From e695d3a0b3b302974c1fd7b36ea91fe58fb9ca14 Mon Sep 17 00:00:00 2001 From: Chen Zhong Date: Wed, 25 Oct 2017 21:15:59 +0800 Subject: mfd: mt6397: Create irq mappings in mfd core driver The core driver should create and manage irq mappings instead of leaf drivers. This patch change to pass irq domain to devm_mfd_add_devices() and it will create mapping for irq resources automatically. And remove irq mapping in rtc driver since this has been done in core driver. Signed-off-by: Chen Zhong Acked-by: Alexandre Belloni Signed-off-by: Lee Jones --- drivers/mfd/mt6397-core.c | 4 ++-- drivers/rtc/rtc-mt6397.c | 7 +++---- 2 files changed, 5 insertions(+), 6 deletions(-) diff --git a/drivers/mfd/mt6397-core.c b/drivers/mfd/mt6397-core.c index 04a601f6aebe..6546d7f88b5e 100644 --- a/drivers/mfd/mt6397-core.c +++ b/drivers/mfd/mt6397-core.c @@ -289,7 +289,7 @@ static int mt6397_probe(struct platform_device *pdev) ret = devm_mfd_add_devices(&pdev->dev, -1, mt6323_devs, ARRAY_SIZE(mt6323_devs), NULL, - 0, NULL); + 0, pmic->irq_domain); break; case MT6397_CID_CODE: @@ -304,7 +304,7 @@ static int mt6397_probe(struct platform_device *pdev) ret = devm_mfd_add_devices(&pdev->dev, -1, mt6397_devs, ARRAY_SIZE(mt6397_devs), NULL, - 0, NULL); + 0, pmic->irq_domain); break; default: diff --git a/drivers/rtc/rtc-mt6397.c b/drivers/rtc/rtc-mt6397.c index 1a61fa56f3ad..385f8303bb41 100644 --- a/drivers/rtc/rtc-mt6397.c +++ b/drivers/rtc/rtc-mt6397.c @@ -322,10 +322,9 @@ static int mtk_rtc_probe(struct platform_device *pdev) res = platform_get_resource(pdev, IORESOURCE_MEM, 0); rtc->addr_base = res->start; - res = platform_get_resource(pdev, IORESOURCE_IRQ, 0); - rtc->irq = irq_create_mapping(mt6397_chip->irq_domain, res->start); - if (rtc->irq <= 0) - return -EINVAL; + rtc->irq = platform_get_irq(pdev, 0); + if (rtc->irq < 0) + return rtc->irq; rtc->regmap = mt6397_chip->regmap; rtc->dev = &pdev->dev; -- cgit v1.2.3 From 61217795decb422c2c3767cb76d5cc88ad85be26 Mon Sep 17 00:00:00 2001 From: Chen Zhong Date: Wed, 25 Oct 2017 21:16:01 +0800 Subject: dt-bindings: input: Add document bindings for mtk-pmic-keys This patch adds the device tree binding documentation for the MediaTek pmic keys found on PMIC MT6397/MT6323. Signed-off-by: Chen Zhong Acked-by: Rob Herring Acked-by: Dmitry Torokhov Signed-off-by: Lee Jones --- .../devicetree/bindings/input/mtk-pmic-keys.txt | 43 ++++++++++++++++++++++ 1 file changed, 43 insertions(+) create mode 100644 Documentation/devicetree/bindings/input/mtk-pmic-keys.txt diff --git a/Documentation/devicetree/bindings/input/mtk-pmic-keys.txt b/Documentation/devicetree/bindings/input/mtk-pmic-keys.txt new file mode 100644 index 000000000000..2888d07c2ef0 --- /dev/null +++ b/Documentation/devicetree/bindings/input/mtk-pmic-keys.txt @@ -0,0 +1,43 @@ +MediaTek MT6397/MT6323 PMIC Keys Device Driver + +There are two key functions provided by MT6397/MT6323 PMIC, pwrkey +and homekey. The key functions are defined as the subnode of the function +node provided by MT6397/MT6323 PMIC that is being defined as one kind +of Muti-Function Device (MFD) + +For MT6397/MT6323 MFD bindings see: +Documentation/devicetree/bindings/mfd/mt6397.txt + +Required properties: +- compatible: "mediatek,mt6397-keys" or "mediatek,mt6323-keys" +- linux,keycodes: See Documentation/devicetree/bindings/input/keys.txt + +Optional Properties: +- wakeup-source: See Documentation/devicetree/bindings/power/wakeup-source.txt +- mediatek,long-press-mode: Long press key shutdown setting, 1 for + pwrkey only, 2 for pwrkey/homekey together, others for disabled. +- power-off-time-sec: See Documentation/devicetree/bindings/input/keys.txt + +Example: + + pmic: mt6397 { + compatible = "mediatek,mt6397"; + + ... + + mt6397keys: mt6397keys { + compatible = "mediatek,mt6397-keys"; + mediatek,long-press-mode = <1>; + power-off-time-sec = <0>; + + power { + linux,keycodes = <116>; + wakeup-source; + }; + + home { + linux,keycodes = <114>; + }; + }; + + }; -- cgit v1.2.3 From 8f59e8cb90e8b8af6576800a358808f2868f573a Mon Sep 17 00:00:00 2001 From: Chen Zhong Date: Wed, 25 Oct 2017 21:16:02 +0800 Subject: dt-bindings: mfd: Add bindings for the keys as subnode of PMIC This patch adds documentation for device tree bindings for keys support as the subnode of MT6397/MT6323 PMIC. Signed-off-by: Chen Zhong Acked-by: Rob Herring Signed-off-by: Lee Jones --- Documentation/devicetree/bindings/mfd/mt6397.txt | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/Documentation/devicetree/bindings/mfd/mt6397.txt b/Documentation/devicetree/bindings/mfd/mt6397.txt index 522a3bbf1bac..d1df77f4d655 100644 --- a/Documentation/devicetree/bindings/mfd/mt6397.txt +++ b/Documentation/devicetree/bindings/mfd/mt6397.txt @@ -7,6 +7,7 @@ MT6397/MT6323 is a multifunction device with the following sub modules: - GPIO - Clock - LED +- Keys It is interfaced to host controller using SPI interface by a proprietary hardware called PMIC wrapper or pwrap. MT6397/MT6323 MFD is a child device of pwrap. @@ -40,6 +41,11 @@ Optional subnodes: - compatible: "mediatek,mt6323-led" see Documentation/devicetree/bindings/leds/leds-mt6323.txt +- keys + Required properties: + - compatible: "mediatek,mt6397-keys" or "mediatek,mt6323-keys" + see Documentation/devicetree/bindings/input/mtk-pmic-keys.txt + Example: pwrap: pwrap@1000f000 { compatible = "mediatek,mt8135-pwrap"; -- cgit v1.2.3 From 3e9f0b3e2b27c0aa1d8d317ff293d9832659d6e9 Mon Sep 17 00:00:00 2001 From: Chen Zhong Date: Wed, 25 Oct 2017 21:16:03 +0800 Subject: input: Add MediaTek PMIC keys support This patch add support to handle MediaTek PMIC MT6397/MT6323 key interrupts including pwrkey and homekey, also add setting for long press key shutdown behavior. Signed-off-by: Chen Zhong Acked-by: Dmitry Torokhov Signed-off-by: Lee Jones --- drivers/input/keyboard/Kconfig | 9 + drivers/input/keyboard/Makefile | 1 + drivers/input/keyboard/mtk-pmic-keys.c | 339 +++++++++++++++++++++++++++++++++ 3 files changed, 349 insertions(+) create mode 100644 drivers/input/keyboard/mtk-pmic-keys.c diff --git a/drivers/input/keyboard/Kconfig b/drivers/input/keyboard/Kconfig index 2b469cc47a78..6bd97ffee761 100644 --- a/drivers/input/keyboard/Kconfig +++ b/drivers/input/keyboard/Kconfig @@ -747,4 +747,13 @@ config KEYBOARD_BCM To compile this driver as a module, choose M here: the module will be called bcm-keypad. +config KEYBOARD_MTK_PMIC + tristate "MediaTek PMIC keys support" + depends on MFD_MT6397 + help + Say Y here if you want to use the pmic keys (powerkey/homekey). + + To compile this driver as a module, choose M here: the + module will be called pmic-keys. + endif diff --git a/drivers/input/keyboard/Makefile b/drivers/input/keyboard/Makefile index 8fab920afa58..182e92985dbf 100644 --- a/drivers/input/keyboard/Makefile +++ b/drivers/input/keyboard/Makefile @@ -40,6 +40,7 @@ obj-$(CONFIG_KEYBOARD_MATRIX) += matrix_keypad.o obj-$(CONFIG_KEYBOARD_MAX7359) += max7359_keypad.o obj-$(CONFIG_KEYBOARD_MCS) += mcs_touchkey.o obj-$(CONFIG_KEYBOARD_MPR121) += mpr121_touchkey.o +obj-$(CONFIG_KEYBOARD_MTK_PMIC) += mtk-pmic-keys.o obj-$(CONFIG_KEYBOARD_NEWTON) += newtonkbd.o obj-$(CONFIG_KEYBOARD_NOMADIK) += nomadik-ske-keypad.o obj-$(CONFIG_KEYBOARD_NSPIRE) += nspire-keypad.o diff --git a/drivers/input/keyboard/mtk-pmic-keys.c b/drivers/input/keyboard/mtk-pmic-keys.c new file mode 100644 index 000000000000..02c67a1749fc --- /dev/null +++ b/drivers/input/keyboard/mtk-pmic-keys.c @@ -0,0 +1,339 @@ +/* + * Copyright (C) 2017 MediaTek, Inc. + * + * Author: Chen Zhong + * + * This software is licensed under the terms of the GNU General Public + * License version 2, as published by the Free Software Foundation, and + * may be copied, distributed, and modified under those terms. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define MTK_PMIC_PWRKEY_RST_EN_MASK 0x1 +#define MTK_PMIC_PWRKEY_RST_EN_SHIFT 6 +#define MTK_PMIC_HOMEKEY_RST_EN_MASK 0x1 +#define MTK_PMIC_HOMEKEY_RST_EN_SHIFT 5 +#define MTK_PMIC_RST_DU_MASK 0x3 +#define MTK_PMIC_RST_DU_SHIFT 8 + +#define MTK_PMIC_PWRKEY_RST \ + (MTK_PMIC_PWRKEY_RST_EN_MASK << MTK_PMIC_PWRKEY_RST_EN_SHIFT) +#define MTK_PMIC_HOMEKEY_RST \ + (MTK_PMIC_HOMEKEY_RST_EN_MASK << MTK_PMIC_HOMEKEY_RST_EN_SHIFT) + +#define MTK_PMIC_PWRKEY_INDEX 0 +#define MTK_PMIC_HOMEKEY_INDEX 1 +#define MTK_PMIC_MAX_KEY_COUNT 2 + +struct mtk_pmic_keys_regs { + u32 deb_reg; + u32 deb_mask; + u32 intsel_reg; + u32 intsel_mask; +}; + +#define MTK_PMIC_KEYS_REGS(_deb_reg, _deb_mask, \ + _intsel_reg, _intsel_mask) \ +{ \ + .deb_reg = _deb_reg, \ + .deb_mask = _deb_mask, \ + .intsel_reg = _intsel_reg, \ + .intsel_mask = _intsel_mask, \ +} + +struct mtk_pmic_regs { + const struct mtk_pmic_keys_regs keys_regs[MTK_PMIC_MAX_KEY_COUNT]; + u32 pmic_rst_reg; +}; + +static const struct mtk_pmic_regs mt6397_regs = { + .keys_regs[MTK_PMIC_PWRKEY_INDEX] = + MTK_PMIC_KEYS_REGS(MT6397_CHRSTATUS, + 0x8, MT6397_INT_RSV, 0x10), + .keys_regs[MTK_PMIC_HOMEKEY_INDEX] = + MTK_PMIC_KEYS_REGS(MT6397_OCSTATUS2, + 0x10, MT6397_INT_RSV, 0x8), + .pmic_rst_reg = MT6397_TOP_RST_MISC, +}; + +static const struct mtk_pmic_regs mt6323_regs = { + .keys_regs[MTK_PMIC_PWRKEY_INDEX] = + MTK_PMIC_KEYS_REGS(MT6323_CHRSTATUS, + 0x2, MT6323_INT_MISC_CON, 0x10), + .keys_regs[MTK_PMIC_HOMEKEY_INDEX] = + MTK_PMIC_KEYS_REGS(MT6323_CHRSTATUS, + 0x4, MT6323_INT_MISC_CON, 0x8), + .pmic_rst_reg = MT6323_TOP_RST_MISC, +}; + +struct mtk_pmic_keys_info { + struct mtk_pmic_keys *keys; + const struct mtk_pmic_keys_regs *regs; + unsigned int keycode; + int irq; + bool wakeup:1; +}; + +struct mtk_pmic_keys { + struct input_dev *input_dev; + struct device *dev; + struct regmap *regmap; + struct mtk_pmic_keys_info keys[MTK_PMIC_MAX_KEY_COUNT]; +}; + +enum mtk_pmic_keys_lp_mode { + LP_DISABLE, + LP_ONEKEY, + LP_TWOKEY, +}; + +static void mtk_pmic_keys_lp_reset_setup(struct mtk_pmic_keys *keys, + u32 pmic_rst_reg) +{ + int ret; + u32 long_press_mode, long_press_debounce; + + ret = of_property_read_u32(keys->dev->of_node, + "power-off-time-sec", &long_press_debounce); + if (ret) + long_press_debounce = 0; + + regmap_update_bits(keys->regmap, pmic_rst_reg, + MTK_PMIC_RST_DU_MASK << MTK_PMIC_RST_DU_SHIFT, + long_press_debounce << MTK_PMIC_RST_DU_SHIFT); + + ret = of_property_read_u32(keys->dev->of_node, + "mediatek,long-press-mode", &long_press_mode); + if (ret) + long_press_mode = LP_DISABLE; + + switch (long_press_mode) { + case LP_ONEKEY: + regmap_update_bits(keys->regmap, pmic_rst_reg, + MTK_PMIC_PWRKEY_RST, + MTK_PMIC_PWRKEY_RST); + regmap_update_bits(keys->regmap, pmic_rst_reg, + MTK_PMIC_HOMEKEY_RST, + 0); + break; + case LP_TWOKEY: + regmap_update_bits(keys->regmap, pmic_rst_reg, + MTK_PMIC_PWRKEY_RST, + MTK_PMIC_PWRKEY_RST); + regmap_update_bits(keys->regmap, pmic_rst_reg, + MTK_PMIC_HOMEKEY_RST, + MTK_PMIC_HOMEKEY_RST); + break; + case LP_DISABLE: + regmap_update_bits(keys->regmap, pmic_rst_reg, + MTK_PMIC_PWRKEY_RST, + 0); + regmap_update_bits(keys->regmap, pmic_rst_reg, + MTK_PMIC_HOMEKEY_RST, + 0); + break; + default: + break; + } +} + +static irqreturn_t mtk_pmic_keys_irq_handler_thread(int irq, void *data) +{ + struct mtk_pmic_keys_info *info = data; + u32 key_deb, pressed; + + regmap_read(info->keys->regmap, info->regs->deb_reg, &key_deb); + + key_deb &= info->regs->deb_mask; + + pressed = !key_deb; + + input_report_key(info->keys->input_dev, info->keycode, pressed); + input_sync(info->keys->input_dev); + + dev_dbg(info->keys->dev, "(%s) key =%d using PMIC\n", + pressed ? "pressed" : "released", info->keycode); + + return IRQ_HANDLED; +} + +static int mtk_pmic_key_setup(struct mtk_pmic_keys *keys, + struct mtk_pmic_keys_info *info) +{ + int ret; + + info->keys = keys; + + ret = regmap_update_bits(keys->regmap, info->regs->intsel_reg, + info->regs->intsel_mask, + info->regs->intsel_mask); + if (ret < 0) + return ret; + + ret = devm_request_threaded_irq(keys->dev, info->irq, NULL, + mtk_pmic_keys_irq_handler_thread, + IRQF_ONESHOT | IRQF_TRIGGER_HIGH, + "mtk-pmic-keys", info); + if (ret) { + dev_err(keys->dev, "Failed to request IRQ: %d: %d\n", + info->irq, ret); + return ret; + } + + input_set_capability(keys->input_dev, EV_KEY, info->keycode); + + return 0; +} + +static int __maybe_unused mtk_pmic_keys_suspend(struct device *dev) +{ + struct mtk_pmic_keys *keys = dev_get_drvdata(dev); + int index; + + for (index = 0; index < MTK_PMIC_MAX_KEY_COUNT; index++) { + if (keys->keys[index].wakeup) + enable_irq_wake(keys->keys[index].irq); + } + + return 0; +} + +static int __maybe_unused mtk_pmic_keys_resume(struct device *dev) +{ + struct mtk_pmic_keys *keys = dev_get_drvdata(dev); + int index; + + for (index = 0; index < MTK_PMIC_MAX_KEY_COUNT; index++) { + if (keys->keys[index].wakeup) + disable_irq_wake(keys->keys[index].irq); + } + + return 0; +} + +static SIMPLE_DEV_PM_OPS(mtk_pmic_keys_pm_ops, mtk_pmic_keys_suspend, + mtk_pmic_keys_resume); + +static const struct of_device_id of_mtk_pmic_keys_match_tbl[] = { + { + .compatible = "mediatek,mt6397-keys", + .data = &mt6397_regs, + }, { + .compatible = "mediatek,mt6323-keys", + .data = &mt6323_regs, + }, { + /* sentinel */ + } +}; +MODULE_DEVICE_TABLE(of, of_mtk_pmic_keys_match_tbl); + +static int mtk_pmic_keys_probe(struct platform_device *pdev) +{ + int error, index = 0; + unsigned int keycount; + struct mt6397_chip *pmic_chip = dev_get_drvdata(pdev->dev.parent); + struct device_node *node = pdev->dev.of_node, *child; + struct mtk_pmic_keys *keys; + const struct mtk_pmic_regs *mtk_pmic_regs; + struct input_dev *input_dev; + const struct of_device_id *of_id = + of_match_device(of_mtk_pmic_keys_match_tbl, &pdev->dev); + + keys = devm_kzalloc(&pdev->dev, sizeof(*keys), GFP_KERNEL); + if (!keys) + return -ENOMEM; + + keys->dev = &pdev->dev; + keys->regmap = pmic_chip->regmap; + mtk_pmic_regs = of_id->data; + + keys->input_dev = input_dev = devm_input_allocate_device(keys->dev); + if (!input_dev) { + dev_err(keys->dev, "input allocate device fail.\n"); + return -ENOMEM; + } + + input_dev->name = "mtk-pmic-keys"; + input_dev->id.bustype = BUS_HOST; + input_dev->id.vendor = 0x0001; + input_dev->id.product = 0x0001; + input_dev->id.version = 0x0001; + + keycount = of_get_available_child_count(node); + if (keycount > MTK_PMIC_MAX_KEY_COUNT) { + dev_err(keys->dev, "too many keys defined (%d)\n", keycount); + return -EINVAL; + } + + for_each_child_of_node(node, child) { + keys->keys[index].regs = &mtk_pmic_regs->keys_regs[index]; + + keys->keys[index].irq = platform_get_irq(pdev, index); + if (keys->keys[index].irq < 0) + return keys->keys[index].irq; + + error = of_property_read_u32(child, + "linux,keycodes", &keys->keys[index].keycode); + if (error) { + dev_err(keys->dev, + "failed to read key:%d linux,keycode property: %d\n", + index, error); + return error; + } + + if (of_property_read_bool(child, "wakeup-source")) + keys->keys[index].wakeup = true; + + error = mtk_pmic_key_setup(keys, &keys->keys[index]); + if (error) + return error; + + index++; + } + + error = input_register_device(input_dev); + if (error) { + dev_err(&pdev->dev, + "register input device failed (%d)\n", error); + return error; + } + + mtk_pmic_keys_lp_reset_setup(keys, mtk_pmic_regs->pmic_rst_reg); + + platform_set_drvdata(pdev, keys); + + return 0; +} + +static struct platform_driver pmic_keys_pdrv = { + .probe = mtk_pmic_keys_probe, + .driver = { + .name = "mtk-pmic-keys", + .of_match_table = of_mtk_pmic_keys_match_tbl, + .pm = &mtk_pmic_keys_pm_ops, + }, +}; + +module_platform_driver(pmic_keys_pdrv); + +MODULE_LICENSE("GPL v2"); +MODULE_AUTHOR("Chen Zhong "); +MODULE_DESCRIPTION("MTK pmic-keys driver v0.1"); -- cgit v1.2.3 From 55d1d1547ab5e52269988af5e7c553796ff68e97 Mon Sep 17 00:00:00 2001 From: Chen Zhong Date: Wed, 25 Oct 2017 21:16:04 +0800 Subject: mfd: mt6397: Add PMIC keys support to MT6397 driver This patch adds compatible strings and interrupts for pmic keys which serves as child device of MFD. Signed-off-by: Chen Zhong Signed-off-by: Lee Jones --- drivers/mfd/mt6397-core.c | 22 +++++++++++++++++++++- 1 file changed, 21 insertions(+), 1 deletion(-) diff --git a/drivers/mfd/mt6397-core.c b/drivers/mfd/mt6397-core.c index 6546d7f88b5e..77b64bd64df3 100644 --- a/drivers/mfd/mt6397-core.c +++ b/drivers/mfd/mt6397-core.c @@ -43,6 +43,16 @@ static const struct resource mt6397_rtc_resources[] = { }, }; +static const struct resource mt6323_keys_resources[] = { + DEFINE_RES_IRQ(MT6323_IRQ_STATUS_PWRKEY), + DEFINE_RES_IRQ(MT6323_IRQ_STATUS_FCHRKEY), +}; + +static const struct resource mt6397_keys_resources[] = { + DEFINE_RES_IRQ(MT6397_IRQ_PWRKEY), + DEFINE_RES_IRQ(MT6397_IRQ_HOMEKEY), +}; + static const struct mfd_cell mt6323_devs[] = { { .name = "mt6323-regulator", @@ -50,6 +60,11 @@ static const struct mfd_cell mt6323_devs[] = { }, { .name = "mt6323-led", .of_compatible = "mediatek,mt6323-led" + }, { + .name = "mtk-pmic-keys", + .num_resources = ARRAY_SIZE(mt6323_keys_resources), + .resources = mt6323_keys_resources, + .of_compatible = "mediatek,mt6323-keys" }, }; @@ -71,7 +86,12 @@ static const struct mfd_cell mt6397_devs[] = { }, { .name = "mt6397-pinctrl", .of_compatible = "mediatek,mt6397-pinctrl", - }, + }, { + .name = "mtk-pmic-keys", + .num_resources = ARRAY_SIZE(mt6397_keys_resources), + .resources = mt6397_keys_resources, + .of_compatible = "mediatek,mt6397-keys" + } }; static void mt6397_irq_lock(struct irq_data *data) -- cgit v1.2.3 From 0c6609805b638debcb7d9d44556546b043ded2e9 Mon Sep 17 00:00:00 2001 From: Fabrice Gasnier Date: Wed, 16 May 2018 09:35:57 +0200 Subject: mfd: stm32-timers: Add support for DMAs STM32 Timers can support up to 7 DMA requests: - 4 channels, update, compare and trigger. Optionally request part, or all DMAs from stm32-timers MFD core. Also add routine to implement burst reads using DMA from timer registers. This is exported. So, it can be used by child drivers, PWM capture for instance (but not limited to). Signed-off-by: Fabrice Gasnier Reviewed-by: Benjamin Gaignard Signed-off-by: Lee Jones --- drivers/mfd/stm32-timers.c | 201 ++++++++++++++++++++++++++++++++++++++- include/linux/mfd/stm32-timers.h | 46 +++++++++ 2 files changed, 245 insertions(+), 2 deletions(-) diff --git a/drivers/mfd/stm32-timers.c b/drivers/mfd/stm32-timers.c index 1d347e5dfa79..efcd4b980c94 100644 --- a/drivers/mfd/stm32-timers.c +++ b/drivers/mfd/stm32-timers.c @@ -4,16 +4,156 @@ * Author: Benjamin Gaignard */ +#include #include #include #include #include +#define STM32_TIMERS_MAX_REGISTERS 0x3fc + +/* DIER register DMA enable bits */ +static const u32 stm32_timers_dier_dmaen[STM32_TIMERS_MAX_DMAS] = { + TIM_DIER_CC1DE, + TIM_DIER_CC2DE, + TIM_DIER_CC3DE, + TIM_DIER_CC4DE, + TIM_DIER_UIE, + TIM_DIER_TDE, + TIM_DIER_COMDE +}; + +static void stm32_timers_dma_done(void *p) +{ + struct stm32_timers_dma *dma = p; + struct dma_tx_state state; + enum dma_status status; + + status = dmaengine_tx_status(dma->chan, dma->chan->cookie, &state); + if (status == DMA_COMPLETE) + complete(&dma->completion); +} + +/** + * stm32_timers_dma_burst_read - Read from timers registers using DMA. + * + * Read from STM32 timers registers using DMA on a single event. + * @dev: reference to stm32_timers MFD device + * @buf: DMA'able destination buffer + * @id: stm32_timers_dmas event identifier (ch[1..4], up, trig or com) + * @reg: registers start offset for DMA to read from (like CCRx for capture) + * @num_reg: number of registers to read upon each DMA request, starting @reg. + * @bursts: number of bursts to read (e.g. like two for pwm period capture) + * @tmo_ms: timeout (milliseconds) + */ +int stm32_timers_dma_burst_read(struct device *dev, u32 *buf, + enum stm32_timers_dmas id, u32 reg, + unsigned int num_reg, unsigned int bursts, + unsigned long tmo_ms) +{ + struct stm32_timers *ddata = dev_get_drvdata(dev); + unsigned long timeout = msecs_to_jiffies(tmo_ms); + struct regmap *regmap = ddata->regmap; + struct stm32_timers_dma *dma = &ddata->dma; + size_t len = num_reg * bursts * sizeof(u32); + struct dma_async_tx_descriptor *desc; + struct dma_slave_config config; + dma_cookie_t cookie; + dma_addr_t dma_buf; + u32 dbl, dba; + long err; + int ret; + + /* Sanity check */ + if (id < STM32_TIMERS_DMA_CH1 || id >= STM32_TIMERS_MAX_DMAS) + return -EINVAL; + + if (!num_reg || !bursts || reg > STM32_TIMERS_MAX_REGISTERS || + (reg + num_reg * sizeof(u32)) > STM32_TIMERS_MAX_REGISTERS) + return -EINVAL; + + if (!dma->chans[id]) + return -ENODEV; + mutex_lock(&dma->lock); + + /* Select DMA channel in use */ + dma->chan = dma->chans[id]; + dma_buf = dma_map_single(dev, buf, len, DMA_FROM_DEVICE); + if (dma_mapping_error(dev, dma_buf)) { + ret = -ENOMEM; + goto unlock; + } + + /* Prepare DMA read from timer registers, using DMA burst mode */ + memset(&config, 0, sizeof(config)); + config.src_addr = (dma_addr_t)dma->phys_base + TIM_DMAR; + config.src_addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES; + ret = dmaengine_slave_config(dma->chan, &config); + if (ret) + goto unmap; + + desc = dmaengine_prep_slave_single(dma->chan, dma_buf, len, + DMA_DEV_TO_MEM, DMA_PREP_INTERRUPT); + if (!desc) { + ret = -EBUSY; + goto unmap; + } + + desc->callback = stm32_timers_dma_done; + desc->callback_param = dma; + cookie = dmaengine_submit(desc); + ret = dma_submit_error(cookie); + if (ret) + goto dma_term; + + reinit_completion(&dma->completion); + dma_async_issue_pending(dma->chan); + + /* Setup and enable timer DMA burst mode */ + dbl = FIELD_PREP(TIM_DCR_DBL, bursts - 1); + dba = FIELD_PREP(TIM_DCR_DBA, reg >> 2); + ret = regmap_write(regmap, TIM_DCR, dbl | dba); + if (ret) + goto dma_term; + + /* Clear pending flags before enabling DMA request */ + ret = regmap_write(regmap, TIM_SR, 0); + if (ret) + goto dcr_clr; + + ret = regmap_update_bits(regmap, TIM_DIER, stm32_timers_dier_dmaen[id], + stm32_timers_dier_dmaen[id]); + if (ret) + goto dcr_clr; + + err = wait_for_completion_interruptible_timeout(&dma->completion, + timeout); + if (err == 0) + ret = -ETIMEDOUT; + else if (err < 0) + ret = err; + + regmap_update_bits(regmap, TIM_DIER, stm32_timers_dier_dmaen[id], 0); + regmap_write(regmap, TIM_SR, 0); +dcr_clr: + regmap_write(regmap, TIM_DCR, 0); +dma_term: + dmaengine_terminate_all(dma->chan); +unmap: + dma_unmap_single(dev, dma_buf, len, DMA_FROM_DEVICE); +unlock: + dma->chan = NULL; + mutex_unlock(&dma->lock); + + return ret; +} +EXPORT_SYMBOL_GPL(stm32_timers_dma_burst_read); + static const struct regmap_config stm32_timers_regmap_cfg = { .reg_bits = 32, .val_bits = 32, .reg_stride = sizeof(u32), - .max_register = 0x3fc, + .max_register = STM32_TIMERS_MAX_REGISTERS, }; static void stm32_timers_get_arr_size(struct stm32_timers *ddata) @@ -27,12 +167,45 @@ static void stm32_timers_get_arr_size(struct stm32_timers *ddata) regmap_write(ddata->regmap, TIM_ARR, 0x0); } +static void stm32_timers_dma_probe(struct device *dev, + struct stm32_timers *ddata) +{ + int i; + char name[4]; + + init_completion(&ddata->dma.completion); + mutex_init(&ddata->dma.lock); + + /* Optional DMA support: get valid DMA channel(s) or NULL */ + for (i = STM32_TIMERS_DMA_CH1; i <= STM32_TIMERS_DMA_CH4; i++) { + snprintf(name, ARRAY_SIZE(name), "ch%1d", i + 1); + ddata->dma.chans[i] = dma_request_slave_channel(dev, name); + } + ddata->dma.chans[STM32_TIMERS_DMA_UP] = + dma_request_slave_channel(dev, "up"); + ddata->dma.chans[STM32_TIMERS_DMA_TRIG] = + dma_request_slave_channel(dev, "trig"); + ddata->dma.chans[STM32_TIMERS_DMA_COM] = + dma_request_slave_channel(dev, "com"); +} + +static void stm32_timers_dma_remove(struct device *dev, + struct stm32_timers *ddata) +{ + int i; + + for (i = STM32_TIMERS_DMA_CH1; i < STM32_TIMERS_MAX_DMAS; i++) + if (ddata->dma.chans[i]) + dma_release_channel(ddata->dma.chans[i]); +} + static int stm32_timers_probe(struct platform_device *pdev) { struct device *dev = &pdev->dev; struct stm32_timers *ddata; struct resource *res; void __iomem *mmio; + int ret; ddata = devm_kzalloc(dev, sizeof(*ddata), GFP_KERNEL); if (!ddata) @@ -43,6 +216,9 @@ static int stm32_timers_probe(struct platform_device *pdev) if (IS_ERR(mmio)) return PTR_ERR(mmio); + /* Timer physical addr for DMA */ + ddata->dma.phys_base = res->start; + ddata->regmap = devm_regmap_init_mmio_clk(dev, "int", mmio, &stm32_timers_regmap_cfg); if (IS_ERR(ddata->regmap)) @@ -54,9 +230,29 @@ static int stm32_timers_probe(struct platform_device *pdev) stm32_timers_get_arr_size(ddata); + stm32_timers_dma_probe(dev, ddata); + platform_set_drvdata(pdev, ddata); - return devm_of_platform_populate(&pdev->dev); + ret = of_platform_populate(pdev->dev.of_node, NULL, NULL, &pdev->dev); + if (ret) + stm32_timers_dma_remove(dev, ddata); + + return ret; +} + +static int stm32_timers_remove(struct platform_device *pdev) +{ + struct stm32_timers *ddata = platform_get_drvdata(pdev); + + /* + * Don't use devm_ here: enfore of_platform_depopulate() happens before + * DMA are released, to avoid race on DMA. + */ + of_platform_depopulate(&pdev->dev); + stm32_timers_dma_remove(&pdev->dev, ddata); + + return 0; } static const struct of_device_id stm32_timers_of_match[] = { @@ -67,6 +263,7 @@ MODULE_DEVICE_TABLE(of, stm32_timers_of_match); static struct platform_driver stm32_timers_driver = { .probe = stm32_timers_probe, + .remove = stm32_timers_remove, .driver = { .name = "stm32-timers", .of_match_table = stm32_timers_of_match, diff --git a/include/linux/mfd/stm32-timers.h b/include/linux/mfd/stm32-timers.h index 2aadab6f34a1..9596d5c58859 100644 --- a/include/linux/mfd/stm32-timers.h +++ b/include/linux/mfd/stm32-timers.h @@ -8,6 +8,8 @@ #define _LINUX_STM32_GPTIMER_H_ #include +#include +#include #include #define TIM_CR1 0x00 /* Control Register 1 */ @@ -27,6 +29,8 @@ #define TIM_CCR3 0x3C /* Capt/Comp Register 3 */ #define TIM_CCR4 0x40 /* Capt/Comp Register 4 */ #define TIM_BDTR 0x44 /* Break and Dead-Time Reg */ +#define TIM_DCR 0x48 /* DMA control register */ +#define TIM_DMAR 0x4C /* DMA register for transfer */ #define TIM_CR1_CEN BIT(0) /* Counter Enable */ #define TIM_CR1_DIR BIT(4) /* Counter Direction */ @@ -36,6 +40,13 @@ #define TIM_SMCR_SMS (BIT(0) | BIT(1) | BIT(2)) /* Slave mode selection */ #define TIM_SMCR_TS (BIT(4) | BIT(5) | BIT(6)) /* Trigger selection */ #define TIM_DIER_UIE BIT(0) /* Update interrupt */ +#define TIM_DIER_UDE BIT(8) /* Update DMA request Enable */ +#define TIM_DIER_CC1DE BIT(9) /* CC1 DMA request Enable */ +#define TIM_DIER_CC2DE BIT(10) /* CC2 DMA request Enable */ +#define TIM_DIER_CC3DE BIT(11) /* CC3 DMA request Enable */ +#define TIM_DIER_CC4DE BIT(12) /* CC4 DMA request Enable */ +#define TIM_DIER_COMDE BIT(13) /* COM DMA request Enable */ +#define TIM_DIER_TDE BIT(14) /* Trigger DMA request Enable */ #define TIM_SR_UIF BIT(0) /* Update interrupt flag */ #define TIM_EGR_UG BIT(0) /* Update Generation */ #define TIM_CCMR_PE BIT(3) /* Channel Preload Enable */ @@ -56,6 +67,8 @@ #define TIM_BDTR_BK2F (BIT(20) | BIT(21) | BIT(22) | BIT(23)) #define TIM_BDTR_BK2E BIT(24) /* Break 2 input enable */ #define TIM_BDTR_BK2P BIT(25) /* Break 2 input polarity */ +#define TIM_DCR_DBA GENMASK(4, 0) /* DMA base addr */ +#define TIM_DCR_DBL GENMASK(12, 8) /* DMA burst len */ #define MAX_TIM_PSC 0xFFFF #define TIM_CR2_MMS_SHIFT 4 @@ -65,9 +78,42 @@ #define TIM_BDTR_BKF_SHIFT 16 #define TIM_BDTR_BK2F_SHIFT 20 +enum stm32_timers_dmas { + STM32_TIMERS_DMA_CH1, + STM32_TIMERS_DMA_CH2, + STM32_TIMERS_DMA_CH3, + STM32_TIMERS_DMA_CH4, + STM32_TIMERS_DMA_UP, + STM32_TIMERS_DMA_TRIG, + STM32_TIMERS_DMA_COM, + STM32_TIMERS_MAX_DMAS, +}; + +/** + * struct stm32_timers_dma - STM32 timer DMA handling. + * @completion: end of DMA transfer completion + * @phys_base: control registers physical base address + * @lock: protect DMA access + * @chan: DMA channel in use + * @chans: DMA channels available for this timer instance + */ +struct stm32_timers_dma { + struct completion completion; + phys_addr_t phys_base; + struct mutex lock; + struct dma_chan *chan; + struct dma_chan *chans[STM32_TIMERS_MAX_DMAS]; +}; + struct stm32_timers { struct clk *clk; struct regmap *regmap; u32 max_arr; + struct stm32_timers_dma dma; /* Only to be used by the parent */ }; + +int stm32_timers_dma_burst_read(struct device *dev, u32 *buf, + enum stm32_timers_dmas id, u32 reg, + unsigned int num_reg, unsigned int bursts, + unsigned long tmo_ms); #endif -- cgit v1.2.3 From 53e38fe73f941291fd20794c15c3bb7b104a4a17 Mon Sep 17 00:00:00 2001 From: Fabrice Gasnier Date: Wed, 16 May 2018 09:35:58 +0200 Subject: pwm: stm32: Add capture support Add support for PMW input mode on pwm-stm32. STM32 timers support period and duty cycle capture as long as they have at least two PWM channels. One capture channel is used for period (rising-edge), one for duty-cycle (falling-edge). When there's only one channel available, only period can be captured. Duty-cycle is simply zero'ed in such a case. Capture requires exclusive access (e.g. no pwm output running at the same time, to protect common prescaler). Timer DMA burst mode (from MFD core) is being used, to take two snapshots of capture registers (upon each period rising edge). Signed-off-by: Fabrice Gasnier Reviewed-by: Benjamin Gaignard Acked-by: Thierry Reding Signed-off-by: Lee Jones --- drivers/pwm/pwm-stm32.c | 176 +++++++++++++++++++++++++++++++++++++++ include/linux/mfd/stm32-timers.h | 11 +++ 2 files changed, 187 insertions(+) diff --git a/drivers/pwm/pwm-stm32.c b/drivers/pwm/pwm-stm32.c index 2708212933f7..ed3961b7b938 100644 --- a/drivers/pwm/pwm-stm32.c +++ b/drivers/pwm/pwm-stm32.c @@ -25,6 +25,7 @@ struct stm32_pwm { struct regmap *regmap; u32 max_arr; bool have_complementary_output; + u32 capture[4] ____cacheline_aligned; /* DMA'able buffer */ }; struct stm32_breakinput { @@ -62,6 +63,178 @@ static int write_ccrx(struct stm32_pwm *dev, int ch, u32 value) return -EINVAL; } +#define TIM_CCER_CC12P (TIM_CCER_CC1P | TIM_CCER_CC2P) +#define TIM_CCER_CC12E (TIM_CCER_CC1E | TIM_CCER_CC2E) +#define TIM_CCER_CC34P (TIM_CCER_CC3P | TIM_CCER_CC4P) +#define TIM_CCER_CC34E (TIM_CCER_CC3E | TIM_CCER_CC4E) + +/* + * Capture using PWM input mode: + * ___ ___ + * TI[1, 2, 3 or 4]: ........._| |________| + * ^0 ^1 ^2 + * . . . + * . . XXXXX + * . . XXXXX | + * . XXXXX . | + * XXXXX . . | + * COUNTER: ______XXXXX . . . |_XXX + * start^ . . . ^stop + * . . . . + * v v . v + * v + * CCR1/CCR3: tx..........t0...........t2 + * CCR2/CCR4: tx..............t1......... + * + * DMA burst transfer: | | + * v v + * DMA buffer: { t0, tx } { t2, t1 } + * DMA done: ^ + * + * 0: IC1/3 snapchot on rising edge: counter value -> CCR1/CCR3 + * + DMA transfer CCR[1/3] & CCR[2/4] values (t0, tx: doesn't care) + * 1: IC2/4 snapchot on falling edge: counter value -> CCR2/CCR4 + * 2: IC1/3 snapchot on rising edge: counter value -> CCR1/CCR3 + * + DMA transfer CCR[1/3] & CCR[2/4] values (t2, t1) + * + * DMA done, compute: + * - Period = t2 - t0 + * - Duty cycle = t1 - t0 + */ +static int stm32_pwm_raw_capture(struct stm32_pwm *priv, struct pwm_device *pwm, + unsigned long tmo_ms, u32 *raw_prd, + u32 *raw_dty) +{ + struct device *parent = priv->chip.dev->parent; + enum stm32_timers_dmas dma_id; + u32 ccen, ccr; + int ret; + + /* Ensure registers have been updated, enable counter and capture */ + regmap_update_bits(priv->regmap, TIM_EGR, TIM_EGR_UG, TIM_EGR_UG); + regmap_update_bits(priv->regmap, TIM_CR1, TIM_CR1_CEN, TIM_CR1_CEN); + + /* Use cc1 or cc3 DMA resp for PWM input channels 1 & 2 or 3 & 4 */ + dma_id = pwm->hwpwm < 2 ? STM32_TIMERS_DMA_CH1 : STM32_TIMERS_DMA_CH3; + ccen = pwm->hwpwm < 2 ? TIM_CCER_CC12E : TIM_CCER_CC34E; + ccr = pwm->hwpwm < 2 ? TIM_CCR1 : TIM_CCR3; + regmap_update_bits(priv->regmap, TIM_CCER, ccen, ccen); + + /* + * Timer DMA burst mode. Request 2 registers, 2 bursts, to get both + * CCR1 & CCR2 (or CCR3 & CCR4) on each capture event. + * We'll get two capture snapchots: { CCR1, CCR2 }, { CCR1, CCR2 } + * or { CCR3, CCR4 }, { CCR3, CCR4 } + */ + ret = stm32_timers_dma_burst_read(parent, priv->capture, dma_id, ccr, 2, + 2, tmo_ms); + if (ret) + goto stop; + + /* Period: t2 - t0 (take care of counter overflow) */ + if (priv->capture[0] <= priv->capture[2]) + *raw_prd = priv->capture[2] - priv->capture[0]; + else + *raw_prd = priv->max_arr - priv->capture[0] + priv->capture[2]; + + /* Duty cycle capture requires at least two capture units */ + if (pwm->chip->npwm < 2) + *raw_dty = 0; + else if (priv->capture[0] <= priv->capture[3]) + *raw_dty = priv->capture[3] - priv->capture[0]; + else + *raw_dty = priv->max_arr - priv->capture[0] + priv->capture[3]; + + if (*raw_dty > *raw_prd) { + /* + * Race beetween PWM input and DMA: it may happen + * falling edge triggers new capture on TI2/4 before DMA + * had a chance to read CCR2/4. It means capture[1] + * contains period + duty_cycle. So, subtract period. + */ + *raw_dty -= *raw_prd; + } + +stop: + regmap_update_bits(priv->regmap, TIM_CCER, ccen, 0); + regmap_update_bits(priv->regmap, TIM_CR1, TIM_CR1_CEN, 0); + + return ret; +} + +static int stm32_pwm_capture(struct pwm_chip *chip, struct pwm_device *pwm, + struct pwm_capture *result, unsigned long tmo_ms) +{ + struct stm32_pwm *priv = to_stm32_pwm_dev(chip); + unsigned long long prd, div, dty; + unsigned long rate; + unsigned int psc = 0; + u32 raw_prd, raw_dty; + int ret = 0; + + mutex_lock(&priv->lock); + + if (active_channels(priv)) { + ret = -EBUSY; + goto unlock; + } + + ret = clk_enable(priv->clk); + if (ret) { + dev_err(priv->chip.dev, "failed to enable counter clock\n"); + goto unlock; + } + + rate = clk_get_rate(priv->clk); + if (!rate) { + ret = -EINVAL; + goto clk_dis; + } + + /* prescaler: fit timeout window provided by upper layer */ + div = (unsigned long long)rate * (unsigned long long)tmo_ms; + do_div(div, MSEC_PER_SEC); + prd = div; + while ((div > priv->max_arr) && (psc < MAX_TIM_PSC)) { + psc++; + div = prd; + do_div(div, psc + 1); + } + regmap_write(priv->regmap, TIM_ARR, priv->max_arr); + regmap_write(priv->regmap, TIM_PSC, psc); + + /* Map TI1 or TI2 PWM input to IC1 & IC2 (or TI3/4 to IC3 & IC4) */ + regmap_update_bits(priv->regmap, + pwm->hwpwm < 2 ? TIM_CCMR1 : TIM_CCMR2, + TIM_CCMR_CC1S | TIM_CCMR_CC2S, pwm->hwpwm & 0x1 ? + TIM_CCMR_CC1S_TI2 | TIM_CCMR_CC2S_TI2 : + TIM_CCMR_CC1S_TI1 | TIM_CCMR_CC2S_TI1); + + /* Capture period on IC1/3 rising edge, duty cycle on IC2/4 falling. */ + regmap_update_bits(priv->regmap, TIM_CCER, pwm->hwpwm < 2 ? + TIM_CCER_CC12P : TIM_CCER_CC34P, pwm->hwpwm < 2 ? + TIM_CCER_CC2P : TIM_CCER_CC4P); + + ret = stm32_pwm_raw_capture(priv, pwm, tmo_ms, &raw_prd, &raw_dty); + if (ret) + goto stop; + + prd = (unsigned long long)raw_prd * (psc + 1) * NSEC_PER_SEC; + result->period = DIV_ROUND_UP_ULL(prd, rate); + dty = (unsigned long long)raw_dty * (psc + 1) * NSEC_PER_SEC; + result->duty_cycle = DIV_ROUND_UP_ULL(dty, rate); +stop: + regmap_write(priv->regmap, TIM_CCER, 0); + regmap_write(priv->regmap, pwm->hwpwm < 2 ? TIM_CCMR1 : TIM_CCMR2, 0); + regmap_write(priv->regmap, TIM_PSC, 0); +clk_dis: + clk_disable(priv->clk); +unlock: + mutex_unlock(&priv->lock); + + return ret; +} + static int stm32_pwm_config(struct stm32_pwm *priv, int ch, int duty_ns, int period_ns) { @@ -230,6 +403,9 @@ static int stm32_pwm_apply_locked(struct pwm_chip *chip, struct pwm_device *pwm, static const struct pwm_ops stm32pwm_ops = { .owner = THIS_MODULE, .apply = stm32_pwm_apply_locked, +#if IS_ENABLED(CONFIG_DMA_ENGINE) + .capture = stm32_pwm_capture, +#endif }; static int stm32_pwm_set_breakinput(struct stm32_pwm *priv, diff --git a/include/linux/mfd/stm32-timers.h b/include/linux/mfd/stm32-timers.h index 9596d5c58859..d46f5500928e 100644 --- a/include/linux/mfd/stm32-timers.h +++ b/include/linux/mfd/stm32-timers.h @@ -51,13 +51,24 @@ #define TIM_EGR_UG BIT(0) /* Update Generation */ #define TIM_CCMR_PE BIT(3) /* Channel Preload Enable */ #define TIM_CCMR_M1 (BIT(6) | BIT(5)) /* Channel PWM Mode 1 */ +#define TIM_CCMR_CC1S (BIT(0) | BIT(1)) /* Capture/compare 1 sel */ +#define TIM_CCMR_IC1PSC GENMASK(3, 2) /* Input capture 1 prescaler */ +#define TIM_CCMR_CC2S (BIT(8) | BIT(9)) /* Capture/compare 2 sel */ +#define TIM_CCMR_IC2PSC GENMASK(11, 10) /* Input capture 2 prescaler */ +#define TIM_CCMR_CC1S_TI1 BIT(0) /* IC1/IC3 selects TI1/TI3 */ +#define TIM_CCMR_CC1S_TI2 BIT(1) /* IC1/IC3 selects TI2/TI4 */ +#define TIM_CCMR_CC2S_TI2 BIT(8) /* IC2/IC4 selects TI2/TI4 */ +#define TIM_CCMR_CC2S_TI1 BIT(9) /* IC2/IC4 selects TI1/TI3 */ #define TIM_CCER_CC1E BIT(0) /* Capt/Comp 1 out Ena */ #define TIM_CCER_CC1P BIT(1) /* Capt/Comp 1 Polarity */ #define TIM_CCER_CC1NE BIT(2) /* Capt/Comp 1N out Ena */ #define TIM_CCER_CC1NP BIT(3) /* Capt/Comp 1N Polarity */ #define TIM_CCER_CC2E BIT(4) /* Capt/Comp 2 out Ena */ +#define TIM_CCER_CC2P BIT(5) /* Capt/Comp 2 Polarity */ #define TIM_CCER_CC3E BIT(8) /* Capt/Comp 3 out Ena */ +#define TIM_CCER_CC3P BIT(9) /* Capt/Comp 3 Polarity */ #define TIM_CCER_CC4E BIT(12) /* Capt/Comp 4 out Ena */ +#define TIM_CCER_CC4P BIT(13) /* Capt/Comp 4 Polarity */ #define TIM_CCER_CCXE (BIT(0) | BIT(4) | BIT(8) | BIT(12)) #define TIM_BDTR_BKE BIT(12) /* Break input enable */ #define TIM_BDTR_BKP BIT(13) /* Break input polarity */ -- cgit v1.2.3 From d66ffb91c374fc500fe666645184e278774bad38 Mon Sep 17 00:00:00 2001 From: Fabrice Gasnier Date: Wed, 16 May 2018 09:35:59 +0200 Subject: pwm: stm32: Improve capture by tuning counter prescaler Currently, capture is based on timeout window to configure prescaler. PWM capture framework provides 1s window at the time of writing. There's place for improvement, after input signal has been captured once: - Finer tune counter clock prescaler, by using 1st capture result (with arbitrary margin). - Do a 2nd capture, with scaled capture window. This increases accuracy, especially at high rates. Signed-off-by: Fabrice Gasnier Reviewed-by: Benjamin Gaignard Acked-by: Thierry Reding Signed-off-by: Lee Jones --- drivers/pwm/pwm-stm32.c | 24 +++++++++++++++++++++++- 1 file changed, 23 insertions(+), 1 deletion(-) diff --git a/drivers/pwm/pwm-stm32.c b/drivers/pwm/pwm-stm32.c index ed3961b7b938..9a50acde1e61 100644 --- a/drivers/pwm/pwm-stm32.c +++ b/drivers/pwm/pwm-stm32.c @@ -168,7 +168,7 @@ static int stm32_pwm_capture(struct pwm_chip *chip, struct pwm_device *pwm, struct stm32_pwm *priv = to_stm32_pwm_dev(chip); unsigned long long prd, div, dty; unsigned long rate; - unsigned int psc = 0; + unsigned int psc = 0, scale; u32 raw_prd, raw_dty; int ret = 0; @@ -219,6 +219,28 @@ static int stm32_pwm_capture(struct pwm_chip *chip, struct pwm_device *pwm, if (ret) goto stop; + /* + * Got a capture. Try to improve accuracy at high rates: + * - decrease counter clock prescaler, scale up to max rate. + */ + if (raw_prd) { + u32 max_arr = priv->max_arr - 0x1000; /* arbitrary margin */ + + scale = max_arr / min(max_arr, raw_prd); + } else { + scale = priv->max_arr; /* bellow resolution, use max scale */ + } + + if (psc && scale > 1) { + /* 2nd measure with new scale */ + psc /= scale; + regmap_write(priv->regmap, TIM_PSC, psc); + ret = stm32_pwm_raw_capture(priv, pwm, tmo_ms, &raw_prd, + &raw_dty); + if (ret) + goto stop; + } + prd = (unsigned long long)raw_prd * (psc + 1) * NSEC_PER_SEC; result->period = DIV_ROUND_UP_ULL(prd, rate); dty = (unsigned long long)raw_dty * (psc + 1) * NSEC_PER_SEC; -- cgit v1.2.3 From ab3a897847834bf3e864fb07b733c444895a24ba Mon Sep 17 00:00:00 2001 From: Fabrice Gasnier Date: Wed, 16 May 2018 09:36:00 +0200 Subject: pwm: stm32: Use input prescaler to improve period capture Using input prescaler, capture unit will trigger DMA once every configurable /2, /4 or /8 events (rising edge). This helps improve period (only) capture accuracy at high rates. Signed-off-by: Fabrice Gasnier Reviewed-by: Benjamin Gaignard Acked-by: Thierry Reding Signed-off-by: Lee Jones --- drivers/pwm/pwm-stm32.c | 63 ++++++++++++++++++++++++++++++++++++++-- include/linux/mfd/stm32-timers.h | 1 + 2 files changed, 62 insertions(+), 2 deletions(-) diff --git a/drivers/pwm/pwm-stm32.c b/drivers/pwm/pwm-stm32.c index 9a50acde1e61..60bfc07c4912 100644 --- a/drivers/pwm/pwm-stm32.c +++ b/drivers/pwm/pwm-stm32.c @@ -8,6 +8,7 @@ * pwm-atmel.c from Bo Shen */ +#include #include #include #include @@ -168,7 +169,7 @@ static int stm32_pwm_capture(struct pwm_chip *chip, struct pwm_device *pwm, struct stm32_pwm *priv = to_stm32_pwm_dev(chip); unsigned long long prd, div, dty; unsigned long rate; - unsigned int psc = 0, scale; + unsigned int psc = 0, icpsc, scale; u32 raw_prd, raw_dty; int ret = 0; @@ -222,6 +223,7 @@ static int stm32_pwm_capture(struct pwm_chip *chip, struct pwm_device *pwm, /* * Got a capture. Try to improve accuracy at high rates: * - decrease counter clock prescaler, scale up to max rate. + * - use input prescaler, capture once every /2 /4 or /8 edges. */ if (raw_prd) { u32 max_arr = priv->max_arr - 0x1000; /* arbitrary margin */ @@ -241,8 +243,65 @@ static int stm32_pwm_capture(struct pwm_chip *chip, struct pwm_device *pwm, goto stop; } + /* Compute intermediate period not to exceed timeout at low rates */ prd = (unsigned long long)raw_prd * (psc + 1) * NSEC_PER_SEC; - result->period = DIV_ROUND_UP_ULL(prd, rate); + do_div(prd, rate); + + for (icpsc = 0; icpsc < MAX_TIM_ICPSC ; icpsc++) { + /* input prescaler: also keep arbitrary margin */ + if (raw_prd >= (priv->max_arr - 0x1000) >> (icpsc + 1)) + break; + if (prd >= (tmo_ms * NSEC_PER_MSEC) >> (icpsc + 2)) + break; + } + + if (!icpsc) + goto done; + + /* Last chance to improve period accuracy, using input prescaler */ + regmap_update_bits(priv->regmap, + pwm->hwpwm < 2 ? TIM_CCMR1 : TIM_CCMR2, + TIM_CCMR_IC1PSC | TIM_CCMR_IC2PSC, + FIELD_PREP(TIM_CCMR_IC1PSC, icpsc) | + FIELD_PREP(TIM_CCMR_IC2PSC, icpsc)); + + ret = stm32_pwm_raw_capture(priv, pwm, tmo_ms, &raw_prd, &raw_dty); + if (ret) + goto stop; + + if (raw_dty >= (raw_prd >> icpsc)) { + /* + * We may fall here using input prescaler, when input + * capture starts on high side (before falling edge). + * Example with icpsc to capture on each 4 events: + * + * start 1st capture 2nd capture + * v v v + * ___ _____ _____ _____ _____ ____ + * TI1..4 |__| |__| |__| |__| |__| + * v v . . . . . v v + * icpsc1/3: . 0 . 1 . 2 . 3 . 0 + * icpsc2/4: 0 1 2 3 0 + * v v v v + * CCR1/3 ......t0..............................t2 + * CCR2/4 ..t1..............................t1'... + * . . . + * Capture0: .<----------------------------->. + * Capture1: .<-------------------------->. . + * . . . + * Period: .<------> . . + * Low side: .<>. + * + * Result: + * - Period = Capture0 / icpsc + * - Duty = Period - Low side = Period - (Capture0 - Capture1) + */ + raw_dty = (raw_prd >> icpsc) - (raw_prd - raw_dty); + } + +done: + prd = (unsigned long long)raw_prd * (psc + 1) * NSEC_PER_SEC; + result->period = DIV_ROUND_UP_ULL(prd, rate << icpsc); dty = (unsigned long long)raw_dty * (psc + 1) * NSEC_PER_SEC; result->duty_cycle = DIV_ROUND_UP_ULL(dty, rate); stop: diff --git a/include/linux/mfd/stm32-timers.h b/include/linux/mfd/stm32-timers.h index d46f5500928e..9da1d7ece079 100644 --- a/include/linux/mfd/stm32-timers.h +++ b/include/linux/mfd/stm32-timers.h @@ -82,6 +82,7 @@ #define TIM_DCR_DBL GENMASK(12, 8) /* DMA burst len */ #define MAX_TIM_PSC 0xFFFF +#define MAX_TIM_ICPSC 0x3 #define TIM_CR2_MMS_SHIFT 4 #define TIM_CR2_MMS2_SHIFT 20 #define TIM_SMCR_TS_SHIFT 4 -- cgit v1.2.3 From 30feec093021ef665233a3c78a99f444673389a2 Mon Sep 17 00:00:00 2001 From: Krzysztof Kozlowski Date: Tue, 9 Jan 2018 19:59:21 +0100 Subject: mfd: syscon: Remove unused Exynos PMU headers Since commit 5812f0106c44 ("phy: exynos4: Remove duplicated defines of PHY register defines") and commit 7a66647b25b6 ("phy: exynos: Use one define for enable bit") all users of syscon Exynos PMU headers (for PHY drivers) are converted to use different headers so these can be removed. Signed-off-by: Krzysztof Kozlowski Signed-off-by: Lee Jones --- include/linux/mfd/syscon/exynos4-pmu.h | 21 --------------------- include/linux/mfd/syscon/exynos5-pmu.h | 19 ------------------- 2 files changed, 40 deletions(-) delete mode 100644 include/linux/mfd/syscon/exynos4-pmu.h delete mode 100644 include/linux/mfd/syscon/exynos5-pmu.h diff --git a/include/linux/mfd/syscon/exynos4-pmu.h b/include/linux/mfd/syscon/exynos4-pmu.h deleted file mode 100644 index 278b1b1549e9..000000000000 --- a/include/linux/mfd/syscon/exynos4-pmu.h +++ /dev/null @@ -1,21 +0,0 @@ -/* - * Copyright (C) 2015 Samsung Electronics Co., Ltd. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - */ - -#ifndef _LINUX_MFD_SYSCON_PMU_EXYNOS4_H_ -#define _LINUX_MFD_SYSCON_PMU_EXYNOS4_H_ - -/* Exynos4 PMU register definitions */ - -/* MIPI_PHYn_CONTROL register offset: n = 0..1 */ -#define EXYNOS4_MIPI_PHY_CONTROL(n) (0x710 + (n) * 4) -#define EXYNOS4_MIPI_PHY_ENABLE (1 << 0) -#define EXYNOS4_MIPI_PHY_SRESETN (1 << 1) -#define EXYNOS4_MIPI_PHY_MRESETN (1 << 2) -#define EXYNOS4_MIPI_PHY_RESET_MASK (3 << 1) - -#endif /* _LINUX_MFD_SYSCON_PMU_EXYNOS4_H_ */ diff --git a/include/linux/mfd/syscon/exynos5-pmu.h b/include/linux/mfd/syscon/exynos5-pmu.h deleted file mode 100644 index b4942a32b81d..000000000000 --- a/include/linux/mfd/syscon/exynos5-pmu.h +++ /dev/null @@ -1,19 +0,0 @@ -/* - * Exynos5 SoC series Power Management Unit (PMU) register offsets - * and bit definitions. - * - * Copyright (C) 2014 Samsung Electronics Co., Ltd. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - */ - -#ifndef _LINUX_MFD_SYSCON_PMU_EXYNOS5_H_ -#define _LINUX_MFD_SYSCON_PMU_EXYNOS5_H_ - -#define EXYNOS5_PHY_ENABLE BIT(0) -#define EXYNOS5_MIPI_PHY_S_RESETN BIT(1) -#define EXYNOS5_MIPI_PHY_M_RESETN BIT(2) - -#endif /* _LINUX_MFD_SYSCON_PMU_EXYNOS5_H_ */ -- cgit v1.2.3 From 2e4d5494ab93a4f5320821e50510682630e556d5 Mon Sep 17 00:00:00 2001 From: Markus Elfring Date: Sun, 14 Jan 2018 22:02:16 +0100 Subject: mfd: htc-i2cpld: Delete error message for a failed memory allocation Omit an extra message for a memory allocation failure in this function. This issue was detected by using the Coccinelle software. Signed-off-by: Markus Elfring Signed-off-by: Lee Jones --- drivers/mfd/htc-i2cpld.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/drivers/mfd/htc-i2cpld.c b/drivers/mfd/htc-i2cpld.c index 3f9eee5f8fb9..4bf8b7781c77 100644 --- a/drivers/mfd/htc-i2cpld.c +++ b/drivers/mfd/htc-i2cpld.c @@ -479,10 +479,8 @@ static int htcpld_setup_chips(struct platform_device *pdev) htcpld->nchips = pdata->num_chip; htcpld->chip = devm_kzalloc(dev, sizeof(struct htcpld_chip) * htcpld->nchips, GFP_KERNEL); - if (!htcpld->chip) { - dev_warn(dev, "Unable to allocate memory for chips\n"); + if (!htcpld->chip) return -ENOMEM; - } /* Add the chips as best we can */ for (i = 0; i < htcpld->nchips; i++) { -- cgit v1.2.3 From 292155bee199c60e31fe9c30c3135154837c86a9 Mon Sep 17 00:00:00 2001 From: Markus Elfring Date: Sun, 14 Jan 2018 22:15:09 +0100 Subject: mfd: janz-cmodio: Delete error message for a failed memory allocation Omit an extra message for a memory allocation failure in this function. This issue was detected by using the Coccinelle software. Signed-off-by: Markus Elfring Signed-off-by: Lee Jones --- drivers/mfd/janz-cmodio.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/drivers/mfd/janz-cmodio.c b/drivers/mfd/janz-cmodio.c index ec1f46a6be3a..317a47ad5bb7 100644 --- a/drivers/mfd/janz-cmodio.c +++ b/drivers/mfd/janz-cmodio.c @@ -183,10 +183,8 @@ static int cmodio_pci_probe(struct pci_dev *dev, int ret; priv = devm_kzalloc(&dev->dev, sizeof(*priv), GFP_KERNEL); - if (!priv) { - dev_err(&dev->dev, "unable to allocate private data\n"); + if (!priv) return -ENOMEM; - } pci_set_drvdata(dev, priv); priv->pdev = dev; -- cgit v1.2.3 From 17963b5445af3443a72d53297f1211a1df5a35c8 Mon Sep 17 00:00:00 2001 From: Markus Elfring Date: Sun, 14 Jan 2018 22:26:21 +0100 Subject: mfd: jz4740-adc: Delete error message for a failed memory allocation Omit an extra message for a memory allocation failure in this function. This issue was detected by using the Coccinelle software. Signed-off-by: Markus Elfring Signed-off-by: Lee Jones --- drivers/mfd/jz4740-adc.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/drivers/mfd/jz4740-adc.c b/drivers/mfd/jz4740-adc.c index 798e44306382..f4cd14294b61 100644 --- a/drivers/mfd/jz4740-adc.c +++ b/drivers/mfd/jz4740-adc.c @@ -212,10 +212,8 @@ static int jz4740_adc_probe(struct platform_device *pdev) int irq_base; adc = devm_kzalloc(&pdev->dev, sizeof(*adc), GFP_KERNEL); - if (!adc) { - dev_err(&pdev->dev, "Failed to allocate driver structure\n"); + if (!adc) return -ENOMEM; - } adc->irq = platform_get_irq(pdev, 0); if (adc->irq < 0) { -- cgit v1.2.3 From f01b90b2c7d6e631c9a0eedef408a814cba0dabe Mon Sep 17 00:00:00 2001 From: Markus Elfring Date: Mon, 15 Jan 2018 09:35:17 +0100 Subject: mfd: max8997: Delete error message for a failed memory allocation Omit an extra message for a memory allocation failure in this function. This issue was detected by using the Coccinelle software. Signed-off-by: Markus Elfring Signed-off-by: Lee Jones --- drivers/mfd/max8997.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/drivers/mfd/max8997.c b/drivers/mfd/max8997.c index 2d6e2c392786..3f554c447521 100644 --- a/drivers/mfd/max8997.c +++ b/drivers/mfd/max8997.c @@ -148,10 +148,8 @@ static struct max8997_platform_data *max8997_i2c_parse_dt_pdata( struct max8997_platform_data *pd; pd = devm_kzalloc(dev, sizeof(*pd), GFP_KERNEL); - if (!pd) { - dev_err(dev, "could not allocate memory for pdata\n"); + if (!pd) return ERR_PTR(-ENOMEM); - } pd->ono = irq_of_parse_and_map(dev->of_node, 1); -- cgit v1.2.3 From 6733f64f8f9c3b55138e83122c2c1927d22b0524 Mon Sep 17 00:00:00 2001 From: Markus Elfring Date: Mon, 15 Jan 2018 14:48:57 +0100 Subject: mfd: rc5t583: Delete error message for a failed memory allocation Omit an extra message for a memory allocation failure in this function. This issue was detected by using the Coccinelle software. Signed-off-by: Markus Elfring Signed-off-by: Lee Jones --- drivers/mfd/rc5t583.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/drivers/mfd/rc5t583.c b/drivers/mfd/rc5t583.c index d12243d5ecb8..411dba636a53 100644 --- a/drivers/mfd/rc5t583.c +++ b/drivers/mfd/rc5t583.c @@ -259,10 +259,8 @@ static int rc5t583_i2c_probe(struct i2c_client *i2c, } rc5t583 = devm_kzalloc(&i2c->dev, sizeof(struct rc5t583), GFP_KERNEL); - if (!rc5t583) { - dev_err(&i2c->dev, "Memory allocation failed\n"); + if (!rc5t583) return -ENOMEM; - } rc5t583->dev = &i2c->dev; i2c_set_clientdata(i2c, rc5t583); -- cgit v1.2.3 From d001117474616057ff715efd702e282db570a902 Mon Sep 17 00:00:00 2001 From: Markus Elfring Date: Mon, 15 Jan 2018 14:50:25 +0100 Subject: mfd: rc5t583: Improve a size determination Replace the specification of a data structure by a pointer dereference as the parameter for the operator "sizeof" to make the corresponding size determination a bit safer according to the Linux coding style convention. This issue was detected by using the Coccinelle software. Signed-off-by: Markus Elfring Signed-off-by: Lee Jones --- drivers/mfd/rc5t583.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/mfd/rc5t583.c b/drivers/mfd/rc5t583.c index 411dba636a53..fd46de02b715 100644 --- a/drivers/mfd/rc5t583.c +++ b/drivers/mfd/rc5t583.c @@ -258,7 +258,7 @@ static int rc5t583_i2c_probe(struct i2c_client *i2c, return -EINVAL; } - rc5t583 = devm_kzalloc(&i2c->dev, sizeof(struct rc5t583), GFP_KERNEL); + rc5t583 = devm_kzalloc(&i2c->dev, sizeof(*rc5t583), GFP_KERNEL); if (!rc5t583) return -ENOMEM; -- cgit v1.2.3 From 24303ee7210efb49467693c32d56fbf5d64a840d Mon Sep 17 00:00:00 2001 From: Markus Elfring Date: Mon, 15 Jan 2018 15:40:46 +0100 Subject: mfd: sm501: Delete error message for a failed memory allocation in two places Omit an extra message for a memory allocation failure in these functions. This issue was detected by using the Coccinelle software. Signed-off-by: Markus Elfring Signed-off-by: Lee Jones --- drivers/mfd/sm501.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/drivers/mfd/sm501.c b/drivers/mfd/sm501.c index ad774161a22d..7298d6b571a1 100644 --- a/drivers/mfd/sm501.c +++ b/drivers/mfd/sm501.c @@ -1385,7 +1385,6 @@ static int sm501_plat_probe(struct platform_device *dev) sm = kzalloc(sizeof(struct sm501_devdata), GFP_KERNEL); if (sm == NULL) { - dev_err(&dev->dev, "no memory for device data\n"); ret = -ENOMEM; goto err1; } @@ -1575,7 +1574,6 @@ static int sm501_pci_probe(struct pci_dev *dev, sm = kzalloc(sizeof(struct sm501_devdata), GFP_KERNEL); if (sm == NULL) { - dev_err(&dev->dev, "no memory for device data\n"); err = -ENOMEM; goto err1; } -- cgit v1.2.3 From 46c8aa8e3fe61c7bb5dbbc9db379eeb01dc97472 Mon Sep 17 00:00:00 2001 From: Markus Elfring Date: Tue, 16 Jan 2018 08:52:27 +0100 Subject: mfd: smsc-ece1099: Delete an error message for a failed memory allocation Omit an extra message for a memory allocation failure in this function. This issue was detected by using the Coccinelle software. Signed-off-by: Markus Elfring Signed-off-by: Lee Jones --- drivers/mfd/smsc-ece1099.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/drivers/mfd/smsc-ece1099.c b/drivers/mfd/smsc-ece1099.c index 93a8297de52a..b9d96651cc0d 100644 --- a/drivers/mfd/smsc-ece1099.c +++ b/drivers/mfd/smsc-ece1099.c @@ -39,10 +39,8 @@ static int smsc_i2c_probe(struct i2c_client *i2c, smsc = devm_kzalloc(&i2c->dev, sizeof(struct smsc), GFP_KERNEL); - if (!smsc) { - dev_err(&i2c->dev, "smsc mfd driver memory allocation failed\n"); + if (!smsc) return -ENOMEM; - } smsc->regmap = devm_regmap_init_i2c(i2c, &smsc_regmap_config); if (IS_ERR(smsc->regmap)) -- cgit v1.2.3 From 16c2004d9e4d6e5bc0a81fa811eb6ebab4fb6307 Mon Sep 17 00:00:00 2001 From: Ladislav Michl Date: Mon, 15 Jan 2018 21:25:05 +0100 Subject: mfd: omap-usb-tll: Allocate driver data at once Allocating memory to store clk array together with driver data simplifies error unwinding and allows deleting memory allocation failure message as there is now only single point of failure already covered by allocation failure report. Signed-off-by: Ladislav Michl [Markus Elfring: simplified error unwinding, error message removal] Signed-off-by: Markus Elfring Acked-by: Roger Quadros Signed-off-by: Lee Jones --- drivers/mfd/omap-usb-tll.c | 60 +++++++++++++++++++--------------------------- 1 file changed, 25 insertions(+), 35 deletions(-) diff --git a/drivers/mfd/omap-usb-tll.c b/drivers/mfd/omap-usb-tll.c index 44a5d66314c6..446713dbee27 100644 --- a/drivers/mfd/omap-usb-tll.c +++ b/drivers/mfd/omap-usb-tll.c @@ -108,9 +108,9 @@ (x) != OMAP_EHCI_PORT_MODE_PHY) struct usbtll_omap { - int nch; /* num. of channels */ - struct clk **ch_clk; - void __iomem *base; + void __iomem *base; + int nch; /* num. of channels */ + struct clk *ch_clk[0]; /* must be the last member */ }; /*-------------------------------------------------------------------------*/ @@ -216,53 +216,49 @@ static int usbtll_omap_probe(struct platform_device *pdev) struct device *dev = &pdev->dev; struct resource *res; struct usbtll_omap *tll; - int ret = 0; - int i, ver; + void __iomem *base; + int i, nch, ver; dev_dbg(dev, "starting TI HSUSB TLL Controller\n"); - tll = devm_kzalloc(dev, sizeof(struct usbtll_omap), GFP_KERNEL); - if (!tll) { - dev_err(dev, "Memory allocation failed\n"); - return -ENOMEM; - } - res = platform_get_resource(pdev, IORESOURCE_MEM, 0); - tll->base = devm_ioremap_resource(dev, res); - if (IS_ERR(tll->base)) - return PTR_ERR(tll->base); + base = devm_ioremap_resource(dev, res); + if (IS_ERR(base)) + return PTR_ERR(base); - platform_set_drvdata(pdev, tll); pm_runtime_enable(dev); pm_runtime_get_sync(dev); - ver = usbtll_read(tll->base, OMAP_USBTLL_REVISION); + ver = usbtll_read(base, OMAP_USBTLL_REVISION); switch (ver) { case OMAP_USBTLL_REV1: case OMAP_USBTLL_REV4: - tll->nch = OMAP_TLL_CHANNEL_COUNT; + nch = OMAP_TLL_CHANNEL_COUNT; break; case OMAP_USBTLL_REV2: case OMAP_USBTLL_REV3: - tll->nch = OMAP_REV2_TLL_CHANNEL_COUNT; + nch = OMAP_REV2_TLL_CHANNEL_COUNT; break; default: - tll->nch = OMAP_TLL_CHANNEL_COUNT; - dev_dbg(dev, - "USB TLL Rev : 0x%x not recognized, assuming %d channels\n", - ver, tll->nch); + nch = OMAP_TLL_CHANNEL_COUNT; + dev_dbg(dev, "rev 0x%x not recognized, assuming %d channels\n", + ver, nch); break; } - tll->ch_clk = devm_kzalloc(dev, sizeof(struct clk *) * tll->nch, - GFP_KERNEL); - if (!tll->ch_clk) { - ret = -ENOMEM; - dev_err(dev, "Couldn't allocate memory for channel clocks\n"); - goto err_clk_alloc; + tll = devm_kzalloc(dev, sizeof(*tll) + sizeof(tll->ch_clk[nch]), + GFP_KERNEL); + if (!tll) { + pm_runtime_put_sync(dev); + pm_runtime_disable(dev); + return -ENOMEM; } - for (i = 0; i < tll->nch; i++) { + tll->base = base; + tll->nch = nch; + platform_set_drvdata(pdev, tll); + + for (i = 0; i < nch; i++) { char clkname[] = "usb_tll_hs_usb_chx_clk"; snprintf(clkname, sizeof(clkname), @@ -282,12 +278,6 @@ static int usbtll_omap_probe(struct platform_device *pdev) spin_unlock(&tll_lock); return 0; - -err_clk_alloc: - pm_runtime_put_sync(dev); - pm_runtime_disable(dev); - - return ret; } /** -- cgit v1.2.3 From 408d1d570a63394785221ffa4131ee85b53df7b1 Mon Sep 17 00:00:00 2001 From: David Lechner Date: Tue, 23 Jan 2018 16:57:34 -0600 Subject: mfd: syscon: Set regmap name to DT node name This sets the regmap name to the device tree node name. This is useful for debugging. Signed-off-by: David Lechner Acked-by: Arnd Bergmann Signed-off-by: Lee Jones --- drivers/mfd/syscon.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/mfd/syscon.c b/drivers/mfd/syscon.c index 7eaa40bc703f..fc9ba0ea4e44 100644 --- a/drivers/mfd/syscon.c +++ b/drivers/mfd/syscon.c @@ -106,6 +106,7 @@ static struct syscon *of_syscon_register(struct device_node *np) } } + syscon_config.name = of_node_full_name(np); syscon_config.reg_stride = reg_io_width; syscon_config.val_bits = reg_io_width * 8; syscon_config.max_register = resource_size(&res) - reg_io_width; -- cgit v1.2.3 From efc9b2048c7f6bb52f70cc84b8b8b8dcc685a0d6 Mon Sep 17 00:00:00 2001 From: Dave Gerlach Date: Thu, 15 Feb 2018 22:17:05 -0600 Subject: mfd: tps65218: Reorder tps65218_regulator_id enum Commit 2dc4940360d4 ("regulator: tps65218: Remove all the compatibles") changes the probe function of drivers/regulator/tps65218-regulator.c so that it iterates through all available regulators and assumes that the regulator IDs are sequential and match the order present in the enum tps65218_regulator_id. However, for some reason the much older commit c0ea88b890d6 ("regulator: tps65218: add support for LS3 current regulator") updated all arrays with LS3 at the end but added it second to last for the enum. Because of this long standing mismatch in order between the tps65218_regulator_id enum and the regulator_desc array in the tps65218 regulator driver, the new probe function causes the strobe values to be associated with the wrong regulator ID. This causes LDO1 to fail to suspend in tps65218_pmic_set_suspend_disable due to not having anything probes for its strobe value. Fix the order in the enum so the probe function works as the update intended. Fixes: 2dc4940360d4 ("regulator: tps65218: Remove all the compatibles") Signed-off-by: Dave Gerlach Signed-off-by: Lee Jones --- include/linux/mfd/tps65218.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/include/linux/mfd/tps65218.h b/include/linux/mfd/tps65218.h index f069c518c0ed..c204d9a79436 100644 --- a/include/linux/mfd/tps65218.h +++ b/include/linux/mfd/tps65218.h @@ -205,10 +205,10 @@ enum tps65218_regulator_id { TPS65218_DCDC_4, TPS65218_DCDC_5, TPS65218_DCDC_6, - /* LS's */ - TPS65218_LS_3, /* LDOs */ TPS65218_LDO_1, + /* LS's */ + TPS65218_LS_3, }; #define TPS65218_MAX_REG_ID TPS65218_LDO_1 -- cgit v1.2.3 From 37c089d1facaf03969f66a5469c169a2c73429f6 Mon Sep 17 00:00:00 2001 From: Rajmohan Mani Date: Tue, 20 Feb 2018 15:54:07 -0800 Subject: mfd: Update to SPDX license identifier Remove the GPL v2 license boilerplate and update with the SPDX license identifier. Signed-off-by: Rajmohan Mani Signed-off-by: Lee Jones --- drivers/mfd/tps68470.c | 10 +--------- include/linux/mfd/tps68470.h | 17 +++-------------- 2 files changed, 4 insertions(+), 23 deletions(-) diff --git a/drivers/mfd/tps68470.c b/drivers/mfd/tps68470.c index 189efaea054c..a5981a79b29a 100644 --- a/drivers/mfd/tps68470.c +++ b/drivers/mfd/tps68470.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * TPS68470 chip Parent driver * @@ -8,15 +9,6 @@ * Tianshu Qiu * Jian Xu Zheng * Yuning Pu - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation version 2. - * - * This program is distributed "as is" WITHOUT ANY WARRANTY of any - * kind, whether express or implied; without even the implied warranty - * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. */ #include diff --git a/include/linux/mfd/tps68470.h b/include/linux/mfd/tps68470.h index 44f9d9f647ed..ffe81127d91c 100644 --- a/include/linux/mfd/tps68470.h +++ b/include/linux/mfd/tps68470.h @@ -1,17 +1,6 @@ -/* - * Copyright (c) 2017 Intel Corporation - * - * Functions to access TPS68470 power management chip. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation version 2. - * - * This program is distributed "as is" WITHOUT ANY WARRANTY of any - * kind, whether express or implied; without even the implied warranty - * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - */ +/* SPDX-License-Identifier: GPL-2.0 */ +/* Copyright (C) 2017 Intel Corporation */ +/* Functions to access TPS68470 power management chip. */ #ifndef __LINUX_MFD_TPS68470_H #define __LINUX_MFD_TPS68470_H -- cgit v1.2.3 From 99fb0f25c448ab72481bd700b66e0e48c583ef5a Mon Sep 17 00:00:00 2001 From: Wenkai Du Date: Thu, 22 Feb 2018 13:30:52 -0800 Subject: Revert "mfd: cros_ec: Add ACPI GPE handler for LID0 devices" This reverts commit e04653a9dcf4d98defe2149c885382e5cc72082f. It is no longer needed to install Chrome EC GPE handler to have GPE enabled in suspend to idle path. It is found that with this handler installed, EC wake up doesn't work because default EC event handler that can wake up system is not getting called. Signed-off-by: Wenkai Du Acked-by: Benson Leung Signed-off-by: Lee Jones --- drivers/mfd/Makefile | 1 - drivers/mfd/cros_ec.c | 15 ++---- drivers/mfd/cros_ec_acpi_gpe.c | 103 ----------------------------------------- include/linux/mfd/cros_ec.h | 18 ------- 4 files changed, 3 insertions(+), 134 deletions(-) delete mode 100644 drivers/mfd/cros_ec_acpi_gpe.c diff --git a/drivers/mfd/Makefile b/drivers/mfd/Makefile index d9d2cf0d32ef..e9fd20dba18d 100644 --- a/drivers/mfd/Makefile +++ b/drivers/mfd/Makefile @@ -13,7 +13,6 @@ obj-$(CONFIG_MFD_ASIC3) += asic3.o tmio_core.o obj-$(CONFIG_MFD_BCM590XX) += bcm590xx.o obj-$(CONFIG_MFD_BD9571MWV) += bd9571mwv.o cros_ec_core-objs := cros_ec.o -cros_ec_core-$(CONFIG_ACPI) += cros_ec_acpi_gpe.o obj-$(CONFIG_MFD_CROS_EC) += cros_ec_core.o obj-$(CONFIG_MFD_CROS_EC_I2C) += cros_ec_i2c.o obj-$(CONFIG_MFD_CROS_EC_SPI) += cros_ec_spi.o diff --git a/drivers/mfd/cros_ec.c b/drivers/mfd/cros_ec.c index d61024141e2b..c221163d5b9e 100644 --- a/drivers/mfd/cros_ec.c +++ b/drivers/mfd/cros_ec.c @@ -173,8 +173,6 @@ int cros_ec_register(struct cros_ec_device *ec_dev) dev_info(dev, "Chrome EC device registered\n"); - cros_ec_acpi_install_gpe_handler(dev); - return 0; fail_mfd: @@ -188,8 +186,6 @@ int cros_ec_remove(struct cros_ec_device *ec_dev) { mfd_remove_devices(ec_dev->dev); - cros_ec_acpi_remove_gpe_handler(); - if (ec_dev->irq) free_irq(ec_dev->irq, ec_dev); @@ -204,14 +200,9 @@ int cros_ec_suspend(struct cros_ec_device *ec_dev) int ret; u8 sleep_event; - if (!IS_ENABLED(CONFIG_ACPI) || pm_suspend_via_firmware()) { - sleep_event = HOST_SLEEP_EVENT_S3_SUSPEND; - } else { - sleep_event = HOST_SLEEP_EVENT_S0IX_SUSPEND; - - /* Clearing the GPE status for any pending event */ - cros_ec_acpi_clear_gpe(); - } + sleep_event = (!IS_ENABLED(CONFIG_ACPI) || pm_suspend_via_firmware()) ? + HOST_SLEEP_EVENT_S3_SUSPEND : + HOST_SLEEP_EVENT_S0IX_SUSPEND; ret = cros_ec_sleep_event(ec_dev, sleep_event); if (ret < 0) diff --git a/drivers/mfd/cros_ec_acpi_gpe.c b/drivers/mfd/cros_ec_acpi_gpe.c deleted file mode 100644 index 56d305dab2d4..000000000000 --- a/drivers/mfd/cros_ec_acpi_gpe.c +++ /dev/null @@ -1,103 +0,0 @@ -/* - * ChromeOS EC multi-function device - * - * Copyright (C) 2017 Google, Inc - * - * This software is licensed under the terms of the GNU General Public - * License version 2, as published by the Free Software Foundation, and - * may be copied, distributed, and modified under those terms. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * The ChromeOS EC multi function device is used to mux all the requests - * to the EC device for its multiple features: keyboard controller, - * battery charging and regulator control, firmware update. - */ -#include - -#define ACPI_LID_DEVICE "LID0" - -static int ec_wake_gpe = -EINVAL; - -/* - * This handler indicates to ACPI core that this GPE should stay enabled for - * lid to work in suspend to idle path. - */ -static u32 cros_ec_gpe_handler(acpi_handle gpe_device, u32 gpe_number, - void *data) -{ - return ACPI_INTERRUPT_HANDLED | ACPI_REENABLE_GPE; -} - -/* - * Get ACPI GPE for LID0 device. - */ -static int cros_ec_get_ec_wake_gpe(struct device *dev) -{ - struct acpi_device *cros_acpi_dev; - struct acpi_device *adev; - acpi_handle handle; - acpi_status status; - int ret; - - cros_acpi_dev = ACPI_COMPANION(dev); - - if (!cros_acpi_dev || !cros_acpi_dev->parent || - !cros_acpi_dev->parent->handle) - return -EINVAL; - - status = acpi_get_handle(cros_acpi_dev->parent->handle, ACPI_LID_DEVICE, - &handle); - if (ACPI_FAILURE(status)) - return -EINVAL; - - ret = acpi_bus_get_device(handle, &adev); - if (ret) - return ret; - - return adev->wakeup.gpe_number; -} - -int cros_ec_acpi_install_gpe_handler(struct device *dev) -{ - acpi_status status; - - ec_wake_gpe = cros_ec_get_ec_wake_gpe(dev); - - if (ec_wake_gpe < 0) - return ec_wake_gpe; - - status = acpi_install_gpe_handler(NULL, ec_wake_gpe, - ACPI_GPE_EDGE_TRIGGERED, - &cros_ec_gpe_handler, NULL); - if (ACPI_FAILURE(status)) - return -ENODEV; - - dev_info(dev, "Initialized, GPE = 0x%x\n", ec_wake_gpe); - - return 0; -} - -void cros_ec_acpi_remove_gpe_handler(void) -{ - acpi_status status; - - if (ec_wake_gpe < 0) - return; - - status = acpi_remove_gpe_handler(NULL, ec_wake_gpe, - &cros_ec_gpe_handler); - if (ACPI_FAILURE(status)) - pr_err("failed to remove gpe handler\n"); -} - -void cros_ec_acpi_clear_gpe(void) -{ - if (ec_wake_gpe < 0) - return; - - acpi_clear_gpe(NULL, ec_wake_gpe); -} diff --git a/include/linux/mfd/cros_ec.h b/include/linux/mfd/cros_ec.h index 2d4e23c9ea0a..4ff0cec979b0 100644 --- a/include/linux/mfd/cros_ec.h +++ b/include/linux/mfd/cros_ec.h @@ -328,22 +328,4 @@ extern struct attribute_group cros_ec_vbc_attr_group; int cros_ec_debugfs_init(struct cros_ec_dev *ec); void cros_ec_debugfs_remove(struct cros_ec_dev *ec); -/* ACPI GPE handler */ -#ifdef CONFIG_ACPI - -int cros_ec_acpi_install_gpe_handler(struct device *dev); -void cros_ec_acpi_remove_gpe_handler(void); -void cros_ec_acpi_clear_gpe(void); - -#else /* CONFIG_ACPI */ - -static inline int cros_ec_acpi_install_gpe_handler(struct device *dev) -{ - return -ENODEV; -} -static inline void cros_ec_acpi_remove_gpe_handler(void) {} -static inline void cros_ec_acpi_clear_gpe(void) {} - -#endif /* CONFIG_ACPI */ - #endif /* __LINUX_MFD_CROS_EC_H */ -- cgit v1.2.3 From 034c3c95294937b5f6b1517ad74623599ce72008 Mon Sep 17 00:00:00 2001 From: Quentin Schulz Date: Wed, 28 Feb 2018 11:35:56 +0100 Subject: mfd: axp20x: Make AXP209/22x cells probe their ADC via DT This makes AXP209 and AXP22x ADCs probe first via DT and then by fallback via platform. Signed-off-by: Quentin Schulz Acked-by: Chen-Yu Tsai Signed-off-by: Lee Jones --- drivers/mfd/axp20x.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/drivers/mfd/axp20x.c b/drivers/mfd/axp20x.c index e94c72c2faa2..1977a039164d 100644 --- a/drivers/mfd/axp20x.c +++ b/drivers/mfd/axp20x.c @@ -660,6 +660,7 @@ static struct mfd_cell axp20x_cells[] = { .name = "axp20x-regulator", }, { .name = "axp20x-adc", + .of_compatible = "x-powers,axp209-adc", }, { .name = "axp20x-battery-power-supply", .of_compatible = "x-powers,axp209-battery-power-supply", @@ -684,7 +685,8 @@ static struct mfd_cell axp221_cells[] = { }, { .name = "axp20x-regulator", }, { - .name = "axp22x-adc" + .name = "axp22x-adc", + .of_compatible = "x-powers,axp221-adc", }, { .name = "axp20x-ac-power-supply", .of_compatible = "x-powers,axp221-ac-power-supply", @@ -708,6 +710,7 @@ static struct mfd_cell axp223_cells[] = { .resources = axp22x_pek_resources, }, { .name = "axp22x-adc", + .of_compatible = "x-powers,axp221-adc", }, { .name = "axp20x-battery-power-supply", .of_compatible = "x-powers,axp221-battery-power-supply", -- cgit v1.2.3 From e5d590fa60fbf0bf1c03ffc19ebce7c17ef6a7fe Mon Sep 17 00:00:00 2001 From: Quentin Schulz Date: Wed, 28 Feb 2018 11:35:57 +0100 Subject: mfd: axp20x: Probe axp20x_adc driver for AXP813 This makes the axp20x_adc driver probe with platform device id "axp813-adc". Signed-off-by: Quentin Schulz Acked-by: Chen-Yu Tsai Signed-off-by: Lee Jones --- drivers/mfd/axp20x.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/drivers/mfd/axp20x.c b/drivers/mfd/axp20x.c index 1977a039164d..e5516aa6f91b 100644 --- a/drivers/mfd/axp20x.c +++ b/drivers/mfd/axp20x.c @@ -885,7 +885,10 @@ static struct mfd_cell axp813_cells[] = { }, { .name = "axp20x-gpio", .of_compatible = "x-powers,axp813-gpio", - } + }, { + .name = "axp813-adc", + .of_compatible = "x-powers,axp813-adc", + }, }; static struct axp20x_dev *axp20x_pm_power_off; -- cgit v1.2.3 From 6720328fc9cff4a2d8d7cbd6c71cd33958ccc0b3 Mon Sep 17 00:00:00 2001 From: Quentin Schulz Date: Wed, 28 Feb 2018 11:36:01 +0100 Subject: mfd: axp20x: Add battery power supply cell for AXP813 As axp20x-battery-power-supply now supports AXP813, add a cell for it. Signed-off-by: Quentin Schulz Reviewed-by: Chen-Yu Tsai Signed-off-by: Lee Jones --- drivers/mfd/axp20x.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/drivers/mfd/axp20x.c b/drivers/mfd/axp20x.c index e5516aa6f91b..aaf2acbef701 100644 --- a/drivers/mfd/axp20x.c +++ b/drivers/mfd/axp20x.c @@ -888,6 +888,9 @@ static struct mfd_cell axp813_cells[] = { }, { .name = "axp813-adc", .of_compatible = "x-powers,axp813-adc", + }, { + .name = "axp20x-battery-power-supply", + .of_compatible = "x-powers,axp813-battery-power-supply", }, }; -- cgit v1.2.3 From 500f9ff518cf55930c670b0e2b8901caf70a7548 Mon Sep 17 00:00:00 2001 From: Jeffy Chen Date: Mon, 12 Mar 2018 17:51:39 +0800 Subject: mfd: syscon: Set name of regmap_config We are now allowing to register debugfs without a valid device, and not having a valid name will end up using "dummy*" to create debugfs dir. Signed-off-by: Jeffy Chen Signed-off-by: Lee Jones --- drivers/mfd/syscon.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/mfd/syscon.c b/drivers/mfd/syscon.c index fc9ba0ea4e44..b6d05cd934e6 100644 --- a/drivers/mfd/syscon.c +++ b/drivers/mfd/syscon.c @@ -110,6 +110,7 @@ static struct syscon *of_syscon_register(struct device_node *np) syscon_config.reg_stride = reg_io_width; syscon_config.val_bits = reg_io_width * 8; syscon_config.max_register = resource_size(&res) - reg_io_width; + syscon_config.name = of_node_full_name(np); regmap = regmap_init_mmio(NULL, base, &syscon_config); if (IS_ERR(regmap)) { -- cgit v1.2.3 From 3683e9e823643f892ee974ca7de28f5ec7f8a067 Mon Sep 17 00:00:00 2001 From: Himanshu Jha Date: Wed, 7 Mar 2018 23:36:01 +0530 Subject: mfd: ab8500-debugfs: Use kasprintf Use kasprintf instead of combination of kmalloc and sprintf. Signed-off-by: Himanshu Jha Signed-off-by: Lee Jones --- drivers/mfd/ab8500-debugfs.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/drivers/mfd/ab8500-debugfs.c b/drivers/mfd/ab8500-debugfs.c index 8ba41073dd89..831a1ceb2ed2 100644 --- a/drivers/mfd/ab8500-debugfs.c +++ b/drivers/mfd/ab8500-debugfs.c @@ -2519,11 +2519,10 @@ static ssize_t ab8500_subscribe_write(struct file *file, if (!dev_attr[irq_index]) return -ENOMEM; - event_name[irq_index] = kmalloc(count, GFP_KERNEL); + event_name[irq_index] = kasprintf(GFP_KERNEL, "%lu", user_val); if (!event_name[irq_index]) return -ENOMEM; - sprintf(event_name[irq_index], "%lu", user_val); dev_attr[irq_index]->show = show_irq; dev_attr[irq_index]->store = NULL; dev_attr[irq_index]->attr.name = event_name[irq_index]; -- cgit v1.2.3 From 6d97b6f1af8bfca0ac37e860a5b80612ce741fe2 Mon Sep 17 00:00:00 2001 From: Andrey Smirnov Date: Thu, 8 Mar 2018 09:37:54 -0800 Subject: mfd: rave-sp: Add code to print firmware versions Add code that would query and print out bootloader and application firmware version info. Signed-off-by: Andrey Smirnov Tested-by: Lucas Stach Signed-off-by: Lee Jones --- drivers/mfd/rave-sp.c | 95 +++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 95 insertions(+) diff --git a/drivers/mfd/rave-sp.c b/drivers/mfd/rave-sp.c index 5c858e784a89..6531329f7986 100644 --- a/drivers/mfd/rave-sp.c +++ b/drivers/mfd/rave-sp.c @@ -160,6 +160,8 @@ struct rave_sp_variant { * @variant: Device variant specific information * @event_notifier_list: Input event notification chain * + * @part_number_firmware: Firmware version + * @part_number_bootloader: Bootloader version */ struct rave_sp { struct serdev_device *serdev; @@ -171,8 +173,40 @@ struct rave_sp { const struct rave_sp_variant *variant; struct blocking_notifier_head event_notifier_list; + + const char *part_number_firmware; + const char *part_number_bootloader; }; +struct rave_sp_version { + u8 hardware; + __le16 major; + u8 minor; + u8 letter[2]; +} __packed; + +struct rave_sp_status { + struct rave_sp_version bootloader_version; + struct rave_sp_version firmware_version; + u16 rdu_eeprom_flag; + u16 dds_eeprom_flag; + u8 pic_flag; + u8 orientation; + u32 etc; + s16 temp[2]; + u8 backlight_current[3]; + u8 dip_switch; + u8 host_interrupt; + u16 voltage_28; + u8 i2c_device_status; + u8 power_status; + u8 general_status; + u8 deprecated1; + u8 power_led_status; + u8 deprecated2; + u8 periph_power_shutoff; +} __packed; + static bool rave_sp_id_is_event(u8 code) { return (code & 0xF0) == RAVE_SP_EVNT_BASE; @@ -609,6 +643,52 @@ static int rave_sp_default_cmd_translate(enum rave_sp_command command) } } +static const char *devm_rave_sp_version(struct device *dev, + struct rave_sp_version *version) +{ + /* + * NOTE: The format string below uses %02d to display u16 + * intentionally for the sake of backwards compatibility with + * legacy software. + */ + return devm_kasprintf(dev, GFP_KERNEL, "%02d%02d%02d.%c%c\n", + version->hardware, + le16_to_cpu(version->major), + version->minor, + version->letter[0], + version->letter[1]); +} + +static int rave_sp_get_status(struct rave_sp *sp) +{ + struct device *dev = &sp->serdev->dev; + u8 cmd[] = { + [0] = RAVE_SP_CMD_STATUS, + [1] = 0 + }; + struct rave_sp_status status; + const char *version; + int ret; + + ret = rave_sp_exec(sp, cmd, sizeof(cmd), &status, sizeof(status)); + if (ret) + return ret; + + version = devm_rave_sp_version(dev, &status.firmware_version); + if (!version) + return -ENOMEM; + + sp->part_number_firmware = version; + + version = devm_rave_sp_version(dev, &status.bootloader_version); + if (!version) + return -ENOMEM; + + sp->part_number_bootloader = version; + + return 0; +} + static const struct rave_sp_checksum rave_sp_checksum_8b2c = { .length = 1, .subroutine = csum_8b2c, @@ -657,6 +737,7 @@ static const struct serdev_device_ops rave_sp_serdev_device_ops = { static int rave_sp_probe(struct serdev_device *serdev) { struct device *dev = &serdev->dev; + const char *unknown = "unknown\n"; struct rave_sp *sp; u32 baud; int ret; @@ -689,6 +770,20 @@ static int rave_sp_probe(struct serdev_device *serdev) serdev_device_set_baudrate(serdev, baud); + ret = rave_sp_get_status(sp); + if (ret) { + dev_warn(dev, "Failed to get firmware status: %d\n", ret); + sp->part_number_firmware = unknown; + sp->part_number_bootloader = unknown; + } + + /* + * Those strings already have a \n embedded, so there's no + * need to have one in format string. + */ + dev_info(dev, "Firmware version: %s", sp->part_number_firmware); + dev_info(dev, "Bootloader version: %s", sp->part_number_bootloader); + return devm_of_platform_populate(dev); } -- cgit v1.2.3 From 44564bc3d999cb1febfdb6750e2059d2b308ce00 Mon Sep 17 00:00:00 2001 From: Andrey Smirnov Date: Thu, 8 Mar 2018 09:37:55 -0800 Subject: mfd: rave-sp: Convert print_hex_dump() to print_hex_dump_debug() Convert print_hex_dump() to print_hex_dump_debug() to be able to leverage CONFIG_DYNAMIC_DEBUG. Signed-off-by: Andrey Smirnov Reviewed-by: Lucas Stach Signed-off-by: Lee Jones --- drivers/mfd/rave-sp.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/drivers/mfd/rave-sp.c b/drivers/mfd/rave-sp.c index 6531329f7986..b70416050a81 100644 --- a/drivers/mfd/rave-sp.c +++ b/drivers/mfd/rave-sp.c @@ -309,8 +309,8 @@ static int rave_sp_write(struct rave_sp *sp, const u8 *data, u8 data_size) length = dest - frame; - print_hex_dump(KERN_DEBUG, "rave-sp tx: ", DUMP_PREFIX_NONE, - 16, 1, frame, length, false); + print_hex_dump_debug("rave-sp tx: ", DUMP_PREFIX_NONE, + 16, 1, frame, length, false); return serdev_device_write(sp->serdev, frame, length, HZ); } @@ -451,8 +451,8 @@ static void rave_sp_receive_frame(struct rave_sp *sp, struct device *dev = &sp->serdev->dev; u8 crc_calculated[checksum_length]; - print_hex_dump(KERN_DEBUG, "rave-sp rx: ", DUMP_PREFIX_NONE, - 16, 1, data, length, false); + print_hex_dump_debug("rave-sp rx: ", DUMP_PREFIX_NONE, + 16, 1, data, length, false); if (unlikely(length <= checksum_length)) { dev_warn(dev, "Dropping short frame\n"); -- cgit v1.2.3 From 5112cab38c76c28f973def1a9c8b881f2dc81a48 Mon Sep 17 00:00:00 2001 From: Andrey Smirnov Date: Thu, 8 Mar 2018 09:37:56 -0800 Subject: mfd: rave-sp: Check received frame length before accepting next byte Check received frame length _before_ accepting next byte in order to avoid incorrectly rejecting payloads that are RAVE_SP_RX_BUFFER_SIZE long. Signed-off-by: Andrey Smirnov Tested-by: Lucas Stach Signed-off-by: Lee Jones --- drivers/mfd/rave-sp.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/mfd/rave-sp.c b/drivers/mfd/rave-sp.c index b70416050a81..cb0cc9d509a0 100644 --- a/drivers/mfd/rave-sp.c +++ b/drivers/mfd/rave-sp.c @@ -546,8 +546,6 @@ static int rave_sp_receive_buf(struct serdev_device *serdev, /* FALLTHROUGH */ case RAVE_SP_EXPECT_ESCAPED_DATA: - deframer->data[deframer->length++] = byte; - if (deframer->length == sizeof(deframer->data)) { dev_warn(dev, "Bad frame: Too long\n"); /* @@ -562,6 +560,8 @@ static int rave_sp_receive_buf(struct serdev_device *serdev, goto reset_framer; } + deframer->data[deframer->length++] = byte; + /* * We've extracted out special byte, now we * can go back to regular data collecting -- cgit v1.2.3 From a5e20bfa250dc6989d4939171283a17a6d25346d Mon Sep 17 00:00:00 2001 From: Markus Elfring Date: Thu, 8 Mar 2018 11:44:33 +0100 Subject: mfd: abx500-core: Delete an error message for a failed memory allocation in abx500_register_ops() Omit an extra message for a memory allocation failure in this function. This issue was detected by using the Coccinelle software. Signed-off-by: Markus Elfring Reviewed-by: Linus Walleij Signed-off-by: Lee Jones --- drivers/mfd/abx500-core.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/drivers/mfd/abx500-core.c b/drivers/mfd/abx500-core.c index 0d3846a4767c..c8c9d41abcaa 100644 --- a/drivers/mfd/abx500-core.c +++ b/drivers/mfd/abx500-core.c @@ -40,10 +40,9 @@ int abx500_register_ops(struct device *dev, struct abx500_ops *ops) dev_entry = devm_kzalloc(dev, sizeof(struct abx500_device_entry), GFP_KERNEL); - if (!dev_entry) { - dev_err(dev, "register_ops kzalloc failed"); + if (!dev_entry) return -ENOMEM; - } + dev_entry->dev = dev; memcpy(&dev_entry->ops, ops, sizeof(struct abx500_ops)); -- cgit v1.2.3 From 5053e3a3383ef3952496146c75e77245e51e9040 Mon Sep 17 00:00:00 2001 From: Markus Elfring Date: Thu, 8 Mar 2018 12:46:47 +0100 Subject: mfd: abx500-core: Improve two size determinations in abx500_register_ops() Replace the specification of two data structures by pointer dereferences as the parameter for the operator "sizeof" to make the corresponding size determination a bit safer according to the Linux coding style convention. This issue was detected by using the Coccinelle software. Signed-off-by: Markus Elfring Reviewed-by: Linus Walleij Signed-off-by: Lee Jones --- drivers/mfd/abx500-core.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/drivers/mfd/abx500-core.c b/drivers/mfd/abx500-core.c index c8c9d41abcaa..17176e91cbd0 100644 --- a/drivers/mfd/abx500-core.c +++ b/drivers/mfd/abx500-core.c @@ -37,14 +37,12 @@ int abx500_register_ops(struct device *dev, struct abx500_ops *ops) { struct abx500_device_entry *dev_entry; - dev_entry = devm_kzalloc(dev, - sizeof(struct abx500_device_entry), - GFP_KERNEL); + dev_entry = devm_kzalloc(dev, sizeof(*dev_entry), GFP_KERNEL); if (!dev_entry) return -ENOMEM; dev_entry->dev = dev; - memcpy(&dev_entry->ops, ops, sizeof(struct abx500_ops)); + memcpy(&dev_entry->ops, ops, sizeof(*ops)); list_add_tail(&dev_entry->list, &abx500_list); return 0; -- cgit v1.2.3 From 6271299d273831bd8f5934e5d6ddf7756cae91f3 Mon Sep 17 00:00:00 2001 From: Markus Elfring Date: Thu, 8 Mar 2018 12:50:12 +0100 Subject: mfd: abx500-core: Adjust 14 checks for null pointers MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The script “checkpatch.pl” pointed information out like the following. Comparison to NULL could be written … Thus fix the affected source code places. Signed-off-by: Markus Elfring Reviewed-by: Linus Walleij Signed-off-by: Lee Jones --- drivers/mfd/abx500-core.c | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/drivers/mfd/abx500-core.c b/drivers/mfd/abx500-core.c index 17176e91cbd0..f282d39a5917 100644 --- a/drivers/mfd/abx500-core.c +++ b/drivers/mfd/abx500-core.c @@ -65,7 +65,7 @@ int abx500_set_register_interruptible(struct device *dev, u8 bank, u8 reg, struct abx500_ops *ops; lookup_ops(dev->parent, &ops); - if ((ops != NULL) && (ops->set_register != NULL)) + if (ops && ops->set_register) return ops->set_register(dev, bank, reg, value); else return -ENOTSUPP; @@ -78,7 +78,7 @@ int abx500_get_register_interruptible(struct device *dev, u8 bank, u8 reg, struct abx500_ops *ops; lookup_ops(dev->parent, &ops); - if ((ops != NULL) && (ops->get_register != NULL)) + if (ops && ops->get_register) return ops->get_register(dev, bank, reg, value); else return -ENOTSUPP; @@ -91,7 +91,7 @@ int abx500_get_register_page_interruptible(struct device *dev, u8 bank, struct abx500_ops *ops; lookup_ops(dev->parent, &ops); - if ((ops != NULL) && (ops->get_register_page != NULL)) + if (ops && ops->get_register_page) return ops->get_register_page(dev, bank, first_reg, regvals, numregs); else @@ -105,7 +105,7 @@ int abx500_mask_and_set_register_interruptible(struct device *dev, u8 bank, struct abx500_ops *ops; lookup_ops(dev->parent, &ops); - if ((ops != NULL) && (ops->mask_and_set_register != NULL)) + if (ops && ops->mask_and_set_register) return ops->mask_and_set_register(dev, bank, reg, bitmask, bitvalues); else @@ -118,7 +118,7 @@ int abx500_get_chip_id(struct device *dev) struct abx500_ops *ops; lookup_ops(dev->parent, &ops); - if ((ops != NULL) && (ops->get_chip_id != NULL)) + if (ops && ops->get_chip_id) return ops->get_chip_id(dev); else return -ENOTSUPP; @@ -130,7 +130,7 @@ int abx500_event_registers_startup_state_get(struct device *dev, u8 *event) struct abx500_ops *ops; lookup_ops(dev->parent, &ops); - if ((ops != NULL) && (ops->event_registers_startup_state_get != NULL)) + if (ops && ops->event_registers_startup_state_get) return ops->event_registers_startup_state_get(dev, event); else return -ENOTSUPP; @@ -142,7 +142,7 @@ int abx500_startup_irq_enabled(struct device *dev, unsigned int irq) struct abx500_ops *ops; lookup_ops(dev->parent, &ops); - if ((ops != NULL) && (ops->startup_irq_enabled != NULL)) + if (ops && ops->startup_irq_enabled) return ops->startup_irq_enabled(dev, irq); else return -ENOTSUPP; -- cgit v1.2.3 From a9241b0921171bc8e595fa200aa021565cefcdcd Mon Sep 17 00:00:00 2001 From: Markus Elfring Date: Thu, 8 Mar 2018 13:45:31 +0100 Subject: mfd: si476x-i2c: Delete an error message for a failed memory allocation in si476x_core_probe() Omit an extra message for a memory allocation failure in this function. This issue was detected by using the Coccinelle software. Signed-off-by: Markus Elfring Signed-off-by: Lee Jones --- drivers/mfd/si476x-i2c.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/drivers/mfd/si476x-i2c.c b/drivers/mfd/si476x-i2c.c index e6a3d999a376..2c5ec93333c3 100644 --- a/drivers/mfd/si476x-i2c.c +++ b/drivers/mfd/si476x-i2c.c @@ -697,11 +697,9 @@ static int si476x_core_probe(struct i2c_client *client, int cell_num; core = devm_kzalloc(&client->dev, sizeof(*core), GFP_KERNEL); - if (!core) { - dev_err(&client->dev, - "failed to allocate 'struct si476x_core'\n"); + if (!core) return -ENOMEM; - } + core->client = client; core->regmap = devm_regmap_init_si476x(core); -- cgit v1.2.3 From 3eec4faddc92c8347d8cdc616aad4e3906ace186 Mon Sep 17 00:00:00 2001 From: Markus Elfring Date: Thu, 8 Mar 2018 14:05:41 +0100 Subject: mfd: sm501: Improve a size determination in two functions Replace the specification of data structures by pointer dereferences as the parameter for the operator "sizeof" to make the corresponding size determination a bit safer according to the Linux coding style convention. This issue was detected by using the Coccinelle software. Signed-off-by: Markus Elfring Signed-off-by: Lee Jones --- drivers/mfd/sm501.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/mfd/sm501.c b/drivers/mfd/sm501.c index 7298d6b571a1..4f4957ea8fa3 100644 --- a/drivers/mfd/sm501.c +++ b/drivers/mfd/sm501.c @@ -1383,7 +1383,7 @@ static int sm501_plat_probe(struct platform_device *dev) struct sm501_devdata *sm; int ret; - sm = kzalloc(sizeof(struct sm501_devdata), GFP_KERNEL); + sm = kzalloc(sizeof(*sm), GFP_KERNEL); if (sm == NULL) { ret = -ENOMEM; goto err1; @@ -1572,7 +1572,7 @@ static int sm501_pci_probe(struct pci_dev *dev, struct sm501_devdata *sm; int err; - sm = kzalloc(sizeof(struct sm501_devdata), GFP_KERNEL); + sm = kzalloc(sizeof(*sm), GFP_KERNEL); if (sm == NULL) { err = -ENOMEM; goto err1; -- cgit v1.2.3 From 4202151f5d4ad8df24fdeac8828dc8a21018da3e Mon Sep 17 00:00:00 2001 From: Markus Elfring Date: Thu, 8 Mar 2018 14:20:06 +0100 Subject: mfd: sm501: Adjust 12 checks for null pointers MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The script “checkpatch.pl” pointed information out like the following. Comparison to NULL could be written … Thus fix the affected source code places. Signed-off-by: Markus Elfring Signed-off-by: Lee Jones --- drivers/mfd/sm501.c | 26 +++++++++++--------------- 1 file changed, 11 insertions(+), 15 deletions(-) diff --git a/drivers/mfd/sm501.c b/drivers/mfd/sm501.c index 4f4957ea8fa3..55d19fd0994e 100644 --- a/drivers/mfd/sm501.c +++ b/drivers/mfd/sm501.c @@ -1050,13 +1050,13 @@ static int sm501_register_gpio(struct sm501_devdata *sm) spin_lock_init(&gpio->lock); gpio->regs_res = request_mem_region(iobase, 0x20, "sm501-gpio"); - if (gpio->regs_res == NULL) { + if (!gpio->regs_res) { dev_err(sm->dev, "gpio: failed to request region\n"); return -ENXIO; } gpio->regs = ioremap(iobase, 0x20); - if (gpio->regs == NULL) { + if (!gpio->regs) { dev_err(sm->dev, "gpio: failed to remap registers\n"); ret = -ENXIO; goto err_claimed; @@ -1358,7 +1358,7 @@ static int sm501_init_dev(struct sm501_devdata *sm) sm501_register_gpio(sm); } - if (pdata && pdata->gpio_i2c != NULL && pdata->gpio_i2c_nr > 0) { + if (pdata && pdata->gpio_i2c && pdata->gpio_i2c_nr > 0) { if (!sm501_gpio_isregistered(sm)) dev_err(sm->dev, "no gpio available for i2c gpio.\n"); else @@ -1384,7 +1384,7 @@ static int sm501_plat_probe(struct platform_device *dev) int ret; sm = kzalloc(sizeof(*sm), GFP_KERNEL); - if (sm == NULL) { + if (!sm) { ret = -ENOMEM; goto err1; } @@ -1402,8 +1402,7 @@ static int sm501_plat_probe(struct platform_device *dev) sm->io_res = platform_get_resource(dev, IORESOURCE_MEM, 1); sm->mem_res = platform_get_resource(dev, IORESOURCE_MEM, 0); - - if (sm->io_res == NULL || sm->mem_res == NULL) { + if (!sm->io_res || !sm->mem_res) { dev_err(&dev->dev, "failed to get IO resource\n"); ret = -ENOENT; goto err_res; @@ -1411,8 +1410,7 @@ static int sm501_plat_probe(struct platform_device *dev) sm->regs_claim = request_mem_region(sm->io_res->start, 0x100, "sm501"); - - if (sm->regs_claim == NULL) { + if (!sm->regs_claim) { dev_err(&dev->dev, "cannot claim registers\n"); ret = -EBUSY; goto err_res; @@ -1421,8 +1419,7 @@ static int sm501_plat_probe(struct platform_device *dev) platform_set_drvdata(dev, sm); sm->regs = ioremap(sm->io_res->start, resource_size(sm->io_res)); - - if (sm->regs == NULL) { + if (!sm->regs) { dev_err(&dev->dev, "cannot remap registers\n"); ret = -EIO; goto err_claim; @@ -1448,7 +1445,7 @@ static void sm501_set_power(struct sm501_devdata *sm, int on) { struct sm501_platdata *pd = sm->platdata; - if (pd == NULL) + if (!pd) return; if (pd->get_power) { @@ -1573,7 +1570,7 @@ static int sm501_pci_probe(struct pci_dev *dev, int err; sm = kzalloc(sizeof(*sm), GFP_KERNEL); - if (sm == NULL) { + if (!sm) { err = -ENOMEM; goto err1; } @@ -1624,15 +1621,14 @@ static int sm501_pci_probe(struct pci_dev *dev, sm->regs_claim = request_mem_region(sm->io_res->start, 0x100, "sm501"); - if (sm->regs_claim == NULL) { + if (!sm->regs_claim) { dev_err(&dev->dev, "cannot claim registers\n"); err= -EBUSY; goto err3; } sm->regs = pci_ioremap_bar(dev, 1); - - if (sm->regs == NULL) { + if (!sm->regs) { dev_err(&dev->dev, "cannot remap registers\n"); err = -EIO; goto err4; -- cgit v1.2.3 From 8349aeb6a766ad188cfa019385a0539662b04e56 Mon Sep 17 00:00:00 2001 From: Markus Elfring Date: Thu, 8 Mar 2018 15:05:16 +0100 Subject: mfd: smsc-ece1099: Improve a size determination in smsc_i2c_probe() Replace the specification of a data structure by a pointer dereference as the parameter for the operator "sizeof" to make the corresponding size determination a bit safer according to the Linux coding style convention. This issue was detected by using the Coccinelle software. Signed-off-by: Markus Elfring Signed-off-by: Lee Jones --- drivers/mfd/smsc-ece1099.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/drivers/mfd/smsc-ece1099.c b/drivers/mfd/smsc-ece1099.c index b9d96651cc0d..57b792eb58fd 100644 --- a/drivers/mfd/smsc-ece1099.c +++ b/drivers/mfd/smsc-ece1099.c @@ -37,8 +37,7 @@ static int smsc_i2c_probe(struct i2c_client *i2c, int devid, rev, venid_l, venid_h; int ret; - smsc = devm_kzalloc(&i2c->dev, sizeof(struct smsc), - GFP_KERNEL); + smsc = devm_kzalloc(&i2c->dev, sizeof(*smsc), GFP_KERNEL); if (!smsc) return -ENOMEM; -- cgit v1.2.3 From a2e87fee55c2024c7d9ad7c26614300effd48d4c Mon Sep 17 00:00:00 2001 From: Markus Elfring Date: Thu, 8 Mar 2018 15:15:51 +0100 Subject: mfd: ti_am335x_tscadc: Delete an error message for a failed memory allocation in ti_tscadc_probe() Omit an extra message for a memory allocation failure in this function. This issue was detected by using the Coccinelle software. Signed-off-by: Markus Elfring Signed-off-by: Lee Jones --- drivers/mfd/ti_am335x_tscadc.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/drivers/mfd/ti_am335x_tscadc.c b/drivers/mfd/ti_am335x_tscadc.c index 3cd958a31f36..47012c0899cd 100644 --- a/drivers/mfd/ti_am335x_tscadc.c +++ b/drivers/mfd/ti_am335x_tscadc.c @@ -169,10 +169,9 @@ static int ti_tscadc_probe(struct platform_device *pdev) /* Allocate memory for device */ tscadc = devm_kzalloc(&pdev->dev, sizeof(*tscadc), GFP_KERNEL); - if (!tscadc) { - dev_err(&pdev->dev, "failed to allocate memory.\n"); + if (!tscadc) return -ENOMEM; - } + tscadc->dev = &pdev->dev; err = platform_get_irq(pdev, 0); -- cgit v1.2.3 From 8a232f0b0d26725e2e57a1fc6fca250089f6597d Mon Sep 17 00:00:00 2001 From: Markus Elfring Date: Thu, 8 Mar 2018 15:25:58 +0100 Subject: mfd: tps65090: Delete an error message for a failed memory allocation in tps65090_i2c_probe() Omit an extra message for a memory allocation failure in this function. This issue was detected by using the Coccinelle software. Signed-off-by: Markus Elfring Signed-off-by: Lee Jones --- drivers/mfd/tps65090.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/drivers/mfd/tps65090.c b/drivers/mfd/tps65090.c index d7ec318c40c3..f13e4cd06e89 100644 --- a/drivers/mfd/tps65090.c +++ b/drivers/mfd/tps65090.c @@ -192,10 +192,8 @@ static int tps65090_i2c_probe(struct i2c_client *client, irq_base = pdata->irq_base; tps65090 = devm_kzalloc(&client->dev, sizeof(*tps65090), GFP_KERNEL); - if (!tps65090) { - dev_err(&client->dev, "mem alloc for tps65090 failed\n"); + if (!tps65090) return -ENOMEM; - } tps65090->dev = &client->dev; i2c_set_clientdata(client, tps65090); -- cgit v1.2.3 From feafdffa47bb03e9a145f4a65fc2a8a25a35aa6c Mon Sep 17 00:00:00 2001 From: Markus Elfring Date: Thu, 8 Mar 2018 15:30:54 +0100 Subject: mfd: tps6586x: Delete an error message for a failed memory allocation in tps6586x_parse_dt() Omit an extra message for a memory allocation failure in this function. This issue was detected by using the Coccinelle software. Signed-off-by: Markus Elfring Signed-off-by: Lee Jones --- drivers/mfd/tps6586x.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/drivers/mfd/tps6586x.c b/drivers/mfd/tps6586x.c index 5628a6b5b19b..b89379782741 100644 --- a/drivers/mfd/tps6586x.c +++ b/drivers/mfd/tps6586x.c @@ -423,10 +423,8 @@ static struct tps6586x_platform_data *tps6586x_parse_dt(struct i2c_client *clien struct tps6586x_platform_data *pdata; pdata = devm_kzalloc(&client->dev, sizeof(*pdata), GFP_KERNEL); - if (!pdata) { - dev_err(&client->dev, "Memory allocation failed\n"); + if (!pdata) return NULL; - } pdata->num_subdevs = 0; pdata->subdevs = NULL; -- cgit v1.2.3 From 93e879ef0e168b4a4cf2ff316184ae2f250aa6c3 Mon Sep 17 00:00:00 2001 From: Markus Elfring Date: Fri, 9 Mar 2018 09:00:59 +0100 Subject: mfd: tps65910: Delete an error message for a failed memory allocation in tps65910_parse_dt() Omit an extra message for a memory allocation failure in this function. This issue was detected by using the Coccinelle software. Signed-off-by: Markus Elfring Signed-off-by: Lee Jones --- drivers/mfd/tps65910.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/drivers/mfd/tps65910.c b/drivers/mfd/tps65910.c index 8263605f6d2f..555bd394efc3 100644 --- a/drivers/mfd/tps65910.c +++ b/drivers/mfd/tps65910.c @@ -395,10 +395,8 @@ static struct tps65910_board *tps65910_parse_dt(struct i2c_client *client, board_info = devm_kzalloc(&client->dev, sizeof(*board_info), GFP_KERNEL); - if (!board_info) { - dev_err(&client->dev, "Failed to allocate pdata\n"); + if (!board_info) return NULL; - } ret = of_property_read_u32(np, "ti,vmbch-threshold", &prop); if (!ret) -- cgit v1.2.3 From dae3be365537b2da53f355e6dfec0e3a8ea1d425 Mon Sep 17 00:00:00 2001 From: Markus Elfring Date: Fri, 9 Mar 2018 09:06:14 +0100 Subject: mfd: tps65910: Delete an unnecessary variable initialisation in four functions The local variable "ret" will be set to an appropriate value a bit later. Thus omit the explicit initialisation at the beginning. Signed-off-by: Markus Elfring Signed-off-by: Lee Jones --- drivers/mfd/tps65910.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/drivers/mfd/tps65910.c b/drivers/mfd/tps65910.c index 555bd394efc3..80ea1474c654 100644 --- a/drivers/mfd/tps65910.c +++ b/drivers/mfd/tps65910.c @@ -229,7 +229,7 @@ static struct regmap_irq_chip tps65910_irq_chip = { static int tps65910_irq_init(struct tps65910 *tps65910, int irq, struct tps65910_platform_data *pdata) { - int ret = 0; + int ret; static struct regmap_irq_chip *tps6591x_irqs_chip; if (!irq) { @@ -313,7 +313,7 @@ static int tps65910_sleepinit(struct tps65910 *tps65910, struct tps65910_board *pmic_pdata) { struct device *dev = NULL; - int ret = 0; + int ret; dev = tps65910->dev; @@ -383,7 +383,7 @@ static struct tps65910_board *tps65910_parse_dt(struct i2c_client *client, struct tps65910_board *board_info; unsigned int prop; const struct of_device_id *match; - int ret = 0; + int ret; match = of_match_device(tps65910_of_match, &client->dev); if (!match) { @@ -460,7 +460,7 @@ static int tps65910_i2c_probe(struct i2c_client *i2c, struct tps65910_board *of_pmic_plat_data = NULL; struct tps65910_platform_data *init_data; unsigned long chip_id = id->driver_data; - int ret = 0; + int ret; pmic_plat_data = dev_get_platdata(&i2c->dev); -- cgit v1.2.3 From da257efa8787be2594baf08ed84461d71d6a6d23 Mon Sep 17 00:00:00 2001 From: Markus Elfring Date: Fri, 9 Mar 2018 09:10:09 +0100 Subject: mfd: tps65910: Delete an unnecessary variable initialisation in tps65910_sleepinit() The local variable "dev" will be reassigned by a following statement. Thus omit the explicit initialisation at the beginning. Signed-off-by: Markus Elfring Signed-off-by: Lee Jones --- drivers/mfd/tps65910.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/mfd/tps65910.c b/drivers/mfd/tps65910.c index 80ea1474c654..7e7d3d1642c6 100644 --- a/drivers/mfd/tps65910.c +++ b/drivers/mfd/tps65910.c @@ -312,7 +312,7 @@ static int tps65910_ck32k_init(struct tps65910 *tps65910, static int tps65910_sleepinit(struct tps65910 *tps65910, struct tps65910_board *pmic_pdata) { - struct device *dev = NULL; + struct device *dev; int ret; dev = tps65910->dev; -- cgit v1.2.3 From 71bc4f1de3c5c14e7512c648249494238fd8405e Mon Sep 17 00:00:00 2001 From: Markus Elfring Date: Fri, 9 Mar 2018 09:19:42 +0100 Subject: mfd: tps65910: Move an assignment in tps65910_sleepinit() Move the assignment for the local variable "dev" so that its setting will be performed after a configuration check by this function. Signed-off-by: Markus Elfring Signed-off-by: Lee Jones --- drivers/mfd/tps65910.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/mfd/tps65910.c b/drivers/mfd/tps65910.c index 7e7d3d1642c6..bf16cbe6fd88 100644 --- a/drivers/mfd/tps65910.c +++ b/drivers/mfd/tps65910.c @@ -315,11 +315,11 @@ static int tps65910_sleepinit(struct tps65910 *tps65910, struct device *dev; int ret; - dev = tps65910->dev; - if (!pmic_pdata->en_dev_slp) return 0; + dev = tps65910->dev; + /* enabling SLEEP device state */ ret = tps65910_reg_set_bits(tps65910, TPS65910_DEVCTRL, DEVCTRL_DEV_SLP_MASK); -- cgit v1.2.3 From 7672c840a3145da641ed1da5ce064f9f5fb986b0 Mon Sep 17 00:00:00 2001 From: Markus Elfring Date: Fri, 9 Mar 2018 09:45:13 +0100 Subject: mfd: tps80031: Delete an error message for a failed memory allocation in tps80031_probe() Omit an extra message for a memory allocation failure in this function. This issue was detected by using the Coccinelle software. Signed-off-by: Markus Elfring Signed-off-by: Lee Jones --- drivers/mfd/tps80031.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/drivers/mfd/tps80031.c b/drivers/mfd/tps80031.c index 0812df3b0d47..608c7f77830e 100644 --- a/drivers/mfd/tps80031.c +++ b/drivers/mfd/tps80031.c @@ -431,10 +431,8 @@ static int tps80031_probe(struct i2c_client *client, } tps80031 = devm_kzalloc(&client->dev, sizeof(*tps80031), GFP_KERNEL); - if (!tps80031) { - dev_err(&client->dev, "Malloc failed for tps80031\n"); + if (!tps80031) return -ENOMEM; - } for (i = 0; i < TPS80031_NUM_SLAVES; i++) { if (tps80031_slave_address[i] == client->addr) -- cgit v1.2.3 From 9363be216aa65ef1713e3c06a49bcbeb747e1c19 Mon Sep 17 00:00:00 2001 From: Markus Elfring Date: Fri, 9 Mar 2018 09:49:32 +0100 Subject: mfd: twl6030-irq: Delete an error message for a failed memory allocation in twl6030_init_irq() Omit an extra message for a memory allocation failure in this function. This issue was detected by using the Coccinelle software. Signed-off-by: Markus Elfring Signed-off-by: Lee Jones --- drivers/mfd/twl6030-irq.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/drivers/mfd/twl6030-irq.c b/drivers/mfd/twl6030-irq.c index e3ec8dfa9f1e..e939431ed10c 100644 --- a/drivers/mfd/twl6030-irq.c +++ b/drivers/mfd/twl6030-irq.c @@ -392,10 +392,8 @@ int twl6030_init_irq(struct device *dev, int irq_num) nr_irqs = TWL6030_NR_IRQS; twl6030_irq = devm_kzalloc(dev, sizeof(*twl6030_irq), GFP_KERNEL); - if (!twl6030_irq) { - dev_err(dev, "twl6030_irq: Memory allocation failed\n"); + if (!twl6030_irq) return -ENOMEM; - } mask[0] = 0xFF; mask[1] = 0xFF; -- cgit v1.2.3 From 59f4d741b15d45e68cdca63232ee8cd4224f2ccc Mon Sep 17 00:00:00 2001 From: Markus Elfring Date: Fri, 9 Mar 2018 09:56:31 +0100 Subject: mfd: viperboard: Delete an error message for a failed memory allocation in vprbrd_probe() Omit an extra message for a memory allocation failure in this function. This issue was detected by using the Coccinelle software. Signed-off-by: Markus Elfring Signed-off-by: Lee Jones --- drivers/mfd/viperboard.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/drivers/mfd/viperboard.c b/drivers/mfd/viperboard.c index e6b3c70aeb22..e9f61262d583 100644 --- a/drivers/mfd/viperboard.c +++ b/drivers/mfd/viperboard.c @@ -59,10 +59,8 @@ static int vprbrd_probe(struct usb_interface *interface, /* allocate memory for our device state and initialize it */ vb = kzalloc(sizeof(*vb), GFP_KERNEL); - if (vb == NULL) { - dev_err(&interface->dev, "Out of memory\n"); + if (!vb) return -ENOMEM; - } mutex_init(&vb->lock); -- cgit v1.2.3 From 52a3a374af06121d6f704d1ab4fe4eeb8a1678a1 Mon Sep 17 00:00:00 2001 From: Christophe JAILLET Date: Wed, 14 Mar 2018 22:47:55 +0100 Subject: mfd: pcf50633: Fix some memory leaks in the error handling path of 'pcf50633_probe()' If a 'platform_device_alloc()' call fails, we still need to release the resources that have already been allocated before returning. Signed-off-by: Christophe JAILLET Signed-off-by: Lee Jones --- drivers/mfd/pcf50633-core.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/drivers/mfd/pcf50633-core.c b/drivers/mfd/pcf50633-core.c index f952dff6765f..0d2a88d53eed 100644 --- a/drivers/mfd/pcf50633-core.c +++ b/drivers/mfd/pcf50633-core.c @@ -242,8 +242,10 @@ static int pcf50633_probe(struct i2c_client *client, for (i = 0; i < PCF50633_NUM_REGULATORS; i++) { pdev = platform_device_alloc("pcf50633-regulator", i); - if (!pdev) - return -ENOMEM; + if (!pdev) { + ret = -ENOMEM; + goto err2; + } pdev->dev.parent = pcf->dev; ret = platform_device_add_data(pdev, &pdata->reg_init_data[i], @@ -269,6 +271,7 @@ static int pcf50633_probe(struct i2c_client *client, err: platform_device_put(pdev); +err2: for (j = 0; j < i; j++) platform_device_put(pcf->regulator_pdev[j]); -- cgit v1.2.3 From e03273e48da64083ef66394b4338361886c9a64d Mon Sep 17 00:00:00 2001 From: Baolin Wang Date: Thu, 22 Mar 2018 13:40:25 +0800 Subject: mfd: sprd: Add one syscon cell to access PMIC global registers There are some global registers in Spreadtrum sc27xx PMICs, which will be accessed by other drivers. So this patch adds one syscon cell to help to access the PMIC's global registers. Signed-off-by: Baolin Wang Signed-off-by: Lee Jones --- drivers/mfd/sprd-sc27xx-spi.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/drivers/mfd/sprd-sc27xx-spi.c b/drivers/mfd/sprd-sc27xx-spi.c index 56a4782f0569..3460ef07623c 100644 --- a/drivers/mfd/sprd-sc27xx-spi.c +++ b/drivers/mfd/sprd-sc27xx-spi.c @@ -111,6 +111,9 @@ static const struct mfd_cell sprd_pmic_devs[] = { }, { .name = "sc27xx-poweroff", .of_compatible = "sprd,sc27xx-poweroff", + }, { + .name = "sc27xx-syscon", + .of_compatible = "sprd,sc27xx-syscon", }, }; -- cgit v1.2.3 From c18604660ad02324dfc21de5dfd0c8d15e9070a5 Mon Sep 17 00:00:00 2001 From: Charles Keepax Date: Mon, 12 Mar 2018 15:52:00 +0000 Subject: mfd: arizona: Update reset pin to use GPIOD Now GPIOD has support for both pdata systems and for non-standard DT bindings the Arizona reset GPIO can be converted to use it. Worth noting gpiod_set_raw_value_cansleep is used to match the behaviour of the old GPIOs. This is because the part is fairly widely used and it is unknown how many DTs are correctly setting active low through device tree, so to avoid breaking any existing users it is best to match the previous behaviour. Signed-off-by: Charles Keepax Reviewed-by: Linus Walleij Signed-off-by: Lee Jones --- drivers/mfd/arizona-core.c | 53 ++++++++++++++++++++++++++------------- include/linux/mfd/arizona/pdata.h | 3 ++- 2 files changed, 37 insertions(+), 19 deletions(-) diff --git a/drivers/mfd/arizona-core.c b/drivers/mfd/arizona-core.c index 77875250abe5..83f1c5a516d9 100644 --- a/drivers/mfd/arizona-core.c +++ b/drivers/mfd/arizona-core.c @@ -13,13 +13,12 @@ #include #include #include -#include +#include #include #include #include #include #include -#include #include #include #include @@ -279,7 +278,7 @@ static int arizona_wait_for_boot(struct arizona *arizona) static inline void arizona_enable_reset(struct arizona *arizona) { if (arizona->pdata.reset) - gpio_set_value_cansleep(arizona->pdata.reset, 0); + gpiod_set_raw_value_cansleep(arizona->pdata.reset, 0); } static void arizona_disable_reset(struct arizona *arizona) @@ -295,7 +294,7 @@ static void arizona_disable_reset(struct arizona *arizona) break; } - gpio_set_value_cansleep(arizona->pdata.reset, 1); + gpiod_set_raw_value_cansleep(arizona->pdata.reset, 1); usleep_range(1000, 5000); } } @@ -799,14 +798,27 @@ static int arizona_of_get_core_pdata(struct arizona *arizona) struct arizona_pdata *pdata = &arizona->pdata; int ret, i; - pdata->reset = of_get_named_gpio(arizona->dev->of_node, "wlf,reset", 0); - if (pdata->reset == -EPROBE_DEFER) { - return pdata->reset; - } else if (pdata->reset < 0) { - dev_err(arizona->dev, "Reset GPIO missing/malformed: %d\n", - pdata->reset); + /* Handle old non-standard DT binding */ + pdata->reset = devm_gpiod_get_from_of_node(arizona->dev, + arizona->dev->of_node, + "wlf,reset", 0, + GPIOD_OUT_LOW, + "arizona /RESET"); + if (IS_ERR(pdata->reset)) { + ret = PTR_ERR(pdata->reset); - pdata->reset = 0; + /* + * Reset missing will be caught when other binding is read + * but all other errors imply this binding is in use but has + * encountered a problem so should be handled. + */ + if (ret == -EPROBE_DEFER) + return ret; + else if (ret != -ENOENT && ret != -ENOSYS) + dev_err(arizona->dev, "Reset GPIO malformed: %d\n", + ret); + + pdata->reset = NULL; } ret = of_property_read_u32_array(arizona->dev->of_node, @@ -1050,14 +1062,19 @@ int arizona_dev_init(struct arizona *arizona) goto err_early; } - if (arizona->pdata.reset) { + if (!arizona->pdata.reset) { /* Start out with /RESET low to put the chip into reset */ - ret = devm_gpio_request_one(arizona->dev, arizona->pdata.reset, - GPIOF_DIR_OUT | GPIOF_INIT_LOW, - "arizona /RESET"); - if (ret != 0) { - dev_err(dev, "Failed to request /RESET: %d\n", ret); - goto err_dcvdd; + arizona->pdata.reset = devm_gpiod_get(arizona->dev, "reset", + GPIOD_OUT_LOW); + if (IS_ERR(arizona->pdata.reset)) { + ret = PTR_ERR(arizona->pdata.reset); + if (ret == -EPROBE_DEFER) + goto err_dcvdd; + + dev_err(arizona->dev, + "Reset GPIO missing/malformed: %d\n", ret); + + arizona->pdata.reset = NULL; } } diff --git a/include/linux/mfd/arizona/pdata.h b/include/linux/mfd/arizona/pdata.h index f72dc53848d7..0013075d4cda 100644 --- a/include/linux/mfd/arizona/pdata.h +++ b/include/linux/mfd/arizona/pdata.h @@ -56,6 +56,7 @@ #define ARIZONA_MAX_PDM_SPK 2 struct regulator_init_data; +struct gpio_desc; struct arizona_micbias { int mV; /** Regulated voltage */ @@ -77,7 +78,7 @@ struct arizona_micd_range { }; struct arizona_pdata { - int reset; /** GPIO controlling /RESET, if any */ + struct gpio_desc *reset; /** GPIO controlling /RESET, if any */ /** Regulator configuration for MICVDD */ struct arizona_micsupp_pdata micvdd; -- cgit v1.2.3 From b16d23931b7ee5acf17432c3a6b5c6edb204aa35 Mon Sep 17 00:00:00 2001 From: Steve Twiss Date: Wed, 28 Mar 2018 12:03:09 +0100 Subject: mfd: da9062: Use core helper regmap_reg_range macros Replace multi-line entries in the regmap_range arrays with single line macros: regmap_reg_range(). This will leave the static structure array entries for regmap_range unaltered. It will significantly reduce the line count in the DA9062/61 core file. Signed-off-by: Steve Twiss Signed-off-by: Lee Jones --- drivers/mfd/da9062-core.c | 462 ++++++++++++---------------------------------- 1 file changed, 114 insertions(+), 348 deletions(-) diff --git a/drivers/mfd/da9062-core.c b/drivers/mfd/da9062-core.c index fe1811523e4a..9f6105906c09 100644 --- a/drivers/mfd/da9062-core.c +++ b/drivers/mfd/da9062-core.c @@ -365,186 +365,69 @@ static int da9062_get_device_type(struct da9062 *chip) } static const struct regmap_range da9061_aa_readable_ranges[] = { - { - .range_min = DA9062AA_PAGE_CON, - .range_max = DA9062AA_STATUS_B, - }, { - .range_min = DA9062AA_STATUS_D, - .range_max = DA9062AA_EVENT_C, - }, { - .range_min = DA9062AA_IRQ_MASK_A, - .range_max = DA9062AA_IRQ_MASK_C, - }, { - .range_min = DA9062AA_CONTROL_A, - .range_max = DA9062AA_GPIO_4, - }, { - .range_min = DA9062AA_GPIO_WKUP_MODE, - .range_max = DA9062AA_GPIO_OUT3_4, - }, { - .range_min = DA9062AA_BUCK1_CONT, - .range_max = DA9062AA_BUCK4_CONT, - }, { - .range_min = DA9062AA_BUCK3_CONT, - .range_max = DA9062AA_BUCK3_CONT, - }, { - .range_min = DA9062AA_LDO1_CONT, - .range_max = DA9062AA_LDO4_CONT, - }, { - .range_min = DA9062AA_DVC_1, - .range_max = DA9062AA_DVC_1, - }, { - .range_min = DA9062AA_SEQ, - .range_max = DA9062AA_ID_4_3, - }, { - .range_min = DA9062AA_ID_12_11, - .range_max = DA9062AA_ID_16_15, - }, { - .range_min = DA9062AA_ID_22_21, - .range_max = DA9062AA_ID_32_31, - }, { - .range_min = DA9062AA_SEQ_A, - .range_max = DA9062AA_WAIT, - }, { - .range_min = DA9062AA_RESET, - .range_max = DA9062AA_BUCK_ILIM_C, - }, { - .range_min = DA9062AA_BUCK1_CFG, - .range_max = DA9062AA_BUCK3_CFG, - }, { - .range_min = DA9062AA_VBUCK1_A, - .range_max = DA9062AA_VBUCK4_A, - }, { - .range_min = DA9062AA_VBUCK3_A, - .range_max = DA9062AA_VBUCK3_A, - }, { - .range_min = DA9062AA_VLDO1_A, - .range_max = DA9062AA_VLDO4_A, - }, { - .range_min = DA9062AA_VBUCK1_B, - .range_max = DA9062AA_VBUCK4_B, - }, { - .range_min = DA9062AA_VBUCK3_B, - .range_max = DA9062AA_VBUCK3_B, - }, { - .range_min = DA9062AA_VLDO1_B, - .range_max = DA9062AA_VLDO4_B, - }, { - .range_min = DA9062AA_INTERFACE, - .range_max = DA9062AA_CONFIG_E, - }, { - .range_min = DA9062AA_CONFIG_G, - .range_max = DA9062AA_CONFIG_K, - }, { - .range_min = DA9062AA_CONFIG_M, - .range_max = DA9062AA_CONFIG_M, - }, { - .range_min = DA9062AA_GP_ID_0, - .range_max = DA9062AA_GP_ID_19, - }, { - .range_min = DA9062AA_DEVICE_ID, - .range_max = DA9062AA_CONFIG_ID, - }, + regmap_reg_range(DA9062AA_PAGE_CON, DA9062AA_STATUS_B), + regmap_reg_range(DA9062AA_STATUS_D, DA9062AA_EVENT_C), + regmap_reg_range(DA9062AA_IRQ_MASK_A, DA9062AA_IRQ_MASK_C), + regmap_reg_range(DA9062AA_CONTROL_A, DA9062AA_GPIO_4), + regmap_reg_range(DA9062AA_GPIO_WKUP_MODE, DA9062AA_GPIO_OUT3_4), + regmap_reg_range(DA9062AA_BUCK1_CONT, DA9062AA_BUCK4_CONT), + regmap_reg_range(DA9062AA_BUCK3_CONT, DA9062AA_BUCK3_CONT), + regmap_reg_range(DA9062AA_LDO1_CONT, DA9062AA_LDO4_CONT), + regmap_reg_range(DA9062AA_DVC_1, DA9062AA_DVC_1), + regmap_reg_range(DA9062AA_SEQ, DA9062AA_ID_4_3), + regmap_reg_range(DA9062AA_ID_12_11, DA9062AA_ID_16_15), + regmap_reg_range(DA9062AA_ID_22_21, DA9062AA_ID_32_31), + regmap_reg_range(DA9062AA_SEQ_A, DA9062AA_WAIT), + regmap_reg_range(DA9062AA_RESET, DA9062AA_BUCK_ILIM_C), + regmap_reg_range(DA9062AA_BUCK1_CFG, DA9062AA_BUCK3_CFG), + regmap_reg_range(DA9062AA_VBUCK1_A, DA9062AA_VBUCK4_A), + regmap_reg_range(DA9062AA_VBUCK3_A, DA9062AA_VBUCK3_A), + regmap_reg_range(DA9062AA_VLDO1_A, DA9062AA_VLDO4_A), + regmap_reg_range(DA9062AA_VBUCK1_B, DA9062AA_VBUCK4_B), + regmap_reg_range(DA9062AA_VBUCK3_B, DA9062AA_VBUCK3_B), + regmap_reg_range(DA9062AA_VLDO1_B, DA9062AA_VLDO4_B), + regmap_reg_range(DA9062AA_INTERFACE, DA9062AA_CONFIG_E), + regmap_reg_range(DA9062AA_CONFIG_G, DA9062AA_CONFIG_K), + regmap_reg_range(DA9062AA_CONFIG_M, DA9062AA_CONFIG_M), + regmap_reg_range(DA9062AA_GP_ID_0, DA9062AA_GP_ID_19), + regmap_reg_range(DA9062AA_DEVICE_ID, DA9062AA_CONFIG_ID), }; static const struct regmap_range da9061_aa_writeable_ranges[] = { - { - .range_min = DA9062AA_PAGE_CON, - .range_max = DA9062AA_PAGE_CON, - }, { - .range_min = DA9062AA_FAULT_LOG, - .range_max = DA9062AA_EVENT_C, - }, { - .range_min = DA9062AA_IRQ_MASK_A, - .range_max = DA9062AA_IRQ_MASK_C, - }, { - .range_min = DA9062AA_CONTROL_A, - .range_max = DA9062AA_GPIO_4, - }, { - .range_min = DA9062AA_GPIO_WKUP_MODE, - .range_max = DA9062AA_GPIO_OUT3_4, - }, { - .range_min = DA9062AA_BUCK1_CONT, - .range_max = DA9062AA_BUCK4_CONT, - }, { - .range_min = DA9062AA_BUCK3_CONT, - .range_max = DA9062AA_BUCK3_CONT, - }, { - .range_min = DA9062AA_LDO1_CONT, - .range_max = DA9062AA_LDO4_CONT, - }, { - .range_min = DA9062AA_DVC_1, - .range_max = DA9062AA_DVC_1, - }, { - .range_min = DA9062AA_SEQ, - .range_max = DA9062AA_ID_4_3, - }, { - .range_min = DA9062AA_ID_12_11, - .range_max = DA9062AA_ID_16_15, - }, { - .range_min = DA9062AA_ID_22_21, - .range_max = DA9062AA_ID_32_31, - }, { - .range_min = DA9062AA_SEQ_A, - .range_max = DA9062AA_WAIT, - }, { - .range_min = DA9062AA_RESET, - .range_max = DA9062AA_BUCK_ILIM_C, - }, { - .range_min = DA9062AA_BUCK1_CFG, - .range_max = DA9062AA_BUCK3_CFG, - }, { - .range_min = DA9062AA_VBUCK1_A, - .range_max = DA9062AA_VBUCK4_A, - }, { - .range_min = DA9062AA_VBUCK3_A, - .range_max = DA9062AA_VBUCK3_A, - }, { - .range_min = DA9062AA_VLDO1_A, - .range_max = DA9062AA_VLDO4_A, - }, { - .range_min = DA9062AA_VBUCK1_B, - .range_max = DA9062AA_VBUCK4_B, - }, { - .range_min = DA9062AA_VBUCK3_B, - .range_max = DA9062AA_VBUCK3_B, - }, { - .range_min = DA9062AA_VLDO1_B, - .range_max = DA9062AA_VLDO4_B, - }, { - .range_min = DA9062AA_GP_ID_0, - .range_max = DA9062AA_GP_ID_19, - }, + regmap_reg_range(DA9062AA_PAGE_CON, DA9062AA_PAGE_CON), + regmap_reg_range(DA9062AA_FAULT_LOG, DA9062AA_EVENT_C), + regmap_reg_range(DA9062AA_IRQ_MASK_A, DA9062AA_IRQ_MASK_C), + regmap_reg_range(DA9062AA_CONTROL_A, DA9062AA_GPIO_4), + regmap_reg_range(DA9062AA_GPIO_WKUP_MODE, DA9062AA_GPIO_OUT3_4), + regmap_reg_range(DA9062AA_BUCK1_CONT, DA9062AA_BUCK4_CONT), + regmap_reg_range(DA9062AA_BUCK3_CONT, DA9062AA_BUCK3_CONT), + regmap_reg_range(DA9062AA_LDO1_CONT, DA9062AA_LDO4_CONT), + regmap_reg_range(DA9062AA_DVC_1, DA9062AA_DVC_1), + regmap_reg_range(DA9062AA_SEQ, DA9062AA_ID_4_3), + regmap_reg_range(DA9062AA_ID_12_11, DA9062AA_ID_16_15), + regmap_reg_range(DA9062AA_ID_22_21, DA9062AA_ID_32_31), + regmap_reg_range(DA9062AA_SEQ_A, DA9062AA_WAIT), + regmap_reg_range(DA9062AA_RESET, DA9062AA_BUCK_ILIM_C), + regmap_reg_range(DA9062AA_BUCK1_CFG, DA9062AA_BUCK3_CFG), + regmap_reg_range(DA9062AA_VBUCK1_A, DA9062AA_VBUCK4_A), + regmap_reg_range(DA9062AA_VBUCK3_A, DA9062AA_VBUCK3_A), + regmap_reg_range(DA9062AA_VLDO1_A, DA9062AA_VLDO4_A), + regmap_reg_range(DA9062AA_VBUCK1_B, DA9062AA_VBUCK4_B), + regmap_reg_range(DA9062AA_VBUCK3_B, DA9062AA_VBUCK3_B), + regmap_reg_range(DA9062AA_VLDO1_B, DA9062AA_VLDO4_B), + regmap_reg_range(DA9062AA_GP_ID_0, DA9062AA_GP_ID_19), }; static const struct regmap_range da9061_aa_volatile_ranges[] = { - { - .range_min = DA9062AA_PAGE_CON, - .range_max = DA9062AA_STATUS_B, - }, { - .range_min = DA9062AA_STATUS_D, - .range_max = DA9062AA_EVENT_C, - }, { - .range_min = DA9062AA_CONTROL_A, - .range_max = DA9062AA_CONTROL_B, - }, { - .range_min = DA9062AA_CONTROL_E, - .range_max = DA9062AA_CONTROL_F, - }, { - .range_min = DA9062AA_BUCK1_CONT, - .range_max = DA9062AA_BUCK4_CONT, - }, { - .range_min = DA9062AA_BUCK3_CONT, - .range_max = DA9062AA_BUCK3_CONT, - }, { - .range_min = DA9062AA_LDO1_CONT, - .range_max = DA9062AA_LDO4_CONT, - }, { - .range_min = DA9062AA_DVC_1, - .range_max = DA9062AA_DVC_1, - }, { - .range_min = DA9062AA_SEQ, - .range_max = DA9062AA_SEQ, - }, + regmap_reg_range(DA9062AA_PAGE_CON, DA9062AA_STATUS_B), + regmap_reg_range(DA9062AA_STATUS_D, DA9062AA_EVENT_C), + regmap_reg_range(DA9062AA_CONTROL_A, DA9062AA_CONTROL_B), + regmap_reg_range(DA9062AA_CONTROL_E, DA9062AA_CONTROL_F), + regmap_reg_range(DA9062AA_BUCK1_CONT, DA9062AA_BUCK4_CONT), + regmap_reg_range(DA9062AA_BUCK3_CONT, DA9062AA_BUCK3_CONT), + regmap_reg_range(DA9062AA_LDO1_CONT, DA9062AA_LDO4_CONT), + regmap_reg_range(DA9062AA_DVC_1, DA9062AA_DVC_1), + regmap_reg_range(DA9062AA_SEQ, DA9062AA_SEQ), }; static const struct regmap_access_table da9061_aa_readable_table = { @@ -587,186 +470,69 @@ static struct regmap_config da9061_regmap_config = { }; static const struct regmap_range da9062_aa_readable_ranges[] = { - { - .range_min = DA9062AA_PAGE_CON, - .range_max = DA9062AA_STATUS_B, - }, { - .range_min = DA9062AA_STATUS_D, - .range_max = DA9062AA_EVENT_C, - }, { - .range_min = DA9062AA_IRQ_MASK_A, - .range_max = DA9062AA_IRQ_MASK_C, - }, { - .range_min = DA9062AA_CONTROL_A, - .range_max = DA9062AA_GPIO_4, - }, { - .range_min = DA9062AA_GPIO_WKUP_MODE, - .range_max = DA9062AA_BUCK4_CONT, - }, { - .range_min = DA9062AA_BUCK3_CONT, - .range_max = DA9062AA_BUCK3_CONT, - }, { - .range_min = DA9062AA_LDO1_CONT, - .range_max = DA9062AA_LDO4_CONT, - }, { - .range_min = DA9062AA_DVC_1, - .range_max = DA9062AA_DVC_1, - }, { - .range_min = DA9062AA_COUNT_S, - .range_max = DA9062AA_SECOND_D, - }, { - .range_min = DA9062AA_SEQ, - .range_max = DA9062AA_ID_4_3, - }, { - .range_min = DA9062AA_ID_12_11, - .range_max = DA9062AA_ID_16_15, - }, { - .range_min = DA9062AA_ID_22_21, - .range_max = DA9062AA_ID_32_31, - }, { - .range_min = DA9062AA_SEQ_A, - .range_max = DA9062AA_BUCK3_CFG, - }, { - .range_min = DA9062AA_VBUCK2_A, - .range_max = DA9062AA_VBUCK4_A, - }, { - .range_min = DA9062AA_VBUCK3_A, - .range_max = DA9062AA_VBUCK3_A, - }, { - .range_min = DA9062AA_VLDO1_A, - .range_max = DA9062AA_VLDO4_A, - }, { - .range_min = DA9062AA_VBUCK2_B, - .range_max = DA9062AA_VBUCK4_B, - }, { - .range_min = DA9062AA_VBUCK3_B, - .range_max = DA9062AA_VBUCK3_B, - }, { - .range_min = DA9062AA_VLDO1_B, - .range_max = DA9062AA_VLDO4_B, - }, { - .range_min = DA9062AA_BBAT_CONT, - .range_max = DA9062AA_BBAT_CONT, - }, { - .range_min = DA9062AA_INTERFACE, - .range_max = DA9062AA_CONFIG_E, - }, { - .range_min = DA9062AA_CONFIG_G, - .range_max = DA9062AA_CONFIG_K, - }, { - .range_min = DA9062AA_CONFIG_M, - .range_max = DA9062AA_CONFIG_M, - }, { - .range_min = DA9062AA_TRIM_CLDR, - .range_max = DA9062AA_GP_ID_19, - }, { - .range_min = DA9062AA_DEVICE_ID, - .range_max = DA9062AA_CONFIG_ID, - }, + regmap_reg_range(DA9062AA_PAGE_CON, DA9062AA_STATUS_B), + regmap_reg_range(DA9062AA_STATUS_D, DA9062AA_EVENT_C), + regmap_reg_range(DA9062AA_IRQ_MASK_A, DA9062AA_IRQ_MASK_C), + regmap_reg_range(DA9062AA_CONTROL_A, DA9062AA_GPIO_4), + regmap_reg_range(DA9062AA_GPIO_WKUP_MODE, DA9062AA_BUCK4_CONT), + regmap_reg_range(DA9062AA_BUCK3_CONT, DA9062AA_BUCK3_CONT), + regmap_reg_range(DA9062AA_LDO1_CONT, DA9062AA_LDO4_CONT), + regmap_reg_range(DA9062AA_DVC_1, DA9062AA_DVC_1), + regmap_reg_range(DA9062AA_COUNT_S, DA9062AA_SECOND_D), + regmap_reg_range(DA9062AA_SEQ, DA9062AA_ID_4_3), + regmap_reg_range(DA9062AA_ID_12_11, DA9062AA_ID_16_15), + regmap_reg_range(DA9062AA_ID_22_21, DA9062AA_ID_32_31), + regmap_reg_range(DA9062AA_SEQ_A, DA9062AA_BUCK3_CFG), + regmap_reg_range(DA9062AA_VBUCK2_A, DA9062AA_VBUCK4_A), + regmap_reg_range(DA9062AA_VBUCK3_A, DA9062AA_VBUCK3_A), + regmap_reg_range(DA9062AA_VLDO1_A, DA9062AA_VLDO4_A), + regmap_reg_range(DA9062AA_VBUCK2_B, DA9062AA_VBUCK4_B), + regmap_reg_range(DA9062AA_VBUCK3_B, DA9062AA_VBUCK3_B), + regmap_reg_range(DA9062AA_VLDO1_B, DA9062AA_VLDO4_B), + regmap_reg_range(DA9062AA_BBAT_CONT, DA9062AA_BBAT_CONT), + regmap_reg_range(DA9062AA_INTERFACE, DA9062AA_CONFIG_E), + regmap_reg_range(DA9062AA_CONFIG_G, DA9062AA_CONFIG_K), + regmap_reg_range(DA9062AA_CONFIG_M, DA9062AA_CONFIG_M), + regmap_reg_range(DA9062AA_TRIM_CLDR, DA9062AA_GP_ID_19), + regmap_reg_range(DA9062AA_DEVICE_ID, DA9062AA_CONFIG_ID), }; static const struct regmap_range da9062_aa_writeable_ranges[] = { - { - .range_min = DA9062AA_PAGE_CON, - .range_max = DA9062AA_PAGE_CON, - }, { - .range_min = DA9062AA_FAULT_LOG, - .range_max = DA9062AA_EVENT_C, - }, { - .range_min = DA9062AA_IRQ_MASK_A, - .range_max = DA9062AA_IRQ_MASK_C, - }, { - .range_min = DA9062AA_CONTROL_A, - .range_max = DA9062AA_GPIO_4, - }, { - .range_min = DA9062AA_GPIO_WKUP_MODE, - .range_max = DA9062AA_BUCK4_CONT, - }, { - .range_min = DA9062AA_BUCK3_CONT, - .range_max = DA9062AA_BUCK3_CONT, - }, { - .range_min = DA9062AA_LDO1_CONT, - .range_max = DA9062AA_LDO4_CONT, - }, { - .range_min = DA9062AA_DVC_1, - .range_max = DA9062AA_DVC_1, - }, { - .range_min = DA9062AA_COUNT_S, - .range_max = DA9062AA_ALARM_Y, - }, { - .range_min = DA9062AA_SEQ, - .range_max = DA9062AA_ID_4_3, - }, { - .range_min = DA9062AA_ID_12_11, - .range_max = DA9062AA_ID_16_15, - }, { - .range_min = DA9062AA_ID_22_21, - .range_max = DA9062AA_ID_32_31, - }, { - .range_min = DA9062AA_SEQ_A, - .range_max = DA9062AA_BUCK3_CFG, - }, { - .range_min = DA9062AA_VBUCK2_A, - .range_max = DA9062AA_VBUCK4_A, - }, { - .range_min = DA9062AA_VBUCK3_A, - .range_max = DA9062AA_VBUCK3_A, - }, { - .range_min = DA9062AA_VLDO1_A, - .range_max = DA9062AA_VLDO4_A, - }, { - .range_min = DA9062AA_VBUCK2_B, - .range_max = DA9062AA_VBUCK4_B, - }, { - .range_min = DA9062AA_VBUCK3_B, - .range_max = DA9062AA_VBUCK3_B, - }, { - .range_min = DA9062AA_VLDO1_B, - .range_max = DA9062AA_VLDO4_B, - }, { - .range_min = DA9062AA_BBAT_CONT, - .range_max = DA9062AA_BBAT_CONT, - }, { - .range_min = DA9062AA_GP_ID_0, - .range_max = DA9062AA_GP_ID_19, - }, + regmap_reg_range(DA9062AA_PAGE_CON, DA9062AA_PAGE_CON), + regmap_reg_range(DA9062AA_FAULT_LOG, DA9062AA_EVENT_C), + regmap_reg_range(DA9062AA_IRQ_MASK_A, DA9062AA_IRQ_MASK_C), + regmap_reg_range(DA9062AA_CONTROL_A, DA9062AA_GPIO_4), + regmap_reg_range(DA9062AA_GPIO_WKUP_MODE, DA9062AA_BUCK4_CONT), + regmap_reg_range(DA9062AA_BUCK3_CONT, DA9062AA_BUCK3_CONT), + regmap_reg_range(DA9062AA_LDO1_CONT, DA9062AA_LDO4_CONT), + regmap_reg_range(DA9062AA_DVC_1, DA9062AA_DVC_1), + regmap_reg_range(DA9062AA_COUNT_S, DA9062AA_ALARM_Y), + regmap_reg_range(DA9062AA_SEQ, DA9062AA_ID_4_3), + regmap_reg_range(DA9062AA_ID_12_11, DA9062AA_ID_16_15), + regmap_reg_range(DA9062AA_ID_22_21, DA9062AA_ID_32_31), + regmap_reg_range(DA9062AA_SEQ_A, DA9062AA_BUCK3_CFG), + regmap_reg_range(DA9062AA_VBUCK2_A, DA9062AA_VBUCK4_A), + regmap_reg_range(DA9062AA_VBUCK3_A, DA9062AA_VBUCK3_A), + regmap_reg_range(DA9062AA_VLDO1_A, DA9062AA_VLDO4_A), + regmap_reg_range(DA9062AA_VBUCK2_B, DA9062AA_VBUCK4_B), + regmap_reg_range(DA9062AA_VBUCK3_B, DA9062AA_VBUCK3_B), + regmap_reg_range(DA9062AA_VLDO1_B, DA9062AA_VLDO4_B), + regmap_reg_range(DA9062AA_BBAT_CONT, DA9062AA_BBAT_CONT), + regmap_reg_range(DA9062AA_GP_ID_0, DA9062AA_GP_ID_19), }; static const struct regmap_range da9062_aa_volatile_ranges[] = { - { - .range_min = DA9062AA_PAGE_CON, - .range_max = DA9062AA_STATUS_B, - }, { - .range_min = DA9062AA_STATUS_D, - .range_max = DA9062AA_EVENT_C, - }, { - .range_min = DA9062AA_CONTROL_A, - .range_max = DA9062AA_CONTROL_B, - }, { - .range_min = DA9062AA_CONTROL_E, - .range_max = DA9062AA_CONTROL_F, - }, { - .range_min = DA9062AA_BUCK2_CONT, - .range_max = DA9062AA_BUCK4_CONT, - }, { - .range_min = DA9062AA_BUCK3_CONT, - .range_max = DA9062AA_BUCK3_CONT, - }, { - .range_min = DA9062AA_LDO1_CONT, - .range_max = DA9062AA_LDO4_CONT, - }, { - .range_min = DA9062AA_DVC_1, - .range_max = DA9062AA_DVC_1, - }, { - .range_min = DA9062AA_COUNT_S, - .range_max = DA9062AA_SECOND_D, - }, { - .range_min = DA9062AA_SEQ, - .range_max = DA9062AA_SEQ, - }, { - .range_min = DA9062AA_EN_32K, - .range_max = DA9062AA_EN_32K, - }, + regmap_reg_range(DA9062AA_PAGE_CON, DA9062AA_STATUS_B), + regmap_reg_range(DA9062AA_STATUS_D, DA9062AA_EVENT_C), + regmap_reg_range(DA9062AA_CONTROL_A, DA9062AA_CONTROL_B), + regmap_reg_range(DA9062AA_CONTROL_E, DA9062AA_CONTROL_F), + regmap_reg_range(DA9062AA_BUCK2_CONT, DA9062AA_BUCK4_CONT), + regmap_reg_range(DA9062AA_BUCK3_CONT, DA9062AA_BUCK3_CONT), + regmap_reg_range(DA9062AA_LDO1_CONT, DA9062AA_LDO4_CONT), + regmap_reg_range(DA9062AA_DVC_1, DA9062AA_DVC_1), + regmap_reg_range(DA9062AA_COUNT_S, DA9062AA_SECOND_D), + regmap_reg_range(DA9062AA_SEQ, DA9062AA_SEQ), + regmap_reg_range(DA9062AA_EN_32K, DA9062AA_EN_32K), }; static const struct regmap_access_table da9062_aa_readable_table = { -- cgit v1.2.3 From 531a469ead6ad1e79e8c84ffd4787c0747336e5a Mon Sep 17 00:00:00 2001 From: Chen-Yu Tsai Date: Thu, 29 Mar 2018 12:31:13 +0800 Subject: mfd: axp20x: Constify struct mfd_cell and struct resource The axp20x driver has lots of mfd_cell and resource structs. These can all be const-ified. Signed-off-by: Chen-Yu Tsai Signed-off-by: Lee Jones --- drivers/mfd/axp20x.c | 44 ++++++++++++++++++++++---------------------- include/linux/mfd/axp20x.h | 2 +- 2 files changed, 23 insertions(+), 23 deletions(-) diff --git a/drivers/mfd/axp20x.c b/drivers/mfd/axp20x.c index aaf2acbef701..14be0f658d74 100644 --- a/drivers/mfd/axp20x.c +++ b/drivers/mfd/axp20x.c @@ -169,18 +169,18 @@ static const struct regmap_access_table axp806_volatile_table = { .n_yes_ranges = ARRAY_SIZE(axp806_volatile_ranges), }; -static struct resource axp152_pek_resources[] = { +static const struct resource axp152_pek_resources[] = { DEFINE_RES_IRQ_NAMED(AXP152_IRQ_PEK_RIS_EDGE, "PEK_DBR"), DEFINE_RES_IRQ_NAMED(AXP152_IRQ_PEK_FAL_EDGE, "PEK_DBF"), }; -static struct resource axp20x_ac_power_supply_resources[] = { +static const struct resource axp20x_ac_power_supply_resources[] = { DEFINE_RES_IRQ_NAMED(AXP20X_IRQ_ACIN_PLUGIN, "ACIN_PLUGIN"), DEFINE_RES_IRQ_NAMED(AXP20X_IRQ_ACIN_REMOVAL, "ACIN_REMOVAL"), DEFINE_RES_IRQ_NAMED(AXP20X_IRQ_ACIN_OVER_V, "ACIN_OVER_V"), }; -static struct resource axp20x_pek_resources[] = { +static const struct resource axp20x_pek_resources[] = { { .name = "PEK_DBR", .start = AXP20X_IRQ_PEK_RIS_EDGE, @@ -194,19 +194,19 @@ static struct resource axp20x_pek_resources[] = { }, }; -static struct resource axp20x_usb_power_supply_resources[] = { +static const struct resource axp20x_usb_power_supply_resources[] = { DEFINE_RES_IRQ_NAMED(AXP20X_IRQ_VBUS_PLUGIN, "VBUS_PLUGIN"), DEFINE_RES_IRQ_NAMED(AXP20X_IRQ_VBUS_REMOVAL, "VBUS_REMOVAL"), DEFINE_RES_IRQ_NAMED(AXP20X_IRQ_VBUS_VALID, "VBUS_VALID"), DEFINE_RES_IRQ_NAMED(AXP20X_IRQ_VBUS_NOT_VALID, "VBUS_NOT_VALID"), }; -static struct resource axp22x_usb_power_supply_resources[] = { +static const struct resource axp22x_usb_power_supply_resources[] = { DEFINE_RES_IRQ_NAMED(AXP22X_IRQ_VBUS_PLUGIN, "VBUS_PLUGIN"), DEFINE_RES_IRQ_NAMED(AXP22X_IRQ_VBUS_REMOVAL, "VBUS_REMOVAL"), }; -static struct resource axp22x_pek_resources[] = { +static const struct resource axp22x_pek_resources[] = { { .name = "PEK_DBR", .start = AXP22X_IRQ_PEK_RIS_EDGE, @@ -220,7 +220,7 @@ static struct resource axp22x_pek_resources[] = { }, }; -static struct resource axp288_power_button_resources[] = { +static const struct resource axp288_power_button_resources[] = { { .name = "PEK_DBR", .start = AXP288_IRQ_POKP, @@ -235,7 +235,7 @@ static struct resource axp288_power_button_resources[] = { }, }; -static struct resource axp288_fuel_gauge_resources[] = { +static const struct resource axp288_fuel_gauge_resources[] = { { .start = AXP288_IRQ_QWBTU, .end = AXP288_IRQ_QWBTU, @@ -268,7 +268,7 @@ static struct resource axp288_fuel_gauge_resources[] = { }, }; -static struct resource axp803_pek_resources[] = { +static const struct resource axp803_pek_resources[] = { { .name = "PEK_DBR", .start = AXP803_IRQ_PEK_RIS_EDGE, @@ -282,7 +282,7 @@ static struct resource axp803_pek_resources[] = { }, }; -static struct resource axp809_pek_resources[] = { +static const struct resource axp809_pek_resources[] = { { .name = "PEK_DBR", .start = AXP809_IRQ_PEK_RIS_EDGE, @@ -648,7 +648,7 @@ static const struct regmap_irq_chip axp809_regmap_irq_chip = { .num_regs = 5, }; -static struct mfd_cell axp20x_cells[] = { +static const struct mfd_cell axp20x_cells[] = { { .name = "axp20x-gpio", .of_compatible = "x-powers,axp209-gpio", @@ -677,7 +677,7 @@ static struct mfd_cell axp20x_cells[] = { }, }; -static struct mfd_cell axp221_cells[] = { +static const struct mfd_cell axp221_cells[] = { { .name = "axp221-pek", .num_resources = ARRAY_SIZE(axp22x_pek_resources), @@ -703,7 +703,7 @@ static struct mfd_cell axp221_cells[] = { }, }; -static struct mfd_cell axp223_cells[] = { +static const struct mfd_cell axp223_cells[] = { { .name = "axp221-pek", .num_resources = ARRAY_SIZE(axp22x_pek_resources), @@ -729,7 +729,7 @@ static struct mfd_cell axp223_cells[] = { }, }; -static struct mfd_cell axp152_cells[] = { +static const struct mfd_cell axp152_cells[] = { { .name = "axp20x-pek", .num_resources = ARRAY_SIZE(axp152_pek_resources), @@ -737,7 +737,7 @@ static struct mfd_cell axp152_cells[] = { }, }; -static struct resource axp288_adc_resources[] = { +static const struct resource axp288_adc_resources[] = { { .name = "GPADC", .start = AXP288_IRQ_GPADC, @@ -746,7 +746,7 @@ static struct resource axp288_adc_resources[] = { }, }; -static struct resource axp288_extcon_resources[] = { +static const struct resource axp288_extcon_resources[] = { { .start = AXP288_IRQ_VBUS_FALL, .end = AXP288_IRQ_VBUS_FALL, @@ -769,7 +769,7 @@ static struct resource axp288_extcon_resources[] = { }, }; -static struct resource axp288_charger_resources[] = { +static const struct resource axp288_charger_resources[] = { { .start = AXP288_IRQ_OV, .end = AXP288_IRQ_OV, @@ -817,7 +817,7 @@ static struct resource axp288_charger_resources[] = { }, }; -static struct mfd_cell axp288_cells[] = { +static const struct mfd_cell axp288_cells[] = { { .name = "axp288_adc", .num_resources = ARRAY_SIZE(axp288_adc_resources), @@ -848,7 +848,7 @@ static struct mfd_cell axp288_cells[] = { }, }; -static struct mfd_cell axp803_cells[] = { +static const struct mfd_cell axp803_cells[] = { { .name = "axp221-pek", .num_resources = ARRAY_SIZE(axp803_pek_resources), @@ -857,14 +857,14 @@ static struct mfd_cell axp803_cells[] = { { .name = "axp20x-regulator" }, }; -static struct mfd_cell axp806_cells[] = { +static const struct mfd_cell axp806_cells[] = { { .id = 2, .name = "axp20x-regulator", }, }; -static struct mfd_cell axp809_cells[] = { +static const struct mfd_cell axp809_cells[] = { { .name = "axp221-pek", .num_resources = ARRAY_SIZE(axp809_pek_resources), @@ -875,7 +875,7 @@ static struct mfd_cell axp809_cells[] = { }, }; -static struct mfd_cell axp813_cells[] = { +static const struct mfd_cell axp813_cells[] = { { .name = "axp221-pek", .num_resources = ARRAY_SIZE(axp803_pek_resources), diff --git a/include/linux/mfd/axp20x.h b/include/linux/mfd/axp20x.h index 82bf7747b312..a2489363a998 100644 --- a/include/linux/mfd/axp20x.h +++ b/include/linux/mfd/axp20x.h @@ -642,7 +642,7 @@ struct axp20x_dev { struct regmap_irq_chip_data *regmap_irqc; long variant; int nr_cells; - struct mfd_cell *cells; + const struct mfd_cell *cells; const struct regmap_config *regmap_cfg; const struct regmap_irq_chip *regmap_irq_chip; }; -- cgit v1.2.3 From e26f87e5ca75a181b6da16dd835e57b329a2664f Mon Sep 17 00:00:00 2001 From: Chen-Yu Tsai Date: Thu, 29 Mar 2018 12:31:14 +0800 Subject: mfd: axp20x: Use DEFINE_RES_IRQ to declare resources for mfd_cells Previously we were open coding the interrupts for the various mfd cells. This made the code somewhat long due to pretty-formatting. This patch convert those into one-line declarations with DEFINE_RES_IRQ, making the code shorter and easier to read. Signed-off-by: Chen-Yu Tsai Signed-off-by: Lee Jones --- drivers/mfd/axp20x.c | 187 +++++++++------------------------------------------ 1 file changed, 30 insertions(+), 157 deletions(-) diff --git a/drivers/mfd/axp20x.c b/drivers/mfd/axp20x.c index 14be0f658d74..b3051e1c3ddc 100644 --- a/drivers/mfd/axp20x.c +++ b/drivers/mfd/axp20x.c @@ -181,17 +181,8 @@ static const struct resource axp20x_ac_power_supply_resources[] = { }; static const struct resource axp20x_pek_resources[] = { - { - .name = "PEK_DBR", - .start = AXP20X_IRQ_PEK_RIS_EDGE, - .end = AXP20X_IRQ_PEK_RIS_EDGE, - .flags = IORESOURCE_IRQ, - }, { - .name = "PEK_DBF", - .start = AXP20X_IRQ_PEK_FAL_EDGE, - .end = AXP20X_IRQ_PEK_FAL_EDGE, - .flags = IORESOURCE_IRQ, - }, + DEFINE_RES_IRQ_NAMED(AXP20X_IRQ_PEK_RIS_EDGE, "PEK_DBR"), + DEFINE_RES_IRQ_NAMED(AXP20X_IRQ_PEK_FAL_EDGE, "PEK_DBF"), }; static const struct resource axp20x_usb_power_supply_resources[] = { @@ -207,93 +198,32 @@ static const struct resource axp22x_usb_power_supply_resources[] = { }; static const struct resource axp22x_pek_resources[] = { - { - .name = "PEK_DBR", - .start = AXP22X_IRQ_PEK_RIS_EDGE, - .end = AXP22X_IRQ_PEK_RIS_EDGE, - .flags = IORESOURCE_IRQ, - }, { - .name = "PEK_DBF", - .start = AXP22X_IRQ_PEK_FAL_EDGE, - .end = AXP22X_IRQ_PEK_FAL_EDGE, - .flags = IORESOURCE_IRQ, - }, + DEFINE_RES_IRQ_NAMED(AXP22X_IRQ_PEK_RIS_EDGE, "PEK_DBR"), + DEFINE_RES_IRQ_NAMED(AXP22X_IRQ_PEK_FAL_EDGE, "PEK_DBF"), }; static const struct resource axp288_power_button_resources[] = { - { - .name = "PEK_DBR", - .start = AXP288_IRQ_POKP, - .end = AXP288_IRQ_POKP, - .flags = IORESOURCE_IRQ, - }, - { - .name = "PEK_DBF", - .start = AXP288_IRQ_POKN, - .end = AXP288_IRQ_POKN, - .flags = IORESOURCE_IRQ, - }, + DEFINE_RES_IRQ_NAMED(AXP288_IRQ_POKP, "PEK_DBR"), + DEFINE_RES_IRQ_NAMED(AXP288_IRQ_POKN, "PEK_DBF"), }; static const struct resource axp288_fuel_gauge_resources[] = { - { - .start = AXP288_IRQ_QWBTU, - .end = AXP288_IRQ_QWBTU, - .flags = IORESOURCE_IRQ, - }, - { - .start = AXP288_IRQ_WBTU, - .end = AXP288_IRQ_WBTU, - .flags = IORESOURCE_IRQ, - }, - { - .start = AXP288_IRQ_QWBTO, - .end = AXP288_IRQ_QWBTO, - .flags = IORESOURCE_IRQ, - }, - { - .start = AXP288_IRQ_WBTO, - .end = AXP288_IRQ_WBTO, - .flags = IORESOURCE_IRQ, - }, - { - .start = AXP288_IRQ_WL2, - .end = AXP288_IRQ_WL2, - .flags = IORESOURCE_IRQ, - }, - { - .start = AXP288_IRQ_WL1, - .end = AXP288_IRQ_WL1, - .flags = IORESOURCE_IRQ, - }, + DEFINE_RES_IRQ(AXP288_IRQ_QWBTU), + DEFINE_RES_IRQ(AXP288_IRQ_WBTU), + DEFINE_RES_IRQ(AXP288_IRQ_QWBTO), + DEFINE_RES_IRQ(AXP288_IRQ_WBTO), + DEFINE_RES_IRQ(AXP288_IRQ_WL2), + DEFINE_RES_IRQ(AXP288_IRQ_WL1), }; static const struct resource axp803_pek_resources[] = { - { - .name = "PEK_DBR", - .start = AXP803_IRQ_PEK_RIS_EDGE, - .end = AXP803_IRQ_PEK_RIS_EDGE, - .flags = IORESOURCE_IRQ, - }, { - .name = "PEK_DBF", - .start = AXP803_IRQ_PEK_FAL_EDGE, - .end = AXP803_IRQ_PEK_FAL_EDGE, - .flags = IORESOURCE_IRQ, - }, + DEFINE_RES_IRQ_NAMED(AXP803_IRQ_PEK_RIS_EDGE, "PEK_DBR"), + DEFINE_RES_IRQ_NAMED(AXP803_IRQ_PEK_FAL_EDGE, "PEK_DBF"), }; static const struct resource axp809_pek_resources[] = { - { - .name = "PEK_DBR", - .start = AXP809_IRQ_PEK_RIS_EDGE, - .end = AXP809_IRQ_PEK_RIS_EDGE, - .flags = IORESOURCE_IRQ, - }, { - .name = "PEK_DBF", - .start = AXP809_IRQ_PEK_FAL_EDGE, - .end = AXP809_IRQ_PEK_FAL_EDGE, - .flags = IORESOURCE_IRQ, - }, + DEFINE_RES_IRQ_NAMED(AXP809_IRQ_PEK_RIS_EDGE, "PEK_DBR"), + DEFINE_RES_IRQ_NAMED(AXP809_IRQ_PEK_FAL_EDGE, "PEK_DBF"), }; static const struct regmap_config axp152_regmap_config = { @@ -738,83 +668,26 @@ static const struct mfd_cell axp152_cells[] = { }; static const struct resource axp288_adc_resources[] = { - { - .name = "GPADC", - .start = AXP288_IRQ_GPADC, - .end = AXP288_IRQ_GPADC, - .flags = IORESOURCE_IRQ, - }, + DEFINE_RES_IRQ_NAMED(AXP288_IRQ_GPADC, "GPADC"), }; static const struct resource axp288_extcon_resources[] = { - { - .start = AXP288_IRQ_VBUS_FALL, - .end = AXP288_IRQ_VBUS_FALL, - .flags = IORESOURCE_IRQ, - }, - { - .start = AXP288_IRQ_VBUS_RISE, - .end = AXP288_IRQ_VBUS_RISE, - .flags = IORESOURCE_IRQ, - }, - { - .start = AXP288_IRQ_MV_CHNG, - .end = AXP288_IRQ_MV_CHNG, - .flags = IORESOURCE_IRQ, - }, - { - .start = AXP288_IRQ_BC_USB_CHNG, - .end = AXP288_IRQ_BC_USB_CHNG, - .flags = IORESOURCE_IRQ, - }, + DEFINE_RES_IRQ(AXP288_IRQ_VBUS_FALL), + DEFINE_RES_IRQ(AXP288_IRQ_VBUS_RISE), + DEFINE_RES_IRQ(AXP288_IRQ_MV_CHNG), + DEFINE_RES_IRQ(AXP288_IRQ_BC_USB_CHNG), }; static const struct resource axp288_charger_resources[] = { - { - .start = AXP288_IRQ_OV, - .end = AXP288_IRQ_OV, - .flags = IORESOURCE_IRQ, - }, - { - .start = AXP288_IRQ_DONE, - .end = AXP288_IRQ_DONE, - .flags = IORESOURCE_IRQ, - }, - { - .start = AXP288_IRQ_CHARGING, - .end = AXP288_IRQ_CHARGING, - .flags = IORESOURCE_IRQ, - }, - { - .start = AXP288_IRQ_SAFE_QUIT, - .end = AXP288_IRQ_SAFE_QUIT, - .flags = IORESOURCE_IRQ, - }, - { - .start = AXP288_IRQ_SAFE_ENTER, - .end = AXP288_IRQ_SAFE_ENTER, - .flags = IORESOURCE_IRQ, - }, - { - .start = AXP288_IRQ_QCBTU, - .end = AXP288_IRQ_QCBTU, - .flags = IORESOURCE_IRQ, - }, - { - .start = AXP288_IRQ_CBTU, - .end = AXP288_IRQ_CBTU, - .flags = IORESOURCE_IRQ, - }, - { - .start = AXP288_IRQ_QCBTO, - .end = AXP288_IRQ_QCBTO, - .flags = IORESOURCE_IRQ, - }, - { - .start = AXP288_IRQ_CBTO, - .end = AXP288_IRQ_CBTO, - .flags = IORESOURCE_IRQ, - }, + DEFINE_RES_IRQ(AXP288_IRQ_OV), + DEFINE_RES_IRQ(AXP288_IRQ_DONE), + DEFINE_RES_IRQ(AXP288_IRQ_CHARGING), + DEFINE_RES_IRQ(AXP288_IRQ_SAFE_QUIT), + DEFINE_RES_IRQ(AXP288_IRQ_SAFE_ENTER), + DEFINE_RES_IRQ(AXP288_IRQ_QCBTU), + DEFINE_RES_IRQ(AXP288_IRQ_CBTU), + DEFINE_RES_IRQ(AXP288_IRQ_QCBTO), + DEFINE_RES_IRQ(AXP288_IRQ_CBTO), }; static const struct mfd_cell axp288_cells[] = { -- cgit v1.2.3 From eef2b53a3ec6b1919d32bd722d2f5d33769a1f48 Mon Sep 17 00:00:00 2001 From: Chen-Yu Tsai Date: Thu, 29 Mar 2018 12:31:15 +0800 Subject: mfd: axp20x: Correct AXP806 POK interrupt prefix When AXP806 support was added, POK was incorrectly expanded to PWROK. However, the datasheet lists them as POK[LSNP], which is the same as on the AXP288. Furthermore, the registers associated with POK functions are the same as the PEK on the other AXP PMICs. This suggests that "POK" means "Power On Key", much like "PEK" means "Power Enable Key", instead of "Power OK". This patch changes the "PWROK" prefix to "POK" for these interrupts. Signed-off-by: Chen-Yu Tsai Signed-off-by: Lee Jones --- drivers/mfd/axp20x.c | 8 ++++---- include/linux/mfd/axp20x.h | 8 ++++---- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/drivers/mfd/axp20x.c b/drivers/mfd/axp20x.c index b3051e1c3ddc..9a2ef3d9b8f8 100644 --- a/drivers/mfd/axp20x.c +++ b/drivers/mfd/axp20x.c @@ -450,11 +450,11 @@ static const struct regmap_irq axp806_regmap_irqs[] = { INIT_REGMAP_IRQ(AXP806, DCDCC_V_LOW, 0, 5), INIT_REGMAP_IRQ(AXP806, DCDCD_V_LOW, 0, 6), INIT_REGMAP_IRQ(AXP806, DCDCE_V_LOW, 0, 7), - INIT_REGMAP_IRQ(AXP806, PWROK_LONG, 1, 0), - INIT_REGMAP_IRQ(AXP806, PWROK_SHORT, 1, 1), + INIT_REGMAP_IRQ(AXP806, POK_LONG, 1, 0), + INIT_REGMAP_IRQ(AXP806, POK_SHORT, 1, 1), INIT_REGMAP_IRQ(AXP806, WAKEUP, 1, 4), - INIT_REGMAP_IRQ(AXP806, PWROK_FALL, 1, 5), - INIT_REGMAP_IRQ(AXP806, PWROK_RISE, 1, 6), + INIT_REGMAP_IRQ(AXP806, POK_FALL, 1, 5), + INIT_REGMAP_IRQ(AXP806, POK_RISE, 1, 6), }; static const struct regmap_irq axp809_regmap_irqs[] = { diff --git a/include/linux/mfd/axp20x.h b/include/linux/mfd/axp20x.h index a2489363a998..517e60eecbcb 100644 --- a/include/linux/mfd/axp20x.h +++ b/include/linux/mfd/axp20x.h @@ -592,11 +592,11 @@ enum axp806_irqs { AXP806_IRQ_DCDCC_V_LOW, AXP806_IRQ_DCDCD_V_LOW, AXP806_IRQ_DCDCE_V_LOW, - AXP806_IRQ_PWROK_LONG, - AXP806_IRQ_PWROK_SHORT, + AXP806_IRQ_POK_LONG, + AXP806_IRQ_POK_SHORT, AXP806_IRQ_WAKEUP, - AXP806_IRQ_PWROK_FALL, - AXP806_IRQ_PWROK_RISE, + AXP806_IRQ_POK_FALL, + AXP806_IRQ_POK_RISE, }; enum axp809_irqs { -- cgit v1.2.3 From fab54649fd9c3eb27fb5aecc583a35a7cdc4599d Mon Sep 17 00:00:00 2001 From: Sebastian Reichel Date: Fri, 30 Mar 2018 14:58:23 +0200 Subject: dt-bindings: mfd: motorola-cpcap: Document audio-codec This adds the DT binding for the audio-codec sub-module found inside the Motorola CPCAP PMIC. Signed-off-by: Sebastian Reichel Acked-by: Mark Brown Acked-by: Tony Lindgren Reviewed-by: Rob Herring Signed-off-by: Lee Jones --- .../devicetree/bindings/mfd/motorola-cpcap.txt | 42 ++++++++++++++++++++++ 1 file changed, 42 insertions(+) diff --git a/Documentation/devicetree/bindings/mfd/motorola-cpcap.txt b/Documentation/devicetree/bindings/mfd/motorola-cpcap.txt index 15bc885f9df4..c639705a98ef 100644 --- a/Documentation/devicetree/bindings/mfd/motorola-cpcap.txt +++ b/Documentation/devicetree/bindings/mfd/motorola-cpcap.txt @@ -12,6 +12,30 @@ Required properties: - spi-max-frequency : Typically set to 3000000 - spi-cs-high : SPI chip select direction +Optional subnodes: + +The sub-functions of CPCAP get their own node with their own compatible values, +which are described in the following files: + +- ../power/supply/cpcap-battery.txt +- ../power/supply/cpcap-charger.txt +- ../regulator/cpcap-regulator.txt +- ../phy/phy-cpcap-usb.txt +- ../input/cpcap-pwrbutton.txt +- ../rtc/cpcap-rtc.txt +- ../leds/leds-cpcap.txt +- ../iio/adc/cpcap-adc.txt + +The only exception is the audio codec. Instead of a compatible value its +node must be named "audio-codec". + +Required properties for the audio-codec subnode: + +- #sound-dai-cells = <1>; + +The audio-codec provides two DAIs. The first one is connected to the +Stereo HiFi DAC and the second one is connected to the Voice DAC. + Example: &mcspi1 { @@ -26,6 +50,24 @@ Example: #size-cells = <0>; spi-max-frequency = <3000000>; spi-cs-high; + + audio-codec { + #sound-dai-cells = <1>; + + /* HiFi */ + port@0 { + endpoint { + remote-endpoint = <&cpu_dai1>; + }; + }; + + /* Voice */ + port@1 { + endpoint { + remote-endpoint = <&cpu_dai2>; + }; + }; + }; }; }; -- cgit v1.2.3 From c218b3b242bd04539621b468f01ecd2af5a21a45 Mon Sep 17 00:00:00 2001 From: Peter Ujfalusi Date: Mon, 9 Apr 2018 11:45:39 +0300 Subject: mfd: twl-core: Fix clock initialization When looking up the clock we must use the client->dev as device since that is the one which is probed via DT. Cc: stable@vger.kernel.org # 4.16+ Signed-off-by: Peter Ujfalusi Signed-off-by: Lee Jones --- drivers/mfd/twl-core.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/mfd/twl-core.c b/drivers/mfd/twl-core.c index d3133a371e27..c649344fd7f2 100644 --- a/drivers/mfd/twl-core.c +++ b/drivers/mfd/twl-core.c @@ -1177,7 +1177,7 @@ twl_probe(struct i2c_client *client, const struct i2c_device_id *id) twl_priv->ready = true; /* setup clock framework */ - clocks_init(&pdev->dev, pdata ? pdata->clock : NULL); + clocks_init(&client->dev, pdata ? pdata->clock : NULL); /* read TWL IDCODE Register */ if (twl_class_is_4030()) { -- cgit v1.2.3 From ac1886165cd1201c5793099b6fbad1876bf98dfe Mon Sep 17 00:00:00 2001 From: Dan Carpenter Date: Fri, 20 Apr 2018 12:21:05 +0300 Subject: mfd: tps65911-comparator: Fix a build error In 2012, we changed the tps65910 API and fixed most drivers but forgot to update this one. Fixes: 3f7e82759c69 ("mfd: Commonize tps65910 regmap access through header") Signed-off-by: Dan Carpenter Signed-off-by: Lee Jones --- drivers/mfd/tps65911-comparator.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/mfd/tps65911-comparator.c b/drivers/mfd/tps65911-comparator.c index c0789f81a1c5..d223857fb4ad 100644 --- a/drivers/mfd/tps65911-comparator.c +++ b/drivers/mfd/tps65911-comparator.c @@ -78,7 +78,7 @@ static int comp_threshold_set(struct tps65910 *tps65910, int id, int voltage) return -EINVAL; val = index << 1; - ret = tps65910->write(tps65910, tps_comp.reg, 1, &val); + ret = tps65910_reg_write(tps65910, tps_comp.reg, val); return ret; } @@ -86,13 +86,13 @@ static int comp_threshold_set(struct tps65910 *tps65910, int id, int voltage) static int comp_threshold_get(struct tps65910 *tps65910, int id) { struct comparator tps_comp = tps_comparators[id]; + unsigned int val; int ret; - u8 val; if (id == COMP) return 0; - ret = tps65910->read(tps65910, tps_comp.reg, 1, &val); + ret = tps65910_reg_read(tps65910, tps_comp.reg, &val); if (ret < 0) return ret; -- cgit v1.2.3 From 7169483ce4570bd2918cb7b1ab04c3e095a22713 Mon Sep 17 00:00:00 2001 From: Kyle Spiers Date: Fri, 27 Apr 2018 15:30:23 -0700 Subject: mfd: rave-sp: Remove VLA As part of the effort to remove VLAs from the kernel[1], this creates constants for the checksum lengths of CCITT and 8B2C and changes crc_calculated to be the maximum size of a checksum. https://lkml.org/lkml/2018/3/7/621 Signed-off-by: Kyle Spiers Reviewed-by: Kees Cook Signed-off-by: Lee Jones --- drivers/mfd/rave-sp.c | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/drivers/mfd/rave-sp.c b/drivers/mfd/rave-sp.c index cb0cc9d509a0..36dcd98977d6 100644 --- a/drivers/mfd/rave-sp.c +++ b/drivers/mfd/rave-sp.c @@ -45,7 +45,9 @@ #define RAVE_SP_DLE 0x10 #define RAVE_SP_MAX_DATA_SIZE 64 -#define RAVE_SP_CHECKSUM_SIZE 2 /* Worst case scenario on RDU2 */ +#define RAVE_SP_CHECKSUM_8B2C 1 +#define RAVE_SP_CHECKSUM_CCITT 2 +#define RAVE_SP_CHECKSUM_SIZE RAVE_SP_CHECKSUM_CCITT /* * We don't store STX, ETX and unescaped bytes, so Rx is only * DATA + CSUM @@ -449,7 +451,12 @@ static void rave_sp_receive_frame(struct rave_sp *sp, const size_t payload_length = length - checksum_length; const u8 *crc_reported = &data[payload_length]; struct device *dev = &sp->serdev->dev; - u8 crc_calculated[checksum_length]; + u8 crc_calculated[RAVE_SP_CHECKSUM_SIZE]; + + if (unlikely(checksum_length > sizeof(crc_calculated))) { + dev_warn(dev, "Checksum too long, dropping\n"); + return; + } print_hex_dump_debug("rave-sp rx: ", DUMP_PREFIX_NONE, 16, 1, data, length, false); -- cgit v1.2.3 From 1768391c3674b0c6bdc4947121f15fb0c2f47ec4 Mon Sep 17 00:00:00 2001 From: Lee Jones Date: Tue, 1 May 2018 10:26:59 +0100 Subject: mfd: tps65911-comparator: Fix an off by one bug The COMP1 and COMP2 elements are in 0 and 1 respectively so this code is accessing the wrong elements and one space beyond the end of the array. The "id" variable is never COMP (0) so that code can be removed. Fixes: 6851ad3ab346 ("TPS65911: Comparator: Add comparator driver") Reported-by: Dan Carpenter Signed-off-by: Lee Jones --- drivers/mfd/tps65911-comparator.c | 11 ++--------- 1 file changed, 2 insertions(+), 9 deletions(-) diff --git a/drivers/mfd/tps65911-comparator.c b/drivers/mfd/tps65911-comparator.c index d223857fb4ad..33591767fb9b 100644 --- a/drivers/mfd/tps65911-comparator.c +++ b/drivers/mfd/tps65911-comparator.c @@ -22,9 +22,8 @@ #include #include -#define COMP 0 -#define COMP1 1 -#define COMP2 2 +#define COMP1 0 +#define COMP2 1 /* Comparator 1 voltage selection table in millivolts */ static const u16 COMP_VSEL_TABLE[] = { @@ -63,9 +62,6 @@ static int comp_threshold_set(struct tps65910 *tps65910, int id, int voltage) int ret; u8 index = 0, val; - if (id == COMP) - return 0; - while (curr_voltage < tps_comp.uV_max) { curr_voltage = tps_comp.vsel_table[index]; if (curr_voltage >= voltage) @@ -89,9 +85,6 @@ static int comp_threshold_get(struct tps65910 *tps65910, int id) unsigned int val; int ret; - if (id == COMP) - return 0; - ret = tps65910_reg_read(tps65910, tps_comp.reg, &val); if (ret < 0) return ret; -- cgit v1.2.3 From 69b7516c5632121510da46ad9a02b6c57b4ce271 Mon Sep 17 00:00:00 2001 From: Fabrice Gasnier Date: Tue, 15 May 2018 17:33:19 +0200 Subject: MAINTAINERS: Add entry for STM32 timer and lptimer drivers Add an entry to make myself a maintainer of STM32 timer and lptimer drivers. Signed-off-by: Fabrice Gasnier Signed-off-by: Lee Jones --- MAINTAINERS | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/MAINTAINERS b/MAINTAINERS index 0a1410d5a621..360bbe8f46d7 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -13382,6 +13382,16 @@ T: git git://linuxtv.org/media_tree.git S: Maintained F: drivers/media/usb/stk1160/ +STM32 TIMER/LPTIMER DRIVERS +M: Fabrice Gasnier +S: Maintained +F: drivers/*/stm32-*timer* +F: drivers/pwm/pwm-stm32* +F: include/linux/*/stm32-*tim* +F: Documentation/ABI/testing/*timer-stm32 +F: Documentation/devicetree/bindings/*/stm32-*timer +F: Documentation/devicetree/bindings/pwm/pwm-stm32* + STMMAC ETHERNET DRIVER M: Giuseppe Cavallaro M: Alexandre Torgue -- cgit v1.2.3 From cadb2b12fbdc956c1f4a00fa371404c25295fb2c Mon Sep 17 00:00:00 2001 From: Sebastian Andrzej Siewior Date: Fri, 4 May 2018 12:34:46 +0200 Subject: mfd: syscon: atmel-smc: Include string.h The string.h header file is needed for the memset() definition. The RT build fails because it is not pulled in via other header files. Signed-off-by: Sebastian Andrzej Siewior Acked-by: Alexandre Belloni Signed-off-by: Lee Jones --- drivers/mfd/atmel-smc.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/mfd/atmel-smc.c b/drivers/mfd/atmel-smc.c index 7d77948567d7..0adbd2e796fe 100644 --- a/drivers/mfd/atmel-smc.c +++ b/drivers/mfd/atmel-smc.c @@ -12,6 +12,7 @@ */ #include +#include /** * atmel_smc_cs_conf_init - initialize a SMC CS conf -- cgit v1.2.3 From 0dbbf25561b29ffab5ba6277429760abdf49ceff Mon Sep 17 00:00:00 2001 From: Vincent Palatin Date: Wed, 18 Apr 2018 12:23:58 +0200 Subject: mfd: cros_ec: Fail early if we cannot identify the EC If we cannot communicate with the EC chip to detect the protocol version and its features, it's very likely useless to continue. Else we will commit all kind of uninformed mistakes (using the wrong protocol, the wrong buffer size, mixing the EC with other chips). Signed-off-by: Vincent Palatin Acked-by: Benson Leung Signed-off-by: Enric Balletbo i Serra Reviewed-by: Gwendal Grignou Reviewed-by: Andy Shevchenko Signed-off-by: Lee Jones --- drivers/mfd/cros_ec.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/drivers/mfd/cros_ec.c b/drivers/mfd/cros_ec.c index c221163d5b9e..1e5276970778 100644 --- a/drivers/mfd/cros_ec.c +++ b/drivers/mfd/cros_ec.c @@ -112,7 +112,11 @@ int cros_ec_register(struct cros_ec_device *ec_dev) mutex_init(&ec_dev->lock); - cros_ec_query_all(ec_dev); + err = cros_ec_query_all(ec_dev); + if (err) { + dev_err(dev, "Cannot identify the EC: error %d\n", err); + return err; + } if (ec_dev->irq) { err = request_threaded_irq(ec_dev->irq, NULL, ec_irq_thread, -- cgit v1.2.3 From eb3f2f2396d1f8e1043b7613aa657fb4fd4ebc3e Mon Sep 17 00:00:00 2001 From: Vincent Palatin Date: Wed, 18 Apr 2018 12:23:59 +0200 Subject: mfd: cros_ec: Free IRQ automatically Free the IRQ we might have requested when removing the cros_ec device, so we can unload and reload the driver properly. Signed-off-by: Vincent Palatin Signed-off-by: Enric Balletbo i Serra Acked-by: Vincent Palatin Reviewed-by: Andy Shevchenko Signed-off-by: Lee Jones --- drivers/mfd/cros_ec.c | 20 ++++++-------------- 1 file changed, 6 insertions(+), 14 deletions(-) diff --git a/drivers/mfd/cros_ec.c b/drivers/mfd/cros_ec.c index 1e5276970778..58e05069163e 100644 --- a/drivers/mfd/cros_ec.c +++ b/drivers/mfd/cros_ec.c @@ -119,9 +119,9 @@ int cros_ec_register(struct cros_ec_device *ec_dev) } if (ec_dev->irq) { - err = request_threaded_irq(ec_dev->irq, NULL, ec_irq_thread, - IRQF_TRIGGER_LOW | IRQF_ONESHOT, - "chromeos-ec", ec_dev); + err = devm_request_threaded_irq(dev, ec_dev->irq, NULL, + ec_irq_thread, IRQF_TRIGGER_LOW | IRQF_ONESHOT, + "chromeos-ec", ec_dev); if (err) { dev_err(dev, "Failed to request IRQ %d: %d", ec_dev->irq, err); @@ -135,7 +135,7 @@ int cros_ec_register(struct cros_ec_device *ec_dev) dev_err(dev, "Failed to register Embedded Controller subdevice %d\n", err); - goto fail_mfd; + return err; } if (ec_dev->max_passthru) { @@ -153,7 +153,7 @@ int cros_ec_register(struct cros_ec_device *ec_dev) dev_err(dev, "Failed to register Power Delivery subdevice %d\n", err); - goto fail_mfd; + return err; } } @@ -162,7 +162,7 @@ int cros_ec_register(struct cros_ec_device *ec_dev) if (err) { mfd_remove_devices(dev); dev_err(dev, "Failed to register sub-devices\n"); - goto fail_mfd; + return err; } } @@ -178,11 +178,6 @@ int cros_ec_register(struct cros_ec_device *ec_dev) dev_info(dev, "Chrome EC device registered\n"); return 0; - -fail_mfd: - if (ec_dev->irq) - free_irq(ec_dev->irq, ec_dev); - return err; } EXPORT_SYMBOL(cros_ec_register); @@ -190,9 +185,6 @@ int cros_ec_remove(struct cros_ec_device *ec_dev) { mfd_remove_devices(ec_dev->dev); - if (ec_dev->irq) - free_irq(ec_dev->irq, ec_dev); - return 0; } EXPORT_SYMBOL(cros_ec_remove); -- cgit v1.2.3 From 44d99d737279eb2021b2c66df3cee6f8a21ff4e4 Mon Sep 17 00:00:00 2001 From: Douglas Anderson Date: Wed, 18 Apr 2018 12:24:00 +0200 Subject: mfd: cros_ec: Don't try to grab log when suspended We should stop our worker thread while we're suspended. If we don't then we'll get messages like: cros-ec-spi spi5.0: spi transfer failed: -108 cros-ec-spi spi5.0: cs-deassert spi transfer failed: -108 cros-ec-ctl cros-ec-ctl.0.auto: EC communication failed Signed-off-by: Douglas Anderson Signed-off-by: Enric Balletbo i Serra Reviewed-by: Andy Shevchenko Signed-off-by: Lee Jones --- drivers/mfd/cros_ec_dev.c | 4 ++++ drivers/platform/chrome/cros_ec_debugfs.c | 20 ++++++++++++++++++++ include/linux/mfd/cros_ec.h | 2 ++ 3 files changed, 26 insertions(+) diff --git a/drivers/mfd/cros_ec_dev.c b/drivers/mfd/cros_ec_dev.c index eafd06f62a3a..5a7d4e1dea70 100644 --- a/drivers/mfd/cros_ec_dev.c +++ b/drivers/mfd/cros_ec_dev.c @@ -466,6 +466,8 @@ static __maybe_unused int ec_device_suspend(struct device *dev) { struct cros_ec_dev *ec = dev_get_drvdata(dev); + cros_ec_debugfs_suspend(ec); + lb_suspend(ec); return 0; @@ -475,6 +477,8 @@ static __maybe_unused int ec_device_resume(struct device *dev) { struct cros_ec_dev *ec = dev_get_drvdata(dev); + cros_ec_debugfs_resume(ec); + lb_resume(ec); return 0; diff --git a/drivers/platform/chrome/cros_ec_debugfs.c b/drivers/platform/chrome/cros_ec_debugfs.c index cc265ed8deb7..c62ee8e610a0 100644 --- a/drivers/platform/chrome/cros_ec_debugfs.c +++ b/drivers/platform/chrome/cros_ec_debugfs.c @@ -470,3 +470,23 @@ void cros_ec_debugfs_remove(struct cros_ec_dev *ec) cros_ec_cleanup_console_log(ec->debug_info); } EXPORT_SYMBOL(cros_ec_debugfs_remove); + +void cros_ec_debugfs_suspend(struct cros_ec_dev *ec) +{ + /* + * cros_ec_debugfs_init() failures are non-fatal; it's also possible + * that we initted things but decided that console log wasn't supported. + * We'll use the same set of checks that cros_ec_debugfs_remove() + + * cros_ec_cleanup_console_log() end up using to handle those cases. + */ + if (ec->debug_info && ec->debug_info->log_buffer.buf) + cancel_delayed_work_sync(&ec->debug_info->log_poll_work); +} +EXPORT_SYMBOL(cros_ec_debugfs_suspend); + +void cros_ec_debugfs_resume(struct cros_ec_dev *ec) +{ + if (ec->debug_info && ec->debug_info->log_buffer.buf) + schedule_delayed_work(&ec->debug_info->log_poll_work, 0); +} +EXPORT_SYMBOL(cros_ec_debugfs_resume); diff --git a/include/linux/mfd/cros_ec.h b/include/linux/mfd/cros_ec.h index 4ff0cec979b0..b8e750d91200 100644 --- a/include/linux/mfd/cros_ec.h +++ b/include/linux/mfd/cros_ec.h @@ -327,5 +327,7 @@ extern struct attribute_group cros_ec_vbc_attr_group; /* debugfs stuff */ int cros_ec_debugfs_init(struct cros_ec_dev *ec); void cros_ec_debugfs_remove(struct cros_ec_dev *ec); +void cros_ec_debugfs_suspend(struct cros_ec_dev *ec); +void cros_ec_debugfs_resume(struct cros_ec_dev *ec); #endif /* __LINUX_MFD_CROS_EC_H */ -- cgit v1.2.3 From 95a4d07fdecbd52a2e683607d561a200d2522033 Mon Sep 17 00:00:00 2001 From: Enric Balletbo i Serra Date: Wed, 18 Apr 2018 12:24:01 +0200 Subject: mfd: cros_ec_dev: Register cros-ec-rtc driver as a subdevice Check whether this EC instance has RTC host command support and instatiate the RTC driver as a subdevice in such case. Signed-off-by: Enric Balletbo i Serra Reviewed-by: Gwendal Grignou Reviewed-by: Andy Shevchenko Signed-off-by: Lee Jones --- drivers/mfd/cros_ec_dev.c | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/drivers/mfd/cros_ec_dev.c b/drivers/mfd/cros_ec_dev.c index 5a7d4e1dea70..a393b3c11aa0 100644 --- a/drivers/mfd/cros_ec_dev.c +++ b/drivers/mfd/cros_ec_dev.c @@ -383,6 +383,10 @@ error: kfree(msg); } +static const struct mfd_cell cros_ec_rtc_cells[] = { + { .name = "cros-ec-rtc" } +}; + static int ec_device_probe(struct platform_device *pdev) { int retval = -ENOMEM; @@ -422,6 +426,18 @@ static int ec_device_probe(struct platform_device *pdev) if (cros_ec_check_features(ec, EC_FEATURE_MOTION_SENSE)) cros_ec_sensors_register(ec); + /* Check whether this EC instance has RTC host command support */ + if (cros_ec_check_features(ec, EC_FEATURE_RTC)) { + retval = mfd_add_devices(ec->dev, PLATFORM_DEVID_AUTO, + cros_ec_rtc_cells, + ARRAY_SIZE(cros_ec_rtc_cells), + NULL, 0, NULL); + if (retval) + dev_err(ec->dev, + "failed to add cros-ec-rtc device: %d\n", + retval); + } + /* Take control of the lightbar from the EC. */ lb_manual_suspend_ctrl(ec, 1); -- cgit v1.2.3 From e15b7f44a224851ea9f03edca65596627913a445 Mon Sep 17 00:00:00 2001 From: Daniel Hung-yu Wu Date: Wed, 18 Apr 2018 12:24:02 +0200 Subject: mfd: cros_ec_dev: Register shutdown function for debugfs Reboot or shutdown during delayed works could corrupt communication with EC and certain I2C controller may not be able to recover from the error state. This patch registers a shutdown callback used to cancel the debugfs log worker thread. Signed-off-by: Daniel Hung-yu Wu Signed-off-by: Enric Balletbo i Serra Reviewed-by: Andy Shevchenko Signed-off-by: Lee Jones --- drivers/mfd/cros_ec_dev.c | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/drivers/mfd/cros_ec_dev.c b/drivers/mfd/cros_ec_dev.c index a393b3c11aa0..1f889523885d 100644 --- a/drivers/mfd/cros_ec_dev.c +++ b/drivers/mfd/cros_ec_dev.c @@ -472,6 +472,14 @@ static int ec_device_remove(struct platform_device *pdev) return 0; } +static void ec_device_shutdown(struct platform_device *pdev) +{ + struct cros_ec_dev *ec = dev_get_drvdata(&pdev->dev); + + /* Be sure to clear up debugfs delayed works */ + cros_ec_debugfs_remove(ec); +} + static const struct platform_device_id cros_ec_id[] = { { DRV_NAME, 0 }, { /* sentinel */ }, @@ -514,6 +522,7 @@ static struct platform_driver cros_ec_dev_driver = { }, .probe = ec_device_probe, .remove = ec_device_remove, + .shutdown = ec_device_shutdown, }; static int __init cros_ec_dev_init(void) -- cgit v1.2.3 From abeed71b645c7e0e75b078e1b6f3db7d6d4404a2 Mon Sep 17 00:00:00 2001 From: Wei-Ning Huang Date: Wed, 18 Apr 2018 12:24:03 +0200 Subject: mfd: cros_ec_i2c: Add ACPI module device table Add ACPI module device table for matching cros-ec devices to load the cros_ec_i2c driver automatically. Signed-off-by: Wei-Ning Huang Acked-by: Benson Leung Signed-off-by: Enric Balletbo i Serra Reviewed-by: Gwendal Grignou Reviewed-by: Andy Shevchenko Signed-off-by: Lee Jones --- drivers/mfd/cros_ec_dev.c | 2 +- drivers/mfd/cros_ec_i2c.c | 12 ++++++++++++ 2 files changed, 13 insertions(+), 1 deletion(-) diff --git a/drivers/mfd/cros_ec_dev.c b/drivers/mfd/cros_ec_dev.c index 1f889523885d..1d6dc5c7a19d 100644 --- a/drivers/mfd/cros_ec_dev.c +++ b/drivers/mfd/cros_ec_dev.c @@ -482,7 +482,7 @@ static void ec_device_shutdown(struct platform_device *pdev) static const struct platform_device_id cros_ec_id[] = { { DRV_NAME, 0 }, - { /* sentinel */ }, + { /* sentinel */ } }; MODULE_DEVICE_TABLE(platform, cros_ec_id); diff --git a/drivers/mfd/cros_ec_i2c.c b/drivers/mfd/cros_ec_i2c.c index 9f70de1e4c70..02a7bacdc056 100644 --- a/drivers/mfd/cros_ec_i2c.c +++ b/drivers/mfd/cros_ec_i2c.c @@ -13,6 +13,7 @@ * GNU General Public License for more details. */ +#include #include #include #include @@ -344,11 +345,13 @@ static int cros_ec_i2c_resume(struct device *dev) static SIMPLE_DEV_PM_OPS(cros_ec_i2c_pm_ops, cros_ec_i2c_suspend, cros_ec_i2c_resume); +#ifdef CONFIG_OF static const struct of_device_id cros_ec_i2c_of_match[] = { { .compatible = "google,cros-ec-i2c", }, { /* sentinel */ }, }; MODULE_DEVICE_TABLE(of, cros_ec_i2c_of_match); +#endif static const struct i2c_device_id cros_ec_i2c_id[] = { { "cros-ec-i2c", 0 }, @@ -356,9 +359,18 @@ static const struct i2c_device_id cros_ec_i2c_id[] = { }; MODULE_DEVICE_TABLE(i2c, cros_ec_i2c_id); +#ifdef CONFIG_ACPI +static const struct acpi_device_id cros_ec_i2c_acpi_id[] = { + { "GOOG0008", 0 }, + { /* sentinel */ } +}; +MODULE_DEVICE_TABLE(acpi, cros_ec_i2c_acpi_id); +#endif + static struct i2c_driver cros_ec_driver = { .driver = { .name = "cros-ec-i2c", + .acpi_match_table = ACPI_PTR(cros_ec_i2c_acpi_id), .of_match_table = of_match_ptr(cros_ec_i2c_of_match), .pm = &cros_ec_i2c_pm_ops, }, -- cgit v1.2.3 From 704800dd3fe6e5bfc52773081acedc62860e508f Mon Sep 17 00:00:00 2001 From: Joseph Lo Date: Wed, 18 Apr 2018 12:24:04 +0200 Subject: mfd: cros_ec_i2c: Moving the system sleep pm ops to late The cros_ec_i2c driver is still active after it had suspended or before it resumes. Besides that, it also tried to transfer data even after the I2C host had been suspended. This will lead the system to crash. During the test, we also observe that the EC needs to be resumed earlier due to some status polling from the EC FW (e.g. battery status). So we move the PM ops to late stage to make it work normally. Signed-off-by: Joseph Lo Signed-off-by: Enric Balletbo i Serra Reviewed-by: Andy Shevchenko Signed-off-by: Lee Jones --- drivers/mfd/cros_ec_i2c.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/drivers/mfd/cros_ec_i2c.c b/drivers/mfd/cros_ec_i2c.c index 02a7bacdc056..ef9b4763356f 100644 --- a/drivers/mfd/cros_ec_i2c.c +++ b/drivers/mfd/cros_ec_i2c.c @@ -342,8 +342,9 @@ static int cros_ec_i2c_resume(struct device *dev) } #endif -static SIMPLE_DEV_PM_OPS(cros_ec_i2c_pm_ops, cros_ec_i2c_suspend, - cros_ec_i2c_resume); +static const struct dev_pm_ops cros_ec_i2c_pm_ops = { + SET_LATE_SYSTEM_SLEEP_PM_OPS(cros_ec_i2c_suspend, cros_ec_i2c_resume) +}; #ifdef CONFIG_OF static const struct of_device_id cros_ec_i2c_of_match[] = { -- cgit v1.2.3 From d28b62520830b2d0bffa2d98e81afc9f5e537e8b Mon Sep 17 00:00:00 2001 From: Andy Shevchenko Date: Tue, 24 Apr 2018 18:00:10 +0300 Subject: mfd: intel-lpss: Program REMAP register in PIO mode According to documentation REMAP register has to be programmed in either DMA or PIO mode of the slice. Move the DMA capability check below to let REMAP register be programmed in PIO mode. Cc: stable@vger.kernel.org # 4.3+ Fixes: 4b45efe85263 ("mfd: Add support for Intel Sunrisepoint LPSS devices") Signed-off-by: Andy Shevchenko Signed-off-by: Lee Jones --- drivers/mfd/intel-lpss.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/mfd/intel-lpss.c b/drivers/mfd/intel-lpss.c index 9e545eb6e8b4..4bcf117a7ba8 100644 --- a/drivers/mfd/intel-lpss.c +++ b/drivers/mfd/intel-lpss.c @@ -275,11 +275,11 @@ static void intel_lpss_init_dev(const struct intel_lpss *lpss) intel_lpss_deassert_reset(lpss); + intel_lpss_set_remap_addr(lpss); + if (!intel_lpss_has_idma(lpss)) return; - intel_lpss_set_remap_addr(lpss); - /* Make sure that SPI multiblock DMA transfers are re-enabled */ if (lpss->type == LPSS_DEV_SPI) writel(value, lpss->priv + LPSS_PRIV_SSP_REG); -- cgit v1.2.3 From c04da893e5943685bcd6927b881afc9e640fc794 Mon Sep 17 00:00:00 2001 From: Stephen Boyd Date: Wed, 2 May 2018 09:35:35 -0700 Subject: mfd: qcom-spmi-pmic: Add support for pm8005, pm8998 and pmi8998 Add the compatibles and PMIC ids for the pm8005, pm8998, and pmi8998 PMICS found on MSM8998 and SDM845 based platforms. Cc: Signed-off-by: Stephen Boyd Reviewed-by: Rob Herring Reviewed-by: Doug Anderson Signed-off-by: Lee Jones --- Documentation/devicetree/bindings/mfd/qcom,spmi-pmic.txt | 3 +++ drivers/mfd/qcom-spmi-pmic.c | 6 ++++++ 2 files changed, 9 insertions(+) diff --git a/Documentation/devicetree/bindings/mfd/qcom,spmi-pmic.txt b/Documentation/devicetree/bindings/mfd/qcom,spmi-pmic.txt index 6ac06c1b9aec..143706222a51 100644 --- a/Documentation/devicetree/bindings/mfd/qcom,spmi-pmic.txt +++ b/Documentation/devicetree/bindings/mfd/qcom,spmi-pmic.txt @@ -29,6 +29,9 @@ Required properties: "qcom,pm8916", "qcom,pm8004", "qcom,pm8909", + "qcom,pm8998", + "qcom,pmi8998", + "qcom,pm8005", or generalized "qcom,spmi-pmic". - reg: Specifies the SPMI USID slave address for this device. For more information see: diff --git a/drivers/mfd/qcom-spmi-pmic.c b/drivers/mfd/qcom-spmi-pmic.c index 2022bdfa7ab4..e2e95de649a4 100644 --- a/drivers/mfd/qcom-spmi-pmic.c +++ b/drivers/mfd/qcom-spmi-pmic.c @@ -39,6 +39,9 @@ #define PM8916_SUBTYPE 0x0b #define PM8004_SUBTYPE 0x0c #define PM8909_SUBTYPE 0x0d +#define PM8998_SUBTYPE 0x14 +#define PMI8998_SUBTYPE 0x15 +#define PM8005_SUBTYPE 0x18 static const struct of_device_id pmic_spmi_id_table[] = { { .compatible = "qcom,spmi-pmic", .data = (void *)COMMON_SUBTYPE }, @@ -55,6 +58,9 @@ static const struct of_device_id pmic_spmi_id_table[] = { { .compatible = "qcom,pm8916", .data = (void *)PM8916_SUBTYPE }, { .compatible = "qcom,pm8004", .data = (void *)PM8004_SUBTYPE }, { .compatible = "qcom,pm8909", .data = (void *)PM8909_SUBTYPE }, + { .compatible = "qcom,pm8998", .data = (void *)PM8998_SUBTYPE }, + { .compatible = "qcom,pmi8998", .data = (void *)PMI8998_SUBTYPE }, + { .compatible = "qcom,pm8005", .data = (void *)PM8005_SUBTYPE }, { } }; -- cgit v1.2.3 From f3b23e5ab43c3bc7fcf6c8f0e9293ee510bf3095 Mon Sep 17 00:00:00 2001 From: Andy Shevchenko Date: Tue, 24 Apr 2018 18:05:12 +0300 Subject: mfd: intel-lpss: Correct names of RESETS register bits According to documentation the function has 2 bits for reset while iDMA 64-bit has only one. Rename it accordingly. Note, there is no functional change since we always handle them together. Signed-off-by: Andy Shevchenko Acked-by: Mika Westerberg Signed-off-by: Lee Jones --- drivers/mfd/intel-lpss.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/mfd/intel-lpss.c b/drivers/mfd/intel-lpss.c index 4bcf117a7ba8..50bffc3382d7 100644 --- a/drivers/mfd/intel-lpss.c +++ b/drivers/mfd/intel-lpss.c @@ -40,8 +40,8 @@ /* Offsets from lpss->priv */ #define LPSS_PRIV_RESETS 0x04 -#define LPSS_PRIV_RESETS_FUNC BIT(2) -#define LPSS_PRIV_RESETS_IDMA 0x3 +#define LPSS_PRIV_RESETS_IDMA BIT(2) +#define LPSS_PRIV_RESETS_FUNC 0x3 #define LPSS_PRIV_ACTIVELTR 0x10 #define LPSS_PRIV_IDLELTR 0x14 -- cgit v1.2.3 From 85415af34e35d86bfd1074bc3aa97dc2078f7571 Mon Sep 17 00:00:00 2001 From: Marek Vasut Date: Wed, 23 May 2018 14:21:40 +0200 Subject: dt-bindings: mfd: Add bindings for DA9063L Add device tree bindings for the Dialog DA9063L. This is a variant of the DA9063 chip with smaller package, with less LDO regulators and without RTC block. The other properties of the chip are the same, including the content of the chip ID register. Signed-off-by: Marek Vasut Reviewed-by: Geert Uytterhoeven Reviewed-by: Rob Herring Signed-off-by: Lee Jones --- Documentation/devicetree/bindings/mfd/da9063.txt | 32 +++++++++++++----------- 1 file changed, 17 insertions(+), 15 deletions(-) diff --git a/Documentation/devicetree/bindings/mfd/da9063.txt b/Documentation/devicetree/bindings/mfd/da9063.txt index 05b21bcb8543..443e68286957 100644 --- a/Documentation/devicetree/bindings/mfd/da9063.txt +++ b/Documentation/devicetree/bindings/mfd/da9063.txt @@ -1,4 +1,4 @@ -* Dialog DA9063 Power Management Integrated Circuit (PMIC) +* Dialog DA9063/DA9063L Power Management Integrated Circuit (PMIC) DA9093 consists of a large and varied group of sub-devices (I2C Only): @@ -6,14 +6,14 @@ Device Supply Names Description ------ ------------ ----------- da9063-regulator : : LDOs & BUCKs da9063-onkey : : On Key -da9063-rtc : : Real-Time Clock +da9063-rtc : : Real-Time Clock (DA9063 only) da9063-watchdog : : Watchdog ====== Required properties: -- compatible : Should be "dlg,da9063" +- compatible : Should be "dlg,da9063" or "dlg,da9063l" - reg : Specifies the I2C slave address (this defaults to 0x58 but it can be modified to match the chip's OTP settings). - interrupt-parent : Specifies the reference to the interrupt controller for @@ -23,8 +23,8 @@ Required properties: Sub-nodes: -- regulators : This node defines the settings for the LDOs and BUCKs. The - DA9063 regulators are bound using their names listed below: +- regulators : This node defines the settings for the LDOs and BUCKs. + The DA9063(L) regulators are bound using their names listed below: bcore1 : BUCK CORE1 bcore2 : BUCK CORE2 @@ -32,16 +32,16 @@ Sub-nodes: bmem : BUCK MEM bio : BUCK IO bperi : BUCK PERI - ldo1 : LDO_1 - ldo2 : LDO_2 + ldo1 : LDO_1 (DA9063 only) + ldo2 : LDO_2 (DA9063 only) ldo3 : LDO_3 - ldo4 : LDO_4 - ldo5 : LDO_5 - ldo6 : LDO_6 + ldo4 : LDO_4 (DA9063 only) + ldo5 : LDO_5 (DA9063 only) + ldo6 : LDO_6 (DA9063 only) ldo7 : LDO_7 ldo8 : LDO_8 ldo9 : LDO_9 - ldo10 : LDO_10 + ldo10 : LDO_10 (DA9063 only) ldo11 : LDO_11 The component follows the standard regulator framework and the bindings @@ -49,8 +49,9 @@ Sub-nodes: Documentation/devicetree/bindings/regulator/regulator.txt - rtc : This node defines settings for the Real-Time Clock associated with - the DA9063. There are currently no entries in this binding, however - compatible = "dlg,da9063-rtc" should be added if a node is created. + the DA9063 only. The RTC is not present in DA9063L. There are currently + no entries in this binding, however compatible = "dlg,da9063-rtc" should + be added if a node is created. - onkey : This node defines the OnKey settings for controlling the key functionality of the device. The node should contain the compatible property @@ -65,8 +66,9 @@ Sub-nodes: and KEY_SLEEP. - watchdog : This node defines settings for the Watchdog timer associated - with the DA9063. There are currently no entries in this binding, however - compatible = "dlg,da9063-watchdog" should be added if a node is created. + with the DA9063 and DA9063L. There are currently no entries in this + binding, however compatible = "dlg,da9063-watchdog" should be added + if a node is created. Example: -- cgit v1.2.3 From fced2963d84b44990f4aa99ed7268223c294c0df Mon Sep 17 00:00:00 2001 From: Charles Keepax Date: Wed, 9 May 2018 11:23:48 +0100 Subject: mfd: arizona: Update DT doc to support more standard Reset binding Signed-off-by: Charles Keepax Reviewed-by: Rob Herring Reviewed-by: Linus Walleij Signed-off-by: Lee Jones --- Documentation/devicetree/bindings/mfd/arizona.txt | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/Documentation/devicetree/bindings/mfd/arizona.txt b/Documentation/devicetree/bindings/mfd/arizona.txt index bdd017686ea5..a014afb07902 100644 --- a/Documentation/devicetree/bindings/mfd/arizona.txt +++ b/Documentation/devicetree/bindings/mfd/arizona.txt @@ -50,7 +50,7 @@ Required properties: Optional properties: - - wlf,reset : GPIO specifier for the GPIO controlling /RESET + - reset-gpios : GPIO specifier for the GPIO controlling /RESET - clocks: Should reference the clocks supplied on MCLK1 and MCLK2 - clock-names: Should contains two strings: @@ -70,6 +70,10 @@ Optional properties: Documentation/devicetree/bindings/regulator/regulator.txt (wm5102, wm5110, wm8280, wm8997, wm8998, wm1814) +Deprecated properties: + + - wlf,reset : GPIO specifier for the GPIO controlling /RESET + Also see child specific device properties: Regulator - ../regulator/arizona-regulator.txt Extcon - ../extcon/extcon-arizona.txt -- cgit v1.2.3 From a3b51be3cdac4844b2d8bb7c4dad95e191a05697 Mon Sep 17 00:00:00 2001 From: Fabrice Gasnier Date: Fri, 18 May 2018 17:24:04 +0200 Subject: pwm: stm32: Initialize raw local variables This removes build warning when COMPILE_TEST=y and MFD_STM32_TIMERS=n in drivers/pwm/pwm-stm32.c. In function 'stm32_pwm_capture' 'raw_prd' and 'raw_dty' may be used uninitialized in this function [-Wmaybe-uninitialized] Signed-off-by: Fabrice Gasnier Acked-by: Thierry Reding Tested-by: Randy Dunlap Signed-off-by: Lee Jones --- drivers/pwm/pwm-stm32.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/pwm/pwm-stm32.c b/drivers/pwm/pwm-stm32.c index 60bfc07c4912..09383c6720fb 100644 --- a/drivers/pwm/pwm-stm32.c +++ b/drivers/pwm/pwm-stm32.c @@ -170,7 +170,7 @@ static int stm32_pwm_capture(struct pwm_chip *chip, struct pwm_device *pwm, unsigned long long prd, div, dty; unsigned long rate; unsigned int psc = 0, icpsc, scale; - u32 raw_prd, raw_dty; + u32 raw_prd = 0, raw_dty = 0; int ret = 0; mutex_lock(&priv->lock); -- cgit v1.2.3 From d95c9760d9c8e046b09b54a3bb6dd0c9aa7a0eff Mon Sep 17 00:00:00 2001 From: Fabrice Gasnier Date: Fri, 18 May 2018 17:24:03 +0200 Subject: mfd: stm32-timers: Fix pwm-stm32 linker issue with COMPILE_TEST This is seen when COMPILE_TEST=y and MFD_STM32_TIMERS=n. drivers/pwm/pwm-stm32.o: In function 'stm32_pwm_raw_capture': pwm-stm32.c:... undefined reference to 'stm32_timers_dma_burst_read' Fixes: 0c6609805b63 ("mfd: stm32-timers: Add support for DMAs") Signed-off-by: Fabrice Gasnier Reported-by: Randy Dunlap Tested-by: Randy Dunlap Signed-off-by: Lee Jones --- include/linux/mfd/stm32-timers.h | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/include/linux/mfd/stm32-timers.h b/include/linux/mfd/stm32-timers.h index 9da1d7ece079..067d14655c28 100644 --- a/include/linux/mfd/stm32-timers.h +++ b/include/linux/mfd/stm32-timers.h @@ -124,8 +124,20 @@ struct stm32_timers { struct stm32_timers_dma dma; /* Only to be used by the parent */ }; +#if IS_REACHABLE(CONFIG_MFD_STM32_TIMERS) int stm32_timers_dma_burst_read(struct device *dev, u32 *buf, enum stm32_timers_dmas id, u32 reg, unsigned int num_reg, unsigned int bursts, unsigned long tmo_ms); +#else +static inline int stm32_timers_dma_burst_read(struct device *dev, u32 *buf, + enum stm32_timers_dmas id, + u32 reg, + unsigned int num_reg, + unsigned int bursts, + unsigned long tmo_ms) +{ + return -ENODEV; +} +#endif #endif -- cgit v1.2.3 From 4c74a1fc948b32df9c5a61eb2203d1e4d977a489 Mon Sep 17 00:00:00 2001 From: Yisheng Xie Date: Mon, 21 May 2018 19:57:39 +0800 Subject: mfd: omap-usb-host: Use match_string() helper match_string() returns the index of an array for a matching string, which can be used intead of open coded variant. Signed-off-by: Yisheng Xie Acked-by: Tony Lindgren Reviewed-by: Andy Shevchenko Signed-off-by: Lee Jones --- drivers/mfd/omap-usb-host.c | 24 ++---------------------- 1 file changed, 2 insertions(+), 22 deletions(-) diff --git a/drivers/mfd/omap-usb-host.c b/drivers/mfd/omap-usb-host.c index 7aab376ecb84..e11ab12fbdf2 100644 --- a/drivers/mfd/omap-usb-host.c +++ b/drivers/mfd/omap-usb-host.c @@ -153,27 +153,6 @@ static const char * const port_modes[] = { [OMAP_OHCI_PORT_MODE_TLL_2PIN_DPDM] = "ohci-tll-2pin-dpdm", }; -/** - * omap_usbhs_get_dt_port_mode - Get the 'enum usbhs_omap_port_mode' - * from the port mode string. - * @mode: The port mode string, usually obtained from device tree. - * - * The function returns the 'enum usbhs_omap_port_mode' that matches the - * provided port mode string as per the port_modes table. - * If no match is found it returns -ENODEV - */ -static int omap_usbhs_get_dt_port_mode(const char *mode) -{ - int i; - - for (i = 0; i < ARRAY_SIZE(port_modes); i++) { - if (!strcmp(mode, port_modes[i])) - return i; - } - - return -ENODEV; -} - static struct platform_device *omap_usbhs_alloc_child(const char *name, struct resource *res, int num_resources, void *pdata, size_t pdata_size, struct device *dev) @@ -529,7 +508,8 @@ static int usbhs_omap_get_dt_pdata(struct device *dev, if (ret < 0) continue; - ret = omap_usbhs_get_dt_port_mode(mode); + /* get 'enum usbhs_omap_port_mode' from port mode string */ + ret = match_string(port_modes, ARRAY_SIZE(port_modes), mode); if (ret < 0) { dev_warn(dev, "Invalid port%d-mode \"%s\" in device tree\n", i, mode); -- cgit v1.2.3 From 5588bd59b216f1c913a7a693d2b7fc351e963512 Mon Sep 17 00:00:00 2001 From: Colin Ian King Date: Sat, 26 May 2018 15:57:13 +0100 Subject: mfd: timberdale: Fix spelling mistake "Uknown" -> "Unknown" Trivial fix to spelling mistake in dev_err message text Signed-off-by: Colin Ian King Signed-off-by: Lee Jones --- drivers/mfd/timberdale.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/mfd/timberdale.c b/drivers/mfd/timberdale.c index cd4a6d7d6750..7c13d2e7061c 100644 --- a/drivers/mfd/timberdale.c +++ b/drivers/mfd/timberdale.c @@ -777,7 +777,7 @@ static int timb_probe(struct pci_dev *dev, &dev->resource[0], msix_entries[0].vector, NULL); break; default: - dev_err(&dev->dev, "Uknown IP setup: %d.%d.%d\n", + dev_err(&dev->dev, "Unknown IP setup: %d.%d.%d\n", priv->fw.major, priv->fw.minor, ip_setup); err = -ENODEV; goto err_mfd; -- cgit v1.2.3 From 4eb1d7fcbc80ec3fc2d628ad8ab7324d8837205e Mon Sep 17 00:00:00 2001 From: Robert Jarzmik Date: Sat, 26 May 2018 11:31:50 +0200 Subject: mfd: asic3: Fix broken MMC card detection The MMC framework requires the ocr_mask to be provided. Without it, the SD card is not detected, especially on the hx4700 platform. Signed-off-by: Robert Jarzmik Signed-off-by: Lee Jones --- drivers/mfd/asic3.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/drivers/mfd/asic3.c b/drivers/mfd/asic3.c index cf2e25ab2940..1531302a50ec 100644 --- a/drivers/mfd/asic3.c +++ b/drivers/mfd/asic3.c @@ -31,6 +31,8 @@ #include #include +#include + enum { ASIC3_CLOCK_SPI, ASIC3_CLOCK_OWM, @@ -719,6 +721,7 @@ static void asic3_mmc_clk_div(struct platform_device *pdev, int state) static struct tmio_mmc_data asic3_mmc_data = { .hclk = 24576000, + .ocr_mask = MMC_VDD_32_33 | MMC_VDD_33_34, .set_pwr = asic3_mmc_pwr, .set_clk_div = asic3_mmc_clk_div, }; -- cgit v1.2.3 From 4e93a658576ab115977225c9d0992b97ff19ba8c Mon Sep 17 00:00:00 2001 From: Jarkko Nikula Date: Fri, 18 May 2018 11:38:27 +0300 Subject: mfd: intel-lpss: Fix Intel Cannon Lake LPSS I2C input clock Intel Cannon Lake PCH has much higher 216 MHz input clock to LPSS I2C than Sunrisepoint which uses 120 MHz. Preliminary information was that both share the same clock rate but actual silicon implements elevated rate for better support for 3.4 MHz high-speed I2C. This incorrect input clock rate results too high I2C bus clock in case ACPI doesn't provide tuned I2C timing parameters since I2C host controller driver calculates them from input clock rate. Fix this by using the correct rate. We still share the same 230 ns SDA hold time value than Sunrisepoint. Cc: stable@vger.kernel.org Fixes: b418bbff36dd ("mfd: intel-lpss: Add Intel Cannonlake PCI IDs") Reported-by: Jian-Hong Pan Reported-by: Chris Chiu Reported-by: Daniel Drake Signed-off-by: Jarkko Nikula Reviewed-by: Andy Shevchenko Acked-by: Mika Westerberg Tested-by: Jian-Hong Pan Signed-off-by: Lee Jones --- drivers/mfd/intel-lpss-pci.c | 25 +++++++++++++++---------- 1 file changed, 15 insertions(+), 10 deletions(-) diff --git a/drivers/mfd/intel-lpss-pci.c b/drivers/mfd/intel-lpss-pci.c index d1c46de89eb4..d9ae983095c5 100644 --- a/drivers/mfd/intel-lpss-pci.c +++ b/drivers/mfd/intel-lpss-pci.c @@ -124,6 +124,11 @@ static const struct intel_lpss_platform_info apl_i2c_info = { .properties = apl_i2c_properties, }; +static const struct intel_lpss_platform_info cnl_i2c_info = { + .clk_rate = 216000000, + .properties = spt_i2c_properties, +}; + static const struct pci_device_id intel_lpss_pci_ids[] = { /* BXT A-Step */ { PCI_VDEVICE(INTEL, 0x0aac), (kernel_ulong_t)&bxt_i2c_info }, @@ -207,13 +212,13 @@ static const struct pci_device_id intel_lpss_pci_ids[] = { { PCI_VDEVICE(INTEL, 0x9daa), (kernel_ulong_t)&spt_info }, { PCI_VDEVICE(INTEL, 0x9dab), (kernel_ulong_t)&spt_info }, { PCI_VDEVICE(INTEL, 0x9dfb), (kernel_ulong_t)&spt_info }, - { PCI_VDEVICE(INTEL, 0x9dc5), (kernel_ulong_t)&spt_i2c_info }, - { PCI_VDEVICE(INTEL, 0x9dc6), (kernel_ulong_t)&spt_i2c_info }, + { PCI_VDEVICE(INTEL, 0x9dc5), (kernel_ulong_t)&cnl_i2c_info }, + { PCI_VDEVICE(INTEL, 0x9dc6), (kernel_ulong_t)&cnl_i2c_info }, { PCI_VDEVICE(INTEL, 0x9dc7), (kernel_ulong_t)&spt_uart_info }, - { PCI_VDEVICE(INTEL, 0x9de8), (kernel_ulong_t)&spt_i2c_info }, - { PCI_VDEVICE(INTEL, 0x9de9), (kernel_ulong_t)&spt_i2c_info }, - { PCI_VDEVICE(INTEL, 0x9dea), (kernel_ulong_t)&spt_i2c_info }, - { PCI_VDEVICE(INTEL, 0x9deb), (kernel_ulong_t)&spt_i2c_info }, + { PCI_VDEVICE(INTEL, 0x9de8), (kernel_ulong_t)&cnl_i2c_info }, + { PCI_VDEVICE(INTEL, 0x9de9), (kernel_ulong_t)&cnl_i2c_info }, + { PCI_VDEVICE(INTEL, 0x9dea), (kernel_ulong_t)&cnl_i2c_info }, + { PCI_VDEVICE(INTEL, 0x9deb), (kernel_ulong_t)&cnl_i2c_info }, /* SPT-H */ { PCI_VDEVICE(INTEL, 0xa127), (kernel_ulong_t)&spt_uart_info }, { PCI_VDEVICE(INTEL, 0xa128), (kernel_ulong_t)&spt_uart_info }, @@ -240,10 +245,10 @@ static const struct pci_device_id intel_lpss_pci_ids[] = { { PCI_VDEVICE(INTEL, 0xa32b), (kernel_ulong_t)&spt_info }, { PCI_VDEVICE(INTEL, 0xa37b), (kernel_ulong_t)&spt_info }, { PCI_VDEVICE(INTEL, 0xa347), (kernel_ulong_t)&spt_uart_info }, - { PCI_VDEVICE(INTEL, 0xa368), (kernel_ulong_t)&spt_i2c_info }, - { PCI_VDEVICE(INTEL, 0xa369), (kernel_ulong_t)&spt_i2c_info }, - { PCI_VDEVICE(INTEL, 0xa36a), (kernel_ulong_t)&spt_i2c_info }, - { PCI_VDEVICE(INTEL, 0xa36b), (kernel_ulong_t)&spt_i2c_info }, + { PCI_VDEVICE(INTEL, 0xa368), (kernel_ulong_t)&cnl_i2c_info }, + { PCI_VDEVICE(INTEL, 0xa369), (kernel_ulong_t)&cnl_i2c_info }, + { PCI_VDEVICE(INTEL, 0xa36a), (kernel_ulong_t)&cnl_i2c_info }, + { PCI_VDEVICE(INTEL, 0xa36b), (kernel_ulong_t)&cnl_i2c_info }, { } }; MODULE_DEVICE_TABLE(pci, intel_lpss_pci_ids); -- cgit v1.2.3 From 3aa2177e47878f7e7616da8a2050c44f22301b6e Mon Sep 17 00:00:00 2001 From: Gwendal Grignou Date: Wed, 30 May 2018 09:54:22 -0700 Subject: mfd: cros_ec: Use devm_kzalloc for private data Use dev_kzmalloc, remove .release entry point. Signed-off-by: Gwendal Grignou Signed-off-by: Lee Jones --- drivers/mfd/cros_ec_dev.c | 10 ++-------- 1 file changed, 2 insertions(+), 8 deletions(-) diff --git a/drivers/mfd/cros_ec_dev.c b/drivers/mfd/cros_ec_dev.c index 1d6dc5c7a19d..81466264f7fc 100644 --- a/drivers/mfd/cros_ec_dev.c +++ b/drivers/mfd/cros_ec_dev.c @@ -262,12 +262,7 @@ static const struct file_operations fops = { #endif }; -static void __remove(struct device *dev) -{ - struct cros_ec_dev *ec = container_of(dev, struct cros_ec_dev, - class_dev); - kfree(ec); -} +static void __remove(struct device *dev) { } static void cros_ec_sensors_register(struct cros_ec_dev *ec) { @@ -392,7 +387,7 @@ static int ec_device_probe(struct platform_device *pdev) int retval = -ENOMEM; struct device *dev = &pdev->dev; struct cros_ec_platform *ec_platform = dev_get_platdata(dev); - struct cros_ec_dev *ec = kzalloc(sizeof(*ec), GFP_KERNEL); + struct cros_ec_dev *ec = devm_kzalloc(dev, sizeof(*ec), GFP_KERNEL); if (!ec) return retval; @@ -414,7 +409,6 @@ static int ec_device_probe(struct platform_device *pdev) ec->class_dev.devt = MKDEV(ec_major, pdev->id); ec->class_dev.class = &cros_class; ec->class_dev.parent = dev; - ec->class_dev.release = __remove; retval = dev_set_name(&ec->class_dev, "%s", ec_platform->ec_name); if (retval) { -- cgit v1.2.3 From df7c3bf24f546ab0e5a23b282d34850f2b8eb0d2 Mon Sep 17 00:00:00 2001 From: Stephen Boyd Date: Wed, 30 May 2018 23:23:43 -0700 Subject: mfd: cros_ec_dev: Don't advertise junk features on failure If the feature query fails during this driver's probe, we memset the features bits to 0, but then we continue to overwrite that with whatever junk we read back when the feature probing failed. In the case of a SPI device, it may be complete junk, causing the caller of this function to think certain features are present when they aren't. Don't copy over the bad message on failure so we can fail more gracefully. Fixes: e4244ebddae2 ("platform/chrome: Introduce a new function to check EC features.") Signed-off-by: Stephen Boyd Acked-by: Benson Leung Signed-off-by: Lee Jones --- drivers/mfd/cros_ec_dev.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/mfd/cros_ec_dev.c b/drivers/mfd/cros_ec_dev.c index 81466264f7fc..dfc9f131aabe 100644 --- a/drivers/mfd/cros_ec_dev.c +++ b/drivers/mfd/cros_ec_dev.c @@ -113,10 +113,10 @@ static int cros_ec_check_features(struct cros_ec_dev *ec, int feature) dev_warn(ec->dev, "cannot get EC features: %d/%d\n", ret, msg->result); memset(ec->features, 0, sizeof(ec->features)); + } else { + memcpy(ec->features, msg->data, sizeof(ec->features)); } - memcpy(ec->features, msg->data, sizeof(ec->features)); - dev_dbg(ec->dev, "EC features %08x %08x\n", ec->features[0], ec->features[1]); -- cgit v1.2.3 From 46f107d0cb22b3f2b23d7fc7c50757f453a36508 Mon Sep 17 00:00:00 2001 From: Robert Jarzmik Date: Sun, 3 Jun 2018 22:16:17 +0200 Subject: mfd: wm97xx-core: Platform data can be NULL It is not mandatory that platform data is passed along the ac97 codec. Actually there are configuration without a battery connected to the ADC of the codec. This is for example the case for the PXA zylonite platform, so fix the NULL dereferencing by adding a test. Fixes: a5c6951c49fb ("mfd: wm97xx-core: core support for wm97xx Codec") Signed-off-by: Robert Jarzmik Signed-off-by: Lee Jones --- drivers/mfd/wm97xx-core.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/mfd/wm97xx-core.c b/drivers/mfd/wm97xx-core.c index 4141ee52a70b..f5a8347f837f 100644 --- a/drivers/mfd/wm97xx-core.c +++ b/drivers/mfd/wm97xx-core.c @@ -278,7 +278,7 @@ static int wm97xx_ac97_probe(struct ac97_codec_device *adev) codec_pdata = &wm97xx->codec_pdata; codec_pdata->ac97 = wm97xx->ac97; - codec_pdata->batt_pdata = pdata->batt_pdata; + codec_pdata->batt_pdata = pdata ? pdata->batt_pdata : NULL; switch (adev->vendor_id) { case WM9705_VENDOR_ID: -- cgit v1.2.3 From 556c242045f0c1613aac2e64dc5b2ff0e4bc89e1 Mon Sep 17 00:00:00 2001 From: Arnd Bergmann Date: Fri, 8 Jun 2018 16:48:06 +0200 Subject: mfd: cros_ec: Remove unused __remove function This function is no longer called, so we get a harmless warning until it is removed as well: drivers/mfd/cros_ec_dev.c:265:13: error: '__remove' defined but not used [-Werror=unused-function] Fixes: 3aa2177e4787 ("mfd: cros_ec: Use devm_kzalloc for private data") Signed-off-by: Arnd Bergmann Signed-off-by: Lee Jones --- drivers/mfd/cros_ec_dev.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/drivers/mfd/cros_ec_dev.c b/drivers/mfd/cros_ec_dev.c index dfc9f131aabe..4199cdd4ff89 100644 --- a/drivers/mfd/cros_ec_dev.c +++ b/drivers/mfd/cros_ec_dev.c @@ -262,8 +262,6 @@ static const struct file_operations fops = { #endif }; -static void __remove(struct device *dev) { } - static void cros_ec_sensors_register(struct cros_ec_dev *ec) { /* -- cgit v1.2.3