mirror of
https://mirrors.bfsu.edu.cn/git/linux.git
synced 2024-12-04 09:34:12 +08:00
imx soc changes for 3.11:
* New SoCs i.MX6 Sololite and Vybrid VF610 support * imx5 and imx6 clock fixes and additions * Update clock driver to use of_clk_init() function * Refactor restart routine mxc_restart() to get it work for DT boot as well * Clean up mxc specific ulpi access ops * imx defconfig updates -----BEGIN PGP SIGNATURE----- Version: GnuPG v1.4.11 (GNU/Linux) iQEcBAABAgAGBQJRvsJmAAoJEFBXWFqHsHzOHOIH/jjVCaAFdOskPI4d9qPPAt9C 5o0aJDjerzTm+vH2mbec2507fChaYrLybAypJUj6wDYRf03RhAgPXorY83Y+3WtG SYz2UWza7MY8GeZv6e9tdrYS3JUSicFXPf8MsOcINsuyIub3dD96z36OqrnWZLFy uH5V81e4gOHECd4PWIxmhdjwawqmwb/Pqzl0V3+vXi2JM07xrn7/SqlZ7VfUwM2q DNhu5ugH7FtaFp75YrmTIhp6i+tovguRr0RIt6dnk/9gbJBQnV2Cw2MzdRPT12U5 bC79P7sojkKRtITcq9c1fnUNhkgc0+hS8HoezcQmzKMin6nFmVAh5wQFSlRJMJE= =mZw+ -----END PGP SIGNATURE----- Merge tag 'imx-soc-3.11' of git://git.linaro.org/people/shawnguo/linux-2.6 into next/soc From Shawn Guo: imx soc changes for 3.11: * New SoCs i.MX6 Sololite and Vybrid VF610 support * imx5 and imx6 clock fixes and additions * Update clock driver to use of_clk_init() function * Refactor restart routine mxc_restart() to get it work for DT boot as well * Clean up mxc specific ulpi access ops * imx defconfig updates * tag 'imx-soc-3.11' of git://git.linaro.org/people/shawnguo/linux-2.6: (29 commits) ARM: imx_v6_v7_defconfig: Enable Vybrid VF610 ARM: imx_v6_v7_defconfig: Enable imx-wm8962 by default ARM: clk-imx6qdl: Add clko1 configuration for imx6qdl-sabresd ARM: imx_v6_v7_defconfig: Enable PWM and backlight options ARM: imx: Remove mxc specific ulpi access ops ARM: imx: add initial support for VF610 ARM: imx: add VF610 clock support ARM: imx_v6_v7_defconfig: enable parallel display ARM: imx: clk: No need to initialize phandle struct ARM: imx: irq-common: Include header to avoid sparse warning ARM: imx: Enable mx6 solo-lite support ARM: imx6: use common of_clk_init() call to initialize clocks ARM: imx6q: call of_clk_init() to register fixed rate clocks ARM: imx: imx_v6_v7_defconfig: Select CONFIG_DRM_IMX_TVE ARM: i.MX6: clk: add different DualLite MLB clock config ARM i.MX5: Add S/PDIF clocks ARM i.MX53: Add SATA clock ARM: imx6q: clk: add the eim_slow clock ARM: imx: remove MLB PLL from pllv3 ARM: imx: disable pll8_mlb in mx6q_clks ... Conflicts: arch/arm/Kconfig.debug (simple add/add conflict) Includes an update to 3.10-rc6 Signed-off-by: Arnd Bergmann <arnd@arndb.de>
This commit is contained in:
commit
e5051b8472
@ -319,7 +319,10 @@ cache<0..n>
|
||||
Symlink to each of the cache devices comprising this cache set.
|
||||
|
||||
cache_available_percent
|
||||
Percentage of cache device free.
|
||||
Percentage of cache device which doesn't contain dirty data, and could
|
||||
potentially be used for writeback. This doesn't mean this space isn't used
|
||||
for clean cached data; the unused statistic (in priority_stats) is typically
|
||||
much lower.
|
||||
|
||||
clear_stats
|
||||
Clears the statistics associated with this cache
|
||||
@ -423,8 +426,11 @@ nbuckets
|
||||
Total buckets in this cache
|
||||
|
||||
priority_stats
|
||||
Statistics about how recently data in the cache has been accessed. This can
|
||||
reveal your working set size.
|
||||
Statistics about how recently data in the cache has been accessed.
|
||||
This can reveal your working set size. Unused is the percentage of
|
||||
the cache that doesn't contain any data. Metadata is bcache's
|
||||
metadata overhead. Average is the average priority of cache buckets.
|
||||
Next is a list of quantiles with the priority threshold of each.
|
||||
|
||||
written
|
||||
Sum of all data that has been written to the cache; comparison with
|
||||
|
@ -498,12 +498,8 @@ Your cooperation is appreciated.
|
||||
|
||||
Each device type has 5 bits (32 minors).
|
||||
|
||||
13 block 8-bit MFM/RLL/IDE controller
|
||||
0 = /dev/xda First XT disk whole disk
|
||||
64 = /dev/xdb Second XT disk whole disk
|
||||
|
||||
Partitions are handled in the same way as IDE disks
|
||||
(see major number 3).
|
||||
13 block Previously used for the XT disk (/dev/xdN)
|
||||
Deleted in kernel v3.9.
|
||||
|
||||
14 char Open Sound System (OSS)
|
||||
0 = /dev/mixer Mixer control
|
||||
|
@ -184,6 +184,19 @@ clocks and IDs.
|
||||
cko2 170
|
||||
srtc_gate 171
|
||||
pata_gate 172
|
||||
sata_gate 173
|
||||
spdif_xtal_sel 174
|
||||
spdif0_sel 175
|
||||
spdif1_sel 176
|
||||
spdif0_pred 177
|
||||
spdif0_podf 178
|
||||
spdif1_pred 179
|
||||
spdif1_podf 180
|
||||
spdif0_com_sel 181
|
||||
spdif1_com_sel 182
|
||||
spdif0_gate 183
|
||||
spdif1_gate 184
|
||||
spdif_ipg_gate 185
|
||||
|
||||
Examples (for mx53):
|
||||
|
||||
|
@ -208,6 +208,7 @@ clocks and IDs.
|
||||
pll4_post_div 193
|
||||
pll5_post_div 194
|
||||
pll5_video_div 195
|
||||
eim_slow 196
|
||||
|
||||
Examples:
|
||||
|
||||
|
10
Documentation/devicetree/bindings/clock/imx6sl-clock.txt
Normal file
10
Documentation/devicetree/bindings/clock/imx6sl-clock.txt
Normal file
@ -0,0 +1,10 @@
|
||||
* Clock bindings for Freescale i.MX6 SoloLite
|
||||
|
||||
Required properties:
|
||||
- compatible: Should be "fsl,imx6sl-ccm"
|
||||
- reg: Address and length of the register set
|
||||
- #clock-cells: Should be <1>
|
||||
|
||||
The clock consumer should specify the desired clock by having the clock
|
||||
ID in its "clocks" phandle cell. See include/dt-bindings/clock/imx6sl-clock.h
|
||||
for the full list of i.MX6 SoloLite clock IDs.
|
26
Documentation/devicetree/bindings/clock/vf610-clock.txt
Normal file
26
Documentation/devicetree/bindings/clock/vf610-clock.txt
Normal file
@ -0,0 +1,26 @@
|
||||
* Clock bindings for Freescale Vybrid VF610 SOC
|
||||
|
||||
Required properties:
|
||||
- compatible: Should be "fsl,vf610-ccm"
|
||||
- reg: Address and length of the register set
|
||||
- #clock-cells: Should be <1>
|
||||
|
||||
The clock consumer should specify the desired clock by having the clock
|
||||
ID in its "clocks" phandle cell. See include/dt-bindings/clock/vf610-clock.h
|
||||
for the full list of VF610 clock IDs.
|
||||
|
||||
Examples:
|
||||
|
||||
clks: ccm@4006b000 {
|
||||
compatible = "fsl,vf610-ccm";
|
||||
reg = <0x4006b000 0x1000>;
|
||||
#clock-cells = <1>;
|
||||
};
|
||||
|
||||
uart1: serial@40028000 {
|
||||
compatible = "fsl,vf610-uart";
|
||||
reg = <0x40028000 0x1000>;
|
||||
interrupts = <0 62 0x04>;
|
||||
clocks = <&clks VF610_CLK_UART1>;
|
||||
clock-names = "ipg";
|
||||
};
|
@ -1,7 +1,7 @@
|
||||
Atmel AT91RM9200 Real Time Clock
|
||||
|
||||
Required properties:
|
||||
- compatible: should be: "atmel,at91rm9200-rtc"
|
||||
- compatible: should be: "atmel,at91rm9200-rtc" or "atmel,at91sam9x5-rtc"
|
||||
- reg: physical base address of the controller and length of memory mapped
|
||||
region.
|
||||
- interrupts: rtc alarm/event interrupt
|
||||
|
@ -3351,9 +3351,6 @@ bytes respectively. Such letter suffixes can also be entirely omitted.
|
||||
plus one apbt timer for broadcast timer.
|
||||
x86_mrst_timer=apbt_only | lapic_and_apbt
|
||||
|
||||
xd= [HW,XT] Original XT pre-IDE (RLL encoded) disks.
|
||||
xd_geo= See header of drivers/block/xd.c.
|
||||
|
||||
xen_emul_unplug= [HW,X86,XEN]
|
||||
Unplug Xen emulated devices
|
||||
Format: [unplug0,][unplug1]
|
||||
|
@ -80,8 +80,6 @@ Valid names are:
|
||||
/dev/sdd: -> 0x0830 (forth SCSI disk)
|
||||
/dev/sde: -> 0x0840 (fifth SCSI disk)
|
||||
/dev/fd : -> 0x0200 (floppy disk)
|
||||
/dev/xda: -> 0x0c00 (first XT disk, unused in Linux/m68k)
|
||||
/dev/xdb: -> 0x0c40 (second XT disk, unused in Linux/m68k)
|
||||
|
||||
The name must be followed by a decimal number, that stands for the
|
||||
partition number. Internally, the value of the number is just
|
||||
|
@ -5766,7 +5766,7 @@ M: Matthew Wilcox <willy@linux.intel.com>
|
||||
L: linux-nvme@lists.infradead.org
|
||||
T: git git://git.infradead.org/users/willy/linux-nvme.git
|
||||
S: Supported
|
||||
F: drivers/block/nvme.c
|
||||
F: drivers/block/nvme*
|
||||
F: include/linux/nvme.h
|
||||
|
||||
OMAP SUPPORT
|
||||
@ -7624,7 +7624,7 @@ F: drivers/clk/spear/
|
||||
SPI SUBSYSTEM
|
||||
M: Mark Brown <broonie@kernel.org>
|
||||
M: Grant Likely <grant.likely@linaro.org>
|
||||
L: spi-devel-general@lists.sourceforge.net
|
||||
L: linux-spi@vger.kernel.org
|
||||
T: git git://git.kernel.org/pub/scm/linux/kernel/git/broonie/spi.git
|
||||
Q: http://patchwork.kernel.org/project/spi-devel-general/list/
|
||||
S: Maintained
|
||||
@ -9004,7 +9004,7 @@ S: Maintained
|
||||
F: drivers/net/wireless/wl3501*
|
||||
|
||||
WM97XX TOUCHSCREEN DRIVERS
|
||||
M: Mark Brown <broonie@opensource.wolfsonmicro.com>
|
||||
M: Mark Brown <broonie@kernel.org>
|
||||
M: Liam Girdwood <lrg@slimlogic.co.uk>
|
||||
L: linux-input@vger.kernel.org
|
||||
T: git git://opensource.wolfsonmicro.com/linux-2.6-touch
|
||||
@ -9014,7 +9014,6 @@ F: drivers/input/touchscreen/*wm97*
|
||||
F: include/linux/wm97xx.h
|
||||
|
||||
WOLFSON MICROELECTRONICS DRIVERS
|
||||
M: Mark Brown <broonie@opensource.wolfsonmicro.com>
|
||||
L: patches@opensource.wolfsonmicro.com
|
||||
T: git git://opensource.wolfsonmicro.com/linux-2.6-asoc
|
||||
T: git git://opensource.wolfsonmicro.com/linux-2.6-audioplus
|
||||
|
2
Makefile
2
Makefile
@ -1,7 +1,7 @@
|
||||
VERSION = 3
|
||||
PATCHLEVEL = 10
|
||||
SUBLEVEL = 0
|
||||
EXTRAVERSION = -rc5
|
||||
EXTRAVERSION = -rc6
|
||||
NAME = Unicycling Gorilla
|
||||
|
||||
# *DOCUMENTATION*
|
||||
|
@ -251,6 +251,13 @@ choice
|
||||
Say Y here if you want kernel low-level debugging support
|
||||
on i.MX6Q/DL.
|
||||
|
||||
config DEBUG_IMX6SL_UART
|
||||
bool "i.MX6SL Debug UART"
|
||||
depends on SOC_IMX6SL
|
||||
help
|
||||
Say Y here if you want kernel low-level debugging support
|
||||
on i.MX6SL.
|
||||
|
||||
config DEBUG_KEYSTONE_UART0
|
||||
bool "Kernel low-level debugging on KEYSTONE2 using UART0"
|
||||
depends on ARCH_KEYSTONE
|
||||
@ -578,7 +585,8 @@ config DEBUG_IMX_UART_PORT
|
||||
DEBUG_IMX35_UART || \
|
||||
DEBUG_IMX51_UART || \
|
||||
DEBUG_IMX53_UART || \
|
||||
DEBUG_IMX6Q_UART
|
||||
DEBUG_IMX6Q_UART || \
|
||||
DEBUG_IMX6SL_UART
|
||||
default 1
|
||||
depends on ARCH_MXC
|
||||
help
|
||||
@ -677,7 +685,8 @@ config DEBUG_LL_INCLUDE
|
||||
DEBUG_IMX35_UART || \
|
||||
DEBUG_IMX51_UART || \
|
||||
DEBUG_IMX53_UART ||\
|
||||
DEBUG_IMX6Q_UART
|
||||
DEBUG_IMX6Q_UART || \
|
||||
DEBUG_IMX6SL_UART
|
||||
default "debug/keystone.S" if DEBUG_KEYSTONE_UART0 || \
|
||||
DEBUG_KEYSTONE_UART1
|
||||
default "debug/mvebu.S" if DEBUG_MVEBU_UART || \
|
||||
|
@ -124,7 +124,7 @@ KBUILD_CFLAGS = $(subst -pg, , $(ORIG_CFLAGS))
|
||||
endif
|
||||
|
||||
ccflags-y := -fpic -mno-single-pic-base -fno-builtin -I$(obj)
|
||||
asflags-y := -Wa,-march=all -DZIMAGE
|
||||
asflags-y := -DZIMAGE
|
||||
|
||||
# Supply kernel BSS size to the decompressor via a linker symbol.
|
||||
KBSS_SZ = $(shell $(CROSS_COMPILE)size $(obj)/../../../../vmlinux | \
|
||||
|
@ -1,6 +1,8 @@
|
||||
#include <linux/linkage.h>
|
||||
#include <asm/assembler.h>
|
||||
|
||||
#ifndef CONFIG_DEBUG_SEMIHOSTING
|
||||
|
||||
#include CONFIG_DEBUG_LL_INCLUDE
|
||||
|
||||
ENTRY(putc)
|
||||
@ -10,3 +12,29 @@ ENTRY(putc)
|
||||
busyuart r3, r1
|
||||
mov pc, lr
|
||||
ENDPROC(putc)
|
||||
|
||||
#else
|
||||
|
||||
ENTRY(putc)
|
||||
adr r1, 1f
|
||||
ldmia r1, {r2, r3}
|
||||
add r2, r2, r1
|
||||
ldr r1, [r2, r3]
|
||||
strb r0, [r1]
|
||||
mov r0, #0x03 @ SYS_WRITEC
|
||||
ARM( svc #0x123456 )
|
||||
THUMB( svc #0xab )
|
||||
mov pc, lr
|
||||
.align 2
|
||||
1: .word _GLOBAL_OFFSET_TABLE_ - .
|
||||
.word semi_writec_buf(GOT)
|
||||
ENDPROC(putc)
|
||||
|
||||
.bss
|
||||
.global semi_writec_buf
|
||||
.type semi_writec_buf, %object
|
||||
semi_writec_buf:
|
||||
.space 4
|
||||
.size semi_writec_buf, 4
|
||||
|
||||
#endif
|
||||
|
@ -11,6 +11,7 @@
|
||||
#include <asm/mach-types.h>
|
||||
|
||||
.section ".start", "ax"
|
||||
.arch armv4
|
||||
|
||||
__SA1100_start:
|
||||
|
||||
|
@ -18,6 +18,7 @@
|
||||
|
||||
.section ".start", "ax"
|
||||
|
||||
.arch armv4
|
||||
b __beginning
|
||||
|
||||
__ofw_data: .long 0 @ the number of memory blocks
|
||||
|
@ -11,6 +11,7 @@
|
||||
#include <linux/linkage.h>
|
||||
#include <asm/assembler.h>
|
||||
|
||||
.arch armv7-a
|
||||
/*
|
||||
* Debugging stuff
|
||||
*
|
||||
@ -805,8 +806,8 @@ call_cache_fn: adr r12, proc_types
|
||||
.align 2
|
||||
.type proc_types,#object
|
||||
proc_types:
|
||||
.word 0x00000000 @ old ARM ID
|
||||
.word 0x0000f000
|
||||
.word 0x41000000 @ old ARM ID
|
||||
.word 0xff00f000
|
||||
mov pc, lr
|
||||
THUMB( nop )
|
||||
mov pc, lr
|
||||
|
@ -409,8 +409,8 @@
|
||||
ti,hwmods = "gpmc";
|
||||
reg = <0x50000000 0x2000>;
|
||||
interrupts = <100>;
|
||||
num-cs = <7>;
|
||||
num-waitpins = <2>;
|
||||
gpmc,num-cs = <7>;
|
||||
gpmc,num-waitpins = <2>;
|
||||
#address-cells = <2>;
|
||||
#size-cells = <1>;
|
||||
status = "disabled";
|
||||
|
@ -39,8 +39,9 @@
|
||||
};
|
||||
|
||||
soc {
|
||||
ranges = <0 0 0xd0000000 0x100000
|
||||
0xf0000000 0 0xf0000000 0x1000000>;
|
||||
ranges = <0 0 0xd0000000 0x100000 /* Internal registers 1MiB */
|
||||
0xe0000000 0 0xe0000000 0x8100000 /* PCIe */
|
||||
0xf0000000 0 0xf0000000 0x1000000 /* Device Bus, NOR 16MiB */>;
|
||||
|
||||
internal-regs {
|
||||
serial@12000 {
|
||||
|
@ -27,8 +27,9 @@
|
||||
};
|
||||
|
||||
soc {
|
||||
ranges = <0 0 0xd0000000 0x100000
|
||||
0xf0000000 0 0xf0000000 0x8000000>;
|
||||
ranges = <0 0 0xd0000000 0x100000 /* Internal registers 1MiB */
|
||||
0xe0000000 0 0xe0000000 0x8100000 /* PCIe */
|
||||
0xf0000000 0 0xf0000000 0x8000000 /* Device Bus, NOR 128MiB */>;
|
||||
|
||||
internal-regs {
|
||||
serial@12000 {
|
||||
|
@ -56,9 +56,23 @@
|
||||
};
|
||||
};
|
||||
|
||||
&omap4_pmx_wkup {
|
||||
pinctrl-names = "default";
|
||||
pinctrl-0 = <
|
||||
&twl6030_wkup_pins
|
||||
>;
|
||||
|
||||
twl6030_wkup_pins: pinmux_twl6030_wkup_pins {
|
||||
pinctrl-single,pins = <
|
||||
0x14 0x2 /* fref_clk0_out.sys_drm_msecure OUTPUT | MODE2 */
|
||||
>;
|
||||
};
|
||||
};
|
||||
|
||||
&omap4_pmx_core {
|
||||
pinctrl-names = "default";
|
||||
pinctrl-0 = <
|
||||
&twl6030_pins
|
||||
&twl6040_pins
|
||||
&mcpdm_pins
|
||||
&mcbsp1_pins
|
||||
@ -66,6 +80,12 @@
|
||||
&tpd12s015_pins
|
||||
>;
|
||||
|
||||
twl6030_pins: pinmux_twl6030_pins {
|
||||
pinctrl-single,pins = <
|
||||
0x15e 0x4118 /* sys_nirq1.sys_nirq1 OMAP_WAKEUP_EN | INPUT_PULLUP | MODE0 */
|
||||
>;
|
||||
};
|
||||
|
||||
twl6040_pins: pinmux_twl6040_pins {
|
||||
pinctrl-single,pins = <
|
||||
0xe0 0x3 /* hdq_sio.gpio_127 OUTPUT | MODE3 */
|
||||
|
@ -142,9 +142,23 @@
|
||||
};
|
||||
};
|
||||
|
||||
&omap4_pmx_wkup {
|
||||
pinctrl-names = "default";
|
||||
pinctrl-0 = <
|
||||
&twl6030_wkup_pins
|
||||
>;
|
||||
|
||||
twl6030_wkup_pins: pinmux_twl6030_wkup_pins {
|
||||
pinctrl-single,pins = <
|
||||
0x14 0x2 /* fref_clk0_out.sys_drm_msecure OUTPUT | MODE2 */
|
||||
>;
|
||||
};
|
||||
};
|
||||
|
||||
&omap4_pmx_core {
|
||||
pinctrl-names = "default";
|
||||
pinctrl-0 = <
|
||||
&twl6030_pins
|
||||
&twl6040_pins
|
||||
&mcpdm_pins
|
||||
&dmic_pins
|
||||
@ -179,6 +193,12 @@
|
||||
>;
|
||||
};
|
||||
|
||||
twl6030_pins: pinmux_twl6030_pins {
|
||||
pinctrl-single,pins = <
|
||||
0x15e 0x4118 /* sys_nirq1.sys_nirq1 OMAP_WAKEUP_EN | INPUT_PULLUP | MODE0 */
|
||||
>;
|
||||
};
|
||||
|
||||
twl6040_pins: pinmux_twl6040_pins {
|
||||
pinctrl-single,pins = <
|
||||
0xe0 0x3 /* hdq_sio.gpio_127 OUTPUT | MODE3 */
|
||||
|
@ -538,6 +538,7 @@
|
||||
interrupts = <0 41 0x4>;
|
||||
ti,hwmods = "timer5";
|
||||
ti,timer-dsp;
|
||||
ti,timer-pwm;
|
||||
};
|
||||
|
||||
timer6: timer@4013a000 {
|
||||
@ -574,6 +575,7 @@
|
||||
reg = <0x4803e000 0x80>;
|
||||
interrupts = <0 45 0x4>;
|
||||
ti,hwmods = "timer9";
|
||||
ti,timer-pwm;
|
||||
};
|
||||
|
||||
timer10: timer@48086000 {
|
||||
@ -581,6 +583,7 @@
|
||||
reg = <0x48086000 0x80>;
|
||||
interrupts = <0 46 0x4>;
|
||||
ti,hwmods = "timer10";
|
||||
ti,timer-pwm;
|
||||
};
|
||||
|
||||
timer11: timer@48088000 {
|
||||
|
@ -37,6 +37,8 @@ CONFIG_MACH_IMX51_DT=y
|
||||
CONFIG_MACH_EUKREA_CPUIMX51SD=y
|
||||
CONFIG_SOC_IMX53=y
|
||||
CONFIG_SOC_IMX6Q=y
|
||||
CONFIG_SOC_IMX6SL=y
|
||||
CONFIG_SOC_VF610=y
|
||||
CONFIG_MXC_PWM=y
|
||||
CONFIG_SMP=y
|
||||
CONFIG_VMSPLIT_2G=y
|
||||
@ -47,6 +49,7 @@ CONFIG_CMDLINE="noinitrd console=ttymxc0,115200"
|
||||
CONFIG_VFP=y
|
||||
CONFIG_NEON=y
|
||||
CONFIG_BINFMT_MISC=m
|
||||
CONFIG_PM_RUNTIME=y
|
||||
CONFIG_PM_DEBUG=y
|
||||
CONFIG_PM_TEST_SUSPEND=y
|
||||
CONFIG_NET=y
|
||||
@ -170,6 +173,7 @@ CONFIG_BACKLIGHT_LCD_SUPPORT=y
|
||||
CONFIG_LCD_CLASS_DEVICE=y
|
||||
CONFIG_LCD_L4F00242T03=y
|
||||
CONFIG_BACKLIGHT_CLASS_DEVICE=y
|
||||
CONFIG_BACKLIGHT_PWM=y
|
||||
CONFIG_FRAMEBUFFER_CONSOLE=y
|
||||
CONFIG_FRAMEBUFFER_CONSOLE_DETECT_PRIMARY=y
|
||||
CONFIG_FONTS=y
|
||||
@ -182,6 +186,7 @@ CONFIG_SND_SOC=y
|
||||
CONFIG_SND_IMX_SOC=y
|
||||
CONFIG_SND_SOC_PHYCORE_AC97=y
|
||||
CONFIG_SND_SOC_EUKREA_TLV320=y
|
||||
CONFIG_SND_SOC_IMX_WM8962=y
|
||||
CONFIG_SND_SOC_IMX_SGTL5000=y
|
||||
CONFIG_SND_SOC_IMX_MC13783=y
|
||||
CONFIG_USB=y
|
||||
@ -208,10 +213,15 @@ CONFIG_IMX_SDMA=y
|
||||
CONFIG_MXS_DMA=y
|
||||
CONFIG_STAGING=y
|
||||
CONFIG_DRM_IMX=y
|
||||
CONFIG_DRM_IMX_TVE=y
|
||||
CONFIG_DRM_IMX_FB_HELPER=y
|
||||
CONFIG_DRM_IMX_PARALLEL_DISPLAY=y
|
||||
CONFIG_DRM_IMX_IPUV3_CORE=y
|
||||
CONFIG_DRM_IMX_IPUV3=y
|
||||
CONFIG_COMMON_CLK_DEBUG=y
|
||||
# CONFIG_IOMMU_SUPPORT is not set
|
||||
CONFIG_PWM=y
|
||||
CONFIG_PWM_IMX=y
|
||||
CONFIG_EXT2_FS=y
|
||||
CONFIG_EXT2_FS_XATTR=y
|
||||
CONFIG_EXT2_FS_POSIX_ACL=y
|
||||
|
@ -30,8 +30,15 @@ static inline void set_my_cpu_offset(unsigned long off)
|
||||
static inline unsigned long __my_cpu_offset(void)
|
||||
{
|
||||
unsigned long off;
|
||||
/* Read TPIDRPRW */
|
||||
asm("mrc p15, 0, %0, c13, c0, 4" : "=r" (off) : : "memory");
|
||||
register unsigned long *sp asm ("sp");
|
||||
|
||||
/*
|
||||
* Read TPIDRPRW.
|
||||
* We want to allow caching the value, so avoid using volatile and
|
||||
* instead use a fake stack read to hazard against barrier().
|
||||
*/
|
||||
asm("mrc p15, 0, %0, c13, c0, 4" : "=r" (off) : "Q" (*sp));
|
||||
|
||||
return off;
|
||||
}
|
||||
#define __my_cpu_offset __my_cpu_offset()
|
||||
|
@ -65,6 +65,14 @@
|
||||
#define IMX6Q_UART_BASE_ADDR(n) IMX6Q_UART##n##_BASE_ADDR
|
||||
#define IMX6Q_UART_BASE(n) IMX6Q_UART_BASE_ADDR(n)
|
||||
|
||||
#define IMX6SL_UART1_BASE_ADDR 0x02020000
|
||||
#define IMX6SL_UART2_BASE_ADDR 0x02024000
|
||||
#define IMX6SL_UART3_BASE_ADDR 0x02034000
|
||||
#define IMX6SL_UART4_BASE_ADDR 0x02038000
|
||||
#define IMX6SL_UART5_BASE_ADDR 0x02018000
|
||||
#define IMX6SL_UART_BASE_ADDR(n) IMX6SL_UART##n##_BASE_ADDR
|
||||
#define IMX6SL_UART_BASE(n) IMX6SL_UART_BASE_ADDR(n)
|
||||
|
||||
#define IMX_DEBUG_UART_BASE(soc) soc##_UART_BASE(CONFIG_DEBUG_IMX_UART_PORT)
|
||||
|
||||
#ifdef CONFIG_DEBUG_IMX1_UART
|
||||
@ -83,6 +91,8 @@
|
||||
#define UART_PADDR IMX_DEBUG_UART_BASE(IMX53)
|
||||
#elif defined(CONFIG_DEBUG_IMX6Q_UART)
|
||||
#define UART_PADDR IMX_DEBUG_UART_BASE(IMX6Q)
|
||||
#elif defined(CONFIG_DEBUG_IMX6SL_UART)
|
||||
#define UART_PADDR IMX_DEBUG_UART_BASE(IMX6SL)
|
||||
#endif
|
||||
|
||||
#endif /* __DEBUG_IMX_UART_H */
|
||||
|
@ -13,6 +13,7 @@
|
||||
|
||||
#include <linux/cpu.h>
|
||||
#include <linux/cpumask.h>
|
||||
#include <linux/export.h>
|
||||
#include <linux/init.h>
|
||||
#include <linux/percpu.h>
|
||||
#include <linux/node.h>
|
||||
@ -200,6 +201,7 @@ static inline void update_cpu_power(unsigned int cpuid, unsigned int mpidr) {}
|
||||
* cpu topology table
|
||||
*/
|
||||
struct cputopo_arm cpu_topology[NR_CPUS];
|
||||
EXPORT_SYMBOL_GPL(cpu_topology);
|
||||
|
||||
const struct cpumask *cpu_coregroup_mask(int cpu)
|
||||
{
|
||||
|
@ -56,9 +56,6 @@ config MXC_USE_EPIT
|
||||
uses the same clocks as the GPT. Anyway, on some systems the GPT
|
||||
may be in use for other purposes.
|
||||
|
||||
config MXC_ULPI
|
||||
bool
|
||||
|
||||
config ARCH_HAS_RNGA
|
||||
bool
|
||||
|
||||
@ -233,7 +230,7 @@ config MACH_EUKREA_CPUIMX25SD
|
||||
select IMX_HAVE_PLATFORM_MXC_EHCI
|
||||
select IMX_HAVE_PLATFORM_MXC_NAND
|
||||
select IMX_HAVE_PLATFORM_SDHCI_ESDHC_IMX
|
||||
select MXC_ULPI if USB_ULPI
|
||||
select USB_ULPI_VIEWPORT if USB_ULPI
|
||||
select SOC_IMX25
|
||||
|
||||
choice
|
||||
@ -284,7 +281,7 @@ config MACH_PCM038
|
||||
select IMX_HAVE_PLATFORM_MXC_NAND
|
||||
select IMX_HAVE_PLATFORM_MXC_W1
|
||||
select IMX_HAVE_PLATFORM_SPI_IMX
|
||||
select MXC_ULPI if USB_ULPI
|
||||
select USB_ULPI_VIEWPORT if USB_ULPI
|
||||
select SOC_IMX27
|
||||
help
|
||||
Include support for phyCORE-i.MX27 (aka pcm038) platform. This
|
||||
@ -314,7 +311,7 @@ config MACH_CPUIMX27
|
||||
select IMX_HAVE_PLATFORM_MXC_EHCI
|
||||
select IMX_HAVE_PLATFORM_MXC_NAND
|
||||
select IMX_HAVE_PLATFORM_MXC_W1
|
||||
select MXC_ULPI if USB_ULPI
|
||||
select USB_ULPI_VIEWPORT if USB_ULPI
|
||||
select SOC_IMX27
|
||||
help
|
||||
Include support for Eukrea CPUIMX27 platform. This includes
|
||||
@ -369,7 +366,7 @@ config MACH_MX27_3DS
|
||||
select IMX_HAVE_PLATFORM_MXC_MMC
|
||||
select IMX_HAVE_PLATFORM_SPI_IMX
|
||||
select MXC_DEBUG_BOARD
|
||||
select MXC_ULPI if USB_ULPI
|
||||
select USB_ULPI_VIEWPORT if USB_ULPI
|
||||
select SOC_IMX27
|
||||
help
|
||||
Include support for MX27PDK platform. This includes specific
|
||||
@ -414,7 +411,7 @@ config MACH_PCA100
|
||||
select IMX_HAVE_PLATFORM_MXC_NAND
|
||||
select IMX_HAVE_PLATFORM_MXC_W1
|
||||
select IMX_HAVE_PLATFORM_SPI_IMX
|
||||
select MXC_ULPI if USB_ULPI
|
||||
select USB_ULPI_VIEWPORT if USB_ULPI
|
||||
select SOC_IMX27
|
||||
help
|
||||
Include support for phyCARD-s (aka pca100) platform. This
|
||||
@ -481,7 +478,7 @@ config MACH_MX31LILLY
|
||||
select IMX_HAVE_PLATFORM_MXC_EHCI
|
||||
select IMX_HAVE_PLATFORM_MXC_MMC
|
||||
select IMX_HAVE_PLATFORM_SPI_IMX
|
||||
select MXC_ULPI if USB_ULPI
|
||||
select USB_ULPI_VIEWPORT if USB_ULPI
|
||||
select SOC_IMX31
|
||||
help
|
||||
Include support for mx31 based LILLY1131 modules. This includes
|
||||
@ -497,7 +494,7 @@ config MACH_MX31LITE
|
||||
select IMX_HAVE_PLATFORM_MXC_RTC
|
||||
select IMX_HAVE_PLATFORM_SPI_IMX
|
||||
select LEDS_GPIO_REGISTER
|
||||
select MXC_ULPI if USB_ULPI
|
||||
select USB_ULPI_VIEWPORT if USB_ULPI
|
||||
select SOC_IMX31
|
||||
help
|
||||
Include support for MX31 LITEKIT platform. This includes specific
|
||||
@ -514,7 +511,7 @@ config MACH_PCM037
|
||||
select IMX_HAVE_PLATFORM_MXC_MMC
|
||||
select IMX_HAVE_PLATFORM_MXC_NAND
|
||||
select IMX_HAVE_PLATFORM_MXC_W1
|
||||
select MXC_ULPI if USB_ULPI
|
||||
select USB_ULPI_VIEWPORT if USB_ULPI
|
||||
select SOC_IMX31
|
||||
help
|
||||
Include support for Phytec pcm037 platform. This includes
|
||||
@ -544,7 +541,7 @@ config MACH_MX31_3DS
|
||||
select IMX_HAVE_PLATFORM_MXC_NAND
|
||||
select IMX_HAVE_PLATFORM_SPI_IMX
|
||||
select MXC_DEBUG_BOARD
|
||||
select MXC_ULPI if USB_ULPI
|
||||
select USB_ULPI_VIEWPORT if USB_ULPI
|
||||
select SOC_IMX31
|
||||
help
|
||||
Include support for MX31PDK (3DS) platform. This includes specific
|
||||
@ -571,7 +568,7 @@ config MACH_MX31MOBOARD
|
||||
select IMX_HAVE_PLATFORM_MXC_MMC
|
||||
select IMX_HAVE_PLATFORM_SPI_IMX
|
||||
select LEDS_GPIO_REGISTER
|
||||
select MXC_ULPI if USB_ULPI
|
||||
select USB_ULPI_VIEWPORT if USB_ULPI
|
||||
select SOC_IMX31
|
||||
help
|
||||
Include support for mx31moboard platform. This includes specific
|
||||
@ -595,7 +592,7 @@ config MACH_ARMADILLO5X0
|
||||
select IMX_HAVE_PLATFORM_MXC_EHCI
|
||||
select IMX_HAVE_PLATFORM_MXC_MMC
|
||||
select IMX_HAVE_PLATFORM_MXC_NAND
|
||||
select MXC_ULPI if USB_ULPI
|
||||
select USB_ULPI_VIEWPORT if USB_ULPI
|
||||
select SOC_IMX31
|
||||
help
|
||||
Include support for Atmark Armadillo-500 platform. This includes
|
||||
@ -639,7 +636,7 @@ config MACH_PCM043
|
||||
select IMX_HAVE_PLATFORM_MXC_EHCI
|
||||
select IMX_HAVE_PLATFORM_MXC_NAND
|
||||
select IMX_HAVE_PLATFORM_SDHCI_ESDHC_IMX
|
||||
select MXC_ULPI if USB_ULPI
|
||||
select USB_ULPI_VIEWPORT if USB_ULPI
|
||||
select SOC_IMX35
|
||||
help
|
||||
Include support for Phytec pcm043 platform. This includes
|
||||
@ -673,7 +670,7 @@ config MACH_EUKREA_CPUIMX35SD
|
||||
select IMX_HAVE_PLATFORM_MXC_EHCI
|
||||
select IMX_HAVE_PLATFORM_MXC_NAND
|
||||
select IMX_HAVE_PLATFORM_SDHCI_ESDHC_IMX
|
||||
select MXC_ULPI if USB_ULPI
|
||||
select USB_ULPI_VIEWPORT if USB_ULPI
|
||||
select SOC_IMX35
|
||||
help
|
||||
Include support for Eukrea CPUIMX35 platform. This includes
|
||||
@ -816,6 +813,40 @@ config SOC_IMX6Q
|
||||
help
|
||||
This enables support for Freescale i.MX6 Quad processor.
|
||||
|
||||
config SOC_IMX6SL
|
||||
bool "i.MX6 SoloLite support"
|
||||
select ARM_ERRATA_754322
|
||||
select ARM_ERRATA_775420
|
||||
select ARM_GIC
|
||||
select CPU_V7
|
||||
select HAVE_IMX_ANATOP
|
||||
select HAVE_IMX_GPC
|
||||
select HAVE_IMX_MMDC
|
||||
select HAVE_IMX_SRC
|
||||
select PINCTRL
|
||||
select PINCTRL_IMX6SL
|
||||
select PL310_ERRATA_588369 if CACHE_PL310
|
||||
select PL310_ERRATA_727915 if CACHE_PL310
|
||||
select PL310_ERRATA_769419 if CACHE_PL310
|
||||
|
||||
help
|
||||
This enables support for Freescale i.MX6 SoloLite processor.
|
||||
|
||||
config SOC_VF610
|
||||
bool "Vybrid Family VF610 support"
|
||||
select CPU_V7
|
||||
select ARM_GIC
|
||||
select CLKSRC_OF
|
||||
select PINCTRL
|
||||
select PINCTRL_VF610
|
||||
select VF_PIT_TIMER
|
||||
select PL310_ERRATA_588369 if CACHE_PL310
|
||||
select PL310_ERRATA_727915 if CACHE_PL310
|
||||
select PL310_ERRATA_769419 if CACHE_PL310
|
||||
|
||||
help
|
||||
This enable support for Freescale Vybrid VF610 processor.
|
||||
|
||||
endif
|
||||
|
||||
source "arch/arm/mach-imx/devices/Kconfig"
|
||||
|
@ -23,7 +23,6 @@ obj-$(CONFIG_ARCH_MXC_IOMUX_V3) += iomux-v3.o
|
||||
obj-$(CONFIG_MXC_TZIC) += tzic.o
|
||||
obj-$(CONFIG_MXC_AVIC) += avic.o
|
||||
|
||||
obj-$(CONFIG_MXC_ULPI) += ulpi.o
|
||||
obj-$(CONFIG_MXC_USE_EPIT) += epit.o
|
||||
obj-$(CONFIG_MXC_DEBUG_BOARD) += 3ds_debugboard.o
|
||||
|
||||
@ -98,6 +97,7 @@ AFLAGS_headsmp.o :=-Wa,-march=armv7-a
|
||||
obj-$(CONFIG_SMP) += headsmp.o platsmp.o
|
||||
obj-$(CONFIG_HOTPLUG_CPU) += hotplug.o
|
||||
obj-$(CONFIG_SOC_IMX6Q) += clk-imx6q.o mach-imx6q.o
|
||||
obj-$(CONFIG_SOC_IMX6SL) += clk-imx6sl.o mach-imx6sl.o
|
||||
|
||||
ifeq ($(CONFIG_PM),y)
|
||||
obj-$(CONFIG_SOC_IMX6Q) += pm-imx6q.o headsmp.o
|
||||
@ -111,4 +111,6 @@ obj-$(CONFIG_MACH_EUKREA_MBIMXSD51_BASEBOARD) += eukrea_mbimxsd51-baseboard.o
|
||||
obj-$(CONFIG_MACH_IMX51_DT) += imx51-dt.o
|
||||
obj-$(CONFIG_SOC_IMX53) += mach-imx53.o
|
||||
|
||||
obj-$(CONFIG_SOC_VF610) += clk-vf610.o mach-vf610.o
|
||||
|
||||
obj-y += devices/
|
||||
|
@ -73,6 +73,12 @@ static const char *mx53_cko2_sel[] = {
|
||||
"tve_sel", "lp_apm",
|
||||
"uart_root", "dummy"/* spdif0_clk_root */,
|
||||
"dummy", "dummy", };
|
||||
static const char *mx51_spdif_xtal_sel[] = { "osc", "ckih", "ckih2", };
|
||||
static const char *mx53_spdif_xtal_sel[] = { "osc", "ckih", "ckih2", "pll4_sw", };
|
||||
static const char *spdif_sel[] = { "pll1_sw", "pll2_sw", "pll3_sw", "spdif_xtal_sel", };
|
||||
static const char *spdif0_com_sel[] = { "spdif0_podf", "ssi1_root_gate", };
|
||||
static const char *mx51_spdif1_com_sel[] = { "spdif1_podf", "ssi2_root_gate", };
|
||||
|
||||
|
||||
enum imx5_clks {
|
||||
dummy, ckil, osc, ckih1, ckih2, ahb, ipg, axi_a, axi_b, uart_pred,
|
||||
@ -110,7 +116,9 @@ enum imx5_clks {
|
||||
owire_gate, gpu3d_s, gpu2d_s, gpu3d_gate, gpu2d_gate, garb_gate,
|
||||
cko1_sel, cko1_podf, cko1,
|
||||
cko2_sel, cko2_podf, cko2,
|
||||
srtc_gate, pata_gate,
|
||||
srtc_gate, pata_gate, sata_gate, spdif_xtal_sel, spdif0_sel,
|
||||
spdif1_sel, spdif0_pred, spdif0_podf, spdif1_pred, spdif1_podf,
|
||||
spdif0_com_s, spdif1_com_sel, spdif0_gate, spdif1_gate, spdif_ipg_gate,
|
||||
clk_max
|
||||
};
|
||||
|
||||
@ -123,11 +131,13 @@ static void __init mx5_clocks_common_init(unsigned long rate_ckil,
|
||||
{
|
||||
int i;
|
||||
|
||||
of_clk_init(NULL);
|
||||
|
||||
clk[dummy] = imx_clk_fixed("dummy", 0);
|
||||
clk[ckil] = imx_clk_fixed("ckil", rate_ckil);
|
||||
clk[osc] = imx_clk_fixed("osc", rate_osc);
|
||||
clk[ckih1] = imx_clk_fixed("ckih1", rate_ckih1);
|
||||
clk[ckih2] = imx_clk_fixed("ckih2", rate_ckih2);
|
||||
clk[ckil] = imx_obtain_fixed_clock("ckil", rate_ckil);
|
||||
clk[osc] = imx_obtain_fixed_clock("osc", rate_osc);
|
||||
clk[ckih1] = imx_obtain_fixed_clock("ckih1", rate_ckih1);
|
||||
clk[ckih2] = imx_obtain_fixed_clock("ckih2", rate_ckih2);
|
||||
|
||||
clk[lp_apm] = imx_clk_mux("lp_apm", MXC_CCM_CCSR, 9, 1,
|
||||
lp_apm_sel, ARRAY_SIZE(lp_apm_sel));
|
||||
@ -267,6 +277,13 @@ static void __init mx5_clocks_common_init(unsigned long rate_ckil,
|
||||
clk[owire_gate] = imx_clk_gate2("owire_gate", "per_root", MXC_CCM_CCGR2, 22);
|
||||
clk[srtc_gate] = imx_clk_gate2("srtc_gate", "per_root", MXC_CCM_CCGR4, 28);
|
||||
clk[pata_gate] = imx_clk_gate2("pata_gate", "ipg", MXC_CCM_CCGR4, 0);
|
||||
clk[spdif0_sel] = imx_clk_mux("spdif0_sel", MXC_CCM_CSCMR2, 0, 2, spdif_sel, ARRAY_SIZE(spdif_sel));
|
||||
clk[spdif0_pred] = imx_clk_divider("spdif0_pred", "spdif0_sel", MXC_CCM_CDCDR, 25, 3);
|
||||
clk[spdif0_podf] = imx_clk_divider("spdif0_podf", "spdif0_pred", MXC_CCM_CDCDR, 19, 6);
|
||||
clk[spdif0_com_s] = imx_clk_mux_flags("spdif0_com_sel", MXC_CCM_CSCMR2, 4, 1,
|
||||
spdif0_com_sel, ARRAY_SIZE(spdif0_com_sel), CLK_SET_RATE_PARENT);
|
||||
clk[spdif0_gate] = imx_clk_gate2("spdif0_gate", "spdif0_com_sel", MXC_CCM_CCGR5, 26);
|
||||
clk[spdif_ipg_gate] = imx_clk_gate2("spdif_ipg_gate", "ipg", MXC_CCM_CCGR5, 30);
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(clk); i++)
|
||||
if (IS_ERR(clk[i]))
|
||||
@ -378,6 +395,15 @@ int __init mx51_clocks_init(unsigned long rate_ckil, unsigned long rate_osc,
|
||||
clk[mipi_hsc2_gate] = imx_clk_gate2("mipi_hsc2_gate", "ipg", MXC_CCM_CCGR4, 8);
|
||||
clk[mipi_esc_gate] = imx_clk_gate2("mipi_esc_gate", "ipg", MXC_CCM_CCGR4, 10);
|
||||
clk[mipi_hsp_gate] = imx_clk_gate2("mipi_hsp_gate", "ipg", MXC_CCM_CCGR4, 12);
|
||||
clk[spdif_xtal_sel] = imx_clk_mux("spdif_xtal_sel", MXC_CCM_CSCMR1, 2, 2,
|
||||
mx51_spdif_xtal_sel, ARRAY_SIZE(mx51_spdif_xtal_sel));
|
||||
clk[spdif1_sel] = imx_clk_mux("spdif1_sel", MXC_CCM_CSCMR2, 2, 2,
|
||||
spdif_sel, ARRAY_SIZE(spdif_sel));
|
||||
clk[spdif1_pred] = imx_clk_divider("spdif1_podf", "spdif1_sel", MXC_CCM_CDCDR, 16, 3);
|
||||
clk[spdif1_podf] = imx_clk_divider("spdif1_podf", "spdif1_pred", MXC_CCM_CDCDR, 9, 6);
|
||||
clk[spdif1_com_sel] = imx_clk_mux("spdif1_com_sel", MXC_CCM_CSCMR2, 5, 1,
|
||||
mx51_spdif1_com_sel, ARRAY_SIZE(mx51_spdif1_com_sel));
|
||||
clk[spdif1_gate] = imx_clk_gate2("spdif1_gate", "spdif1_com_sel", MXC_CCM_CCGR5, 28);
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(clk); i++)
|
||||
if (IS_ERR(clk[i]))
|
||||
@ -485,6 +511,7 @@ int __init mx53_clocks_init(unsigned long rate_ckil, unsigned long rate_osc,
|
||||
clk[can2_serial_gate] = imx_clk_gate2("can2_serial_gate", "can_sel", MXC_CCM_CCGR4, 8);
|
||||
clk[can2_ipg_gate] = imx_clk_gate2("can2_ipg_gate", "ipg", MXC_CCM_CCGR4, 6);
|
||||
clk[i2c3_gate] = imx_clk_gate2("i2c3_gate", "per_root", MXC_CCM_CCGR1, 22);
|
||||
clk[sata_gate] = imx_clk_gate2("sata_gate", "ipg", MXC_CCM_CCGR4, 2);
|
||||
|
||||
clk[cko1_sel] = imx_clk_mux("cko1_sel", MXC_CCM_CCOSR, 0, 4,
|
||||
mx53_cko1_sel, ARRAY_SIZE(mx53_cko1_sel));
|
||||
@ -495,6 +522,8 @@ int __init mx53_clocks_init(unsigned long rate_ckil, unsigned long rate_osc,
|
||||
mx53_cko2_sel, ARRAY_SIZE(mx53_cko2_sel));
|
||||
clk[cko2_podf] = imx_clk_divider("cko2_podf", "cko2_sel", MXC_CCM_CCOSR, 21, 3);
|
||||
clk[cko2] = imx_clk_gate2("cko2", "cko2_podf", MXC_CCM_CCOSR, 24);
|
||||
clk[spdif_xtal_sel] = imx_clk_mux("spdif_xtal_sel", MXC_CCM_CSCMR1, 2, 2,
|
||||
mx53_spdif_xtal_sel, ARRAY_SIZE(mx53_spdif_xtal_sel));
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(clk); i++)
|
||||
if (IS_ERR(clk[i]))
|
||||
@ -542,42 +571,12 @@ int __init mx53_clocks_init(unsigned long rate_ckil, unsigned long rate_osc,
|
||||
return 0;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_OF
|
||||
static void __init clk_get_freq_dt(unsigned long *ckil, unsigned long *osc,
|
||||
unsigned long *ckih1, unsigned long *ckih2)
|
||||
{
|
||||
struct device_node *np;
|
||||
|
||||
/* retrieve the freqency of fixed clocks from device tree */
|
||||
for_each_compatible_node(np, NULL, "fixed-clock") {
|
||||
u32 rate;
|
||||
if (of_property_read_u32(np, "clock-frequency", &rate))
|
||||
continue;
|
||||
|
||||
if (of_device_is_compatible(np, "fsl,imx-ckil"))
|
||||
*ckil = rate;
|
||||
else if (of_device_is_compatible(np, "fsl,imx-osc"))
|
||||
*osc = rate;
|
||||
else if (of_device_is_compatible(np, "fsl,imx-ckih1"))
|
||||
*ckih1 = rate;
|
||||
else if (of_device_is_compatible(np, "fsl,imx-ckih2"))
|
||||
*ckih2 = rate;
|
||||
}
|
||||
}
|
||||
|
||||
int __init mx51_clocks_init_dt(void)
|
||||
{
|
||||
unsigned long ckil, osc, ckih1, ckih2;
|
||||
|
||||
clk_get_freq_dt(&ckil, &osc, &ckih1, &ckih2);
|
||||
return mx51_clocks_init(ckil, osc, ckih1, ckih2);
|
||||
return mx51_clocks_init(0, 0, 0, 0);
|
||||
}
|
||||
|
||||
int __init mx53_clocks_init_dt(void)
|
||||
{
|
||||
unsigned long ckil, osc, ckih1, ckih2;
|
||||
|
||||
clk_get_freq_dt(&ckil, &osc, &ckih1, &ckih2);
|
||||
return mx53_clocks_init(ckil, osc, ckih1, ckih2);
|
||||
return mx53_clocks_init(0, 0, 0, 0);
|
||||
}
|
||||
#endif
|
||||
|
@ -238,7 +238,7 @@ enum mx6q_clks {
|
||||
pll4_audio, pll5_video, pll8_mlb, pll7_usb_host, pll6_enet, ssi1_ipg,
|
||||
ssi2_ipg, ssi3_ipg, rom, usbphy1, usbphy2, ldb_di0_div_3_5, ldb_di1_div_3_5,
|
||||
sata_ref, sata_ref_100m, pcie_ref, pcie_ref_125m, enet_ref, usbphy1_gate,
|
||||
usbphy2_gate, pll4_post_div, pll5_post_div, pll5_video_div, clk_max
|
||||
usbphy2_gate, pll4_post_div, pll5_post_div, pll5_video_div, eim_slow, clk_max
|
||||
};
|
||||
|
||||
static struct clk *clk[clk_max];
|
||||
@ -270,27 +270,16 @@ static struct clk_div_table video_div_table[] = {
|
||||
{ }
|
||||
};
|
||||
|
||||
int __init mx6q_clocks_init(void)
|
||||
static void __init imx6q_clocks_init(struct device_node *ccm_node)
|
||||
{
|
||||
struct device_node *np;
|
||||
void __iomem *base;
|
||||
int i, irq;
|
||||
|
||||
clk[dummy] = imx_clk_fixed("dummy", 0);
|
||||
|
||||
/* retrieve the freqency of fixed clocks from device tree */
|
||||
for_each_compatible_node(np, NULL, "fixed-clock") {
|
||||
u32 rate;
|
||||
if (of_property_read_u32(np, "clock-frequency", &rate))
|
||||
continue;
|
||||
|
||||
if (of_device_is_compatible(np, "fsl,imx-ckil"))
|
||||
clk[ckil] = imx_clk_fixed("ckil", rate);
|
||||
else if (of_device_is_compatible(np, "fsl,imx-ckih1"))
|
||||
clk[ckih] = imx_clk_fixed("ckih", rate);
|
||||
else if (of_device_is_compatible(np, "fsl,imx-osc"))
|
||||
clk[osc] = imx_clk_fixed("osc", rate);
|
||||
}
|
||||
clk[ckil] = imx_obtain_fixed_clock("ckil", 0);
|
||||
clk[ckih] = imx_obtain_fixed_clock("ckih1", 0);
|
||||
clk[osc] = imx_obtain_fixed_clock("osc", 0);
|
||||
|
||||
np = of_find_compatible_node(NULL, NULL, "fsl,imx6q-anatop");
|
||||
base = of_iomap(np, 0);
|
||||
@ -312,7 +301,6 @@ int __init mx6q_clocks_init(void)
|
||||
clk[pll5_video] = imx_clk_pllv3(IMX_PLLV3_AV, "pll5_video", "osc", base + 0xa0, 0x7f);
|
||||
clk[pll6_enet] = imx_clk_pllv3(IMX_PLLV3_ENET, "pll6_enet", "osc", base + 0xe0, 0x3);
|
||||
clk[pll7_usb_host] = imx_clk_pllv3(IMX_PLLV3_USB, "pll7_usb_host","osc", base + 0x20, 0x3);
|
||||
clk[pll8_mlb] = imx_clk_pllv3(IMX_PLLV3_MLB, "pll8_mlb", "osc", base + 0xd0, 0x0);
|
||||
|
||||
/*
|
||||
* Bit 20 is the reserved and read-only bit, we do this only for:
|
||||
@ -360,7 +348,7 @@ int __init mx6q_clocks_init(void)
|
||||
clk[pll5_post_div] = clk_register_divider_table(NULL, "pll5_post_div", "pll5_video", CLK_SET_RATE_PARENT, base + 0xa0, 19, 2, 0, post_div_table, &imx_ccm_lock);
|
||||
clk[pll5_video_div] = clk_register_divider_table(NULL, "pll5_video_div", "pll5_post_div", CLK_SET_RATE_PARENT, base + 0x170, 30, 2, 0, video_div_table, &imx_ccm_lock);
|
||||
|
||||
np = of_find_compatible_node(NULL, NULL, "fsl,imx6q-ccm");
|
||||
np = ccm_node;
|
||||
base = of_iomap(np, 0);
|
||||
WARN_ON(!base);
|
||||
ccm_base = base;
|
||||
@ -481,7 +469,14 @@ int __init mx6q_clocks_init(void)
|
||||
clk[esai] = imx_clk_gate2("esai", "esai_podf", base + 0x6c, 16);
|
||||
clk[gpt_ipg] = imx_clk_gate2("gpt_ipg", "ipg", base + 0x6c, 20);
|
||||
clk[gpt_ipg_per] = imx_clk_gate2("gpt_ipg_per", "ipg_per", base + 0x6c, 22);
|
||||
clk[gpu2d_core] = imx_clk_gate2("gpu2d_core", "gpu2d_core_podf", base + 0x6c, 24);
|
||||
if (cpu_is_imx6dl())
|
||||
/*
|
||||
* The multiplexer and divider of imx6q clock gpu3d_shader get
|
||||
* redefined/reused as gpu2d_core_sel and gpu2d_core_podf on imx6dl.
|
||||
*/
|
||||
clk[gpu2d_core] = imx_clk_gate2("gpu2d_core", "gpu3d_shader", base + 0x6c, 24);
|
||||
else
|
||||
clk[gpu2d_core] = imx_clk_gate2("gpu2d_core", "gpu2d_core_podf", base + 0x6c, 24);
|
||||
clk[gpu3d_core] = imx_clk_gate2("gpu3d_core", "gpu3d_core_podf", base + 0x6c, 26);
|
||||
clk[hdmi_iahb] = imx_clk_gate2("hdmi_iahb", "ahb", base + 0x70, 0);
|
||||
clk[hdmi_isfr] = imx_clk_gate2("hdmi_isfr", "pll3_pfd1_540m", base + 0x70, 4);
|
||||
@ -499,7 +494,14 @@ int __init mx6q_clocks_init(void)
|
||||
clk[ldb_di1] = imx_clk_gate2("ldb_di1", "ldb_di1_podf", base + 0x74, 14);
|
||||
clk[ipu2_di1] = imx_clk_gate2("ipu2_di1", "ipu2_di1_sel", base + 0x74, 10);
|
||||
clk[hsi_tx] = imx_clk_gate2("hsi_tx", "hsi_tx_podf", base + 0x74, 16);
|
||||
clk[mlb] = imx_clk_gate2("mlb", "axi", base + 0x74, 18);
|
||||
if (cpu_is_imx6dl())
|
||||
/*
|
||||
* The multiplexer and divider of the imx6q clock gpu2d get
|
||||
* redefined/reused as mlb_sys_sel and mlb_sys_clk_podf on imx6dl.
|
||||
*/
|
||||
clk[mlb] = imx_clk_gate2("mlb", "gpu2d_core_podf", base + 0x74, 18);
|
||||
else
|
||||
clk[mlb] = imx_clk_gate2("mlb", "axi", base + 0x74, 18);
|
||||
clk[mmdc_ch0_axi] = imx_clk_gate2("mmdc_ch0_axi", "mmdc_ch0_axi_podf", base + 0x74, 20);
|
||||
clk[mmdc_ch1_axi] = imx_clk_gate2("mmdc_ch1_axi", "mmdc_ch1_axi_podf", base + 0x74, 22);
|
||||
clk[ocram] = imx_clk_gate2("ocram", "ahb", base + 0x74, 28);
|
||||
@ -528,6 +530,7 @@ int __init mx6q_clocks_init(void)
|
||||
clk[usdhc2] = imx_clk_gate2("usdhc2", "usdhc2_podf", base + 0x80, 4);
|
||||
clk[usdhc3] = imx_clk_gate2("usdhc3", "usdhc3_podf", base + 0x80, 6);
|
||||
clk[usdhc4] = imx_clk_gate2("usdhc4", "usdhc4_podf", base + 0x80, 8);
|
||||
clk[eim_slow] = imx_clk_gate2("eim_slow", "emi_slow_podf", base + 0x80, 10);
|
||||
clk[vdo_axi] = imx_clk_gate2("vdo_axi", "vdo_axi_sel", base + 0x80, 12);
|
||||
clk[vpu_axi] = imx_clk_gate2("vpu_axi", "vpu_axi_podf", base + 0x80, 14);
|
||||
clk[cko1] = imx_clk_gate("cko1", "cko1_podf", base + 0x60, 7);
|
||||
@ -547,6 +550,8 @@ int __init mx6q_clocks_init(void)
|
||||
clk_register_clkdev(clk[ahb], "ahb", NULL);
|
||||
clk_register_clkdev(clk[cko1], "cko1", NULL);
|
||||
clk_register_clkdev(clk[arm], NULL, "cpu0");
|
||||
clk_register_clkdev(clk[pll4_post_div], "pll4_post_div", NULL);
|
||||
clk_register_clkdev(clk[pll4_audio], "pll4_audio", NULL);
|
||||
|
||||
if (imx6q_revision() != IMX_CHIP_REVISION_1_0) {
|
||||
clk_set_parent(clk[ldb_di0_sel], clk[pll5_video_div]);
|
||||
@ -576,6 +581,5 @@ int __init mx6q_clocks_init(void)
|
||||
WARN_ON(!base);
|
||||
irq = irq_of_parse_and_map(np, 0);
|
||||
mxc_timer_init(base, irq);
|
||||
|
||||
return 0;
|
||||
}
|
||||
CLK_OF_DECLARE(imx6q, "fsl,imx6q-ccm", imx6q_clocks_init);
|
||||
|
267
arch/arm/mach-imx/clk-imx6sl.c
Normal file
267
arch/arm/mach-imx/clk-imx6sl.c
Normal file
@ -0,0 +1,267 @@
|
||||
/*
|
||||
* Copyright 2013 Freescale Semiconductor, Inc.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
*/
|
||||
|
||||
#include <linux/clk.h>
|
||||
#include <linux/clkdev.h>
|
||||
#include <linux/err.h>
|
||||
#include <linux/of.h>
|
||||
#include <linux/of_address.h>
|
||||
#include <linux/of_irq.h>
|
||||
#include <dt-bindings/clock/imx6sl-clock.h>
|
||||
|
||||
#include "clk.h"
|
||||
#include "common.h"
|
||||
|
||||
static const char const *step_sels[] = { "osc", "pll2_pfd2", };
|
||||
static const char const *pll1_sw_sels[] = { "pll1_sys", "step", };
|
||||
static const char const *ocram_alt_sels[] = { "pll2_pfd2", "pll3_pfd1", };
|
||||
static const char const *ocram_sels[] = { "periph", "ocram_alt_sels", };
|
||||
static const char const *pre_periph_sels[] = { "pll2_bus", "pll2_pfd2", "pll2_pfd0", "pll2_198m", };
|
||||
static const char const *periph_clk2_sels[] = { "pll3_usb_otg", "osc", "osc", "dummy", };
|
||||
static const char const *periph2_clk2_sels[] = { "pll3_usb_otg", "pll2_bus", };
|
||||
static const char const *periph_sels[] = { "pre_periph_sel", "periph_clk2_podf", };
|
||||
static const char const *periph2_sels[] = { "pre_periph2_sel", "periph2_clk2_podf", };
|
||||
static const char const *csi_lcdif_sels[] = { "mmdc", "pll2_pfd2", "pll3_120m", "pll3_pfd1", };
|
||||
static const char const *usdhc_sels[] = { "pll2_pfd2", "pll2_pfd0", };
|
||||
static const char const *ssi_sels[] = { "pll3_pfd2", "pll3_pfd3", "pll4_post_div", "dummy", };
|
||||
static const char const *perclk_sels[] = { "ipg", "osc", };
|
||||
static const char const *epdc_pxp_sels[] = { "mmdc", "pll3_usb_otg", "pll5_video_div", "pll2_pfd0", "pll2_pfd2", "pll3_pfd1", };
|
||||
static const char const *gpu2d_ovg_sels[] = { "pll3_pfd1", "pll3_usb_otg", "pll2_bus", "pll2_pfd2", };
|
||||
static const char const *gpu2d_sels[] = { "pll2_pfd2", "pll3_usb_otg", "pll3_pfd1", "pll2_bus", };
|
||||
static const char const *lcdif_pix_sels[] = { "pll2_bus", "pll3_usb_otg", "pll5_video_div", "pll2_pfd0", "pll3_pfd0", "pll3_pfd1", };
|
||||
static const char const *epdc_pix_sels[] = { "pll2_bus", "pll3_usb_otg", "pll5_video_div", "pll2_pfd0", "pll2_pfd1", "pll3_pfd1", };
|
||||
static const char const *audio_sels[] = { "pll4_post_div", "pll3_pfd2", "pll3_pfd3", "pll3_usb_otg", };
|
||||
static const char const *ecspi_sels[] = { "pll3_60m", "osc", };
|
||||
static const char const *uart_sels[] = { "pll3_80m", "osc", };
|
||||
|
||||
static struct clk_div_table clk_enet_ref_table[] = {
|
||||
{ .val = 0, .div = 20, },
|
||||
{ .val = 1, .div = 10, },
|
||||
{ .val = 2, .div = 5, },
|
||||
{ .val = 3, .div = 4, },
|
||||
{ }
|
||||
};
|
||||
|
||||
static struct clk_div_table post_div_table[] = {
|
||||
{ .val = 2, .div = 1, },
|
||||
{ .val = 1, .div = 2, },
|
||||
{ .val = 0, .div = 4, },
|
||||
{ }
|
||||
};
|
||||
|
||||
static struct clk_div_table video_div_table[] = {
|
||||
{ .val = 0, .div = 1, },
|
||||
{ .val = 1, .div = 2, },
|
||||
{ .val = 2, .div = 1, },
|
||||
{ .val = 3, .div = 4, },
|
||||
{ }
|
||||
};
|
||||
|
||||
static struct clk *clks[IMX6SL_CLK_CLK_END];
|
||||
static struct clk_onecell_data clk_data;
|
||||
|
||||
static void __init imx6sl_clocks_init(struct device_node *ccm_node)
|
||||
{
|
||||
struct device_node *np;
|
||||
void __iomem *base;
|
||||
int irq;
|
||||
int i;
|
||||
|
||||
clks[IMX6SL_CLK_DUMMY] = imx_clk_fixed("dummy", 0);
|
||||
clks[IMX6SL_CLK_CKIL] = imx_obtain_fixed_clock("ckil", 0);
|
||||
clks[IMX6SL_CLK_OSC] = imx_obtain_fixed_clock("osc", 0);
|
||||
|
||||
np = of_find_compatible_node(NULL, NULL, "fsl,imx6sl-anatop");
|
||||
base = of_iomap(np, 0);
|
||||
WARN_ON(!base);
|
||||
|
||||
/* type name parent base div_mask */
|
||||
clks[IMX6SL_CLK_PLL1_SYS] = imx_clk_pllv3(IMX_PLLV3_SYS, "pll1_sys", "osc", base, 0x7f);
|
||||
clks[IMX6SL_CLK_PLL2_BUS] = imx_clk_pllv3(IMX_PLLV3_GENERIC, "pll2_bus", "osc", base + 0x30, 0x1);
|
||||
clks[IMX6SL_CLK_PLL3_USB_OTG] = imx_clk_pllv3(IMX_PLLV3_USB, "pll3_usb_otg", "osc", base + 0x10, 0x3);
|
||||
clks[IMX6SL_CLK_PLL4_AUDIO] = imx_clk_pllv3(IMX_PLLV3_AV, "pll4_audio", "osc", base + 0x70, 0x7f);
|
||||
clks[IMX6SL_CLK_PLL5_VIDEO] = imx_clk_pllv3(IMX_PLLV3_AV, "pll5_video", "osc", base + 0xa0, 0x7f);
|
||||
clks[IMX6SL_CLK_PLL6_ENET] = imx_clk_pllv3(IMX_PLLV3_ENET, "pll6_enet", "osc", base + 0xe0, 0x3);
|
||||
clks[IMX6SL_CLK_PLL7_USB_HOST] = imx_clk_pllv3(IMX_PLLV3_USB, "pll7_usb_host", "osc", base + 0x20, 0x3);
|
||||
|
||||
/*
|
||||
* usbphy1 and usbphy2 are implemented as dummy gates using reserve
|
||||
* bit 20. They are used by phy driver to keep the refcount of
|
||||
* parent PLL correct. usbphy1_gate and usbphy2_gate only needs to be
|
||||
* turned on during boot, and software will not need to control it
|
||||
* anymore after that.
|
||||
*/
|
||||
clks[IMX6SL_CLK_USBPHY1] = imx_clk_gate("usbphy1", "pll3_usb_otg", base + 0x10, 20);
|
||||
clks[IMX6SL_CLK_USBPHY2] = imx_clk_gate("usbphy2", "pll7_usb_host", base + 0x20, 20);
|
||||
clks[IMX6SL_CLK_USBPHY1_GATE] = imx_clk_gate("usbphy1_gate", "dummy", base + 0x10, 6);
|
||||
clks[IMX6SL_CLK_USBPHY2_GATE] = imx_clk_gate("usbphy2_gate", "dummy", base + 0x20, 6);
|
||||
|
||||
/* dev name parent_name flags reg shift width div: flags, div_table lock */
|
||||
clks[IMX6SL_CLK_PLL4_POST_DIV] = clk_register_divider_table(NULL, "pll4_post_div", "pll4_audio", CLK_SET_RATE_PARENT, base + 0x70, 19, 2, 0, post_div_table, &imx_ccm_lock);
|
||||
clks[IMX6SL_CLK_PLL5_POST_DIV] = clk_register_divider_table(NULL, "pll5_post_div", "pll5_video", CLK_SET_RATE_PARENT, base + 0xa0, 19, 2, 0, post_div_table, &imx_ccm_lock);
|
||||
clks[IMX6SL_CLK_PLL5_VIDEO_DIV] = clk_register_divider_table(NULL, "pll5_video_div", "pll5_post_div", CLK_SET_RATE_PARENT, base + 0x170, 30, 2, 0, video_div_table, &imx_ccm_lock);
|
||||
clks[IMX6SL_CLK_ENET_REF] = clk_register_divider_table(NULL, "enet_ref", "pll6_enet", 0, base + 0xe0, 0, 2, 0, clk_enet_ref_table, &imx_ccm_lock);
|
||||
|
||||
/* name parent_name reg idx */
|
||||
clks[IMX6SL_CLK_PLL2_PFD0] = imx_clk_pfd("pll2_pfd0", "pll2_bus", base + 0x100, 0);
|
||||
clks[IMX6SL_CLK_PLL2_PFD1] = imx_clk_pfd("pll2_pfd1", "pll2_bus", base + 0x100, 1);
|
||||
clks[IMX6SL_CLK_PLL2_PFD2] = imx_clk_pfd("pll2_pfd2", "pll2_bus", base + 0x100, 2);
|
||||
clks[IMX6SL_CLK_PLL3_PFD0] = imx_clk_pfd("pll3_pfd0", "pll3_usb_otg", base + 0xf0, 0);
|
||||
clks[IMX6SL_CLK_PLL3_PFD1] = imx_clk_pfd("pll3_pfd1", "pll3_usb_otg", base + 0xf0, 1);
|
||||
clks[IMX6SL_CLK_PLL3_PFD2] = imx_clk_pfd("pll3_pfd2", "pll3_usb_otg", base + 0xf0, 2);
|
||||
clks[IMX6SL_CLK_PLL3_PFD3] = imx_clk_pfd("pll3_pfd3", "pll3_usb_otg", base + 0xf0, 3);
|
||||
|
||||
/* name parent_name mult div */
|
||||
clks[IMX6SL_CLK_PLL2_198M] = imx_clk_fixed_factor("pll2_198m", "pll2_pfd2", 1, 2);
|
||||
clks[IMX6SL_CLK_PLL3_120M] = imx_clk_fixed_factor("pll3_120m", "pll3_usb_otg", 1, 4);
|
||||
clks[IMX6SL_CLK_PLL3_80M] = imx_clk_fixed_factor("pll3_80m", "pll3_usb_otg", 1, 6);
|
||||
clks[IMX6SL_CLK_PLL3_60M] = imx_clk_fixed_factor("pll3_60m", "pll3_usb_otg", 1, 8);
|
||||
|
||||
np = ccm_node;
|
||||
base = of_iomap(np, 0);
|
||||
WARN_ON(!base);
|
||||
|
||||
/* name reg shift width parent_names num_parents */
|
||||
clks[IMX6SL_CLK_STEP] = imx_clk_mux("step", base + 0xc, 8, 1, step_sels, ARRAY_SIZE(step_sels));
|
||||
clks[IMX6SL_CLK_PLL1_SW] = imx_clk_mux("pll1_sw", base + 0xc, 2, 1, pll1_sw_sels, ARRAY_SIZE(pll1_sw_sels));
|
||||
clks[IMX6SL_CLK_OCRAM_ALT_SEL] = imx_clk_mux("ocram_alt_sel", base + 0x14, 7, 1, ocram_alt_sels, ARRAY_SIZE(ocram_alt_sels));
|
||||
clks[IMX6SL_CLK_OCRAM_SEL] = imx_clk_mux("ocram_sel", base + 0x14, 6, 1, ocram_sels, ARRAY_SIZE(ocram_sels));
|
||||
clks[IMX6SL_CLK_PRE_PERIPH2_SEL] = imx_clk_mux("pre_periph2_sel", base + 0x18, 21, 2, pre_periph_sels, ARRAY_SIZE(pre_periph_sels));
|
||||
clks[IMX6SL_CLK_PRE_PERIPH_SEL] = imx_clk_mux("pre_periph_sel", base + 0x18, 18, 2, pre_periph_sels, ARRAY_SIZE(pre_periph_sels));
|
||||
clks[IMX6SL_CLK_PERIPH2_CLK2_SEL] = imx_clk_mux("periph2_clk2_sel", base + 0x18, 20, 1, periph2_clk2_sels, ARRAY_SIZE(periph2_clk2_sels));
|
||||
clks[IMX6SL_CLK_PERIPH_CLK2_SEL] = imx_clk_mux("periph_clk2_sel", base + 0x18, 12, 2, periph_clk2_sels, ARRAY_SIZE(periph_clk2_sels));
|
||||
clks[IMX6SL_CLK_CSI_SEL] = imx_clk_mux("csi_sel", base + 0x3c, 9, 2, csi_lcdif_sels, ARRAY_SIZE(csi_lcdif_sels));
|
||||
clks[IMX6SL_CLK_LCDIF_AXI_SEL] = imx_clk_mux("lcdif_axi_sel", base + 0x3c, 14, 2, csi_lcdif_sels, ARRAY_SIZE(csi_lcdif_sels));
|
||||
clks[IMX6SL_CLK_USDHC1_SEL] = imx_clk_mux("usdhc1_sel", base + 0x1c, 16, 1, usdhc_sels, ARRAY_SIZE(usdhc_sels));
|
||||
clks[IMX6SL_CLK_USDHC2_SEL] = imx_clk_mux("usdhc2_sel", base + 0x1c, 17, 1, usdhc_sels, ARRAY_SIZE(usdhc_sels));
|
||||
clks[IMX6SL_CLK_USDHC3_SEL] = imx_clk_mux("usdhc3_sel", base + 0x1c, 18, 1, usdhc_sels, ARRAY_SIZE(usdhc_sels));
|
||||
clks[IMX6SL_CLK_USDHC4_SEL] = imx_clk_mux("usdhc4_sel", base + 0x1c, 19, 1, usdhc_sels, ARRAY_SIZE(usdhc_sels));
|
||||
clks[IMX6SL_CLK_SSI1_SEL] = imx_clk_mux("ssi1_sel", base + 0x1c, 10, 2, ssi_sels, ARRAY_SIZE(ssi_sels));
|
||||
clks[IMX6SL_CLK_SSI2_SEL] = imx_clk_mux("ssi2_sel", base + 0x1c, 12, 2, ssi_sels, ARRAY_SIZE(ssi_sels));
|
||||
clks[IMX6SL_CLK_SSI3_SEL] = imx_clk_mux("ssi3_sel", base + 0x1c, 14, 2, ssi_sels, ARRAY_SIZE(ssi_sels));
|
||||
clks[IMX6SL_CLK_PERCLK_SEL] = imx_clk_mux("perclk_sel", base + 0x1c, 6, 1, perclk_sels, ARRAY_SIZE(perclk_sels));
|
||||
clks[IMX6SL_CLK_PXP_AXI_SEL] = imx_clk_mux("pxp_axi_sel", base + 0x34, 6, 3, epdc_pxp_sels, ARRAY_SIZE(epdc_pxp_sels));
|
||||
clks[IMX6SL_CLK_EPDC_AXI_SEL] = imx_clk_mux("epdc_axi_sel", base + 0x34, 15, 3, epdc_pxp_sels, ARRAY_SIZE(epdc_pxp_sels));
|
||||
clks[IMX6SL_CLK_GPU2D_OVG_SEL] = imx_clk_mux("gpu2d_ovg_sel", base + 0x18, 4, 2, gpu2d_ovg_sels, ARRAY_SIZE(gpu2d_ovg_sels));
|
||||
clks[IMX6SL_CLK_GPU2D_SEL] = imx_clk_mux("gpu2d_sel", base + 0x18, 8, 2, gpu2d_sels, ARRAY_SIZE(gpu2d_sels));
|
||||
clks[IMX6SL_CLK_LCDIF_PIX_SEL] = imx_clk_mux("lcdif_pix_sel", base + 0x38, 6, 3, lcdif_pix_sels, ARRAY_SIZE(lcdif_pix_sels));
|
||||
clks[IMX6SL_CLK_EPDC_PIX_SEL] = imx_clk_mux("epdc_pix_sel", base + 0x38, 15, 3, epdc_pix_sels, ARRAY_SIZE(epdc_pix_sels));
|
||||
clks[IMX6SL_CLK_SPDIF0_SEL] = imx_clk_mux("spdif0_sel", base + 0x30, 20, 2, audio_sels, ARRAY_SIZE(audio_sels));
|
||||
clks[IMX6SL_CLK_SPDIF1_SEL] = imx_clk_mux("spdif1_sel", base + 0x30, 7, 2, audio_sels, ARRAY_SIZE(audio_sels));
|
||||
clks[IMX6SL_CLK_EXTERN_AUDIO_SEL] = imx_clk_mux("extern_audio_sel", base + 0x20, 19, 2, audio_sels, ARRAY_SIZE(audio_sels));
|
||||
clks[IMX6SL_CLK_ECSPI_SEL] = imx_clk_mux("ecspi_sel", base + 0x38, 18, 1, ecspi_sels, ARRAY_SIZE(ecspi_sels));
|
||||
clks[IMX6SL_CLK_UART_SEL] = imx_clk_mux("uart_sel", base + 0x24, 6, 1, uart_sels, ARRAY_SIZE(uart_sels));
|
||||
|
||||
/* name reg shift width busy: reg, shift parent_names num_parents */
|
||||
clks[IMX6SL_CLK_PERIPH] = imx_clk_busy_mux("periph", base + 0x14, 25, 1, base + 0x48, 5, periph_sels, ARRAY_SIZE(periph_sels));
|
||||
clks[IMX6SL_CLK_PERIPH2] = imx_clk_busy_mux("periph2", base + 0x14, 26, 1, base + 0x48, 3, periph2_sels, ARRAY_SIZE(periph2_sels));
|
||||
|
||||
/* name parent_name reg shift width */
|
||||
clks[IMX6SL_CLK_OCRAM_PODF] = imx_clk_divider("ocram_podf", "ocram_sel", base + 0x14, 16, 3);
|
||||
clks[IMX6SL_CLK_PERIPH_CLK2_PODF] = imx_clk_divider("periph_clk2_podf", "periph_clk2_sel", base + 0x14, 27, 3);
|
||||
clks[IMX6SL_CLK_PERIPH2_CLK2_PODF] = imx_clk_divider("periph2_clk2_podf", "periph2_clk2_sel", base + 0x14, 0, 3);
|
||||
clks[IMX6SL_CLK_IPG] = imx_clk_divider("ipg", "ahb", base + 0x14, 8, 2);
|
||||
clks[IMX6SL_CLK_CSI_PODF] = imx_clk_divider("csi_podf", "csi_sel", base + 0x3c, 11, 3);
|
||||
clks[IMX6SL_CLK_LCDIF_AXI_PODF] = imx_clk_divider("lcdif_axi_podf", "lcdif_axi_sel", base + 0x3c, 16, 3);
|
||||
clks[IMX6SL_CLK_USDHC1_PODF] = imx_clk_divider("usdhc1_podf", "usdhc1_sel", base + 0x24, 11, 3);
|
||||
clks[IMX6SL_CLK_USDHC2_PODF] = imx_clk_divider("usdhc2_podf", "usdhc2_sel", base + 0x24, 16, 3);
|
||||
clks[IMX6SL_CLK_USDHC3_PODF] = imx_clk_divider("usdhc3_podf", "usdhc3_sel", base + 0x24, 19, 3);
|
||||
clks[IMX6SL_CLK_USDHC4_PODF] = imx_clk_divider("usdhc4_podf", "usdhc4_sel", base + 0x24, 22, 3);
|
||||
clks[IMX6SL_CLK_SSI1_PRED] = imx_clk_divider("ssi1_pred", "ssi1_sel", base + 0x28, 6, 3);
|
||||
clks[IMX6SL_CLK_SSI1_PODF] = imx_clk_divider("ssi1_podf", "ssi1_pred", base + 0x28, 0, 6);
|
||||
clks[IMX6SL_CLK_SSI2_PRED] = imx_clk_divider("ssi2_pred", "ssi2_sel", base + 0x2c, 6, 3);
|
||||
clks[IMX6SL_CLK_SSI2_PODF] = imx_clk_divider("ssi2_podf", "ssi2_pred", base + 0x2c, 0, 6);
|
||||
clks[IMX6SL_CLK_SSI3_PRED] = imx_clk_divider("ssi3_pred", "ssi3_sel", base + 0x28, 22, 3);
|
||||
clks[IMX6SL_CLK_SSI3_PODF] = imx_clk_divider("ssi3_podf", "ssi3_pred", base + 0x28, 16, 6);
|
||||
clks[IMX6SL_CLK_PERCLK] = imx_clk_divider("perclk", "perclk_sel", base + 0x1c, 0, 6);
|
||||
clks[IMX6SL_CLK_PXP_AXI_PODF] = imx_clk_divider("pxp_axi_podf", "pxp_axi_sel", base + 0x34, 3, 3);
|
||||
clks[IMX6SL_CLK_EPDC_AXI_PODF] = imx_clk_divider("epdc_axi_podf", "epdc_axi_sel", base + 0x34, 12, 3);
|
||||
clks[IMX6SL_CLK_GPU2D_OVG_PODF] = imx_clk_divider("gpu2d_ovg_podf", "gpu2d_ovg_sel", base + 0x18, 26, 3);
|
||||
clks[IMX6SL_CLK_GPU2D_PODF] = imx_clk_divider("gpu2d_podf", "gpu2d_sel", base + 0x18, 29, 3);
|
||||
clks[IMX6SL_CLK_LCDIF_PIX_PRED] = imx_clk_divider("lcdif_pix_pred", "lcdif_pix_sel", base + 0x38, 3, 3);
|
||||
clks[IMX6SL_CLK_EPDC_PIX_PRED] = imx_clk_divider("epdc_pix_pred", "epdc_pix_sel", base + 0x38, 12, 3);
|
||||
clks[IMX6SL_CLK_LCDIF_PIX_PODF] = imx_clk_divider("lcdif_pix_podf", "lcdif_pix_pred", base + 0x1c, 20, 3);
|
||||
clks[IMX6SL_CLK_EPDC_PIX_PODF] = imx_clk_divider("epdc_pix_podf", "epdc_pix_pred", base + 0x18, 23, 3);
|
||||
clks[IMX6SL_CLK_SPDIF0_PRED] = imx_clk_divider("spdif0_pred", "spdif0_sel", base + 0x30, 25, 3);
|
||||
clks[IMX6SL_CLK_SPDIF0_PODF] = imx_clk_divider("spdif0_podf", "spdif0_pred", base + 0x30, 22, 3);
|
||||
clks[IMX6SL_CLK_SPDIF1_PRED] = imx_clk_divider("spdif1_pred", "spdif1_sel", base + 0x30, 12, 3);
|
||||
clks[IMX6SL_CLK_SPDIF1_PODF] = imx_clk_divider("spdif1_podf", "spdif1_pred", base + 0x30, 9, 3);
|
||||
clks[IMX6SL_CLK_EXTERN_AUDIO_PRED] = imx_clk_divider("extern_audio_pred", "extern_audio_sel", base + 0x28, 9, 3);
|
||||
clks[IMX6SL_CLK_EXTERN_AUDIO_PODF] = imx_clk_divider("extern_audio_podf", "extern_audio_pred", base + 0x28, 25, 3);
|
||||
clks[IMX6SL_CLK_ECSPI_ROOT] = imx_clk_divider("ecspi_root", "ecspi_sel", base + 0x38, 19, 6);
|
||||
clks[IMX6SL_CLK_UART_ROOT] = imx_clk_divider("uart_root", "uart_sel", base + 0x24, 0, 6);
|
||||
|
||||
/* name parent_name reg shift width busy: reg, shift */
|
||||
clks[IMX6SL_CLK_AHB] = imx_clk_busy_divider("ahb", "periph", base + 0x14, 10, 3, base + 0x48, 1);
|
||||
clks[IMX6SL_CLK_MMDC_ROOT] = imx_clk_busy_divider("mmdc", "periph2", base + 0x14, 3, 3, base + 0x48, 2);
|
||||
clks[IMX6SL_CLK_ARM] = imx_clk_busy_divider("arm", "pll1_sw", base + 0x10, 0, 3, base + 0x48, 16);
|
||||
|
||||
/* name parent_name reg shift */
|
||||
clks[IMX6SL_CLK_ECSPI1] = imx_clk_gate2("ecspi1", "ecspi_root", base + 0x6c, 0);
|
||||
clks[IMX6SL_CLK_ECSPI2] = imx_clk_gate2("ecspi2", "ecspi_root", base + 0x6c, 2);
|
||||
clks[IMX6SL_CLK_ECSPI3] = imx_clk_gate2("ecspi3", "ecspi_root", base + 0x6c, 4);
|
||||
clks[IMX6SL_CLK_ECSPI4] = imx_clk_gate2("ecspi4", "ecspi_root", base + 0x6c, 6);
|
||||
clks[IMX6SL_CLK_EPIT1] = imx_clk_gate2("epit1", "perclk", base + 0x6c, 12);
|
||||
clks[IMX6SL_CLK_EPIT2] = imx_clk_gate2("epit2", "perclk", base + 0x6c, 14);
|
||||
clks[IMX6SL_CLK_EXTERN_AUDIO] = imx_clk_gate2("extern_audio", "extern_audio_podf", base + 0x6c, 16);
|
||||
clks[IMX6SL_CLK_GPT] = imx_clk_gate2("gpt", "perclk", base + 0x6c, 20);
|
||||
clks[IMX6SL_CLK_GPT_SERIAL] = imx_clk_gate2("gpt_serial", "perclk", base + 0x6c, 22);
|
||||
clks[IMX6SL_CLK_GPU2D_OVG] = imx_clk_gate2("gpu2d_ovg", "gpu2d_ovg_podf", base + 0x6c, 26);
|
||||
clks[IMX6SL_CLK_I2C1] = imx_clk_gate2("i2c1", "perclk", base + 0x70, 6);
|
||||
clks[IMX6SL_CLK_I2C2] = imx_clk_gate2("i2c2", "perclk", base + 0x70, 8);
|
||||
clks[IMX6SL_CLK_I2C3] = imx_clk_gate2("i2c3", "perclk", base + 0x70, 10);
|
||||
clks[IMX6SL_CLK_OCOTP] = imx_clk_gate2("ocotp", "ipg", base + 0x70, 12);
|
||||
clks[IMX6SL_CLK_CSI] = imx_clk_gate2("csi", "csi_podf", base + 0x74, 0);
|
||||
clks[IMX6SL_CLK_PXP_AXI] = imx_clk_gate2("pxp_axi", "pxp_axi_podf", base + 0x74, 2);
|
||||
clks[IMX6SL_CLK_EPDC_AXI] = imx_clk_gate2("epdc_axi", "epdc_axi_podf", base + 0x74, 4);
|
||||
clks[IMX6SL_CLK_LCDIF_AXI] = imx_clk_gate2("lcdif_axi", "lcdif_axi_podf", base + 0x74, 6);
|
||||
clks[IMX6SL_CLK_LCDIF_PIX] = imx_clk_gate2("lcdif_pix", "lcdif_pix_podf", base + 0x74, 8);
|
||||
clks[IMX6SL_CLK_EPDC_PIX] = imx_clk_gate2("epdc_pix", "epdc_pix_podf", base + 0x74, 10);
|
||||
clks[IMX6SL_CLK_OCRAM] = imx_clk_gate2("ocram", "ocram_podf", base + 0x74, 28);
|
||||
clks[IMX6SL_CLK_PWM1] = imx_clk_gate2("pwm1", "perclk", base + 0x78, 16);
|
||||
clks[IMX6SL_CLK_PWM2] = imx_clk_gate2("pwm2", "perclk", base + 0x78, 18);
|
||||
clks[IMX6SL_CLK_PWM3] = imx_clk_gate2("pwm3", "perclk", base + 0x78, 20);
|
||||
clks[IMX6SL_CLK_PWM4] = imx_clk_gate2("pwm4", "perclk", base + 0x78, 22);
|
||||
clks[IMX6SL_CLK_SDMA] = imx_clk_gate2("sdma", "ipg", base + 0x7c, 6);
|
||||
clks[IMX6SL_CLK_SPDIF] = imx_clk_gate2("spdif", "spdif0_podf", base + 0x7c, 14);
|
||||
clks[IMX6SL_CLK_SSI1] = imx_clk_gate2("ssi1", "ssi1_podf", base + 0x7c, 18);
|
||||
clks[IMX6SL_CLK_SSI2] = imx_clk_gate2("ssi2", "ssi2_podf", base + 0x7c, 20);
|
||||
clks[IMX6SL_CLK_SSI3] = imx_clk_gate2("ssi3", "ssi3_podf", base + 0x7c, 22);
|
||||
clks[IMX6SL_CLK_UART] = imx_clk_gate2("uart", "ipg", base + 0x7c, 24);
|
||||
clks[IMX6SL_CLK_UART_SERIAL] = imx_clk_gate2("uart_serial", "uart_root", base + 0x7c, 26);
|
||||
clks[IMX6SL_CLK_USBOH3] = imx_clk_gate2("usboh3", "ipg", base + 0x80, 0);
|
||||
clks[IMX6SL_CLK_USDHC1] = imx_clk_gate2("usdhc1", "usdhc1_podf", base + 0x80, 2);
|
||||
clks[IMX6SL_CLK_USDHC2] = imx_clk_gate2("usdhc2", "usdhc2_podf", base + 0x80, 4);
|
||||
clks[IMX6SL_CLK_USDHC3] = imx_clk_gate2("usdhc3", "usdhc3_podf", base + 0x80, 6);
|
||||
clks[IMX6SL_CLK_USDHC4] = imx_clk_gate2("usdhc4", "usdhc4_podf", base + 0x80, 8);
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(clks); i++)
|
||||
if (IS_ERR(clks[i]))
|
||||
pr_err("i.MX6SL clk %d: register failed with %ld\n",
|
||||
i, PTR_ERR(clks[i]));
|
||||
|
||||
clk_data.clks = clks;
|
||||
clk_data.clk_num = ARRAY_SIZE(clks);
|
||||
of_clk_add_provider(np, of_clk_src_onecell_get, &clk_data);
|
||||
|
||||
clk_register_clkdev(clks[IMX6SL_CLK_GPT], "ipg", "imx-gpt.0");
|
||||
clk_register_clkdev(clks[IMX6SL_CLK_GPT_SERIAL], "per", "imx-gpt.0");
|
||||
|
||||
if (IS_ENABLED(CONFIG_USB_MXS_PHY)) {
|
||||
clk_prepare_enable(clks[IMX6SL_CLK_USBPHY1_GATE]);
|
||||
clk_prepare_enable(clks[IMX6SL_CLK_USBPHY2_GATE]);
|
||||
}
|
||||
|
||||
np = of_find_compatible_node(NULL, NULL, "fsl,imx6sl-gpt");
|
||||
base = of_iomap(np, 0);
|
||||
WARN_ON(!base);
|
||||
irq = irq_of_parse_and_map(np, 0);
|
||||
mxc_timer_init(base, irq);
|
||||
}
|
||||
CLK_OF_DECLARE(imx6sl, "fsl,imx6sl-ccm", imx6sl_clocks_init);
|
@ -296,13 +296,6 @@ static const struct clk_ops clk_pllv3_enet_ops = {
|
||||
.recalc_rate = clk_pllv3_enet_recalc_rate,
|
||||
};
|
||||
|
||||
static const struct clk_ops clk_pllv3_mlb_ops = {
|
||||
.prepare = clk_pllv3_prepare,
|
||||
.unprepare = clk_pllv3_unprepare,
|
||||
.enable = clk_pllv3_enable,
|
||||
.disable = clk_pllv3_disable,
|
||||
};
|
||||
|
||||
struct clk *imx_clk_pllv3(enum imx_pllv3_type type, const char *name,
|
||||
const char *parent_name, void __iomem *base,
|
||||
u32 div_mask)
|
||||
@ -330,9 +323,6 @@ struct clk *imx_clk_pllv3(enum imx_pllv3_type type, const char *name,
|
||||
case IMX_PLLV3_ENET:
|
||||
ops = &clk_pllv3_enet_ops;
|
||||
break;
|
||||
case IMX_PLLV3_MLB:
|
||||
ops = &clk_pllv3_mlb_ops;
|
||||
break;
|
||||
default:
|
||||
ops = &clk_pllv3_ops;
|
||||
}
|
||||
|
319
arch/arm/mach-imx/clk-vf610.c
Normal file
319
arch/arm/mach-imx/clk-vf610.c
Normal file
@ -0,0 +1,319 @@
|
||||
/*
|
||||
* Copyright 2012-2013 Freescale Semiconductor, Inc.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
*/
|
||||
|
||||
#include <linux/of_address.h>
|
||||
#include <linux/clk.h>
|
||||
#include <dt-bindings/clock/vf610-clock.h>
|
||||
|
||||
#include "clk.h"
|
||||
|
||||
#define CCM_CCR (ccm_base + 0x00)
|
||||
#define CCM_CSR (ccm_base + 0x04)
|
||||
#define CCM_CCSR (ccm_base + 0x08)
|
||||
#define CCM_CACRR (ccm_base + 0x0c)
|
||||
#define CCM_CSCMR1 (ccm_base + 0x10)
|
||||
#define CCM_CSCDR1 (ccm_base + 0x14)
|
||||
#define CCM_CSCDR2 (ccm_base + 0x18)
|
||||
#define CCM_CSCDR3 (ccm_base + 0x1c)
|
||||
#define CCM_CSCMR2 (ccm_base + 0x20)
|
||||
#define CCM_CSCDR4 (ccm_base + 0x24)
|
||||
#define CCM_CLPCR (ccm_base + 0x2c)
|
||||
#define CCM_CISR (ccm_base + 0x30)
|
||||
#define CCM_CIMR (ccm_base + 0x34)
|
||||
#define CCM_CGPR (ccm_base + 0x3c)
|
||||
#define CCM_CCGR0 (ccm_base + 0x40)
|
||||
#define CCM_CCGR1 (ccm_base + 0x44)
|
||||
#define CCM_CCGR2 (ccm_base + 0x48)
|
||||
#define CCM_CCGR3 (ccm_base + 0x4c)
|
||||
#define CCM_CCGR4 (ccm_base + 0x50)
|
||||
#define CCM_CCGR5 (ccm_base + 0x54)
|
||||
#define CCM_CCGR6 (ccm_base + 0x58)
|
||||
#define CCM_CCGR7 (ccm_base + 0x5c)
|
||||
#define CCM_CCGR8 (ccm_base + 0x60)
|
||||
#define CCM_CCGR9 (ccm_base + 0x64)
|
||||
#define CCM_CCGR10 (ccm_base + 0x68)
|
||||
#define CCM_CCGR11 (ccm_base + 0x6c)
|
||||
#define CCM_CMEOR0 (ccm_base + 0x70)
|
||||
#define CCM_CMEOR1 (ccm_base + 0x74)
|
||||
#define CCM_CMEOR2 (ccm_base + 0x78)
|
||||
#define CCM_CMEOR3 (ccm_base + 0x7c)
|
||||
#define CCM_CMEOR4 (ccm_base + 0x80)
|
||||
#define CCM_CMEOR5 (ccm_base + 0x84)
|
||||
#define CCM_CPPDSR (ccm_base + 0x88)
|
||||
#define CCM_CCOWR (ccm_base + 0x8c)
|
||||
#define CCM_CCPGR0 (ccm_base + 0x90)
|
||||
#define CCM_CCPGR1 (ccm_base + 0x94)
|
||||
#define CCM_CCPGR2 (ccm_base + 0x98)
|
||||
#define CCM_CCPGR3 (ccm_base + 0x9c)
|
||||
|
||||
#define CCM_CCGRx_CGn(n) ((n) * 2)
|
||||
|
||||
#define PFD_PLL1_BASE (anatop_base + 0x2b0)
|
||||
#define PFD_PLL2_BASE (anatop_base + 0x100)
|
||||
#define PFD_PLL3_BASE (anatop_base + 0xf0)
|
||||
|
||||
static void __iomem *anatop_base;
|
||||
static void __iomem *ccm_base;
|
||||
|
||||
/* sources for multiplexer clocks, this is used multiple times */
|
||||
static const char const *fast_sels[] = { "firc", "fxosc", };
|
||||
static const char const *slow_sels[] = { "sirc_32k", "sxosc", };
|
||||
static const char const *pll1_sels[] = { "pll1_main", "pll1_pfd1", "pll1_pfd2", "pll1_pfd3", "pll1_pfd4", };
|
||||
static const char const *pll2_sels[] = { "pll2_main", "pll2_pfd1", "pll2_pfd2", "pll2_pfd3", "pll2_pfd4", };
|
||||
static const char const *sys_sels[] = { "fast_clk_sel", "slow_clk_sel", "pll2_pfd_sel", "pll2_main", "pll1_pfd_sel", "pll3_main", };
|
||||
static const char const *ddr_sels[] = { "pll2_pfd2", "sys_sel", };
|
||||
static const char const *rmii_sels[] = { "enet_ext", "audio_ext", "enet_50m", "enet_25m", };
|
||||
static const char const *enet_ts_sels[] = { "enet_ext", "fxosc", "audio_ext", "usb", "enet_ts", "enet_25m", "enet_50m", };
|
||||
static const char const *esai_sels[] = { "audio_ext", "mlb", "spdif_rx", "pll4_main_div", };
|
||||
static const char const *sai_sels[] = { "audio_ext", "mlb", "spdif_rx", "pll4_main_div", };
|
||||
static const char const *nfc_sels[] = { "platform_bus", "pll1_pfd1", "pll3_pfd1", "pll3_pfd3", };
|
||||
static const char const *qspi_sels[] = { "pll3_main", "pll3_pfd4", "pll2_pfd4", "pll1_pfd4", };
|
||||
static const char const *esdhc_sels[] = { "pll3_main", "pll3_pfd3", "pll1_pfd3", "platform_bus", };
|
||||
static const char const *dcu_sels[] = { "pll1_pfd2", "pll3_main", };
|
||||
static const char const *gpu_sels[] = { "pll2_pfd2", "pll3_pfd2", };
|
||||
static const char const *vadc_sels[] = { "pll6_main_div", "pll3_main_div", "pll3_main", };
|
||||
/* FTM counter clock source, not module clock */
|
||||
static const char const *ftm_ext_sels[] = {"sirc_128k", "sxosc", "fxosc_half", "audio_ext", };
|
||||
static const char const *ftm_fix_sels[] = { "sxosc", "ipg_bus", };
|
||||
|
||||
static struct clk_div_table pll4_main_div_table[] = {
|
||||
{ .val = 0, .div = 1 },
|
||||
{ .val = 1, .div = 2 },
|
||||
{ .val = 2, .div = 6 },
|
||||
{ .val = 3, .div = 8 },
|
||||
{ .val = 4, .div = 10 },
|
||||
{ .val = 5, .div = 12 },
|
||||
{ .val = 6, .div = 14 },
|
||||
{ .val = 7, .div = 16 },
|
||||
{ }
|
||||
};
|
||||
|
||||
static struct clk *clk[VF610_CLK_END];
|
||||
static struct clk_onecell_data clk_data;
|
||||
|
||||
static void __init vf610_clocks_init(struct device_node *ccm_node)
|
||||
{
|
||||
struct device_node *np;
|
||||
|
||||
clk[VF610_CLK_DUMMY] = imx_clk_fixed("dummy", 0);
|
||||
clk[VF610_CLK_SIRC_128K] = imx_clk_fixed("sirc_128k", 128000);
|
||||
clk[VF610_CLK_SIRC_32K] = imx_clk_fixed("sirc_32k", 32000);
|
||||
clk[VF610_CLK_FIRC] = imx_clk_fixed("firc", 24000000);
|
||||
|
||||
clk[VF610_CLK_SXOSC] = imx_obtain_fixed_clock("sxosc", 0);
|
||||
clk[VF610_CLK_FXOSC] = imx_obtain_fixed_clock("fxosc", 0);
|
||||
clk[VF610_CLK_AUDIO_EXT] = imx_obtain_fixed_clock("audio_ext", 0);
|
||||
clk[VF610_CLK_ENET_EXT] = imx_obtain_fixed_clock("enet_ext", 0);
|
||||
|
||||
clk[VF610_CLK_FXOSC_HALF] = imx_clk_fixed_factor("fxosc_half", "fxosc", 1, 2);
|
||||
|
||||
np = of_find_compatible_node(NULL, NULL, "fsl,vf610-anatop");
|
||||
anatop_base = of_iomap(np, 0);
|
||||
BUG_ON(!anatop_base);
|
||||
|
||||
np = ccm_node;
|
||||
ccm_base = of_iomap(np, 0);
|
||||
BUG_ON(!ccm_base);
|
||||
|
||||
clk[VF610_CLK_SLOW_CLK_SEL] = imx_clk_mux("slow_clk_sel", CCM_CCSR, 4, 1, slow_sels, ARRAY_SIZE(slow_sels));
|
||||
clk[VF610_CLK_FASK_CLK_SEL] = imx_clk_mux("fast_clk_sel", CCM_CCSR, 5, 1, fast_sels, ARRAY_SIZE(fast_sels));
|
||||
|
||||
clk[VF610_CLK_PLL1_MAIN] = imx_clk_fixed_factor("pll1_main", "fast_clk_sel", 22, 1);
|
||||
clk[VF610_CLK_PLL1_PFD1] = imx_clk_pfd("pll1_pfd1", "pll1_main", PFD_PLL1_BASE, 0);
|
||||
clk[VF610_CLK_PLL1_PFD2] = imx_clk_pfd("pll1_pfd2", "pll1_main", PFD_PLL1_BASE, 1);
|
||||
clk[VF610_CLK_PLL1_PFD3] = imx_clk_pfd("pll1_pfd3", "pll1_main", PFD_PLL1_BASE, 2);
|
||||
clk[VF610_CLK_PLL1_PFD4] = imx_clk_pfd("pll1_pfd4", "pll1_main", PFD_PLL1_BASE, 3);
|
||||
|
||||
clk[VF610_CLK_PLL2_MAIN] = imx_clk_fixed_factor("pll2_main", "fast_clk_sel", 22, 1);
|
||||
clk[VF610_CLK_PLL2_PFD1] = imx_clk_pfd("pll2_pfd1", "pll2_main", PFD_PLL2_BASE, 0);
|
||||
clk[VF610_CLK_PLL2_PFD2] = imx_clk_pfd("pll2_pfd2", "pll2_main", PFD_PLL2_BASE, 1);
|
||||
clk[VF610_CLK_PLL2_PFD3] = imx_clk_pfd("pll2_pfd3", "pll2_main", PFD_PLL2_BASE, 2);
|
||||
clk[VF610_CLK_PLL2_PFD4] = imx_clk_pfd("pll2_pfd4", "pll2_main", PFD_PLL2_BASE, 3);
|
||||
|
||||
clk[VF610_CLK_PLL3_MAIN] = imx_clk_fixed_factor("pll3_main", "fast_clk_sel", 20, 1);
|
||||
clk[VF610_CLK_PLL3_PFD1] = imx_clk_pfd("pll3_pfd1", "pll3_main", PFD_PLL3_BASE, 0);
|
||||
clk[VF610_CLK_PLL3_PFD2] = imx_clk_pfd("pll3_pfd2", "pll3_main", PFD_PLL3_BASE, 1);
|
||||
clk[VF610_CLK_PLL3_PFD3] = imx_clk_pfd("pll3_pfd3", "pll3_main", PFD_PLL3_BASE, 2);
|
||||
clk[VF610_CLK_PLL3_PFD4] = imx_clk_pfd("pll3_pfd4", "pll3_main", PFD_PLL3_BASE, 3);
|
||||
|
||||
clk[VF610_CLK_PLL4_MAIN] = imx_clk_fixed_factor("pll4_main", "fast_clk_sel", 25, 1);
|
||||
/* Enet pll: fixed 50Mhz */
|
||||
clk[VF610_CLK_PLL5_MAIN] = imx_clk_fixed_factor("pll5_main", "fast_clk_sel", 125, 6);
|
||||
/* pll6: default 960Mhz */
|
||||
clk[VF610_CLK_PLL6_MAIN] = imx_clk_fixed_factor("pll6_main", "fast_clk_sel", 40, 1);
|
||||
clk[VF610_CLK_PLL1_PFD_SEL] = imx_clk_mux("pll1_pfd_sel", CCM_CCSR, 16, 3, pll1_sels, 5);
|
||||
clk[VF610_CLK_PLL2_PFD_SEL] = imx_clk_mux("pll2_pfd_sel", CCM_CCSR, 19, 3, pll2_sels, 5);
|
||||
clk[VF610_CLK_SYS_SEL] = imx_clk_mux("sys_sel", CCM_CCSR, 0, 3, sys_sels, ARRAY_SIZE(sys_sels));
|
||||
clk[VF610_CLK_DDR_SEL] = imx_clk_mux("ddr_sel", CCM_CCSR, 6, 1, ddr_sels, ARRAY_SIZE(ddr_sels));
|
||||
clk[VF610_CLK_SYS_BUS] = imx_clk_divider("sys_bus", "sys_sel", CCM_CACRR, 0, 3);
|
||||
clk[VF610_CLK_PLATFORM_BUS] = imx_clk_divider("platform_bus", "sys_bus", CCM_CACRR, 3, 3);
|
||||
clk[VF610_CLK_IPG_BUS] = imx_clk_divider("ipg_bus", "platform_bus", CCM_CACRR, 11, 2);
|
||||
|
||||
clk[VF610_CLK_PLL3_MAIN_DIV] = imx_clk_divider("pll3_main_div", "pll3_main", CCM_CACRR, 20, 1);
|
||||
clk[VF610_CLK_PLL4_MAIN_DIV] = clk_register_divider_table(NULL, "pll4_main_div", "pll4_main", 0, CCM_CACRR, 6, 3, 0, pll4_main_div_table, &imx_ccm_lock);
|
||||
clk[VF610_CLK_PLL6_MAIN_DIV] = imx_clk_divider("pll6_main_div", "pll6_main", CCM_CACRR, 21, 1);
|
||||
|
||||
clk[VF610_CLK_USBC0] = imx_clk_gate2("usbc0", "pll3_main", CCM_CCGR1, CCM_CCGRx_CGn(4));
|
||||
clk[VF610_CLK_USBC1] = imx_clk_gate2("usbc1", "pll3_main", CCM_CCGR7, CCM_CCGRx_CGn(4));
|
||||
|
||||
clk[VF610_CLK_QSPI0_SEL] = imx_clk_mux("qspi0_sel", CCM_CSCMR1, 22, 2, qspi_sels, 4);
|
||||
clk[VF610_CLK_QSPI0_EN] = imx_clk_gate("qspi0_en", "qspi0_sel", CCM_CSCDR3, 4);
|
||||
clk[VF610_CLK_QSPI0_X4_DIV] = imx_clk_divider("qspi0_x4", "qspi0_en", CCM_CSCDR3, 0, 2);
|
||||
clk[VF610_CLK_QSPI0_X2_DIV] = imx_clk_divider("qspi0_x2", "qspi0_x4", CCM_CSCDR3, 2, 1);
|
||||
clk[VF610_CLK_QSPI0_X1_DIV] = imx_clk_divider("qspi0_x1", "qspi0_x2", CCM_CSCDR3, 3, 1);
|
||||
clk[VF610_CLK_QSPI0] = imx_clk_gate2("qspi0", "qspi0_x1", CCM_CCGR2, CCM_CCGRx_CGn(4));
|
||||
|
||||
clk[VF610_CLK_QSPI1_SEL] = imx_clk_mux("qspi1_sel", CCM_CSCMR1, 24, 2, qspi_sels, 4);
|
||||
clk[VF610_CLK_QSPI1_EN] = imx_clk_gate("qspi1_en", "qspi1_sel", CCM_CSCDR3, 12);
|
||||
clk[VF610_CLK_QSPI1_X4_DIV] = imx_clk_divider("qspi1_x4", "qspi1_en", CCM_CSCDR3, 8, 2);
|
||||
clk[VF610_CLK_QSPI1_X2_DIV] = imx_clk_divider("qspi1_x2", "qspi1_x4", CCM_CSCDR3, 10, 1);
|
||||
clk[VF610_CLK_QSPI1_X1_DIV] = imx_clk_divider("qspi1_x1", "qspi1_x2", CCM_CSCDR3, 11, 1);
|
||||
clk[VF610_CLK_QSPI1] = imx_clk_gate2("qspi1", "qspi1_x1", CCM_CCGR8, CCM_CCGRx_CGn(4));
|
||||
|
||||
clk[VF610_CLK_ENET_50M] = imx_clk_fixed_factor("enet_50m", "pll5_main", 1, 10);
|
||||
clk[VF610_CLK_ENET_25M] = imx_clk_fixed_factor("enet_25m", "pll5_main", 1, 20);
|
||||
clk[VF610_CLK_ENET_SEL] = imx_clk_mux("enet_sel", CCM_CSCMR2, 4, 2, rmii_sels, 4);
|
||||
clk[VF610_CLK_ENET_TS_SEL] = imx_clk_mux("enet_ts_sel", CCM_CSCMR2, 0, 3, enet_ts_sels, 7);
|
||||
clk[VF610_CLK_ENET] = imx_clk_gate("enet", "enet_sel", CCM_CSCDR1, 24);
|
||||
clk[VF610_CLK_ENET_TS] = imx_clk_gate("enet_ts", "enet_ts_sel", CCM_CSCDR1, 23);
|
||||
|
||||
clk[VF610_CLK_PIT] = imx_clk_gate2("pit", "ipg_bus", CCM_CCGR1, CCM_CCGRx_CGn(7));
|
||||
|
||||
clk[VF610_CLK_UART0] = imx_clk_gate2("uart0", "ipg_bus", CCM_CCGR0, CCM_CCGRx_CGn(7));
|
||||
clk[VF610_CLK_UART1] = imx_clk_gate2("uart1", "ipg_bus", CCM_CCGR0, CCM_CCGRx_CGn(8));
|
||||
clk[VF610_CLK_UART2] = imx_clk_gate2("uart2", "ipg_bus", CCM_CCGR0, CCM_CCGRx_CGn(9));
|
||||
clk[VF610_CLK_UART3] = imx_clk_gate2("uart3", "ipg_bus", CCM_CCGR0, CCM_CCGRx_CGn(10));
|
||||
|
||||
clk[VF610_CLK_I2C0] = imx_clk_gate2("i2c0", "ipg_bus", CCM_CCGR4, CCM_CCGRx_CGn(6));
|
||||
clk[VF610_CLK_I2C1] = imx_clk_gate2("i2c1", "ipg_bus", CCM_CCGR4, CCM_CCGRx_CGn(7));
|
||||
|
||||
clk[VF610_CLK_DSPI0] = imx_clk_gate2("dspi0", "ipg_bus", CCM_CCGR0, CCM_CCGRx_CGn(12));
|
||||
clk[VF610_CLK_DSPI1] = imx_clk_gate2("dspi1", "ipg_bus", CCM_CCGR0, CCM_CCGRx_CGn(13));
|
||||
clk[VF610_CLK_DSPI2] = imx_clk_gate2("dspi2", "ipg_bus", CCM_CCGR6, CCM_CCGRx_CGn(12));
|
||||
clk[VF610_CLK_DSPI3] = imx_clk_gate2("dspi3", "ipg_bus", CCM_CCGR6, CCM_CCGRx_CGn(13));
|
||||
|
||||
clk[VF610_CLK_WDT] = imx_clk_gate2("wdt", "ipg_bus", CCM_CCGR1, CCM_CCGRx_CGn(14));
|
||||
|
||||
clk[VF610_CLK_ESDHC0_SEL] = imx_clk_mux("esdhc0_sel", CCM_CSCMR1, 16, 2, esdhc_sels, 4);
|
||||
clk[VF610_CLK_ESDHC0_EN] = imx_clk_gate("esdhc0_en", "esdhc0_sel", CCM_CSCDR2, 28);
|
||||
clk[VF610_CLK_ESDHC0_DIV] = imx_clk_divider("esdhc0_div", "esdhc0_en", CCM_CSCDR2, 16, 4);
|
||||
clk[VF610_CLK_ESDHC0] = imx_clk_gate2("eshc0", "esdhc0_div", CCM_CCGR7, CCM_CCGRx_CGn(1));
|
||||
|
||||
clk[VF610_CLK_ESDHC1_SEL] = imx_clk_mux("esdhc1_sel", CCM_CSCMR1, 18, 2, esdhc_sels, 4);
|
||||
clk[VF610_CLK_ESDHC1_EN] = imx_clk_gate("esdhc1_en", "esdhc1_sel", CCM_CSCDR2, 29);
|
||||
clk[VF610_CLK_ESDHC1_DIV] = imx_clk_divider("esdhc1_div", "esdhc1_en", CCM_CSCDR2, 20, 4);
|
||||
clk[VF610_CLK_ESDHC1] = imx_clk_gate2("eshc1", "esdhc1_div", CCM_CCGR7, CCM_CCGRx_CGn(2));
|
||||
|
||||
/*
|
||||
* ftm_ext_clk and ftm_fix_clk are FTM timer counter's
|
||||
* selectable clock sources, both use a common enable bit
|
||||
* in CCM_CSCDR1, selecting "dummy" clock as parent of
|
||||
* "ftm0_ext_fix" make it serve only for enable/disable.
|
||||
*/
|
||||
clk[VF610_CLK_FTM0_EXT_SEL] = imx_clk_mux("ftm0_ext_sel", CCM_CSCMR2, 6, 2, ftm_ext_sels, 4);
|
||||
clk[VF610_CLK_FTM0_FIX_SEL] = imx_clk_mux("ftm0_fix_sel", CCM_CSCMR2, 14, 1, ftm_fix_sels, 2);
|
||||
clk[VF610_CLK_FTM0_EXT_FIX_EN] = imx_clk_gate("ftm0_ext_fix_en", "dummy", CCM_CSCDR1, 25);
|
||||
clk[VF610_CLK_FTM1_EXT_SEL] = imx_clk_mux("ftm1_ext_sel", CCM_CSCMR2, 8, 2, ftm_ext_sels, 4);
|
||||
clk[VF610_CLK_FTM1_FIX_SEL] = imx_clk_mux("ftm1_fix_sel", CCM_CSCMR2, 15, 1, ftm_fix_sels, 2);
|
||||
clk[VF610_CLK_FTM1_EXT_FIX_EN] = imx_clk_gate("ftm1_ext_fix_en", "dummy", CCM_CSCDR1, 26);
|
||||
clk[VF610_CLK_FTM2_EXT_SEL] = imx_clk_mux("ftm2_ext_sel", CCM_CSCMR2, 10, 2, ftm_ext_sels, 4);
|
||||
clk[VF610_CLK_FTM2_FIX_SEL] = imx_clk_mux("ftm2_fix_sel", CCM_CSCMR2, 16, 1, ftm_fix_sels, 2);
|
||||
clk[VF610_CLK_FTM2_EXT_FIX_EN] = imx_clk_gate("ftm2_ext_fix_en", "dummy", CCM_CSCDR1, 27);
|
||||
clk[VF610_CLK_FTM3_EXT_SEL] = imx_clk_mux("ftm3_ext_sel", CCM_CSCMR2, 12, 2, ftm_ext_sels, 4);
|
||||
clk[VF610_CLK_FTM3_FIX_SEL] = imx_clk_mux("ftm3_fix_sel", CCM_CSCMR2, 17, 1, ftm_fix_sels, 2);
|
||||
clk[VF610_CLK_FTM3_EXT_FIX_EN] = imx_clk_gate("ftm3_ext_fix_en", "dummy", CCM_CSCDR1, 28);
|
||||
|
||||
/* ftm(n)_clk are FTM module operation clock */
|
||||
clk[VF610_CLK_FTM0] = imx_clk_gate2("ftm0", "ipg_bus", CCM_CCGR1, CCM_CCGRx_CGn(8));
|
||||
clk[VF610_CLK_FTM1] = imx_clk_gate2("ftm1", "ipg_bus", CCM_CCGR1, CCM_CCGRx_CGn(9));
|
||||
clk[VF610_CLK_FTM2] = imx_clk_gate2("ftm2", "ipg_bus", CCM_CCGR7, CCM_CCGRx_CGn(8));
|
||||
clk[VF610_CLK_FTM3] = imx_clk_gate2("ftm3", "ipg_bus", CCM_CCGR7, CCM_CCGRx_CGn(9));
|
||||
|
||||
clk[VF610_CLK_DCU0_SEL] = imx_clk_mux("dcu0_sel", CCM_CSCMR1, 28, 1, dcu_sels, 2);
|
||||
clk[VF610_CLK_DCU0_EN] = imx_clk_gate("dcu0_en", "dcu0_sel", CCM_CSCDR3, 19);
|
||||
clk[VF610_CLK_DCU0_DIV] = imx_clk_divider("dcu0_div", "dcu0_en", CCM_CSCDR3, 16, 3);
|
||||
clk[VF610_CLK_DCU0] = imx_clk_gate2("dcu0", "dcu0_div", CCM_CCGR3, CCM_CCGRx_CGn(8));
|
||||
clk[VF610_CLK_DCU1_SEL] = imx_clk_mux("dcu1_sel", CCM_CSCMR1, 29, 1, dcu_sels, 2);
|
||||
clk[VF610_CLK_DCU1_EN] = imx_clk_gate("dcu1_en", "dcu1_sel", CCM_CSCDR3, 23);
|
||||
clk[VF610_CLK_DCU1_DIV] = imx_clk_divider("dcu1_div", "dcu1_en", CCM_CSCDR3, 20, 3);
|
||||
clk[VF610_CLK_DCU1] = imx_clk_gate2("dcu1", "dcu1_div", CCM_CCGR9, CCM_CCGRx_CGn(8));
|
||||
|
||||
clk[VF610_CLK_ESAI_SEL] = imx_clk_mux("esai_sel", CCM_CSCMR1, 20, 2, esai_sels, 4);
|
||||
clk[VF610_CLK_ESAI_EN] = imx_clk_gate("esai_en", "esai_sel", CCM_CSCDR2, 30);
|
||||
clk[VF610_CLK_ESAI_DIV] = imx_clk_divider("esai_div", "esai_en", CCM_CSCDR2, 24, 4);
|
||||
clk[VF610_CLK_ESAI] = imx_clk_gate2("esai", "esai_div", CCM_CCGR4, CCM_CCGRx_CGn(2));
|
||||
|
||||
clk[VF610_CLK_SAI0_SEL] = imx_clk_mux("sai0_sel", CCM_CSCMR1, 0, 2, sai_sels, 4);
|
||||
clk[VF610_CLK_SAI0_EN] = imx_clk_gate("sai0_en", "sai0_sel", CCM_CSCDR1, 16);
|
||||
clk[VF610_CLK_SAI0_DIV] = imx_clk_divider("sai0_div", "sai0_en", CCM_CSCDR1, 0, 4);
|
||||
clk[VF610_CLK_SAI0] = imx_clk_gate2("sai0", "sai0_div", CCM_CCGR0, CCM_CCGRx_CGn(15));
|
||||
|
||||
clk[VF610_CLK_SAI1_SEL] = imx_clk_mux("sai1_sel", CCM_CSCMR1, 2, 2, sai_sels, 4);
|
||||
clk[VF610_CLK_SAI1_EN] = imx_clk_gate("sai1_en", "sai1_sel", CCM_CSCDR1, 17);
|
||||
clk[VF610_CLK_SAI1_DIV] = imx_clk_divider("sai1_div", "sai1_en", CCM_CSCDR1, 4, 4);
|
||||
clk[VF610_CLK_SAI1] = imx_clk_gate2("sai1", "sai1_div", CCM_CCGR1, CCM_CCGRx_CGn(0));
|
||||
|
||||
clk[VF610_CLK_SAI2_SEL] = imx_clk_mux("sai2_sel", CCM_CSCMR1, 4, 2, sai_sels, 4);
|
||||
clk[VF610_CLK_SAI2_EN] = imx_clk_gate("sai2_en", "sai2_sel", CCM_CSCDR1, 18);
|
||||
clk[VF610_CLK_SAI2_DIV] = imx_clk_divider("sai2_div", "sai2_en", CCM_CSCDR1, 8, 4);
|
||||
clk[VF610_CLK_SAI2] = imx_clk_gate2("sai2", "sai2_div", CCM_CCGR1, CCM_CCGRx_CGn(1));
|
||||
|
||||
clk[VF610_CLK_SAI3_SEL] = imx_clk_mux("sai3_sel", CCM_CSCMR1, 6, 2, sai_sels, 4);
|
||||
clk[VF610_CLK_SAI3_EN] = imx_clk_gate("sai3_en", "sai3_sel", CCM_CSCDR1, 19);
|
||||
clk[VF610_CLK_SAI3_DIV] = imx_clk_divider("sai3_div", "sai3_en", CCM_CSCDR1, 12, 4);
|
||||
clk[VF610_CLK_SAI3] = imx_clk_gate2("sai3", "sai3_div", CCM_CCGR1, CCM_CCGRx_CGn(2));
|
||||
|
||||
clk[VF610_CLK_NFC_SEL] = imx_clk_mux("nfc_sel", CCM_CSCMR1, 12, 2, nfc_sels, 4);
|
||||
clk[VF610_CLK_NFC_EN] = imx_clk_gate("nfc_en", "nfc_sel", CCM_CSCDR2, 9);
|
||||
clk[VF610_CLK_NFC_PRE_DIV] = imx_clk_divider("nfc_pre_div", "nfc_en", CCM_CSCDR3, 13, 3);
|
||||
clk[VF610_CLK_NFC_FRAC_DIV] = imx_clk_divider("nfc_frac_div", "nfc_pre_div", CCM_CSCDR2, 4, 4);
|
||||
clk[VF610_CLK_NFC] = imx_clk_gate2("nfc", "nfc_frac_div", CCM_CCGR10, CCM_CCGRx_CGn(0));
|
||||
|
||||
clk[VF610_CLK_GPU_SEL] = imx_clk_mux("gpu_sel", CCM_CSCMR1, 14, 1, gpu_sels, 2);
|
||||
clk[VF610_CLK_GPU_EN] = imx_clk_gate("gpu_en", "gpu_sel", CCM_CSCDR2, 10);
|
||||
clk[VF610_CLK_GPU2D] = imx_clk_gate2("gpu", "gpu_en", CCM_CCGR8, CCM_CCGRx_CGn(15));
|
||||
|
||||
clk[VF610_CLK_VADC_SEL] = imx_clk_mux("vadc_sel", CCM_CSCMR1, 8, 2, vadc_sels, 3);
|
||||
clk[VF610_CLK_VADC_EN] = imx_clk_gate("vadc_en", "vadc_sel", CCM_CSCDR1, 22);
|
||||
clk[VF610_CLK_VADC_DIV] = imx_clk_divider("vadc_div", "vadc_en", CCM_CSCDR1, 20, 2);
|
||||
clk[VF610_CLK_VADC_DIV_HALF] = imx_clk_fixed_factor("vadc_div_half", "vadc_div", 1, 2);
|
||||
clk[VF610_CLK_VADC] = imx_clk_gate2("vadc", "vadc_div", CCM_CCGR8, CCM_CCGRx_CGn(7));
|
||||
|
||||
clk[VF610_CLK_ADC0] = imx_clk_gate2("adc0", "ipg_bus", CCM_CCGR1, CCM_CCGRx_CGn(11));
|
||||
clk[VF610_CLK_ADC1] = imx_clk_gate2("adc1", "ipg_bus", CCM_CCGR7, CCM_CCGRx_CGn(11));
|
||||
clk[VF610_CLK_DAC0] = imx_clk_gate2("dac0", "ipg_bus", CCM_CCGR8, CCM_CCGRx_CGn(12));
|
||||
clk[VF610_CLK_DAC1] = imx_clk_gate2("dac1", "ipg_bus", CCM_CCGR8, CCM_CCGRx_CGn(13));
|
||||
|
||||
clk[VF610_CLK_ASRC] = imx_clk_gate2("asrc", "ipg_bus", CCM_CCGR4, CCM_CCGRx_CGn(1));
|
||||
|
||||
clk[VF610_CLK_FLEXCAN0] = imx_clk_gate2("flexcan0", "ipg_bus", CCM_CCGR0, CCM_CCGRx_CGn(0));
|
||||
clk[VF610_CLK_FLEXCAN1] = imx_clk_gate2("flexcan1", "ipg_bus", CCM_CCGR9, CCM_CCGRx_CGn(4));
|
||||
|
||||
clk_set_parent(clk[VF610_CLK_QSPI0_SEL], clk[VF610_CLK_PLL1_PFD4]);
|
||||
clk_set_rate(clk[VF610_CLK_QSPI0_X4_DIV], clk_get_rate(clk[VF610_CLK_QSPI0_SEL]) / 2);
|
||||
clk_set_rate(clk[VF610_CLK_QSPI0_X2_DIV], clk_get_rate(clk[VF610_CLK_QSPI0_X4_DIV]) / 2);
|
||||
clk_set_rate(clk[VF610_CLK_QSPI0_X1_DIV], clk_get_rate(clk[VF610_CLK_QSPI0_X2_DIV]) / 2);
|
||||
|
||||
clk_set_parent(clk[VF610_CLK_QSPI1_SEL], clk[VF610_CLK_PLL1_PFD4]);
|
||||
clk_set_rate(clk[VF610_CLK_QSPI1_X4_DIV], clk_get_rate(clk[VF610_CLK_QSPI1_SEL]) / 2);
|
||||
clk_set_rate(clk[VF610_CLK_QSPI1_X2_DIV], clk_get_rate(clk[VF610_CLK_QSPI1_X4_DIV]) / 2);
|
||||
clk_set_rate(clk[VF610_CLK_QSPI1_X1_DIV], clk_get_rate(clk[VF610_CLK_QSPI1_X2_DIV]) / 2);
|
||||
|
||||
clk_set_parent(clk[VF610_CLK_SAI0_SEL], clk[VF610_CLK_AUDIO_EXT]);
|
||||
clk_set_parent(clk[VF610_CLK_SAI1_SEL], clk[VF610_CLK_AUDIO_EXT]);
|
||||
clk_set_parent(clk[VF610_CLK_SAI2_SEL], clk[VF610_CLK_AUDIO_EXT]);
|
||||
clk_set_parent(clk[VF610_CLK_SAI3_SEL], clk[VF610_CLK_AUDIO_EXT]);
|
||||
|
||||
/* Add the clocks to provider list */
|
||||
clk_data.clks = clk;
|
||||
clk_data.clk_num = ARRAY_SIZE(clk);
|
||||
of_clk_add_provider(np, of_clk_src_onecell_get, &clk_data);
|
||||
}
|
||||
CLK_OF_DECLARE(vf610, "fsl,vf610-ccm", vf610_clocks_init);
|
@ -1,4 +1,39 @@
|
||||
#include <linux/clk.h>
|
||||
#include <linux/err.h>
|
||||
#include <linux/of.h>
|
||||
#include <linux/slab.h>
|
||||
#include <linux/spinlock.h>
|
||||
#include "clk.h"
|
||||
|
||||
DEFINE_SPINLOCK(imx_ccm_lock);
|
||||
|
||||
static struct clk * __init imx_obtain_fixed_clock_from_dt(const char *name)
|
||||
{
|
||||
struct of_phandle_args phandle;
|
||||
struct clk *clk = ERR_PTR(-ENODEV);
|
||||
char *path;
|
||||
|
||||
path = kasprintf(GFP_KERNEL, "/clocks/%s", name);
|
||||
if (!path)
|
||||
return ERR_PTR(-ENOMEM);
|
||||
|
||||
phandle.np = of_find_node_by_path(path);
|
||||
kfree(path);
|
||||
|
||||
if (phandle.np) {
|
||||
clk = of_clk_get_from_provider(&phandle);
|
||||
of_node_put(phandle.np);
|
||||
}
|
||||
return clk;
|
||||
}
|
||||
|
||||
struct clk * __init imx_obtain_fixed_clock(
|
||||
const char *name, unsigned long rate)
|
||||
{
|
||||
struct clk *clk;
|
||||
|
||||
clk = imx_obtain_fixed_clock_from_dt(name);
|
||||
if (IS_ERR(clk))
|
||||
clk = imx_clk_fixed(name, rate);
|
||||
return clk;
|
||||
}
|
||||
|
@ -18,7 +18,6 @@ enum imx_pllv3_type {
|
||||
IMX_PLLV3_USB,
|
||||
IMX_PLLV3_AV,
|
||||
IMX_PLLV3_ENET,
|
||||
IMX_PLLV3_MLB,
|
||||
};
|
||||
|
||||
struct clk *imx_clk_pllv3(enum imx_pllv3_type type, const char *name,
|
||||
@ -29,6 +28,9 @@ struct clk *clk_register_gate2(struct device *dev, const char *name,
|
||||
void __iomem *reg, u8 bit_idx,
|
||||
u8 clk_gate_flags, spinlock_t *lock);
|
||||
|
||||
struct clk * imx_obtain_fixed_clock(
|
||||
const char *name, unsigned long rate);
|
||||
|
||||
static inline struct clk *imx_clk_gate2(const char *name, const char *parent,
|
||||
void __iomem *reg, u8 shift)
|
||||
{
|
||||
|
@ -68,12 +68,12 @@ extern int mx27_clocks_init_dt(void);
|
||||
extern int mx31_clocks_init_dt(void);
|
||||
extern int mx51_clocks_init_dt(void);
|
||||
extern int mx53_clocks_init_dt(void);
|
||||
extern int mx6q_clocks_init(void);
|
||||
extern struct platform_device *mxc_register_gpio(char *name, int id,
|
||||
resource_size_t iobase, resource_size_t iosize, int irq, int irq_high);
|
||||
extern void mxc_set_cpu_type(unsigned int type);
|
||||
extern void mxc_restart(char, const char *);
|
||||
extern void mxc_arch_reset_init(void __iomem *);
|
||||
extern void mxc_arch_reset_init_dt(void);
|
||||
extern int mx53_revision(void);
|
||||
extern int imx6q_revision(void);
|
||||
extern int mx53_display_revision(void);
|
||||
|
@ -20,6 +20,7 @@
|
||||
#ifndef __ASM_ARCH_MXC_HARDWARE_H__
|
||||
#define __ASM_ARCH_MXC_HARDWARE_H__
|
||||
|
||||
#include <asm/io.h>
|
||||
#include <asm/sizes.h>
|
||||
|
||||
#define addr_in_module(addr, mod) \
|
||||
|
@ -19,6 +19,8 @@
|
||||
|
||||
static void __init imx25_dt_init(void)
|
||||
{
|
||||
mxc_arch_reset_init_dt();
|
||||
|
||||
of_platform_populate(NULL, of_default_bus_match_table, NULL, NULL);
|
||||
}
|
||||
|
||||
|
@ -22,6 +22,8 @@ static void __init imx27_dt_init(void)
|
||||
{
|
||||
struct platform_device_info devinfo = { .name = "cpufreq-cpu0", };
|
||||
|
||||
mxc_arch_reset_init_dt();
|
||||
|
||||
of_platform_populate(NULL, of_default_bus_match_table, NULL, NULL);
|
||||
|
||||
platform_device_register_full(&devinfo);
|
||||
|
@ -20,6 +20,8 @@
|
||||
|
||||
static void __init imx31_dt_init(void)
|
||||
{
|
||||
mxc_arch_reset_init_dt();
|
||||
|
||||
of_platform_populate(NULL, of_default_bus_match_table, NULL, NULL);
|
||||
}
|
||||
|
||||
|
@ -23,6 +23,8 @@ static void __init imx51_dt_init(void)
|
||||
{
|
||||
struct platform_device_info devinfo = { .name = "cpufreq-cpu0", };
|
||||
|
||||
mxc_arch_reset_init_dt();
|
||||
|
||||
of_platform_populate(NULL, of_default_bus_match_table, NULL, NULL);
|
||||
platform_device_register_full(&devinfo);
|
||||
}
|
||||
|
@ -18,6 +18,7 @@
|
||||
|
||||
#include <linux/module.h>
|
||||
#include <linux/irq.h>
|
||||
#include <linux/platform_data/asoc-imx-ssi.h>
|
||||
|
||||
#include "irq-common.h"
|
||||
|
||||
|
@ -21,6 +21,7 @@
|
||||
#include <asm/mach/time.h>
|
||||
|
||||
#include "common.h"
|
||||
#include "hardware.h"
|
||||
#include "mx53.h"
|
||||
|
||||
static void __init imx53_qsb_init(void)
|
||||
@ -38,6 +39,8 @@ static void __init imx53_qsb_init(void)
|
||||
|
||||
static void __init imx53_dt_init(void)
|
||||
{
|
||||
mxc_arch_reset_init_dt();
|
||||
|
||||
if (of_machine_is_compatible("fsl,imx53-qsb"))
|
||||
imx53_qsb_init();
|
||||
|
||||
|
@ -11,6 +11,7 @@
|
||||
*/
|
||||
|
||||
#include <linux/clk.h>
|
||||
#include <linux/clk-provider.h>
|
||||
#include <linux/clkdev.h>
|
||||
#include <linux/clocksource.h>
|
||||
#include <linux/cpu.h>
|
||||
@ -145,6 +146,45 @@ static void __init imx6q_sabrelite_init(void)
|
||||
imx6q_sabrelite_cko1_setup();
|
||||
}
|
||||
|
||||
static void __init imx6q_sabresd_cko1_setup(void)
|
||||
{
|
||||
struct clk *cko1_sel, *pll4, *pll4_post, *cko1;
|
||||
unsigned long rate;
|
||||
|
||||
cko1_sel = clk_get_sys(NULL, "cko1_sel");
|
||||
pll4 = clk_get_sys(NULL, "pll4_audio");
|
||||
pll4_post = clk_get_sys(NULL, "pll4_post_div");
|
||||
cko1 = clk_get_sys(NULL, "cko1");
|
||||
if (IS_ERR(cko1_sel) || IS_ERR(pll4)
|
||||
|| IS_ERR(pll4_post) || IS_ERR(cko1)) {
|
||||
pr_err("cko1 setup failed!\n");
|
||||
goto put_clk;
|
||||
}
|
||||
/*
|
||||
* Setting pll4 at 768MHz (24MHz * 32)
|
||||
* So its child clock can get 24MHz easily
|
||||
*/
|
||||
clk_set_rate(pll4, 768000000);
|
||||
|
||||
clk_set_parent(cko1_sel, pll4_post);
|
||||
rate = clk_round_rate(cko1, 24000000);
|
||||
clk_set_rate(cko1, rate);
|
||||
put_clk:
|
||||
if (!IS_ERR(cko1_sel))
|
||||
clk_put(cko1_sel);
|
||||
if (!IS_ERR(pll4_post))
|
||||
clk_put(pll4_post);
|
||||
if (!IS_ERR(pll4))
|
||||
clk_put(pll4);
|
||||
if (!IS_ERR(cko1))
|
||||
clk_put(cko1);
|
||||
}
|
||||
|
||||
static void __init imx6q_sabresd_init(void)
|
||||
{
|
||||
imx6q_sabresd_cko1_setup();
|
||||
}
|
||||
|
||||
static void __init imx6q_1588_init(void)
|
||||
{
|
||||
struct regmap *gpr;
|
||||
@ -165,6 +205,9 @@ static void __init imx6q_init_machine(void)
|
||||
{
|
||||
if (of_machine_is_compatible("fsl,imx6q-sabrelite"))
|
||||
imx6q_sabrelite_init();
|
||||
else if (of_machine_is_compatible("fsl,imx6q-sabresd") ||
|
||||
of_machine_is_compatible("fsl,imx6dl-sabresd"))
|
||||
imx6q_sabresd_init();
|
||||
|
||||
of_platform_populate(NULL, of_default_bus_match_table, NULL, NULL);
|
||||
|
||||
@ -253,10 +296,44 @@ static void __init imx6q_map_io(void)
|
||||
imx_scu_map_io();
|
||||
}
|
||||
|
||||
#ifdef CONFIG_CACHE_L2X0
|
||||
static void __init imx6q_init_l2cache(void)
|
||||
{
|
||||
void __iomem *l2x0_base;
|
||||
struct device_node *np;
|
||||
unsigned int val;
|
||||
|
||||
np = of_find_compatible_node(NULL, NULL, "arm,pl310-cache");
|
||||
if (!np)
|
||||
goto out;
|
||||
|
||||
l2x0_base = of_iomap(np, 0);
|
||||
if (!l2x0_base) {
|
||||
of_node_put(np);
|
||||
goto out;
|
||||
}
|
||||
|
||||
/* Configure the L2 PREFETCH and POWER registers */
|
||||
val = readl_relaxed(l2x0_base + L2X0_PREFETCH_CTRL);
|
||||
val |= 0x70800000;
|
||||
writel_relaxed(val, l2x0_base + L2X0_PREFETCH_CTRL);
|
||||
val = L2X0_DYNAMIC_CLK_GATING_EN | L2X0_STNDBY_MODE_EN;
|
||||
writel_relaxed(val, l2x0_base + L2X0_POWER_CTRL);
|
||||
|
||||
iounmap(l2x0_base);
|
||||
of_node_put(np);
|
||||
|
||||
out:
|
||||
l2x0_of_init(0, ~0UL);
|
||||
}
|
||||
#else
|
||||
static inline void imx6q_init_l2cache(void) {}
|
||||
#endif
|
||||
|
||||
static void __init imx6q_init_irq(void)
|
||||
{
|
||||
imx6q_init_revision();
|
||||
l2x0_of_init(0, ~0UL);
|
||||
imx6q_init_l2cache();
|
||||
imx_src_init();
|
||||
imx_gpc_init();
|
||||
irqchip_init();
|
||||
@ -264,7 +341,7 @@ static void __init imx6q_init_irq(void)
|
||||
|
||||
static void __init imx6q_timer_init(void)
|
||||
{
|
||||
mx6q_clocks_init();
|
||||
of_clk_init(NULL);
|
||||
clocksource_of_init();
|
||||
imx_print_silicon_rev(cpu_is_imx6dl() ? "i.MX6DL" : "i.MX6Q",
|
||||
imx6q_revision());
|
||||
|
52
arch/arm/mach-imx/mach-imx6sl.c
Normal file
52
arch/arm/mach-imx/mach-imx6sl.c
Normal file
@ -0,0 +1,52 @@
|
||||
/*
|
||||
* Copyright 2013 Freescale Semiconductor, Inc.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
*/
|
||||
|
||||
#include <linux/clk-provider.h>
|
||||
#include <linux/irqchip.h>
|
||||
#include <linux/of.h>
|
||||
#include <linux/of_platform.h>
|
||||
#include <asm/hardware/cache-l2x0.h>
|
||||
#include <asm/mach/arch.h>
|
||||
#include <asm/mach/map.h>
|
||||
|
||||
#include "common.h"
|
||||
|
||||
static void __init imx6sl_init_machine(void)
|
||||
{
|
||||
mxc_arch_reset_init_dt();
|
||||
|
||||
of_platform_populate(NULL, of_default_bus_match_table, NULL, NULL);
|
||||
}
|
||||
|
||||
static void __init imx6sl_init_irq(void)
|
||||
{
|
||||
l2x0_of_init(0, ~0UL);
|
||||
imx_src_init();
|
||||
imx_gpc_init();
|
||||
irqchip_init();
|
||||
}
|
||||
|
||||
static void __init imx6sl_timer_init(void)
|
||||
{
|
||||
of_clk_init(NULL);
|
||||
}
|
||||
|
||||
static const char *imx6sl_dt_compat[] __initdata = {
|
||||
"fsl,imx6sl",
|
||||
NULL,
|
||||
};
|
||||
|
||||
DT_MACHINE_START(IMX6SL, "Freescale i.MX6 SoloLite (Device Tree)")
|
||||
.map_io = debug_ll_io_init,
|
||||
.init_irq = imx6sl_init_irq,
|
||||
.init_time = imx6sl_timer_init,
|
||||
.init_machine = imx6sl_init_machine,
|
||||
.dt_compat = imx6sl_dt_compat,
|
||||
.restart = mxc_restart,
|
||||
MACHINE_END
|
@ -398,8 +398,8 @@ static void __init pca100_init(void)
|
||||
imx27_add_fsl_usb2_udc(&otg_device_pdata);
|
||||
}
|
||||
|
||||
usbh2_pdata.otg = otg_ulpi_create(&mxc_ulpi_access_ops,
|
||||
ULPI_OTG_DRVVBUS | ULPI_OTG_DRVVBUS_EXT);
|
||||
usbh2_pdata.otg = imx_otg_ulpi_create(
|
||||
ULPI_OTG_DRVVBUS | ULPI_OTG_DRVVBUS_EXT);
|
||||
|
||||
if (usbh2_pdata.otg)
|
||||
imx27_add_mxc_ehci_hs(2, &usbh2_pdata);
|
||||
|
48
arch/arm/mach-imx/mach-vf610.c
Normal file
48
arch/arm/mach-imx/mach-vf610.c
Normal file
@ -0,0 +1,48 @@
|
||||
/*
|
||||
* Copyright 2012-2013 Freescale Semiconductor, Inc.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*/
|
||||
|
||||
#include <linux/of_platform.h>
|
||||
#include <linux/clocksource.h>
|
||||
#include <linux/irqchip.h>
|
||||
#include <linux/clk-provider.h>
|
||||
#include <asm/mach/arch.h>
|
||||
#include <asm/hardware/cache-l2x0.h>
|
||||
|
||||
#include "common.h"
|
||||
|
||||
static void __init vf610_init_machine(void)
|
||||
{
|
||||
mxc_arch_reset_init_dt();
|
||||
of_platform_populate(NULL, of_default_bus_match_table, NULL, NULL);
|
||||
}
|
||||
|
||||
static void __init vf610_init_irq(void)
|
||||
{
|
||||
l2x0_of_init(0, ~0UL);
|
||||
irqchip_init();
|
||||
}
|
||||
|
||||
static void __init vf610_init_time(void)
|
||||
{
|
||||
of_clk_init(NULL);
|
||||
clocksource_of_init();
|
||||
}
|
||||
|
||||
static const char *vf610_dt_compat[] __initdata = {
|
||||
"fsl,vf610",
|
||||
NULL,
|
||||
};
|
||||
|
||||
DT_MACHINE_START(VYBRID_VF610, "Freescale Vybrid VF610 (Device Tree)")
|
||||
.init_irq = vf610_init_irq,
|
||||
.init_time = vf610_init_time,
|
||||
.init_machine = vf610_init_machine,
|
||||
.dt_compat = vf610_dt_compat,
|
||||
.restart = mxc_restart,
|
||||
MACHINE_END
|
@ -39,7 +39,6 @@ void __init mx1_map_io(void)
|
||||
void __init imx1_init_early(void)
|
||||
{
|
||||
mxc_set_cpu_type(MXC_CPU_MX1);
|
||||
mxc_arch_reset_init(MX1_IO_ADDRESS(MX1_WDT_BASE_ADDR));
|
||||
imx_iomuxv1_init(MX1_IO_ADDRESS(MX1_GPIO_BASE_ADDR),
|
||||
MX1_NUM_GPIO_PORT);
|
||||
}
|
||||
@ -51,6 +50,7 @@ void __init mx1_init_irq(void)
|
||||
|
||||
void __init imx1_soc_init(void)
|
||||
{
|
||||
mxc_arch_reset_init(MX1_IO_ADDRESS(MX1_WDT_BASE_ADDR));
|
||||
mxc_device_init();
|
||||
|
||||
mxc_register_gpio("imx1-gpio", 0, MX1_GPIO1_BASE_ADDR, SZ_256,
|
||||
|
@ -66,7 +66,6 @@ void __init mx21_map_io(void)
|
||||
void __init imx21_init_early(void)
|
||||
{
|
||||
mxc_set_cpu_type(MXC_CPU_MX21);
|
||||
mxc_arch_reset_init(MX21_IO_ADDRESS(MX21_WDOG_BASE_ADDR));
|
||||
imx_iomuxv1_init(MX21_IO_ADDRESS(MX21_GPIO_BASE_ADDR),
|
||||
MX21_NUM_GPIO_PORT);
|
||||
}
|
||||
@ -82,6 +81,7 @@ static const struct resource imx21_audmux_res[] __initconst = {
|
||||
|
||||
void __init imx21_soc_init(void)
|
||||
{
|
||||
mxc_arch_reset_init(MX21_IO_ADDRESS(MX21_WDOG_BASE_ADDR));
|
||||
mxc_device_init();
|
||||
|
||||
mxc_register_gpio("imx21-gpio", 0, MX21_GPIO1_BASE_ADDR, SZ_256, MX21_INT_GPIO, 0);
|
||||
|
@ -54,7 +54,6 @@ void __init imx25_init_early(void)
|
||||
{
|
||||
mxc_set_cpu_type(MXC_CPU_MX25);
|
||||
mxc_iomux_v3_init(MX25_IO_ADDRESS(MX25_IOMUXC_BASE_ADDR));
|
||||
mxc_arch_reset_init(MX25_IO_ADDRESS(MX25_WDOG_BASE_ADDR));
|
||||
}
|
||||
|
||||
void __init mx25_init_irq(void)
|
||||
@ -89,6 +88,7 @@ static const struct resource imx25_audmux_res[] __initconst = {
|
||||
|
||||
void __init imx25_soc_init(void)
|
||||
{
|
||||
mxc_arch_reset_init(MX25_IO_ADDRESS(MX25_WDOG_BASE_ADDR));
|
||||
mxc_device_init();
|
||||
|
||||
/* i.mx25 has the i.mx35 type gpio */
|
||||
|
@ -66,7 +66,6 @@ void __init mx27_map_io(void)
|
||||
void __init imx27_init_early(void)
|
||||
{
|
||||
mxc_set_cpu_type(MXC_CPU_MX27);
|
||||
mxc_arch_reset_init(MX27_IO_ADDRESS(MX27_WDOG_BASE_ADDR));
|
||||
imx_iomuxv1_init(MX27_IO_ADDRESS(MX27_GPIO_BASE_ADDR),
|
||||
MX27_NUM_GPIO_PORT);
|
||||
}
|
||||
@ -82,6 +81,7 @@ static const struct resource imx27_audmux_res[] __initconst = {
|
||||
|
||||
void __init imx27_soc_init(void)
|
||||
{
|
||||
mxc_arch_reset_init(MX27_IO_ADDRESS(MX27_WDOG_BASE_ADDR));
|
||||
mxc_device_init();
|
||||
|
||||
/* i.mx27 has the i.mx21 type gpio */
|
||||
|
@ -138,7 +138,6 @@ void __init mx31_map_io(void)
|
||||
void __init imx31_init_early(void)
|
||||
{
|
||||
mxc_set_cpu_type(MXC_CPU_MX31);
|
||||
mxc_arch_reset_init(MX31_IO_ADDRESS(MX31_WDOG_BASE_ADDR));
|
||||
arch_ioremap_caller = imx3_ioremap_caller;
|
||||
arm_pm_idle = imx3_idle;
|
||||
mx3_ccm_base = MX31_IO_ADDRESS(MX31_CCM_BASE_ADDR);
|
||||
@ -174,6 +173,7 @@ void __init imx31_soc_init(void)
|
||||
|
||||
imx3_init_l2x0();
|
||||
|
||||
mxc_arch_reset_init(MX31_IO_ADDRESS(MX31_WDOG_BASE_ADDR));
|
||||
mxc_device_init();
|
||||
|
||||
mxc_register_gpio("imx31-gpio", 0, MX31_GPIO1_BASE_ADDR, SZ_16K, MX31_INT_GPIO1, 0);
|
||||
@ -216,7 +216,6 @@ void __init imx35_init_early(void)
|
||||
{
|
||||
mxc_set_cpu_type(MXC_CPU_MX35);
|
||||
mxc_iomux_v3_init(MX35_IO_ADDRESS(MX35_IOMUXC_BASE_ADDR));
|
||||
mxc_arch_reset_init(MX35_IO_ADDRESS(MX35_WDOG_BASE_ADDR));
|
||||
arm_pm_idle = imx3_idle;
|
||||
arch_ioremap_caller = imx3_ioremap_caller;
|
||||
mx3_ccm_base = MX35_IO_ADDRESS(MX35_CCM_BASE_ADDR);
|
||||
@ -272,6 +271,7 @@ void __init imx35_soc_init(void)
|
||||
|
||||
imx3_init_l2x0();
|
||||
|
||||
mxc_arch_reset_init(MX35_IO_ADDRESS(MX35_WDOG_BASE_ADDR));
|
||||
mxc_device_init();
|
||||
|
||||
mxc_register_gpio("imx35-gpio", 0, MX35_GPIO1_BASE_ADDR, SZ_16K, MX35_INT_GPIO1, 0);
|
||||
|
@ -83,7 +83,6 @@ void __init imx51_init_early(void)
|
||||
imx51_ipu_mipi_setup();
|
||||
mxc_set_cpu_type(MXC_CPU_MX51);
|
||||
mxc_iomux_v3_init(MX51_IO_ADDRESS(MX51_IOMUXC_BASE_ADDR));
|
||||
mxc_arch_reset_init(MX51_IO_ADDRESS(MX51_WDOG1_BASE_ADDR));
|
||||
imx_src_init();
|
||||
}
|
||||
|
||||
@ -91,7 +90,6 @@ void __init imx53_init_early(void)
|
||||
{
|
||||
mxc_set_cpu_type(MXC_CPU_MX53);
|
||||
mxc_iomux_v3_init(MX53_IO_ADDRESS(MX53_IOMUXC_BASE_ADDR));
|
||||
mxc_arch_reset_init(MX53_IO_ADDRESS(MX53_WDOG1_BASE_ADDR));
|
||||
imx_src_init();
|
||||
}
|
||||
|
||||
@ -129,6 +127,7 @@ static const struct resource imx51_audmux_res[] __initconst = {
|
||||
|
||||
void __init imx51_soc_init(void)
|
||||
{
|
||||
mxc_arch_reset_init(MX51_IO_ADDRESS(MX51_WDOG1_BASE_ADDR));
|
||||
mxc_device_init();
|
||||
|
||||
/* i.mx51 has the i.mx35 type gpio */
|
||||
|
@ -21,6 +21,8 @@
|
||||
#include <linux/io.h>
|
||||
#include <linux/err.h>
|
||||
#include <linux/delay.h>
|
||||
#include <linux/of.h>
|
||||
#include <linux/of_address.h>
|
||||
|
||||
#include <asm/system_misc.h>
|
||||
#include <asm/proc-fns.h>
|
||||
@ -30,6 +32,7 @@
|
||||
#include "hardware.h"
|
||||
|
||||
static void __iomem *wdog_base;
|
||||
static struct clk *wdog_clk;
|
||||
|
||||
/*
|
||||
* Reset the system. It is called by machine_restart().
|
||||
@ -38,16 +41,13 @@ void mxc_restart(char mode, const char *cmd)
|
||||
{
|
||||
unsigned int wcr_enable;
|
||||
|
||||
if (cpu_is_mx1()) {
|
||||
wcr_enable = (1 << 0);
|
||||
} else {
|
||||
struct clk *clk;
|
||||
if (wdog_clk)
|
||||
clk_enable(wdog_clk);
|
||||
|
||||
clk = clk_get_sys("imx2-wdt.0", NULL);
|
||||
if (!IS_ERR(clk))
|
||||
clk_prepare_enable(clk);
|
||||
if (cpu_is_mx1())
|
||||
wcr_enable = (1 << 0);
|
||||
else
|
||||
wcr_enable = (1 << 2);
|
||||
}
|
||||
|
||||
/* Assert SRS signal */
|
||||
__raw_writew(wcr_enable, wdog_base);
|
||||
@ -55,7 +55,7 @@ void mxc_restart(char mode, const char *cmd)
|
||||
/* wait for reset to assert... */
|
||||
mdelay(500);
|
||||
|
||||
printk(KERN_ERR "Watchdog reset failed to assert reset\n");
|
||||
pr_err("%s: Watchdog reset failed to assert reset\n", __func__);
|
||||
|
||||
/* delay to allow the serial port to show the message */
|
||||
mdelay(50);
|
||||
@ -64,7 +64,34 @@ void mxc_restart(char mode, const char *cmd)
|
||||
soft_restart(0);
|
||||
}
|
||||
|
||||
void mxc_arch_reset_init(void __iomem *base)
|
||||
void __init mxc_arch_reset_init(void __iomem *base)
|
||||
{
|
||||
wdog_base = base;
|
||||
|
||||
wdog_clk = clk_get_sys("imx2-wdt.0", NULL);
|
||||
if (IS_ERR(wdog_clk)) {
|
||||
pr_warn("%s: failed to get wdog clock\n", __func__);
|
||||
wdog_clk = NULL;
|
||||
return;
|
||||
}
|
||||
|
||||
clk_prepare(wdog_clk);
|
||||
}
|
||||
|
||||
void __init mxc_arch_reset_init_dt(void)
|
||||
{
|
||||
struct device_node *np;
|
||||
|
||||
np = of_find_compatible_node(NULL, NULL, "fsl,imx21-wdt");
|
||||
wdog_base = of_iomap(np, 0);
|
||||
WARN_ON(!wdog_base);
|
||||
|
||||
wdog_clk = of_clk_get(np, 0);
|
||||
if (IS_ERR(wdog_clk)) {
|
||||
pr_warn("%s: failed to get wdog clock\n", __func__);
|
||||
wdog_clk = NULL;
|
||||
return;
|
||||
}
|
||||
|
||||
clk_prepare(wdog_clk);
|
||||
}
|
||||
|
@ -1,118 +0,0 @@
|
||||
/*
|
||||
* Copyright 2008 Sascha Hauer, Pengutronix <s.hauer@pengutronix.de>
|
||||
* Copyright 2009 Daniel Mack <daniel@caiaq.de>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* 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 Street, Fifth Floor, Boston,
|
||||
* MA 02110-1301, USA.
|
||||
*/
|
||||
|
||||
#include <linux/module.h>
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/io.h>
|
||||
#include <linux/delay.h>
|
||||
#include <linux/usb/otg.h>
|
||||
#include <linux/usb/ulpi.h>
|
||||
|
||||
#include "ulpi.h"
|
||||
|
||||
/* ULPIVIEW register bits */
|
||||
#define ULPIVW_WU (1 << 31) /* Wakeup */
|
||||
#define ULPIVW_RUN (1 << 30) /* read/write run */
|
||||
#define ULPIVW_WRITE (1 << 29) /* 0 = read 1 = write */
|
||||
#define ULPIVW_SS (1 << 27) /* SyncState */
|
||||
#define ULPIVW_PORT_MASK 0x07 /* Port field */
|
||||
#define ULPIVW_PORT_SHIFT 24
|
||||
#define ULPIVW_ADDR_MASK 0xff /* data address field */
|
||||
#define ULPIVW_ADDR_SHIFT 16
|
||||
#define ULPIVW_RDATA_MASK 0xff /* read data field */
|
||||
#define ULPIVW_RDATA_SHIFT 8
|
||||
#define ULPIVW_WDATA_MASK 0xff /* write data field */
|
||||
#define ULPIVW_WDATA_SHIFT 0
|
||||
|
||||
static int ulpi_poll(void __iomem *view, u32 bit)
|
||||
{
|
||||
int timeout = 10000;
|
||||
|
||||
while (timeout--) {
|
||||
u32 data = __raw_readl(view);
|
||||
|
||||
if (!(data & bit))
|
||||
return 0;
|
||||
|
||||
cpu_relax();
|
||||
};
|
||||
|
||||
printk(KERN_WARNING "timeout polling for ULPI device\n");
|
||||
|
||||
return -ETIMEDOUT;
|
||||
}
|
||||
|
||||
static int ulpi_read(struct usb_phy *otg, u32 reg)
|
||||
{
|
||||
int ret;
|
||||
void __iomem *view = otg->io_priv;
|
||||
|
||||
/* make sure interface is running */
|
||||
if (!(__raw_readl(view) & ULPIVW_SS)) {
|
||||
__raw_writel(ULPIVW_WU, view);
|
||||
|
||||
/* wait for wakeup */
|
||||
ret = ulpi_poll(view, ULPIVW_WU);
|
||||
if (ret)
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* read the register */
|
||||
__raw_writel((ULPIVW_RUN | (reg << ULPIVW_ADDR_SHIFT)), view);
|
||||
|
||||
/* wait for completion */
|
||||
ret = ulpi_poll(view, ULPIVW_RUN);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
return (__raw_readl(view) >> ULPIVW_RDATA_SHIFT) & ULPIVW_RDATA_MASK;
|
||||
}
|
||||
|
||||
static int ulpi_write(struct usb_phy *otg, u32 val, u32 reg)
|
||||
{
|
||||
int ret;
|
||||
void __iomem *view = otg->io_priv;
|
||||
|
||||
/* make sure the interface is running */
|
||||
if (!(__raw_readl(view) & ULPIVW_SS)) {
|
||||
__raw_writel(ULPIVW_WU, view);
|
||||
/* wait for wakeup */
|
||||
ret = ulpi_poll(view, ULPIVW_WU);
|
||||
if (ret)
|
||||
return ret;
|
||||
}
|
||||
|
||||
__raw_writel((ULPIVW_RUN | ULPIVW_WRITE |
|
||||
(reg << ULPIVW_ADDR_SHIFT) |
|
||||
((val & ULPIVW_WDATA_MASK) << ULPIVW_WDATA_SHIFT)), view);
|
||||
|
||||
/* wait for completion */
|
||||
return ulpi_poll(view, ULPIVW_RUN);
|
||||
}
|
||||
|
||||
struct usb_phy_io_ops mxc_ulpi_access_ops = {
|
||||
.read = ulpi_read,
|
||||
.write = ulpi_write,
|
||||
};
|
||||
EXPORT_SYMBOL_GPL(mxc_ulpi_access_ops);
|
||||
|
||||
struct usb_phy *imx_otg_ulpi_create(unsigned int flags)
|
||||
{
|
||||
return otg_ulpi_create(&mxc_ulpi_access_ops, flags);
|
||||
}
|
@ -1,8 +1,13 @@
|
||||
#ifndef __MACH_ULPI_H
|
||||
#define __MACH_ULPI_H
|
||||
|
||||
#ifdef CONFIG_USB_ULPI
|
||||
struct usb_phy *imx_otg_ulpi_create(unsigned int flags);
|
||||
#include <linux/usb/ulpi.h>
|
||||
|
||||
#ifdef CONFIG_USB_ULPI_VIEWPORT
|
||||
static inline struct usb_phy *imx_otg_ulpi_create(unsigned int flags)
|
||||
{
|
||||
return otg_ulpi_create(&ulpi_viewport_access_ops, flags);
|
||||
}
|
||||
#else
|
||||
static inline struct usb_phy *imx_otg_ulpi_create(unsigned int flags)
|
||||
{
|
||||
@ -10,7 +15,5 @@ static inline struct usb_phy *imx_otg_ulpi_create(unsigned int flags)
|
||||
}
|
||||
#endif
|
||||
|
||||
extern struct usb_phy_io_ops mxc_ulpi_access_ops;
|
||||
|
||||
#endif /* __MACH_ULPI_H */
|
||||
|
||||
|
@ -22,9 +22,10 @@ static unsigned int __init kirkwood_variant(void)
|
||||
|
||||
kirkwood_pcie_id(&dev, &rev);
|
||||
|
||||
if ((dev == MV88F6281_DEV_ID && rev >= MV88F6281_REV_A0) ||
|
||||
(dev == MV88F6282_DEV_ID))
|
||||
if (dev == MV88F6281_DEV_ID && rev >= MV88F6281_REV_A0)
|
||||
return MPP_F6281_MASK;
|
||||
if (dev == MV88F6282_DEV_ID)
|
||||
return MPP_F6282_MASK;
|
||||
if (dev == MV88F6192_DEV_ID && rev >= MV88F6192_REV_A0)
|
||||
return MPP_F6192_MASK;
|
||||
if (dev == MV88F6180_DEV_ID)
|
||||
|
@ -20,11 +20,12 @@
|
||||
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/clk.h>
|
||||
#include <linux/clk-provider.h>
|
||||
#include <linux/io.h>
|
||||
|
||||
#include "clock.h"
|
||||
#include "clock36xx.h"
|
||||
|
||||
#define to_clk_divider(_hw) container_of(_hw, struct clk_divider, hw)
|
||||
|
||||
/**
|
||||
* omap36xx_pwrdn_clk_enable_with_hsdiv_restore - enable clocks suffering
|
||||
@ -39,29 +40,28 @@
|
||||
*/
|
||||
int omap36xx_pwrdn_clk_enable_with_hsdiv_restore(struct clk_hw *clk)
|
||||
{
|
||||
struct clk_hw_omap *parent;
|
||||
struct clk_divider *parent;
|
||||
struct clk_hw *parent_hw;
|
||||
u32 dummy_v, orig_v, clksel_shift;
|
||||
u32 dummy_v, orig_v;
|
||||
int ret;
|
||||
|
||||
/* Clear PWRDN bit of HSDIVIDER */
|
||||
ret = omap2_dflt_clk_enable(clk);
|
||||
|
||||
parent_hw = __clk_get_hw(__clk_get_parent(clk->clk));
|
||||
parent = to_clk_hw_omap(parent_hw);
|
||||
parent = to_clk_divider(parent_hw);
|
||||
|
||||
/* Restore the dividers */
|
||||
if (!ret) {
|
||||
clksel_shift = __ffs(parent->clksel_mask);
|
||||
orig_v = __raw_readl(parent->clksel_reg);
|
||||
orig_v = __raw_readl(parent->reg);
|
||||
dummy_v = orig_v;
|
||||
|
||||
/* Write any other value different from the Read value */
|
||||
dummy_v ^= (1 << clksel_shift);
|
||||
__raw_writel(dummy_v, parent->clksel_reg);
|
||||
dummy_v ^= (1 << parent->shift);
|
||||
__raw_writel(dummy_v, parent->reg);
|
||||
|
||||
/* Write the original divider */
|
||||
__raw_writel(orig_v, parent->clksel_reg);
|
||||
__raw_writel(orig_v, parent->reg);
|
||||
}
|
||||
|
||||
return ret;
|
||||
|
@ -2008,6 +2008,13 @@ static struct omap_hwmod am33xx_uart1_hwmod = {
|
||||
},
|
||||
};
|
||||
|
||||
/* uart2 */
|
||||
static struct omap_hwmod_dma_info uart2_edma_reqs[] = {
|
||||
{ .name = "tx", .dma_req = 28, },
|
||||
{ .name = "rx", .dma_req = 29, },
|
||||
{ .dma_req = -1 }
|
||||
};
|
||||
|
||||
static struct omap_hwmod_irq_info am33xx_uart2_irqs[] = {
|
||||
{ .irq = 73 + OMAP_INTC_START, },
|
||||
{ .irq = -1 },
|
||||
@ -2019,7 +2026,7 @@ static struct omap_hwmod am33xx_uart2_hwmod = {
|
||||
.clkdm_name = "l4ls_clkdm",
|
||||
.flags = HWMOD_SWSUP_SIDLE_ACT,
|
||||
.mpu_irqs = am33xx_uart2_irqs,
|
||||
.sdma_reqs = uart1_edma_reqs,
|
||||
.sdma_reqs = uart2_edma_reqs,
|
||||
.main_clk = "dpll_per_m2_div4_ck",
|
||||
.prcm = {
|
||||
.omap4 = {
|
||||
|
@ -546,8 +546,10 @@ static void __init prcm_setup_regs(void)
|
||||
/* Clear any pending PRCM interrupts */
|
||||
omap2_prm_write_mod_reg(0, OCP_MOD, OMAP3_PRM_IRQSTATUS_MPU_OFFSET);
|
||||
|
||||
if (omap3_has_iva())
|
||||
omap3_iva_idle();
|
||||
/*
|
||||
* We need to idle iva2_pwrdm even on am3703 with no iva2.
|
||||
*/
|
||||
omap3_iva_idle();
|
||||
|
||||
omap3_d2d_idle();
|
||||
}
|
||||
|
@ -101,8 +101,10 @@ static int __init sirfsoc_of_pwrc_init(void)
|
||||
struct device_node *np;
|
||||
|
||||
np = of_find_matching_node(NULL, pwrc_ids);
|
||||
if (!np)
|
||||
panic("unable to find compatible pwrc node in dtb\n");
|
||||
if (!np) {
|
||||
pr_err("unable to find compatible sirf pwrc node in dtb\n");
|
||||
return -ENOENT;
|
||||
}
|
||||
|
||||
/*
|
||||
* pwrc behind rtciobrg is not located in memory space
|
||||
|
@ -28,8 +28,10 @@ static int __init sirfsoc_of_rstc_init(void)
|
||||
struct device_node *np;
|
||||
|
||||
np = of_find_matching_node(NULL, rstc_ids);
|
||||
if (!np)
|
||||
panic("unable to find compatible rstc node in dtb\n");
|
||||
if (!np) {
|
||||
pr_err("unable to find compatible sirf rstc node in dtb\n");
|
||||
return -ENOENT;
|
||||
}
|
||||
|
||||
sirfsoc_rstc_base = of_iomap(np, 0);
|
||||
if (!sirfsoc_rstc_base)
|
||||
|
@ -16,6 +16,7 @@
|
||||
#include <linux/suspend.h>
|
||||
#include <linux/errno.h>
|
||||
#include <linux/delay.h>
|
||||
#include <linux/of.h>
|
||||
#include <linux/serial_core.h>
|
||||
#include <linux/io.h>
|
||||
|
||||
@ -261,7 +262,8 @@ static int s3c_pm_enter(suspend_state_t state)
|
||||
* require a full power-cycle)
|
||||
*/
|
||||
|
||||
if (!any_allowed(s3c_irqwake_intmask, s3c_irqwake_intallow) &&
|
||||
if (!of_have_populated_dt() &&
|
||||
!any_allowed(s3c_irqwake_intmask, s3c_irqwake_intallow) &&
|
||||
!any_allowed(s3c_irqwake_eintmask, s3c_irqwake_eintallow)) {
|
||||
printk(KERN_ERR "%s: No wake-up sources!\n", __func__);
|
||||
printk(KERN_ERR "%s: Aborting sleep\n", __func__);
|
||||
@ -270,8 +272,11 @@ static int s3c_pm_enter(suspend_state_t state)
|
||||
|
||||
/* save all necessary core registers not covered by the drivers */
|
||||
|
||||
samsung_pm_save_gpios();
|
||||
samsung_pm_saved_gpios();
|
||||
if (!of_have_populated_dt()) {
|
||||
samsung_pm_save_gpios();
|
||||
samsung_pm_saved_gpios();
|
||||
}
|
||||
|
||||
s3c_pm_save_uarts();
|
||||
s3c_pm_save_core();
|
||||
|
||||
@ -310,8 +315,11 @@ static int s3c_pm_enter(suspend_state_t state)
|
||||
|
||||
s3c_pm_restore_core();
|
||||
s3c_pm_restore_uarts();
|
||||
samsung_pm_restore_gpios();
|
||||
s3c_pm_restored_gpios();
|
||||
|
||||
if (!of_have_populated_dt()) {
|
||||
samsung_pm_restore_gpios();
|
||||
s3c_pm_restored_gpios();
|
||||
}
|
||||
|
||||
s3c_pm_debug_init();
|
||||
|
||||
|
@ -117,7 +117,7 @@ get_new_mmu_context(struct mm_struct *mm, unsigned long cpu)
|
||||
if (! ((asid += ASID_INC) & ASID_MASK) ) {
|
||||
if (cpu_has_vtag_icache)
|
||||
flush_icache_all();
|
||||
#ifdef CONFIG_VIRTUALIZATION
|
||||
#ifdef CONFIG_KVM
|
||||
kvm_local_flush_tlb_all(); /* start new asid cycle */
|
||||
#else
|
||||
local_flush_tlb_all(); /* start new asid cycle */
|
||||
|
@ -58,56 +58,53 @@ struct kvm_fpu {
|
||||
* bits[2..0] - Register 'sel' index.
|
||||
* bits[7..3] - Register 'rd' index.
|
||||
* bits[15..8] - Must be zero.
|
||||
* bits[63..16] - 1 -> CP0 registers.
|
||||
* bits[31..16] - 1 -> CP0 registers.
|
||||
* bits[51..32] - Must be zero.
|
||||
* bits[63..52] - As per linux/kvm.h
|
||||
*
|
||||
* Other sets registers may be added in the future. Each set would
|
||||
* have its own identifier in bits[63..16].
|
||||
*
|
||||
* The addr field of struct kvm_one_reg must point to an aligned
|
||||
* 64-bit wide location. For registers that are narrower than
|
||||
* 64-bits, the value is stored in the low order bits of the location,
|
||||
* and sign extended to 64-bits.
|
||||
* have its own identifier in bits[31..16].
|
||||
*
|
||||
* The registers defined in struct kvm_regs are also accessible, the
|
||||
* id values for these are below.
|
||||
*/
|
||||
|
||||
#define KVM_REG_MIPS_R0 0
|
||||
#define KVM_REG_MIPS_R1 1
|
||||
#define KVM_REG_MIPS_R2 2
|
||||
#define KVM_REG_MIPS_R3 3
|
||||
#define KVM_REG_MIPS_R4 4
|
||||
#define KVM_REG_MIPS_R5 5
|
||||
#define KVM_REG_MIPS_R6 6
|
||||
#define KVM_REG_MIPS_R7 7
|
||||
#define KVM_REG_MIPS_R8 8
|
||||
#define KVM_REG_MIPS_R9 9
|
||||
#define KVM_REG_MIPS_R10 10
|
||||
#define KVM_REG_MIPS_R11 11
|
||||
#define KVM_REG_MIPS_R12 12
|
||||
#define KVM_REG_MIPS_R13 13
|
||||
#define KVM_REG_MIPS_R14 14
|
||||
#define KVM_REG_MIPS_R15 15
|
||||
#define KVM_REG_MIPS_R16 16
|
||||
#define KVM_REG_MIPS_R17 17
|
||||
#define KVM_REG_MIPS_R18 18
|
||||
#define KVM_REG_MIPS_R19 19
|
||||
#define KVM_REG_MIPS_R20 20
|
||||
#define KVM_REG_MIPS_R21 21
|
||||
#define KVM_REG_MIPS_R22 22
|
||||
#define KVM_REG_MIPS_R23 23
|
||||
#define KVM_REG_MIPS_R24 24
|
||||
#define KVM_REG_MIPS_R25 25
|
||||
#define KVM_REG_MIPS_R26 26
|
||||
#define KVM_REG_MIPS_R27 27
|
||||
#define KVM_REG_MIPS_R28 28
|
||||
#define KVM_REG_MIPS_R29 29
|
||||
#define KVM_REG_MIPS_R30 30
|
||||
#define KVM_REG_MIPS_R31 31
|
||||
#define KVM_REG_MIPS_R0 (KVM_REG_MIPS | KVM_REG_SIZE_U64 | 0)
|
||||
#define KVM_REG_MIPS_R1 (KVM_REG_MIPS | KVM_REG_SIZE_U64 | 1)
|
||||
#define KVM_REG_MIPS_R2 (KVM_REG_MIPS | KVM_REG_SIZE_U64 | 2)
|
||||
#define KVM_REG_MIPS_R3 (KVM_REG_MIPS | KVM_REG_SIZE_U64 | 3)
|
||||
#define KVM_REG_MIPS_R4 (KVM_REG_MIPS | KVM_REG_SIZE_U64 | 4)
|
||||
#define KVM_REG_MIPS_R5 (KVM_REG_MIPS | KVM_REG_SIZE_U64 | 5)
|
||||
#define KVM_REG_MIPS_R6 (KVM_REG_MIPS | KVM_REG_SIZE_U64 | 6)
|
||||
#define KVM_REG_MIPS_R7 (KVM_REG_MIPS | KVM_REG_SIZE_U64 | 7)
|
||||
#define KVM_REG_MIPS_R8 (KVM_REG_MIPS | KVM_REG_SIZE_U64 | 8)
|
||||
#define KVM_REG_MIPS_R9 (KVM_REG_MIPS | KVM_REG_SIZE_U64 | 9)
|
||||
#define KVM_REG_MIPS_R10 (KVM_REG_MIPS | KVM_REG_SIZE_U64 | 10)
|
||||
#define KVM_REG_MIPS_R11 (KVM_REG_MIPS | KVM_REG_SIZE_U64 | 11)
|
||||
#define KVM_REG_MIPS_R12 (KVM_REG_MIPS | KVM_REG_SIZE_U64 | 12)
|
||||
#define KVM_REG_MIPS_R13 (KVM_REG_MIPS | KVM_REG_SIZE_U64 | 13)
|
||||
#define KVM_REG_MIPS_R14 (KVM_REG_MIPS | KVM_REG_SIZE_U64 | 14)
|
||||
#define KVM_REG_MIPS_R15 (KVM_REG_MIPS | KVM_REG_SIZE_U64 | 15)
|
||||
#define KVM_REG_MIPS_R16 (KVM_REG_MIPS | KVM_REG_SIZE_U64 | 16)
|
||||
#define KVM_REG_MIPS_R17 (KVM_REG_MIPS | KVM_REG_SIZE_U64 | 17)
|
||||
#define KVM_REG_MIPS_R18 (KVM_REG_MIPS | KVM_REG_SIZE_U64 | 18)
|
||||
#define KVM_REG_MIPS_R19 (KVM_REG_MIPS | KVM_REG_SIZE_U64 | 19)
|
||||
#define KVM_REG_MIPS_R20 (KVM_REG_MIPS | KVM_REG_SIZE_U64 | 20)
|
||||
#define KVM_REG_MIPS_R21 (KVM_REG_MIPS | KVM_REG_SIZE_U64 | 21)
|
||||
#define KVM_REG_MIPS_R22 (KVM_REG_MIPS | KVM_REG_SIZE_U64 | 22)
|
||||
#define KVM_REG_MIPS_R23 (KVM_REG_MIPS | KVM_REG_SIZE_U64 | 23)
|
||||
#define KVM_REG_MIPS_R24 (KVM_REG_MIPS | KVM_REG_SIZE_U64 | 24)
|
||||
#define KVM_REG_MIPS_R25 (KVM_REG_MIPS | KVM_REG_SIZE_U64 | 25)
|
||||
#define KVM_REG_MIPS_R26 (KVM_REG_MIPS | KVM_REG_SIZE_U64 | 26)
|
||||
#define KVM_REG_MIPS_R27 (KVM_REG_MIPS | KVM_REG_SIZE_U64 | 27)
|
||||
#define KVM_REG_MIPS_R28 (KVM_REG_MIPS | KVM_REG_SIZE_U64 | 28)
|
||||
#define KVM_REG_MIPS_R29 (KVM_REG_MIPS | KVM_REG_SIZE_U64 | 29)
|
||||
#define KVM_REG_MIPS_R30 (KVM_REG_MIPS | KVM_REG_SIZE_U64 | 30)
|
||||
#define KVM_REG_MIPS_R31 (KVM_REG_MIPS | KVM_REG_SIZE_U64 | 31)
|
||||
|
||||
#define KVM_REG_MIPS_HI 32
|
||||
#define KVM_REG_MIPS_LO 33
|
||||
#define KVM_REG_MIPS_PC 34
|
||||
#define KVM_REG_MIPS_HI (KVM_REG_MIPS | KVM_REG_SIZE_U64 | 32)
|
||||
#define KVM_REG_MIPS_LO (KVM_REG_MIPS | KVM_REG_SIZE_U64 | 33)
|
||||
#define KVM_REG_MIPS_PC (KVM_REG_MIPS | KVM_REG_SIZE_U64 | 34)
|
||||
|
||||
/*
|
||||
* KVM MIPS specific structures and definitions
|
||||
|
@ -25,12 +25,16 @@
|
||||
#define MCOUNT_OFFSET_INSNS 4
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_DYNAMIC_FTRACE
|
||||
|
||||
/* Arch override because MIPS doesn't need to run this from stop_machine() */
|
||||
void arch_ftrace_update_code(int command)
|
||||
{
|
||||
ftrace_modify_all_code(command);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Check if the address is in kernel space
|
||||
*
|
||||
|
@ -93,26 +93,27 @@ static void rm7k_wait_irqoff(void)
|
||||
}
|
||||
|
||||
/*
|
||||
* The Au1xxx wait is available only if using 32khz counter or
|
||||
* external timer source, but specifically not CP0 Counter.
|
||||
* alchemy/common/time.c may override cpu_wait!
|
||||
* Au1 'wait' is only useful when the 32kHz counter is used as timer,
|
||||
* since coreclock (and the cp0 counter) stops upon executing it. Only an
|
||||
* interrupt can wake it, so they must be enabled before entering idle modes.
|
||||
*/
|
||||
static void au1k_wait(void)
|
||||
{
|
||||
unsigned long c0status = read_c0_status() | 1; /* irqs on */
|
||||
|
||||
__asm__(
|
||||
" .set mips3 \n"
|
||||
" cache 0x14, 0(%0) \n"
|
||||
" cache 0x14, 32(%0) \n"
|
||||
" sync \n"
|
||||
" nop \n"
|
||||
" mtc0 %1, $12 \n" /* wr c0status */
|
||||
" wait \n"
|
||||
" nop \n"
|
||||
" nop \n"
|
||||
" nop \n"
|
||||
" nop \n"
|
||||
" .set mips0 \n"
|
||||
: : "r" (au1k_wait));
|
||||
local_irq_enable();
|
||||
: : "r" (au1k_wait), "r" (c0status));
|
||||
}
|
||||
|
||||
static int __initdata nowait;
|
||||
|
@ -485,29 +485,35 @@ kvm_arch_vcpu_ioctl_set_mpstate(struct kvm_vcpu *vcpu,
|
||||
return -ENOIOCTLCMD;
|
||||
}
|
||||
|
||||
#define KVM_REG_MIPS_CP0_INDEX (0x10000 + 8 * 0 + 0)
|
||||
#define KVM_REG_MIPS_CP0_ENTRYLO0 (0x10000 + 8 * 2 + 0)
|
||||
#define KVM_REG_MIPS_CP0_ENTRYLO1 (0x10000 + 8 * 3 + 0)
|
||||
#define KVM_REG_MIPS_CP0_CONTEXT (0x10000 + 8 * 4 + 0)
|
||||
#define KVM_REG_MIPS_CP0_USERLOCAL (0x10000 + 8 * 4 + 2)
|
||||
#define KVM_REG_MIPS_CP0_PAGEMASK (0x10000 + 8 * 5 + 0)
|
||||
#define KVM_REG_MIPS_CP0_PAGEGRAIN (0x10000 + 8 * 5 + 1)
|
||||
#define KVM_REG_MIPS_CP0_WIRED (0x10000 + 8 * 6 + 0)
|
||||
#define KVM_REG_MIPS_CP0_HWRENA (0x10000 + 8 * 7 + 0)
|
||||
#define KVM_REG_MIPS_CP0_BADVADDR (0x10000 + 8 * 8 + 0)
|
||||
#define KVM_REG_MIPS_CP0_COUNT (0x10000 + 8 * 9 + 0)
|
||||
#define KVM_REG_MIPS_CP0_ENTRYHI (0x10000 + 8 * 10 + 0)
|
||||
#define KVM_REG_MIPS_CP0_COMPARE (0x10000 + 8 * 11 + 0)
|
||||
#define KVM_REG_MIPS_CP0_STATUS (0x10000 + 8 * 12 + 0)
|
||||
#define KVM_REG_MIPS_CP0_CAUSE (0x10000 + 8 * 13 + 0)
|
||||
#define KVM_REG_MIPS_CP0_EBASE (0x10000 + 8 * 15 + 1)
|
||||
#define KVM_REG_MIPS_CP0_CONFIG (0x10000 + 8 * 16 + 0)
|
||||
#define KVM_REG_MIPS_CP0_CONFIG1 (0x10000 + 8 * 16 + 1)
|
||||
#define KVM_REG_MIPS_CP0_CONFIG2 (0x10000 + 8 * 16 + 2)
|
||||
#define KVM_REG_MIPS_CP0_CONFIG3 (0x10000 + 8 * 16 + 3)
|
||||
#define KVM_REG_MIPS_CP0_CONFIG7 (0x10000 + 8 * 16 + 7)
|
||||
#define KVM_REG_MIPS_CP0_XCONTEXT (0x10000 + 8 * 20 + 0)
|
||||
#define KVM_REG_MIPS_CP0_ERROREPC (0x10000 + 8 * 30 + 0)
|
||||
#define MIPS_CP0_32(_R, _S) \
|
||||
(KVM_REG_MIPS | KVM_REG_SIZE_U32 | 0x10000 | (8 * (_R) + (_S)))
|
||||
|
||||
#define MIPS_CP0_64(_R, _S) \
|
||||
(KVM_REG_MIPS | KVM_REG_SIZE_U64 | 0x10000 | (8 * (_R) + (_S)))
|
||||
|
||||
#define KVM_REG_MIPS_CP0_INDEX MIPS_CP0_32(0, 0)
|
||||
#define KVM_REG_MIPS_CP0_ENTRYLO0 MIPS_CP0_64(2, 0)
|
||||
#define KVM_REG_MIPS_CP0_ENTRYLO1 MIPS_CP0_64(3, 0)
|
||||
#define KVM_REG_MIPS_CP0_CONTEXT MIPS_CP0_64(4, 0)
|
||||
#define KVM_REG_MIPS_CP0_USERLOCAL MIPS_CP0_64(4, 2)
|
||||
#define KVM_REG_MIPS_CP0_PAGEMASK MIPS_CP0_32(5, 0)
|
||||
#define KVM_REG_MIPS_CP0_PAGEGRAIN MIPS_CP0_32(5, 1)
|
||||
#define KVM_REG_MIPS_CP0_WIRED MIPS_CP0_32(6, 0)
|
||||
#define KVM_REG_MIPS_CP0_HWRENA MIPS_CP0_32(7, 0)
|
||||
#define KVM_REG_MIPS_CP0_BADVADDR MIPS_CP0_64(8, 0)
|
||||
#define KVM_REG_MIPS_CP0_COUNT MIPS_CP0_32(9, 0)
|
||||
#define KVM_REG_MIPS_CP0_ENTRYHI MIPS_CP0_64(10, 0)
|
||||
#define KVM_REG_MIPS_CP0_COMPARE MIPS_CP0_32(11, 0)
|
||||
#define KVM_REG_MIPS_CP0_STATUS MIPS_CP0_32(12, 0)
|
||||
#define KVM_REG_MIPS_CP0_CAUSE MIPS_CP0_32(13, 0)
|
||||
#define KVM_REG_MIPS_CP0_EBASE MIPS_CP0_64(15, 1)
|
||||
#define KVM_REG_MIPS_CP0_CONFIG MIPS_CP0_32(16, 0)
|
||||
#define KVM_REG_MIPS_CP0_CONFIG1 MIPS_CP0_32(16, 1)
|
||||
#define KVM_REG_MIPS_CP0_CONFIG2 MIPS_CP0_32(16, 2)
|
||||
#define KVM_REG_MIPS_CP0_CONFIG3 MIPS_CP0_32(16, 3)
|
||||
#define KVM_REG_MIPS_CP0_CONFIG7 MIPS_CP0_32(16, 7)
|
||||
#define KVM_REG_MIPS_CP0_XCONTEXT MIPS_CP0_64(20, 0)
|
||||
#define KVM_REG_MIPS_CP0_ERROREPC MIPS_CP0_64(30, 0)
|
||||
|
||||
static u64 kvm_mips_get_one_regs[] = {
|
||||
KVM_REG_MIPS_R0,
|
||||
@ -567,8 +573,6 @@ static u64 kvm_mips_get_one_regs[] = {
|
||||
static int kvm_mips_get_reg(struct kvm_vcpu *vcpu,
|
||||
const struct kvm_one_reg *reg)
|
||||
{
|
||||
u64 __user *uaddr = (u64 __user *)(long)reg->addr;
|
||||
|
||||
struct mips_coproc *cop0 = vcpu->arch.cop0;
|
||||
s64 v;
|
||||
|
||||
@ -631,18 +635,39 @@ static int kvm_mips_get_reg(struct kvm_vcpu *vcpu,
|
||||
default:
|
||||
return -EINVAL;
|
||||
}
|
||||
return put_user(v, uaddr);
|
||||
if ((reg->id & KVM_REG_SIZE_MASK) == KVM_REG_SIZE_U64) {
|
||||
u64 __user *uaddr64 = (u64 __user *)(long)reg->addr;
|
||||
return put_user(v, uaddr64);
|
||||
} else if ((reg->id & KVM_REG_SIZE_MASK) == KVM_REG_SIZE_U32) {
|
||||
u32 __user *uaddr32 = (u32 __user *)(long)reg->addr;
|
||||
u32 v32 = (u32)v;
|
||||
return put_user(v32, uaddr32);
|
||||
} else {
|
||||
return -EINVAL;
|
||||
}
|
||||
}
|
||||
|
||||
static int kvm_mips_set_reg(struct kvm_vcpu *vcpu,
|
||||
const struct kvm_one_reg *reg)
|
||||
{
|
||||
u64 __user *uaddr = (u64 __user *)(long)reg->addr;
|
||||
struct mips_coproc *cop0 = vcpu->arch.cop0;
|
||||
u64 v;
|
||||
|
||||
if (get_user(v, uaddr) != 0)
|
||||
return -EFAULT;
|
||||
if ((reg->id & KVM_REG_SIZE_MASK) == KVM_REG_SIZE_U64) {
|
||||
u64 __user *uaddr64 = (u64 __user *)(long)reg->addr;
|
||||
|
||||
if (get_user(v, uaddr64) != 0)
|
||||
return -EFAULT;
|
||||
} else if ((reg->id & KVM_REG_SIZE_MASK) == KVM_REG_SIZE_U32) {
|
||||
u32 __user *uaddr32 = (u32 __user *)(long)reg->addr;
|
||||
s32 v32;
|
||||
|
||||
if (get_user(v32, uaddr32) != 0)
|
||||
return -EFAULT;
|
||||
v = (s64)v32;
|
||||
} else {
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
switch (reg->id) {
|
||||
case KVM_REG_MIPS_R0:
|
||||
|
@ -176,6 +176,7 @@ extern const char *powerpc_base_platform;
|
||||
#define CPU_FTR_CFAR LONG_ASM_CONST(0x0100000000000000)
|
||||
#define CPU_FTR_HAS_PPR LONG_ASM_CONST(0x0200000000000000)
|
||||
#define CPU_FTR_DAWR LONG_ASM_CONST(0x0400000000000000)
|
||||
#define CPU_FTR_DABRX LONG_ASM_CONST(0x0800000000000000)
|
||||
|
||||
#ifndef __ASSEMBLY__
|
||||
|
||||
@ -394,19 +395,20 @@ extern const char *powerpc_base_platform;
|
||||
CPU_FTR_PPCAS_ARCH_V2 | CPU_FTR_CTRL | CPU_FTR_ARCH_201 | \
|
||||
CPU_FTR_ALTIVEC_COMP | CPU_FTR_CAN_NAP | CPU_FTR_MMCRA | \
|
||||
CPU_FTR_CP_USE_DCBTZ | CPU_FTR_STCX_CHECKS_ADDRESS | \
|
||||
CPU_FTR_HVMODE)
|
||||
CPU_FTR_HVMODE | CPU_FTR_DABRX)
|
||||
#define CPU_FTRS_POWER5 (CPU_FTR_USE_TB | CPU_FTR_LWSYNC | \
|
||||
CPU_FTR_PPCAS_ARCH_V2 | CPU_FTR_CTRL | \
|
||||
CPU_FTR_MMCRA | CPU_FTR_SMT | \
|
||||
CPU_FTR_COHERENT_ICACHE | CPU_FTR_PURR | \
|
||||
CPU_FTR_STCX_CHECKS_ADDRESS | CPU_FTR_POPCNTB)
|
||||
CPU_FTR_STCX_CHECKS_ADDRESS | CPU_FTR_POPCNTB | CPU_FTR_DABRX)
|
||||
#define CPU_FTRS_POWER6 (CPU_FTR_USE_TB | CPU_FTR_LWSYNC | \
|
||||
CPU_FTR_PPCAS_ARCH_V2 | CPU_FTR_CTRL | \
|
||||
CPU_FTR_MMCRA | CPU_FTR_SMT | \
|
||||
CPU_FTR_COHERENT_ICACHE | \
|
||||
CPU_FTR_PURR | CPU_FTR_SPURR | CPU_FTR_REAL_LE | \
|
||||
CPU_FTR_DSCR | CPU_FTR_UNALIGNED_LD_STD | \
|
||||
CPU_FTR_STCX_CHECKS_ADDRESS | CPU_FTR_POPCNTB | CPU_FTR_CFAR)
|
||||
CPU_FTR_STCX_CHECKS_ADDRESS | CPU_FTR_POPCNTB | CPU_FTR_CFAR | \
|
||||
CPU_FTR_DABRX)
|
||||
#define CPU_FTRS_POWER7 (CPU_FTR_USE_TB | CPU_FTR_LWSYNC | \
|
||||
CPU_FTR_PPCAS_ARCH_V2 | CPU_FTR_CTRL | CPU_FTR_ARCH_206 |\
|
||||
CPU_FTR_MMCRA | CPU_FTR_SMT | \
|
||||
@ -415,7 +417,7 @@ extern const char *powerpc_base_platform;
|
||||
CPU_FTR_DSCR | CPU_FTR_SAO | CPU_FTR_ASYM_SMT | \
|
||||
CPU_FTR_STCX_CHECKS_ADDRESS | CPU_FTR_POPCNTB | CPU_FTR_POPCNTD | \
|
||||
CPU_FTR_ICSWX | CPU_FTR_CFAR | CPU_FTR_HVMODE | \
|
||||
CPU_FTR_VMX_COPY | CPU_FTR_HAS_PPR)
|
||||
CPU_FTR_VMX_COPY | CPU_FTR_HAS_PPR | CPU_FTR_DABRX)
|
||||
#define CPU_FTRS_POWER8 (CPU_FTR_USE_TB | CPU_FTR_LWSYNC | \
|
||||
CPU_FTR_PPCAS_ARCH_V2 | CPU_FTR_CTRL | CPU_FTR_ARCH_206 |\
|
||||
CPU_FTR_MMCRA | CPU_FTR_SMT | \
|
||||
@ -430,14 +432,15 @@ extern const char *powerpc_base_platform;
|
||||
CPU_FTR_PPCAS_ARCH_V2 | CPU_FTR_CTRL | \
|
||||
CPU_FTR_ALTIVEC_COMP | CPU_FTR_MMCRA | CPU_FTR_SMT | \
|
||||
CPU_FTR_PAUSE_ZERO | CPU_FTR_CELL_TB_BUG | CPU_FTR_CP_USE_DCBTZ | \
|
||||
CPU_FTR_UNALIGNED_LD_STD)
|
||||
CPU_FTR_UNALIGNED_LD_STD | CPU_FTR_DABRX)
|
||||
#define CPU_FTRS_PA6T (CPU_FTR_USE_TB | CPU_FTR_LWSYNC | \
|
||||
CPU_FTR_PPCAS_ARCH_V2 | CPU_FTR_ALTIVEC_COMP | \
|
||||
CPU_FTR_PURR | CPU_FTR_REAL_LE)
|
||||
CPU_FTR_PURR | CPU_FTR_REAL_LE | CPU_FTR_DABRX)
|
||||
#define CPU_FTRS_COMPATIBLE (CPU_FTR_USE_TB | CPU_FTR_PPCAS_ARCH_V2)
|
||||
|
||||
#define CPU_FTRS_A2 (CPU_FTR_USE_TB | CPU_FTR_SMT | CPU_FTR_DBELL | \
|
||||
CPU_FTR_NOEXECUTE | CPU_FTR_NODSISRALIGN | CPU_FTR_ICSWX)
|
||||
CPU_FTR_NOEXECUTE | CPU_FTR_NODSISRALIGN | \
|
||||
CPU_FTR_ICSWX | CPU_FTR_DABRX )
|
||||
|
||||
#ifdef __powerpc64__
|
||||
#ifdef CONFIG_PPC_BOOK3E
|
||||
|
@ -513,7 +513,7 @@ label##_common: \
|
||||
*/
|
||||
#define STD_EXCEPTION_COMMON_ASYNC(trap, label, hdlr) \
|
||||
EXCEPTION_COMMON(trap, label, hdlr, ret_from_except_lite, \
|
||||
FINISH_NAP;RUNLATCH_ON;DISABLE_INTS)
|
||||
FINISH_NAP;DISABLE_INTS;RUNLATCH_ON)
|
||||
|
||||
/*
|
||||
* When the idle code in power4_idle puts the CPU into NAP mode,
|
||||
|
@ -54,8 +54,16 @@
|
||||
#define BOOKE_INTERRUPT_DEBUG 15
|
||||
|
||||
/* E500 */
|
||||
#define BOOKE_INTERRUPT_SPE_UNAVAIL 32
|
||||
#define BOOKE_INTERRUPT_SPE_FP_DATA 33
|
||||
#define BOOKE_INTERRUPT_SPE_ALTIVEC_UNAVAIL 32
|
||||
#define BOOKE_INTERRUPT_SPE_FP_DATA_ALTIVEC_ASSIST 33
|
||||
/*
|
||||
* TODO: Unify 32-bit and 64-bit kernel exception handlers to use same defines
|
||||
*/
|
||||
#define BOOKE_INTERRUPT_SPE_UNAVAIL BOOKE_INTERRUPT_SPE_ALTIVEC_UNAVAIL
|
||||
#define BOOKE_INTERRUPT_SPE_FP_DATA BOOKE_INTERRUPT_SPE_FP_DATA_ALTIVEC_ASSIST
|
||||
#define BOOKE_INTERRUPT_ALTIVEC_UNAVAIL BOOKE_INTERRUPT_SPE_ALTIVEC_UNAVAIL
|
||||
#define BOOKE_INTERRUPT_ALTIVEC_ASSIST \
|
||||
BOOKE_INTERRUPT_SPE_FP_DATA_ALTIVEC_ASSIST
|
||||
#define BOOKE_INTERRUPT_SPE_FP_ROUND 34
|
||||
#define BOOKE_INTERRUPT_PERFORMANCE_MONITOR 35
|
||||
#define BOOKE_INTERRUPT_DOORBELL 36
|
||||
@ -67,10 +75,6 @@
|
||||
#define BOOKE_INTERRUPT_HV_SYSCALL 40
|
||||
#define BOOKE_INTERRUPT_HV_PRIV 41
|
||||
|
||||
/* altivec */
|
||||
#define BOOKE_INTERRUPT_ALTIVEC_UNAVAIL 42
|
||||
#define BOOKE_INTERRUPT_ALTIVEC_ASSIST 43
|
||||
|
||||
/* book3s */
|
||||
|
||||
#define BOOK3S_INTERRUPT_SYSTEM_RESET 0x100
|
||||
|
@ -452,8 +452,8 @@ static struct cpu_spec __initdata cpu_specs[] = {
|
||||
.mmu_features = MMU_FTRS_POWER8,
|
||||
.icache_bsize = 128,
|
||||
.dcache_bsize = 128,
|
||||
.oprofile_type = PPC_OPROFILE_POWER4,
|
||||
.oprofile_cpu_type = 0,
|
||||
.oprofile_type = PPC_OPROFILE_INVALID,
|
||||
.oprofile_cpu_type = "ppc64/ibm-compat-v1",
|
||||
.cpu_setup = __setup_cpu_power8,
|
||||
.cpu_restore = __restore_cpu_power8,
|
||||
.platform = "power8",
|
||||
@ -506,8 +506,8 @@ static struct cpu_spec __initdata cpu_specs[] = {
|
||||
.dcache_bsize = 128,
|
||||
.num_pmcs = 6,
|
||||
.pmc_type = PPC_PMC_IBM,
|
||||
.oprofile_cpu_type = 0,
|
||||
.oprofile_type = PPC_OPROFILE_POWER4,
|
||||
.oprofile_cpu_type = "ppc64/power8",
|
||||
.oprofile_type = PPC_OPROFILE_INVALID,
|
||||
.cpu_setup = __setup_cpu_power8,
|
||||
.cpu_restore = __restore_cpu_power8,
|
||||
.platform = "power8",
|
||||
|
@ -465,20 +465,6 @@ BEGIN_FTR_SECTION
|
||||
std r0, THREAD_EBBHR(r3)
|
||||
mfspr r0, SPRN_EBBRR
|
||||
std r0, THREAD_EBBRR(r3)
|
||||
|
||||
/* PMU registers made user read/(write) by EBB */
|
||||
mfspr r0, SPRN_SIAR
|
||||
std r0, THREAD_SIAR(r3)
|
||||
mfspr r0, SPRN_SDAR
|
||||
std r0, THREAD_SDAR(r3)
|
||||
mfspr r0, SPRN_SIER
|
||||
std r0, THREAD_SIER(r3)
|
||||
mfspr r0, SPRN_MMCR0
|
||||
std r0, THREAD_MMCR0(r3)
|
||||
mfspr r0, SPRN_MMCR2
|
||||
std r0, THREAD_MMCR2(r3)
|
||||
mfspr r0, SPRN_MMCRA
|
||||
std r0, THREAD_MMCRA(r3)
|
||||
END_FTR_SECTION_IFSET(CPU_FTR_ARCH_207S)
|
||||
#endif
|
||||
|
||||
@ -581,20 +567,6 @@ BEGIN_FTR_SECTION
|
||||
ld r0, THREAD_EBBRR(r4)
|
||||
mtspr SPRN_EBBRR, r0
|
||||
|
||||
/* PMU registers made user read/(write) by EBB */
|
||||
ld r0, THREAD_SIAR(r4)
|
||||
mtspr SPRN_SIAR, r0
|
||||
ld r0, THREAD_SDAR(r4)
|
||||
mtspr SPRN_SDAR, r0
|
||||
ld r0, THREAD_SIER(r4)
|
||||
mtspr SPRN_SIER, r0
|
||||
ld r0, THREAD_MMCR0(r4)
|
||||
mtspr SPRN_MMCR0, r0
|
||||
ld r0, THREAD_MMCR2(r4)
|
||||
mtspr SPRN_MMCR2, r0
|
||||
ld r0, THREAD_MMCRA(r4)
|
||||
mtspr SPRN_MMCRA, r0
|
||||
|
||||
ld r0,THREAD_TAR(r4)
|
||||
mtspr SPRN_TAR,r0
|
||||
END_FTR_SECTION_IFSET(CPU_FTR_ARCH_207S)
|
||||
|
@ -454,38 +454,14 @@ BEGIN_FTR_SECTION
|
||||
xori r10,r10,(MSR_FE0|MSR_FE1)
|
||||
mtmsrd r10
|
||||
sync
|
||||
fmr 0,0
|
||||
fmr 1,1
|
||||
fmr 2,2
|
||||
fmr 3,3
|
||||
fmr 4,4
|
||||
fmr 5,5
|
||||
fmr 6,6
|
||||
fmr 7,7
|
||||
fmr 8,8
|
||||
fmr 9,9
|
||||
fmr 10,10
|
||||
fmr 11,11
|
||||
fmr 12,12
|
||||
fmr 13,13
|
||||
fmr 14,14
|
||||
fmr 15,15
|
||||
fmr 16,16
|
||||
fmr 17,17
|
||||
fmr 18,18
|
||||
fmr 19,19
|
||||
fmr 20,20
|
||||
fmr 21,21
|
||||
fmr 22,22
|
||||
fmr 23,23
|
||||
fmr 24,24
|
||||
fmr 25,25
|
||||
fmr 26,26
|
||||
fmr 27,27
|
||||
fmr 28,28
|
||||
fmr 29,29
|
||||
fmr 30,30
|
||||
fmr 31,31
|
||||
|
||||
#define FMR2(n) fmr (n), (n) ; fmr n+1, n+1
|
||||
#define FMR4(n) FMR2(n) ; FMR2(n+2)
|
||||
#define FMR8(n) FMR4(n) ; FMR4(n+4)
|
||||
#define FMR16(n) FMR8(n) ; FMR8(n+8)
|
||||
#define FMR32(n) FMR16(n) ; FMR16(n+16)
|
||||
FMR32(0)
|
||||
|
||||
FTR_SECTION_ELSE
|
||||
/*
|
||||
* To denormalise we need to move a copy of the register to itself.
|
||||
@ -495,39 +471,25 @@ FTR_SECTION_ELSE
|
||||
oris r10,r10,MSR_VSX@h
|
||||
mtmsrd r10
|
||||
sync
|
||||
XVCPSGNDP(0,0,0)
|
||||
XVCPSGNDP(1,1,1)
|
||||
XVCPSGNDP(2,2,2)
|
||||
XVCPSGNDP(3,3,3)
|
||||
XVCPSGNDP(4,4,4)
|
||||
XVCPSGNDP(5,5,5)
|
||||
XVCPSGNDP(6,6,6)
|
||||
XVCPSGNDP(7,7,7)
|
||||
XVCPSGNDP(8,8,8)
|
||||
XVCPSGNDP(9,9,9)
|
||||
XVCPSGNDP(10,10,10)
|
||||
XVCPSGNDP(11,11,11)
|
||||
XVCPSGNDP(12,12,12)
|
||||
XVCPSGNDP(13,13,13)
|
||||
XVCPSGNDP(14,14,14)
|
||||
XVCPSGNDP(15,15,15)
|
||||
XVCPSGNDP(16,16,16)
|
||||
XVCPSGNDP(17,17,17)
|
||||
XVCPSGNDP(18,18,18)
|
||||
XVCPSGNDP(19,19,19)
|
||||
XVCPSGNDP(20,20,20)
|
||||
XVCPSGNDP(21,21,21)
|
||||
XVCPSGNDP(22,22,22)
|
||||
XVCPSGNDP(23,23,23)
|
||||
XVCPSGNDP(24,24,24)
|
||||
XVCPSGNDP(25,25,25)
|
||||
XVCPSGNDP(26,26,26)
|
||||
XVCPSGNDP(27,27,27)
|
||||
XVCPSGNDP(28,28,28)
|
||||
XVCPSGNDP(29,29,29)
|
||||
XVCPSGNDP(30,30,30)
|
||||
XVCPSGNDP(31,31,31)
|
||||
|
||||
#define XVCPSGNDP2(n) XVCPSGNDP(n,n,n) ; XVCPSGNDP(n+1,n+1,n+1)
|
||||
#define XVCPSGNDP4(n) XVCPSGNDP2(n) ; XVCPSGNDP2(n+2)
|
||||
#define XVCPSGNDP8(n) XVCPSGNDP4(n) ; XVCPSGNDP4(n+4)
|
||||
#define XVCPSGNDP16(n) XVCPSGNDP8(n) ; XVCPSGNDP8(n+8)
|
||||
#define XVCPSGNDP32(n) XVCPSGNDP16(n) ; XVCPSGNDP16(n+16)
|
||||
XVCPSGNDP32(0)
|
||||
|
||||
ALT_FTR_SECTION_END_IFCLR(CPU_FTR_ARCH_206)
|
||||
|
||||
BEGIN_FTR_SECTION
|
||||
b denorm_done
|
||||
END_FTR_SECTION_IFCLR(CPU_FTR_ARCH_207S)
|
||||
/*
|
||||
* To denormalise we need to move a copy of the register to itself.
|
||||
* For POWER8 we need to do that for all 64 VSX registers
|
||||
*/
|
||||
XVCPSGNDP32(32)
|
||||
denorm_done:
|
||||
mtspr SPRN_HSRR0,r11
|
||||
mtcrf 0x80,r9
|
||||
ld r9,PACA_EXGEN+EX_R9(r13)
|
||||
@ -721,7 +683,7 @@ machine_check_common:
|
||||
STD_EXCEPTION_COMMON(0xb00, trap_0b, .unknown_exception)
|
||||
STD_EXCEPTION_COMMON(0xd00, single_step, .single_step_exception)
|
||||
STD_EXCEPTION_COMMON(0xe00, trap_0e, .unknown_exception)
|
||||
STD_EXCEPTION_COMMON(0xe40, emulation_assist, .program_check_exception)
|
||||
STD_EXCEPTION_COMMON(0xe40, emulation_assist, .emulation_assist_interrupt)
|
||||
STD_EXCEPTION_COMMON(0xe60, hmi_exception, .unknown_exception)
|
||||
#ifdef CONFIG_PPC_DOORBELL
|
||||
STD_EXCEPTION_COMMON_ASYNC(0xe80, h_doorbell, .doorbell_exception)
|
||||
|
@ -162,7 +162,7 @@ notrace unsigned int __check_irq_replay(void)
|
||||
* in case we also had a rollover while hard disabled
|
||||
*/
|
||||
local_paca->irq_happened &= ~PACA_IRQ_DEC;
|
||||
if (decrementer_check_overflow())
|
||||
if ((happened & PACA_IRQ_DEC) || decrementer_check_overflow())
|
||||
return 0x900;
|
||||
|
||||
/* Finally check if an external interrupt happened */
|
||||
|
@ -827,6 +827,7 @@ static void pcibios_fixup_resources(struct pci_dev *dev)
|
||||
}
|
||||
for (i = 0; i < DEVICE_COUNT_RESOURCE; i++) {
|
||||
struct resource *res = dev->resource + i;
|
||||
struct pci_bus_region reg;
|
||||
if (!res->flags)
|
||||
continue;
|
||||
|
||||
@ -835,8 +836,9 @@ static void pcibios_fixup_resources(struct pci_dev *dev)
|
||||
* at 0 as unset as well, except if PCI_PROBE_ONLY is also set
|
||||
* since in that case, we don't want to re-assign anything
|
||||
*/
|
||||
pcibios_resource_to_bus(dev, ®, res);
|
||||
if (pci_has_flag(PCI_REASSIGN_ALL_RSRC) ||
|
||||
(res->start == 0 && !pci_has_flag(PCI_PROBE_ONLY))) {
|
||||
(reg.start == 0 && !pci_has_flag(PCI_PROBE_ONLY))) {
|
||||
/* Only print message if not re-assigning */
|
||||
if (!pci_has_flag(PCI_REASSIGN_ALL_RSRC))
|
||||
pr_debug("PCI:%s Resource %d %016llx-%016llx [%x] "
|
||||
|
@ -399,7 +399,8 @@ static inline int __set_dabr(unsigned long dabr, unsigned long dabrx)
|
||||
static inline int __set_dabr(unsigned long dabr, unsigned long dabrx)
|
||||
{
|
||||
mtspr(SPRN_DABR, dabr);
|
||||
mtspr(SPRN_DABRX, dabrx);
|
||||
if (cpu_has_feature(CPU_FTR_DABRX))
|
||||
mtspr(SPRN_DABRX, dabrx);
|
||||
return 0;
|
||||
}
|
||||
#else
|
||||
@ -1368,7 +1369,7 @@ void show_stack(struct task_struct *tsk, unsigned long *stack)
|
||||
|
||||
#ifdef CONFIG_PPC64
|
||||
/* Called with hard IRQs off */
|
||||
void __ppc64_runlatch_on(void)
|
||||
void notrace __ppc64_runlatch_on(void)
|
||||
{
|
||||
struct thread_info *ti = current_thread_info();
|
||||
unsigned long ctrl;
|
||||
@ -1381,7 +1382,7 @@ void __ppc64_runlatch_on(void)
|
||||
}
|
||||
|
||||
/* Called with hard IRQs off */
|
||||
void __ppc64_runlatch_off(void)
|
||||
void notrace __ppc64_runlatch_off(void)
|
||||
{
|
||||
struct thread_info *ti = current_thread_info();
|
||||
unsigned long ctrl;
|
||||
|
@ -1165,6 +1165,16 @@ bail:
|
||||
exception_exit(prev_state);
|
||||
}
|
||||
|
||||
/*
|
||||
* This occurs when running in hypervisor mode on POWER6 or later
|
||||
* and an illegal instruction is encountered.
|
||||
*/
|
||||
void __kprobes emulation_assist_interrupt(struct pt_regs *regs)
|
||||
{
|
||||
regs->msr |= REASON_ILLEGAL;
|
||||
program_check_exception(regs);
|
||||
}
|
||||
|
||||
void alignment_exception(struct pt_regs *regs)
|
||||
{
|
||||
enum ctx_state prev_state = exception_enter();
|
||||
|
@ -441,6 +441,7 @@ int kvmppc_44x_emul_tlbwe(struct kvm_vcpu *vcpu, u8 ra, u8 rs, u8 ws)
|
||||
struct kvmppc_vcpu_44x *vcpu_44x = to_44x(vcpu);
|
||||
struct kvmppc_44x_tlbe *tlbe;
|
||||
unsigned int gtlb_index;
|
||||
int idx;
|
||||
|
||||
gtlb_index = kvmppc_get_gpr(vcpu, ra);
|
||||
if (gtlb_index >= KVM44x_GUEST_TLB_SIZE) {
|
||||
@ -473,6 +474,8 @@ int kvmppc_44x_emul_tlbwe(struct kvm_vcpu *vcpu, u8 ra, u8 rs, u8 ws)
|
||||
return EMULATE_FAIL;
|
||||
}
|
||||
|
||||
idx = srcu_read_lock(&vcpu->kvm->srcu);
|
||||
|
||||
if (tlbe_is_host_safe(vcpu, tlbe)) {
|
||||
gva_t eaddr;
|
||||
gpa_t gpaddr;
|
||||
@ -489,6 +492,8 @@ int kvmppc_44x_emul_tlbwe(struct kvm_vcpu *vcpu, u8 ra, u8 rs, u8 ws)
|
||||
kvmppc_mmu_map(vcpu, eaddr, gpaddr, gtlb_index);
|
||||
}
|
||||
|
||||
srcu_read_unlock(&vcpu->kvm->srcu, idx);
|
||||
|
||||
trace_kvm_gtlb_write(gtlb_index, tlbe->tid, tlbe->word0, tlbe->word1,
|
||||
tlbe->word2);
|
||||
|
||||
|
@ -832,6 +832,18 @@ int kvmppc_handle_exit(struct kvm_run *run, struct kvm_vcpu *vcpu,
|
||||
{
|
||||
int r = RESUME_HOST;
|
||||
int s;
|
||||
int idx;
|
||||
|
||||
#ifdef CONFIG_PPC64
|
||||
WARN_ON(local_paca->irq_happened != 0);
|
||||
#endif
|
||||
|
||||
/*
|
||||
* We enter with interrupts disabled in hardware, but
|
||||
* we need to call hard_irq_disable anyway to ensure that
|
||||
* the software state is kept in sync.
|
||||
*/
|
||||
hard_irq_disable();
|
||||
|
||||
/* update before a new last_exit_type is rewritten */
|
||||
kvmppc_update_timing_stats(vcpu);
|
||||
@ -1053,6 +1065,8 @@ int kvmppc_handle_exit(struct kvm_run *run, struct kvm_vcpu *vcpu,
|
||||
break;
|
||||
}
|
||||
|
||||
idx = srcu_read_lock(&vcpu->kvm->srcu);
|
||||
|
||||
gpaddr = kvmppc_mmu_xlate(vcpu, gtlb_index, eaddr);
|
||||
gfn = gpaddr >> PAGE_SHIFT;
|
||||
|
||||
@ -1075,6 +1089,7 @@ int kvmppc_handle_exit(struct kvm_run *run, struct kvm_vcpu *vcpu,
|
||||
kvmppc_account_exit(vcpu, MMIO_EXITS);
|
||||
}
|
||||
|
||||
srcu_read_unlock(&vcpu->kvm->srcu, idx);
|
||||
break;
|
||||
}
|
||||
|
||||
@ -1098,6 +1113,8 @@ int kvmppc_handle_exit(struct kvm_run *run, struct kvm_vcpu *vcpu,
|
||||
|
||||
kvmppc_account_exit(vcpu, ITLB_VIRT_MISS_EXITS);
|
||||
|
||||
idx = srcu_read_lock(&vcpu->kvm->srcu);
|
||||
|
||||
gpaddr = kvmppc_mmu_xlate(vcpu, gtlb_index, eaddr);
|
||||
gfn = gpaddr >> PAGE_SHIFT;
|
||||
|
||||
@ -1114,6 +1131,7 @@ int kvmppc_handle_exit(struct kvm_run *run, struct kvm_vcpu *vcpu,
|
||||
kvmppc_booke_queue_irqprio(vcpu, BOOKE_IRQPRIO_MACHINE_CHECK);
|
||||
}
|
||||
|
||||
srcu_read_unlock(&vcpu->kvm->srcu, idx);
|
||||
break;
|
||||
}
|
||||
|
||||
|
@ -396,6 +396,7 @@ int kvmppc_e500_emul_tlbwe(struct kvm_vcpu *vcpu)
|
||||
struct kvm_book3e_206_tlb_entry *gtlbe;
|
||||
int tlbsel, esel;
|
||||
int recal = 0;
|
||||
int idx;
|
||||
|
||||
tlbsel = get_tlb_tlbsel(vcpu);
|
||||
esel = get_tlb_esel(vcpu, tlbsel);
|
||||
@ -430,6 +431,8 @@ int kvmppc_e500_emul_tlbwe(struct kvm_vcpu *vcpu)
|
||||
kvmppc_set_tlb1map_range(vcpu, gtlbe);
|
||||
}
|
||||
|
||||
idx = srcu_read_lock(&vcpu->kvm->srcu);
|
||||
|
||||
/* Invalidate shadow mappings for the about-to-be-clobbered TLBE. */
|
||||
if (tlbe_is_host_safe(vcpu, gtlbe)) {
|
||||
u64 eaddr = get_tlb_eaddr(gtlbe);
|
||||
@ -444,6 +447,8 @@ int kvmppc_e500_emul_tlbwe(struct kvm_vcpu *vcpu)
|
||||
kvmppc_mmu_map(vcpu, eaddr, raddr, index_of(tlbsel, esel));
|
||||
}
|
||||
|
||||
srcu_read_unlock(&vcpu->kvm->srcu, idx);
|
||||
|
||||
kvmppc_set_exit_type(vcpu, EMULATED_TLBWE_EXITS);
|
||||
return EMULATE_DONE;
|
||||
}
|
||||
|
@ -177,8 +177,6 @@ int kvmppc_core_check_processor_compat(void)
|
||||
r = 0;
|
||||
else if (strcmp(cur_cpu_spec->cpu_name, "e5500") == 0)
|
||||
r = 0;
|
||||
else if (strcmp(cur_cpu_spec->cpu_name, "e6500") == 0)
|
||||
r = 0;
|
||||
else
|
||||
r = -ENOTSUPP;
|
||||
|
||||
|
@ -1758,7 +1758,7 @@ static void perf_event_interrupt(struct pt_regs *regs)
|
||||
}
|
||||
}
|
||||
}
|
||||
if ((!found) && printk_ratelimit())
|
||||
if (!found && !nmi && printk_ratelimit())
|
||||
printk(KERN_WARNING "Can't find PMC that caused IRQ\n");
|
||||
|
||||
/*
|
||||
|
@ -83,7 +83,11 @@ static int pseries_eeh_init(void)
|
||||
ibm_configure_pe = rtas_token("ibm,configure-pe");
|
||||
ibm_configure_bridge = rtas_token("ibm,configure-bridge");
|
||||
|
||||
/* necessary sanity check */
|
||||
/*
|
||||
* Necessary sanity check. We needn't check "get-config-addr-info"
|
||||
* and its variant since the old firmware probably support address
|
||||
* of domain/bus/slot/function for EEH RTAS operations.
|
||||
*/
|
||||
if (ibm_set_eeh_option == RTAS_UNKNOWN_SERVICE) {
|
||||
pr_warning("%s: RTAS service <ibm,set-eeh-option> invalid\n",
|
||||
__func__);
|
||||
@ -102,12 +106,6 @@ static int pseries_eeh_init(void)
|
||||
pr_warning("%s: RTAS service <ibm,slot-error-detail> invalid\n",
|
||||
__func__);
|
||||
return -EINVAL;
|
||||
} else if (ibm_get_config_addr_info2 == RTAS_UNKNOWN_SERVICE &&
|
||||
ibm_get_config_addr_info == RTAS_UNKNOWN_SERVICE) {
|
||||
pr_warning("%s: RTAS service <ibm,get-config-addr-info2> and "
|
||||
"<ibm,get-config-addr-info> invalid\n",
|
||||
__func__);
|
||||
return -EINVAL;
|
||||
} else if (ibm_configure_pe == RTAS_UNKNOWN_SERVICE &&
|
||||
ibm_configure_bridge == RTAS_UNKNOWN_SERVICE) {
|
||||
pr_warning("%s: RTAS service <ibm,configure-pe> and "
|
||||
|
@ -623,7 +623,7 @@ static inline pgste_t pgste_get_lock(pte_t *ptep)
|
||||
" csg %0,%1,%2\n"
|
||||
" jl 0b\n"
|
||||
: "=&d" (old), "=&d" (new), "=Q" (ptep[PTRS_PER_PTE])
|
||||
: "Q" (ptep[PTRS_PER_PTE]) : "cc");
|
||||
: "Q" (ptep[PTRS_PER_PTE]) : "cc", "memory");
|
||||
#endif
|
||||
return __pgste(new);
|
||||
}
|
||||
@ -635,11 +635,19 @@ static inline void pgste_set_unlock(pte_t *ptep, pgste_t pgste)
|
||||
" nihh %1,0xff7f\n" /* clear RCP_PCL_BIT */
|
||||
" stg %1,%0\n"
|
||||
: "=Q" (ptep[PTRS_PER_PTE])
|
||||
: "d" (pgste_val(pgste)), "Q" (ptep[PTRS_PER_PTE]) : "cc");
|
||||
: "d" (pgste_val(pgste)), "Q" (ptep[PTRS_PER_PTE])
|
||||
: "cc", "memory");
|
||||
preempt_enable();
|
||||
#endif
|
||||
}
|
||||
|
||||
static inline void pgste_set(pte_t *ptep, pgste_t pgste)
|
||||
{
|
||||
#ifdef CONFIG_PGSTE
|
||||
*(pgste_t *)(ptep + PTRS_PER_PTE) = pgste;
|
||||
#endif
|
||||
}
|
||||
|
||||
static inline pgste_t pgste_update_all(pte_t *ptep, pgste_t pgste)
|
||||
{
|
||||
#ifdef CONFIG_PGSTE
|
||||
@ -704,17 +712,19 @@ static inline void pgste_set_key(pte_t *ptep, pgste_t pgste, pte_t entry)
|
||||
{
|
||||
#ifdef CONFIG_PGSTE
|
||||
unsigned long address;
|
||||
unsigned long okey, nkey;
|
||||
unsigned long nkey;
|
||||
|
||||
if (pte_val(entry) & _PAGE_INVALID)
|
||||
return;
|
||||
VM_BUG_ON(!(pte_val(*ptep) & _PAGE_INVALID));
|
||||
address = pte_val(entry) & PAGE_MASK;
|
||||
okey = nkey = page_get_storage_key(address);
|
||||
nkey &= ~(_PAGE_ACC_BITS | _PAGE_FP_BIT);
|
||||
/* Set page access key and fetch protection bit from pgste */
|
||||
nkey |= (pgste_val(pgste) & (RCP_ACC_BITS | RCP_FP_BIT)) >> 56;
|
||||
if (okey != nkey)
|
||||
page_set_storage_key(address, nkey, 0);
|
||||
/*
|
||||
* Set page access key and fetch protection bit from pgste.
|
||||
* The guest C/R information is still in the PGSTE, set real
|
||||
* key C/R to 0.
|
||||
*/
|
||||
nkey = (pgste_val(pgste) & (RCP_ACC_BITS | RCP_FP_BIT)) >> 56;
|
||||
page_set_storage_key(address, nkey, 0);
|
||||
#endif
|
||||
}
|
||||
|
||||
@ -1099,8 +1109,10 @@ static inline pte_t ptep_modify_prot_start(struct mm_struct *mm,
|
||||
if (!mm_exclusive(mm))
|
||||
__ptep_ipte(address, ptep);
|
||||
|
||||
if (mm_has_pgste(mm))
|
||||
if (mm_has_pgste(mm)) {
|
||||
pgste = pgste_update_all(&pte, pgste);
|
||||
pgste_set(ptep, pgste);
|
||||
}
|
||||
return pte;
|
||||
}
|
||||
|
||||
|
@ -74,6 +74,8 @@ __show_trace(unsigned long sp, unsigned long low, unsigned long high)
|
||||
|
||||
static void show_trace(struct task_struct *task, unsigned long *stack)
|
||||
{
|
||||
const unsigned long frame_size =
|
||||
STACK_FRAME_OVERHEAD + sizeof(struct pt_regs);
|
||||
register unsigned long __r15 asm ("15");
|
||||
unsigned long sp;
|
||||
|
||||
@ -82,11 +84,13 @@ static void show_trace(struct task_struct *task, unsigned long *stack)
|
||||
sp = task ? task->thread.ksp : __r15;
|
||||
printk("Call Trace:\n");
|
||||
#ifdef CONFIG_CHECK_STACK
|
||||
sp = __show_trace(sp, S390_lowcore.panic_stack - 4096,
|
||||
S390_lowcore.panic_stack);
|
||||
sp = __show_trace(sp,
|
||||
S390_lowcore.panic_stack + frame_size - 4096,
|
||||
S390_lowcore.panic_stack + frame_size);
|
||||
#endif
|
||||
sp = __show_trace(sp, S390_lowcore.async_stack - ASYNC_SIZE,
|
||||
S390_lowcore.async_stack);
|
||||
sp = __show_trace(sp,
|
||||
S390_lowcore.async_stack + frame_size - ASYNC_SIZE,
|
||||
S390_lowcore.async_stack + frame_size);
|
||||
if (task)
|
||||
__show_trace(sp, (unsigned long) task_stack_page(task),
|
||||
(unsigned long) task_stack_page(task) + THREAD_SIZE);
|
||||
|
@ -311,3 +311,67 @@ void measurement_alert_subclass_unregister(void)
|
||||
spin_unlock(&ma_subclass_lock);
|
||||
}
|
||||
EXPORT_SYMBOL(measurement_alert_subclass_unregister);
|
||||
|
||||
void synchronize_irq(unsigned int irq)
|
||||
{
|
||||
/*
|
||||
* Not needed, the handler is protected by a lock and IRQs that occur
|
||||
* after the handler is deleted are just NOPs.
|
||||
*/
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(synchronize_irq);
|
||||
|
||||
#ifndef CONFIG_PCI
|
||||
|
||||
/* Only PCI devices have dynamically-defined IRQ handlers */
|
||||
|
||||
int request_irq(unsigned int irq, irq_handler_t handler,
|
||||
unsigned long irqflags, const char *devname, void *dev_id)
|
||||
{
|
||||
return -EINVAL;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(request_irq);
|
||||
|
||||
void free_irq(unsigned int irq, void *dev_id)
|
||||
{
|
||||
WARN_ON(1);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(free_irq);
|
||||
|
||||
void enable_irq(unsigned int irq)
|
||||
{
|
||||
WARN_ON(1);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(enable_irq);
|
||||
|
||||
void disable_irq(unsigned int irq)
|
||||
{
|
||||
WARN_ON(1);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(disable_irq);
|
||||
|
||||
#endif /* !CONFIG_PCI */
|
||||
|
||||
void disable_irq_nosync(unsigned int irq)
|
||||
{
|
||||
disable_irq(irq);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(disable_irq_nosync);
|
||||
|
||||
unsigned long probe_irq_on(void)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(probe_irq_on);
|
||||
|
||||
int probe_irq_off(unsigned long val)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(probe_irq_off);
|
||||
|
||||
unsigned int probe_irq_mask(unsigned long val)
|
||||
{
|
||||
return val;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(probe_irq_mask);
|
||||
|
@ -225,7 +225,7 @@ _sclp_print:
|
||||
ahi %r2,1
|
||||
ltr %r0,%r0 # end of string?
|
||||
jz .LfinalizemtoS4
|
||||
chi %r0,0x15 # end of line (NL)?
|
||||
chi %r0,0x0a # end of line (NL)?
|
||||
jz .LfinalizemtoS4
|
||||
stc %r0,0(%r6,%r7) # copy to mto
|
||||
la %r11,0(%r6,%r7)
|
||||
|
@ -302,15 +302,6 @@ static int zpci_cfg_store(struct zpci_dev *zdev, int offset, u32 val, u8 len)
|
||||
return rc;
|
||||
}
|
||||
|
||||
void synchronize_irq(unsigned int irq)
|
||||
{
|
||||
/*
|
||||
* Not needed, the handler is protected by a lock and IRQs that occur
|
||||
* after the handler is deleted are just NOPs.
|
||||
*/
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(synchronize_irq);
|
||||
|
||||
void enable_irq(unsigned int irq)
|
||||
{
|
||||
struct msi_desc *msi = irq_get_msi_desc(irq);
|
||||
@ -327,30 +318,6 @@ void disable_irq(unsigned int irq)
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(disable_irq);
|
||||
|
||||
void disable_irq_nosync(unsigned int irq)
|
||||
{
|
||||
disable_irq(irq);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(disable_irq_nosync);
|
||||
|
||||
unsigned long probe_irq_on(void)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(probe_irq_on);
|
||||
|
||||
int probe_irq_off(unsigned long val)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(probe_irq_off);
|
||||
|
||||
unsigned int probe_irq_mask(unsigned long val)
|
||||
{
|
||||
return val;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(probe_irq_mask);
|
||||
|
||||
void pcibios_fixup_bus(struct pci_bus *bus)
|
||||
{
|
||||
}
|
||||
|
@ -54,6 +54,7 @@ EXPORT_SYMBOL(of_set_property_mutex);
|
||||
int of_set_property(struct device_node *dp, const char *name, void *val, int len)
|
||||
{
|
||||
struct property **prevp;
|
||||
unsigned long flags;
|
||||
void *new_val;
|
||||
int err;
|
||||
|
||||
@ -64,7 +65,7 @@ int of_set_property(struct device_node *dp, const char *name, void *val, int len
|
||||
err = -ENODEV;
|
||||
|
||||
mutex_lock(&of_set_property_mutex);
|
||||
raw_spin_lock(&devtree_lock);
|
||||
raw_spin_lock_irqsave(&devtree_lock, flags);
|
||||
prevp = &dp->properties;
|
||||
while (*prevp) {
|
||||
struct property *prop = *prevp;
|
||||
@ -91,7 +92,7 @@ int of_set_property(struct device_node *dp, const char *name, void *val, int len
|
||||
}
|
||||
prevp = &(*prevp)->next;
|
||||
}
|
||||
raw_spin_unlock(&devtree_lock);
|
||||
raw_spin_unlock_irqrestore(&devtree_lock, flags);
|
||||
mutex_unlock(&of_set_property_mutex);
|
||||
|
||||
/* XXX Upate procfs if necessary... */
|
||||
|
@ -251,51 +251,6 @@ static void find_bits(unsigned long mask, u8 *pos, u8 *size)
|
||||
*size = len;
|
||||
}
|
||||
|
||||
static efi_status_t setup_efi_vars(struct boot_params *params)
|
||||
{
|
||||
struct setup_data *data;
|
||||
struct efi_var_bootdata *efidata;
|
||||
u64 store_size, remaining_size, var_size;
|
||||
efi_status_t status;
|
||||
|
||||
if (sys_table->runtime->hdr.revision < EFI_2_00_SYSTEM_TABLE_REVISION)
|
||||
return EFI_UNSUPPORTED;
|
||||
|
||||
data = (struct setup_data *)(unsigned long)params->hdr.setup_data;
|
||||
|
||||
while (data && data->next)
|
||||
data = (struct setup_data *)(unsigned long)data->next;
|
||||
|
||||
status = efi_call_phys4((void *)sys_table->runtime->query_variable_info,
|
||||
EFI_VARIABLE_NON_VOLATILE |
|
||||
EFI_VARIABLE_BOOTSERVICE_ACCESS |
|
||||
EFI_VARIABLE_RUNTIME_ACCESS, &store_size,
|
||||
&remaining_size, &var_size);
|
||||
|
||||
if (status != EFI_SUCCESS)
|
||||
return status;
|
||||
|
||||
status = efi_call_phys3(sys_table->boottime->allocate_pool,
|
||||
EFI_LOADER_DATA, sizeof(*efidata), &efidata);
|
||||
|
||||
if (status != EFI_SUCCESS)
|
||||
return status;
|
||||
|
||||
efidata->data.type = SETUP_EFI_VARS;
|
||||
efidata->data.len = sizeof(struct efi_var_bootdata) -
|
||||
sizeof(struct setup_data);
|
||||
efidata->data.next = 0;
|
||||
efidata->store_size = store_size;
|
||||
efidata->remaining_size = remaining_size;
|
||||
efidata->max_var_size = var_size;
|
||||
|
||||
if (data)
|
||||
data->next = (unsigned long)efidata;
|
||||
else
|
||||
params->hdr.setup_data = (unsigned long)efidata;
|
||||
|
||||
}
|
||||
|
||||
static efi_status_t setup_efi_pci(struct boot_params *params)
|
||||
{
|
||||
efi_pci_io_protocol *pci;
|
||||
@ -1202,8 +1157,6 @@ struct boot_params *efi_main(void *handle, efi_system_table_t *_table,
|
||||
|
||||
setup_graphics(boot_params);
|
||||
|
||||
setup_efi_vars(boot_params);
|
||||
|
||||
setup_efi_pci(boot_params);
|
||||
|
||||
status = efi_call_phys3(sys_table->boottime->allocate_pool,
|
||||
|
@ -102,13 +102,6 @@ extern void efi_call_phys_epilog(void);
|
||||
extern void efi_unmap_memmap(void);
|
||||
extern void efi_memory_uc(u64 addr, unsigned long size);
|
||||
|
||||
struct efi_var_bootdata {
|
||||
struct setup_data data;
|
||||
u64 store_size;
|
||||
u64 remaining_size;
|
||||
u64 max_var_size;
|
||||
};
|
||||
|
||||
#ifdef CONFIG_EFI
|
||||
|
||||
static inline bool efi_is_native(void)
|
||||
|
@ -6,7 +6,6 @@
|
||||
#define SETUP_E820_EXT 1
|
||||
#define SETUP_DTB 2
|
||||
#define SETUP_PCI 3
|
||||
#define SETUP_EFI_VARS 4
|
||||
|
||||
/* ram_size flags */
|
||||
#define RAMDISK_IMAGE_START_MASK 0x07FF
|
||||
|
@ -160,7 +160,7 @@ identity_mapped:
|
||||
xorq %rbp, %rbp
|
||||
xorq %r8, %r8
|
||||
xorq %r9, %r9
|
||||
xorq %r10, %r9
|
||||
xorq %r10, %r10
|
||||
xorq %r11, %r11
|
||||
xorq %r12, %r12
|
||||
xorq %r13, %r13
|
||||
|
@ -277,6 +277,9 @@ static int __meminit split_mem_range(struct map_range *mr, int nr_range,
|
||||
end_pfn = limit_pfn;
|
||||
nr_range = save_mr(mr, nr_range, start_pfn, end_pfn, 0);
|
||||
|
||||
if (!after_bootmem)
|
||||
adjust_range_page_size_mask(mr, nr_range);
|
||||
|
||||
/* try to merge same page size and continuous */
|
||||
for (i = 0; nr_range > 1 && i < nr_range - 1; i++) {
|
||||
unsigned long old_start;
|
||||
@ -291,9 +294,6 @@ static int __meminit split_mem_range(struct map_range *mr, int nr_range,
|
||||
nr_range--;
|
||||
}
|
||||
|
||||
if (!after_bootmem)
|
||||
adjust_range_page_size_mask(mr, nr_range);
|
||||
|
||||
for (i = 0; i < nr_range; i++)
|
||||
printk(KERN_DEBUG " [mem %#010lx-%#010lx] page %s\n",
|
||||
mr[i].start, mr[i].end - 1,
|
||||
|
@ -42,7 +42,6 @@
|
||||
#include <linux/io.h>
|
||||
#include <linux/reboot.h>
|
||||
#include <linux/bcd.h>
|
||||
#include <linux/ucs2_string.h>
|
||||
|
||||
#include <asm/setup.h>
|
||||
#include <asm/efi.h>
|
||||
@ -54,12 +53,12 @@
|
||||
|
||||
#define EFI_DEBUG 1
|
||||
|
||||
/*
|
||||
* There's some additional metadata associated with each
|
||||
* variable. Intel's reference implementation is 60 bytes - bump that
|
||||
* to account for potential alignment constraints
|
||||
*/
|
||||
#define VAR_METADATA_SIZE 64
|
||||
#define EFI_MIN_RESERVE 5120
|
||||
|
||||
#define EFI_DUMMY_GUID \
|
||||
EFI_GUID(0x4424ac57, 0xbe4b, 0x47dd, 0x9e, 0x97, 0xed, 0x50, 0xf0, 0x9f, 0x92, 0xa9)
|
||||
|
||||
static efi_char16_t efi_dummy_name[6] = { 'D', 'U', 'M', 'M', 'Y', 0 };
|
||||
|
||||
struct efi __read_mostly efi = {
|
||||
.mps = EFI_INVALID_TABLE_ADDR,
|
||||
@ -79,13 +78,6 @@ struct efi_memory_map memmap;
|
||||
static struct efi efi_phys __initdata;
|
||||
static efi_system_table_t efi_systab __initdata;
|
||||
|
||||
static u64 efi_var_store_size;
|
||||
static u64 efi_var_remaining_size;
|
||||
static u64 efi_var_max_var_size;
|
||||
static u64 boot_used_size;
|
||||
static u64 boot_var_size;
|
||||
static u64 active_size;
|
||||
|
||||
unsigned long x86_efi_facility;
|
||||
|
||||
/*
|
||||
@ -188,53 +180,8 @@ static efi_status_t virt_efi_get_next_variable(unsigned long *name_size,
|
||||
efi_char16_t *name,
|
||||
efi_guid_t *vendor)
|
||||
{
|
||||
efi_status_t status;
|
||||
static bool finished = false;
|
||||
static u64 var_size;
|
||||
|
||||
status = efi_call_virt3(get_next_variable,
|
||||
name_size, name, vendor);
|
||||
|
||||
if (status == EFI_NOT_FOUND) {
|
||||
finished = true;
|
||||
if (var_size < boot_used_size) {
|
||||
boot_var_size = boot_used_size - var_size;
|
||||
active_size += boot_var_size;
|
||||
} else {
|
||||
printk(KERN_WARNING FW_BUG "efi: Inconsistent initial sizes\n");
|
||||
}
|
||||
}
|
||||
|
||||
if (boot_used_size && !finished) {
|
||||
unsigned long size = 0;
|
||||
u32 attr;
|
||||
efi_status_t s;
|
||||
void *tmp;
|
||||
|
||||
s = virt_efi_get_variable(name, vendor, &attr, &size, NULL);
|
||||
|
||||
if (s != EFI_BUFFER_TOO_SMALL || !size)
|
||||
return status;
|
||||
|
||||
tmp = kmalloc(size, GFP_ATOMIC);
|
||||
|
||||
if (!tmp)
|
||||
return status;
|
||||
|
||||
s = virt_efi_get_variable(name, vendor, &attr, &size, tmp);
|
||||
|
||||
if (s == EFI_SUCCESS && (attr & EFI_VARIABLE_NON_VOLATILE)) {
|
||||
var_size += size;
|
||||
var_size += ucs2_strsize(name, 1024);
|
||||
active_size += size;
|
||||
active_size += VAR_METADATA_SIZE;
|
||||
active_size += ucs2_strsize(name, 1024);
|
||||
}
|
||||
|
||||
kfree(tmp);
|
||||
}
|
||||
|
||||
return status;
|
||||
return efi_call_virt3(get_next_variable,
|
||||
name_size, name, vendor);
|
||||
}
|
||||
|
||||
static efi_status_t virt_efi_set_variable(efi_char16_t *name,
|
||||
@ -243,34 +190,9 @@ static efi_status_t virt_efi_set_variable(efi_char16_t *name,
|
||||
unsigned long data_size,
|
||||
void *data)
|
||||
{
|
||||
efi_status_t status;
|
||||
u32 orig_attr = 0;
|
||||
unsigned long orig_size = 0;
|
||||
|
||||
status = virt_efi_get_variable(name, vendor, &orig_attr, &orig_size,
|
||||
NULL);
|
||||
|
||||
if (status != EFI_BUFFER_TOO_SMALL)
|
||||
orig_size = 0;
|
||||
|
||||
status = efi_call_virt5(set_variable,
|
||||
name, vendor, attr,
|
||||
data_size, data);
|
||||
|
||||
if (status == EFI_SUCCESS) {
|
||||
if (orig_size) {
|
||||
active_size -= orig_size;
|
||||
active_size -= ucs2_strsize(name, 1024);
|
||||
active_size -= VAR_METADATA_SIZE;
|
||||
}
|
||||
if (data_size) {
|
||||
active_size += data_size;
|
||||
active_size += ucs2_strsize(name, 1024);
|
||||
active_size += VAR_METADATA_SIZE;
|
||||
}
|
||||
}
|
||||
|
||||
return status;
|
||||
return efi_call_virt5(set_variable,
|
||||
name, vendor, attr,
|
||||
data_size, data);
|
||||
}
|
||||
|
||||
static efi_status_t virt_efi_query_variable_info(u32 attr,
|
||||
@ -786,9 +708,6 @@ void __init efi_init(void)
|
||||
char vendor[100] = "unknown";
|
||||
int i = 0;
|
||||
void *tmp;
|
||||
struct setup_data *data;
|
||||
struct efi_var_bootdata *efi_var_data;
|
||||
u64 pa_data;
|
||||
|
||||
#ifdef CONFIG_X86_32
|
||||
if (boot_params.efi_info.efi_systab_hi ||
|
||||
@ -806,22 +725,6 @@ void __init efi_init(void)
|
||||
if (efi_systab_init(efi_phys.systab))
|
||||
return;
|
||||
|
||||
pa_data = boot_params.hdr.setup_data;
|
||||
while (pa_data) {
|
||||
data = early_ioremap(pa_data, sizeof(*efi_var_data));
|
||||
if (data->type == SETUP_EFI_VARS) {
|
||||
efi_var_data = (struct efi_var_bootdata *)data;
|
||||
|
||||
efi_var_store_size = efi_var_data->store_size;
|
||||
efi_var_remaining_size = efi_var_data->remaining_size;
|
||||
efi_var_max_var_size = efi_var_data->max_var_size;
|
||||
}
|
||||
pa_data = data->next;
|
||||
early_iounmap(data, sizeof(*efi_var_data));
|
||||
}
|
||||
|
||||
boot_used_size = efi_var_store_size - efi_var_remaining_size;
|
||||
|
||||
set_bit(EFI_SYSTEM_TABLES, &x86_efi_facility);
|
||||
|
||||
/*
|
||||
@ -1085,6 +988,13 @@ void __init efi_enter_virtual_mode(void)
|
||||
runtime_code_page_mkexec();
|
||||
|
||||
kfree(new_memmap);
|
||||
|
||||
/* clean DUMMY object */
|
||||
efi.set_variable(efi_dummy_name, &EFI_DUMMY_GUID,
|
||||
EFI_VARIABLE_NON_VOLATILE |
|
||||
EFI_VARIABLE_BOOTSERVICE_ACCESS |
|
||||
EFI_VARIABLE_RUNTIME_ACCESS,
|
||||
0, NULL);
|
||||
}
|
||||
|
||||
/*
|
||||
@ -1136,33 +1046,65 @@ efi_status_t efi_query_variable_store(u32 attributes, unsigned long size)
|
||||
efi_status_t status;
|
||||
u64 storage_size, remaining_size, max_size;
|
||||
|
||||
if (!(attributes & EFI_VARIABLE_NON_VOLATILE))
|
||||
return 0;
|
||||
|
||||
status = efi.query_variable_info(attributes, &storage_size,
|
||||
&remaining_size, &max_size);
|
||||
if (status != EFI_SUCCESS)
|
||||
return status;
|
||||
|
||||
if (!max_size && remaining_size > size)
|
||||
printk_once(KERN_ERR FW_BUG "Broken EFI implementation"
|
||||
" is returning MaxVariableSize=0\n");
|
||||
/*
|
||||
* Some firmware implementations refuse to boot if there's insufficient
|
||||
* space in the variable store. We account for that by refusing the
|
||||
* write if permitting it would reduce the available space to under
|
||||
* 50%. However, some firmware won't reclaim variable space until
|
||||
* after the used (not merely the actively used) space drops below
|
||||
* a threshold. We can approximate that case with the value calculated
|
||||
* above. If both the firmware and our calculations indicate that the
|
||||
* available space would drop below 50%, refuse the write.
|
||||
* 5KB. This figure was provided by Samsung, so should be safe.
|
||||
*/
|
||||
if ((remaining_size - size < EFI_MIN_RESERVE) &&
|
||||
!efi_no_storage_paranoia) {
|
||||
|
||||
if (!storage_size || size > remaining_size ||
|
||||
(max_size && size > max_size))
|
||||
return EFI_OUT_OF_RESOURCES;
|
||||
/*
|
||||
* Triggering garbage collection may require that the firmware
|
||||
* generate a real EFI_OUT_OF_RESOURCES error. We can force
|
||||
* that by attempting to use more space than is available.
|
||||
*/
|
||||
unsigned long dummy_size = remaining_size + 1024;
|
||||
void *dummy = kmalloc(dummy_size, GFP_ATOMIC);
|
||||
|
||||
if (!efi_no_storage_paranoia &&
|
||||
((active_size + size + VAR_METADATA_SIZE > storage_size / 2) &&
|
||||
(remaining_size - size < storage_size / 2)))
|
||||
return EFI_OUT_OF_RESOURCES;
|
||||
status = efi.set_variable(efi_dummy_name, &EFI_DUMMY_GUID,
|
||||
EFI_VARIABLE_NON_VOLATILE |
|
||||
EFI_VARIABLE_BOOTSERVICE_ACCESS |
|
||||
EFI_VARIABLE_RUNTIME_ACCESS,
|
||||
dummy_size, dummy);
|
||||
|
||||
if (status == EFI_SUCCESS) {
|
||||
/*
|
||||
* This should have failed, so if it didn't make sure
|
||||
* that we delete it...
|
||||
*/
|
||||
efi.set_variable(efi_dummy_name, &EFI_DUMMY_GUID,
|
||||
EFI_VARIABLE_NON_VOLATILE |
|
||||
EFI_VARIABLE_BOOTSERVICE_ACCESS |
|
||||
EFI_VARIABLE_RUNTIME_ACCESS,
|
||||
0, dummy);
|
||||
}
|
||||
|
||||
/*
|
||||
* The runtime code may now have triggered a garbage collection
|
||||
* run, so check the variable info again
|
||||
*/
|
||||
status = efi.query_variable_info(attributes, &storage_size,
|
||||
&remaining_size, &max_size);
|
||||
|
||||
if (status != EFI_SUCCESS)
|
||||
return status;
|
||||
|
||||
/*
|
||||
* There still isn't enough room, so return an error
|
||||
*/
|
||||
if (remaining_size - size < EFI_MIN_RESERVE)
|
||||
return EFI_OUT_OF_RESOURCES;
|
||||
}
|
||||
|
||||
return EFI_SUCCESS;
|
||||
}
|
||||
|
@ -42,9 +42,6 @@ static const char * const sym_regex_kernel[S_NSYMTYPES] = {
|
||||
"^(xen_irq_disable_direct_reloc$|"
|
||||
"xen_save_fl_direct_reloc$|"
|
||||
"VDSO|"
|
||||
#if ELF_BITS == 64
|
||||
"__vvar_page|"
|
||||
#endif
|
||||
"__crc_)",
|
||||
|
||||
/*
|
||||
@ -72,6 +69,7 @@ static const char * const sym_regex_kernel[S_NSYMTYPES] = {
|
||||
"__per_cpu_load|"
|
||||
"init_per_cpu__.*|"
|
||||
"__end_rodata_hpage_align|"
|
||||
"__vvar_page|"
|
||||
#endif
|
||||
"_end)$"
|
||||
};
|
||||
|
@ -17,6 +17,7 @@
|
||||
#include <linux/slab.h>
|
||||
#include <linux/smp.h>
|
||||
#include <linux/irq_work.h>
|
||||
#include <linux/tick.h>
|
||||
|
||||
#include <asm/paravirt.h>
|
||||
#include <asm/desc.h>
|
||||
@ -447,6 +448,13 @@ static void __cpuinit xen_play_dead(void) /* used only with HOTPLUG_CPU */
|
||||
play_dead_common();
|
||||
HYPERVISOR_vcpu_op(VCPUOP_down, smp_processor_id(), NULL);
|
||||
cpu_bringup();
|
||||
/*
|
||||
* commit 4b0c0f294 (tick: Cleanup NOHZ per cpu data on cpu down)
|
||||
* clears certain data that the cpu_idle loop (which called us
|
||||
* and that we return from) expects. The only way to get that
|
||||
* data back is to call:
|
||||
*/
|
||||
tick_nohz_idle_enter();
|
||||
}
|
||||
|
||||
#else /* !CONFIG_HOTPLUG_CPU */
|
||||
|
@ -3164,7 +3164,7 @@ void blk_post_runtime_resume(struct request_queue *q, int err)
|
||||
q->rpm_status = RPM_ACTIVE;
|
||||
__blk_run_queue(q);
|
||||
pm_runtime_mark_last_busy(q->dev);
|
||||
pm_runtime_autosuspend(q->dev);
|
||||
pm_request_autosuspend(q->dev);
|
||||
} else {
|
||||
q->rpm_status = RPM_SUSPENDED;
|
||||
}
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user