diff options
Diffstat (limited to 'drivers/misc')
29 files changed, 511 insertions, 58 deletions
diff --git a/drivers/misc/Kconfig b/drivers/misc/Kconfig index 433aa4197785..75e427f124b2 100644 --- a/drivers/misc/Kconfig +++ b/drivers/misc/Kconfig @@ -538,6 +538,29 @@ config TMR_INJECT Say N here unless you know what you are doing. +config TPS6594_ESM + tristate "TI TPS6594 Error Signal Monitor support" + depends on MFD_TPS6594 + default MFD_TPS6594 + help + Support ESM (Error Signal Monitor) on TPS6594 PMIC devices. + ESM is used typically to reboot the board in error condition. + + This driver can also be built as a module. If so, the module + will be called tps6594-esm. + +config TPS6594_PFSM + tristate "TI TPS6594 Pre-configurable Finite State Machine support" + depends on MFD_TPS6594 + default MFD_TPS6594 + help + Support PFSM (Pre-configurable Finite State Machine) on TPS6594 PMIC devices. + These devices integrate a finite state machine engine, which manages the state + of the device during operating state transition. + + This driver can also be built as a module. If so, the module + will be called tps6594-pfsm. + 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 56de43943cd5..f2a4d1ff65d4 100644 --- a/drivers/misc/Makefile +++ b/drivers/misc/Makefile @@ -65,3 +65,5 @@ 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 +obj-$(CONFIG_TPS6594_ESM) += tps6594-esm.o +obj-$(CONFIG_TPS6594_PFSM) += tps6594-pfsm.o diff --git a/drivers/misc/ad525x_dpot-i2c.c b/drivers/misc/ad525x_dpot-i2c.c index 3856d5c04c5f..469478f7a1d3 100644 --- a/drivers/misc/ad525x_dpot-i2c.c +++ b/drivers/misc/ad525x_dpot-i2c.c @@ -106,7 +106,7 @@ static struct i2c_driver ad_dpot_i2c_driver = { .driver = { .name = "ad_dpot", }, - .probe_new = ad_dpot_i2c_probe, + .probe = ad_dpot_i2c_probe, .remove = ad_dpot_i2c_remove, .id_table = ad_dpot_id, }; diff --git a/drivers/misc/altera-stapl/Makefile b/drivers/misc/altera-stapl/Makefile index dd0f8189666b..90f18e7bf9b0 100644 --- a/drivers/misc/altera-stapl/Makefile +++ b/drivers/misc/altera-stapl/Makefile @@ -1,4 +1,5 @@ # SPDX-License-Identifier: GPL-2.0-only -altera-stapl-objs = altera-lpt.o altera-jtag.o altera-comp.o altera.o +altera-stapl-y = altera-jtag.o altera-comp.o altera.o +altera-stapl-$(CONFIG_HAS_IOPORT) += altera-lpt.o obj-$(CONFIG_ALTERA_STAPL) += altera-stapl.o diff --git a/drivers/misc/altera-stapl/altera.c b/drivers/misc/altera-stapl/altera.c index a58b7cb81d98..587427b73914 100644 --- a/drivers/misc/altera-stapl/altera.c +++ b/drivers/misc/altera-stapl/altera.c @@ -2407,6 +2407,10 @@ int altera_init(struct altera_config *config, const struct firmware *fw) astate->config = config; if (!astate->config->jtag_io) { + if (!IS_ENABLED(CONFIG_HAS_IOPORT)) { + retval = -ENODEV; + goto free_state; + } dprintk("%s: using byteblaster!\n", __func__); astate->config->jtag_io = netup_jtag_io_lpt; } @@ -2481,7 +2485,7 @@ int altera_init(struct altera_config *config, const struct firmware *fw) } else if (exec_result) printk(KERN_ERR "%s: error %d\n", __func__, exec_result); - +free_state: kfree(astate); free_value: kfree(value); diff --git a/drivers/misc/apds9802als.c b/drivers/misc/apds9802als.c index 0526c55d5cd5..693f0e539f37 100644 --- a/drivers/misc/apds9802als.c +++ b/drivers/misc/apds9802als.c @@ -296,7 +296,7 @@ static struct i2c_driver apds9802als_driver = { .name = DRIVER_NAME, .pm = APDS9802ALS_PM_OPS, }, - .probe_new = apds9802als_probe, + .probe = apds9802als_probe, .remove = apds9802als_remove, .id_table = apds9802als_id, }; diff --git a/drivers/misc/apds990x.c b/drivers/misc/apds990x.c index 0024503ea6db..92b92be91d60 100644 --- a/drivers/misc/apds990x.c +++ b/drivers/misc/apds990x.c @@ -1267,11 +1267,11 @@ static const struct dev_pm_ops apds990x_pm_ops = { }; static struct i2c_driver apds990x_driver = { - .driver = { + .driver = { .name = "apds990x", .pm = &apds990x_pm_ops, }, - .probe_new = apds990x_probe, + .probe = apds990x_probe, .remove = apds990x_remove, .id_table = apds990x_id, }; diff --git a/drivers/misc/bh1770glc.c b/drivers/misc/bh1770glc.c index bedbe0efb330..1629b62fd052 100644 --- a/drivers/misc/bh1770glc.c +++ b/drivers/misc/bh1770glc.c @@ -1374,11 +1374,11 @@ static const struct dev_pm_ops bh1770_pm_ops = { }; static struct i2c_driver bh1770_driver = { - .driver = { + .driver = { .name = "bh1770glc", .pm = &bh1770_pm_ops, }, - .probe_new = bh1770_probe, + .probe = bh1770_probe, .remove = bh1770_remove, .id_table = bh1770_id, }; diff --git a/drivers/misc/ds1682.c b/drivers/misc/ds1682.c index d517eed32971..21fc5bc85c5c 100644 --- a/drivers/misc/ds1682.c +++ b/drivers/misc/ds1682.c @@ -250,7 +250,7 @@ static struct i2c_driver ds1682_driver = { .name = "ds1682", .of_match_table = ds1682_of_match, }, - .probe_new = ds1682_probe, + .probe = ds1682_probe, .remove = ds1682_remove, .id_table = ds1682_id, }; diff --git a/drivers/misc/eeprom/at24.c b/drivers/misc/eeprom/at24.c index 938c4f41b98c..dbbf7db4ff2f 100644 --- a/drivers/misc/eeprom/at24.c +++ b/drivers/misc/eeprom/at24.c @@ -761,7 +761,8 @@ static int at24_probe(struct i2c_client *client) pm_runtime_disable(dev); if (!pm_runtime_status_suspended(dev)) regulator_disable(at24->vcc_reg); - return PTR_ERR(at24->nvmem); + return dev_err_probe(dev, PTR_ERR(at24->nvmem), + "failed to register nvmem\n"); } /* @@ -832,7 +833,7 @@ static struct i2c_driver at24_driver = { .of_match_table = at24_of_match, .acpi_match_table = ACPI_PTR(at24_acpi_ids), }, - .probe_new = at24_probe, + .probe = at24_probe, .remove = at24_remove, .id_table = at24_ids, .flags = I2C_DRV_ACPI_WAIVE_D0_PROBE, diff --git a/drivers/misc/eeprom/ee1004.c b/drivers/misc/eeprom/ee1004.c index c8c6deb7ed89..a1acd77130f2 100644 --- a/drivers/misc/eeprom/ee1004.c +++ b/drivers/misc/eeprom/ee1004.c @@ -234,7 +234,7 @@ static struct i2c_driver ee1004_driver = { .name = "ee1004", .dev_groups = ee1004_groups, }, - .probe_new = ee1004_probe, + .probe = ee1004_probe, .remove = ee1004_remove, .id_table = ee1004_ids, }; diff --git a/drivers/misc/eeprom/eeprom.c b/drivers/misc/eeprom/eeprom.c index 32611100d5cd..ccb7c2f7ee2f 100644 --- a/drivers/misc/eeprom/eeprom.c +++ b/drivers/misc/eeprom/eeprom.c @@ -196,7 +196,7 @@ static struct i2c_driver eeprom_driver = { .driver = { .name = "eeprom", }, - .probe_new = eeprom_probe, + .probe = eeprom_probe, .remove = eeprom_remove, .id_table = eeprom_id, diff --git a/drivers/misc/eeprom/idt_89hpesx.c b/drivers/misc/eeprom/idt_89hpesx.c index 7075d0b37881..740c06382b83 100644 --- a/drivers/misc/eeprom/idt_89hpesx.c +++ b/drivers/misc/eeprom/idt_89hpesx.c @@ -1556,7 +1556,7 @@ static struct i2c_driver idt_driver = { .name = IDT_NAME, .of_match_table = idt_of_match, }, - .probe_new = idt_probe, + .probe = idt_probe, .remove = idt_remove, .id_table = idt_ids, }; diff --git a/drivers/misc/eeprom/max6875.c b/drivers/misc/eeprom/max6875.c index 79cf8afcef2e..cb6b1efeafe0 100644 --- a/drivers/misc/eeprom/max6875.c +++ b/drivers/misc/eeprom/max6875.c @@ -192,7 +192,7 @@ static struct i2c_driver max6875_driver = { .driver = { .name = "max6875", }, - .probe_new = max6875_probe, + .probe = max6875_probe, .remove = max6875_remove, .id_table = max6875_id, }; diff --git a/drivers/misc/fastrpc.c b/drivers/misc/fastrpc.c index 30d4d0476248..9666d28037e1 100644 --- a/drivers/misc/fastrpc.c +++ b/drivers/misc/fastrpc.c @@ -1437,7 +1437,7 @@ static int fastrpc_init_create_process(struct fastrpc_user *fl, sc = FASTRPC_SCALARS(FASTRPC_RMID_INIT_CREATE, 4, 0); if (init.attrs) - sc = FASTRPC_SCALARS(FASTRPC_RMID_INIT_CREATE_ATTR, 6, 0); + sc = FASTRPC_SCALARS(FASTRPC_RMID_INIT_CREATE_ATTR, 4, 0); err = fastrpc_internal_invoke(fl, true, FASTRPC_INIT_HANDLE, sc, args); @@ -2225,6 +2225,9 @@ static int fastrpc_device_register(struct device *dev, struct fastrpc_channel_ct fdev->miscdev.fops = &fastrpc_fops; fdev->miscdev.name = devm_kasprintf(dev, GFP_KERNEL, "fastrpc-%s%s", domain, is_secured ? "-secure" : ""); + if (!fdev->miscdev.name) + return -ENOMEM; + err = misc_register(&fdev->miscdev); if (!err) { if (is_secured) diff --git a/drivers/misc/hmc6352.c b/drivers/misc/hmc6352.c index 8967940ecd1e..759eaeb64307 100644 --- a/drivers/misc/hmc6352.c +++ b/drivers/misc/hmc6352.c @@ -131,7 +131,7 @@ static struct i2c_driver hmc6352_driver = { .driver = { .name = "hmc6352", }, - .probe_new = hmc6352_probe, + .probe = hmc6352_probe, .remove = hmc6352_remove, .id_table = hmc6352_id, }; diff --git a/drivers/misc/ics932s401.c b/drivers/misc/ics932s401.c index 12108a7b9b40..ee6296b98078 100644 --- a/drivers/misc/ics932s401.c +++ b/drivers/misc/ics932s401.c @@ -105,7 +105,7 @@ static struct i2c_driver ics932s401_driver = { .driver = { .name = "ics932s401", }, - .probe_new = ics932s401_probe, + .probe = ics932s401_probe, .remove = ics932s401_remove, .id_table = ics932s401_id, .detect = ics932s401_detect, diff --git a/drivers/misc/isl29003.c b/drivers/misc/isl29003.c index 147b58f7968d..ebf0635aee64 100644 --- a/drivers/misc/isl29003.c +++ b/drivers/misc/isl29003.c @@ -459,7 +459,7 @@ static struct i2c_driver isl29003_driver = { .name = ISL29003_DRV_NAME, .pm = ISL29003_PM_OPS, }, - .probe_new = isl29003_probe, + .probe = isl29003_probe, .remove = isl29003_remove, .id_table = isl29003_id, }; diff --git a/drivers/misc/isl29020.c b/drivers/misc/isl29020.c index 3be02093368c..c5976fa8c825 100644 --- a/drivers/misc/isl29020.c +++ b/drivers/misc/isl29020.c @@ -214,7 +214,7 @@ static struct i2c_driver isl29020_driver = { .name = "isl29020", .pm = ISL29020_PM_OPS, }, - .probe_new = isl29020_probe, + .probe = isl29020_probe, .remove = isl29020_remove, .id_table = isl29020_id, }; diff --git a/drivers/misc/lis3lv02d/lis3lv02d_i2c.c b/drivers/misc/lis3lv02d/lis3lv02d_i2c.c index 7071412d6bf6..3882e97e96a7 100644 --- a/drivers/misc/lis3lv02d/lis3lv02d_i2c.c +++ b/drivers/misc/lis3lv02d/lis3lv02d_i2c.c @@ -262,7 +262,7 @@ static struct i2c_driver lis3lv02d_i2c_driver = { .pm = &lis3_pm_ops, .of_match_table = of_match_ptr(lis3lv02d_i2c_dt_ids), }, - .probe_new = lis3lv02d_i2c_probe, + .probe = lis3lv02d_i2c_probe, .remove = lis3lv02d_i2c_remove, .id_table = lis3lv02d_id, }; diff --git a/drivers/misc/lkdtm/core.c b/drivers/misc/lkdtm/core.c index b4712ff196b4..0772e4a4757e 100644 --- a/drivers/misc/lkdtm/core.c +++ b/drivers/misc/lkdtm/core.c @@ -79,7 +79,7 @@ static struct crashpoint crashpoints[] = { CRASHPOINT("INT_HARDWARE_ENTRY", "do_IRQ"), CRASHPOINT("INT_HW_IRQ_EN", "handle_irq_event"), CRASHPOINT("INT_TASKLET_ENTRY", "tasklet_action"), - CRASHPOINT("FS_DEVRW", "ll_rw_block"), + CRASHPOINT("FS_SUBMIT_BH", "submit_bh"), CRASHPOINT("MEM_SWAPOUT", "shrink_inactive_list"), CRASHPOINT("TIMERADD", "hrtimer_start"), CRASHPOINT("SCSI_QUEUE_RQ", "scsi_queue_rq"), diff --git a/drivers/misc/mei/bus-fixup.c b/drivers/misc/mei/bus-fixup.c index 31e3c74ca1f1..b8b716faf192 100644 --- a/drivers/misc/mei/bus-fixup.c +++ b/drivers/misc/mei/bus-fixup.c @@ -108,7 +108,7 @@ struct mkhi_fw_ver { static int mei_osver(struct mei_cl_device *cldev) { const size_t size = MKHI_OSVER_BUF_LEN; - char buf[MKHI_OSVER_BUF_LEN]; + u8 buf[MKHI_OSVER_BUF_LEN]; struct mkhi_msg *req; struct mkhi_fwcaps *fwcaps; struct mei_os_ver *os_ver; @@ -137,7 +137,7 @@ static int mei_osver(struct mei_cl_device *cldev) sizeof(struct mkhi_fw_ver_block) * (__num)) static int mei_fwver(struct mei_cl_device *cldev) { - char buf[MKHI_FWVER_BUF_LEN]; + u8 buf[MKHI_FWVER_BUF_LEN]; struct mkhi_msg req; struct mkhi_msg *rsp; struct mkhi_fw_ver *fwver; diff --git a/drivers/misc/mei/bus.c b/drivers/misc/mei/bus.c index 5d7a68674d9b..33ec6424dfee 100644 --- a/drivers/misc/mei/bus.c +++ b/drivers/misc/mei/bus.c @@ -1046,9 +1046,6 @@ static int mei_cl_device_match(struct device *dev, struct device_driver *drv) const struct mei_cl_driver *cldrv = to_mei_cl_driver(drv); const struct mei_cl_device_id *found_id; - if (!cldev) - return 0; - if (!cldev->do_match) return 0; @@ -1079,9 +1076,6 @@ static int mei_cl_device_probe(struct device *dev) cldev = to_mei_cl_device(dev); cldrv = to_mei_cl_driver(dev->driver); - if (!cldev) - return 0; - if (!cldrv || !cldrv->probe) return -ENODEV; @@ -1276,9 +1270,6 @@ static void mei_cl_bus_dev_release(struct device *dev) { struct mei_cl_device *cldev = to_mei_cl_device(dev); - if (!cldev) - return; - mei_cl_flush_queues(cldev->cl, NULL); mei_me_cl_put(cldev->me_cl); mei_dev_bus_put(cldev->bus); diff --git a/drivers/misc/smpro-errmon.c b/drivers/misc/smpro-errmon.c index a1f0b2c77fac..c12035a46585 100644 --- a/drivers/misc/smpro-errmon.c +++ b/drivers/misc/smpro-errmon.c @@ -6,7 +6,6 @@ * */ -#include <linux/i2c.h> #include <linux/mod_devicetable.h> #include <linux/module.h> #include <linux/platform_device.h> diff --git a/drivers/misc/tps6594-esm.c b/drivers/misc/tps6594-esm.c new file mode 100644 index 000000000000..b488f704f104 --- /dev/null +++ b/drivers/misc/tps6594-esm.c @@ -0,0 +1,132 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * ESM (Error Signal Monitor) driver for TI TPS6594/TPS6593/LP8764 PMICs + * + * Copyright (C) 2023 BayLibre Incorporated - https://www.baylibre.com/ + */ + +#include <linux/interrupt.h> +#include <linux/module.h> +#include <linux/platform_device.h> +#include <linux/pm_runtime.h> +#include <linux/regmap.h> + +#include <linux/mfd/tps6594.h> + +static irqreturn_t tps6594_esm_isr(int irq, void *dev_id) +{ + struct platform_device *pdev = dev_id; + int i; + + for (i = 0 ; i < pdev->num_resources ; i++) { + if (irq == platform_get_irq_byname(pdev, pdev->resource[i].name)) { + dev_err(pdev->dev.parent, "%s error detected\n", pdev->resource[i].name); + return IRQ_HANDLED; + } + } + + return IRQ_NONE; +} + +static int tps6594_esm_probe(struct platform_device *pdev) +{ + struct tps6594 *tps = dev_get_drvdata(pdev->dev.parent); + struct device *dev = &pdev->dev; + int irq; + int ret; + int i; + + for (i = 0 ; i < pdev->num_resources ; i++) { + irq = platform_get_irq_byname(pdev, pdev->resource[i].name); + if (irq < 0) + return dev_err_probe(dev, irq, "Failed to get %s irq\n", + pdev->resource[i].name); + + ret = devm_request_threaded_irq(dev, irq, NULL, + tps6594_esm_isr, IRQF_ONESHOT, + pdev->resource[i].name, pdev); + if (ret) + return dev_err_probe(dev, ret, "Failed to request irq\n"); + } + + ret = regmap_set_bits(tps->regmap, TPS6594_REG_ESM_SOC_MODE_CFG, + TPS6594_BIT_ESM_SOC_EN | TPS6594_BIT_ESM_SOC_ENDRV); + if (ret) + return dev_err_probe(dev, ret, "Failed to configure ESM\n"); + + ret = regmap_set_bits(tps->regmap, TPS6594_REG_ESM_SOC_START_REG, + TPS6594_BIT_ESM_SOC_START); + if (ret) + return dev_err_probe(dev, ret, "Failed to start ESM\n"); + + pm_runtime_enable(dev); + pm_runtime_get_sync(dev); + + return 0; +} + +static int tps6594_esm_remove(struct platform_device *pdev) +{ + struct tps6594 *tps = dev_get_drvdata(pdev->dev.parent); + struct device *dev = &pdev->dev; + int ret; + + ret = regmap_clear_bits(tps->regmap, TPS6594_REG_ESM_SOC_START_REG, + TPS6594_BIT_ESM_SOC_START); + if (ret) { + dev_err(dev, "Failed to stop ESM\n"); + goto out; + } + + ret = regmap_clear_bits(tps->regmap, TPS6594_REG_ESM_SOC_MODE_CFG, + TPS6594_BIT_ESM_SOC_EN | TPS6594_BIT_ESM_SOC_ENDRV); + if (ret) + dev_err(dev, "Failed to unconfigure ESM\n"); + +out: + pm_runtime_put_sync(dev); + pm_runtime_disable(dev); + + return ret; +} + +static int tps6594_esm_suspend(struct device *dev) +{ + struct tps6594 *tps = dev_get_drvdata(dev->parent); + int ret; + + ret = regmap_clear_bits(tps->regmap, TPS6594_REG_ESM_SOC_START_REG, + TPS6594_BIT_ESM_SOC_START); + + pm_runtime_put_sync(dev); + + return ret; +} + +static int tps6594_esm_resume(struct device *dev) +{ + struct tps6594 *tps = dev_get_drvdata(dev->parent); + + pm_runtime_get_sync(dev); + + return regmap_set_bits(tps->regmap, TPS6594_REG_ESM_SOC_START_REG, + TPS6594_BIT_ESM_SOC_START); +} + +static DEFINE_SIMPLE_DEV_PM_OPS(tps6594_esm_pm_ops, tps6594_esm_suspend, tps6594_esm_resume); + +static struct platform_driver tps6594_esm_driver = { + .driver = { + .name = "tps6594-esm", + .pm = pm_sleep_ptr(&tps6594_esm_pm_ops), + }, + .probe = tps6594_esm_probe, + .remove = tps6594_esm_remove, +}; + +module_platform_driver(tps6594_esm_driver); + +MODULE_ALIAS("platform:tps6594-esm"); +MODULE_AUTHOR("Julien Panis <jpanis@baylibre.com>"); +MODULE_DESCRIPTION("TPS6594 Error Signal Monitor Driver"); +MODULE_LICENSE("GPL"); diff --git a/drivers/misc/tps6594-pfsm.c b/drivers/misc/tps6594-pfsm.c new file mode 100644 index 000000000000..5223d1580807 --- /dev/null +++ b/drivers/misc/tps6594-pfsm.c @@ -0,0 +1,306 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * PFSM (Pre-configurable Finite State Machine) driver for TI TPS6594/TPS6593/LP8764 PMICs + * + * Copyright (C) 2023 BayLibre Incorporated - https://www.baylibre.com/ + */ + +#include <linux/errno.h> +#include <linux/fs.h> +#include <linux/interrupt.h> +#include <linux/ioctl.h> +#include <linux/miscdevice.h> +#include <linux/module.h> +#include <linux/platform_device.h> +#include <linux/regmap.h> + +#include <linux/mfd/tps6594.h> + +#include <linux/tps6594_pfsm.h> + +#define TPS6594_STARTUP_DEST_MCU_ONLY_VAL 2 +#define TPS6594_STARTUP_DEST_ACTIVE_VAL 3 +#define TPS6594_STARTUP_DEST_SHIFT 5 +#define TPS6594_STARTUP_DEST_MCU_ONLY (TPS6594_STARTUP_DEST_MCU_ONLY_VAL \ + << TPS6594_STARTUP_DEST_SHIFT) +#define TPS6594_STARTUP_DEST_ACTIVE (TPS6594_STARTUP_DEST_ACTIVE_VAL \ + << TPS6594_STARTUP_DEST_SHIFT) + +/* + * To update the PMIC firmware, the user must be able to access + * page 0 (user registers) and page 1 (NVM control and configuration). + */ +#define TPS6594_PMIC_MAX_POS 0x200 + +#define TPS6594_FILE_TO_PFSM(f) container_of((f)->private_data, struct tps6594_pfsm, miscdev) + +/** + * struct tps6594_pfsm - device private data structure + * + * @miscdev: misc device infos + * @regmap: regmap for accessing the device registers + */ +struct tps6594_pfsm { + struct miscdevice miscdev; + struct regmap *regmap; +}; + +static ssize_t tps6594_pfsm_read(struct file *f, char __user *buf, + size_t count, loff_t *ppos) +{ + struct tps6594_pfsm *pfsm = TPS6594_FILE_TO_PFSM(f); + loff_t pos = *ppos; + unsigned int val; + int ret; + int i; + + if (pos < 0) + return -EINVAL; + if (pos >= TPS6594_PMIC_MAX_POS) + return 0; + if (count > TPS6594_PMIC_MAX_POS - pos) + count = TPS6594_PMIC_MAX_POS - pos; + + for (i = 0 ; i < count ; i++) { + ret = regmap_read(pfsm->regmap, pos + i, &val); + if (ret) + return ret; + + if (put_user(val, buf + i)) + return -EFAULT; + } + + *ppos = pos + count; + + return count; +} + +static ssize_t tps6594_pfsm_write(struct file *f, const char __user *buf, + size_t count, loff_t *ppos) +{ + struct tps6594_pfsm *pfsm = TPS6594_FILE_TO_PFSM(f); + loff_t pos = *ppos; + char val; + int ret; + int i; + + if (pos < 0) + return -EINVAL; + if (pos >= TPS6594_PMIC_MAX_POS || !count) + return 0; + if (count > TPS6594_PMIC_MAX_POS - pos) + count = TPS6594_PMIC_MAX_POS - pos; + + for (i = 0 ; i < count ; i++) { + if (get_user(val, buf + i)) + return -EFAULT; + + ret = regmap_write(pfsm->regmap, pos + i, val); + if (ret) + return ret; + } + + *ppos = pos + count; + + return count; +} + +static int tps6594_pfsm_configure_ret_trig(struct regmap *regmap, u8 gpio_ret, u8 ddr_ret) +{ + int ret; + + if (gpio_ret) + ret = regmap_set_bits(regmap, TPS6594_REG_FSM_I2C_TRIGGERS, + TPS6594_BIT_TRIGGER_I2C(5) | TPS6594_BIT_TRIGGER_I2C(6)); + else + ret = regmap_clear_bits(regmap, TPS6594_REG_FSM_I2C_TRIGGERS, + TPS6594_BIT_TRIGGER_I2C(5) | TPS6594_BIT_TRIGGER_I2C(6)); + if (ret) + return ret; + + if (ddr_ret) + ret = regmap_set_bits(regmap, TPS6594_REG_FSM_I2C_TRIGGERS, + TPS6594_BIT_TRIGGER_I2C(7)); + else + ret = regmap_clear_bits(regmap, TPS6594_REG_FSM_I2C_TRIGGERS, + TPS6594_BIT_TRIGGER_I2C(7)); + + return ret; +} + +static long tps6594_pfsm_ioctl(struct file *f, unsigned int cmd, unsigned long arg) +{ + struct tps6594_pfsm *pfsm = TPS6594_FILE_TO_PFSM(f); + struct pmic_state_opt state_opt; + void __user *argp = (void __user *)arg; + 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; + + /* 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: + /* Enable LP mode */ + ret = regmap_set_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_UPDATE_PGM: + /* Force trigger */ + ret = regmap_write_bits(pfsm->regmap, TPS6594_REG_FSM_I2C_TRIGGERS, + TPS6594_BIT_TRIGGER_I2C(3), TPS6594_BIT_TRIGGER_I2C(3)); + break; + case PMIC_SET_ACTIVE_STATE: + /* Modify NSLEEP1-2 bits */ + ret = regmap_set_bits(pfsm->regmap, TPS6594_REG_FSM_NSLEEP_TRIGGERS, + TPS6594_BIT_NSLEEP1B | TPS6594_BIT_NSLEEP2B); + break; + case PMIC_SET_MCU_ONLY_STATE: + if (copy_from_user(&state_opt, argp, sizeof(state_opt))) + return -EFAULT; + + /* Configure retention triggers */ + ret = tps6594_pfsm_configure_ret_trig(pfsm->regmap, state_opt.gpio_retention, + state_opt.ddr_retention); + if (ret) + return ret; + + /* Modify NSLEEP1-2 bits */ + ret = regmap_clear_bits(pfsm->regmap, TPS6594_REG_FSM_NSLEEP_TRIGGERS, + TPS6594_BIT_NSLEEP1B); + if (ret) + return ret; + + ret = regmap_set_bits(pfsm->regmap, TPS6594_REG_FSM_NSLEEP_TRIGGERS, + TPS6594_BIT_NSLEEP2B); + break; + case PMIC_SET_RETENTION_STATE: + if (copy_from_user(&state_opt, argp, sizeof(state_opt))) + return -EFAULT; + + /* Configure wake-up destination */ + 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); + else + ret = regmap_write_bits(pfsm->regmap, TPS6594_REG_RTC_CTRL_2, + TPS6594_MASK_STARTUP_DEST, + TPS6594_STARTUP_DEST_ACTIVE); + if (ret) + return ret; + + /* Configure retention triggers */ + ret = tps6594_pfsm_configure_ret_trig(pfsm->regmap, state_opt.gpio_retention, + state_opt.ddr_retention); + if (ret) + return ret; + + /* Modify NSLEEP1-2 bits */ + ret = regmap_clear_bits(pfsm->regmap, TPS6594_REG_FSM_NSLEEP_TRIGGERS, + TPS6594_BIT_NSLEEP2B); + break; + } + + return ret; +} + +static const struct file_operations tps6594_pfsm_fops = { + .owner = THIS_MODULE, + .llseek = generic_file_llseek, + .read = tps6594_pfsm_read, + .write = tps6594_pfsm_write, + .unlocked_ioctl = tps6594_pfsm_ioctl, + .compat_ioctl = compat_ptr_ioctl, +}; + +static irqreturn_t tps6594_pfsm_isr(int irq, void *dev_id) +{ + struct platform_device *pdev = dev_id; + int i; + + for (i = 0 ; i < pdev->num_resources ; i++) { + if (irq == platform_get_irq_byname(pdev, pdev->resource[i].name)) { + dev_err(pdev->dev.parent, "%s event detected\n", pdev->resource[i].name); + return IRQ_HANDLED; + } + } + + return IRQ_NONE; +} + +static int tps6594_pfsm_probe(struct platform_device *pdev) +{ + struct tps6594_pfsm *pfsm; + struct tps6594 *tps = dev_get_drvdata(pdev->dev.parent); + struct device *dev = &pdev->dev; + int irq; + int ret; + int i; + + pfsm = devm_kzalloc(dev, sizeof(struct tps6594_pfsm), GFP_KERNEL); + if (!pfsm) + return -ENOMEM; + + pfsm->regmap = tps->regmap; + + pfsm->miscdev.minor = MISC_DYNAMIC_MINOR; + pfsm->miscdev.name = devm_kasprintf(dev, GFP_KERNEL, "pfsm-%ld-0x%02x", + tps->chip_id, tps->reg); + pfsm->miscdev.fops = &tps6594_pfsm_fops; + pfsm->miscdev.parent = dev->parent; + + for (i = 0 ; i < pdev->num_resources ; i++) { + irq = platform_get_irq_byname(pdev, pdev->resource[i].name); + if (irq < 0) + return dev_err_probe(dev, irq, "Failed to get %s irq\n", + pdev->resource[i].name); + + ret = devm_request_threaded_irq(dev, irq, NULL, + tps6594_pfsm_isr, IRQF_ONESHOT, + pdev->resource[i].name, pdev); + if (ret) + return dev_err_probe(dev, ret, "Failed to request irq\n"); + } + + platform_set_drvdata(pdev, pfsm); + + return misc_register(&pfsm->miscdev); +} + +static int tps6594_pfsm_remove(struct platform_device *pdev) +{ + struct tps6594_pfsm *pfsm = platform_get_drvdata(pdev); + + misc_deregister(&pfsm->miscdev); + + return 0; +} + +static struct platform_driver tps6594_pfsm_driver = { + .driver = { + .name = "tps6594-pfsm", + }, + .probe = tps6594_pfsm_probe, + .remove = tps6594_pfsm_remove, +}; + +module_platform_driver(tps6594_pfsm_driver); + +MODULE_ALIAS("platform:tps6594-pfsm"); +MODULE_AUTHOR("Julien Panis <jpanis@baylibre.com>"); +MODULE_DESCRIPTION("TPS6594 Pre-configurable Finite State Machine Driver"); +MODULE_LICENSE("GPL"); diff --git a/drivers/misc/tsl2550.c b/drivers/misc/tsl2550.c index 6c62b94e0acd..a3bc2823143e 100644 --- a/drivers/misc/tsl2550.c +++ b/drivers/misc/tsl2550.c @@ -437,7 +437,7 @@ static struct i2c_driver tsl2550_driver = { .of_match_table = tsl2550_of_match, .pm = TSL2550_PM_OPS, }, - .probe_new = tsl2550_probe, + .probe = tsl2550_probe, .remove = tsl2550_remove, .id_table = tsl2550_id, }; diff --git a/drivers/misc/uacce/uacce.c b/drivers/misc/uacce/uacce.c index 346bd7cf2e94..930c252753a0 100644 --- a/drivers/misc/uacce/uacce.c +++ b/drivers/misc/uacce/uacce.c @@ -166,8 +166,8 @@ static int uacce_fops_open(struct inode *inode, struct file *filep) init_waitqueue_head(&q->wait); filep->private_data = q; - uacce->inode = inode; q->state = UACCE_Q_INIT; + q->mapping = filep->f_mapping; mutex_init(&q->mutex); list_add(&q->list, &uacce->queues); mutex_unlock(&uacce->mutex); @@ -200,12 +200,15 @@ static int uacce_fops_release(struct inode *inode, struct file *filep) static void uacce_vma_close(struct vm_area_struct *vma) { struct uacce_queue *q = vma->vm_private_data; - struct uacce_qfile_region *qfr = NULL; - if (vma->vm_pgoff < UACCE_MAX_REGION) - qfr = q->qfrs[vma->vm_pgoff]; + if (vma->vm_pgoff < UACCE_MAX_REGION) { + struct uacce_qfile_region *qfr = q->qfrs[vma->vm_pgoff]; - kfree(qfr); + mutex_lock(&q->mutex); + q->qfrs[vma->vm_pgoff] = NULL; + mutex_unlock(&q->mutex); + kfree(qfr); + } } static const struct vm_operations_struct uacce_vm_ops = { @@ -574,12 +577,6 @@ void uacce_remove(struct uacce_device *uacce) if (!uacce) return; - /* - * unmap remaining mapping from user space, preventing user still - * access the mmaped area while parent device is already removed - */ - if (uacce->inode) - unmap_mapping_range(uacce->inode->i_mapping, 0, 0, 1); /* * uacce_fops_open() may be running concurrently, even after we remove @@ -597,6 +594,12 @@ void uacce_remove(struct uacce_device *uacce) uacce_put_queue(q); mutex_unlock(&q->mutex); uacce_unbind_queue(q); + + /* + * unmap remaining mapping from user space, preventing user still + * access the mmaped area while parent device is already removed + */ + unmap_mapping_range(q->mapping, 0, 0, 1); } /* disable sva now since no opened queues */ diff --git a/drivers/misc/xilinx_sdfec.c b/drivers/misc/xilinx_sdfec.c index cb9506f9cbd0..270ff4c5971a 100644 --- a/drivers/misc/xilinx_sdfec.c +++ b/drivers/misc/xilinx_sdfec.c @@ -855,16 +855,6 @@ static int xsdfec_cfg_axi_streams(struct xsdfec_dev *xsdfec) return 0; } -static int xsdfec_dev_open(struct inode *iptr, struct file *fptr) -{ - return 0; -} - -static int xsdfec_dev_release(struct inode *iptr, struct file *fptr) -{ - return 0; -} - static int xsdfec_start(struct xsdfec_dev *xsdfec) { u32 regread; @@ -1030,8 +1020,6 @@ static __poll_t xsdfec_poll(struct file *file, poll_table *wait) static const struct file_operations xsdfec_fops = { .owner = THIS_MODULE, - .open = xsdfec_dev_open, - .release = xsdfec_dev_release, .unlocked_ioctl = xsdfec_dev_ioctl, .poll = xsdfec_poll, .compat_ioctl = compat_ptr_ioctl, |