Received: by 10.192.165.148 with SMTP id m20csp2341903imm; Thu, 26 Apr 2018 09:24:03 -0700 (PDT) X-Google-Smtp-Source: AIpwx48SkSbNcQj7xCgUur/4H4/E+TEGwIwjmogHto6vevo0BLKf8Q4rz/6YMdmlU2PV6j7G6crk X-Received: by 10.98.56.144 with SMTP id f138mr33280372pfa.173.1524759843524; Thu, 26 Apr 2018 09:24:03 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1524759843; cv=none; d=google.com; s=arc-20160816; b=jV353lPYyiu4EhNUMQSiZEhVZ12ZoJwk+M/JsVYPyETwY8CPdBq7NG33YG0HJeVg+Q jt5lyOxCf6REXrvs96s4uwAH7wABPS3bnO3ULMEI4af9EBocjaOWrkIxz9MFQq6PPHJs /rDrLIpZQdu+0ixq27Y7q7URkUpr1fhFdBDUsRZPFo8w0oGqH3GuzDgDhwqGPt81eEsl /0Jv4ktz50OgIDV3XBHI+aixnrsdUdyvh0pVxP3wJNVE6LHFK07FrAfsneX807p21hGz urjw9k615S3r1wmEhrSvo7AdFxZ5kVGy1sZu/+nd6QlSw/Eh6mv7qWX3LCrI/iLH8sm9 bUOg== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:arc-authentication-results; bh=tOs865YHAhL/Hq3Givq3OBIAVVhVrRG7xThpwVuruv0=; b=SeyE6kCLamC8zGiygd4dGb13v08GnOXX3ejlYXTT2ogxfo1MNV8uSJqb7eGQe5UWF/ 37Sh9s00ZyWsaGh4K5ZsLeDlceFva7+AjIZvhPme8RRGHVaYRhfCnhBKnaA1AD5fJFdU FBVfOe9zDrXXzx81jH874kOxqoYkaE1km5wcOZOw2gCeCxyu5B3JuF0q/mJDZkVHWEoW PGi5+1dVqtY1Qh0+aseql4N4VzjuCWABzXJdIahANSOix/F2/gBhfsPQ07ftSrhqwz/D 5fYDura0slU6vdpYcVWmpdmOmoTSSVXJ/bZuwW7IhI5g4QfnbyV2ZGxUnfx8Xx24OyUX a1Fw== ARC-Authentication-Results: i=1; mx.google.com; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id x10-v6si20019193plm.5.2018.04.26.09.23.48; Thu, 26 Apr 2018 09:24:03 -0700 (PDT) Received-SPF: pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) client-ip=209.132.180.67; Authentication-Results: mx.google.com; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S932150AbeDZQWI (ORCPT + 99 others); Thu, 26 Apr 2018 12:22:08 -0400 Received: from mx08-00178001.pphosted.com ([91.207.212.93]:52613 "EHLO mx07-00178001.pphosted.com" rhost-flags-OK-OK-OK-FAIL) by vger.kernel.org with ESMTP id S1756661AbeDZQTQ (ORCPT ); Thu, 26 Apr 2018 12:19:16 -0400 Received: from pps.filterd (m0046661.ppops.net [127.0.0.1]) by mx08-.pphosted.com (8.16.0.21/8.16.0.21) with SMTP id w3QFsRT8020597; Thu, 26 Apr 2018 18:18:43 +0200 Received: from beta.dmz-eu.st.com (beta.dmz-eu.st.com [164.129.1.35]) by mx08-00178001.pphosted.com with ESMTP id 2hfv6f3t41-1 (version=TLSv1 cipher=ECDHE-RSA-AES256-SHA bits=256 verify=NOT); Thu, 26 Apr 2018 18:18:43 +0200 Received: from zeta.dmz-eu.st.com (zeta.dmz-eu.st.com [164.129.230.9]) by beta.dmz-eu.st.com (STMicroelectronics) with ESMTP id DD82534; Thu, 26 Apr 2018 16:18:42 +0000 (GMT) Received: from Webmail-eu.st.com (Safex1hubcas24.st.com [10.75.90.94]) by zeta.dmz-eu.st.com (STMicroelectronics) with ESMTP id BB7E25147; Thu, 26 Apr 2018 16:18:42 +0000 (GMT) Received: from SAFEX1HUBCAS21.st.com (10.75.90.44) by Safex1hubcas24.st.com (10.75.90.94) with Microsoft SMTP Server (TLS) id 14.3.361.1; Thu, 26 Apr 2018 18:18:42 +0200 Received: from lmecxl0923.lme.st.com (10.48.0.237) by Webmail-ga.st.com (10.75.90.48) with Microsoft SMTP Server (TLS) id 14.3.361.1; Thu, 26 Apr 2018 18:18:42 +0200 From: Ludovic Barre To: Thomas Gleixner , Jason Cooper , Marc Zyngier , Rob Herring CC: Maxime Coquelin , Alexandre Torgue , Gerald BAEZA , Loic PALLARDY , , , , "Ludovic Barre" Subject: [PATCH 05/11] irqchip: stm32: add host and driver data structures Date: Thu, 26 Apr 2018 18:18:28 +0200 Message-ID: <1524759514-12392-6-git-send-email-ludovic.Barre@st.com> X-Mailer: git-send-email 2.7.4 In-Reply-To: <1524759514-12392-1-git-send-email-ludovic.Barre@st.com> References: <1524759514-12392-1-git-send-email-ludovic.Barre@st.com> MIME-Version: 1.0 Content-Type: text/plain X-Originating-IP: [10.48.0.237] X-Proofpoint-Virus-Version: vendor=fsecure engine=2.50.10434:,, definitions=2018-04-26_06:,, signatures=0 Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org From: Ludovic Barre This patch adds host and driver data structures to support different stm32 exti controllers with variants. Signed-off-by: Ludovic Barre --- drivers/irqchip/irq-stm32-exti.c | 152 ++++++++++++++++++++++++++------------- 1 file changed, 104 insertions(+), 48 deletions(-) diff --git a/drivers/irqchip/irq-stm32-exti.c b/drivers/irqchip/irq-stm32-exti.c index 1e09667..9655a57 100644 --- a/drivers/irqchip/irq-stm32-exti.c +++ b/drivers/irqchip/irq-stm32-exti.c @@ -29,13 +29,23 @@ struct stm32_exti_bank { #define UNDEF_REG ~0 +struct stm32_exti_drv_data { + const struct stm32_exti_bank **exti_banks; + u32 bank_nr; +}; + struct stm32_exti_chip_data { + struct stm32_exti_host_data *host_data; const struct stm32_exti_bank *reg_bank; u32 rtsr_cache; u32 ftsr_cache; }; -static struct stm32_exti_chip_data *stm32_exti_data; +struct stm32_exti_host_data { + void __iomem *base; + struct stm32_exti_chip_data *chips_data; + const struct stm32_exti_drv_data *drv_data; +}; static const struct stm32_exti_bank stm32f4xx_exti_b1 = { .imr_ofst = 0x00, @@ -51,6 +61,11 @@ static const struct stm32_exti_bank *stm32f4xx_exti_banks[] = { &stm32f4xx_exti_b1, }; +static const struct stm32_exti_drv_data stm32f4xx_drv_data = { + .exti_banks = stm32f4xx_exti_banks, + .bank_nr = ARRAY_SIZE(stm32f4xx_exti_banks), +}; + static const struct stm32_exti_bank stm32h7xx_exti_b1 = { .imr_ofst = 0x80, .emr_ofst = 0x84, @@ -87,6 +102,11 @@ static const struct stm32_exti_bank *stm32h7xx_exti_banks[] = { &stm32h7xx_exti_b3, }; +static const struct stm32_exti_drv_data stm32h7xx_drv_data = { + .exti_banks = stm32h7xx_exti_banks, + .bank_nr = ARRAY_SIZE(stm32h7xx_exti_banks), +}; + static unsigned long stm32_exti_pending(struct irq_chip_generic *gc) { struct stm32_exti_chip_data *chip_data = gc->private; @@ -237,29 +257,85 @@ static void stm32_irq_ack(struct irq_data *d) irq_gc_unlock(gc); } +static struct +stm32_exti_host_data *stm32_exti_host_init(const struct stm32_exti_drv_data *dd, + struct device_node *node) +{ + struct stm32_exti_host_data *host_data; + + host_data = kzalloc(sizeof(*host_data), GFP_KERNEL); + if (!host_data) + return NULL; + + host_data->drv_data = dd; + host_data->chips_data = kcalloc(dd->bank_nr, + sizeof(struct stm32_exti_chip_data), + GFP_KERNEL); + if (!host_data->chips_data) + return NULL; + + host_data->base = of_iomap(node, 0); + if (!host_data->base) { + pr_err("%pOF: Unable to map registers\n", node); + return NULL; + } -static int -__init stm32_exti_init(const struct stm32_exti_bank **stm32_exti_banks, - int bank_nr, struct device_node *node) + return host_data; +} + +static struct +stm32_exti_chip_data *stm32_exti_chip_init(struct stm32_exti_host_data *h_data, + u32 bank_idx, + struct device_node *node) +{ + const struct stm32_exti_bank *stm32_bank; + struct stm32_exti_chip_data *chip_data; + void __iomem *base = h_data->base; + u32 irqs_mask; + + stm32_bank = h_data->drv_data->exti_banks[bank_idx]; + chip_data = &h_data->chips_data[bank_idx]; + chip_data->host_data = h_data; + chip_data->reg_bank = stm32_bank; + + /* Determine number of irqs supported */ + writel_relaxed(~0UL, base + stm32_bank->rtsr_ofst); + irqs_mask = readl_relaxed(base + stm32_bank->rtsr_ofst); + + /* + * This IP has no reset, so after hot reboot we should + * clear registers to avoid residue + */ + writel_relaxed(0, base + stm32_bank->imr_ofst); + writel_relaxed(0, base + stm32_bank->emr_ofst); + writel_relaxed(0, base + stm32_bank->rtsr_ofst); + writel_relaxed(0, base + stm32_bank->ftsr_ofst); + writel_relaxed(~0UL, base + stm32_bank->rpr_ofst); + if (stm32_bank->fpr_ofst != UNDEF_REG) + writel_relaxed(~0UL, base + stm32_bank->fpr_ofst); + + pr_info("%s: bank%d, External IRQs available:%#x\n", + node->full_name, bank_idx, irqs_mask); + + return chip_data; +} + +static int __init stm32_exti_init(const struct stm32_exti_drv_data *drv_data, + struct device_node *node) { + struct stm32_exti_host_data *host_data; unsigned int clr = IRQ_NOREQUEST | IRQ_NOPROBE | IRQ_NOAUTOEN; - int nr_irqs, nr_exti, ret, i; + int nr_irqs, ret, i; struct irq_chip_generic *gc; struct irq_domain *domain; - void *base; - base = of_iomap(node, 0); - if (!base) { - pr_err("%pOF: Unable to map registers\n", node); - return -ENOMEM; + host_data = stm32_exti_host_init(drv_data, node); + if (!host_data) { + ret = -ENOMEM; + goto out_free_mem; } - stm32_exti_data = kcalloc(bank_nr, sizeof(*stm32_exti_data), - GFP_KERNEL); - if (!stm32_exti_data) - return -ENOMEM; - - domain = irq_domain_add_linear(node, bank_nr * IRQS_PER_BANK, + domain = irq_domain_add_linear(node, drv_data->bank_nr * IRQS_PER_BANK, &irq_exti_domain_ops, NULL); if (!domain) { pr_err("%s: Could not register interrupt domain.\n", @@ -276,16 +352,16 @@ __init stm32_exti_init(const struct stm32_exti_bank **stm32_exti_banks, goto out_free_domain; } - for (i = 0; i < bank_nr; i++) { - const struct stm32_exti_bank *stm32_bank = stm32_exti_banks[i]; - struct stm32_exti_chip_data *chip_data = &stm32_exti_data[i]; - u32 irqs_mask; + for (i = 0; i < drv_data->bank_nr; i++) { + const struct stm32_exti_bank *stm32_bank; + struct stm32_exti_chip_data *chip_data; - chip_data->reg_bank = stm32_bank; + stm32_bank = drv_data->exti_banks[i]; + chip_data = stm32_exti_chip_init(host_data, i, node); gc = irq_get_domain_generic_chip(domain, i * IRQS_PER_BANK); - gc->reg_base = base; + gc->reg_base = host_data->base; gc->chip_types->type = IRQ_TYPE_EDGE_BOTH; gc->chip_types->chip.irq_ack = stm32_irq_ack; gc->chip_types->chip.irq_mask = irq_gc_mask_clr_bit; @@ -298,26 +374,6 @@ __init stm32_exti_init(const struct stm32_exti_bank **stm32_exti_banks, gc->chip_types->regs.mask = stm32_bank->imr_ofst; gc->private = (void *)chip_data; - - /* Determine number of irqs supported */ - writel_relaxed(~0UL, base + stm32_bank->rtsr_ofst); - irqs_mask = readl_relaxed(base + stm32_bank->rtsr_ofst); - nr_exti = fls(readl_relaxed(base + stm32_bank->rtsr_ofst)); - - /* - * This IP has no reset, so after hot reboot we should - * clear registers to avoid residue - */ - writel_relaxed(0, base + stm32_bank->imr_ofst); - writel_relaxed(0, base + stm32_bank->emr_ofst); - writel_relaxed(0, base + stm32_bank->rtsr_ofst); - writel_relaxed(0, base + stm32_bank->ftsr_ofst); - writel_relaxed(~0UL, base + stm32_bank->rpr_ofst); - if (stm32_bank->fpr_ofst != UNDEF_REG) - writel_relaxed(~0UL, base + stm32_bank->fpr_ofst); - - pr_info("%s: bank%d, External IRQs available:%#x\n", - node->full_name, i, irqs_mask); } nr_irqs = of_irq_count(node); @@ -333,16 +389,17 @@ __init stm32_exti_init(const struct stm32_exti_bank **stm32_exti_banks, out_free_domain: irq_domain_remove(domain); out_unmap: - iounmap(base); - kfree(stm32_exti_data); + iounmap(host_data->base); +out_free_mem: + kfree(host_data->chips_data); + kfree(host_data); return ret; } static int __init stm32f4_exti_of_init(struct device_node *np, struct device_node *parent) { - return stm32_exti_init(stm32f4xx_exti_banks, - ARRAY_SIZE(stm32f4xx_exti_banks), np); + return stm32_exti_init(&stm32f4xx_drv_data, np); } IRQCHIP_DECLARE(stm32f4_exti, "st,stm32-exti", stm32f4_exti_of_init); @@ -350,8 +407,7 @@ IRQCHIP_DECLARE(stm32f4_exti, "st,stm32-exti", stm32f4_exti_of_init); static int __init stm32h7_exti_of_init(struct device_node *np, struct device_node *parent) { - return stm32_exti_init(stm32h7xx_exti_banks, - ARRAY_SIZE(stm32h7xx_exti_banks), np); + return stm32_exti_init(&stm32h7xx_drv_data, np); } IRQCHIP_DECLARE(stm32h7_exti, "st,stm32h7-exti", stm32h7_exti_of_init); -- 2.7.4