Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 4 additions & 2 deletions arch/arm64/configs/eve_defconfig
Original file line number Diff line number Diff line change
Expand Up @@ -543,7 +543,6 @@ CONFIG_MHI_BUS_EP=m
CONFIG_CONNECTOR=y
CONFIG_ARM_SCMI_PROTOCOL=y
CONFIG_ARM_SCPI_PROTOCOL=y
CONFIG_ARM_SDE_INTERFACE=y
CONFIG_FIRMWARE_MEMMAP=y
CONFIG_RASPBERRYPI_FIRMWARE=y
CONFIG_EFI_GENERIC_STUB_INITRD_CMDLINE_LOADER=y
Expand Down Expand Up @@ -787,10 +786,12 @@ CONFIG_I2C_RK3X=m
CONFIG_I2C_SPRD=y
CONFIG_I2C_TEGRA=y
CONFIG_SPI=y
CONFIG_SPI_MEM=y
CONFIG_SPI_BCM2835=m
CONFIG_SPI_BCM2835AUX=m
CONFIG_SPI_BCM_QSPI=m
CONFIG_SPI_DESIGNWARE=m
CONFIG_SPI_DW_DMA=y
CONFIG_SPI_DW_MMIO=m
CONFIG_SPI_GPIO=m
CONFIG_SPI_IMX=m
CONFIG_SPI_FSL_SPI=m
Expand Down Expand Up @@ -1069,6 +1070,7 @@ CONFIG_RTC_DRV_IMX_SC=y
CONFIG_RTC_DRV_XGENE=y
CONFIG_DMADEVICES=y
CONFIG_DMA_BCM2835=y
CONFIG_DW_AXI_DMAC=y
CONFIG_FSL_EDMA=y
CONFIG_FSL_QDMA=m
CONFIG_IMX_SDMA=y
Expand Down
70 changes: 53 additions & 17 deletions drivers/irqchip/irq-bcm2712-mip.c
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
#include <linux/of_address.h>
#include <linux/of_irq.h>
#include <linux/of_pci.h>
#include <linux/platform_device.h>

#include <linux/irqchip.h>

Expand Down Expand Up @@ -229,8 +230,8 @@ static int mip_init_domains(struct mip_priv *priv,
return 0;
}

static int __init mip_of_msi_init(struct device_node *node,
struct device_node *parent)
static int mip_of_msi_init(struct device_node *node,
struct device_node *parent)
{
struct mip_priv *priv;
struct resource res;
Expand All @@ -249,25 +250,50 @@ static int __init mip_of_msi_init(struct device_node *node,
goto err_priv;
}

if (of_property_read_u32(node, "brcm,msi-base-spi", &priv->msi_base)) {
pr_err("Unable to parse MSI base\n");
ret = -EINVAL;
goto err_priv;
}

if (of_property_read_u32(node, "brcm,msi-num-spis", &priv->num_msis)) {
pr_err("Unable to parse MSI numbers\n");
ret = -EINVAL;
goto err_priv;
}

if (of_property_read_u32(node, "brcm,msi-offset", &priv->msi_offset))
priv->msi_offset = 0;

/*
* The MSI base SPI and count come from the brcm,msi-base-spi /
* brcm,msi-num-spis properties in the original "brcm,bcm2712-mip-intc"
* binding, or from the msi-ranges property in the upstream
* "brcm,bcm2712-mip" binding used by newer firmware device trees.
*/
if (of_property_read_u32(node, "brcm,msi-base-spi", &priv->msi_base) ||
of_property_read_u32(node, "brcm,msi-num-spis", &priv->num_msis)) {
struct of_phandle_args args;

ret = of_parse_phandle_with_args(node, "msi-ranges",
"#interrupt-cells", 0, &args);
if (!ret) {
priv->msi_base = args.args[1];
ret = of_property_read_u32_index(node, "msi-ranges",
args.args_count + 1,
&priv->num_msis);
of_node_put(args.np);
}
if (ret) {
pr_err("Unable to parse MSI base/count\n");
ret = -EINVAL;
goto err_priv;
}
}

/*
* The MSI target (doorbell) address comes from the brcm,msi-pci-addr
* property in the original binding, or from the second (untranslated)
* reg region in the upstream binding.
*/
if (of_property_read_u64(node, "brcm,msi-pci-addr", &priv->msg_addr)) {
pr_err("Unable to parse MSI address\n");
ret = -EINVAL;
goto err_priv;
const __be32 *addrp;

addrp = of_get_address(node, 1, NULL, NULL);
if (!addrp) {
pr_err("Unable to parse MSI address\n");
ret = -EINVAL;
goto err_priv;
}
priv->msg_addr = of_read_number(addrp, of_n_addr_cells(node));
}

priv->base = ioremap(res.start, resource_size(&res));
Expand Down Expand Up @@ -321,3 +347,13 @@ static int __init mip_of_msi_init(struct device_node *node,
return ret;
}
IRQCHIP_DECLARE(bcm_mip, "brcm,bcm2712-mip-intc", mip_of_msi_init);

/*
* Newer Raspberry Pi firmware device trees describe the MIP using the
* upstream "brcm,bcm2712-mip" binding. That node only has a "msi-controller"
* property (no "interrupt-controller"), so it is not matched by
* of_irq_init()/IRQCHIP_DECLARE and must be probed as a platform device.
*/
IRQCHIP_PLATFORM_DRIVER_BEGIN(bcm2712_mip)
IRQCHIP_MATCH("brcm,bcm2712-mip", mip_of_msi_init)
IRQCHIP_PLATFORM_DRIVER_END(bcm2712_mip)
32 changes: 27 additions & 5 deletions drivers/pci/controller/pcie-brcmstb.c
Original file line number Diff line number Diff line change
Expand Up @@ -2003,12 +2003,34 @@ static int brcm_pcie_probe(struct platform_device *pdev)
u64 msi_phys_addr;

if (of_property_read_u64(msi_np, "brcm,msi-pci-addr", &msi_pci_addr)) {
dev_err(pcie->dev, "Unable to find MSI PCI address\n");
ret = -EINVAL;
goto fail;
}
/*
* Newer firmware device trees use the upstream
* "brcm,bcm2712-mip" binding, which has no
* brcm,msi-pci-addr property: the MSI doorbell PCI
* address is the second reg region and the MIP register
* base is the first. These are PCI/raw addresses that
* must not be range-translated, so read them directly
* from the reg cells.
*/
const __be32 *addrp;
int na = of_n_addr_cells(msi_np);

addrp = of_get_address(msi_np, 1, NULL, NULL);
if (!addrp) {
dev_err(pcie->dev, "Unable to find MSI PCI address\n");
ret = -EINVAL;
goto fail;
}
msi_pci_addr = of_read_number(addrp, na);

if (of_property_read_u64(msi_np, "reg", &msi_phys_addr)) {
addrp = of_get_address(msi_np, 0, NULL, NULL);
if (!addrp) {
dev_err(pcie->dev, "Unable to find MSI physical address\n");
ret = -EINVAL;
goto fail;
}
msi_phys_addr = of_read_number(addrp, na);
} else if (of_property_read_u64(msi_np, "reg", &msi_phys_addr)) {
dev_err(pcie->dev, "Unable to find MSI physical address\n");
ret = -EINVAL;
goto fail;
Expand Down