From: Thomas Gleixner <tglx@linutronix.de>
To: Herve Codina <herve.codina@bootlin.com>,
Simon Horman <horms@kernel.org>,
Sai Krishna Gajula <saikrishnag@marvell.com>,
Herve Codina <herve.codina@bootlin.com>,
Rob Herring <robh@kernel.org>,
Krzysztof Kozlowski <krzk+dt@kernel.org>,
Conor Dooley <conor+dt@kernel.org>,
"David S. Miller" <davem@davemloft.net>,
Eric Dumazet <edumazet@google.com>,
Jakub Kicinski <kuba@kernel.org>, Paolo Abeni <pabeni@redhat.com>,
Lee Jones <lee@kernel.org>, Arnd Bergmann <arnd@arndb.de>,
Horatiu Vultur <horatiu.vultur@microchip.com>,
UNGLinuxDriver@microchip.com, Andrew Lunn <andrew@lunn.ch>,
Heiner Kallweit <hkallweit1@gmail.com>,
Russell King <linux@armlinux.org.uk>,
Saravana Kannan <saravanak@google.com>,
Bjorn Helgaas <bhelgaas@google.com>,
Philipp Zabel <p.zabel@pengutronix.de>,
Lars Povlsen <lars.povlsen@microchip.com>,
Steen Hegelund <Steen.Hegelund@microchip.com>,
Daniel Machon <daniel.machon@microchip.com>,
Alexandre Belloni <alexandre.belloni@bootlin.com>
Cc: linux-kernel@vger.kernel.org, devicetree@vger.kernel.org,
netdev@vger.kernel.org, linux-pci@vger.kernel.org,
linux-arm-kernel@lists.infradead.org,
Allan Nielsen <allan.nielsen@microchip.com>,
Steen Hegelund <steen.hegelund@microchip.com>,
Luca Ceresoli <luca.ceresoli@bootlin.com>,
Thomas Petazzoni <thomas.petazzoni@bootlin.com>
Subject: Re: [PATCH v2 10/19] irqdomain: Introduce irq_domain_alloc() and irq_domain_publish()
Date: Wed, 05 Jun 2024 15:02:46 +0200 [thread overview]
Message-ID: <8734pr5yq1.ffs@tglx> (raw)
In-Reply-To: <20240527161450.326615-11-herve.codina@bootlin.com>
On Mon, May 27 2024 at 18:14, Herve Codina wrote:
> The irq_domain_add_*() family functions create an irq_domain and also
> publish this newly created to domain. Once an irq_domain is published,
> consumers can request IRQ in order to use them.
>
> Some interrupt controller drivers have to perform some more operations
> with the created irq_domain in order to have it ready to be used.
> For instance:
> - Allocate generic irq chips with irq_alloc_domain_generic_chips()
> - Retrieve the generic irq chips with irq_get_domain_generic_chip()
> - Initialize retrieved chips: set register base address and offsets,
> set several hooks such as irq_mask, irq_unmask, ...
>
> To avoid a window where the domain is published but not yet ready to be
I can see the point, but why is this suddenly a problem? There are tons
of interrupt chip drivers which have exactly that pattern.
Also why is all of this burried in a series which aims to add a network
driver and touches the world and some more. If you had sent the two irq
domain patches seperately w/o spamming 100 people on CC then this would
have been solved long ago. That's documented clearly, no?
> void irq_domain_free_fwnode(struct fwnode_handle *fwnode);
> +struct irq_domain *irq_domain_alloc(struct fwnode_handle *fwnode, unsigned int size,
> + irq_hw_number_t hwirq_max, int direct_max,
> + const struct irq_domain_ops *ops,
> + void *host_data);
> +
> +static inline struct irq_domain *irq_domain_alloc_linear(struct fwnode_handle *fwnode,
> + unsigned int size,
> + const struct irq_domain_ops *ops,
> + void *host_data)
> +{
> + return irq_domain_alloc(fwnode, size, size, 0, ops, host_data);
> +}
So this creates exactly one wrapper, which means we'll grow another ton
of wrappers if that becomes popular for whatever reason. We have already
too many of variants for creating domains.
But what's worse is that this does not work for hierarchical domains and
is just an ad hoc scratch my itch solution.
Also looking at the irq chip drivers which use generic interrupt
chips. There are 24 instances of irq_alloc_domain_generic_chips() and
most of this code is just boilerplate.
So what we really want is a proper solution to get rid of this mess
instead of creating interfaces which just proliferate and extend it.
Something like the uncompiled below allows to convert all the
boilerplate into a template based setup/remove.
I just converted a random driver over to it and the result is pretty
neutral in terms of lines, but the amount of code to get wrong is
significantly smaller. I'm sure that more complex drivers will benefit
even more and your problem should be completely solved by that.
The below is just an initial sketch which allows further consolidation
in the irqdomain space. You get the idea.
Thanks,
tglx
---
--- a/include/linux/irq.h
+++ b/include/linux/irq.h
@@ -1106,6 +1106,7 @@ enum irq_gc_flags {
* @irq_flags_to_set: IRQ* flags to set on irq setup
* @irq_flags_to_clear: IRQ* flags to clear on irq setup
* @gc_flags: Generic chip specific setup flags
+ * FIXME
* @gc: Array of pointers to generic interrupt chips
*/
struct irq_domain_chip_generic {
@@ -1114,9 +1115,26 @@ struct irq_domain_chip_generic {
unsigned int irq_flags_to_clear;
unsigned int irq_flags_to_set;
enum irq_gc_flags gc_flags;
+ void (*destroy)(struct irq_chip_generic *c);
struct irq_chip_generic *gc[];
};
+/**
+ * irq_domain_chip_generic_info - Init structure
+ * FIXME
+ */
+struct irq_domain_chip_generic_info {
+ const char *name;
+ irq_flow_handler_t handler;
+ void (*init)(struct irq_chip_generic *d);
+ void (*destroy)(struct irq_chip_generic *c);
+ unsigned int irqs_per_chip;
+ unsigned int num_chips;
+ unsigned int irq_flags_to_clear;
+ unsigned int irq_flags_to_set;
+ enum irq_gc_flags gc_flags;
+};
+
/* Generic chip callback functions */
void irq_gc_noop(struct irq_data *d);
void irq_gc_mask_disable_reg(struct irq_data *d);
@@ -1153,6 +1171,9 @@ int devm_irq_setup_generic_chip(struct d
struct irq_chip_generic *irq_get_domain_generic_chip(struct irq_domain *d, unsigned int hw_irq);
+int irq_domain_alloc_generic_chips(struct irq_domain *d, struct irq_domain_chip_generic_info *info);
+void irq_domain_remove_generic_chips(struct irq_domain *d);
+
int __irq_alloc_domain_generic_chips(struct irq_domain *d, int irqs_per_chip,
int num_ct, const char *name,
irq_flow_handler_t handler,
--- a/include/linux/irqdomain.h
+++ b/include/linux/irqdomain.h
@@ -41,13 +41,13 @@ struct device_node;
struct fwnode_handle;
struct irq_domain;
struct irq_chip;
+struct irq_chip_generic;
struct irq_data;
struct irq_desc;
struct cpumask;
struct seq_file;
struct irq_affinity_desc;
struct msi_parent_ops;
-
#define IRQ_DOMAIN_IRQ_SPEC_PARAMS 16
/**
@@ -169,6 +169,7 @@ struct irq_domain {
#ifdef CONFIG_GENERIC_MSI_IRQ
const struct msi_parent_ops *msi_parent_ops;
#endif
+ void (*destroy)(struct irq_domain *d);
/* reverse map data. The linear map gets appended to the irq_domain */
irq_hw_number_t hwirq_max;
@@ -208,6 +209,9 @@ enum {
/* Irq domain is a MSI device domain */
IRQ_DOMAIN_FLAG_MSI_DEVICE = (1 << 9),
+ /* Irq domain must destroy generic chips when removed */
+ IRQ_DOMAIN_FLAG_DESTROY_GC = (1 << 10),
+
/*
* Flags starting from IRQ_DOMAIN_FLAG_NONCORE are reserved
* for implementation specific purposes and ignored by the
@@ -257,6 +261,28 @@ static inline struct fwnode_handle *irq_
}
void irq_domain_free_fwnode(struct fwnode_handle *fwnode);
+
+struct irq_domain_chip_generic_info;
+
+/**
+ * irq_domain_info - Init structure
+ * FIXME
+ */
+struct irq_domain_info {
+ struct fwnode_handle *fwnode;
+ unsigned int domain_flags;
+ unsigned int size;
+ irq_hw_number_t hwirq_max;
+ int direct_max;
+ enum irq_domain_bus_token bus_token;
+ const struct irq_domain_ops *ops;
+ void *host_data;
+ struct irq_domain_chip_generic_info *gc_info;
+ void (*init)(struct irq_domain *d);
+};
+
+struct irq_domain *irq_domain_instantiate(struct irq_domain_info *info);
+
struct irq_domain *__irq_domain_add(struct fwnode_handle *fwnode, unsigned int size,
irq_hw_number_t hwirq_max, int direct_max,
const struct irq_domain_ops *ops,
--- a/kernel/irq/generic-chip.c
+++ b/kernel/irq/generic-chip.c
@@ -274,23 +274,11 @@ irq_gc_init_mask_cache(struct irq_chip_g
*mskptr = irq_reg_readl(gc, mskreg);
}
}
-
/**
- * __irq_alloc_domain_generic_chips - Allocate generic chips for an irq domain
- * @d: irq domain for which to allocate chips
- * @irqs_per_chip: Number of interrupts each chip handles (max 32)
- * @num_ct: Number of irq_chip_type instances associated with this
- * @name: Name of the irq chip
- * @handler: Default flow handler associated with these chips
- * @clr: IRQ_* bits to clear in the mapping function
- * @set: IRQ_* bits to set in the mapping function
- * @gcflags: Generic chip specific setup flags
+ * irq_domain_alloc_generic_chips - Allocate generic chips for an irq domain
+ * FIXME
*/
-int __irq_alloc_domain_generic_chips(struct irq_domain *d, int irqs_per_chip,
- int num_ct, const char *name,
- irq_flow_handler_t handler,
- unsigned int clr, unsigned int set,
- enum irq_gc_flags gcflags)
+int irq_domain_alloc_generic_chips(struct irq_domain *d, struct irq_domain_chip_generic_info *info)
{
struct irq_domain_chip_generic *dgc;
struct irq_chip_generic *gc;
@@ -304,23 +292,24 @@ int __irq_alloc_domain_generic_chips(str
if (d->gc)
return -EBUSY;
- numchips = DIV_ROUND_UP(d->revmap_size, irqs_per_chip);
+ numchips = DIV_ROUND_UP(d->revmap_size, info->irqs_per_chip);
if (!numchips)
return -EINVAL;
/* Allocate a pointer, generic chip and chiptypes for each chip */
- gc_sz = struct_size(gc, chip_types, num_ct);
+ gc_sz = struct_size(gc, chip_types, info->num_ct);
dgc_sz = struct_size(dgc, gc, numchips);
sz = dgc_sz + numchips * gc_sz;
tmp = dgc = kzalloc(sz, GFP_KERNEL);
if (!dgc)
return -ENOMEM;
- dgc->irqs_per_chip = irqs_per_chip;
+ dgc->irqs_per_chip = info->irqs_per_chip;
dgc->num_chips = numchips;
- dgc->irq_flags_to_set = set;
- dgc->irq_flags_to_clear = clr;
- dgc->gc_flags = gcflags;
+ dgc->irq_flags_to_set = info->irq_flags_to_set;
+ dgc->irq_flags_to_clear = info->irq_flags_to_clear;
+ dgc->gc_flags = info->gcflags;
+ dgc->destroy = info->destroy;
d->gc = dgc;
/* Calc pointer to the first generic chip */
@@ -337,6 +326,9 @@ int __irq_alloc_domain_generic_chips(str
gc->reg_writel = &irq_writel_be;
}
+ if (info->init)
+ info->init(gc);
+
raw_spin_lock_irqsave(&gc_lock, flags);
list_add_tail(&gc->list, &gc_list);
raw_spin_unlock_irqrestore(&gc_lock, flags);
@@ -345,6 +337,56 @@ int __irq_alloc_domain_generic_chips(str
}
return 0;
}
+
+/**
+ * irq_domain_remove_generic_chips - Remove generic chips from an interrupt domain
+ * FIXME
+ */
+void irq_domain_remove_generic_chips(struct irq_domain *d)
+{
+ struct irq_domain_chip_generic *dgc = d->gc;
+ struct irq_domain_ops *ops = d->ops;
+
+ if (!dgc)
+ return;
+
+ for (unsigned int i = 0; i < dgc->num_chips, i++) {
+ if (dgc->destroy)
+ dgc->destroy_gc(dgc->gc + i);
+ irq_remove_generic_chip(dgc->gc + i, ~0U, 0, 0);
+ }
+ d->dgc = NULL;
+ kfree(dgc);
+}
+
+/**
+ * __irq_alloc_domain_generic_chips - Allocate generic chips for an irq domain
+ * @d: irq domain for which to allocate chips
+ * @irqs_per_chip: Number of interrupts each chip handles (max 32)
+ * @num_ct: Number of irq_chip_type instances associated with this
+ * @name: Name of the irq chip
+ * @handler: Default flow handler associated with these chips
+ * @clr: IRQ_* bits to clear in the mapping function
+ * @set: IRQ_* bits to set in the mapping function
+ * @gcflags: Generic chip specific setup flags
+ */
+int __irq_alloc_domain_generic_chips(struct irq_domain *d, int irqs_per_chip,
+ int num_ct, const char *name,
+ irq_flow_handler_t handler,
+ unsigned int clr, unsigned int set,
+ enum irq_gc_flags gcflags)
+{
+ struct irq_domain_chip_generic_info info = {
+ .name = name,
+ .handler = handler,
+ .irqs_per_chip = irqs_per_chip,
+ .irq_flags_to_set = set,
+ .irq_flags_to_clear = clr,
+ .gc_flags = gcflags,
+ };
+
+ return irq_domain_alloc_generic_chips(d, &info);
+}
EXPORT_SYMBOL_GPL(__irq_alloc_domain_generic_chips);
static struct irq_chip_generic *
--- a/kernel/irq/irqdomain.c
+++ b/kernel/irq/irqdomain.c
@@ -240,6 +240,47 @@ static void __irq_domain_publish(struct
pr_debug("Added domain %s\n", domain->name);
}
+static void irq_domain_free(struct irq_domain *domain)
+{
+ fwnode_dev_initialized(domain->fwnode, false);
+ fwnode_handle_put(domain->fwnode);
+ if (domain->flags & IRQ_DOMAIN_NAME_ALLOCATED)
+ kfree(domain->name);
+ kfree(domain);
+}
+
+/**
+ * irq_domain_instantiate() - Instantiate a new irq_domain data structure
+ * FIXME
+ */
+struct irq_domain *irq_domain_instantiate(struct irq_domain_info *info)
+{
+ struct irq_domain *domain;
+
+ // FIXME: Convert irq_domain_create() to use @info
+ domain = __irq_domain_create(info->fwnode, info->size, info->hwirq_max, info->direct_max,
+ info->ops, info->host_data);
+ if (!domain)
+ return NULL;
+
+ domain->flags |= info->domain_flags;
+
+ if (info->gc_info) {
+ if (!irq_domain_alloc_generic_chips(domain, info->gc_info)) {
+ irq_domain_remove(domain);
+ return NULL;
+ }
+ }
+ if (info->init)
+ info->init(domain);
+ __irq_domain_publish(domain);
+
+ // FIXME: Make this part of irq_domain_create()
+ if (info->bus_token)
+ irq_domain_update_bus_token(domain, info->bus_token);
+ return domain;
+}
+
/**
* __irq_domain_add() - Allocate a new irq_domain data structure
* @fwnode: firmware node for the interrupt controller
@@ -279,6 +320,9 @@ EXPORT_SYMBOL_GPL(__irq_domain_add);
*/
void irq_domain_remove(struct irq_domain *domain)
{
+ if (domain->destroy)
+ domain->destroy(domain);
+
mutex_lock(&irq_domain_mutex);
debugfs_remove_domain_dir(domain);
@@ -294,13 +338,11 @@ void irq_domain_remove(struct irq_domain
mutex_unlock(&irq_domain_mutex);
- pr_debug("Removed domain %s\n", domain->name);
+ if (domain->flags & IRQ_DOMAIN_FLAG_DESTROY_GC)
+ irq_domain_remove_generic_chips(domain);
- fwnode_dev_initialized(domain->fwnode, false);
- fwnode_handle_put(domain->fwnode);
- if (domain->flags & IRQ_DOMAIN_NAME_ALLOCATED)
- kfree(domain->name);
- kfree(domain);
+ pr_debug("Removed domain %s\n", domain->name);
+ irq_domain_free(domain);
}
EXPORT_SYMBOL_GPL(irq_domain_remove);
--- a/drivers/irqchip/irq-al-fic.c
+++ b/drivers/irqchip/irq-al-fic.c
@@ -133,32 +133,10 @@ static int al_fic_irq_retrigger(struct i
return 1;
}
-static int al_fic_register(struct device_node *node,
- struct al_fic *fic)
+static void al_fic_gc_init(struct irq_chip_generic *gc)
{
- struct irq_chip_generic *gc;
- int ret;
+ struct al_fic *fic = gc->domain->host_data;
- fic->domain = irq_domain_add_linear(node,
- NR_FIC_IRQS,
- &irq_generic_chip_ops,
- fic);
- if (!fic->domain) {
- pr_err("fail to add irq domain\n");
- return -ENOMEM;
- }
-
- ret = irq_alloc_domain_generic_chips(fic->domain,
- NR_FIC_IRQS,
- 1, fic->name,
- handle_level_irq,
- 0, 0, IRQ_GC_INIT_MASK_CACHE);
- if (ret) {
- pr_err("fail to allocate generic chip (%d)\n", ret);
- goto err_domain_remove;
- }
-
- gc = irq_get_domain_generic_chip(fic->domain, 0);
gc->reg_base = fic->base;
gc->chip_types->regs.mask = AL_FIC_MASK;
gc->chip_types->regs.ack = AL_FIC_CAUSE;
@@ -169,16 +147,37 @@ static int al_fic_register(struct device
gc->chip_types->chip.irq_retrigger = al_fic_irq_retrigger;
gc->chip_types->chip.flags = IRQCHIP_SKIP_SET_WAKE;
gc->private = fic;
+}
+
+static void al_fic_domain_init(struct irq_domain *d)
+{
+ struct al_fic *fic = d->host_data;
- irq_set_chained_handler_and_data(fic->parent_irq,
- al_fic_irq_handler,
- fic);
- return 0;
+ irq_set_chained_handler_and_data(fic->parent_irq, al_fic_irq_handler, fic);
+}
-err_domain_remove:
- irq_domain_remove(fic->domain);
+static int al_fic_register(struct device_node *node, struct al_fic *fic)
+{
+ struct irq_domain_chip_generic_info gc_info = {
+ .irqs_per_chip = NR_FIC_IRQS,
+ .num_chips = 1,
+ .name = fic->name,
+ .handler = handle_level_irq,
+ .gc_flags = IRQ_GC_INIT_MASK_CACHE,
+ .init = al_fic_gc_init,
+ };
+ struct irq_domain_info info = {
+ .fwnode = of_node_to_fwnode(node),
+ .size = NR_FIC_IRQS,
+ .hwirq_max = NR_FIC_IRQS,
+ .ops = &irq_generic_chip_ops,
+ .host_data = fic,
+ .gc_info = &gc_info,
+ .init = al_fic_domain_init,
+ };
- return ret;
+ fic->domain = irq_domain_instantiate(&info);
+ return fic->domain ? 0 : -ENOMEM;
}
/*
next prev parent reply other threads:[~2024-06-05 13:02 UTC|newest]
Thread overview: 54+ messages / expand[flat|nested] mbox.gz Atom feed top
2024-05-27 16:14 [PATCH v2 00/19] Add support for the LAN966x PCI device using a DT overlay Herve Codina
2024-05-27 16:14 ` [PATCH v2 01/19] mfd: syscon: Add reference counting and device managed support Herve Codina
2024-06-18 14:53 ` Arnd Bergmann
2024-06-18 15:55 ` Herve Codina
2024-05-27 16:14 ` [PATCH v2 02/19] reset: mchp: sparx5: Remove dependencies and allow building as a module Herve Codina
2024-05-27 16:14 ` [PATCH v2 03/19] reset: mchp: sparx5: Release syscon when not use anymore Herve Codina
2024-05-27 16:14 ` [PATCH v2 04/19] reset: core: add get_device()/put_device on rcdev Herve Codina
2024-05-27 16:14 ` [PATCH v2 05/19] reset: mchp: sparx5: set the dev member of the reset controller Herve Codina
2024-05-27 16:14 ` [PATCH v2 06/19] dt-bindings: net: mscc-miim: Add resets property Herve Codina
2024-05-27 19:14 ` Andrew Lunn
2024-05-28 6:44 ` Krzysztof Kozlowski
2024-05-27 16:14 ` [PATCH v2 07/19] net: mdio: mscc-miim: Handle the switch reset Herve Codina
2024-05-27 19:16 ` Andrew Lunn
2024-05-27 16:14 ` [PATCH v2 08/19] dt-bindings: interrupt-controller: Add support for Microchip LAN966x OIC Herve Codina
2024-05-27 16:14 ` [PATCH v2 09/19] irqdomain: Add missing parameter descriptions in docs Herve Codina
2024-06-04 19:02 ` Thomas Gleixner
2024-06-05 20:02 ` Andy Shevchenko
2024-06-06 7:14 ` Herve Codina
2024-06-06 8:46 ` Andy Shevchenko
2024-06-06 10:16 ` Herve Codina
2024-05-27 16:14 ` [PATCH v2 10/19] irqdomain: Introduce irq_domain_alloc() and irq_domain_publish() Herve Codina
2024-06-04 19:59 ` Thomas Gleixner
2024-06-05 13:02 ` Thomas Gleixner [this message]
2024-06-06 15:52 ` Herve Codina
2024-06-06 18:11 ` Thomas Gleixner
2024-06-07 8:06 ` Herve Codina
2024-05-27 16:14 ` [PATCH v2 11/19] irqchip: Add support for LAN966x OIC Herve Codina
2024-06-05 14:17 ` Thomas Gleixner
2024-06-05 20:14 ` Andy Shevchenko
2024-06-06 15:53 ` Herve Codina
2024-05-27 16:14 ` [PATCH v2 12/19] MAINTAINERS: Add the Microchip LAN966x OIC driver entry Herve Codina
2024-05-27 16:14 ` [PATCH v2 13/19] of: dynamic: Constify parameter in of_changeset_add_prop_string_array() Herve Codina
2024-05-27 16:14 ` [PATCH v2 14/19] of: unittest: Add tests for changeset properties adding Herve Codina
2024-05-27 16:14 ` [PATCH v2 15/19] of: dynamic: Introduce of_changeset_add_prop_bool() Herve Codina
2024-05-27 16:14 ` [PATCH v2 16/19] of: unittest: Add a test case for of_changeset_add_prop_bool() Herve Codina
2024-05-27 16:14 ` [PATCH v2 17/19] PCI: of_property: Add interrupt-controller property in PCI device nodes Herve Codina
2024-06-06 19:26 ` Bjorn Helgaas
2024-06-10 21:37 ` Rob Herring
2024-06-11 17:13 ` Bjorn Helgaas
2024-05-27 16:14 ` [PATCH v2 18/19] mfd: Add support for LAN966x PCI device Herve Codina
2024-06-05 20:24 ` Andy Shevchenko
[not found] ` <20240620175646.24455efb@bootlin.com>
2024-06-20 16:43 ` Herve Codina
[not found] ` <CAHp75VdDkv-dxWa60=OLfXAQ8T5CkFiKALbDHaVVKQOK3gJehA@mail.gmail.com>
2024-06-20 16:43 ` Herve Codina
2024-06-20 17:19 ` Herve Codina
2024-06-21 15:45 ` Andy Shevchenko
2024-06-21 18:49 ` Bjorn Helgaas
2024-06-24 11:46 ` Steen Hegelund
2024-06-26 6:52 ` Herve Codina
2024-06-26 7:17 ` Steen Hegelund
2024-06-24 8:20 ` Herve Codina
2024-06-05 21:34 ` Bjorn Helgaas
2024-05-27 16:14 ` [PATCH v2 19/19] MAINTAINERS: Add the Microchip LAN966x PCI driver entry Herve Codina
2024-05-30 0:08 ` [PATCH v2 00/19] Add support for the LAN966x PCI device using a DT overlay Jakub Kicinski
2024-06-11 19:33 ` Rob Herring
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=8734pr5yq1.ffs@tglx \
--to=tglx@linutronix.de \
--cc=Steen.Hegelund@microchip.com \
--cc=UNGLinuxDriver@microchip.com \
--cc=alexandre.belloni@bootlin.com \
--cc=allan.nielsen@microchip.com \
--cc=andrew@lunn.ch \
--cc=arnd@arndb.de \
--cc=bhelgaas@google.com \
--cc=conor+dt@kernel.org \
--cc=daniel.machon@microchip.com \
--cc=davem@davemloft.net \
--cc=devicetree@vger.kernel.org \
--cc=edumazet@google.com \
--cc=herve.codina@bootlin.com \
--cc=hkallweit1@gmail.com \
--cc=horatiu.vultur@microchip.com \
--cc=horms@kernel.org \
--cc=krzk+dt@kernel.org \
--cc=kuba@kernel.org \
--cc=lars.povlsen@microchip.com \
--cc=lee@kernel.org \
--cc=linux-arm-kernel@lists.infradead.org \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-pci@vger.kernel.org \
--cc=linux@armlinux.org.uk \
--cc=luca.ceresoli@bootlin.com \
--cc=netdev@vger.kernel.org \
--cc=p.zabel@pengutronix.de \
--cc=pabeni@redhat.com \
--cc=robh@kernel.org \
--cc=saikrishnag@marvell.com \
--cc=saravanak@google.com \
--cc=thomas.petazzoni@bootlin.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).