On Tue, Feb 20, 2018 at 11:21:05AM -0800, Jolly Shah wrote: > This patch is adding communication layer with firmware. > Firmware driver provides an interface to firmware APIs. > Interface APIs can be used by any driver to communicate to > PMUFW(Platform Management Unit). All requests go through ATF. > > Signed-off-by: Jolly Shah <jollys@xxxxxxxxxx> > Signed-off-by: Rajan Vaja <rajanv@xxxxxxxxxx> > --- > arch/arm64/Kconfig.platforms | 1 + > drivers/firmware/Kconfig | 1 + > drivers/firmware/Makefile | 1 + > drivers/firmware/xilinx/Kconfig | 4 + > drivers/firmware/xilinx/Makefile | 4 + > drivers/firmware/xilinx/zynqmp/Kconfig | 16 + > drivers/firmware/xilinx/zynqmp/Makefile | 4 + > drivers/firmware/xilinx/zynqmp/firmware.c | 1051 +++++++++++++++++++++++ Why are you 2 levels deep? Why not just drivers/firmware/zynqmp.c? Or at the worst: drivers/firmware/xilinx/zynqmp.c Don't over do it, if we really get too many firmware drivers, we can always move things around in the future. > include/linux/firmware/xilinx/zynqmp/firmware.h | 590 +++++++++++++ I still think this include directly depth is crazy. What's wrong with: include/linux/firmware/zynqmp.h ? > 9 files changed, 1672 insertions(+) > create mode 100644 drivers/firmware/xilinx/Kconfig > create mode 100644 drivers/firmware/xilinx/Makefile > create mode 100644 drivers/firmware/xilinx/zynqmp/Kconfig > create mode 100644 drivers/firmware/xilinx/zynqmp/Makefile > create mode 100644 drivers/firmware/xilinx/zynqmp/firmware.c > create mode 100644 include/linux/firmware/xilinx/zynqmp/firmware.h > > diff --git a/arch/arm64/Kconfig.platforms b/arch/arm64/Kconfig.platforms > index fbedbd8..6454458 100644 > --- a/arch/arm64/Kconfig.platforms > +++ b/arch/arm64/Kconfig.platforms > @@ -274,6 +274,7 @@ config ARCH_ZX > > config ARCH_ZYNQMP > bool "Xilinx ZynqMP Family" > + select ZYNQMP_FIRMWARE Select and not depends? > help > This enables support for Xilinx ZynqMP Family > > diff --git a/drivers/firmware/Kconfig b/drivers/firmware/Kconfig > index b7c7482..f41eb0d 100644 > --- a/drivers/firmware/Kconfig > +++ b/drivers/firmware/Kconfig > @@ -257,5 +257,6 @@ source "drivers/firmware/google/Kconfig" > source "drivers/firmware/efi/Kconfig" > source "drivers/firmware/meson/Kconfig" > source "drivers/firmware/tegra/Kconfig" > +source "drivers/firmware/xilinx/Kconfig" > > endmenu > diff --git a/drivers/firmware/Makefile b/drivers/firmware/Makefile > index b248238..f90363e 100644 > --- a/drivers/firmware/Makefile > +++ b/drivers/firmware/Makefile > @@ -31,3 +31,4 @@ obj-$(CONFIG_GOOGLE_FIRMWARE) += google/ > obj-$(CONFIG_EFI) += efi/ > obj-$(CONFIG_UEFI_CPER) += efi/ > obj-y += tegra/ > +obj-y += xilinx/ > diff --git a/drivers/firmware/xilinx/Kconfig b/drivers/firmware/xilinx/Kconfig > new file mode 100644 > index 0000000..eb4cdcf > --- /dev/null > +++ b/drivers/firmware/xilinx/Kconfig > @@ -0,0 +1,4 @@ > +# SPDX-License-Identifier: GPL-2.0+ 2+ for a Kconfig file? > +# Kconfig for Xilinx firmwares > + > +source "drivers/firmware/xilinx/zynqmp/Kconfig" > diff --git a/drivers/firmware/xilinx/Makefile b/drivers/firmware/xilinx/Makefile > new file mode 100644 > index 0000000..beff5dc > --- /dev/null > +++ b/drivers/firmware/xilinx/Makefile > @@ -0,0 +1,4 @@ > +# SPDX-License-Identifier: GPL-2.0+ 2+ for a Makefile? > +# Makefile for Xilinx firmwares > + > +obj-$(CONFIG_ARCH_ZYNQMP) += zynqmp/ > diff --git a/drivers/firmware/xilinx/zynqmp/Kconfig b/drivers/firmware/xilinx/zynqmp/Kconfig > new file mode 100644 > index 0000000..5054b80 > --- /dev/null > +++ b/drivers/firmware/xilinx/zynqmp/Kconfig > @@ -0,0 +1,16 @@ > +# SPDX-License-Identifier: GPL-2.0+ Again... > +# Kconfig for Xilinx ZynqMP firmware > + > +menu "Zynq MPSoC Firmware Drivers" > + depends on ARCH_ZYNQMP > + > +config ZYNQMP_FIRMWARE > + bool "Enable Xilinx Zynq MPSoC firmware interface" > + help > + Firmware interface driver is used by different to > + communicate with the firmware for various platform > + management services. > + Say yes to enable ZynqMP firmware interface driver. > + In doubt, say N > + > +endmenu > diff --git a/drivers/firmware/xilinx/zynqmp/Makefile b/drivers/firmware/xilinx/zynqmp/Makefile > new file mode 100644 > index 0000000..c3ec669 > --- /dev/null > +++ b/drivers/firmware/xilinx/zynqmp/Makefile > @@ -0,0 +1,4 @@ > +# SPDX-License-Identifier: GPL-2.0+ And again? > +# Makefile for Xilinx firmwares > + > +obj-$(CONFIG_ZYNQMP_FIRMWARE) += firmware.o > diff --git a/drivers/firmware/xilinx/zynqmp/firmware.c b/drivers/firmware/xilinx/zynqmp/firmware.c > new file mode 100644 > index 0000000..6979f4b > --- /dev/null > +++ b/drivers/firmware/xilinx/zynqmp/firmware.c > @@ -0,0 +1,1051 @@ > +// SPDX-License-Identifier: GPL-2.0+ And I have to ask, you really mean "any future version"? > +/* > + * Xilinx Zynq MPSoC Firmware layer > + * > + * Copyright (C) 2014-2018 Xilinx, Inc. > + * > + * Michal Simek <michal.simek@xxxxxxxxxx> > + * Davorin Mista <davorin.mista@xxxxxxxxxx> > + * Jolly Shah <jollys@xxxxxxxxxx> > + * Rajan Vaja <rajanv@xxxxxxxxxx> > + */ > + > +#include <linux/arm-smccc.h> > +#include <linux/compiler.h> > +#include <linux/init.h> > +#include <linux/module.h> > +#include <linux/of.h> > +#include <linux/slab.h> > +#include <linux/uaccess.h> > + > +#include <linux/firmware/xilinx/zynqmp/firmware.h> Why do you need a file in linux/firmware anyway? > +struct zynqmp_eemi_ops { > + int (*get_api_version)(u32 *version); > + int (*get_chipid)(u32 *idcode, u32 *version); > + int (*reset_assert)(const enum zynqmp_pm_reset reset, > + const enum zynqmp_pm_reset_action assert_flag); > + int (*reset_get_status)(const enum zynqmp_pm_reset reset, u32 *status); > + int (*fpga_load)(const u64 address, const u32 size, const u32 flags); > + int (*fpga_get_status)(u32 *value); > + int (*sha_hash)(const u64 address, const u32 size, const u32 flags); > + int (*rsa)(const u64 address, const u32 size, const u32 flags); > + int (*request_suspend)(const u32 node, > + const enum zynqmp_pm_request_ack ack, > + const u32 latency, > + const u32 state); > + int (*force_powerdown)(const u32 target, > + const enum zynqmp_pm_request_ack ack); > + int (*request_wakeup)(const u32 node, > + const bool set_addr, > + const u64 address, > + const enum zynqmp_pm_request_ack ack); > + int (*set_wakeup_source)(const u32 target, > + const u32 wakeup_node, > + const u32 enable); > + int (*system_shutdown)(const u32 type, const u32 subtype); > + int (*request_node)(const u32 node, > + const u32 capabilities, > + const u32 qos, > + const enum zynqmp_pm_request_ack ack); > + int (*release_node)(const u32 node); > + int (*set_requirement)(const u32 node, > + const u32 capabilities, > + const u32 qos, > + const enum zynqmp_pm_request_ack ack); > + int (*set_max_latency)(const u32 node, const u32 latency); > + int (*set_configuration)(const u32 physical_addr); > + int (*get_node_status)(const u32 node, u32 *const status, > + u32 *const requirements, u32 *const usage); > + int (*get_operating_characteristic)(const u32 node, > + const enum zynqmp_pm_opchar_type > + type, u32 *const result); > + int (*init_finalize)(void); > + int (*set_suspend_mode)(u32 mode); > + int (*ioctl)(u32 node_id, u32 ioctl_id, u32 arg1, u32 arg2, u32 *out); > + int (*query_data)(struct zynqmp_pm_query_data qdata, u32 *out); > + int (*pinctrl_request)(const u32 pin); > + int (*pinctrl_release)(const u32 pin); > + int (*pinctrl_get_function)(const u32 pin, u32 *id); > + int (*pinctrl_set_function)(const u32 pin, const u32 id); > + int (*pinctrl_get_config)(const u32 pin, const u32 param, u32 *value); > + int (*pinctrl_set_config)(const u32 pin, const u32 param, u32 value); > + int (*clock_enable)(u32 clock_id); > + int (*clock_disable)(u32 clock_id); > + int (*clock_getstate)(u32 clock_id, u32 *state); > + int (*clock_setdivider)(u32 clock_id, u32 divider); > + int (*clock_getdivider)(u32 clock_id, u32 *divider); > + int (*clock_setrate)(u32 clock_id, u64 rate); > + int (*clock_getrate)(u32 clock_id, u64 *rate); > + int (*clock_setparent)(u32 clock_id, u32 parent_id); > + int (*clock_getparent)(u32 clock_id, u32 *parent_id); > +}; Why do you need this huge structure of pointers to functions, when you only ever set them to 1 value, and no one even calls them? Why not just export the needed symbols and call them directly? What is the indirection getting you here? thanks, greg k-h -- To unsubscribe from this list: send the line "unsubscribe devicetree" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html