diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2018-10-29 23:37:33 +0100 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2018-10-29 23:37:33 +0100 |
commit | 4b42745211af552f170f38a1b97f4a112b5da6b2 (patch) | |
tree | 83b165e30cc685ba335d3295deb193dd910c7271 /arch/arm | |
parent | Merge tag 'armsoc-drivers' of git://git.kernel.org/pub/scm/linux/kernel/git/a... (diff) | |
parent | MAINTAINERS: Assign myself as a maintainer of ARM/LPC18XX architecture (diff) | |
download | linux-4b42745211af552f170f38a1b97f4a112b5da6b2.tar.xz linux-4b42745211af552f170f38a1b97f4a112b5da6b2.zip |
Merge tag 'armsoc-soc' of git://git.kernel.org/pub/scm/linux/kernel/git/arm/arm-soc
Pull ARM SoC platform updates from Arnd Bergmann:
"A couple of platforms change hands in the MAINTAINERS file:
- Linus Walleij lists himself for the ARM Reference platforms:
versatile, vexpress, integrator and realview. He has been the main
contributor for these for a while, and makes it official now.
- Vladimir Zapolskiy takes over the LPC18xx platform from Joachim
Eastwood
- Manivannan Sadhasivam becomes a secondary maintainer for the
Actions Semi machines
- Nicolas Ferre lists updates the MAINTAINER listing for the AT91
platform: Ludovic Desroches is now a co-maintainer for the
platform, and several other people (Claudiu Beznea, Cristian
Birsan, Eugen Hristev, Codrin Ciubotariu) take over individual
device drivers.
Thanks everyone for working on this, and welcome to the new
maintainers!
The "virt" platform on qemy or kvm can now be used in big-endian mode
without additional tricks, thanks to Jason Donenfeld.
Once again, we gain support for another NXP i.MX6 variant, this time
it's the i.MX 6ULZ 32-bit single-core version.
On arm64, we add support for two SoCs from Renesas: RZ/G2E (r8a774c0)
and RZ/G2M (r8a774a1). These are described as microcontrollers on the
manufacturer website, but appear to be rather powerful. The RZ/G2M is
used on the reference board for the CIP Super Long Term Support (SLTS)
Linux Kernels"
* tag 'armsoc-soc' of git://git.kernel.org/pub/scm/linux/kernel/git/arm/arm-soc: (54 commits)
MAINTAINERS: Assign myself as a maintainer of ARM/LPC18XX architecture
arm64: exynos: Enable generic power domain support
MAINTAINERS: remove non-exsiting email address of Baoyou
MAINTAINERS: fix pattern in ARM/Synaptics berlin SoC section
MAINTAINERS: Drop dt-bindings/genpd/k2g.h
ARM: samsung: Limit SAMSUNG_PM_CHECK config option to non-Exynos platforms
arm64: actions: Enable PINCTRL in platforms Kconfig
MAINTAINERS: Add entry for Actions Semi Owl SoCs DMA driver
MAINTAINERS: Add entry for Actions Semiconductor Owl I2C driver
MAINTAINERS: Update clock binding entry for Actions Semi Owl SoCs
ARM: imx: add i.mx6ulz msl support
ARM: Assume maintainership of ARM reference designs
ARM: support big-endian for the virt architecture
MAINTAINERS: sdhci: move the Microchip entry to proper location
MAINTAINERS: move former ATMEL entries to proper MICROCHIP location
MAINTAINERS: remove the / ATMEL string from MICROCHIP entries
MAINTAINERS: iio: add co-maintainer to SAMA5D2-compatible ADC driver
MAINTAINERS: pwm: add entry for Microchip pwm driver
MAINTAINERS: dmaengine: add files to Microchip dma entry
MAINTAINERS: USB: change maintainer for Microchip USBA gadget driver
...
Diffstat (limited to 'arch/arm')
32 files changed, 365 insertions, 530 deletions
diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig index e8cd55a5b04c..b8c6062ca0c1 100644 --- a/arch/arm/Kconfig +++ b/arch/arm/Kconfig @@ -701,6 +701,7 @@ config ARCH_VIRT select ARM_GIC_V3_ITS if PCI select ARM_PSCI select HAVE_ARM_ARCH_TIMER + select ARCH_SUPPORTS_BIG_ENDIAN # # This is sorted alphabetically by mach-* pathname. However, plat-* diff --git a/arch/arm/Kconfig.debug b/arch/arm/Kconfig.debug index a810fa8ba404..d6a49f59ecd9 100644 --- a/arch/arm/Kconfig.debug +++ b/arch/arm/Kconfig.debug @@ -947,12 +947,13 @@ choice config DEBUG_RCAR_GEN2_SCIF0 bool "Kernel low-level debugging messages via SCIF0 on R-Car Gen2 and RZ/G1" - depends on ARCH_R8A7743 || ARCH_R8A7790 || ARCH_R8A7791 || \ - ARCH_R8A7792 || ARCH_R8A7793 + depends on ARCH_R8A7743 || ARCH_R8A7744 || ARCH_R8A7790 || \ + ARCH_R8A7791 || ARCH_R8A7792 || ARCH_R8A7793 help Say Y here if you want kernel low-level debugging support - via SCIF0 on Renesas RZ/G1M (R8A7743), R-Car H2 (R8A7790), - M2-W (R8A7791), V2H (R8A7792), or M2-N (R8A7793). + via SCIF0 on Renesas RZ/G1M (R8A7743), RZ/G1N (R8A7744), + R-Car H2 (R8A7790), M2-W (R8A7791), V2H (R8A7792), or + M2-N (R8A7793). config DEBUG_RCAR_GEN2_SCIF1 bool "Kernel low-level debugging messages via SCIF1 on R8A77470" diff --git a/arch/arm/mach-at91/pm.c b/arch/arm/mach-at91/pm.c index 32fae4dbd63b..51e808adb00c 100644 --- a/arch/arm/mach-at91/pm.c +++ b/arch/arm/mach-at91/pm.c @@ -143,15 +143,15 @@ static int at91_pm_config_ws(unsigned int pm_mode, bool set) /* Check if enabled on SHDWC. */ if (wsi->shdwc_mr_bit && !(val & wsi->shdwc_mr_bit)) - goto put_node; + goto put_device; mode |= wsi->pmc_fsmr_bit; if (wsi->set_polarity) polarity |= wsi->pmc_fsmr_bit; } -put_node: - of_node_put(np); +put_device: + put_device(&pdev->dev); } if (mode) { @@ -580,8 +580,6 @@ static int __init at91_pm_backup_init(void) if (!at91_is_pm_mode_active(AT91_PM_BACKUP)) return 0; - pm_bu = NULL; - np = of_find_compatible_node(NULL, NULL, "atmel,sama5d2-sfrbu"); if (!np) { pr_warn("%s: failed to find sfrbu!\n", __func__); @@ -590,7 +588,6 @@ static int __init at91_pm_backup_init(void) pm_data.sfrbu = of_iomap(np, 0); of_node_put(np); - pm_bu = NULL; np = of_find_compatible_node(NULL, NULL, "atmel,sama5d2-securam"); if (!np) diff --git a/arch/arm/mach-imx/anatop.c b/arch/arm/mach-imx/anatop.c index 61f3d94f1633..45d618abf26b 100644 --- a/arch/arm/mach-imx/anatop.c +++ b/arch/arm/mach-imx/anatop.c @@ -31,6 +31,8 @@ #define ANADIG_DIGPROG_IMX6SL 0x280 #define ANADIG_DIGPROG_IMX7D 0x800 +#define SRC_SBMR2 0x1c + #define BM_ANADIG_REG_2P5_ENABLE_WEAK_LINREG 0x40000 #define BM_ANADIG_REG_2P5_ENABLE_PULLDOWN 0x8 #define BM_ANADIG_REG_CORE_FET_ODRIVE 0x20000000 @@ -148,6 +150,24 @@ void __init imx_init_revision_from_anatop(void) major_part = (digprog >> 8) & 0xf; minor_part = digprog & 0xf; revision = ((major_part + 1) << 4) | minor_part; + + if ((digprog >> 16) == MXC_CPU_IMX6ULL) { + void __iomem *src_base; + u32 sbmr2; + + np = of_find_compatible_node(NULL, NULL, + "fsl,imx6ul-src"); + src_base = of_iomap(np, 0); + WARN_ON(!src_base); + sbmr2 = readl_relaxed(src_base + SRC_SBMR2); + iounmap(src_base); + + /* src_sbmr2 bit 6 is to identify if it is i.MX6ULZ */ + if (sbmr2 & (1 << 6)) { + digprog &= ~(0xff << 16); + digprog |= (MXC_CPU_IMX6ULZ << 16); + } + } } mxc_set_cpu_type(digprog >> 16 & 0xff); diff --git a/arch/arm/mach-imx/cpu.c b/arch/arm/mach-imx/cpu.c index c6b1bf97a6c1..c73593e09121 100644 --- a/arch/arm/mach-imx/cpu.c +++ b/arch/arm/mach-imx/cpu.c @@ -136,6 +136,9 @@ struct device * __init imx_soc_device_init(void) case MXC_CPU_IMX6ULL: soc_id = "i.MX6ULL"; break; + case MXC_CPU_IMX6ULZ: + soc_id = "i.MX6ULZ"; + break; case MXC_CPU_IMX6SLL: soc_id = "i.MX6SLL"; break; diff --git a/arch/arm/mach-imx/mmdc.c b/arch/arm/mach-imx/mmdc.c index 04b3bf71de94..e49e06834516 100644 --- a/arch/arm/mach-imx/mmdc.c +++ b/arch/arm/mach-imx/mmdc.c @@ -11,6 +11,7 @@ * http://www.gnu.org/copyleft/gpl.html */ +#include <linux/clk.h> #include <linux/hrtimer.h> #include <linux/init.h> #include <linux/interrupt.h> @@ -546,7 +547,20 @@ static int imx_mmdc_probe(struct platform_device *pdev) { struct device_node *np = pdev->dev.of_node; void __iomem *mmdc_base, *reg; + struct clk *mmdc_ipg_clk; u32 val; + int err; + + /* the ipg clock is optional */ + mmdc_ipg_clk = devm_clk_get(&pdev->dev, NULL); + if (IS_ERR(mmdc_ipg_clk)) + mmdc_ipg_clk = NULL; + + err = clk_prepare_enable(mmdc_ipg_clk); + if (err) { + dev_err(&pdev->dev, "Unable to enable mmdc ipg clock.\n"); + return err; + } mmdc_base = of_iomap(np, 0); WARN_ON(!mmdc_base); diff --git a/arch/arm/mach-imx/mxc.h b/arch/arm/mach-imx/mxc.h index 026e2ca45f1e..b130a53ff62a 100644 --- a/arch/arm/mach-imx/mxc.h +++ b/arch/arm/mach-imx/mxc.h @@ -40,6 +40,8 @@ #define MXC_CPU_IMX6Q 0x63 #define MXC_CPU_IMX6UL 0x64 #define MXC_CPU_IMX6ULL 0x65 +/* virtual cpu id for i.mx6ulz */ +#define MXC_CPU_IMX6ULZ 0x6b #define MXC_CPU_IMX6SLL 0x67 #define MXC_CPU_IMX7D 0x72 @@ -80,6 +82,11 @@ static inline bool cpu_is_imx6ull(void) return __mxc_cpu_type == MXC_CPU_IMX6ULL; } +static inline bool cpu_is_imx6ulz(void) +{ + return __mxc_cpu_type == MXC_CPU_IMX6ULZ; +} + static inline bool cpu_is_imx6sll(void) { return __mxc_cpu_type == MXC_CPU_IMX6SLL; diff --git a/arch/arm/mach-imx/pm-imx6.c b/arch/arm/mach-imx/pm-imx6.c index b08e407d8d96..87f45b926c78 100644 --- a/arch/arm/mach-imx/pm-imx6.c +++ b/arch/arm/mach-imx/pm-imx6.c @@ -313,7 +313,7 @@ int imx6_set_lpm(enum mxc_cpu_pwr_mode mode) if (cpu_is_imx6sl()) val |= BM_CLPCR_BYPASS_PMIC_READY; if (cpu_is_imx6sl() || cpu_is_imx6sx() || cpu_is_imx6ul() || - cpu_is_imx6ull() || cpu_is_imx6sll()) + cpu_is_imx6ull() || cpu_is_imx6sll() || cpu_is_imx6ulz()) val |= BM_CLPCR_BYP_MMDC_CH0_LPM_HS; else val |= BM_CLPCR_BYP_MMDC_CH1_LPM_HS; @@ -331,7 +331,7 @@ int imx6_set_lpm(enum mxc_cpu_pwr_mode mode) if (cpu_is_imx6sl() || cpu_is_imx6sx()) val |= BM_CLPCR_BYPASS_PMIC_READY; if (cpu_is_imx6sl() || cpu_is_imx6sx() || cpu_is_imx6ul() || - cpu_is_imx6ull() || cpu_is_imx6sll()) + cpu_is_imx6ull() || cpu_is_imx6sll() || cpu_is_imx6ulz()) val |= BM_CLPCR_BYP_MMDC_CH0_LPM_HS; else val |= BM_CLPCR_BYP_MMDC_CH1_LPM_HS; @@ -618,6 +618,28 @@ static void __init imx6_pm_common_init(const struct imx6_pm_socdata IMX6Q_GPR1_GINT); } +static void imx6_pm_stby_poweroff(void) +{ + imx6_set_lpm(STOP_POWER_OFF); + imx6q_suspend_finish(0); + + mdelay(1000); + + pr_emerg("Unable to poweroff system\n"); +} + +static int imx6_pm_stby_poweroff_probe(void) +{ + if (pm_power_off) { + pr_warn("%s: pm_power_off already claimed %p %pf!\n", + __func__, pm_power_off, pm_power_off); + return -EBUSY; + } + + pm_power_off = imx6_pm_stby_poweroff; + return 0; +} + void __init imx6_pm_ccm_init(const char *ccm_compat) { struct device_node *np; @@ -634,6 +656,9 @@ void __init imx6_pm_ccm_init(const char *ccm_compat) val = readl_relaxed(ccm_base + CLPCR); val &= ~BM_CLPCR_LPM; writel_relaxed(val, ccm_base + CLPCR); + + if (of_property_read_bool(np, "fsl,pmic-stby-poweroff")) + imx6_pm_stby_poweroff_probe(); } void __init imx6q_pm_init(void) diff --git a/arch/arm/mach-mvebu/board-v7.c b/arch/arm/mach-mvebu/board-v7.c index ccca95173e17..0b10acd7d1b9 100644 --- a/arch/arm/mach-mvebu/board-v7.c +++ b/arch/arm/mach-mvebu/board-v7.c @@ -145,6 +145,13 @@ static void __init mvebu_dt_init(void) i2c_quirk(); } +static void __init armada_370_xp_dt_fixup(void) +{ +#ifdef CONFIG_SMP + smp_set_ops(smp_ops(armada_xp_smp_ops)); +#endif +} + static const char * const armada_370_xp_dt_compat[] __initconst = { "marvell,armada-370-xp", NULL, @@ -153,17 +160,12 @@ static const char * const armada_370_xp_dt_compat[] __initconst = { DT_MACHINE_START(ARMADA_370_XP_DT, "Marvell Armada 370/XP (Device Tree)") .l2c_aux_val = 0, .l2c_aux_mask = ~0, -/* - * The following field (.smp) is still needed to ensure backward - * compatibility with old Device Trees that were not specifying the - * cpus enable-method property. - */ - .smp = smp_ops(armada_xp_smp_ops), .init_machine = mvebu_dt_init, .init_irq = mvebu_init_irq, .restart = mvebu_restart, .reserve = mvebu_memblock_reserve, .dt_compat = armada_370_xp_dt_compat, + .dt_fixup = armada_370_xp_dt_fixup, MACHINE_END static const char * const armada_375_dt_compat[] __initconst = { diff --git a/arch/arm/mach-omap1/ams-delta-fiq-handler.S b/arch/arm/mach-omap1/ams-delta-fiq-handler.S index ddc27638ba2a..e3faa0274b56 100644 --- a/arch/arm/mach-omap1/ams-delta-fiq-handler.S +++ b/arch/arm/mach-omap1/ams-delta-fiq-handler.S @@ -15,6 +15,7 @@ #include <linux/linkage.h> #include <linux/platform_data/ams-delta-fiq.h> +#include <linux/platform_data/gpio-omap.h> #include <asm/assembler.h> #include <mach/board-ams-delta.h> @@ -24,17 +25,10 @@ #include "soc.h" /* - * GPIO related definitions, copied from arch/arm/plat-omap/gpio.c. - * Unfortunately, those were not placed in a separate header file. + * OMAP1510 GPIO related symbol copied from arch/arm/mach-omap1/gpio15xx.c. + * Unfortunately, it was not placed in a separate header file. */ #define OMAP1510_GPIO_BASE 0xFFFCE000 -#define OMAP1510_GPIO_DATA_INPUT 0x00 -#define OMAP1510_GPIO_DATA_OUTPUT 0x04 -#define OMAP1510_GPIO_DIR_CONTROL 0x08 -#define OMAP1510_GPIO_INT_CONTROL 0x0c -#define OMAP1510_GPIO_INT_MASK 0x10 -#define OMAP1510_GPIO_INT_STATUS 0x14 -#define OMAP1510_GPIO_PIN_CONTROL 0x18 /* GPIO register bitmasks */ #define KEYBRD_DATA_MASK (0x1 << AMS_DELTA_GPIO_PIN_KEYBRD_DATA) diff --git a/arch/arm/mach-omap1/board-ams-delta.c b/arch/arm/mach-omap1/board-ams-delta.c index f226973f3d8c..af318d958fd2 100644 --- a/arch/arm/mach-omap1/board-ams-delta.c +++ b/arch/arm/mach-omap1/board-ams-delta.c @@ -250,39 +250,6 @@ static struct platform_device latch2_gpio_device = { #define LATCH2_PIN_HOOKFLASH1 14 #define LATCH2_PIN_HOOKFLASH2 15 -static const struct gpio latch_gpios[] __initconst = { - { - .gpio = LATCH1_GPIO_BASE + 6, - .flags = GPIOF_OUT_INIT_LOW, - .label = "dockit1", - }, - { - .gpio = LATCH1_GPIO_BASE + 7, - .flags = GPIOF_OUT_INIT_LOW, - .label = "dockit2", - }, - { - .gpio = AMS_DELTA_GPIO_PIN_SCARD_RSTIN, - .flags = GPIOF_OUT_INIT_LOW, - .label = "scard_rstin", - }, - { - .gpio = AMS_DELTA_GPIO_PIN_SCARD_CMDVCC, - .flags = GPIOF_OUT_INIT_LOW, - .label = "scard_cmdvcc", - }, - { - .gpio = AMS_DELTA_LATCH2_GPIO_BASE + 14, - .flags = GPIOF_OUT_INIT_LOW, - .label = "hookflash1", - }, - { - .gpio = AMS_DELTA_LATCH2_GPIO_BASE + 15, - .flags = GPIOF_OUT_INIT_LOW, - .label = "hookflash2", - }, -}; - static struct regulator_consumer_supply modem_nreset_consumers[] = { REGULATOR_SUPPLY("RESET#", "serial8250.1"), REGULATOR_SUPPLY("POR", "cx20442-codec"), @@ -329,20 +296,6 @@ struct modem_private_data { static struct modem_private_data modem_priv; -void ams_delta_latch_write(int base, int ngpio, u16 mask, u16 value) -{ - int bit = 0; - u16 bitpos = 1 << bit; - - for (; bit < ngpio; bit++, bitpos = bitpos << 1) { - if (!(mask & bitpos)) - continue; - else - gpio_set_value(base + bit, (value & bitpos) != 0); - } -} -EXPORT_SYMBOL(ams_delta_latch_write); - static struct resource ams_delta_nand_resources[] = { [0] = { .start = OMAP1_MPUIO_BASE, @@ -638,6 +591,28 @@ static struct gpiod_hog ams_delta_gpio_hogs[] = { {}, }; +static struct plat_serial8250_port ams_delta_modem_ports[]; + +/* + * Obtain MODEM IRQ GPIO descriptor using its hardware pin + * number and assign related IRQ number to the MODEM port. + * Keep the GPIO descriptor open so nobody steps in. + */ +static void __init modem_assign_irq(struct gpio_chip *chip) +{ + struct gpio_desc *gpiod; + + gpiod = gpiochip_request_own_desc(chip, AMS_DELTA_GPIO_PIN_MODEM_IRQ, + "modem_irq"); + if (IS_ERR(gpiod)) { + pr_err("%s: modem IRQ GPIO request failed (%ld)\n", __func__, + PTR_ERR(gpiod)); + } else { + gpiod_direction_input(gpiod); + ams_delta_modem_ports[0].irq = gpiod_to_irq(gpiod); + } +} + /* * The purpose of this function is to take care of proper initialization of * devices and data structures which depend on GPIO lines provided by OMAP GPIO @@ -657,7 +632,47 @@ static void __init omap_gpio_deps_init(void) return; } + /* + * Start with FIQ initialization as it may have to request + * and release successfully each OMAP GPIO pin in turn. + */ ams_delta_init_fiq(chip, &ams_delta_serio_device); + + modem_assign_irq(chip); +} + +/* + * Initialize latch2 pins with values which are safe for dependent on-board + * devices or useful for their successull initialization even before GPIO + * driver takes control over the latch pins: + * - LATCH2_PIN_LCD_VBLEN = 0 + * - LATCH2_PIN_LCD_NDISP = 0 Keep LCD device powered off before its + * driver takes control over it. + * - LATCH2_PIN_NAND_NCE = 0 + * - LATCH2_PIN_NAND_NWP = 0 Keep NAND device down and write- + * protected before its driver takes + * control over it. + * - LATCH2_PIN_KEYBRD_PWR = 0 Keep keyboard powered off before serio + * driver takes control over it. + * - LATCH2_PIN_KEYBRD_DATAOUT = 0 Keep low to avoid corruption of first + * byte of data received from attached + * keyboard when serio device is probed; + * the pin is also hogged low by the latch2 + * GPIO driver as soon as it is ready. + * - LATCH2_PIN_MODEM_NRESET = 1 Enable voice MODEM device, allowing for + * its successful probe even before a + * regulator it depends on, which in turn + * takes control over the pin, is set up. + * - LATCH2_PIN_MODEM_CODEC = 1 Attach voice MODEM CODEC data port + * to the MODEM so the CODEC is under + * control even if audio driver doesn't + * take it over. + */ +static void __init ams_delta_latch2_init(void) +{ + u16 latch2 = 1 << LATCH2_PIN_MODEM_NRESET | 1 << LATCH2_PIN_MODEM_CODEC; + + __raw_writew(latch2, LATCH2_VIRT); } static void __init ams_delta_init(void) @@ -681,6 +696,7 @@ static void __init ams_delta_init(void) omap_cfg_reg(J18_1610_CAM_D7); omap_gpio_deps_init(); + ams_delta_latch2_init(); gpiod_add_hogs(ams_delta_gpio_hogs); omap_serial_init(); @@ -821,7 +837,6 @@ static void __init ams_delta_led_init(struct gpio_chip *chip) static int __init ams_delta_gpio_init(void) { struct gpio_chip *chip; - int err; if (!machine_is_ams_delta()) return -ENODEV; @@ -832,11 +847,7 @@ static int __init ams_delta_gpio_init(void) else ams_delta_led_init(chip); - err = gpio_request_array(latch_gpios, ARRAY_SIZE(latch_gpios)); - if (err) - pr_err("Couldn't take over latch1/latch2 GPIO pins\n"); - - return err; + return 0; } device_initcall_sync(ams_delta_gpio_init); @@ -852,33 +863,44 @@ static int __init modem_nreset_init(void) } +/* + * This function expects MODEM IRQ number already assigned to the port + * and fails if it's not. + * The MODEM device requires its RESET# pin kept high during probe. + * That requirement can be fulfilled in several ways: + * - with a descriptor of already functional modem_nreset regulator + * assigned to the MODEM private data, + * - with the regulator not yet controlled by modem_pm function but + * already enabled by default on probe, + * - before the modem_nreset regulator is probed, with the pin already + * set high explicitly. + * The last one is already guaranteed by ams_delta_latch2_init() called + * from machine_init. + * In order to avoid taking over ttyS0 device slot, the MODEM device + * should be registered after OMAP serial ports. Since those ports + * are registered at arch_initcall, this function can be called safely + * at arch_initcall_sync earliest. + */ static int __init ams_delta_modem_init(void) { int err; - omap_cfg_reg(M14_1510_GPIO2); - ams_delta_modem_ports[0].irq = - gpio_to_irq(AMS_DELTA_GPIO_PIN_MODEM_IRQ); + if (!machine_is_ams_delta()) + return -ENODEV; - err = gpio_request(AMS_DELTA_GPIO_PIN_MODEM_IRQ, "modem"); - if (err) { - pr_err("Couldn't request gpio pin for modem\n"); - return err; - } - gpio_direction_input(AMS_DELTA_GPIO_PIN_MODEM_IRQ); + if (ams_delta_modem_ports[0].irq < 0) + return ams_delta_modem_ports[0].irq; + + omap_cfg_reg(M14_1510_GPIO2); /* Initialize the modem_nreset regulator consumer before use */ modem_priv.regulator = ERR_PTR(-ENODEV); - ams_delta_latch2_write(AMS_DELTA_LATCH2_MODEM_CODEC, - AMS_DELTA_LATCH2_MODEM_CODEC); - err = platform_device_register(&ams_delta_modem_device); - if (err) - gpio_free(AMS_DELTA_GPIO_PIN_MODEM_IRQ); return err; } +arch_initcall_sync(ams_delta_modem_init); static int __init late_init(void) { @@ -888,10 +910,6 @@ static int __init late_init(void) if (err) return err; - err = ams_delta_modem_init(); - if (err) - return err; - /* * Once the modem device is registered, the modem_nreset * regulator can be requested on behalf of that device. @@ -906,7 +924,6 @@ static int __init late_init(void) unregister: platform_device_unregister(&ams_delta_modem_device); - gpio_free(AMS_DELTA_GPIO_PIN_MODEM_IRQ); return err; } diff --git a/arch/arm/mach-omap1/include/mach/board-ams-delta.h b/arch/arm/mach-omap1/include/mach/board-ams-delta.h index ad6f865d1f16..3b2d8019238a 100644 --- a/arch/arm/mach-omap1/include/mach/board-ams-delta.h +++ b/arch/arm/mach-omap1/include/mach/board-ams-delta.h @@ -59,13 +59,6 @@ #define AMS_DELTA_LATCH2_GPIO_BASE AMS_DELTA_GPIO_PIN_LCD_VBLEN #define AMS_DELTA_LATCH2_NGPIO 16 -#ifndef __ASSEMBLY__ -void ams_delta_latch_write(int base, int ngpio, u16 mask, u16 value); -#define ams_delta_latch2_write(mask, value) \ - ams_delta_latch_write(AMS_DELTA_LATCH2_GPIO_BASE, \ - AMS_DELTA_LATCH2_NGPIO, (mask), (value)) -#endif - #endif /* CONFIG_MACH_AMS_DELTA */ #endif /* __ASM_ARCH_OMAP_AMS_DELTA_H */ diff --git a/arch/arm/mach-omap2/omap_hwmod.c b/arch/arm/mach-omap2/omap_hwmod.c index cd65ea4e9c54..56a1fe90d394 100644 --- a/arch/arm/mach-omap2/omap_hwmod.c +++ b/arch/arm/mach-omap2/omap_hwmod.c @@ -188,16 +188,16 @@ /** * struct clkctrl_provider - clkctrl provider mapping data - * @addr: base address for the provider - * @size: size of the provider address space - * @offset: offset of the provider from PRCM instance base + * @num_addrs: number of base address ranges for the provider + * @addr: base address(es) for the provider + * @size: size(s) of the provider address space(s) * @node: device node associated with the provider * @link: list link */ struct clkctrl_provider { - u32 addr; - u32 size; - u16 offset; + int num_addrs; + u32 *addr; + u32 *size; struct device_node *node; struct list_head link; }; @@ -724,23 +724,34 @@ static int __init _setup_clkctrl_provider(struct device_node *np) const __be32 *addrp; struct clkctrl_provider *provider; u64 size; + int i; provider = memblock_virt_alloc(sizeof(*provider), 0); if (!provider) return -ENOMEM; - addrp = of_get_address(np, 0, &size, NULL); - provider->addr = (u32)of_translate_address(np, addrp); - addrp = of_get_address(np->parent, 0, NULL, NULL); - provider->offset = provider->addr - - (u32)of_translate_address(np->parent, addrp); - provider->addr &= ~0xff; - provider->size = size | 0xff; provider->node = np; - pr_debug("%s: %s: %x...%x [+%x]\n", __func__, np->parent->name, - provider->addr, provider->addr + provider->size, - provider->offset); + provider->num_addrs = + of_property_count_elems_of_size(np, "reg", sizeof(u32)) / 2; + + provider->addr = + memblock_virt_alloc(sizeof(void *) * provider->num_addrs, 0); + if (!provider->addr) + return -ENOMEM; + + provider->size = + memblock_virt_alloc(sizeof(u32) * provider->num_addrs, 0); + if (!provider->size) + return -ENOMEM; + + for (i = 0; i < provider->num_addrs; i++) { + addrp = of_get_address(np, i, &size, NULL); + provider->addr[i] = (u32)of_translate_address(np, addrp); + provider->size[i] = size; + pr_debug("%s: %pOF: %x...%x\n", __func__, np, provider->addr[i], + provider->addr[i] + provider->size[i]); + } list_add(&provider->link, &clkctrl_providers); @@ -787,23 +798,26 @@ static struct clk *_lookup_clkctrl_clk(struct omap_hwmod *oh) pr_debug("%s: %s: addr=%x\n", __func__, oh->name, addr); list_for_each_entry(provider, &clkctrl_providers, link) { - if (provider->addr <= addr && - provider->addr + provider->size >= addr) { - struct of_phandle_args clkspec; + int i; - clkspec.np = provider->node; - clkspec.args_count = 2; - clkspec.args[0] = addr - provider->addr - - provider->offset; - clkspec.args[1] = 0; + for (i = 0; i < provider->num_addrs; i++) { + if (provider->addr[i] <= addr && + provider->addr[i] + provider->size[i] > addr) { + struct of_phandle_args clkspec; - clk = of_clk_get_from_provider(&clkspec); + clkspec.np = provider->node; + clkspec.args_count = 2; + clkspec.args[0] = addr - provider->addr[0]; + clkspec.args[1] = 0; - pr_debug("%s: %s got %p (offset=%x, provider=%s)\n", - __func__, oh->name, clk, clkspec.args[0], - provider->node->parent->name); + clk = of_clk_get_from_provider(&clkspec); - return clk; + pr_debug("%s: %s got %p (offset=%x, provider=%pOF)\n", + __func__, oh->name, clk, + clkspec.args[0], provider->node); + + return clk; + } } } @@ -2107,8 +2121,8 @@ static int of_dev_find_hwmod(struct device_node *np, if (res) continue; if (!strcmp(p, oh->name)) { - pr_debug("omap_hwmod: dt %s[%i] uses hwmod %s\n", - np->name, i, oh->name); + pr_debug("omap_hwmod: dt %pOFn[%i] uses hwmod %s\n", + np, i, oh->name); return i; } } @@ -2241,8 +2255,8 @@ int omap_hwmod_parse_module_range(struct omap_hwmod *oh, return -ENOENT; if (nr_addr != 1 || nr_size != 1) { - pr_err("%s: invalid range for %s->%s\n", __func__, - oh->name, np->name); + pr_err("%s: invalid range for %s->%pOFn\n", __func__, + oh->name, np); return -EINVAL; } @@ -2250,8 +2264,8 @@ int omap_hwmod_parse_module_range(struct omap_hwmod *oh, base = of_translate_address(np, ranges++); size = be32_to_cpup(ranges); - pr_debug("omap_hwmod: %s %s at 0x%llx size 0x%llx\n", - oh ? oh->name : "", np->name, base, size); + pr_debug("omap_hwmod: %s %pOFn at 0x%llx size 0x%llx\n", + oh->name, np, base, size); if (oh && oh->mpu_rt_idx) { omap_hwmod_fix_mpu_rt_idx(oh, np, res); @@ -2359,8 +2373,8 @@ static int __init _init(struct omap_hwmod *oh, void *data) if (r) pr_debug("omap_hwmod: %s missing dt data\n", oh->name); else if (np && index) - pr_warn("omap_hwmod: %s using broken dt data from %s\n", - oh->name, np->name); + pr_warn("omap_hwmod: %s using broken dt data from %pOFn\n", + oh->name, np); r = _init_mpu_rt_base(oh, NULL, index, np); if (r < 0) { diff --git a/arch/arm/mach-shmobile/Kconfig b/arch/arm/mach-shmobile/Kconfig index 94e9431d92b8..b100c26a858f 100644 --- a/arch/arm/mach-shmobile/Kconfig +++ b/arch/arm/mach-shmobile/Kconfig @@ -1,6 +1,4 @@ -config ARCH_SHMOBILE - bool - +# SPDX-License-Identifier: GPL-2.0 config PM_RMOBILE bool select PM @@ -30,7 +28,6 @@ config ARCH_RMOBILE menuconfig ARCH_RENESAS bool "Renesas ARM SoCs" depends on ARCH_MULTI_V7 && MMU - select ARCH_SHMOBILE select ARM_GIC select GPIOLIB select HAVE_ARM_SCU if SMP @@ -78,6 +75,11 @@ config ARCH_R8A7743 select ARCH_RCAR_GEN2 select ARM_ERRATA_798181 if SMP +config ARCH_R8A7744 + bool "RZ/G1N (R8A77440)" + select ARCH_RCAR_GEN2 + select ARM_ERRATA_798181 if SMP + config ARCH_R8A7745 bool "RZ/G1E (R8A77450)" select ARCH_RCAR_GEN2 diff --git a/arch/arm/mach-shmobile/headsmp-scu.S b/arch/arm/mach-shmobile/headsmp-scu.S index 936d7011c314..d0234296ae62 100644 --- a/arch/arm/mach-shmobile/headsmp-scu.S +++ b/arch/arm/mach-shmobile/headsmp-scu.S @@ -1,17 +1,8 @@ -/* +/* SPDX-License-Identifier: GPL-2.0+ + * * Shared SCU setup for mach-shmobile * * Copyright (C) 2012 Bastian Hecht - * - * 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. - * - * 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/arch/arm/mach-shmobile/headsmp.S b/arch/arm/mach-shmobile/headsmp.S index cef8e8c555f8..9466ae61f56a 100644 --- a/arch/arm/mach-shmobile/headsmp.S +++ b/arch/arm/mach-shmobile/headsmp.S @@ -1,14 +1,11 @@ -/* +/* SPDX-License-Identifier: GPL-2.0 + * * SMP support for R-Mobile / SH-Mobile * * Copyright (C) 2010 Magnus Damm * Copyright (C) 2010 Takashi Yoshii * * Based on vexpress, Copyright (c) 2003 ARM Limited, 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. */ #include <linux/init.h> #include <linux/linkage.h> diff --git a/arch/arm/mach-shmobile/platsmp-scu.c b/arch/arm/mach-shmobile/platsmp-scu.c index f1a1efde4beb..fcfcef1d1ae4 100644 --- a/arch/arm/mach-shmobile/platsmp-scu.c +++ b/arch/arm/mach-shmobile/platsmp-scu.c @@ -1,11 +1,8 @@ +// SPDX-License-Identifier: GPL-2.0 /* * SMP support for SoCs with SCU covered by mach-shmobile * * Copyright (C) 2013 Magnus Damm - * - * 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. */ #include <linux/cpu.h> #include <linux/delay.h> diff --git a/arch/arm/mach-shmobile/platsmp.c b/arch/arm/mach-shmobile/platsmp.c index b23378f3d7e1..7437c01513f6 100644 --- a/arch/arm/mach-shmobile/platsmp.c +++ b/arch/arm/mach-shmobile/platsmp.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * SMP support for R-Mobile / SH-Mobile * @@ -5,10 +6,6 @@ * Copyright (C) 2011 Paul Mundt * * Based on vexpress, Copyright (C) 2002 ARM Ltd, 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. */ #include <linux/init.h> #include <asm/cacheflush.h> diff --git a/arch/arm/mach-shmobile/pm-rcar-gen2.c b/arch/arm/mach-shmobile/pm-rcar-gen2.c index 7efe95bd584f..8c2a20591524 100644 --- a/arch/arm/mach-shmobile/pm-rcar-gen2.c +++ b/arch/arm/mach-shmobile/pm-rcar-gen2.c @@ -1,13 +1,10 @@ +// SPDX-License-Identifier: GPL-2.0 /* * R-Car Generation 2 Power management support * * Copyright (C) 2013 - 2015 Renesas Electronics Corporation * Copyright (C) 2011 Renesas Solutions Corp. * Copyright (C) 2011 Magnus Damm - * - * This file is subject to the terms and conditions of the GNU General Public - * License. See the file "COPYING" in the main directory of this archive - * for more details. */ #include <linux/kernel.h> diff --git a/arch/arm/mach-shmobile/pm-rmobile.c b/arch/arm/mach-shmobile/pm-rmobile.c index 94fdeef11b81..c6a11b5ec6db 100644 --- a/arch/arm/mach-shmobile/pm-rmobile.c +++ b/arch/arm/mach-shmobile/pm-rmobile.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * rmobile power management support * @@ -7,10 +8,6 @@ * * based on pm-sh7372.c * Copyright (C) 2011 Magnus Damm - * - * This file is subject to the terms and conditions of the GNU General Public - * License. See the file "COPYING" in the main directory of this archive - * for more details. */ #include <linux/clk/renesas.h> #include <linux/console.h> @@ -189,7 +186,7 @@ static void __init add_special_pd(struct device_node *np, enum pd_types type) return; } - pr_debug("Special PM domain %s type %d for %pOF\n", pd->name, type, np); + pr_debug("Special PM domain %pOFn type %d for %pOF\n", pd, type, np); special_pds[num_special_pds].pd = pd; special_pds[num_special_pds].type = type; diff --git a/arch/arm/mach-shmobile/pm-rmobile.h b/arch/arm/mach-shmobile/pm-rmobile.h index 8146bb6d7237..69f839259b09 100644 --- a/arch/arm/mach-shmobile/pm-rmobile.h +++ b/arch/arm/mach-shmobile/pm-rmobile.h @@ -1,11 +1,8 @@ -/* +/* SPDX-License-Identifier: GPL-2.0 + * * Copyright (C) 2012 Renesas Solutions Corp. * * Kuninori Morimoto <morimoto.kuninori@renesas.com> - * - * This file is subject to the terms and conditions of the GNU General Public - * License. See the file "COPYING" in the main directory of this archive - * for more details. */ #ifndef PM_RMOBILE_H #define PM_RMOBILE_H diff --git a/arch/arm/mach-shmobile/regulator-quirk-rcar-gen2.c b/arch/arm/mach-shmobile/regulator-quirk-rcar-gen2.c index 21ebc7678ffd..8e50daa99151 100644 --- a/arch/arm/mach-shmobile/regulator-quirk-rcar-gen2.c +++ b/arch/arm/mach-shmobile/regulator-quirk-rcar-gen2.c @@ -23,11 +23,12 @@ #include <linux/i2c.h> #include <linux/init.h> #include <linux/io.h> +#include <linux/list.h> #include <linux/notifier.h> #include <linux/of.h> +#include <linux/of_irq.h> #include <linux/mfd/da9063/registers.h> - #define IRQC_BASE 0xe61c0000 #define IRQC_MONITOR 0x104 /* IRQn Signal Level Monitor Register */ @@ -36,34 +37,45 @@ /* start of DA9210 System Control and Event Registers */ #define DA9210_REG_MASK_A 0x54 +struct regulator_quirk { + struct list_head list; + const struct of_device_id *id; + struct of_phandle_args irq_args; + struct i2c_msg i2c_msg; + bool shared; /* IRQ line is shared */ +}; + +static LIST_HEAD(quirk_list); static void __iomem *irqc; /* first byte sets the memory pointer, following are consecutive reg values */ static u8 da9063_irq_clr[] = { DA9063_REG_IRQ_MASK_A, 0xff, 0xff, 0xff, 0xff }; static u8 da9210_irq_clr[] = { DA9210_REG_MASK_A, 0xff, 0xff }; -static struct i2c_msg da9xxx_msgs[3] = { - { - .addr = 0x58, - .len = ARRAY_SIZE(da9063_irq_clr), - .buf = da9063_irq_clr, - }, { - .addr = 0x68, - .len = ARRAY_SIZE(da9210_irq_clr), - .buf = da9210_irq_clr, - }, { - .addr = 0x70, - .len = ARRAY_SIZE(da9210_irq_clr), - .buf = da9210_irq_clr, - }, +static struct i2c_msg da9063_msg = { + .len = ARRAY_SIZE(da9063_irq_clr), + .buf = da9063_irq_clr, +}; + +static struct i2c_msg da9210_msg = { + .len = ARRAY_SIZE(da9210_irq_clr), + .buf = da9210_irq_clr, +}; + +static const struct of_device_id rcar_gen2_quirk_match[] = { + { .compatible = "dlg,da9063", .data = &da9063_msg }, + { .compatible = "dlg,da9210", .data = &da9210_msg }, + {}, }; static int regulator_quirk_notify(struct notifier_block *nb, unsigned long action, void *data) { + struct regulator_quirk *pos, *tmp; struct device *dev = data; struct i2c_client *client; static bool done; + int ret; u32 mon; if (done) @@ -80,17 +92,20 @@ static int regulator_quirk_notify(struct notifier_block *nb, client = to_i2c_client(dev); dev_dbg(dev, "Detected %s\n", client->name); - if ((client->addr == 0x58 && !strcmp(client->name, "da9063")) || - (client->addr == 0x68 && !strcmp(client->name, "da9210")) || - (client->addr == 0x70 && !strcmp(client->name, "da9210"))) { - int ret, len; + /* + * Send message to all PMICs that share an IRQ line to deassert it. + * + * WARNING: This works only if all the PMICs are on the same I2C bus. + */ + list_for_each_entry(pos, &quirk_list, list) { + if (!pos->shared) + continue; - /* There are two DA9210 on Stout, one on the other boards. */ - len = of_machine_is_compatible("renesas,stout") ? 3 : 2; + dev_info(&client->dev, "clearing %s@0x%02x interrupts\n", + pos->id->compatible, pos->i2c_msg.addr); - dev_info(&client->dev, "clearing da9063/da9210 interrupts\n"); - ret = i2c_transfer(client->adapter, da9xxx_msgs, len); - if (ret != len) + ret = i2c_transfer(client->adapter, &pos->i2c_msg, 1); + if (ret != 1) dev_err(&client->dev, "i2c error %d\n", ret); } @@ -103,6 +118,11 @@ static int regulator_quirk_notify(struct notifier_block *nb, remove: dev_info(dev, "IRQ2 is not asserted, removing quirk\n"); + list_for_each_entry_safe(pos, tmp, &quirk_list, list) { + list_del(&pos->list); + kfree(pos); + } + done = true; iounmap(irqc); return 0; @@ -114,7 +134,12 @@ static struct notifier_block regulator_quirk_nb = { static int __init rcar_gen2_regulator_quirk(void) { - u32 mon; + struct regulator_quirk *quirk, *pos, *tmp; + struct of_phandle_args *argsa, *argsb; + const struct of_device_id *id; + struct device_node *np; + u32 mon, addr; + int ret; if (!of_machine_is_compatible("renesas,koelsch") && !of_machine_is_compatible("renesas,lager") && @@ -122,22 +147,78 @@ static int __init rcar_gen2_regulator_quirk(void) !of_machine_is_compatible("renesas,gose")) return -ENODEV; + for_each_matching_node_and_match(np, rcar_gen2_quirk_match, &id) { + if (!of_device_is_available(np)) + break; + + ret = of_property_read_u32(np, "reg", &addr); + if (ret) /* Skip invalid entry and continue */ + continue; + + quirk = kzalloc(sizeof(*quirk), GFP_KERNEL); + if (!quirk) { + ret = -ENOMEM; + goto err_mem; + } + + argsa = &quirk->irq_args; + memcpy(&quirk->i2c_msg, id->data, sizeof(quirk->i2c_msg)); + + quirk->id = id; + quirk->i2c_msg.addr = addr; + + ret = of_irq_parse_one(np, 0, argsa); + if (ret) { /* Skip invalid entry and continue */ + kfree(quirk); + continue; + } + + list_for_each_entry(pos, &quirk_list, list) { + argsb = &pos->irq_args; + + if (argsa->args_count != argsb->args_count) + continue; + + ret = memcmp(argsa->args, argsb->args, + argsa->args_count * + sizeof(argsa->args[0])); + if (!ret) { + pos->shared = true; + quirk->shared = true; + } + } + + list_add_tail(&quirk->list, &quirk_list); + } + irqc = ioremap(IRQC_BASE, PAGE_SIZE); - if (!irqc) - return -ENOMEM; + if (!irqc) { + ret = -ENOMEM; + goto err_mem; + } mon = ioread32(irqc + IRQC_MONITOR); if (mon & REGULATOR_IRQ_MASK) { pr_debug("%s: IRQ2 is not asserted, not installing quirk\n", __func__); - iounmap(irqc); - return 0; + ret = 0; + goto err_free; } pr_info("IRQ2 is asserted, installing da9063/da9210 regulator quirk\n"); bus_register_notifier(&i2c_bus_type, ®ulator_quirk_nb); return 0; + +err_free: + iounmap(irqc); +err_mem: + list_for_each_entry_safe(pos, tmp, &quirk_list, list) { + list_del(&pos->list); + kfree(pos); + } + + return ret; } arch_initcall(rcar_gen2_regulator_quirk); diff --git a/arch/arm/mach-shmobile/setup-r8a7779.c b/arch/arm/mach-shmobile/setup-r8a7779.c index d589326099e0..b13ec9088ce5 100644 --- a/arch/arm/mach-shmobile/setup-r8a7779.c +++ b/arch/arm/mach-shmobile/setup-r8a7779.c @@ -7,9 +7,7 @@ * Copyright (C) 2013 Cogent Embedded, Inc. */ #include <linux/init.h> -#include <linux/irq.h> #include <linux/irqchip.h> -#include <linux/irqchip/arm-gic.h> #include <asm/mach/arch.h> #include <asm/mach/map.h> diff --git a/arch/arm/mach-shmobile/setup-rcar-gen2.c b/arch/arm/mach-shmobile/setup-rcar-gen2.c index 013acc97795c..eea60b20c6b4 100644 --- a/arch/arm/mach-shmobile/setup-rcar-gen2.c +++ b/arch/arm/mach-shmobile/setup-rcar-gen2.c @@ -25,6 +25,7 @@ static const struct of_device_id cpg_matches[] __initconst = { { .compatible = "renesas,rcar-gen2-cpg-clocks", }, { .compatible = "renesas,r8a7743-cpg-mssr", .data = "extal" }, + { .compatible = "renesas,r8a7744-cpg-mssr", .data = "extal" }, { .compatible = "renesas,r8a7790-cpg-mssr", .data = "extal" }, { .compatible = "renesas,r8a7791-cpg-mssr", .data = "extal" }, { .compatible = "renesas,r8a7793-cpg-mssr", .data = "extal" }, @@ -193,6 +194,7 @@ MACHINE_END static const char * const rz_g1_boards_compat_dt[] __initconst = { "renesas,r8a7743", + "renesas,r8a7744", "renesas,r8a7745", "renesas,r8a77470", NULL, diff --git a/arch/arm/mach-shmobile/smp-sh73a0.c b/arch/arm/mach-shmobile/smp-sh73a0.c index 41137404382e..9bc543faba96 100644 --- a/arch/arm/mach-shmobile/smp-sh73a0.c +++ b/arch/arm/mach-shmobile/smp-sh73a0.c @@ -1,17 +1,9 @@ +// SPDX-License-Identifier: GPL-2.0 /* * SMP support for R-Mobile / SH-Mobile - sh73a0 portion * * Copyright (C) 2010 Magnus Damm * Copyright (C) 2010 Takashi Yoshii - * - * 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; version 2 of the License. - * - * 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> #include <linux/init.h> diff --git a/arch/arm/mach-shmobile/suspend.c b/arch/arm/mach-shmobile/suspend.c index 74b30bade2c1..3969a499746e 100644 --- a/arch/arm/mach-shmobile/suspend.c +++ b/arch/arm/mach-shmobile/suspend.c @@ -1,11 +1,8 @@ +// SPDX-License-Identifier: GPL-2.0 /* * Suspend-to-RAM support code for SH-Mobile ARM * * Copyright (C) 2011 Magnus Damm - * - * This file is subject to the terms and conditions of the GNU General Public - * License. See the file "COPYING" in the main directory of this archive - * for more details. */ #include <linux/pm.h> diff --git a/arch/arm/mach-shmobile/timer.c b/arch/arm/mach-shmobile/timer.c index e48b0939693f..2335311b5f36 100644 --- a/arch/arm/mach-shmobile/timer.c +++ b/arch/arm/mach-shmobile/timer.c @@ -1,17 +1,9 @@ +// SPDX-License-Identifier: GPL-2.0 /* * SH-Mobile Timer * * Copyright (C) 2010 Magnus Damm * Copyright (C) 2002 - 2009 Paul Mundt - * - * 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; version 2 of the License. - * - * 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/platform_device.h> #include <linux/clocksource.h> diff --git a/arch/arm/mach-u300/Kconfig b/arch/arm/mach-u300/Kconfig index 4f43c1cd5db0..c3c8bf54f033 100644 --- a/arch/arm/mach-u300/Kconfig +++ b/arch/arm/mach-u300/Kconfig @@ -29,17 +29,4 @@ config U300_DEBUG help Debug support for U300 in sysfs, procfs etc. -config MACH_U300_SPIDUMMY - depends on ARCH_U300 - bool "SSP/SPI dummy chip" - select SPI - select SPI_MASTER - select SPI_PL022 - help - This creates a small kernel module that creates a dummy - SPI device to be used for loopback tests. Regularly used - to test reference designs. If you're not testing SPI, - you don't need it. Selecting this will activate the - SPI framework and ARM PL022 support. - endif diff --git a/arch/arm/mach-u300/Makefile b/arch/arm/mach-u300/Makefile index 87d37de054b6..5a8804fa8776 100644 --- a/arch/arm/mach-u300/Makefile +++ b/arch/arm/mach-u300/Makefile @@ -4,5 +4,4 @@ obj-y := core.o -obj-$(CONFIG_MACH_U300_SPIDUMMY) += dummyspichip.o obj-$(CONFIG_REGULATOR_AB3100) += regulator.o diff --git a/arch/arm/mach-u300/dummyspichip.c b/arch/arm/mach-u300/dummyspichip.c deleted file mode 100644 index 68fe986ca42e..000000000000 --- a/arch/arm/mach-u300/dummyspichip.c +++ /dev/null @@ -1,276 +0,0 @@ -/* - * arch/arm/mach-u300/dummyspichip.c - * - * Copyright (C) 2007-2009 ST-Ericsson AB - * License terms: GNU General Public License (GPL) version 2 - * This is a dummy loopback SPI "chip" used for testing SPI. - * Author: Linus Walleij <linus.walleij@stericsson.com> - */ -#include <linux/init.h> -#include <linux/module.h> -#include <linux/kernel.h> -#include <linux/device.h> -#include <linux/err.h> -#include <linux/sysfs.h> -#include <linux/mutex.h> -#include <linux/spi/spi.h> -#include <linux/dma-mapping.h> -#include <linux/slab.h> -/* - * WARNING! Do not include this pl022-specific controller header - * for any generic driver. It is only done in this dummy chip - * because we alter the chip configuration in order to test some - * different settings on the loopback device. Normal chip configs - * shall be STATIC and not altered by the driver! - */ -#include <linux/amba/pl022.h> - -struct dummy { - struct device *dev; - struct mutex lock; -}; - -#define DMA_TEST_SIZE 2048 - -/* When we cat /sys/bus/spi/devices/spi0.0/looptest this will be triggered */ -static ssize_t dummy_looptest(struct device *dev, - struct device_attribute *attr, char *buf) -{ - struct spi_device *spi = to_spi_device(dev); - struct dummy *p_dummy = dev_get_drvdata(&spi->dev); - - /* - * WARNING! Do not dereference the chip-specific data in any normal - * driver for a chip. It is usually STATIC and shall not be read - * or written to. Your chip driver should NOT depend on fields in this - * struct, this is just used here to alter the behaviour of the chip - * in order to perform tests. - */ - int status; - u8 txbuf[14] = {0xDE, 0xAD, 0xBE, 0xEF, 0x2B, 0xAD, - 0xCA, 0xFE, 0xBA, 0xBE, 0xB1, 0x05, - 0xF0, 0x0D}; - u8 rxbuf[14]; - u8 *bigtxbuf_virtual; - u8 *bigrxbuf_virtual; - - if (mutex_lock_interruptible(&p_dummy->lock)) - return -ERESTARTSYS; - - bigtxbuf_virtual = kmalloc(DMA_TEST_SIZE, GFP_KERNEL); - if (bigtxbuf_virtual == NULL) { - status = -ENOMEM; - goto out; - } - bigrxbuf_virtual = kmalloc(DMA_TEST_SIZE, GFP_KERNEL); - - /* Fill TXBUF with some happy pattern */ - memset(bigtxbuf_virtual, 0xAA, DMA_TEST_SIZE); - - /* - * Force chip to 8 bit mode - * WARNING: NEVER DO THIS IN REAL DRIVER CODE, THIS SHOULD BE STATIC! - */ - spi->bits_per_word = 8; - /* You should NOT DO THIS EITHER */ - spi->master->setup(spi); - - /* Now run the tests for 8bit mode */ - pr_info("Simple test 1: write 0xAA byte, read back garbage byte " - "in 8bit mode\n"); - status = spi_w8r8(spi, 0xAA); - if (status < 0) - pr_warn("Simple test 1: FAILURE: spi_write_then_read failed with status %d\n", - status); - else - pr_info("Simple test 1: SUCCESS!\n"); - - pr_info("Simple test 2: write 8 bytes, read back 8 bytes garbage " - "in 8bit mode (full FIFO)\n"); - status = spi_write_then_read(spi, &txbuf[0], 8, &rxbuf[0], 8); - if (status < 0) - pr_warn("Simple test 2: FAILURE: spi_write_then_read() failed with status %d\n", - status); - else - pr_info("Simple test 2: SUCCESS!\n"); - - pr_info("Simple test 3: write 14 bytes, read back 14 bytes garbage " - "in 8bit mode (see if we overflow FIFO)\n"); - status = spi_write_then_read(spi, &txbuf[0], 14, &rxbuf[0], 14); - if (status < 0) - pr_warn("Simple test 3: FAILURE: failed with status %d (probably FIFO overrun)\n", - status); - else - pr_info("Simple test 3: SUCCESS!\n"); - - pr_info("Simple test 4: write 8 bytes with spi_write(), read 8 " - "bytes garbage with spi_read() in 8bit mode\n"); - status = spi_write(spi, &txbuf[0], 8); - if (status < 0) - pr_warn("Simple test 4 step 1: FAILURE: spi_write() failed with status %d\n", - status); - else - pr_info("Simple test 4 step 1: SUCCESS!\n"); - status = spi_read(spi, &rxbuf[0], 8); - if (status < 0) - pr_warn("Simple test 4 step 2: FAILURE: spi_read() failed with status %d\n", - status); - else - pr_info("Simple test 4 step 2: SUCCESS!\n"); - - pr_info("Simple test 5: write 14 bytes with spi_write(), read " - "14 bytes garbage with spi_read() in 8bit mode\n"); - status = spi_write(spi, &txbuf[0], 14); - if (status < 0) - pr_warn("Simple test 5 step 1: FAILURE: spi_write() failed with status %d (probably FIFO overrun)\n", - status); - else - pr_info("Simple test 5 step 1: SUCCESS!\n"); - status = spi_read(spi, &rxbuf[0], 14); - if (status < 0) - pr_warn("Simple test 5 step 2: FAILURE: spi_read() failed with status %d (probably FIFO overrun)\n", - status); - else - pr_info("Simple test 5: SUCCESS!\n"); - - pr_info("Simple test 6: write %d bytes with spi_write(), " - "read %d bytes garbage with spi_read() in 8bit mode\n", - DMA_TEST_SIZE, DMA_TEST_SIZE); - status = spi_write(spi, &bigtxbuf_virtual[0], DMA_TEST_SIZE); - if (status < 0) - pr_warn("Simple test 6 step 1: FAILURE: spi_write() failed with status %d (probably FIFO overrun)\n", - status); - else - pr_info("Simple test 6 step 1: SUCCESS!\n"); - status = spi_read(spi, &bigrxbuf_virtual[0], DMA_TEST_SIZE); - if (status < 0) - pr_warn("Simple test 6 step 2: FAILURE: spi_read() failed with status %d (probably FIFO overrun)\n", - status); - else - pr_info("Simple test 6: SUCCESS!\n"); - - - /* - * Force chip to 16 bit mode - * WARNING: NEVER DO THIS IN REAL DRIVER CODE, THIS SHOULD BE STATIC! - */ - spi->bits_per_word = 16; - /* You should NOT DO THIS EITHER */ - spi->master->setup(spi); - - pr_info("Simple test 7: write 0xAA byte, read back garbage byte " - "in 16bit bus mode\n"); - status = spi_w8r8(spi, 0xAA); - if (status == -EIO) - pr_info("Simple test 7: SUCCESS! (expected failure with " - "status EIO)\n"); - else if (status < 0) - pr_warn("Simple test 7: FAILURE: spi_write_then_read failed with status %d\n", - status); - else - pr_warn("Simple test 7: FAILURE: spi_write_then_read succeeded but it was expected to fail!\n"); - - pr_info("Simple test 8: write 8 bytes, read back 8 bytes garbage " - "in 16bit mode (full FIFO)\n"); - status = spi_write_then_read(spi, &txbuf[0], 8, &rxbuf[0], 8); - if (status < 0) - pr_warn("Simple test 8: FAILURE: spi_write_then_read() failed with status %d\n", - status); - else - pr_info("Simple test 8: SUCCESS!\n"); - - pr_info("Simple test 9: write 14 bytes, read back 14 bytes garbage " - "in 16bit mode (see if we overflow FIFO)\n"); - status = spi_write_then_read(spi, &txbuf[0], 14, &rxbuf[0], 14); - if (status < 0) - pr_warn("Simple test 9: FAILURE: failed with status %d (probably FIFO overrun)\n", - status); - else - pr_info("Simple test 9: SUCCESS!\n"); - - pr_info("Simple test 10: write %d bytes with spi_write(), " - "read %d bytes garbage with spi_read() in 16bit mode\n", - DMA_TEST_SIZE, DMA_TEST_SIZE); - status = spi_write(spi, &bigtxbuf_virtual[0], DMA_TEST_SIZE); - if (status < 0) - pr_warn("Simple test 10 step 1: FAILURE: spi_write() failed with status %d (probably FIFO overrun)\n", - status); - else - pr_info("Simple test 10 step 1: SUCCESS!\n"); - - status = spi_read(spi, &bigrxbuf_virtual[0], DMA_TEST_SIZE); - if (status < 0) - pr_warn("Simple test 10 step 2: FAILURE: spi_read() failed with status %d (probably FIFO overrun)\n", - status); - else - pr_info("Simple test 10: SUCCESS!\n"); - - status = sprintf(buf, "loop test complete\n"); - kfree(bigrxbuf_virtual); - kfree(bigtxbuf_virtual); - out: - mutex_unlock(&p_dummy->lock); - return status; -} - -static DEVICE_ATTR(looptest, S_IRUGO, dummy_looptest, NULL); - -static int pl022_dummy_probe(struct spi_device *spi) -{ - struct dummy *p_dummy; - int status; - - dev_info(&spi->dev, "probing dummy SPI device\n"); - - p_dummy = kzalloc(sizeof *p_dummy, GFP_KERNEL); - if (!p_dummy) - return -ENOMEM; - - dev_set_drvdata(&spi->dev, p_dummy); - mutex_init(&p_dummy->lock); - - /* sysfs hook */ - status = device_create_file(&spi->dev, &dev_attr_looptest); - if (status) { - dev_dbg(&spi->dev, "device_create_file looptest failure.\n"); - goto out_dev_create_looptest_failed; - } - - return 0; - -out_dev_create_looptest_failed: - dev_set_drvdata(&spi->dev, NULL); - kfree(p_dummy); - return status; -} - -static int pl022_dummy_remove(struct spi_device *spi) -{ - struct dummy *p_dummy = dev_get_drvdata(&spi->dev); - - dev_info(&spi->dev, "removing dummy SPI device\n"); - device_remove_file(&spi->dev, &dev_attr_looptest); - dev_set_drvdata(&spi->dev, NULL); - kfree(p_dummy); - - return 0; -} - -static const struct of_device_id pl022_dummy_dt_match[] = { - { .compatible = "arm,pl022-dummy" }, - {}, -}; - -static struct spi_driver pl022_dummy_driver = { - .driver = { - .name = "spi-dummy", - .of_match_table = pl022_dummy_dt_match, - }, - .probe = pl022_dummy_probe, - .remove = pl022_dummy_remove, -}; - -module_spi_driver(pl022_dummy_driver); -MODULE_AUTHOR("Linus Walleij <linus.walleij@stericsson.com>"); -MODULE_DESCRIPTION("PL022 SSP/SPI DUMMY Linux driver"); -MODULE_LICENSE("GPL"); diff --git a/arch/arm/mach-zynq/slcr.c b/arch/arm/mach-zynq/slcr.c index f0292a30e6f6..10ef99ce1d90 100644 --- a/arch/arm/mach-zynq/slcr.c +++ b/arch/arm/mach-zynq/slcr.c @@ -233,7 +233,7 @@ int __init zynq_early_slcr_init(void) register_restart_handler(&zynq_slcr_restart_nb); - pr_info("%s mapped to %p\n", np->name, zynq_slcr_base); + pr_info("%pOFn mapped to %p\n", np, zynq_slcr_base); of_node_put(np); diff --git a/arch/arm/plat-samsung/Kconfig b/arch/arm/plat-samsung/Kconfig index b600e38364eb..377ff9cda667 100644 --- a/arch/arm/plat-samsung/Kconfig +++ b/arch/arm/plat-samsung/Kconfig @@ -256,7 +256,7 @@ config S3C_PM_DEBUG_LED_SMDK config SAMSUNG_PM_CHECK bool "S3C2410 PM Suspend Memory CRC" - depends on PM + depends on PM && (PLAT_S3C24XX || ARCH_S3C64XX || ARCH_S5PV210) select CRC32 help Enable the PM code's memory area checksum over sleep. This option |