Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

misc: tps6594-esm: Add driver for TI TPS6594 ESM

This patch adds support for TPS6594 ESM (Error Signal Monitor).
This device monitors the SoC error output signal at its nERR_SOC input pin.
In error condition, ESM toggles its nRSTOUT_SOC pin to reset the SoC.

Signed-off-by: Julien Panis <jpanis@baylibre.com>
Message-ID: <20230511095126.105104-4-jpanis@baylibre.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>

authored by

Julien Panis and committed by
Greg Kroah-Hartman
875fdd07 9fb90804

+144
+11
drivers/misc/Kconfig
··· 538 538 539 539 Say N here unless you know what you are doing. 540 540 541 + config TPS6594_ESM 542 + tristate "TI TPS6594 Error Signal Monitor support" 543 + depends on MFD_TPS6594 544 + default MFD_TPS6594 545 + help 546 + Support ESM (Error Signal Monitor) on TPS6594 PMIC devices. 547 + ESM is used typically to reboot the board in error condition. 548 + 549 + This driver can also be built as a module. If so, the module 550 + will be called tps6594-esm. 551 + 541 552 source "drivers/misc/c2port/Kconfig" 542 553 source "drivers/misc/eeprom/Kconfig" 543 554 source "drivers/misc/cb710/Kconfig"
+1
drivers/misc/Makefile
··· 65 65 obj-$(CONFIG_VCPU_STALL_DETECTOR) += vcpu_stall_detector.o 66 66 obj-$(CONFIG_TMR_MANAGER) += xilinx_tmr_manager.o 67 67 obj-$(CONFIG_TMR_INJECT) += xilinx_tmr_inject.o 68 + obj-$(CONFIG_TPS6594_ESM) += tps6594-esm.o
+132
drivers/misc/tps6594-esm.c
··· 1 + // SPDX-License-Identifier: GPL-2.0 2 + /* 3 + * ESM (Error Signal Monitor) driver for TI TPS6594/TPS6593/LP8764 PMICs 4 + * 5 + * Copyright (C) 2023 BayLibre Incorporated - https://www.baylibre.com/ 6 + */ 7 + 8 + #include <linux/interrupt.h> 9 + #include <linux/module.h> 10 + #include <linux/platform_device.h> 11 + #include <linux/pm_runtime.h> 12 + #include <linux/regmap.h> 13 + 14 + #include <linux/mfd/tps6594.h> 15 + 16 + static irqreturn_t tps6594_esm_isr(int irq, void *dev_id) 17 + { 18 + struct platform_device *pdev = dev_id; 19 + int i; 20 + 21 + for (i = 0 ; i < pdev->num_resources ; i++) { 22 + if (irq == platform_get_irq_byname(pdev, pdev->resource[i].name)) { 23 + dev_err(pdev->dev.parent, "%s error detected\n", pdev->resource[i].name); 24 + return IRQ_HANDLED; 25 + } 26 + } 27 + 28 + return IRQ_NONE; 29 + } 30 + 31 + static int tps6594_esm_probe(struct platform_device *pdev) 32 + { 33 + struct tps6594 *tps = dev_get_drvdata(pdev->dev.parent); 34 + struct device *dev = &pdev->dev; 35 + int irq; 36 + int ret; 37 + int i; 38 + 39 + for (i = 0 ; i < pdev->num_resources ; i++) { 40 + irq = platform_get_irq_byname(pdev, pdev->resource[i].name); 41 + if (irq < 0) 42 + return dev_err_probe(dev, irq, "Failed to get %s irq\n", 43 + pdev->resource[i].name); 44 + 45 + ret = devm_request_threaded_irq(dev, irq, NULL, 46 + tps6594_esm_isr, IRQF_ONESHOT, 47 + pdev->resource[i].name, pdev); 48 + if (ret) 49 + return dev_err_probe(dev, ret, "Failed to request irq\n"); 50 + } 51 + 52 + ret = regmap_set_bits(tps->regmap, TPS6594_REG_ESM_SOC_MODE_CFG, 53 + TPS6594_BIT_ESM_SOC_EN | TPS6594_BIT_ESM_SOC_ENDRV); 54 + if (ret) 55 + return dev_err_probe(dev, ret, "Failed to configure ESM\n"); 56 + 57 + ret = regmap_set_bits(tps->regmap, TPS6594_REG_ESM_SOC_START_REG, 58 + TPS6594_BIT_ESM_SOC_START); 59 + if (ret) 60 + return dev_err_probe(dev, ret, "Failed to start ESM\n"); 61 + 62 + pm_runtime_enable(dev); 63 + pm_runtime_get_sync(dev); 64 + 65 + return 0; 66 + } 67 + 68 + static int tps6594_esm_remove(struct platform_device *pdev) 69 + { 70 + struct tps6594 *tps = dev_get_drvdata(pdev->dev.parent); 71 + struct device *dev = &pdev->dev; 72 + int ret; 73 + 74 + ret = regmap_clear_bits(tps->regmap, TPS6594_REG_ESM_SOC_START_REG, 75 + TPS6594_BIT_ESM_SOC_START); 76 + if (ret) { 77 + dev_err(dev, "Failed to stop ESM\n"); 78 + goto out; 79 + } 80 + 81 + ret = regmap_clear_bits(tps->regmap, TPS6594_REG_ESM_SOC_MODE_CFG, 82 + TPS6594_BIT_ESM_SOC_EN | TPS6594_BIT_ESM_SOC_ENDRV); 83 + if (ret) 84 + dev_err(dev, "Failed to unconfigure ESM\n"); 85 + 86 + out: 87 + pm_runtime_put_sync(dev); 88 + pm_runtime_disable(dev); 89 + 90 + return ret; 91 + } 92 + 93 + static int tps6594_esm_suspend(struct device *dev) 94 + { 95 + struct tps6594 *tps = dev_get_drvdata(dev->parent); 96 + int ret; 97 + 98 + ret = regmap_clear_bits(tps->regmap, TPS6594_REG_ESM_SOC_START_REG, 99 + TPS6594_BIT_ESM_SOC_START); 100 + 101 + pm_runtime_put_sync(dev); 102 + 103 + return ret; 104 + } 105 + 106 + static int tps6594_esm_resume(struct device *dev) 107 + { 108 + struct tps6594 *tps = dev_get_drvdata(dev->parent); 109 + 110 + pm_runtime_get_sync(dev); 111 + 112 + return regmap_set_bits(tps->regmap, TPS6594_REG_ESM_SOC_START_REG, 113 + TPS6594_BIT_ESM_SOC_START); 114 + } 115 + 116 + static DEFINE_SIMPLE_DEV_PM_OPS(tps6594_esm_pm_ops, tps6594_esm_suspend, tps6594_esm_resume); 117 + 118 + static struct platform_driver tps6594_esm_driver = { 119 + .driver = { 120 + .name = "tps6594-esm", 121 + .pm = pm_sleep_ptr(&tps6594_esm_pm_ops), 122 + }, 123 + .probe = tps6594_esm_probe, 124 + .remove = tps6594_esm_remove, 125 + }; 126 + 127 + module_platform_driver(tps6594_esm_driver); 128 + 129 + MODULE_ALIAS("platform:tps6594-esm"); 130 + MODULE_AUTHOR("Julien Panis <jpanis@baylibre.com>"); 131 + MODULE_DESCRIPTION("TPS6594 Error Signal Monitor Driver"); 132 + MODULE_LICENSE("GPL");