Linux-ARM-Kernel Archive on lore.kernel.org
 help / color / mirror / Atom feed
From: Andrew Jeffery <andrew@codeconstruct.com.au>
To: "Grégoire Layet" <gregoire.layet@9elements.com>, joel@jms.id.au
Cc: andrew@lunn.ch, jacky_chou@aspeedtech.com,
	yh_chung@aspeedtech.com,  ninad@linux.ibm.com,
	linux-aspeed@lists.ozlabs.org,
	 linux-arm-kernel@lists.infradead.org,
	linux-kernel@vger.kernel.org
Subject: Re: [PATCH v2 1/2] soc: aspeed: add BMC-side PCIe BMC device driver
Date: Wed, 10 Jun 2026 22:03:49 +0930	[thread overview]
Message-ID: <4839c31f666b612799a795bb47c884901fd2a903.camel@codeconstruct.com.au> (raw)
In-Reply-To: <af322e76d34ad504e0bdec470293a017b489cfd7.1780929570.git.gregoire.layet@9elements.com>

Hello Grégoire,

On Mon, 2026-06-08 at 14:51 +0000, Grégoire Layet wrote:
> Taken from ASPEED 6.18 Kernel SDK

It's probably best to use ASPEED's SDK as a source of inspiration for
fixing obscure bugs, but not send drivers directly extracted from it.

> 
> Add support for VUART over PCIe between BMC and host.
> This add BMC side driver.
> 
> Signed-off-by: Jacky Chou <jacky_chou@aspeedtech.com>
> Signed-off-by: aspeedyh <yh_chung@aspeedtech.com>
> Signed-off-by: Grégoire Layet <gregoire.layet@9elements.com>
> Tested-by: Grégoire Layet <gregoire.layet@9elements.com>
> ---
>  drivers/soc/aspeed/Kconfig          |   7 ++
>  drivers/soc/aspeed/Makefile         |   1 +
>  drivers/soc/aspeed/aspeed-bmc-dev.c | 187 ++++++++++++++++++++++++++++

We should avoid adding more drivers in drivers/soc/aspeed where we can.

Is this really necessary?

>  3 files changed, 195 insertions(+)
>  create mode 100644 drivers/soc/aspeed/aspeed-bmc-dev.c
> 
> diff --git a/drivers/soc/aspeed/Kconfig b/drivers/soc/aspeed/Kconfig
> index f579ee0b5afa..3e1fcf3c3268 100644
> --- a/drivers/soc/aspeed/Kconfig
> +++ b/drivers/soc/aspeed/Kconfig
> @@ -4,6 +4,13 @@ if ARCH_ASPEED || COMPILE_TEST
>  
>  menu "ASPEED SoC drivers"
>  
> +config ASPEED_BMC_DEV
> +	tristate "ASPEED BMC Device"
> +	default n
> +	help
> +	  Enable support for the ASPEED AST2600 BMC Device.
> +	  This exposes the PCIe-to-LPC bridge of the BMC to the host over PCIe.
> +
>  config ASPEED_LPC_CTRL
>  	tristate "ASPEED LPC firmware cycle control"
>  	select REGMAP
> diff --git a/drivers/soc/aspeed/Makefile b/drivers/soc/aspeed/Makefile
> index b35d74592964..fab0d247df66 100644
> --- a/drivers/soc/aspeed/Makefile
> +++ b/drivers/soc/aspeed/Makefile
> @@ -1,4 +1,5 @@
>  # SPDX-License-Identifier: GPL-2.0-only
> +obj-$(CONFIG_ASPEED_BMC_DEV)		+= aspeed-bmc-dev.o
>  obj-$(CONFIG_ASPEED_LPC_CTRL)		+= aspeed-lpc-ctrl.o
>  obj-$(CONFIG_ASPEED_LPC_SNOOP)		+= aspeed-lpc-snoop.o
>  obj-$(CONFIG_ASPEED_UART_ROUTING)	+= aspeed-uart-routing.o
> diff --git a/drivers/soc/aspeed/aspeed-bmc-dev.c b/drivers/soc/aspeed/aspeed-bmc-dev.c
> new file mode 100644
> index 000000000000..7a204b543c97
> --- /dev/null
> +++ b/drivers/soc/aspeed/aspeed-bmc-dev.c
> @@ -0,0 +1,187 @@
> +// SPDX-License-Identifier: GPL-2.0-or-later
> +// Copyright (C) ASPEED Technology Inc.
> +
> +#include <linux/init.h>
> +#include <linux/module.h>
> +#include <linux/kernel.h>
> +#include <linux/errno.h>
> +
> +#include <linux/of_address.h>
> +#include <linux/platform_device.h>
> +
> +#include <linux/regmap.h>
> +#include <linux/interrupt.h>
> +#include <linux/mfd/syscon.h>
> +
> +#define SCU_TRIGGER_MSI
> +
> +/* AST2600 SCU */
> +#define ASPEED_SCU04			0x04
> +#define AST2600A3_SCU04				0x05030303
> +#define ASPEED_SCUC20			0xC20
> +#define ASPEED_SCUC24			0xC24

