From patchwork Sun Mar 25 12:38:49 2012 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: thomas.abraham@linaro.org X-Patchwork-Id: 7452 Return-Path: X-Original-To: patchwork@peony.canonical.com Delivered-To: patchwork@peony.canonical.com Received: from fiordland.canonical.com (fiordland.canonical.com [91.189.94.145]) by peony.canonical.com (Postfix) with ESMTP id 41B4C23E40 for ; Sun, 25 Mar 2012 12:33:58 +0000 (UTC) Received: from mail-iy0-f180.google.com (mail-iy0-f180.google.com [209.85.210.180]) by fiordland.canonical.com (Postfix) with ESMTP id D2927A180D6 for ; Sun, 25 Mar 2012 12:33:57 +0000 (UTC) Received: by iage36 with SMTP id e36so9142527iag.11 for ; Sun, 25 Mar 2012 05:33:57 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20120113; h=x-forwarded-to:x-forwarded-for:delivered-to:received-spf:x-auditid :from:to:cc:subject:date:message-id:x-mailer:in-reply-to:references :x-brightmail-tracker:x-tm-as-mml:x-gm-message-state; bh=XlHIRTzbfgQDxiVRwsu2PMceKPQE2xQKNmsVTrunFP0=; b=psTlMp7BSdZosd5ZD2+wBXc8viyt7FBv+PtkEqc95J63QQLqQtFl0ecZDeDaxZS07s B7KEelBsS3XDKa+8sr+7iIhIFrA6n+9NUn2MhGJbRtgmSVuQzzag1g0gK0aERZ7RwaMX PidH519F4p2CGqN27GMPY03bVxKbvAdVL95Tu5CJObKH86yW35XqmhzKk1MEuExNaZnc mPU5v02TtzqUvN8TLqkHSpTLpRt4soGnnNde5r7tQApLE+UQ50tNOJCvuwIbIuKrGePc UK5AAuW9QPPPPpYtjLG0QrFpVnnAiXC0v1SN2eoiqyXemtvfyLtxa0RP5P0bJtLIHcDr 2MIQ== Received: by 10.50.183.163 with SMTP id en3mr3257230igc.12.1332678837105; Sun, 25 Mar 2012 05:33:57 -0700 (PDT) X-Forwarded-To: linaro-patchwork@canonical.com X-Forwarded-For: patch@linaro.org linaro-patchwork@canonical.com Delivered-To: patches@linaro.org Received: by 10.231.203.79 with SMTP id fh15csp65971ibb; Sun, 25 Mar 2012 05:33:56 -0700 (PDT) Received: by 10.68.217.97 with SMTP id ox1mr44560795pbc.81.1332678835857; Sun, 25 Mar 2012 05:33:55 -0700 (PDT) Received: from mailout3.samsung.com (mailout3.samsung.com. [203.254.224.33]) by mx.google.com with ESMTP id s4si15184949pbc.75.2012.03.25.05.33.55; Sun, 25 Mar 2012 05:33:55 -0700 (PDT) Received-SPF: neutral (google.com: 203.254.224.33 is neither permitted nor denied by best guess record for domain of thomas.abraham@linaro.org) client-ip=203.254.224.33; Authentication-Results: mx.google.com; spf=neutral (google.com: 203.254.224.33 is neither permitted nor denied by best guess record for domain of thomas.abraham@linaro.org) smtp.mail=thomas.abraham@linaro.org Received: from epcpsbgm1.samsung.com (mailout3.samsung.com [203.254.224.33]) by mailout3.samsung.com (Oracle Communications Messaging Exchange Server 7u4-19.01 64bit (built Sep 7 2010)) with ESMTP id <0M1F00D40XKIXZ20@mailout3.samsung.com> for patches@linaro.org; Sun, 25 Mar 2012 21:33:54 +0900 (KST) X-AuditID: cbfee61a-b7c49ae0000061d4-a1-4f6f10b263e9 Received: from epmmp1.local.host ( [203.254.227.16]) by epcpsbgm1.samsung.com (MMPCPMTA) with SMTP id 34.A2.25044.2B01F6F4; Sun, 25 Mar 2012 21:33:54 +0900 (KST) Received: from localhost.localdomain ([107.108.73.37]) by mmp1.samsung.com (Oracle Communications Messaging Exchange Server 7u4-19.01 64bit (built Sep 7 2010)) with ESMTPA id <0M1F002OKXKCG870@mmp1.samsung.com> for patches@linaro.org; Sun, 25 Mar 2012 21:33:53 +0900 (KST) From: Thomas Abraham To: devicetree-discuss@lists.ozlabs.org, linux-kernel@vger.kernel.org Cc: rob.herring@calxeda.com, grant.likely@secretlab.ca, linux-samsung-soc@vger.kernel.org, patches@linaro.org Subject: [PATCH] of/irq: of_irq_init: Call initialization function for all controllers Date: Sun, 25 Mar 2012 18:08:49 +0530 Message-id: <1332679129-23864-1-git-send-email-thomas.abraham@linaro.org> X-Mailer: git-send-email 1.6.6.rc2 In-reply-to: References: X-Brightmail-Tracker: AAAAAA== X-TM-AS-MML: No X-Gm-Message-State: ALoCoQnR+J1NEdrEdJJxPuBfq1VqtybZwyQgiENW+ko08p7Ei/OiNfVBOlA6uI0L0AiiVGWbkBep The of_irq_init function stops processing the interrupt controller hierarchy when there are no more interrupt controller parents identified. Though this condition suffices most cases, there are cases where a interrupt controller's parent controller does not participate in the initialization of the interrupt hierarchy. An example of such a case is the use of a interrupt nexus node by a interrupt controller node which delivers interrupts to separate interrupt parent controllers. Instead of stopping the processing of interrupt controller hierarchy in such a case, the orphan interrupt controller node's descriptor can be identified and its 'logical' parent in the descriptor is set as NULL. The processing of interrupt hierarchy is then restarted by looking for descriptors which have a NULL interrupt parent. Cc: Rob Herring Cc: Grant Likely Signed-off-by: Thomas Abraham --- drivers/of/irq.c | 45 ++++++++++++++++++++++++++++++++++++++++++++- 1 files changed, 44 insertions(+), 1 deletions(-) diff --git a/drivers/of/irq.c b/drivers/of/irq.c index 9cf0060..70c6ece 100644 --- a/drivers/of/irq.c +++ b/drivers/of/irq.c @@ -400,6 +400,38 @@ struct intc_desc { }; /** + * of_irq_mark_orphan_desc - Set parent as NULL for a orphan intc_desc + * @intc_desc_list: the list of intc_desc to search for orphan intc_desc + * + * This is a helper function for the of_irq_init function and is invoked + * when there are child nodes available in intc_desc_list but there are + * no parent nodes in intc_parent_list. When invoked, this function + * searches for a intc_desc instance that does not have a parent intc_desc + * instance in intc_desc_list. The very reason of the invocation of this + * function ensures that a orphan intc_desc will be found. When found, the + * interrupt_parent of the orphan intc_desc is set to NULL. + */ +static void of_irq_mark_orphan_desc(struct list_head *intc_desc_list) +{ + struct intc_desc *desc, *temp_desc; + + list_for_each_entry_safe(desc, temp_desc, intc_desc_list, list) { + struct intc_desc *td1, *td2; + list_for_each_entry_safe(td1, td2, intc_desc_list, list) { + if (desc->interrupt_parent == td1->dev) + break; + } + if (desc->interrupt_parent == td1->dev) + continue; + + pr_debug("%s: set interrupt_parent of 'intc_desc' with dev name" + " %s as NULL\n", __func__, desc->dev->full_name); + desc->interrupt_parent = NULL; + return; + } +} + +/** * of_irq_init - Scan and init matching interrupt controllers in DT * @matches: 0 terminated array of nodes to match and init function to call * @@ -481,8 +513,19 @@ void __init of_irq_init(const struct of_device_id *matches) /* Get the next pending parent that might have children */ desc = list_first_entry(&intc_parent_list, typeof(*desc), list); if (list_empty(&intc_parent_list) || !desc) { + /* + * This has reached a point where there are children in + * the intc_desc_list but no parent in intc_parent_list. + * This means there is a child desc in intc_desc_list + * whose parent is not one of the remaining elements of + * the intc_desc_list. Such a child node is marked as + * orphan (interrupt_parent is set to NULL) and the + * process continues with parent set to NULL. + */ pr_err("of_irq_init: children remain, but no parents\n"); - break; + of_irq_mark_orphan_desc(&intc_desc_list); + parent = NULL; + continue; } list_del(&desc->list); parent = desc->dev;