From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1753723AbdBPBBr (ORCPT ); Wed, 15 Feb 2017 20:01:47 -0500 Received: from mail-bl2nam02on0079.outbound.protection.outlook.com ([104.47.38.79]:40256 "EHLO NAM02-BL2-obe.outbound.protection.outlook.com" rhost-flags-OK-OK-OK-FAIL) by vger.kernel.org with ESMTP id S1752039AbdBPBBn (ORCPT ); Wed, 15 Feb 2017 20:01:43 -0500 Authentication-Results: spf=none (sender IP is ) smtp.mailfrom=David.Daney@cavium.com; From: David Daney To: Linus Walleij , Alexandre Courbot , Rob Herring , Mark Rutland , Marc Zyngier , Thomas Gleixner , linux-gpio@vger.kernel.org, devicetree@vger.kernel.org Cc: linux-kernel@vger.kernel.org, David Daney Subject: [PATCH v4 3/6] irqdomain: Add irq_domain_{push,pop}_irq() functions. Date: Wed, 15 Feb 2017 17:01:03 -0800 Message-Id: <1487206866-4011-4-git-send-email-david.daney@cavium.com> X-Mailer: git-send-email 1.8.3.1 In-Reply-To: <1487206866-4011-1-git-send-email-david.daney@cavium.com> References: <1487206866-4011-1-git-send-email-david.daney@cavium.com> MIME-Version: 1.0 Content-Type: text/plain X-Originating-IP: [50.233.148.156] X-ClientProxiedBy: BN1PR07CA0054.namprd07.prod.outlook.com (10.255.193.29) To CY1PR0701MB1979.namprd07.prod.outlook.com (10.163.141.21) X-MS-Office365-Filtering-Correlation-Id: 788e4f32-e54e-4765-3418-08d456075710 X-Microsoft-Antispam: UriScan:;BCL:0;PCL:0;RULEID:(22001);SRVR:CY1PR0701MB1979; X-Microsoft-Exchange-Diagnostics: 1;CY1PR0701MB1979;3:71rf0UqsxabR6Ky5CilUZGXc5N7M6Hb+65qgj4gL2rtdpHi8UA+IYt+CFLnxQt19AHjduIE2XyV8udEC5a4nAWyqNo6vCKgETgE4x+uNirTCX3sZUTDKO+zDROQe57A9fQQgAwCtVFCtw6vPK2rMSM0CwWHQS4D3I433HBM8ID/SeI/esq/obZ7s2NyNVkXdVv4k4gNjH2CctNTmqhN4eR2iMUH+ZoUbolgyuiqCH6qeCaMEs16I2XqlBmLmkG/PB1uM2dielzIwl0zWY9WAXg==;25:VbIC00UJ2uTOenGZQ+QQOTUvLQ4p9xTBXNj5MLxQDhRprx+LKW9CEn3bAaRgq8lN7ym8AgALW9RqzdbleRLZOiqmdWWkKDp+ERXEkktFVv98hbGebpVv8dd11nv5guDE5KQzxkDiP9WX/9Qi5IVEY0QHbRsoo5flND+4kaJiGv7+/hwJOf37GuuyZHRm8pNbrpYfd1gXl+DMsxPHZdBPbb30baJV7p6kJ0Em3soxDnA1ivp3ZrHTeooYx9stV96nMwCeoco9WRQFrsYHQ3ZdcxSUpiKfppkZROpVHSk3y5xCX6ns/A2dxnEg9fjOWCjQDW34Srl8rH1ojUkaOUTuHEWSQdjfHq8jOoNbro4Z4/ho+uOFjbjwf5sDJzeAKfMO3GCNTrNYVNbQaMTaK/KKrBi+6FBVdWB6RVEY4DMYNiZbPppHc7/A6eY1wjM4N8YNPGCGs313VnwKY2D0q6t+VQ== X-Microsoft-Exchange-Diagnostics: 1;CY1PR0701MB1979;31:LebiEYJ7GRNgGenz7MV4q2K8wljdT7O1dPcZx9rlL62/9z7wegb7fB6AGdf02p+kKAFNJITY60MgcVJZpwo7feZf6Z8eklUkYGNVkoPlolyLjlk9nWxciM8fXOn9uhlFTZOHPSRKPrKlSkAwxbMMJS8El2GbDdHfRQkVXAfQzFYuLNcv5JZQw+FD7PQVgUF4bZIGORqUEKET/OMpWB9RW7OmL4zdGoNKEwEJn8b6/piIHr/FCACSAIyqoo3jjVqn;20:y4CB1G5iVuDf2v7MmMFXjacatYOpx7vt7UEDNjZitINZXkgW9wol13E8uw/C1lBlrS8IywrM1D0yFKg6sBq2Xz73md90MUNj1wMGz9cgAoJ7Uu7x+90Icm8eyzC+PQIkOosMN55b8qqGMJicud/HsO85fHYDheKSJOGQecs9Z8kX3OhOu2Pm1zhKl5Rgbg2tj57MLRoKYVB017GmGtjsSHselKzglj8e7PccLAc7XMVAC0eElwHgAqUBNW3mKk0LlP1L0r43eKC4jEdR/Be+W4sPlEVeWF2zqV4Ph0o1557QsOX/XquEUdzu5/StVKhPoEsULVX9+03yoy407ULtZkxm5ygJKu3BouGVH2wCV8GZQW2tQtWCPxz7vEOsjcCRKz9t8YuX1QLjf5V1WT8eYxkIIuxgUvtv+FDiXgYn1/XFOSFfNznN6owBcQbBaYxH/S0slx3GeN0SLutBNuaJ79X5dtRCfWTq4AP1zI7vUw0ieY1dE8U60WUj8DVu6eap X-Microsoft-Antispam-PRVS: X-Exchange-Antispam-Report-Test: UriScan:; X-Exchange-Antispam-Report-CFA-Test: BCL:0;PCL:0;RULEID:(6040375)(601004)(2401047)(8121501046)(5005006)(3002001)(10201501046)(6041248)(20161123558025)(20161123562025)(20161123560025)(20161123555025)(20161123564025)(6072148);SRVR:CY1PR0701MB1979;BCL:0;PCL:0;RULEID:;SRVR:CY1PR0701MB1979; X-Microsoft-Exchange-Diagnostics: 1;CY1PR0701MB1979;4:78RYxVjFKdIZYFkNkPrfWMA0g5mKZY5vyz1n88exIF0+/jeLYTxgvN3v1350eZbfgUa7HAhUcAWeL9YgZQTkApA+vxdJ+PdHbhXaE/3PXsI0Fl18NsB/GVfhlFPBJbFBW+rI7s0W1EuxX/+xFelvASmZHHJ7CfxvQZ5F3AjFKYqzsBYbBor2K5TSAwkFPkYqaQLO7xKiBXwm181/nSQRMd+pROTuGmq7ILbbM3UxK3VzrHFDRSPf6ts9rpLqn1JXsrWrJZ/92TlLDFIK4+Lv1ADLCuIAgN+QzMXOY7wJeQc224NiEqeUwJAxQLTZJcsPcnFYjjNrUsjRF23cPMuq1XZ50I9E+qmlK+us41FNmYVbnDnKgsVrMaXl4bOc78sVfuzy0ClLU3BWLGQCMJhdGWZw2TjXMjXW+0v9J/+pWPVOqjbbFFh0Y+CMrBd7E2vqPTNglb6aBNEreEZDNBFWkF1vD4SPFiit3SNoYdF4qv0HibsqMj3ZnqaM2Bkl/4mjUP7knz2X7Qrfsh0rdJU1rsk0tDa+iVsd8xqSlP6ka4CwrRg7mxUQstX/OdhnkaPICk5LBwrW99VM4hQgzr2yFmIqOOCzWbV4lAtmk+mg9UU= X-Forefront-PRVS: 0220D4B98D X-Forefront-Antispam-Report: SFV:NSPM;SFS:(10009020)(4630300001)(6009001)(6069001)(7916002)(39450400003)(189002)(199003)(76506005)(5660300001)(305945005)(2906002)(33646002)(25786008)(53416004)(105586002)(106356001)(42186005)(189998001)(4326007)(92566002)(36756003)(101416001)(76176999)(50986999)(8676002)(81166006)(68736007)(3846002)(2950100002)(6666003)(81156014)(7736002)(86362001)(5003940100001)(4720700003)(6116002)(6512007)(6506006)(69596002)(47776003)(97736004)(107886003)(6486002)(50466002)(50226002)(66066001)(48376002)(53936002)(389900002)(38730400002)(142933001);DIR:OUT;SFP:1101;SCL:1;SRVR:CY1PR0701MB1979;H:localhost.caveonetworks.com;FPR:;SPF:None;PTR:InfoNoRecords;MX:1;A:1;LANG:en; X-Microsoft-Exchange-Diagnostics: =?us-ascii?Q?1;CY1PR0701MB1979;23:wfolJM/Kg99l+8in4LLX90z149uEHQsWETtnACb?= =?us-ascii?Q?Ti6RcKVsc9vT2jl0KHnSlccvup+kLf/gCOHlcHar9Beq932yZmnUwKmF+6+T?= =?us-ascii?Q?8/4TT9cWp9FYiXCb2FVycTpcx1DBqOuxnVFf36cDEG9hqFaYV5Qycab4WLyy?= =?us-ascii?Q?Evir1S948xmxxtq+chILXmCR6n50rjrxNnq4Sh/WHRJ79kJV2jgtMjGrwbUY?= =?us-ascii?Q?VfxC2mJd1IDGl8Gsix9ZyE90oi7T00b1UiOI2lpHJy62x+Ur5sKiRjF2Pmx7?= =?us-ascii?Q?WLRf4BW9glOFYQypTgQjGAoTNklV6YzUtfZqDC+SGiGva92HsDxznKgFjGoe?= =?us-ascii?Q?HJpJC3wjWqi23ltLG82ykkNvEgYtaAov3OIvAOn6Cc+MFnmJu75wwib89HGt?= =?us-ascii?Q?95FHot6P9InfMISrWaNPggrOvxuFcnWSBu7c+QcPUKM1TJhTpkVpulDeldWS?= =?us-ascii?Q?sDTRaem/hLcNq5EqnZmp53pRhf+PD8Kfl3fFBuTok1NWM8gj8FEEFyU3Oth8?= =?us-ascii?Q?I6UPv6KAGCP/pG+mNfKFzGNQEpyRhKwW4e8eVNJcnlzv6VD+DVBgF8Hg29Xf?= =?us-ascii?Q?9GCQjDTGENztPhs3p9RTLdQJB9/JzQjU9P9gRuSf69F0FK6Ch592oHAHVvak?= =?us-ascii?Q?lIADHay3oPLx+D67/zmkohECo9vCc8TwbPmqHqhoDxA5oCvZ+TqGx5CfUk0Y?= =?us-ascii?Q?BGM47EyZdArKEjHtS0j00GFzXDU29cgObwBuRRxpcFALdfH3tzH8D/ZCG1NX?= =?us-ascii?Q?uhYasWmAb3tx7HTSa5YrDVf9f44qejQP2A0e2w2G0ztRxhDMR5PHKWxFt37x?= =?us-ascii?Q?E9TXc+k0NtJ5/Os583jmJ3N/dH0mX6Rh4gSChudhbTjlTlSTxe0apRPmcgwH?= =?us-ascii?Q?D7Fa3+eyBJC/7CiA9zwBQOK24D9a2ld3mMOf2RuNGs28lAChhss1n8ZAH+ph?= =?us-ascii?Q?JplpliPW+cVohwvPGWsHM9St/2fAGtDyQGP2nSWqBk2lbYUUHHWYX1w7wI5g?= =?us-ascii?Q?4N9CIIVXeOdKpalKywGyZVRNjsNnGMaMLfKsMgJs8GmW2cdEzOULNvMcPaJs?= =?us-ascii?Q?NgxGGlN0deSHWad9l+Q+Nwq31ru1IFEZOq75t/cPYeoWgkQX2aeI0n+elzSM?= =?us-ascii?Q?ipBOfpbihzAAF/DA/Z11c4y9pvsl9sxY+l98CdsTOrRPIimzAbRBaT7RA5Ab?= =?us-ascii?Q?8Cv/+l/WevGwWuy1/UCI8yXFP2h4t1YkLN0MTXzzjSaj0QFqadgu8WBnrag?= =?us-ascii?Q?=3D=3D?= X-Microsoft-Exchange-Diagnostics: 1;CY1PR0701MB1979;6:Sh7PoR+CZ5Oqx0hzYbSTrPzwl+48YLF9K0MKwflmrmQOWbZ0o/Y5Dy6ig3xJdEmOn7GhLRLLOUdTbMIXDa1c+wTb/vL3KDAEqNfznPvN/rHRqCL8iCHF/wK0OwqxQ74ces+Tk5R8uSIvU6ZJj2pv5fOjCF7yStkz4cYNSvSOk4IOnYxjdAcoV1Ja7UmAJqNFJHAxJIpf2BhAby+zhEHBhTsKfMXMwaMX4Qit1uRSUbLkvZVsIC2MN0rygYGvdR+GhoZMRwps3YfsLKSgS3RmKAqudBMuV632UwjCwjOIAUTc4gMdsUQA54SKSIZleofG0oi8EUyASrBAKb3+YUi9KWXSnSqS0ZFzZ6jXl6UT7XXwtE7CQF1fTqjXXpbIaY0q5JOYrU96KtGyv5n5W0PR7Q==;5:WwXPqPsuHqOGr0NUnVAnZWx58taPcRScHudIOOhz9TfUwd4MniYPAfWaAP+FqV6/ZaiifGJEYQQCzo58qMFGFZr/CDGB1UcI4U5ASDpQ6IImbXrDSJiI+PuHakcI+BWbHteITR5bt3AV1lFXv5u/TA==;24:jv8CJ31uf0w4yeDA3+t5IIMN46APxN7UjhE17pZ7MarpvYKV/oq7PxwQf+GWR3n35NkHz3wDAn3ytH9Y7nqiyrd9ib4grT660sq8aaBm4/k= SpamDiagnosticOutput: 1:99 SpamDiagnosticMetadata: NSPM X-Microsoft-Exchange-Diagnostics: 1;CY1PR0701MB1979;7:Y6ERC/Y4leB6zYkwJY6A9MaO9WvjR2/ctesq8mN1vHRgBaDPxSZ4wLc77ZQNKFstZPTJvlC9F8ypeqjKeA5+4Y1EvIOAPKPlMSgPPHLWditNx0oHHz4VqBIk12pfRAI3Gr97r/k9UBP6+T+1ta1nXhrmXgs6EuXZGJTQZUTs1LWIoN34QJcqIsgUw5JlwdSCPGl6oOQrtlTlNWltEwxMtoMXO2/A0+oxYci/kW4ao1ahxOsFU7TsQc02grgAAu8BNeL0n/Q7OmiKdLaJT2nA33+u4oQ2oz3Yd8rEPvJ2YzAu6o00Xptyl5SvSOizQsBfgzF1YOEfFTYTC7MEx5AQCA== X-OriginatorOrg: cavium.com X-MS-Exchange-CrossTenant-OriginalArrivalTime: 16 Feb 2017 01:01:27.7302 (UTC) X-MS-Exchange-CrossTenant-FromEntityHeader: Hosted X-MS-Exchange-Transport-CrossTenantHeadersStamped: CY1PR0701MB1979 Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org For an already existing irqdomain hierarchy, as might be obtained via a call to pci_enable_msix(), a PCI driver wishing to add an additional irqdomain to the hierarchy needs to be able to insert the irqdomain to that already initialized hierarchy. Calling irq_domain_create_hierarchy() allows the new irqdomain to be created, but no existing code allows for initializing the associated irq_data. Add a couple of helper functions (irq_domain_push_irq() irq_domain_pop_irq()) to initialize the irq_data for the new irqdomain. Signed-off-by: David Daney --- include/linux/irqdomain.h | 3 + kernel/irq/irqdomain.c | 137 ++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 140 insertions(+) diff --git a/include/linux/irqdomain.h b/include/linux/irqdomain.h index ffb8460..d8e60d1 100644 --- a/include/linux/irqdomain.h +++ b/include/linux/irqdomain.h @@ -418,6 +418,9 @@ extern void irq_domain_free_irqs_common(struct irq_domain *domain, extern void irq_domain_free_irqs_top(struct irq_domain *domain, unsigned int virq, unsigned int nr_irqs); +extern int irq_domain_push_irq(struct irq_domain *domain, int virq, void *arg); +extern int irq_domain_pop_irq(struct irq_domain *domain, int virq); + extern int irq_domain_alloc_irqs_parent(struct irq_domain *domain, unsigned int irq_base, unsigned int nr_irqs, void *arg); diff --git a/kernel/irq/irqdomain.c b/kernel/irq/irqdomain.c index b59e676..5266251 100644 --- a/kernel/irq/irqdomain.c +++ b/kernel/irq/irqdomain.c @@ -1279,6 +1279,143 @@ int __irq_domain_alloc_irqs(struct irq_domain *domain, int irq_base, return ret; } +/* The irq_data was moved, fix the revmap to refer to the new location */ +static void irq_domain_fix_revmap(struct irq_data *d) +{ + void **slot; + + if (d->hwirq < d->domain->revmap_size) + return; /* Not using radix tree. */ + + /* Fix up the revmap. */ + mutex_lock(&revmap_trees_mutex); + slot = radix_tree_lookup_slot(&d->domain->revmap_tree, d->hwirq); + if (slot) + radix_tree_replace_slot(&d->domain->revmap_tree, slot, d); + mutex_unlock(&revmap_trees_mutex); +} + +/** + * irq_domain_push_irq() - Push a domain in to the top of a hierarchy. + * @domain: Domain to push. + * @virq: Irq to push the domain in to. + * @arg: Passed to the irq_domain_ops alloc() function. + * + * For an already existing irqdomain hierarchy, as might be obtained + * via a call to pci_enable_msix(), add an additional domain to the + * head of the processing chain. + */ +int irq_domain_push_irq(struct irq_domain *domain, int virq, void *arg) +{ + struct irq_data *child_irq_data; + struct irq_data *root_irq_data = irq_get_irq_data(virq); + + if (domain == NULL) + return -EINVAL; + + if (WARN_ON(!domain->ops->alloc)) + return -ENOSYS; + + if (!root_irq_data) + return -EINVAL; + + child_irq_data = kzalloc_node(sizeof(*child_irq_data), GFP_KERNEL, + irq_data_get_node(root_irq_data)); + if (!child_irq_data) + return -ENOMEM; + + mutex_lock(&irq_domain_mutex); + + /* Copy the original irq_data. */ + *child_irq_data = *root_irq_data; + + irq_domain_fix_revmap(child_irq_data); + + /* + * Overwrite the root_irq_data, which is embedded in struct + * irq_desc, with values for this domain. + */ + root_irq_data->parent_data = child_irq_data; + root_irq_data->domain = domain; + root_irq_data->mask = 0; + root_irq_data->hwirq = 0; + root_irq_data->chip = NULL; + root_irq_data->chip_data = NULL; + domain->ops->alloc(domain, virq, 1, arg); + + if (root_irq_data->hwirq < domain->revmap_size) { + domain->linear_revmap[root_irq_data->hwirq] = virq; + } else { + mutex_lock(&revmap_trees_mutex); + radix_tree_insert(&domain->revmap_tree, + root_irq_data->hwirq, root_irq_data); + mutex_unlock(&revmap_trees_mutex); + } + + mutex_unlock(&irq_domain_mutex); + + return 0; +} +EXPORT_SYMBOL_GPL(irq_domain_push_irq); + +/** + * irq_domain_pop_irq() - Remove a domain from the top of a hierarchy. + * @domain: Domain to remove. + * @virq: Irq to remove the domain from. + * + * Undo the effects of a call to irq_domain_push_irq(). + */ +int irq_domain_pop_irq(struct irq_domain *domain, int virq) +{ + struct irq_data *root_irq_data = irq_get_irq_data(virq); + struct irq_data *child_irq_data; + struct irq_data *tmp_irq_data; + + if (domain == NULL) + return -EINVAL; + + if (!root_irq_data) + return -EINVAL; + + tmp_irq_data = irq_domain_get_irq_data(domain, virq); + + /* We can only "pop" if this domain is at the top of the list */ + if (WARN_ON(root_irq_data != tmp_irq_data)) + return -ENOSYS; + + if (WARN_ON(root_irq_data->domain != domain)) + return -ENOSYS; + + child_irq_data = root_irq_data->parent_data; + if (WARN_ON(!child_irq_data)) + return -ENOSYS; + + mutex_lock(&irq_domain_mutex); + + root_irq_data->parent_data = NULL; + + if (root_irq_data->hwirq >= domain->revmap_size) { + mutex_lock(&revmap_trees_mutex); + radix_tree_delete(&domain->revmap_tree, root_irq_data->hwirq); + mutex_unlock(&revmap_trees_mutex); + } + + if (domain->ops->free) + domain->ops->free(domain, virq, 1); + + /* Restore the original irq_data. */ + *root_irq_data = *child_irq_data; + + irq_domain_fix_revmap(root_irq_data); + + mutex_unlock(&irq_domain_mutex); + + kfree(child_irq_data); + + return 0; +} +EXPORT_SYMBOL_GPL(irq_domain_pop_irq); + /** * irq_domain_free_irqs - Free IRQ number and associated data structures * @virq: base IRQ number -- 1.8.3.1