From: Thomas Gleixner <tglx@linutronix.de>
To: Chen Wang <unicornxw@gmail.com>,
u.kleine-koenig@baylibre.com, aou@eecs.berkeley.edu,
arnd@arndb.de, unicorn_wang@outlook.com, conor+dt@kernel.org,
guoren@kernel.org, inochiama@outlook.com, krzk+dt@kernel.org,
palmer@dabbelt.com, paul.walmsley@sifive.com, robh@kernel.org,
devicetree@vger.kernel.org, linux-kernel@vger.kernel.org,
linux-riscv@lists.infradead.org, chao.wei@sophgo.com,
xiaoguang.xing@sophgo.com, fengchun.li@sophgo.com
Subject: Re: [PATCH 2/3] irqchip: Add the Sophgo SG2042 MSI interrupt controller
Date: Wed, 13 Nov 2024 07:14:52 +0100 [thread overview]
Message-ID: <87cyizmzhf.ffs@tglx> (raw)
In-Reply-To: <8076fe2af9f2b007a42c986ed193ba50ff674bfa.1731296803.git.unicorn_wang@outlook.com>
On Mon, Nov 11 2024 at 12:01, Chen Wang wrote:
> +struct sg2042_msi_data {
> + void __iomem *reg_clr; /* clear reg, see TRM, 10.1.33, GP_INTR0_CLR */
Please make these tail comments tabular aligned so they actually stand
out.
https://www.kernel.org/doc/html/latest/process/maintainer-tip.html#comment-style
> +
> + u64 doorbell_addr; /* see TRM, 10.1.32, GP_INTR0_SET */
> +
> + u32 irq_first; /* The vector number that MSIs starts */
> + u32 num_irqs; /* The number of vectors for MSIs */
> +
> + unsigned long *msi_map;
> + struct mutex msi_map_lock; /* lock for msi_map */
> +};
> +
> +static int sg2042_msi_allocate_hwirq(struct sg2042_msi_data *priv, int num_req)
> +{
> + int first;
> +
> + mutex_lock(&priv->msi_map_lock);
Please use
guard(mutex)(&priv->msi_map_lock);
which removes all the mutex_unlock() hackery and boils this down
> +
> + first = bitmap_find_free_region(priv->msi_map, priv->num_irqs,
> + get_count_order(num_req));
> + if (first < 0) {
> + mutex_unlock(&priv->msi_map_lock);
> + return -ENOSPC;
> + }
> +
> + mutex_unlock(&priv->msi_map_lock);
> +
> + return priv->irq_first + first;
to
guard(mutex)(&priv->msi_map_lock);
first = bitmap_find_free_region(priv->msi_map, priv->num_irqs,
get_count_order(num_req));
return first >= 0 ? priv->irq_first + first : -ENOSPC;
See?
> +}
> +
> +static void sg2042_msi_free_hwirq(struct sg2042_msi_data *priv,
> + int hwirq, int num_req)
> +{
> + int first = hwirq - priv->irq_first;
> +
> + mutex_lock(&priv->msi_map_lock);
Ditto.
> + bitmap_release_region(priv->msi_map, first, get_count_order(num_req));
> + mutex_unlock(&priv->msi_map_lock);
> +}
> +static void sg2042_msi_irq_compose_msi_msg(struct irq_data *data,
> + struct msi_msg *msg)
> +{
> + struct sg2042_msi_data *priv = irq_data_get_irq_chip_data(data);
> +
> + msg->address_hi = upper_32_bits(priv->doorbell_addr);
> + msg->address_lo = lower_32_bits(priv->doorbell_addr);
> + msg->data = 1 << (data->hwirq - priv->irq_first);
> +
> + pr_debug("%s hwirq[%d]: address_hi[%#x], address_lo[%#x], data[%#x]\n",
> + __func__,
No point in having this line break. You have 100 characters. Please fix
this all over the place.
> + (int)data->hwirq, msg->address_hi, msg->address_lo, msg->data);
(int) ? Why can't you use the proper conversion specifier instead of %d?
> +static int sg2042_msi_middle_domain_alloc(struct irq_domain *domain,
> + unsigned int virq,
> + unsigned int nr_irqs, void *args)
> +{
> + struct sg2042_msi_data *priv = domain->host_data;
> + int hwirq, err, i;
> +
> + hwirq = sg2042_msi_allocate_hwirq(priv, nr_irqs);
> + if (hwirq < 0)
> + return hwirq;
> +
> + for (i = 0; i < nr_irqs; i++) {
> + err = sg2042_msi_parent_domain_alloc(domain, virq + i, hwirq + i);
> + if (err)
> + goto err_hwirq;
> +
> + pr_debug("%s: virq[%d], hwirq[%d]\n",
> + __func__, virq + i, (int)hwirq + i);
No line break required.
> + irq_domain_set_hwirq_and_chip(domain, virq + i, hwirq + i,
> + &sg2042_msi_middle_irq_chip, priv);
> + }
> +static int sg2042_msi_init_domains(struct sg2042_msi_data *priv,
> + struct device_node *node)
> +{
> + struct irq_domain *plic_domain, *middle_domain;
> + struct device_node *plic_node;
> + struct fwnode_handle *fwnode = of_node_to_fwnode(node);
https://www.kernel.org/doc/html/latest/process/maintainer-tip.html#variable-declarations
> + if (!of_find_property(node, "interrupt-parent", NULL)) {
> + pr_err("Can't find interrupt-parent!\n");
> + return -EINVAL;
> + }
> +
> + plic_node = of_irq_find_parent(node);
> + if (!plic_node) {
> + pr_err("Failed to find the PLIC node!\n");
> + return -ENXIO;
> + }
> +
> + plic_domain = irq_find_host(plic_node);
> + of_node_put(plic_node);
> + if (!plic_domain) {
> + pr_err("Failed to find the PLIC domain\n");
> + return -ENXIO;
> + }
> +
> + middle_domain = irq_domain_create_hierarchy(plic_domain, 0, priv->num_irqs,
> + fwnode,
> + &pch_msi_middle_domain_ops,
> + priv);
So now you have created a domain. How is that supposed to be used by the
PCI layer?
> + if (!middle_domain) {
> + pr_err("Failed to create the MSI middle domain\n");
> + return -ENOMEM;
> + }
> +
> + return 0;
> +}
> +static int sg2042_msi_probe(struct platform_device *pdev)
> +{
....
> + data->msi_map = bitmap_zalloc(data->num_irqs, GFP_KERNEL);
> + if (!data->msi_map)
> + return -ENOMEM;
> +
> + return sg2042_msi_init_domains(data, pdev->dev.of_node);
In case of error this leaks data->msi_map, no?
> +static struct platform_driver sg2042_msi_driver = {
> + .driver = {
> + .name = "sg2042-msi",
> + .of_match_table = of_match_ptr(sg2042_msi_of_match),
> + },
> + .probe = sg2042_msi_probe,
> +};
Please see the documentation I pointed you to above and search for
struct initializers.
Thanks,
tglx
_______________________________________________
linux-riscv mailing list
linux-riscv@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-riscv
WARNING: multiple messages have this Message-ID (diff)
From: Thomas Gleixner <tglx@linutronix.de>
To: Chen Wang <unicornxw@gmail.com>,
u.kleine-koenig@baylibre.com, aou@eecs.berkeley.edu,
arnd@arndb.de, unicorn_wang@outlook.com, conor+dt@kernel.org,
guoren@kernel.org, inochiama@outlook.com, krzk+dt@kernel.org,
palmer@dabbelt.com, paul.walmsley@sifive.com, robh@kernel.org,
devicetree@vger.kernel.org, linux-kernel@vger.kernel.org,
linux-riscv@lists.infradead.org, chao.wei@sophgo.com,
xiaoguang.xing@sophgo.com, fengchun.li@sophgo.com
Subject: Re: [PATCH 2/3] irqchip: Add the Sophgo SG2042 MSI interrupt controller
Date: Wed, 13 Nov 2024 07:14:52 +0100 [thread overview]
Message-ID: <87cyizmzhf.ffs@tglx> (raw)
In-Reply-To: <8076fe2af9f2b007a42c986ed193ba50ff674bfa.1731296803.git.unicorn_wang@outlook.com>
On Mon, Nov 11 2024 at 12:01, Chen Wang wrote:
> +struct sg2042_msi_data {
> + void __iomem *reg_clr; /* clear reg, see TRM, 10.1.33, GP_INTR0_CLR */
Please make these tail comments tabular aligned so they actually stand
out.
https://www.kernel.org/doc/html/latest/process/maintainer-tip.html#comment-style
> +
> + u64 doorbell_addr; /* see TRM, 10.1.32, GP_INTR0_SET */
> +
> + u32 irq_first; /* The vector number that MSIs starts */
> + u32 num_irqs; /* The number of vectors for MSIs */
> +
> + unsigned long *msi_map;
> + struct mutex msi_map_lock; /* lock for msi_map */
> +};
> +
> +static int sg2042_msi_allocate_hwirq(struct sg2042_msi_data *priv, int num_req)
> +{
> + int first;
> +
> + mutex_lock(&priv->msi_map_lock);
Please use
guard(mutex)(&priv->msi_map_lock);
which removes all the mutex_unlock() hackery and boils this down
> +
> + first = bitmap_find_free_region(priv->msi_map, priv->num_irqs,
> + get_count_order(num_req));
> + if (first < 0) {
> + mutex_unlock(&priv->msi_map_lock);
> + return -ENOSPC;
> + }
> +
> + mutex_unlock(&priv->msi_map_lock);
> +
> + return priv->irq_first + first;
to
guard(mutex)(&priv->msi_map_lock);
first = bitmap_find_free_region(priv->msi_map, priv->num_irqs,
get_count_order(num_req));
return first >= 0 ? priv->irq_first + first : -ENOSPC;
See?
> +}
> +
> +static void sg2042_msi_free_hwirq(struct sg2042_msi_data *priv,
> + int hwirq, int num_req)
> +{
> + int first = hwirq - priv->irq_first;
> +
> + mutex_lock(&priv->msi_map_lock);
Ditto.
> + bitmap_release_region(priv->msi_map, first, get_count_order(num_req));
> + mutex_unlock(&priv->msi_map_lock);
> +}
> +static void sg2042_msi_irq_compose_msi_msg(struct irq_data *data,
> + struct msi_msg *msg)
> +{
> + struct sg2042_msi_data *priv = irq_data_get_irq_chip_data(data);
> +
> + msg->address_hi = upper_32_bits(priv->doorbell_addr);
> + msg->address_lo = lower_32_bits(priv->doorbell_addr);
> + msg->data = 1 << (data->hwirq - priv->irq_first);
> +
> + pr_debug("%s hwirq[%d]: address_hi[%#x], address_lo[%#x], data[%#x]\n",
> + __func__,
No point in having this line break. You have 100 characters. Please fix
this all over the place.
> + (int)data->hwirq, msg->address_hi, msg->address_lo, msg->data);
(int) ? Why can't you use the proper conversion specifier instead of %d?
> +static int sg2042_msi_middle_domain_alloc(struct irq_domain *domain,
> + unsigned int virq,
> + unsigned int nr_irqs, void *args)
> +{
> + struct sg2042_msi_data *priv = domain->host_data;
> + int hwirq, err, i;
> +
> + hwirq = sg2042_msi_allocate_hwirq(priv, nr_irqs);
> + if (hwirq < 0)
> + return hwirq;
> +
> + for (i = 0; i < nr_irqs; i++) {
> + err = sg2042_msi_parent_domain_alloc(domain, virq + i, hwirq + i);
> + if (err)
> + goto err_hwirq;
> +
> + pr_debug("%s: virq[%d], hwirq[%d]\n",
> + __func__, virq + i, (int)hwirq + i);
No line break required.
> + irq_domain_set_hwirq_and_chip(domain, virq + i, hwirq + i,
> + &sg2042_msi_middle_irq_chip, priv);
> + }
> +static int sg2042_msi_init_domains(struct sg2042_msi_data *priv,
> + struct device_node *node)
> +{
> + struct irq_domain *plic_domain, *middle_domain;
> + struct device_node *plic_node;
> + struct fwnode_handle *fwnode = of_node_to_fwnode(node);
https://www.kernel.org/doc/html/latest/process/maintainer-tip.html#variable-declarations
> + if (!of_find_property(node, "interrupt-parent", NULL)) {
> + pr_err("Can't find interrupt-parent!\n");
> + return -EINVAL;
> + }
> +
> + plic_node = of_irq_find_parent(node);
> + if (!plic_node) {
> + pr_err("Failed to find the PLIC node!\n");
> + return -ENXIO;
> + }
> +
> + plic_domain = irq_find_host(plic_node);
> + of_node_put(plic_node);
> + if (!plic_domain) {
> + pr_err("Failed to find the PLIC domain\n");
> + return -ENXIO;
> + }
> +
> + middle_domain = irq_domain_create_hierarchy(plic_domain, 0, priv->num_irqs,
> + fwnode,
> + &pch_msi_middle_domain_ops,
> + priv);
So now you have created a domain. How is that supposed to be used by the
PCI layer?
> + if (!middle_domain) {
> + pr_err("Failed to create the MSI middle domain\n");
> + return -ENOMEM;
> + }
> +
> + return 0;
> +}
> +static int sg2042_msi_probe(struct platform_device *pdev)
> +{
....
> + data->msi_map = bitmap_zalloc(data->num_irqs, GFP_KERNEL);
> + if (!data->msi_map)
> + return -ENOMEM;
> +
> + return sg2042_msi_init_domains(data, pdev->dev.of_node);
In case of error this leaks data->msi_map, no?
> +static struct platform_driver sg2042_msi_driver = {
> + .driver = {
> + .name = "sg2042-msi",
> + .of_match_table = of_match_ptr(sg2042_msi_of_match),
> + },
> + .probe = sg2042_msi_probe,
> +};
Please see the documentation I pointed you to above and search for
struct initializers.
Thanks,
tglx
next prev parent reply other threads:[~2024-11-13 6:14 UTC|newest]
Thread overview: 20+ messages / expand[flat|nested] mbox.gz Atom feed top
2024-11-11 4:01 [PATCH 0/3] irqchip: Add Sophgo SG2042 MSI controller Chen Wang
2024-11-11 4:01 ` Chen Wang
2024-11-11 4:01 ` [PATCH 1/3] dt-bindings: interrupt-controller: Add Sophgo SG2042 MSI Chen Wang
2024-11-11 4:01 ` Chen Wang
2024-11-12 15:52 ` Rob Herring
2024-11-12 15:52 ` Rob Herring
2024-11-13 7:16 ` Chen Wang
2024-11-13 7:16 ` Chen Wang
2024-11-11 4:01 ` [PATCH 2/3] irqchip: Add the Sophgo SG2042 MSI interrupt controller Chen Wang
2024-11-11 4:01 ` Chen Wang
2024-11-13 6:14 ` Thomas Gleixner [this message]
2024-11-13 6:14 ` Thomas Gleixner
2024-11-13 6:43 ` Chen Wang
2024-11-13 6:43 ` Chen Wang
2024-11-13 15:31 ` Thomas Gleixner
2024-11-13 15:31 ` Thomas Gleixner
2024-11-14 0:20 ` Chen Wang
2024-11-14 0:20 ` Chen Wang
2024-11-11 4:02 ` [PATCH 3/3] riscv: sophgo: dts: add msi controller for SG2042 Chen Wang
2024-11-11 4:02 ` Chen Wang
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=87cyizmzhf.ffs@tglx \
--to=tglx@linutronix.de \
--cc=aou@eecs.berkeley.edu \
--cc=arnd@arndb.de \
--cc=chao.wei@sophgo.com \
--cc=conor+dt@kernel.org \
--cc=devicetree@vger.kernel.org \
--cc=fengchun.li@sophgo.com \
--cc=guoren@kernel.org \
--cc=inochiama@outlook.com \
--cc=krzk+dt@kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-riscv@lists.infradead.org \
--cc=palmer@dabbelt.com \
--cc=paul.walmsley@sifive.com \
--cc=robh@kernel.org \
--cc=u.kleine-koenig@baylibre.com \
--cc=unicorn_wang@outlook.com \
--cc=unicornxw@gmail.com \
--cc=xiaoguang.xing@sophgo.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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.