From patchwork Thu Jul 25 13:15:50 2013 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Grygorii Strashko X-Patchwork-Id: 2833408 Return-Path: X-Original-To: patchwork-linux-omap@patchwork.kernel.org Delivered-To: patchwork-parsemail@patchwork1.web.kernel.org Received: from mail.kernel.org (mail.kernel.org [198.145.19.201]) by patchwork1.web.kernel.org (Postfix) with ESMTP id 166F19F243 for ; Thu, 25 Jul 2013 13:18:56 +0000 (UTC) Received: from mail.kernel.org (localhost [127.0.0.1]) by mail.kernel.org (Postfix) with ESMTP id 3E86320214 for ; Thu, 25 Jul 2013 13:18:51 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id B3EE920203 for ; Thu, 25 Jul 2013 13:18:49 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1756020Ab3GYNRw (ORCPT ); Thu, 25 Jul 2013 09:17:52 -0400 Received: from arroyo.ext.ti.com ([192.94.94.40]:51298 "EHLO arroyo.ext.ti.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1755964Ab3GYNRu (ORCPT ); Thu, 25 Jul 2013 09:17:50 -0400 Received: from dlelxv90.itg.ti.com ([172.17.2.17]) by arroyo.ext.ti.com (8.13.7/8.13.7) with ESMTP id r6PDHcMY010364; Thu, 25 Jul 2013 08:17:38 -0500 Received: from DFLE73.ent.ti.com (dfle73.ent.ti.com [128.247.5.110]) by dlelxv90.itg.ti.com (8.14.3/8.13.8) with ESMTP id r6PDHcq8024654; Thu, 25 Jul 2013 08:17:38 -0500 Received: from dlelxv22.itg.ti.com (172.17.1.197) by DFLE73.ent.ti.com (128.247.5.110) with Microsoft SMTP Server id 14.2.342.3; Thu, 25 Jul 2013 08:17:38 -0500 Received: from localhost (uglx0174654.ucm2.emeaucm.ext.ti.com [10.167.145.172]) by dlelxv22.itg.ti.com (8.13.8/8.13.8) with ESMTP id r6PDHbme022396; Thu, 25 Jul 2013 08:17:38 -0500 From: Grygorii Strashko To: Samuel Ortiz , Lee Jones CC: Kevin Hilman , Graeme Gregory , , Ruslan Bilovol , , Grygorii Strashko Subject: [PATCH v2 4/5] mfd: twl6030-irq: create struct twl6030_irq Date: Thu, 25 Jul 2013 16:15:50 +0300 Message-ID: <1374758151-12097-5-git-send-email-grygorii.strashko@ti.com> X-Mailer: git-send-email 1.7.9.5 In-Reply-To: <1374758151-12097-1-git-send-email-grygorii.strashko@ti.com> References: <1374758151-12097-1-git-send-email-grygorii.strashko@ti.com> MIME-Version: 1.0 Sender: linux-omap-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-omap@vger.kernel.org X-Spam-Status: No, score=-6.9 required=5.0 tests=BAYES_00, RCVD_IN_DNSWL_HI, 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 Create "struct twl6030_irq" and place all local variables inside it. Also allocate twl6030_irq structure dynamically during initialization. Signed-off-by: Grygorii Strashko --- drivers/mfd/twl6030-irq.c | 101 ++++++++++++++++++++++++++------------------- 1 file changed, 59 insertions(+), 42 deletions(-) diff --git a/drivers/mfd/twl6030-irq.c b/drivers/mfd/twl6030-irq.c index 1b03ce9..e3c54f8 100644 --- a/drivers/mfd/twl6030-irq.c +++ b/drivers/mfd/twl6030-irq.c @@ -86,36 +86,44 @@ static int twl6030_interrupt_mapping[24] = { }; /*----------------------------------------------------------------------*/ -static int twl_irq; -static bool twl_irq_wake_enabled; +struct twl6030_irq { + unsigned int irq_base; + int twl_irq; + bool irq_wake_enabled; + atomic_t wakeirqs; + struct notifier_block pm_nb; + struct irq_chip irq_chip; + struct irq_domain *irq_domain; +}; -static atomic_t twl6030_wakeirqs = ATOMIC_INIT(0); -struct irq_domain *irq_domain; +static struct twl6030_irq *twl6030_irq; static int twl6030_irq_pm_notifier(struct notifier_block *notifier, unsigned long pm_event, void *unused) { int chained_wakeups; + struct twl6030_irq *pdata = container_of(notifier, struct twl6030_irq, + pm_nb); switch (pm_event) { case PM_SUSPEND_PREPARE: - chained_wakeups = atomic_read(&twl6030_wakeirqs); + chained_wakeups = atomic_read(&pdata->wakeirqs); - if (chained_wakeups && !twl_irq_wake_enabled) { - if (enable_irq_wake(twl_irq)) + if (chained_wakeups && !pdata->irq_wake_enabled) { + if (enable_irq_wake(pdata->twl_irq)) pr_err("twl6030 IRQ wake enable failed\n"); else - twl_irq_wake_enabled = true; - } else if (!chained_wakeups && twl_irq_wake_enabled) { - disable_irq_wake(twl_irq); - twl_irq_wake_enabled = false; + pdata->irq_wake_enabled = true; + } else if (!chained_wakeups && pdata->irq_wake_enabled) { + disable_irq_wake(pdata->twl_irq); + pdata->irq_wake_enabled = false; } - disable_irq(twl_irq); + disable_irq(pdata->twl_irq); break; case PM_POST_SUSPEND: - enable_irq(twl_irq); + enable_irq(pdata->twl_irq); break; default: @@ -125,10 +133,6 @@ static int twl6030_irq_pm_notifier(struct notifier_block *notifier, return NOTIFY_DONE; } -static struct notifier_block twl6030_irq_pm_notifier_block = { - .notifier_call = twl6030_irq_pm_notifier, -}; - /* * Threaded irq handler for the twl6030 interrupt. * We query the interrupt controller in the twl6030 to determine @@ -138,11 +142,11 @@ static struct notifier_block twl6030_irq_pm_notifier_block = { static irqreturn_t twl6030_irq_thread(int irq, void *data) { int i, ret; - struct irq_domain *irq_domain = (struct irq_domain *)data; union { u8 bytes[4]; u32 int_sts; } sts; + struct twl6030_irq *pdata = data; /* read INT_STS_A, B and C in one shot using a burst read */ ret = twl_i2c_read(TWL_MODULE_PIH, sts.bytes, REG_INT_STS_A, 3); @@ -163,7 +167,7 @@ static irqreturn_t twl6030_irq_thread(int irq, void *data) for (i = 0; sts.int_sts; sts.int_sts >>= 1, i++) if (sts.int_sts & 0x1) { int module_irq = - irq_find_mapping(irq_domain, + irq_find_mapping(pdata->irq_domain, twl6030_interrupt_mapping[i]); if (module_irq) handle_nested_irq(module_irq); @@ -194,10 +198,12 @@ static irqreturn_t twl6030_irq_thread(int irq, void *data) static int twl6030_irq_set_wake(struct irq_data *d, unsigned int on) { + struct twl6030_irq *pdata = irq_get_chip_data(d->irq); + if (on) - atomic_inc(&twl6030_wakeirqs); + atomic_inc(&pdata->wakeirqs); else - atomic_dec(&twl6030_wakeirqs); + atomic_dec(&pdata->wakeirqs); return 0; } @@ -272,7 +278,8 @@ int twl6030_mmc_card_detect_config(void) return ret; } - return irq_find_mapping(irq_domain, MMCDETECT_INTR_OFFSET); + return irq_find_mapping(twl6030_irq->irq_domain, + MMCDETECT_INTR_OFFSET); } EXPORT_SYMBOL(twl6030_mmc_card_detect_config); @@ -301,15 +308,15 @@ int twl6030_mmc_card_detect(struct device *dev, int slot) } EXPORT_SYMBOL(twl6030_mmc_card_detect); -static struct irq_chip twl6030_irq_chip; - static int twl6030_irq_map(struct irq_domain *d, unsigned int virq, irq_hw_number_t hwirq) { - irq_set_chip_data(virq, &twl6030_irq_chip); - irq_set_chip_and_handler(virq, &twl6030_irq_chip, handle_simple_irq); + struct twl6030_irq *pdata = d->host_data; + + irq_set_chip_data(virq, pdata); + irq_set_chip_and_handler(virq, &pdata->irq_chip, handle_simple_irq); irq_set_nested_thread(virq, true); - irq_set_parent(virq, twl_irq); + irq_set_parent(virq, pdata->twl_irq); #ifdef CONFIG_ARM /* @@ -349,6 +356,12 @@ 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"); + return -ENOMEM; + } + mask[0] = 0xFF; mask[1] = 0xFF; mask[2] = 0xFF; @@ -369,14 +382,18 @@ int twl6030_init_irq(struct device *dev, int irq_num) * install an irq handler for each of the modules; * clone dummy irq_chip since PIH can't *do* anything */ - twl6030_irq_chip = dummy_irq_chip; - twl6030_irq_chip.name = "twl6030"; - twl6030_irq_chip.irq_set_type = NULL; - twl6030_irq_chip.irq_set_wake = twl6030_irq_set_wake; - - irq_domain = irq_domain_add_linear(node, nr_irqs, - &twl6030_irq_domain_ops, NULL); - if (!irq_domain) { + twl6030_irq->irq_chip = dummy_irq_chip; + twl6030_irq->irq_chip.name = "twl6030"; + twl6030_irq->irq_chip.irq_set_type = NULL; + twl6030_irq->irq_chip.irq_set_wake = twl6030_irq_set_wake; + + twl6030_irq->pm_nb.notifier_call = twl6030_irq_pm_notifier; + atomic_set(&twl6030_irq->wakeirqs, 0); + + twl6030_irq->irq_domain = + irq_domain_add_linear(node, nr_irqs, + &twl6030_irq_domain_ops, twl6030_irq); + if (!twl6030_irq->irq_domain) { dev_err(dev, "Can't add irq_domain\n"); return -ENOMEM; } @@ -385,26 +402,26 @@ int twl6030_init_irq(struct device *dev, int irq_num) /* install an irq handler to demultiplex the TWL6030 interrupt */ status = request_threaded_irq(irq_num, NULL, twl6030_irq_thread, - IRQF_ONESHOT, "TWL6030-PIH", irq_domain); + IRQF_ONESHOT, "TWL6030-PIH", twl6030_irq); if (status < 0) { dev_err(dev, "could not claim irq %d: %d\n", irq_num, status); goto fail_irq; } - twl_irq = irq_num; - register_pm_notifier(&twl6030_irq_pm_notifier_block); + twl6030_irq->twl_irq = irq_num; + register_pm_notifier(&twl6030_irq->pm_nb); return 0; fail_irq: - irq_domain_remove(irq_domain); + irq_domain_remove(twl6030_irq->irq_domain); return status; } int twl6030_exit_irq(void) { - if (twl_irq) { - unregister_pm_notifier(&twl6030_irq_pm_notifier_block); - free_irq(twl_irq, NULL); + if (twl6030_irq && twl6030_irq->twl_irq) { + unregister_pm_notifier(&twl6030_irq->pm_nb); + free_irq(twl6030_irq->twl_irq, NULL); /* * TODO: IRQ domain and allocated nested IRQ descriptors * should be freed somehow here. Now It can't be done, because