From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-9.8 required=3.0 tests=HEADER_FROM_DIFFERENT_DOMAINS, INCLUDES_PATCH,MAILING_LIST_MULTI,SIGNED_OFF_BY,SPF_HELO_NONE,SPF_PASS, UNPARSEABLE_RELAY,USER_AGENT_GIT autolearn=unavailable autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 6BFC4C3A5A2 for ; Fri, 23 Aug 2019 03:46:21 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id 38B7C23407 for ; Fri, 23 Aug 2019 03:46:21 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S2388786AbfHWDpw (ORCPT ); Thu, 22 Aug 2019 23:45:52 -0400 Received: from mailgw01.mediatek.com ([210.61.82.183]:47706 "EHLO mailgw01.mediatek.com" rhost-flags-OK-FAIL-OK-FAIL) by vger.kernel.org with ESMTP id S2389640AbfHWDpw (ORCPT ); Thu, 22 Aug 2019 23:45:52 -0400 X-UUID: 53d75f8f2a234655927ad3982a2226c4-20190823 X-UUID: 53d75f8f2a234655927ad3982a2226c4-20190823 Received: from mtkexhb02.mediatek.inc [(172.21.101.103)] by mailgw01.mediatek.com (envelope-from ) (Cellopoint E-mail Firewall v4.1.10 Build 0707 with TLS) with ESMTP id 495887021; Fri, 23 Aug 2019 11:45:41 +0800 Received: from MTKCAS06.mediatek.inc (172.21.101.30) by mtkmbs01n1.mediatek.inc (172.21.101.68) with Microsoft SMTP Server (TLS) id 15.0.1395.4; Fri, 23 Aug 2019 11:45:34 +0800 Received: from mtksdccf07.mediatek.inc (172.21.84.99) by MTKCAS06.mediatek.inc (172.21.101.73) with Microsoft SMTP Server id 15.0.1395.4 via Frontend Transport; Fri, 23 Aug 2019 11:45:34 +0800 From: Hsin-Hsiung Wang To: Lee Jones , Rob Herring , Mark Brown , Matthias Brugger , Alexandre Belloni CC: Mark Rutland , Liam Girdwood , Eddie Huang , Sean Wang , Alessandro Zummo , Hsin-Hsiung Wang , Kate Stewart , Greg Kroah-Hartman , Thomas Gleixner , Richard Fontana , , , , , , Subject: [PATCH v5 02/10] mfd: mt6397: extract irq related code from core driver Date: Fri, 23 Aug 2019 11:45:23 +0800 Message-ID: <1566531931-9772-3-git-send-email-hsin-hsiung.wang@mediatek.com> X-Mailer: git-send-email 1.9.1 In-Reply-To: <1566531931-9772-1-git-send-email-hsin-hsiung.wang@mediatek.com> References: <1566531931-9772-1-git-send-email-hsin-hsiung.wang@mediatek.com> MIME-Version: 1.0 Content-Type: text/plain X-MTK: N Sender: linux-rtc-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-rtc@vger.kernel.org In order to support different types of irq design, we decide to add separate irq drivers for different design and keep mt6397 mfd core simple and reusable to all generations of PMICs so far. Acked-for-mfd-by: Lee Jones Signed-off-by: Hsin-Hsiung Wang --- drivers/mfd/Makefile | 3 +- drivers/mfd/mt6397-core.c | 146 -------------------------------- drivers/mfd/mt6397-irq.c | 181 ++++++++++++++++++++++++++++++++++++++++ include/linux/mfd/mt6397/core.h | 9 ++ 4 files changed, 192 insertions(+), 147 deletions(-) create mode 100644 drivers/mfd/mt6397-irq.c diff --git a/drivers/mfd/Makefile b/drivers/mfd/Makefile index f026ada..9a96325 100644 --- a/drivers/mfd/Makefile +++ b/drivers/mfd/Makefile @@ -241,7 +241,8 @@ obj-$(CONFIG_INTEL_SOC_PMIC) += intel-soc-pmic.o obj-$(CONFIG_INTEL_SOC_PMIC_BXTWC) += intel_soc_pmic_bxtwc.o obj-$(CONFIG_INTEL_SOC_PMIC_CHTWC) += intel_soc_pmic_chtwc.o obj-$(CONFIG_INTEL_SOC_PMIC_CHTDC_TI) += intel_soc_pmic_chtdc_ti.o -obj-$(CONFIG_MFD_MT6397) += mt6397-core.o +mt6397-objs := mt6397-core.o mt6397-irq.o +obj-$(CONFIG_MFD_MT6397) += mt6397.o obj-$(CONFIG_MFD_ALTERA_A10SR) += altera-a10sr.o obj-$(CONFIG_MFD_ALTERA_SYSMGR) += altera-sysmgr.o diff --git a/drivers/mfd/mt6397-core.c b/drivers/mfd/mt6397-core.c index c070862..93c8881 100644 --- a/drivers/mfd/mt6397-core.c +++ b/drivers/mfd/mt6397-core.c @@ -18,10 +18,6 @@ #define MT6397_RTC_BASE 0xe000 #define MT6397_RTC_SIZE 0x3e -#define MT6323_CHIP_ID 0x23 -#define MT6391_CHIP_ID 0x91 -#define MT6397_CHIP_ID 0x97 - static const struct resource mt6397_rtc_resources[] = { { .start = MT6397_RTC_BASE, @@ -86,148 +82,6 @@ } }; -static void mt6397_irq_lock(struct irq_data *data) -{ - struct mt6397_chip *mt6397 = irq_data_get_irq_chip_data(data); - - mutex_lock(&mt6397->irqlock); -} - -static void mt6397_irq_sync_unlock(struct irq_data *data) -{ - struct mt6397_chip *mt6397 = irq_data_get_irq_chip_data(data); - - regmap_write(mt6397->regmap, mt6397->int_con[0], - mt6397->irq_masks_cur[0]); - regmap_write(mt6397->regmap, mt6397->int_con[1], - mt6397->irq_masks_cur[1]); - - mutex_unlock(&mt6397->irqlock); -} - -static void mt6397_irq_disable(struct irq_data *data) -{ - struct mt6397_chip *mt6397 = irq_data_get_irq_chip_data(data); - int shift = data->hwirq & 0xf; - int reg = data->hwirq >> 4; - - mt6397->irq_masks_cur[reg] &= ~BIT(shift); -} - -static void mt6397_irq_enable(struct irq_data *data) -{ - struct mt6397_chip *mt6397 = irq_data_get_irq_chip_data(data); - int shift = data->hwirq & 0xf; - int reg = data->hwirq >> 4; - - mt6397->irq_masks_cur[reg] |= BIT(shift); -} - -#ifdef CONFIG_PM_SLEEP -static int mt6397_irq_set_wake(struct irq_data *irq_data, unsigned int on) -{ - struct mt6397_chip *mt6397 = irq_data_get_irq_chip_data(irq_data); - int shift = irq_data->hwirq & 0xf; - int reg = irq_data->hwirq >> 4; - - if (on) - mt6397->wake_mask[reg] |= BIT(shift); - else - mt6397->wake_mask[reg] &= ~BIT(shift); - - return 0; -} -#else -#define mt6397_irq_set_wake NULL -#endif - -static struct irq_chip mt6397_irq_chip = { - .name = "mt6397-irq", - .irq_bus_lock = mt6397_irq_lock, - .irq_bus_sync_unlock = mt6397_irq_sync_unlock, - .irq_enable = mt6397_irq_enable, - .irq_disable = mt6397_irq_disable, - .irq_set_wake = mt6397_irq_set_wake, -}; - -static void mt6397_irq_handle_reg(struct mt6397_chip *mt6397, int reg, - int irqbase) -{ - unsigned int status; - int i, irq, ret; - - ret = regmap_read(mt6397->regmap, reg, &status); - if (ret) { - dev_err(mt6397->dev, "Failed to read irq status: %d\n", ret); - return; - } - - for (i = 0; i < 16; i++) { - if (status & BIT(i)) { - irq = irq_find_mapping(mt6397->irq_domain, irqbase + i); - if (irq) - handle_nested_irq(irq); - } - } - - regmap_write(mt6397->regmap, reg, status); -} - -static irqreturn_t mt6397_irq_thread(int irq, void *data) -{ - struct mt6397_chip *mt6397 = data; - - mt6397_irq_handle_reg(mt6397, mt6397->int_status[0], 0); - mt6397_irq_handle_reg(mt6397, mt6397->int_status[1], 16); - - return IRQ_HANDLED; -} - -static int mt6397_irq_domain_map(struct irq_domain *d, unsigned int irq, - irq_hw_number_t hw) -{ - struct mt6397_chip *mt6397 = d->host_data; - - irq_set_chip_data(irq, mt6397); - irq_set_chip_and_handler(irq, &mt6397_irq_chip, handle_level_irq); - irq_set_nested_thread(irq, 1); - irq_set_noprobe(irq); - - return 0; -} - -static const struct irq_domain_ops mt6397_irq_domain_ops = { - .map = mt6397_irq_domain_map, -}; - -static int mt6397_irq_init(struct mt6397_chip *mt6397) -{ - int ret; - - mutex_init(&mt6397->irqlock); - - /* Mask all interrupt sources */ - regmap_write(mt6397->regmap, mt6397->int_con[0], 0x0); - regmap_write(mt6397->regmap, mt6397->int_con[1], 0x0); - - mt6397->irq_domain = irq_domain_add_linear(mt6397->dev->of_node, - MT6397_IRQ_NR, &mt6397_irq_domain_ops, mt6397); - if (!mt6397->irq_domain) { - dev_err(mt6397->dev, "could not create irq domain\n"); - return -ENOMEM; - } - - ret = devm_request_threaded_irq(mt6397->dev, mt6397->irq, NULL, - mt6397_irq_thread, IRQF_ONESHOT, "mt6397-pmic", mt6397); - if (ret) { - dev_err(mt6397->dev, "failed to register irq=%d; err: %d\n", - mt6397->irq, ret); - return ret; - } - - return 0; -} - #ifdef CONFIG_PM_SLEEP static int mt6397_irq_suspend(struct device *dev) { diff --git a/drivers/mfd/mt6397-irq.c b/drivers/mfd/mt6397-irq.c new file mode 100644 index 0000000..b2d3ce1 --- /dev/null +++ b/drivers/mfd/mt6397-irq.c @@ -0,0 +1,181 @@ +// SPDX-License-Identifier: GPL-2.0 +// +// Copyright (c) 2019 MediaTek Inc. + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +static void mt6397_irq_lock(struct irq_data *data) +{ + struct mt6397_chip *mt6397 = irq_data_get_irq_chip_data(data); + + mutex_lock(&mt6397->irqlock); +} + +static void mt6397_irq_sync_unlock(struct irq_data *data) +{ + struct mt6397_chip *mt6397 = irq_data_get_irq_chip_data(data); + + regmap_write(mt6397->regmap, mt6397->int_con[0], + mt6397->irq_masks_cur[0]); + regmap_write(mt6397->regmap, mt6397->int_con[1], + mt6397->irq_masks_cur[1]); + + mutex_unlock(&mt6397->irqlock); +} + +static void mt6397_irq_disable(struct irq_data *data) +{ + struct mt6397_chip *mt6397 = irq_data_get_irq_chip_data(data); + int shift = data->hwirq & 0xf; + int reg = data->hwirq >> 4; + + mt6397->irq_masks_cur[reg] &= ~BIT(shift); +} + +static void mt6397_irq_enable(struct irq_data *data) +{ + struct mt6397_chip *mt6397 = irq_data_get_irq_chip_data(data); + int shift = data->hwirq & 0xf; + int reg = data->hwirq >> 4; + + mt6397->irq_masks_cur[reg] |= BIT(shift); +} + +#ifdef CONFIG_PM_SLEEP +static int mt6397_irq_set_wake(struct irq_data *irq_data, unsigned int on) +{ + struct mt6397_chip *mt6397 = irq_data_get_irq_chip_data(irq_data); + int shift = irq_data->hwirq & 0xf; + int reg = irq_data->hwirq >> 4; + + if (on) + mt6397->wake_mask[reg] |= BIT(shift); + else + mt6397->wake_mask[reg] &= ~BIT(shift); + + return 0; +} +#else +#define mt6397_irq_set_wake NULL +#endif + +static struct irq_chip mt6397_irq_chip = { + .name = "mt6397-irq", + .irq_bus_lock = mt6397_irq_lock, + .irq_bus_sync_unlock = mt6397_irq_sync_unlock, + .irq_enable = mt6397_irq_enable, + .irq_disable = mt6397_irq_disable, + .irq_set_wake = mt6397_irq_set_wake, +}; + +static void mt6397_irq_handle_reg(struct mt6397_chip *mt6397, int reg, + int irqbase) +{ + unsigned int status; + int i, irq, ret; + + ret = regmap_read(mt6397->regmap, reg, &status); + if (ret) { + dev_err(mt6397->dev, "Failed to read irq status: %d\n", ret); + return; + } + + for (i = 0; i < 16; i++) { + if (status & BIT(i)) { + irq = irq_find_mapping(mt6397->irq_domain, irqbase + i); + if (irq) + handle_nested_irq(irq); + } + } + + regmap_write(mt6397->regmap, reg, status); +} + +static irqreturn_t mt6397_irq_thread(int irq, void *data) +{ + struct mt6397_chip *mt6397 = data; + + mt6397_irq_handle_reg(mt6397, mt6397->int_status[0], 0); + mt6397_irq_handle_reg(mt6397, mt6397->int_status[1], 16); + + return IRQ_HANDLED; +} + +static int mt6397_irq_domain_map(struct irq_domain *d, unsigned int irq, + irq_hw_number_t hw) +{ + struct mt6397_chip *mt6397 = d->host_data; + + irq_set_chip_data(irq, mt6397); + irq_set_chip_and_handler(irq, &mt6397_irq_chip, handle_level_irq); + irq_set_nested_thread(irq, 1); + irq_set_noprobe(irq); + + return 0; +} + +static const struct irq_domain_ops mt6397_irq_domain_ops = { + .map = mt6397_irq_domain_map, +}; + +int mt6397_irq_init(struct mt6397_chip *chip) +{ + int ret; + + mutex_init(&chip->irqlock); + + switch (chip->chip_id) { + case MT6323_CHIP_ID: + chip->int_con[0] = MT6323_INT_CON0; + chip->int_con[1] = MT6323_INT_CON1; + chip->int_status[0] = MT6323_INT_STATUS0; + chip->int_status[1] = MT6323_INT_STATUS1; + break; + + case MT6391_CHIP_ID: + case MT6397_CHIP_ID: + chip->int_con[0] = MT6397_INT_CON0; + chip->int_con[1] = MT6397_INT_CON1; + chip->int_status[0] = MT6397_INT_STATUS0; + chip->int_status[1] = MT6397_INT_STATUS1; + break; + + default: + dev_err(chip->dev, "unsupported chip: 0x%x\n", chip->chip_id); + return -ENODEV; + } + + /* Mask all interrupt sources */ + regmap_write(chip->regmap, chip->int_con[0], 0x0); + regmap_write(chip->regmap, chip->int_con[1], 0x0); + + chip->irq_domain = irq_domain_add_linear(chip->dev->of_node, + MT6397_IRQ_NR, + &mt6397_irq_domain_ops, + chip); + if (!chip->irq_domain) { + dev_err(chip->dev, "could not create irq domain\n"); + return -ENOMEM; + } + + ret = devm_request_threaded_irq(chip->dev, chip->irq, NULL, + mt6397_irq_thread, IRQF_ONESHOT, + "mt6397-pmic", chip); + if (ret) { + dev_err(chip->dev, "failed to register irq=%d; err: %d\n", + chip->irq, ret); + return ret; + } + + return 0; +} diff --git a/include/linux/mfd/mt6397/core.h b/include/linux/mfd/mt6397/core.h index 25a95e7..9320c2a 100644 --- a/include/linux/mfd/mt6397/core.h +++ b/include/linux/mfd/mt6397/core.h @@ -7,6 +7,12 @@ #ifndef __MFD_MT6397_CORE_H__ #define __MFD_MT6397_CORE_H__ +enum chip_id { + MT6323_CHIP_ID = 0x23, + MT6391_CHIP_ID = 0x91, + MT6397_CHIP_ID = 0x97, +}; + enum mt6397_irq_numbers { MT6397_IRQ_SPKL_AB = 0, MT6397_IRQ_SPKR_AB, @@ -54,6 +60,9 @@ struct mt6397_chip { u16 irq_masks_cache[2]; u16 int_con[2]; u16 int_status[2]; + u16 chip_id; }; +int mt6397_irq_init(struct mt6397_chip *chip); + #endif /* __MFD_MT6397_CORE_H__ */ -- 1.9.1