diff options
Diffstat (limited to 'drivers/soc')
113 files changed, 1357 insertions, 568 deletions
diff --git a/drivers/soc/Kconfig b/drivers/soc/Kconfig index 75bdbb2c5140..833e04a7835c 100644 --- a/drivers/soc/Kconfig +++ b/drivers/soc/Kconfig @@ -1,3 +1,4 @@ +# SPDX-License-Identifier: GPL-2.0-only menu "SOC (System On Chip) specific Drivers" source "drivers/soc/actions/Kconfig" diff --git a/drivers/soc/actions/Kconfig b/drivers/soc/actions/Kconfig index 1a0b9649efb4..1aca2058a40c 100644 --- a/drivers/soc/actions/Kconfig +++ b/drivers/soc/actions/Kconfig @@ -1,3 +1,4 @@ +# SPDX-License-Identifier: GPL-2.0-only if ARCH_ACTIONS || COMPILE_TEST config OWL_PM_DOMAINS_HELPER diff --git a/drivers/soc/amlogic/Kconfig b/drivers/soc/amlogic/Kconfig index 5501ad5650b2..23bfb8ef4fdb 100644 --- a/drivers/soc/amlogic/Kconfig +++ b/drivers/soc/amlogic/Kconfig @@ -1,3 +1,4 @@ +# SPDX-License-Identifier: GPL-2.0-only menu "Amlogic SoC drivers" config MESON_CANVAS diff --git a/drivers/soc/amlogic/Makefile b/drivers/soc/amlogic/Makefile index bf2d109f61e9..f2e4ed171297 100644 --- a/drivers/soc/amlogic/Makefile +++ b/drivers/soc/amlogic/Makefile @@ -1,3 +1,4 @@ +# SPDX-License-Identifier: GPL-2.0-only obj-$(CONFIG_MESON_CANVAS) += meson-canvas.o obj-$(CONFIG_MESON_CLK_MEASURE) += meson-clk-measure.o obj-$(CONFIG_MESON_GX_SOCINFO) += meson-gx-socinfo.o diff --git a/drivers/soc/amlogic/meson-canvas.c b/drivers/soc/amlogic/meson-canvas.c index be95a37c3fec..c655f5f92b12 100644 --- a/drivers/soc/amlogic/meson-canvas.c +++ b/drivers/soc/amlogic/meson-canvas.c @@ -35,6 +35,7 @@ struct meson_canvas { void __iomem *reg_base; spinlock_t lock; /* canvas device lock */ u8 used[NUM_CANVAS]; + bool supports_endianness; }; static void canvas_write(struct meson_canvas *canvas, u32 reg, u32 val) @@ -86,6 +87,12 @@ int meson_canvas_config(struct meson_canvas *canvas, u8 canvas_index, { unsigned long flags; + if (endian && !canvas->supports_endianness) { + dev_err(canvas->dev, + "Endianness is not supported on this SoC\n"); + return -EINVAL; + } + spin_lock_irqsave(&canvas->lock, flags); if (!canvas->used[canvas_index]) { dev_err(canvas->dev, @@ -172,6 +179,8 @@ static int meson_canvas_probe(struct platform_device *pdev) if (IS_ERR(canvas->reg_base)) return PTR_ERR(canvas->reg_base); + canvas->supports_endianness = of_device_get_match_data(dev); + canvas->dev = dev; spin_lock_init(&canvas->lock); dev_set_drvdata(dev, canvas); @@ -180,7 +189,10 @@ static int meson_canvas_probe(struct platform_device *pdev) } static const struct of_device_id canvas_dt_match[] = { - { .compatible = "amlogic,canvas" }, + { .compatible = "amlogic,meson8-canvas", .data = (void *)false, }, + { .compatible = "amlogic,meson8b-canvas", .data = (void *)false, }, + { .compatible = "amlogic,meson8m2-canvas", .data = (void *)false, }, + { .compatible = "amlogic,canvas", .data = (void *)true, }, {} }; MODULE_DEVICE_TABLE(of, canvas_dt_match); diff --git a/drivers/soc/aspeed/Kconfig b/drivers/soc/aspeed/Kconfig index 765d10191387..323e177aa74d 100644 --- a/drivers/soc/aspeed/Kconfig +++ b/drivers/soc/aspeed/Kconfig @@ -1,3 +1,4 @@ +# SPDX-License-Identifier: GPL-2.0-only menu "Aspeed SoC drivers" config SOC_ASPEED diff --git a/drivers/soc/aspeed/Makefile b/drivers/soc/aspeed/Makefile index 2f7b6da7be79..b64be47f2b1f 100644 --- a/drivers/soc/aspeed/Makefile +++ b/drivers/soc/aspeed/Makefile @@ -1,3 +1,4 @@ +# SPDX-License-Identifier: GPL-2.0-only obj-$(CONFIG_ASPEED_LPC_CTRL) += aspeed-lpc-ctrl.o obj-$(CONFIG_ASPEED_LPC_SNOOP) += aspeed-lpc-snoop.o obj-$(CONFIG_ASPEED_P2A_CTRL) += aspeed-p2a-ctrl.o diff --git a/drivers/soc/aspeed/aspeed-lpc-ctrl.c b/drivers/soc/aspeed/aspeed-lpc-ctrl.c index eee26c2d8b52..01ed21e8bfee 100644 --- a/drivers/soc/aspeed/aspeed-lpc-ctrl.c +++ b/drivers/soc/aspeed/aspeed-lpc-ctrl.c @@ -1,10 +1,6 @@ +// SPDX-License-Identifier: GPL-2.0-or-later /* * Copyright 2017 IBM Corporation - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version - * 2 of the License, or (at your option) any later version. */ #include <linux/clk.h> diff --git a/drivers/soc/aspeed/aspeed-lpc-snoop.c b/drivers/soc/aspeed/aspeed-lpc-snoop.c index 2feb4347d67f..48f7ac238861 100644 --- a/drivers/soc/aspeed/aspeed-lpc-snoop.c +++ b/drivers/soc/aspeed/aspeed-lpc-snoop.c @@ -1,11 +1,7 @@ +// SPDX-License-Identifier: GPL-2.0-or-later /* * Copyright 2017 Google Inc * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version - * 2 of the License, or (at your option) any later version. - * * Provides a simple driver to control the ASPEED LPC snoop interface which * allows the BMC to listen on and save the data written by * the host to an arbitrary LPC I/O port. diff --git a/drivers/soc/atmel/Kconfig b/drivers/soc/atmel/Kconfig index 6242ebb41abb..05528139b023 100644 --- a/drivers/soc/atmel/Kconfig +++ b/drivers/soc/atmel/Kconfig @@ -1,3 +1,4 @@ +# SPDX-License-Identifier: GPL-2.0-only config AT91_SOC_ID bool "SoC bus for Atmel ARM SoCs" depends on ARCH_AT91 || COMPILE_TEST diff --git a/drivers/soc/atmel/Makefile b/drivers/soc/atmel/Makefile index 2d92f32e4ea5..7ca355d10553 100644 --- a/drivers/soc/atmel/Makefile +++ b/drivers/soc/atmel/Makefile @@ -1 +1,2 @@ +# SPDX-License-Identifier: GPL-2.0-only obj-$(CONFIG_AT91_SOC_ID) += soc.o diff --git a/drivers/soc/bcm/Kconfig b/drivers/soc/bcm/Kconfig index 03fa91fbe2da..648e32693b7e 100644 --- a/drivers/soc/bcm/Kconfig +++ b/drivers/soc/bcm/Kconfig @@ -1,3 +1,4 @@ +# SPDX-License-Identifier: GPL-2.0-only menu "Broadcom SoC drivers" config BCM2835_POWER diff --git a/drivers/soc/bcm/Makefile b/drivers/soc/bcm/Makefile index c81df4b2403c..d92268a829a9 100644 --- a/drivers/soc/bcm/Makefile +++ b/drivers/soc/bcm/Makefile @@ -1,3 +1,4 @@ +# SPDX-License-Identifier: GPL-2.0-only obj-$(CONFIG_BCM2835_POWER) += bcm2835-power.o obj-$(CONFIG_RASPBERRYPI_POWER) += raspberrypi-power.o obj-$(CONFIG_SOC_BRCMSTB) += brcmstb/ diff --git a/drivers/soc/bcm/brcmstb/Kconfig b/drivers/soc/bcm/brcmstb/Kconfig index d36f6e03c1a6..38e476905d96 100644 --- a/drivers/soc/bcm/brcmstb/Kconfig +++ b/drivers/soc/bcm/brcmstb/Kconfig @@ -1,3 +1,4 @@ +# SPDX-License-Identifier: GPL-2.0-only if SOC_BRCMSTB config BRCMSTB_PM diff --git a/drivers/soc/bcm/brcmstb/Makefile b/drivers/soc/bcm/brcmstb/Makefile index 01687c26535b..fe5c43d26dce 100644 --- a/drivers/soc/bcm/brcmstb/Makefile +++ b/drivers/soc/bcm/brcmstb/Makefile @@ -1,2 +1,3 @@ +# SPDX-License-Identifier: GPL-2.0-only obj-y += common.o biuctrl.o obj-$(CONFIG_BRCMSTB_PM) += pm/ diff --git a/drivers/soc/bcm/brcmstb/biuctrl.c b/drivers/soc/bcm/brcmstb/biuctrl.c index 6d89ebf13b8a..b3dbdb365749 100644 --- a/drivers/soc/bcm/brcmstb/biuctrl.c +++ b/drivers/soc/bcm/brcmstb/biuctrl.c @@ -1,16 +1,8 @@ +// SPDX-License-Identifier: GPL-2.0-only /* * Broadcom STB SoCs Bus Unit Interface controls * * Copyright (C) 2015, Broadcom Corporation - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. */ #define pr_fmt(fmt) "brcmstb: " KBUILD_MODNAME ": " fmt diff --git a/drivers/soc/bcm/brcmstb/common.c b/drivers/soc/bcm/brcmstb/common.c index bf9123f727e8..d33a383701dd 100644 --- a/drivers/soc/bcm/brcmstb/common.c +++ b/drivers/soc/bcm/brcmstb/common.c @@ -1,15 +1,7 @@ +// SPDX-License-Identifier: GPL-2.0-only /* * Copyright © 2014 NVIDIA Corporation * Copyright © 2015 Broadcom Corporation - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. */ #include <linux/io.h> diff --git a/drivers/soc/bcm/brcmstb/pm/Makefile b/drivers/soc/bcm/brcmstb/pm/Makefile index 08bbd244ef11..8e10abb14f8b 100644 --- a/drivers/soc/bcm/brcmstb/pm/Makefile +++ b/drivers/soc/bcm/brcmstb/pm/Makefile @@ -1,3 +1,4 @@ +# SPDX-License-Identifier: GPL-2.0-only obj-$(CONFIG_ARM) += s2-arm.o pm-arm.o AFLAGS_s2-arm.o := -march=armv7-a obj-$(CONFIG_BMIPS_GENERIC) += s2-mips.o s3-mips.o pm-mips.o diff --git a/drivers/soc/bcm/brcmstb/pm/aon_defs.h b/drivers/soc/bcm/brcmstb/pm/aon_defs.h index fb936abd847d..f695262ac930 100644 --- a/drivers/soc/bcm/brcmstb/pm/aon_defs.h +++ b/drivers/soc/bcm/brcmstb/pm/aon_defs.h @@ -1,16 +1,8 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ /* * Always ON (AON) register interface between bootloader and Linux * * Copyright © 2014-2017 Broadcom - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. */ #ifndef __BRCMSTB_AON_DEFS_H__ diff --git a/drivers/soc/bcm/brcmstb/pm/pm-arm.c b/drivers/soc/bcm/brcmstb/pm/pm-arm.c index 8ee06347447c..b1062334e608 100644 --- a/drivers/soc/bcm/brcmstb/pm/pm-arm.c +++ b/drivers/soc/bcm/brcmstb/pm/pm-arm.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0-only /* * ARM-specific support for Broadcom STB S2/S3/S5 power management * @@ -8,15 +9,6 @@ * treat this mode like a soft power-off, with wakeup allowed from AON * * Copyright © 2014-2017 Broadcom - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. */ #define pr_fmt(fmt) "brcmstb-pm: " fmt diff --git a/drivers/soc/bcm/brcmstb/pm/pm-mips.c b/drivers/soc/bcm/brcmstb/pm/pm-mips.c index 9300b5f62e56..cdc3e387f049 100644 --- a/drivers/soc/bcm/brcmstb/pm/pm-mips.c +++ b/drivers/soc/bcm/brcmstb/pm/pm-mips.c @@ -1,16 +1,8 @@ +// SPDX-License-Identifier: GPL-2.0-only /* * MIPS-specific support for Broadcom STB S2/S3/S5 power management * * Copyright (C) 2016-2017 Broadcom - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. */ #include <linux/kernel.h> diff --git a/drivers/soc/bcm/brcmstb/pm/pm.h b/drivers/soc/bcm/brcmstb/pm/pm.h index b7d35ac70e60..94a380470a2f 100644 --- a/drivers/soc/bcm/brcmstb/pm/pm.h +++ b/drivers/soc/bcm/brcmstb/pm/pm.h @@ -1,16 +1,8 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ /* * Definitions for Broadcom STB power management / Always ON (AON) block * * Copyright © 2016-2017 Broadcom - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. */ #ifndef __BRCMSTB_PM_H__ diff --git a/drivers/soc/bcm/brcmstb/pm/s2-arm.S b/drivers/soc/bcm/brcmstb/pm/s2-arm.S index 1d472d564638..5f0c4a8ae9df 100644 --- a/drivers/soc/bcm/brcmstb/pm/s2-arm.S +++ b/drivers/soc/bcm/brcmstb/pm/s2-arm.S @@ -1,14 +1,6 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ /* * Copyright © 2014-2017 Broadcom - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. */ #include <linux/linkage.h> diff --git a/drivers/soc/bcm/brcmstb/pm/s2-mips.S b/drivers/soc/bcm/brcmstb/pm/s2-mips.S index 27a14bc46043..2a26a94eb9bb 100644 --- a/drivers/soc/bcm/brcmstb/pm/s2-mips.S +++ b/drivers/soc/bcm/brcmstb/pm/s2-mips.S @@ -1,14 +1,6 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ /* * Copyright (C) 2016 Broadcom Corporation - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. */ #include <asm/asm.h> diff --git a/drivers/soc/bcm/brcmstb/pm/s3-mips.S b/drivers/soc/bcm/brcmstb/pm/s3-mips.S index 1242308a8868..ecfcfd34c2f8 100644 --- a/drivers/soc/bcm/brcmstb/pm/s3-mips.S +++ b/drivers/soc/bcm/brcmstb/pm/s3-mips.S @@ -1,14 +1,6 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ /* * Copyright (C) 2016 Broadcom Corporation - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. */ #include <asm/asm.h> diff --git a/drivers/soc/dove/Makefile b/drivers/soc/dove/Makefile index 2db8e65513a3..daf4549ec7d4 100644 --- a/drivers/soc/dove/Makefile +++ b/drivers/soc/dove/Makefile @@ -1 +1,2 @@ +# SPDX-License-Identifier: GPL-2.0-only obj-y += pmu.o diff --git a/drivers/soc/fsl/Kconfig b/drivers/soc/fsl/Kconfig index 61f8e1433d0a..f9ad8ad54a7d 100644 --- a/drivers/soc/fsl/Kconfig +++ b/drivers/soc/fsl/Kconfig @@ -1,3 +1,4 @@ +# SPDX-License-Identifier: GPL-2.0-only # # NXP/Freescale QorIQ series SOC drivers # @@ -29,4 +30,14 @@ config FSL_MC_DPIO other DPAA2 objects. This driver does not expose the DPIO objects individually, but groups them under a service layer API. + +config DPAA2_CONSOLE + tristate "QorIQ DPAA2 console driver" + depends on OF && (ARCH_LAYERSCAPE || COMPILE_TEST) + default y + help + Console driver for DPAA2 platforms. Exports 2 char devices, + /dev/dpaa2_mc_console and /dev/dpaa2_aiop_console, + which can be used to dump the Management Complex and AIOP + firmware logs. endmenu diff --git a/drivers/soc/fsl/Makefile b/drivers/soc/fsl/Makefile index 803ef1bfb5ff..71dee8d0d1f0 100644 --- a/drivers/soc/fsl/Makefile +++ b/drivers/soc/fsl/Makefile @@ -1,3 +1,4 @@ +# SPDX-License-Identifier: GPL-2.0-only # # Makefile for the Linux Kernel SOC fsl specific device drivers # @@ -7,3 +8,4 @@ obj-$(CONFIG_QUICC_ENGINE) += qe/ obj-$(CONFIG_CPM) += qe/ obj-$(CONFIG_FSL_GUTS) += guts.o obj-$(CONFIG_FSL_MC_DPIO) += dpio/ +obj-$(CONFIG_DPAA2_CONSOLE) += dpaa2-console.o diff --git a/drivers/soc/fsl/dpaa2-console.c b/drivers/soc/fsl/dpaa2-console.c new file mode 100644 index 000000000000..9168d8ddc932 --- /dev/null +++ b/drivers/soc/fsl/dpaa2-console.c @@ -0,0 +1,329 @@ +// SPDX-License-Identifier: (GPL-2.0+ OR BSD-3-Clause) +/* + * Freescale DPAA2 Platforms Console Driver + * + * Copyright 2015-2016 Freescale Semiconductor Inc. + * Copyright 2018 NXP + */ + +#define pr_fmt(fmt) "dpaa2-console: " fmt + +#include <linux/module.h> +#include <linux/of_device.h> +#include <linux/of_address.h> +#include <linux/miscdevice.h> +#include <linux/uaccess.h> +#include <linux/slab.h> +#include <linux/fs.h> +#include <linux/io.h> + +/* MC firmware base low/high registers indexes */ +#define MCFBALR_OFFSET 0 +#define MCFBAHR_OFFSET 1 + +/* Bit masks used to get the most/least significant part of the MC base addr */ +#define MC_FW_ADDR_MASK_HIGH 0x1FFFF +#define MC_FW_ADDR_MASK_LOW 0xE0000000 + +#define MC_BUFFER_OFFSET 0x01000000 +#define MC_BUFFER_SIZE (1024 * 1024 * 16) +#define MC_OFFSET_DELTA MC_BUFFER_OFFSET + +#define AIOP_BUFFER_OFFSET 0x06000000 +#define AIOP_BUFFER_SIZE (1024 * 1024 * 16) +#define AIOP_OFFSET_DELTA 0 + +#define LOG_HEADER_FLAG_BUFFER_WRAPAROUND 0x80000000 +#define LAST_BYTE(a) ((a) & ~(LOG_HEADER_FLAG_BUFFER_WRAPAROUND)) + +/* MC and AIOP Magic words */ +#define MAGIC_MC 0x4d430100 +#define MAGIC_AIOP 0x41494F50 + +struct log_header { + __le32 magic_word; + char reserved[4]; + __le32 buf_start; + __le32 buf_length; + __le32 last_byte; +}; + +struct console_data { + void __iomem *map_addr; + struct log_header __iomem *hdr; + void __iomem *start_addr; + void __iomem *end_addr; + void __iomem *end_of_data; + void __iomem *cur_ptr; +}; + +static struct resource mc_base_addr; + +static inline void adjust_end(struct console_data *cd) +{ + u32 last_byte = readl(&cd->hdr->last_byte); + + cd->end_of_data = cd->start_addr + LAST_BYTE(last_byte); +} + +static u64 get_mc_fw_base_address(void) +{ + u64 mcfwbase = 0ULL; + u32 __iomem *mcfbaregs; + + mcfbaregs = ioremap(mc_base_addr.start, resource_size(&mc_base_addr)); + if (!mcfbaregs) { + pr_err("could not map MC Firmaware Base registers\n"); + return 0; + } + + mcfwbase = readl(mcfbaregs + MCFBAHR_OFFSET) & + MC_FW_ADDR_MASK_HIGH; + mcfwbase <<= 32; + mcfwbase |= readl(mcfbaregs + MCFBALR_OFFSET) & MC_FW_ADDR_MASK_LOW; + iounmap(mcfbaregs); + + pr_debug("MC base address at 0x%016llx\n", mcfwbase); + return mcfwbase; +} + +static ssize_t dpaa2_console_size(struct console_data *cd) +{ + ssize_t size; + + if (cd->cur_ptr <= cd->end_of_data) + size = cd->end_of_data - cd->cur_ptr; + else + size = (cd->end_addr - cd->cur_ptr) + + (cd->end_of_data - cd->start_addr); + + return size; +} + +static int dpaa2_generic_console_open(struct inode *node, struct file *fp, + u64 offset, u64 size, + u32 expected_magic, + u32 offset_delta) +{ + u32 read_magic, wrapped, last_byte, buf_start, buf_length; + struct console_data *cd; + u64 base_addr; + int err; + + cd = kmalloc(sizeof(*cd), GFP_KERNEL); + if (!cd) + return -ENOMEM; + + base_addr = get_mc_fw_base_address(); + if (!base_addr) { + err = -EIO; + goto err_fwba; + } + + cd->map_addr = ioremap(base_addr + offset, size); + if (!cd->map_addr) { + pr_err("cannot map console log memory\n"); + err = -EIO; + goto err_ioremap; + } + + cd->hdr = (struct log_header __iomem *)cd->map_addr; + read_magic = readl(&cd->hdr->magic_word); + last_byte = readl(&cd->hdr->last_byte); + buf_start = readl(&cd->hdr->buf_start); + buf_length = readl(&cd->hdr->buf_length); + + if (read_magic != expected_magic) { + pr_warn("expected = %08x, read = %08x\n", + expected_magic, read_magic); + err = -EIO; + goto err_magic; + } + + cd->start_addr = cd->map_addr + buf_start - offset_delta; + cd->end_addr = cd->start_addr + buf_length; + + wrapped = last_byte & LOG_HEADER_FLAG_BUFFER_WRAPAROUND; + + adjust_end(cd); + if (wrapped && cd->end_of_data != cd->end_addr) + cd->cur_ptr = cd->end_of_data + 1; + else + cd->cur_ptr = cd->start_addr; + + fp->private_data = cd; + + return 0; + +err_magic: + iounmap(cd->map_addr); + +err_ioremap: +err_fwba: + kfree(cd); + + return err; +} + +static int dpaa2_mc_console_open(struct inode *node, struct file *fp) +{ + return dpaa2_generic_console_open(node, fp, + MC_BUFFER_OFFSET, MC_BUFFER_SIZE, + MAGIC_MC, MC_OFFSET_DELTA); +} + +static int dpaa2_aiop_console_open(struct inode *node, struct file *fp) +{ + return dpaa2_generic_console_open(node, fp, + AIOP_BUFFER_OFFSET, AIOP_BUFFER_SIZE, + MAGIC_AIOP, AIOP_OFFSET_DELTA); +} + +static int dpaa2_console_close(struct inode *node, struct file *fp) +{ + struct console_data *cd = fp->private_data; + + iounmap(cd->map_addr); + kfree(cd); + return 0; +} + +static ssize_t dpaa2_console_read(struct file *fp, char __user *buf, + size_t count, loff_t *f_pos) +{ + struct console_data *cd = fp->private_data; + size_t bytes = dpaa2_console_size(cd); + size_t bytes_end = cd->end_addr - cd->cur_ptr; + size_t written = 0; + void *kbuf; + int err; + + /* Check if we need to adjust the end of data addr */ + adjust_end(cd); + + if (cd->end_of_data == cd->cur_ptr) + return 0; + + if (count < bytes) + bytes = count; + + kbuf = kmalloc(bytes, GFP_KERNEL); + if (!kbuf) + return -ENOMEM; + + if (bytes > bytes_end) { + memcpy_fromio(kbuf, cd->cur_ptr, bytes_end); + if (copy_to_user(buf, kbuf, bytes_end)) { + err = -EFAULT; + goto err_free_buf; + } + buf += bytes_end; + cd->cur_ptr = cd->start_addr; + bytes -= bytes_end; + written += bytes_end; + } + + memcpy_fromio(kbuf, cd->cur_ptr, bytes); + if (copy_to_user(buf, kbuf, bytes)) { + err = -EFAULT; + goto err_free_buf; + } + cd->cur_ptr += bytes; + written += bytes; + + return written; + +err_free_buf: + kfree(kbuf); + + return err; +} + +static const struct file_operations dpaa2_mc_console_fops = { + .owner = THIS_MODULE, + .open = dpaa2_mc_console_open, + .release = dpaa2_console_close, + .read = dpaa2_console_read, +}; + +static struct miscdevice dpaa2_mc_console_dev = { + .minor = MISC_DYNAMIC_MINOR, + .name = "dpaa2_mc_console", + .fops = &dpaa2_mc_console_fops +}; + +static const struct file_operations dpaa2_aiop_console_fops = { + .owner = THIS_MODULE, + .open = dpaa2_aiop_console_open, + .release = dpaa2_console_close, + .read = dpaa2_console_read, +}; + +static struct miscdevice dpaa2_aiop_console_dev = { + .minor = MISC_DYNAMIC_MINOR, + .name = "dpaa2_aiop_console", + .fops = &dpaa2_aiop_console_fops +}; + +static int dpaa2_console_probe(struct platform_device *pdev) +{ + int error; + + error = of_address_to_resource(pdev->dev.of_node, 0, &mc_base_addr); + if (error < 0) { + pr_err("of_address_to_resource() failed for %pOF with %d\n", + pdev->dev.of_node, error); + return error; + } + + error = misc_register(&dpaa2_mc_console_dev); + if (error) { + pr_err("cannot register device %s\n", + dpaa2_mc_console_dev.name); + goto err_register_mc; + } + + error = misc_register(&dpaa2_aiop_console_dev); + if (error) { + pr_err("cannot register device %s\n", + dpaa2_aiop_console_dev.name); + goto err_register_aiop; + } + + return 0; + +err_register_aiop: + misc_deregister(&dpaa2_mc_console_dev); +err_register_mc: + return error; +} + +static int dpaa2_console_remove(struct platform_device *pdev) +{ + misc_deregister(&dpaa2_mc_console_dev); + misc_deregister(&dpaa2_aiop_console_dev); + + return 0; +} + +static const struct of_device_id dpaa2_console_match_table[] = { + { .compatible = "fsl,dpaa2-console",}, + {}, +}; + +MODULE_DEVICE_TABLE(of, dpaa2_console_match_table); + +static struct platform_driver dpaa2_console_driver = { + .driver = { + .name = "dpaa2-console", + .pm = NULL, + .of_match_table = dpaa2_console_match_table, + }, + .probe = dpaa2_console_probe, + .remove = dpaa2_console_remove, +}; +module_platform_driver(dpaa2_console_driver); + +MODULE_LICENSE("Dual BSD/GPL"); +MODULE_AUTHOR("Roy Pledge <roy.pledge@nxp.com>"); +MODULE_DESCRIPTION("DPAA2 console driver"); diff --git a/drivers/soc/fsl/dpio/dpio-driver.c b/drivers/soc/fsl/dpio/dpio-driver.c index c0cdc8946031..70014ecce2a7 100644 --- a/drivers/soc/fsl/dpio/dpio-driver.c +++ b/drivers/soc/fsl/dpio/dpio-driver.c @@ -197,13 +197,22 @@ static int dpaa2_dpio_probe(struct fsl_mc_device *dpio_dev) desc.cpu); } - /* - * Set the CENA regs to be the cache inhibited area of the portal to - * avoid coherency issues if a user migrates to another core. - */ - desc.regs_cena = devm_memremap(dev, dpio_dev->regions[1].start, - resource_size(&dpio_dev->regions[1]), - MEMREMAP_WC); + if (dpio_dev->obj_desc.region_count < 3) { + /* No support for DDR backed portals, use classic mapping */ + /* + * Set the CENA regs to be the cache inhibited area of the + * portal to avoid coherency issues if a user migrates to + * another core. + */ + desc.regs_cena = devm_memremap(dev, dpio_dev->regions[1].start, + resource_size(&dpio_dev->regions[1]), + MEMREMAP_WC); + } else { + desc.regs_cena = devm_memremap(dev, dpio_dev->regions[2].start, + resource_size(&dpio_dev->regions[2]), + MEMREMAP_WB); + } + if (IS_ERR(desc.regs_cena)) { dev_err(dev, "devm_memremap failed\n"); err = PTR_ERR(desc.regs_cena); diff --git a/drivers/soc/fsl/dpio/qbman-portal.c b/drivers/soc/fsl/dpio/qbman-portal.c index d02013556a1b..c66f5b73777c 100644 --- a/drivers/soc/fsl/dpio/qbman-portal.c +++ b/drivers/soc/fsl/dpio/qbman-portal.c @@ -15,6 +15,8 @@ #define QMAN_REV_4000 0x04000000 #define QMAN_REV_4100 0x04010000 #define QMAN_REV_4101 0x04010001 +#define QMAN_REV_5000 0x05000000 + #define QMAN_REV_MASK 0xffff0000 /* All QBMan command and result structures use this "valid bit" encoding */ @@ -25,10 +27,17 @@ #define QBMAN_WQCHAN_CONFIGURE 0x46 /* CINH register offsets */ +#define QBMAN_CINH_SWP_EQCR_PI 0x800 #define QBMAN_CINH_SWP_EQAR 0x8c0 +#define QBMAN_CINH_SWP_CR_RT 0x900 +#define QBMAN_CINH_SWP_VDQCR_RT 0x940 +#define QBMAN_CINH_SWP_EQCR_AM_RT 0x980 +#define QBMAN_CINH_SWP_RCR_AM_RT 0x9c0 #define QBMAN_CINH_SWP_DQPI 0xa00 #define QBMAN_CINH_SWP_DCAP 0xac0 #define QBMAN_CINH_SWP_SDQCR 0xb00 +#define QBMAN_CINH_SWP_EQCR_AM_RT2 0xb40 +#define QBMAN_CINH_SWP_RCR_PI 0xc00 #define QBMAN_CINH_SWP_RAR 0xcc0 #define QBMAN_CINH_SWP_ISR 0xe00 #define QBMAN_CINH_SWP_IER 0xe40 @@ -43,6 +52,13 @@ #define QBMAN_CENA_SWP_RR(vb) (0x700 + ((u32)(vb) >> 1)) #define QBMAN_CENA_SWP_VDQCR 0x780 +/* CENA register offsets in memory-backed mode */ +#define QBMAN_CENA_SWP_DQRR_MEM(n) (0x800 + ((u32)(n) << 6)) +#define QBMAN_CENA_SWP_RCR_MEM(n) (0x1400 + ((u32)(n) << 6)) +#define QBMAN_CENA_SWP_CR_MEM 0x1600 +#define QBMAN_CENA_SWP_RR_MEM 0x1680 +#define QBMAN_CENA_SWP_VDQCR_MEM 0x1780 + /* Reverse mapping of QBMAN_CENA_SWP_DQRR() */ #define QBMAN_IDX_FROM_DQRR(p) (((unsigned long)(p) & 0x1ff) >> 6) @@ -96,10 +112,13 @@ static inline void *qbman_get_cmd(struct qbman_swp *p, u32 offset) #define SWP_CFG_DQRR_MF_SHIFT 20 #define SWP_CFG_EST_SHIFT 16 +#define SWP_CFG_CPBS_SHIFT 15 #define SWP_CFG_WN_SHIFT 14 #define SWP_CFG_RPM_SHIFT 12 #define SWP_CFG_DCM_SHIFT 10 #define SWP_CFG_EPM_SHIFT 8 +#define SWP_CFG_VPM_SHIFT 7 +#define SWP_CFG_CPM_SHIFT 6 #define SWP_CFG_SD_SHIFT 5 #define SWP_CFG_SP_SHIFT 4 #define SWP_CFG_SE_SHIFT 3 @@ -125,6 +144,8 @@ static inline u32 qbman_set_swp_cfg(u8 max_fill, u8 wn, u8 est, u8 rpm, u8 dcm, ep << SWP_CFG_EP_SHIFT); } +#define QMAN_RT_MODE 0x00000100 + /** * qbman_swp_init() - Create a functional object representing the given * QBMan portal descriptor. @@ -146,6 +167,8 @@ struct qbman_swp *qbman_swp_init(const struct qbman_swp_desc *d) p->sdq |= qbman_sdqcr_dct_prio_ics << QB_SDQCR_DCT_SHIFT; p->sdq |= qbman_sdqcr_fc_up_to_3 << QB_SDQCR_FC_SHIFT; p->sdq |= QMAN_SDQCR_TOKEN << QB_SDQCR_TOK_SHIFT; + if ((p->desc->qman_version & QMAN_REV_MASK) >= QMAN_REV_5000) + p->mr.valid_bit = QB_VALID_BIT; atomic_set(&p->vdq.available, 1); p->vdq.valid_bit = QB_VALID_BIT; @@ -163,6 +186,9 @@ struct qbman_swp *qbman_swp_init(const struct qbman_swp_desc *d) p->addr_cena = d->cena_bar; p->addr_cinh = d->cinh_bar; + if ((p->desc->qman_version & QMAN_REV_MASK) >= QMAN_REV_5000) + memset(p->addr_cena, 0, 64 * 1024); + reg = qbman_set_swp_cfg(p->dqrr.dqrr_size, 1, /* Writes Non-cacheable */ 0, /* EQCR_CI stashing threshold */ @@ -175,6 +201,10 @@ struct qbman_swp *qbman_swp_init(const struct qbman_swp_desc *d) 1, /* dequeue stashing priority == TRUE */ 0, /* dequeue stashing enable == FALSE */ 0); /* EQCR_CI stashing priority == FALSE */ + if ((p->desc->qman_version & QMAN_REV_MASK) >= QMAN_REV_5000) + reg |= 1 << SWP_CFG_CPBS_SHIFT | /* memory-backed mode */ + 1 << SWP_CFG_VPM_SHIFT | /* VDQCR read triggered mode */ + 1 << SWP_CFG_CPM_SHIFT; /* CR read triggered mode */ qbman_write_register(p, QBMAN_CINH_SWP_CFG, reg); reg = qbman_read_register(p, QBMAN_CINH_SWP_CFG); @@ -184,6 +214,10 @@ struct qbman_swp *qbman_swp_init(const struct qbman_swp_desc *d) return NULL; } + if ((p->desc->qman_version & QMAN_REV_MASK) >= QMAN_REV_5000) { + qbman_write_register(p, QBMAN_CINH_SWP_EQCR_PI, QMAN_RT_MODE); + qbman_write_register(p, QBMAN_CINH_SWP_RCR_PI, QMAN_RT_MODE); + } /* * SDQCR needs to be initialized to 0 when no channels are * being dequeued from or else the QMan HW will indicate an @@ -278,7 +312,10 @@ void qbman_swp_interrupt_set_inhibit(struct qbman_swp *p, int inhibit) */ void *qbman_swp_mc_start(struct qbman_swp *p) { - return qbman_get_cmd(p, QBMAN_CENA_SWP_CR); + if ((p->desc->qman_version & QMAN_REV_MASK) < QMAN_REV_5000) + return qbman_get_cmd(p, QBMAN_CENA_SWP_CR); + else + return qbman_get_cmd(p, QBMAN_CENA_SWP_CR_MEM); } /* @@ -289,8 +326,14 @@ void qbman_swp_mc_submit(struct qbman_swp *p, void *cmd, u8 cmd_verb) { u8 *v = cmd; - dma_wmb(); - *v = cmd_verb | p->mc.valid_bit; + if ((p->desc->qman_version & QMAN_REV_MASK) < QMAN_REV_5000) { + dma_wmb(); + *v = cmd_verb | p->mc.valid_bit; + } else { + *v = cmd_verb | p->mc.valid_bit; + dma_wmb(); + qbman_write_register(p, QBMAN_CINH_SWP_CR_RT, QMAN_RT_MODE); + } } /* @@ -301,13 +344,27 @@ void *qbman_swp_mc_result(struct qbman_swp *p) { u32 *ret, verb; - ret = qbman_get_cmd(p, QBMAN_CENA_SWP_RR(p->mc.valid_bit)); + if ((p->desc->qman_version & QMAN_REV_MASK) < QMAN_REV_5000) { + ret = qbman_get_cmd(p, QBMAN_CENA_SWP_RR(p->mc.valid_bit)); + /* Remove the valid-bit - command completed if the rest + * is non-zero. + */ + verb = ret[0] & ~QB_VALID_BIT; + if (!verb) + return NULL; + p->mc.valid_bit ^= QB_VALID_BIT; + } else { + ret = qbman_get_cmd(p, QBMAN_CENA_SWP_RR_MEM); + /* Command completed if the valid bit is toggled */ + if (p->mr.valid_bit != (ret[0] & QB_VALID_BIT)) + return NULL; + /* Command completed if the rest is non-zero */ + verb = ret[0] & ~QB_VALID_BIT; + if (!verb) + return NULL; + p->mr.valid_bit ^= QB_VALID_BIT; + } - /* Remove the valid-bit - command completed if the rest is non-zero */ - verb = ret[0] & ~QB_VALID_BIT; - if (!verb) - return NULL; - p->mc.valid_bit ^= QB_VALID_BIT; return ret; } @@ -384,6 +441,18 @@ void qbman_eq_desc_set_qd(struct qbman_eq_desc *d, u32 qdid, #define EQAR_VB(eqar) ((eqar) & 0x80) #define EQAR_SUCCESS(eqar) ((eqar) & 0x100) +static inline void qbman_write_eqcr_am_rt_register(struct qbman_swp *p, + u8 idx) +{ + if (idx < 16) + qbman_write_register(p, QBMAN_CINH_SWP_EQCR_AM_RT + idx * 4, + QMAN_RT_MODE); + else + qbman_write_register(p, QBMAN_CINH_SWP_EQCR_AM_RT2 + + (idx - 16) * 4, + QMAN_RT_MODE); +} + /** * qbman_swp_enqueue() - Issue an enqueue command * @s: the software portal used for enqueue @@ -408,9 +477,15 @@ int qbman_swp_enqueue(struct qbman_swp *s, const struct qbman_eq_desc *d, memcpy(&p->dca, &d->dca, 31); memcpy(&p->fd, fd, sizeof(*fd)); - /* Set the verb byte, have to substitute in the valid-bit */ - dma_wmb(); - p->verb = d->verb | EQAR_VB(eqar); + if ((s->desc->qman_version & QMAN_REV_MASK) < QMAN_REV_5000) { + /* Set the verb byte, have to substitute in the valid-bit */ + dma_wmb(); + p->verb = d->verb | EQAR_VB(eqar); + } else { + p->verb = d->verb | EQAR_VB(eqar); + dma_wmb(); + qbman_write_eqcr_am_rt_register(s, EQAR_IDX(eqar)); + } return 0; } @@ -587,17 +662,27 @@ int qbman_swp_pull(struct qbman_swp *s, struct qbman_pull_desc *d) return -EBUSY; } s->vdq.storage = (void *)(uintptr_t)d->rsp_addr_virt; - p = qbman_get_cmd(s, QBMAN_CENA_SWP_VDQCR); + if ((s->desc->qman_version & QMAN_REV_MASK) < QMAN_REV_5000) + p = qbman_get_cmd(s, QBMAN_CENA_SWP_VDQCR); + else + p = qbman_get_cmd(s, QBMAN_CENA_SWP_VDQCR_MEM); p->numf = d->numf; p->tok = QMAN_DQ_TOKEN_VALID; p->dq_src = d->dq_src; p->rsp_addr = d->rsp_addr; p->rsp_addr_virt = d->rsp_addr_virt; - dma_wmb(); - /* Set the verb byte, have to substitute in the valid-bit */ - p->verb = d->verb | s->vdq.valid_bit; - s->vdq.valid_bit ^= QB_VALID_BIT; + if ((s->desc->qman_version & QMAN_REV_MASK) < QMAN_REV_5000) { + dma_wmb(); + /* Set the verb byte, have to substitute in the valid-bit */ + p->verb = d->verb | s->vdq.valid_bit; + s->vdq.valid_bit ^= QB_VALID_BIT; + } else { + p->verb = d->verb | s->vdq.valid_bit; + s->vdq.valid_bit ^= QB_VALID_BIT; + dma_wmb(); + qbman_write_register(s, QBMAN_CINH_SWP_VDQCR_RT, QMAN_RT_MODE); + } return 0; } @@ -655,7 +740,10 @@ const struct dpaa2_dq *qbman_swp_dqrr_next(struct qbman_swp *s) QBMAN_CENA_SWP_DQRR(s->dqrr.next_idx))); } - p = qbman_get_cmd(s, QBMAN_CENA_SWP_DQRR(s->dqrr.next_idx)); + if ((s->desc->qman_version & QMAN_REV_MASK) < QMAN_REV_5000) + p = qbman_get_cmd(s, QBMAN_CENA_SWP_DQRR(s->dqrr.next_idx)); + else + p = qbman_get_cmd(s, QBMAN_CENA_SWP_DQRR_MEM(s->dqrr.next_idx)); verb = p->dq.verb; /* @@ -807,18 +895,28 @@ int qbman_swp_release(struct qbman_swp *s, const struct qbman_release_desc *d, return -EBUSY; /* Start the release command */ - p = qbman_get_cmd(s, QBMAN_CENA_SWP_RCR(RAR_IDX(rar))); + if ((s->desc->qman_version & QMAN_REV_MASK) < QMAN_REV_5000) + p = qbman_get_cmd(s, QBMAN_CENA_SWP_RCR(RAR_IDX(rar))); + else + p = qbman_get_cmd(s, QBMAN_CENA_SWP_RCR_MEM(RAR_IDX(rar))); /* Copy the caller's buffer pointers to the command */ for (i = 0; i < num_buffers; i++) p->buf[i] = cpu_to_le64(buffers[i]); p->bpid = d->bpid; - /* - * Set the verb byte, have to substitute in the valid-bit and the number - * of buffers. - */ - dma_wmb(); - p->verb = d->verb | RAR_VB(rar) | num_buffers; + if ((s->desc->qman_version & QMAN_REV_MASK) < QMAN_REV_5000) { + /* + * Set the verb byte, have to substitute in the valid-bit + * and the number of buffers. + */ + dma_wmb(); + p->verb = d->verb | RAR_VB(rar) | num_buffers; + } else { + p->verb = d->verb | RAR_VB(rar) | num_buffers; + dma_wmb(); + qbman_write_register(s, QBMAN_CINH_SWP_RCR_AM_RT + + RAR_IDX(rar) * 4, QMAN_RT_MODE); + } return 0; } diff --git a/drivers/soc/fsl/dpio/qbman-portal.h b/drivers/soc/fsl/dpio/qbman-portal.h index fa35fc1afeaa..f3ec5d2044fb 100644 --- a/drivers/soc/fsl/dpio/qbman-portal.h +++ b/drivers/soc/fsl/dpio/qbman-portal.h @@ -1,7 +1,7 @@ /* SPDX-License-Identifier: (GPL-2.0+ OR BSD-3-Clause) */ /* * Copyright (C) 2014-2016 Freescale Semiconductor, Inc. - * Copyright 2016 NXP + * Copyright 2016-2019 NXP * */ #ifndef __FSL_QBMAN_PORTAL_H @@ -110,6 +110,11 @@ struct qbman_swp { u32 valid_bit; /* 0x00 or 0x80 */ } mc; + /* Management response */ + struct { + u32 valid_bit; /* 0x00 or 0x80 */ + } mr; + /* Push dequeues */ u32 sdq; @@ -428,7 +433,7 @@ static inline int qbman_swp_CDAN_set_context_enable(struct qbman_swp *s, static inline void *qbman_swp_mc_complete(struct qbman_swp *swp, void *cmd, u8 cmd_verb) { - int loopvar = 1000; + int loopvar = 2000; qbman_swp_mc_submit(swp, cmd, cmd_verb); diff --git a/drivers/soc/fsl/guts.c b/drivers/soc/fsl/guts.c index 63f6df86f9e5..1ef8068c8dd3 100644 --- a/drivers/soc/fsl/guts.c +++ b/drivers/soc/fsl/guts.c @@ -1,12 +1,8 @@ +// SPDX-License-Identifier: GPL-2.0-or-later /* * Freescale QorIQ Platforms GUTS Driver * * Copyright (C) 2016 Freescale Semiconductor, Inc. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. */ #include <linux/io.h> @@ -101,6 +97,11 @@ static const struct fsl_soc_die_attr fsl_soc_die[] = { .svr = 0x87000000, .mask = 0xfff70000, }, + /* Die: LX2160A, SoC: LX2160A/LX2120A/LX2080A */ + { .die = "LX2160A", + .svr = 0x87360000, + .mask = 0xff3f0000, + }, { }, }; @@ -222,6 +223,7 @@ static const struct of_device_id fsl_guts_of_match[] = { { .compatible = "fsl,ls1088a-dcfg", }, { .compatible = "fsl,ls1012a-dcfg", }, { .compatible = "fsl,ls1046a-dcfg", }, + { .compatible = "fsl,lx2160a-dcfg", }, {} }; MODULE_DEVICE_TABLE(of, fsl_guts_of_match); diff --git a/drivers/soc/fsl/qbman/Kconfig b/drivers/soc/fsl/qbman/Kconfig index b0943e541796..bdecb86bb656 100644 --- a/drivers/soc/fsl/qbman/Kconfig +++ b/drivers/soc/fsl/qbman/Kconfig @@ -1,3 +1,4 @@ +# SPDX-License-Identifier: GPL-2.0-only menuconfig FSL_DPAA bool "QorIQ DPAA1 framework support" depends on ((FSL_SOC_BOOKE || ARCH_LAYERSCAPE) && ARCH_DMA_ADDR_T_64BIT) diff --git a/drivers/soc/fsl/qbman/bman_portal.c b/drivers/soc/fsl/qbman/bman_portal.c index 2c95cf59f3e7..cf4f10d6f590 100644 --- a/drivers/soc/fsl/qbman/bman_portal.c +++ b/drivers/soc/fsl/qbman/bman_portal.c @@ -32,6 +32,7 @@ static struct bman_portal *affine_bportals[NR_CPUS]; static struct cpumask portal_cpus; +static int __bman_portals_probed; /* protect bman global registers and global data shared among portals */ static DEFINE_SPINLOCK(bman_lock); @@ -87,6 +88,12 @@ static int bman_online_cpu(unsigned int cpu) return 0; } +int bman_portals_probed(void) +{ + return __bman_portals_probed; +} +EXPORT_SYMBOL_GPL(bman_portals_probed); + static int bman_portal_probe(struct platform_device *pdev) { struct device *dev = &pdev->dev; @@ -104,8 +111,10 @@ static int bman_portal_probe(struct platform_device *pdev) } pcfg = devm_kmalloc(dev, sizeof(*pcfg), GFP_KERNEL); - if (!pcfg) + if (!pcfg) { + __bman_portals_probed = -1; return -ENOMEM; + } pcfg->dev = dev; @@ -113,14 +122,14 @@ static int bman_portal_probe(struct platform_device *pdev) DPAA_PORTAL_CE); if (!addr_phys[0]) { dev_err(dev, "Can't get %pOF property 'reg::CE'\n", node); - return -ENXIO; + goto err_ioremap1; } addr_phys[1] = platform_get_resource(pdev, IORESOURCE_MEM, DPAA_PORTAL_CI); if (!addr_phys[1]) { dev_err(dev, "Can't get %pOF property 'reg::CI'\n", node); - return -ENXIO; + goto err_ioremap1; } pcfg->cpu = -1; @@ -128,7 +137,7 @@ static int bman_portal_probe(struct platform_device *pdev) irq = platform_get_irq(pdev, 0); if (irq <= 0) { dev_err(dev, "Can't get %pOF IRQ'\n", node); - return -ENXIO; + goto err_ioremap1; } pcfg->irq = irq; @@ -150,6 +159,7 @@ static int bman_portal_probe(struct platform_device *pdev) spin_lock(&bman_lock); cpu = cpumask_next_zero(-1, &portal_cpus); if (cpu >= nr_cpu_ids) { + __bman_portals_probed = 1; /* unassigned portal, skip init */ spin_unlock(&bman_lock); return 0; @@ -175,6 +185,8 @@ err_portal_init: err_ioremap2: memunmap(pcfg->addr_virt_ce); err_ioremap1: + __bman_portals_probed = -1; + return -ENXIO; } diff --git a/drivers/soc/fsl/qbman/qman_ccsr.c b/drivers/soc/fsl/qbman/qman_ccsr.c index 109b38de3176..a6bb43007d03 100644 --- a/drivers/soc/fsl/qbman/qman_ccsr.c +++ b/drivers/soc/fsl/qbman/qman_ccsr.c @@ -596,7 +596,7 @@ static int qman_init_ccsr(struct device *dev) } #define LIO_CFG_LIODN_MASK 0x0fff0000 -void qman_liodn_fixup(u16 channel) +void __qman_liodn_fixup(u16 channel) { static int done; static u32 liodn_offset; diff --git a/drivers/soc/fsl/qbman/qman_portal.c b/drivers/soc/fsl/qbman/qman_portal.c index 661c9b234d32..e2186b681d87 100644 --- a/drivers/soc/fsl/qbman/qman_portal.c +++ b/drivers/soc/fsl/qbman/qman_portal.c @@ -38,6 +38,7 @@ EXPORT_SYMBOL(qman_dma_portal); #define CONFIG_FSL_DPA_PIRQ_FAST 1 static struct cpumask portal_cpus; +static int __qman_portals_probed; /* protect qman global registers and global data shared among portals */ static DEFINE_SPINLOCK(qman_lock); @@ -220,6 +221,12 @@ static int qman_online_cpu(unsigned int cpu) return 0; } +int qman_portals_probed(void) +{ + return __qman_portals_probed; +} +EXPORT_SYMBOL_GPL(qman_portals_probed); + static int qman_portal_probe(struct platform_device *pdev) { struct device *dev = &pdev->dev; @@ -238,8 +245,10 @@ static int qman_portal_probe(struct platform_device *pdev) } pcfg = devm_kmalloc(dev, sizeof(*pcfg), GFP_KERNEL); - if (!pcfg) + if (!pcfg) { + __qman_portals_probed = -1; return -ENOMEM; + } pcfg->dev = dev; @@ -247,19 +256,20 @@ static int qman_portal_probe(struct platform_device *pdev) DPAA_PORTAL_CE); if (!addr_phys[0]) { dev_err(dev, "Can't get %pOF property 'reg::CE'\n", node); - return -ENXIO; + goto err_ioremap1; } addr_phys[1] = platform_get_resource(pdev, IORESOURCE_MEM, DPAA_PORTAL_CI); if (!addr_phys[1]) { dev_err(dev, "Can't get %pOF property 'reg::CI'\n", node); - return -ENXIO; + goto err_ioremap1; } err = of_property_read_u32(node, "cell-index", &val); if (err) { dev_err(dev, "Can't get %pOF property 'cell-index'\n", node); + __qman_portals_probed = -1; return err; } pcfg->channel = val; @@ -267,7 +277,7 @@ static int qman_portal_probe(struct platform_device *pdev) irq = platform_get_irq(pdev, 0); if (irq <= 0) { dev_err(dev, "Can't get %pOF IRQ\n", node); - return -ENXIO; + goto err_ioremap1; } pcfg->irq = irq; @@ -291,6 +301,7 @@ static int qman_portal_probe(struct platform_device *pdev) spin_lock(&qman_lock); cpu = cpumask_next_zero(-1, &portal_cpus); if (cpu >= nr_cpu_ids) { + __qman_portals_probed = 1; /* unassigned portal, skip init */ spin_unlock(&qman_lock); return 0; @@ -321,6 +332,8 @@ err_portal_init: err_ioremap2: memunmap(pcfg->addr_virt_ce); err_ioremap1: + __qman_portals_probed = -1; + return -ENXIO; } diff --git a/drivers/soc/fsl/qbman/qman_priv.h b/drivers/soc/fsl/qbman/qman_priv.h index 75a8f905f8f7..04515718cfd9 100644 --- a/drivers/soc/fsl/qbman/qman_priv.h +++ b/drivers/soc/fsl/qbman/qman_priv.h @@ -193,7 +193,14 @@ extern struct gen_pool *qm_cgralloc; /* CGR ID allocator */ u32 qm_get_pools_sdqcr(void); int qman_wq_alloc(void); -void qman_liodn_fixup(u16 channel); +#ifdef CONFIG_FSL_PAMU +#define qman_liodn_fixup __qman_liodn_fixup +#else +static inline void qman_liodn_fixup(u16 channel) +{ +} +#endif +void __qman_liodn_fixup(u16 channel); void qman_set_sdest(u16 channel, unsigned int cpu_idx); struct qman_portal *qman_create_affine_portal( diff --git a/drivers/soc/fsl/qe/Kconfig b/drivers/soc/fsl/qe/Kconfig index fabba17e9d65..cfa4b2939992 100644 --- a/drivers/soc/fsl/qe/Kconfig +++ b/drivers/soc/fsl/qe/Kconfig @@ -1,3 +1,4 @@ +# SPDX-License-Identifier: GPL-2.0-only # # QE Communication options # diff --git a/drivers/soc/fsl/qe/gpio.c b/drivers/soc/fsl/qe/gpio.c index 51b3a47b5a55..f0c29ed8f0ff 100644 --- a/drivers/soc/fsl/qe/gpio.c +++ b/drivers/soc/fsl/qe/gpio.c @@ -1,14 +1,10 @@ +// SPDX-License-Identifier: GPL-2.0-or-later /* * QUICC Engine GPIOs * * Copyright (c) MontaVista Software, Inc. 2008. * * Author: Anton Vorontsov <avorontsov@ru.mvista.com> - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the - * Free Software Foundation; either version 2 of the License, or (at your - * option) any later version. */ #include <linux/kernel.h> diff --git a/drivers/soc/fsl/qe/qe.c b/drivers/soc/fsl/qe/qe.c index 612d9c551be5..62c6ba17991a 100644 --- a/drivers/soc/fsl/qe/qe.c +++ b/drivers/soc/fsl/qe/qe.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0-or-later /* * Copyright (C) 2006-2010 Freescale Semiconductor, Inc. All rights reserved. * @@ -8,11 +9,6 @@ * Description: * General Purpose functions for the global management of the * QUICC Engine (QE). - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the - * Free Software Foundation; either version 2 of the License, or (at your - * option) any later version. */ #include <linux/errno.h> #include <linux/sched.h> diff --git a/drivers/soc/fsl/qe/qe_common.c b/drivers/soc/fsl/qe/qe_common.c index 104e68d9b84f..83e85e61669f 100644 --- a/drivers/soc/fsl/qe/qe_common.c +++ b/drivers/soc/fsl/qe/qe_common.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0-only /* * Common CPM code * @@ -11,10 +12,6 @@ * Copyright (c) 2000 MontaVista Software, Inc (source@mvista.com) * 2006 (c) MontaVista Software, Inc. * Vitaly Bordug <vbordug@ru.mvista.com> - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of version 2 of the GNU General Public License as - * published by the Free Software Foundation. */ #include <linux/genalloc.h> #include <linux/init.h> diff --git a/drivers/soc/fsl/qe/qe_ic.c b/drivers/soc/fsl/qe/qe_ic.c index ec2ca864b0c5..9bac546998d3 100644 --- a/drivers/soc/fsl/qe/qe_ic.c +++ b/drivers/soc/fsl/qe/qe_ic.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0-or-later /* * arch/powerpc/sysdev/qe_lib/qe_ic.c * @@ -7,11 +8,6 @@ * Based on code from Shlomi Gridish <gridish@freescale.com> * * QUICC ENGINE Interrupt Controller - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the - * Free Software Foundation; either version 2 of the License, or (at your - * option) any later version. */ #include <linux/of_irq.h> diff --git a/drivers/soc/fsl/qe/qe_ic.h b/drivers/soc/fsl/qe/qe_ic.h index 926a2ed42319..08c695672a03 100644 --- a/drivers/soc/fsl/qe/qe_ic.h +++ b/drivers/soc/fsl/qe/qe_ic.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ /* * drivers/soc/fsl/qe/qe_ic.h * @@ -7,11 +8,6 @@ * * Author: Li Yang <leoli@freescale.com> * Based on code from Shlomi Gridish <gridish@freescale.com> - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the - * Free Software Foundation; either version 2 of the License, or (at your - * option) any later version. */ #ifndef _POWERPC_SYSDEV_QE_IC_H #define _POWERPC_SYSDEV_QE_IC_H diff --git a/drivers/soc/fsl/qe/qe_io.c b/drivers/soc/fsl/qe/qe_io.c index 7ae59abc7863..3657e296a8a2 100644 --- a/drivers/soc/fsl/qe/qe_io.c +++ b/drivers/soc/fsl/qe/qe_io.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0-or-later /* * arch/powerpc/sysdev/qe_lib/qe_io.c * @@ -7,11 +8,6 @@ * * Author: Li Yang <LeoLi@freescale.com> * Based on code from Shlomi Gridish <gridish@freescale.com> - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the - * Free Software Foundation; either version 2 of the License, or (at your - * option) any later version. */ #include <linux/stddef.h> diff --git a/drivers/soc/fsl/qe/qe_tdm.c b/drivers/soc/fsl/qe/qe_tdm.c index 76480df195a8..e37ebc3be661 100644 --- a/drivers/soc/fsl/qe/qe_tdm.c +++ b/drivers/soc/fsl/qe/qe_tdm.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0-or-later /* * Copyright (C) 2015 Freescale Semiconductor, Inc. All rights reserved. * @@ -5,11 +6,6 @@ * * Description: * QE TDM API Set - TDM specific routines implementations. - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the - * Free Software Foundation; either version 2 of the License, or (at your - * option) any later version. */ #include <linux/io.h> #include <linux/kernel.h> diff --git a/drivers/soc/fsl/qe/ucc.c b/drivers/soc/fsl/qe/ucc.c index 681f7d4b7724..024d239ac1e1 100644 --- a/drivers/soc/fsl/qe/ucc.c +++ b/drivers/soc/fsl/qe/ucc.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0-or-later /* * arch/powerpc/sysdev/qe_lib/ucc.c * @@ -7,11 +8,6 @@ * * Authors: Shlomi Gridish <gridish@freescale.com> * Li Yang <leoli@freescale.com> - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the - * Free Software Foundation; either version 2 of the License, or (at your - * option) any later version. */ #include <linux/kernel.h> #include <linux/errno.h> diff --git a/drivers/soc/fsl/qe/ucc_fast.c b/drivers/soc/fsl/qe/ucc_fast.c index 83d8d16e3a69..af4d80e38521 100644 --- a/drivers/soc/fsl/qe/ucc_fast.c +++ b/drivers/soc/fsl/qe/ucc_fast.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0-or-later /* * Copyright (C) 2006 Freescale Semiconductor, Inc. All rights reserved. * @@ -6,11 +7,6 @@ * * Description: * QE UCC Fast API Set - UCC Fast specific routines implementations. - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the - * Free Software Foundation; either version 2 of the License, or (at your - * option) any later version. */ #include <linux/kernel.h> #include <linux/errno.h> diff --git a/drivers/soc/fsl/qe/ucc_slow.c b/drivers/soc/fsl/qe/ucc_slow.c index 9334bdbd9b30..34f0ec3a63b5 100644 --- a/drivers/soc/fsl/qe/ucc_slow.c +++ b/drivers/soc/fsl/qe/ucc_slow.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0-or-later /* * Copyright (C) 2006 Freescale Semiconductor, Inc. All rights reserved. * @@ -6,11 +7,6 @@ * * Description: * QE UCC Slow API Set - UCC Slow specific routines implementations. - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the - * Free Software Foundation; either version 2 of the License, or (at your - * option) any later version. */ #include <linux/kernel.h> #include <linux/errno.h> diff --git a/drivers/soc/fsl/qe/usb.c b/drivers/soc/fsl/qe/usb.c index 111f7ab80f04..32d8269fa692 100644 --- a/drivers/soc/fsl/qe/usb.c +++ b/drivers/soc/fsl/qe/usb.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0-or-later /* * QE USB routines * @@ -6,11 +7,6 @@ * Jerry Huang <Chang-Ming.Huang@freescale.com> * Copyright (c) MontaVista Software, Inc. 2008. * Anton Vorontsov <avorontsov@ru.mvista.com> - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the - * Free Software Foundation; either version 2 of the License, or (at your - * option) any later version. */ #include <linux/kernel.h> diff --git a/drivers/soc/imx/Kconfig b/drivers/soc/imx/Kconfig index d80f899d22f9..ade1b46d669c 100644 --- a/drivers/soc/imx/Kconfig +++ b/drivers/soc/imx/Kconfig @@ -1,3 +1,4 @@ +# SPDX-License-Identifier: GPL-2.0-only menu "i.MX SoC drivers" config IMX_GPCV2_PM_DOMAINS diff --git a/drivers/soc/imx/Makefile b/drivers/soc/imx/Makefile index d6b529e06d9a..caa8653600f2 100644 --- a/drivers/soc/imx/Makefile +++ b/drivers/soc/imx/Makefile @@ -1,3 +1,4 @@ +# SPDX-License-Identifier: GPL-2.0-only obj-$(CONFIG_HAVE_IMX_GPC) += gpc.o obj-$(CONFIG_IMX_GPCV2_PM_DOMAINS) += gpcv2.o obj-$(CONFIG_ARCH_MXC) += soc-imx8.o diff --git a/drivers/soc/ixp4xx/Kconfig b/drivers/soc/ixp4xx/Kconfig index de6becdc78a2..de2e62c3310a 100644 --- a/drivers/soc/ixp4xx/Kconfig +++ b/drivers/soc/ixp4xx/Kconfig @@ -1,3 +1,4 @@ +# SPDX-License-Identifier: GPL-2.0-only menu "IXP4xx SoC drivers" config IXP4XX_QMGR diff --git a/drivers/soc/ixp4xx/Makefile b/drivers/soc/ixp4xx/Makefile index d20d99e6df65..bebb07d52a90 100644 --- a/drivers/soc/ixp4xx/Makefile +++ b/drivers/soc/ixp4xx/Makefile @@ -1,2 +1,3 @@ +# SPDX-License-Identifier: GPL-2.0-only obj-$(CONFIG_IXP4XX_QMGR) += ixp4xx-qmgr.o obj-$(CONFIG_IXP4XX_NPE) += ixp4xx-npe.o diff --git a/drivers/soc/ixp4xx/ixp4xx-npe.c b/drivers/soc/ixp4xx/ixp4xx-npe.c index 15979d4376ab..bc10e3194809 100644 --- a/drivers/soc/ixp4xx/ixp4xx-npe.c +++ b/drivers/soc/ixp4xx/ixp4xx-npe.c @@ -1,12 +1,9 @@ +// SPDX-License-Identifier: GPL-2.0-only /* * Intel IXP4xx Network Processor Engine driver for Linux * * Copyright (C) 2007 Krzysztof Halasa <khc@pm.waw.pl> * - * This program is free software; you can redistribute it and/or modify it - * under the terms of version 2 of the GNU General Public License - * as published by the Free Software Foundation. - * * The code is based on publicly available information: * - Intel IXP4xx Developer's Manual and other e-papers * - Intel IXP400 Access Library Software (BSD license) diff --git a/drivers/soc/ixp4xx/ixp4xx-qmgr.c b/drivers/soc/ixp4xx/ixp4xx-qmgr.c index bb90670ec160..8c968382cea7 100644 --- a/drivers/soc/ixp4xx/ixp4xx-qmgr.c +++ b/drivers/soc/ixp4xx/ixp4xx-qmgr.c @@ -1,11 +1,8 @@ +// SPDX-License-Identifier: GPL-2.0-only /* * Intel IXP4xx Queue Manager driver for Linux * * Copyright (C) 2007 Krzysztof Halasa <khc@pm.waw.pl> - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of version 2 of the GNU General Public License - * as published by the Free Software Foundation. */ #include <linux/ioport.h> diff --git a/drivers/soc/lantiq/Makefile b/drivers/soc/lantiq/Makefile index 35aa86bd1023..976f42f806c3 100644 --- a/drivers/soc/lantiq/Makefile +++ b/drivers/soc/lantiq/Makefile @@ -1 +1,2 @@ +# SPDX-License-Identifier: GPL-2.0-only obj-y += fpi-bus.o diff --git a/drivers/soc/mediatek/Kconfig b/drivers/soc/mediatek/Kconfig index 17bd7590464f..2114b563478c 100644 --- a/drivers/soc/mediatek/Kconfig +++ b/drivers/soc/mediatek/Kconfig @@ -1,3 +1,4 @@ +# SPDX-License-Identifier: GPL-2.0-only # # MediaTek SoC drivers # diff --git a/drivers/soc/mediatek/Makefile b/drivers/soc/mediatek/Makefile index 64ce5eeaba32..b01733074ad6 100644 --- a/drivers/soc/mediatek/Makefile +++ b/drivers/soc/mediatek/Makefile @@ -1,3 +1,4 @@ +# SPDX-License-Identifier: GPL-2.0-only obj-$(CONFIG_MTK_CMDQ) += mtk-cmdq-helper.o obj-$(CONFIG_MTK_INFRACFG) += mtk-infracfg.o obj-$(CONFIG_MTK_PMIC_WRAP) += mtk-pmic-wrap.o diff --git a/drivers/soc/mediatek/mtk-infracfg.c b/drivers/soc/mediatek/mtk-infracfg.c index 958861c9e6ee..341c7ac250e3 100644 --- a/drivers/soc/mediatek/mtk-infracfg.c +++ b/drivers/soc/mediatek/mtk-infracfg.c @@ -1,14 +1,6 @@ +// SPDX-License-Identifier: GPL-2.0-only /* * Copyright (c) 2015 Pengutronix, Sascha Hauer <kernel@pengutronix.de> - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. */ #include <linux/export.h> diff --git a/drivers/soc/mediatek/mtk-pmic-wrap.c b/drivers/soc/mediatek/mtk-pmic-wrap.c index c4449a163991..c725315cf6a8 100644 --- a/drivers/soc/mediatek/mtk-pmic-wrap.c +++ b/drivers/soc/mediatek/mtk-pmic-wrap.c @@ -1,15 +1,7 @@ +// SPDX-License-Identifier: GPL-2.0-only /* * Copyright (c) 2014 MediaTek Inc. * Author: Flora Fu, MediaTek - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. */ #include <linux/clk.h> #include <linux/interrupt.h> diff --git a/drivers/soc/mediatek/mtk-scpsys.c b/drivers/soc/mediatek/mtk-scpsys.c index 5b24bb4bfbf6..503222d0d0da 100644 --- a/drivers/soc/mediatek/mtk-scpsys.c +++ b/drivers/soc/mediatek/mtk-scpsys.c @@ -1,14 +1,6 @@ +// SPDX-License-Identifier: GPL-2.0-only /* * Copyright (c) 2015 Pengutronix, Sascha Hauer <kernel@pengutronix.de> - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. */ #include <linux/clk.h> #include <linux/init.h> diff --git a/drivers/soc/qcom/Kconfig b/drivers/soc/qcom/Kconfig index 1ee298f6bf17..a6d1bfb17279 100644 --- a/drivers/soc/qcom/Kconfig +++ b/drivers/soc/qcom/Kconfig @@ -1,8 +1,21 @@ +# SPDX-License-Identifier: GPL-2.0-only # # QCOM Soc drivers # menu "Qualcomm SoC drivers" +config QCOM_AOSS_QMP + tristate "Qualcomm AOSS Driver" + depends on ARCH_QCOM || COMPILE_TEST + depends on MAILBOX + depends on COMMON_CLK && PM + select PM_GENERIC_DOMAINS + help + This driver provides the means of communicating with and controlling + the low-power state for resources related to the remoteproc + subsystems as well as controlling the debug clocks exposed by the Always On + Subsystem (AOSS) using Qualcomm Messaging Protocol (QMP). + config QCOM_COMMAND_DB bool "Qualcomm Command DB" depends on ARCH_QCOM || COMPILE_TEST diff --git a/drivers/soc/qcom/Makefile b/drivers/soc/qcom/Makefile index ffe519b0cb66..eeb088beb15f 100644 --- a/drivers/soc/qcom/Makefile +++ b/drivers/soc/qcom/Makefile @@ -1,5 +1,6 @@ # SPDX-License-Identifier: GPL-2.0 CFLAGS_rpmh-rsc.o := -I$(src) +obj-$(CONFIG_QCOM_AOSS_QMP) += qcom_aoss.o obj-$(CONFIG_QCOM_GENI_SE) += qcom-geni-se.o obj-$(CONFIG_QCOM_COMMAND_DB) += cmd-db.o obj-$(CONFIG_QCOM_GLINK_SSR) += glink_ssr.o diff --git a/drivers/soc/qcom/apr.c b/drivers/soc/qcom/apr.c index 74f8b9607daa..4fcc32420c47 100644 --- a/drivers/soc/qcom/apr.c +++ b/drivers/soc/qcom/apr.c @@ -8,6 +8,7 @@ #include <linux/spinlock.h> #include <linux/idr.h> #include <linux/slab.h> +#include <linux/workqueue.h> #include <linux/of_device.h> #include <linux/soc/qcom/apr.h> #include <linux/rpmsg.h> @@ -17,8 +18,18 @@ struct apr { struct rpmsg_endpoint *ch; struct device *dev; spinlock_t svcs_lock; + spinlock_t rx_lock; struct idr svcs_idr; int dest_domain_id; + struct workqueue_struct *rxwq; + struct work_struct rx_work; + struct list_head rx_list; +}; + +struct apr_rx_buf { + struct list_head node; + int len; + uint8_t buf[]; }; /** @@ -62,11 +73,7 @@ static int apr_callback(struct rpmsg_device *rpdev, void *buf, int len, void *priv, u32 addr) { struct apr *apr = dev_get_drvdata(&rpdev->dev); - uint16_t hdr_size, msg_type, ver, svc_id; - struct apr_device *svc = NULL; - struct apr_driver *adrv = NULL; - struct apr_resp_pkt resp; - struct apr_hdr *hdr; + struct apr_rx_buf *abuf; unsigned long flags; if (len <= APR_HDR_SIZE) { @@ -75,6 +82,34 @@ static int apr_callback(struct rpmsg_device *rpdev, void *buf, return -EINVAL; } + abuf = kzalloc(sizeof(*abuf) + len, GFP_ATOMIC); + if (!abuf) + return -ENOMEM; + + abuf->len = len; + memcpy(abuf->buf, buf, len); + + spin_lock_irqsave(&apr->rx_lock, flags); + list_add_tail(&abuf->node, &apr->rx_list); + spin_unlock_irqrestore(&apr->rx_lock, flags); + + queue_work(apr->rxwq, &apr->rx_work); + + return 0; +} + + +static int apr_do_rx_callback(struct apr *apr, struct apr_rx_buf *abuf) +{ + uint16_t hdr_size, msg_type, ver, svc_id; + struct apr_device *svc = NULL; + struct apr_driver *adrv = NULL; + struct apr_resp_pkt resp; + struct apr_hdr *hdr; + unsigned long flags; + void *buf = abuf->buf; + int len = abuf->len; + hdr = buf; ver = APR_HDR_FIELD_VER(hdr->hdr_field); if (ver > APR_PKT_VER + 1) @@ -132,6 +167,23 @@ static int apr_callback(struct rpmsg_device *rpdev, void *buf, return 0; } +static void apr_rxwq(struct work_struct *work) +{ + struct apr *apr = container_of(work, struct apr, rx_work); + struct apr_rx_buf *abuf, *b; + unsigned long flags; + + if (!list_empty(&apr->rx_list)) { + list_for_each_entry_safe(abuf, b, &apr->rx_list, node) { + apr_do_rx_callback(apr, abuf); + spin_lock_irqsave(&apr->rx_lock, flags); + list_del(&abuf->node); + spin_unlock_irqrestore(&apr->rx_lock, flags); + kfree(abuf); + } + } +} + static int apr_device_match(struct device *dev, struct device_driver *drv) { struct apr_device *adev = to_apr_device(dev); @@ -276,7 +328,7 @@ static int apr_probe(struct rpmsg_device *rpdev) if (!apr) return -ENOMEM; - ret = of_property_read_u32(dev->of_node, "reg", &apr->dest_domain_id); + ret = of_property_read_u32(dev->of_node, "qcom,apr-domain", &apr->dest_domain_id); if (ret) { dev_err(dev, "APR Domain ID not specified in DT\n"); return ret; @@ -285,6 +337,14 @@ static int apr_probe(struct rpmsg_device *rpdev) dev_set_drvdata(dev, apr); apr->ch = rpdev->ept; apr->dev = dev; + apr->rxwq = create_singlethread_workqueue("qcom_apr_rx"); + if (!apr->rxwq) { + dev_err(apr->dev, "Failed to start Rx WQ\n"); + return -ENOMEM; + } + INIT_WORK(&apr->rx_work, apr_rxwq); + INIT_LIST_HEAD(&apr->rx_list); + spin_lock_init(&apr->rx_lock); spin_lock_init(&apr->svcs_lock); idr_init(&apr->svcs_idr); of_register_apr_devices(dev); @@ -303,7 +363,11 @@ static int apr_remove_device(struct device *dev, void *null) static void apr_remove(struct rpmsg_device *rpdev) { + struct apr *apr = dev_get_drvdata(&rpdev->dev); + device_for_each_child(&rpdev->dev, NULL, apr_remove_device); + flush_workqueue(apr->rxwq); + destroy_workqueue(apr->rxwq); } /* diff --git a/drivers/soc/qcom/glink_ssr.c b/drivers/soc/qcom/glink_ssr.c index 19c7399eddb5..d7babe3d67bc 100644 --- a/drivers/soc/qcom/glink_ssr.c +++ b/drivers/soc/qcom/glink_ssr.c @@ -1,15 +1,7 @@ +// SPDX-License-Identifier: GPL-2.0-only /* * Copyright (c) 2014-2017, The Linux Foundation. All rights reserved. * Copyright (c) 2017, Linaro Ltd. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 and - * only version 2 as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. */ #include <linux/completion.h> diff --git a/drivers/soc/qcom/mdt_loader.c b/drivers/soc/qcom/mdt_loader.c index 1c488024c698..9ca7d9484de0 100644 --- a/drivers/soc/qcom/mdt_loader.c +++ b/drivers/soc/qcom/mdt_loader.c @@ -1,18 +1,10 @@ +// SPDX-License-Identifier: GPL-2.0-only /* * Qualcomm Peripheral Image Loader * * Copyright (C) 2016 Linaro Ltd * Copyright (C) 2015 Sony Mobile Communications Inc * Copyright (c) 2012-2013, The Linux Foundation. All rights reserved. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * version 2 as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. */ #include <linux/device.h> diff --git a/drivers/soc/qcom/qcom-geni-se.c b/drivers/soc/qcom/qcom-geni-se.c index 6b8ef01472e9..d5cf953b4337 100644 --- a/drivers/soc/qcom/qcom-geni-se.c +++ b/drivers/soc/qcom/qcom-geni-se.c @@ -1,6 +1,7 @@ // SPDX-License-Identifier: GPL-2.0 // Copyright (c) 2017-2018, The Linux Foundation. All rights reserved. +#include <linux/acpi.h> #include <linux/clk.h> #include <linux/slab.h> #include <linux/dma-mapping.h> @@ -450,6 +451,9 @@ int geni_se_resources_off(struct geni_se *se) { int ret; + if (has_acpi_companion(se->dev)) + return 0; + ret = pinctrl_pm_select_sleep_state(se->dev); if (ret) return ret; @@ -487,6 +491,9 @@ int geni_se_resources_on(struct geni_se *se) { int ret; + if (has_acpi_companion(se->dev)) + return 0; + ret = geni_se_clks_on(se); if (ret) return ret; @@ -724,12 +731,14 @@ static int geni_se_probe(struct platform_device *pdev) if (IS_ERR(wrapper->base)) return PTR_ERR(wrapper->base); - wrapper->ahb_clks[0].id = "m-ahb"; - wrapper->ahb_clks[1].id = "s-ahb"; - ret = devm_clk_bulk_get(dev, NUM_AHB_CLKS, wrapper->ahb_clks); - if (ret) { - dev_err(dev, "Err getting AHB clks %d\n", ret); - return ret; + if (!has_acpi_companion(&pdev->dev)) { + wrapper->ahb_clks[0].id = "m-ahb"; + wrapper->ahb_clks[1].id = "s-ahb"; + ret = devm_clk_bulk_get(dev, NUM_AHB_CLKS, wrapper->ahb_clks); + if (ret) { + dev_err(dev, "Err getting AHB clks %d\n", ret); + return ret; + } } dev_set_drvdata(dev, wrapper); diff --git a/drivers/soc/qcom/qcom_aoss.c b/drivers/soc/qcom/qcom_aoss.c new file mode 100644 index 000000000000..5f885196f4d0 --- /dev/null +++ b/drivers/soc/qcom/qcom_aoss.c @@ -0,0 +1,480 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Copyright (c) 2019, Linaro Ltd + */ +#include <dt-bindings/power/qcom-aoss-qmp.h> +#include <linux/clk-provider.h> +#include <linux/interrupt.h> +#include <linux/io.h> +#include <linux/mailbox_client.h> +#include <linux/module.h> +#include <linux/platform_device.h> +#include <linux/pm_domain.h> + +#define QMP_DESC_MAGIC 0x0 +#define QMP_DESC_VERSION 0x4 +#define QMP_DESC_FEATURES 0x8 + +/* AOP-side offsets */ +#define QMP_DESC_UCORE_LINK_STATE 0xc +#define QMP_DESC_UCORE_LINK_STATE_ACK 0x10 +#define QMP_DESC_UCORE_CH_STATE 0x14 +#define QMP_DESC_UCORE_CH_STATE_ACK 0x18 +#define QMP_DESC_UCORE_MBOX_SIZE 0x1c +#define QMP_DESC_UCORE_MBOX_OFFSET 0x20 + +/* Linux-side offsets */ +#define QMP_DESC_MCORE_LINK_STATE 0x24 +#define QMP_DESC_MCORE_LINK_STATE_ACK 0x28 +#define QMP_DESC_MCORE_CH_STATE 0x2c +#define QMP_DESC_MCORE_CH_STATE_ACK 0x30 +#define QMP_DESC_MCORE_MBOX_SIZE 0x34 +#define QMP_DESC_MCORE_MBOX_OFFSET 0x38 + +#define QMP_STATE_UP GENMASK(15, 0) +#define QMP_STATE_DOWN GENMASK(31, 16) + +#define QMP_MAGIC 0x4d41494c /* mail */ +#define QMP_VERSION 1 + +/* 64 bytes is enough to store the requests and provides padding to 4 bytes */ +#define QMP_MSG_LEN 64 + +/** + * struct qmp - driver state for QMP implementation + * @msgram: iomem referencing the message RAM used for communication + * @dev: reference to QMP device + * @mbox_client: mailbox client used to ring the doorbell on transmit + * @mbox_chan: mailbox channel used to ring the doorbell on transmit + * @offset: offset within @msgram where messages should be written + * @size: maximum size of the messages to be transmitted + * @event: wait_queue for synchronization with the IRQ + * @tx_lock: provides synchronization between multiple callers of qmp_send() + * @qdss_clk: QDSS clock hw struct + * @pd_data: genpd data + */ +struct qmp { + void __iomem *msgram; + struct device *dev; + + struct mbox_client mbox_client; + struct mbox_chan *mbox_chan; + + size_t offset; + size_t size; + + wait_queue_head_t event; + + struct mutex tx_lock; + + struct clk_hw qdss_clk; + struct genpd_onecell_data pd_data; +}; + +struct qmp_pd { + struct qmp *qmp; + struct generic_pm_domain pd; +}; + +#define to_qmp_pd_resource(res) container_of(res, struct qmp_pd, pd) + +static void qmp_kick(struct qmp *qmp) +{ + mbox_send_message(qmp->mbox_chan, NULL); + mbox_client_txdone(qmp->mbox_chan, 0); +} + +static bool qmp_magic_valid(struct qmp *qmp) +{ + return readl(qmp->msgram + QMP_DESC_MAGIC) == QMP_MAGIC; +} + +static bool qmp_link_acked(struct qmp *qmp) +{ + return readl(qmp->msgram + QMP_DESC_MCORE_LINK_STATE_ACK) == QMP_STATE_UP; +} + +static bool qmp_mcore_channel_acked(struct qmp *qmp) +{ + return readl(qmp->msgram + QMP_DESC_MCORE_CH_STATE_ACK) == QMP_STATE_UP; +} + +static bool qmp_ucore_channel_up(struct qmp *qmp) +{ + return readl(qmp->msgram + QMP_DESC_UCORE_CH_STATE) == QMP_STATE_UP; +} + +static int qmp_open(struct qmp *qmp) +{ + int ret; + u32 val; + + if (!qmp_magic_valid(qmp)) { + dev_err(qmp->dev, "QMP magic doesn't match\n"); + return -EINVAL; + } + + val = readl(qmp->msgram + QMP_DESC_VERSION); + if (val != QMP_VERSION) { + dev_err(qmp->dev, "unsupported QMP version %d\n", val); + return -EINVAL; + } + + qmp->offset = readl(qmp->msgram + QMP_DESC_MCORE_MBOX_OFFSET); + qmp->size = readl(qmp->msgram + QMP_DESC_MCORE_MBOX_SIZE); + if (!qmp->size) { + dev_err(qmp->dev, "invalid mailbox size\n"); + return -EINVAL; + } + + /* Ack remote core's link state */ + val = readl(qmp->msgram + QMP_DESC_UCORE_LINK_STATE); + writel(val, qmp->msgram + QMP_DESC_UCORE_LINK_STATE_ACK); + + /* Set local core's link state to up */ + writel(QMP_STATE_UP, qmp->msgram + QMP_DESC_MCORE_LINK_STATE); + + qmp_kick(qmp); + + ret = wait_event_timeout(qmp->event, qmp_link_acked(qmp), HZ); + if (!ret) { + dev_err(qmp->dev, "ucore didn't ack link\n"); + goto timeout_close_link; + } + + writel(QMP_STATE_UP, qmp->msgram + QMP_DESC_MCORE_CH_STATE); + + qmp_kick(qmp); + + ret = wait_event_timeout(qmp->event, qmp_ucore_channel_up(qmp), HZ); + if (!ret) { + dev_err(qmp->dev, "ucore didn't open channel\n"); + goto timeout_close_channel; + } + + /* Ack remote core's channel state */ + writel(QMP_STATE_UP, qmp->msgram + QMP_DESC_UCORE_CH_STATE_ACK); + + qmp_kick(qmp); + + ret = wait_event_timeout(qmp->event, qmp_mcore_channel_acked(qmp), HZ); + if (!ret) { + dev_err(qmp->dev, "ucore didn't ack channel\n"); + goto timeout_close_channel; + } + + return 0; + +timeout_close_channel: + writel(QMP_STATE_DOWN, qmp->msgram + QMP_DESC_MCORE_CH_STATE); + +timeout_close_link: + writel(QMP_STATE_DOWN, qmp->msgram + QMP_DESC_MCORE_LINK_STATE); + qmp_kick(qmp); + + return -ETIMEDOUT; +} + +static void qmp_close(struct qmp *qmp) +{ + writel(QMP_STATE_DOWN, qmp->msgram + QMP_DESC_MCORE_CH_STATE); + writel(QMP_STATE_DOWN, qmp->msgram + QMP_DESC_MCORE_LINK_STATE); + qmp_kick(qmp); +} + +static irqreturn_t qmp_intr(int irq, void *data) +{ + struct qmp *qmp = data; + + wake_up_interruptible_all(&qmp->event); + + return IRQ_HANDLED; +} + +static bool qmp_message_empty(struct qmp *qmp) +{ + return readl(qmp->msgram + qmp->offset) == 0; +} + +/** + * qmp_send() - send a message to the AOSS + * @qmp: qmp context + * @data: message to be sent + * @len: length of the message + * + * Transmit @data to AOSS and wait for the AOSS to acknowledge the message. + * @len must be a multiple of 4 and not longer than the mailbox size. Access is + * synchronized by this implementation. + * + * Return: 0 on success, negative errno on failure + */ +static int qmp_send(struct qmp *qmp, const void *data, size_t len) +{ + long time_left; + int ret; + + if (WARN_ON(len + sizeof(u32) > qmp->size)) + return -EINVAL; + + if (WARN_ON(len % sizeof(u32))) + return -EINVAL; + + mutex_lock(&qmp->tx_lock); + + /* The message RAM only implements 32-bit accesses */ + __iowrite32_copy(qmp->msgram + qmp->offset + sizeof(u32), + data, len / sizeof(u32)); + writel(len, qmp->msgram + qmp->offset); + qmp_kick(qmp); + + time_left = wait_event_interruptible_timeout(qmp->event, + qmp_message_empty(qmp), HZ); + if (!time_left) { + dev_err(qmp->dev, "ucore did not ack channel\n"); + ret = -ETIMEDOUT; + + /* Clear message from buffer */ + writel(0, qmp->msgram + qmp->offset); + } else { + ret = 0; + } + + mutex_unlock(&qmp->tx_lock); + + return ret; +} + +static int qmp_qdss_clk_prepare(struct clk_hw *hw) +{ + static const char buf[QMP_MSG_LEN] = "{class: clock, res: qdss, val: 1}"; + struct qmp *qmp = container_of(hw, struct qmp, qdss_clk); + + return qmp_send(qmp, buf, sizeof(buf)); +} + +static void qmp_qdss_clk_unprepare(struct clk_hw *hw) +{ + static const char buf[QMP_MSG_LEN] = "{class: clock, res: qdss, val: 0}"; + struct qmp *qmp = container_of(hw, struct qmp, qdss_clk); + + qmp_send(qmp, buf, sizeof(buf)); +} + +static const struct clk_ops qmp_qdss_clk_ops = { + .prepare = qmp_qdss_clk_prepare, + .unprepare = qmp_qdss_clk_unprepare, +}; + +static int qmp_qdss_clk_add(struct qmp *qmp) +{ + static const struct clk_init_data qdss_init = { + .ops = &qmp_qdss_clk_ops, + .name = "qdss", + }; + int ret; + + qmp->qdss_clk.init = &qdss_init; + ret = clk_hw_register(qmp->dev, &qmp->qdss_clk); + if (ret < 0) { + dev_err(qmp->dev, "failed to register qdss clock\n"); + return ret; + } + + ret = of_clk_add_hw_provider(qmp->dev->of_node, of_clk_hw_simple_get, + &qmp->qdss_clk); + if (ret < 0) { + dev_err(qmp->dev, "unable to register of clk hw provider\n"); + clk_hw_unregister(&qmp->qdss_clk); + } + + return ret; +} + +static void qmp_qdss_clk_remove(struct qmp *qmp) +{ + of_clk_del_provider(qmp->dev->of_node); + clk_hw_unregister(&qmp->qdss_clk); +} + +static int qmp_pd_power_toggle(struct qmp_pd *res, bool enable) +{ + char buf[QMP_MSG_LEN] = {}; + + snprintf(buf, sizeof(buf), + "{class: image, res: load_state, name: %s, val: %s}", + res->pd.name, enable ? "on" : "off"); + return qmp_send(res->qmp, buf, sizeof(buf)); +} + +static int qmp_pd_power_on(struct generic_pm_domain *domain) +{ + return qmp_pd_power_toggle(to_qmp_pd_resource(domain), true); +} + +static int qmp_pd_power_off(struct generic_pm_domain *domain) +{ + return qmp_pd_power_toggle(to_qmp_pd_resource(domain), false); +} + +static const char * const sdm845_resources[] = { + [AOSS_QMP_LS_CDSP] = "cdsp", + [AOSS_QMP_LS_LPASS] = "adsp", + [AOSS_QMP_LS_MODEM] = "modem", + [AOSS_QMP_LS_SLPI] = "slpi", + [AOSS_QMP_LS_SPSS] = "spss", + [AOSS_QMP_LS_VENUS] = "venus", +}; + +static int qmp_pd_add(struct qmp *qmp) +{ + struct genpd_onecell_data *data = &qmp->pd_data; + struct device *dev = qmp->dev; + struct qmp_pd *res; + size_t num = ARRAY_SIZE(sdm845_resources); + int ret; + int i; + + res = devm_kcalloc(dev, num, sizeof(*res), GFP_KERNEL); + if (!res) + return -ENOMEM; + + data->domains = devm_kcalloc(dev, num, sizeof(*data->domains), + GFP_KERNEL); + if (!data->domains) + return -ENOMEM; + + for (i = 0; i < num; i++) { + res[i].qmp = qmp; + res[i].pd.name = sdm845_resources[i]; + res[i].pd.power_on = qmp_pd_power_on; + res[i].pd.power_off = qmp_pd_power_off; + + ret = pm_genpd_init(&res[i].pd, NULL, true); + if (ret < 0) { + dev_err(dev, "failed to init genpd\n"); + goto unroll_genpds; + } + + data->domains[i] = &res[i].pd; + } + + data->num_domains = i; + + ret = of_genpd_add_provider_onecell(dev->of_node, data); + if (ret < 0) + goto unroll_genpds; + + return 0; + +unroll_genpds: + for (i--; i >= 0; i--) + pm_genpd_remove(data->domains[i]); + + return ret; +} + +static void qmp_pd_remove(struct qmp *qmp) +{ + struct genpd_onecell_data *data = &qmp->pd_data; + struct device *dev = qmp->dev; + int i; + + of_genpd_del_provider(dev->of_node); + + for (i = 0; i < data->num_domains; i++) + pm_genpd_remove(data->domains[i]); +} + +static int qmp_probe(struct platform_device *pdev) +{ + struct resource *res; + struct qmp *qmp; + int irq; + int ret; + + qmp = devm_kzalloc(&pdev->dev, sizeof(*qmp), GFP_KERNEL); + if (!qmp) + return -ENOMEM; + + qmp->dev = &pdev->dev; + init_waitqueue_head(&qmp->event); + mutex_init(&qmp->tx_lock); + + res = platform_get_resource(pdev, IORESOURCE_MEM, 0); + qmp->msgram = devm_ioremap_resource(&pdev->dev, res); + if (IS_ERR(qmp->msgram)) + return PTR_ERR(qmp->msgram); + + qmp->mbox_client.dev = &pdev->dev; + qmp->mbox_client.knows_txdone = true; + qmp->mbox_chan = mbox_request_channel(&qmp->mbox_client, 0); + if (IS_ERR(qmp->mbox_chan)) { + dev_err(&pdev->dev, "failed to acquire ipc mailbox\n"); + return PTR_ERR(qmp->mbox_chan); + } + + irq = platform_get_irq(pdev, 0); + ret = devm_request_irq(&pdev->dev, irq, qmp_intr, IRQF_ONESHOT, + "aoss-qmp", qmp); + if (ret < 0) { + dev_err(&pdev->dev, "failed to request interrupt\n"); + goto err_free_mbox; + } + + ret = qmp_open(qmp); + if (ret < 0) + goto err_free_mbox; + + ret = qmp_qdss_clk_add(qmp); + if (ret) + goto err_close_qmp; + + ret = qmp_pd_add(qmp); + if (ret) + goto err_remove_qdss_clk; + + platform_set_drvdata(pdev, qmp); + + return 0; + +err_remove_qdss_clk: + qmp_qdss_clk_remove(qmp); +err_close_qmp: + qmp_close(qmp); +err_free_mbox: + mbox_free_channel(qmp->mbox_chan); + + return ret; +} + +static int qmp_remove(struct platform_device *pdev) +{ + struct qmp *qmp = platform_get_drvdata(pdev); + + qmp_qdss_clk_remove(qmp); + qmp_pd_remove(qmp); + + qmp_close(qmp); + mbox_free_channel(qmp->mbox_chan); + + return 0; +} + +static const struct of_device_id qmp_dt_match[] = { + { .compatible = "qcom,sdm845-aoss-qmp", }, + {} +}; +MODULE_DEVICE_TABLE(of, qmp_dt_match); + +static struct platform_driver qmp_driver = { + .driver = { + .name = "qcom_aoss_qmp", + .of_match_table = qmp_dt_match, + }, + .probe = qmp_probe, + .remove = qmp_remove, +}; +module_platform_driver(qmp_driver); + +MODULE_DESCRIPTION("Qualcomm AOSS QMP driver"); +MODULE_LICENSE("GPL v2"); diff --git a/drivers/soc/qcom/qcom_gsbi.c b/drivers/soc/qcom/qcom_gsbi.c index 038abc377fdb..304afc223a58 100644 --- a/drivers/soc/qcom/qcom_gsbi.c +++ b/drivers/soc/qcom/qcom_gsbi.c @@ -1,14 +1,6 @@ +// SPDX-License-Identifier: GPL-2.0-only /* * Copyright (c) 2014, The Linux foundation. All rights reserved. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License rev 2 and - * only rev 2 as published by the free Software foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or fITNESS fOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. */ #include <linux/clk.h> diff --git a/drivers/soc/qcom/rmtfs_mem.c b/drivers/soc/qcom/rmtfs_mem.c index 6f5e8be9689c..0feaae357821 100644 --- a/drivers/soc/qcom/rmtfs_mem.c +++ b/drivers/soc/qcom/rmtfs_mem.c @@ -1,14 +1,6 @@ +// SPDX-License-Identifier: GPL-2.0-only /* * Copyright (c) 2017 Linaro Ltd. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 and - * only version 2 as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. */ #include <linux/kernel.h> diff --git a/drivers/soc/qcom/rpmpd.c b/drivers/soc/qcom/rpmpd.c index 005326050c23..3c1a55cf25d6 100644 --- a/drivers/soc/qcom/rpmpd.c +++ b/drivers/soc/qcom/rpmpd.c @@ -16,56 +16,76 @@ #define domain_to_rpmpd(domain) container_of(domain, struct rpmpd, pd) -/* Resource types */ +/* Resource types: + * RPMPD_X is X encoded as a little-endian, lower-case, ASCII string */ #define RPMPD_SMPA 0x61706d73 #define RPMPD_LDOA 0x616f646c +#define RPMPD_RWCX 0x78637772 +#define RPMPD_RWMX 0x786d7772 +#define RPMPD_RWLC 0x636c7772 +#define RPMPD_RWLM 0x6d6c7772 +#define RPMPD_RWSC 0x63737772 +#define RPMPD_RWSM 0x6d737772 /* Operation Keys */ #define KEY_CORNER 0x6e726f63 /* corn */ #define KEY_ENABLE 0x6e657773 /* swen */ #define KEY_FLOOR_CORNER 0x636676 /* vfc */ +#define KEY_FLOOR_LEVEL 0x6c6676 /* vfl */ +#define KEY_LEVEL 0x6c766c76 /* vlvl */ -#define MAX_RPMPD_STATE 6 +#define MAX_8996_RPMPD_STATE 6 -#define DEFINE_RPMPD_CORNER_SMPA(_platform, _name, _active, r_id) \ +#define DEFINE_RPMPD_PAIR(_platform, _name, _active, r_type, r_key, \ + r_id) \ static struct rpmpd _platform##_##_active; \ static struct rpmpd _platform##_##_name = { \ .pd = { .name = #_name, }, \ .peer = &_platform##_##_active, \ - .res_type = RPMPD_SMPA, \ + .res_type = RPMPD_##r_type, \ .res_id = r_id, \ - .key = KEY_CORNER, \ + .key = KEY_##r_key, \ }; \ static struct rpmpd _platform##_##_active = { \ .pd = { .name = #_active, }, \ .peer = &_platform##_##_name, \ .active_only = true, \ - .res_type = RPMPD_SMPA, \ + .res_type = RPMPD_##r_type, \ .res_id = r_id, \ - .key = KEY_CORNER, \ + .key = KEY_##r_key, \ } -#define DEFINE_RPMPD_CORNER_LDOA(_platform, _name, r_id) \ +#define DEFINE_RPMPD_CORNER(_platform, _name, r_type, r_id) \ static struct rpmpd _platform##_##_name = { \ .pd = { .name = #_name, }, \ - .res_type = RPMPD_LDOA, \ + .res_type = RPMPD_##r_type, \ .res_id = r_id, \ .key = KEY_CORNER, \ } -#define DEFINE_RPMPD_VFC(_platform, _name, r_id, r_type) \ +#define DEFINE_RPMPD_LEVEL(_platform, _name, r_type, r_id) \ static struct rpmpd _platform##_##_name = { \ .pd = { .name = #_name, }, \ - .res_type = r_type, \ + .res_type = RPMPD_##r_type, \ .res_id = r_id, \ - .key = KEY_FLOOR_CORNER, \ + .key = KEY_LEVEL, \ } -#define DEFINE_RPMPD_VFC_SMPA(_platform, _name, r_id) \ - DEFINE_RPMPD_VFC(_platform, _name, r_id, RPMPD_SMPA) +#define DEFINE_RPMPD_VFC(_platform, _name, r_type, r_id) \ + static struct rpmpd _platform##_##_name = { \ + .pd = { .name = #_name, }, \ + .res_type = RPMPD_##r_type, \ + .res_id = r_id, \ + .key = KEY_FLOOR_CORNER, \ + } -#define DEFINE_RPMPD_VFC_LDOA(_platform, _name, r_id) \ - DEFINE_RPMPD_VFC(_platform, _name, r_id, RPMPD_LDOA) +#define DEFINE_RPMPD_VFL(_platform, _name, r_type, r_id) \ + static struct rpmpd _platform##_##_name = { \ + .pd = { .name = #_name, }, \ + .res_type = RPMPD_##r_type, \ + .res_id = r_id, \ + .key = KEY_FLOOR_LEVEL, \ + } struct rpmpd_req { __le32 key; @@ -83,23 +103,25 @@ struct rpmpd { const int res_type; const int res_id; struct qcom_smd_rpm *rpm; + unsigned int max_state; __le32 key; }; struct rpmpd_desc { struct rpmpd **rpmpds; size_t num_pds; + unsigned int max_state; }; static DEFINE_MUTEX(rpmpd_lock); /* msm8996 RPM Power domains */ -DEFINE_RPMPD_CORNER_SMPA(msm8996, vddcx, vddcx_ao, 1); -DEFINE_RPMPD_CORNER_SMPA(msm8996, vddmx, vddmx_ao, 2); -DEFINE_RPMPD_CORNER_LDOA(msm8996, vddsscx, 26); +DEFINE_RPMPD_PAIR(msm8996, vddcx, vddcx_ao, SMPA, CORNER, 1); +DEFINE_RPMPD_PAIR(msm8996, vddmx, vddmx_ao, SMPA, CORNER, 2); +DEFINE_RPMPD_CORNER(msm8996, vddsscx, LDOA, 26); -DEFINE_RPMPD_VFC_SMPA(msm8996, vddcx_vfc, 1); -DEFINE_RPMPD_VFC_LDOA(msm8996, vddsscx_vfc, 26); +DEFINE_RPMPD_VFC(msm8996, vddcx_vfc, SMPA, 1); +DEFINE_RPMPD_VFC(msm8996, vddsscx_vfc, LDOA, 26); static struct rpmpd *msm8996_rpmpds[] = { [MSM8996_VDDCX] = &msm8996_vddcx, @@ -114,10 +136,71 @@ static struct rpmpd *msm8996_rpmpds[] = { static const struct rpmpd_desc msm8996_desc = { .rpmpds = msm8996_rpmpds, .num_pds = ARRAY_SIZE(msm8996_rpmpds), + .max_state = MAX_8996_RPMPD_STATE, +}; + +/* msm8998 RPM Power domains */ +DEFINE_RPMPD_PAIR(msm8998, vddcx, vddcx_ao, RWCX, LEVEL, 0); +DEFINE_RPMPD_VFL(msm8998, vddcx_vfl, RWCX, 0); + +DEFINE_RPMPD_PAIR(msm8998, vddmx, vddmx_ao, RWMX, LEVEL, 0); +DEFINE_RPMPD_VFL(msm8998, vddmx_vfl, RWMX, 0); + +DEFINE_RPMPD_LEVEL(msm8998, vdd_ssccx, RWSC, 0); +DEFINE_RPMPD_VFL(msm8998, vdd_ssccx_vfl, RWSC, 0); + +DEFINE_RPMPD_LEVEL(msm8998, vdd_sscmx, RWSM, 0); +DEFINE_RPMPD_VFL(msm8998, vdd_sscmx_vfl, RWSM, 0); + +static struct rpmpd *msm8998_rpmpds[] = { + [MSM8998_VDDCX] = &msm8998_vddcx, + [MSM8998_VDDCX_AO] = &msm8998_vddcx_ao, + [MSM8998_VDDCX_VFL] = &msm8998_vddcx_vfl, + [MSM8998_VDDMX] = &msm8998_vddmx, + [MSM8998_VDDMX_AO] = &msm8998_vddmx_ao, + [MSM8998_VDDMX_VFL] = &msm8998_vddmx_vfl, + [MSM8998_SSCCX] = &msm8998_vdd_ssccx, + [MSM8998_SSCCX_VFL] = &msm8998_vdd_ssccx_vfl, + [MSM8998_SSCMX] = &msm8998_vdd_sscmx, + [MSM8998_SSCMX_VFL] = &msm8998_vdd_sscmx_vfl, +}; + +static const struct rpmpd_desc msm8998_desc = { + .rpmpds = msm8998_rpmpds, + .num_pds = ARRAY_SIZE(msm8998_rpmpds), + .max_state = RPM_SMD_LEVEL_BINNING, +}; + +/* qcs404 RPM Power domains */ +DEFINE_RPMPD_PAIR(qcs404, vddmx, vddmx_ao, RWMX, LEVEL, 0); +DEFINE_RPMPD_VFL(qcs404, vddmx_vfl, RWMX, 0); + +DEFINE_RPMPD_LEVEL(qcs404, vdd_lpicx, RWLC, 0); +DEFINE_RPMPD_VFL(qcs404, vdd_lpicx_vfl, RWLC, 0); + +DEFINE_RPMPD_LEVEL(qcs404, vdd_lpimx, RWLM, 0); +DEFINE_RPMPD_VFL(qcs404, vdd_lpimx_vfl, RWLM, 0); + +static struct rpmpd *qcs404_rpmpds[] = { + [QCS404_VDDMX] = &qcs404_vddmx, + [QCS404_VDDMX_AO] = &qcs404_vddmx_ao, + [QCS404_VDDMX_VFL] = &qcs404_vddmx_vfl, + [QCS404_LPICX] = &qcs404_vdd_lpicx, + [QCS404_LPICX_VFL] = &qcs404_vdd_lpicx_vfl, + [QCS404_LPIMX] = &qcs404_vdd_lpimx, + [QCS404_LPIMX_VFL] = &qcs404_vdd_lpimx_vfl, +}; + +static const struct rpmpd_desc qcs404_desc = { + .rpmpds = qcs404_rpmpds, + .num_pds = ARRAY_SIZE(qcs404_rpmpds), + .max_state = RPM_SMD_LEVEL_BINNING, }; static const struct of_device_id rpmpd_match_table[] = { { .compatible = "qcom,msm8996-rpmpd", .data = &msm8996_desc }, + { .compatible = "qcom,msm8998-rpmpd", .data = &msm8998_desc }, + { .compatible = "qcom,qcs404-rpmpd", .data = &qcs404_desc }, { } }; @@ -225,14 +308,16 @@ static int rpmpd_set_performance(struct generic_pm_domain *domain, int ret = 0; struct rpmpd *pd = domain_to_rpmpd(domain); - if (state > MAX_RPMPD_STATE) - goto out; + if (state > pd->max_state) + state = pd->max_state; mutex_lock(&rpmpd_lock); pd->corner = state; - if (!pd->enabled && pd->key != KEY_FLOOR_CORNER) + /* Always send updates for vfc and vfl */ + if (!pd->enabled && pd->key != KEY_FLOOR_CORNER && + pd->key != KEY_FLOOR_LEVEL) goto out; ret = rpmpd_aggregate_corner(pd); @@ -287,6 +372,7 @@ static int rpmpd_probe(struct platform_device *pdev) } rpmpds[i]->rpm = rpm; + rpmpds[i]->max_state = desc->max_state; rpmpds[i]->pd.power_off = rpmpd_power_off; rpmpds[i]->pd.power_on = rpmpd_power_on; rpmpds[i]->pd.set_performance_state = rpmpd_set_performance; diff --git a/drivers/soc/qcom/smd-rpm.c b/drivers/soc/qcom/smd-rpm.c index 9956bb2c63f2..fa9dd12b5e39 100644 --- a/drivers/soc/qcom/smd-rpm.c +++ b/drivers/soc/qcom/smd-rpm.c @@ -1,15 +1,7 @@ +// SPDX-License-Identifier: GPL-2.0-only /* * Copyright (c) 2015, Sony Mobile Communications AB. * Copyright (c) 2012-2013, The Linux Foundation. All rights reserved. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 and - * only version 2 as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. */ #include <linux/module.h> diff --git a/drivers/soc/qcom/smem.c b/drivers/soc/qcom/smem.c index f80d040601fd..f27c00d82ae4 100644 --- a/drivers/soc/qcom/smem.c +++ b/drivers/soc/qcom/smem.c @@ -1,15 +1,7 @@ +// SPDX-License-Identifier: GPL-2.0-only /* * Copyright (c) 2015, Sony Mobile Communications AB. * Copyright (c) 2012-2013, The Linux Foundation. All rights reserved. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 and - * only version 2 as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. */ #include <linux/hwspinlock.h> diff --git a/drivers/soc/qcom/smem_state.c b/drivers/soc/qcom/smem_state.c index d5437ca76ed9..d2b558438deb 100644 --- a/drivers/soc/qcom/smem_state.c +++ b/drivers/soc/qcom/smem_state.c @@ -1,15 +1,7 @@ +// SPDX-License-Identifier: GPL-2.0-only /* * Copyright (c) 2015, Sony Mobile Communications Inc. * Copyright (c) 2012-2013, The Linux Foundation. All rights reserved. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 and - * only version 2 as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. */ #include <linux/device.h> #include <linux/list.h> diff --git a/drivers/soc/qcom/smp2p.c b/drivers/soc/qcom/smp2p.c index c22503cd1edf..c7300d54e444 100644 --- a/drivers/soc/qcom/smp2p.c +++ b/drivers/soc/qcom/smp2p.c @@ -1,15 +1,7 @@ +// SPDX-License-Identifier: GPL-2.0-only /* * Copyright (c) 2015, Sony Mobile Communications AB. * Copyright (c) 2012-2013, The Linux Foundation. All rights reserved. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 and - * only version 2 as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. */ #include <linux/interrupt.h> diff --git a/drivers/soc/qcom/smsm.c b/drivers/soc/qcom/smsm.c index 50214b620865..70c3c90b997c 100644 --- a/drivers/soc/qcom/smsm.c +++ b/drivers/soc/qcom/smsm.c @@ -1,15 +1,7 @@ +// SPDX-License-Identifier: GPL-2.0-only /* * Copyright (c) 2015, Sony Mobile Communications Inc. * Copyright (c) 2012-2013, The Linux Foundation. All rights reserved. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 and - * only version 2 as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. */ #include <linux/interrupt.h> diff --git a/drivers/soc/qcom/spm.c b/drivers/soc/qcom/spm.c index 53807e839664..8e10e02c6aa5 100644 --- a/drivers/soc/qcom/spm.c +++ b/drivers/soc/qcom/spm.c @@ -1,17 +1,9 @@ +// SPDX-License-Identifier: GPL-2.0-only /* * Copyright (c) 2011-2014, The Linux Foundation. All rights reserved. * Copyright (c) 2014,2015, Linaro Ltd. * * SAW power controller driver - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 and - * only version 2 as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. */ #include <linux/kernel.h> diff --git a/drivers/soc/qcom/wcnss_ctrl.c b/drivers/soc/qcom/wcnss_ctrl.c index 373400dd816d..e5c68051fb17 100644 --- a/drivers/soc/qcom/wcnss_ctrl.c +++ b/drivers/soc/qcom/wcnss_ctrl.c @@ -1,15 +1,7 @@ +// SPDX-License-Identifier: GPL-2.0-only /* * Copyright (c) 2016, Linaro Ltd. * Copyright (c) 2015, Sony Mobile Communications Inc. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 and - * only version 2 as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. */ #include <linux/firmware.h> #include <linux/module.h> diff --git a/drivers/soc/rockchip/Kconfig b/drivers/soc/rockchip/Kconfig index 20da55d9cbb1..b71b73bf5fc5 100644 --- a/drivers/soc/rockchip/Kconfig +++ b/drivers/soc/rockchip/Kconfig @@ -1,3 +1,4 @@ +# SPDX-License-Identifier: GPL-2.0-only if ARCH_ROCKCHIP || COMPILE_TEST # diff --git a/drivers/soc/rockchip/Makefile b/drivers/soc/rockchip/Makefile index c851fa0056d0..afca0a4c4b72 100644 --- a/drivers/soc/rockchip/Makefile +++ b/drivers/soc/rockchip/Makefile @@ -1,3 +1,4 @@ +# SPDX-License-Identifier: GPL-2.0-only # # Rockchip Soc drivers # diff --git a/drivers/soc/sunxi/Kconfig b/drivers/soc/sunxi/Kconfig index e84eb4e59f58..f10fd6cae13e 100644 --- a/drivers/soc/sunxi/Kconfig +++ b/drivers/soc/sunxi/Kconfig @@ -1,3 +1,4 @@ +# SPDX-License-Identifier: GPL-2.0-only # # Allwinner sunXi SoC drivers # diff --git a/drivers/soc/sunxi/Makefile b/drivers/soc/sunxi/Makefile index 4cf9dbdf346e..7816fbbec387 100644 --- a/drivers/soc/sunxi/Makefile +++ b/drivers/soc/sunxi/Makefile @@ -1 +1,2 @@ +# SPDX-License-Identifier: GPL-2.0-only obj-$(CONFIG_SUNXI_SRAM) += sunxi_sram.o diff --git a/drivers/soc/tegra/Kconfig b/drivers/soc/tegra/Kconfig index a0b03443d8c1..c8ef05d6b8c7 100644 --- a/drivers/soc/tegra/Kconfig +++ b/drivers/soc/tegra/Kconfig @@ -1,3 +1,4 @@ +# SPDX-License-Identifier: GPL-2.0-only if ARCH_TEGRA # 32-bit ARM SoCs @@ -108,6 +109,7 @@ config ARCH_TEGRA_186_SOC config ARCH_TEGRA_194_SOC bool "NVIDIA Tegra194 SoC" select MAILBOX + select PINCTRL_TEGRA194 select TEGRA_BPMP select TEGRA_HSP_MBOX select TEGRA_IVC diff --git a/drivers/soc/tegra/flowctrl.c b/drivers/soc/tegra/flowctrl.c index 5433cc7a043e..b6bdeef33db1 100644 --- a/drivers/soc/tegra/flowctrl.c +++ b/drivers/soc/tegra/flowctrl.c @@ -1,21 +1,10 @@ +// SPDX-License-Identifier: GPL-2.0-only /* * drivers/soc/tegra/flowctrl.c * * Functions and macros to control the flowcontroller * * Copyright (c) 2010-2012, NVIDIA Corporation. All rights reserved. - * - * This program is free software; you can redistribute it and/or modify it - * under the terms and conditions of the GNU General Public License, - * version 2, as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for - * more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see <http://www.gnu.org/licenses/>. */ #include <linux/cpumask.h> diff --git a/drivers/soc/tegra/fuse/fuse-tegra.c b/drivers/soc/tegra/fuse/fuse-tegra.c index 51625703399e..3eb44e65b326 100644 --- a/drivers/soc/tegra/fuse/fuse-tegra.c +++ b/drivers/soc/tegra/fuse/fuse-tegra.c @@ -1,18 +1,6 @@ +// SPDX-License-Identifier: GPL-2.0-only /* * Copyright (c) 2013-2014, NVIDIA CORPORATION. All rights reserved. - * - * This program is free software; you can redistribute it and/or modify it - * under the terms and conditions of the GNU General Public License, - * version 2, as published by the Free Software Foundation. - * - * This program is distributed in the hope it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for - * more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see <http://www.gnu.org/licenses/>. - * */ #include <linux/clk.h> @@ -145,8 +133,10 @@ static int tegra_fuse_probe(struct platform_device *pdev) fuse->clk = devm_clk_get(&pdev->dev, "fuse"); if (IS_ERR(fuse->clk)) { - dev_err(&pdev->dev, "failed to get FUSE clock: %ld", - PTR_ERR(fuse->clk)); + if (PTR_ERR(fuse->clk) != -EPROBE_DEFER) + dev_err(&pdev->dev, "failed to get FUSE clock: %ld", + PTR_ERR(fuse->clk)); + fuse->base = base; return PTR_ERR(fuse->clk); } diff --git a/drivers/soc/tegra/fuse/fuse-tegra20.c b/drivers/soc/tegra/fuse/fuse-tegra20.c index 49ff017f3ded..4bb16e9bc297 100644 --- a/drivers/soc/tegra/fuse/fuse-tegra20.c +++ b/drivers/soc/tegra/fuse/fuse-tegra20.c @@ -1,18 +1,7 @@ +// SPDX-License-Identifier: GPL-2.0-only /* * Copyright (c) 2013-2014, NVIDIA CORPORATION. All rights reserved. * - * This program is free software; you can redistribute it and/or modify it - * under the terms and conditions of the GNU General Public License, - * version 2, as published by the Free Software Foundation. - * - * This program is distributed in the hope it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for - * more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see <http://www.gnu.org/licenses/>. - * * Based on drivers/misc/eeprom/sunxi_sid.c */ diff --git a/drivers/soc/tegra/fuse/fuse-tegra30.c b/drivers/soc/tegra/fuse/fuse-tegra30.c index 257e254c6137..be9424a87173 100644 --- a/drivers/soc/tegra/fuse/fuse-tegra30.c +++ b/drivers/soc/tegra/fuse/fuse-tegra30.c @@ -1,18 +1,6 @@ +// SPDX-License-Identifier: GPL-2.0-only /* * Copyright (c) 2013-2014, NVIDIA CORPORATION. All rights reserved. - * - * This program is free software; you can redistribute it and/or modify it - * under the terms and conditions of the GNU General Public License, - * version 2, as published by the Free Software Foundation. - * - * This program is distributed in the hope it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for - * more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see <http://www.gnu.org/licenses/>. - * */ #include <linux/device.h> diff --git a/drivers/soc/tegra/fuse/fuse.h b/drivers/soc/tegra/fuse/fuse.h index f355b9d54915..7230cb330503 100644 --- a/drivers/soc/tegra/fuse/fuse.h +++ b/drivers/soc/tegra/fuse/fuse.h @@ -1,19 +1,10 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ /* * Copyright (C) 2010 Google, Inc. * Copyright (c) 2013, NVIDIA CORPORATION. All rights reserved. * * Author: * Colin Cross <ccross@android.com> - * - * This software is licensed under the terms of the GNU General Public - * License version 2, as published by the Free Software Foundation, and - * may be copied, distributed, and modified under those terms. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * */ #ifndef __DRIVERS_MISC_TEGRA_FUSE_H diff --git a/drivers/soc/tegra/fuse/speedo-tegra114.c b/drivers/soc/tegra/fuse/speedo-tegra114.c index 1ba41ebbb23d..6695702bdb4c 100644 --- a/drivers/soc/tegra/fuse/speedo-tegra114.c +++ b/drivers/soc/tegra/fuse/speedo-tegra114.c @@ -1,17 +1,6 @@ +// SPDX-License-Identifier: GPL-2.0-only /* * Copyright (c) 2013-2014, NVIDIA CORPORATION. All rights reserved. - * - * This program is free software; you can redistribute it and/or modify it - * under the terms and conditions of the GNU General Public License, - * version 2, as published by the Free Software Foundation. - * - * This program is distributed in the hope it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for - * more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see <http://www.gnu.org/licenses/>. */ #include <linux/bug.h> diff --git a/drivers/soc/tegra/fuse/speedo-tegra124.c b/drivers/soc/tegra/fuse/speedo-tegra124.c index a63a134101ab..bdbf76bb184f 100644 --- a/drivers/soc/tegra/fuse/speedo-tegra124.c +++ b/drivers/soc/tegra/fuse/speedo-tegra124.c @@ -1,17 +1,6 @@ +// SPDX-License-Identifier: GPL-2.0-only /* * Copyright (c) 2013-2014, NVIDIA CORPORATION. All rights reserved. - * - * This program is free software; you can redistribute it and/or modify it - * under the terms and conditions of the GNU General Public License, - * version 2, as published by the Free Software Foundation. - * - * This program is distributed in the hope it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for - * more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see <http://www.gnu.org/licenses/>. */ #include <linux/device.h> diff --git a/drivers/soc/tegra/fuse/speedo-tegra20.c b/drivers/soc/tegra/fuse/speedo-tegra20.c index 5f7818bf6072..2546bddbab93 100644 --- a/drivers/soc/tegra/fuse/speedo-tegra20.c +++ b/drivers/soc/tegra/fuse/speedo-tegra20.c @@ -1,17 +1,6 @@ +// SPDX-License-Identifier: GPL-2.0-only /* * Copyright (c) 2012-2014, NVIDIA CORPORATION. All rights reserved. - * - * This program is free software; you can redistribute it and/or modify it - * under the terms and conditions of the GNU General Public License, - * version 2, as published by the Free Software Foundation. - * - * This program is distributed in the hope it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for - * more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see <http://www.gnu.org/licenses/>. */ #include <linux/bug.h> diff --git a/drivers/soc/tegra/fuse/speedo-tegra210.c b/drivers/soc/tegra/fuse/speedo-tegra210.c index 8ed35d9851f8..70d3f6e1aa33 100644 --- a/drivers/soc/tegra/fuse/speedo-tegra210.c +++ b/drivers/soc/tegra/fuse/speedo-tegra210.c @@ -1,17 +1,6 @@ +// SPDX-License-Identifier: GPL-2.0-only /* * Copyright (c) 2013-2015, NVIDIA CORPORATION. All rights reserved. - * - * This program is free software; you can redistribute it and/or modify it - * under the terms and conditions of the GNU General Public License, - * version 2, as published by the Free Software Foundation. - * - * This program is distributed in the hope it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for - * more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see <http://www.gnu.org/licenses/>. */ #include <linux/device.h> diff --git a/drivers/soc/tegra/fuse/speedo-tegra30.c b/drivers/soc/tegra/fuse/speedo-tegra30.c index 9b010b3ef009..b1d09944b3f3 100644 --- a/drivers/soc/tegra/fuse/speedo-tegra30.c +++ b/drivers/soc/tegra/fuse/speedo-tegra30.c @@ -1,17 +1,6 @@ +// SPDX-License-Identifier: GPL-2.0-only /* * Copyright (c) 2012-2014, NVIDIA CORPORATION. All rights reserved. - * - * This program is free software; you can redistribute it and/or modify it - * under the terms and conditions of the GNU General Public License, - * version 2, as published by the Free Software Foundation. - * - * This program is distributed in the hope it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for - * more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see <http://www.gnu.org/licenses/>. */ #include <linux/bug.h> diff --git a/drivers/soc/tegra/fuse/tegra-apbmisc.c b/drivers/soc/tegra/fuse/tegra-apbmisc.c index e5a4d8f98b10..df76778af601 100644 --- a/drivers/soc/tegra/fuse/tegra-apbmisc.c +++ b/drivers/soc/tegra/fuse/tegra-apbmisc.c @@ -1,18 +1,6 @@ +// SPDX-License-Identifier: GPL-2.0-only /* * Copyright (c) 2014, NVIDIA CORPORATION. All rights reserved. - * - * This program is free software; you can redistribute it and/or modify it - * under the terms and conditions of the GNU General Public License, - * version 2, as published by the Free Software Foundation. - * - * This program is distributed in the hope it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for - * more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see <http://www.gnu.org/licenses/>. - * */ #include <linux/kernel.h> diff --git a/drivers/soc/tegra/pmc.c b/drivers/soc/tegra/pmc.c index 5648e5c09ef5..edd4fe06810f 100644 --- a/drivers/soc/tegra/pmc.c +++ b/drivers/soc/tegra/pmc.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0-only /* * drivers/soc/tegra/pmc.c * @@ -6,16 +7,6 @@ * * Author: * Colin Cross <ccross@google.com> - * - * This software is licensed under the terms of the GNU General Public - * License version 2, as published by the Free Software Foundation, and - * may be copied, distributed, and modified under those terms. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * */ #define pr_fmt(fmt) "tegra-pmc: " fmt @@ -241,6 +232,11 @@ struct tegra_pmc_soc { const char * const *reset_levels; unsigned int num_reset_levels; + /* + * These describe events that can wake the system from sleep (i.e. + * LP0 or SC7). Wakeup from other sleep states (such as LP1 or LP2) + * are dealt with in the LIC. + */ const struct tegra_wake_event *wake_events; unsigned int num_wake_events; }; @@ -1863,6 +1859,9 @@ static int tegra_pmc_irq_alloc(struct irq_domain *domain, unsigned int virq, unsigned int i; int err = 0; + if (WARN_ON(num_irqs > 1)) + return -EINVAL; + for (i = 0; i < soc->num_wake_events; i++) { const struct tegra_wake_event *event = &soc->wake_events[i]; @@ -1903,6 +1902,11 @@ static int tegra_pmc_irq_alloc(struct irq_domain *domain, unsigned int virq, } } + /* + * For interrupts that don't have associated wake events, assign a + * dummy hardware IRQ number. This is used in the ->irq_set_type() + * and ->irq_set_wake() callbacks to return early for these IRQs. + */ if (i == soc->num_wake_events) err = irq_domain_set_hwirq_and_chip(domain, virq, ULONG_MAX, &pmc->irq, pmc); @@ -1921,6 +1925,10 @@ static int tegra_pmc_irq_set_wake(struct irq_data *data, unsigned int on) unsigned int offset, bit; u32 value; + /* nothing to do if there's no associated wake event */ + if (WARN_ON(data->hwirq == ULONG_MAX)) + return 0; + offset = data->hwirq / 32; bit = data->hwirq % 32; @@ -1948,6 +1956,7 @@ static int tegra_pmc_irq_set_type(struct irq_data *data, unsigned int type) struct tegra_pmc *pmc = irq_data_get_irq_chip_data(data); u32 value; + /* nothing to do if there's no associated wake event */ if (data->hwirq == ULONG_MAX) return 0; diff --git a/drivers/soc/tegra/powergate-bpmp.c b/drivers/soc/tegra/powergate-bpmp.c index 82c7e27cd8bb..06c792bafca5 100644 --- a/drivers/soc/tegra/powergate-bpmp.c +++ b/drivers/soc/tegra/powergate-bpmp.c @@ -1,14 +1,6 @@ +// SPDX-License-Identifier: GPL-2.0-only /* * Copyright (c) 2016-2017, NVIDIA CORPORATION. All rights reserved - * - * This program is free software; you can redistribute it and/or modify it - * under the terms and conditions of the GNU General Public License, - * version 2, as published by the Free Software Foundation. - * - * This program is distributed in the hope it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for - * more details. */ #include <linux/of.h> diff --git a/drivers/soc/ti/Kconfig b/drivers/soc/ti/Kconfig index dbd6c60b81db..ea0859f7b185 100644 --- a/drivers/soc/ti/Kconfig +++ b/drivers/soc/ti/Kconfig @@ -1,3 +1,4 @@ +# SPDX-License-Identifier: GPL-2.0-only # 64-bit ARM SoCs from TI if ARM64 diff --git a/drivers/soc/ti/knav_qmss.h b/drivers/soc/ti/knav_qmss.h index 4c28fa938ac7..038aec352df7 100644 --- a/drivers/soc/ti/knav_qmss.h +++ b/drivers/soc/ti/knav_qmss.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ /* * Keystone Navigator QMSS driver internal header * @@ -5,15 +6,6 @@ * Author: Sandeep Nair <sandeep_n@ti.com> * Cyril Chemparathy <cyril@ti.com> * Santosh Shilimkar <santosh.shilimkar@ti.com> - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * version 2 as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. */ #ifndef __KNAV_QMSS_H__ diff --git a/drivers/soc/ti/knav_qmss_acc.c b/drivers/soc/ti/knav_qmss_acc.c index 2f7fb2dcc1d6..1762d89fc05d 100644 --- a/drivers/soc/ti/knav_qmss_acc.c +++ b/drivers/soc/ti/knav_qmss_acc.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0-only /* * Keystone accumulator queue manager * @@ -5,15 +6,6 @@ * Author: Sandeep Nair <sandeep_n@ti.com> * Cyril Chemparathy <cyril@ti.com> * Santosh Shilimkar <santosh.shilimkar@ti.com> - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * version 2 as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. */ #include <linux/dma-mapping.h> diff --git a/drivers/soc/ti/knav_qmss_queue.c b/drivers/soc/ti/knav_qmss_queue.c index 8b418379272d..1ccc9064e1eb 100644 --- a/drivers/soc/ti/knav_qmss_queue.c +++ b/drivers/soc/ti/knav_qmss_queue.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0-only /* * Keystone Queue Manager subsystem driver * @@ -5,15 +6,6 @@ * Authors: Sandeep Nair <sandeep_n@ti.com> * Cyril Chemparathy <cyril@ti.com> * Santosh Shilimkar <santosh.shilimkar@ti.com> - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * version 2 as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. */ #include <linux/debugfs.h> diff --git a/drivers/soc/ti/ti_sci_pm_domains.c b/drivers/soc/ti/ti_sci_pm_domains.c index de31b9389e2e..97817dd7ba24 100644 --- a/drivers/soc/ti/ti_sci_pm_domains.c +++ b/drivers/soc/ti/ti_sci_pm_domains.c @@ -1,18 +1,10 @@ +// SPDX-License-Identifier: GPL-2.0-only /* * TI SCI Generic Power Domain Driver * * Copyright (C) 2015-2017 Texas Instruments Incorporated - http://www.ti.com/ * J Keerthy <j-keerthy@ti.com> * Dave Gerlach <d-gerlach@ti.com> - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * version 2 as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. */ #include <linux/err.h> diff --git a/drivers/soc/ti/wkup_m3_ipc.c b/drivers/soc/ti/wkup_m3_ipc.c index d65e361c5de1..378369d9364a 100644 --- a/drivers/soc/ti/wkup_m3_ipc.c +++ b/drivers/soc/ti/wkup_m3_ipc.c @@ -1,18 +1,10 @@ +// SPDX-License-Identifier: GPL-2.0-only /* * AMx3 Wkup M3 IPC driver * * Copyright (C) 2015 Texas Instruments, Inc. * * Dave Gerlach <d-gerlach@ti.com> - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * version 2 as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. */ #include <linux/err.h> diff --git a/drivers/soc/ux500/Kconfig b/drivers/soc/ux500/Kconfig index 025a44aef5db..0e04272edfe4 100644 --- a/drivers/soc/ux500/Kconfig +++ b/drivers/soc/ux500/Kconfig @@ -1,3 +1,4 @@ +# SPDX-License-Identifier: GPL-2.0-only config UX500_SOC_ID bool "SoC bus for ST-Ericsson ux500" depends on ARCH_U8500 || COMPILE_TEST diff --git a/drivers/soc/ux500/Makefile b/drivers/soc/ux500/Makefile index 0b87ad04b018..f1645397d60d 100644 --- a/drivers/soc/ux500/Makefile +++ b/drivers/soc/ux500/Makefile @@ -1 +1,2 @@ +# SPDX-License-Identifier: GPL-2.0-only obj-$(CONFIG_UX500_SOC_ID) += ux500-soc-id.o diff --git a/drivers/soc/ux500/ux500-soc-id.c b/drivers/soc/ux500/ux500-soc-id.c index 6c1be74e5fcc..ea5fd2e5e340 100644 --- a/drivers/soc/ux500/ux500-soc-id.c +++ b/drivers/soc/ux500/ux500-soc-id.c @@ -1,8 +1,8 @@ +// SPDX-License-Identifier: GPL-2.0-only /* * Copyright (C) ST-Ericsson SA 2010 * * Author: Rabin Vincent <rabin.vincent@stericsson.com> for ST-Ericsson - * License terms: GNU General Public License (GPL) version 2 */ #include <linux/kernel.h> diff --git a/drivers/soc/versatile/Kconfig b/drivers/soc/versatile/Kconfig index a928a7fc6be4..c3792c0a84ac 100644 --- a/drivers/soc/versatile/Kconfig +++ b/drivers/soc/versatile/Kconfig @@ -1,3 +1,4 @@ +# SPDX-License-Identifier: GPL-2.0-only # # ARM Versatile SoC drivers # diff --git a/drivers/soc/versatile/Makefile b/drivers/soc/versatile/Makefile index cf612fe3a659..1e0a37c0a5ac 100644 --- a/drivers/soc/versatile/Makefile +++ b/drivers/soc/versatile/Makefile @@ -1,2 +1,3 @@ +# SPDX-License-Identifier: GPL-2.0-only obj-$(CONFIG_SOC_INTEGRATOR_CM) += soc-integrator.o obj-$(CONFIG_SOC_REALVIEW) += soc-realview.o diff --git a/drivers/soc/zte/Kconfig b/drivers/soc/zte/Kconfig index e9d750c510cd..1cf1938da541 100644 --- a/drivers/soc/zte/Kconfig +++ b/drivers/soc/zte/Kconfig @@ -1,3 +1,4 @@ +# SPDX-License-Identifier: GPL-2.0-only # # ZTE SoC drivers # diff --git a/drivers/soc/zte/Makefile b/drivers/soc/zte/Makefile index 96b7cd4c9629..728c677addcd 100644 --- a/drivers/soc/zte/Makefile +++ b/drivers/soc/zte/Makefile @@ -1,3 +1,4 @@ +# SPDX-License-Identifier: GPL-2.0-only # # ZTE SOC drivers # diff --git a/drivers/soc/zte/zx296718_pm_domains.c b/drivers/soc/zte/zx296718_pm_domains.c index 4dc5d62ee81b..4daab06bbc26 100644 --- a/drivers/soc/zte/zx296718_pm_domains.c +++ b/drivers/soc/zte/zx296718_pm_domains.c @@ -1,8 +1,8 @@ +// SPDX-License-Identifier: GPL-2.0-only /* * Copyright (C) 2017 ZTE Ltd. * * Author: Baoyou Xie <baoyou.xie@linaro.org> - * License terms: GNU General Public License (GPL) version 2 */ #include <dt-bindings/soc/zte,pm_domains.h> diff --git a/drivers/soc/zte/zx2967_pm_domains.c b/drivers/soc/zte/zx2967_pm_domains.c index c42aeaaa34ba..a4503e31b616 100644 --- a/drivers/soc/zte/zx2967_pm_domains.c +++ b/drivers/soc/zte/zx2967_pm_domains.c @@ -1,8 +1,8 @@ +// SPDX-License-Identifier: GPL-2.0-only /* * Copyright (C) 2017 ZTE Ltd. * * Author: Baoyou Xie <baoyou.xie@linaro.org> - * License terms: GNU General Public License (GPL) version 2 */ #include <linux/delay.h> diff --git a/drivers/soc/zte/zx2967_pm_domains.h b/drivers/soc/zte/zx2967_pm_domains.h index cb46595a7ff3..f586c02410ff 100644 --- a/drivers/soc/zte/zx2967_pm_domains.h +++ b/drivers/soc/zte/zx2967_pm_domains.h @@ -1,10 +1,10 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ /* * Header for ZTE's Power Domain Driver support * * Copyright (C) 2017 ZTE Ltd. * * Author: Baoyou Xie <baoyou.xie@linaro.org> - * License terms: GNU General Public License (GPL) version 2 */ #ifndef __ZTE_ZX2967_PM_DOMAIN_H |