From c0a2b086b22b4af3253e4e22d5a9d1e809fd1352 Mon Sep 17 00:00:00 2001 From: Mario Six Date: Thu, 4 Oct 2018 09:00:54 +0200 Subject: [PATCH] misc: Add gdsys_soc driver This patch adds a driver for the bus associated with a IHS FPGA. Reviewed-by: Simon Glass Signed-off-by: Mario Six --- .../devicetree/bindings/misc/gdsys,soc.txt | 16 ++++ drivers/misc/Kconfig | 8 ++ drivers/misc/Makefile | 1 + drivers/misc/gdsys_soc.c | 74 +++++++++++++++++++ drivers/misc/gdsys_soc.h | 23 ++++++ 5 files changed, 122 insertions(+) create mode 100644 Documentation/devicetree/bindings/misc/gdsys,soc.txt create mode 100644 drivers/misc/gdsys_soc.c create mode 100644 drivers/misc/gdsys_soc.h diff --git a/Documentation/devicetree/bindings/misc/gdsys,soc.txt b/Documentation/devicetree/bindings/misc/gdsys,soc.txt new file mode 100644 index 0000000000..278e935b16 --- /dev/null +++ b/Documentation/devicetree/bindings/misc/gdsys,soc.txt @@ -0,0 +1,16 @@ +gdsys soc bus driver + +This driver provides a simple interface for the busses associated with gdsys +IHS FPGAs. The bus itself contains devices whose register maps are contained +within the FPGA's register space. + +Required properties: +- fpga: A phandle to the controlling IHS FPGA + +Example: + +FPGA0BUS: fpga0bus { + compatible = "gdsys,soc"; + ranges = <0x0 0xe0600000 0x00004000>; + fpga = <&FPGA0>; +}; diff --git a/drivers/misc/Kconfig b/drivers/misc/Kconfig index c5697011f2..d589f32a55 100644 --- a/drivers/misc/Kconfig +++ b/drivers/misc/Kconfig @@ -312,4 +312,12 @@ config FS_LOADER The consumer driver would then use this loader to program whatever, ie. the FPGA device. +config GDSYS_SOC + bool "Enable gdsys SOC driver" + depends on MISC + help + Support for gdsys IHS SOC, a simple bus associated with each gdsys + IHS (Integrated Hardware Systems) FPGA, which holds all devices whose + register maps are contained within the FPGA's register map. + endmenu diff --git a/drivers/misc/Makefile b/drivers/misc/Makefile index d9ac672ab8..4a5a18675a 100644 --- a/drivers/misc/Makefile +++ b/drivers/misc/Makefile @@ -35,6 +35,7 @@ obj-$(CONFIG_FSL_SEC_MON) += fsl_sec_mon.o obj-$(CONFIG_FS_LOADER) += fs_loader.o obj-$(CONFIG_GDSYS_IOEP) += gdsys_ioep.o obj-$(CONFIG_GDSYS_RXAUI_CTRL) += gdsys_rxaui_ctrl.o +obj-$(CONFIG_GDSYS_SOC) += gdsys_soc.o obj-$(CONFIG_$(SPL_)I2C_EEPROM) += i2c_eeprom.o obj-$(CONFIG_IMX8) += imx8/ obj-$(CONFIG_LED_STATUS) += status_led.o diff --git a/drivers/misc/gdsys_soc.c b/drivers/misc/gdsys_soc.c new file mode 100644 index 0000000000..94a21e08af --- /dev/null +++ b/drivers/misc/gdsys_soc.c @@ -0,0 +1,74 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * (C) Copyright 2017 + * Mario Six, Guntermann & Drunck GmbH, mario.six@gdsys.cc + */ + +#include +#include +#include + +#include "gdsys_soc.h" + +/** + * struct gdsys_soc_priv - Private data for gdsys soc bus + * @fpga: The gdsys IHS FPGA this bus is associated with + */ +struct gdsys_soc_priv { + struct udevice *fpga; +}; + +static const struct udevice_id gdsys_soc_ids[] = { + { .compatible = "gdsys,soc" }, + { /* sentinel */ } +}; + +int gdsys_soc_get_fpga(struct udevice *child, struct udevice **fpga) +{ + struct gdsys_soc_priv *bus_priv; + + if (!child->parent) { + debug("%s: Invalid parent\n", child->name); + return -EINVAL; + } + + if (!device_is_compatible(child->parent, "gdsys,soc")) { + debug("%s: Not child of a gdsys soc\n", child->name); + return -EINVAL; + } + + bus_priv = dev_get_priv(child->parent); + + *fpga = bus_priv->fpga; + + return 0; +} + +static int gdsys_soc_probe(struct udevice *dev) +{ + struct gdsys_soc_priv *priv = dev_get_priv(dev); + struct udevice *fpga; + int res = uclass_get_device_by_phandle(UCLASS_MISC, dev, "fpga", + &fpga); + if (res == -ENOENT) { + debug("%s: Could not find 'fpga' phandle\n", dev->name); + return -EINVAL; + } + + if (res == -ENODEV) { + debug("%s: Could not get FPGA device\n", dev->name); + return -EINVAL; + } + + priv->fpga = fpga; + + return 0; +} + +U_BOOT_DRIVER(gdsys_soc_bus) = { + .name = "gdsys_soc_bus", + .id = UCLASS_SIMPLE_BUS, + .of_match = gdsys_soc_ids, + .probe = gdsys_soc_probe, + .priv_auto_alloc_size = sizeof(struct gdsys_soc_priv), +}; diff --git a/drivers/misc/gdsys_soc.h b/drivers/misc/gdsys_soc.h new file mode 100644 index 0000000000..088d3b6523 --- /dev/null +++ b/drivers/misc/gdsys_soc.h @@ -0,0 +1,23 @@ +/* SPDX-License-Identifier: GPL-2.0+ */ +/* + * (C) Copyright 2017 + * Mario Six, Guntermann & Drunck GmbH, mario.six@gdsys.cc + */ + +#ifndef _GDSYS_SOC_H_ +#define _GDSYS_SOC_H_ + +/** + * gdsys_soc_get_fpga() - Retrieve pointer to parent bus' FPGA device + * @child: The child device on the FPGA bus needing access to the FPGA. + * @fpga: Pointer to the retrieved FPGA device. + * + * To access their register maps, devices on gdsys soc buses usually have + * facilitate the accessor function of the IHS FPGA their parent bus is + * attached to. To access the FPGA device from within the bus' children, this + * function returns a pointer to it. + * + * Return: 0 on success, -ve on failure + */ +int gdsys_soc_get_fpga(struct udevice *child, struct udevice **fpga); +#endif /* _GDSYS_SOC_H_ */ -- 2.39.5