misc: tc9564: introduce base PCI driver

The Toshiba TC9564 is small and highly-specialized SoC that implements
a PCIe switch as well as an Ethernet AVB/TSN bridge.  In addition to
these, the SoC implements other functions, including a reset and clock
controller, an address translation unit, and a few other devices.  PCIe
BARs provide access to registers that manage these IP blocks, and the
SoC is modeled using a PCI endpoint bus in devicetree.  This allows the
IP blocks to be bound to platform drivers that do MMIO via the PCI BARs.

Create a new PCI driver under drivers/misc that binds with the embedded
PCI endpoint functions within the TC9564 SoC.  Because these functions
will use devicetree pci-ep-bus to provide access to other IP blocks
within the TC9564 chip, the main purpose of this driver is to do basic
PCI initialization, then call of_platform_default_populate() to scan for
the any endpoint bus children, and probe all devices defined therein.

Because we're using pci-ep-bus, we need to use the PCI quirks mechanism
to have of_pci_make_dev_node() be called for each endpoint device in
pci_bus_add_device() (via pci_fixup_device(pci_fixup_final, dev)).

Co-developed-by: Daniel Thompson <daniel@riscstar.com>
Signed-off-by: Daniel Thompson <daniel@riscstar.com>
Signed-off-by: Alex Elder <elder@riscstar.com>
Acked-by: Bjorn Helgaas <bhelgaas@google.com>	# quirks.c
Link: https://patch.msgid.link/20260918152659.413268-3-elder@riscstar.com
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
This commit is contained in:
Alex Elder authored and Greg Kroah-Hartman committed 2026-10-01 14:05:43 +02:00
1 parent ed0a1c1eaa
commit 1304b0c47e
5 files changed
+102

No files matched your search

+1
View File
@@ -27736,6 +27736,7 @@ M: Alex Elder <elder@kernel.org>
M: Daniel Thompson <danielt@kernel.org>
S: Maintained
F: Documentation/devicetree/bindings/misc/pci1179,0220.yaml
F: drivers/misc/tc9564-pci.c
TOSHIBA WMI HOTKEYS DRIVER
M: Azael Avalos <coproscefalo@gmail.com>
+15
View File
@@ -568,6 +568,21 @@ config MCHP_LAN966X_PCI
- lan966x-miim (MDIO_MSCC_MIIM)
- lan966x-switch (LAN966X_SWITCH)
config TC9564_PCI
tristate "Toshiba TC9564 PCI function support"
depends on OF
depends on PCI
select PCI_DYNAMIC_OF_NODES
select PCI_QUIRKS
default m
help
This enables support for two PCI functions implemented by the
embedded PCIe endpoint in the Toshiba TC9564 SoC. A platform
driver uses a pci-ep-bus node in devicetree to provide MMIO
access to other SoC devices through PCI function BARs. A PCI
quirk causes the ranges property in the endpoint's devicetree
node to be updated dynamically.
source "drivers/misc/c2port/Kconfig"
source "drivers/misc/eeprom/Kconfig"
source "drivers/misc/cb710/Kconfig"
+1
View File
@@ -71,3 +71,4 @@ obj-y += keba/
obj-y += amd-sbi/
obj-$(CONFIG_MISC_RP1) += rp1/
obj-$(CONFIG_INTEL_SSEI) += issei/
obj-$(CONFIG_TC9564_PCI) += tc9564-pci.o
+84
View File
@@ -0,0 +1,84 @@
// SPDX-License-Identifier: GPL-2.0
/*
* Copyright (C) 2026 by RISCstar Solutions Corporation. All rights reserved.
*/
/*
* The Toshiba TC9564 implements a PCIe Gen 3 switch that connects an
* upstream x4 port to three downstream PCIe ports. Two of the downstream
* ports are external, and the third is internal, implementing a PCIe
* endpoint which implements two PCIe functions. Each PCIe function drives
* a Synopsys XGMAC Ethernet interface capable of 10 Gbps operation.
*
* The TC9564 implements other functionality, including an embedded MCU,
* a UART, a GPIO controller, a reset controller, a clock controller, and
* interrupt handling. These features are separate from (and in some
* cases used by) both Ethernet XGMACs. Each Ethernet MAC must be
* attached to a working PHY for it to be functional, and for this
* reason either of them (or both!) might not be usable/used.
*
* This PCI driver binds to the Toshiba TC9564 (physical) PCI function
* (VID 0x1179, DID 0x0220).
*/
#include <linux/device.h>
#include <linux/irqdomain.h>
#include <linux/of.h>
#include <linux/of_platform.h>
#include <linux/pci.h>
static void tc9564_function_remove(struct pci_dev *pdev)
{
of_platform_depopulate(&pdev->dev);
pci_clear_master(pdev);
pci_disable_device(pdev);
}
static int
tc9564_function_probe(struct pci_dev *pdev, const struct pci_device_id *id)
{
struct device *dev = &pdev->dev;
struct device_node *np;
int ret;
/* Despite being a PCI device, we require devicetree */
np = dev_of_node(dev);
if (!np)
return dev_err_probe(dev, -EINVAL, "no devicetree node\n");
ret = pci_enable_device(pdev);
if (ret)
return dev_err_probe(dev, ret, "failed to enable device\n");
pci_set_master(pdev);
/* Scan for pci-ep-bus (simple-bus) nodes and probe their sub-devices */
ret = of_platform_default_populate(np, NULL, dev);
if (ret)
goto err_depopulate;
return 0;
err_depopulate:
tc9564_function_remove(pdev);
return dev_err_probe(dev, ret, "failed to populate platform bus\n");
}
static const struct pci_device_id tc9564_function_id_table[] = {
{ PCI_DEVICE(PCI_VENDOR_ID_TOSHIBA, 0x0220), },
{ },
};
MODULE_DEVICE_TABLE(pci, tc9564_function_id_table);
static struct pci_driver tc9564_function_driver = {
.name = KBUILD_MODNAME,
.id_table = tc9564_function_id_table,
.probe = tc9564_function_probe,
.remove = tc9564_function_remove,
};
module_pci_driver(tc9564_function_driver);
MODULE_DESCRIPTION("Toshiba TC9564 PCIe Embedded Function Driver");
MODULE_LICENSE("GPL");
+1
View File
@@ -6391,6 +6391,7 @@ DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_XILINX, 0x5020, of_pci_make_dev_node);
DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_XILINX, 0x5021, of_pci_make_dev_node);
DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_REDHAT, 0x0005, of_pci_make_dev_node);
DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_EFAR, 0x9660, of_pci_make_dev_node);
DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_TOSHIBA, 0x0220, of_pci_make_dev_node);
/*
* Devices known to require a longer delay before first config space access