From patchwork Fri Jun 21 12:33:35 2013 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Tomasz Figa X-Patchwork-Id: 2762001 Return-Path: X-Original-To: patchwork-linux-arm@patchwork.kernel.org Delivered-To: patchwork-parsemail@patchwork2.web.kernel.org Received: from mail.kernel.org (mail.kernel.org [198.145.19.201]) by patchwork2.web.kernel.org (Postfix) with ESMTP id 6DDB3C0AB1 for ; Fri, 21 Jun 2013 12:36:45 +0000 (UTC) Received: from mail.kernel.org (localhost [127.0.0.1]) by mail.kernel.org (Postfix) with ESMTP id 071EF201E9 for ; Fri, 21 Jun 2013 12:36:44 +0000 (UTC) Received: from casper.infradead.org (casper.infradead.org [85.118.1.10]) (using TLSv1 with cipher DHE-RSA-AES256-SHA (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id E70C6201D2 for ; Fri, 21 Jun 2013 12:36:41 +0000 (UTC) Received: from merlin.infradead.org ([2001:4978:20e::2]) by casper.infradead.org with esmtps (Exim 4.80.1 #2 (Red Hat Linux)) id 1Uq0Yp-0001Ew-R2; Fri, 21 Jun 2013 12:35:29 +0000 Received: from localhost ([::1] helo=merlin.infradead.org) by merlin.infradead.org with esmtp (Exim 4.80.1 #2 (Red Hat Linux)) id 1Uq0YN-00012h-6h; Fri, 21 Jun 2013 12:34:59 +0000 Received: from mailout1.w1.samsung.com ([210.118.77.11]) by merlin.infradead.org with esmtp (Exim 4.80.1 #2 (Red Hat Linux)) id 1Uq0Xq-0000yh-FG for linux-arm-kernel@lists.infradead.org; Fri, 21 Jun 2013 12:34:28 +0000 Received: from eucpsbgm2.samsung.com (unknown [203.254.199.245]) by mailout1.w1.samsung.com (Oracle Communications Messaging Server 7u4-24.01(7.0.4.24.0) 64bit (built Nov 17 2011)) with ESMTP id <0MOQ002ZMTKIYU00@mailout1.w1.samsung.com> for linux-arm-kernel@lists.infradead.org; Fri, 21 Jun 2013 13:33:59 +0100 (BST) X-AuditID: cbfec7f5-b7f376d000001ec6-98-51c448364b2f Received: from eusync3.samsung.com ( [203.254.199.213]) by eucpsbgm2.samsung.com (EUCPMTA) with SMTP id E3.F3.07878.63844C15; Fri, 21 Jun 2013 13:33:58 +0100 (BST) Received: from amdc1227.digital.local ([106.116.147.199]) by eusync3.samsung.com (Oracle Communications Messaging Server 7u4-23.01(7.0.4.23.0) 64bit (built Aug 10 2011)) with ESMTPA id <0MOQ007XITKFX7A0@eusync3.samsung.com>; Fri, 21 Jun 2013 13:33:58 +0100 (BST) From: Tomasz Figa To: linux-kernel@vger.kernel.org Subject: [PATCH v2 1/3] mfd: Add irq domain support for max8998 interrupts Date: Fri, 21 Jun 2013 14:33:35 +0200 Message-id: <1371818017-5215-2-git-send-email-t.figa@samsung.com> X-Mailer: git-send-email 1.8.2.1 In-reply-to: <1371818017-5215-1-git-send-email-t.figa@samsung.com> References: <1371818017-5215-1-git-send-email-t.figa@samsung.com> X-Brightmail-Tracker: H4sIAAAAAAAAA+NgFjrLLMWRmVeSWpSXmKPExsVy+t/xq7pmHkcCDRa3GlgsuXiV3WLqwyds Fgf+7GC02D1nMYtF74KrbBZnm96wW3y70sFksenxNVaLy7vmsFnMOL+PyeL2ZV6LwysOMFms ezmdxWJ/ZwejxeluVotLM66zW6yf8ZrFQdCjpbmHzWPB5yvsHjtn3WX32DPxJJvHplWdbB6v Vs9k9bhzbQ+bx7yTgR6bl9R79G1ZxehxZsERdo/p834yeXzeJBfAG8Vlk5Kak1mWWqRvl8CV 8ePdIvaCl3YVS/bNY29gPGDcxcjJISFgItGyfBU7hC0mceHeerYuRi4OIYGljBINc64yQTh9 TBLrZv1hA6liE1CT+NzwCMwWEVCQ2Nz7jBWkiFngGovElis3wBLCAl4SczrmM4HYLAKqEmsX /mMFsXkFHCX+/XrNCLFOQeL49m1gNqeAk8SnBUvAzhACqtnzcB/LBEbeBYwMqxhFU0uTC4qT 0nON9IoTc4tL89L1kvNzNzFCouDrDsalx6wOMQpwMCrx8AYqHQ4UYk0sK67MPcQowcGsJMIb fAcoxJuSWFmVWpQfX1Sak1p8iJGJg1OqgTF9zQ5rjVqtZ5baSZMuB9+3TF4X6lzUXrLx0Bxm U6/o9G6hyBMfu5etN/izd46c1quSPo73pzQn2L3Nyf31JMtv18vNFo6/V9sve/9LKOaGb9SL 7PpXJuuPZ22ae+vZ1IvcXukHlLY0Bywre+j7t37NtITu56UTpqxSirrw7ZbztvRoje+Bh0OV WIozEg21mIuKEwHFuP9sYAIAAA== X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20130621_083426_642831_F49E4BD2 X-CRM114-Status: GOOD ( 21.83 ) X-Spam-Score: -8.4 (--------) Cc: Alessandro Zummo , Kukjin Kim , Russell King , Samuel Ortiz , rtc-linux@googlegroups.com, Jiri Kosina , Mark Brown , Liam Girdwood , Rob Herring , Masanari Iida , Kyungmin Park , linux-samsung-soc@vger.kernel.org, Rob Landley , Grant Likely , Tomasz Figa , linux-arm-kernel@lists.infradead.org X-BeenThere: linux-arm-kernel@lists.infradead.org X-Mailman-Version: 2.1.15 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , MIME-Version: 1.0 Sender: "linux-arm-kernel" Errors-To: linux-arm-kernel-bounces+patchwork-linux-arm=patchwork.kernel.org@lists.infradead.org X-Spam-Status: No, score=-5.7 required=5.0 tests=BAYES_00, RCVD_IN_DNSWL_MED, RP_MATCHES_RCVD, UNPARSEABLE_RELAY autolearn=unavailable version=3.3.1 X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on mail.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP This patch adds irq domain support for max8998 interrupts. The reverse mapping method used is linear mapping since the sub-drivers of max8998 such as regulator and charger drivers can use the max8998 irq_domain to get the virtual irq number for max8998 interrupts. All uses of irq_base in platform data and max8997 driver private data are removed. Signed-off-by: Tomasz Figa Signed-off-by: Kyungmin Park --- drivers/mfd/Kconfig | 1 + drivers/mfd/max8998-irq.c | 61 ++++++++++++++++++++++--------------- drivers/mfd/max8998.c | 1 - drivers/rtc/rtc-max8998.c | 12 +++++++- include/linux/mfd/max8998-private.h | 4 ++- include/linux/mfd/max8998.h | 2 -- 6 files changed, 51 insertions(+), 30 deletions(-) diff --git a/drivers/mfd/Kconfig b/drivers/mfd/Kconfig index d54e985..360be92 100644 --- a/drivers/mfd/Kconfig +++ b/drivers/mfd/Kconfig @@ -1002,6 +1002,7 @@ config MFD_TC6393XB config MFD_VX855 tristate "VIA VX855/VX875 integrated south bridge" depends on PCI && GENERIC_HARDIRQS + select IRQ_DOMAIN select MFD_CORE help Say yes here to enable support for various functions of the diff --git a/drivers/mfd/max8998-irq.c b/drivers/mfd/max8998-irq.c index 5919710..f770abf 100644 --- a/drivers/mfd/max8998-irq.c +++ b/drivers/mfd/max8998-irq.c @@ -14,6 +14,7 @@ #include #include #include +#include #include struct max8998_irq_data { @@ -99,7 +100,8 @@ static struct max8998_irq_data max8998_irqs[] = { static inline struct max8998_irq_data * irq_to_max8998_irq(struct max8998_dev *max8998, int irq) { - return &max8998_irqs[irq - max8998->irq_base]; + struct irq_data *data = irq_get_irq_data(irq); + return &max8998_irqs[data->hwirq]; } static void max8998_irq_lock(struct irq_data *data) @@ -176,8 +178,10 @@ static irqreturn_t max8998_irq_thread(int irq, void *data) /* Report */ for (i = 0; i < MAX8998_IRQ_NR; i++) { - if (irq_reg[max8998_irqs[i].reg - 1] & max8998_irqs[i].mask) - handle_nested_irq(max8998->irq_base + i); + if (irq_reg[max8998_irqs[i].reg - 1] & max8998_irqs[i].mask) { + irq = irq_linear_revmap(max8998->irq_domain, i); + handle_nested_irq(irq); + } } return IRQ_HANDLED; @@ -185,27 +189,40 @@ static irqreturn_t max8998_irq_thread(int irq, void *data) int max8998_irq_resume(struct max8998_dev *max8998) { - if (max8998->irq && max8998->irq_base) - max8998_irq_thread(max8998->irq_base, max8998); + if (max8998->irq && max8998->irq_domain) + max8998_irq_thread(0, max8998); + return 0; +} + +static int max8998_irq_domain_map(struct irq_domain *d, unsigned int irq, + irq_hw_number_t hw) +{ + struct max8997_dev *max8998 = d->host_data; + + irq_set_chip_data(irq, max8998); + irq_set_chip_and_handler(irq, &max8998_irq_chip, handle_edge_irq); + irq_set_nested_thread(irq, 1); +#ifdef CONFIG_ARM + set_irq_flags(irq, IRQF_VALID); +#else + irq_set_noprobe(irq); +#endif return 0; } +static struct irq_domain_ops max8998_irq_domain_ops = { + .map = max8998_irq_domain_map, +}; + int max8998_irq_init(struct max8998_dev *max8998) { int i; - int cur_irq; int ret; + struct irq_domain *domain; if (!max8998->irq) { dev_warn(max8998->dev, "No interrupt specified, no interrupts\n"); - max8998->irq_base = 0; - return 0; - } - - if (!max8998->irq_base) { - dev_err(max8998->dev, - "No interrupt base specified, no interrupts\n"); return 0; } @@ -221,19 +238,13 @@ int max8998_irq_init(struct max8998_dev *max8998) max8998_write_reg(max8998->i2c, MAX8998_REG_STATUSM1, 0xff); max8998_write_reg(max8998->i2c, MAX8998_REG_STATUSM2, 0xff); - /* register with genirq */ - for (i = 0; i < MAX8998_IRQ_NR; i++) { - cur_irq = i + max8998->irq_base; - irq_set_chip_data(cur_irq, max8998); - irq_set_chip_and_handler(cur_irq, &max8998_irq_chip, - handle_edge_irq); - irq_set_nested_thread(cur_irq, 1); -#ifdef CONFIG_ARM - set_irq_flags(cur_irq, IRQF_VALID); -#else - irq_set_noprobe(cur_irq); -#endif + domain = irq_domain_add_linear(NULL, MAX8998_IRQ_NR, + &max8998_irq_domain_ops, max8998); + if (!domain) { + dev_err(max8998->dev, "could not create irq domain\n"); + return -ENODEV; } + max8998->irq_domain = domain; ret = request_threaded_irq(max8998->irq, NULL, max8998_irq_thread, IRQF_TRIGGER_FALLING | IRQF_ONESHOT, diff --git a/drivers/mfd/max8998.c b/drivers/mfd/max8998.c index d7218cc..e9bd352 100644 --- a/drivers/mfd/max8998.c +++ b/drivers/mfd/max8998.c @@ -146,7 +146,6 @@ static int max8998_i2c_probe(struct i2c_client *i2c, max8998->type = id->driver_data; if (pdata) { max8998->ono = pdata->ono; - max8998->irq_base = pdata->irq_base; max8998->wakeup = pdata->wakeup; } mutex_init(&max8998->iolock); diff --git a/drivers/rtc/rtc-max8998.c b/drivers/rtc/rtc-max8998.c index d5af7ba..46f2301 100644 --- a/drivers/rtc/rtc-max8998.c +++ b/drivers/rtc/rtc-max8998.c @@ -16,6 +16,7 @@ #include #include #include +#include #include #include #include @@ -264,7 +265,6 @@ static int max8998_rtc_probe(struct platform_device *pdev) info->dev = &pdev->dev; info->max8998 = max8998; info->rtc = max8998->rtc; - info->irq = max8998->irq_base + MAX8998_IRQ_ALARM0; platform_set_drvdata(pdev, info); @@ -277,6 +277,15 @@ static int max8998_rtc_probe(struct platform_device *pdev) goto out_rtc; } + if (!max8998->irq_domain) + goto no_irq; + + info->irq = irq_create_mapping(max8998->irq_domain, MAX8998_IRQ_ALARM0); + if (!info->irq) { + dev_warn(&pdev->dev, "Failed to map alarm IRQ\n"); + goto no_irq; + } + ret = devm_request_threaded_irq(&pdev->dev, info->irq, NULL, max8998_rtc_alarm_irq, 0, "rtc-alarm0", info); @@ -284,6 +293,7 @@ static int max8998_rtc_probe(struct platform_device *pdev) dev_err(&pdev->dev, "Failed to request alarm IRQ: %d: %d\n", info->irq, ret); +no_irq: dev_info(&pdev->dev, "RTC CHIP NAME: %s\n", pdev->id_entry->name); if (pdata && pdata->rtc_delay) { info->lp3974_bug_workaround = true; diff --git a/include/linux/mfd/max8998-private.h b/include/linux/mfd/max8998-private.h index effa5d3..e81077a 100644 --- a/include/linux/mfd/max8998-private.h +++ b/include/linux/mfd/max8998-private.h @@ -132,6 +132,8 @@ enum { #define MAX8998_ENRAMP (1 << 4) +struct irq_domain; + /** * struct max8998_dev - max8998 master device for sub-drivers * @dev: master device of the chip (can be used to access platform data) @@ -153,7 +155,7 @@ struct max8998_dev { struct mutex iolock; struct mutex irqlock; - int irq_base; + struct irq_domain *irq_domain; int irq; int ono; u8 irq_masks_cur[MAX8998_NUM_IRQ_REGS]; diff --git a/include/linux/mfd/max8998.h b/include/linux/mfd/max8998.h index 6823548..9df60ba 100644 --- a/include/linux/mfd/max8998.h +++ b/include/linux/mfd/max8998.h @@ -68,7 +68,6 @@ struct max8998_regulator_data { * struct max8998_board - packages regulator init data * @regulators: array of defined regulators * @num_regulators: number of regulators used - * @irq_base: base IRQ number for max8998, required for IRQs * @ono: power onoff IRQ number for max8998 * @buck_voltage_lock: Do NOT change the values of the following six * registers set by buck?_voltage?. The voltage of BUCK1/2 cannot @@ -100,7 +99,6 @@ struct max8998_regulator_data { struct max8998_platform_data { struct max8998_regulator_data *regulators; int num_regulators; - int irq_base; int ono; bool buck_voltage_lock; int buck1_voltage1;