These could all use properly descriptive names.

Pinctrl is an exception because of how the documentation is structured.

> +#define MSI_ROUTING_MASK			GENMASK(11, 10)
> +#define PCIDEV1_INTX_MSI_HOST2BMC_EN		BIT(18)
> +#define MSI_ROUTING_PCIe2LPC_PCIDEV0		(0x1 << 10)
> +#define MSI_ROUTING_PCIe2LPC_PCIDEV1		(0x2 << 10)
> +
> +#define ASPEED_SCU_PCIE_CONF_CTRL	0xC20
> +#define  SCU_PCIE_CONF_BMC_DEV_EN			 BIT(8)
> +#define  SCU_PCIE_CONF_BMC_DEV_EN_MMIO		 BIT(9)
> +#define  SCU_PCIE_CONF_BMC_DEV_EN_MSI		 BIT(11)
> +#define  SCU_PCIE_CONF_BMC_DEV_EN_IRQ		 BIT(13)
> +#define  SCU_PCIE_CONF_BMC_DEV_EN_DMA		 BIT(14)
> +#define  SCU_PCIE_CONF_BMC_DEV_EN_E2L		 BIT(15)
> +#define  SCU_PCIE_CONF_BMC_DEV_EN_LPC_DECODE BIT(21)
> +
> +#define ASPEED_SCU_BMC_DEV_CLASS	0xC68
> +
> +
> +struct aspeed_platform {
> +	int (*init)(struct platform_device *pdev);
> +};
> +
> +struct aspeed_bmc_device {
> +	struct device *dev;
> +	int id;
> +	void __iomem *reg_base;
> +
> +	int pcie2lpc;
> +	int irq;
> +
> +	const struct aspeed_platform *platform;
> +
> +	struct regmap *scu;
> +	int pcie_irq;
> +};
> +
> +
> +static int aspeed_ast2600_init(struct platform_device *pdev)
> +{
> +	struct aspeed_bmc_device *bmc_device = platform_get_drvdata(pdev);
> +	struct device *dev = &pdev->dev;
> +	u32 pcie_config_ctl = SCU_PCIE_CONF_BMC_DEV_EN_IRQ |
> +			      SCU_PCIE_CONF_BMC_DEV_EN_MMIO | SCU_PCIE_CONF_BMC_DEV_EN;
> +	u32 scu_id;
> +
> +	bmc_device->scu = syscon_regmap_lookup_by_phandle(dev->of_node, "aspeed,scu");

We should rather look at auxbus for the SCU.

> +	if (IS_ERR(bmc_device->scu)) {
> +		dev_err(&pdev->dev, "failed to find SCU regmap\n");
> +		return PTR_ERR(bmc_device->scu);
> +	}
> +
> +	if (bmc_device->pcie2lpc)
> +		pcie_config_ctl |= SCU_PCIE_CONF_BMC_DEV_EN_E2L |
> +				   SCU_PCIE_CONF_BMC_DEV_EN_LPC_DECODE;
> +
> +	regmap_update_bits(bmc_device->scu, ASPEED_SCU_PCIE_CONF_CTRL,
> +			   pcie_config_ctl, pcie_config_ctl);
> +
> +	/* update class code to others as it is a MFD device */
> +	regmap_write(bmc_device->scu, ASPEED_SCU_BMC_DEV_CLASS, 0xff000000);
> +
> +#ifdef SCU_TRIGGER_MSI

I don't see that this needs to be a CPP test. This could be a C test.
The construct would be optimised because of the constant and we'd get
compile time coverage of both sides without additional configuration.

Have you tested both sides?

> +	//SCUC24[17]: Enable PCI device 1 INTx/MSI from SCU560[15]. Will be added in next version
> +	regmap_update_bits(bmc_device->scu, ASPEED_SCUC20, BIT(11) | BIT(14), BIT(11) | BIT(14));

These bits need descriptive macros.

> +
> +	regmap_read(bmc_device->scu, ASPEED_SCU04, &scu_id);
> +	if (scu_id == AST2600A3_SCU04)
> +		regmap_update_bits(bmc_device->scu, ASPEED_SCUC24,
> +				   PCIDEV1_INTX_MSI_HOST2BMC_EN | MSI_ROUTING_MASK,
> +				   PCIDEV1_INTX_MSI_HOST2BMC_EN | MSI_ROUTING_PCIe2LPC_PCIDEV1);
> +	else
> +		regmap_update_bits(bmc_device->scu, ASPEED_SCUC24,
> +				   BIT(17) | BIT(14) | BIT(11), BIT(17) | BIT(14) | BIT(11));

As do these

> +#else
> +	//SCUC24[18]: Enable PCI device 1 INTx/MSI from Host-to-BMC controller.
> +	regmap_update_bits(bmc_device->scu, 0xc24, BIT(18) | BIT(14), BIT(18) | BIT(14));

And these.

> +#endif
> +
> +
> +	return 0;
> +}
> +
> +
> +static struct aspeed_platform ast2600_plaform = {
> +	.init = aspeed_ast2600_init
> +};
> +
> +
> +static const struct of_device_id aspeed_bmc_device_of_matches[] = {
> +	{ .compatible = "aspeed,ast2600-bmc-device", .data = &ast2600_plaform },

This compatible isn't documented in this series and isn't present in
linux-next at a87737435cfa ("Add linux-next specific files for
20260608"). You'll need to address that if it's reasonable to continue
down this path. I expect you'll want to avoid it, and define any
necessary properties on the SCU node rather than add further children.

> +	{},
> +};
> +MODULE_DEVICE_TABLE(of, aspeed_bmc_device_of_matches);
> +
> +static int aspeed_bmc_device_probe(struct platform_device *pdev)
> +{
> +	struct aspeed_bmc_device *bmc_device;
> +	struct device *dev = &pdev->dev;

This shortcut is defined but inconsistently used.

> +	const void *md = of_device_get_match_data(dev);

I think we can do without this, see below.

> +	int ret = 0;
> +
> +	if (!md)
> +		return -ENODEV;
> +
> +	bmc_device = devm_kzalloc(&pdev->dev, sizeof(struct aspeed_bmc_device), GFP_KERNEL);
> +	if (!bmc_device)
> +		return -ENOMEM;
> +	dev_set_drvdata(dev, bmc_device);
> +
> +	bmc_device->platform = md;
> +
> +	bmc_device->id = of_alias_get_id(dev->of_node, "bmcdev");
> +	if (bmc_device->id < 0)
> +		bmc_device->id = 0;
> +
> +	bmc_device->dev = dev;
> +	bmc_device->reg_base = devm_platform_ioremap_resource(pdev, 0);
> +	if (IS_ERR(bmc_device->reg_base))
> +		return PTR_ERR(bmc_device->reg_base);
> +
> +	bmc_device->irq = platform_get_irq(pdev, 0);

This seems unnecessary.

> +	if (bmc_device->irq < 0) {
> +		dev_err(&pdev->dev, "platform get of irq[=%d] failed!\n", bmc_device->irq);
> +		return bmc_device->irq;
> +	}
> +
> +	if (of_property_read_bool(dev->of_node, "pcie2lpc"))

This property isn't documented.

> +		bmc_device->pcie2lpc = 1;
> +
> +	ret = bmc_device->platform->init(pdev);

The driver only supports one SoC, this indirection seems unnecessary
right now. We can add that later when there's a need to differentiate.
I'd rather you call the setup function directly for now.

> +	if (ret) {
> +		dev_err(dev, "Initialize bmc device failed\n");
> +		goto out;
> +	}
> +
> +	dev_info(dev, "aspeed bmc device: driver successfully loaded.\n");
> +
> +	return 0;
> +
> +out:
> +	dev_warn(dev, "aspeed bmc device: driver init failed (ret=%d)!\n", ret);
> +	return ret;
> +}
> +
> +static void aspeed_bmc_device_remove(struct platform_device *pdev)
> +{
> +	struct aspeed_bmc_device *bmc_device = platform_get_drvdata(pdev);
> +
> +	devm_free_irq(&pdev->dev, bmc_device->irq, bmc_device);
> +	devm_kfree(&pdev->dev, bmc_device);

These are unnecessary due to cleanup of devres on release.

Andrew


  reply	other threads:[~2026-06-10 12:34 UTC|newest]

Thread overview: 19+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-06-02 14:42 [PATCH v1 0/2] soc: aspeed: Add BMC and host driver for PCIe BMC device Grégoire Layet
2026-06-02 14:42 ` [PATCH v1 1/2] soc: aspeed: add BMC-side PCIe BMC device driver Grégoire Layet
2026-06-02 14:42 ` [PATCH v1 2/2] soc: aspeed: add host-side " Grégoire Layet
2026-06-02 15:49   ` Andrew Lunn
2026-06-03 13:43     ` Grégoire Layet
2026-06-03 14:30       ` Andrew Lunn
2026-06-04  0:44         ` Andrew Jeffery
2026-06-04  0:46       ` Andrew Jeffery
2026-06-08 14:51 ` [PATCH v2 0/2] soc: aspeed: Add BMC and host driver for PCIe BMC device Grégoire Layet
2026-06-08 14:51   ` [PATCH v2 1/2] soc: aspeed: add BMC-side PCIe BMC device driver Grégoire Layet
2026-06-10 12:33     ` Andrew Jeffery [this message]
2026-06-11  8:40       ` Grégoire Layet
2026-06-12  9:21         ` Grégoire Layet
2026-06-16  0:16           ` Andrew Jeffery
2026-06-08 14:51   ` [PATCH v2 2/2] soc: aspeed: add host-side " Grégoire Layet
2026-06-10 12:51     ` Andrew Jeffery
2026-06-11  8:41       ` Grégoire Layet
2026-06-08 18:05   ` [PATCH v2 0/2] soc: aspeed: Add BMC and host driver for PCIe BMC device Andrew Lunn
2026-06-09 13:34     ` Grégoire Layet

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=4839c31f666b612799a795bb47c884901fd2a903.camel@codeconstruct.com.au \
    --to=andrew@codeconstruct.com.au \
    --cc=andrew@lunn.ch \
    --cc=gregoire.layet@9elements.com \
    --cc=jacky_chou@aspeedtech.com \
    --cc=joel@jms.id.au \
    --cc=linux-arm-kernel@lists.infradead.org \
    --cc=linux-aspeed@lists.ozlabs.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=ninad@linux.ibm.com \
    --cc=yh_chung@aspeedtech.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