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:
Arnd Bergmann 2013-06-20 02:14:59 +02:00
commit e5051b8472
280 changed files with 4001 additions and 2081 deletions

View File

@ -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

View File

@ -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

View File

@ -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):

View File

@ -208,6 +208,7 @@ clocks and IDs.
pll4_post_div 193
pll5_post_div 194
pll5_video_div 195
eim_slow 196
Examples:

View 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.

View 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";
};

View File

@ -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

View File

@ -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]

View File

@ -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

View File

@ -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

View File

@ -1,7 +1,7 @@
VERSION = 3
PATCHLEVEL = 10
SUBLEVEL = 0
EXTRAVERSION = -rc5
EXTRAVERSION = -rc6
NAME = Unicycling Gorilla
# *DOCUMENTATION*

View File

@ -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 || \

View File

@ -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 | \

View File

@ -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

View File

@ -11,6 +11,7 @@
#include <asm/mach-types.h>
.section ".start", "ax"
.arch armv4
__SA1100_start:

View File

@ -18,6 +18,7 @@
.section ".start", "ax"
.arch armv4
b __beginning
__ofw_data: .long 0 @ the number of memory blocks

View File

@ -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

View File

@ -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";

View File

@ -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 {

View File

@ -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 {

View File

@ -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 */

View File

@ -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 */

View File

@ -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 {

View File

@ -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

View File

@ -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()

View File

@ -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 */

View File

@ -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)
{

View File

@ -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"

View File

@ -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/

View File

@ -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

View File

@ -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);

View 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);

View File

@ -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;
}

View 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);

View File

@ -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;
}

View File

@ -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)
{

View File

@ -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);

View File

@ -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) \

View File

@ -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);
}

View File

@ -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);

View File

@ -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);
}

View File

@ -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);
}

View File

@ -18,6 +18,7 @@
#include <linux/module.h>
#include <linux/irq.h>
#include <linux/platform_data/asoc-imx-ssi.h>
#include "irq-common.h"

View File

@ -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();

View File

@ -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());

View 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

View File

@ -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);

View 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

View File

@ -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,

View File

@ -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);

View File

@ -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 */

View File

@ -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 */

View File

@ -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);

View File

@ -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 */

View File

@ -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);
}

View File

@ -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);
}

View File

@ -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 */

View File

@ -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)

View File

@ -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;

View File

@ -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 = {

View File

@ -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();
}

View File

@ -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

View File

@ -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)

View File

@ -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();

View File

@ -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 */

View File

@ -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

View File

@ -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
*

View File

@ -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;

View File

@ -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:

View File

@ -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

View File

@ -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,

View File

@ -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

View File

@ -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",

View File

@ -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)

View File

@ -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)

View File

@ -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 */

View File

@ -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, &reg, 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] "

View File

@ -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;

View File

@ -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();

View File

@ -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);

View File

@ -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;
}

View File

@ -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;
}

View File

@ -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;

View File

@ -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");
/*

View File

@ -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 "

View File

@ -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;
}

View File

@ -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);

View File

@ -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);

View File

@ -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)

View File

@ -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)
{
}

View File

@ -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... */

View File

@ -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,

View File

@ -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)

View File

@ -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

View File

@ -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

View File

@ -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,

View File

@ -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;
}

View File

@ -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)$"
};

View File

@ -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 */

View File

@ -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