diff options
Diffstat (limited to 'arch')
156 files changed, 3710 insertions, 1687 deletions
diff --git a/arch/arc/include/asm/spinlock.h b/arch/arc/include/asm/spinlock.h index f158197ac5b0..b6a8c2dfbe6e 100644 --- a/arch/arc/include/asm/spinlock.h +++ b/arch/arc/include/asm/spinlock.h @@ -45,7 +45,14 @@ static inline int arch_spin_trylock(arch_spinlock_t *lock) static inline void arch_spin_unlock(arch_spinlock_t *lock) { - lock->slock = __ARCH_SPIN_LOCK_UNLOCKED__; + unsigned int tmp = __ARCH_SPIN_LOCK_UNLOCKED__; + + __asm__ __volatile__( + " ex %0, [%1] \n" + : "+r" (tmp) + : "r"(&(lock->slock)) + : "memory"); + smp_mb(); } diff --git a/arch/arc/include/asm/uaccess.h b/arch/arc/include/asm/uaccess.h index 32420824375b..30c9baffa96f 100644 --- a/arch/arc/include/asm/uaccess.h +++ b/arch/arc/include/asm/uaccess.h @@ -43,7 +43,7 @@ * Because it essentially checks if buffer end is within limit and @len is * non-ngeative, which implies that buffer start will be within limit too. * - * The reason for rewriting being, for majorit yof cases, @len is generally + * The reason for rewriting being, for majority of cases, @len is generally * compile time constant, causing first sub-expression to be compile time * subsumed. * @@ -53,7 +53,7 @@ * */ #define __user_ok(addr, sz) (((sz) <= TASK_SIZE) && \ - (((addr)+(sz)) <= get_fs())) + ((addr) <= (get_fs() - (sz)))) #define __access_ok(addr, sz) (unlikely(__kernel_ok) || \ likely(__user_ok((addr), (sz)))) diff --git a/arch/arc/kernel/signal.c b/arch/arc/kernel/signal.c index ee6ef2f60a28..7e95e1a86510 100644 --- a/arch/arc/kernel/signal.c +++ b/arch/arc/kernel/signal.c @@ -101,7 +101,6 @@ SYSCALL_DEFINE0(rt_sigreturn) { struct rt_sigframe __user *sf; unsigned int magic; - int err; struct pt_regs *regs = current_pt_regs(); /* Always make any pending restarted system calls return -EINTR */ @@ -119,15 +118,16 @@ SYSCALL_DEFINE0(rt_sigreturn) if (!access_ok(VERIFY_READ, sf, sizeof(*sf))) goto badframe; - err = restore_usr_regs(regs, sf); - err |= __get_user(magic, &sf->sigret_magic); - if (err) + if (__get_user(magic, &sf->sigret_magic)) goto badframe; if (unlikely(is_do_ss_needed(magic))) if (restore_altstack(&sf->uc.uc_stack)) goto badframe; + if (restore_usr_regs(regs, sf)) + goto badframe; + /* Don't restart from sigreturn */ syscall_wont_restart(regs); @@ -191,6 +191,15 @@ setup_rt_frame(int signo, struct k_sigaction *ka, siginfo_t *info, return 1; /* + * w/o SA_SIGINFO, struct ucontext is partially populated (only + * uc_mcontext/uc_sigmask) for kernel's normal user state preservation + * during signal handler execution. This works for SA_SIGINFO as well + * although the semantics are now overloaded (the same reg state can be + * inspected by userland: but are they allowed to fiddle with it ? + */ + err |= stash_usr_regs(sf, regs, set); + + /* * SA_SIGINFO requires 3 args to signal handler: * #1: sig-no (common to any handler) * #2: struct siginfo @@ -213,14 +222,6 @@ setup_rt_frame(int signo, struct k_sigaction *ka, siginfo_t *info, magic = MAGIC_SIGALTSTK; } - /* - * w/o SA_SIGINFO, struct ucontext is partially populated (only - * uc_mcontext/uc_sigmask) for kernel's normal user state preservation - * during signal handler execution. This works for SA_SIGINFO as well - * although the semantics are now overloaded (the same reg state can be - * inspected by userland: but are they allowed to fiddle with it ? - */ - err |= stash_usr_regs(sf, regs, set); err |= __put_user(magic, &sf->sigret_magic); if (err) return err; diff --git a/arch/arc/kernel/time.c b/arch/arc/kernel/time.c index 0e51e69cf30d..3fde7de3ea67 100644 --- a/arch/arc/kernel/time.c +++ b/arch/arc/kernel/time.c @@ -227,12 +227,9 @@ void __attribute__((weak)) arc_local_timer_setup(unsigned int cpu) { struct clock_event_device *clk = &per_cpu(arc_clockevent_device, cpu); - clockevents_calc_mult_shift(clk, arc_get_core_freq(), 5); - - clk->max_delta_ns = clockevent_delta2ns(ARC_TIMER_MAX, clk); clk->cpumask = cpumask_of(cpu); - - clockevents_register_device(clk); + clockevents_config_and_register(clk, arc_get_core_freq(), + 0, ARC_TIMER_MAX); /* * setup the per-cpu timer IRQ handler - for all cpus diff --git a/arch/arc/kernel/unaligned.c b/arch/arc/kernel/unaligned.c index 28d170060747..7ff5b5c183bb 100644 --- a/arch/arc/kernel/unaligned.c +++ b/arch/arc/kernel/unaligned.c @@ -245,6 +245,12 @@ int misaligned_fixup(unsigned long address, struct pt_regs *regs, regs->status32 &= ~STATUS_DE_MASK; } else { regs->ret += state.instr_len; + + /* handle zero-overhead-loop */ + if ((regs->ret == regs->lp_end) && (regs->lp_count)) { + regs->ret = regs->lp_start; + regs->lp_count--; + } } return 0; diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig index 1ad6fb6c094d..5ef81367a8e8 100644 --- a/arch/arm/Kconfig +++ b/arch/arm/Kconfig @@ -727,6 +727,7 @@ config ARCH_S3C64XX select ARM_VIC select CLKDEV_LOOKUP select CLKSRC_SAMSUNG_PWM + select COMMON_CLK select CPU_V6 select GENERIC_CLOCKEVENTS select GPIO_SAMSUNG @@ -740,7 +741,6 @@ config ARCH_S3C64XX select S3C_DEV_NAND select S3C_GPIO_TRACK select SAMSUNG_ATAGS - select SAMSUNG_CLKSRC select SAMSUNG_GPIOLIB_4BIT select SAMSUNG_WDT_RESET select USB_ARCH_HAS_OHCI diff --git a/arch/arm/boot/dts/Makefile b/arch/arm/boot/dts/Makefile index e95af3f5433b..802720e3e8fd 100644 --- a/arch/arm/boot/dts/Makefile +++ b/arch/arm/boot/dts/Makefile @@ -41,6 +41,8 @@ dtb-$(CONFIG_ARCH_AT91) += sama5d33ek.dtb dtb-$(CONFIG_ARCH_AT91) += sama5d34ek.dtb dtb-$(CONFIG_ARCH_AT91) += sama5d35ek.dtb +dtb-$(CONFIG_ARCH_ATLAS6) += atlas6-evb.dtb + dtb-$(CONFIG_ARCH_BCM2835) += bcm2835-rpi-b.dtb dtb-$(CONFIG_ARCH_BCM) += bcm11351-brt.dtb \ bcm28155-ap.dtb diff --git a/arch/arm/boot/dts/armada-370-netgear-rn102.dts b/arch/arm/boot/dts/armada-370-netgear-rn102.dts index 05e4485a8225..8ac2ac1f69cc 100644 --- a/arch/arm/boot/dts/armada-370-netgear-rn102.dts +++ b/arch/arm/boot/dts/armada-370-netgear-rn102.dts @@ -27,6 +27,25 @@ }; soc { + ranges = <MBUS_ID(0xf0, 0x01) 0 0xd0000000 0x100000 + MBUS_ID(0x01, 0xe0) 0 0xfff00000 0x100000>; + + pcie-controller { + status = "okay"; + + /* Connected to Marvell SATA controller */ + pcie@1,0 { + /* Port 0, Lane 0 */ + status = "okay"; + }; + + /* Connected to FL1009 USB 3.0 controller */ + pcie@2,0 { + /* Port 1, Lane 0 */ + status = "okay"; + }; + }; + internal-regs { serial@12000 { clock-frequency = <200000000>; @@ -57,6 +76,11 @@ marvell,pins = "mpp56"; marvell,function = "gpio"; }; + + poweroff: poweroff { + marvell,pins = "mpp8"; + marvell,function = "gpio"; + }; }; mdio { @@ -89,22 +113,6 @@ pwm_polarity = <0>; }; }; - - pcie-controller { - status = "okay"; - - /* Connected to Marvell SATA controller */ - pcie@1,0 { - /* Port 0, Lane 0 */ - status = "okay"; - }; - - /* Connected to FL1009 USB 3.0 controller */ - pcie@2,0 { - /* Port 1, Lane 0 */ - status = "okay"; - }; - }; }; }; @@ -160,7 +168,7 @@ button@1 { label = "Power Button"; linux,code = <116>; /* KEY_POWER */ - gpios = <&gpio1 30 1>; + gpios = <&gpio1 30 0>; }; button@2 { @@ -176,4 +184,11 @@ }; }; + gpio_poweroff { + compatible = "gpio-poweroff"; + pinctrl-0 = <&poweroff>; + pinctrl-names = "default"; + gpios = <&gpio0 8 1>; + }; + }; diff --git a/arch/arm/boot/dts/armada-xp.dtsi b/arch/arm/boot/dts/armada-xp.dtsi index def125c0eeaa..3058522f5aad 100644 --- a/arch/arm/boot/dts/armada-xp.dtsi +++ b/arch/arm/boot/dts/armada-xp.dtsi @@ -70,6 +70,8 @@ timer@20300 { compatible = "marvell,armada-xp-timer"; + clocks = <&coreclk 2>, <&refclk>; + clock-names = "nbclk", "fixed"; }; coreclk: mvebu-sar@18230 { @@ -169,4 +171,13 @@ }; }; }; + + clocks { + /* 25 MHz reference crystal */ + refclk: oscillator { + compatible = "fixed-clock"; + #clock-cells = <0>; + clock-frequency = <25000000>; + }; + }; }; diff --git a/arch/arm/boot/dts/at91sam9x5.dtsi b/arch/arm/boot/dts/at91sam9x5.dtsi index cf78ac0b04b1..e74dc15efa9d 100644 --- a/arch/arm/boot/dts/at91sam9x5.dtsi +++ b/arch/arm/boot/dts/at91sam9x5.dtsi @@ -190,12 +190,12 @@ AT91_PIOA 8 AT91_PERIPH_A AT91_PINCTRL_NONE>; /* PA8 periph A */ }; - pinctrl_uart2_rts: uart2_rts-0 { + pinctrl_usart2_rts: usart2_rts-0 { atmel,pins = <AT91_PIOB 0 AT91_PERIPH_B AT91_PINCTRL_NONE>; /* PB0 periph B */ }; - pinctrl_uart2_cts: uart2_cts-0 { + pinctrl_usart2_cts: usart2_cts-0 { atmel,pins = <AT91_PIOB 1 AT91_PERIPH_B AT91_PINCTRL_NONE>; /* PB1 periph B */ }; @@ -556,6 +556,7 @@ interrupts = <12 IRQ_TYPE_LEVEL_HIGH 0>; dmas = <&dma0 1 AT91_DMA_CFG_PER_ID(0)>; dma-names = "rxtx"; + pinctrl-names = "default"; #address-cells = <1>; #size-cells = <0>; status = "disabled"; @@ -567,6 +568,7 @@ interrupts = <26 IRQ_TYPE_LEVEL_HIGH 0>; dmas = <&dma1 1 AT91_DMA_CFG_PER_ID(0)>; dma-names = "rxtx"; + pinctrl-names = "default"; #address-cells = <1>; #size-cells = <0>; status = "disabled"; diff --git a/arch/arm/boot/dts/atlas6.dtsi b/arch/arm/boot/dts/atlas6.dtsi index 8678e0c11119..6db4f81d4795 100644 --- a/arch/arm/boot/dts/atlas6.dtsi +++ b/arch/arm/boot/dts/atlas6.dtsi @@ -181,6 +181,8 @@ interrupts = <17>; fifosize = <128>; clocks = <&clks 13>; + sirf,uart-dma-rx-channel = <21>; + sirf,uart-dma-tx-channel = <2>; }; uart1: uart@b0060000 { @@ -199,6 +201,8 @@ interrupts = <19>; fifosize = <128>; clocks = <&clks 15>; + sirf,uart-dma-rx-channel = <6>; + sirf,uart-dma-tx-channel = <7>; }; usp0: usp@b0080000 { @@ -206,7 +210,10 @@ compatible = "sirf,prima2-usp"; reg = <0xb0080000 0x10000>; interrupts = <20>; + fifosize = <128>; clocks = <&clks 28>; + sirf,usp-dma-rx-channel = <17>; + sirf,usp-dma-tx-channel = <18>; }; usp1: usp@b0090000 { @@ -214,7 +221,10 @@ compatible = "sirf,prima2-usp"; reg = <0xb0090000 0x10000>; interrupts = <21>; + fifosize = <128>; clocks = <&clks 29>; + sirf,usp-dma-rx-channel = <14>; + sirf,usp-dma-tx-channel = <15>; }; dmac0: dma-controller@b00b0000 { @@ -237,6 +247,8 @@ compatible = "sirf,prima2-vip"; reg = <0xb00C0000 0x10000>; clocks = <&clks 31>; + interrupts = <14>; + sirf,vip-dma-rx-channel = <16>; }; spi0: spi@b00d0000 { diff --git a/arch/arm/boot/dts/keystone-clocks.dtsi b/arch/arm/boot/dts/keystone-clocks.dtsi new file mode 100644 index 000000000000..d6713b113258 --- /dev/null +++ b/arch/arm/boot/dts/keystone-clocks.dtsi @@ -0,0 +1,821 @@ +/* + * Device Tree Source for Keystone 2 clock tree + * + * Copyright (C) 2013 Texas Instruments, 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 as + * published by the Free Software Foundation. + */ + +clocks { + #address-cells = <1>; + #size-cells = <1>; + ranges; + + refclkmain: refclkmain { + #clock-cells = <0>; + compatible = "fixed-clock"; + clock-frequency = <122880000>; + clock-output-names = "refclk-main"; + }; + + mainpllclk: mainpllclk@2310110 { + #clock-cells = <0>; + compatible = "ti,keystone,main-pll-clock"; + clocks = <&refclkmain>; + reg = <0x02620350 4>, <0x02310110 4>; + reg-names = "control", "multiplier"; + fixed-postdiv = <2>; + }; + + papllclk: papllclk@2620358 { + #clock-cells = <0>; + compatible = "ti,keystone,pll-clock"; + clocks = <&refclkmain>; + clock-output-names = "pa-pll-clk"; + reg = <0x02620358 4>; + reg-names = "control"; + fixed-postdiv = <6>; + }; + + ddr3allclk: ddr3apllclk@2620360 { + #clock-cells = <0>; + compatible = "ti,keystone,pll-clock"; + clocks = <&refclkmain>; + clock-output-names = "ddr-3a-pll-clk"; + reg = <0x02620360 4>; + reg-names = "control"; + fixed-postdiv = <6>; + }; + + ddr3bllclk: ddr3bpllclk@2620368 { + #clock-cells = <0>; + compatible = "ti,keystone,pll-clock"; + clocks = <&refclkmain>; + clock-output-names = "ddr-3b-pll-clk"; + reg = <0x02620368 4>; + reg-names = "control"; + fixed-postdiv = <6>; + }; + + armpllclk: armpllclk@2620370 { + #clock-cells = <0>; + compatible = "ti,keystone,pll-clock"; + clocks = <&refclkmain>; + clock-output-names = "arm-pll-clk"; + reg = <0x02620370 4>; + reg-names = "control"; + fixed-postdiv = <6>; + }; + + mainmuxclk: mainmuxclk@2310108 { + #clock-cells = <0>; + compatible = "ti,keystone,pll-mux-clock"; + clocks = <&mainpllclk>, <&refclkmain>; + reg = <0x02310108 4>; + bit-shift = <23>; + bit-mask = <1>; + clock-output-names = "mainmuxclk"; + }; + + chipclk1: chipclk1 { + #clock-cells = <0>; + compatible = "fixed-factor-clock"; + clocks = <&mainmuxclk>; + clock-div = <1>; + clock-mult = <1>; + clock-output-names = "chipclk1"; + }; + + chipclk1rstiso: chipclk1rstiso { + #clock-cells = <0>; + compatible = "fixed-factor-clock"; + clocks = <&mainmuxclk>; + clock-div = <1>; + clock-mult = <1>; + clock-output-names = "chipclk1rstiso"; + }; + + gemtraceclk: gemtraceclk@2310120 { + #clock-cells = <0>; + compatible = "ti,keystone,pll-divider-clock"; + clocks = <&mainmuxclk>; + reg = <0x02310120 4>; + bit-shift = <0>; + bit-mask = <8>; + clock-output-names = "gemtraceclk"; + }; + + chipstmxptclk: chipstmxptclk { + #clock-cells = <0>; + compatible = "ti,keystone,pll-divider-clock"; + clocks = <&mainmuxclk>; + reg = <0x02310164 4>; + bit-shift = <0>; + bit-mask = <8>; + clock-output-names = "chipstmxptclk"; + }; + + chipclk12: chipclk12 { + #clock-cells = <0>; + compatible = "fixed-factor-clock"; + clocks = <&chipclk1>; + clock-div = <2>; + clock-mult = <1>; + clock-output-names = "chipclk12"; + }; + + chipclk13: chipclk13 { + #clock-cells = <0>; + compatible = "fixed-factor-clock"; + clocks = <&chipclk1>; + clock-div = <3>; + clock-mult = <1>; + clock-output-names = "chipclk13"; + }; + + chipclk14: chipclk14 { + #clock-cells = <0>; + compatible = "fixed-factor-clock"; + clocks = <&chipclk1>; + clock-div = <4>; + clock-mult = <1>; + clock-output-names = "chipclk14"; + }; + + chipclk16: chipclk16 { + #clock-cells = <0>; + compatible = "fixed-factor-clock"; + clocks = <&chipclk1>; + clock-div = <6>; + clock-mult = <1>; + clock-output-names = "chipclk16"; + }; + + chipclk112: chipclk112 { + #clock-cells = <0>; + compatible = "fixed-factor-clock"; + clocks = <&chipclk1>; + clock-div = <12>; + clock-mult = <1>; + clock-output-names = "chipclk112"; + }; + + chipclk124: chipclk124 { + #clock-cells = <0>; + compatible = "fixed-factor-clock"; + clocks = <&chipclk1>; + clock-div = <24>; + clock-mult = <1>; + clock-output-names = "chipclk114"; + }; + + chipclk1rstiso13: chipclk1rstiso13 { + #clock-cells = <0>; + compatible = "fixed-factor-clock"; + clocks = <&chipclk1rstiso>; + clock-div = <3>; + clock-mult = <1>; + clock-output-names = "chipclk1rstiso13"; + }; + + chipclk1rstiso14: chipclk1rstiso14 { + #clock-cells = <0>; + compatible = "fixed-factor-clock"; + clocks = <&chipclk1rstiso>; + clock-div = <4>; + clock-mult = <1>; + clock-output-names = "chipclk1rstiso14"; + }; + + chipclk1rstiso16: chipclk1rstiso16 { + #clock-cells = <0>; + compatible = "fixed-factor-clock"; + clocks = <&chipclk1rstiso>; + clock-div = <6>; + clock-mult = <1>; + clock-output-names = "chipclk1rstiso16"; + }; + + chipclk1rstiso112: chipclk1rstiso112 { + #clock-cells = <0>; + compatible = "fixed-factor-clock"; + clocks = <&chipclk1rstiso>; + clock-div = <12>; + clock-mult = <1>; + clock-output-names = "chipclk1rstiso112"; + }; + + clkmodrst0: clkmodrst0 { + #clock-cells = <0>; + compatible = "ti,keystone,psc-clock"; + clocks = <&chipclk16>; + clock-output-names = "modrst0"; + reg = <0x02350000 0xb00>, <0x02350000 0x400>; + reg-names = "control", "domain"; + domain-id = <0>; + }; + + + clkusb: clkusb { + #clock-cells = <0>; + compatible = "ti,keystone,psc-clock"; + clocks = <&chipclk16>; + clock-output-names = "usb"; + reg = <0x02350008 0xb00>, <0x02350000 0x400>; + reg-names = "control", "domain"; + domain-id = <0>; + }; + + clkaemifspi: clkaemifspi { + #clock-cells = <0>; + compatible = "ti,keystone,psc-clock"; + clocks = <&chipclk16>; + clock-output-names = "aemif-spi"; + reg = <0x0235000c 0xb00>, <0x02350000 0x400>; + reg-names = "control", "domain"; + domain-id = <0>; + }; + + + clkdebugsstrc: clkdebugsstrc { + #clock-cells = <0>; + compatible = "ti,keystone,psc-clock"; + clocks = <&chipclk13>; + clock-output-names = "debugss-trc"; + reg = <0x02350014 0xb00>, <0x02350000 0x400>; + reg-names = "control", "domain"; + domain-id = <0>; + }; + + clktetbtrc: clktetbtrc { + #clock-cells = <0>; + compatible = "ti,keystone,psc-clock"; + clocks = <&chipclk13>; + clock-output-names = "tetb-trc"; + reg = <0x02350018 0xb00>, <0x02350004 0x400>; + reg-names = "control", "domain"; + domain-id = <1>; + }; + + clkpa: clkpa { + #clock-cells = <0>; + compatible = "ti,keystone,psc-clock"; + clocks = <&chipclk16>; + clock-output-names = "pa"; + reg = <0x0235001c 0xb00>, <0x02350008 0x400>; + reg-names = "control", "domain"; + domain-id = <2>; + }; + + clkcpgmac: clkcpgmac { + #clock-cells = <0>; + compatible = "ti,keystone,psc-clock"; + clocks = <&clkpa>; + clock-output-names = "cpgmac"; + reg = <0x02350020 0xb00>, <0x02350008 0x400>; + reg-names = "control", "domain"; + domain-id = <2>; + }; + + clksa: clksa { + #clock-cells = <0>; + compatible = "ti,keystone,psc-clock"; + clocks = <&clkpa>; + clock-output-names = "sa"; + reg = <0x02350024 0xb00>, <0x02350008 0x400>; + reg-names = "control", "domain"; + domain-id = <2>; + }; + + clkpcie: clkpcie { + #clock-cells = <0>; + compatible = "ti,keystone,psc-clock"; + clocks = <&chipclk12>; + clock-output-names = "pcie"; + reg = <0x02350028 0xb00>, <0x0235000c 0x400>; + reg-names = "control", "domain"; + domain-id = <3>; + }; + + clksrio: clksrio { + #clock-cells = <0>; + compatible = "ti,keystone,psc-clock"; + clocks = <&chipclk1rstiso13>; + clock-output-names = "srio"; + reg = <0x0235002c 0xb00>, <0x02350010 0x400>; + reg-names = "control", "domain"; + domain-id = <4>; + }; + + clkhyperlink0: clkhyperlink0 { + #clock-cells = <0>; + compatible = "ti,keystone,psc-clock"; + clocks = <&chipclk12>; + clock-output-names = "hyperlink-0"; + reg = <0x02350030 0xb00>, <0x02350014 0x400>; + reg-names = "control", "domain"; + domain-id = <5>; + }; + + clksr: clksr { + #clock-cells = <0>; + compatible = "ti,keystone,psc-clock"; + clocks = <&chipclk1rstiso112>; + clock-output-names = "sr"; + reg = <0x02350034 0xb00>, <0x02350018 0x400>; + reg-names = "control", "domain"; + domain-id = <6>; + }; + + clkmsmcsram: clkmsmcsram { + #clock-cells = <0>; + compatible = "ti,keystone,psc-clock"; + clocks = <&chipclk1>; + clock-output-names = "msmcsram"; + reg = <0x02350038 0xb00>, <0x0235001c 0x400>; + reg-names = "control", "domain"; + domain-id = <7>; + }; + + clkgem0: clkgem0 { + #clock-cells = <0>; + compatible = "ti,keystone,psc-clock"; + clocks = <&chipclk1>; + clock-output-names = "gem0"; + reg = <0x0235003c 0xb00>, <0x02350020 0x400>; + reg-names = "control", "domain"; + domain-id = <8>; + }; + + clkgem1: clkgem1 { + #clock-cells = <0>; + compatible = "ti,keystone,psc-clock"; + clocks = <&chipclk1>; + clock-output-names = "gem1"; + reg = <0x02350040 0xb00>, <0x02350024 0x400>; + reg-names = "control", "domain"; + domain-id = <9>; + }; + + clkgem2: clkgem2 { + #clock-cells = <0>; + compatible = "ti,keystone,psc-clock"; + clocks = <&chipclk1>; + clock-output-names = "gem2"; + reg = <0x02350044 0xb00>, <0x02350028 0x400>; + reg-names = "control", "domain"; + domain-id = <10>; + }; + + clkgem3: clkgem3 { + #clock-cells = <0>; + compatible = "ti,keystone,psc-clock"; + clocks = <&chipclk1>; + clock-output-names = "gem3"; + reg = <0x02350048 0xb00>, <0x0235002c 0x400>; + reg-names = "control", "domain"; + domain-id = <11>; + }; + + clkgem4: clkgem4 { + #clock-cells = <0>; + compatible = "ti,keystone,psc-clock"; + clocks = <&chipclk1>; + clock-output-names = "gem4"; + reg = <0x0235004c 0xb00>, <0x02350030 0x400>; + reg-names = "control", "domain"; + domain-id = <12>; + }; + + clkgem5: clkgem5 { + #clock-cells = <0>; + compatible = "ti,keystone,psc-clock"; + clocks = <&chipclk1>; + clock-output-names = "gem5"; + reg = <0x02350050 0xb00>, <0x02350034 0x400>; + reg-names = "control", "domain"; + domain-id = <13>; + }; + + clkgem6: clkgem6 { + #clock-cells = <0>; + compatible = "ti,keystone,psc-clock"; + clocks = <&chipclk1>; + clock-output-names = "gem6"; + reg = <0x02350054 0xb00>, <0x02350038 0x400>; + reg-names = "control", "domain"; + domain-id = <14>; + }; + + clkgem7: clkgem7 { + #clock-cells = <0>; + compatible = "ti,keystone,psc-clock"; + clocks = <&chipclk1>; + clock-output-names = "gem7"; + reg = <0x02350058 0xb00>, <0x0235003c 0x400>; + reg-names = "control", "domain"; + domain-id = <15>; + }; + + clkddr30: clkddr30 { + #clock-cells = <0>; + compatible = "ti,keystone,psc-clock"; + clocks = <&chipclk12>; + clock-output-names = "ddr3-0"; + reg = <0x0235005c 0xb00>, <0x02350040 0x400>; + reg-names = "control", "domain"; + domain-id = <16>; + }; + + clkddr31: clkddr31 { + #clock-cells = <0>; + compatible = "ti,keystone,psc-clock"; + clocks = <&chipclk13>; + clock-output-names = "ddr3-1"; + reg = <0x02350060 0xb00>, <0x02350040 0x400>; + reg-names = "control", "domain"; + domain-id = <16>; + }; + + clktac: clktac { + #clock-cells = <0>; + compatible = "ti,keystone,psc-clock"; + clocks = <&chipclk13>; + clock-output-names = "tac"; + reg = <0x02350064 0xb00>, <0x02350044 0x400>; + reg-names = "control", "domain"; + domain-id = <17>; + }; + + clkrac01: clktac01 { + #clock-cells = <0>; + compatible = "ti,keystone,psc-clock"; + clocks = <&chipclk13>; + clock-output-names = "rac-01"; + reg = <0x02350068 0xb00>, <0x02350044 0x400>; + reg-names = "control", "domain"; + domain-id = <17>; + }; + + clkrac23: clktac23 { + #clock-cells = <0>; + compatible = "ti,keystone,psc-clock"; + clocks = <&chipclk13>; + clock-output-names = "rac-23"; + reg = <0x0235006c 0xb00>, <0x02350048 0x400>; + reg-names = "control", "domain"; + domain-id = <18>; + }; + + clkfftc0: clkfftc0 { + #clock-cells = <0>; + compatible = "ti,keystone,psc-clock"; + clocks = <&chipclk13>; + clock-output-names = "fftc-0"; + reg = <0x02350070 0xb00>, <0x0235004c 0x400>; + reg-names = "control", "domain"; + domain-id = <19>; + }; + + clkfftc1: clkfftc1 { + #clock-cells = <0>; + compatible = "ti,keystone,psc-clock"; + clocks = <&chipclk13>; + clock-output-names = "fftc-1"; + reg = <0x02350074 0xb00>, <0x023504c0 0x400>; + reg-names = "control", "domain"; + domain-id = <19>; + }; + + clkfftc2: clkfftc2 { + #clock-cells = <0>; + compatible = "ti,keystone,psc-clock"; + clocks = <&chipclk13>; + clock-output-names = "fftc-2"; + reg = <0x02350078 0xb00>, <0x02350050 0x400>; + reg-names = "control", "domain"; + domain-id = <20>; + }; + + clkfftc3: clkfftc3 { + #clock-cells = <0>; + compatible = "ti,keystone,psc-clock"; + clocks = <&chipclk13>; + clock-output-names = "fftc-3"; + reg = <0x0235007c 0xb00>, <0x02350050 0x400>; + reg-names = "control", "domain"; + domain-id = <20>; + }; + + clkfftc4: clkfftc4 { + #clock-cells = <0>; + compatible = "ti,keystone,psc-clock"; + clocks = <&chipclk13>; + clock-output-names = "fftc-4"; + reg = <0x02350080 0xb00>, <0x02350050 0x400>; + reg-names = "control", "domain"; + domain-id = <20>; + }; + + clkfftc5: clkfftc5 { + #clock-cells = <0>; + compatible = "ti,keystone,psc-clock"; + clocks = <&chipclk13>; + clock-output-names = "fftc-5"; + reg = <0x02350084 0xb00>, <0x02350050 0x400>; + reg-names = "control", "domain"; + domain-id = <20>; + }; + + clkaif: clkaif { + #clock-cells = <0>; + compatible = "ti,keystone,psc-clock"; + clocks = <&chipclk13>; + clock-output-names = "aif"; + reg = <0x02350088 0xb00>, <0x02350054 0x400>; + reg-names = "control", "domain"; + domain-id = <21>; + }; + + clktcp3d0: clktcp3d0 { + #clock-cells = <0>; + compatible = "ti,keystone,psc-clock"; + clocks = <&chipclk13>; + clock-output-names = "tcp3d-0"; + reg = <0x0235008c 0xb00>, <0x02350058 0x400>; + reg-names = "control", "domain"; + domain-id = <22>; + }; + + clktcp3d1: clktcp3d1 { + #clock-cells = <0>; + compatible = "ti,keystone,psc-clock"; + clocks = <&chipclk13>; + clock-output-names = "tcp3d-1"; + reg = <0x02350090 0xb00>, <0x02350058 0x400>; + reg-names = "control", "domain"; + domain-id = <22>; + }; + + clktcp3d2: clktcp3d2 { + #clock-cells = <0>; + compatible = "ti,keystone,psc-clock"; + clocks = <&chipclk13>; + clock-output-names = "tcp3d-2"; + reg = <0x02350094 0xb00>, <0x0235005c 0x400>; + reg-names = "control", "domain"; + domain-id = <23>; + }; + + clktcp3d3: clktcp3d3 { + #clock-cells = <0>; + compatible = "ti,keystone,psc-clock"; + clocks = <&chipclk13>; + clock-output-names = "tcp3d-3"; + reg = <0x02350098 0xb00>, <0x0235005c 0x400>; + reg-names = "control", "domain"; + domain-id = <23>; + }; + + clkvcp0: clkvcp0 { + #clock-cells = <0>; + compatible = "ti,keystone,psc-clock"; + clocks = <&chipclk13>; + clock-output-names = "vcp-0"; + reg = <0x0235009c 0xb00>, <0x02350060 0x400>; + reg-names = "control", "domain"; + domain-id = <24>; + }; + + clkvcp1: clkvcp1 { + #clock-cells = <0>; + compatible = "ti,keystone,psc-clock"; + clocks = <&chipclk13>; + clock-output-names = "vcp-1"; + reg = <0x023500a0 0xb00>, <0x02350060 0x400>; + reg-names = "control", "domain"; + domain-id = <24>; + }; + + clkvcp2: clkvcp2 { + #clock-cells = <0>; + compatible = "ti,keystone,psc-clock"; + clocks = <&chipclk13>; + clock-output-names = "vcp-2"; + reg = <0x023500a4 0xb00>, <0x02350060 0x400>; + reg-names = "control", "domain"; + domain-id = <24>; + }; + + clkvcp3: clkvcp3 { + #clock-cells = <0>; + compatible = "ti,keystone,psc-clock"; + clocks = <&chipclk13>; + clock-output-names = "vcp-3"; + reg = <0x0235000a8 0xb00>, <0x02350060 0x400>; + reg-names = "control", "domain"; + domain-id = <24>; + }; + + clkvcp4: clkvcp4 { + #clock-cells = <0>; + compatible = "ti,keystone,psc-clock"; + clocks = <&chipclk13>; + clock-output-names = "vcp-4"; + reg = <0x023500ac 0xb00>, <0x02350064 0x400>; + reg-names = "control", "domain"; + domain-id = <25>; + }; + + clkvcp5: clkvcp5 { + #clock-cells = <0>; + compatible = "ti,keystone,psc-clock"; + clocks = <&chipclk13>; + clock-output-names = "vcp-5"; + reg = <0x023500b0 0xb00>, <0x02350064 0x400>; + reg-names = "control", "domain"; + domain-id = <25>; + }; + + clkvcp6: clkvcp6 { + #clock-cells = <0>; + compatible = "ti,keystone,psc-clock"; + clocks = <&chipclk13>; + clock-output-names = "vcp-6"; + reg = <0x023500b4 0xb00>, <0x02350064 0x400>; + reg-names = "control", "domain"; + domain-id = <25>; + }; + + clkvcp7: clkvcp7 { + #clock-cells = <0>; + compatible = "ti,keystone,psc-clock"; + clocks = <&chipclk13>; + clock-output-names = "vcp-7"; + reg = <0x023500b8 0xb00>, <0x02350064 0x400>; + reg-names = "control", "domain"; + domain-id = <25>; + }; + + clkbcp: clkbcp { + #clock-cells = <0>; + compatible = "ti,keystone,psc-clock"; + clocks = <&chipclk13>; + clock-output-names = "bcp"; + reg = <0x023500bc 0xb00>, <0x02350068 0x400>; + reg-names = "control", "domain"; + domain-id = <26>; + }; + + clkdxb: clkdxb { + #clock-cells = <0>; + compatible = "ti,keystone,psc-clock"; + clocks = <&chipclk13>; + clock-output-names = "dxb"; + reg = <0x023500c0 0xb00>, <0x0235006c 0x400>; + reg-names = "control", "domain"; + domain-id = <27>; + }; + + clkhyperlink1: clkhyperlink1 { + #clock-cells = <0>; + compatible = "ti,keystone,psc-clock"; + clocks = <&chipclk12>; + clock-output-names = "hyperlink-1"; + reg = <0x023500c4 0xb00>, <0x02350070 0x400>; + reg-names = "control", "domain"; + domain-id = <28>; + }; + + clkxge: clkxge { + #clock-cells = <0>; + compatible = "ti,keystone,psc-clock"; + clocks = <&chipclk13>; + clock-output-names = "xge"; + reg = <0x023500c8 0xb00>, <0x02350074 0x400>; + reg-names = "control", "domain"; + domain-id = <29>; + }; + + clkwdtimer0: clkwdtimer0 { + #clock-cells = <0>; + compatible = "ti,keystone,psc-clock"; + clocks = <&clkmodrst0>; + clock-output-names = "timer0"; + reg = <0x02350000 0xb00>, <0x02350000 0x400>; + reg-names = "control", "domain"; + domain-id = <0>; + }; + + clkwdtimer1: clkwdtimer1 { + #clock-cells = <0>; + compatible = "ti,keystone,psc-clock"; + clocks = <&clkmodrst0>; + clock-output-names = "timer1"; + reg = <0x02350000 0xb00>, <0x02350000 0x400>; + reg-names = "control", "domain"; + domain-id = <0>; + }; + + clkwdtimer2: clkwdtimer2 { + #clock-cells = <0>; + compatible = "ti,keystone,psc-clock"; + clocks = <&clkmodrst0>; + clock-output-names = "timer2"; + reg = <0x02350000 0xb00>, <0x02350000 0x400>; + reg-names = "control", "domain"; + domain-id = <0>; + }; + + clkwdtimer3: clkwdtimer3 { + #clock-cells = <0>; + compatible = "ti,keystone,psc-clock"; + clocks = <&clkmodrst0>; + clock-output-names = "timer3"; + reg = <0x02350000 0xb00>, <0x02350000 0x400>; + reg-names = "control", "domain"; + domain-id = <0>; + }; + + clkuart0: clkuart0 { + #clock-cells = <0>; + compatible = "ti,keystone,psc-clock"; + clocks = <&clkmodrst0>; + clock-output-names = "uart0"; + reg = <0x02350000 0xb00>, <0x02350000 0x400>; + reg-names = "control", "domain"; + domain-id = <0>; + }; + + clkuart1: clkuart1 { + #clock-cells = <0>; + compatible = "ti,keystone,psc-clock"; + clocks = <&clkmodrst0>; + clock-output-names = "uart1"; + reg = <0x02350000 0xb00>, <0x02350000 0x400>; + reg-names = "control", "domain"; + domain-id = <0>; + }; + + clkaemif: clkaemif { + #clock-cells = <0>; + compatible = "ti,keystone,psc-clock"; + clocks = <&clkaemifspi>; + clock-output-names = "aemif"; + reg = <0x02350000 0xb00>, <0x02350000 0x400>; + reg-names = "control", "domain"; + domain-id = <0>; + }; + + clkusim: clkusim { + #clock-cells = <0>; + compatible = "ti,keystone,psc-clock"; + clocks = <&clkmodrst0>; + clock-output-names = "usim"; + reg = <0x02350000 0xb00>, <0x02350000 0x400>; + reg-names = "control", "domain"; + domain-id = <0>; + }; + + clki2c: clki2c { + #clock-cells = <0>; + compatible = "ti,keystone,psc-clock"; + clocks = <&clkmodrst0>; + clock-output-names = "i2c"; + reg = <0x02350000 0xb00>, <0x02350000 0x400>; + reg-names = "control", "domain"; + domain-id = <0>; + }; + + clkspi: clkspi { + #clock-cells = <0>; + compatible = "ti,keystone,psc-clock"; + clocks = <&clkaemifspi>; + clock-output-names = "spi"; + reg = <0x02350000 0xb00>, <0x02350000 0x400>; + reg-names = "control", "domain"; + domain-id = <0>; + }; + + clkgpio: clkgpio { + #clock-cells = <0>; + compatible = "ti,keystone,psc-clock"; + clocks = <&clkmodrst0>; + clock-output-names = "gpio"; + reg = <0x02350000 0xb00>, <0x02350000 0x400>; + reg-names = "control", "domain"; + domain-id = <0>; + }; + + clkkeymgr: clkkeymgr { + #clock-cells = <0>; + compatible = "ti,keystone,psc-clock"; + clocks = <&clkmodrst0>; + clock-output-names = "keymgr"; + reg = <0x02350000 0xb00>, <0x02350000 0x400>; + reg-names = "control", "domain"; + domain-id = <0>; + }; +}; diff --git a/arch/arm/boot/dts/keystone.dts b/arch/arm/boot/dts/keystone.dts index a68e34bbecb2..100bdf52b847 100644 --- a/arch/arm/boot/dts/keystone.dts +++ b/arch/arm/boot/dts/keystone.dts @@ -100,13 +100,15 @@ reg = <0x023100e8 4>; /* pll reset control reg */ }; + /include/ "keystone-clocks.dtsi" + uart0: serial@02530c00 { compatible = "ns16550a"; current-speed = <115200>; reg-shift = <2>; reg-io-width = <4>; reg = <0x02530c00 0x100>; - clock-frequency = <133120000>; + clocks = <&clkuart0>; interrupts = <GIC_SPI 277 IRQ_TYPE_EDGE_RISING>; }; @@ -116,9 +118,66 @@ reg-shift = <2>; reg-io-width = <4>; reg = <0x02531000 0x100>; - clock-frequency = <133120000>; + clocks = <&clkuart1>; interrupts = <GIC_SPI 280 IRQ_TYPE_EDGE_RISING>; }; + i2c0: i2c@2530000 { + compatible = "ti,davinci-i2c"; + reg = <0x02530000 0x400>; + clock-frequency = <100000>; + clocks = <&clki2c>; + interrupts = <GIC_SPI 283 IRQ_TYPE_EDGE_RISING>; + #address-cells = <1>; + #size-cells = <0>; + + dtt@50 { + compatible = "at,24c1024"; + reg = <0x50>; + }; + }; + + i2c1: i2c@2530400 { + compatible = "ti,davinci-i2c"; + reg = <0x02530400 0x400>; + clock-frequency = <100000>; + clocks = <&clki2c>; + interrupts = <GIC_SPI 286 IRQ_TYPE_EDGE_RISING>; + }; + + i2c2: i2c@2530800 { + compatible = "ti,davinci-i2c"; + reg = <0x02530800 0x400>; + clock-frequency = <100000>; + clocks = <&clki2c>; + interrupts = <GIC_SPI 289 IRQ_TYPE_EDGE_RISING>; + }; + + spi0: spi@21000400 { + compatible = "ti,dm6441-spi"; + reg = <0x21000400 0x200>; + num-cs = <4>; + ti,davinci-spi-intr-line = <0>; + interrupts = <GIC_SPI 292 IRQ_TYPE_EDGE_RISING>; + clocks = <&clkspi>; + }; + + spi1: spi@21000600 { + compatible = "ti,dm6441-spi"; + reg = <0x21000600 0x200>; + num-cs = <4>; + ti,davinci-spi-intr-line = <0>; + interrupts = <GIC_SPI 296 IRQ_TYPE_EDGE_RISING>; + clocks = <&clkspi>; + }; + + spi2: spi@21000800 { + compatible = "ti,dm6441-spi"; + reg = <0x21000800 0x200>; + num-cs = <4>; + ti,davinci-spi-intr-line = <0>; + interrupts = <GIC_SPI 300 IRQ_TYPE_EDGE_RISING>; + clocks = <&clkspi>; + }; }; }; diff --git a/arch/arm/boot/dts/kirkwood.dtsi b/arch/arm/boot/dts/kirkwood.dtsi index cf7aeaf89e9c..1335b2e1bed4 100644 --- a/arch/arm/boot/dts/kirkwood.dtsi +++ b/arch/arm/boot/dts/kirkwood.dtsi @@ -13,6 +13,7 @@ cpu@0 { device_type = "cpu"; compatible = "marvell,feroceon"; + reg = <0>; clocks = <&core_clk 1>, <&core_clk 3>, <&gate_clk 11>; clock-names = "cpu_clk", "ddrclk", "powersave"; }; @@ -167,7 +168,7 @@ xor@60900 { compatible = "marvell,orion-xor"; reg = <0x60900 0x100 - 0xd0B00 0x100>; + 0x60B00 0x100>; status = "okay"; clocks = <&gate_clk 16>; diff --git a/arch/arm/boot/dts/prima2.dtsi b/arch/arm/boot/dts/prima2.dtsi index bbeb623fc2c6..27ed9f5144bc 100644 --- a/arch/arm/boot/dts/prima2.dtsi +++ b/arch/arm/boot/dts/prima2.dtsi @@ -171,7 +171,8 @@ compatible = "simple-bus"; #address-cells = <1>; #size-cells = <1>; - ranges = <0xb0000000 0xb0000000 0x180000>; + ranges = <0xb0000000 0xb0000000 0x180000>, + <0x56000000 0x56000000 0x1b00000>; timer@b0020000 { compatible = "sirf,prima2-tick"; @@ -196,25 +197,32 @@ uart0: uart@b0050000 { cell-index = <0>; compatible = "sirf,prima2-uart"; - reg = <0xb0050000 0x10000>; + reg = <0xb0050000 0x1000>; interrupts = <17>; + fifosize = <128>; clocks = <&clks 13>; + sirf,uart-dma-rx-channel = <21>; + sirf,uart-dma-tx-channel = <2>; }; uart1: uart@b0060000 { cell-index = <1>; compatible = "sirf,prima2-uart"; - reg = <0xb0060000 0x10000>; + reg = <0xb0060000 0x1000>; interrupts = <18>; + fifosize = <32>; clocks = <&clks 14>; }; uart2: uart@b0070000 { cell-index = <2>; compatible = "sirf,prima2-uart"; - reg = <0xb0070000 0x10000>; + reg = <0xb0070000 0x1000>; interrupts = <19>; + fifosize = <128>; clocks = <&clks 15>; + sirf,uart-dma-rx-channel = <6>; + sirf,uart-dma-tx-channel = <7>; }; usp0: usp@b0080000 { @@ -222,7 +230,10 @@ compatible = "sirf,prima2-usp"; reg = <0xb0080000 0x10000>; interrupts = <20>; + fifosize = <128>; clocks = <&clks 28>; + sirf,usp-dma-rx-channel = <17>; + sirf,usp-dma-tx-channel = <18>; }; usp1: usp@b0090000 { @@ -230,7 +241,10 @@ compatible = "sirf,prima2-usp"; reg = <0xb0090000 0x10000>; interrupts = <21>; + fifosize = <128>; clocks = <&clks 29>; + sirf,usp-dma-rx-channel = <14>; + sirf,usp-dma-tx-channel = <15>; }; usp2: usp@b00a0000 { @@ -238,7 +252,10 @@ compatible = "sirf,prima2-usp"; reg = <0xb00a0000 0x10000>; interrupts = <22>; + fifosize = <128>; clocks = <&clks 30>; + sirf,usp-dma-rx-channel = <10>; + sirf,usp-dma-tx-channel = <11>; }; dmac0: dma-controller@b00b0000 { @@ -261,6 +278,8 @@ compatible = "sirf,prima2-vip"; reg = <0xb00C0000 0x10000>; clocks = <&clks 31>; + interrupts = <14>; + sirf,vip-dma-rx-channel = <16>; }; spi0: spi@b00d0000 { diff --git a/arch/arm/boot/dts/r7s72100.dtsi b/arch/arm/boot/dts/r7s72100.dtsi new file mode 100644 index 000000000000..46b82aa7dc4e --- /dev/null +++ b/arch/arm/boot/dts/r7s72100.dtsi @@ -0,0 +1,36 @@ +/* + * Device Tree Source for the r7s72100 SoC + * + * Copyright (C) 2013 Renesas Solutions Corp. + * + * This file is licensed under the terms of the GNU General Public License + * version 2. This program is licensed "as is" without any warranty of any + * kind, whether express or implied. + */ + +/ { + compatible = "renesas,r7s72100"; + interrupt-parent = <&gic>; + #address-cells = <1>; + #size-cells = <1>; + + cpus { + #address-cells = <1>; + #size-cells = <0>; + + cpu@0 { + device_type = "cpu"; + compatible = "arm,cortex-a9"; + reg = <0>; + }; + }; + + gic: interrupt-controller@e8201000 { + compatible = "arm,cortex-a9-gic"; + #interrupt-cells = <3>; + #address-cells = <0>; + interrupt-controller; + reg = <0xe8201000 0x1000>, + <0xe8202000 0x1000>; + }; +}; diff --git a/arch/arm/boot/dts/r8a73a4.dtsi b/arch/arm/boot/dts/r8a73a4.dtsi index 6c26caa880f2..658fcc537576 100644 --- a/arch/arm/boot/dts/r8a73a4.dtsi +++ b/arch/arm/boot/dts/r8a73a4.dtsi @@ -193,7 +193,7 @@ }; sdhi0: sdhi@ee100000 { - compatible = "renesas,r8a73a4-sdhi"; + compatible = "renesas,sdhi-r8a73a4"; reg = <0 0xee100000 0 0x100>; interrupt-parent = <&gic>; interrupts = <0 165 4>; @@ -202,7 +202,7 @@ }; sdhi1: sdhi@ee120000 { - compatible = "renesas,r8a73a4-sdhi"; + compatible = "renesas,sdhi-r8a73a4"; reg = <0 0xee120000 0 0x100>; interrupt-parent = <&gic>; interrupts = <0 166 4>; @@ -211,7 +211,7 @@ }; sdhi2: sdhi@ee140000 { - compatible = "renesas,r8a73a4-sdhi"; + compatible = "renesas,sdhi-r8a73a4"; reg = <0 0xee140000 0 0x100>; interrupt-parent = <&gic>; interrupts = <0 167 4>; diff --git a/arch/arm/boot/dts/r8a7778.dtsi b/arch/arm/boot/dts/r8a7778.dtsi index 45ac404ab6d8..3577aba82583 100644 --- a/arch/arm/boot/dts/r8a7778.dtsi +++ b/arch/arm/boot/dts/r8a7778.dtsi @@ -96,6 +96,5 @@ pfc: pfc@fffc0000 { compatible = "renesas,pfc-r8a7778"; reg = <0xfffc000 0x118>; - #gpio-range-cells = <3>; }; }; diff --git a/arch/arm/boot/dts/r8a7779.dtsi b/arch/arm/boot/dts/r8a7779.dtsi index 23a62447359c..ebbe507fcbfa 100644 --- a/arch/arm/boot/dts/r8a7779.dtsi +++ b/arch/arm/boot/dts/r8a7779.dtsi @@ -188,7 +188,6 @@ pfc: pfc@fffc0000 { compatible = "renesas,pfc-r8a7779"; reg = <0xfffc0000 0x23c>; - #gpio-range-cells = <3>; }; thermal@ffc48000 { diff --git a/arch/arm/boot/dts/r8a7790.dtsi b/arch/arm/boot/dts/r8a7790.dtsi index 3b879e7c697c..413b4c29e782 100644 --- a/arch/arm/boot/dts/r8a7790.dtsi +++ b/arch/arm/boot/dts/r8a7790.dtsi @@ -148,11 +148,10 @@ pfc: pfc@e6060000 { compatible = "renesas,pfc-r8a7790"; reg = <0 0xe6060000 0 0x250>; - #gpio-range-cells = <3>; }; sdhi0: sdhi@ee100000 { - compatible = "renesas,r8a7790-sdhi"; + compatible = "renesas,sdhi-r8a7790"; reg = <0 0xee100000 0 0x100>; interrupt-parent = <&gic>; interrupts = <0 165 4>; @@ -161,7 +160,7 @@ }; sdhi1: sdhi@ee120000 { - compatible = "renesas,r8a7790-sdhi"; + compatible = "renesas,sdhi-r8a7790"; reg = <0 0xee120000 0 0x100>; interrupt-parent = <&gic>; interrupts = <0 166 4>; @@ -170,7 +169,7 @@ }; sdhi2: sdhi@ee140000 { - compatible = "renesas,r8a7790-sdhi"; + compatible = "renesas,sdhi-r8a7790"; reg = <0 0xee140000 0 0x100>; interrupt-parent = <&gic>; interrupts = <0 167 4>; @@ -179,7 +178,7 @@ }; sdhi3: sdhi@ee160000 { - compatible = "renesas,r8a7790-sdhi"; + compatible = "renesas,sdhi-r8a7790"; reg = <0 0xee160000 0 0x100>; interrupt-parent = <&gic>; interrupts = <0 168 4>; diff --git a/arch/arm/boot/dts/r8a7791.dtsi b/arch/arm/boot/dts/r8a7791.dtsi new file mode 100644 index 000000000000..bbed43bd9be9 --- /dev/null +++ b/arch/arm/boot/dts/r8a7791.dtsi @@ -0,0 +1,41 @@ +/* + * Device Tree Source for the r8a7791 SoC + * + * Copyright (C) 2013 Renesas Electronics Corporation + * Copyright (C) 2013 Renesas Solutions Corp. + * + * This file is licensed under the terms of the GNU General Public License + * version 2. This program is licensed "as is" without any warranty of any + * kind, whether express or implied. + */ + +/ { + compatible = "renesas,r8a7791"; + interrupt-parent = <&gic>; + #address-cells = <2>; + #size-cells = <2>; + + cpus { + #address-cells = <1>; + #size-cells = <0>; + + cpu0: cpu@0 { + device_type = "cpu"; + compatible = "arm,cortex-a15"; + reg = <0>; + clock-frequency = <1300000000>; + }; + }; + + gic: interrupt-controller@f1001000 { + compatible = "arm,cortex-a15-gic"; + #interrupt-cells = <3>; + #address-cells = <0>; + interrupt-controller; + reg = <0 0xf1001000 0 0x1000>, + <0 0xf1002000 0 0x1000>, + <0 0xf1004000 0 0x2000>, + <0 0xf1006000 0 0x2000>; + interrupts = <1 9 0xf04>; + }; +}; diff --git a/arch/arm/boot/dts/sh73a0.dtsi b/arch/arm/boot/dts/sh73a0.dtsi index ba59a5875a10..3955c7606a6f 100644 --- a/arch/arm/boot/dts/sh73a0.dtsi +++ b/arch/arm/boot/dts/sh73a0.dtsi @@ -196,7 +196,7 @@ }; sdhi0: sdhi@ee100000 { - compatible = "renesas,r8a7740-sdhi"; + compatible = "renesas,sdhi-r8a7740"; reg = <0xee100000 0x100>; interrupt-parent = <&gic>; interrupts = <0 83 4 @@ -208,7 +208,7 @@ /* SDHI1 and SDHI2 have no CD pins, no need for CD IRQ */ sdhi1: sdhi@ee120000 { - compatible = "renesas,r8a7740-sdhi"; + compatible = "renesas,sdhi-r8a7740"; reg = <0xee120000 0x100>; interrupt-parent = <&gic>; interrupts = <0 88 4 @@ -219,7 +219,7 @@ }; sdhi2: sdhi@ee140000 { - compatible = "renesas,r8a7740-sdhi"; + compatible = "renesas,sdhi-r8a7740"; reg = <0xee140000 0x100>; interrupt-parent = <&gic>; interrupts = <0 104 4 diff --git a/arch/arm/common/edma.c b/arch/arm/common/edma.c index 117f955a2a06..8e1a0245907f 100644 --- a/arch/arm/common/edma.c +++ b/arch/arm/common/edma.c @@ -269,6 +269,11 @@ static const struct edmacc_param dummy_paramset = { .ccnt = 1, }; +static const struct of_device_id edma_of_ids[] = { + { .compatible = "ti,edma3", }, + {} +}; + /*****************************************************************************/ static void map_dmach_queue(unsigned ctlr, unsigned ch_no, @@ -560,14 +565,38 @@ static int reserve_contiguous_slots(int ctlr, unsigned int id, static int prepare_unused_channel_list(struct device *dev, void *data) { struct platform_device *pdev = to_platform_device(dev); - int i, ctlr; + int i, count, ctlr; + struct of_phandle_args dma_spec; + if (dev->of_node) { + count = of_property_count_strings(dev->of_node, "dma-names"); + if (count < 0) + return 0; + for (i = 0; i < count; i++) { + if (of_parse_phandle_with_args(dev->of_node, "dmas", + "#dma-cells", i, + &dma_spec)) + continue; + + if (!of_match_node(edma_of_ids, dma_spec.np)) { + of_node_put(dma_spec.np); + continue; + } + + clear_bit(EDMA_CHAN_SLOT(dma_spec.args[0]), + edma_cc[0]->edma_unused); + of_node_put(dma_spec.np); + } + return 0; + } + + /* For non-OF case */ for (i = 0; i < pdev->num_resources; i++) { if ((pdev->resource[i].flags & IORESOURCE_DMA) && (int)pdev->resource[i].start >= 0) { ctlr = EDMA_CTLR(pdev->resource[i].start); clear_bit(EDMA_CHAN_SLOT(pdev->resource[i].start), - edma_cc[ctlr]->edma_unused); + edma_cc[ctlr]->edma_unused); } } @@ -1762,11 +1791,6 @@ static int edma_probe(struct platform_device *pdev) return 0; } -static const struct of_device_id edma_of_ids[] = { - { .compatible = "ti,edma3", }, - {} -}; - static struct platform_driver edma_driver = { .driver = { .name = "edma", diff --git a/arch/arm/configs/keystone_defconfig b/arch/arm/configs/keystone_defconfig index 1f36b823905f..9943e5da74f1 100644 --- a/arch/arm/configs/keystone_defconfig +++ b/arch/arm/configs/keystone_defconfig @@ -123,7 +123,9 @@ CONFIG_SERIAL_OF_PLATFORM=y CONFIG_I2C=y # CONFIG_I2C_COMPAT is not set CONFIG_I2C_CHARDEV=y +CONFIG_I2C_DAVINCI=y CONFIG_SPI=y +CONFIG_SPI_DAVINCI=y CONFIG_SPI_SPIDEV=y # CONFIG_HWMON is not set CONFIG_WATCHDOG=y diff --git a/arch/arm/configs/multi_v7_defconfig b/arch/arm/configs/multi_v7_defconfig index f3935b46df29..119fc378fc52 100644 --- a/arch/arm/configs/multi_v7_defconfig +++ b/arch/arm/configs/multi_v7_defconfig @@ -135,6 +135,7 @@ CONFIG_MMC=y CONFIG_MMC_ARMMMCI=y CONFIG_MMC_SDHCI=y CONFIG_MMC_SDHCI_PLTFM=y +CONFIG_MMC_SDHCI_ESDHC_IMX=y CONFIG_MMC_SDHCI_TEGRA=y CONFIG_MMC_SDHCI_SPEAR=y CONFIG_MMC_OMAP=y diff --git a/arch/arm/kvm/reset.c b/arch/arm/kvm/reset.c index 71e08baee209..c02ba4af599f 100644 --- a/arch/arm/kvm/reset.c +++ b/arch/arm/kvm/reset.c @@ -58,14 +58,14 @@ static const struct kvm_irq_level a15_vtimer_irq = { */ int kvm_reset_vcpu(struct kvm_vcpu *vcpu) { - struct kvm_regs *cpu_reset; + struct kvm_regs *reset_regs; const struct kvm_irq_level *cpu_vtimer_irq; switch (vcpu->arch.target) { case KVM_ARM_TARGET_CORTEX_A15: if (vcpu->vcpu_id > a15_max_cpu_idx) return -EINVAL; - cpu_reset = &a15_regs_reset; + reset_regs = &a15_regs_reset; vcpu->arch.midr = read_cpuid_id(); cpu_vtimer_irq = &a15_vtimer_irq; break; @@ -74,7 +74,7 @@ int kvm_reset_vcpu(struct kvm_vcpu *vcpu) } /* Reset core registers */ - memcpy(&vcpu->arch.regs, cpu_reset, sizeof(vcpu->arch.regs)); + memcpy(&vcpu->arch.regs, reset_regs, sizeof(vcpu->arch.regs)); /* Reset CP15 registers */ kvm_reset_coprocs(vcpu); diff --git a/arch/arm/mach-at91/at91rm9200_time.c b/arch/arm/mach-at91/at91rm9200_time.c index 180b3024bec3..f607deb40f4d 100644 --- a/arch/arm/mach-at91/at91rm9200_time.c +++ b/arch/arm/mach-at91/at91rm9200_time.c @@ -93,7 +93,7 @@ static irqreturn_t at91rm9200_timer_interrupt(int irq, void *dev_id) static struct irqaction at91rm9200_timer_irq = { .name = "at91_tick", - .flags = IRQF_SHARED | IRQF_DISABLED | IRQF_TIMER | IRQF_IRQPOLL, + .flags = IRQF_SHARED | IRQF_TIMER | IRQF_IRQPOLL, .handler = at91rm9200_timer_interrupt, .irq = NR_IRQS_LEGACY + AT91_ID_SYS, }; diff --git a/arch/arm/mach-at91/at91sam926x_time.c b/arch/arm/mach-at91/at91sam926x_time.c index 3a4bc2e1a65e..bb392320a0dd 100644 --- a/arch/arm/mach-at91/at91sam926x_time.c +++ b/arch/arm/mach-at91/at91sam926x_time.c @@ -171,7 +171,7 @@ static irqreturn_t at91sam926x_pit_interrupt(int irq, void *dev_id) static struct irqaction at91sam926x_pit_irq = { .name = "at91_tick", - .flags = IRQF_SHARED | IRQF_DISABLED | IRQF_TIMER | IRQF_IRQPOLL, + .flags = IRQF_SHARED | IRQF_TIMER | IRQF_IRQPOLL, .handler = at91sam926x_pit_interrupt, .irq = NR_IRQS_LEGACY + AT91_ID_SYS, }; diff --git a/arch/arm/mach-at91/at91sam9g45_reset.S b/arch/arm/mach-at91/at91sam9g45_reset.S index 721a1a34dd1d..c40c1e2ef80f 100644 --- a/arch/arm/mach-at91/at91sam9g45_reset.S +++ b/arch/arm/mach-at91/at91sam9g45_reset.S @@ -16,11 +16,17 @@ #include "at91_rstc.h" .arm +/* + * at91_ramc_base is an array void* + * init at NULL if only one DDR controler is present in or DT + */ .globl at91sam9g45_restart at91sam9g45_restart: ldr r5, =at91_ramc_base @ preload constants ldr r0, [r5] + ldr r5, [r5, #4] @ ddr1 + cmp r5, #0 ldr r4, =at91_rstc_base ldr r1, [r4] @@ -30,6 +36,8 @@ at91sam9g45_restart: .balign 32 @ align to cache line + strne r2, [r5, #AT91_DDRSDRC_RTR] @ disable DDR1 access + strne r3, [r5, #AT91_DDRSDRC_LPR] @ power down DDR1 str r2, [r0, #AT91_DDRSDRC_RTR] @ disable DDR0 access str r3, [r0, #AT91_DDRSDRC_LPR] @ power down DDR0 str r4, [r1, #AT91_RSTC_CR] @ reset processor diff --git a/arch/arm/mach-at91/at91x40_time.c b/arch/arm/mach-at91/at91x40_time.c index 2919eba41ff4..c0e637adf65d 100644 --- a/arch/arm/mach-at91/at91x40_time.c +++ b/arch/arm/mach-at91/at91x40_time.c @@ -57,7 +57,7 @@ static irqreturn_t at91x40_timer_interrupt(int irq, void *dev_id) static struct irqaction at91x40_timer_irq = { .name = "at91_tick", - .flags = IRQF_DISABLED | IRQF_TIMER, + .flags = IRQF_TIMER, .handler = at91x40_timer_interrupt }; diff --git a/arch/arm/mach-davinci/board-da830-evm.c b/arch/arm/mach-davinci/board-da830-evm.c index c4bdc0a1c36e..30a44e2df47e 100644 --- a/arch/arm/mach-davinci/board-da830-evm.c +++ b/arch/arm/mach-davinci/board-da830-evm.c @@ -74,7 +74,7 @@ static int da830_evm_usb_ocic_notify(da8xx_ocic_handler_t handler) if (handler != NULL) { da830_evm_usb_ocic_handler = handler; - error = request_irq(irq, da830_evm_usb_ocic_irq, IRQF_DISABLED | + error = request_irq(irq, da830_evm_usb_ocic_irq, IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING, "OHCI over-current indicator", NULL); if (error) diff --git a/arch/arm/mach-davinci/board-dm365-evm.c b/arch/arm/mach-davinci/board-dm365-evm.c index 92b7f770615a..4078ba93776b 100644 --- a/arch/arm/mach-davinci/board-dm365-evm.c +++ b/arch/arm/mach-davinci/board-dm365-evm.c @@ -176,7 +176,7 @@ static struct at24_platform_data eeprom_info = { .context = (void *)0x7f00, }; -static struct snd_platform_data dm365_evm_snd_data = { +static struct snd_platform_data dm365_evm_snd_data __maybe_unused = { .asp_chan_q = EVENTQ_3, }; diff --git a/arch/arm/mach-davinci/board-omapl138-hawk.c b/arch/arm/mach-davinci/board-omapl138-hawk.c index ab98c75cabb4..e0de2da41b5c 100644 --- a/arch/arm/mach-davinci/board-omapl138-hawk.c +++ b/arch/arm/mach-davinci/board-omapl138-hawk.c @@ -211,7 +211,7 @@ static int hawk_usb_ocic_notify(da8xx_ocic_handler_t handler) hawk_usb_ocic_handler = handler; error = request_irq(irq, omapl138_hawk_usb_ocic_irq, - IRQF_DISABLED | IRQF_TRIGGER_RISING | + IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING, "OHCI over-current indicator", NULL); if (error) diff --git a/arch/arm/mach-davinci/include/mach/serial.h b/arch/arm/mach-davinci/include/mach/serial.h index 52b8571b2e70..ce402cd21fa0 100644 --- a/arch/arm/mach-davinci/include/mach/serial.h +++ b/arch/arm/mach-davinci/include/mach/serial.h @@ -15,8 +15,6 @@ #include <mach/hardware.h> -#include <linux/platform_device.h> - #define DAVINCI_UART0_BASE (IO_PHYS + 0x20000) #define DAVINCI_UART1_BASE (IO_PHYS + 0x20400) #define DAVINCI_UART2_BASE (IO_PHYS + 0x20800) @@ -39,6 +37,8 @@ #define UART_DM646X_SCR_TX_WATERMARK 0x08 #ifndef __ASSEMBLY__ +#include <linux/platform_device.h> + extern int davinci_serial_init(struct platform_device *); #endif diff --git a/arch/arm/mach-davinci/time.c b/arch/arm/mach-davinci/time.c index ef2645a6f39f..56c6eb5266ad 100644 --- a/arch/arm/mach-davinci/time.c +++ b/arch/arm/mach-davinci/time.c @@ -181,7 +181,7 @@ static struct timer_s timers[] = { .name = "clockevent", .opts = TIMER_OPTS_DISABLED, .irqaction = { - .flags = IRQF_DISABLED | IRQF_TIMER, + .flags = IRQF_TIMER, .handler = timer_interrupt, } }, @@ -190,7 +190,7 @@ static struct timer_s timers[] = { .period = ~0, .opts = TIMER_OPTS_PERIODIC, .irqaction = { - .flags = IRQF_DISABLED | IRQF_TIMER, + .flags = IRQF_TIMER, .handler = freerun_interrupt, } }, diff --git a/arch/arm/mach-integrator/pci_v3.h b/arch/arm/mach-integrator/pci_v3.h index 755fd29fed4a..06a9e2e7d007 100644 --- a/arch/arm/mach-integrator/pci_v3.h +++ b/arch/arm/mach-integrator/pci_v3.h @@ -1,2 +1,9 @@ /* Simple oneliner include to the PCIv3 early init */ +#ifdef CONFIG_PCI extern int pci_v3_early_init(void); +#else +static inline int pci_v3_early_init(void) +{ + return 0; +} +#endif diff --git a/arch/arm/mach-keystone/Kconfig b/arch/arm/mach-keystone/Kconfig index 366d1a3b418d..f20c53e75ed9 100644 --- a/arch/arm/mach-keystone/Kconfig +++ b/arch/arm/mach-keystone/Kconfig @@ -9,6 +9,8 @@ config ARCH_KEYSTONE select GENERIC_CLOCKEVENTS select ARCH_WANT_OPTIONAL_GPIOLIB select ARM_ERRATA_798181 if SMP + select COMMON_CLK_KEYSTONE + select TI_EDMA help Support for boards based on the Texas Instruments Keystone family of SoCs. diff --git a/arch/arm/mach-keystone/Makefile b/arch/arm/mach-keystone/Makefile index ddc52b05dc84..25d92396fbfa 100644 --- a/arch/arm/mach-keystone/Makefile +++ b/arch/arm/mach-keystone/Makefile @@ -4,3 +4,6 @@ plus_sec := $(call as-instr,.arch_extension sec,+sec) AFLAGS_smc.o :=-Wa,-march=armv7-a$(plus_sec) obj-$(CONFIG_SMP) += platsmp.o + +# PM domain driver for Keystone SOCs +obj-$(CONFIG_ARCH_KEYSTONE) += pm_domain.o diff --git a/arch/arm/mach-keystone/pm_domain.c b/arch/arm/mach-keystone/pm_domain.c new file mode 100644 index 000000000000..29625232e954 --- /dev/null +++ b/arch/arm/mach-keystone/pm_domain.c @@ -0,0 +1,82 @@ +/* + * PM domain driver for Keystone2 devices + * + * Copyright 2013 Texas Instruments, Inc. + * Santosh Shilimkar <santosh.shillimkar@ti.com> + * + * Based on Kevins work on DAVINCI SOCs + * Kevin Hilman <khilman@linaro.org> + * + * 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. + */ + +#include <linux/init.h> +#include <linux/pm_runtime.h> +#include <linux/pm_clock.h> +#include <linux/platform_device.h> +#include <linux/clk-provider.h> +#include <linux/of.h> + +#ifdef CONFIG_PM_RUNTIME +static int keystone_pm_runtime_suspend(struct device *dev) +{ + int ret; + + dev_dbg(dev, "%s\n", __func__); + + ret = pm_generic_runtime_suspend(dev); + if (ret) + return ret; + + ret = pm_clk_suspend(dev); + if (ret) { + pm_generic_runtime_resume(dev); + return ret; + } + + return 0; +} + +static int keystone_pm_runtime_resume(struct device *dev) +{ + dev_dbg(dev, "%s\n", __func__); + + pm_clk_resume(dev); + + return pm_generic_runtime_resume(dev); +} +#endif + +static struct dev_pm_domain keystone_pm_domain = { + .ops = { + SET_RUNTIME_PM_OPS(keystone_pm_runtime_suspend, + keystone_pm_runtime_resume, NULL) + USE_PLATFORM_PM_SLEEP_OPS + }, +}; + +static struct pm_clk_notifier_block platform_domain_notifier = { + .pm_domain = &keystone_pm_domain, +}; + +static struct of_device_id of_keystone_table[] = { + {.compatible = "ti,keystone"}, + { /* end of list */ }, +}; + +int __init keystone_pm_runtime_init(void) +{ + struct device_node *np; + + np = of_find_matching_node(NULL, of_keystone_table); + if (!np) + return 0; + + of_clk_init(NULL); + pm_clk_add_notifier(&platform_bus_type, &platform_domain_notifier); + + return 0; +} +subsys_initcall(keystone_pm_runtime_init); diff --git a/arch/arm/mach-mvebu/coherency.c b/arch/arm/mach-mvebu/coherency.c index 4c24303ec481..58adf2fd9cfc 100644 --- a/arch/arm/mach-mvebu/coherency.c +++ b/arch/arm/mach-mvebu/coherency.c @@ -140,6 +140,7 @@ int __init coherency_init(void) coherency_base = of_iomap(np, 0); coherency_cpu_base = of_iomap(np, 1); set_cpu_coherent(cpu_logical_map(smp_processor_id()), 0); + of_node_put(np); } return 0; @@ -147,9 +148,14 @@ int __init coherency_init(void) static int __init coherency_late_init(void) { - if (of_find_matching_node(NULL, of_coherency_table)) + struct device_node *np; + + np = of_find_matching_node(NULL, of_coherency_table); + if (np) { bus_register_notifier(&platform_bus_type, &mvebu_hwcc_platform_nb); + of_node_put(np); + } return 0; } diff --git a/arch/arm/mach-mvebu/pmsu.c b/arch/arm/mach-mvebu/pmsu.c index 3cc4bef6401c..27fc4f049474 100644 --- a/arch/arm/mach-mvebu/pmsu.c +++ b/arch/arm/mach-mvebu/pmsu.c @@ -67,6 +67,7 @@ int __init armada_370_xp_pmsu_init(void) pr_info("Initializing Power Management Service Unit\n"); pmsu_mp_base = of_iomap(np, 0); pmsu_reset_base = of_iomap(np, 1); + of_node_put(np); } return 0; diff --git a/arch/arm/mach-mvebu/system-controller.c b/arch/arm/mach-mvebu/system-controller.c index f875124ff4f9..5175083cdb34 100644 --- a/arch/arm/mach-mvebu/system-controller.c +++ b/arch/arm/mach-mvebu/system-controller.c @@ -98,6 +98,7 @@ static int __init mvebu_system_controller_init(void) BUG_ON(!match); system_controller_base = of_iomap(np, 0); mvebu_sc = (struct mvebu_system_controller *)match->data; + of_node_put(np); } return 0; diff --git a/arch/arm/mach-omap2/id.c b/arch/arm/mach-omap2/id.c index 0289adcb6efb..4f8f1cb3f5f7 100644 --- a/arch/arm/mach-omap2/id.c +++ b/arch/arm/mach-omap2/id.c @@ -576,8 +576,8 @@ void __init omap5xxx_check_revision(void) case 0xb942: switch (rev) { case 0: - omap_revision = OMAP5430_REV_ES1_0; - break; + /* No support for ES1.0 Test chip */ + BUG(); case 1: default: omap_revision = OMAP5430_REV_ES2_0; @@ -587,8 +587,8 @@ void __init omap5xxx_check_revision(void) case 0xb998: switch (rev) { case 0: - omap_revision = OMAP5432_REV_ES1_0; - break; + /* No support for ES1.0 Test chip */ + BUG(); case 1: default: omap_revision = OMAP5432_REV_ES2_0; diff --git a/arch/arm/mach-omap2/omap-secure.h b/arch/arm/mach-omap2/omap-secure.h index 0e729170c46b..a5ee09d20ac9 100644 --- a/arch/arm/mach-omap2/omap-secure.h +++ b/arch/arm/mach-omap2/omap-secure.h @@ -42,6 +42,8 @@ #define OMAP4_MON_L2X0_AUXCTRL_INDEX 0x109 #define OMAP4_MON_L2X0_PREFETCH_INDEX 0x113 +#define OMAP5_DRA7_MON_SET_CNTFRQ_INDEX 0x109 + /* Secure PPA(Primary Protected Application) APIs */ #define OMAP4_PPA_L2_POR_INDEX 0x23 #define OMAP4_PPA_CPU_ACTRL_SMP_INDEX 0x25 @@ -60,5 +62,7 @@ extern int omap_barrier_reserve_memblock(void); static inline void omap_barrier_reserve_memblock(void) { } #endif + +void set_cntfreq(void); #endif /* __ASSEMBLER__ */ #endif /* OMAP_ARCH_OMAP_SECURE_H */ diff --git a/arch/arm/mach-omap2/omap-smp.c b/arch/arm/mach-omap2/omap-smp.c index 891211093295..75e95d4fb448 100644 --- a/arch/arm/mach-omap2/omap-smp.c +++ b/arch/arm/mach-omap2/omap-smp.c @@ -66,6 +66,13 @@ static void omap4_secondary_init(unsigned int cpu) 4, 0, 0, 0, 0, 0); /* + * Configure the CNTFRQ register for the secondary cpu's which + * indicates the frequency of the cpu local timers. + */ + if (soc_is_omap54xx() || soc_is_dra7xx()) + set_cntfreq(); + + /* * Synchronise with the boot thread. */ spin_lock(&boot_lock); diff --git a/arch/arm/mach-omap2/omap_hwmod.c b/arch/arm/mach-omap2/omap_hwmod.c index d9ee0ff094d4..1c217e89deb9 100644 --- a/arch/arm/mach-omap2/omap_hwmod.c +++ b/arch/arm/mach-omap2/omap_hwmod.c @@ -2357,25 +2357,29 @@ static struct device_node *of_dev_hwmod_lookup(struct device_node *np, /** * _init_mpu_rt_base - populate the virtual address for a hwmod * @oh: struct omap_hwmod * to locate the virtual address + * @data: (unused, caller should pass NULL) + * @np: struct device_node * of the IP block's device node in the DT data * * Cache the virtual address used by the MPU to access this IP block's * registers. This address is needed early so the OCP registers that * are part of the device's address space can be ioremapped properly. - * No return value. + * + * Returns 0 on success, -EINVAL if an invalid hwmod is passed, and + * -ENXIO on absent or invalid register target address space. */ -static void __init _init_mpu_rt_base(struct omap_hwmod *oh, void *data) +static int __init _init_mpu_rt_base(struct omap_hwmod *oh, void *data, + struct device_node *np) { struct omap_hwmod_addr_space *mem; void __iomem *va_start = NULL; - struct device_node *np; if (!oh) - return; + return -EINVAL; _save_mpu_port_index(oh); if (oh->_int_flags & _HWMOD_NO_MPU_PORT) - return; + return -ENXIO; mem = _find_mpu_rt_addr_space(oh); if (!mem) { @@ -2383,25 +2387,24 @@ static void __init _init_mpu_rt_base(struct omap_hwmod *oh, void *data) oh->name); /* Extract the IO space from device tree blob */ - if (!of_have_populated_dt()) - return; + if (!np) + return -ENXIO; - np = of_dev_hwmod_lookup(of_find_node_by_name(NULL, "ocp"), oh); - if (np) - va_start = of_iomap(np, oh->mpu_rt_idx); + va_start = of_iomap(np, oh->mpu_rt_idx); } else { va_start = ioremap(mem->pa_start, mem->pa_end - mem->pa_start); } if (!va_start) { pr_err("omap_hwmod: %s: Could not ioremap\n", oh->name); - return; + return -ENXIO; } pr_debug("omap_hwmod: %s: MPU register target at va %p\n", oh->name, va_start); oh->_mpu_rt_va = va_start; + return 0; } /** @@ -2414,18 +2417,28 @@ static void __init _init_mpu_rt_base(struct omap_hwmod *oh, void *data) * registered at this point. This is the first of two phases for * hwmod initialization. Code called here does not touch any hardware * registers, it simply prepares internal data structures. Returns 0 - * upon success or if the hwmod isn't registered, or -EINVAL upon - * failure. + * upon success or if the hwmod isn't registered or if the hwmod's + * address space is not defined, or -EINVAL upon failure. */ static int __init _init(struct omap_hwmod *oh, void *data) { int r; + struct device_node *np = NULL; if (oh->_state != _HWMOD_STATE_REGISTERED) return 0; - if (oh->class->sysc) - _init_mpu_rt_base(oh, NULL); + if (of_have_populated_dt()) + np = of_dev_hwmod_lookup(of_find_node_by_name(NULL, "ocp"), oh); + + if (oh->class->sysc) { + r = _init_mpu_rt_base(oh, NULL, np); + if (r < 0) { + WARN(1, "omap_hwmod: %s: doesn't have mpu register target base\n", + oh->name); + return 0; + } + } r = _init_clocks(oh, NULL); if (r < 0) { @@ -2433,6 +2446,12 @@ static int __init _init(struct omap_hwmod *oh, void *data) return -EINVAL; } + if (np) + if (of_find_property(np, "ti,no-reset-on-init", NULL)) + oh->flags |= HWMOD_INIT_NO_RESET; + if (of_find_property(np, "ti,no-idle-on-init", NULL)) + oh->flags |= HWMOD_INIT_NO_IDLE; + oh->_state = _HWMOD_STATE_INITIALIZED; return 0; diff --git a/arch/arm/mach-omap2/omap_hwmod_33xx_data.c b/arch/arm/mach-omap2/omap_hwmod_33xx_data.c index 215894f8910d..a166e5394113 100644 --- a/arch/arm/mach-omap2/omap_hwmod_33xx_data.c +++ b/arch/arm/mach-omap2/omap_hwmod_33xx_data.c @@ -52,7 +52,7 @@ static struct omap_hwmod am33xx_emif_hwmod = { .name = "emif", .class = &am33xx_emif_hwmod_class, .clkdm_name = "l3_clkdm", - .flags = (HWMOD_INIT_NO_IDLE | HWMOD_INIT_NO_RESET), + .flags = HWMOD_INIT_NO_IDLE, .main_clk = "dpll_ddr_m2_div2_ck", .prcm = { .omap4 = { @@ -74,7 +74,7 @@ static struct omap_hwmod am33xx_l3_main_hwmod = { .name = "l3_main", .class = &am33xx_l3_hwmod_class, .clkdm_name = "l3_clkdm", - .flags = (HWMOD_INIT_NO_IDLE | HWMOD_INIT_NO_RESET), + .flags = HWMOD_INIT_NO_IDLE, .main_clk = "l3_gclk", .prcm = { .omap4 = { @@ -96,7 +96,7 @@ static struct omap_hwmod am33xx_l3_instr_hwmod = { .name = "l3_instr", .class = &am33xx_l3_hwmod_class, .clkdm_name = "l3_clkdm", - .flags = (HWMOD_INIT_NO_IDLE | HWMOD_INIT_NO_RESET), + .flags = HWMOD_INIT_NO_IDLE, .main_clk = "l3_gclk", .prcm = { .omap4 = { @@ -119,7 +119,7 @@ static struct omap_hwmod am33xx_l4_ls_hwmod = { .name = "l4_ls", .class = &am33xx_l4_hwmod_class, .clkdm_name = "l4ls_clkdm", - .flags = (HWMOD_INIT_NO_IDLE | HWMOD_INIT_NO_RESET), + .flags = HWMOD_INIT_NO_IDLE, .main_clk = "l4ls_gclk", .prcm = { .omap4 = { @@ -134,7 +134,7 @@ static struct omap_hwmod am33xx_l4_hs_hwmod = { .name = "l4_hs", .class = &am33xx_l4_hwmod_class, .clkdm_name = "l4hs_clkdm", - .flags = (HWMOD_INIT_NO_IDLE | HWMOD_INIT_NO_RESET), + .flags = HWMOD_INIT_NO_IDLE, .main_clk = "l4hs_gclk", .prcm = { .omap4 = { @@ -150,7 +150,7 @@ static struct omap_hwmod am33xx_l4_wkup_hwmod = { .name = "l4_wkup", .class = &am33xx_l4_hwmod_class, .clkdm_name = "l4_wkup_clkdm", - .flags = (HWMOD_INIT_NO_IDLE | HWMOD_INIT_NO_RESET), + .flags = HWMOD_INIT_NO_IDLE, .prcm = { .omap4 = { .clkctrl_offs = AM33XX_CM_WKUP_L4WKUP_CLKCTRL_OFFSET, @@ -170,7 +170,7 @@ static struct omap_hwmod am33xx_mpu_hwmod = { .name = "mpu", .class = &am33xx_mpu_hwmod_class, .clkdm_name = "mpu_clkdm", - .flags = (HWMOD_INIT_NO_IDLE | HWMOD_INIT_NO_RESET), + .flags = HWMOD_INIT_NO_IDLE, .main_clk = "dpll_mpu_m2_ck", .prcm = { .omap4 = { @@ -450,7 +450,7 @@ static struct omap_hwmod am33xx_ocmcram_hwmod = { .name = "ocmcram", .class = &am33xx_ocmcram_hwmod_class, .clkdm_name = "l3_clkdm", - .flags = (HWMOD_INIT_NO_IDLE | HWMOD_INIT_NO_RESET), + .flags = HWMOD_INIT_NO_IDLE, .main_clk = "l3_gclk", .prcm = { .omap4 = { @@ -532,7 +532,7 @@ static struct omap_hwmod am33xx_control_hwmod = { .name = "control", .class = &am33xx_control_hwmod_class, .clkdm_name = "l4_wkup_clkdm", - .flags = (HWMOD_INIT_NO_IDLE | HWMOD_INIT_NO_RESET), + .flags = HWMOD_INIT_NO_IDLE, .main_clk = "dpll_core_m4_div2_ck", .prcm = { .omap4 = { @@ -1278,8 +1278,21 @@ static struct omap_hwmod am33xx_spi1_hwmod = { * spinlock provides hardware assistance for synchronizing the * processes running on multiple processors */ + +static struct omap_hwmod_class_sysconfig am33xx_spinlock_sysc = { + .rev_offs = 0x0000, + .sysc_offs = 0x0010, + .syss_offs = 0x0014, + .sysc_flags = (SYSC_HAS_AUTOIDLE | SYSC_HAS_CLOCKACTIVITY | + SYSC_HAS_ENAWAKEUP | SYSC_HAS_SIDLEMODE | + SYSC_HAS_SOFTRESET | SYSS_HAS_RESET_STATUS), + .idlemodes = (SIDLE_FORCE | SIDLE_NO | SIDLE_SMART), + .sysc_fields = &omap_hwmod_sysc_type1, +}; + static struct omap_hwmod_class am33xx_spinlock_hwmod_class = { .name = "spinlock", + .sysc = &am33xx_spinlock_sysc, }; static struct omap_hwmod am33xx_spinlock_hwmod = { @@ -2480,6 +2493,41 @@ static struct omap_hwmod_ocp_if am33xx_l3_main__aes0 = { .user = OCP_USER_MPU | OCP_USER_SDMA, }; +/* rng */ +static struct omap_hwmod_class_sysconfig am33xx_rng_sysc = { + .rev_offs = 0x1fe0, + .sysc_offs = 0x1fe4, + .sysc_flags = SYSC_HAS_AUTOIDLE | SYSC_HAS_SIDLEMODE, + .idlemodes = SIDLE_FORCE | SIDLE_NO, + .sysc_fields = &omap_hwmod_sysc_type1, +}; + +static struct omap_hwmod_class am33xx_rng_hwmod_class = { + .name = "rng", + .sysc = &am33xx_rng_sysc, +}; + +static struct omap_hwmod am33xx_rng_hwmod = { + .name = "rng", + .class = &am33xx_rng_hwmod_class, + .clkdm_name = "l4ls_clkdm", + .flags = HWMOD_SWSUP_SIDLE, + .main_clk = "rng_fck", + .prcm = { + .omap4 = { + .clkctrl_offs = AM33XX_CM_PER_RNG_CLKCTRL_OFFSET, + .modulemode = MODULEMODE_SWCTRL, + }, + }, +}; + +static struct omap_hwmod_ocp_if am33xx_l4_per__rng = { + .master = &am33xx_l4_ls_hwmod, + .slave = &am33xx_rng_hwmod, + .clk = "rng_fck", + .user = OCP_USER_MPU, +}; + static struct omap_hwmod_ocp_if *am33xx_hwmod_ocp_ifs[] __initdata = { &am33xx_l3_main__emif, &am33xx_mpu__l3_main, @@ -2559,6 +2607,7 @@ static struct omap_hwmod_ocp_if *am33xx_hwmod_ocp_ifs[] __initdata = { &am33xx_cpgmac0__mdio, &am33xx_l3_main__sha0, &am33xx_l3_main__aes0, + &am33xx_l4_per__rng, NULL, }; diff --git a/arch/arm/mach-omap2/omap_hwmod_3xxx_data.c b/arch/arm/mach-omap2/omap_hwmod_3xxx_data.c index 0c3a427da544..9e56fabd7fa3 100644 --- a/arch/arm/mach-omap2/omap_hwmod_3xxx_data.c +++ b/arch/arm/mach-omap2/omap_hwmod_3xxx_data.c @@ -3693,6 +3693,53 @@ static struct omap_hwmod_ocp_if omap3xxx_l4_core__aes = { .user = OCP_USER_MPU | OCP_USER_SDMA, }; +/* + * 'ssi' class + * synchronous serial interface (multichannel and full-duplex serial if) + */ + +static struct omap_hwmod_class_sysconfig omap34xx_ssi_sysc = { + .rev_offs = 0x0000, + .sysc_offs = 0x0010, + .syss_offs = 0x0014, + .sysc_flags = (SYSC_HAS_AUTOIDLE | SYSC_HAS_EMUFREE | + SYSC_HAS_MIDLEMODE | SYSC_HAS_SIDLEMODE | + SYSC_HAS_SOFTRESET | SYSS_HAS_RESET_STATUS), + .idlemodes = (SIDLE_FORCE | SIDLE_NO | SIDLE_SMART | + SIDLE_SMART_WKUP | MSTANDBY_FORCE | MSTANDBY_NO | + MSTANDBY_SMART | MSTANDBY_SMART_WKUP), + .sysc_fields = &omap_hwmod_sysc_type1, +}; + +static struct omap_hwmod_class omap34xx_ssi_hwmod_class = { + .name = "ssi", + .sysc = &omap34xx_ssi_sysc, +}; + +static struct omap_hwmod omap34xx_ssi_hwmod = { + .name = "ssi", + .class = &omap34xx_ssi_hwmod_class, + .clkdm_name = "core_l4_clkdm", + .main_clk = "ssi_ssr_fck", + .prcm = { + .omap2 = { + .prcm_reg_id = 1, + .module_bit = OMAP3430_EN_SSI_SHIFT, + .module_offs = CORE_MOD, + .idlest_reg_id = 1, + .idlest_idle_bit = OMAP3430ES2_ST_SSI_IDLE_SHIFT, + }, + }, +}; + +/* L4 CORE -> SSI */ +static struct omap_hwmod_ocp_if omap34xx_l4_core__ssi = { + .master = &omap3xxx_l4_core_hwmod, + .slave = &omap34xx_ssi_hwmod, + .clk = "ssi_ick", + .user = OCP_USER_MPU | OCP_USER_SDMA, +}; + static struct omap_hwmod_ocp_if *omap3xxx_hwmod_ocp_ifs[] __initdata = { &omap3xxx_l3_main__l4_core, &omap3xxx_l3_main__l4_per, @@ -3818,6 +3865,7 @@ static struct omap_hwmod_ocp_if *omap34xx_hwmod_ocp_ifs[] __initdata = { #ifdef CONFIG_OMAP_IOMMU_IVA2 &omap3xxx_l3_main__mmu_iva, #endif + &omap34xx_l4_core__ssi, NULL }; diff --git a/arch/arm/mach-omap2/omap_hwmod_44xx_data.c b/arch/arm/mach-omap2/omap_hwmod_44xx_data.c index 9c3b504477d7..1e5b12cb8246 100644 --- a/arch/arm/mach-omap2/omap_hwmod_44xx_data.c +++ b/arch/arm/mach-omap2/omap_hwmod_44xx_data.c @@ -914,7 +914,7 @@ static struct omap_hwmod omap44xx_emif1_hwmod = { .name = "emif1", .class = &omap44xx_emif_hwmod_class, .clkdm_name = "l3_emif_clkdm", - .flags = HWMOD_INIT_NO_IDLE | HWMOD_INIT_NO_RESET, + .flags = HWMOD_INIT_NO_IDLE, .main_clk = "ddrphy_ck", .prcm = { .omap4 = { @@ -930,7 +930,7 @@ static struct omap_hwmod omap44xx_emif2_hwmod = { .name = "emif2", .class = &omap44xx_emif_hwmod_class, .clkdm_name = "l3_emif_clkdm", - .flags = HWMOD_INIT_NO_IDLE | HWMOD_INIT_NO_RESET, + .flags = HWMOD_INIT_NO_IDLE, .main_clk = "ddrphy_ck", .prcm = { .omap4 = { @@ -2193,7 +2193,7 @@ static struct omap_hwmod omap44xx_mpu_hwmod = { .name = "mpu", .class = &omap44xx_mpu_hwmod_class, .clkdm_name = "mpuss_clkdm", - .flags = HWMOD_INIT_NO_IDLE | HWMOD_INIT_NO_RESET, + .flags = HWMOD_INIT_NO_IDLE, .main_clk = "dpll_mpu_m2_ck", .prcm = { .omap4 = { diff --git a/arch/arm/mach-omap2/omap_hwmod_54xx_data.c b/arch/arm/mach-omap2/omap_hwmod_54xx_data.c index cde415570e04..9e08d6994a0b 100644 --- a/arch/arm/mach-omap2/omap_hwmod_54xx_data.c +++ b/arch/arm/mach-omap2/omap_hwmod_54xx_data.c @@ -352,7 +352,7 @@ static struct omap_hwmod omap54xx_emif1_hwmod = { .name = "emif1", .class = &omap54xx_emif_hwmod_class, .clkdm_name = "emif_clkdm", - .flags = HWMOD_INIT_NO_IDLE | HWMOD_INIT_NO_RESET, + .flags = HWMOD_INIT_NO_IDLE, .main_clk = "dpll_core_h11x2_ck", .prcm = { .omap4 = { @@ -368,7 +368,7 @@ static struct omap_hwmod omap54xx_emif2_hwmod = { .name = "emif2", .class = &omap54xx_emif_hwmod_class, .clkdm_name = "emif_clkdm", - .flags = HWMOD_INIT_NO_IDLE | HWMOD_INIT_NO_RESET, + .flags = HWMOD_INIT_NO_IDLE, .main_clk = "dpll_core_h11x2_ck", .prcm = { .omap4 = { @@ -1135,7 +1135,7 @@ static struct omap_hwmod omap54xx_mpu_hwmod = { .name = "mpu", .class = &omap54xx_mpu_hwmod_class, .clkdm_name = "mpu_clkdm", - .flags = HWMOD_INIT_NO_IDLE | HWMOD_INIT_NO_RESET, + .flags = HWMOD_INIT_NO_IDLE, .main_clk = "dpll_mpu_m2_ck", .prcm = { .omap4 = { @@ -1146,6 +1146,77 @@ static struct omap_hwmod omap54xx_mpu_hwmod = { }; /* + * 'spinlock' class + * spinlock provides hardware assistance for synchronizing the processes + * running on multiple processors + */ + +static struct omap_hwmod_class_sysconfig omap54xx_spinlock_sysc = { + .rev_offs = 0x0000, + .sysc_offs = 0x0010, + .syss_offs = 0x0014, + .sysc_flags = (SYSC_HAS_AUTOIDLE | SYSC_HAS_CLOCKACTIVITY | + SYSC_HAS_ENAWAKEUP | SYSC_HAS_SIDLEMODE | + SYSC_HAS_SOFTRESET | SYSS_HAS_RESET_STATUS), + .idlemodes = (SIDLE_FORCE | SIDLE_NO | SIDLE_SMART), + .sysc_fields = &omap_hwmod_sysc_type1, +}; + +static struct omap_hwmod_class omap54xx_spinlock_hwmod_class = { + .name = "spinlock", + .sysc = &omap54xx_spinlock_sysc, +}; + +/* spinlock */ +static struct omap_hwmod omap54xx_spinlock_hwmod = { + .name = "spinlock", + .class = &omap54xx_spinlock_hwmod_class, + .clkdm_name = "l4cfg_clkdm", + .prcm = { + .omap4 = { + .clkctrl_offs = OMAP54XX_CM_L4CFG_SPINLOCK_CLKCTRL_OFFSET, + .context_offs = OMAP54XX_RM_L4CFG_SPINLOCK_CONTEXT_OFFSET, + }, + }, +}; + +/* + * 'ocp2scp' class + * bridge to transform ocp interface protocol to scp (serial control port) + * protocol + */ + +static struct omap_hwmod_class_sysconfig omap54xx_ocp2scp_sysc = { + .rev_offs = 0x0000, + .sysc_offs = 0x0010, + .syss_offs = 0x0014, + .sysc_flags = (SYSC_HAS_AUTOIDLE | SYSC_HAS_SIDLEMODE | + SYSC_HAS_SOFTRESET | SYSS_HAS_RESET_STATUS), + .idlemodes = (SIDLE_FORCE | SIDLE_NO | SIDLE_SMART), + .sysc_fields = &omap_hwmod_sysc_type1, +}; + +static struct omap_hwmod_class omap54xx_ocp2scp_hwmod_class = { + .name = "ocp2scp", + .sysc = &omap54xx_ocp2scp_sysc, +}; + +/* ocp2scp1 */ +static struct omap_hwmod omap54xx_ocp2scp1_hwmod = { + .name = "ocp2scp1", + .class = &omap54xx_ocp2scp_hwmod_class, + .clkdm_name = "l3init_clkdm", + .main_clk = "l4_root_clk_div", + .prcm = { + .omap4 = { + .clkctrl_offs = OMAP54XX_CM_L3INIT_OCP2SCP1_CLKCTRL_OFFSET, + .context_offs = OMAP54XX_RM_L3INIT_OCP2SCP1_CONTEXT_OFFSET, + .modulemode = MODULEMODE_HWCTRL, + }, + }, +}; + +/* * 'timer' class * general purpose timer module with accurate 1ms tick * This class contains several variants: ['timer_1ms', 'timer'] @@ -1465,6 +1536,123 @@ static struct omap_hwmod omap54xx_uart6_hwmod = { }; /* + * 'usb_host_hs' class + * high-speed multi-port usb host controller + */ + +static struct omap_hwmod_class_sysconfig omap54xx_usb_host_hs_sysc = { + .rev_offs = 0x0000, + .sysc_offs = 0x0010, + .sysc_flags = (SYSC_HAS_MIDLEMODE | SYSC_HAS_RESET_STATUS | + SYSC_HAS_SIDLEMODE | SYSC_HAS_SOFTRESET), + .idlemodes = (SIDLE_FORCE | SIDLE_NO | SIDLE_SMART | + SIDLE_SMART_WKUP | MSTANDBY_FORCE | MSTANDBY_NO | + MSTANDBY_SMART | MSTANDBY_SMART_WKUP), + .sysc_fields = &omap_hwmod_sysc_type2, +}; + +static struct omap_hwmod_class omap54xx_usb_host_hs_hwmod_class = { + .name = "usb_host_hs", + .sysc = &omap54xx_usb_host_hs_sysc, +}; + +static struct omap_hwmod omap54xx_usb_host_hs_hwmod = { + .name = "usb_host_hs", + .class = &omap54xx_usb_host_hs_hwmod_class, + .clkdm_name = "l3init_clkdm", + /* + * Errata: USBHOST Configured In Smart-Idle Can Lead To a Deadlock + * id: i660 + * + * Description: + * In the following configuration : + * - USBHOST module is set to smart-idle mode + * - PRCM asserts idle_req to the USBHOST module ( This typically + * happens when the system is going to a low power mode : all ports + * have been suspended, the master part of the USBHOST module has + * entered the standby state, and SW has cut the functional clocks) + * - an USBHOST interrupt occurs before the module is able to answer + * idle_ack, typically a remote wakeup IRQ. + * Then the USB HOST module will enter a deadlock situation where it + * is no more accessible nor functional. + * + * Workaround: + * Don't use smart idle; use only force idle, hence HWMOD_SWSUP_SIDLE + */ + + /* + * Errata: USB host EHCI may stall when entering smart-standby mode + * Id: i571 + * + * Description: + * When the USBHOST module is set to smart-standby mode, and when it is + * ready to enter the standby state (i.e. all ports are suspended and + * all attached devices are in suspend mode), then it can wrongly assert + * the Mstandby signal too early while there are still some residual OCP + * transactions ongoing. If this condition occurs, the internal state + * machine may go to an undefined state and the USB link may be stuck + * upon the next resume. + * + * Workaround: + * Don't use smart standby; use only force standby, + * hence HWMOD_SWSUP_MSTANDBY + */ + + /* + * During system boot; If the hwmod framework resets the module + * the module will have smart idle settings; which can lead to deadlock + * (above Errata Id:i660); so, dont reset the module during boot; + * Use HWMOD_INIT_NO_RESET. + */ + + .flags = HWMOD_SWSUP_SIDLE | HWMOD_SWSUP_MSTANDBY | + HWMOD_INIT_NO_RESET, + .main_clk = "l3init_60m_fclk", + .prcm = { + .omap4 = { + .clkctrl_offs = OMAP54XX_CM_L3INIT_USB_HOST_HS_CLKCTRL_OFFSET, + .context_offs = OMAP54XX_RM_L3INIT_USB_HOST_HS_CONTEXT_OFFSET, + .modulemode = MODULEMODE_SWCTRL, + }, + }, +}; + +/* + * 'usb_tll_hs' class + * usb_tll_hs module is the adapter on the usb_host_hs ports + */ + +static struct omap_hwmod_class_sysconfig omap54xx_usb_tll_hs_sysc = { + .rev_offs = 0x0000, + .sysc_offs = 0x0010, + .syss_offs = 0x0014, + .sysc_flags = (SYSC_HAS_AUTOIDLE | SYSC_HAS_CLOCKACTIVITY | + SYSC_HAS_ENAWAKEUP | SYSC_HAS_SIDLEMODE | + SYSC_HAS_SOFTRESET | SYSS_HAS_RESET_STATUS), + .idlemodes = (SIDLE_FORCE | SIDLE_NO | SIDLE_SMART), + .sysc_fields = &omap_hwmod_sysc_type1, +}; + +static struct omap_hwmod_class omap54xx_usb_tll_hs_hwmod_class = { + .name = "usb_tll_hs", + .sysc = &omap54xx_usb_tll_hs_sysc, +}; + +static struct omap_hwmod omap54xx_usb_tll_hs_hwmod = { + .name = "usb_tll_hs", + .class = &omap54xx_usb_tll_hs_hwmod_class, + .clkdm_name = "l3init_clkdm", + .main_clk = "l4_root_clk_div", + .prcm = { + .omap4 = { + .clkctrl_offs = OMAP54XX_CM_L3INIT_USB_TLL_HS_CLKCTRL_OFFSET, + .context_offs = OMAP54XX_RM_L3INIT_USB_TLL_HS_CONTEXT_OFFSET, + .modulemode = MODULEMODE_HWCTRL, + }, + }, +}; + +/* * 'usb_otg_ss' class * 2.0 super speed (usb_otg_ss) controller */ @@ -1960,6 +2148,22 @@ static struct omap_hwmod_ocp_if omap54xx_l4_cfg__mpu = { .user = OCP_USER_MPU | OCP_USER_SDMA, }; +/* l4_cfg -> spinlock */ +static struct omap_hwmod_ocp_if omap54xx_l4_cfg__spinlock = { + .master = &omap54xx_l4_cfg_hwmod, + .slave = &omap54xx_spinlock_hwmod, + .clk = "l4_root_clk_div", + .user = OCP_USER_MPU | OCP_USER_SDMA, +}; + +/* l4_cfg -> ocp2scp1 */ +static struct omap_hwmod_ocp_if omap54xx_l4_cfg__ocp2scp1 = { + .master = &omap54xx_l4_cfg_hwmod, + .slave = &omap54xx_ocp2scp1_hwmod, + .clk = "l4_root_clk_div", + .user = OCP_USER_MPU | OCP_USER_SDMA, +}; + /* l4_wkup -> timer1 */ static struct omap_hwmod_ocp_if omap54xx_l4_wkup__timer1 = { .master = &omap54xx_l4_wkup_hwmod, @@ -2096,6 +2300,22 @@ static struct omap_hwmod_ocp_if omap54xx_l4_per__uart6 = { .user = OCP_USER_MPU | OCP_USER_SDMA, }; +/* l4_cfg -> usb_host_hs */ +static struct omap_hwmod_ocp_if omap54xx_l4_cfg__usb_host_hs = { + .master = &omap54xx_l4_cfg_hwmod, + .slave = &omap54xx_usb_host_hs_hwmod, + .clk = "l3_iclk_div", + .user = OCP_USER_MPU | OCP_USER_SDMA, +}; + +/* l4_cfg -> usb_tll_hs */ +static struct omap_hwmod_ocp_if omap54xx_l4_cfg__usb_tll_hs = { + .master = &omap54xx_l4_cfg_hwmod, + .slave = &omap54xx_usb_tll_hs_hwmod, + .clk = "l4_root_clk_div", + .user = OCP_USER_MPU | OCP_USER_SDMA, +}; + /* l4_cfg -> usb_otg_ss */ static struct omap_hwmod_ocp_if omap54xx_l4_cfg__usb_otg_ss = { .master = &omap54xx_l4_cfg_hwmod, @@ -2163,6 +2383,8 @@ static struct omap_hwmod_ocp_if *omap54xx_hwmod_ocp_ifs[] __initdata = { &omap54xx_l4_per__mmc4, &omap54xx_l4_per__mmc5, &omap54xx_l4_cfg__mpu, + &omap54xx_l4_cfg__spinlock, + &omap54xx_l4_cfg__ocp2scp1, &omap54xx_l4_wkup__timer1, &omap54xx_l4_per__timer2, &omap54xx_l4_per__timer3, @@ -2180,6 +2402,8 @@ static struct omap_hwmod_ocp_if *omap54xx_hwmod_ocp_ifs[] __initdata = { &omap54xx_l4_per__uart4, &omap54xx_l4_per__uart5, &omap54xx_l4_per__uart6, + &omap54xx_l4_cfg__usb_host_hs, + &omap54xx_l4_cfg__usb_tll_hs, &omap54xx_l4_cfg__usb_otg_ss, &omap54xx_l4_wkup__wd_timer2, NULL, diff --git a/arch/arm/mach-omap2/soc.h b/arch/arm/mach-omap2/soc.h index 4588df1447ed..076bd90a6ce0 100644 --- a/arch/arm/mach-omap2/soc.h +++ b/arch/arm/mach-omap2/soc.h @@ -455,9 +455,7 @@ IS_OMAP_TYPE(3430, 0x3430) #define OMAP4470_REV_ES1_0 (OMAP447X_CLASS | (0x10 << 8)) #define OMAP54XX_CLASS 0x54000054 -#define OMAP5430_REV_ES1_0 (OMAP54XX_CLASS | (0x30 << 16) | (0x10 << 8)) #define OMAP5430_REV_ES2_0 (OMAP54XX_CLASS | (0x30 << 16) | (0x20 << 8)) -#define OMAP5432_REV_ES1_0 (OMAP54XX_CLASS | (0x32 << 16) | (0x10 << 8)) #define OMAP5432_REV_ES2_0 (OMAP54XX_CLASS | (0x32 << 16) | (0x20 << 8)) void omap2xxx_check_revision(void); diff --git a/arch/arm/mach-omap2/timer.c b/arch/arm/mach-omap2/timer.c index fa74a0625da1..d59b51f07cf2 100644 --- a/arch/arm/mach-omap2/timer.c +++ b/arch/arm/mach-omap2/timer.c @@ -55,6 +55,7 @@ #include "soc.h" #include "common.h" #include "powerdomain.h" +#include "omap-secure.h" #define REALTIME_COUNTER_BASE 0x48243200 #define INCREMENTER_NUMERATOR_OFFSET 0x10 @@ -66,6 +67,15 @@ static struct omap_dm_timer clkev; static struct clock_event_device clockevent_gpt; +#ifdef CONFIG_SOC_HAS_REALTIME_COUNTER +static unsigned long arch_timer_freq; + +void set_cntfreq(void) +{ + omap_smc1(OMAP5_DRA7_MON_SET_CNTFRQ_INDEX, arch_timer_freq); +} +#endif + static irqreturn_t omap2_gp_timer_interrupt(int irq, void *dev_id) { struct clock_event_device *evt = &clockevent_gpt; @@ -515,6 +525,10 @@ static void __init realtime_counter_init(void) num = 8; den = 25; break; + case 20000000: + num = 192; + den = 625; + break; case 2600000: num = 384; den = 1625; @@ -542,6 +556,9 @@ static void __init realtime_counter_init(void) reg |= den; __raw_writel(reg, base + INCREMENTER_DENUMERATOR_RELOAD_OFFSET); + arch_timer_freq = (rate / den) * num; + set_cntfreq(); + iounmap(base); } #else diff --git a/arch/arm/mach-s3c64xx/Makefile b/arch/arm/mach-s3c64xx/Makefile index 31d0c9101272..645a8fe55f8d 100644 --- a/arch/arm/mach-s3c64xx/Makefile +++ b/arch/arm/mach-s3c64xx/Makefile @@ -12,7 +12,7 @@ obj- := # Core -obj-y += common.o clock.o +obj-y += common.o # Core support diff --git a/arch/arm/mach-s3c64xx/clock.c b/arch/arm/mach-s3c64xx/clock.c deleted file mode 100644 index c1bcc4a6d3a8..000000000000 --- a/arch/arm/mach-s3c64xx/clock.c +++ /dev/null @@ -1,1007 +0,0 @@ -/* linux/arch/arm/plat-s3c64xx/clock.c - * - * Copyright 2008 Openmoko, Inc. - * Copyright 2008 Simtec Electronics - * Ben Dooks <ben@simtec.co.uk> - * http://armlinux.simtec.co.uk/ - * - * S3C64XX Base clock support - * - * 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/module.h> -#include <linux/interrupt.h> -#include <linux/ioport.h> -#include <linux/clk.h> -#include <linux/err.h> -#include <linux/io.h> - -#include <mach/hardware.h> -#include <mach/map.h> - -#include <mach/regs-clock.h> - -#include <plat/cpu.h> -#include <plat/devs.h> -#include <plat/cpu-freq.h> -#include <plat/clock.h> -#include <plat/clock-clksrc.h> -#include <plat/pll.h> - -#include "regs-sys.h" - -/* fin_apll, fin_mpll and fin_epll are all the same clock, which we call - * ext_xtal_mux for want of an actual name from the manual. -*/ - -static struct clk clk_ext_xtal_mux = { - .name = "ext_xtal", -}; - -#define clk_fin_apll clk_ext_xtal_mux -#define clk_fin_mpll clk_ext_xtal_mux -#define clk_fin_epll clk_ext_xtal_mux - -#define clk_fout_mpll clk_mpll -#define clk_fout_epll clk_epll - -struct clk clk_h2 = { - .name = "hclk2", - .rate = 0, -}; - -struct clk clk_27m = { - .name = "clk_27m", - .rate = 27000000, -}; - -static int clk_48m_ctrl(struct clk *clk, int enable) -{ - unsigned long flags; - u32 val; - - /* can't rely on clock lock, this register has other usages */ - local_irq_save(flags); - - val = __raw_readl(S3C64XX_OTHERS); - if (enable) - val |= S3C64XX_OTHERS_USBMASK; - else - val &= ~S3C64XX_OTHERS_USBMASK; - - __raw_writel(val, S3C64XX_OTHERS); - local_irq_restore(flags); - - return 0; -} - -struct clk clk_48m = { - .name = "clk_48m", - .rate = 48000000, - .enable = clk_48m_ctrl, -}; - -struct clk clk_xusbxti = { - .name = "xusbxti", - .rate = 48000000, -}; - -static int inline s3c64xx_gate(void __iomem *reg, - struct clk *clk, - int enable) -{ - unsigned int ctrlbit = clk->ctrlbit; - u32 con; - - con = __raw_readl(reg); - - if (enable) - con |= ctrlbit; - else - con &= ~ctrlbit; - - __raw_writel(con, reg); - return 0; -} - -static int s3c64xx_pclk_ctrl(struct clk *clk, int enable) -{ - return s3c64xx_gate(S3C_PCLK_GATE, clk, enable); -} - -static int s3c64xx_hclk_ctrl(struct clk *clk, int enable) -{ - return s3c64xx_gate(S3C_HCLK_GATE, clk, enable); -} - -int s3c64xx_sclk_ctrl(struct clk *clk, int enable) -{ - return s3c64xx_gate(S3C_SCLK_GATE, clk, enable); -} - -static struct clk init_clocks_off[] = { - { - .name = "nand", - .parent = &clk_h, - }, { - .name = "rtc", - .parent = &clk_p, - .enable = s3c64xx_pclk_ctrl, - .ctrlbit = S3C_CLKCON_PCLK_RTC, - }, { - .name = "adc", - .parent = &clk_p, - .enable = s3c64xx_pclk_ctrl, - .ctrlbit = S3C_CLKCON_PCLK_TSADC, - }, { - .name = "i2c", - .devname = "s3c2440-i2c.0", - .parent = &clk_p, - .enable = s3c64xx_pclk_ctrl, - .ctrlbit = S3C_CLKCON_PCLK_IIC, - }, { - .name = "i2c", - .devname = "s3c2440-i2c.1", - .parent = &clk_p, - .enable = s3c64xx_pclk_ctrl, - .ctrlbit = S3C6410_CLKCON_PCLK_I2C1, - }, { - .name = "keypad", - .parent = &clk_p, - .enable = s3c64xx_pclk_ctrl, - .ctrlbit = S3C_CLKCON_PCLK_KEYPAD, - }, { - .name = "spi", - .devname = "s3c6410-spi.0", - .parent = &clk_p, - .enable = s3c64xx_pclk_ctrl, - .ctrlbit = S3C_CLKCON_PCLK_SPI0, - }, { - .name = "spi", - .devname = "s3c6410-spi.1", - .parent = &clk_p, - .enable = s3c64xx_pclk_ctrl, - .ctrlbit = S3C_CLKCON_PCLK_SPI1, - }, { - .name = "48m", - .devname = "s3c-sdhci.0", - .parent = &clk_48m, - .enable = s3c64xx_sclk_ctrl, - .ctrlbit = S3C_CLKCON_SCLK_MMC0_48, - }, { - .name = "48m", - .devname = "s3c-sdhci.1", - .parent = &clk_48m, - .enable = s3c64xx_sclk_ctrl, - .ctrlbit = S3C_CLKCON_SCLK_MMC1_48, - }, { - .name = "48m", - .devname = "s3c-sdhci.2", - .parent = &clk_48m, - .enable = s3c64xx_sclk_ctrl, - .ctrlbit = S3C_CLKCON_SCLK_MMC2_48, - }, { - .name = "ac97", - .parent = &clk_p, - .ctrlbit = S3C_CLKCON_PCLK_AC97, - }, { - .name = "cfcon", - .parent = &clk_h, - .enable = s3c64xx_hclk_ctrl, - .ctrlbit = S3C_CLKCON_HCLK_IHOST, - }, { - .name = "dma0", - .parent = &clk_h, - .enable = s3c64xx_hclk_ctrl, - .ctrlbit = S3C_CLKCON_HCLK_DMA0, - }, { - .name = "dma1", - .parent = &clk_h, - .enable = s3c64xx_hclk_ctrl, - .ctrlbit = S3C_CLKCON_HCLK_DMA1, - }, { - .name = "3dse", - .parent = &clk_h, - .enable = s3c64xx_hclk_ctrl, - .ctrlbit = S3C_CLKCON_HCLK_3DSE, - }, { - .name = "hclk_secur", - .parent = &clk_h, - .enable = s3c64xx_hclk_ctrl, - .ctrlbit = S3C_CLKCON_HCLK_SECUR, - }, { - .name = "sdma1", - .parent = &clk_h, - .enable = s3c64xx_hclk_ctrl, - .ctrlbit = S3C_CLKCON_HCLK_SDMA1, - }, { - .name = "sdma0", - .parent = &clk_h, - .enable = s3c64xx_hclk_ctrl, - .ctrlbit = S3C_CLKCON_HCLK_SDMA0, - }, { - .name = "hclk_jpeg", - .parent = &clk_h, - .enable = s3c64xx_hclk_ctrl, - .ctrlbit = S3C_CLKCON_HCLK_JPEG, - }, { - .name = "camif", - .parent = &clk_h, - .enable = s3c64xx_hclk_ctrl, - .ctrlbit = S3C_CLKCON_HCLK_CAMIF, - }, { - .name = "hclk_scaler", - .parent = &clk_h, - .enable = s3c64xx_hclk_ctrl, - .ctrlbit = S3C_CLKCON_HCLK_SCALER, - }, { - .name = "2d", - .parent = &clk_h, - .enable = s3c64xx_hclk_ctrl, - .ctrlbit = S3C_CLKCON_HCLK_2D, - }, { - .name = "tv", - .parent = &clk_h, - .enable = s3c64xx_hclk_ctrl, - .ctrlbit = S3C_CLKCON_HCLK_TV, - }, { - .name = "post0", - .parent = &clk_h, - .enable = s3c64xx_hclk_ctrl, - .ctrlbit = S3C_CLKCON_HCLK_POST0, - }, { - .name = "rot", - .parent = &clk_h, - .enable = s3c64xx_hclk_ctrl, - .ctrlbit = S3C_CLKCON_HCLK_ROT, - }, { - .name = "hclk_mfc", - .parent = &clk_h, - .enable = s3c64xx_hclk_ctrl, - .ctrlbit = S3C_CLKCON_HCLK_MFC, - }, { - .name = "pclk_mfc", - .parent = &clk_p, - .enable = s3c64xx_pclk_ctrl, - .ctrlbit = S3C_CLKCON_PCLK_MFC, - }, { - .name = "dac27", - .enable = s3c64xx_sclk_ctrl, - .ctrlbit = S3C_CLKCON_SCLK_DAC27, - }, { - .name = "tv27", - .enable = s3c64xx_sclk_ctrl, - .ctrlbit = S3C_CLKCON_SCLK_TV27, - }, { - .name = "scaler27", - .enable = s3c64xx_sclk_ctrl, - .ctrlbit = S3C_CLKCON_SCLK_SCALER27, - }, { - .name = "sclk_scaler", - .enable = s3c64xx_sclk_ctrl, - .ctrlbit = S3C_CLKCON_SCLK_SCALER, - }, { - .name = "post0_27", - .enable = s3c64xx_sclk_ctrl, - .ctrlbit = S3C_CLKCON_SCLK_POST0_27, - }, { - .name = "secur", - .enable = s3c64xx_sclk_ctrl, - .ctrlbit = S3C_CLKCON_SCLK_SECUR, - }, { - .name = "sclk_mfc", - .enable = s3c64xx_sclk_ctrl, - .ctrlbit = S3C_CLKCON_SCLK_MFC, - }, { - .name = "sclk_jpeg", - .enable = s3c64xx_sclk_ctrl, - .ctrlbit = S3C_CLKCON_SCLK_JPEG, - }, -}; - -static struct clk clk_48m_spi0 = { - .name = "spi_48m", - .devname = "s3c6410-spi.0", - .parent = &clk_48m, - .enable = s3c64xx_sclk_ctrl, - .ctrlbit = S3C_CLKCON_SCLK_SPI0_48, -}; - -static struct clk clk_48m_spi1 = { - .name = "spi_48m", - .devname = "s3c6410-spi.1", - .parent = &clk_48m, - .enable = s3c64xx_sclk_ctrl, - .ctrlbit = S3C_CLKCON_SCLK_SPI1_48, -}; - -static struct clk clk_i2s0 = { - .name = "iis", - .devname = "samsung-i2s.0", - .parent = &clk_p, - .enable = s3c64xx_pclk_ctrl, - .ctrlbit = S3C_CLKCON_PCLK_IIS0, -}; - -static struct clk clk_i2s1 = { - .name = "iis", - .devname = "samsung-i2s.1", - .parent = &clk_p, - .enable = s3c64xx_pclk_ctrl, - .ctrlbit = S3C_CLKCON_PCLK_IIS1, -}; - -#ifdef CONFIG_CPU_S3C6410 -static struct clk clk_i2s2 = { - .name = "iis", - .devname = "samsung-i2s.2", - .parent = &clk_p, - .enable = s3c64xx_pclk_ctrl, - .ctrlbit = S3C6410_CLKCON_PCLK_IIS2, -}; -#endif - -static struct clk init_clocks[] = { - { - .name = "lcd", - .parent = &clk_h, - .enable = s3c64xx_hclk_ctrl, - .ctrlbit = S3C_CLKCON_HCLK_LCD, - }, { - .name = "gpio", - .parent = &clk_p, - .enable = s3c64xx_pclk_ctrl, - .ctrlbit = S3C_CLKCON_PCLK_GPIO, - }, { - .name = "usb-host", - .parent = &clk_h, - .enable = s3c64xx_hclk_ctrl, - .ctrlbit = S3C_CLKCON_HCLK_UHOST, - }, { - .name = "otg", - .parent = &clk_h, - .enable = s3c64xx_hclk_ctrl, - .ctrlbit = S3C_CLKCON_HCLK_USB, - }, { - .name = "timers", - .parent = &clk_p, - .enable = s3c64xx_pclk_ctrl, - .ctrlbit = S3C_CLKCON_PCLK_PWM, - }, { - .name = "uart", - .devname = "s3c6400-uart.0", - .parent = &clk_p, - .enable = s3c64xx_pclk_ctrl, - .ctrlbit = S3C_CLKCON_PCLK_UART0, - }, { - .name = "uart", - .devname = "s3c6400-uart.1", - .parent = &clk_p, - .enable = s3c64xx_pclk_ctrl, - .ctrlbit = S3C_CLKCON_PCLK_UART1, - }, { - .name = "uart", - .devname = "s3c6400-uart.2", - .parent = &clk_p, - .enable = s3c64xx_pclk_ctrl, - .ctrlbit = S3C_CLKCON_PCLK_UART2, - }, { - .name = "uart", - .devname = "s3c6400-uart.3", - .parent = &clk_p, - .enable = s3c64xx_pclk_ctrl, - .ctrlbit = S3C_CLKCON_PCLK_UART3, - }, { - .name = "watchdog", - .parent = &clk_p, - .ctrlbit = S3C_CLKCON_PCLK_WDT, - }, -}; - -static struct clk clk_hsmmc0 = { - .name = "hsmmc", - .devname = "s3c-sdhci.0", - .parent = &clk_h, - .enable = s3c64xx_hclk_ctrl, - .ctrlbit = S3C_CLKCON_HCLK_HSMMC0, -}; - -static struct clk clk_hsmmc1 = { - .name = "hsmmc", - .devname = "s3c-sdhci.1", - .parent = &clk_h, - .enable = s3c64xx_hclk_ctrl, - .ctrlbit = S3C_CLKCON_HCLK_HSMMC1, -}; - -static struct clk clk_hsmmc2 = { - .name = "hsmmc", - .devname = "s3c-sdhci.2", - .parent = &clk_h, - .enable = s3c64xx_hclk_ctrl, - .ctrlbit = S3C_CLKCON_HCLK_HSMMC2, -}; - -static struct clk clk_fout_apll = { - .name = "fout_apll", -}; - -static struct clk *clk_src_apll_list[] = { - [0] = &clk_fin_apll, - [1] = &clk_fout_apll, -}; - -static struct clksrc_sources clk_src_apll = { - .sources = clk_src_apll_list, - .nr_sources = ARRAY_SIZE(clk_src_apll_list), -}; - -static struct clksrc_clk clk_mout_apll = { - .clk = { - .name = "mout_apll", - }, - .reg_src = { .reg = S3C_CLK_SRC, .shift = 0, .size = 1 }, - .sources = &clk_src_apll, -}; - -static struct clk *clk_src_epll_list[] = { - [0] = &clk_fin_epll, - [1] = &clk_fout_epll, -}; - -static struct clksrc_sources clk_src_epll = { - .sources = clk_src_epll_list, - .nr_sources = ARRAY_SIZE(clk_src_epll_list), -}; - -static struct clksrc_clk clk_mout_epll = { - .clk = { - .name = "mout_epll", - }, - .reg_src = { .reg = S3C_CLK_SRC, .shift = 2, .size = 1 }, - .sources = &clk_src_epll, -}; - -static struct clk *clk_src_mpll_list[] = { - [0] = &clk_fin_mpll, - [1] = &clk_fout_mpll, -}; - -static struct clksrc_sources clk_src_mpll = { - .sources = clk_src_mpll_list, - .nr_sources = ARRAY_SIZE(clk_src_mpll_list), -}; - -static struct clksrc_clk clk_mout_mpll = { - .clk = { - .name = "mout_mpll", - }, - .reg_src = { .reg = S3C_CLK_SRC, .shift = 1, .size = 1 }, - .sources = &clk_src_mpll, -}; - -static unsigned int armclk_mask; - -static unsigned long s3c64xx_clk_arm_get_rate(struct clk *clk) -{ - unsigned long rate = clk_get_rate(clk->parent); - u32 clkdiv; - - /* divisor mask starts at bit0, so no need to shift */ - clkdiv = __raw_readl(S3C_CLK_DIV0) & armclk_mask; - - return rate / (clkdiv + 1); -} - -static unsigned long s3c64xx_clk_arm_round_rate(struct clk *clk, - unsigned long rate) -{ - unsigned long parent = clk_get_rate(clk->parent); - u32 div; - - if (parent < rate) - return parent; - - div = (parent / rate) - 1; - if (div > armclk_mask) - div = armclk_mask; - - return parent / (div + 1); -} - -static int s3c64xx_clk_arm_set_rate(struct clk *clk, unsigned long rate) -{ - unsigned long parent = clk_get_rate(clk->parent); - u32 div; - u32 val; - - if (rate < parent / (armclk_mask + 1)) - return -EINVAL; - - rate = clk_round_rate(clk, rate); - div = clk_get_rate(clk->parent) / rate; - - val = __raw_readl(S3C_CLK_DIV0); - val &= ~armclk_mask; - val |= (div - 1); - __raw_writel(val, S3C_CLK_DIV0); - - return 0; - -} - -static struct clk clk_arm = { - .name = "armclk", - .parent = &clk_mout_apll.clk, - .ops = &(struct clk_ops) { - .get_rate = s3c64xx_clk_arm_get_rate, - .set_rate = s3c64xx_clk_arm_set_rate, - .round_rate = s3c64xx_clk_arm_round_rate, - }, -}; - -static unsigned long s3c64xx_clk_doutmpll_get_rate(struct clk *clk) -{ - unsigned long rate = clk_get_rate(clk->parent); - - printk(KERN_DEBUG "%s: parent is %ld\n", __func__, rate); - - if (__raw_readl(S3C_CLK_DIV0) & S3C6400_CLKDIV0_MPLL_MASK) - rate /= 2; - - return rate; -} - -static struct clk_ops clk_dout_ops = { - .get_rate = s3c64xx_clk_doutmpll_get_rate, -}; - -static struct clk clk_dout_mpll = { - .name = "dout_mpll", - .parent = &clk_mout_mpll.clk, - .ops = &clk_dout_ops, -}; - -static struct clk *clkset_spi_mmc_list[] = { - &clk_mout_epll.clk, - &clk_dout_mpll, - &clk_fin_epll, - &clk_27m, -}; - -static struct clksrc_sources clkset_spi_mmc = { - .sources = clkset_spi_mmc_list, - .nr_sources = ARRAY_SIZE(clkset_spi_mmc_list), -}; - -static struct clk *clkset_irda_list[] = { - &clk_mout_epll.clk, - &clk_dout_mpll, - NULL, - &clk_27m, -}; - -static struct clksrc_sources clkset_irda = { - .sources = clkset_irda_list, - .nr_sources = ARRAY_SIZE(clkset_irda_list), -}; - -static struct clk *clkset_uart_list[] = { - &clk_mout_epll.clk, - &clk_dout_mpll, - NULL, - NULL -}; - -static struct clksrc_sources clkset_uart = { - .sources = clkset_uart_list, - .nr_sources = ARRAY_SIZE(clkset_uart_list), -}; - -static struct clk *clkset_uhost_list[] = { - &clk_48m, - &clk_mout_epll.clk, - &clk_dout_mpll, - &clk_fin_epll, -}; - -static struct clksrc_sources clkset_uhost = { - .sources = clkset_uhost_list, - .nr_sources = ARRAY_SIZE(clkset_uhost_list), -}; - -/* The peripheral clocks are all controlled via clocksource followed - * by an optional divider and gate stage. We currently roll this into - * one clock which hides the intermediate clock from the mux. - * - * Note, the JPEG clock can only be an even divider... - * - * The scaler and LCD clocks depend on the S3C64XX version, and also - * have a common parent divisor so are not included here. - */ - -/* clocks that feed other parts of the clock source tree */ - -static struct clk clk_iis_cd0 = { - .name = "iis_cdclk0", -}; - -static struct clk clk_iis_cd1 = { - .name = "iis_cdclk1", -}; - -static struct clk clk_iisv4_cd = { - .name = "iis_cdclk_v4", -}; - -static struct clk clk_pcm_cd = { - .name = "pcm_cdclk", -}; - -static struct clk *clkset_audio0_list[] = { - [0] = &clk_mout_epll.clk, - [1] = &clk_dout_mpll, - [2] = &clk_fin_epll, - [3] = &clk_iis_cd0, - [4] = &clk_pcm_cd, -}; - -static struct clksrc_sources clkset_audio0 = { - .sources = clkset_audio0_list, - .nr_sources = ARRAY_SIZE(clkset_audio0_list), -}; - -static struct clk *clkset_audio1_list[] = { - [0] = &clk_mout_epll.clk, - [1] = &clk_dout_mpll, - [2] = &clk_fin_epll, - [3] = &clk_iis_cd1, - [4] = &clk_pcm_cd, -}; - -static struct clksrc_sources clkset_audio1 = { - .sources = clkset_audio1_list, - .nr_sources = ARRAY_SIZE(clkset_audio1_list), -}; - -#ifdef CONFIG_CPU_S3C6410 -static struct clk *clkset_audio2_list[] = { - [0] = &clk_mout_epll.clk, - [1] = &clk_dout_mpll, - [2] = &clk_fin_epll, - [3] = &clk_iisv4_cd, - [4] = &clk_pcm_cd, -}; - -static struct clksrc_sources clkset_audio2 = { - .sources = clkset_audio2_list, - .nr_sources = ARRAY_SIZE(clkset_audio2_list), -}; -#endif - -static struct clksrc_clk clksrcs[] = { - { - .clk = { - .name = "usb-bus-host", - .ctrlbit = S3C_CLKCON_SCLK_UHOST, - .enable = s3c64xx_sclk_ctrl, - }, - .reg_src = { .reg = S3C_CLK_SRC, .shift = 5, .size = 2 }, - .reg_div = { .reg = S3C_CLK_DIV1, .shift = 20, .size = 4 }, - .sources = &clkset_uhost, - }, { - .clk = { - .name = "irda-bus", - .ctrlbit = S3C_CLKCON_SCLK_IRDA, - .enable = s3c64xx_sclk_ctrl, - }, - .reg_src = { .reg = S3C_CLK_SRC, .shift = 24, .size = 2 }, - .reg_div = { .reg = S3C_CLK_DIV2, .shift = 20, .size = 4 }, - .sources = &clkset_irda, - }, { - .clk = { - .name = "camera", - .ctrlbit = S3C_CLKCON_SCLK_CAM, - .enable = s3c64xx_sclk_ctrl, - .parent = &clk_h2, - }, - .reg_div = { .reg = S3C_CLK_DIV0, .shift = 20, .size = 4 }, - }, -}; - -/* Where does UCLK0 come from? */ -static struct clksrc_clk clk_sclk_uclk = { - .clk = { - .name = "uclk1", - .ctrlbit = S3C_CLKCON_SCLK_UART, - .enable = s3c64xx_sclk_ctrl, - }, - .reg_src = { .reg = S3C_CLK_SRC, .shift = 13, .size = 1 }, - .reg_div = { .reg = S3C_CLK_DIV2, .shift = 16, .size = 4 }, - .sources = &clkset_uart, -}; - -static struct clksrc_clk clk_sclk_mmc0 = { - .clk = { - .name = "mmc_bus", - .devname = "s3c-sdhci.0", - .ctrlbit = S3C_CLKCON_SCLK_MMC0, - .enable = s3c64xx_sclk_ctrl, - }, - .reg_src = { .reg = S3C_CLK_SRC, .shift = 18, .size = 2 }, - .reg_div = { .reg = S3C_CLK_DIV1, .shift = 0, .size = 4 }, - .sources = &clkset_spi_mmc, -}; - -static struct clksrc_clk clk_sclk_mmc1 = { - .clk = { - .name = "mmc_bus", - .devname = "s3c-sdhci.1", - .ctrlbit = S3C_CLKCON_SCLK_MMC1, - .enable = s3c64xx_sclk_ctrl, - }, - .reg_src = { .reg = S3C_CLK_SRC, .shift = 20, .size = 2 }, - .reg_div = { .reg = S3C_CLK_DIV1, .shift = 4, .size = 4 }, - .sources = &clkset_spi_mmc, -}; - -static struct clksrc_clk clk_sclk_mmc2 = { - .clk = { - .name = "mmc_bus", - .devname = "s3c-sdhci.2", - .ctrlbit = S3C_CLKCON_SCLK_MMC2, - .enable = s3c64xx_sclk_ctrl, - }, - .reg_src = { .reg = S3C_CLK_SRC, .shift = 22, .size = 2 }, - .reg_div = { .reg = S3C_CLK_DIV1, .shift = 8, .size = 4 }, - .sources = &clkset_spi_mmc, -}; - -static struct clksrc_clk clk_sclk_spi0 = { - .clk = { - .name = "spi-bus", - .devname = "s3c6410-spi.0", - .ctrlbit = S3C_CLKCON_SCLK_SPI0, - .enable = s3c64xx_sclk_ctrl, - }, - .reg_src = { .reg = S3C_CLK_SRC, .shift = 14, .size = 2 }, - .reg_div = { .reg = S3C_CLK_DIV2, .shift = 0, .size = 4 }, - .sources = &clkset_spi_mmc, -}; - -static struct clksrc_clk clk_sclk_spi1 = { - .clk = { - .name = "spi-bus", - .devname = "s3c6410-spi.1", - .ctrlbit = S3C_CLKCON_SCLK_SPI1, - .enable = s3c64xx_sclk_ctrl, - }, - .reg_src = { .reg = S3C_CLK_SRC, .shift = 16, .size = 2 }, - .reg_div = { .reg = S3C_CLK_DIV2, .shift = 4, .size = 4 }, - .sources = &clkset_spi_mmc, -}; - -static struct clksrc_clk clk_audio_bus0 = { - .clk = { - .name = "audio-bus", - .devname = "samsung-i2s.0", - .ctrlbit = S3C_CLKCON_SCLK_AUDIO0, - .enable = s3c64xx_sclk_ctrl, - }, - .reg_src = { .reg = S3C_CLK_SRC, .shift = 7, .size = 3 }, - .reg_div = { .reg = S3C_CLK_DIV2, .shift = 8, .size = 4 }, - .sources = &clkset_audio0, -}; - -static struct clksrc_clk clk_audio_bus1 = { - .clk = { - .name = "audio-bus", - .devname = "samsung-i2s.1", - .ctrlbit = S3C_CLKCON_SCLK_AUDIO1, - .enable = s3c64xx_sclk_ctrl, - }, - .reg_src = { .reg = S3C_CLK_SRC, .shift = 10, .size = 3 }, - .reg_div = { .reg = S3C_CLK_DIV2, .shift = 12, .size = 4 }, - .sources = &clkset_audio1, -}; - -#ifdef CONFIG_CPU_S3C6410 -static struct clksrc_clk clk_audio_bus2 = { - .clk = { - .name = "audio-bus", - .devname = "samsung-i2s.2", - .ctrlbit = S3C6410_CLKCON_SCLK_AUDIO2, - .enable = s3c64xx_sclk_ctrl, - }, - .reg_src = { .reg = S3C6410_CLK_SRC2, .shift = 0, .size = 3 }, - .reg_div = { .reg = S3C_CLK_DIV2, .shift = 24, .size = 4 }, - .sources = &clkset_audio2, -}; -#endif -/* Clock initialisation code */ - -static struct clksrc_clk *init_parents[] = { - &clk_mout_apll, - &clk_mout_epll, - &clk_mout_mpll, -}; - -static struct clksrc_clk *clksrc_cdev[] = { - &clk_sclk_uclk, - &clk_sclk_mmc0, - &clk_sclk_mmc1, - &clk_sclk_mmc2, - &clk_sclk_spi0, - &clk_sclk_spi1, - &clk_audio_bus0, - &clk_audio_bus1, -}; - -static struct clk *clk_cdev[] = { - &clk_hsmmc0, - &clk_hsmmc1, - &clk_hsmmc2, - &clk_48m_spi0, - &clk_48m_spi1, - &clk_i2s0, - &clk_i2s1, -}; - -static struct clk_lookup s3c64xx_clk_lookup[] = { - CLKDEV_INIT(NULL, "clk_uart_baud2", &clk_p), - CLKDEV_INIT(NULL, "clk_uart_baud3", &clk_sclk_uclk.clk), - CLKDEV_INIT("s3c-sdhci.0", "mmc_busclk.0", &clk_hsmmc0), - CLKDEV_INIT("s3c-sdhci.1", "mmc_busclk.0", &clk_hsmmc1), - CLKDEV_INIT("s3c-sdhci.2", "mmc_busclk.0", &clk_hsmmc2), - CLKDEV_INIT("s3c-sdhci.0", "mmc_busclk.2", &clk_sclk_mmc0.clk), - CLKDEV_INIT("s3c-sdhci.1", "mmc_busclk.2", &clk_sclk_mmc1.clk), - CLKDEV_INIT("s3c-sdhci.2", "mmc_busclk.2", &clk_sclk_mmc2.clk), - CLKDEV_INIT(NULL, "spi_busclk0", &clk_p), - CLKDEV_INIT("s3c6410-spi.0", "spi_busclk1", &clk_sclk_spi0.clk), - CLKDEV_INIT("s3c6410-spi.0", "spi_busclk2", &clk_48m_spi0), - CLKDEV_INIT("s3c6410-spi.1", "spi_busclk1", &clk_sclk_spi1.clk), - CLKDEV_INIT("s3c6410-spi.1", "spi_busclk2", &clk_48m_spi1), - CLKDEV_INIT("samsung-i2s.0", "i2s_opclk0", &clk_i2s0), - CLKDEV_INIT("samsung-i2s.0", "i2s_opclk1", &clk_audio_bus0.clk), - CLKDEV_INIT("samsung-i2s.1", "i2s_opclk0", &clk_i2s1), - CLKDEV_INIT("samsung-i2s.1", "i2s_opclk1", &clk_audio_bus1.clk), -#ifdef CONFIG_CPU_S3C6410 - CLKDEV_INIT("samsung-i2s.2", "i2s_opclk0", &clk_i2s2), - CLKDEV_INIT("samsung-i2s.2", "i2s_opclk1", &clk_audio_bus2.clk), -#endif -}; - -#define GET_DIV(clk, field) ((((clk) & field##_MASK) >> field##_SHIFT) + 1) - -void __init_or_cpufreq s3c64xx_setup_clocks(void) -{ - struct clk *xtal_clk; - unsigned long xtal; - unsigned long fclk; - unsigned long hclk; - unsigned long hclk2; - unsigned long pclk; - unsigned long epll; - unsigned long apll; - unsigned long mpll; - unsigned int ptr; - u32 clkdiv0; - - printk(KERN_DEBUG "%s: registering clocks\n", __func__); - - clkdiv0 = __raw_readl(S3C_CLK_DIV0); - printk(KERN_DEBUG "%s: clkdiv0 = %08x\n", __func__, clkdiv0); - - xtal_clk = clk_get(NULL, "xtal"); - BUG_ON(IS_ERR(xtal_clk)); - - xtal = clk_get_rate(xtal_clk); - clk_put(xtal_clk); - - printk(KERN_DEBUG "%s: xtal is %ld\n", __func__, xtal); - - /* For now assume the mux always selects the crystal */ - clk_ext_xtal_mux.parent = xtal_clk; - - epll = s3c_get_pll6553x(xtal, __raw_readl(S3C_EPLL_CON0), - __raw_readl(S3C_EPLL_CON1)); - mpll = s3c6400_get_pll(xtal, __raw_readl(S3C_MPLL_CON)); - apll = s3c6400_get_pll(xtal, __raw_readl(S3C_APLL_CON)); - - fclk = mpll; - - printk(KERN_INFO "S3C64XX: PLL settings, A=%ld, M=%ld, E=%ld\n", - apll, mpll, epll); - - if(__raw_readl(S3C64XX_OTHERS) & S3C64XX_OTHERS_SYNCMUXSEL) - /* Synchronous mode */ - hclk2 = apll / GET_DIV(clkdiv0, S3C6400_CLKDIV0_HCLK2); - else - /* Asynchronous mode */ - hclk2 = mpll / GET_DIV(clkdiv0, S3C6400_CLKDIV0_HCLK2); - - hclk = hclk2 / GET_DIV(clkdiv0, S3C6400_CLKDIV0_HCLK); - pclk = hclk2 / GET_DIV(clkdiv0, S3C6400_CLKDIV0_PCLK); - - printk(KERN_INFO "S3C64XX: HCLK2=%ld, HCLK=%ld, PCLK=%ld\n", - hclk2, hclk, pclk); - - clk_fout_mpll.rate = mpll; - clk_fout_epll.rate = epll; - clk_fout_apll.rate = apll; - - clk_h2.rate = hclk2; - clk_h.rate = hclk; - clk_p.rate = pclk; - clk_f.rate = fclk; - - for (ptr = 0; ptr < ARRAY_SIZE(init_parents); ptr++) - s3c_set_clksrc(init_parents[ptr], true); - - for (ptr = 0; ptr < ARRAY_SIZE(clksrcs); ptr++) - s3c_set_clksrc(&clksrcs[ptr], true); -} - -static struct clk *clks1[] __initdata = { - &clk_ext_xtal_mux, - &clk_iis_cd0, - &clk_iis_cd1, - &clk_iisv4_cd, - &clk_pcm_cd, - &clk_mout_epll.clk, - &clk_mout_mpll.clk, - &clk_dout_mpll, - &clk_arm, -}; - -static struct clk *clks[] __initdata = { - &clk_ext, - &clk_epll, - &clk_27m, - &clk_48m, - &clk_h2, - &clk_xusbxti, -}; - -/** - * s3c64xx_register_clocks - register clocks for s3c6400 and s3c6410 - * @xtal: The rate for the clock crystal feeding the PLLs. - * @armclk_divlimit: Divisor mask for ARMCLK. - * - * Register the clocks for the S3C6400 and S3C6410 SoC range, such - * as ARMCLK as well as the necessary parent clocks. - * - * This call does not setup the clocks, which is left to the - * s3c64xx_setup_clocks() call which may be needed by the cpufreq - * or resume code to re-set the clocks if the bootloader has changed - * them. - */ -void __init s3c64xx_register_clocks(unsigned long xtal, - unsigned armclk_divlimit) -{ - unsigned int cnt; - - armclk_mask = armclk_divlimit; - - s3c24xx_register_baseclocks(xtal); - s3c24xx_register_clocks(clks, ARRAY_SIZE(clks)); - - s3c_register_clocks(init_clocks, ARRAY_SIZE(init_clocks)); - - s3c_register_clocks(init_clocks_off, ARRAY_SIZE(init_clocks_off)); - s3c_disable_clocks(init_clocks_off, ARRAY_SIZE(init_clocks_off)); - - s3c24xx_register_clocks(clk_cdev, ARRAY_SIZE(clk_cdev)); - for (cnt = 0; cnt < ARRAY_SIZE(clk_cdev); cnt++) - s3c_disable_clocks(clk_cdev[cnt], 1); - - s3c24xx_register_clocks(clks1, ARRAY_SIZE(clks1)); - s3c_register_clksrc(clksrcs, ARRAY_SIZE(clksrcs)); - for (cnt = 0; cnt < ARRAY_SIZE(clksrc_cdev); cnt++) - s3c_register_clksrc(clksrc_cdev[cnt], 1); - clkdev_add_table(s3c64xx_clk_lookup, ARRAY_SIZE(s3c64xx_clk_lookup)); -} diff --git a/arch/arm/mach-s3c64xx/common.c b/arch/arm/mach-s3c64xx/common.c index 73d79cf5e141..7d3cb58f1856 100644 --- a/arch/arm/mach-s3c64xx/common.c +++ b/arch/arm/mach-s3c64xx/common.c @@ -17,6 +17,7 @@ #include <linux/kernel.h> #include <linux/init.h> #include <linux/module.h> +#include <linux/clk-provider.h> #include <linux/interrupt.h> #include <linux/ioport.h> #include <linux/serial_core.h> @@ -38,7 +39,6 @@ #include <mach/regs-gpio.h> #include <plat/cpu.h> -#include <plat/clock.h> #include <plat/devs.h> #include <plat/pm.h> #include <plat/gpio-cfg.h> @@ -50,6 +50,19 @@ #include "common.h" +/* External clock frequency */ +static unsigned long xtal_f = 12000000, xusbxti_f = 48000000; + +void __init s3c64xx_set_xtal_freq(unsigned long freq) +{ + xtal_f = freq; +} + +void __init s3c64xx_set_xusbxti_freq(unsigned long freq) +{ + xusbxti_f = freq; +} + /* uart registration process */ static void __init s3c64xx_init_uarts(struct s3c2410_uartcfg *cfg, int no) @@ -67,7 +80,6 @@ static struct cpu_table cpu_ids[] __initdata = { .idcode = S3C6400_CPU_ID, .idmask = S3C64XX_CPU_MASK, .map_io = s3c6400_map_io, - .init_clocks = s3c6400_init_clocks, .init_uarts = s3c64xx_init_uarts, .init = s3c6400_init, .name = name_s3c6400, @@ -75,7 +87,6 @@ static struct cpu_table cpu_ids[] __initdata = { .idcode = S3C6410_CPU_ID, .idmask = S3C64XX_CPU_MASK, .map_io = s3c6410_map_io, - .init_clocks = s3c6410_init_clocks, .init_uarts = s3c64xx_init_uarts, .init = s3c6410_init, .name = name_s3c6410, @@ -213,8 +224,10 @@ void __init s3c64xx_init_irq(u32 vic0_valid, u32 vic1_valid) { /* * FIXME: there is no better place to put this at the moment - * (samsung_wdt_reset_init needs clocks) + * (s3c64xx_clk_init needs ioremap and must happen before init_time + * samsung_wdt_reset_init needs clocks) */ + s3c64xx_clk_init(NULL, xtal_f, xusbxti_f, soc_is_s3c6400(), S3C_VA_SYS); samsung_wdt_reset_init(S3C_VA_WATCHDOG); printk(KERN_DEBUG "%s: initialising interrupts\n", __func__); diff --git a/arch/arm/mach-s3c64xx/common.h b/arch/arm/mach-s3c64xx/common.h index e8f990b37665..bd3bd562011e 100644 --- a/arch/arm/mach-s3c64xx/common.h +++ b/arch/arm/mach-s3c64xx/common.h @@ -22,21 +22,21 @@ void s3c64xx_init_irq(u32 vic0, u32 vic1); void s3c64xx_init_io(struct map_desc *mach_desc, int size); -void s3c64xx_register_clocks(unsigned long xtal, unsigned armclk_limit); -void s3c64xx_setup_clocks(void); - void s3c64xx_restart(enum reboot_mode mode, const char *cmd); void s3c64xx_init_late(void); +void s3c64xx_clk_init(struct device_node *np, unsigned long xtal_f, + unsigned long xusbxti_f, bool is_s3c6400, void __iomem *reg_base); +void s3c64xx_set_xtal_freq(unsigned long freq); +void s3c64xx_set_xusbxti_freq(unsigned long freq); + #ifdef CONFIG_CPU_S3C6400 extern int s3c6400_init(void); extern void s3c6400_init_irq(void); extern void s3c6400_map_io(void); -extern void s3c6400_init_clocks(int xtal); #else -#define s3c6400_init_clocks NULL #define s3c6400_map_io NULL #define s3c6400_init NULL #endif @@ -46,10 +46,8 @@ extern void s3c6400_init_clocks(int xtal); extern int s3c6410_init(void); extern void s3c6410_init_irq(void); extern void s3c6410_map_io(void); -extern void s3c6410_init_clocks(int xtal); #else -#define s3c6410_init_clocks NULL #define s3c6410_map_io NULL #define s3c6410_init NULL #endif diff --git a/arch/arm/mach-s3c64xx/dma.c b/arch/arm/mach-s3c64xx/dma.c index 759846c28d12..c511dfaae148 100644 --- a/arch/arm/mach-s3c64xx/dma.c +++ b/arch/arm/mach-s3c64xx/dma.c @@ -677,7 +677,7 @@ static int s3c64xx_dma_init1(int chno, enum dma_ch chbase, goto err_map; } - clk_enable(dmac->clk); + clk_prepare_enable(dmac->clk); dmac->regs = regs; dmac->chanbase = chbase; @@ -711,7 +711,7 @@ static int s3c64xx_dma_init1(int chno, enum dma_ch chbase, return 0; err_clk: - clk_disable(dmac->clk); + clk_disable_unprepare(dmac->clk); clk_put(dmac->clk); err_map: iounmap(regs); diff --git a/arch/arm/mach-s3c64xx/include/mach/regs-clock.h b/arch/arm/mach-s3c64xx/include/mach/regs-clock.h index 05332b998ec0..4f44aac77092 100644 --- a/arch/arm/mach-s3c64xx/include/mach/regs-clock.h +++ b/arch/arm/mach-s3c64xx/include/mach/regs-clock.h @@ -15,145 +15,21 @@ #ifndef __PLAT_REGS_CLOCK_H #define __PLAT_REGS_CLOCK_H __FILE__ +/* + * FIXME: Remove remaining definitions + */ + #define S3C_CLKREG(x) (S3C_VA_SYS + (x)) -#define S3C_APLL_LOCK S3C_CLKREG(0x00) -#define S3C_MPLL_LOCK S3C_CLKREG(0x04) -#define S3C_EPLL_LOCK S3C_CLKREG(0x08) -#define S3C_APLL_CON S3C_CLKREG(0x0C) -#define S3C_MPLL_CON S3C_CLKREG(0x10) -#define S3C_EPLL_CON0 S3C_CLKREG(0x14) -#define S3C_EPLL_CON1 S3C_CLKREG(0x18) -#define S3C_CLK_SRC S3C_CLKREG(0x1C) -#define S3C_CLK_DIV0 S3C_CLKREG(0x20) -#define S3C_CLK_DIV1 S3C_CLKREG(0x24) -#define S3C_CLK_DIV2 S3C_CLKREG(0x28) -#define S3C_CLK_OUT S3C_CLKREG(0x2C) -#define S3C_HCLK_GATE S3C_CLKREG(0x30) #define S3C_PCLK_GATE S3C_CLKREG(0x34) -#define S3C_SCLK_GATE S3C_CLKREG(0x38) -#define S3C_MEM0_GATE S3C_CLKREG(0x3C) #define S3C6410_CLK_SRC2 S3C_CLKREG(0x10C) #define S3C_MEM_SYS_CFG S3C_CLKREG(0x120) -/* CLKDIV0 */ -#define S3C6400_CLKDIV0_PCLK_MASK (0xf << 12) -#define S3C6400_CLKDIV0_PCLK_SHIFT (12) -#define S3C6400_CLKDIV0_HCLK2_MASK (0x7 << 9) -#define S3C6400_CLKDIV0_HCLK2_SHIFT (9) -#define S3C6400_CLKDIV0_HCLK_MASK (0x1 << 8) -#define S3C6400_CLKDIV0_HCLK_SHIFT (8) -#define S3C6400_CLKDIV0_MPLL_MASK (0x1 << 4) -#define S3C6400_CLKDIV0_MPLL_SHIFT (4) - -#define S3C6400_CLKDIV0_ARM_MASK (0x7 << 0) -#define S3C6410_CLKDIV0_ARM_MASK (0xf << 0) -#define S3C6400_CLKDIV0_ARM_SHIFT (0) - -/* HCLK GATE Registers */ -#define S3C_CLKCON_HCLK_3DSE (1<<31) -#define S3C_CLKCON_HCLK_UHOST (1<<29) -#define S3C_CLKCON_HCLK_SECUR (1<<28) -#define S3C_CLKCON_HCLK_SDMA1 (1<<27) -#define S3C_CLKCON_HCLK_SDMA0 (1<<26) -#define S3C_CLKCON_HCLK_IROM (1<<25) -#define S3C_CLKCON_HCLK_DDR1 (1<<24) -#define S3C_CLKCON_HCLK_DDR0 (1<<23) -#define S3C_CLKCON_HCLK_MEM1 (1<<22) -#define S3C_CLKCON_HCLK_MEM0 (1<<21) -#define S3C_CLKCON_HCLK_USB (1<<20) -#define S3C_CLKCON_HCLK_HSMMC2 (1<<19) -#define S3C_CLKCON_HCLK_HSMMC1 (1<<18) -#define S3C_CLKCON_HCLK_HSMMC0 (1<<17) -#define S3C_CLKCON_HCLK_MDP (1<<16) -#define S3C_CLKCON_HCLK_DHOST (1<<15) -#define S3C_CLKCON_HCLK_IHOST (1<<14) -#define S3C_CLKCON_HCLK_DMA1 (1<<13) -#define S3C_CLKCON_HCLK_DMA0 (1<<12) -#define S3C_CLKCON_HCLK_JPEG (1<<11) -#define S3C_CLKCON_HCLK_CAMIF (1<<10) -#define S3C_CLKCON_HCLK_SCALER (1<<9) -#define S3C_CLKCON_HCLK_2D (1<<8) -#define S3C_CLKCON_HCLK_TV (1<<7) -#define S3C_CLKCON_HCLK_POST0 (1<<5) -#define S3C_CLKCON_HCLK_ROT (1<<4) -#define S3C_CLKCON_HCLK_LCD (1<<3) -#define S3C_CLKCON_HCLK_TZIC (1<<2) -#define S3C_CLKCON_HCLK_INTC (1<<1) -#define S3C_CLKCON_HCLK_MFC (1<<0) - /* PCLK GATE Registers */ -#define S3C6410_CLKCON_PCLK_I2C1 (1<<27) -#define S3C6410_CLKCON_PCLK_IIS2 (1<<26) -#define S3C_CLKCON_PCLK_SKEY (1<<24) -#define S3C_CLKCON_PCLK_CHIPID (1<<23) -#define S3C_CLKCON_PCLK_SPI1 (1<<22) -#define S3C_CLKCON_PCLK_SPI0 (1<<21) -#define S3C_CLKCON_PCLK_HSIRX (1<<20) -#define S3C_CLKCON_PCLK_HSITX (1<<19) -#define S3C_CLKCON_PCLK_GPIO (1<<18) -#define S3C_CLKCON_PCLK_IIC (1<<17) -#define S3C_CLKCON_PCLK_IIS1 (1<<16) -#define S3C_CLKCON_PCLK_IIS0 (1<<15) -#define S3C_CLKCON_PCLK_AC97 (1<<14) -#define S3C_CLKCON_PCLK_TZPC (1<<13) -#define S3C_CLKCON_PCLK_TSADC (1<<12) -#define S3C_CLKCON_PCLK_KEYPAD (1<<11) -#define S3C_CLKCON_PCLK_IRDA (1<<10) -#define S3C_CLKCON_PCLK_PCM1 (1<<9) -#define S3C_CLKCON_PCLK_PCM0 (1<<8) -#define S3C_CLKCON_PCLK_PWM (1<<7) -#define S3C_CLKCON_PCLK_RTC (1<<6) -#define S3C_CLKCON_PCLK_WDT (1<<5) #define S3C_CLKCON_PCLK_UART3 (1<<4) #define S3C_CLKCON_PCLK_UART2 (1<<3) #define S3C_CLKCON_PCLK_UART1 (1<<2) #define S3C_CLKCON_PCLK_UART0 (1<<1) -#define S3C_CLKCON_PCLK_MFC (1<<0) - -/* SCLK GATE Registers */ -#define S3C_CLKCON_SCLK_UHOST (1<<30) -#define S3C_CLKCON_SCLK_MMC2_48 (1<<29) -#define S3C_CLKCON_SCLK_MMC1_48 (1<<28) -#define S3C_CLKCON_SCLK_MMC0_48 (1<<27) -#define S3C_CLKCON_SCLK_MMC2 (1<<26) -#define S3C_CLKCON_SCLK_MMC1 (1<<25) -#define S3C_CLKCON_SCLK_MMC0 (1<<24) -#define S3C_CLKCON_SCLK_SPI1_48 (1<<23) -#define S3C_CLKCON_SCLK_SPI0_48 (1<<22) -#define S3C_CLKCON_SCLK_SPI1 (1<<21) -#define S3C_CLKCON_SCLK_SPI0 (1<<20) -#define S3C_CLKCON_SCLK_DAC27 (1<<19) -#define S3C_CLKCON_SCLK_TV27 (1<<18) -#define S3C_CLKCON_SCLK_SCALER27 (1<<17) -#define S3C_CLKCON_SCLK_SCALER (1<<16) -#define S3C_CLKCON_SCLK_LCD27 (1<<15) -#define S3C_CLKCON_SCLK_LCD (1<<14) -#define S3C6400_CLKCON_SCLK_POST1_27 (1<<13) -#define S3C6410_CLKCON_FIMC (1<<13) -#define S3C_CLKCON_SCLK_POST0_27 (1<<12) -#define S3C6400_CLKCON_SCLK_POST1 (1<<11) -#define S3C6410_CLKCON_SCLK_AUDIO2 (1<<11) -#define S3C_CLKCON_SCLK_POST0 (1<<10) -#define S3C_CLKCON_SCLK_AUDIO1 (1<<9) -#define S3C_CLKCON_SCLK_AUDIO0 (1<<8) -#define S3C_CLKCON_SCLK_SECUR (1<<7) -#define S3C_CLKCON_SCLK_IRDA (1<<6) -#define S3C_CLKCON_SCLK_UART (1<<5) -#define S3C_CLKCON_SCLK_ONENAND (1<<4) -#define S3C_CLKCON_SCLK_MFC (1<<3) -#define S3C_CLKCON_SCLK_CAM (1<<2) -#define S3C_CLKCON_SCLK_JPEG (1<<1) - -/* CLKSRC */ - -#define S3C6400_CLKSRC_APLL_MOUT (1 << 0) -#define S3C6400_CLKSRC_MPLL_MOUT (1 << 1) -#define S3C6400_CLKSRC_EPLL_MOUT (1 << 2) -#define S3C6400_CLKSRC_APLL_MOUT_SHIFT (0) -#define S3C6400_CLKSRC_MPLL_MOUT_SHIFT (1) -#define S3C6400_CLKSRC_EPLL_MOUT_SHIFT (2) -#define S3C6400_CLKSRC_MFC (1 << 4) /* MEM_SYS_CFG */ #define MEM_SYS_CFG_INDEP_CF 0x4000 diff --git a/arch/arm/mach-s3c64xx/mach-anw6410.c b/arch/arm/mach-s3c64xx/mach-anw6410.c index 35e3f54574ef..d266dd5f7060 100644 --- a/arch/arm/mach-s3c64xx/mach-anw6410.c +++ b/arch/arm/mach-s3c64xx/mach-anw6410.c @@ -207,7 +207,7 @@ static struct platform_device *anw6410_devices[] __initdata = { static void __init anw6410_map_io(void) { s3c64xx_init_io(anw6410_iodesc, ARRAY_SIZE(anw6410_iodesc)); - s3c24xx_init_clocks(12000000); + s3c64xx_set_xtal_freq(12000000); s3c24xx_init_uarts(anw6410_uartcfgs, ARRAY_SIZE(anw6410_uartcfgs)); samsung_set_timer_source(SAMSUNG_PWM3, SAMSUNG_PWM4); diff --git a/arch/arm/mach-s3c64xx/mach-crag6410.c b/arch/arm/mach-s3c64xx/mach-crag6410.c index eb8e5a1aca42..1a911df9e451 100644 --- a/arch/arm/mach-s3c64xx/mach-crag6410.c +++ b/arch/arm/mach-s3c64xx/mach-crag6410.c @@ -743,7 +743,7 @@ static struct s3c2410_platform_i2c i2c1_pdata = { static void __init crag6410_map_io(void) { s3c64xx_init_io(NULL, 0); - s3c24xx_init_clocks(12000000); + s3c64xx_set_xtal_freq(12000000); s3c24xx_init_uarts(crag6410_uartcfgs, ARRAY_SIZE(crag6410_uartcfgs)); samsung_set_timer_source(SAMSUNG_PWM3, SAMSUNG_PWM4); diff --git a/arch/arm/mach-s3c64xx/mach-hmt.c b/arch/arm/mach-s3c64xx/mach-hmt.c index f39569e0f2e6..e8064044ef79 100644 --- a/arch/arm/mach-s3c64xx/mach-hmt.c +++ b/arch/arm/mach-s3c64xx/mach-hmt.c @@ -247,7 +247,7 @@ static struct platform_device *hmt_devices[] __initdata = { static void __init hmt_map_io(void) { s3c64xx_init_io(hmt_iodesc, ARRAY_SIZE(hmt_iodesc)); - s3c24xx_init_clocks(12000000); + s3c64xx_set_xtal_freq(12000000); s3c24xx_init_uarts(hmt_uartcfgs, ARRAY_SIZE(hmt_uartcfgs)); samsung_set_timer_source(SAMSUNG_PWM3, SAMSUNG_PWM4); } diff --git a/arch/arm/mach-s3c64xx/mach-mini6410.c b/arch/arm/mach-s3c64xx/mach-mini6410.c index fc043e3ecdf8..58d46a3d7b78 100644 --- a/arch/arm/mach-s3c64xx/mach-mini6410.c +++ b/arch/arm/mach-s3c64xx/mach-mini6410.c @@ -231,7 +231,7 @@ static void __init mini6410_map_io(void) u32 tmp; s3c64xx_init_io(NULL, 0); - s3c24xx_init_clocks(12000000); + s3c64xx_set_xtal_freq(12000000); s3c24xx_init_uarts(mini6410_uartcfgs, ARRAY_SIZE(mini6410_uartcfgs)); samsung_set_timer_source(SAMSUNG_PWM3, SAMSUNG_PWM4); diff --git a/arch/arm/mach-s3c64xx/mach-ncp.c b/arch/arm/mach-s3c64xx/mach-ncp.c index 7e2c3908f1f8..2067b0bf55b4 100644 --- a/arch/arm/mach-s3c64xx/mach-ncp.c +++ b/arch/arm/mach-s3c64xx/mach-ncp.c @@ -86,7 +86,7 @@ static struct map_desc ncp_iodesc[] __initdata = {}; static void __init ncp_map_io(void) { s3c64xx_init_io(ncp_iodesc, ARRAY_SIZE(ncp_iodesc)); - s3c24xx_init_clocks(12000000); + s3c64xx_set_xtal_freq(12000000); s3c24xx_init_uarts(ncp_uartcfgs, ARRAY_SIZE(ncp_uartcfgs)); samsung_set_timer_source(SAMSUNG_PWM3, SAMSUNG_PWM4); } diff --git a/arch/arm/mach-s3c64xx/mach-smartq.c b/arch/arm/mach-s3c64xx/mach-smartq.c index 86d980b448fd..0f47237be3b2 100644 --- a/arch/arm/mach-s3c64xx/mach-smartq.c +++ b/arch/arm/mach-s3c64xx/mach-smartq.c @@ -337,13 +337,6 @@ err: return ret; } -static int __init smartq_usb_otg_init(void) -{ - clk_xusbxti.rate = 12000000; - - return 0; -} - static int __init smartq_wifi_init(void) { int ret; @@ -377,7 +370,8 @@ static struct map_desc smartq_iodesc[] __initdata = {}; void __init smartq_map_io(void) { s3c64xx_init_io(smartq_iodesc, ARRAY_SIZE(smartq_iodesc)); - s3c24xx_init_clocks(12000000); + s3c64xx_set_xtal_freq(12000000); + s3c64xx_set_xusbxti_freq(12000000); s3c24xx_init_uarts(smartq_uartcfgs, ARRAY_SIZE(smartq_uartcfgs)); samsung_set_timer_source(SAMSUNG_PWM3, SAMSUNG_PWM4); @@ -399,7 +393,6 @@ void __init smartq_machine_init(void) WARN_ON(smartq_lcd_setup_gpio()); WARN_ON(smartq_power_off_init()); WARN_ON(smartq_usb_host_init()); - WARN_ON(smartq_usb_otg_init()); WARN_ON(smartq_wifi_init()); platform_add_devices(smartq_devices, ARRAY_SIZE(smartq_devices)); diff --git a/arch/arm/mach-s3c64xx/mach-smdk6400.c b/arch/arm/mach-s3c64xx/mach-smdk6400.c index d70c0843aea2..27381cfcabbe 100644 --- a/arch/arm/mach-s3c64xx/mach-smdk6400.c +++ b/arch/arm/mach-s3c64xx/mach-smdk6400.c @@ -65,7 +65,7 @@ static struct map_desc smdk6400_iodesc[] = {}; static void __init smdk6400_map_io(void) { s3c64xx_init_io(smdk6400_iodesc, ARRAY_SIZE(smdk6400_iodesc)); - s3c24xx_init_clocks(12000000); + s3c64xx_set_xtal_freq(12000000); s3c24xx_init_uarts(smdk6400_uartcfgs, ARRAY_SIZE(smdk6400_uartcfgs)); samsung_set_timer_source(SAMSUNG_PWM3, SAMSUNG_PWM4); } diff --git a/arch/arm/mach-s3c64xx/mach-smdk6410.c b/arch/arm/mach-s3c64xx/mach-smdk6410.c index d90b450c5645..2a7b32ca5c96 100644 --- a/arch/arm/mach-s3c64xx/mach-smdk6410.c +++ b/arch/arm/mach-s3c64xx/mach-smdk6410.c @@ -634,7 +634,7 @@ static void __init smdk6410_map_io(void) u32 tmp; s3c64xx_init_io(smdk6410_iodesc, ARRAY_SIZE(smdk6410_iodesc)); - s3c24xx_init_clocks(12000000); + s3c64xx_set_xtal_freq(12000000); s3c24xx_init_uarts(smdk6410_uartcfgs, ARRAY_SIZE(smdk6410_uartcfgs)); samsung_set_timer_source(SAMSUNG_PWM3, SAMSUNG_PWM4); diff --git a/arch/arm/mach-s3c64xx/pm.c b/arch/arm/mach-s3c64xx/pm.c index 6a1f91fea678..8cdb824a3b43 100644 --- a/arch/arm/mach-s3c64xx/pm.c +++ b/arch/arm/mach-s3c64xx/pm.c @@ -194,29 +194,8 @@ void s3c_pm_debug_smdkled(u32 set, u32 clear) #endif static struct sleep_save core_save[] = { - SAVE_ITEM(S3C_APLL_LOCK), - SAVE_ITEM(S3C_MPLL_LOCK), - SAVE_ITEM(S3C_EPLL_LOCK), - SAVE_ITEM(S3C_CLK_SRC), - SAVE_ITEM(S3C_CLK_DIV0), - SAVE_ITEM(S3C_CLK_DIV1), - SAVE_ITEM(S3C_CLK_DIV2), - SAVE_ITEM(S3C_CLK_OUT), - SAVE_ITEM(S3C_HCLK_GATE), - SAVE_ITEM(S3C_PCLK_GATE), - SAVE_ITEM(S3C_SCLK_GATE), - SAVE_ITEM(S3C_MEM0_GATE), - - SAVE_ITEM(S3C_EPLL_CON1), - SAVE_ITEM(S3C_EPLL_CON0), - SAVE_ITEM(S3C64XX_MEM0DRVCON), SAVE_ITEM(S3C64XX_MEM1DRVCON), - -#ifndef CONFIG_CPU_FREQ - SAVE_ITEM(S3C_APLL_CON), - SAVE_ITEM(S3C_MPLL_CON), -#endif }; static struct sleep_save misc_save[] = { diff --git a/arch/arm/mach-s3c64xx/s3c6400.c b/arch/arm/mach-s3c64xx/s3c6400.c index 4869714c6f1b..331fe8e58145 100644 --- a/arch/arm/mach-s3c64xx/s3c6400.c +++ b/arch/arm/mach-s3c64xx/s3c6400.c @@ -58,12 +58,6 @@ void __init s3c6400_map_io(void) s3c64xx_onenand1_setname("s3c6400-onenand"); } -void __init s3c6400_init_clocks(int xtal) -{ - s3c64xx_register_clocks(xtal, S3C6400_CLKDIV0_ARM_MASK); - s3c64xx_setup_clocks(); -} - void __init s3c6400_init_irq(void) { /* VIC0 does not have IRQS 5..7, diff --git a/arch/arm/mach-s3c64xx/s3c6410.c b/arch/arm/mach-s3c64xx/s3c6410.c index 31c29fdf1800..7e6fa125584a 100644 --- a/arch/arm/mach-s3c64xx/s3c6410.c +++ b/arch/arm/mach-s3c64xx/s3c6410.c @@ -62,13 +62,6 @@ void __init s3c6410_map_io(void) s3c_cfcon_setname("s3c64xx-pata"); } -void __init s3c6410_init_clocks(int xtal) -{ - printk(KERN_DEBUG "%s: initialising clocks\n", __func__); - s3c64xx_register_clocks(xtal, S3C6410_CLKDIV0_ARM_MASK); - s3c64xx_setup_clocks(); -} - void __init s3c6410_init_irq(void) { /* VIC0 is missing IRQ7, VIC1 is fully populated. */ diff --git a/arch/arm/mach-shmobile/Kconfig b/arch/arm/mach-shmobile/Kconfig index 1f94c310c477..5dd5f9f7897a 100644 --- a/arch/arm/mach-shmobile/Kconfig +++ b/arch/arm/mach-shmobile/Kconfig @@ -101,12 +101,24 @@ config ARCH_R8A7790 select SH_CLK_CPG select RENESAS_IRQC +config ARCH_R8A7791 + bool "R-Car M2 (R8A77910)" + select ARM_GIC + select CPU_V7 + select SH_CLK_CPG + config ARCH_EMEV2 bool "Emma Mobile EV2" select ARCH_WANT_OPTIONAL_GPIOLIB select ARM_GIC select CPU_V7 +config ARCH_R7S72100 + bool "RZ/A1H (R7S72100)" + select ARM_GIC + select CPU_V7 + select SH_CLK_CPG + comment "SH-Mobile Board Type" config MACH_APE6EVM diff --git a/arch/arm/mach-shmobile/Makefile b/arch/arm/mach-shmobile/Makefile index 2705bfa8c113..f2d40edadcc9 100644 --- a/arch/arm/mach-shmobile/Makefile +++ b/arch/arm/mach-shmobile/Makefile @@ -15,7 +15,10 @@ obj-$(CONFIG_ARCH_R8A7740) += setup-r8a7740.o obj-$(CONFIG_ARCH_R8A7778) += setup-r8a7778.o obj-$(CONFIG_ARCH_R8A7779) += setup-r8a7779.o obj-$(CONFIG_ARCH_R8A7790) += setup-r8a7790.o +obj-$(CONFIG_ARCH_R8A7790) += setup-r8a7790.o setup-rcar-gen2.o +obj-$(CONFIG_ARCH_R8A7791) += setup-r8a7791.o setup-rcar-gen2.o obj-$(CONFIG_ARCH_EMEV2) += setup-emev2.o +obj-$(CONFIG_ARCH_R7S72100) += setup-r7s72100.o # Clock objects ifndef CONFIG_COMMON_CLK @@ -27,13 +30,17 @@ obj-$(CONFIG_ARCH_R8A7740) += clock-r8a7740.o obj-$(CONFIG_ARCH_R8A7778) += clock-r8a7778.o obj-$(CONFIG_ARCH_R8A7779) += clock-r8a7779.o obj-$(CONFIG_ARCH_R8A7790) += clock-r8a7790.o +obj-$(CONFIG_ARCH_R8A7791) += clock-r8a7791.o obj-$(CONFIG_ARCH_EMEV2) += clock-emev2.o +obj-$(CONFIG_ARCH_R7S72100) += clock-r7s72100.o endif # SMP objects smp-y := platsmp.o headsmp.o smp-$(CONFIG_ARCH_SH73A0) += smp-sh73a0.o headsmp-scu.o platsmp-scu.o smp-$(CONFIG_ARCH_R8A7779) += smp-r8a7779.o headsmp-scu.o platsmp-scu.o +smp-$(CONFIG_ARCH_R8A7790) += smp-r8a7790.o platsmp-apmu.o +smp-$(CONFIG_ARCH_R8A7791) += smp-r8a7791.o platsmp-apmu.o smp-$(CONFIG_ARCH_EMEV2) += smp-emev2.o headsmp-scu.o platsmp-scu.o # IRQ objects diff --git a/arch/arm/mach-shmobile/board-ape6evm-reference.c b/arch/arm/mach-shmobile/board-ape6evm-reference.c index a23fa714f7ac..3276afcf3cc9 100644 --- a/arch/arm/mach-shmobile/board-ape6evm-reference.c +++ b/arch/arm/mach-shmobile/board-ape6evm-reference.c @@ -57,7 +57,7 @@ static const char *ape6evm_boards_compat_dt[] __initdata = { }; DT_MACHINE_START(APE6EVM_DT, "ape6evm") - .init_early = r8a73a4_init_delay, + .init_early = r8a73a4_init_early, .init_machine = ape6evm_add_standard_devices, .dt_compat = ape6evm_boards_compat_dt, MACHINE_END diff --git a/arch/arm/mach-shmobile/board-ape6evm.c b/arch/arm/mach-shmobile/board-ape6evm.c index 24b87eea9da3..d36e23f5d8b7 100644 --- a/arch/arm/mach-shmobile/board-ape6evm.c +++ b/arch/arm/mach-shmobile/board-ape6evm.c @@ -240,7 +240,7 @@ static const char *ape6evm_boards_compat_dt[] __initdata = { }; DT_MACHINE_START(APE6EVM_DT, "ape6evm") - .init_early = r8a73a4_init_delay, + .init_early = r8a73a4_init_early, .init_machine = ape6evm_add_standard_devices, .dt_compat = ape6evm_boards_compat_dt, MACHINE_END diff --git a/arch/arm/mach-shmobile/board-armadillo800eva.c b/arch/arm/mach-shmobile/board-armadillo800eva.c index 5bd1479d3deb..7f8f6076d360 100644 --- a/arch/arm/mach-shmobile/board-armadillo800eva.c +++ b/arch/arm/mach-shmobile/board-armadillo800eva.c @@ -1108,9 +1108,9 @@ static const struct pinctrl_map eva_pinctrl_map[] = { PIN_MAP_MUX_GROUP_DEFAULT("asoc-simple-card.1", "pfc-r8a7740", "fsib_mclk_in", "fsib"), /* GETHER */ - PIN_MAP_MUX_GROUP_DEFAULT("sh-eth", "pfc-r8a7740", + PIN_MAP_MUX_GROUP_DEFAULT("r8a7740-gether", "pfc-r8a7740", "gether_mii", "gether"), - PIN_MAP_MUX_GROUP_DEFAULT("sh-eth", "pfc-r8a7740", + PIN_MAP_MUX_GROUP_DEFAULT("r8a7740-gether", "pfc-r8a7740", "gether_int", "gether"), /* HDMI */ PIN_MAP_MUX_GROUP_DEFAULT("sh-mobile-hdmi", "pfc-r8a7740", diff --git a/arch/arm/mach-shmobile/board-lager-reference.c b/arch/arm/mach-shmobile/board-lager-reference.c index 9c316a1b2e32..1a1a4a888632 100644 --- a/arch/arm/mach-shmobile/board-lager-reference.c +++ b/arch/arm/mach-shmobile/board-lager-reference.c @@ -38,8 +38,9 @@ static const char *lager_boards_compat_dt[] __initdata = { }; DT_MACHINE_START(LAGER_DT, "lager") - .init_early = r8a7790_init_delay, + .smp = smp_ops(r8a7790_smp_ops), + .init_early = r8a7790_init_early, + .init_time = rcar_gen2_timer_init, .init_machine = lager_add_standard_devices, - .init_time = r8a7790_timer_init, .dt_compat = lager_boards_compat_dt, MACHINE_END diff --git a/arch/arm/mach-shmobile/board-lager.c b/arch/arm/mach-shmobile/board-lager.c index ffb6f0ac7606..4e040e4d1102 100644 --- a/arch/arm/mach-shmobile/board-lager.c +++ b/arch/arm/mach-shmobile/board-lager.c @@ -29,6 +29,7 @@ #include <linux/pinctrl/machine.h> #include <linux/platform_data/gpio-rcar.h> #include <linux/platform_device.h> +#include <linux/phy.h> #include <linux/regulator/fixed.h> #include <linux/regulator/machine.h> #include <linux/sh_eth.h> @@ -155,14 +156,39 @@ static void __init lager_add_standard_devices(void) ðer_pdata, sizeof(ether_pdata)); } +/* + * Ether LEDs on the Lager board are named LINK and ACTIVE which corresponds + * to non-default 01 setting of the Micrel KSZ8041 PHY control register 1 bits + * 14-15. We have to set them back to 01 from the default 00 value each time + * the PHY is reset. It's also important because the PHY's LED0 signal is + * connected to SoC's ETH_LINK signal and in the PHY's default mode it will + * bounce on and off after each packet, which we apparently want to avoid. + */ +static int lager_ksz8041_fixup(struct phy_device *phydev) +{ + u16 phyctrl1 = phy_read(phydev, 0x1e); + + phyctrl1 &= ~0xc000; + phyctrl1 |= 0x4000; + return phy_write(phydev, 0x1e, phyctrl1); +} + +static void __init lager_init(void) +{ + lager_add_standard_devices(); + + phy_register_fixup_for_id("r8a7790-ether-ff:01", lager_ksz8041_fixup); +} + static const char *lager_boards_compat_dt[] __initdata = { "renesas,lager", NULL, }; DT_MACHINE_START(LAGER_DT, "lager") - .init_early = r8a7790_init_delay, - .init_time = r8a7790_timer_init, - .init_machine = lager_add_standard_devices, + .smp = smp_ops(r8a7790_smp_ops), + .init_early = r8a7790_init_early, + .init_time = rcar_gen2_timer_init, + .init_machine = lager_init, .dt_compat = lager_boards_compat_dt, MACHINE_END diff --git a/arch/arm/mach-shmobile/clock-r7s72100.c b/arch/arm/mach-shmobile/clock-r7s72100.c new file mode 100644 index 000000000000..4aba20ca127e --- /dev/null +++ b/arch/arm/mach-shmobile/clock-r7s72100.c @@ -0,0 +1,202 @@ +/* + * r7a72100 clock framework support + * + * Copyright (C) 2013 Renesas Solutions Corp. + * Copyright (C) 2012 Phil Edworthy + * Copyright (C) 2011 Magnus Damm + * + * 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/init.h> +#include <linux/kernel.h> +#include <linux/io.h> +#include <linux/sh_clk.h> +#include <linux/clkdev.h> +#include <mach/common.h> +#include <mach/r7s72100.h> + +/* registers */ +#define FRQCR 0xfcfe0010 +#define FRQCR2 0xfcfe0014 +#define STBCR3 0xfcfe0420 +#define STBCR4 0xfcfe0424 + +#define PLL_RATE 30 + +static struct clk_mapping cpg_mapping = { + .phys = 0xfcfe0000, + .len = 0x1000, +}; + +/* Fixed 32 KHz root clock for RTC */ +static struct clk r_clk = { + .rate = 32768, +}; + +/* + * Default rate for the root input clock, reset this with clk_set_rate() + * from the platform code. + */ +static struct clk extal_clk = { + .rate = 13330000, + .mapping = &cpg_mapping, +}; + +static unsigned long pll_recalc(struct clk *clk) +{ + return clk->parent->rate * PLL_RATE; +} + +static struct sh_clk_ops pll_clk_ops = { + .recalc = pll_recalc, +}; + +static struct clk pll_clk = { + .ops = &pll_clk_ops, + .parent = &extal_clk, + .flags = CLK_ENABLE_ON_INIT, +}; + +static unsigned long bus_recalc(struct clk *clk) +{ + return clk->parent->rate * 2 / 3; +} + +static struct sh_clk_ops bus_clk_ops = { + .recalc = bus_recalc, +}; + +static struct clk bus_clk = { + .ops = &bus_clk_ops, + .parent = &pll_clk, + .flags = CLK_ENABLE_ON_INIT, +}; + +static unsigned long peripheral0_recalc(struct clk *clk) +{ + return clk->parent->rate / 12; +} + +static struct sh_clk_ops peripheral0_clk_ops = { + .recalc = peripheral0_recalc, +}; + +static struct clk peripheral0_clk = { + .ops = &peripheral0_clk_ops, + .parent = &pll_clk, + .flags = CLK_ENABLE_ON_INIT, +}; + +static unsigned long peripheral1_recalc(struct clk *clk) +{ + return clk->parent->rate / 6; +} + +static struct sh_clk_ops peripheral1_clk_ops = { + .recalc = peripheral1_recalc, +}; + +static struct clk peripheral1_clk = { + .ops = &peripheral1_clk_ops, + .parent = &pll_clk, + .flags = CLK_ENABLE_ON_INIT, +}; + +struct clk *main_clks[] = { + &r_clk, + &extal_clk, + &pll_clk, + &bus_clk, + &peripheral0_clk, + &peripheral1_clk, +}; + +static int div2[] = { 1, 3, 0, 3 }; /* 1, 2/3, reserve, 1/3 */ +static int multipliers[] = { 1, 2, 1, 1 }; + +static struct clk_div_mult_table div4_div_mult_table = { + .divisors = div2, + .nr_divisors = ARRAY_SIZE(div2), + .multipliers = multipliers, + .nr_multipliers = ARRAY_SIZE(multipliers), +}; + +static struct clk_div4_table div4_table = { + .div_mult_table = &div4_div_mult_table, +}; + +enum { DIV4_I, + DIV4_NR }; + +#define DIV4(_reg, _bit, _mask, _flags) \ + SH_CLK_DIV4(&pll_clk, _reg, _bit, _mask, _flags) + +/* The mask field specifies the div2 entries that are valid */ +struct clk div4_clks[DIV4_NR] = { + [DIV4_I] = DIV4(FRQCR, 8, 0xB, CLK_ENABLE_REG_16BIT + | CLK_ENABLE_ON_INIT), +}; + +enum { MSTP47, MSTP46, MSTP45, MSTP44, MSTP43, MSTP42, MSTP41, MSTP40, + MSTP33, MSTP_NR }; + +static struct clk mstp_clks[MSTP_NR] = { + [MSTP47] = SH_CLK_MSTP8(&peripheral1_clk, STBCR4, 7, 0), /* SCIF0 */ + [MSTP46] = SH_CLK_MSTP8(&peripheral1_clk, STBCR4, 6, 0), /* SCIF1 */ + [MSTP45] = SH_CLK_MSTP8(&peripheral1_clk, STBCR4, 5, 0), /* SCIF2 */ + [MSTP44] = SH_CLK_MSTP8(&peripheral1_clk, STBCR4, 4, 0), /* SCIF3 */ + [MSTP43] = SH_CLK_MSTP8(&peripheral1_clk, STBCR4, 3, 0), /* SCIF4 */ + [MSTP42] = SH_CLK_MSTP8(&peripheral1_clk, STBCR4, 2, 0), /* SCIF5 */ + [MSTP41] = SH_CLK_MSTP8(&peripheral1_clk, STBCR4, 1, 0), /* SCIF6 */ + [MSTP40] = SH_CLK_MSTP8(&peripheral1_clk, STBCR4, 0, 0), /* SCIF7 */ + [MSTP33] = SH_CLK_MSTP8(&peripheral0_clk, STBCR3, 3, 0), /* MTU2 */ +}; + +static struct clk_lookup lookups[] = { + /* main clocks */ + CLKDEV_CON_ID("rclk", &r_clk), + CLKDEV_CON_ID("extal", &extal_clk), + CLKDEV_CON_ID("pll_clk", &pll_clk), + CLKDEV_CON_ID("peripheral_clk", &peripheral1_clk), + + /* DIV4 clocks */ + CLKDEV_CON_ID("cpu_clk", &div4_clks[DIV4_I]), + + /* MSTP clocks */ + CLKDEV_ICK_ID("sci_fck", "sh-sci.0", &mstp_clks[MSTP47]), + CLKDEV_ICK_ID("sci_fck", "sh-sci.1", &mstp_clks[MSTP46]), + CLKDEV_ICK_ID("sci_fck", "sh-sci.2", &mstp_clks[MSTP45]), + CLKDEV_ICK_ID("sci_fck", "sh-sci.3", &mstp_clks[MSTP44]), + CLKDEV_ICK_ID("sci_fck", "sh-sci.4", &mstp_clks[MSTP43]), + CLKDEV_ICK_ID("sci_fck", "sh-sci.5", &mstp_clks[MSTP42]), + CLKDEV_ICK_ID("sci_fck", "sh-sci.6", &mstp_clks[MSTP41]), + CLKDEV_ICK_ID("sci_fck", "sh-sci.7", &mstp_clks[MSTP40]), +}; + +void __init r7s72100_clock_init(void) +{ + int k, ret = 0; + + for (k = 0; !ret && (k < ARRAY_SIZE(main_clks)); k++) + ret = clk_register(main_clks[k]); + + clkdev_add_table(lookups, ARRAY_SIZE(lookups)); + + if (!ret) + ret = sh_clk_div4_register(div4_clks, DIV4_NR, &div4_table); + + if (!ret) + ret = sh_clk_mstp_register(mstp_clks, MSTP_NR); + + if (!ret) + shmobile_clk_init(); + else + panic("failed to setup rza1 clocks\n"); +} diff --git a/arch/arm/mach-shmobile/clock-r8a73a4.c b/arch/arm/mach-shmobile/clock-r8a73a4.c index 5bd2e851e3c7..571409b611d3 100644 --- a/arch/arm/mach-shmobile/clock-r8a73a4.c +++ b/arch/arm/mach-shmobile/clock-r8a73a4.c @@ -504,7 +504,7 @@ static struct clk div6_clks[DIV6_NR] = { /* MSTP */ enum { - MSTP217, MSTP216, MSTP207, MSTP206, MSTP204, MSTP203, + MSTP218, MSTP217, MSTP216, MSTP207, MSTP206, MSTP204, MSTP203, MSTP329, MSTP323, MSTP318, MSTP317, MSTP316, MSTP315, MSTP314, MSTP313, MSTP312, MSTP305, MSTP300, MSTP411, MSTP410, MSTP409, @@ -519,6 +519,7 @@ static struct clk mstp_clks[MSTP_NR] = { [MSTP207] = SH_CLK_MSTP32(&div6_clks[DIV6_MP], SMSTPCR2, 7, 0), /* SCIFB1 */ [MSTP216] = SH_CLK_MSTP32(&div6_clks[DIV6_MP], SMSTPCR2, 16, 0), /* SCIFB2 */ [MSTP217] = SH_CLK_MSTP32(&div6_clks[DIV6_MP], SMSTPCR2, 17, 0), /* SCIFB3 */ + [MSTP218] = SH_CLK_MSTP32(&div4_clks[DIV4_HP], SMSTPCR2, 18, 0), /* DMAC */ [MSTP300] = SH_CLK_MSTP32(&div4_clks[DIV4_HP], SMSTPCR3, 0, 0), /* IIC2 */ [MSTP305] = SH_CLK_MSTP32(&div6_clks[DIV6_MMC1],SMSTPCR3, 5, 0), /* MMCIF1 */ [MSTP312] = SH_CLK_MSTP32(&div6_clks[DIV6_SDHI2],SMSTPCR3, 12, 0), /* SDHI2 */ @@ -578,6 +579,8 @@ static struct clk_lookup lookups[] = { CLKDEV_DEV_ID("sh-sci.3", &mstp_clks[MSTP207]), CLKDEV_DEV_ID("sh-sci.4", &mstp_clks[MSTP216]), CLKDEV_DEV_ID("sh-sci.5", &mstp_clks[MSTP217]), + CLKDEV_DEV_ID("sh-dma-engine.0", &mstp_clks[MSTP218]), + CLKDEV_DEV_ID("e6700020.dma-controller", &mstp_clks[MSTP218]), CLKDEV_DEV_ID("rcar_thermal", &mstp_clks[MSTP522]), CLKDEV_DEV_ID("e6520000.i2c", &mstp_clks[MSTP300]), CLKDEV_DEV_ID("sh_mmcif.1", &mstp_clks[MSTP305]), diff --git a/arch/arm/mach-shmobile/clock-r8a7778.c b/arch/arm/mach-shmobile/clock-r8a7778.c index c4bf2d8fb111..fb6af83858e3 100644 --- a/arch/arm/mach-shmobile/clock-r8a7778.c +++ b/arch/arm/mach-shmobile/clock-r8a7778.c @@ -69,6 +69,15 @@ static struct clk extal_clk = { .mapping = &cpg_mapping, }; +static struct clk audio_clk_a = { +}; + +static struct clk audio_clk_b = { +}; + +static struct clk audio_clk_c = { +}; + /* * clock ratio of these clock will be updated * on r8a7778_clock_init() @@ -100,18 +109,23 @@ static struct clk *main_clks[] = { &p_clk, &g_clk, &z_clk, + &audio_clk_a, + &audio_clk_b, + &audio_clk_c, }; enum { MSTP331, MSTP323, MSTP322, MSTP321, + MSTP311, MSTP310, + MSTP309, MSTP308, MSTP307, MSTP114, MSTP110, MSTP109, MSTP100, MSTP030, MSTP029, MSTP028, MSTP027, MSTP026, MSTP025, MSTP024, MSTP023, MSTP022, MSTP021, - MSTP016, MSTP015, - MSTP007, + MSTP016, MSTP015, MSTP012, MSTP011, MSTP010, + MSTP009, MSTP008, MSTP007, MSTP_NR }; static struct clk mstp_clks[MSTP_NR] = { @@ -119,6 +133,11 @@ static struct clk mstp_clks[MSTP_NR] = { [MSTP323] = SH_CLK_MSTP32(&p_clk, MSTPCR3, 23, 0), /* SDHI0 */ [MSTP322] = SH_CLK_MSTP32(&p_clk, MSTPCR3, 22, 0), /* SDHI1 */ [MSTP321] = SH_CLK_MSTP32(&p_clk, MSTPCR3, 21, 0), /* SDHI2 */ + [MSTP311] = SH_CLK_MSTP32(&p_clk, MSTPCR3, 11, 0), /* SSI4 */ + [MSTP310] = SH_CLK_MSTP32(&p_clk, MSTPCR3, 10, 0), /* SSI5 */ + [MSTP309] = SH_CLK_MSTP32(&p_clk, MSTPCR3, 9, 0), /* SSI6 */ + [MSTP308] = SH_CLK_MSTP32(&p_clk, MSTPCR3, 8, 0), /* SSI7 */ + [MSTP307] = SH_CLK_MSTP32(&p_clk, MSTPCR3, 7, 0), /* SSI8 */ [MSTP114] = SH_CLK_MSTP32(&p_clk, MSTPCR1, 14, 0), /* Ether */ [MSTP110] = SH_CLK_MSTP32(&s_clk, MSTPCR1, 10, 0), /* VIN0 */ [MSTP109] = SH_CLK_MSTP32(&s_clk, MSTPCR1, 9, 0), /* VIN1 */ @@ -135,11 +154,20 @@ static struct clk mstp_clks[MSTP_NR] = { [MSTP021] = SH_CLK_MSTP32(&p_clk, MSTPCR0, 21, 0), /* SCIF5 */ [MSTP016] = SH_CLK_MSTP32(&p_clk, MSTPCR0, 16, 0), /* TMU0 */ [MSTP015] = SH_CLK_MSTP32(&p_clk, MSTPCR0, 15, 0), /* TMU1 */ + [MSTP012] = SH_CLK_MSTP32(&p_clk, MSTPCR0, 12, 0), /* SSI0 */ + [MSTP011] = SH_CLK_MSTP32(&p_clk, MSTPCR0, 11, 0), /* SSI1 */ + [MSTP010] = SH_CLK_MSTP32(&p_clk, MSTPCR0, 10, 0), /* SSI2 */ + [MSTP009] = SH_CLK_MSTP32(&p_clk, MSTPCR0, 9, 0), /* SSI3 */ + [MSTP008] = SH_CLK_MSTP32(&p_clk, MSTPCR0, 8, 0), /* SRU */ [MSTP007] = SH_CLK_MSTP32(&p_clk, MSTPCR0, 7, 0), /* HSPI */ }; static struct clk_lookup lookups[] = { /* main */ + CLKDEV_CON_ID("audio_clk_a", &audio_clk_a), + CLKDEV_CON_ID("audio_clk_b", &audio_clk_b), + CLKDEV_CON_ID("audio_clk_c", &audio_clk_c), + CLKDEV_CON_ID("audio_clk_internal", &s1_clk), CLKDEV_CON_ID("shyway_clk", &s_clk), CLKDEV_CON_ID("peripheral_clk", &p_clk), @@ -153,6 +181,7 @@ static struct clk_lookup lookups[] = { CLKDEV_DEV_ID("r8a7778-vin.1", &mstp_clks[MSTP109]), /* VIN1 */ CLKDEV_DEV_ID("ehci-platform", &mstp_clks[MSTP100]), /* USB EHCI port0/1 */ CLKDEV_DEV_ID("ohci-platform", &mstp_clks[MSTP100]), /* USB OHCI port0/1 */ + CLKDEV_DEV_ID("renesas_usbhs", &mstp_clks[MSTP100]), /* USB FUNC */ CLKDEV_DEV_ID("i2c-rcar.0", &mstp_clks[MSTP030]), /* I2C0 */ CLKDEV_DEV_ID("i2c-rcar.1", &mstp_clks[MSTP029]), /* I2C1 */ CLKDEV_DEV_ID("i2c-rcar.2", &mstp_clks[MSTP028]), /* I2C2 */ @@ -168,6 +197,17 @@ static struct clk_lookup lookups[] = { CLKDEV_DEV_ID("sh-hspi.0", &mstp_clks[MSTP007]), /* HSPI0 */ CLKDEV_DEV_ID("sh-hspi.1", &mstp_clks[MSTP007]), /* HSPI1 */ CLKDEV_DEV_ID("sh-hspi.2", &mstp_clks[MSTP007]), /* HSPI2 */ + CLKDEV_DEV_ID("rcar_sound", &mstp_clks[MSTP008]), /* SRU */ + + CLKDEV_ICK_ID("ssi.0", "rcar_sound", &mstp_clks[MSTP012]), + CLKDEV_ICK_ID("ssi.1", "rcar_sound", &mstp_clks[MSTP011]), + CLKDEV_ICK_ID("ssi.2", "rcar_sound", &mstp_clks[MSTP010]), + CLKDEV_ICK_ID("ssi.3", "rcar_sound", &mstp_clks[MSTP009]), + CLKDEV_ICK_ID("ssi.4", "rcar_sound", &mstp_clks[MSTP311]), + CLKDEV_ICK_ID("ssi.5", "rcar_sound", &mstp_clks[MSTP310]), + CLKDEV_ICK_ID("ssi.6", "rcar_sound", &mstp_clks[MSTP309]), + CLKDEV_ICK_ID("ssi.7", "rcar_sound", &mstp_clks[MSTP308]), + CLKDEV_ICK_ID("ssi.8", "rcar_sound", &mstp_clks[MSTP307]), }; void __init r8a7778_clock_init(void) diff --git a/arch/arm/mach-shmobile/clock-r8a7779.c b/arch/arm/mach-shmobile/clock-r8a7779.c index bd6ad922eb7e..1f7080fab0a5 100644 --- a/arch/arm/mach-shmobile/clock-r8a7779.c +++ b/arch/arm/mach-shmobile/clock-r8a7779.c @@ -200,7 +200,7 @@ static struct clk_lookup lookups[] = { CLKDEV_DEV_ID("sh_mobile_sdhi.1", &mstp_clks[MSTP322]), /* SDHI1 */ CLKDEV_DEV_ID("sh_mobile_sdhi.2", &mstp_clks[MSTP321]), /* SDHI2 */ CLKDEV_DEV_ID("sh_mobile_sdhi.3", &mstp_clks[MSTP320]), /* SDHI3 */ - CLKDEV_DEV_ID("rcar-du.0", &mstp_clks[MSTP103]), /* DU */ + CLKDEV_DEV_ID("rcar-du-r8a7779", &mstp_clks[MSTP103]), /* DU */ }; void __init r8a7779_clock_init(void) diff --git a/arch/arm/mach-shmobile/clock-r8a7790.c b/arch/arm/mach-shmobile/clock-r8a7790.c index fc36d3db0b4d..a64f965c7da1 100644 --- a/arch/arm/mach-shmobile/clock-r8a7790.c +++ b/arch/arm/mach-shmobile/clock-r8a7790.c @@ -52,6 +52,7 @@ #define SMSTPCR5 0xe6150144 #define SMSTPCR7 0xe615014c #define SMSTPCR8 0xe6150990 +#define SMSTPCR9 0xe6150994 #define SDCKCR 0xE6150074 #define SD2CKCR 0xE6150078 @@ -181,8 +182,9 @@ static struct clk div6_clks[DIV6_NR] = { /* MSTP */ enum { + MSTP931, MSTP930, MSTP929, MSTP928, MSTP813, - MSTP721, MSTP720, + MSTP726, MSTP725, MSTP724, MSTP723, MSTP722, MSTP721, MSTP720, MSTP717, MSTP716, MSTP522, MSTP315, MSTP314, MSTP313, MSTP312, MSTP311, MSTP305, MSTP304, @@ -192,7 +194,16 @@ enum { }; static struct clk mstp_clks[MSTP_NR] = { + [MSTP931] = SH_CLK_MSTP32(&hp_clk, SMSTPCR9, 31, 0), /* I2C0 */ + [MSTP930] = SH_CLK_MSTP32(&hp_clk, SMSTPCR9, 30, 0), /* I2C1 */ + [MSTP929] = SH_CLK_MSTP32(&hp_clk, SMSTPCR9, 29, 0), /* I2C2 */ + [MSTP928] = SH_CLK_MSTP32(&hp_clk, SMSTPCR9, 28, 0), /* I2C3 */ [MSTP813] = SH_CLK_MSTP32(&p_clk, SMSTPCR8, 13, 0), /* Ether */ + [MSTP726] = SH_CLK_MSTP32(&zx_clk, SMSTPCR7, 26, 0), /* LVDS0 */ + [MSTP725] = SH_CLK_MSTP32(&zx_clk, SMSTPCR7, 25, 0), /* LVDS1 */ + [MSTP724] = SH_CLK_MSTP32(&zx_clk, SMSTPCR7, 24, 0), /* DU0 */ + [MSTP723] = SH_CLK_MSTP32(&zx_clk, SMSTPCR7, 23, 0), /* DU1 */ + [MSTP722] = SH_CLK_MSTP32(&zx_clk, SMSTPCR7, 22, 0), /* DU2 */ [MSTP721] = SH_CLK_MSTP32(&p_clk, SMSTPCR7, 21, 0), /* SCIF0 */ [MSTP720] = SH_CLK_MSTP32(&p_clk, SMSTPCR7, 20, 0), /* SCIF1 */ [MSTP717] = SH_CLK_MSTP32(&zs_clk, SMSTPCR7, 17, 0), /* HSCIF0 */ @@ -251,6 +262,11 @@ static struct clk_lookup lookups[] = { CLKDEV_CON_ID("ssprs", &div6_clks[DIV6_SSPRS]), /* MSTP */ + CLKDEV_ICK_ID("lvds.0", "rcar-du-r8a7790", &mstp_clks[MSTP726]), + CLKDEV_ICK_ID("lvds.1", "rcar-du-r8a7790", &mstp_clks[MSTP725]), + CLKDEV_ICK_ID("du.0", "rcar-du-r8a7790", &mstp_clks[MSTP724]), + CLKDEV_ICK_ID("du.1", "rcar-du-r8a7790", &mstp_clks[MSTP723]), + CLKDEV_ICK_ID("du.2", "rcar-du-r8a7790", &mstp_clks[MSTP722]), CLKDEV_DEV_ID("sh-sci.0", &mstp_clks[MSTP204]), CLKDEV_DEV_ID("sh-sci.1", &mstp_clks[MSTP203]), CLKDEV_DEV_ID("sh-sci.2", &mstp_clks[MSTP206]), @@ -261,6 +277,10 @@ static struct clk_lookup lookups[] = { CLKDEV_DEV_ID("sh-sci.7", &mstp_clks[MSTP720]), CLKDEV_DEV_ID("sh-sci.8", &mstp_clks[MSTP717]), CLKDEV_DEV_ID("sh-sci.9", &mstp_clks[MSTP716]), + CLKDEV_DEV_ID("e6508000.i2c", &mstp_clks[MSTP931]), + CLKDEV_DEV_ID("e6518000.i2c", &mstp_clks[MSTP930]), + CLKDEV_DEV_ID("e6530000.i2c", &mstp_clks[MSTP929]), + CLKDEV_DEV_ID("e6540000.i2c", &mstp_clks[MSTP928]), CLKDEV_DEV_ID("r8a7790-ether", &mstp_clks[MSTP813]), CLKDEV_DEV_ID("rcar_thermal", &mstp_clks[MSTP522]), CLKDEV_DEV_ID("ee200000.mmcif", &mstp_clks[MSTP315]), @@ -290,7 +310,7 @@ static struct clk_lookup lookups[] = { void __init r8a7790_clock_init(void) { - u32 mode = r8a7790_read_mode_pins(); + u32 mode = rcar_gen2_read_mode_pins(); int k, ret = 0; switch (mode & (MD(14) | MD(13))) { diff --git a/arch/arm/mach-shmobile/clock-r8a7791.c b/arch/arm/mach-shmobile/clock-r8a7791.c new file mode 100644 index 000000000000..c9a26f16ce5b --- /dev/null +++ b/arch/arm/mach-shmobile/clock-r8a7791.c @@ -0,0 +1,237 @@ +/* + * r8a7791 clock framework support + * + * Copyright (C) 2013 Renesas Electronics Corporation + * Copyright (C) 2013 Renesas Solutions Corp. + * 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 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. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ +#include <linux/init.h> +#include <linux/io.h> +#include <linux/kernel.h> +#include <linux/sh_clk.h> +#include <linux/clkdev.h> +#include <mach/clock.h> +#include <mach/common.h> + +/* + * MD EXTAL PLL0 PLL1 PLL3 + * 14 13 19 (MHz) *1 *1 + *--------------------------------------------------- + * 0 0 0 15 x 1 x172/2 x208/2 x106 + * 0 0 1 15 x 1 x172/2 x208/2 x88 + * 0 1 0 20 x 1 x130/2 x156/2 x80 + * 0 1 1 20 x 1 x130/2 x156/2 x66 + * 1 0 0 26 / 2 x200/2 x240/2 x122 + * 1 0 1 26 / 2 x200/2 x240/2 x102 + * 1 1 0 30 / 2 x172/2 x208/2 x106 + * 1 1 1 30 / 2 x172/2 x208/2 x88 + * + * *1 : Table 7.6 indicates VCO ouput (PLLx = VCO/2) + * see "p1 / 2" on R8A7791_CLOCK_ROOT() below + */ + +#define MD(nr) (1 << nr) + +#define CPG_BASE 0xe6150000 +#define CPG_LEN 0x1000 + +#define SMSTPCR0 0xE6150130 +#define SMSTPCR1 0xE6150134 +#define SMSTPCR2 0xe6150138 +#define SMSTPCR3 0xE615013C +#define SMSTPCR5 0xE6150144 +#define SMSTPCR7 0xe615014c +#define SMSTPCR8 0xE6150990 +#define SMSTPCR9 0xE6150994 +#define SMSTPCR10 0xE6150998 +#define SMSTPCR11 0xE615099C + +#define MODEMR 0xE6160060 +#define SDCKCR 0xE6150074 +#define SD2CKCR 0xE6150078 +#define SD3CKCR 0xE615007C +#define MMC0CKCR 0xE6150240 +#define MMC1CKCR 0xE6150244 +#define SSPCKCR 0xE6150248 +#define SSPRSCKCR 0xE615024C + +static struct clk_mapping cpg_mapping = { + .phys = CPG_BASE, + .len = CPG_LEN, +}; + +static struct clk extal_clk = { + /* .rate will be updated on r8a7791_clock_init() */ + .mapping = &cpg_mapping, +}; + +static struct sh_clk_ops followparent_clk_ops = { + .recalc = followparent_recalc, +}; + +static struct clk main_clk = { + /* .parent will be set r8a73a4_clock_init */ + .ops = &followparent_clk_ops, +}; + +/* + * clock ratio of these clock will be updated + * on r8a7791_clock_init() + */ +SH_FIXED_RATIO_CLK_SET(pll1_clk, main_clk, 1, 1); +SH_FIXED_RATIO_CLK_SET(pll3_clk, main_clk, 1, 1); + +/* fixed ratio clock */ +SH_FIXED_RATIO_CLK_SET(extal_div2_clk, extal_clk, 1, 2); +SH_FIXED_RATIO_CLK_SET(cp_clk, extal_clk, 1, 2); + +SH_FIXED_RATIO_CLK_SET(pll1_div2_clk, pll1_clk, 1, 2); +SH_FIXED_RATIO_CLK_SET(hp_clk, pll1_clk, 1, 12); +SH_FIXED_RATIO_CLK_SET(p_clk, pll1_clk, 1, 24); +SH_FIXED_RATIO_CLK_SET(rclk_clk, pll1_clk, 1, (48 * 1024)); +SH_FIXED_RATIO_CLK_SET(mp_clk, pll1_div2_clk, 1, 15); + +static struct clk *main_clks[] = { + &extal_clk, + &extal_div2_clk, + &main_clk, + &pll1_clk, + &pll1_div2_clk, + &pll3_clk, + &hp_clk, + &p_clk, + &rclk_clk, + &mp_clk, + &cp_clk, +}; + +/* MSTP */ +enum { + MSTP721, MSTP720, + MSTP719, MSTP718, MSTP715, MSTP714, + MSTP216, MSTP207, MSTP206, + MSTP204, MSTP203, MSTP202, MSTP1105, MSTP1106, MSTP1107, + MSTP124, + MSTP_NR +}; + +static struct clk mstp_clks[MSTP_NR] = { + [MSTP721] = SH_CLK_MSTP32(&p_clk, SMSTPCR7, 21, 0), /* SCIF0 */ + [MSTP720] = SH_CLK_MSTP32(&p_clk, SMSTPCR7, 20, 0), /* SCIF1 */ + [MSTP719] = SH_CLK_MSTP32(&p_clk, SMSTPCR7, 19, 0), /* SCIF2 */ + [MSTP718] = SH_CLK_MSTP32(&p_clk, SMSTPCR7, 18, 0), /* SCIF3 */ + [MSTP715] = SH_CLK_MSTP32(&p_clk, SMSTPCR7, 15, 0), /* SCIF4 */ + [MSTP714] = SH_CLK_MSTP32(&p_clk, SMSTPCR7, 14, 0), /* SCIF5 */ + [MSTP216] = SH_CLK_MSTP32(&mp_clk, SMSTPCR2, 16, 0), /* SCIFB2 */ + [MSTP207] = SH_CLK_MSTP32(&mp_clk, SMSTPCR2, 7, 0), /* SCIFB1 */ + [MSTP206] = SH_CLK_MSTP32(&mp_clk, SMSTPCR2, 6, 0), /* SCIFB0 */ + [MSTP204] = SH_CLK_MSTP32(&mp_clk, SMSTPCR2, 4, 0), /* SCIFA0 */ + [MSTP203] = SH_CLK_MSTP32(&mp_clk, SMSTPCR2, 3, 0), /* SCIFA1 */ + [MSTP202] = SH_CLK_MSTP32(&mp_clk, SMSTPCR2, 2, 0), /* SCIFA2 */ + [MSTP1105] = SH_CLK_MSTP32(&mp_clk, SMSTPCR11, 5, 0), /* SCIFA3 */ + [MSTP1106] = SH_CLK_MSTP32(&mp_clk, SMSTPCR11, 6, 0), /* SCIFA4 */ + [MSTP1107] = SH_CLK_MSTP32(&mp_clk, SMSTPCR11, 7, 0), /* SCIFA5 */ + [MSTP124] = SH_CLK_MSTP32(&rclk_clk, SMSTPCR1, 24, 0), /* CMT0 */ +}; + +static struct clk_lookup lookups[] = { + + /* main clocks */ + CLKDEV_CON_ID("extal", &extal_clk), + CLKDEV_CON_ID("extal_div2", &extal_div2_clk), + CLKDEV_CON_ID("main", &main_clk), + CLKDEV_CON_ID("pll1", &pll1_clk), + CLKDEV_CON_ID("pll1_div2", &pll1_div2_clk), + CLKDEV_CON_ID("pll3", &pll3_clk), + CLKDEV_CON_ID("hp", &hp_clk), + CLKDEV_CON_ID("p", &p_clk), + CLKDEV_CON_ID("rclk", &rclk_clk), + CLKDEV_CON_ID("mp", &mp_clk), + CLKDEV_CON_ID("cp", &cp_clk), + CLKDEV_CON_ID("peripheral_clk", &hp_clk), + + /* MSTP */ + CLKDEV_DEV_ID("sh-sci.0", &mstp_clks[MSTP204]), /* SCIFA0 */ + CLKDEV_DEV_ID("sh-sci.1", &mstp_clks[MSTP203]), /* SCIFA1 */ + CLKDEV_DEV_ID("sh-sci.2", &mstp_clks[MSTP206]), /* SCIFB0 */ + CLKDEV_DEV_ID("sh-sci.3", &mstp_clks[MSTP207]), /* SCIFB1 */ + CLKDEV_DEV_ID("sh-sci.4", &mstp_clks[MSTP216]), /* SCIFB2 */ + CLKDEV_DEV_ID("sh-sci.5", &mstp_clks[MSTP202]), /* SCIFA2 */ + CLKDEV_DEV_ID("sh-sci.6", &mstp_clks[MSTP721]), /* SCIF0 */ + CLKDEV_DEV_ID("sh-sci.7", &mstp_clks[MSTP720]), /* SCIF1 */ + CLKDEV_DEV_ID("sh-sci.8", &mstp_clks[MSTP719]), /* SCIF2 */ + CLKDEV_DEV_ID("sh-sci.9", &mstp_clks[MSTP718]), /* SCIF3 */ + CLKDEV_DEV_ID("sh-sci.10", &mstp_clks[MSTP715]), /* SCIF4 */ + CLKDEV_DEV_ID("sh-sci.11", &mstp_clks[MSTP714]), /* SCIF5 */ + CLKDEV_DEV_ID("sh-sci.12", &mstp_clks[MSTP1105]), /* SCIFA3 */ + CLKDEV_DEV_ID("sh-sci.13", &mstp_clks[MSTP1106]), /* SCIFA4 */ + CLKDEV_DEV_ID("sh-sci.14", &mstp_clks[MSTP1107]), /* SCIFA5 */ + CLKDEV_DEV_ID("sh_cmt.0", &mstp_clks[MSTP124]), +}; + +#define R8A7791_CLOCK_ROOT(e, m, p0, p1, p30, p31) \ + extal_clk.rate = e * 1000 * 1000; \ + main_clk.parent = m; \ + SH_CLK_SET_RATIO(&pll1_clk_ratio, p1 / 2, 1); \ + if (mode & MD(19)) \ + SH_CLK_SET_RATIO(&pll3_clk_ratio, p31, 1); \ + else \ + SH_CLK_SET_RATIO(&pll3_clk_ratio, p30, 1) + + +void __init r8a7791_clock_init(void) +{ + void __iomem *modemr = ioremap_nocache(MODEMR, PAGE_SIZE); + u32 mode; + int k, ret = 0; + + BUG_ON(!modemr); + mode = ioread32(modemr); + iounmap(modemr); + + switch (mode & (MD(14) | MD(13))) { + case 0: + R8A7791_CLOCK_ROOT(15, &extal_clk, 172, 208, 106, 88); + break; + case MD(13): + R8A7791_CLOCK_ROOT(20, &extal_clk, 130, 156, 80, 66); + break; + case MD(14): + R8A7791_CLOCK_ROOT(26, &extal_div2_clk, 200, 240, 122, 102); + break; + case MD(13) | MD(14): + R8A7791_CLOCK_ROOT(30, &extal_div2_clk, 172, 208, 106, 88); + break; + } + + for (k = 0; !ret && (k < ARRAY_SIZE(main_clks)); k++) + ret = clk_register(main_clks[k]); + + if (!ret) + ret = sh_clk_mstp_register(mstp_clks, MSTP_NR); + + clkdev_add_table(lookups, ARRAY_SIZE(lookups)); + + if (!ret) + shmobile_clk_init(); + else + goto epanic; + + return; + +epanic: + panic("failed to setup r8a7791 clocks\n"); +} diff --git a/arch/arm/mach-shmobile/headsmp.S b/arch/arm/mach-shmobile/headsmp.S index f93751caf5cb..e5be5c88644b 100644 --- a/arch/arm/mach-shmobile/headsmp.S +++ b/arch/arm/mach-shmobile/headsmp.S @@ -40,6 +40,9 @@ shmobile_boot_fn: .globl shmobile_boot_arg shmobile_boot_arg: 2: .space 4 + .globl shmobile_boot_size +shmobile_boot_size: + .long . - shmobile_boot_vector /* * Per-CPU SMP boot function/argument selection code based on MPIDR diff --git a/arch/arm/mach-shmobile/include/mach/common.h b/arch/arm/mach-shmobile/include/mach/common.h index 7b938681e756..e31980590eb4 100644 --- a/arch/arm/mach-shmobile/include/mach/common.h +++ b/arch/arm/mach-shmobile/include/mach/common.h @@ -9,16 +9,23 @@ extern void shmobile_setup_console(void); extern void shmobile_boot_vector(void); extern unsigned long shmobile_boot_fn; extern unsigned long shmobile_boot_arg; +extern unsigned long shmobile_boot_size; extern void shmobile_smp_boot(void); extern void shmobile_smp_sleep(void); extern void shmobile_smp_hook(unsigned int cpu, unsigned long fn, unsigned long arg); +extern int shmobile_smp_cpu_disable(unsigned int cpu); +extern void shmobile_invalidate_start(void); extern void shmobile_boot_scu(void); extern void shmobile_smp_scu_prepare_cpus(unsigned int max_cpus); -extern int shmobile_smp_scu_boot_secondary(unsigned int cpu, - struct task_struct *idle); extern void shmobile_smp_scu_cpu_die(unsigned int cpu); extern int shmobile_smp_scu_cpu_kill(unsigned int cpu); +extern void shmobile_smp_apmu_prepare_cpus(unsigned int max_cpus); +extern int shmobile_smp_apmu_boot_secondary(unsigned int cpu, + struct task_struct *idle); +extern void shmobile_smp_apmu_cpu_die(unsigned int cpu); +extern int shmobile_smp_apmu_cpu_kill(unsigned int cpu); +extern void shmobile_invalidate_start(void); struct clk; extern int shmobile_clk_init(void); extern void shmobile_handle_irq_intc(struct pt_regs *); @@ -39,7 +46,6 @@ static inline int shmobile_cpuidle_init(void) { return 0; } #endif extern void __iomem *shmobile_scu_base; -extern void shmobile_smp_init_cpus(unsigned int ncores); static inline void __init shmobile_init_late(void) { diff --git a/arch/arm/mach-shmobile/include/mach/r7s72100.h b/arch/arm/mach-shmobile/include/mach/r7s72100.h new file mode 100644 index 000000000000..5f34b20ecd4a --- /dev/null +++ b/arch/arm/mach-shmobile/include/mach/r7s72100.h @@ -0,0 +1,8 @@ +#ifndef __ASM_R7S72100_H__ +#define __ASM_R7S72100_H__ + +void r7s72100_add_dt_devices(void); +void r7s72100_clock_init(void); +void r7s72100_init_early(void); + +#endif /* __ASM_R7S72100_H__ */ diff --git a/arch/arm/mach-shmobile/include/mach/r8a73a4.h b/arch/arm/mach-shmobile/include/mach/r8a73a4.h index f3a9b702da56..ce8bdd1d8a8a 100644 --- a/arch/arm/mach-shmobile/include/mach/r8a73a4.h +++ b/arch/arm/mach-shmobile/include/mach/r8a73a4.h @@ -1,10 +1,19 @@ #ifndef __ASM_R8A73A4_H__ #define __ASM_R8A73A4_H__ +/* DMA slave IDs */ +enum { + SHDMA_SLAVE_INVALID, + SHDMA_SLAVE_MMCIF0_TX, + SHDMA_SLAVE_MMCIF0_RX, + SHDMA_SLAVE_MMCIF1_TX, + SHDMA_SLAVE_MMCIF1_RX, +}; + void r8a73a4_add_standard_devices(void); void r8a73a4_add_dt_devices(void); void r8a73a4_clock_init(void); void r8a73a4_pinmux_init(void); -void r8a73a4_init_delay(void); +void r8a73a4_init_early(void); #endif /* __ASM_R8A73A4_H__ */ diff --git a/arch/arm/mach-shmobile/include/mach/r8a7778.h b/arch/arm/mach-shmobile/include/mach/r8a7778.h index adfcf51b163d..dbe221a484d5 100644 --- a/arch/arm/mach-shmobile/include/mach/r8a7778.h +++ b/arch/arm/mach-shmobile/include/mach/r8a7778.h @@ -1,6 +1,7 @@ /* * Copyright (C) 2013 Renesas Solutions Corp. * Copyright (C) 2013 Kuninori Morimoto <kuninori.morimoto.gx@renesas.com> + * Copyright (C) 2013 Cogent Embedded, 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 @@ -21,6 +22,13 @@ #include <linux/sh_eth.h> #include <linux/platform_data/camera-rcar.h> +/* HPB-DMA slave IDs */ +enum { + HPBDMA_SLAVE_DUMMY, + HPBDMA_SLAVE_SDHI0_TX, + HPBDMA_SLAVE_SDHI0_RX, +}; + extern void r8a7778_add_standard_devices(void); extern void r8a7778_add_standard_devices_dt(void); extern void r8a7778_add_ether_device(struct sh_eth_plat_data *pdata); @@ -33,6 +41,9 @@ extern void r8a7778_init_delay(void); extern void r8a7778_init_irq_dt(void); extern void r8a7778_clock_init(void); extern void r8a7778_init_irq_extpin(int irlm); +extern void r8a7778_init_irq_extpin_dt(int irlm); extern void r8a7778_pinmux_init(void); +extern int r8a7778_usb_phy_power(bool enable); + #endif /* __ASM_R8A7778_H__ */ diff --git a/arch/arm/mach-shmobile/include/mach/r8a7779.h b/arch/arm/mach-shmobile/include/mach/r8a7779.h index 11c740047e14..17af34ed89c8 100644 --- a/arch/arm/mach-shmobile/include/mach/r8a7779.h +++ b/arch/arm/mach-shmobile/include/mach/r8a7779.h @@ -6,6 +6,13 @@ #include <linux/sh_eth.h> #include <linux/platform_data/camera-rcar.h> +/* HPB-DMA slave IDs */ +enum { + HPBDMA_SLAVE_DUMMY, + HPBDMA_SLAVE_SDHI0_TX, + HPBDMA_SLAVE_SDHI0_RX, +}; + struct platform_device; struct r8a7779_pm_ch { @@ -26,6 +33,7 @@ static inline struct r8a7779_pm_ch *to_r8a7779_ch(struct generic_pm_domain *d) extern void r8a7779_init_delay(void); extern void r8a7779_init_irq_extpin(int irlm); +extern void r8a7779_init_irq_extpin_dt(int irlm); extern void r8a7779_init_irq_dt(void); extern void r8a7779_map_io(void); extern void r8a7779_earlytimer_init(void); diff --git a/arch/arm/mach-shmobile/include/mach/r8a7790.h b/arch/arm/mach-shmobile/include/mach/r8a7790.h index 788d55952091..5fbfa28b40b6 100644 --- a/arch/arm/mach-shmobile/include/mach/r8a7790.h +++ b/arch/arm/mach-shmobile/include/mach/r8a7790.h @@ -1,14 +1,13 @@ #ifndef __ASM_R8A7790_H__ #define __ASM_R8A7790_H__ +#include <mach/rcar-gen2.h> + void r8a7790_add_standard_devices(void); void r8a7790_add_dt_devices(void); void r8a7790_clock_init(void); void r8a7790_pinmux_init(void); -void r8a7790_init_delay(void); -void r8a7790_timer_init(void); - -#define MD(nr) BIT(nr) -u32 r8a7790_read_mode_pins(void); +void r8a7790_init_early(void); +extern struct smp_operations r8a7790_smp_ops; #endif /* __ASM_R8A7790_H__ */ diff --git a/arch/arm/mach-shmobile/include/mach/r8a7791.h b/arch/arm/mach-shmobile/include/mach/r8a7791.h new file mode 100644 index 000000000000..051ead3c286e --- /dev/null +++ b/arch/arm/mach-shmobile/include/mach/r8a7791.h @@ -0,0 +1,10 @@ +#ifndef __ASM_R8A7791_H__ +#define __ASM_R8A7791_H__ + +void r8a7791_add_standard_devices(void); +void r8a7791_add_dt_devices(void); +void r8a7791_clock_init(void); +void r8a7791_init_early(void); +extern struct smp_operations r8a7791_smp_ops; + +#endif /* __ASM_R8A7791_H__ */ diff --git a/arch/arm/mach-shmobile/include/mach/rcar-gen2.h b/arch/arm/mach-shmobile/include/mach/rcar-gen2.h new file mode 100644 index 000000000000..43f606eb2d82 --- /dev/null +++ b/arch/arm/mach-shmobile/include/mach/rcar-gen2.h @@ -0,0 +1,8 @@ +#ifndef __ASM_RCAR_GEN2_H__ +#define __ASM_RCAR_GEN2_H__ + +void rcar_gen2_timer_init(void); +#define MD(nr) BIT(nr) +u32 rcar_gen2_read_mode_pins(void); + +#endif /* __ASM_RCAR_GEN2_H__ */ diff --git a/arch/arm/mach-shmobile/platsmp-apmu.c b/arch/arm/mach-shmobile/platsmp-apmu.c new file mode 100644 index 000000000000..1da5a72d9642 --- /dev/null +++ b/arch/arm/mach-shmobile/platsmp-apmu.c @@ -0,0 +1,195 @@ +/* + * SMP support for SoCs with APMU + * + * 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/delay.h> +#include <linux/init.h> +#include <linux/io.h> +#include <linux/ioport.h> +#include <linux/of_address.h> +#include <linux/smp.h> +#include <asm/cacheflush.h> +#include <asm/cp15.h> +#include <asm/smp_plat.h> +#include <mach/common.h> + +static struct { + void __iomem *iomem; + int bit; +} apmu_cpus[CONFIG_NR_CPUS]; + +#define WUPCR_OFFS 0x10 +#define PSTR_OFFS 0x40 +#define CPUNCR_OFFS(n) (0x100 + (0x10 * (n))) + +static int apmu_power_on(void __iomem *p, int bit) +{ + /* request power on */ + writel_relaxed(BIT(bit), p + WUPCR_OFFS); + + /* wait for APMU to finish */ + while (readl_relaxed(p + WUPCR_OFFS) != 0) + ; + + return 0; +} + +static int apmu_power_off(void __iomem *p, int bit) +{ + /* request Core Standby for next WFI */ + writel_relaxed(3, p + CPUNCR_OFFS(bit)); + return 0; +} + +static int apmu_power_off_poll(void __iomem *p, int bit) +{ + int k; + + for (k = 0; k < 1000; k++) { + if (((readl_relaxed(p + PSTR_OFFS) >> (bit * 4)) & 0x03) == 3) + return 1; + + mdelay(1); + } + + return 0; +} + +static int apmu_wrap(int cpu, int (*fn)(void __iomem *p, int cpu)) +{ + void __iomem *p = apmu_cpus[cpu].iomem; + + return p ? fn(p, apmu_cpus[cpu].bit) : -EINVAL; +} + +static void apmu_init_cpu(struct resource *res, int cpu, int bit) +{ + if (apmu_cpus[cpu].iomem) + return; + + apmu_cpus[cpu].iomem = ioremap_nocache(res->start, resource_size(res)); + apmu_cpus[cpu].bit = bit; + + pr_debug("apmu ioremap %d %d 0x%08x 0x%08x\n", cpu, bit, + res->start, resource_size(res)); +} + +static struct { + struct resource iomem; + int cpus[4]; +} apmu_config[] = { + { + .iomem = DEFINE_RES_MEM(0xe6152000, 0x88), + .cpus = { 0, 1, 2, 3 }, + }, + { + .iomem = DEFINE_RES_MEM(0xe6151000, 0x88), + .cpus = { 0x100, 0x101, 0x102, 0x103 }, + } +}; + +static void apmu_parse_cfg(void (*fn)(struct resource *res, int cpu, int bit)) +{ + u32 id; + int k; + int bit, index; + bool is_allowed; + + for (k = 0; k < ARRAY_SIZE(apmu_config); k++) { + /* only enable the cluster that includes the boot CPU */ + is_allowed = false; + for (bit = 0; bit < ARRAY_SIZE(apmu_config[k].cpus); bit++) { + id = apmu_config[k].cpus[bit]; + if (id >= 0) { + if (id == cpu_logical_map(0)) + is_allowed = true; + } + } + if (!is_allowed) + continue; + + for (bit = 0; bit < ARRAY_SIZE(apmu_config[k].cpus); bit++) { + id = apmu_config[k].cpus[bit]; + if (id >= 0) { + index = get_logical_index(id); + if (index >= 0) + fn(&apmu_config[k].iomem, index, bit); + } + } + } +} + +void __init shmobile_smp_apmu_prepare_cpus(unsigned int max_cpus) +{ + /* install boot code shared by all CPUs */ + shmobile_boot_fn = virt_to_phys(shmobile_smp_boot); + shmobile_boot_arg = MPIDR_HWID_BITMASK; + + /* perform per-cpu setup */ + apmu_parse_cfg(apmu_init_cpu); +} + +int shmobile_smp_apmu_boot_secondary(unsigned int cpu, struct task_struct *idle) +{ + /* For this particular CPU register boot vector */ + shmobile_smp_hook(cpu, virt_to_phys(shmobile_invalidate_start), 0); + + return apmu_wrap(cpu, apmu_power_on); +} + +#ifdef CONFIG_HOTPLUG_CPU +/* nicked from arch/arm/mach-exynos/hotplug.c */ +static inline void cpu_enter_lowpower_a15(void) +{ + unsigned int v; + + asm volatile( + " mrc p15, 0, %0, c1, c0, 0\n" + " bic %0, %0, %1\n" + " mcr p15, 0, %0, c1, c0, 0\n" + : "=&r" (v) + : "Ir" (CR_C) + : "cc"); + + flush_cache_louis(); + + asm volatile( + /* + * Turn off coherency + */ + " mrc p15, 0, %0, c1, c0, 1\n" + " bic %0, %0, %1\n" + " mcr p15, 0, %0, c1, c0, 1\n" + : "=&r" (v) + : "Ir" (0x40) + : "cc"); + + isb(); + dsb(); +} + +void shmobile_smp_apmu_cpu_die(unsigned int cpu) +{ + /* For this particular CPU deregister boot vector */ + shmobile_smp_hook(cpu, 0, 0); + + /* Select next sleep mode using the APMU */ + apmu_wrap(cpu, apmu_power_off); + + /* Do ARM specific CPU shutdown */ + cpu_enter_lowpower_a15(); + + /* jump to shared mach-shmobile sleep / reset code */ + shmobile_smp_sleep(); +} + +int shmobile_smp_apmu_cpu_kill(unsigned int cpu) +{ + return apmu_wrap(cpu, apmu_power_off_poll); +} +#endif diff --git a/arch/arm/mach-shmobile/platsmp-scu.c b/arch/arm/mach-shmobile/platsmp-scu.c index c96f50160be6..673ad6e80869 100644 --- a/arch/arm/mach-shmobile/platsmp-scu.c +++ b/arch/arm/mach-shmobile/platsmp-scu.c @@ -7,6 +7,7 @@ * 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> #include <linux/init.h> #include <linux/io.h> @@ -16,6 +17,26 @@ #include <asm/smp_scu.h> #include <mach/common.h> +static int shmobile_smp_scu_notifier_call(struct notifier_block *nfb, + unsigned long action, void *hcpu) +{ + unsigned int cpu = (long)hcpu; + + switch (action) { + case CPU_UP_PREPARE: + /* For this particular CPU register SCU SMP boot vector */ + shmobile_smp_hook(cpu, virt_to_phys(shmobile_boot_scu), + (unsigned long)shmobile_scu_base); + break; + }; + + return NOTIFY_OK; +} + +static struct notifier_block shmobile_smp_scu_notifier = { + .notifier_call = shmobile_smp_scu_notifier_call, +}; + void __init shmobile_smp_scu_prepare_cpus(unsigned int max_cpus) { /* install boot code shared by all CPUs */ @@ -25,14 +46,9 @@ void __init shmobile_smp_scu_prepare_cpus(unsigned int max_cpus) /* enable SCU and cache coherency on booting CPU */ scu_enable(shmobile_scu_base); scu_power_mode(shmobile_scu_base, SCU_PM_NORMAL); -} -int shmobile_smp_scu_boot_secondary(unsigned int cpu, struct task_struct *idle) -{ - /* For this particular CPU register SCU boot vector */ - shmobile_smp_hook(cpu, virt_to_phys(shmobile_boot_scu), - (unsigned long)shmobile_scu_base); - return 0; + /* Use CPU notifier for reset vector control */ + register_cpu_notifier(&shmobile_smp_scu_notifier); } #ifdef CONFIG_HOTPLUG_CPU diff --git a/arch/arm/mach-shmobile/platsmp.c b/arch/arm/mach-shmobile/platsmp.c index d4ae616bcedb..9ebc246b8d7d 100644 --- a/arch/arm/mach-shmobile/platsmp.c +++ b/arch/arm/mach-shmobile/platsmp.c @@ -11,25 +11,10 @@ * published by the Free Software Foundation. */ #include <linux/init.h> -#include <linux/smp.h> #include <asm/cacheflush.h> #include <asm/smp_plat.h> #include <mach/common.h> -void __init shmobile_smp_init_cpus(unsigned int ncores) -{ - unsigned int i; - - if (ncores > nr_cpu_ids) { - pr_warn("SMP: %u cores greater than maximum (%u), clipping\n", - ncores, nr_cpu_ids); - ncores = nr_cpu_ids; - } - - for (i = 0; i < ncores; i++) - set_cpu_possible(i, true); -} - extern unsigned long shmobile_smp_fn[]; extern unsigned long shmobile_smp_arg[]; extern unsigned long shmobile_smp_mpidr[]; @@ -44,3 +29,10 @@ void shmobile_smp_hook(unsigned int cpu, unsigned long fn, unsigned long arg) shmobile_smp_arg[cpu] = arg; flush_cache_all(); } + +#ifdef CONFIG_HOTPLUG_CPU +int shmobile_smp_cpu_disable(unsigned int cpu) +{ + return 0; /* Hotplug of any CPU is supported */ +} +#endif diff --git a/arch/arm/mach-shmobile/setup-r7s72100.c b/arch/arm/mach-shmobile/setup-r7s72100.c new file mode 100644 index 000000000000..d4eb509a1c87 --- /dev/null +++ b/arch/arm/mach-shmobile/setup-r7s72100.c @@ -0,0 +1,88 @@ +/* + * r7s72100 processor support + * + * Copyright (C) 2013 Renesas Solutions Corp. + * 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 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. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include <linux/irq.h> +#include <linux/kernel.h> +#include <linux/of_platform.h> +#include <linux/serial_sci.h> +#include <mach/common.h> +#include <mach/irqs.h> +#include <mach/r7s72100.h> +#include <asm/mach/arch.h> + +#define SCIF_DATA(index, baseaddr, irq) \ +[index] = { \ + .type = PORT_SCIF, \ + .regtype = SCIx_SH2_SCIF_FIFODATA_REGTYPE, \ + .flags = UPF_BOOT_AUTOCONF | UPF_IOREMAP, \ + .scbrr_algo_id = SCBRR_ALGO_2, \ + .scscr = SCSCR_RIE | SCSCR_TIE | SCSCR_RE | SCSCR_TE | \ + SCSCR_REIE, \ + .mapbase = baseaddr, \ + .irqs = { irq + 1, irq + 2, irq + 3, irq }, \ +} + +enum { SCIF0, SCIF1, SCIF2, SCIF3, SCIF4, SCIF5, SCIF6, SCIF7 }; + +static const struct plat_sci_port scif[] __initconst = { + SCIF_DATA(SCIF0, 0xe8007000, gic_iid(221)), /* SCIF0 */ + SCIF_DATA(SCIF1, 0xe8007800, gic_iid(225)), /* SCIF1 */ + SCIF_DATA(SCIF2, 0xe8008000, gic_iid(229)), /* SCIF2 */ + SCIF_DATA(SCIF3, 0xe8008800, gic_iid(233)), /* SCIF3 */ + SCIF_DATA(SCIF4, 0xe8009000, gic_iid(237)), /* SCIF4 */ + SCIF_DATA(SCIF5, 0xe8009800, gic_iid(241)), /* SCIF5 */ + SCIF_DATA(SCIF6, 0xe800a000, gic_iid(245)), /* SCIF6 */ + SCIF_DATA(SCIF7, 0xe800a800, gic_iid(249)), /* SCIF7 */ +}; + +static inline void r7s72100_register_scif(int idx) +{ + platform_device_register_data(&platform_bus, "sh-sci", idx, &scif[idx], + sizeof(struct plat_sci_port)); +} + +void __init r7s72100_add_dt_devices(void) +{ + r7s72100_register_scif(SCIF0); + r7s72100_register_scif(SCIF1); + r7s72100_register_scif(SCIF2); + r7s72100_register_scif(SCIF3); + r7s72100_register_scif(SCIF4); + r7s72100_register_scif(SCIF5); + r7s72100_register_scif(SCIF6); + r7s72100_register_scif(SCIF7); +} + +void __init r7s72100_init_early(void) +{ + shmobile_setup_delay(400, 1, 3); /* Cortex-A9 @ 400MHz */ +} + +#ifdef CONFIG_USE_OF +static const char *r7s72100_boards_compat_dt[] __initdata = { + "renesas,r7s72100", + NULL, +}; + +DT_MACHINE_START(R7S72100_DT, "Generic R7S72100 (Flattened Device Tree)") + .init_early = r7s72100_init_early, + .dt_compat = r7s72100_boards_compat_dt, +MACHINE_END +#endif /* CONFIG_USE_OF */ diff --git a/arch/arm/mach-shmobile/setup-r8a73a4.c b/arch/arm/mach-shmobile/setup-r8a73a4.c index 89491700afb7..b0f2749071be 100644 --- a/arch/arm/mach-shmobile/setup-r8a73a4.c +++ b/arch/arm/mach-shmobile/setup-r8a73a4.c @@ -22,8 +22,10 @@ #include <linux/of_platform.h> #include <linux/platform_data/irq-renesas-irqc.h> #include <linux/serial_sci.h> +#include <linux/sh_dma.h> #include <linux/sh_timer.h> #include <mach/common.h> +#include <mach/dma-register.h> #include <mach/irqs.h> #include <mach/r8a73a4.h> #include <asm/mach/arch.h> @@ -199,15 +201,104 @@ void __init r8a73a4_add_dt_devices(void) r8a7790_register_cmt(10); } +/* DMA */ +static const struct sh_dmae_slave_config dma_slaves[] = { + { + .slave_id = SHDMA_SLAVE_MMCIF0_TX, + .addr = 0xee200034, + .chcr = CHCR_TX(XMIT_SZ_32BIT), + .mid_rid = 0xd1, + }, { + .slave_id = SHDMA_SLAVE_MMCIF0_RX, + .addr = 0xee200034, + .chcr = CHCR_RX(XMIT_SZ_32BIT), + .mid_rid = 0xd2, + }, { + .slave_id = SHDMA_SLAVE_MMCIF1_TX, + .addr = 0xee220034, + .chcr = CHCR_TX(XMIT_SZ_32BIT), + .mid_rid = 0xe1, + }, { + .slave_id = SHDMA_SLAVE_MMCIF1_RX, + .addr = 0xee220034, + .chcr = CHCR_RX(XMIT_SZ_32BIT), + .mid_rid = 0xe2, + }, +}; + +#define DMAE_CHANNEL(a, b) \ + { \ + .offset = (a) - 0x20, \ + .dmars = (a) - 0x20 + 0x40, \ + .chclr_bit = (b), \ + .chclr_offset = 0x80 - 0x20, \ + } + +static const struct sh_dmae_channel dma_channels[] = { + DMAE_CHANNEL(0x8000, 0), + DMAE_CHANNEL(0x8080, 1), + DMAE_CHANNEL(0x8100, 2), + DMAE_CHANNEL(0x8180, 3), + DMAE_CHANNEL(0x8200, 4), + DMAE_CHANNEL(0x8280, 5), + DMAE_CHANNEL(0x8300, 6), + DMAE_CHANNEL(0x8380, 7), + DMAE_CHANNEL(0x8400, 8), + DMAE_CHANNEL(0x8480, 9), + DMAE_CHANNEL(0x8500, 10), + DMAE_CHANNEL(0x8580, 11), + DMAE_CHANNEL(0x8600, 12), + DMAE_CHANNEL(0x8680, 13), + DMAE_CHANNEL(0x8700, 14), + DMAE_CHANNEL(0x8780, 15), + DMAE_CHANNEL(0x8800, 16), + DMAE_CHANNEL(0x8880, 17), + DMAE_CHANNEL(0x8900, 18), + DMAE_CHANNEL(0x8980, 19), +}; + +static const struct sh_dmae_pdata dma_pdata = { + .slave = dma_slaves, + .slave_num = ARRAY_SIZE(dma_slaves), + .channel = dma_channels, + .channel_num = ARRAY_SIZE(dma_channels), + .ts_low_shift = TS_LOW_SHIFT, + .ts_low_mask = TS_LOW_BIT << TS_LOW_SHIFT, + .ts_high_shift = TS_HI_SHIFT, + .ts_high_mask = TS_HI_BIT << TS_HI_SHIFT, + .ts_shift = dma_ts_shift, + .ts_shift_num = ARRAY_SIZE(dma_ts_shift), + .dmaor_init = DMAOR_DME, + .chclr_present = 1, + .chclr_bitwise = 1, +}; + +static struct resource dma_resources[] = { + DEFINE_RES_MEM(0xe6700020, 0x89e0), + DEFINE_RES_IRQ_NAMED(gic_spi(220), "error_irq"), + { + /* IRQ for channels 0-19 */ + .start = gic_spi(200), + .end = gic_spi(219), + .flags = IORESOURCE_IRQ, + }, +}; + +#define r8a73a4_register_dmac() \ + platform_device_register_resndata(&platform_bus, "sh-dma-engine", 0, \ + dma_resources, ARRAY_SIZE(dma_resources), \ + &dma_pdata, sizeof(dma_pdata)) + void __init r8a73a4_add_standard_devices(void) { r8a73a4_add_dt_devices(); r8a73a4_register_irqc(0); r8a73a4_register_irqc(1); r8a73a4_register_thermal(); + r8a73a4_register_dmac(); } -void __init r8a73a4_init_delay(void) +void __init r8a73a4_init_early(void) { #ifndef CONFIG_ARM_ARCH_TIMER shmobile_setup_delay(1500, 2, 4); /* Cortex-A15 @ 1500MHz */ @@ -222,7 +313,7 @@ static const char *r8a73a4_boards_compat_dt[] __initdata = { }; DT_MACHINE_START(R8A73A4_DT, "Generic R8A73A4 (Flattened Device Tree)") - .init_early = r8a73a4_init_delay, + .init_early = r8a73a4_init_early, .dt_compat = r8a73a4_boards_compat_dt, MACHINE_END #endif /* CONFIG_USE_OF */ diff --git a/arch/arm/mach-shmobile/setup-r8a7778.c b/arch/arm/mach-shmobile/setup-r8a7778.c index 6a2657ebd197..16d49aa8b5db 100644 --- a/arch/arm/mach-shmobile/setup-r8a7778.c +++ b/arch/arm/mach-shmobile/setup-r8a7778.c @@ -24,6 +24,7 @@ #include <linux/irqchip/arm-gic.h> #include <linux/of.h> #include <linux/of_platform.h> +#include <linux/platform_data/dma-rcar-hpbdma.h> #include <linux/platform_data/gpio-rcar.h> #include <linux/platform_data/irq-renesas-intc-irqpin.h> #include <linux/platform_device.h> @@ -95,29 +96,46 @@ static struct sh_timer_config sh_tmu1_platform_data __initdata = { &sh_tmu##idx##_platform_data, \ sizeof(sh_tmu##idx##_platform_data)) -/* USB */ -static struct usb_phy *phy; +int r8a7778_usb_phy_power(bool enable) +{ + static struct usb_phy *phy = NULL; + int ret = 0; + + if (!phy) + phy = usb_get_phy(USB_PHY_TYPE_USB2); + + if (IS_ERR(phy)) { + pr_err("kernel doesn't have usb phy driver\n"); + return PTR_ERR(phy); + } + + if (enable) + ret = usb_phy_init(phy); + else + usb_phy_shutdown(phy); + return ret; +} + +/* USB */ static int usb_power_on(struct platform_device *pdev) { - if (IS_ERR(phy)) - return PTR_ERR(phy); + int ret = r8a7778_usb_phy_power(true); + + if (ret) + return ret; pm_runtime_enable(&pdev->dev); pm_runtime_get_sync(&pdev->dev); - usb_phy_init(phy); - return 0; } static void usb_power_off(struct platform_device *pdev) { - if (IS_ERR(phy)) + if (r8a7778_usb_phy_power(false)) return; - usb_phy_shutdown(phy); - pm_runtime_put_sync(&pdev->dev); pm_runtime_disable(&pdev->dev); } @@ -339,6 +357,88 @@ void __init r8a7778_add_dt_devices(void) r8a7778_register_tmu(1); } +/* HPB-DMA */ + +/* Asynchronous mode register (ASYNCMDR) bits */ +#define HPB_DMAE_ASYNCMDR_ASMD22_MASK BIT(2) /* SDHI0 */ +#define HPB_DMAE_ASYNCMDR_ASMD22_SINGLE BIT(2) /* SDHI0 */ +#define HPB_DMAE_ASYNCMDR_ASMD22_MULTI 0 /* SDHI0 */ +#define HPB_DMAE_ASYNCMDR_ASMD21_MASK BIT(1) /* SDHI0 */ +#define HPB_DMAE_ASYNCMDR_ASMD21_SINGLE BIT(1) /* SDHI0 */ +#define HPB_DMAE_ASYNCMDR_ASMD21_MULTI 0 /* SDHI0 */ + +static const struct hpb_dmae_slave_config hpb_dmae_slaves[] = { + { + .id = HPBDMA_SLAVE_SDHI0_TX, + .addr = 0xffe4c000 + 0x30, + .dcr = HPB_DMAE_DCR_SPDS_16BIT | + HPB_DMAE_DCR_DMDL | + HPB_DMAE_DCR_DPDS_16BIT, + .rstr = HPB_DMAE_ASYNCRSTR_ASRST21 | + HPB_DMAE_ASYNCRSTR_ASRST22 | + HPB_DMAE_ASYNCRSTR_ASRST23, + .mdr = HPB_DMAE_ASYNCMDR_ASMD21_MULTI, + .mdm = HPB_DMAE_ASYNCMDR_ASMD21_MASK, + .port = 0x0D0C, + .flags = HPB_DMAE_SET_ASYNC_RESET | HPB_DMAE_SET_ASYNC_MODE, + .dma_ch = 21, + }, { + .id = HPBDMA_SLAVE_SDHI0_RX, + .addr = 0xffe4c000 + 0x30, + .dcr = HPB_DMAE_DCR_SMDL | + HPB_DMAE_DCR_SPDS_16BIT | + HPB_DMAE_DCR_DPDS_16BIT, + .rstr = HPB_DMAE_ASYNCRSTR_ASRST21 | + HPB_DMAE_ASYNCRSTR_ASRST22 | + HPB_DMAE_ASYNCRSTR_ASRST23, + .mdr = HPB_DMAE_ASYNCMDR_ASMD22_MULTI, + .mdm = HPB_DMAE_ASYNCMDR_ASMD22_MASK, + .port = 0x0D0C, + .flags = HPB_DMAE_SET_ASYNC_RESET | HPB_DMAE_SET_ASYNC_MODE, + .dma_ch = 22, + }, +}; + +static const struct hpb_dmae_channel hpb_dmae_channels[] = { + HPB_DMAE_CHANNEL(0x7e, HPBDMA_SLAVE_SDHI0_TX), /* ch. 21 */ + HPB_DMAE_CHANNEL(0x7e, HPBDMA_SLAVE_SDHI0_RX), /* ch. 22 */ +}; + +static struct hpb_dmae_pdata dma_platform_data __initdata = { + .slaves = hpb_dmae_slaves, + .num_slaves = ARRAY_SIZE(hpb_dmae_slaves), + .channels = hpb_dmae_channels, + .num_channels = ARRAY_SIZE(hpb_dmae_channels), + .ts_shift = { + [XMIT_SZ_8BIT] = 0, + [XMIT_SZ_16BIT] = 1, + [XMIT_SZ_32BIT] = 2, + }, + .num_hw_channels = 39, +}; + +static struct resource hpb_dmae_resources[] __initdata = { + /* Channel registers */ + DEFINE_RES_MEM(0xffc08000, 0x1000), + /* Common registers */ + DEFINE_RES_MEM(0xffc09000, 0x170), + /* Asynchronous reset registers */ + DEFINE_RES_MEM(0xffc00300, 4), + /* Asynchronous mode registers */ + DEFINE_RES_MEM(0xffc00400, 4), + /* IRQ for DMA channels */ + DEFINE_RES_NAMED(gic_iid(0x7b), 5, NULL, IORESOURCE_IRQ), +}; + +static void __init r8a7778_register_hpb_dmae(void) +{ + platform_device_register_resndata(&platform_bus, "hpb-dma-engine", -1, + hpb_dmae_resources, + ARRAY_SIZE(hpb_dmae_resources), + &dma_platform_data, + sizeof(dma_platform_data)); +} + void __init r8a7778_add_standard_devices(void) { r8a7778_add_dt_devices(); @@ -349,12 +449,12 @@ void __init r8a7778_add_standard_devices(void) r8a7778_register_hspi(0); r8a7778_register_hspi(1); r8a7778_register_hspi(2); + + r8a7778_register_hpb_dmae(); } void __init r8a7778_init_late(void) { - phy = usb_get_phy(USB_PHY_TYPE_USB2); - platform_device_register_full(&ehci_info); platform_device_register_full(&ohci_info); } @@ -376,7 +476,7 @@ static struct resource irqpin_resources[] __initdata = { DEFINE_RES_IRQ(gic_iid(0x3e)), /* IRQ3 */ }; -void __init r8a7778_init_irq_extpin(int irlm) +void __init r8a7778_init_irq_extpin_dt(int irlm) { void __iomem *icr0 = ioremap_nocache(0xfe780000, PAGE_SIZE); unsigned long tmp; @@ -394,7 +494,11 @@ void __init r8a7778_init_irq_extpin(int irlm) tmp |= (1 << 21); /* LVLMODE = 1 */ iowrite32(tmp, icr0); iounmap(icr0); +} +void __init r8a7778_init_irq_extpin(int irlm) +{ + r8a7778_init_irq_extpin_dt(irlm); if (irlm) platform_device_register_resndata( &platform_bus, "renesas_intc_irqpin", -1, diff --git a/arch/arm/mach-shmobile/setup-r8a7779.c b/arch/arm/mach-shmobile/setup-r8a7779.c index ecd0148ee1e1..13049e9d691c 100644 --- a/arch/arm/mach-shmobile/setup-r8a7779.c +++ b/arch/arm/mach-shmobile/setup-r8a7779.c @@ -25,6 +25,7 @@ #include <linux/irqchip.h> #include <linux/irqchip/arm-gic.h> #include <linux/of_platform.h> +#include <linux/platform_data/dma-rcar-hpbdma.h> #include <linux/platform_data/gpio-rcar.h> #include <linux/platform_data/irq-renesas-intc-irqpin.h> #include <linux/platform_device.h> @@ -97,7 +98,7 @@ static struct resource irqpin0_resources[] __initdata = { DEFINE_RES_IRQ(gic_spi(30)), /* IRQ3 */ }; -void __init r8a7779_init_irq_extpin(int irlm) +void __init r8a7779_init_irq_extpin_dt(int irlm) { void __iomem *icr0 = ioremap_nocache(0xfe780000, PAGE_SIZE); u32 tmp; @@ -115,7 +116,11 @@ void __init r8a7779_init_irq_extpin(int irlm) tmp |= (1 << 21); /* LVLMODE = 1 */ iowrite32(tmp, icr0); iounmap(icr0); +} +void __init r8a7779_init_irq_extpin(int irlm) +{ + r8a7779_init_irq_extpin_dt(irlm); if (irlm) platform_device_register_resndata( &platform_bus, "renesas_intc_irqpin", -1, @@ -632,6 +637,158 @@ static struct platform_device_info *vin_info_table[] __initdata = { &vin3_info, }; +/* HPB-DMA */ + +/* Asynchronous mode register bits */ +#define HPB_DMAE_ASYNCMDR_ASMD43_MASK BIT(23) /* MMC1 */ +#define HPB_DMAE_ASYNCMDR_ASMD43_SINGLE BIT(23) /* MMC1 */ +#define HPB_DMAE_ASYNCMDR_ASMD43_MULTI 0 /* MMC1 */ +#define HPB_DMAE_ASYNCMDR_ASBTMD43_MASK BIT(22) /* MMC1 */ +#define HPB_DMAE_ASYNCMDR_ASBTMD43_BURST BIT(22) /* MMC1 */ +#define HPB_DMAE_ASYNCMDR_ASBTMD43_NBURST 0 /* MMC1 */ +#define HPB_DMAE_ASYNCMDR_ASMD24_MASK BIT(21) /* MMC0 */ +#define HPB_DMAE_ASYNCMDR_ASMD24_SINGLE BIT(21) /* MMC0 */ +#define HPB_DMAE_ASYNCMDR_ASMD24_MULTI 0 /* MMC0 */ +#define HPB_DMAE_ASYNCMDR_ASBTMD24_MASK BIT(20) /* MMC0 */ +#define HPB_DMAE_ASYNCMDR_ASBTMD24_BURST BIT(20) /* MMC0 */ +#define HPB_DMAE_ASYNCMDR_ASBTMD24_NBURST 0 /* MMC0 */ +#define HPB_DMAE_ASYNCMDR_ASMD41_MASK BIT(19) /* SDHI3 */ +#define HPB_DMAE_ASYNCMDR_ASMD41_SINGLE BIT(19) /* SDHI3 */ +#define HPB_DMAE_ASYNCMDR_ASMD41_MULTI 0 /* SDHI3 */ +#define HPB_DMAE_ASYNCMDR_ASBTMD41_MASK BIT(18) /* SDHI3 */ +#define HPB_DMAE_ASYNCMDR_ASBTMD41_BURST BIT(18) /* SDHI3 */ +#define HPB_DMAE_ASYNCMDR_ASBTMD41_NBURST 0 /* SDHI3 */ +#define HPB_DMAE_ASYNCMDR_ASMD40_MASK BIT(17) /* SDHI3 */ +#define HPB_DMAE_ASYNCMDR_ASMD40_SINGLE BIT(17) /* SDHI3 */ +#define HPB_DMAE_ASYNCMDR_ASMD40_MULTI 0 /* SDHI3 */ +#define HPB_DMAE_ASYNCMDR_ASBTMD40_MASK BIT(16) /* SDHI3 */ +#define HPB_DMAE_ASYNCMDR_ASBTMD40_BURST BIT(16) /* SDHI3 */ +#define HPB_DMAE_ASYNCMDR_ASBTMD40_NBURST 0 /* SDHI3 */ +#define HPB_DMAE_ASYNCMDR_ASMD39_MASK BIT(15) /* SDHI3 */ +#define HPB_DMAE_ASYNCMDR_ASMD39_SINGLE BIT(15) /* SDHI3 */ +#define HPB_DMAE_ASYNCMDR_ASMD39_MULTI 0 /* SDHI3 */ +#define HPB_DMAE_ASYNCMDR_ASBTMD39_MASK BIT(14) /* SDHI3 */ +#define HPB_DMAE_ASYNCMDR_ASBTMD39_BURST BIT(14) /* SDHI3 */ +#define HPB_DMAE_ASYNCMDR_ASBTMD39_NBURST 0 /* SDHI3 */ +#define HPB_DMAE_ASYNCMDR_ASMD27_MASK BIT(13) /* SDHI2 */ +#define HPB_DMAE_ASYNCMDR_ASMD27_SINGLE BIT(13) /* SDHI2 */ +#define HPB_DMAE_ASYNCMDR_ASMD27_MULTI 0 /* SDHI2 */ +#define HPB_DMAE_ASYNCMDR_ASBTMD27_MASK BIT(12) /* SDHI2 */ +#define HPB_DMAE_ASYNCMDR_ASBTMD27_BURST BIT(12) /* SDHI2 */ +#define HPB_DMAE_ASYNCMDR_ASBTMD27_NBURST 0 /* SDHI2 */ +#define HPB_DMAE_ASYNCMDR_ASMD26_MASK BIT(11) /* SDHI2 */ +#define HPB_DMAE_ASYNCMDR_ASMD26_SINGLE BIT(11) /* SDHI2 */ +#define HPB_DMAE_ASYNCMDR_ASMD26_MULTI 0 /* SDHI2 */ +#define HPB_DMAE_ASYNCMDR_ASBTMD26_MASK BIT(10) /* SDHI2 */ +#define HPB_DMAE_ASYNCMDR_ASBTMD26_BURST BIT(10) /* SDHI2 */ +#define HPB_DMAE_ASYNCMDR_ASBTMD26_NBURST 0 /* SDHI2 */ +#define HPB_DMAE_ASYNCMDR_ASMD25_MASK BIT(9) /* SDHI2 */ +#define HPB_DMAE_ASYNCMDR_ASMD25_SINGLE BIT(9) /* SDHI2 */ +#define HPB_DMAE_ASYNCMDR_ASMD25_MULTI 0 /* SDHI2 */ +#define HPB_DMAE_ASYNCMDR_ASBTMD25_MASK BIT(8) /* SDHI2 */ +#define HPB_DMAE_ASYNCMDR_ASBTMD25_BURST BIT(8) /* SDHI2 */ +#define HPB_DMAE_ASYNCMDR_ASBTMD25_NBURST 0 /* SDHI2 */ +#define HPB_DMAE_ASYNCMDR_ASMD23_MASK BIT(7) /* SDHI0 */ +#define HPB_DMAE_ASYNCMDR_ASMD23_SINGLE BIT(7) /* SDHI0 */ +#define HPB_DMAE_ASYNCMDR_ASMD23_MULTI 0 /* SDHI0 */ +#define HPB_DMAE_ASYNCMDR_ASBTMD23_MASK BIT(6) /* SDHI0 */ +#define HPB_DMAE_ASYNCMDR_ASBTMD23_BURST BIT(6) /* SDHI0 */ +#define HPB_DMAE_ASYNCMDR_ASBTMD23_NBURST 0 /* SDHI0 */ +#define HPB_DMAE_ASYNCMDR_ASMD22_MASK BIT(5) /* SDHI0 */ +#define HPB_DMAE_ASYNCMDR_ASMD22_SINGLE BIT(5) /* SDHI0 */ +#define HPB_DMAE_ASYNCMDR_ASMD22_MULTI 0 /* SDHI0 */ +#define HPB_DMAE_ASYNCMDR_ASBTMD22_MASK BIT(4) /* SDHI0 */ +#define HPB_DMAE_ASYNCMDR_ASBTMD22_BURST BIT(4) /* SDHI0 */ +#define HPB_DMAE_ASYNCMDR_ASBTMD22_NBURST 0 /* SDHI0 */ +#define HPB_DMAE_ASYNCMDR_ASMD21_MASK BIT(3) /* SDHI0 */ +#define HPB_DMAE_ASYNCMDR_ASMD21_SINGLE BIT(3) /* SDHI0 */ +#define HPB_DMAE_ASYNCMDR_ASMD21_MULTI 0 /* SDHI0 */ +#define HPB_DMAE_ASYNCMDR_ASBTMD21_MASK BIT(2) /* SDHI0 */ +#define HPB_DMAE_ASYNCMDR_ASBTMD21_BURST BIT(2) /* SDHI0 */ +#define HPB_DMAE_ASYNCMDR_ASBTMD21_NBURST 0 /* SDHI0 */ +#define HPB_DMAE_ASYNCMDR_ASMD20_MASK BIT(1) /* SDHI1 */ +#define HPB_DMAE_ASYNCMDR_ASMD20_SINGLE BIT(1) /* SDHI1 */ +#define HPB_DMAE_ASYNCMDR_ASMD20_MULTI 0 /* SDHI1 */ +#define HPB_DMAE_ASYNCMDR_ASBTMD20_MASK BIT(0) /* SDHI1 */ +#define HPB_DMAE_ASYNCMDR_ASBTMD20_BURST BIT(0) /* SDHI1 */ +#define HPB_DMAE_ASYNCMDR_ASBTMD20_NBURST 0 /* SDHI1 */ + +static const struct hpb_dmae_slave_config hpb_dmae_slaves[] = { + { + .id = HPBDMA_SLAVE_SDHI0_TX, + .addr = 0xffe4c000 + 0x30, + .dcr = HPB_DMAE_DCR_SPDS_16BIT | + HPB_DMAE_DCR_DMDL | + HPB_DMAE_DCR_DPDS_16BIT, + .rstr = HPB_DMAE_ASYNCRSTR_ASRST21 | + HPB_DMAE_ASYNCRSTR_ASRST22 | + HPB_DMAE_ASYNCRSTR_ASRST23, + .mdr = HPB_DMAE_ASYNCMDR_ASMD21_SINGLE | + HPB_DMAE_ASYNCMDR_ASBTMD21_NBURST, + .mdm = HPB_DMAE_ASYNCMDR_ASMD21_MASK | + HPB_DMAE_ASYNCMDR_ASBTMD21_MASK, + .port = 0x0D0C, + .flags = HPB_DMAE_SET_ASYNC_RESET | HPB_DMAE_SET_ASYNC_MODE, + .dma_ch = 21, + }, { + .id = HPBDMA_SLAVE_SDHI0_RX, + .addr = 0xffe4c000 + 0x30, + .dcr = HPB_DMAE_DCR_SMDL | + HPB_DMAE_DCR_SPDS_16BIT | + HPB_DMAE_DCR_DPDS_16BIT, + .rstr = HPB_DMAE_ASYNCRSTR_ASRST21 | + HPB_DMAE_ASYNCRSTR_ASRST22 | + HPB_DMAE_ASYNCRSTR_ASRST23, + .mdr = HPB_DMAE_ASYNCMDR_ASMD22_SINGLE | + HPB_DMAE_ASYNCMDR_ASBTMD22_NBURST, + .mdm = HPB_DMAE_ASYNCMDR_ASMD22_MASK | + HPB_DMAE_ASYNCMDR_ASBTMD22_MASK, + .port = 0x0D0C, + .flags = HPB_DMAE_SET_ASYNC_RESET | HPB_DMAE_SET_ASYNC_MODE, + .dma_ch = 22, + }, +}; + +static const struct hpb_dmae_channel hpb_dmae_channels[] = { + HPB_DMAE_CHANNEL(0x93, HPBDMA_SLAVE_SDHI0_TX), /* ch. 21 */ + HPB_DMAE_CHANNEL(0x93, HPBDMA_SLAVE_SDHI0_RX), /* ch. 22 */ +}; + +static struct hpb_dmae_pdata dma_platform_data __initdata = { + .slaves = hpb_dmae_slaves, + .num_slaves = ARRAY_SIZE(hpb_dmae_slaves), + .channels = hpb_dmae_channels, + .num_channels = ARRAY_SIZE(hpb_dmae_channels), + .ts_shift = { + [XMIT_SZ_8BIT] = 0, + [XMIT_SZ_16BIT] = 1, + [XMIT_SZ_32BIT] = 2, + }, + .num_hw_channels = 44, +}; + +static struct resource hpb_dmae_resources[] __initdata = { + /* Channel registers */ + DEFINE_RES_MEM(0xffc08000, 0x1000), + /* Common registers */ + DEFINE_RES_MEM(0xffc09000, 0x170), + /* Asynchronous reset registers */ + DEFINE_RES_MEM(0xffc00300, 4), + /* Asynchronous mode registers */ + DEFINE_RES_MEM(0xffc00400, 4), + /* IRQ for DMA channels */ + DEFINE_RES_NAMED(gic_iid(0x8e), 12, NULL, IORESOURCE_IRQ), +}; + +static void __init r8a7779_register_hpb_dmae(void) +{ + platform_device_register_resndata(&platform_bus, "hpb-dma-engine", -1, + hpb_dmae_resources, + ARRAY_SIZE(hpb_dmae_resources), + &dma_platform_data, + sizeof(dma_platform_data)); +} + static struct platform_device *r8a7779_devices_dt[] __initdata = { &scif0_device, &scif1_device, @@ -665,6 +822,7 @@ void __init r8a7779_add_standard_devices(void) ARRAY_SIZE(r8a7779_devices_dt)); platform_add_devices(r8a7779_standard_devices, ARRAY_SIZE(r8a7779_standard_devices)); + r8a7779_register_hpb_dmae(); } void __init r8a7779_add_ether_device(struct sh_eth_plat_data *pdata) diff --git a/arch/arm/mach-shmobile/setup-r8a7790.c b/arch/arm/mach-shmobile/setup-r8a7790.c index d0f5c9f9349a..c47bcebbcb00 100644 --- a/arch/arm/mach-shmobile/setup-r8a7790.c +++ b/arch/arm/mach-shmobile/setup-r8a7790.c @@ -18,7 +18,6 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ -#include <linux/clocksource.h> #include <linux/irq.h> #include <linux/kernel.h> #include <linux/of_platform.h> @@ -31,17 +30,18 @@ #include <mach/r8a7790.h> #include <asm/mach/arch.h> -static struct resource pfc_resources[] __initdata = { +static const struct resource pfc_resources[] __initconst = { DEFINE_RES_MEM(0xe6060000, 0x250), }; #define R8A7790_GPIO(idx) \ -static struct resource r8a7790_gpio##idx##_resources[] __initdata = { \ +static const struct resource r8a7790_gpio##idx##_resources[] __initconst = { \ DEFINE_RES_MEM(0xe6050000 + 0x1000 * (idx), 0x50), \ DEFINE_RES_IRQ(gic_spi(4 + (idx))), \ }; \ \ -static struct gpio_rcar_config r8a7790_gpio##idx##_platform_data __initdata = { \ +static const struct gpio_rcar_config \ +r8a7790_gpio##idx##_platform_data __initconst = { \ .gpio_base = 32 * (idx), \ .irq_base = 0, \ .number_of_pins = 32, \ @@ -112,7 +112,7 @@ void __init r8a7790_pinmux_init(void) enum { SCIFA0, SCIFA1, SCIFB0, SCIFB1, SCIFB2, SCIFA2, SCIF0, SCIF1, HSCIF0, HSCIF1 }; -static struct plat_sci_port scif[] __initdata = { +static const struct plat_sci_port scif[] __initconst = { SCIFA_DATA(SCIFA0, 0xe6c40000, gic_spi(144)), /* SCIFA0 */ SCIFA_DATA(SCIFA1, 0xe6c50000, gic_spi(145)), /* SCIFA1 */ SCIFB_DATA(SCIFB0, 0xe6c20000, gic_spi(148)), /* SCIFB0 */ @@ -131,11 +131,11 @@ static inline void r8a7790_register_scif(int idx) sizeof(struct plat_sci_port)); } -static struct renesas_irqc_config irqc0_data __initdata = { +static const struct renesas_irqc_config irqc0_data __initconst = { .irq_base = irq_pin(0), /* IRQ0 -> IRQ3 */ }; -static struct resource irqc0_resources[] __initdata = { +static const struct resource irqc0_resources[] __initconst = { DEFINE_RES_MEM(0xe61c0000, 0x200), /* IRQC Event Detector Block_0 */ DEFINE_RES_IRQ(gic_spi(0)), /* IRQ0 */ DEFINE_RES_IRQ(gic_spi(1)), /* IRQ1 */ @@ -150,7 +150,7 @@ static struct resource irqc0_resources[] __initdata = { &irqc##idx##_data, \ sizeof(struct renesas_irqc_config)) -static struct resource thermal_resources[] __initdata = { +static const struct resource thermal_resources[] __initconst = { DEFINE_RES_MEM(0xe61f0000, 0x14), DEFINE_RES_MEM(0xe61f0100, 0x38), DEFINE_RES_IRQ(gic_spi(69)), @@ -161,13 +161,13 @@ static struct resource thermal_resources[] __initdata = { thermal_resources, \ ARRAY_SIZE(thermal_resources)) -static struct sh_timer_config cmt00_platform_data __initdata = { +static const struct sh_timer_config cmt00_platform_data __initconst = { .name = "CMT00", .timer_bit = 0, .clockevent_rating = 80, }; -static struct resource cmt00_resources[] __initdata = { +static const struct resource cmt00_resources[] __initconst = { DEFINE_RES_MEM(0xffca0510, 0x0c), DEFINE_RES_MEM(0xffca0500, 0x04), DEFINE_RES_IRQ(gic_spi(142)), /* CMT0_0 */ @@ -202,72 +202,7 @@ void __init r8a7790_add_standard_devices(void) r8a7790_register_thermal(); } -#define MODEMR 0xe6160060 - -u32 __init r8a7790_read_mode_pins(void) -{ - void __iomem *modemr = ioremap_nocache(MODEMR, 4); - u32 mode; - - BUG_ON(!modemr); - mode = ioread32(modemr); - iounmap(modemr); - - return mode; -} - -#define CNTCR 0 -#define CNTFID0 0x20 - -void __init r8a7790_timer_init(void) -{ -#ifdef CONFIG_ARM_ARCH_TIMER - u32 mode = r8a7790_read_mode_pins(); - void __iomem *base; - int extal_mhz = 0; - u32 freq; - - /* At Linux boot time the r8a7790 arch timer comes up - * with the counter disabled. Moreover, it may also report - * a potentially incorrect fixed 13 MHz frequency. To be - * correct these registers need to be updated to use the - * frequency EXTAL / 2 which can be determined by the MD pins. - */ - - switch (mode & (MD(14) | MD(13))) { - case 0: - extal_mhz = 15; - break; - case MD(13): - extal_mhz = 20; - break; - case MD(14): - extal_mhz = 26; - break; - case MD(13) | MD(14): - extal_mhz = 30; - break; - } - - /* The arch timer frequency equals EXTAL / 2 */ - freq = extal_mhz * (1000000 / 2); - - /* Remap "armgcnt address map" space */ - base = ioremap(0xe6080000, PAGE_SIZE); - - /* Update registers with correct frequency */ - iowrite32(freq, base + CNTFID0); - asm volatile("mcr p15, 0, %0, c14, c0, 0" : : "r" (freq)); - - /* make sure arch timer is started by setting bit 0 of CNTCR */ - iowrite32(1, base + CNTCR); - iounmap(base); -#endif /* CONFIG_ARM_ARCH_TIMER */ - - clocksource_of_init(); -} - -void __init r8a7790_init_delay(void) +void __init r8a7790_init_early(void) { #ifndef CONFIG_ARM_ARCH_TIMER shmobile_setup_delay(1300, 2, 4); /* Cortex-A15 @ 1300MHz */ @@ -276,14 +211,15 @@ void __init r8a7790_init_delay(void) #ifdef CONFIG_USE_OF -static const char *r8a7790_boards_compat_dt[] __initdata = { +static const char * const r8a7790_boards_compat_dt[] __initconst = { "renesas,r8a7790", NULL, }; DT_MACHINE_START(R8A7790_DT, "Generic R8A7790 (Flattened Device Tree)") - .init_early = r8a7790_init_delay, - .init_time = r8a7790_timer_init, + .smp = smp_ops(r8a7790_smp_ops), + .init_early = r8a7790_init_early, + .init_time = rcar_gen2_timer_init, .dt_compat = r8a7790_boards_compat_dt, MACHINE_END #endif /* CONFIG_USE_OF */ diff --git a/arch/arm/mach-shmobile/setup-r8a7791.c b/arch/arm/mach-shmobile/setup-r8a7791.c new file mode 100644 index 000000000000..d9393d61ee27 --- /dev/null +++ b/arch/arm/mach-shmobile/setup-r8a7791.c @@ -0,0 +1,184 @@ +/* + * r8a7791 processor support + * + * Copyright (C) 2013 Renesas Electronics Corporation + * Copyright (C) 2013 Renesas Solutions Corp. + * 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 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. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include <linux/irq.h> +#include <linux/kernel.h> +#include <linux/of_platform.h> +#include <linux/platform_data/irq-renesas-irqc.h> +#include <linux/serial_sci.h> +#include <linux/sh_timer.h> +#include <mach/common.h> +#include <mach/irqs.h> +#include <mach/r8a7791.h> +#include <mach/rcar-gen2.h> +#include <asm/mach/arch.h> + +#define SCIF_COMMON(scif_type, baseaddr, irq) \ + .type = scif_type, \ + .mapbase = baseaddr, \ + .flags = UPF_BOOT_AUTOCONF | UPF_IOREMAP, \ + .irqs = SCIx_IRQ_MUXED(irq) + +#define SCIFA_DATA(index, baseaddr, irq) \ +[index] = { \ + SCIF_COMMON(PORT_SCIFA, baseaddr, irq), \ + .scbrr_algo_id = SCBRR_ALGO_4, \ + .scscr = SCSCR_RE | SCSCR_TE, \ +} + +#define SCIFB_DATA(index, baseaddr, irq) \ +[index] = { \ + SCIF_COMMON(PORT_SCIFB, baseaddr, irq), \ + .scbrr_algo_id = SCBRR_ALGO_4, \ + .scscr = SCSCR_RE | SCSCR_TE, \ +} + +#define SCIF_DATA(index, baseaddr, irq) \ +[index] = { \ + SCIF_COMMON(PORT_SCIF, baseaddr, irq), \ + .scbrr_algo_id = SCBRR_ALGO_2, \ + .scscr = SCSCR_RE | SCSCR_TE, \ +} + +#define HSCIF_DATA(index, baseaddr, irq) \ +[index] = { \ + SCIF_COMMON(PORT_HSCIF, baseaddr, irq), \ + .scbrr_algo_id = SCBRR_ALGO_6, \ + .scscr = SCSCR_RE | SCSCR_TE, \ +} + +enum { SCIFA0, SCIFA1, SCIFB0, SCIFB1, SCIFB2, SCIFA2, SCIF0, SCIF1, + SCIF2, SCIF3, SCIF4, SCIF5, SCIFA3, SCIFA4, SCIFA5 }; + +static const struct plat_sci_port scif[] __initconst = { + SCIFA_DATA(SCIFA0, 0xe6c40000, gic_spi(144)), /* SCIFA0 */ + SCIFA_DATA(SCIFA1, 0xe6c50000, gic_spi(145)), /* SCIFA1 */ + SCIFB_DATA(SCIFB0, 0xe6c20000, gic_spi(148)), /* SCIFB0 */ + SCIFB_DATA(SCIFB1, 0xe6c30000, gic_spi(149)), /* SCIFB1 */ + SCIFB_DATA(SCIFB2, 0xe6ce0000, gic_spi(150)), /* SCIFB2 */ + SCIFA_DATA(SCIFA2, 0xe6c60000, gic_spi(151)), /* SCIFA2 */ + SCIF_DATA(SCIF0, 0xe6e60000, gic_spi(152)), /* SCIF0 */ + SCIF_DATA(SCIF1, 0xe6e68000, gic_spi(153)), /* SCIF1 */ + SCIF_DATA(SCIF2, 0xe6e58000, gic_spi(22)), /* SCIF2 */ + SCIF_DATA(SCIF3, 0xe6ea8000, gic_spi(23)), /* SCIF3 */ + SCIF_DATA(SCIF4, 0xe6ee0000, gic_spi(24)), /* SCIF4 */ + SCIF_DATA(SCIF5, 0xe6ee8000, gic_spi(25)), /* SCIF5 */ + SCIFA_DATA(SCIFA3, 0xe6c70000, gic_spi(29)), /* SCIFA3 */ + SCIFA_DATA(SCIFA4, 0xe6c78000, gic_spi(30)), /* SCIFA4 */ + SCIFA_DATA(SCIFA5, 0xe6c80000, gic_spi(31)), /* SCIFA5 */ +}; + +static inline void r8a7791_register_scif(int idx) +{ + platform_device_register_data(&platform_bus, "sh-sci", idx, &scif[idx], + sizeof(struct plat_sci_port)); +} + +static const struct sh_timer_config cmt00_platform_data __initconst = { + .name = "CMT00", + .timer_bit = 0, + .clockevent_rating = 80, +}; + +static const struct resource cmt00_resources[] __initconst = { + DEFINE_RES_MEM(0xffca0510, 0x0c), + DEFINE_RES_MEM(0xffca0500, 0x04), + DEFINE_RES_IRQ(gic_spi(142)), /* CMT0_0 */ +}; + +#define r8a7791_register_cmt(idx) \ + platform_device_register_resndata(&platform_bus, "sh_cmt", \ + idx, cmt##idx##_resources, \ + ARRAY_SIZE(cmt##idx##_resources), \ + &cmt##idx##_platform_data, \ + sizeof(struct sh_timer_config)) + +static struct renesas_irqc_config irqc0_data = { + .irq_base = irq_pin(0), /* IRQ0 -> IRQ9 */ +}; + +static struct resource irqc0_resources[] = { + DEFINE_RES_MEM(0xe61c0000, 0x200), /* IRQC Event Detector Block_0 */ + DEFINE_RES_IRQ(gic_spi(0)), /* IRQ0 */ + DEFINE_RES_IRQ(gic_spi(1)), /* IRQ1 */ + DEFINE_RES_IRQ(gic_spi(2)), /* IRQ2 */ + DEFINE_RES_IRQ(gic_spi(3)), /* IRQ3 */ + DEFINE_RES_IRQ(gic_spi(12)), /* IRQ4 */ + DEFINE_RES_IRQ(gic_spi(13)), /* IRQ5 */ + DEFINE_RES_IRQ(gic_spi(14)), /* IRQ6 */ + DEFINE_RES_IRQ(gic_spi(15)), /* IRQ7 */ + DEFINE_RES_IRQ(gic_spi(16)), /* IRQ8 */ + DEFINE_RES_IRQ(gic_spi(17)), /* IRQ9 */ +}; + +#define r8a7791_register_irqc(idx) \ + platform_device_register_resndata(&platform_bus, "renesas_irqc", \ + idx, irqc##idx##_resources, \ + ARRAY_SIZE(irqc##idx##_resources), \ + &irqc##idx##_data, \ + sizeof(struct renesas_irqc_config)) + +void __init r8a7791_add_dt_devices(void) +{ + r8a7791_register_scif(SCIFA0); + r8a7791_register_scif(SCIFA1); + r8a7791_register_scif(SCIFB0); + r8a7791_register_scif(SCIFB1); + r8a7791_register_scif(SCIFB2); + r8a7791_register_scif(SCIFA2); + r8a7791_register_scif(SCIF0); + r8a7791_register_scif(SCIF1); + r8a7791_register_scif(SCIF2); + r8a7791_register_scif(SCIF3); + r8a7791_register_scif(SCIF4); + r8a7791_register_scif(SCIF5); + r8a7791_register_scif(SCIFA3); + r8a7791_register_scif(SCIFA4); + r8a7791_register_scif(SCIFA5); + r8a7791_register_cmt(00); +} + +void __init r8a7791_add_standard_devices(void) +{ + r8a7791_add_dt_devices(); + r8a7791_register_irqc(0); +} + +void __init r8a7791_init_early(void) +{ +#ifndef CONFIG_ARM_ARCH_TIMER + shmobile_setup_delay(1300, 2, 4); /* Cortex-A15 @ 1300MHz */ +#endif +} + +#ifdef CONFIG_USE_OF +static const char *r8a7791_boards_compat_dt[] __initdata = { + "renesas,r8a7791", + NULL, +}; + +DT_MACHINE_START(R8A7791_DT, "Generic R8A7791 (Flattened Device Tree)") + .smp = smp_ops(r8a7791_smp_ops), + .init_early = r8a7791_init_early, + .init_time = rcar_gen2_timer_init, + .dt_compat = r8a7791_boards_compat_dt, +MACHINE_END +#endif /* CONFIG_USE_OF */ diff --git a/arch/arm/mach-shmobile/setup-rcar-gen2.c b/arch/arm/mach-shmobile/setup-rcar-gen2.c new file mode 100644 index 000000000000..5734c24bf6c7 --- /dev/null +++ b/arch/arm/mach-shmobile/setup-rcar-gen2.c @@ -0,0 +1,91 @@ +/* + * R-Car Generation 2 support + * + * Copyright (C) 2013 Renesas Solutions Corp. + * 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 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. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include <linux/clocksource.h> +#include <linux/io.h> +#include <linux/kernel.h> +#include <mach/common.h> +#include <mach/rcar-gen2.h> +#include <asm/mach/arch.h> + +#define MODEMR 0xe6160060 + +u32 __init rcar_gen2_read_mode_pins(void) +{ + void __iomem *modemr = ioremap_nocache(MODEMR, 4); + u32 mode; + + BUG_ON(!modemr); + mode = ioread32(modemr); + iounmap(modemr); + + return mode; +} + +#define CNTCR 0 +#define CNTFID0 0x20 + +void __init rcar_gen2_timer_init(void) +{ +#ifdef CONFIG_ARM_ARCH_TIMER + u32 mode = rcar_gen2_read_mode_pins(); + void __iomem *base; + int extal_mhz = 0; + u32 freq; + + /* At Linux boot time the r8a7790 arch timer comes up + * with the counter disabled. Moreover, it may also report + * a potentially incorrect fixed 13 MHz frequency. To be + * correct these registers need to be updated to use the + * frequency EXTAL / 2 which can be determined by the MD pins. + */ + + switch (mode & (MD(14) | MD(13))) { + case 0: + extal_mhz = 15; + break; + case MD(13): + extal_mhz = 20; + break; + case MD(14): + extal_mhz = 26; + break; + case MD(13) | MD(14): + extal_mhz = 30; + break; + } + + /* The arch timer frequency equals EXTAL / 2 */ + freq = extal_mhz * (1000000 / 2); + + /* Remap "armgcnt address map" space */ + base = ioremap(0xe6080000, PAGE_SIZE); + + /* Update registers with correct frequency */ + iowrite32(freq, base + CNTFID0); + asm volatile("mcr p15, 0, %0, c14, c0, 0" : : "r" (freq)); + + /* make sure arch timer is started by setting bit 0 of CNTCR */ + iowrite32(1, base + CNTCR); + iounmap(base); +#endif /* CONFIG_ARM_ARCH_TIMER */ + + clocksource_of_init(); +} diff --git a/arch/arm/mach-shmobile/smp-emev2.c b/arch/arm/mach-shmobile/smp-emev2.c index 522de5ebb55f..f2ca92308f75 100644 --- a/arch/arm/mach-shmobile/smp-emev2.c +++ b/arch/arm/mach-shmobile/smp-emev2.c @@ -34,12 +34,6 @@ static int emev2_boot_secondary(unsigned int cpu, struct task_struct *idle) { - int ret; - - ret = shmobile_smp_scu_boot_secondary(cpu, idle); - if (ret) - return ret; - arch_send_wakeup_ipi_mask(cpumask_of(cpu_logical_map(cpu))); return 0; } diff --git a/arch/arm/mach-shmobile/smp-r8a7779.c b/arch/arm/mach-shmobile/smp-r8a7779.c index 0f05e9fb722f..627c1f0d9478 100644 --- a/arch/arm/mach-shmobile/smp-r8a7779.c +++ b/arch/arm/mach-shmobile/smp-r8a7779.c @@ -87,10 +87,6 @@ static int r8a7779_boot_secondary(unsigned int cpu, struct task_struct *idle) unsigned int lcpu = cpu_logical_map(cpu); int ret; - ret = shmobile_smp_scu_boot_secondary(cpu, idle); - if (ret) - return ret; - if (lcpu < ARRAY_SIZE(r8a7779_ch_cpu)) ch = r8a7779_ch_cpu[lcpu]; diff --git a/arch/arm/mach-shmobile/smp-r8a7790.c b/arch/arm/mach-shmobile/smp-r8a7790.c new file mode 100644 index 000000000000..015e2753de1f --- /dev/null +++ b/arch/arm/mach-shmobile/smp-r8a7790.c @@ -0,0 +1,67 @@ +/* + * SMP support for r8a7790 + * + * Copyright (C) 2012-2013 Renesas Solutions Corp. + * Copyright (C) 2012 Takashi Yoshii <takashi.yoshii.ze@renesas.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; 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> +#include <linux/smp.h> +#include <linux/io.h> +#include <asm/smp_plat.h> +#include <mach/common.h> + +#define RST 0xe6160000 +#define CA15BAR 0x0020 +#define CA7BAR 0x0030 +#define CA15RESCNT 0x0040 +#define CA7RESCNT 0x0044 +#define MERAM 0xe8080000 + +static void __init r8a7790_smp_prepare_cpus(unsigned int max_cpus) +{ + void __iomem *p; + u32 bar; + + /* let APMU code install data related to shmobile_boot_vector */ + shmobile_smp_apmu_prepare_cpus(max_cpus); + + /* MERAM for jump stub, because BAR requires 256KB aligned address */ + p = ioremap_nocache(MERAM, shmobile_boot_size); + memcpy_toio(p, shmobile_boot_vector, shmobile_boot_size); + iounmap(p); + + /* setup reset vectors */ + p = ioremap_nocache(RST, 0x63); + bar = (MERAM >> 8) & 0xfffffc00; + writel_relaxed(bar, p + CA15BAR); + writel_relaxed(bar, p + CA7BAR); + writel_relaxed(bar | 0x10, p + CA15BAR); + writel_relaxed(bar | 0x10, p + CA7BAR); + + /* enable clocks to all CPUs */ + writel_relaxed((readl_relaxed(p + CA15RESCNT) & ~0x0f) | 0xa5a50000, + p + CA15RESCNT); + writel_relaxed((readl_relaxed(p + CA7RESCNT) & ~0x0f) | 0x5a5a0000, + p + CA7RESCNT); + iounmap(p); +} + +struct smp_operations r8a7790_smp_ops __initdata = { + .smp_prepare_cpus = r8a7790_smp_prepare_cpus, + .smp_boot_secondary = shmobile_smp_apmu_boot_secondary, +#ifdef CONFIG_HOTPLUG_CPU + .cpu_disable = shmobile_smp_cpu_disable, + .cpu_die = shmobile_smp_apmu_cpu_die, + .cpu_kill = shmobile_smp_apmu_cpu_kill, +#endif +}; diff --git a/arch/arm/mach-shmobile/smp-r8a7791.c b/arch/arm/mach-shmobile/smp-r8a7791.c new file mode 100644 index 000000000000..2df5bd190fe4 --- /dev/null +++ b/arch/arm/mach-shmobile/smp-r8a7791.c @@ -0,0 +1,62 @@ +/* + * SMP support for r8a7791 + * + * Copyright (C) 2013 Renesas Solutions Corp. + * 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 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> +#include <linux/smp.h> +#include <linux/io.h> +#include <asm/smp_plat.h> +#include <mach/common.h> +#include <mach/r8a7791.h> + +#define RST 0xe6160000 +#define CA15BAR 0x0020 +#define CA15RESCNT 0x0040 +#define RAM 0xe6300000 + +static void __init r8a7791_smp_prepare_cpus(unsigned int max_cpus) +{ + void __iomem *p; + u32 bar; + + /* let APMU code install data related to shmobile_boot_vector */ + shmobile_smp_apmu_prepare_cpus(max_cpus); + + /* RAM for jump stub, because BAR requires 256KB aligned address */ + p = ioremap_nocache(RAM, shmobile_boot_size); + memcpy_toio(p, shmobile_boot_vector, shmobile_boot_size); + iounmap(p); + + /* setup reset vectors */ + p = ioremap_nocache(RST, 0x63); + bar = (RAM >> 8) & 0xfffffc00; + writel_relaxed(bar, p + CA15BAR); + writel_relaxed(bar | 0x10, p + CA15BAR); + + /* enable clocks to all CPUs */ + writel_relaxed((readl_relaxed(p + CA15RESCNT) & ~0x0f) | 0xa5a50000, + p + CA15RESCNT); + iounmap(p); +} + +struct smp_operations r8a7791_smp_ops __initdata = { + .smp_prepare_cpus = r8a7791_smp_prepare_cpus, + .smp_boot_secondary = shmobile_smp_apmu_boot_secondary, +#ifdef CONFIG_HOTPLUG_CPU + .cpu_disable = shmobile_smp_cpu_disable, + .cpu_die = shmobile_smp_apmu_cpu_die, + .cpu_kill = shmobile_smp_apmu_cpu_kill, +#endif +}; diff --git a/arch/arm/mach-shmobile/smp-sh73a0.c b/arch/arm/mach-shmobile/smp-sh73a0.c index 0baa24443793..13ba36a6831f 100644 --- a/arch/arm/mach-shmobile/smp-sh73a0.c +++ b/arch/arm/mach-shmobile/smp-sh73a0.c @@ -46,11 +46,6 @@ void __init sh73a0_register_twd(void) static int sh73a0_boot_secondary(unsigned int cpu, struct task_struct *idle) { unsigned int lcpu = cpu_logical_map(cpu); - int ret; - - ret = shmobile_smp_scu_boot_secondary(cpu, idle); - if (ret) - return ret; if (((__raw_readl(PSTR) >> (4 * lcpu)) & 3) == 3) __raw_writel(1 << lcpu, WUPCR); /* wake up */ @@ -71,18 +66,11 @@ static void __init sh73a0_smp_prepare_cpus(unsigned int max_cpus) shmobile_smp_scu_prepare_cpus(max_cpus); } -#ifdef CONFIG_HOTPLUG_CPU -static int sh73a0_cpu_disable(unsigned int cpu) -{ - return 0; /* CPU0 and CPU1 supported */ -} -#endif /* CONFIG_HOTPLUG_CPU */ - struct smp_operations sh73a0_smp_ops __initdata = { .smp_prepare_cpus = sh73a0_smp_prepare_cpus, .smp_boot_secondary = sh73a0_boot_secondary, #ifdef CONFIG_HOTPLUG_CPU - .cpu_disable = sh73a0_cpu_disable, + .cpu_disable = shmobile_smp_cpu_disable, .cpu_die = shmobile_smp_scu_cpu_die, .cpu_kill = shmobile_smp_scu_cpu_kill, #endif diff --git a/arch/arm/mach-vexpress/tc2_pm.c b/arch/arm/mach-vexpress/tc2_pm.c index 7aeb5d60e484..e6eb48192912 100644 --- a/arch/arm/mach-vexpress/tc2_pm.c +++ b/arch/arm/mach-vexpress/tc2_pm.c @@ -131,6 +131,16 @@ static void tc2_pm_down(u64 residency) } else BUG(); + /* + * If the CPU is committed to power down, make sure + * the power controller will be in charge of waking it + * up upon IRQ, ie IRQ lines are cut from GIC CPU IF + * to the CPU by disabling the GIC CPU IF to prevent wfi + * from completing execution behind power controller back + */ + if (!skip_wfi) + gic_cpu_if_down(); + if (last_man && __mcpm_outbound_enter_critical(cpu, cluster)) { arch_spin_unlock(&tc2_pm_lock); @@ -231,7 +241,6 @@ static void tc2_pm_suspend(u64 residency) cpu = MPIDR_AFFINITY_LEVEL(mpidr, 0); cluster = MPIDR_AFFINITY_LEVEL(mpidr, 1); ve_spc_set_resume_addr(cluster, cpu, virt_to_phys(mcpm_entry_point)); - gic_cpu_if_down(); tc2_pm_down(residency); } diff --git a/arch/arm/plat-samsung/include/plat/cpu.h b/arch/arm/plat-samsung/include/plat/cpu.h index 4fb1f03a10d1..335beb341355 100644 --- a/arch/arm/plat-samsung/include/plat/cpu.h +++ b/arch/arm/plat-samsung/include/plat/cpu.h @@ -87,8 +87,12 @@ IS_SAMSUNG_CPU(exynos5440, EXYNOS5440_SOC_ID, EXYNOS5_SOC_MASK) #endif #if defined(CONFIG_CPU_S3C6400) || defined(CONFIG_CPU_S3C6410) +# define soc_is_s3c6400() is_samsung_s3c6400() +# define soc_is_s3c6410() is_samsung_s3c6410() # define soc_is_s3c64xx() (is_samsung_s3c6400() || is_samsung_s3c6410()) #else +# define soc_is_s3c6400() 0 +# define soc_is_s3c6410() 0 # define soc_is_s3c64xx() 0 #endif diff --git a/arch/arm64/Kconfig.debug b/arch/arm64/Kconfig.debug index 1a6bfe954d49..835c559786bd 100644 --- a/arch/arm64/Kconfig.debug +++ b/arch/arm64/Kconfig.debug @@ -6,13 +6,6 @@ config FRAME_POINTER bool default y -config DEBUG_STACK_USAGE - bool "Enable stack utilization instrumentation" - depends on DEBUG_KERNEL - help - Enables the display of the minimum amount of free stack which each - task has ever had available in the sysrq-T output. - config EARLY_PRINTK bool "Early printk support" default y diff --git a/arch/arm64/configs/defconfig b/arch/arm64/configs/defconfig index 5b3e83217b03..31c81e9b792e 100644 --- a/arch/arm64/configs/defconfig +++ b/arch/arm64/configs/defconfig @@ -42,7 +42,7 @@ CONFIG_IP_PNP_BOOTP=y # CONFIG_WIRELESS is not set CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug" CONFIG_DEVTMPFS=y -# CONFIG_BLK_DEV is not set +CONFIG_BLK_DEV=y CONFIG_SCSI=y # CONFIG_SCSI_PROC_FS is not set CONFIG_BLK_DEV_SD=y @@ -72,6 +72,7 @@ CONFIG_LOGO=y # CONFIG_IOMMU_SUPPORT is not set CONFIG_EXT2_FS=y CONFIG_EXT3_FS=y +CONFIG_EXT4_FS=y # CONFIG_EXT3_DEFAULTS_TO_ORDERED is not set # CONFIG_EXT3_FS_XATTR is not set CONFIG_FUSE_FS=y @@ -90,3 +91,5 @@ CONFIG_DEBUG_KERNEL=y CONFIG_DEBUG_INFO=y # CONFIG_FTRACE is not set CONFIG_ATOMIC64_SELFTEST=y +CONFIG_VIRTIO_MMIO=y +CONFIG_VIRTIO_BLK=y diff --git a/arch/arm64/include/asm/uaccess.h b/arch/arm64/include/asm/uaccess.h index edb3d5c73a32..7ecc2b23882e 100644 --- a/arch/arm64/include/asm/uaccess.h +++ b/arch/arm64/include/asm/uaccess.h @@ -166,9 +166,10 @@ do { \ #define get_user(x, ptr) \ ({ \ + __typeof__(*(ptr)) __user *__p = (ptr); \ might_fault(); \ - access_ok(VERIFY_READ, (ptr), sizeof(*(ptr))) ? \ - __get_user((x), (ptr)) : \ + access_ok(VERIFY_READ, __p, sizeof(*__p)) ? \ + __get_user((x), __p) : \ ((x) = 0, -EFAULT); \ }) @@ -227,9 +228,10 @@ do { \ #define put_user(x, ptr) \ ({ \ + __typeof__(*(ptr)) __user *__p = (ptr); \ might_fault(); \ - access_ok(VERIFY_WRITE, (ptr), sizeof(*(ptr))) ? \ - __put_user((x), (ptr)) : \ + access_ok(VERIFY_WRITE, __p, sizeof(*__p)) ? \ + __put_user((x), __p) : \ -EFAULT; \ }) diff --git a/arch/arm64/kernel/fpsimd.c b/arch/arm64/kernel/fpsimd.c index 1f2e4d5a5c0f..bb785d23dbde 100644 --- a/arch/arm64/kernel/fpsimd.c +++ b/arch/arm64/kernel/fpsimd.c @@ -80,8 +80,10 @@ void fpsimd_thread_switch(struct task_struct *next) void fpsimd_flush_thread(void) { + preempt_disable(); memset(¤t->thread.fpsimd_state, 0, sizeof(struct fpsimd_state)); fpsimd_load_state(¤t->thread.fpsimd_state); + preempt_enable(); } #ifdef CONFIG_KERNEL_MODE_NEON diff --git a/arch/arm64/mm/tlb.S b/arch/arm64/mm/tlb.S index 8ae80a18e8ec..19da91e0cd27 100644 --- a/arch/arm64/mm/tlb.S +++ b/arch/arm64/mm/tlb.S @@ -35,7 +35,7 @@ */ ENTRY(__cpu_flush_user_tlb_range) vma_vm_mm x3, x2 // get vma->vm_mm - mmid x3, x3 // get vm_mm->context.id + mmid w3, x3 // get vm_mm->context.id dsb sy lsr x0, x0, #12 // align address lsr x1, x1, #12 diff --git a/arch/avr32/include/asm/Kbuild b/arch/avr32/include/asm/Kbuild index d22af851f3f6..fd7980743890 100644 --- a/arch/avr32/include/asm/Kbuild +++ b/arch/avr32/include/asm/Kbuild @@ -1,5 +1,19 @@ generic-y += clkdev.h +generic-y += cputime.h +generic-y += delay.h +generic-y += device.h +generic-y += div64.h +generic-y += emergency-restart.h generic-y += exec.h -generic-y += trace_clock.h +generic-y += futex.h +generic-y += irq_regs.h generic-y += param.h +generic-y += local.h +generic-y += local64.h +generic-y += percpu.h +generic-y += scatterlist.h +generic-y += sections.h +generic-y += topology.h +generic-y += trace_clock.h +generic-y += xor.h diff --git a/arch/avr32/include/asm/cputime.h b/arch/avr32/include/asm/cputime.h deleted file mode 100644 index e87e0f81cbeb..000000000000 --- a/arch/avr32/include/asm/cputime.h +++ /dev/null @@ -1,6 +0,0 @@ -#ifndef __ASM_AVR32_CPUTIME_H -#define __ASM_AVR32_CPUTIME_H - -#include <asm-generic/cputime.h> - -#endif /* __ASM_AVR32_CPUTIME_H */ diff --git a/arch/avr32/include/asm/delay.h b/arch/avr32/include/asm/delay.h deleted file mode 100644 index 9670e127b7b2..000000000000 --- a/arch/avr32/include/asm/delay.h +++ /dev/null @@ -1 +0,0 @@ -#include <asm-generic/delay.h> diff --git a/arch/avr32/include/asm/device.h b/arch/avr32/include/asm/device.h deleted file mode 100644 index d8f9872b0e2d..000000000000 --- a/arch/avr32/include/asm/device.h +++ /dev/null @@ -1,7 +0,0 @@ -/* - * Arch specific extensions to struct device - * - * This file is released under the GPLv2 - */ -#include <asm-generic/device.h> - diff --git a/arch/avr32/include/asm/div64.h b/arch/avr32/include/asm/div64.h deleted file mode 100644 index d7ddd4fdeca6..000000000000 --- a/arch/avr32/include/asm/div64.h +++ /dev/null @@ -1,6 +0,0 @@ -#ifndef __ASM_AVR32_DIV64_H -#define __ASM_AVR32_DIV64_H - -#include <asm-generic/div64.h> - -#endif /* __ASM_AVR32_DIV64_H */ diff --git a/arch/avr32/include/asm/emergency-restart.h b/arch/avr32/include/asm/emergency-restart.h deleted file mode 100644 index 3e7e014776ba..000000000000 --- a/arch/avr32/include/asm/emergency-restart.h +++ /dev/null @@ -1,6 +0,0 @@ -#ifndef __ASM_AVR32_EMERGENCY_RESTART_H -#define __ASM_AVR32_EMERGENCY_RESTART_H - -#include <asm-generic/emergency-restart.h> - -#endif /* __ASM_AVR32_EMERGENCY_RESTART_H */ diff --git a/arch/avr32/include/asm/futex.h b/arch/avr32/include/asm/futex.h deleted file mode 100644 index 10419f14a68a..000000000000 --- a/arch/avr32/include/asm/futex.h +++ /dev/null @@ -1,6 +0,0 @@ -#ifndef __ASM_AVR32_FUTEX_H -#define __ASM_AVR32_FUTEX_H - -#include <asm-generic/futex.h> - -#endif /* __ASM_AVR32_FUTEX_H */ diff --git a/arch/avr32/include/asm/irq_regs.h b/arch/avr32/include/asm/irq_regs.h deleted file mode 100644 index 3dd9c0b70270..000000000000 --- a/arch/avr32/include/asm/irq_regs.h +++ /dev/null @@ -1 +0,0 @@ -#include <asm-generic/irq_regs.h> diff --git a/arch/avr32/include/asm/local.h b/arch/avr32/include/asm/local.h deleted file mode 100644 index 1c1619694da3..000000000000 --- a/arch/avr32/include/asm/local.h +++ /dev/null @@ -1,6 +0,0 @@ -#ifndef __ASM_AVR32_LOCAL_H -#define __ASM_AVR32_LOCAL_H - -#include <asm-generic/local.h> - -#endif /* __ASM_AVR32_LOCAL_H */ diff --git a/arch/avr32/include/asm/local64.h b/arch/avr32/include/asm/local64.h deleted file mode 100644 index 36c93b5cc239..000000000000 --- a/arch/avr32/include/asm/local64.h +++ /dev/null @@ -1 +0,0 @@ -#include <asm-generic/local64.h> diff --git a/arch/avr32/include/asm/percpu.h b/arch/avr32/include/asm/percpu.h deleted file mode 100644 index 69227b4cd0d4..000000000000 --- a/arch/avr32/include/asm/percpu.h +++ /dev/null @@ -1,6 +0,0 @@ -#ifndef __ASM_AVR32_PERCPU_H -#define __ASM_AVR32_PERCPU_H - -#include <asm-generic/percpu.h> - -#endif /* __ASM_AVR32_PERCPU_H */ diff --git a/arch/avr32/include/asm/scatterlist.h b/arch/avr32/include/asm/scatterlist.h deleted file mode 100644 index a5902d9834e8..000000000000 --- a/arch/avr32/include/asm/scatterlist.h +++ /dev/null @@ -1,6 +0,0 @@ -#ifndef __ASM_AVR32_SCATTERLIST_H -#define __ASM_AVR32_SCATTERLIST_H - -#include <asm-generic/scatterlist.h> - -#endif /* __ASM_AVR32_SCATTERLIST_H */ diff --git a/arch/avr32/include/asm/sections.h b/arch/avr32/include/asm/sections.h deleted file mode 100644 index aa14252e4181..000000000000 --- a/arch/avr32/include/asm/sections.h +++ /dev/null @@ -1,6 +0,0 @@ -#ifndef __ASM_AVR32_SECTIONS_H -#define __ASM_AVR32_SECTIONS_H - -#include <asm-generic/sections.h> - -#endif /* __ASM_AVR32_SECTIONS_H */ diff --git a/arch/avr32/include/asm/topology.h b/arch/avr32/include/asm/topology.h deleted file mode 100644 index 5b766cbb4806..000000000000 --- a/arch/avr32/include/asm/topology.h +++ /dev/null @@ -1,6 +0,0 @@ -#ifndef __ASM_AVR32_TOPOLOGY_H -#define __ASM_AVR32_TOPOLOGY_H - -#include <asm-generic/topology.h> - -#endif /* __ASM_AVR32_TOPOLOGY_H */ diff --git a/arch/avr32/include/asm/xor.h b/arch/avr32/include/asm/xor.h deleted file mode 100644 index 99c87aa0af4f..000000000000 --- a/arch/avr32/include/asm/xor.h +++ /dev/null @@ -1,6 +0,0 @@ -#ifndef _ASM_XOR_H -#define _ASM_XOR_H - -#include <asm-generic/xor.h> - -#endif diff --git a/arch/avr32/kernel/process.c b/arch/avr32/kernel/process.c index c2731003edef..42a53e740a7e 100644 --- a/arch/avr32/kernel/process.c +++ b/arch/avr32/kernel/process.c @@ -289,7 +289,7 @@ int copy_thread(unsigned long clone_flags, unsigned long usp, memset(childregs, 0, sizeof(struct pt_regs)); p->thread.cpu_context.r0 = arg; p->thread.cpu_context.r1 = usp; /* fn */ - p->thread.cpu_context.r2 = syscall_return; + p->thread.cpu_context.r2 = (unsigned long)syscall_return; p->thread.cpu_context.pc = (unsigned long)ret_from_kernel_thread; childregs->sr = MODE_SUPERVISOR; } else { diff --git a/arch/avr32/kernel/time.c b/arch/avr32/kernel/time.c index 869a1c6ffeee..12f828ad5058 100644 --- a/arch/avr32/kernel/time.c +++ b/arch/avr32/kernel/time.c @@ -98,7 +98,14 @@ static void comparator_mode(enum clock_event_mode mode, case CLOCK_EVT_MODE_SHUTDOWN: sysreg_write(COMPARE, 0); pr_debug("%s: stop\n", evdev->name); - cpu_idle_poll_ctrl(false); + if (evdev->mode == CLOCK_EVT_MODE_ONESHOT || + evdev->mode == CLOCK_EVT_MODE_RESUME) { + /* + * Only disable idle poll if we have forced that + * in a previous call. + */ + cpu_idle_poll_ctrl(false); + } break; default: BUG(); diff --git a/arch/mips/alchemy/board-mtx1.c b/arch/mips/alchemy/board-mtx1.c index 4a9baa9f6330..9969dbab19e3 100644 --- a/arch/mips/alchemy/board-mtx1.c +++ b/arch/mips/alchemy/board-mtx1.c @@ -276,7 +276,7 @@ static struct platform_device mtx1_pci_host = { .resource = alchemy_pci_host_res, }; -static struct __initdata platform_device * mtx1_devs[] = { +static struct platform_device *mtx1_devs[] __initdata = { &mtx1_pci_host, &mtx1_gpio_leds, &mtx1_wdt, diff --git a/arch/mips/mm/c-r4k.c b/arch/mips/mm/c-r4k.c index 627883bc6d5f..bc6f96fcb529 100644 --- a/arch/mips/mm/c-r4k.c +++ b/arch/mips/mm/c-r4k.c @@ -609,6 +609,7 @@ static void r4k_dma_cache_wback_inv(unsigned long addr, unsigned long size) r4k_blast_scache(); else blast_scache_range(addr, addr + size); + preempt_enable(); __sync(); return; } @@ -650,6 +651,7 @@ static void r4k_dma_cache_inv(unsigned long addr, unsigned long size) */ blast_inv_scache_range(addr, addr + size); } + preempt_enable(); __sync(); return; } diff --git a/arch/parisc/mm/fault.c b/arch/parisc/mm/fault.c index d10d27a720c0..00c0ed333a3d 100644 --- a/arch/parisc/mm/fault.c +++ b/arch/parisc/mm/fault.c @@ -182,6 +182,9 @@ void do_page_fault(struct pt_regs *regs, unsigned long code, if (user_mode(regs)) flags |= FAULT_FLAG_USER; + + acc_type = parisc_acctyp(code, regs->iir); + if (acc_type & VM_WRITE) flags |= FAULT_FLAG_WRITE; retry: @@ -196,8 +199,6 @@ retry: good_area: - acc_type = parisc_acctyp(code,regs->iir); - if ((vma->vm_flags & acc_type) != acc_type) goto bad_area; diff --git a/arch/powerpc/kernel/iommu.c b/arch/powerpc/kernel/iommu.c index 0adab06ce5c0..572bb5b95f35 100644 --- a/arch/powerpc/kernel/iommu.c +++ b/arch/powerpc/kernel/iommu.c @@ -661,7 +661,7 @@ struct iommu_table *iommu_init_table(struct iommu_table *tbl, int nid) /* number of bytes needed for the bitmap */ sz = BITS_TO_LONGS(tbl->it_size) * sizeof(unsigned long); - page = alloc_pages_node(nid, GFP_ATOMIC, get_order(sz)); + page = alloc_pages_node(nid, GFP_KERNEL, get_order(sz)); if (!page) panic("iommu_init_table: Can't allocate %ld bytes\n", sz); tbl->it_map = page_address(page); diff --git a/arch/powerpc/kernel/sysfs.c b/arch/powerpc/kernel/sysfs.c index 27a90b99ef67..b4e667663d9b 100644 --- a/arch/powerpc/kernel/sysfs.c +++ b/arch/powerpc/kernel/sysfs.c @@ -17,6 +17,7 @@ #include <asm/machdep.h> #include <asm/smp.h> #include <asm/pmc.h> +#include <asm/firmware.h> #include "cacheinfo.h" @@ -179,15 +180,25 @@ SYSFS_PMCSETUP(spurr, SPRN_SPURR); SYSFS_PMCSETUP(dscr, SPRN_DSCR); SYSFS_PMCSETUP(pir, SPRN_PIR); +/* + Lets only enable read for phyp resources and + enable write when needed with a separate function. + Lets be conservative and default to pseries. +*/ static DEVICE_ATTR(mmcra, 0600, show_mmcra, store_mmcra); static DEVICE_ATTR(spurr, 0400, show_spurr, NULL); static DEVICE_ATTR(dscr, 0600, show_dscr, store_dscr); -static DEVICE_ATTR(purr, 0600, show_purr, store_purr); +static DEVICE_ATTR(purr, 0400, show_purr, store_purr); static DEVICE_ATTR(pir, 0400, show_pir, NULL); unsigned long dscr_default = 0; EXPORT_SYMBOL(dscr_default); +static void add_write_permission_dev_attr(struct device_attribute *attr) +{ + attr->attr.mode |= 0200; +} + static ssize_t show_dscr_default(struct device *dev, struct device_attribute *attr, char *buf) { @@ -394,8 +405,11 @@ static void register_cpu_online(unsigned int cpu) if (cpu_has_feature(CPU_FTR_MMCRA)) device_create_file(s, &dev_attr_mmcra); - if (cpu_has_feature(CPU_FTR_PURR)) + if (cpu_has_feature(CPU_FTR_PURR)) { + if (!firmware_has_feature(FW_FEATURE_LPAR)) + add_write_permission_dev_attr(&dev_attr_purr); device_create_file(s, &dev_attr_purr); + } if (cpu_has_feature(CPU_FTR_SPURR)) device_create_file(s, &dev_attr_spurr); diff --git a/arch/powerpc/kernel/tm.S b/arch/powerpc/kernel/tm.S index 7b60b9851469..cd809eaa8b5c 100644 --- a/arch/powerpc/kernel/tm.S +++ b/arch/powerpc/kernel/tm.S @@ -79,6 +79,11 @@ _GLOBAL(tm_abort) TABORT(R3) blr + .section ".toc","aw" +DSCR_DEFAULT: + .tc dscr_default[TC],dscr_default + + .section ".text" /* void tm_reclaim(struct thread_struct *thread, * unsigned long orig_msr, @@ -123,6 +128,7 @@ _GLOBAL(tm_reclaim) mr r15, r14 ori r15, r15, MSR_FP li r16, MSR_RI + ori r16, r16, MSR_EE /* IRQs hard off */ andc r15, r15, r16 oris r15, r15, MSR_VEC@h #ifdef CONFIG_VSX @@ -187,11 +193,18 @@ dont_backup_fp: std r1, PACATMSCRATCH(r13) ld r1, PACAR1(r13) + /* Store the PPR in r11 and reset to decent value */ + std r11, GPR11(r1) /* Temporary stash */ + mfspr r11, SPRN_PPR + HMT_MEDIUM + /* Now get some more GPRS free */ std r7, GPR7(r1) /* Temporary stash */ std r12, GPR12(r1) /* '' '' '' */ ld r12, STACK_PARAM(0)(r1) /* Param 0, thread_struct * */ + std r11, THREAD_TM_PPR(r12) /* Store PPR and free r11 */ + addi r7, r12, PT_CKPT_REGS /* Thread's ckpt_regs */ /* Make r7 look like an exception frame so that we @@ -203,15 +216,19 @@ dont_backup_fp: SAVE_GPR(0, r7) /* user r0 */ SAVE_GPR(2, r7) /* user r2 */ SAVE_4GPRS(3, r7) /* user r3-r6 */ - SAVE_4GPRS(8, r7) /* user r8-r11 */ + SAVE_GPR(8, r7) /* user r8 */ + SAVE_GPR(9, r7) /* user r9 */ + SAVE_GPR(10, r7) /* user r10 */ ld r3, PACATMSCRATCH(r13) /* user r1 */ ld r4, GPR7(r1) /* user r7 */ - ld r5, GPR12(r1) /* user r12 */ - GET_SCRATCH0(6) /* user r13 */ + ld r5, GPR11(r1) /* user r11 */ + ld r6, GPR12(r1) /* user r12 */ + GET_SCRATCH0(8) /* user r13 */ std r3, GPR1(r7) std r4, GPR7(r7) - std r5, GPR12(r7) - std r6, GPR13(r7) + std r5, GPR11(r7) + std r6, GPR12(r7) + std r8, GPR13(r7) SAVE_NVGPRS(r7) /* user r14-r31 */ @@ -234,14 +251,12 @@ dont_backup_fp: std r6, _XER(r7) - /* ******************** TAR, PPR, DSCR ********** */ + /* ******************** TAR, DSCR ********** */ mfspr r3, SPRN_TAR - mfspr r4, SPRN_PPR - mfspr r5, SPRN_DSCR + mfspr r4, SPRN_DSCR std r3, THREAD_TM_TAR(r12) - std r4, THREAD_TM_PPR(r12) - std r5, THREAD_TM_DSCR(r12) + std r4, THREAD_TM_DSCR(r12) /* MSR and flags: We don't change CRs, and we don't need to alter * MSR. @@ -258,7 +273,7 @@ dont_backup_fp: std r3, THREAD_TM_TFHAR(r12) std r4, THREAD_TM_TFIAR(r12) - /* AMR and PPR are checkpointed too, but are unsupported by Linux. */ + /* AMR is checkpointed too, but is unsupported by Linux. */ /* Restore original MSR/IRQ state & clear TM mode */ ld r14, TM_FRAME_L0(r1) /* Orig MSR */ @@ -274,6 +289,12 @@ dont_backup_fp: mtcr r4 mtlr r0 ld r2, 40(r1) + + /* Load system default DSCR */ + ld r4, DSCR_DEFAULT@toc(r2) + ld r0, 0(r4) + mtspr SPRN_DSCR, r0 + blr @@ -358,25 +379,24 @@ dont_restore_fp: restore_gprs: - /* ******************** TAR, PPR, DSCR ********** */ - ld r4, THREAD_TM_TAR(r3) - ld r5, THREAD_TM_PPR(r3) - ld r6, THREAD_TM_DSCR(r3) + /* ******************** CR,LR,CCR,MSR ********** */ + ld r4, _CTR(r7) + ld r5, _LINK(r7) + ld r6, _CCR(r7) + ld r8, _XER(r7) - mtspr SPRN_TAR, r4 - mtspr SPRN_PPR, r5 - mtspr SPRN_DSCR, r6 + mtctr r4 + mtlr r5 + mtcr r6 + mtxer r8 - /* ******************** CR,LR,CCR,MSR ********** */ - ld r3, _CTR(r7) - ld r4, _LINK(r7) - ld r5, _CCR(r7) - ld r6, _XER(r7) + /* ******************** TAR ******************** */ + ld r4, THREAD_TM_TAR(r3) + mtspr SPRN_TAR, r4 - mtctr r3 - mtlr r4 - mtcr r5 - mtxer r6 + /* Load up the PPR and DSCR in GPRs only at this stage */ + ld r5, THREAD_TM_DSCR(r3) + ld r6, THREAD_TM_PPR(r3) /* Clear the MSR RI since we are about to change R1. EE is already off */ @@ -384,19 +404,26 @@ restore_gprs: mtmsrd r4, 1 REST_4GPRS(0, r7) /* GPR0-3 */ - REST_GPR(4, r7) /* GPR4-6 */ - REST_GPR(5, r7) - REST_GPR(6, r7) + REST_GPR(4, r7) /* GPR4 */ REST_4GPRS(8, r7) /* GPR8-11 */ REST_2GPRS(12, r7) /* GPR12-13 */ REST_NVGPRS(r7) /* GPR14-31 */ - ld r7, GPR7(r7) /* GPR7 */ + /* Load up PPR and DSCR here so we don't run with user values for long + */ + mtspr SPRN_DSCR, r5 + mtspr SPRN_PPR, r6 + + REST_GPR(5, r7) /* GPR5-7 */ + REST_GPR(6, r7) + ld r7, GPR7(r7) /* Commit register state as checkpointed state: */ TRECHKPT + HMT_MEDIUM + /* Our transactional state has now changed. * * Now just get out of here. Transactional (current) state will be @@ -419,6 +446,12 @@ restore_gprs: mtcr r4 mtlr r0 ld r2, 40(r1) + + /* Load system default DSCR */ + ld r4, DSCR_DEFAULT@toc(r2) + ld r0, 0(r4) + mtspr SPRN_DSCR, r0 + blr /* ****************************************************************** */ diff --git a/arch/powerpc/kernel/vio.c b/arch/powerpc/kernel/vio.c index 78a350670de3..d38cc08b16c7 100644 --- a/arch/powerpc/kernel/vio.c +++ b/arch/powerpc/kernel/vio.c @@ -1530,11 +1530,15 @@ static ssize_t modalias_show(struct device *dev, struct device_attribute *attr, const char *cp; dn = dev->of_node; - if (!dn) - return -ENODEV; + if (!dn) { + strcat(buf, "\n"); + return strlen(buf); + } cp = of_get_property(dn, "compatible", NULL); - if (!cp) - return -ENODEV; + if (!cp) { + strcat(buf, "\n"); + return strlen(buf); + } return sprintf(buf, "vio:T%sS%s\n", vio_dev->type, cp); } diff --git a/arch/powerpc/lib/checksum_64.S b/arch/powerpc/lib/checksum_64.S index 167f72555d60..57a072065057 100644 --- a/arch/powerpc/lib/checksum_64.S +++ b/arch/powerpc/lib/checksum_64.S @@ -226,19 +226,35 @@ _GLOBAL(csum_partial) blr - .macro source + .macro srcnr 100: .section __ex_table,"a" .align 3 - .llong 100b,.Lsrc_error + .llong 100b,.Lsrc_error_nr .previous .endm - .macro dest + .macro source +150: + .section __ex_table,"a" + .align 3 + .llong 150b,.Lsrc_error + .previous + .endm + + .macro dstnr 200: .section __ex_table,"a" .align 3 - .llong 200b,.Ldest_error + .llong 200b,.Ldest_error_nr + .previous + .endm + + .macro dest +250: + .section __ex_table,"a" + .align 3 + .llong 250b,.Ldest_error .previous .endm @@ -269,16 +285,16 @@ _GLOBAL(csum_partial_copy_generic) rldicl. r6,r3,64-1,64-2 /* r6 = (r3 & 0x3) >> 1 */ beq .Lcopy_aligned - li r7,4 - sub r6,r7,r6 + li r9,4 + sub r6,r9,r6 mtctr r6 1: -source; lhz r6,0(r3) /* align to doubleword */ +srcnr; lhz r6,0(r3) /* align to doubleword */ subi r5,r5,2 addi r3,r3,2 adde r0,r0,r6 -dest; sth r6,0(r4) +dstnr; sth r6,0(r4) addi r4,r4,2 bdnz 1b @@ -392,10 +408,10 @@ dest; std r16,56(r4) mtctr r6 3: -source; ld r6,0(r3) +srcnr; ld r6,0(r3) addi r3,r3,8 adde r0,r0,r6 -dest; std r6,0(r4) +dstnr; std r6,0(r4) addi r4,r4,8 bdnz 3b @@ -405,10 +421,10 @@ dest; std r6,0(r4) srdi. r6,r5,2 beq .Lcopy_tail_halfword -source; lwz r6,0(r3) +srcnr; lwz r6,0(r3) addi r3,r3,4 adde r0,r0,r6 -dest; stw r6,0(r4) +dstnr; stw r6,0(r4) addi r4,r4,4 subi r5,r5,4 @@ -416,10 +432,10 @@ dest; stw r6,0(r4) srdi. r6,r5,1 beq .Lcopy_tail_byte -source; lhz r6,0(r3) +srcnr; lhz r6,0(r3) addi r3,r3,2 adde r0,r0,r6 -dest; sth r6,0(r4) +dstnr; sth r6,0(r4) addi r4,r4,2 subi r5,r5,2 @@ -427,10 +443,10 @@ dest; sth r6,0(r4) andi. r6,r5,1 beq .Lcopy_finish -source; lbz r6,0(r3) +srcnr; lbz r6,0(r3) sldi r9,r6,8 /* Pad the byte out to 16 bits */ adde r0,r0,r9 -dest; stb r6,0(r4) +dstnr; stb r6,0(r4) .Lcopy_finish: addze r0,r0 /* add in final carry */ @@ -440,6 +456,11 @@ dest; stb r6,0(r4) blr .Lsrc_error: + ld r14,STK_REG(R14)(r1) + ld r15,STK_REG(R15)(r1) + ld r16,STK_REG(R16)(r1) + addi r1,r1,STACKFRAMESIZE +.Lsrc_error_nr: cmpdi 0,r7,0 beqlr li r6,-EFAULT @@ -447,6 +468,11 @@ dest; stb r6,0(r4) blr .Ldest_error: + ld r14,STK_REG(R14)(r1) + ld r15,STK_REG(R15)(r1) + ld r16,STK_REG(R16)(r1) + addi r1,r1,STACKFRAMESIZE +.Ldest_error_nr: cmpdi 0,r8,0 beqlr li r6,-EFAULT diff --git a/arch/powerpc/mm/init_64.c b/arch/powerpc/mm/init_64.c index d0cd9e4c6837..8ed035d2edb5 100644 --- a/arch/powerpc/mm/init_64.c +++ b/arch/powerpc/mm/init_64.c @@ -300,5 +300,9 @@ void vmemmap_free(unsigned long start, unsigned long end) { } +void register_page_bootmem_memmap(unsigned long section_nr, + struct page *start_page, unsigned long size) +{ +} #endif /* CONFIG_SPARSEMEM_VMEMMAP */ diff --git a/arch/powerpc/mm/mem.c b/arch/powerpc/mm/mem.c index 1cf9c5b67f24..3fa93dc7fe75 100644 --- a/arch/powerpc/mm/mem.c +++ b/arch/powerpc/mm/mem.c @@ -297,12 +297,21 @@ void __init paging_init(void) } #endif /* ! CONFIG_NEED_MULTIPLE_NODES */ +static void __init register_page_bootmem_info(void) +{ + int i; + + for_each_online_node(i) + register_page_bootmem_info_node(NODE_DATA(i)); +} + void __init mem_init(void) { #ifdef CONFIG_SWIOTLB swiotlb_init(0); #endif + register_page_bootmem_info(); high_memory = (void *) __va(max_low_pfn * PAGE_SIZE); set_max_mapnr(max_pfn); free_all_bootmem(); diff --git a/arch/powerpc/perf/power8-pmu.c b/arch/powerpc/perf/power8-pmu.c index 2ee4a707f0df..a3f7abd2f13f 100644 --- a/arch/powerpc/perf/power8-pmu.c +++ b/arch/powerpc/perf/power8-pmu.c @@ -199,6 +199,7 @@ #define MMCR1_UNIT_SHIFT(pmc) (60 - (4 * ((pmc) - 1))) #define MMCR1_COMBINE_SHIFT(pmc) (35 - ((pmc) - 1)) #define MMCR1_PMCSEL_SHIFT(pmc) (24 - (((pmc) - 1)) * 8) +#define MMCR1_FAB_SHIFT 36 #define MMCR1_DC_QUAL_SHIFT 47 #define MMCR1_IC_QUAL_SHIFT 46 @@ -388,8 +389,8 @@ static int power8_compute_mmcr(u64 event[], int n_ev, * the threshold bits are used for the match value. */ if (event_is_fab_match(event[i])) { - mmcr1 |= (event[i] >> EVENT_THR_CTL_SHIFT) & - EVENT_THR_CTL_MASK; + mmcr1 |= ((event[i] >> EVENT_THR_CTL_SHIFT) & + EVENT_THR_CTL_MASK) << MMCR1_FAB_SHIFT; } else { val = (event[i] >> EVENT_THR_CTL_SHIFT) & EVENT_THR_CTL_MASK; mmcra |= val << MMCRA_THR_CTL_SHIFT; diff --git a/arch/score/Kconfig b/arch/score/Kconfig index a1be70db75fe..305f7ee1f382 100644 --- a/arch/score/Kconfig +++ b/arch/score/Kconfig @@ -2,6 +2,7 @@ menu "Machine selection" config SCORE def_bool y + select HAVE_GENERIC_HARDIRQS select GENERIC_IRQ_SHOW select GENERIC_IOMAP select GENERIC_ATOMIC64 @@ -110,3 +111,6 @@ source "security/Kconfig" source "crypto/Kconfig" source "lib/Kconfig" + +config NO_IOMEM + def_bool y diff --git a/arch/score/Makefile b/arch/score/Makefile index 974aefe86123..9e3e060290e0 100644 --- a/arch/score/Makefile +++ b/arch/score/Makefile @@ -20,8 +20,8 @@ cflags-y += -G0 -pipe -mel -mnhwloop -D__SCOREEL__ \ # KBUILD_AFLAGS += $(cflags-y) KBUILD_CFLAGS += $(cflags-y) -KBUILD_AFLAGS_MODULE += -mlong-calls -KBUILD_CFLAGS_MODULE += -mlong-calls +KBUILD_AFLAGS_MODULE += +KBUILD_CFLAGS_MODULE += LDFLAGS += --oformat elf32-littlescore LDFLAGS_vmlinux += -G0 -static -nostdlib diff --git a/arch/score/include/asm/checksum.h b/arch/score/include/asm/checksum.h index f909ac3144a4..961bd64015a8 100644 --- a/arch/score/include/asm/checksum.h +++ b/arch/score/include/asm/checksum.h @@ -184,48 +184,57 @@ static inline __sum16 csum_ipv6_magic(const struct in6_addr *saddr, __wsum sum) { __asm__ __volatile__( - ".set\tnoreorder\t\t\t# csum_ipv6_magic\n\t" - ".set\tnoat\n\t" - "addu\t%0, %5\t\t\t# proto (long in network byte order)\n\t" - "sltu\t$1, %0, %5\n\t" - "addu\t%0, $1\n\t" - "addu\t%0, %6\t\t\t# csum\n\t" - "sltu\t$1, %0, %6\n\t" - "lw\t%1, 0(%2)\t\t\t# four words source address\n\t" - "addu\t%0, $1\n\t" - "addu\t%0, %1\n\t" - "sltu\t$1, %0, %1\n\t" - "lw\t%1, 4(%2)\n\t" - "addu\t%0, $1\n\t" - "addu\t%0, %1\n\t" - "sltu\t$1, %0, %1\n\t" - "lw\t%1, 8(%2)\n\t" - "addu\t%0, $1\n\t" - "addu\t%0, %1\n\t" - "sltu\t$1, %0, %1\n\t" - "lw\t%1, 12(%2)\n\t" - "addu\t%0, $1\n\t" - "addu\t%0, %1\n\t" - "sltu\t$1, %0, %1\n\t" - "lw\t%1, 0(%3)\n\t" - "addu\t%0, $1\n\t" - "addu\t%0, %1\n\t" - "sltu\t$1, %0, %1\n\t" - "lw\t%1, 4(%3)\n\t" - "addu\t%0, $1\n\t" - "addu\t%0, %1\n\t" - "sltu\t$1, %0, %1\n\t" - "lw\t%1, 8(%3)\n\t" - "addu\t%0, $1\n\t" - "addu\t%0, %1\n\t" - "sltu\t$1, %0, %1\n\t" - "lw\t%1, 12(%3)\n\t" - "addu\t%0, $1\n\t" - "addu\t%0, %1\n\t" - "sltu\t$1, %0, %1\n\t" - "addu\t%0, $1\t\t\t# Add final carry\n\t" - ".set\tnoat\n\t" - ".set\tnoreorder" + ".set\tvolatile\t\t\t# csum_ipv6_magic\n\t" + "add\t%0, %0, %5\t\t\t# proto (long in network byte order)\n\t" + "cmp.c\t%5, %0\n\t" + "bleu 1f\n\t" + "addi\t%0, 0x1\n\t" + "1:add\t%0, %0, %6\t\t\t# csum\n\t" + "cmp.c\t%6, %0\n\t" + "lw\t%1, [%2, 0]\t\t\t# four words source address\n\t" + "bleu 1f\n\t" + "addi\t%0, 0x1\n\t" + "1:add\t%0, %0, %1\n\t" + "cmp.c\t%1, %0\n\t" + "1:lw\t%1, [%2, 4]\n\t" + "bleu 1f\n\t" + "addi\t%0, 0x1\n\t" + "1:add\t%0, %0, %1\n\t" + "cmp.c\t%1, %0\n\t" + "lw\t%1, [%2,8]\n\t" + "bleu 1f\n\t" + "addi\t%0, 0x1\n\t" + "1:add\t%0, %0, %1\n\t" + "cmp.c\t%1, %0\n\t" + "lw\t%1, [%2, 12]\n\t" + "bleu 1f\n\t" + "addi\t%0, 0x1\n\t" + "1:add\t%0, %0,%1\n\t" + "cmp.c\t%1, %0\n\t" + "lw\t%1, [%3, 0]\n\t" + "bleu 1f\n\t" + "addi\t%0, 0x1\n\t" + "1:add\t%0, %0, %1\n\t" + "cmp.c\t%1, %0\n\t" + "lw\t%1, [%3, 4]\n\t" + "bleu 1f\n\t" + "addi\t%0, 0x1\n\t" + "1:add\t%0, %0, %1\n\t" + "cmp.c\t%1, %0\n\t" + "lw\t%1, [%3, 8]\n\t" + "bleu 1f\n\t" + "addi\t%0, 0x1\n\t" + "1:add\t%0, %0, %1\n\t" + "cmp.c\t%1, %0\n\t" + "lw\t%1, [%3, 12]\n\t" + "bleu 1f\n\t" + "addi\t%0, 0x1\n\t" + "1:add\t%0, %0, %1\n\t" + "cmp.c\t%1, %0\n\t" + "bleu 1f\n\t" + "addi\t%0, 0x1\n\t" + "1:\n\t" + ".set\toptimize" : "=r" (sum), "=r" (proto) : "r" (saddr), "r" (daddr), "0" (htonl(len)), "1" (htonl(proto)), "r" (sum)); diff --git a/arch/score/include/asm/io.h b/arch/score/include/asm/io.h index fbbfd7132e3b..574c8827abe2 100644 --- a/arch/score/include/asm/io.h +++ b/arch/score/include/asm/io.h @@ -5,5 +5,4 @@ #define virt_to_bus virt_to_phys #define bus_to_virt phys_to_virt - #endif /* _ASM_SCORE_IO_H */ diff --git a/arch/score/include/asm/pgalloc.h b/arch/score/include/asm/pgalloc.h index 059a61b7071b..716b3fd1d863 100644 --- a/arch/score/include/asm/pgalloc.h +++ b/arch/score/include/asm/pgalloc.h @@ -2,7 +2,7 @@ #define _ASM_SCORE_PGALLOC_H #include <linux/mm.h> - +#include <linux/highmem.h> static inline void pmd_populate_kernel(struct mm_struct *mm, pmd_t *pmd, pte_t *pte) { diff --git a/arch/score/kernel/entry.S b/arch/score/kernel/entry.S index 7234ed09b7b7..befb87d30a89 100644 --- a/arch/score/kernel/entry.S +++ b/arch/score/kernel/entry.S @@ -264,7 +264,7 @@ resume_kernel: disable_irq lw r8, [r28, TI_PRE_COUNT] cmpz.c r8 - bne r8, restore_all + bne restore_all need_resched: lw r8, [r28, TI_FLAGS] andri.c r9, r8, _TIF_NEED_RESCHED @@ -415,7 +415,7 @@ ENTRY(handle_sys) sw r9, [r0, PT_EPC] cmpi.c r27, __NR_syscalls # check syscall number - bgeu illegal_syscall + bcs illegal_syscall slli r8, r27, 2 # get syscall routine la r11, sys_call_table diff --git a/arch/score/kernel/process.c b/arch/score/kernel/process.c index f4c6d02421d3..a1519ad3d49d 100644 --- a/arch/score/kernel/process.c +++ b/arch/score/kernel/process.c @@ -78,8 +78,8 @@ int copy_thread(unsigned long clone_flags, unsigned long usp, p->thread.reg0 = (unsigned long) childregs; if (unlikely(p->flags & PF_KTHREAD)) { memset(childregs, 0, sizeof(struct pt_regs)); - p->thread->reg12 = usp; - p->thread->reg13 = arg; + p->thread.reg12 = usp; + p->thread.reg13 = arg; p->thread.reg3 = (unsigned long) ret_from_kernel_thread; } else { *childregs = *current_pt_regs(); diff --git a/arch/sparc/Kconfig b/arch/sparc/Kconfig index 2137ad667438..78c4fdb91bc5 100644 --- a/arch/sparc/Kconfig +++ b/arch/sparc/Kconfig @@ -506,12 +506,17 @@ config SUN_OPENPROMFS Only choose N if you know in advance that you will not need to modify OpenPROM settings on the running system. -# Makefile helper +# Makefile helpers config SPARC64_PCI bool default y depends on SPARC64 && PCI +config SPARC64_PCI_MSI + bool + default y + depends on SPARC64_PCI && PCI_MSI + endmenu menu "Executable file formats" diff --git a/arch/sparc/include/asm/floppy_64.h b/arch/sparc/include/asm/floppy_64.h index e204f902e6c9..7c90c50c200d 100644 --- a/arch/sparc/include/asm/floppy_64.h +++ b/arch/sparc/include/asm/floppy_64.h @@ -254,7 +254,7 @@ static int sun_fd_request_irq(void) once = 1; error = request_irq(FLOPPY_IRQ, sparc_floppy_irq, - IRQF_DISABLED, "floppy", NULL); + 0, "floppy", NULL); return ((error == 0) ? 0 : -1); } diff --git a/arch/sparc/kernel/Makefile b/arch/sparc/kernel/Makefile index d432fb20358e..d15cc1794b0e 100644 --- a/arch/sparc/kernel/Makefile +++ b/arch/sparc/kernel/Makefile @@ -1,3 +1,4 @@ + # # Makefile for the linux kernel. # @@ -99,7 +100,7 @@ obj-$(CONFIG_STACKTRACE) += stacktrace.o obj-$(CONFIG_SPARC64_PCI) += pci.o pci_common.o psycho_common.o obj-$(CONFIG_SPARC64_PCI) += pci_psycho.o pci_sabre.o pci_schizo.o obj-$(CONFIG_SPARC64_PCI) += pci_sun4v.o pci_sun4v_asm.o pci_fire.o -obj-$(CONFIG_PCI_MSI) += pci_msi.o +obj-$(CONFIG_SPARC64_PCI_MSI) += pci_msi.o obj-$(CONFIG_COMPAT) += sys32.o sys_sparc32.o signal32.o diff --git a/arch/sparc/kernel/ds.c b/arch/sparc/kernel/ds.c index 62d6b153ffa2..dff60abbea01 100644 --- a/arch/sparc/kernel/ds.c +++ b/arch/sparc/kernel/ds.c @@ -849,9 +849,8 @@ void ldom_reboot(const char *boot_command) if (boot_command && strlen(boot_command)) { unsigned long len; - strcpy(full_boot_str, "boot "); - strlcpy(full_boot_str + strlen("boot "), boot_command, - sizeof(full_boot_str + strlen("boot "))); + snprintf(full_boot_str, sizeof(full_boot_str), "boot %s", + boot_command); len = strlen(full_boot_str); if (reboot_data_supported) { diff --git a/arch/sparc/kernel/ldc.c b/arch/sparc/kernel/ldc.c index 54df554b82d9..e01d75d40329 100644 --- a/arch/sparc/kernel/ldc.c +++ b/arch/sparc/kernel/ldc.c @@ -1249,12 +1249,12 @@ int ldc_bind(struct ldc_channel *lp, const char *name) snprintf(lp->rx_irq_name, LDC_IRQ_NAME_MAX, "%s RX", name); snprintf(lp->tx_irq_name, LDC_IRQ_NAME_MAX, "%s TX", name); - err = request_irq(lp->cfg.rx_irq, ldc_rx, IRQF_DISABLED, + err = request_irq(lp->cfg.rx_irq, ldc_rx, 0, lp->rx_irq_name, lp); if (err) return err; - err = request_irq(lp->cfg.tx_irq, ldc_tx, IRQF_DISABLED, + err = request_irq(lp->cfg.tx_irq, ldc_tx, 0, lp->tx_irq_name, lp); if (err) { free_irq(lp->cfg.rx_irq, lp); diff --git a/arch/x86/kernel/sysfb_simplefb.c b/arch/x86/kernel/sysfb_simplefb.c index 22513e96b012..86179d409893 100644 --- a/arch/x86/kernel/sysfb_simplefb.c +++ b/arch/x86/kernel/sysfb_simplefb.c @@ -72,14 +72,14 @@ __init int create_simplefb(const struct screen_info *si, * the part that is occupied by the framebuffer */ len = mode->height * mode->stride; len = PAGE_ALIGN(len); - if (len > si->lfb_size << 16) { + if (len > (u64)si->lfb_size << 16) { printk(KERN_WARNING "sysfb: VRAM smaller than advertised\n"); return -EINVAL; } /* setup IORESOURCE_MEM as framebuffer memory */ memset(&res, 0, sizeof(res)); - res.flags = IORESOURCE_MEM; + res.flags = IORESOURCE_MEM | IORESOURCE_BUSY; res.name = simplefb_resname; res.start = si->lfb_base; res.end = si->lfb_base + len - 1; diff --git a/arch/x86/kvm/vmx.c b/arch/x86/kvm/vmx.c index a1216de9ffda..3b8e7459dd4d 100644 --- a/arch/x86/kvm/vmx.c +++ b/arch/x86/kvm/vmx.c @@ -5345,7 +5345,9 @@ static int handle_ept_violation(struct kvm_vcpu *vcpu) * There are errata that may cause this bit to not be set: * AAK134, BY25. */ - if (exit_qualification & INTR_INFO_UNBLOCK_NMI) + if (!(to_vmx(vcpu)->idt_vectoring_info & VECTORING_INFO_VALID_MASK) && + cpu_has_virtual_nmis() && + (exit_qualification & INTR_INFO_UNBLOCK_NMI)) vmcs_set_bits(GUEST_INTERRUPTIBILITY_INFO, GUEST_INTR_STATE_NMI); gpa = vmcs_read64(GUEST_PHYSICAL_ADDRESS); diff --git a/arch/x86/pci/mmconfig-shared.c b/arch/x86/pci/mmconfig-shared.c index 5596c7bdd327..082e88129712 100644 --- a/arch/x86/pci/mmconfig-shared.c +++ b/arch/x86/pci/mmconfig-shared.c @@ -700,7 +700,7 @@ int pci_mmconfig_insert(struct device *dev, u16 seg, u8 start, u8 end, if (!(pci_probe & PCI_PROBE_MMCONF) || pci_mmcfg_arch_init_failed) return -ENODEV; - if (start > end || !addr) + if (start > end) return -EINVAL; mutex_lock(&pci_mmcfg_lock); @@ -716,6 +716,11 @@ int pci_mmconfig_insert(struct device *dev, u16 seg, u8 start, u8 end, return -EEXIST; } + if (!addr) { + mutex_unlock(&pci_mmcfg_lock); + return -EINVAL; + } + rc = -EBUSY; cfg = pci_mmconfig_alloc(seg, start, end, addr); if (cfg == NULL) { |