summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Documentation/arm/OMAP/omap_dvfs111
-rw-r--r--Documentation/cpu-freq/governors.txt11
-rw-r--r--arch/arm/Kconfig73
-rw-r--r--arch/arm/Makefile8
-rw-r--r--arch/arm/boot/Makefile4
-rw-r--r--arch/arm/boot/compressed/Makefile4
-rw-r--r--arch/arm/boot/compressed/head.S251
-rw-r--r--arch/arm/boot/compressed/misc.c2
-rw-r--r--arch/arm/boot/compressed/vmlinux.lds.in3
-rw-r--r--arch/arm/common/Kconfig2
-rw-r--r--arch/arm/common/gic.c25
-rw-r--r--arch/arm/configs/omap2plus_defconfig5
-rw-r--r--arch/arm/configs/u8500_defconfig59
-rw-r--r--arch/arm/configs/vexpress_defconfig140
-rw-r--r--arch/arm/include/asm/bitops.h60
-rw-r--r--arch/arm/include/asm/cacheflush.h23
-rw-r--r--arch/arm/include/asm/cputype.h3
-rw-r--r--arch/arm/include/asm/fncpy.h94
-rw-r--r--arch/arm/include/asm/highmem.h29
-rw-r--r--arch/arm/include/asm/mach/arch.h13
-rw-r--r--arch/arm/include/asm/memory.h75
-rw-r--r--arch/arm/include/asm/module.h27
-rw-r--r--arch/arm/include/asm/pgalloc.h2
-rw-r--r--arch/arm/include/asm/pmu.h14
-rw-r--r--arch/arm/include/asm/proc-fns.h2
-rw-r--r--arch/arm/include/asm/processor.h12
-rw-r--r--arch/arm/include/asm/prom.h37
-rw-r--r--arch/arm/include/asm/ptrace.h2
-rw-r--r--arch/arm/include/asm/setup.h5
-rw-r--r--arch/arm/include/asm/spinlock.h53
-rw-r--r--arch/arm/include/asm/system.h17
-rw-r--r--arch/arm/include/asm/tls.h11
-rw-r--r--arch/arm/include/asm/traps.h1
-rw-r--r--arch/arm/kernel/Makefile1
-rw-r--r--arch/arm/kernel/armksyms.c22
-rw-r--r--arch/arm/kernel/bios32.c5
-rw-r--r--arch/arm/kernel/debug.S2
-rw-r--r--arch/arm/kernel/devtree.c147
-rw-r--r--arch/arm/kernel/entry-header.S14
-rw-r--r--arch/arm/kernel/etm.c4
-rw-r--r--arch/arm/kernel/head-common.S114
-rw-r--r--arch/arm/kernel/head-nommu.S3
-rw-r--r--arch/arm/kernel/head.S199
-rw-r--r--arch/arm/kernel/hw_breakpoint.c26
-rw-r--r--arch/arm/kernel/irq.c50
-rw-r--r--arch/arm/kernel/module.c35
-rw-r--r--arch/arm/kernel/perf_event.c17
-rw-r--r--arch/arm/kernel/perf_event_v6.c4
-rw-r--r--arch/arm/kernel/ptrace.c389
-rw-r--r--arch/arm/kernel/ptrace.h37
-rw-r--r--arch/arm/kernel/relocate_kernel.S12
-rw-r--r--arch/arm/kernel/return_address.c1
-rw-r--r--arch/arm/kernel/setup.c128
-rw-r--r--arch/arm/kernel/signal.c9
-rw-r--r--arch/arm/kernel/tcm.c2
-rw-r--r--arch/arm/kernel/traps.c4
-rw-r--r--arch/arm/kernel/vmlinux.lds.S4
-rw-r--r--arch/arm/lib/bitops.h50
-rw-r--r--arch/arm/lib/changebit.S10
-rw-r--r--arch/arm/lib/clearbit.S11
-rw-r--r--arch/arm/lib/setbit.S11
-rw-r--r--arch/arm/lib/testchangebit.S9
-rw-r--r--arch/arm/lib/testclearbit.S9
-rw-r--r--arch/arm/lib/testsetbit.S9
-rw-r--r--arch/arm/mach-aaec2000/include/mach/memory.h2
-rw-r--r--arch/arm/mach-at91/include/mach/memory.h2
-rw-r--r--arch/arm/mach-bcmring/include/mach/hardware.h2
-rw-r--r--arch/arm/mach-bcmring/include/mach/memory.h2
-rw-r--r--arch/arm/mach-clps711x/include/mach/memory.h2
-rw-r--r--arch/arm/mach-cns3xxx/include/mach/memory.h2
-rw-r--r--arch/arm/mach-davinci/include/mach/memory.h4
-rw-r--r--arch/arm/mach-dove/Kconfig2
-rw-r--r--arch/arm/mach-dove/include/mach/memory.h2
-rw-r--r--arch/arm/mach-ebsa110/include/mach/memory.h2
-rw-r--r--arch/arm/mach-ep93xx/include/mach/memory.h10
-rw-r--r--arch/arm/mach-footbridge/include/mach/memory.h2
-rw-r--r--arch/arm/mach-gemini/include/mach/memory.h4
-rw-r--r--arch/arm/mach-h720x/include/mach/memory.h2
-rw-r--r--arch/arm/mach-integrator/include/mach/memory.h2
-rw-r--r--arch/arm/mach-iop13xx/include/mach/memory.h2
-rw-r--r--arch/arm/mach-iop32x/include/mach/memory.h2
-rw-r--r--arch/arm/mach-iop33x/include/mach/memory.h2
-rw-r--r--arch/arm/mach-ixp2000/include/mach/memory.h2
-rw-r--r--arch/arm/mach-ixp23xx/include/mach/memory.h2
-rw-r--r--arch/arm/mach-ixp4xx/include/mach/memory.h2
-rw-r--r--arch/arm/mach-kirkwood/include/mach/memory.h2
-rw-r--r--arch/arm/mach-ks8695/include/mach/memory.h2
-rw-r--r--arch/arm/mach-lh7a40x/include/mach/memory.h2
-rw-r--r--arch/arm/mach-loki/include/mach/memory.h2
-rw-r--r--arch/arm/mach-lpc32xx/include/mach/memory.h2
-rw-r--r--arch/arm/mach-mmp/include/mach/memory.h2
-rw-r--r--arch/arm/mach-msm/board-msm7x27.c8
-rw-r--r--arch/arm/mach-msm/board-msm7x30.c8
-rw-r--r--arch/arm/mach-msm/board-qsd8x50.c4
-rw-r--r--arch/arm/mach-msm/board-sapphire.c2
-rw-r--r--arch/arm/mach-msm/include/mach/memory.h10
-rw-r--r--arch/arm/mach-mv78xx0/include/mach/memory.h2
-rw-r--r--arch/arm/mach-mx3/mach-kzm_arm11_01.c2
-rw-r--r--arch/arm/mach-mx5/clock-mx51-mx53.c41
-rw-r--r--arch/arm/mach-netx/include/mach/memory.h2
-rw-r--r--arch/arm/mach-nomadik/include/mach/memory.h2
-rw-r--r--arch/arm/mach-ns9xxx/include/mach/memory.h2
-rw-r--r--arch/arm/mach-nuc93x/include/mach/memory.h2
-rw-r--r--arch/arm/mach-omap1/Makefile3
-rw-r--r--arch/arm/mach-omap1/include/mach/debug-macro.S9
-rw-r--r--arch/arm/mach-omap1/omap1-cpufreq.c176
-rw-r--r--arch/arm/mach-omap1/pm.h6
-rw-r--r--arch/arm/mach-omap1/sleep.S3
-rw-r--r--arch/arm/mach-omap1/sram.S1
-rw-r--r--arch/arm/mach-omap2/Makefile8
-rw-r--r--arch/arm/mach-omap2/board-3430sdp.c26
-rw-r--r--arch/arm/mach-omap2/board-3630sdp.c19
-rw-r--r--arch/arm/mach-omap2/board-am3517evm.c16
-rw-r--r--arch/arm/mach-omap2/board-cm-t35.c22
-rw-r--r--arch/arm/mach-omap2/board-devkit8000.c22
-rw-r--r--arch/arm/mach-omap2/board-igep0020.c20
-rw-r--r--arch/arm/mach-omap2/board-omap3beagle.c22
-rw-r--r--arch/arm/mach-omap2/board-omap3evm.c30
-rw-r--r--arch/arm/mach-omap2/board-omap3pandora.c17
-rw-r--r--arch/arm/mach-omap2/board-omap3stalker.c26
-rw-r--r--arch/arm/mach-omap2/board-omap4panda.c137
-rw-r--r--arch/arm/mach-omap2/board-overo.c240
-rw-r--r--arch/arm/mach-omap2/board-rx51-peripherals.c4
-rw-r--r--arch/arm/mach-omap2/board-rx51-video.c15
-rw-r--r--arch/arm/mach-omap2/board-zoom-display.c15
-rw-r--r--arch/arm/mach-omap2/board-zoom-peripherals.c12
-rw-r--r--arch/arm/mach-omap2/board-zoom.c19
-rw-r--r--arch/arm/mach-omap2/clock2420_data.c9
-rw-r--r--arch/arm/mach-omap2/clock2430_data.c9
-rw-r--r--arch/arm/mach-omap2/clock3xxx_data.c15
-rw-r--r--arch/arm/mach-omap2/clock44xx_data.c16
-rw-r--r--arch/arm/mach-omap2/cpuidle34xx.c49
-rw-r--r--arch/arm/mach-omap2/display.c103
-rw-r--r--arch/arm/mach-omap2/dvfs.c770
-rw-r--r--arch/arm/mach-omap2/include/mach/debug-macro.S13
-rw-r--r--arch/arm/mach-omap2/include/mach/omap4-common.h4
-rw-r--r--arch/arm/mach-omap2/omap-headsmp.S2
-rw-r--r--arch/arm/mach-omap2/omap2plus-cpufreq.c250
-rw-r--r--arch/arm/mach-omap2/omap44xx-smc.S8
-rw-r--r--arch/arm/mach-omap2/omap_hwmod_2420_data.c311
-rw-r--r--arch/arm/mach-omap2/omap_hwmod_2430_data.c284
-rw-r--r--arch/arm/mach-omap2/omap_hwmod_3xxx_data.c436
-rw-r--r--arch/arm/mach-omap2/omap_hwmod_44xx_data.c604
-rw-r--r--arch/arm/mach-omap2/omap_twl.c60
-rw-r--r--arch/arm/mach-omap2/opp3xxx_data.c47
-rw-r--r--arch/arm/mach-omap2/opp4xxx_data.c13
-rw-r--r--arch/arm/mach-omap2/pm.c96
-rw-r--r--arch/arm/mach-omap2/pm.h3
-rw-r--r--arch/arm/mach-omap2/sleep24xx.S2
-rw-r--r--arch/arm/mach-omap2/sleep34xx.S71
-rw-r--r--arch/arm/mach-omap2/sram242x.S3
-rw-r--r--arch/arm/mach-omap2/sram243x.S3
-rw-r--r--arch/arm/mach-omap2/sram34xx.S37
-rw-r--r--arch/arm/mach-omap2/voltage.c159
-rw-r--r--arch/arm/mach-orion5x/include/mach/memory.h2
-rw-r--r--arch/arm/mach-pnx4008/include/mach/memory.h2
-rw-r--r--arch/arm/mach-pxa/balloon3.c2
-rw-r--r--arch/arm/mach-pxa/include/mach/memory.h2
-rw-r--r--arch/arm/mach-pxa/pxa25x.c1
-rw-r--r--arch/arm/mach-pxa/tosa-bt.c2
-rw-r--r--arch/arm/mach-pxa/tosa.c6
-rw-r--r--arch/arm/mach-realview/Kconfig5
-rw-r--r--arch/arm/mach-realview/include/mach/memory.h4
-rw-r--r--arch/arm/mach-realview/realview_eb.c2
-rw-r--r--arch/arm/mach-realview/realview_pb1176.c2
-rw-r--r--arch/arm/mach-realview/realview_pb11mp.c2
-rw-r--r--arch/arm/mach-realview/realview_pba8.c2
-rw-r--r--arch/arm/mach-realview/realview_pbx.c2
-rw-r--r--arch/arm/mach-rpc/include/mach/memory.h2
-rw-r--r--arch/arm/mach-s3c2400/include/mach/memory.h2
-rw-r--r--arch/arm/mach-s3c2410/include/mach/memory.h2
-rw-r--r--arch/arm/mach-s3c2410/mach-bast.c2
-rw-r--r--arch/arm/mach-s3c2412/mach-jive.c2
-rw-r--r--arch/arm/mach-s3c2440/mach-osiris.c2
-rw-r--r--arch/arm/mach-s3c2440/s3c244x.c2
-rw-r--r--arch/arm/mach-s3c24a0/include/mach/memory.h2
-rw-r--r--arch/arm/mach-s3c64xx/Makefile6
-rw-r--r--arch/arm/mach-s3c64xx/include/mach/memory.h2
-rw-r--r--arch/arm/mach-s5p6442/include/mach/memory.h2
-rw-r--r--arch/arm/mach-s5p64x0/include/mach/memory.h2
-rw-r--r--arch/arm/mach-s5pc100/include/mach/memory.h2
-rw-r--r--arch/arm/mach-s5pv210/cpufreq.c4
-rw-r--r--arch/arm/mach-s5pv210/include/mach/memory.h2
-rw-r--r--arch/arm/mach-s5pv210/sleep.S2
-rw-r--r--arch/arm/mach-s5pv310/cpufreq.c4
-rw-r--r--arch/arm/mach-s5pv310/include/mach/memory.h2
-rw-r--r--arch/arm/mach-s5pv310/irq-eint.c2
-rw-r--r--arch/arm/mach-sa1100/include/mach/memory.h2
-rw-r--r--arch/arm/mach-shark/include/mach/memory.h2
-rw-r--r--arch/arm/mach-shmobile/include/mach/memory.h2
-rw-r--r--arch/arm/mach-tcc8k/board-tcc8000-sdk.c2
-rw-r--r--arch/arm/mach-tegra/board-harmony.c6
-rw-r--r--arch/arm/mach-tegra/include/mach/memory.h2
-rw-r--r--arch/arm/mach-u300/include/mach/memory.h6
-rw-r--r--arch/arm/mach-u300/u300.c2
-rw-r--r--arch/arm/mach-ux500/board-mop500-sdi.c4
-rw-r--r--arch/arm/mach-ux500/board-mop500.c10
-rw-r--r--arch/arm/mach-ux500/clock.c2
-rw-r--r--arch/arm/mach-ux500/cpu-db8500.c51
-rw-r--r--arch/arm/mach-ux500/include/mach/memory.h2
-rw-r--r--arch/arm/mach-versatile/include/mach/memory.h2
-rw-r--r--arch/arm/mach-versatile/versatile_ab.c6
-rw-r--r--arch/arm/mach-versatile/versatile_pb.c6
-rw-r--r--arch/arm/mach-vexpress/Kconfig3
-rw-r--r--arch/arm/mach-vexpress/ct-ca9x4.c2
-rw-r--r--arch/arm/mach-vexpress/include/mach/memory.h2
-rw-r--r--arch/arm/mach-w90x900/include/mach/memory.h2
-rw-r--r--arch/arm/mm/Kconfig55
-rw-r--r--arch/arm/mm/Makefile1
-rw-r--r--arch/arm/mm/abort-ev6.S6
-rw-r--r--arch/arm/mm/init.c11
-rw-r--r--arch/arm/mm/mmap.c2
-rw-r--r--arch/arm/mm/mmu.c10
-rw-r--r--arch/arm/mm/vmregion.c17
-rw-r--r--arch/arm/plat-mxc/Kconfig6
-rw-r--r--arch/arm/plat-mxc/clock.c121
-rw-r--r--arch/arm/plat-mxc/include/mach/clock.h11
-rw-r--r--arch/arm/plat-mxc/include/mach/memory.h18
-rw-r--r--arch/arm/plat-omap/Makefile1
-rw-r--r--arch/arm/plat-omap/include/plat/display.h16
-rw-r--r--arch/arm/plat-omap/include/plat/dvfs.h34
-rw-r--r--arch/arm/plat-omap/include/plat/l3_2xxx.h20
-rw-r--r--arch/arm/plat-omap/include/plat/l3_3xxx.h20
-rw-r--r--arch/arm/plat-omap/include/plat/l4_2xxx.h24
-rw-r--r--arch/arm/plat-omap/include/plat/l4_3xxx.h10
-rw-r--r--arch/arm/plat-omap/include/plat/memory.h4
-rw-r--r--arch/arm/plat-omap/include/plat/omap_device.h9
-rw-r--r--arch/arm/plat-omap/include/plat/serial.h2
-rw-r--r--arch/arm/plat-omap/include/plat/sram.h14
-rw-r--r--arch/arm/plat-omap/include/plat/voltage.h148
-rw-r--r--arch/arm/plat-omap/omap_device.c58
-rw-r--r--arch/arm/plat-omap/sram.c14
-rw-r--r--arch/arm/plat-s3c24xx/Makefile6
-rw-r--r--arch/arm/plat-s3c24xx/cpu-freq.c2
-rw-r--r--arch/arm/plat-s3c24xx/dma.c2
-rw-r--r--arch/arm/plat-s3c24xx/include/plat/irq.h2
-rw-r--r--arch/arm/plat-s5p/Makefile4
-rw-r--r--arch/arm/plat-s5p/irq-eint.c4
-rw-r--r--arch/arm/plat-samsung/Makefile4
-rw-r--r--arch/arm/plat-samsung/adc.c2
-rw-r--r--arch/arm/plat-samsung/gpio.c2
-rw-r--r--arch/arm/plat-samsung/include/plat/gpio-core.h6
-rw-r--r--arch/arm/plat-samsung/include/plat/pm.h4
-rw-r--r--arch/arm/plat-samsung/pwm.c2
-rw-r--r--arch/arm/plat-spear/include/plat/memory.h2
-rw-r--r--arch/arm/plat-stmp3xxx/include/mach/memory.h2
-rw-r--r--arch/arm/plat-tcc/include/mach/memory.h2
-rw-r--r--arch/arm/vfp/vfpmodule.c9
-rw-r--r--drivers/amba/bus.c8
-rw-r--r--drivers/char/hw_random/nomadik-rng.c2
-rw-r--r--drivers/dma/amba-pl08x.c2
-rw-r--r--drivers/dma/pl330.c2
-rw-r--r--drivers/gpio/pl061.c2
-rw-r--r--drivers/input/serio/ambakmi.c3
-rw-r--r--drivers/mmc/host/mmci.c3
-rw-r--r--drivers/pcmcia/pxa2xx_colibri.c3
-rw-r--r--drivers/rtc/rtc-pl030.c2
-rw-r--r--drivers/rtc/rtc-pl031.c2
-rw-r--r--drivers/spi/amba-pl022.c2
-rw-r--r--drivers/tty/serial/amba-pl010.c2
-rw-r--r--drivers/tty/serial/amba-pl011.c2
-rw-r--r--drivers/video/amba-clcd.c2
-rw-r--r--drivers/video/omap2/dss/Kconfig6
-rw-r--r--drivers/video/omap2/dss/core.c448
-rw-r--r--drivers/video/omap2/dss/dispc.c181
-rw-r--r--drivers/video/omap2/dss/dpi.c16
-rw-r--r--drivers/video/omap2/dss/dsi.c96
-rw-r--r--drivers/video/omap2/dss/dss.c550
-rw-r--r--drivers/video/omap2/dss/dss.h56
-rw-r--r--drivers/video/omap2/dss/dss_features.c10
-rw-r--r--drivers/video/omap2/dss/dss_features.h22
-rw-r--r--drivers/video/omap2/dss/manager.c4
-rw-r--r--drivers/video/omap2/dss/overlay.c4
-rw-r--r--drivers/video/omap2/dss/rfbi.c128
-rw-r--r--drivers/video/omap2/dss/sdi.c8
-rw-r--r--drivers/video/omap2/dss/venc.c133
-rw-r--r--drivers/video/omap2/omapfb/Kconfig6
-rw-r--r--drivers/watchdog/sp805_wdt.c2
-rw-r--r--include/linux/amba/bus.h6
-rw-r--r--sound/arm/aaci.c3
280 files changed, 7101 insertions, 2412 deletions
diff --git a/Documentation/arm/OMAP/omap_dvfs b/Documentation/arm/OMAP/omap_dvfs
new file mode 100644
index 00000000000..3ddc5a5c78d
--- /dev/null
+++ b/Documentation/arm/OMAP/omap_dvfs
@@ -0,0 +1,111 @@
+*=============*
+* DVFS Framework *
+*=============*
+(C) 2011 Vishwnath BS <vishwanath.bs@ti.com>, Texas Instruments Incorporated
+Contents
+--------
+1. Introduction
+2. Data Structure Organization
+3. DVFS APIs
+
+1. Introduction
+===============
+DVFS is a technique that uses the optimal operating frequency and voltage to
+allow a task to be performed in the required amount of time.
+OMAP processors have voltage domains whose voltage can be scaled to
+various levels depending on which the operating frequencies of certain
+devices belonging to the domain will also need to be scaled. This voltage
+frequency tuple is known as Operating Performance Point (OPP). A device
+can have multiple OPP's. Also a voltage domain could be shared between
+multiple devices. Also there could be dependencies between various
+voltage domains for maintaining system performance like VDD<X>
+should be at voltage v1 when VDD<Y> is at voltage v2.
+
+The design of this framework takes into account all the above mentioned points.
+To summarize the basic design of DVFS framework:-
+
+1. Have device opp tables for each device whose operating frequency can be
+ scaled. This is easy now due to the existance of hwmod layer which
+ allow storing of device specific info. The device opp tables contain
+ the opp pairs (frequency voltage tuples), the voltage domain pointer
+ to which the device belongs to, the device specific set_rate and
+ get_rate API's which will do the actual scaling of the device frequency
+ and retrieve the current device frequency.
+2. Introduce use counting on a per VDD basis. This is to take care multiple
+ requests to scale a VDD. The VDD will be scaled to the maximum of the
+ voltages requested.
+3. Keep track of all scalable devices belonging to a particular voltage
+ domain the voltage layer.
+4. Keep track of frequency requests for each of the device. This will enable
+ to scale individual devices to different frequency (even w/o scaling voltage
+ aka frequency throttling)
+5. Generic dvfs API that can be called by anybody to scale a device opp.
+ This API takes the device pointer and frequency to which the device
+ needs to be scaled to. This API then internally finds out the voltage
+ domain to which the device belongs to and the voltage to which the voltage
+ domain needs to be put to for the device to be scaled to the new frequency
+ from he device opp table. Then this API will add requested frequency into
+ the corresponding target device frequency list and add voltage request to
+ the corresponding vdd. Subsequently it calls voltage scale function which
+ will find out the highest requested voltage for the given vdd and scales
+ the voltage to the required one. It also runs through the list of all
+ scalable devices belonging to this voltage domain and scale them to the
+ appropriate frequencies using the set_rate pointer in the device opp tables.
+6. Handle inter VDD dependecies.
+
+
+2. The Core DVFS data structure:
+=================================
+
+ |-------------------| |-------------------|
+ |User2 (dev2, freq2)| |User4 (dev4, freq4)|
+ |-------^-----------| |-------^-----------|
+ | |
+ |-------|-----------| |-------|-----------|
+ |User1 (dev1, freq1)| |User3 (dev3, freq3)|(omap_dev_user_list)
+ |-------^-----------| |-------^-----------|
+ | |
+ |---|--------------| |------------------|
+ |--------->| DEV1 (dev) |------------>| DEV2 (dev) |(omap_vdd_dev_list)
+ | |omap_dev_user_list| |omap_dev_user_list|
+ | |------------------| |------------------|
+ |
+ |---------|-----------|
+ | VDD_n |
+ | omap_vdd_dev_list |
+ | omap_vdd_user_list |(omap_vdd_dvfs_info)
+ | |
+ |--------|------------|
+ |
+ | |------------| |------------| |--------------|
+ |---------> | vdd_user1 |->| vdd_user2 |->| vdd_user3 | (omap_vdd_user_list)
+ | (dev, volt)| | (dev, volt)| | (dev, volt) |
+ |------------| |------------| |--------------|
+
+3. APIs:
+ =====
+ 1. omap_device_scale - Set a new rate at which the device is to operate
+
+ Examples:
+ 1. Simple Device scaling:
+ Suppose module M wants to put device dev1 to frequency f1. Let's say that mdev
+ is the device * for module M. Then this could be achieved by
+ ret = omap_device_scale(mdev, dev1, f1)
+ if (ret)
+ /* handle error *.
+
+ 2. Frequency Throttling
+ Suppose say there are 2 modules M1 and M2 in Voltage domain VDDx.
+ Module M1 wants to set VDDx to OPP100 voltage which means M1 and M2 will
+ be running at OPP100 frequency. Suppose Module M2 wants to run at OPP50
+ frequency (say f2_opp50) instead of OPP100. This can be achieved by
+
+ /* this operation will place M1 and M2 to run at OPP100 */
+ ret = omap_device_scale(mdev1, dev1, f1_opp100);
+ if (ret)
+ /* handle error *.
+
+ /* This operation will bring M2 to run at f2_opp50 w/o decreasing VDDx voltage */
+ ret = omap_device_scale(mdev2, dev2, f2_opp50);
+ if (ret)
+ /* handle error *.
diff --git a/Documentation/cpu-freq/governors.txt b/Documentation/cpu-freq/governors.txt
index 737988fca64..e74d0a2eb1c 100644
--- a/Documentation/cpu-freq/governors.txt
+++ b/Documentation/cpu-freq/governors.txt
@@ -158,6 +158,17 @@ intensive calculation on your laptop that you do not care how long it
takes to complete as you can 'nice' it and prevent it from taking part
in the deciding process of whether to increase your CPU frequency.
+sampling_down_factor: this parameter controls the rate at which the
+kernel makes a decision on when to decrease the frequency while running
+at top speed. When set to 1 (the default) decisions to reevaluate load
+are made at the same interval regardless of current clock speed. But
+when set to greater than 1 (e.g. 100) it acts as a multiplier for the
+scheduling interval for reevaluating load when the CPU is at its top
+speed due to high load. This improves performance by reducing the overhead
+of load evaluation and helping the CPU stay at its top speed when truly
+busy, rather than shifting back and forth in speed. This tunable has no
+effect on behavior at lower speeds/lower CPU loads.
+
2.5 Conservative
----------------
diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
index 166efa2a19c..a53245a9ef5 100644
--- a/arch/arm/Kconfig
+++ b/arch/arm/Kconfig
@@ -7,7 +7,7 @@ config ARM
select HAVE_MEMBLOCK
select RTC_LIB
select SYS_SUPPORTS_APM_EMULATION
- select GENERIC_ATOMIC64 if (!CPU_32v6K || !AEABI)
+ select GENERIC_ATOMIC64 if (CPU_V6 || !CPU_32v6K || !AEABI)
select HAVE_OPROFILE if (HAVE_PERF_EVENTS)
select HAVE_ARCH_KGDB
select HAVE_KPROBES if (!XIP_KERNEL && !THUMB2_KERNEL)
@@ -24,7 +24,7 @@ config ARM
select HAVE_PERF_EVENTS
select PERF_USE_VMALLOC
select HAVE_REGS_AND_STACK_ACCESS_API
- select HAVE_HW_BREAKPOINT if (PERF_EVENTS && (CPU_V6 || CPU_V7))
+ select HAVE_HW_BREAKPOINT if (PERF_EVENTS && (CPU_V6 || CPU_V6K || CPU_V7))
select HAVE_C_RECORDMCOUNT
select HAVE_GENERIC_HARDIRQS
select HAVE_SPARSE_IRQ
@@ -178,11 +178,6 @@ config FIQ
config ARCH_MTD_XIP
bool
-config ARM_L1_CACHE_SHIFT_6
- bool
- help
- Setting ARM L1 cache line size to 64 Bytes.
-
config VECTORS_BASE
hex
default 0xffff0000 if MMU || CPU_HIGH_VECTOR
@@ -191,6 +186,22 @@ config VECTORS_BASE
help
The base address of exception vectors.
+config ARM_PATCH_PHYS_VIRT
+ bool "Patch physical to virtual translations at runtime (EXPERIMENTAL)"
+ depends on EXPERIMENTAL
+ depends on !XIP_KERNEL && MMU
+ depends on !ARCH_REALVIEW || !SPARSEMEM
+ help
+ Patch phys-to-virt translation functions at runtime according to
+ the position of the kernel in system memory.
+
+ This can only be used with non-XIP with MMU kernels where
+ the base of physical memory is at a 16MB boundary.
+
+config ARM_PATCH_PHYS_VIRT_16BIT
+ def_bool y
+ depends on ARM_PATCH_PHYS_VIRT && ARCH_MSM
+
source "init/Kconfig"
source "kernel/Kconfig.freezer"
@@ -457,6 +468,7 @@ config ARCH_IXP4XX
config ARCH_DOVE
bool "Marvell Dove"
+ select CPU_V6K
select PCI
select ARCH_REQUIRE_GPIOLIB
select GENERIC_CLOCKEVENTS
@@ -1048,7 +1060,7 @@ config XSCALE_PMU
default y
config CPU_HAS_PMU
- depends on (CPU_V6 || CPU_V7 || XSCALE_PMU) && \
+ depends on (CPU_V6 || CPU_V6K || CPU_V7 || XSCALE_PMU) && \
(!ARCH_OMAP3 || OMAP3_EMU)
default y
bool
@@ -1064,7 +1076,7 @@ endif
config ARM_ERRATA_411920
bool "ARM errata: Invalidation of the Instruction Cache operation can fail"
- depends on CPU_V6
+ depends on CPU_V6 || CPU_V6K
help
Invalidation of the Instruction Cache operation can
fail. This erratum is present in 1136 (before r1p4), 1156 and 1176.
@@ -1275,6 +1287,7 @@ source "kernel/time/Kconfig"
config SMP
bool "Symmetric Multi-Processing (EXPERIMENTAL)"
depends on EXPERIMENTAL
+ depends on CPU_V6K || CPU_V7
depends on GENERIC_CLOCKEVENTS
depends on REALVIEW_EB_ARM11MP || REALVIEW_EB_A9MP || \
MACH_REALVIEW_PB11MP || MACH_REALVIEW_PBX || ARCH_OMAP4 || \
@@ -1386,7 +1399,7 @@ config HZ
config THUMB2_KERNEL
bool "Compile the kernel in Thumb-2 mode (EXPERIMENTAL)"
- depends on CPU_V7 && !CPU_V6 && EXPERIMENTAL
+ depends on CPU_V7 && !CPU_V6 && !CPU_V6K && EXPERIMENTAL
select AEABI
select ARM_ASM_UNIFIED
help
@@ -1396,6 +1409,37 @@ config THUMB2_KERNEL
If unsure, say N.
+config THUMB2_AVOID_R_ARM_THM_JUMP11
+ bool "Work around buggy Thumb-2 short branch relocations in gas"
+ depends on THUMB2_KERNEL && MODULES
+ default y
+ help
+ Various binutils versions can resolve Thumb-2 branches to
+ locally-defined, preemptible global symbols as short-range "b.n"
+ branch instructions.
+
+ This is a problem, because there's no guarantee the final
+ destination of the symbol, or any candidate locations for a
+ trampoline, are within range of the branch. For this reason, the
+ kernel does not support fixing up the R_ARM_THM_JUMP11 (102)
+ relocation in modules at all, and it makes little sense to add
+ support.
+
+ The symptom is that the kernel fails with an "unsupported
+ relocation" error when loading some modules.
+
+ Until fixed tools are available, passing
+ -fno-optimize-sibling-calls to gcc should prevent gcc generating
+ code which hits this problem, at the cost of a bit of extra runtime
+ stack usage in some cases.
+
+ The problem is described in more detail at:
+ https://bugs.launchpad.net/binutils-linaro/+bug/725126
+
+ Only Thumb-2 kernels are affected.
+
+ Unless you are sure your tools don't have this problem, say Y.
+
config ARM_ASM_UNIFIED
bool
@@ -1611,6 +1655,13 @@ endmenu
menu "Boot options"
+config USE_OF
+ bool "Flattened Device Tree support"
+ select OF
+ select OF_EARLY_FLATTREE
+ help
+ Include support for flattened device tree machine descriptions.
+
# Compressed boot loader in ROM. Yes, we really want to ask about
# TEXT and BSS so we preserve their values in the config files.
config ZBOOT_ROM_TEXT
@@ -1877,7 +1928,7 @@ config FPE_FASTFPE
config VFP
bool "VFP-format floating point maths"
- depends on CPU_V6 || CPU_ARM926T || CPU_V7 || CPU_FEROCEON
+ depends on CPU_V6 || CPU_V6K || CPU_ARM926T || CPU_V7 || CPU_FEROCEON
help
Say Y to include VFP support code in the kernel. This is needed
if your hardware includes a VFP unit.
diff --git a/arch/arm/Makefile b/arch/arm/Makefile
index 6f7b29294c8..b1031504fad 100644
--- a/arch/arm/Makefile
+++ b/arch/arm/Makefile
@@ -89,6 +89,7 @@ tune-$(CONFIG_CPU_XSCALE) :=$(call cc-option,-mtune=xscale,-mtune=strongarm110)
tune-$(CONFIG_CPU_XSC3) :=$(call cc-option,-mtune=xscale,-mtune=strongarm110) -Wa,-mcpu=xscale
tune-$(CONFIG_CPU_FEROCEON) :=$(call cc-option,-mtune=marvell-f,-mtune=xscale)
tune-$(CONFIG_CPU_V6) :=$(call cc-option,-mtune=arm1136j-s,-mtune=strongarm)
+tune-$(CONFIG_CPU_V6K) :=$(call cc-option,-mtune=arm1136j-s,-mtune=strongarm)
ifeq ($(CONFIG_AEABI),y)
CFLAGS_ABI :=-mabi=aapcs-linux -mno-thumb-interwork
@@ -105,6 +106,10 @@ AFLAGS_AUTOIT :=$(call as-option,-Wa$(comma)-mimplicit-it=always,-Wa$(comma)-mau
AFLAGS_NOWARN :=$(call as-option,-Wa$(comma)-mno-warn-deprecated,-Wa$(comma)-W)
CFLAGS_THUMB2 :=-mthumb $(AFLAGS_AUTOIT) $(AFLAGS_NOWARN)
AFLAGS_THUMB2 :=$(CFLAGS_THUMB2) -Wa$(comma)-mthumb
+# Work around buggy relocation from gas if requested:
+ifeq ($(CONFIG_THUMB2_AVOID_R_ARM_THM_JUMP11),y)
+CFLAGS_MODULE +=-fno-optimize-sibling-calls
+endif
endif
# Need -Uarm for gcc < 3.x
@@ -280,7 +285,7 @@ bzImage: zImage
zImage Image xipImage bootpImage uImage: vmlinux
$(Q)$(MAKE) $(build)=$(boot) MACHINE=$(MACHINE) $(boot)/$@
-zinstall install: vmlinux
+zinstall uinstall install: vmlinux
$(Q)$(MAKE) $(build)=$(boot) MACHINE=$(MACHINE) $@
# We use MRPROPER_FILES and CLEAN_FILES now
@@ -301,6 +306,7 @@ define archhelp
echo ' (supply initrd image via make variable INITRD=<path>)'
echo ' install - Install uncompressed kernel'
echo ' zinstall - Install compressed kernel'
+ echo ' uinstall - Install U-Boot wrapped compressed kernel'
echo ' Install using (your) ~/bin/$(INSTALLKERNEL) or'
echo ' (distribution) /sbin/$(INSTALLKERNEL) or'
echo ' install to $$(INSTALL_PATH) and run lilo'
diff --git a/arch/arm/boot/Makefile b/arch/arm/boot/Makefile
index 4d26f2c52a7..9128fddf110 100644
--- a/arch/arm/boot/Makefile
+++ b/arch/arm/boot/Makefile
@@ -99,6 +99,10 @@ zinstall: $(obj)/zImage
$(CONFIG_SHELL) $(srctree)/$(src)/install.sh $(KERNELRELEASE) \
$(obj)/zImage System.map "$(INSTALL_PATH)"
+uinstall: $(obj)/uImage
+ $(CONFIG_SHELL) $(srctree)/$(src)/install.sh $(KERNELRELEASE) \
+ $(obj)/uImage System.map "$(INSTALL_PATH)"
+
zi:
$(CONFIG_SHELL) $(srctree)/$(src)/install.sh $(KERNELRELEASE) \
$(obj)/zImage System.map "$(INSTALL_PATH)"
diff --git a/arch/arm/boot/compressed/Makefile b/arch/arm/boot/compressed/Makefile
index 0a8f748e506..9d328be6e5e 100644
--- a/arch/arm/boot/compressed/Makefile
+++ b/arch/arm/boot/compressed/Makefile
@@ -83,9 +83,11 @@ endif
EXTRA_CFLAGS := -fpic -fno-builtin
EXTRA_AFLAGS := -Wa,-march=all
+# Provide size of uncompressed kernel to the decompressor via a linker symbol.
+LDFLAGS_vmlinux := --defsym _image_size=$(shell stat -c "%s" $(obj)/../Image)
# Supply ZRELADDR to the decompressor via a linker symbol.
ifneq ($(CONFIG_AUTO_ZRELADDR),y)
-LDFLAGS_vmlinux := --defsym zreladdr=$(ZRELADDR)
+LDFLAGS_vmlinux += --defsym zreladdr=$(ZRELADDR)
endif
ifeq ($(CONFIG_CPU_ENDIAN_BE8),y)
LDFLAGS_vmlinux += --be8
diff --git a/arch/arm/boot/compressed/head.S b/arch/arm/boot/compressed/head.S
index 7193884ed8b..84ac4d65631 100644
--- a/arch/arm/boot/compressed/head.S
+++ b/arch/arm/boot/compressed/head.S
@@ -21,7 +21,7 @@
#if defined(CONFIG_DEBUG_ICEDCC)
-#ifdef CONFIG_CPU_V6
+#if defined(CONFIG_CPU_V6) || defined(CONFIG_CPU_V6K)
.macro loadsp, rb, tmp
.endm
.macro writeb, ch, rb
@@ -128,14 +128,14 @@ wait: mrc p14, 0, pc, c0, c1, 0
.arm @ Always enter in ARM state
start:
.type start,#function
- THUMB( adr r12, BSYM(1f) )
- THUMB( bx r12 )
- THUMB( .rept 6 )
- ARM( .rept 8 )
+ .rept 7
mov r0, r0
.endr
+ ARM( mov r0, r0 )
+ ARM( b 1f )
+ THUMB( adr r12, BSYM(1f) )
+ THUMB( bx r12 )
- b 1f
.word 0x016f2818 @ Magic numbers to help the loader
.word start @ absolute load/run zImage address
.word _edata @ zImage end address
@@ -174,9 +174,7 @@ not_angel:
*/
.text
- adr r0, LC0
- ldmia r0, {r1, r2, r3, r5, r6, r11, ip}
- ldr sp, [r0, #28]
+
#ifdef CONFIG_AUTO_ZRELADDR
@ determine final kernel image address
mov r4, pc
@@ -185,35 +183,108 @@ not_angel:
#else
ldr r4, =zreladdr
#endif
- subs r0, r0, r1 @ calculate the delta offset
- @ if delta is zero, we are
- beq not_relocated @ running at the address we
- @ were linked at.
+ bl cache_on
+
+restart: adr r0, LC0
+ ldmia r0, {r1, r2, r3, r5, r6, r9, r11, r12}
+ ldr sp, [r0, #32]
+
+ /*
+ * We might be running at a different address. We need
+ * to fix up various pointers.
+ */
+ sub r0, r0, r1 @ calculate the delta offset
+ add r5, r5, r0 @ _start
+ add r6, r6, r0 @ _edata
+#ifndef CONFIG_ZBOOT_ROM
+ /* malloc space is above the relocated stack (64k max) */
+ add sp, sp, r0
+ add r10, sp, #0x10000
+#else
/*
- * We're running at a different address. We need to fix
- * up various pointers:
- * r5 - zImage base address (_start)
- * r6 - size of decompressed image
- * r11 - GOT start
- * ip - GOT end
+ * With ZBOOT_ROM the bss/stack is non relocatable,
+ * but someone could still run this code from RAM,
+ * in which case our reference is _edata.
*/
- add r5, r5, r0
+ mov r10, r6
+#endif
+
+/*
+ * Check to see if we will overwrite ourselves.
+ * r4 = final kernel address
+ * r5 = start of this image
+ * r9 = size of decompressed image
+ * r10 = end of this image, including bss/stack/malloc space if non XIP
+ * We basically want:
+ * r4 >= r10 -> OK
+ * r4 + image length <= r5 -> OK
+ */
+ cmp r4, r10
+ bhs wont_overwrite
+ add r10, r4, r9
+ cmp r10, r5
+ bls wont_overwrite
+
+/*
+ * Relocate ourselves past the end of the decompressed kernel.
+ * r5 = start of this image
+ * r6 = _edata
+ * r10 = end of the decompressed kernel
+ * Because we always copy ahead, we need to do it from the end and go
+ * backward in case the source and destination overlap.
+ */
+ /* Round up to next 256-byte boundary. */
+ add r10, r10, #256
+ bic r10, r10, #255
+
+ sub r9, r6, r5 @ size to copy
+ add r9, r9, #31 @ rounded up to a multiple
+ bic r9, r9, #31 @ ... of 32 bytes
+ add r6, r9, r5
+ add r9, r9, r10
+
+1: ldmdb r6!, {r0 - r3, r10 - r12, lr}
+ cmp r6, r5
+ stmdb r9!, {r0 - r3, r10 - r12, lr}
+ bhi 1b
+
+ /* Preserve offset to relocated code. */
+ sub r6, r9, r6
+
+ bl cache_clean_flush
+
+ adr r0, BSYM(restart)
+ add r0, r0, r6
+ mov pc, r0
+
+wont_overwrite:
+/*
+ * If delta is zero, we are running at the address we were linked at.
+ * r0 = delta
+ * r2 = BSS start
+ * r3 = BSS end
+ * r4 = kernel execution address
+ * r7 = architecture ID
+ * r8 = atags pointer
+ * r11 = GOT start
+ * r12 = GOT end
+ * sp = stack pointer
+ */
+ teq r0, #0
+ beq not_relocated
add r11, r11, r0
- add ip, ip, r0
+ add r12, r12, r0
#ifndef CONFIG_ZBOOT_ROM
/*
* If we're running fully PIC === CONFIG_ZBOOT_ROM = n,
* we need to fix up pointers into the BSS region.
- * r2 - BSS start
- * r3 - BSS end
- * sp - stack pointer
+ * Note that the stack pointer has already been fixed up.
*/
add r2, r2, r0
add r3, r3, r0
- add sp, sp, r0
/*
* Relocate all entries in the GOT table.
@@ -221,7 +292,7 @@ not_angel:
1: ldr r1, [r11, #0] @ relocate entries in the GOT
add r1, r1, r0 @ table. This fixes up the
str r1, [r11], #4 @ C references.
- cmp r11, ip
+ cmp r11, r12
blo 1b
#else
@@ -234,7 +305,7 @@ not_angel:
cmphs r3, r1 @ _end < entry
addlo r1, r1, r0 @ table. This fixes up the
str r1, [r11], #4 @ C references.
- cmp r11, ip
+ cmp r11, r12
blo 1b
#endif
@@ -246,76 +317,24 @@ not_relocated: mov r0, #0
cmp r2, r3
blo 1b
- /*
- * The C runtime environment should now be setup
- * sufficiently. Turn the cache on, set up some
- * pointers, and start decompressing.
- */
- bl cache_on
-
- mov r1, sp @ malloc space above stack
- add r2, sp, #0x10000 @ 64k max
-
/*
- * Check to see if we will overwrite ourselves.
- * r4 = final kernel address
- * r5 = start of this image
- * r6 = size of decompressed image
- * r2 = end of malloc space (and therefore this image)
- * We basically want:
- * r4 >= r2 -> OK
- * r4 + image length <= r5 -> OK
+ * The C runtime environment should now be setup sufficiently.
+ * Set up some pointers, and start decompressing.
+ * r4 = kernel execution address
+ * r7 = architecture ID
+ * r8 = atags pointer
*/
- cmp r4, r2
- bhs wont_overwrite
- add r0, r4, r6
- cmp r0, r5
- bls wont_overwrite
-
- mov r5, r2 @ decompress after malloc space
- mov r0, r5
+ mov r0, r4
+ mov r1, sp @ malloc space above stack
+ add r2, sp, #0x10000 @ 64k max
mov r3, r7
bl decompress_kernel
-
- add r0, r0, #127 + 128 @ alignment + stack
- bic r0, r0, #127 @ align the kernel length
-/*
- * r0 = decompressed kernel length
- * r1-r3 = unused
- * r4 = kernel execution address
- * r5 = decompressed kernel start
- * r7 = architecture ID
- * r8 = atags pointer
- * r9-r12,r14 = corrupted
- */
- add r1, r5, r0 @ end of decompressed kernel
- adr r2, reloc_start
- ldr r3, LC1
- add r3, r2, r3
-1: ldmia r2!, {r9 - r12, r14} @ copy relocation code
- stmia r1!, {r9 - r12, r14}
- ldmia r2!, {r9 - r12, r14}
- stmia r1!, {r9 - r12, r14}
- cmp r2, r3
- blo 1b
- mov sp, r1
- add sp, sp, #128 @ relocate the stack
-
bl cache_clean_flush
- ARM( add pc, r5, r0 ) @ call relocation code
- THUMB( add r12, r5, r0 )
- THUMB( mov pc, r12 ) @ call relocation code
-
-/*
- * We're not in danger of overwriting ourselves. Do this the simple way.
- *
- * r4 = kernel execution address
- * r7 = architecture ID
- */
-wont_overwrite: mov r0, r4
- mov r3, r7
- bl decompress_kernel
- b call_kernel
+ bl cache_off
+ mov r0, #0 @ must be zero
+ mov r1, r7 @ restore architecture number
+ mov r2, r8 @ restore atags pointer
+ mov pc, r4 @ call kernel
.align 2
.type LC0, #object
@@ -323,11 +342,11 @@ LC0: .word LC0 @ r1
.word __bss_start @ r2
.word _end @ r3
.word _start @ r5
- .word _image_size @ r6
+ .word _edata @ r6
+ .word _image_size @ r9
.word _got_start @ r11
.word _got_end @ ip
.word user_stack_end @ sp
-LC1: .word reloc_end - reloc_start
.size LC0, . - LC0
#ifdef CONFIG_ARCH_RPC
@@ -353,7 +372,7 @@ params: ldr r0, =0x10000100 @ params_phys for RPC
* On exit,
* r0, r1, r2, r3, r9, r10, r12 corrupted
* This routine must preserve:
- * r4, r5, r6, r7, r8
+ * r4, r7, r8
*/
.align 5
cache_on: mov r3, #8 @ cache_on function
@@ -551,43 +570,6 @@ __common_mmu_cache_on:
#endif
/*
- * All code following this line is relocatable. It is relocated by
- * the above code to the end of the decompressed kernel image and
- * executed there. During this time, we have no stacks.
- *
- * r0 = decompressed kernel length
- * r1-r3 = unused
- * r4 = kernel execution address
- * r5 = decompressed kernel start
- * r7 = architecture ID
- * r8 = atags pointer
- * r9-r12,r14 = corrupted
- */
- .align 5
-reloc_start: add r9, r5, r0
- sub r9, r9, #128 @ do not copy the stack
- debug_reloc_start
- mov r1, r4
-1:
- .rept 4
- ldmia r5!, {r0, r2, r3, r10 - r12, r14} @ relocate kernel
- stmia r1!, {r0, r2, r3, r10 - r12, r14}
- .endr
-
- cmp r5, r9
- blo 1b
- mov sp, r1
- add sp, sp, #128 @ relocate the stack
- debug_reloc_end
-
-call_kernel: bl cache_clean_flush
- bl cache_off
- mov r0, #0 @ must be zero
- mov r1, r7 @ restore architecture number
- mov r2, r8 @ restore atags pointer
- mov pc, r4 @ call kernel
-
-/*
* Here follow the relocatable cache support functions for the
* various processors. This is a generic hook for locating an
* entry and jumping to an instruction at the specified offset
@@ -791,7 +773,7 @@ proc_types:
* On exit,
* r0, r1, r2, r3, r9, r12 corrupted
* This routine must preserve:
- * r4, r6, r7
+ * r4, r7, r8
*/
.align 5
cache_off: mov r3, #12 @ cache_off function
@@ -866,7 +848,7 @@ __armv3_mmu_cache_off:
* On exit,
* r1, r2, r3, r9, r10, r11, r12 corrupted
* This routine must preserve:
- * r0, r4, r5, r6, r7
+ * r4, r6, r7, r8
*/
.align 5
cache_clean_flush:
@@ -1088,7 +1070,6 @@ memdump: mov r12, r0
#endif
.ltorg
-reloc_end:
.align
.section ".stack", "aw", %nobits
diff --git a/arch/arm/boot/compressed/misc.c b/arch/arm/boot/compressed/misc.c
index e653a6d3c8d..4657e877bf8 100644
--- a/arch/arm/boot/compressed/misc.c
+++ b/arch/arm/boot/compressed/misc.c
@@ -36,7 +36,7 @@ extern void error(char *x);
#ifdef CONFIG_DEBUG_ICEDCC
-#ifdef CONFIG_CPU_V6
+#if defined(CONFIG_CPU_V6) || defined(CONFIG_CPU_V6K)
static void icedcc_putc(int ch)
{
diff --git a/arch/arm/boot/compressed/vmlinux.lds.in b/arch/arm/boot/compressed/vmlinux.lds.in
index 366a924019a..5309909d728 100644
--- a/arch/arm/boot/compressed/vmlinux.lds.in
+++ b/arch/arm/boot/compressed/vmlinux.lds.in
@@ -43,9 +43,6 @@ SECTIONS
_etext = .;
- /* Assume size of decompressed image is 4x the compressed image */
- _image_size = (_etext - _text) * 4;
-
_got_start = .;
.got : { *(.got) }
_got_end = .;
diff --git a/arch/arm/common/Kconfig b/arch/arm/common/Kconfig
index 778655f0257..ea5ee4d067f 100644
--- a/arch/arm/common/Kconfig
+++ b/arch/arm/common/Kconfig
@@ -6,6 +6,8 @@ config ARM_VIC
config ARM_VIC_NR
int
+ default 4 if ARCH_S5PV210
+ default 3 if ARCH_S5P6442 || ARCH_S5PC100
default 2
depends on ARM_VIC
help
diff --git a/arch/arm/common/gic.c b/arch/arm/common/gic.c
index 22437721115..e21c1f4218d 100644
--- a/arch/arm/common/gic.c
+++ b/arch/arm/common/gic.c
@@ -142,25 +142,24 @@ static int gic_set_type(struct irq_data *d, unsigned int type)
}
#ifdef CONFIG_SMP
-static int
-gic_set_cpu(struct irq_data *d, const struct cpumask *mask_val, bool force)
+static int gic_set_affinity(struct irq_data *d, const struct cpumask *mask_val,
+ bool force)
{
void __iomem *reg = gic_dist_base(d) + GIC_DIST_TARGET + (gic_irq(d) & ~3);
unsigned int shift = (d->irq % 4) * 8;
unsigned int cpu = cpumask_first(mask_val);
- u32 val;
- struct irq_desc *desc;
+ u32 val, mask, bit;
- spin_lock(&irq_controller_lock);
- desc = irq_to_desc(d->irq);
- if (desc == NULL) {
- spin_unlock(&irq_controller_lock);
+ if (cpu >= 8)
return -EINVAL;
- }
+
+ mask = 0xff << shift;
+ bit = 1 << (cpu + shift);
+
+ spin_lock(&irq_controller_lock);
d->node = cpu;
- val = readl(reg) & ~(0xff << shift);
- val |= 1 << (cpu + shift);
- writel(val, reg);
+ val = readl(reg) & ~mask;
+ writel(val | bit, reg);
spin_unlock(&irq_controller_lock);
return 0;
@@ -203,7 +202,7 @@ static struct irq_chip gic_chip = {
.irq_unmask = gic_unmask_irq,
.irq_set_type = gic_set_type,
#ifdef CONFIG_SMP
- .irq_set_affinity = gic_set_cpu,
+ .irq_set_affinity = gic_set_affinity,
#endif
};
diff --git a/arch/arm/configs/omap2plus_defconfig b/arch/arm/configs/omap2plus_defconfig
index ae890caa17a..ccfd51cd2bc 100644
--- a/arch/arm/configs/omap2plus_defconfig
+++ b/arch/arm/configs/omap2plus_defconfig
@@ -58,6 +58,7 @@ CONFIG_ARM_ERRATA_411920=y
CONFIG_NO_HZ=y
CONFIG_HIGH_RES_TIMERS=y
CONFIG_SMP=y
+CONFIG_NR_CPUS=2
# CONFIG_LOCAL_TIMERS is not set
CONFIG_AEABI=y
CONFIG_LEDS=y
@@ -291,3 +292,7 @@ CONFIG_CRC_T10DIF=y
CONFIG_CRC_ITU_T=y
CONFIG_CRC7=y
CONFIG_LIBCRC32C=y
+CONFIG_CPU_FREQ=y
+CONFIG_CPU_FREQ_GOV_USERSPACE=y
+CONFIG_OMAP_SMARTREFLEX=y
+CONFIG_OMAP_SMARTREFLEX_CLASS3=y
diff --git a/arch/arm/configs/u8500_defconfig b/arch/arm/configs/u8500_defconfig
index 52d86c4485b..a5cce242a77 100644
--- a/arch/arm/configs/u8500_defconfig
+++ b/arch/arm/configs/u8500_defconfig
@@ -1,7 +1,6 @@
CONFIG_EXPERIMENTAL=y
# CONFIG_SWAP is not set
CONFIG_SYSVIPC=y
-CONFIG_SYSFS_DEPRECATED_V2=y
CONFIG_BLK_DEV_INITRD=y
CONFIG_KALLSYMS_ALL=y
CONFIG_MODULES=y
@@ -13,43 +12,89 @@ CONFIG_UX500_SOC_DB5500=y
CONFIG_UX500_SOC_DB8500=y
CONFIG_MACH_U8500=y
CONFIG_MACH_U5500=y
+CONFIG_NO_HZ=y
+CONFIG_HIGH_RES_TIMERS=y
CONFIG_SMP=y
CONFIG_NR_CPUS=2
+CONFIG_HOTPLUG_CPU=y
CONFIG_PREEMPT=y
CONFIG_AEABI=y
CONFIG_CMDLINE="root=/dev/ram0 console=ttyAMA2,115200n8"
+CONFIG_CPU_FREQ=y
+CONFIG_CPU_FREQ_DEFAULT_GOV_ONDEMAND=y
CONFIG_VFP=y
CONFIG_NEON=y
+CONFIG_NET=y
+CONFIG_PHONET=y
+CONFIG_PHONET_PIPECTRLR=y
+# CONFIG_WIRELESS is not set
+CONFIG_CAIF=y
CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
CONFIG_BLK_DEV_RAM=y
CONFIG_BLK_DEV_RAM_SIZE=65536
-# CONFIG_MISC_DEVICES is not set
+CONFIG_MISC_DEVICES=y
+CONFIG_AB8500_PWM=y
+CONFIG_SENSORS_BH1780=y
# CONFIG_INPUT_MOUSEDEV_PSAUX is not set
CONFIG_INPUT_EVDEV=y
-# CONFIG_INPUT_KEYBOARD is not set
+# CONFIG_KEYBOARD_ATKBD is not set
+CONFIG_KEYBOARD_GPIO=y
+CONFIG_KEYBOARD_NOMADIK=y
+CONFIG_KEYBOARD_STMPE=y
+CONFIG_KEYBOARD_TC3589X=y
# CONFIG_INPUT_MOUSE is not set
+CONFIG_INPUT_TOUCHSCREEN=y
+CONFIG_TOUCHSCREEN_BU21013=y
+CONFIG_INPUT_MISC=y
+CONFIG_INPUT_AB8500_PONKEY=y
# CONFIG_SERIO is not set
CONFIG_VT_HW_CONSOLE_BINDING=y
CONFIG_SERIAL_AMBA_PL011=y
CONFIG_SERIAL_AMBA_PL011_CONSOLE=y
# CONFIG_LEGACY_PTYS is not set
-# CONFIG_HW_RANDOM is not set
+CONFIG_HW_RANDOM=y
+CONFIG_HW_RANDOM_NOMADIK=y
+CONFIG_I2C=y
+CONFIG_I2C_NOMADIK=y
CONFIG_SPI=y
CONFIG_SPI_PL022=y
+CONFIG_GPIO_STMPE=y
+CONFIG_GPIO_TC3589X=y
# CONFIG_HWMON is not set
-# CONFIG_VGA_CONSOLE is not set
+CONFIG_MFD_STMPE=y
+CONFIG_MFD_TC3589X=y
+CONFIG_AB8500_CORE=y
+CONFIG_REGULATOR=y
+CONFIG_REGULATOR_AB8500=y
# CONFIG_HID_SUPPORT is not set
# CONFIG_USB_SUPPORT is not set
+CONFIG_MMC=y
+CONFIG_MMC_ARMMMCI=y
+CONFIG_NEW_LEDS=y
+CONFIG_LEDS_CLASS=y
+CONFIG_LEDS_LP5521=y
+CONFIG_RTC_CLASS=y
+CONFIG_RTC_DRV_AB8500=y
+CONFIG_RTC_DRV_PL031=y
+CONFIG_DMADEVICES=y
+CONFIG_STE_DMA40=y
+CONFIG_STAGING=y
+# CONFIG_STAGING_EXCLUDE_BUILD is not set
+CONFIG_TOUCHSCREEN_SYNAPTICS_I2C_RMI4=y
CONFIG_EXT2_FS=y
CONFIG_EXT2_FS_XATTR=y
CONFIG_EXT2_FS_POSIX_ACL=y
CONFIG_EXT2_FS_SECURITY=y
-CONFIG_INOTIFY=y
+CONFIG_EXT3_FS=y
+CONFIG_VFAT_FS=y
CONFIG_TMPFS=y
CONFIG_TMPFS_POSIX_ACL=y
CONFIG_CONFIGFS_FS=m
# CONFIG_MISC_FILESYSTEMS is not set
+CONFIG_NLS_CODEPAGE_437=y
+CONFIG_NLS_ISO8859_1=y
CONFIG_MAGIC_SYSRQ=y
+CONFIG_DEBUG_FS=y
CONFIG_DEBUG_KERNEL=y
# CONFIG_SCHED_DEBUG is not set
# CONFIG_DEBUG_PREEMPT is not set
@@ -58,5 +103,3 @@ CONFIG_DEBUG_INFO=y
# CONFIG_FTRACE is not set
CONFIG_DEBUG_USER=y
CONFIG_DEBUG_ERRORS=y
-CONFIG_CRC_T10DIF=m
-# CONFIG_CRC32 is not set
diff --git a/arch/arm/configs/vexpress_defconfig b/arch/arm/configs/vexpress_defconfig
new file mode 100644
index 00000000000..f2de51f0bd1
--- /dev/null
+++ b/arch/arm/configs/vexpress_defconfig
@@ -0,0 +1,140 @@
+CONFIG_EXPERIMENTAL=y
+# CONFIG_LOCALVERSION_AUTO is not set
+CONFIG_SYSVIPC=y
+CONFIG_IKCONFIG=y
+CONFIG_IKCONFIG_PROC=y
+CONFIG_LOG_BUF_SHIFT=14
+CONFIG_CGROUPS=y
+CONFIG_CPUSETS=y
+# CONFIG_UTS_NS is not set
+# CONFIG_IPC_NS is not set
+# CONFIG_USER_NS is not set
+# CONFIG_PID_NS is not set
+# CONFIG_NET_NS is not set
+CONFIG_BLK_DEV_INITRD=y
+# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
+CONFIG_PROFILING=y
+CONFIG_OPROFILE=y
+CONFIG_MODULES=y
+CONFIG_MODULE_UNLOAD=y
+# CONFIG_LBDAF is not set
+# CONFIG_BLK_DEV_BSG is not set
+# CONFIG_IOSCHED_DEADLINE is not set
+# CONFIG_IOSCHED_CFQ is not set
+CONFIG_ARCH_VEXPRESS=y
+CONFIG_ARCH_VEXPRESS_CA9X4=y
+# CONFIG_SWP_EMULATE is not set
+CONFIG_SMP=y
+CONFIG_VMSPLIT_2G=y
+CONFIG_HOTPLUG_CPU=y
+CONFIG_AEABI=y
+CONFIG_ZBOOT_ROM_TEXT=0x0
+CONFIG_ZBOOT_ROM_BSS=0x0
+CONFIG_CMDLINE="root=/dev/nfs nfsroot=10.1.69.3:/work/nfsroot ip=dhcp console=ttyAMA0 mem=128M"
+CONFIG_VFP=y
+CONFIG_NEON=y
+# CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set
+CONFIG_NET=y
+CONFIG_PACKET=y
+CONFIG_UNIX=y
+CONFIG_INET=y
+CONFIG_IP_PNP=y
+CONFIG_IP_PNP_DHCP=y
+CONFIG_IP_PNP_BOOTP=y
+# CONFIG_INET_LRO is not set
+# CONFIG_IPV6 is not set
+# CONFIG_WIRELESS is not set
+CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
+CONFIG_MTD=y
+CONFIG_MTD_CONCAT=y
+CONFIG_MTD_PARTITIONS=y
+CONFIG_MTD_CMDLINE_PARTS=y
+CONFIG_MTD_CHAR=y
+CONFIG_MTD_BLOCK=y
+CONFIG_MTD_CFI=y
+CONFIG_MTD_CFI_INTELEXT=y
+CONFIG_MTD_CFI_AMDSTD=y
+CONFIG_MTD_ARM_INTEGRATOR=y
+CONFIG_MISC_DEVICES=y
+# CONFIG_SCSI_PROC_FS is not set
+CONFIG_BLK_DEV_SD=y
+# CONFIG_SCSI_LOWLEVEL is not set
+CONFIG_ATA=y
+# CONFIG_SATA_PMP is not set
+CONFIG_NETDEVICES=y
+CONFIG_NET_ETHERNET=y
+CONFIG_SMSC911X=y
+# CONFIG_NETDEV_1000 is not set
+# CONFIG_NETDEV_10000 is not set
+# CONFIG_WLAN is not set
+CONFIG_INPUT_EVDEV=y
+# CONFIG_SERIO_SERPORT is not set
+CONFIG_SERIO_AMBAKMI=y
+CONFIG_SERIAL_AMBA_PL011=y
+CONFIG_SERIAL_AMBA_PL011_CONSOLE=y
+CONFIG_LEGACY_PTY_COUNT=16
+# CONFIG_HW_RANDOM is not set
+# CONFIG_HWMON is not set
+CONFIG_FB=y
+CONFIG_FB_ARMCLCD=y
+CONFIG_FRAMEBUFFER_CONSOLE=y
+CONFIG_LOGO=y
+# CONFIG_LOGO_LINUX_MONO is not set
+# CONFIG_LOGO_LINUX_VGA16 is not set
+CONFIG_SOUND=y
+CONFIG_SND=y
+CONFIG_SND_MIXER_OSS=y
+CONFIG_SND_PCM_OSS=y
+# CONFIG_SND_DRIVERS is not set
+CONFIG_SND_ARMAACI=y
+CONFIG_HID_DRAGONRISE=y
+CONFIG_HID_GYRATION=y
+CONFIG_HID_TWINHAN=y
+CONFIG_HID_NTRIG=y
+CONFIG_HID_PANTHERLORD=y
+CONFIG_HID_PETALYNX=y
+CONFIG_HID_SAMSUNG=y
+CONFIG_HID_SONY=y
+CONFIG_HID_SUNPLUS=y
+CONFIG_HID_GREENASIA=y
+CONFIG_HID_SMARTJOYPLUS=y
+CONFIG_HID_TOPSEED=y
+CONFIG_HID_THRUSTMASTER=y
+CONFIG_HID_ZEROPLUS=y
+CONFIG_USB=y
+CONFIG_USB_ANNOUNCE_NEW_DEVICES=y
+# CONFIG_USB_DEVICE_CLASS is not set
+CONFIG_USB_MON=y
+CONFIG_USB_ISP1760_HCD=y
+CONFIG_USB_STORAGE=y
+CONFIG_MMC=y
+CONFIG_MMC_ARMMMCI=y
+CONFIG_RTC_CLASS=y
+CONFIG_RTC_DRV_PL031=y
+CONFIG_EXT2_FS=y
+CONFIG_EXT3_FS=y
+# CONFIG_EXT3_DEFAULTS_TO_ORDERED is not set
+# CONFIG_EXT3_FS_XATTR is not set
+CONFIG_VFAT_FS=y
+CONFIG_TMPFS=y
+CONFIG_JFFS2_FS=y
+CONFIG_CRAMFS=y
+CONFIG_NFS_FS=y
+CONFIG_NFS_V3=y
+CONFIG_ROOT_NFS=y
+# CONFIG_RPCSEC_GSS_KRB5 is not set
+CONFIG_NLS_CODEPAGE_437=y
+CONFIG_NLS_ISO8859_1=y
+CONFIG_MAGIC_SYSRQ=y
+CONFIG_DEBUG_FS=y
+CONFIG_DEBUG_KERNEL=y
+CONFIG_DETECT_HUNG_TASK=y
+# CONFIG_SCHED_DEBUG is not set
+CONFIG_DEBUG_INFO=y
+# CONFIG_RCU_CPU_STALL_DETECTOR is not set
+CONFIG_DEBUG_USER=y
+CONFIG_DEBUG_ERRORS=y
+CONFIG_DEBUG_LL=y
+CONFIG_EARLY_PRINTK=y
+# CONFIG_CRYPTO_ANSI_CPRNG is not set
+# CONFIG_CRYPTO_HW is not set
diff --git a/arch/arm/include/asm/bitops.h b/arch/arm/include/asm/bitops.h
index 7b1bb2bbaf8..af54ed102f5 100644
--- a/arch/arm/include/asm/bitops.h
+++ b/arch/arm/include/asm/bitops.h
@@ -149,14 +149,18 @@ ____atomic_test_and_change_bit(unsigned int bit, volatile unsigned long *p)
*/
/*
+ * Native endian assembly bitops. nr = 0 -> word 0 bit 0.
+ */
+extern void _set_bit(int nr, volatile unsigned long * p);
+extern void _clear_bit(int nr, volatile unsigned long * p);
+extern void _change_bit(int nr, volatile unsigned long * p);
+extern int _test_and_set_bit(int nr, volatile unsigned long * p);
+extern int _test_and_clear_bit(int nr, volatile unsigned long * p);
+extern int _test_and_change_bit(int nr, volatile unsigned long * p);
+
+/*
* Little endian assembly bitops. nr = 0 -> byte 0 bit 0.
*/
-extern void _set_bit_le(int nr, volatile unsigned long * p);
-extern void _clear_bit_le(int nr, volatile unsigned long * p);
-extern void _change_bit_le(int nr, volatile unsigned long * p);
-extern int _test_and_set_bit_le(int nr, volatile unsigned long * p);
-extern int _test_and_clear_bit_le(int nr, volatile unsigned long * p);
-extern int _test_and_change_bit_le(int nr, volatile unsigned long * p);
extern int _find_first_zero_bit_le(const void * p, unsigned size);
extern int _find_next_zero_bit_le(const void * p, int size, int offset);
extern int _find_first_bit_le(const unsigned long *p, unsigned size);
@@ -165,12 +169,6 @@ extern int _find_next_bit_le(const unsigned long *p, int size, int offset);
/*
* Big endian assembly bitops. nr = 0 -> byte 3 bit 0.
*/
-extern void _set_bit_be(int nr, volatile unsigned long * p);
-extern void _clear_bit_be(int nr, volatile unsigned long * p);
-extern void _change_bit_be(int nr, volatile unsigned long * p);
-extern int _test_and_set_bit_be(int nr, volatile unsigned long * p);
-extern int _test_and_clear_bit_be(int nr, volatile unsigned long * p);
-extern int _test_and_change_bit_be(int nr, volatile unsigned long * p);
extern int _find_first_zero_bit_be(const void * p, unsigned size);
extern int _find_next_zero_bit_be(const void * p, int size, int offset);
extern int _find_first_bit_be(const unsigned long *p, unsigned size);
@@ -180,33 +178,26 @@ extern int _find_next_bit_be(const unsigned long *p, int size, int offset);
/*
* The __* form of bitops are non-atomic and may be reordered.
*/
-#define ATOMIC_BITOP_LE(name,nr,p) \
- (__builtin_constant_p(nr) ? \
- ____atomic_##name(nr, p) : \
- _##name##_le(nr,p))
-
-#define ATOMIC_BITOP_BE(name,nr,p) \
- (__builtin_constant_p(nr) ? \
- ____atomic_##name(nr, p) : \
- _##name##_be(nr,p))
+#define ATOMIC_BITOP(name,nr,p) \
+ (__builtin_constant_p(nr) ? ____atomic_##name(nr, p) : _##name(nr,p))
#else
-#define ATOMIC_BITOP_LE(name,nr,p) _##name##_le(nr,p)
-#define ATOMIC_BITOP_BE(name,nr,p) _##name##_be(nr,p)
+#define ATOMIC_BITOP(name,nr,p) _##name(nr,p)
#endif
-#define NONATOMIC_BITOP(name,nr,p) \
- (____nonatomic_##name(nr, p))
+/*
+ * Native endian atomic definitions.
+ */
+#define set_bit(nr,p) ATOMIC_BITOP(set_bit,nr,p)
+#define clear_bit(nr,p) ATOMIC_BITOP(clear_bit,nr,p)
+#define change_bit(nr,p) ATOMIC_BITOP(change_bit,nr,p)
+#define test_and_set_bit(nr,p) ATOMIC_BITOP(test_and_set_bit,nr,p)
+#define test_and_clear_bit(nr,p) ATOMIC_BITOP(test_and_clear_bit,nr,p)
+#define test_and_change_bit(nr,p) ATOMIC_BITOP(test_and_change_bit,nr,p)
#ifndef __ARMEB__
/*
* These are the little endian, atomic definitions.
*/
-#define set_bit(nr,p) ATOMIC_BITOP_LE(set_bit,nr,p)
-#define clear_bit(nr,p) ATOMIC_BITOP_LE(clear_bit,nr,p)
-#define change_bit(nr,p) ATOMIC_BITOP_LE(change_bit,nr,p)
-#define test_and_set_bit(nr,p) ATOMIC_BITOP_LE(test_and_set_bit,nr,p)
-#define test_and_clear_bit(nr,p) ATOMIC_BITOP_LE(test_and_clear_bit,nr,p)
-#define test_and_change_bit(nr,p) ATOMIC_BITOP_LE(test_and_change_bit,nr,p)
#define find_first_zero_bit(p,sz) _find_first_zero_bit_le(p,sz)
#define find_next_zero_bit(p,sz,off) _find_next_zero_bit_le(p,sz,off)
#define find_first_bit(p,sz) _find_first_bit_le(p,sz)
@@ -215,16 +206,9 @@ extern int _find_next_bit_be(const unsigned long *p, int size, int offset);
#define WORD_BITOFF_TO_LE(x) ((x))
#else
-
/*
* These are the big endian, atomic definitions.
*/
-#define set_bit(nr,p) ATOMIC_BITOP_BE(set_bit,nr,p)
-#define clear_bit(nr,p) ATOMIC_BITOP_BE(clear_bit,nr,p)
-#define change_bit(nr,p) ATOMIC_BITOP_BE(change_bit,nr,p)
-#define test_and_set_bit(nr,p) ATOMIC_BITOP_BE(test_and_set_bit,nr,p)
-#define test_and_clear_bit(nr,p) ATOMIC_BITOP_BE(test_and_clear_bit,nr,p)
-#define test_and_change_bit(nr,p) ATOMIC_BITOP_BE(test_and_change_bit,nr,p)
#define find_first_zero_bit(p,sz) _find_first_zero_bit_be(p,sz)
#define find_next_zero_bit(p,sz,off) _find_next_zero_bit_be(p,sz,off)
#define find_first_bit(p,sz) _find_first_bit_be(p,sz)
diff --git a/arch/arm/include/asm/cacheflush.h b/arch/arm/include/asm/cacheflush.h
index 3acd8fa25e3..d9b4c42d62f 100644
--- a/arch/arm/include/asm/cacheflush.h
+++ b/arch/arm/include/asm/cacheflush.h
@@ -116,20 +116,20 @@
# define MULTI_CACHE 1
#endif
-#if defined(CONFIG_CPU_V6)
-//# ifdef _CACHE
+#if defined(CONFIG_CPU_CACHE_V6)
+# ifdef _CACHE
# define MULTI_CACHE 1
-//# else
-//# define _CACHE v6
-//# endif
+# else
+# define _CACHE v6
+# endif
#endif
-#if defined(CONFIG_CPU_V7)
-//# ifdef _CACHE
+#if defined(CONFIG_CPU_CACHE_V7)
+# ifdef _CACHE
# define MULTI_CACHE 1
-//# else
-//# define _CACHE v7
-//# endif
+# else
+# define _CACHE v7
+# endif
#endif
#if !defined(_CACHE) && !defined(MULTI_CACHE)
@@ -316,7 +316,8 @@ extern void copy_to_user_page(struct vm_area_struct *, struct page *,
* Optimized __flush_icache_all for the common cases. Note that UP ARMv7
* will fall through to use __flush_icache_all_generic.
*/
-#if (defined(CONFIG_CPU_V7) && defined(CONFIG_CPU_V6)) || \
+#if (defined(CONFIG_CPU_V7) && \
+ (defined(CONFIG_CPU_V6) || defined(CONFIG_CPU_V6K))) || \
defined(CONFIG_SMP_ON_UP)
#define __flush_icache_preferred __cpuc_flush_icache_all
#elif __LINUX_ARM_ARCH__ >= 7 && defined(CONFIG_SMP)
diff --git a/arch/arm/include/asm/cputype.h b/arch/arm/include/asm/cputype.h
index 20ae96cc002..ed5bc9e05a4 100644
--- a/arch/arm/include/asm/cputype.h
+++ b/arch/arm/include/asm/cputype.h
@@ -23,6 +23,8 @@
#define CPUID_EXT_ISAR4 "c2, 4"
#define CPUID_EXT_ISAR5 "c2, 5"
+extern unsigned int processor_id;
+
#ifdef CONFIG_CPU_CP15
#define read_cpuid(reg) \
({ \
@@ -43,7 +45,6 @@
__val; \
})
#else
-extern unsigned int processor_id;
#define read_cpuid(reg) (processor_id)
#define read_cpuid_ext(reg) 0
#endif
diff --git a/arch/arm/include/asm/fncpy.h b/arch/arm/include/asm/fncpy.h
new file mode 100644
index 00000000000..de535474692
--- /dev/null
+++ b/arch/arm/include/asm/fncpy.h
@@ -0,0 +1,94 @@
+/*
+ * arch/arm/include/asm/fncpy.h - helper macros for function body copying
+ *
+ * Copyright (C) 2011 Linaro Limited
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+/*
+ * These macros are intended for use when there is a need to copy a low-level
+ * function body into special memory.
+ *
+ * For example, when reconfiguring the SDRAM controller, the code doing the
+ * reconfiguration may need to run from SRAM.
+ *
+ * NOTE: that the copied function body must be entirely self-contained and
+ * position-independent in order for this to work properly.
+ *
+ * NOTE: in order for embedded literals and data to get referenced correctly,
+ * the alignment of functions must be preserved when copying. To ensure this,
+ * the source and destination addresses for fncpy() must be aligned to a
+ * multiple of 8 bytes: you will be get a BUG() if this condition is not met.
+ * You will typically need a ".align 3" directive in the assembler where the
+ * function to be copied is defined, and ensure that your allocator for the
+ * destination buffer returns 8-byte-aligned pointers.
+ *
+ * Typical usage example:
+ *
+ * extern int f(args);
+ * extern uint32_t size_of_f;
+ * int (*copied_f)(args);
+ * void *sram_buffer;
+ *
+ * copied_f = fncpy(sram_buffer, &f, size_of_f);
+ *
+ * ... later, call the function: ...
+ *
+ * copied_f(args);
+ *
+ * The size of the function to be copied can't be determined from C:
+ * this must be determined by other means, such as adding assmbler directives
+ * in the file where f is defined.
+ */
+
+#ifndef __ASM_FNCPY_H
+#define __ASM_FNCPY_H
+
+#include <linux/types.h>
+#include <linux/string.h>
+
+#include <asm/bug.h>
+#include <asm/cacheflush.h>
+
+/*
+ * Minimum alignment requirement for the source and destination addresses
+ * for function copying.
+ */
+#define FNCPY_ALIGN 8
+
+#define fncpy(dest_buf, funcp, size) ({ \
+ uintptr_t __funcp_address; \
+ typeof(funcp) __result; \
+ \
+ asm("" : "=r" (__funcp_address) : "0" (funcp)); \
+ \
+ /* \
+ * Ensure alignment of source and destination addresses, \
+ * disregarding the function's Thumb bit: \
+ */ \
+ BUG_ON((uintptr_t)(dest_buf) & (FNCPY_ALIGN - 1) || \
+ (__funcp_address & ~(uintptr_t)1 & (FNCPY_ALIGN - 1))); \
+ \
+ memcpy(dest_buf, (void const *)(__funcp_address & ~1), size); \
+ flush_icache_range((unsigned long)(dest_buf), \
+ (unsigned long)(dest_buf) + (size)); \
+ \
+ asm("" : "=r" (__result) \
+ : "0" ((uintptr_t)(dest_buf) | (__funcp_address & 1))); \
+ \
+ __result; \
+})
+
+#endif /* !__ASM_FNCPY_H */
diff --git a/arch/arm/include/asm/highmem.h b/arch/arm/include/asm/highmem.h
index 7080e2c8fa6..a4edd19dd3d 100644
--- a/arch/arm/include/asm/highmem.h
+++ b/arch/arm/include/asm/highmem.h
@@ -19,11 +19,36 @@
extern pte_t *pkmap_page_table;
+extern void *kmap_high(struct page *page);
+extern void kunmap_high(struct page *page);
+
+/*
+ * The reason for kmap_high_get() is to ensure that the currently kmap'd
+ * page usage count does not decrease to zero while we're using its
+ * existing virtual mapping in an atomic context. With a VIVT cache this
+ * is essential to do, but with a VIPT cache this is only an optimization
+ * so not to pay the price of establishing a second mapping if an existing
+ * one can be used. However, on platforms without hardware TLB maintenance
+ * broadcast, we simply cannot use ARCH_NEEDS_KMAP_HIGH_GET at all since
+ * the locking involved must also disable IRQs which is incompatible with
+ * the IPI mechanism used by global TLB operations.
+ */
#define ARCH_NEEDS_KMAP_HIGH_GET
+#if defined(CONFIG_SMP) && defined(CONFIG_CPU_TLB_V6)
+#undef ARCH_NEEDS_KMAP_HIGH_GET
+#if defined(CONFIG_HIGHMEM) && defined(CONFIG_CPU_CACHE_VIVT)
+#error "The sum of features in your kernel config cannot be supported together"
+#endif
+#endif
-extern void *kmap_high(struct page *page);
+#ifdef ARCH_NEEDS_KMAP_HIGH_GET
extern void *kmap_high_get(struct page *page);
-extern void kunmap_high(struct page *page);
+#else
+static inline void *kmap_high_get(struct page *page)
+{
+ return NULL;
+}
+#endif
/*
* The following functions are already defined by <linux/highmem.h>
diff --git a/arch/arm/include/asm/mach/arch.h b/arch/arm/include/asm/mach/arch.h
index 3a0893a76a3..946f4d778f7 100644
--- a/arch/arm/include/asm/mach/arch.h
+++ b/arch/arm/include/asm/mach/arch.h
@@ -15,13 +15,11 @@ struct meminfo;
struct sys_timer;
struct machine_desc {
- /*
- * Note! The first two elements are used
- * by assembler code in head.S, head-common.S
- */
unsigned int nr; /* architecture number */
const char *name; /* architecture name */
unsigned long boot_params; /* tagged list */
+ const char **dt_compat; /* array of device tree
+ * 'compatible' strings */
unsigned int nr_irqs; /* number of IRQs */
@@ -52,6 +50,13 @@ struct machine_desc {
extern struct machine_desc *machine_desc;
/*
+ * Machine type table - also only accessible during boot
+ */
+extern struct machine_desc __arch_info_begin[], __arch_info_end[];
+#define for_each_machine_desc(p) \
+ for (p = __arch_info_begin; p < __arch_info_end; p++)
+
+/*
* Set of macros to define architecture features. This is built into
* a table by the linker.
*/
diff --git a/arch/arm/include/asm/memory.h b/arch/arm/include/asm/memory.h
index d0ee74b7cf8..431077c5a86 100644
--- a/arch/arm/include/asm/memory.h
+++ b/arch/arm/include/asm/memory.h
@@ -15,6 +15,7 @@
#include <linux/compiler.h>
#include <linux/const.h>
+#include <linux/types.h>
#include <mach/memory.h>
#include <asm/sizes.h>
@@ -133,20 +134,10 @@
#endif
/*
- * Physical vs virtual RAM address space conversion. These are
- * private definitions which should NOT be used outside memory.h
- * files. Use virt_to_phys/phys_to_virt/__pa/__va instead.
- */
-#ifndef __virt_to_phys
-#define __virt_to_phys(x) ((x) - PAGE_OFFSET + PHYS_OFFSET)
-#define __phys_to_virt(x) ((x) - PHYS_OFFSET + PAGE_OFFSET)
-#endif
-
-/*
* Convert a physical address to a Page Frame Number and back
*/
-#define __phys_to_pfn(paddr) ((paddr) >> PAGE_SHIFT)
-#define __pfn_to_phys(pfn) ((pfn) << PAGE_SHIFT)
+#define __phys_to_pfn(paddr) ((unsigned long)((paddr) >> PAGE_SHIFT))
+#define __pfn_to_phys(pfn) ((phys_addr_t)(pfn) << PAGE_SHIFT)
/*
* Convert a page to/from a physical address
@@ -157,6 +148,62 @@
#ifndef __ASSEMBLY__
/*
+ * Physical vs virtual RAM address space conversion. These are
+ * private definitions which should NOT be used outside memory.h
+ * files. Use virt_to_phys/phys_to_virt/__pa/__va instead.
+ */
+#ifndef __virt_to_phys
+#ifdef CONFIG_ARM_PATCH_PHYS_VIRT
+
+/*
+ * Constants used to force the right instruction encodings and shifts
+ * so that all we need to do is modify the 8-bit constant field.
+ */
+#define __PV_BITS_31_24 0x81000000
+#define __PV_BITS_23_16 0x00810000
+
+extern unsigned long __pv_phys_offset;
+#define PHYS_OFFSET __pv_phys_offset
+
+#define __pv_stub(from,to,instr,type) \
+ __asm__("@ __pv_stub\n" \
+ "1: " instr " %0, %1, %2\n" \
+ " .pushsection .pv_table,\"a\"\n" \
+ " .long 1b\n" \
+ " .popsection\n" \
+ : "=r" (to) \
+ : "r" (from), "I" (type))
+
+static inline unsigned long __virt_to_phys(unsigned long x)
+{
+ unsigned long t;
+ __pv_stub(x, t, "add", __PV_BITS_31_24);
+#ifdef CONFIG_ARM_PATCH_PHYS_VIRT_16BIT
+ __pv_stub(t, t, "add", __PV_BITS_23_16);
+#endif
+ return t;
+}
+
+static inline unsigned long __phys_to_virt(unsigned long x)
+{
+ unsigned long t;
+ __pv_stub(x, t, "sub", __PV_BITS_31_24);
+#ifdef CONFIG_ARM_PATCH_PHYS_VIRT_16BIT
+ __pv_stub(t, t, "sub", __PV_BITS_23_16);
+#endif
+ return t;
+}
+#else
+#define __virt_to_phys(x) ((x) - PAGE_OFFSET + PHYS_OFFSET)
+#define __phys_to_virt(x) ((x) - PHYS_OFFSET + PAGE_OFFSET)
+#endif
+#endif
+
+#ifndef PHYS_OFFSET
+#define PHYS_OFFSET PLAT_PHYS_OFFSET
+#endif
+
+/*
* The DMA mask corresponding to the maximum bus address allocatable
* using GFP_DMA. The default here places no restriction on DMA
* allocations. This must be the smallest DMA mask in the system,
@@ -188,12 +235,12 @@
* translation for translating DMA addresses. Use the driver
* DMA support - see dma-mapping.h.
*/
-static inline unsigned long virt_to_phys(const volatile void *x)
+static inline phys_addr_t virt_to_phys(const volatile void *x)
{
return __virt_to_phys((unsigned long)(x));
}
-static inline void *phys_to_virt(unsigned long x)
+static inline void *phys_to_virt(phys_addr_t x)
{
return (void *)(__phys_to_virt((unsigned long)(x)));
}
diff --git a/arch/arm/include/asm/module.h b/arch/arm/include/asm/module.h
index 12c8e680cbf..543b44916d2 100644
--- a/arch/arm/include/asm/module.h
+++ b/arch/arm/include/asm/module.h
@@ -25,8 +25,31 @@ struct mod_arch_specific {
};
/*
- * Include the ARM architecture version.
+ * Add the ARM architecture version to the version magic string
*/
-#define MODULE_ARCH_VERMAGIC "ARMv" __stringify(__LINUX_ARM_ARCH__) " "
+#define MODULE_ARCH_VERMAGIC_ARMVSN "ARMv" __stringify(__LINUX_ARM_ARCH__) " "
+
+/* Add __virt_to_phys patching state as well */
+#ifdef CONFIG_ARM_PATCH_PHYS_VIRT
+#ifdef CONFIG_ARM_PATCH_PHYS_VIRT_16BIT
+#define MODULE_ARCH_VERMAGIC_P2V "p2v16 "
+#else
+#define MODULE_ARCH_VERMAGIC_P2V "p2v8 "
+#endif
+#else
+#define MODULE_ARCH_VERMAGIC_P2V ""
+#endif
+
+/* Add instruction set architecture tag to distinguish ARM/Thumb kernels */
+#ifdef CONFIG_THUMB2_KERNEL
+#define MODULE_ARCH_VERMAGIC_ARMTHUMB "thumb2 "
+#else
+#define MODULE_ARCH_VERMAGIC_ARMTHUMB ""
+#endif
+
+#define MODULE_ARCH_VERMAGIC \
+ MODULE_ARCH_VERMAGIC_ARMVSN \
+ MODULE_ARCH_VERMAGIC_ARMTHUMB \
+ MODULE_ARCH_VERMAGIC_P2V
#endif /* _ASM_ARM_MODULE_H */
diff --git a/arch/arm/include/asm/pgalloc.h b/arch/arm/include/asm/pgalloc.h
index 9763be04f77..22de005f159 100644
--- a/arch/arm/include/asm/pgalloc.h
+++ b/arch/arm/include/asm/pgalloc.h
@@ -10,6 +10,8 @@
#ifndef _ASMARM_PGALLOC_H
#define _ASMARM_PGALLOC_H
+#include <linux/pagemap.h>
+
#include <asm/domain.h>
#include <asm/pgtable-hwdef.h>
#include <asm/processor.h>
diff --git a/arch/arm/include/asm/pmu.h b/arch/arm/include/asm/pmu.h
index 8ccea012722..7544ce6b481 100644
--- a/arch/arm/include/asm/pmu.h
+++ b/arch/arm/include/asm/pmu.h
@@ -12,11 +12,25 @@
#ifndef __ARM_PMU_H__
#define __ARM_PMU_H__
+#include <linux/interrupt.h>
+
enum arm_pmu_type {
ARM_PMU_DEVICE_CPU = 0,
ARM_NUM_PMU_DEVICES,
};
+/*
+ * struct arm_pmu_platdata - ARM PMU platform data
+ *
+ * @handle_irq: an optional handler which will be called from the interrupt and
+ * passed the address of the low level handler, and can be used to implement
+ * any platform specific handling before or after calling it.
+ */
+struct arm_pmu_platdata {
+ irqreturn_t (*handle_irq)(int irq, void *dev,
+ irq_handler_t pmu_handler);
+};
+
#ifdef CONFIG_CPU_HAS_PMU
/**
diff --git a/arch/arm/include/asm/proc-fns.h b/arch/arm/include/asm/proc-fns.h
index 8fdae9bc9ab..296ca47489f 100644
--- a/arch/arm/include/asm/proc-fns.h
+++ b/arch/arm/include/asm/proc-fns.h
@@ -231,7 +231,7 @@
# endif
#endif
-#ifdef CONFIG_CPU_V6
+#if defined(CONFIG_CPU_V6) || defined(CONFIG_CPU_V6K)
# ifdef CPU_NAME
# undef MULTI_CPU
# define MULTI_CPU
diff --git a/arch/arm/include/asm/processor.h b/arch/arm/include/asm/processor.h
index 67357baaeee..b439b41aeac 100644
--- a/arch/arm/include/asm/processor.h
+++ b/arch/arm/include/asm/processor.h
@@ -29,19 +29,7 @@
#define STACK_TOP_MAX TASK_SIZE
#endif
-union debug_insn {
- u32 arm;
- u16 thumb;
-};
-
-struct debug_entry {
- u32 address;
- union debug_insn insn;
-};
-
struct debug_info {
- int nsaved;
- struct debug_entry bp[2];
#ifdef CONFIG_HAVE_HW_BREAKPOINT
struct perf_event *hbp[ARM_MAX_HBP_SLOTS];
#endif
diff --git a/arch/arm/include/asm/prom.h b/arch/arm/include/asm/prom.h
new file mode 100644
index 00000000000..11b8708fc4d
--- /dev/null
+++ b/arch/arm/include/asm/prom.h
@@ -0,0 +1,37 @@
+/*
+ * arch/arm/include/asm/prom.h
+ *
+ * Copyright (C) 2009 Canonical Ltd. <jeremy.kerr@canonical.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ */
+#ifndef __ASMARM_PROM_H
+#define __ASMARM_PROM_H
+
+#ifdef CONFIG_OF
+
+#include <asm/setup.h>
+#include <asm/irq.h>
+
+static inline void irq_dispose_mapping(unsigned int virq)
+{
+ return;
+}
+
+extern struct machine_desc *setup_machine_fdt(unsigned int dt_phys);
+extern void arm_dt_memblock_reserve(void);
+
+#else /* CONFIG_OF */
+
+static inline struct machine_desc *setup_machine_fdt(unsigned int dt_phys)
+{
+ return NULL;
+}
+
+static inline void arm_dt_memblock_reserve(void) { }
+
+#endif /* CONFIG_OF */
+#endif /* ASMARM_PROM_H */
diff --git a/arch/arm/include/asm/ptrace.h b/arch/arm/include/asm/ptrace.h
index 783d50f3261..a8ff22b2a39 100644
--- a/arch/arm/include/asm/ptrace.h
+++ b/arch/arm/include/asm/ptrace.h
@@ -130,8 +130,6 @@ struct pt_regs {
#ifdef __KERNEL__
-#define arch_has_single_step() (1)
-
#define user_mode(regs) \
(((regs)->ARM_cpsr & 0xf) == 0)
diff --git a/arch/arm/include/asm/setup.h b/arch/arm/include/asm/setup.h
index f1e5a9bca24..207f911a173 100644
--- a/arch/arm/include/asm/setup.h
+++ b/arch/arm/include/asm/setup.h
@@ -221,6 +221,11 @@ extern struct meminfo meminfo;
#define bank_phys_end(bank) ((bank)->start + (bank)->size)
#define bank_phys_size(bank) (bank)->size
+extern int arm_add_memory(unsigned long start, unsigned long size);
+extern char cmd_line[COMMAND_LINE_SIZE];
+extern void early_print(const char *str, ...);
+extern void dump_machine_table(void);
+
#endif /* __KERNEL__ */
#endif
diff --git a/arch/arm/include/asm/spinlock.h b/arch/arm/include/asm/spinlock.h
index 17eb355707d..fdd3820edff 100644
--- a/arch/arm/include/asm/spinlock.h
+++ b/arch/arm/include/asm/spinlock.h
@@ -5,17 +5,52 @@
#error SMP not supported on pre-ARMv6 CPUs
#endif
+/*
+ * sev and wfe are ARMv6K extensions. Uniprocessor ARMv6 may not have the K
+ * extensions, so when running on UP, we have to patch these instructions away.
+ */
+#define ALT_SMP(smp, up) \
+ "9998: " smp "\n" \
+ " .pushsection \".alt.smp.init\", \"a\"\n" \
+ " .long 9998b\n" \
+ " " up "\n" \
+ " .popsection\n"
+
+#ifdef CONFIG_THUMB2_KERNEL
+#define SEV ALT_SMP("sev.w", "nop.w")
+/*
+ * For Thumb-2, special care is needed to ensure that the conditional WFE
+ * instruction really does assemble to exactly 4 bytes (as required by
+ * the SMP_ON_UP fixup code). By itself "wfene" might cause the
+ * assembler to insert a extra (16-bit) IT instruction, depending on the
+ * presence or absence of neighbouring conditional instructions.
+ *
+ * To avoid this unpredictableness, an approprite IT is inserted explicitly:
+ * the assembler won't change IT instructions which are explicitly present
+ * in the input.
+ */
+#define WFE(cond) ALT_SMP( \
+ "it " cond "\n\t" \
+ "wfe" cond ".n", \
+ \
+ "nop.w" \
+)
+#else
+#define SEV ALT_SMP("sev", "nop")
+#define WFE(cond) ALT_SMP("wfe" cond, "nop")
+#endif
+
static inline void dsb_sev(void)
{
#if __LINUX_ARM_ARCH__ >= 7
__asm__ __volatile__ (
"dsb\n"
- "sev"
+ SEV
);
-#elif defined(CONFIG_CPU_32v6K)
+#else
__asm__ __volatile__ (
"mcr p15, 0, %0, c7, c10, 4\n"
- "sev"
+ SEV
: : "r" (0)
);
#endif
@@ -46,9 +81,7 @@ static inline void arch_spin_lock(arch_spinlock_t *lock)
__asm__ __volatile__(
"1: ldrex %0, [%1]\n"
" teq %0, #0\n"
-#ifdef CONFIG_CPU_32v6K
-" wfene\n"
-#endif
+ WFE("ne")
" strexeq %0, %2, [%1]\n"
" teqeq %0, #0\n"
" bne 1b"
@@ -107,9 +140,7 @@ static inline void arch_write_lock(arch_rwlock_t *rw)
__asm__ __volatile__(
"1: ldrex %0, [%1]\n"
" teq %0, #0\n"
-#ifdef CONFIG_CPU_32v6K
-" wfene\n"
-#endif
+ WFE("ne")
" strexeq %0, %2, [%1]\n"
" teq %0, #0\n"
" bne 1b"
@@ -176,9 +207,7 @@ static inline void arch_read_lock(arch_rwlock_t *rw)
"1: ldrex %0, [%2]\n"
" adds %0, %0, #1\n"
" strexpl %1, %0, [%2]\n"
-#ifdef CONFIG_CPU_32v6K
-" wfemi\n"
-#endif
+ WFE("mi")
" rsbpls %0, %1, #0\n"
" bmi 1b"
: "=&r" (tmp), "=&r" (tmp2)
diff --git a/arch/arm/include/asm/system.h b/arch/arm/include/asm/system.h
index 97f6d60297d..9a87823642d 100644
--- a/arch/arm/include/asm/system.h
+++ b/arch/arm/include/asm/system.h
@@ -347,6 +347,7 @@ void cpu_idle_wait(void);
#include <asm-generic/cmpxchg-local.h>
#if __LINUX_ARM_ARCH__ < 6
+/* min ARCH < ARMv6 */
#ifdef CONFIG_SMP
#error "SMP is not supported on this platform"
@@ -365,7 +366,7 @@ void cpu_idle_wait(void);
#include <asm-generic/cmpxchg.h>
#endif
-#else /* __LINUX_ARM_ARCH__ >= 6 */
+#else /* min ARCH >= ARMv6 */
extern void __bad_cmpxchg(volatile void *ptr, int size);
@@ -379,7 +380,7 @@ static inline unsigned long __cmpxchg(volatile void *ptr, unsigned long old,
unsigned long oldval, res;
switch (size) {
-#ifdef CONFIG_CPU_32v6K
+#ifndef CONFIG_CPU_V6 /* min ARCH >= ARMv6K */
case 1:
do {
asm volatile("@ __cmpxchg1\n"
@@ -404,7 +405,7 @@ static inline unsigned long __cmpxchg(volatile void *ptr, unsigned long old,
: "memory", "cc");
} while (res);
break;
-#endif /* CONFIG_CPU_32v6K */
+#endif
case 4:
do {
asm volatile("@ __cmpxchg4\n"
@@ -450,12 +451,12 @@ static inline unsigned long __cmpxchg_local(volatile void *ptr,
unsigned long ret;
switch (size) {
-#ifndef CONFIG_CPU_32v6K
+#ifdef CONFIG_CPU_V6 /* min ARCH == ARMv6 */
case 1:
case 2:
ret = __cmpxchg_local_generic(ptr, old, new, size);
break;
-#endif /* !CONFIG_CPU_32v6K */
+#endif
default:
ret = __cmpxchg(ptr, old, new, size);
}
@@ -469,7 +470,7 @@ static inline unsigned long __cmpxchg_local(volatile void *ptr,
(unsigned long)(n), \
sizeof(*(ptr))))
-#ifdef CONFIG_CPU_32v6K
+#ifndef CONFIG_CPU_V6 /* min ARCH >= ARMv6K */
/*
* Note : ARMv7-M (currently unsupported by Linux) does not support
@@ -524,11 +525,11 @@ static inline unsigned long long __cmpxchg64_mb(volatile void *ptr,
(unsigned long long)(o), \
(unsigned long long)(n)))
-#else /* !CONFIG_CPU_32v6K */
+#else /* min ARCH = ARMv6 */
#define cmpxchg64_local(ptr, o, n) __cmpxchg64_local_generic((ptr), (o), (n))
-#endif /* CONFIG_CPU_32v6K */
+#endif
#endif /* __LINUX_ARM_ARCH__ >= 6 */
diff --git a/arch/arm/include/asm/tls.h b/arch/arm/include/asm/tls.h
index e71d6ff8d10..60843eb0f61 100644
--- a/arch/arm/include/asm/tls.h
+++ b/arch/arm/include/asm/tls.h
@@ -28,15 +28,14 @@
#define tls_emu 1
#define has_tls_reg 1
#define set_tls set_tls_none
-#elif __LINUX_ARM_ARCH__ >= 7 || \
- (__LINUX_ARM_ARCH__ == 6 && defined(CONFIG_CPU_32v6K))
-#define tls_emu 0
-#define has_tls_reg 1
-#define set_tls set_tls_v6k
-#elif __LINUX_ARM_ARCH__ == 6
+#elif defined(CONFIG_CPU_V6)
#define tls_emu 0
#define has_tls_reg (elf_hwcap & HWCAP_TLS)
#define set_tls set_tls_v6
+#elif defined(CONFIG_CPU_32v6K)
+#define tls_emu 0
+#define has_tls_reg 1
+#define set_tls set_tls_v6k
#else
#define tls_emu 0
#define has_tls_reg 0
diff --git a/arch/arm/include/asm/traps.h b/arch/arm/include/asm/traps.h
index 1b960d5ef6a..f90756dc16d 100644
--- a/arch/arm/include/asm/traps.h
+++ b/arch/arm/include/asm/traps.h
@@ -45,6 +45,7 @@ static inline int in_exception_text(unsigned long ptr)
extern void __init early_trap_init(void);
extern void dump_backtrace_entry(unsigned long where, unsigned long from, unsigned long frame);
+extern void ptrace_break(struct task_struct *tsk, struct pt_regs *regs);
extern void *vectors_page;
diff --git a/arch/arm/kernel/Makefile b/arch/arm/kernel/Makefile
index 185ee822c93..8df05fd4c91 100644
--- a/arch/arm/kernel/Makefile
+++ b/arch/arm/kernel/Makefile
@@ -43,6 +43,7 @@ obj-$(CONFIG_ARM_THUMBEE) += thumbee.o
obj-$(CONFIG_KGDB) += kgdb.o
obj-$(CONFIG_ARM_UNWIND) += unwind.o
obj-$(CONFIG_HAVE_TCM) += tcm.o
+obj-$(CONFIG_OF) += devtree.o
obj-$(CONFIG_CRASH_DUMP) += crash_dump.o
obj-$(CONFIG_SWP_EMULATE) += swp_emulate.o
CFLAGS_swp_emulate.o := -Wa,-march=armv7-a
diff --git a/arch/arm/kernel/armksyms.c b/arch/arm/kernel/armksyms.c
index e5e1e538767..acca35aebe2 100644
--- a/arch/arm/kernel/armksyms.c
+++ b/arch/arm/kernel/armksyms.c
@@ -140,24 +140,18 @@ EXPORT_SYMBOL(__aeabi_ulcmp);
#endif
/* bitops */
-EXPORT_SYMBOL(_set_bit_le);
-EXPORT_SYMBOL(_test_and_set_bit_le);
-EXPORT_SYMBOL(_clear_bit_le);
-EXPORT_SYMBOL(_test_and_clear_bit_le);
-EXPORT_SYMBOL(_change_bit_le);
-EXPORT_SYMBOL(_test_and_change_bit_le);
+EXPORT_SYMBOL(_set_bit);
+EXPORT_SYMBOL(_test_and_set_bit);
+EXPORT_SYMBOL(_clear_bit);
+EXPORT_SYMBOL(_test_and_clear_bit);
+EXPORT_SYMBOL(_change_bit);
+EXPORT_SYMBOL(_test_and_change_bit);
EXPORT_SYMBOL(_find_first_zero_bit_le);
EXPORT_SYMBOL(_find_next_zero_bit_le);
EXPORT_SYMBOL(_find_first_bit_le);
EXPORT_SYMBOL(_find_next_bit_le);
#ifdef __ARMEB__
-EXPORT_SYMBOL(_set_bit_be);
-EXPORT_SYMBOL(_test_and_set_bit_be);
-EXPORT_SYMBOL(_clear_bit_be);
-EXPORT_SYMBOL(_test_and_clear_bit_be);
-EXPORT_SYMBOL(_change_bit_be);
-EXPORT_SYMBOL(_test_and_change_bit_be);
EXPORT_SYMBOL(_find_first_zero_bit_be);
EXPORT_SYMBOL(_find_next_zero_bit_be);
EXPORT_SYMBOL(_find_first_bit_be);
@@ -170,3 +164,7 @@ EXPORT_SYMBOL(mcount);
#endif
EXPORT_SYMBOL(__gnu_mcount_nc);
#endif
+
+#ifdef CONFIG_ARM_PATCH_PHYS_VIRT
+EXPORT_SYMBOL(__pv_phys_offset);
+#endif
diff --git a/arch/arm/kernel/bios32.c b/arch/arm/kernel/bios32.c
index c6273a3bfc2..d86fcd44b22 100644
--- a/arch/arm/kernel/bios32.c
+++ b/arch/arm/kernel/bios32.c
@@ -583,6 +583,11 @@ void __init pci_common_init(struct hw_pci *hw)
* Assign resources.
*/
pci_bus_assign_resources(bus);
+
+ /*
+ * Enable bridges
+ */
+ pci_enable_bridges(bus);
}
/*
diff --git a/arch/arm/kernel/debug.S b/arch/arm/kernel/debug.S
index a0f07521ca8..d2d983be096 100644
--- a/arch/arm/kernel/debug.S
+++ b/arch/arm/kernel/debug.S
@@ -25,7 +25,7 @@
.macro addruart, rp, rv
.endm
-#if defined(CONFIG_CPU_V6)
+#if defined(CONFIG_CPU_V6) || defined(CONFIG_CPU_V6K)
.macro senduart, rd, rx
mcr p14, 0, \rd, c0, c5, 0
diff --git a/arch/arm/kernel/devtree.c b/arch/arm/kernel/devtree.c
new file mode 100644
index 00000000000..4dd725acba6
--- /dev/null
+++ b/arch/arm/kernel/devtree.c
@@ -0,0 +1,147 @@
+/*
+ * linux/arch/arm/kernel/devtree.c
+ *
+ * Copyright (C) 2009 Canonical Ltd. <jeremy.kerr@canonical.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/init.h>
+#include <linux/module.h>
+#include <linux/errno.h>
+#include <linux/types.h>
+#include <linux/bootmem.h>
+#include <linux/memblock.h>
+#include <linux/of.h>
+#include <linux/of_fdt.h>
+#include <linux/of_irq.h>
+#include <linux/of_platform.h>
+
+#include <asm/setup.h>
+#include <asm/page.h>
+#include <asm/mach/arch.h>
+#include <asm/mach-types.h>
+
+void __init early_init_dt_add_memory_arch(u64 base, u64 size)
+{
+ arm_add_memory(base, size);
+}
+
+void * __init early_init_dt_alloc_memory_arch(u64 size, u64 align)
+{
+ return alloc_bootmem_align(size, align);
+}
+
+void __init arm_dt_memblock_reserve(void)
+{
+ u64 *reserve_map, base, size;
+
+ if (!initial_boot_params)
+ return;
+
+ /* Reserve the dtb region */
+ memblock_reserve(virt_to_phys(initial_boot_params),
+ be32_to_cpu(initial_boot_params->totalsize));
+
+ /*
+ * Process the reserve map. This will probably overlap the initrd
+ * and dtb locations which are already reserved, but overlaping
+ * doesn't hurt anything
+ */
+ reserve_map = ((void*)initial_boot_params) +
+ be32_to_cpu(initial_boot_params->off_mem_rsvmap);
+ while (1) {
+ base = be64_to_cpup(reserve_map++);
+ size = be64_to_cpup(reserve_map++);
+ if (!size)
+ break;
+ memblock_reserve(base, size);
+ }
+}
+
+/**
+ * irq_create_of_mapping - Hook to resolve OF irq specifier into a Linux irq#
+ *
+ * Currently the mapping mechanism is trivial; simple flat hwirq numbers are
+ * mapped 1:1 onto Linux irq numbers. Cascaded irq controllers are not
+ * supported.
+ */
+unsigned int irq_create_of_mapping(struct device_node *controller,
+ const u32 *intspec, unsigned int intsize)
+{
+ return intspec[0];
+}
+EXPORT_SYMBOL_GPL(irq_create_of_mapping);
+
+/**
+ * setup_machine_fdt - Machine setup when an dtb was passed to the kernel
+ * @dt_phys: physical address of dt blob
+ *
+ * If a dtb was passed to the kernel in r2, then use it to choose the
+ * correct machine_desc and to setup the system.
+ */
+struct machine_desc * __init setup_machine_fdt(unsigned int dt_phys)
+{
+ struct boot_param_header *devtree;
+ struct machine_desc *mdesc, *mdesc_best = NULL;
+ unsigned int score, mdesc_score = ~1;
+ unsigned long dt_root;
+ const char *model;
+
+ devtree = phys_to_virt(dt_phys);
+
+ /* check device tree validity */
+ if (be32_to_cpu(devtree->magic) != OF_DT_HEADER)
+ return NULL;
+
+ /* Search the mdescs for the 'best' compatible value match */
+ initial_boot_params = devtree;
+ dt_root = of_get_flat_dt_root();
+ for_each_machine_desc(mdesc) {
+ score = of_flat_dt_match(dt_root, mdesc->dt_compat);
+ if (score > 0 && score < mdesc_score) {
+ mdesc_best = mdesc;
+ mdesc_score = score;
+ }
+ }
+ if (!mdesc_best) {
+ const char *prop;
+ long size;
+
+ early_print("\nError: unrecognized/unsupported "
+ "device tree compatible list:\n[ ");
+
+ prop = of_get_flat_dt_prop(dt_root, "compatible", &size);
+ while (size > 0) {
+ early_print("'%s' ", prop);
+ size -= strlen(prop) + 1;
+ prop += strlen(prop) + 1;
+ }
+ early_print("]\n\n");
+
+ dump_machine_table(); /* does not return */
+ }
+
+ model = of_get_flat_dt_prop(dt_root, "model", NULL);
+ if (!model)
+ model = of_get_flat_dt_prop(dt_root, "compatible", NULL);
+ if (!model)
+ model = "<unknown>";
+ pr_info("Machine: %s, model: %s\n", mdesc_best->name, model);
+
+ /* Retrieve various information from the /chosen node */
+ of_scan_flat_dt(early_init_dt_scan_chosen, NULL);
+ /* Initialize {size,address}-cells info */
+ of_scan_flat_dt(early_init_dt_scan_root, NULL);
+ /* Setup memory, calling early_init_dt_add_memory_arch */
+ of_scan_flat_dt(early_init_dt_scan_memory, NULL);
+ /* Save command line for /proc/cmdline */
+ strlcpy(boot_command_line, cmd_line, COMMAND_LINE_SIZE);
+
+ /* Change machine number to match the mdesc we're using */
+ __machine_arch_type = mdesc->nr;
+
+ return mdesc_best;
+}
diff --git a/arch/arm/kernel/entry-header.S b/arch/arm/kernel/entry-header.S
index ae946490016..051166c2a93 100644
--- a/arch/arm/kernel/entry-header.S
+++ b/arch/arm/kernel/entry-header.S
@@ -76,13 +76,13 @@
#ifndef CONFIG_THUMB2_KERNEL
.macro svc_exit, rpsr
msr spsr_cxsf, \rpsr
-#if defined(CONFIG_CPU_32v6K)
- clrex @ clear the exclusive monitor
- ldmia sp, {r0 - pc}^ @ load r0 - pc, cpsr
-#elif defined (CONFIG_CPU_V6)
+#if defined(CONFIG_CPU_V6)
ldr r0, [sp]
strex r1, r2, [sp] @ clear the exclusive monitor
ldmib sp, {r1 - pc}^ @ load r1 - pc, cpsr
+#elif defined(CONFIG_CPU_32v6K)
+ clrex @ clear the exclusive monitor
+ ldmia sp, {r0 - pc}^ @ load r0 - pc, cpsr
#else
ldmia sp, {r0 - pc}^ @ load r0 - pc, cpsr
#endif
@@ -92,10 +92,10 @@
ldr r1, [sp, #\offset + S_PSR] @ get calling cpsr
ldr lr, [sp, #\offset + S_PC]! @ get pc
msr spsr_cxsf, r1 @ save in spsr_svc
-#if defined(CONFIG_CPU_32v6K)
- clrex @ clear the exclusive monitor
-#elif defined (CONFIG_CPU_V6)
+#if defined(CONFIG_CPU_V6)
strex r1, r2, [sp] @ clear the exclusive monitor
+#elif defined(CONFIG_CPU_32v6K)
+ clrex @ clear the exclusive monitor
#endif
.if \fast
ldmdb sp, {r1 - lr}^ @ get calling r1 - lr
diff --git a/arch/arm/kernel/etm.c b/arch/arm/kernel/etm.c
index 11db62806a1..052b509e2d5 100644
--- a/arch/arm/kernel/etm.c
+++ b/arch/arm/kernel/etm.c
@@ -338,7 +338,7 @@ static struct miscdevice etb_miscdev = {
.fops = &etb_fops,
};
-static int __init etb_probe(struct amba_device *dev, struct amba_id *id)
+static int __init etb_probe(struct amba_device *dev, const struct amba_id *id)
{
struct tracectx *t = &tracer;
int ret = 0;
@@ -530,7 +530,7 @@ static ssize_t trace_mode_store(struct kobject *kobj,
static struct kobj_attribute trace_mode_attr =
__ATTR(trace_mode, 0644, trace_mode_show, trace_mode_store);
-static int __init etm_probe(struct amba_device *dev, struct amba_id *id)
+static int __init etm_probe(struct amba_device *dev, const struct amba_id *id)
{
struct tracectx *t = &tracer;
int ret = 0;
diff --git a/arch/arm/kernel/head-common.S b/arch/arm/kernel/head-common.S
index 8f57515bbdb..854bd22380d 100644
--- a/arch/arm/kernel/head-common.S
+++ b/arch/arm/kernel/head-common.S
@@ -15,6 +15,12 @@
#define ATAG_CORE_SIZE ((2*4 + 3*4) >> 2)
#define ATAG_CORE_SIZE_EMPTY ((2*4) >> 2)
+#ifdef CONFIG_CPU_BIG_ENDIAN
+#define OF_DT_MAGIC 0xd00dfeed
+#else
+#define OF_DT_MAGIC 0xedfe0dd0 /* 0xd00dfeed in big-endian */
+#endif
+
/*
* Exception handling. Something went wrong and we can't proceed. We
* ought to tell the user, but since we don't have any guarantee that
@@ -25,102 +31,29 @@
* machine ID for example).
*/
__HEAD
-__error_a:
-#ifdef CONFIG_DEBUG_LL
- mov r4, r1 @ preserve machine ID
- adr r0, str_a1
- bl printascii
- mov r0, r4
- bl printhex8
- adr r0, str_a2
- bl printascii
- adr r3, __lookup_machine_type_data
- ldmia r3, {r4, r5, r6} @ get machine desc list
- sub r4, r3, r4 @ get offset between virt&phys
- add r5, r5, r4 @ convert virt addresses to
- add r6, r6, r4 @ physical address space
-1: ldr r0, [r5, #MACHINFO_TYPE] @ get machine type
- bl printhex8
- mov r0, #'\t'
- bl printch
- ldr r0, [r5, #MACHINFO_NAME] @ get machine name
- add r0, r0, r4
- bl printascii
- mov r0, #'\n'
- bl printch
- add r5, r5, #SIZEOF_MACHINE_DESC @ next machine_desc
- cmp r5, r6
- blo 1b
- adr r0, str_a3
- bl printascii
- b __error
-ENDPROC(__error_a)
-
-str_a1: .asciz "\nError: unrecognized/unsupported machine ID (r1 = 0x"
-str_a2: .asciz ").\n\nAvailable machine support:\n\nID (hex)\tNAME\n"
-str_a3: .asciz "\nPlease check your kernel config and/or bootloader.\n"
- .align
-#else
- b __error
-#endif
-
-/*
- * Lookup machine architecture in the linker-build list of architectures.
- * Note that we can't use the absolute addresses for the __arch_info
- * lists since we aren't running with the MMU on (and therefore, we are
- * not in the correct address space). We have to calculate the offset.
- *
- * r1 = machine architecture number
- * Returns:
- * r3, r4, r6 corrupted
- * r5 = mach_info pointer in physical address space
- */
-__lookup_machine_type:
- adr r3, __lookup_machine_type_data
- ldmia r3, {r4, r5, r6}
- sub r3, r3, r4 @ get offset between virt&phys
- add r5, r5, r3 @ convert virt addresses to
- add r6, r6, r3 @ physical address space
-1: ldr r3, [r5, #MACHINFO_TYPE] @ get machine type
- teq r3, r1 @ matches loader number?
- beq 2f @ found
- add r5, r5, #SIZEOF_MACHINE_DESC @ next machine_desc
- cmp r5, r6
- blo 1b
- mov r5, #0 @ unknown machine
-2: mov pc, lr
-ENDPROC(__lookup_machine_type)
-
-/*
- * Look in arch/arm/kernel/arch.[ch] for information about the
- * __arch_info structures.
- */
- .align 2
- .type __lookup_machine_type_data, %object
-__lookup_machine_type_data:
- .long .
- .long __arch_info_begin
- .long __arch_info_end
- .size __lookup_machine_type_data, . - __lookup_machine_type_data
/* Determine validity of the r2 atags pointer. The heuristic requires
* that the pointer be aligned, in the first 16k of physical RAM and
- * that the ATAG_CORE marker is first and present. Future revisions
+ * that the ATAG_CORE marker is first and present. If CONFIG_OF_FLATTREE
+ * is selected, then it will also accept a dtb pointer. Future revisions
* of this function may be more lenient with the physical address and
* may also be able to move the ATAGS block if necessary.
*
- * r8 = machinfo
- *
* Returns:
- * r2 either valid atags pointer, or zero
+ * r2 either valid atags pointer, valid dtb pointer, or zero
* r5, r6 corrupted
*/
__vet_atags:
tst r2, #0x3 @ aligned?
bne 1f
- ldr r5, [r2, #0] @ is first tag ATAG_CORE?
- cmp r5, #ATAG_CORE_SIZE
+ ldr r5, [r2, #0]
+#ifdef CONFIG_OF_FLATTREE
+ ldr r6, =OF_DT_MAGIC @ is it a DTB?
+ cmp r5, r6
+ beq 2f
+#endif
+ cmp r5, #ATAG_CORE_SIZE @ is first tag ATAG_CORE?
cmpne r5, #ATAG_CORE_SIZE_EMPTY
bne 1f
ldr r5, [r2, #4]
@@ -128,7 +61,7 @@ __vet_atags:
cmp r5, r6
bne 1f
- mov pc, lr @ atag pointer is ok
+2: mov pc, lr @ atag/dtb pointer is ok
1: mov r2, #0
mov pc, lr
@@ -140,7 +73,7 @@ ENDPROC(__vet_atags)
*
* r0 = cp#15 control register
* r1 = machine ID
- * r2 = atags pointer
+ * r2 = atags/dtb pointer
* r9 = processor ID
*/
__INIT
@@ -185,17 +118,6 @@ __mmap_switched_data:
.size __mmap_switched_data, . - __mmap_switched_data
/*
- * This provides a C-API version of __lookup_machine_type
- */
-ENTRY(lookup_machine_type)
- stmfd sp!, {r4 - r6, lr}
- mov r1, r0
- bl __lookup_machine_type
- mov r0, r5
- ldmfd sp!, {r4 - r6, pc}
-ENDPROC(lookup_machine_type)
-
-/*
* This provides a C-API version of __lookup_processor_type
*/
ENTRY(lookup_processor_type)
diff --git a/arch/arm/kernel/head-nommu.S b/arch/arm/kernel/head-nommu.S
index 814ce1a7327..6b1e0ad9ec3 100644
--- a/arch/arm/kernel/head-nommu.S
+++ b/arch/arm/kernel/head-nommu.S
@@ -44,9 +44,6 @@ ENTRY(stext)
bl __lookup_processor_type @ r5=procinfo r9=cpuid
movs r10, r5 @ invalid processor (r5=0)?
beq __error_p @ yes, error 'p'
- bl __lookup_machine_type @ r5=machinfo
- movs r8, r5 @ invalid machine (r5=0)?
- beq __error_a @ yes, error 'a'
adr lr, BSYM(__after_proc_init) @ return (PIC) address
ARM( add pc, r10, #PROCINFO_INITFUNC )
diff --git a/arch/arm/kernel/head.S b/arch/arm/kernel/head.S
index f06ff9feb0d..a5e5c5b9b48 100644
--- a/arch/arm/kernel/head.S
+++ b/arch/arm/kernel/head.S
@@ -26,14 +26,6 @@
#include <mach/debug-macro.S>
#endif
-#if (PHYS_OFFSET & 0x001fffff)
-#error "PHYS_OFFSET must be at an even 2MiB boundary!"
-#endif
-
-#define KERNEL_RAM_VADDR (PAGE_OFFSET + TEXT_OFFSET)
-#define KERNEL_RAM_PADDR (PHYS_OFFSET + TEXT_OFFSET)
-
-
/*
* swapper_pg_dir is the virtual address of the initial page table.
* We place the page tables 16K below KERNEL_RAM_VADDR. Therefore, we must
@@ -41,6 +33,7 @@
* the least significant 16 bits to be 0x8000, but we could probably
* relax this restriction to KERNEL_RAM_VADDR >= PAGE_OFFSET + 0x4000.
*/
+#define KERNEL_RAM_VADDR (PAGE_OFFSET + TEXT_OFFSET)
#if (KERNEL_RAM_VADDR & 0xffff) != 0x8000
#error KERNEL_RAM_VADDR must start at 0xXXXX8000
#endif
@@ -48,8 +41,8 @@
.globl swapper_pg_dir
.equ swapper_pg_dir, KERNEL_RAM_VADDR - 0x4000
- .macro pgtbl, rd
- ldr \rd, =(KERNEL_RAM_PADDR - 0x4000)
+ .macro pgtbl, rd, phys
+ add \rd, \phys, #TEXT_OFFSET - 0x4000
.endm
#ifdef CONFIG_XIP_KERNEL
@@ -66,7 +59,7 @@
*
* This is normally called from the decompressor code. The requirements
* are: MMU = off, D-cache = off, I-cache = dont care, r0 = 0,
- * r1 = machine nr, r2 = atags pointer.
+ * r1 = machine nr, r2 = atags or dtb pointer.
*
* This code is mostly position independent, so if you link the kernel at
* 0xc0008000, you call this at __pa(0xc0008000).
@@ -87,25 +80,33 @@ ENTRY(stext)
movs r10, r5 @ invalid processor (r5=0)?
THUMB( it eq ) @ force fixup-able long branch encoding
beq __error_p @ yes, error 'p'
- bl __lookup_machine_type @ r5=machinfo
- movs r8, r5 @ invalid machine (r5=0)?
- THUMB( it eq ) @ force fixup-able long branch encoding
- beq __error_a @ yes, error 'a'
+
+#ifndef CONFIG_XIP_KERNEL
+ adr r3, 2f
+ ldmia r3, {r4, r8}
+ sub r4, r3, r4 @ (PHYS_OFFSET - PAGE_OFFSET)
+ add r8, r8, r4 @ PHYS_OFFSET
+#else
+ ldr r8, =PLAT_PHYS_OFFSET
+#endif
/*
- * r1 = machine no, r2 = atags,
- * r8 = machinfo, r9 = cpuid, r10 = procinfo
+ * r1 = machine no, r2 = atags or dtb,
+ * r8 = phys_offset, r9 = cpuid, r10 = procinfo
*/
bl __vet_atags
#ifdef CONFIG_SMP_ON_UP
bl __fixup_smp
#endif
+#ifdef CONFIG_ARM_PATCH_PHYS_VIRT
+ bl __fixup_pv_table
+#endif
bl __create_page_tables
/*
* The following calls CPU specific code in a position independent
* manner. See arch/arm/mm/proc-*.S for details. r10 = base of
- * xxx_proc_info structure selected by __lookup_machine_type
+ * xxx_proc_info structure selected by __lookup_processor_type
* above. On return, the CPU will be ready for the MMU to be
* turned on, and r0 will hold the CPU control register value.
*/
@@ -118,22 +119,24 @@ ENTRY(stext)
1: b __enable_mmu
ENDPROC(stext)
.ltorg
+#ifndef CONFIG_XIP_KERNEL
+2: .long .
+ .long PAGE_OFFSET
+#endif
/*
* Setup the initial page tables. We only setup the barest
* amount which are required to get the kernel running, which
* generally means mapping in the kernel code.
*
- * r8 = machinfo
- * r9 = cpuid
- * r10 = procinfo
+ * r8 = phys_offset, r9 = cpuid, r10 = procinfo
*
* Returns:
* r0, r3, r5-r7 corrupted
* r4 = physical page table address
*/
__create_page_tables:
- pgtbl r4 @ page table address
+ pgtbl r4, r8 @ page table address
/*
* Clear the 16K level 1 swapper page table
@@ -189,10 +192,8 @@ __create_page_tables:
/*
* Map some ram to cover our .data and .bss areas.
*/
- orr r3, r7, #(KERNEL_RAM_PADDR & 0xff000000)
- .if (KERNEL_RAM_PADDR & 0x00f00000)
- orr r3, r3, #(KERNEL_RAM_PADDR & 0x00f00000)
- .endif
+ add r3, r8, #TEXT_OFFSET
+ orr r3, r3, r7
add r0, r4, #(KERNEL_RAM_VADDR & 0xff000000) >> 18
str r3, [r0, #(KERNEL_RAM_VADDR & 0x00f00000) >> 18]!
ldr r6, =(_end - 1)
@@ -205,14 +206,17 @@ __create_page_tables:
#endif
/*
- * Then map first 1MB of ram in case it contains our boot params.
+ * Then map boot params address in r2 or
+ * the first 1MB of ram if boot params address is not specified.
*/
- add r0, r4, #PAGE_OFFSET >> 18
- orr r6, r7, #(PHYS_OFFSET & 0xff000000)
- .if (PHYS_OFFSET & 0x00f00000)
- orr r6, r6, #(PHYS_OFFSET & 0x00f00000)
- .endif
- str r6, [r0]
+ mov r0, r2, lsr #20
+ movs r0, r0, lsl #20
+ moveq r0, r8
+ sub r3, r0, r8
+ add r3, r3, #PAGE_OFFSET
+ add r3, r4, r3, lsr #18
+ orr r6, r7, r0
+ str r6, [r3]
#ifdef CONFIG_DEBUG_LL
#ifndef CONFIG_DEBUG_ICEDCC
@@ -335,7 +339,7 @@ __secondary_data:
*
* r0 = cp#15 control register
* r1 = machine ID
- * r2 = atags pointer
+ * r2 = atags or dtb pointer
* r4 = page table pointer
* r9 = processor ID
* r13 = *virtual* address to jump to upon completion
@@ -372,7 +376,7 @@ ENDPROC(__enable_mmu)
*
* r0 = cp#15 control register
* r1 = machine ID
- * r2 = atags pointer
+ * r2 = atags or dtb pointer
* r9 = processor ID
* r13 = *virtual* address to jump to upon completion
*
@@ -457,4 +461,129 @@ ENTRY(fixup_smp)
ldmfd sp!, {r4 - r6, pc}
ENDPROC(fixup_smp)
+#ifdef CONFIG_ARM_PATCH_PHYS_VIRT
+
+/* __fixup_pv_table - patch the stub instructions with the delta between
+ * PHYS_OFFSET and PAGE_OFFSET, which is assumed to be 16MiB aligned and
+ * can be expressed by an immediate shifter operand. The stub instruction
+ * has a form of '(add|sub) rd, rn, #imm'.
+ */
+ __HEAD
+__fixup_pv_table:
+ adr r0, 1f
+ ldmia r0, {r3-r5, r7}
+ sub r3, r0, r3 @ PHYS_OFFSET - PAGE_OFFSET
+ add r4, r4, r3 @ adjust table start address
+ add r5, r5, r3 @ adjust table end address
+ add r7, r7, r3 @ adjust __pv_phys_offset address
+ str r8, [r7] @ save computed PHYS_OFFSET to __pv_phys_offset
+#ifndef CONFIG_ARM_PATCH_PHYS_VIRT_16BIT
+ mov r6, r3, lsr #24 @ constant for add/sub instructions
+ teq r3, r6, lsl #24 @ must be 16MiB aligned
+#else
+ mov r6, r3, lsr #16 @ constant for add/sub instructions
+ teq r3, r6, lsl #16 @ must be 64kiB aligned
+#endif
+THUMB( it ne @ cross section branch )
+ bne __error
+ str r6, [r7, #4] @ save to __pv_offset
+ b __fixup_a_pv_table
+ENDPROC(__fixup_pv_table)
+
+ .align
+1: .long .
+ .long __pv_table_begin
+ .long __pv_table_end
+2: .long __pv_phys_offset
+
+ .text
+__fixup_a_pv_table:
+#ifdef CONFIG_THUMB2_KERNEL
+#ifdef CONFIG_ARM_PATCH_PHYS_VIRT_16BIT
+ lsls r0, r6, #24
+ lsr r6, #8
+ beq 1f
+ clz r7, r0
+ lsr r0, #24
+ lsl r0, r7
+ bic r0, 0x0080
+ lsrs r7, #1
+ orrcs r0, #0x0080
+ orr r0, r0, r7, lsl #12
+#endif
+1: lsls r6, #24
+ beq 4f
+ clz r7, r6
+ lsr r6, #24
+ lsl r6, r7
+ bic r6, #0x0080
+ lsrs r7, #1
+ orrcs r6, #0x0080
+ orr r6, r6, r7, lsl #12
+ orr r6, #0x4000
+ b 4f
+2: @ at this point the C flag is always clear
+ add r7, r3
+#ifdef CONFIG_ARM_PATCH_PHYS_VIRT_16BIT
+ ldrh ip, [r7]
+ tst ip, 0x0400 @ the i bit tells us LS or MS byte
+ beq 3f
+ cmp r0, #0 @ set C flag, and ...
+ biceq ip, 0x0400 @ immediate zero value has a special encoding
+ streqh ip, [r7] @ that requires the i bit cleared
+#endif
+3: ldrh ip, [r7, #2]
+ and ip, 0x8f00
+ orrcc ip, r6 @ mask in offset bits 31-24
+ orrcs ip, r0 @ mask in offset bits 23-16
+ strh ip, [r7, #2]
+4: cmp r4, r5
+ ldrcc r7, [r4], #4 @ use branch for delay slot
+ bcc 2b
+ bx lr
+#else
+#ifdef CONFIG_ARM_PATCH_PHYS_VIRT_16BIT
+ and r0, r6, #255 @ offset bits 23-16
+ mov r6, r6, lsr #8 @ offset bits 31-24
+#else
+ mov r0, #0 @ just in case...
+#endif
+ b 3f
+2: ldr ip, [r7, r3]
+ bic ip, ip, #0x000000ff
+ tst ip, #0x400 @ rotate shift tells us LS or MS byte
+ orrne ip, ip, r6 @ mask in offset bits 31-24
+ orreq ip, ip, r0 @ mask in offset bits 23-16
+ str ip, [r7, r3]
+3: cmp r4, r5
+ ldrcc r7, [r4], #4 @ use branch for delay slot
+ bcc 2b
+ mov pc, lr
+#endif
+ENDPROC(__fixup_a_pv_table)
+
+ENTRY(fixup_pv_table)
+ stmfd sp!, {r4 - r7, lr}
+ ldr r2, 2f @ get address of __pv_phys_offset
+ mov r3, #0 @ no offset
+ mov r4, r0 @ r0 = table start
+ add r5, r0, r1 @ r1 = table size
+ ldr r6, [r2, #4] @ get __pv_offset
+ bl __fixup_a_pv_table
+ ldmfd sp!, {r4 - r7, pc}
+ENDPROC(fixup_pv_table)
+
+ .align
+2: .long __pv_phys_offset
+
+ .data
+ .globl __pv_phys_offset
+ .type __pv_phys_offset, %object
+__pv_phys_offset:
+ .long 0
+ .size __pv_phys_offset, . - __pv_phys_offset
+__pv_offset:
+ .long 0
+#endif
+
#include "head-common.S"
diff --git a/arch/arm/kernel/hw_breakpoint.c b/arch/arm/kernel/hw_breakpoint.c
index d600bd35070..44b84fe6e1b 100644
--- a/arch/arm/kernel/hw_breakpoint.c
+++ b/arch/arm/kernel/hw_breakpoint.c
@@ -836,9 +836,11 @@ static int hw_breakpoint_pending(unsigned long addr, unsigned int fsr,
/*
* One-time initialisation.
*/
-static void reset_ctrl_regs(void *unused)
+static void reset_ctrl_regs(void *info)
{
- int i;
+ int i, cpu = smp_processor_id();
+ u32 dbg_power;
+ cpumask_t *cpumask = info;
/*
* v7 debug contains save and restore registers so that debug state
@@ -850,6 +852,17 @@ static void reset_ctrl_regs(void *unused)
*/
if (debug_arch >= ARM_DEBUG_ARCH_V7_ECP14) {
/*
+ * Ensure sticky power-down is clear (i.e. debug logic is
+ * powered up).
+ */
+ asm volatile("mrc p14, 0, %0, c1, c5, 4" : "=r" (dbg_power));
+ if ((dbg_power & 0x1) == 0) {
+ pr_warning("CPU %d debug is powered down!\n", cpu);
+ cpumask_or(cpumask, cpumask, cpumask_of(cpu));
+ return;
+ }
+
+ /*
* Unconditionally clear the lock by writing a value
* other than 0xC5ACCE55 to the access register.
*/
@@ -887,6 +900,7 @@ static struct notifier_block __cpuinitdata dbg_reset_nb = {
static int __init arch_hw_breakpoint_init(void)
{
u32 dscr;
+ cpumask_t cpumask = { CPU_BITS_NONE };
debug_arch = get_debug_arch();
@@ -911,7 +925,13 @@ static int __init arch_hw_breakpoint_init(void)
* Reset the breakpoint resources. We assume that a halting
* debugger will leave the world in a nice state for us.
*/
- on_each_cpu(reset_ctrl_regs, NULL, 1);
+ on_each_cpu(reset_ctrl_regs, &cpumask, 1);
+ if (!cpumask_empty(&cpumask)) {
+ core_num_brps = 0;
+ core_num_reserved_brps = 0;
+ core_num_wrps = 0;
+ return 0;
+ }
ARM_DBG_READ(c1, 0, dscr);
if (dscr & ARM_DSCR_HDBGEN) {
diff --git a/arch/arm/kernel/irq.c b/arch/arm/kernel/irq.c
index 28536e352de..3535d3793e6 100644
--- a/arch/arm/kernel/irq.c
+++ b/arch/arm/kernel/irq.c
@@ -179,14 +179,21 @@ int __init arch_probe_nr_irqs(void)
#ifdef CONFIG_HOTPLUG_CPU
-static void route_irq(struct irq_desc *desc, unsigned int irq, unsigned int cpu)
+static bool migrate_one_irq(struct irq_data *d)
{
- pr_debug("IRQ%u: moving from cpu%u to cpu%u\n", irq, desc->irq_data.node, cpu);
+ unsigned int cpu = cpumask_any_and(d->affinity, cpu_online_mask);
+ bool ret = false;
- raw_spin_lock_irq(&desc->lock);
- desc->irq_data.chip->irq_set_affinity(&desc->irq_data,
- cpumask_of(cpu), false);
- raw_spin_unlock_irq(&desc->lock);
+ if (cpu >= nr_cpu_ids) {
+ cpu = cpumask_any(cpu_online_mask);
+ ret = true;
+ }
+
+ pr_debug("IRQ%u: moving from cpu%u to cpu%u\n", d->irq, d->node, cpu);
+
+ d->chip->irq_set_affinity(d, cpumask_of(cpu), true);
+
+ return ret;
}
/*
@@ -198,25 +205,30 @@ void migrate_irqs(void)
{
unsigned int i, cpu = smp_processor_id();
struct irq_desc *desc;
+ unsigned long flags;
+
+ local_irq_save(flags);
for_each_irq_desc(i, desc) {
struct irq_data *d = &desc->irq_data;
+ bool affinity_broken = false;
- if (d->node == cpu) {
- unsigned int newcpu = cpumask_any_and(d->affinity,
- cpu_online_mask);
- if (newcpu >= nr_cpu_ids) {
- if (printk_ratelimit())
- printk(KERN_INFO "IRQ%u no longer affine to CPU%u\n",
- i, cpu);
+ raw_spin_lock(&desc->lock);
+ do {
+ if (desc->action == NULL)
+ break;
- cpumask_setall(d->affinity);
- newcpu = cpumask_any_and(d->affinity,
- cpu_online_mask);
- }
+ if (d->node != cpu)
+ break;
- route_irq(desc, i, newcpu);
- }
+ affinity_broken = migrate_one_irq(d);
+ } while (0);
+ raw_spin_unlock(&desc->lock);
+
+ if (affinity_broken && printk_ratelimit())
+ pr_warning("IRQ%u no longer affine to CPU%u\n", i, cpu);
}
+
+ local_irq_restore(flags);
}
#endif /* CONFIG_HOTPLUG_CPU */
diff --git a/arch/arm/kernel/module.c b/arch/arm/kernel/module.c
index 6d4105e6872..fee7c36349e 100644
--- a/arch/arm/kernel/module.c
+++ b/arch/arm/kernel/module.c
@@ -76,6 +76,7 @@ apply_relocate(Elf32_Shdr *sechdrs, const char *strtab, unsigned int symindex,
for (i = 0; i < relsec->sh_size / sizeof(Elf32_Rel); i++, rel++) {
unsigned long loc;
Elf32_Sym *sym;
+ const char *symname;
s32 offset;
#ifdef CONFIG_THUMB2_KERNEL
u32 upper, lower, sign, j1, j2;
@@ -83,18 +84,18 @@ apply_relocate(Elf32_Shdr *sechdrs, const char *strtab, unsigned int symindex,
offset = ELF32_R_SYM(rel->r_info);
if (offset < 0 || offset > (symsec->sh_size / sizeof(Elf32_Sym))) {
- printk(KERN_ERR "%s: bad relocation, section %d reloc %d\n",
+ pr_err("%s: section %u reloc %u: bad relocation sym offset\n",
module->name, relindex, i);
return -ENOEXEC;
}
sym = ((Elf32_Sym *)symsec->sh_addr) + offset;
+ symname = strtab + sym->st_name;
if (rel->r_offset < 0 || rel->r_offset > dstsec->sh_size - sizeof(u32)) {
- printk(KERN_ERR "%s: out of bounds relocation, "
- "section %d reloc %d offset %d size %d\n",
- module->name, relindex, i, rel->r_offset,
- dstsec->sh_size);
+ pr_err("%s: section %u reloc %u sym '%s': out of bounds relocation, offset %d size %u\n",
+ module->name, relindex, i, symname,
+ rel->r_offset, dstsec->sh_size);
return -ENOEXEC;
}
@@ -120,10 +121,10 @@ apply_relocate(Elf32_Shdr *sechdrs, const char *strtab, unsigned int symindex,
if (offset & 3 ||
offset <= (s32)0xfe000000 ||
offset >= (s32)0x02000000) {
- printk(KERN_ERR
- "%s: relocation out of range, section "
- "%d reloc %d sym '%s'\n", module->name,
- relindex, i, strtab + sym->st_name);
+ pr_err("%s: section %u reloc %u sym '%s': relocation %u out of range (%#lx -> %#x)\n",
+ module->name, relindex, i, symname,
+ ELF32_R_TYPE(rel->r_info), loc,
+ sym->st_value);
return -ENOEXEC;
}
@@ -196,10 +197,10 @@ apply_relocate(Elf32_Shdr *sechdrs, const char *strtab, unsigned int symindex,
if (!(offset & 1) ||
offset <= (s32)0xff000000 ||
offset >= (s32)0x01000000) {
- printk(KERN_ERR
- "%s: relocation out of range, section "
- "%d reloc %d sym '%s'\n", module->name,
- relindex, i, strtab + sym->st_name);
+ pr_err("%s: section %u reloc %u sym '%s': relocation %u out of range (%#lx -> %#x)\n",
+ module->name, relindex, i, symname,
+ ELF32_R_TYPE(rel->r_info), loc,
+ sym->st_value);
return -ENOEXEC;
}
@@ -282,12 +283,13 @@ static const Elf_Shdr *find_mod_section(const Elf32_Ehdr *hdr,
return NULL;
}
+extern void fixup_pv_table(const void *, unsigned long);
extern void fixup_smp(const void *, unsigned long);
int module_finalize(const Elf32_Ehdr *hdr, const Elf_Shdr *sechdrs,
struct module *mod)
{
- const Elf_Shdr * __maybe_unused s = NULL;
+ const Elf_Shdr *s = NULL;
#ifdef CONFIG_ARM_UNWIND
const char *secstrs = (void *)hdr + sechdrs[hdr->e_shstrndx].sh_offset;
const Elf_Shdr *sechdrs_end = sechdrs + hdr->e_shnum;
@@ -332,6 +334,11 @@ int module_finalize(const Elf32_Ehdr *hdr, const Elf_Shdr *sechdrs,
maps[i].txt_sec->sh_addr,
maps[i].txt_sec->sh_size);
#endif
+#ifdef CONFIG_ARM_PATCH_PHYS_VIRT
+ s = find_mod_section(hdr, sechdrs, ".pv_table");
+ if (s)
+ fixup_pv_table((void *)s->sh_addr, s->sh_size);
+#endif
s = find_mod_section(hdr, sechdrs, ".alt.smp.init");
if (s && !is_smp())
fixup_smp((void *)s->sh_addr, s->sh_size);
diff --git a/arch/arm/kernel/perf_event.c b/arch/arm/kernel/perf_event.c
index d150ad1ccb5..22e194eb853 100644
--- a/arch/arm/kernel/perf_event.c
+++ b/arch/arm/kernel/perf_event.c
@@ -377,9 +377,18 @@ validate_group(struct perf_event *event)
return 0;
}
+static irqreturn_t armpmu_platform_irq(int irq, void *dev)
+{
+ struct arm_pmu_platdata *plat = dev_get_platdata(&pmu_device->dev);
+
+ return plat->handle_irq(irq, dev, armpmu->handle_irq);
+}
+
static int
armpmu_reserve_hardware(void)
{
+ struct arm_pmu_platdata *plat;
+ irq_handler_t handle_irq;
int i, err = -ENODEV, irq;
pmu_device = reserve_pmu(ARM_PMU_DEVICE_CPU);
@@ -390,6 +399,12 @@ armpmu_reserve_hardware(void)
init_pmu(ARM_PMU_DEVICE_CPU);
+ plat = dev_get_platdata(&pmu_device->dev);
+ if (plat && plat->handle_irq)
+ handle_irq = armpmu_platform_irq;
+ else
+ handle_irq = armpmu->handle_irq;
+
if (pmu_device->num_resources < 1) {
pr_err("no irqs for PMUs defined\n");
return -ENODEV;
@@ -400,7 +415,7 @@ armpmu_reserve_hardware(void)
if (irq < 0)
continue;
- err = request_irq(irq, armpmu->handle_irq,
+ err = request_irq(irq, handle_irq,
IRQF_DISABLED | IRQF_NOBALANCING,
"armpmu", NULL);
if (err) {
diff --git a/arch/arm/kernel/perf_event_v6.c b/arch/arm/kernel/perf_event_v6.c
index c058bfc8532..6fc2d228db5 100644
--- a/arch/arm/kernel/perf_event_v6.c
+++ b/arch/arm/kernel/perf_event_v6.c
@@ -30,7 +30,7 @@
* enable the interrupt.
*/
-#ifdef CONFIG_CPU_V6
+#if defined(CONFIG_CPU_V6) || defined(CONFIG_CPU_V6K)
enum armv6_perf_types {
ARMV6_PERFCTR_ICACHE_MISS = 0x0,
ARMV6_PERFCTR_IBUF_STALL = 0x1,
@@ -669,4 +669,4 @@ static const struct arm_pmu *__init armv6mpcore_pmu_init(void)
{
return NULL;
}
-#endif /* CONFIG_CPU_V6 */
+#endif /* CONFIG_CPU_V6 || CONFIG_CPU_V6K */
diff --git a/arch/arm/kernel/ptrace.c b/arch/arm/kernel/ptrace.c
index 19c6816db61..2bf27f364d0 100644
--- a/arch/arm/kernel/ptrace.c
+++ b/arch/arm/kernel/ptrace.c
@@ -26,8 +26,6 @@
#include <asm/system.h>
#include <asm/traps.h>
-#include "ptrace.h"
-
#define REG_PC 15
#define REG_PSR 16
/*
@@ -184,389 +182,12 @@ put_user_reg(struct task_struct *task, int offset, long data)
return ret;
}
-static inline int
-read_u32(struct task_struct *task, unsigned long addr, u32 *res)
-{
- int ret;
-
- ret = access_process_vm(task, addr, res, sizeof(*res), 0);
-
- return ret == sizeof(*res) ? 0 : -EIO;
-}
-
-static inline int
-read_instr(struct task_struct *task, unsigned long addr, u32 *res)
-{
- int ret;
-
- if (addr & 1) {
- u16 val;
- ret = access_process_vm(task, addr & ~1, &val, sizeof(val), 0);
- ret = ret == sizeof(val) ? 0 : -EIO;
- *res = val;
- } else {
- u32 val;
- ret = access_process_vm(task, addr & ~3, &val, sizeof(val), 0);
- ret = ret == sizeof(val) ? 0 : -EIO;
- *res = val;
- }
- return ret;
-}
-
-/*
- * Get value of register `rn' (in the instruction)
- */
-static unsigned long
-ptrace_getrn(struct task_struct *child, unsigned long insn)
-{
- unsigned int reg = (insn >> 16) & 15;
- unsigned long val;
-
- val = get_user_reg(child, reg);
- if (reg == 15)
- val += 8;
-
- return val;
-}
-
-/*
- * Get value of operand 2 (in an ALU instruction)
- */
-static unsigned long
-ptrace_getaluop2(struct task_struct *child, unsigned long insn)
-{
- unsigned long val;
- int shift;
- int type;
-
- if (insn & 1 << 25) {
- val = insn & 255;
- shift = (insn >> 8) & 15;
- type = 3;
- } else {
- val = get_user_reg (child, insn & 15);
-
- if (insn & (1 << 4))
- shift = (int)get_user_reg (child, (insn >> 8) & 15);
- else
- shift = (insn >> 7) & 31;
-
- type = (insn >> 5) & 3;
- }
-
- switch (type) {
- case 0: val <<= shift; break;
- case 1: val >>= shift; break;
- case 2:
- val = (((signed long)val) >> shift);
- break;
- case 3:
- val = (val >> shift) | (val << (32 - shift));
- break;
- }
- return val;
-}
-
-/*
- * Get value of operand 2 (in a LDR instruction)
- */
-static unsigned long
-ptrace_getldrop2(struct task_struct *child, unsigned long insn)
-{
- unsigned long val;
- int shift;
- int type;
-
- val = get_user_reg(child, insn & 15);
- shift = (insn >> 7) & 31;
- type = (insn >> 5) & 3;
-
- switch (type) {
- case 0: val <<= shift; break;
- case 1: val >>= shift; break;
- case 2:
- val = (((signed long)val) >> shift);
- break;
- case 3:
- val = (val >> shift) | (val << (32 - shift));
- break;
- }
- return val;
-}
-
-#define OP_MASK 0x01e00000
-#define OP_AND 0x00000000
-#define OP_EOR 0x00200000
-#define OP_SUB 0x00400000
-#define OP_RSB 0x00600000
-#define OP_ADD 0x00800000
-#define OP_ADC 0x00a00000
-#define OP_SBC 0x00c00000
-#define OP_RSC 0x00e00000
-#define OP_ORR 0x01800000
-#define OP_MOV 0x01a00000
-#define OP_BIC 0x01c00000
-#define OP_MVN 0x01e00000
-
-static unsigned long
-get_branch_address(struct task_struct *child, unsigned long pc, unsigned long insn)
-{
- u32 alt = 0;
-
- switch (insn & 0x0e000000) {
- case 0x00000000:
- case 0x02000000: {
- /*
- * data processing
- */
- long aluop1, aluop2, ccbit;
-
- if ((insn & 0x0fffffd0) == 0x012fff10) {
- /*
- * bx or blx
- */
- alt = get_user_reg(child, insn & 15);
- break;
- }
-
-
- if ((insn & 0xf000) != 0xf000)
- break;
-
- aluop1 = ptrace_getrn(child, insn);
- aluop2 = ptrace_getaluop2(child, insn);
- ccbit = get_user_reg(child, REG_PSR) & PSR_C_BIT ? 1 : 0;
-
- switch (insn & OP_MASK) {
- case OP_AND: alt = aluop1 & aluop2; break;
- case OP_EOR: alt = aluop1 ^ aluop2; break;
- case OP_SUB: alt = aluop1 - aluop2; break;
- case OP_RSB: alt = aluop2 - aluop1; break;
- case OP_ADD: alt = aluop1 + aluop2; break;
- case OP_ADC: alt = aluop1 + aluop2 + ccbit; break;
- case OP_SBC: alt = aluop1 - aluop2 + ccbit; break;
- case OP_RSC: alt = aluop2 - aluop1 + ccbit; break;
- case OP_ORR: alt = aluop1 | aluop2; break;
- case OP_MOV: alt = aluop2; break;
- case OP_BIC: alt = aluop1 & ~aluop2; break;
- case OP_MVN: alt = ~aluop2; break;
- }
- break;
- }
-
- case 0x04000000:
- case 0x06000000:
- /*
- * ldr
- */
- if ((insn & 0x0010f000) == 0x0010f000) {
- unsigned long base;
-
- base = ptrace_getrn(child, insn);
- if (insn & 1 << 24) {
- long aluop2;
-
- if (insn & 0x02000000)
- aluop2 = ptrace_getldrop2(child, insn);
- else
- aluop2 = insn & 0xfff;
-
- if (insn & 1 << 23)
- base += aluop2;
- else
- base -= aluop2;
- }
- read_u32(child, base, &alt);
- }
- break;
-
- case 0x08000000:
- /*
- * ldm
- */
- if ((insn & 0x00108000) == 0x00108000) {
- unsigned long base;
- unsigned int nr_regs;
-
- if (insn & (1 << 23)) {
- nr_regs = hweight16(insn & 65535) << 2;
-
- if (!(insn & (1 << 24)))
- nr_regs -= 4;
- } else {
- if (insn & (1 << 24))
- nr_regs = -4;
- else
- nr_regs = 0;
- }
-
- base = ptrace_getrn(child, insn);
-
- read_u32(child, base + nr_regs, &alt);
- break;
- }
- break;
-
- case 0x0a000000: {
- /*
- * bl or b
- */
- signed long displ;
- /* It's a branch/branch link: instead of trying to
- * figure out whether the branch will be taken or not,
- * we'll put a breakpoint at both locations. This is
- * simpler, more reliable, and probably not a whole lot
- * slower than the alternative approach of emulating the
- * branch.
- */
- displ = (insn & 0x00ffffff) << 8;
- displ = (displ >> 6) + 8;
- if (displ != 0 && displ != 4)
- alt = pc + displ;
- }
- break;
- }
-
- return alt;
-}
-
-static int
-swap_insn(struct task_struct *task, unsigned long addr,
- void *old_insn, void *new_insn, int size)
-{
- int ret;
-
- ret = access_process_vm(task, addr, old_insn, size, 0);
- if (ret == size)
- ret = access_process_vm(task, addr, new_insn, size, 1);
- return ret;
-}
-
-static void
-add_breakpoint(struct task_struct *task, struct debug_info *dbg, unsigned long addr)
-{
- int nr = dbg->nsaved;
-
- if (nr < 2) {
- u32 new_insn = BREAKINST_ARM;
- int res;
-
- res = swap_insn(task, addr, &dbg->bp[nr].insn, &new_insn, 4);
-
- if (res == 4) {
- dbg->bp[nr].address = addr;
- dbg->nsaved += 1;
- }
- } else
- printk(KERN_ERR "ptrace: too many breakpoints\n");
-}
-
-/*
- * Clear one breakpoint in the user program. We copy what the hardware
- * does and use bit 0 of the address to indicate whether this is a Thumb
- * breakpoint or an ARM breakpoint.
- */
-static void clear_breakpoint(struct task_struct *task, struct debug_entry *bp)
-{
- unsigned long addr = bp->address;
- union debug_insn old_insn;
- int ret;
-
- if (addr & 1) {
- ret = swap_insn(task, addr & ~1, &old_insn.thumb,
- &bp->insn.thumb, 2);
-
- if (ret != 2 || old_insn.thumb != BREAKINST_THUMB)
- printk(KERN_ERR "%s:%d: corrupted Thumb breakpoint at "
- "0x%08lx (0x%04x)\n", task->comm,
- task_pid_nr(task), addr, old_insn.thumb);
- } else {
- ret = swap_insn(task, addr & ~3, &old_insn.arm,
- &bp->insn.arm, 4);
-
- if (ret != 4 || old_insn.arm != BREAKINST_ARM)
- printk(KERN_ERR "%s:%d: corrupted ARM breakpoint at "
- "0x%08lx (0x%08x)\n", task->comm,
- task_pid_nr(task), addr, old_insn.arm);
- }
-}
-
-void ptrace_set_bpt(struct task_struct *child)
-{
- struct pt_regs *regs;
- unsigned long pc;
- u32 insn;
- int res;
-
- regs = task_pt_regs(child);
- pc = instruction_pointer(regs);
-
- if (thumb_mode(regs)) {
- printk(KERN_WARNING "ptrace: can't handle thumb mode\n");
- return;
- }
-
- res = read_instr(child, pc, &insn);
- if (!res) {
- struct debug_info *dbg = &child->thread.debug;
- unsigned long alt;
-
- dbg->nsaved = 0;
-
- alt = get_branch_address(child, pc, insn);
- if (alt)
- add_breakpoint(child, dbg, alt);
-
- /*
- * Note that we ignore the result of setting the above
- * breakpoint since it may fail. When it does, this is
- * not so much an error, but a forewarning that we may
- * be receiving a prefetch abort shortly.
- *
- * If we don't set this breakpoint here, then we can
- * lose control of the thread during single stepping.
- */
- if (!alt || predicate(insn) != PREDICATE_ALWAYS)
- add_breakpoint(child, dbg, pc + 4);
- }
-}
-
-/*
- * Ensure no single-step breakpoint is pending. Returns non-zero
- * value if child was being single-stepped.
- */
-void ptrace_cancel_bpt(struct task_struct *child)
-{
- int i, nsaved = child->thread.debug.nsaved;
-
- child->thread.debug.nsaved = 0;
-
- if (nsaved > 2) {
- printk("ptrace_cancel_bpt: bogus nsaved: %d!\n", nsaved);
- nsaved = 2;
- }
-
- for (i = 0; i < nsaved; i++)
- clear_breakpoint(child, &child->thread.debug.bp[i]);
-}
-
-void user_disable_single_step(struct task_struct *task)
-{
- task->ptrace &= ~PT_SINGLESTEP;
- ptrace_cancel_bpt(task);
-}
-
-void user_enable_single_step(struct task_struct *task)
-{
- task->ptrace |= PT_SINGLESTEP;
-}
-
/*
* Called by kernel/ptrace.c when detaching..
*/
void ptrace_disable(struct task_struct *child)
{
- user_disable_single_step(child);
+ /* Nothing to do. */
}
/*
@@ -576,8 +197,6 @@ void ptrace_break(struct task_struct *tsk, struct pt_regs *regs)
{
siginfo_t info;
- ptrace_cancel_bpt(tsk);
-
info.si_signo = SIGTRAP;
info.si_errno = 0;
info.si_code = TRAP_BRKPT;
@@ -996,10 +615,10 @@ static int ptrace_gethbpregs(struct task_struct *tsk, long num,
while (!(arch_ctrl.len & 0x1))
arch_ctrl.len >>= 1;
- if (idx & 0x1)
- reg = encode_ctrl_reg(arch_ctrl);
- else
+ if (num & 0x1)
reg = bp->attr.bp_addr;
+ else
+ reg = encode_ctrl_reg(arch_ctrl);
}
put:
diff --git a/arch/arm/kernel/ptrace.h b/arch/arm/kernel/ptrace.h
deleted file mode 100644
index 3926605b82e..00000000000
--- a/arch/arm/kernel/ptrace.h
+++ /dev/null
@@ -1,37 +0,0 @@
-/*
- * linux/arch/arm/kernel/ptrace.h
- *
- * Copyright (C) 2000-2003 Russell King
- *
- * 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/ptrace.h>
-
-extern void ptrace_cancel_bpt(struct task_struct *);
-extern void ptrace_set_bpt(struct task_struct *);
-extern void ptrace_break(struct task_struct *, struct pt_regs *);
-
-/*
- * Send SIGTRAP if we're single-stepping
- */
-static inline void single_step_trap(struct task_struct *task)
-{
- if (task->ptrace & PT_SINGLESTEP) {
- ptrace_cancel_bpt(task);
- send_sig(SIGTRAP, task, 1);
- }
-}
-
-static inline void single_step_clear(struct task_struct *task)
-{
- if (task->ptrace & PT_SINGLESTEP)
- ptrace_cancel_bpt(task);
-}
-
-static inline void single_step_set(struct task_struct *task)
-{
- if (task->ptrace & PT_SINGLESTEP)
- ptrace_set_bpt(task);
-}
diff --git a/arch/arm/kernel/relocate_kernel.S b/arch/arm/kernel/relocate_kernel.S
index 9cf4cbf8f95..a2599e7e151 100644
--- a/arch/arm/kernel/relocate_kernel.S
+++ b/arch/arm/kernel/relocate_kernel.S
@@ -7,8 +7,8 @@
.globl relocate_new_kernel
relocate_new_kernel:
- ldr r0,kexec_indirection_page
- ldr r1,kexec_start_address
+ ldr r0,__kexec_indirection_page
+ ldr r1,__kexec_start_address
/*
* If there is no indirection page (we are doing crashdumps)
@@ -55,27 +55,31 @@ relocate_new_kernel:
/* Jump to relocated kernel */
mov lr,r1
mov r0,#0
- ldr r1,kexec_mach_type
- ldr r2,kexec_boot_atags
+ ldr r1,__kexec_mach_type
+ ldr r2,__kexec_boot_atags
mov pc,lr
.align
.globl kexec_start_address
kexec_start_address:
+__kexec_start_address:
.long 0x0
.globl kexec_indirection_page
kexec_indirection_page:
+__kexec_indirection_page:
.long 0x0
.globl kexec_mach_type
kexec_mach_type:
+__kexec_mach_type:
.long 0x0
/* phy addr of the atags for the new kernel */
.globl kexec_boot_atags
kexec_boot_atags:
+__kexec_boot_atags:
.long 0x0
relocate_new_kernel_end:
diff --git a/arch/arm/kernel/return_address.c b/arch/arm/kernel/return_address.c
index df246da4cec..0b13a72f855 100644
--- a/arch/arm/kernel/return_address.c
+++ b/arch/arm/kernel/return_address.c
@@ -9,6 +9,7 @@
* the Free Software Foundation.
*/
#include <linux/module.h>
+#include <linux/ftrace.h>
#if defined(CONFIG_FRAME_POINTER) && !defined(CONFIG_ARM_UNWIND)
#include <linux/sched.h>
diff --git a/arch/arm/kernel/setup.c b/arch/arm/kernel/setup.c
index 5ea4fb718b9..319199b0ab2 100644
--- a/arch/arm/kernel/setup.c
+++ b/arch/arm/kernel/setup.c
@@ -20,6 +20,7 @@
#include <linux/screen_info.h>
#include <linux/init.h>
#include <linux/kexec.h>
+#include <linux/of_fdt.h>
#include <linux/crash_dump.h>
#include <linux/root_dev.h>
#include <linux/cpu.h>
@@ -42,6 +43,7 @@
#include <asm/cachetype.h>
#include <asm/tlbflush.h>
+#include <asm/prom.h>
#include <asm/mach/arch.h>
#include <asm/mach/irq.h>
#include <asm/mach/time.h>
@@ -125,7 +127,7 @@ EXPORT_SYMBOL(elf_platform);
static const char *cpu_name;
static const char *machine_name;
-static char __initdata cmd_line[COMMAND_LINE_SIZE];
+char cmd_line[COMMAND_LINE_SIZE];
struct machine_desc *machine_desc __initdata;
static char default_command_line[COMMAND_LINE_SIZE] __initdata = CONFIG_CMDLINE;
@@ -308,7 +310,22 @@ static void __init cacheid_init(void)
* already provide the required functionality.
*/
extern struct proc_info_list *lookup_processor_type(unsigned int);
-extern struct machine_desc *lookup_machine_type(unsigned int);
+
+void __init early_print(const char *str, ...)
+{
+ extern void printascii(const char *);
+ char buf[256];
+ va_list ap;
+
+ va_start(ap, str);
+ vsnprintf(buf, sizeof(buf), str, ap);
+ va_end(ap);
+
+#ifdef CONFIG_DEBUG_LL
+ printascii(buf);
+#endif
+ printk("%s", buf);
+}
static void __init feat_v6_fixup(void)
{
@@ -424,26 +441,21 @@ void cpu_init(void)
: "r14");
}
-static struct machine_desc * __init setup_machine(unsigned int nr)
+void __init dump_machine_table(void)
{
- struct machine_desc *list;
+ struct machine_desc *p;
- /*
- * locate machine in the list of supported machines.
- */
- list = lookup_machine_type(nr);
- if (!list) {
- printk("Machine configuration botched (nr %d), unable "
- "to continue.\n", nr);
- while (1);
- }
+ early_print("Available machine support:\n\nID (hex)\tNAME\n");
+ for_each_machine_desc(p)
+ early_print("%08x\t%s\n", p->nr, p->name);
- printk("Machine: %s\n", list->name);
+ early_print("\nPlease check your kernel config and/or bootloader.\n");
- return list;
+ while (true)
+ /* can't use cpu_relax() here as it may require MMU setup */;
}
-static int __init arm_add_memory(unsigned long start, unsigned long size)
+int __init arm_add_memory(unsigned long start, unsigned long size)
{
struct membank *bank = &meminfo.bank[meminfo.nr_banks];
@@ -703,7 +715,7 @@ static struct init_tags {
{ tag_size(tag_core), ATAG_CORE },
{ 1, PAGE_SIZE, 0xff },
{ tag_size(tag_mem32), ATAG_MEM },
- { MEM_SIZE, PHYS_OFFSET },
+ { MEM_SIZE },
{ 0, ATAG_NONE }
};
@@ -796,26 +808,51 @@ static void __init squash_mem_tags(struct tag *tag)
tag->hdr.tag = ATAG_NONE;
}
-void __init setup_arch(char **cmdline_p)
+static struct machine_desc * __init setup_machine_tags(unsigned int nr)
{
struct tag *tags = (struct tag *)&init_tags;
- struct machine_desc *mdesc;
+ struct machine_desc *mdesc = NULL, *p;
char *from = default_command_line;
- unwind_init();
+ /*
+ * locate machine in the list of supported machines.
+ */
+ for_each_machine_desc(p)
+ if (nr == p->nr) {
+ printk("Machine: %s\n", p->name);
+ mdesc = p;
+ break;
+ }
- setup_processor();
- mdesc = setup_machine(machine_arch_type);
- machine_desc = mdesc;
- machine_name = mdesc->name;
+ if (!mdesc) {
+ early_print("\nError: unrecognized/unsupported machine ID"
+ " (r1 = 0x%08x).\n\n", nr);
+ dump_machine_table(); /* does not return */
+ }
- if (mdesc->soft_reboot)
- reboot_setup("s");
+ printk("Machine: %s\n", mdesc->name);
if (__atags_pointer)
tags = phys_to_virt(__atags_pointer);
- else if (mdesc->boot_params)
- tags = phys_to_virt(mdesc->boot_params);
+ else if (mdesc->boot_params) {
+#ifdef CONFIG_MMU
+ /*
+ * We still are executing with a minimal MMU mapping created
+ * with the presumption that the machine default for this
+ * is located in the first MB of RAM. Anything else will
+ * fault and silently hang the kernel at this point.
+ */
+ if (mdesc->boot_params < PHYS_OFFSET ||
+ mdesc->boot_params >= PHYS_OFFSET + SZ_1M) {
+ printk(KERN_WARNING
+ "Default boot params at physical 0x%08lx out of reach\n",
+ mdesc->boot_params);
+ } else
+#endif
+ {
+ tags = phys_to_virt(mdesc->boot_params);
+ }
+ }
#if defined(CONFIG_DEPRECATED_PARAM_STRUCT)
/*
@@ -838,16 +875,39 @@ void __init setup_arch(char **cmdline_p)
parse_tags(tags);
}
- init_mm.start_code = (unsigned long) _text;
- init_mm.end_code = (unsigned long) _etext;
- init_mm.end_data = (unsigned long) _edata;
- init_mm.brk = (unsigned long) _end;
-
/* parse_early_param needs a boot_command_line */
strlcpy(boot_command_line, from, COMMAND_LINE_SIZE);
/* populate cmd_line too for later use, preserving boot_command_line */
strlcpy(cmd_line, boot_command_line, COMMAND_LINE_SIZE);
+
+ return mdesc;
+}
+
+
+void __init setup_arch(char **cmdline_p)
+{
+ struct machine_desc *mdesc;
+
+ init_tags.mem.start = PHYS_OFFSET;
+
+ unwind_init();
+
+ setup_processor();
+ mdesc = setup_machine_fdt(__atags_pointer);
+ if (!mdesc)
+ mdesc = setup_machine_tags(machine_arch_type);
+ machine_desc = mdesc;
+ machine_name = mdesc->name;
+
+ if (mdesc->soft_reboot)
+ reboot_setup("s");
+
+ init_mm.start_code = (unsigned long) _text;
+ init_mm.end_code = (unsigned long) _etext;
+ init_mm.end_data = (unsigned long) _edata;
+ init_mm.brk = (unsigned long) _end;
+
*cmdline_p = cmd_line;
parse_early_param();
@@ -857,6 +917,8 @@ void __init setup_arch(char **cmdline_p)
paging_init(mdesc);
request_standard_resources(mdesc);
+ unflatten_device_tree();
+
#ifdef CONFIG_SMP
if (is_smp())
smp_init_cpus();
diff --git a/arch/arm/kernel/signal.c b/arch/arm/kernel/signal.c
index abaf8445ce2..cb839831764 100644
--- a/arch/arm/kernel/signal.c
+++ b/arch/arm/kernel/signal.c
@@ -20,7 +20,6 @@
#include <asm/unistd.h>
#include <asm/vfp.h>
-#include "ptrace.h"
#include "signal.h"
#define _BLOCKABLE (~(sigmask(SIGKILL) | sigmask(SIGSTOP)))
@@ -348,8 +347,6 @@ asmlinkage int sys_sigreturn(struct pt_regs *regs)
if (restore_sigframe(regs, frame))
goto badframe;
- single_step_trap(current);
-
return regs->ARM_r0;
badframe:
@@ -383,8 +380,6 @@ asmlinkage int sys_rt_sigreturn(struct pt_regs *regs)
if (do_sigaltstack(&frame->sig.uc.uc_stack, NULL, regs->ARM_sp) == -EFAULT)
goto badframe;
- single_step_trap(current);
-
return regs->ARM_r0;
badframe:
@@ -706,8 +701,6 @@ static void do_signal(struct pt_regs *regs, int syscall)
if (try_to_freeze())
goto no_signal;
- single_step_clear(current);
-
signr = get_signal_to_deliver(&info, &ka, regs, NULL);
if (signr > 0) {
sigset_t *oldset;
@@ -726,7 +719,6 @@ static void do_signal(struct pt_regs *regs, int syscall)
if (test_thread_flag(TIF_RESTORE_SIGMASK))
clear_thread_flag(TIF_RESTORE_SIGMASK);
}
- single_step_set(current);
return;
}
@@ -772,7 +764,6 @@ static void do_signal(struct pt_regs *regs, int syscall)
sigprocmask(SIG_SETMASK, &current->saved_sigmask, NULL);
}
}
- single_step_set(current);
}
asmlinkage void
diff --git a/arch/arm/kernel/tcm.c b/arch/arm/kernel/tcm.c
index 26685c2f7a4..f5cf660eefc 100644
--- a/arch/arm/kernel/tcm.c
+++ b/arch/arm/kernel/tcm.c
@@ -15,7 +15,7 @@
#include <linux/string.h> /* memcpy */
#include <asm/cputype.h>
#include <asm/mach/map.h>
-#include <mach/memory.h>
+#include <asm/memory.h>
#include "tcm.h"
static struct gen_pool *tcm_pool;
diff --git a/arch/arm/kernel/traps.c b/arch/arm/kernel/traps.c
index ee57640ba2b..21ac43f1c2d 100644
--- a/arch/arm/kernel/traps.c
+++ b/arch/arm/kernel/traps.c
@@ -23,6 +23,7 @@
#include <linux/kexec.h>
#include <linux/delay.h>
#include <linux/init.h>
+#include <linux/sched.h>
#include <asm/atomic.h>
#include <asm/cacheflush.h>
@@ -32,7 +33,6 @@
#include <asm/unwind.h>
#include <asm/tls.h>
-#include "ptrace.h"
#include "signal.h"
static const char *handler[]= { "prefetch abort", "data abort", "address exception", "interrupt" };
@@ -256,7 +256,7 @@ static int __die(const char *str, int err, struct thread_info *thread, struct pt
return ret;
}
-DEFINE_SPINLOCK(die_lock);
+static DEFINE_SPINLOCK(die_lock);
/*
* This function is protected against re-entrancy.
diff --git a/arch/arm/kernel/vmlinux.lds.S b/arch/arm/kernel/vmlinux.lds.S
index 61462790757..dfbb377e251 100644
--- a/arch/arm/kernel/vmlinux.lds.S
+++ b/arch/arm/kernel/vmlinux.lds.S
@@ -64,6 +64,10 @@ SECTIONS
__smpalt_end = .;
#endif
+ __pv_table_begin = .;
+ *(.pv_table)
+ __pv_table_end = .;
+
INIT_SETUP(16)
INIT_CALLS
diff --git a/arch/arm/lib/bitops.h b/arch/arm/lib/bitops.h
index d42252918bf..10d868a5a48 100644
--- a/arch/arm/lib/bitops.h
+++ b/arch/arm/lib/bitops.h
@@ -1,44 +1,52 @@
-
-#if __LINUX_ARM_ARCH__ >= 6 && defined(CONFIG_CPU_32v6K)
+#if __LINUX_ARM_ARCH__ >= 6
.macro bitop, instr
+ ands ip, r1, #3
+ strneb r1, [ip] @ assert word-aligned
mov r2, #1
- and r3, r0, #7 @ Get bit offset
- add r1, r1, r0, lsr #3 @ Get byte offset
+ and r3, r0, #31 @ Get bit offset
+ mov r0, r0, lsr #5
+ add r1, r1, r0, lsl #2 @ Get word offset
mov r3, r2, lsl r3
-1: ldrexb r2, [r1]
+1: ldrex r2, [r1]
\instr r2, r2, r3
- strexb r0, r2, [r1]
+ strex r0, r2, [r1]
cmp r0, #0
bne 1b
- mov pc, lr
+ bx lr
.endm
.macro testop, instr, store
- and r3, r0, #7 @ Get bit offset
+ ands ip, r1, #3
+ strneb r1, [ip] @ assert word-aligned
mov r2, #1
- add r1, r1, r0, lsr #3 @ Get byte offset
+ and r3, r0, #31 @ Get bit offset
+ mov r0, r0, lsr #5
+ add r1, r1, r0, lsl #2 @ Get word offset
mov r3, r2, lsl r3 @ create mask
smp_dmb
-1: ldrexb r2, [r1]
+1: ldrex r2, [r1]
ands r0, r2, r3 @ save old value of bit
- \instr r2, r2, r3 @ toggle bit
- strexb ip, r2, [r1]
+ \instr r2, r2, r3 @ toggle bit
+ strex ip, r2, [r1]
cmp ip, #0
bne 1b
smp_dmb
cmp r0, #0
movne r0, #1
-2: mov pc, lr
+2: bx lr
.endm
#else
.macro bitop, instr
- and r2, r0, #7
+ ands ip, r1, #3
+ strneb r1, [ip] @ assert word-aligned
+ and r2, r0, #31
+ mov r0, r0, lsr #5
mov r3, #1
mov r3, r3, lsl r2
save_and_disable_irqs ip
- ldrb r2, [r1, r0, lsr #3]
+ ldr r2, [r1, r0, lsl #2]
\instr r2, r2, r3
- strb r2, [r1, r0, lsr #3]
+ str r2, [r1, r0, lsl #2]
restore_irqs ip
mov pc, lr
.endm
@@ -52,11 +60,13 @@
* to avoid dirtying the data cache.
*/
.macro testop, instr, store
- add r1, r1, r0, lsr #3
- and r3, r0, #7
- mov r0, #1
+ ands ip, r1, #3
+ strneb r1, [ip] @ assert word-aligned
+ and r3, r0, #31
+ mov r0, r0, lsr #5
save_and_disable_irqs ip
- ldrb r2, [r1]
+ ldr r2, [r1, r0, lsl #2]!
+ mov r0, #1
tst r2, r0, lsl r3
\instr r2, r2, r0, lsl r3
\store r2, [r1]
diff --git a/arch/arm/lib/changebit.S b/arch/arm/lib/changebit.S
index 80f3115cbee..68ed5b62e83 100644
--- a/arch/arm/lib/changebit.S
+++ b/arch/arm/lib/changebit.S
@@ -12,12 +12,6 @@
#include "bitops.h"
.text
-/* Purpose : Function to change a bit
- * Prototype: int change_bit(int bit, void *addr)
- */
-ENTRY(_change_bit_be)
- eor r0, r0, #0x18 @ big endian byte ordering
-ENTRY(_change_bit_le)
+ENTRY(_change_bit)
bitop eor
-ENDPROC(_change_bit_be)
-ENDPROC(_change_bit_le)
+ENDPROC(_change_bit)
diff --git a/arch/arm/lib/clearbit.S b/arch/arm/lib/clearbit.S
index 1a63e43a1df..4c04c3b51ee 100644
--- a/arch/arm/lib/clearbit.S
+++ b/arch/arm/lib/clearbit.S
@@ -12,13 +12,6 @@
#include "bitops.h"
.text
-/*
- * Purpose : Function to clear a bit
- * Prototype: int clear_bit(int bit, void *addr)
- */
-ENTRY(_clear_bit_be)
- eor r0, r0, #0x18 @ big endian byte ordering
-ENTRY(_clear_bit_le)
+ENTRY(_clear_bit)
bitop bic
-ENDPROC(_clear_bit_be)
-ENDPROC(_clear_bit_le)
+ENDPROC(_clear_bit)
diff --git a/arch/arm/lib/setbit.S b/arch/arm/lib/setbit.S
index 1dd7176c4b2..bbee5c66a23 100644
--- a/arch/arm/lib/setbit.S
+++ b/arch/arm/lib/setbit.S
@@ -12,13 +12,6 @@
#include "bitops.h"
.text
-/*
- * Purpose : Function to set a bit
- * Prototype: int set_bit(int bit, void *addr)
- */
-ENTRY(_set_bit_be)
- eor r0, r0, #0x18 @ big endian byte ordering
-ENTRY(_set_bit_le)
+ENTRY(_set_bit)
bitop orr
-ENDPROC(_set_bit_be)
-ENDPROC(_set_bit_le)
+ENDPROC(_set_bit)
diff --git a/arch/arm/lib/testchangebit.S b/arch/arm/lib/testchangebit.S
index 5c98dc567f0..15a4d431f22 100644
--- a/arch/arm/lib/testchangebit.S
+++ b/arch/arm/lib/testchangebit.S
@@ -12,9 +12,6 @@
#include "bitops.h"
.text
-ENTRY(_test_and_change_bit_be)
- eor r0, r0, #0x18 @ big endian byte ordering
-ENTRY(_test_and_change_bit_le)
- testop eor, strb
-ENDPROC(_test_and_change_bit_be)
-ENDPROC(_test_and_change_bit_le)
+ENTRY(_test_and_change_bit)
+ testop eor, str
+ENDPROC(_test_and_change_bit)
diff --git a/arch/arm/lib/testclearbit.S b/arch/arm/lib/testclearbit.S
index 543d7094d18..521b66b5b95 100644
--- a/arch/arm/lib/testclearbit.S
+++ b/arch/arm/lib/testclearbit.S
@@ -12,9 +12,6 @@
#include "bitops.h"
.text
-ENTRY(_test_and_clear_bit_be)
- eor r0, r0, #0x18 @ big endian byte ordering
-ENTRY(_test_and_clear_bit_le)
- testop bicne, strneb
-ENDPROC(_test_and_clear_bit_be)
-ENDPROC(_test_and_clear_bit_le)
+ENTRY(_test_and_clear_bit)
+ testop bicne, strne
+ENDPROC(_test_and_clear_bit)
diff --git a/arch/arm/lib/testsetbit.S b/arch/arm/lib/testsetbit.S
index 0b3f390401c..1c98cc2185b 100644
--- a/arch/arm/lib/testsetbit.S
+++ b/arch/arm/lib/testsetbit.S
@@ -12,9 +12,6 @@
#include "bitops.h"
.text
-ENTRY(_test_and_set_bit_be)
- eor r0, r0, #0x18 @ big endian byte ordering
-ENTRY(_test_and_set_bit_le)
- testop orreq, streqb
-ENDPROC(_test_and_set_bit_be)
-ENDPROC(_test_and_set_bit_le)
+ENTRY(_test_and_set_bit)
+ testop orreq, streq
+ENDPROC(_test_and_set_bit)
diff --git a/arch/arm/mach-aaec2000/include/mach/memory.h b/arch/arm/mach-aaec2000/include/mach/memory.h
index 4f93c567a35..4a10bf0bd36 100644
--- a/arch/arm/mach-aaec2000/include/mach/memory.h
+++ b/arch/arm/mach-aaec2000/include/mach/memory.h
@@ -12,6 +12,6 @@
#define __ASM_ARCH_MEMORY_H
-#define PHYS_OFFSET UL(0xf0000000)
+#define PLAT_PHYS_OFFSET UL(0xf0000000)
#endif /* __ASM_ARCH_MEMORY_H */
diff --git a/arch/arm/mach-at91/include/mach/memory.h b/arch/arm/mach-at91/include/mach/memory.h
index 14f4ef4b6a9..c2cfe504064 100644
--- a/arch/arm/mach-at91/include/mach/memory.h
+++ b/arch/arm/mach-at91/include/mach/memory.h
@@ -23,6 +23,6 @@
#include <mach/hardware.h>
-#define PHYS_OFFSET (AT91_SDRAM_BASE)
+#define PLAT_PHYS_OFFSET (AT91_SDRAM_BASE)
#endif
diff --git a/arch/arm/mach-bcmring/include/mach/hardware.h b/arch/arm/mach-bcmring/include/mach/hardware.h
index 447eb340c61..8bf3564fba5 100644
--- a/arch/arm/mach-bcmring/include/mach/hardware.h
+++ b/arch/arm/mach-bcmring/include/mach/hardware.h
@@ -31,7 +31,7 @@
* *_SIZE is the size of the region
* *_BASE is the virtual address
*/
-#define RAM_START PHYS_OFFSET
+#define RAM_START PLAT_PHYS_OFFSET
#define RAM_SIZE (CFG_GLOBAL_RAM_SIZE-CFG_GLOBAL_RAM_SIZE_RESERVED)
#define RAM_BASE PAGE_OFFSET
diff --git a/arch/arm/mach-bcmring/include/mach/memory.h b/arch/arm/mach-bcmring/include/mach/memory.h
index 114f942bb4f..15162e4c75f 100644
--- a/arch/arm/mach-bcmring/include/mach/memory.h
+++ b/arch/arm/mach-bcmring/include/mach/memory.h
@@ -23,7 +23,7 @@
* files. Use virt_to_phys/phys_to_virt/__pa/__va instead.
*/
-#define PHYS_OFFSET CFG_GLOBAL_RAM_BASE
+#define PLAT_PHYS_OFFSET CFG_GLOBAL_RAM_BASE
/*
* Maximum DMA memory allowed is 14M
diff --git a/arch/arm/mach-clps711x/include/mach/memory.h b/arch/arm/mach-clps711x/include/mach/memory.h
index f45c8e892cb..3a032a67725 100644
--- a/arch/arm/mach-clps711x/include/mach/memory.h
+++ b/arch/arm/mach-clps711x/include/mach/memory.h
@@ -23,7 +23,7 @@
/*
* Physical DRAM offset.
*/
-#define PHYS_OFFSET UL(0xc0000000)
+#define PLAT_PHYS_OFFSET UL(0xc0000000)
#if !defined(CONFIG_ARCH_CDB89712) && !defined (CONFIG_ARCH_AUTCPU12)
diff --git a/arch/arm/mach-cns3xxx/include/mach/memory.h b/arch/arm/mach-cns3xxx/include/mach/memory.h
index 3b6b769b7a2..dc16c5c5d86 100644
--- a/arch/arm/mach-cns3xxx/include/mach/memory.h
+++ b/arch/arm/mach-cns3xxx/include/mach/memory.h
@@ -13,7 +13,7 @@
/*
* Physical DRAM offset.
*/
-#define PHYS_OFFSET UL(0x00000000)
+#define PLAT_PHYS_OFFSET UL(0x00000000)
#define __phys_to_bus(x) ((x) + PHYS_OFFSET)
#define __bus_to_phys(x) ((x) - PHYS_OFFSET)
diff --git a/arch/arm/mach-davinci/include/mach/memory.h b/arch/arm/mach-davinci/include/mach/memory.h
index 22eb97c1c30..78822723f38 100644
--- a/arch/arm/mach-davinci/include/mach/memory.h
+++ b/arch/arm/mach-davinci/include/mach/memory.h
@@ -26,9 +26,9 @@
#if defined(CONFIG_ARCH_DAVINCI_DA8XX) && defined(CONFIG_ARCH_DAVINCI_DMx)
#error Cannot enable DaVinci and DA8XX platforms concurrently
#elif defined(CONFIG_ARCH_DAVINCI_DA8XX)
-#define PHYS_OFFSET DA8XX_DDR_BASE
+#define PLAT_PHYS_OFFSET DA8XX_DDR_BASE
#else
-#define PHYS_OFFSET DAVINCI_DDR_BASE
+#define PLAT_PHYS_OFFSET DAVINCI_DDR_BASE
#endif
#define DDR2_SDRCR_OFFSET 0xc
diff --git a/arch/arm/mach-dove/Kconfig b/arch/arm/mach-dove/Kconfig
index a4ed3900912..dd937c526a4 100644
--- a/arch/arm/mach-dove/Kconfig
+++ b/arch/arm/mach-dove/Kconfig
@@ -9,7 +9,7 @@ config MACH_DOVE_DB
Say 'Y' here if you want your kernel to support the
Marvell DB-MV88AP510 Development Board.
- config MACH_CM_A510
+config MACH_CM_A510
bool "CompuLab CM-A510 Board"
help
Say 'Y' here if you want your kernel to support the
diff --git a/arch/arm/mach-dove/include/mach/memory.h b/arch/arm/mach-dove/include/mach/memory.h
index d6687207494..bbc93fee6c7 100644
--- a/arch/arm/mach-dove/include/mach/memory.h
+++ b/arch/arm/mach-dove/include/mach/memory.h
@@ -5,6 +5,6 @@
#ifndef __ASM_ARCH_MEMORY_H
#define __ASM_ARCH_MEMORY_H
-#define PHYS_OFFSET UL(0x00000000)
+#define PLAT_PHYS_OFFSET UL(0x00000000)
#endif
diff --git a/arch/arm/mach-ebsa110/include/mach/memory.h b/arch/arm/mach-ebsa110/include/mach/memory.h
index 0ca66d080c6..8e49066ad85 100644
--- a/arch/arm/mach-ebsa110/include/mach/memory.h
+++ b/arch/arm/mach-ebsa110/include/mach/memory.h
@@ -19,7 +19,7 @@
/*
* Physical DRAM offset.
*/
-#define PHYS_OFFSET UL(0x00000000)
+#define PLAT_PHYS_OFFSET UL(0x00000000)
/*
* Cache flushing area - SRAM
diff --git a/arch/arm/mach-ep93xx/include/mach/memory.h b/arch/arm/mach-ep93xx/include/mach/memory.h
index 554064e9030..c9400cf0051 100644
--- a/arch/arm/mach-ep93xx/include/mach/memory.h
+++ b/arch/arm/mach-ep93xx/include/mach/memory.h
@@ -6,15 +6,15 @@
#define __ASM_ARCH_MEMORY_H
#if defined(CONFIG_EP93XX_SDCE3_SYNC_PHYS_OFFSET)
-#define PHYS_OFFSET UL(0x00000000)
+#define PLAT_PHYS_OFFSET UL(0x00000000)
#elif defined(CONFIG_EP93XX_SDCE0_PHYS_OFFSET)
-#define PHYS_OFFSET UL(0xc0000000)
+#define PLAT_PHYS_OFFSET UL(0xc0000000)
#elif defined(CONFIG_EP93XX_SDCE1_PHYS_OFFSET)
-#define PHYS_OFFSET UL(0xd0000000)
+#define PLAT_PHYS_OFFSET UL(0xd0000000)
#elif defined(CONFIG_EP93XX_SDCE2_PHYS_OFFSET)
-#define PHYS_OFFSET UL(0xe0000000)
+#define PLAT_PHYS_OFFSET UL(0xe0000000)
#elif defined(CONFIG_EP93XX_SDCE3_ASYNC_PHYS_OFFSET)
-#define PHYS_OFFSET UL(0xf0000000)
+#define PLAT_PHYS_OFFSET UL(0xf0000000)
#else
#error "Kconfig bug: No EP93xx PHYS_OFFSET set"
#endif
diff --git a/arch/arm/mach-footbridge/include/mach/memory.h b/arch/arm/mach-footbridge/include/mach/memory.h
index 8d64f457408..5c6df377f96 100644
--- a/arch/arm/mach-footbridge/include/mach/memory.h
+++ b/arch/arm/mach-footbridge/include/mach/memory.h
@@ -62,7 +62,7 @@ extern unsigned long __bus_to_pfn(unsigned long);
/*
* Physical DRAM offset.
*/
-#define PHYS_OFFSET UL(0x00000000)
+#define PLAT_PHYS_OFFSET UL(0x00000000)
#define FLUSH_BASE_PHYS 0x50000000
diff --git a/arch/arm/mach-gemini/include/mach/memory.h b/arch/arm/mach-gemini/include/mach/memory.h
index 2d14d5bf1f9..a50915f764d 100644
--- a/arch/arm/mach-gemini/include/mach/memory.h
+++ b/arch/arm/mach-gemini/include/mach/memory.h
@@ -11,9 +11,9 @@
#define __MACH_MEMORY_H
#ifdef CONFIG_GEMINI_MEM_SWAP
-# define PHYS_OFFSET UL(0x00000000)
+# define PLAT_PHYS_OFFSET UL(0x00000000)
#else
-# define PHYS_OFFSET UL(0x10000000)
+# define PLAT_PHYS_OFFSET UL(0x10000000)
#endif
#endif /* __MACH_MEMORY_H */
diff --git a/arch/arm/mach-h720x/include/mach/memory.h b/arch/arm/mach-h720x/include/mach/memory.h
index ef4c1e26f18..9d368765146 100644
--- a/arch/arm/mach-h720x/include/mach/memory.h
+++ b/arch/arm/mach-h720x/include/mach/memory.h
@@ -7,7 +7,7 @@
#ifndef __ASM_ARCH_MEMORY_H
#define __ASM_ARCH_MEMORY_H
-#define PHYS_OFFSET UL(0x40000000)
+#define PLAT_PHYS_OFFSET UL(0x40000000)
/*
* This is the maximum DMA address that can be DMAd to.
* There should not be more than (0xd0000000 - 0xc0000000)
diff --git a/arch/arm/mach-integrator/include/mach/memory.h b/arch/arm/mach-integrator/include/mach/memory.h
index 991f24d2c11..334d5e27188 100644
--- a/arch/arm/mach-integrator/include/mach/memory.h
+++ b/arch/arm/mach-integrator/include/mach/memory.h
@@ -23,7 +23,7 @@
/*
* Physical DRAM offset.
*/
-#define PHYS_OFFSET UL(0x00000000)
+#define PLAT_PHYS_OFFSET UL(0x00000000)
#define BUS_OFFSET UL(0x80000000)
#define __virt_to_bus(x) ((x) - PAGE_OFFSET + BUS_OFFSET)
diff --git a/arch/arm/mach-iop13xx/include/mach/memory.h b/arch/arm/mach-iop13xx/include/mach/memory.h
index 3ad45531886..1afa99ef97f 100644
--- a/arch/arm/mach-iop13xx/include/mach/memory.h
+++ b/arch/arm/mach-iop13xx/include/mach/memory.h
@@ -6,7 +6,7 @@
/*
* Physical DRAM offset.
*/
-#define PHYS_OFFSET UL(0x00000000)
+#define PLAT_PHYS_OFFSET UL(0x00000000)
#ifndef __ASSEMBLY__
diff --git a/arch/arm/mach-iop32x/include/mach/memory.h b/arch/arm/mach-iop32x/include/mach/memory.h
index c30f6450ad5..169cc239f76 100644
--- a/arch/arm/mach-iop32x/include/mach/memory.h
+++ b/arch/arm/mach-iop32x/include/mach/memory.h
@@ -8,6 +8,6 @@
/*
* Physical DRAM offset.
*/
-#define PHYS_OFFSET UL(0xa0000000)
+#define PLAT_PHYS_OFFSET UL(0xa0000000)
#endif
diff --git a/arch/arm/mach-iop33x/include/mach/memory.h b/arch/arm/mach-iop33x/include/mach/memory.h
index a30a96aa6d2..8e1daf7006b 100644
--- a/arch/arm/mach-iop33x/include/mach/memory.h
+++ b/arch/arm/mach-iop33x/include/mach/memory.h
@@ -8,6 +8,6 @@
/*
* Physical DRAM offset.
*/
-#define PHYS_OFFSET UL(0x00000000)
+#define PLAT_PHYS_OFFSET UL(0x00000000)
#endif
diff --git a/arch/arm/mach-ixp2000/include/mach/memory.h b/arch/arm/mach-ixp2000/include/mach/memory.h
index 98e3471be15..5f0c4fd4076 100644
--- a/arch/arm/mach-ixp2000/include/mach/memory.h
+++ b/arch/arm/mach-ixp2000/include/mach/memory.h
@@ -13,7 +13,7 @@
#ifndef __ASM_ARCH_MEMORY_H
#define __ASM_ARCH_MEMORY_H
-#define PHYS_OFFSET UL(0x00000000)
+#define PLAT_PHYS_OFFSET UL(0x00000000)
#include <mach/ixp2000-regs.h>
diff --git a/arch/arm/mach-ixp23xx/include/mach/memory.h b/arch/arm/mach-ixp23xx/include/mach/memory.h
index 6ef65d813f1..6cf0704e946 100644
--- a/arch/arm/mach-ixp23xx/include/mach/memory.h
+++ b/arch/arm/mach-ixp23xx/include/mach/memory.h
@@ -17,7 +17,7 @@
/*
* Physical DRAM offset.
*/
-#define PHYS_OFFSET (0x00000000)
+#define PLAT_PHYS_OFFSET (0x00000000)
#define IXP23XX_PCI_SDRAM_OFFSET (*((volatile int *)IXP23XX_PCI_SDRAM_BAR) & 0xfffffff0)
diff --git a/arch/arm/mach-ixp4xx/include/mach/memory.h b/arch/arm/mach-ixp4xx/include/mach/memory.h
index 0136eaa2922..6d388c9d0e2 100644
--- a/arch/arm/mach-ixp4xx/include/mach/memory.h
+++ b/arch/arm/mach-ixp4xx/include/mach/memory.h
@@ -12,7 +12,7 @@
/*
* Physical DRAM offset.
*/
-#define PHYS_OFFSET UL(0x00000000)
+#define PLAT_PHYS_OFFSET UL(0x00000000)
#if !defined(__ASSEMBLY__) && defined(CONFIG_PCI)
diff --git a/arch/arm/mach-kirkwood/include/mach/memory.h b/arch/arm/mach-kirkwood/include/mach/memory.h
index 45431e13146..4600b44e3ad 100644
--- a/arch/arm/mach-kirkwood/include/mach/memory.h
+++ b/arch/arm/mach-kirkwood/include/mach/memory.h
@@ -5,6 +5,6 @@
#ifndef __ASM_ARCH_MEMORY_H
#define __ASM_ARCH_MEMORY_H
-#define PHYS_OFFSET UL(0x00000000)
+#define PLAT_PHYS_OFFSET UL(0x00000000)
#endif
diff --git a/arch/arm/mach-ks8695/include/mach/memory.h b/arch/arm/mach-ks8695/include/mach/memory.h
index bace9a681ad..f7e1b9bce34 100644
--- a/arch/arm/mach-ks8695/include/mach/memory.h
+++ b/arch/arm/mach-ks8695/include/mach/memory.h
@@ -18,7 +18,7 @@
/*
* Physical SRAM offset.
*/
-#define PHYS_OFFSET KS8695_SDRAM_PA
+#define PLAT_PHYS_OFFSET KS8695_SDRAM_PA
#ifndef __ASSEMBLY__
diff --git a/arch/arm/mach-lh7a40x/include/mach/memory.h b/arch/arm/mach-lh7a40x/include/mach/memory.h
index edb8f5faf5d..f77bde80fe4 100644
--- a/arch/arm/mach-lh7a40x/include/mach/memory.h
+++ b/arch/arm/mach-lh7a40x/include/mach/memory.h
@@ -17,7 +17,7 @@
/*
* Physical DRAM offset.
*/
-#define PHYS_OFFSET UL(0xc0000000)
+#define PLAT_PHYS_OFFSET UL(0xc0000000)
/*
* Sparsemem version of the above
diff --git a/arch/arm/mach-loki/include/mach/memory.h b/arch/arm/mach-loki/include/mach/memory.h
index 2ed7e6e732c..66366657a87 100644
--- a/arch/arm/mach-loki/include/mach/memory.h
+++ b/arch/arm/mach-loki/include/mach/memory.h
@@ -5,6 +5,6 @@
#ifndef __ASM_ARCH_MEMORY_H
#define __ASM_ARCH_MEMORY_H
-#define PHYS_OFFSET UL(0x00000000)
+#define PLAT_PHYS_OFFSET UL(0x00000000)
#endif
diff --git a/arch/arm/mach-lpc32xx/include/mach/memory.h b/arch/arm/mach-lpc32xx/include/mach/memory.h
index 044e1acecbe..a647dd624af 100644
--- a/arch/arm/mach-lpc32xx/include/mach/memory.h
+++ b/arch/arm/mach-lpc32xx/include/mach/memory.h
@@ -22,6 +22,6 @@
/*
* Physical DRAM offset of bank 0
*/
-#define PHYS_OFFSET UL(0x80000000)
+#define PLAT_PHYS_OFFSET UL(0x80000000)
#endif
diff --git a/arch/arm/mach-mmp/include/mach/memory.h b/arch/arm/mach-mmp/include/mach/memory.h
index bdb21d70714..d68b50a2d6a 100644
--- a/arch/arm/mach-mmp/include/mach/memory.h
+++ b/arch/arm/mach-mmp/include/mach/memory.h
@@ -9,6 +9,6 @@
#ifndef __ASM_MACH_MEMORY_H
#define __ASM_MACH_MEMORY_H
-#define PHYS_OFFSET UL(0x00000000)
+#define PLAT_PHYS_OFFSET UL(0x00000000)
#endif /* __ASM_MACH_MEMORY_H */
diff --git a/arch/arm/mach-msm/board-msm7x27.c b/arch/arm/mach-msm/board-msm7x27.c
index e7a76eff57d..08fcd40a8cb 100644
--- a/arch/arm/mach-msm/board-msm7x27.c
+++ b/arch/arm/mach-msm/board-msm7x27.c
@@ -132,7 +132,7 @@ static void __init msm7x2x_map_io(void)
MACHINE_START(MSM7X27_SURF, "QCT MSM7x27 SURF")
#ifdef CONFIG_MSM_DEBUG_UART
#endif
- .boot_params = PHYS_OFFSET + 0x100,
+ .boot_params = PLAT_PHYS_OFFSET + 0x100,
.map_io = msm7x2x_map_io,
.init_irq = msm7x2x_init_irq,
.init_machine = msm7x2x_init,
@@ -142,7 +142,7 @@ MACHINE_END
MACHINE_START(MSM7X27_FFA, "QCT MSM7x27 FFA")
#ifdef CONFIG_MSM_DEBUG_UART
#endif
- .boot_params = PHYS_OFFSET + 0x100,
+ .boot_params = PLAT_PHYS_OFFSET + 0x100,
.map_io = msm7x2x_map_io,
.init_irq = msm7x2x_init_irq,
.init_machine = msm7x2x_init,
@@ -152,7 +152,7 @@ MACHINE_END
MACHINE_START(MSM7X25_SURF, "QCT MSM7x25 SURF")
#ifdef CONFIG_MSM_DEBUG_UART
#endif
- .boot_params = PHYS_OFFSET + 0x100,
+ .boot_params = PLAT_PHYS_OFFSET + 0x100,
.map_io = msm7x2x_map_io,
.init_irq = msm7x2x_init_irq,
.init_machine = msm7x2x_init,
@@ -162,7 +162,7 @@ MACHINE_END
MACHINE_START(MSM7X25_FFA, "QCT MSM7x25 FFA")
#ifdef CONFIG_MSM_DEBUG_UART
#endif
- .boot_params = PHYS_OFFSET + 0x100,
+ .boot_params = PLAT_PHYS_OFFSET + 0x100,
.map_io = msm7x2x_map_io,
.init_irq = msm7x2x_init_irq,
.init_machine = msm7x2x_init,
diff --git a/arch/arm/mach-msm/board-msm7x30.c b/arch/arm/mach-msm/board-msm7x30.c
index 6f3b9735e97..25db8fd71a7 100644
--- a/arch/arm/mach-msm/board-msm7x30.c
+++ b/arch/arm/mach-msm/board-msm7x30.c
@@ -26,11 +26,11 @@
#include <asm/mach-types.h>
#include <asm/mach/arch.h>
+#include <asm/memory.h>
#include <asm/setup.h>
#include <mach/gpio.h>
#include <mach/board.h>
-#include <mach/memory.h>
#include <mach/msm_iomap.h>
#include <mach/dma.h>
@@ -85,7 +85,7 @@ static void __init msm7x30_map_io(void)
MACHINE_START(MSM7X30_SURF, "QCT MSM7X30 SURF")
#ifdef CONFIG_MSM_DEBUG_UART
#endif
- .boot_params = PHYS_OFFSET + 0x100,
+ .boot_params = PLAT_PHYS_OFFSET + 0x100,
.map_io = msm7x30_map_io,
.init_irq = msm7x30_init_irq,
.init_machine = msm7x30_init,
@@ -95,7 +95,7 @@ MACHINE_END
MACHINE_START(MSM7X30_FFA, "QCT MSM7X30 FFA")
#ifdef CONFIG_MSM_DEBUG_UART
#endif
- .boot_params = PHYS_OFFSET + 0x100,
+ .boot_params = PLAT_PHYS_OFFSET + 0x100,
.map_io = msm7x30_map_io,
.init_irq = msm7x30_init_irq,
.init_machine = msm7x30_init,
@@ -105,7 +105,7 @@ MACHINE_END
MACHINE_START(MSM7X30_FLUID, "QCT MSM7X30 FLUID")
#ifdef CONFIG_MSM_DEBUG_UART
#endif
- .boot_params = PHYS_OFFSET + 0x100,
+ .boot_params = PLAT_PHYS_OFFSET + 0x100,
.map_io = msm7x30_map_io,
.init_irq = msm7x30_init_irq,
.init_machine = msm7x30_init,
diff --git a/arch/arm/mach-msm/board-qsd8x50.c b/arch/arm/mach-msm/board-qsd8x50.c
index 6dde8185205..15c2bbd2ef8 100644
--- a/arch/arm/mach-msm/board-qsd8x50.c
+++ b/arch/arm/mach-msm/board-qsd8x50.c
@@ -118,7 +118,7 @@ static void __init qsd8x50_init(void)
MACHINE_START(QSD8X50_SURF, "QCT QSD8X50 SURF")
#ifdef CONFIG_MSM_DEBUG_UART
#endif
- .boot_params = PHYS_OFFSET + 0x100,
+ .boot_params = PLAT_PHYS_OFFSET + 0x100,
.map_io = qsd8x50_map_io,
.init_irq = qsd8x50_init_irq,
.init_machine = qsd8x50_init,
@@ -128,7 +128,7 @@ MACHINE_END
MACHINE_START(QSD8X50A_ST1_5, "QCT QSD8X50A ST1.5")
#ifdef CONFIG_MSM_DEBUG_UART
#endif
- .boot_params = PHYS_OFFSET + 0x100,
+ .boot_params = PLAT_PHYS_OFFSET + 0x100,
.map_io = qsd8x50_map_io,
.init_irq = qsd8x50_init_irq,
.init_machine = qsd8x50_init,
diff --git a/arch/arm/mach-msm/board-sapphire.c b/arch/arm/mach-msm/board-sapphire.c
index 8919ffb1719..83604f526f0 100644
--- a/arch/arm/mach-msm/board-sapphire.c
+++ b/arch/arm/mach-msm/board-sapphire.c
@@ -107,7 +107,7 @@ MACHINE_START(SAPPHIRE, "sapphire")
/* Maintainer: Brian Swetland <swetland@google.com> */
#ifdef CONFIG_MSM_DEBUG_UART
#endif
- .boot_params = PHYS_OFFSET + 0x100,
+ .boot_params = PLAT_PHYS_OFFSET + 0x100,
.fixup = sapphire_fixup,
.map_io = sapphire_map_io,
.init_irq = sapphire_init_irq,
diff --git a/arch/arm/mach-msm/include/mach/memory.h b/arch/arm/mach-msm/include/mach/memory.h
index 070e17d237f..176875df241 100644
--- a/arch/arm/mach-msm/include/mach/memory.h
+++ b/arch/arm/mach-msm/include/mach/memory.h
@@ -18,15 +18,15 @@
/* physical offset of RAM */
#if defined(CONFIG_ARCH_QSD8X50) && defined(CONFIG_MSM_SOC_REV_A)
-#define PHYS_OFFSET UL(0x00000000)
+#define PLAT_PHYS_OFFSET UL(0x00000000)
#elif defined(CONFIG_ARCH_QSD8X50)
-#define PHYS_OFFSET UL(0x20000000)
+#define PLAT_PHYS_OFFSET UL(0x20000000)
#elif defined(CONFIG_ARCH_MSM7X30)
-#define PHYS_OFFSET UL(0x00200000)
+#define PLAT_PHYS_OFFSET UL(0x00200000)
#elif defined(CONFIG_ARCH_MSM8X60)
-#define PHYS_OFFSET UL(0x40200000)
+#define PLAT_PHYS_OFFSET UL(0x40200000)
#else
-#define PHYS_OFFSET UL(0x10000000)
+#define PLAT_PHYS_OFFSET UL(0x10000000)
#endif
#endif
diff --git a/arch/arm/mach-mv78xx0/include/mach/memory.h b/arch/arm/mach-mv78xx0/include/mach/memory.h
index e663042d307..a648c51f2e4 100644
--- a/arch/arm/mach-mv78xx0/include/mach/memory.h
+++ b/arch/arm/mach-mv78xx0/include/mach/memory.h
@@ -5,6 +5,6 @@
#ifndef __ASM_ARCH_MEMORY_H
#define __ASM_ARCH_MEMORY_H
-#define PHYS_OFFSET UL(0x00000000)
+#define PLAT_PHYS_OFFSET UL(0x00000000)
#endif
diff --git a/arch/arm/mach-mx3/mach-kzm_arm11_01.c b/arch/arm/mach-mx3/mach-kzm_arm11_01.c
index a5f3eb24e4d..df1a6ce8e3e 100644
--- a/arch/arm/mach-mx3/mach-kzm_arm11_01.c
+++ b/arch/arm/mach-mx3/mach-kzm_arm11_01.c
@@ -27,6 +27,7 @@
#include <asm/irq.h>
#include <asm/mach-types.h>
+#include <asm/memory.h>
#include <asm/setup.h>
#include <asm/mach/arch.h>
#include <asm/mach/irq.h>
@@ -36,7 +37,6 @@
#include <mach/clock.h>
#include <mach/common.h>
#include <mach/iomux-mx3.h>
-#include <mach/memory.h>
#include "devices-imx31.h"
#include "devices.h"
diff --git a/arch/arm/mach-mx5/clock-mx51-mx53.c b/arch/arm/mach-mx5/clock-mx51-mx53.c
index 0a19e7567c0..d8a65daa8be 100644
--- a/arch/arm/mach-mx5/clock-mx51-mx53.c
+++ b/arch/arm/mach-mx5/clock-mx51-mx53.c
@@ -464,7 +464,14 @@ static int _clk_main_bus_set_parent(struct clk *clk, struct clk *parent)
return 0;
}
+#ifdef CONFIG_CLK_DEBUG
+#define __INIT_CLK_DEBUG(n) .name = #n,
+#else
+#define __INIT_CLK_DEBUG(n)
+#endif
+
static struct clk main_bus_clk = {
+ __INIT_CLK_DEBUG(main_bus_clk)
.parent = &pll2_sw_clk,
.set_parent = _clk_main_bus_set_parent,
};
@@ -728,23 +735,28 @@ static unsigned long _clk_ddr_hf_get_rate(struct clk *clk)
/* External high frequency clock */
static struct clk ckih_clk = {
+ __INIT_CLK_DEBUG(ckih_clk)
.get_rate = get_high_reference_clock_rate,
};
static struct clk ckih2_clk = {
+ __INIT_CLK_DEBUG(ckih2_clk)
.get_rate = get_ckih2_reference_clock_rate,
};
static struct clk osc_clk = {
+ __INIT_CLK_DEBUG(osc_clk)
.get_rate = get_oscillator_reference_clock_rate,
};
/* External low frequency (32kHz) clock */
static struct clk ckil_clk = {
+ __INIT_CLK_DEBUG(ckil_clk)
.get_rate = get_low_reference_clock_rate,
};
static struct clk pll1_main_clk = {
+ __INIT_CLK_DEBUG(pll1_main_clk)
.parent = &osc_clk,
.get_rate = clk_pll_get_rate,
.enable = _clk_pll_enable,
@@ -762,6 +774,7 @@ static struct clk pll1_main_clk = {
/* PLL1 SW supplies to ARM core */
static struct clk pll1_sw_clk = {
+ __INIT_CLK_DEBUG(pll1_sw_clk)
.parent = &pll1_main_clk,
.set_parent = _clk_pll1_sw_set_parent,
.get_rate = clk_pll1_sw_get_rate,
@@ -769,6 +782,7 @@ static struct clk pll1_sw_clk = {
/* PLL2 SW supplies to AXI/AHB/IP buses */
static struct clk pll2_sw_clk = {
+ __INIT_CLK_DEBUG(pll2_sw_clk)
.parent = &osc_clk,
.get_rate = clk_pll_get_rate,
.set_rate = _clk_pll_set_rate,
@@ -779,6 +793,7 @@ static struct clk pll2_sw_clk = {
/* PLL3 SW supplies to serial clocks like USB, SSI, etc. */
static struct clk pll3_sw_clk = {
+ __INIT_CLK_DEBUG(pll3_sw_clk)
.parent = &osc_clk,
.set_rate = _clk_pll_set_rate,
.get_rate = clk_pll_get_rate,
@@ -788,6 +803,7 @@ static struct clk pll3_sw_clk = {
/* PLL4 SW supplies to LVDS Display Bridge(LDB) */
static struct clk mx53_pll4_sw_clk = {
+ __INIT_CLK_DEBUG(mx53_pll4_clk)
.parent = &osc_clk,
.set_rate = _clk_pll_set_rate,
.enable = _clk_pll_enable,
@@ -796,22 +812,26 @@ static struct clk mx53_pll4_sw_clk = {
/* Low-power Audio Playback Mode clock */
static struct clk lp_apm_clk = {
+ __INIT_CLK_DEBUG(lp_apm_clk)
.parent = &osc_clk,
.set_parent = _clk_lp_apm_set_parent,
};
static struct clk periph_apm_clk = {
+ __INIT_CLK_DEBUG(periph_apm_clk)
.parent = &pll1_sw_clk,
.set_parent = _clk_periph_apm_set_parent,
};
static struct clk cpu_clk = {
+ __INIT_CLK_DEBUG(cpu_clk)
.parent = &pll1_sw_clk,
.get_rate = clk_cpu_get_rate,
.set_rate = clk_cpu_set_rate,
};
static struct clk ahb_clk = {
+ __INIT_CLK_DEBUG(ahb_clk)
.parent = &main_bus_clk,
.get_rate = clk_ahb_get_rate,
.set_rate = _clk_ahb_set_rate,
@@ -819,6 +839,7 @@ static struct clk ahb_clk = {
};
static struct clk iim_clk = {
+ __INIT_CLK_DEBUG(iim_clk)
.parent = &ipg_clk,
.enable_reg = MXC_CCM_CCGR0,
.enable_shift = MXC_CCM_CCGRx_CG15_OFFSET,
@@ -826,17 +847,20 @@ static struct clk iim_clk = {
/* Main IP interface clock for access to registers */
static struct clk ipg_clk = {
+ __INIT_CLK_DEBUG(ipg_clk)
.parent = &ahb_clk,
.get_rate = clk_ipg_get_rate,
};
static struct clk ipg_perclk = {
+ __INIT_CLK_DEBUG(ipg_clk)
.parent = &lp_apm_clk,
.get_rate = clk_ipg_per_get_rate,
.set_parent = _clk_ipg_per_set_parent,
};
static struct clk ahb_max_clk = {
+ __INIT_CLK_DEBUG(ahb_max_clk)
.parent = &ahb_clk,
.enable_reg = MXC_CCM_CCGR0,
.enable_shift = MXC_CCM_CCGRx_CG14_OFFSET,
@@ -845,6 +869,7 @@ static struct clk ahb_max_clk = {
};
static struct clk aips_tz1_clk = {
+ __INIT_CLK_DEBUG(aips_tz1_clk)
.parent = &ahb_clk,
.secondary = &ahb_max_clk,
.enable_reg = MXC_CCM_CCGR0,
@@ -854,6 +879,7 @@ static struct clk aips_tz1_clk = {
};
static struct clk aips_tz2_clk = {
+ __INIT_CLK_DEBUG(aips_tz2_clk)
.parent = &ahb_clk,
.secondary = &ahb_max_clk,
.enable_reg = MXC_CCM_CCGR0,
@@ -863,11 +889,13 @@ static struct clk aips_tz2_clk = {
};
static struct clk gpt_32k_clk = {
+ __INIT_CLK_DEBUG(gpt_32k_clk)
.id = 0,
.parent = &ckil_clk,
};
static struct clk kpp_clk = {
+ __INIT_CLK_DEBUG(kpp_clk)
.id = 0,
};
@@ -876,6 +904,7 @@ static struct clk dummy_clk = {
};
static struct clk emi_slow_clk = {
+ __INIT_CLK_DEBUG(emi_slow_clk)
.parent = &pll2_sw_clk,
.enable_reg = MXC_CCM_CCGR5,
.enable_shift = MXC_CCM_CCGRx_CG8_OFFSET,
@@ -989,6 +1018,7 @@ static struct clk mipi_hsp_clk = {
#define DEFINE_CLOCK_CCGR(name, i, er, es, pfx, p, s) \
static struct clk name = { \
+ __INIT_CLK_DEBUG(name) \
.id = i, \
.enable_reg = er, \
.enable_shift = es, \
@@ -1004,6 +1034,7 @@ static struct clk mipi_hsp_clk = {
#define DEFINE_CLOCK_MAX(name, i, er, es, pfx, p, s) \
static struct clk name = { \
+ __INIT_CLK_DEBUG(name) \
.id = i, \
.enable_reg = er, \
.enable_shift = es, \
@@ -1082,6 +1113,7 @@ CLK_GET_RATE(uart, 1, UART)
CLK_SET_PARENT(uart, 1, UART)
static struct clk uart_root_clk = {
+ __INIT_CLK_DEBUG(uart_root_clk)
.parent = &pll2_sw_clk,
.get_rate = clk_uart_get_rate,
.set_parent = clk_uart_set_parent,
@@ -1092,6 +1124,7 @@ CLK_GET_RATE(usboh3, 1, USBOH3)
CLK_SET_PARENT(usboh3, 1, USBOH3)
static struct clk usboh3_clk = {
+ __INIT_CLK_DEBUG(usboh3_clk)
.parent = &pll2_sw_clk,
.get_rate = clk_usboh3_get_rate,
.set_parent = clk_usboh3_set_parent,
@@ -1137,6 +1170,7 @@ CLK_GET_RATE(ecspi, 2, CSPI)
CLK_SET_PARENT(ecspi, 1, CSPI)
static struct clk ecspi_main_clk = {
+ __INIT_CLK_DEBUG(ecspi_main_clk)
.parent = &pll3_sw_clk,
.get_rate = clk_ecspi_get_rate,
.set_parent = clk_ecspi_set_parent,
@@ -1152,7 +1186,8 @@ CLK_SET_PARENT(esdhc2, 1, ESDHC2_MSHC2)
CLK_SET_RATE(esdhc2, 1, ESDHC2_MSHC2)
#define DEFINE_CLOCK_FULL(name, i, er, es, gr, sr, e, d, p, s) \
- static struct clk name = { \
+static struct clk name = { \
+ __INIT_CLK_DEBUG(name) \
.id = i, \
.enable_reg = er, \
.enable_shift = es, \
@@ -1372,8 +1407,10 @@ int __init mx51_clocks_init(unsigned long ckil, unsigned long osc,
ckih2_reference = ckih2;
oscillator_reference = osc;
- for (i = 0; i < ARRAY_SIZE(mx51_lookups); i++)
+ for (i = 0; i < ARRAY_SIZE(mx51_lookups); i++) {
clkdev_add(&mx51_lookups[i]);
+ clk_debug_register(mx51_lookups[i].clk);
+ }
clk_tree_init();
diff --git a/arch/arm/mach-netx/include/mach/memory.h b/arch/arm/mach-netx/include/mach/memory.h
index 9a363f297f9..59561496c36 100644
--- a/arch/arm/mach-netx/include/mach/memory.h
+++ b/arch/arm/mach-netx/include/mach/memory.h
@@ -20,7 +20,7 @@
#ifndef __ASM_ARCH_MEMORY_H
#define __ASM_ARCH_MEMORY_H
-#define PHYS_OFFSET UL(0x80000000)
+#define PLAT_PHYS_OFFSET UL(0x80000000)
#endif
diff --git a/arch/arm/mach-nomadik/include/mach/memory.h b/arch/arm/mach-nomadik/include/mach/memory.h
index 1e5689d98ec..d3325211ba6 100644
--- a/arch/arm/mach-nomadik/include/mach/memory.h
+++ b/arch/arm/mach-nomadik/include/mach/memory.h
@@ -23,6 +23,6 @@
/*
* Physical DRAM offset.
*/
-#define PHYS_OFFSET UL(0x00000000)
+#define PLAT_PHYS_OFFSET UL(0x00000000)
#endif
diff --git a/arch/arm/mach-ns9xxx/include/mach/memory.h b/arch/arm/mach-ns9xxx/include/mach/memory.h
index 6107193adbf..5c65aee6e7a 100644
--- a/arch/arm/mach-ns9xxx/include/mach/memory.h
+++ b/arch/arm/mach-ns9xxx/include/mach/memory.h
@@ -19,6 +19,6 @@
#define NS9XXX_CS2STAT_LENGTH UL(0x1000)
#define NS9XXX_CS3STAT_LENGTH UL(0x1000)
-#define PHYS_OFFSET UL(0x00000000)
+#define PLAT_PHYS_OFFSET UL(0x00000000)
#endif
diff --git a/arch/arm/mach-nuc93x/include/mach/memory.h b/arch/arm/mach-nuc93x/include/mach/memory.h
index 323ab0db3f7..ef9864b002a 100644
--- a/arch/arm/mach-nuc93x/include/mach/memory.h
+++ b/arch/arm/mach-nuc93x/include/mach/memory.h
@@ -16,6 +16,6 @@
#ifndef __ASM_ARCH_MEMORY_H
#define __ASM_ARCH_MEMORY_H
-#define PHYS_OFFSET UL(0x00000000)
+#define PLAT_PHYS_OFFSET UL(0x00000000)
#endif
diff --git a/arch/arm/mach-omap1/Makefile b/arch/arm/mach-omap1/Makefile
index ba6009f2767..cb2d3a64858 100644
--- a/arch/arm/mach-omap1/Makefile
+++ b/arch/arm/mach-omap1/Makefile
@@ -10,6 +10,9 @@ obj-$(CONFIG_OMAP_MCBSP) += mcbsp.o
obj-$(CONFIG_OMAP_32K_TIMER) += timer32k.o
+# CPUFREQ driver
+obj-$(CONFIG_CPU_FREQ) += omap1-cpufreq.o
+
# Power Management
obj-$(CONFIG_PM) += pm.o sleep.o pm_bus.o
diff --git a/arch/arm/mach-omap1/include/mach/debug-macro.S b/arch/arm/mach-omap1/include/mach/debug-macro.S
index 6a0fa046236..62856044eb6 100644
--- a/arch/arm/mach-omap1/include/mach/debug-macro.S
+++ b/arch/arm/mach-omap1/include/mach/debug-macro.S
@@ -17,6 +17,9 @@
#include <plat/serial.h>
+#define omap_uart_v2p(x) ((x) - PAGE_OFFSET + PLAT_PHYS_OFFSET)
+#define omap_uart_p2v(x) ((x) - PLAT_PHYS_OFFSET + PAGE_OFFSET)
+
.pushsection .data
omap_uart_phys: .word 0x0
omap_uart_virt: .word 0x0
@@ -33,7 +36,7 @@ omap_uart_virt: .word 0x0
/* Use omap_uart_phys/virt if already configured */
9: mrc p15, 0, \rp, c1, c0
tst \rp, #1 @ MMU enabled?
- ldreq \rp, =__virt_to_phys(omap_uart_phys) @ MMU not enabled
+ ldreq \rp, =omap_uart_v2p(omap_uart_phys) @ MMU disabled
ldrne \rp, =omap_uart_phys @ MMU enabled
add \rv, \rp, #4 @ omap_uart_virt
ldr \rp, [\rp, #0]
@@ -46,7 +49,7 @@ omap_uart_virt: .word 0x0
mrc p15, 0, \rp, c1, c0
tst \rp, #1 @ MMU enabled?
ldreq \rp, =OMAP_UART_INFO @ MMU not enabled
- ldrne \rp, =__phys_to_virt(OMAP_UART_INFO) @ MMU enabled
+ ldrne \rp, =omap_uart_p2v(OMAP_UART_INFO) @ MMU enabled
ldr \rp, [\rp, #0]
/* Select the UART to use based on the UART1 scratchpad value */
@@ -73,7 +76,7 @@ omap_uart_virt: .word 0x0
98: add \rp, \rp, #0xff000000 @ phys base
mrc p15, 0, \rv, c1, c0
tst \rv, #1 @ MMU enabled?
- ldreq \rv, =__virt_to_phys(omap_uart_phys) @ MMU not enabled
+ ldreq \rv, =omap_uart_v2p(omap_uart_phys) @ MMU disabled
ldrne \rv, =omap_uart_phys @ MMU enabled
str \rp, [\rv, #0]
sub \rp, \rp, #0xff000000 @ phys base
diff --git a/arch/arm/mach-omap1/omap1-cpufreq.c b/arch/arm/mach-omap1/omap1-cpufreq.c
new file mode 100644
index 00000000000..64faf3f28d9
--- /dev/null
+++ b/arch/arm/mach-omap1/omap1-cpufreq.c
@@ -0,0 +1,176 @@
+/*
+ * OMAP1 cpufreq driver
+ *
+ * CPU frequency scaling for OMAP
+ *
+ * Copyright (C) 2005 Nokia Corporation
+ * Written by Tony Lindgren <tony@atomide.com>
+ *
+ * Based on cpu-sa1110.c, Copyright (C) 2001 Russell King
+ *
+ * Copyright (C) 2007-2008 Texas Instruments, Inc.
+ * Updated to support OMAP3
+ * Rajendra Nayak <rnayak@ti.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+#include <linux/types.h>
+#include <linux/kernel.h>
+#include <linux/sched.h>
+#include <linux/cpufreq.h>
+#include <linux/delay.h>
+#include <linux/init.h>
+#include <linux/err.h>
+#include <linux/clk.h>
+#include <linux/io.h>
+#include <linux/opp.h>
+
+#include <asm/system.h>
+
+#include <plat/clock.h>
+#include <plat/omap-pm.h>
+
+#include <mach/hardware.h>
+
+#define VERY_HI_RATE 900000000
+
+static struct cpufreq_frequency_table *freq_table;
+static struct clk *mpu_clk;
+
+static int omap_verify_speed(struct cpufreq_policy *policy)
+{
+ if (freq_table)
+ return cpufreq_frequency_table_verify(policy, freq_table);
+
+ if (policy->cpu)
+ return -EINVAL;
+
+ cpufreq_verify_within_limits(policy, policy->cpuinfo.min_freq,
+ policy->cpuinfo.max_freq);
+
+ policy->min = clk_round_rate(mpu_clk, policy->min * 1000) / 1000;
+ policy->max = clk_round_rate(mpu_clk, policy->max * 1000) / 1000;
+ cpufreq_verify_within_limits(policy, policy->cpuinfo.min_freq,
+ policy->cpuinfo.max_freq);
+ return 0;
+}
+
+static unsigned int omap_getspeed(unsigned int cpu)
+{
+ unsigned long rate;
+
+ if (cpu)
+ return 0;
+
+ rate = clk_get_rate(mpu_clk) / 1000;
+ return rate;
+}
+
+static int omap_target(struct cpufreq_policy *policy,
+ unsigned int target_freq,
+ unsigned int relation)
+{
+ struct cpufreq_freqs freqs;
+ int ret = 0;
+
+ /* Ensure desired rate is within allowed range. Some govenors
+ * (ondemand) will just pass target_freq=0 to get the minimum. */
+ if (target_freq < policy->min)
+ target_freq = policy->min;
+ if (target_freq > policy->max)
+ target_freq = policy->max;
+
+ freqs.old = omap_getspeed(0);
+ freqs.new = clk_round_rate(mpu_clk, target_freq * 1000) / 1000;
+ freqs.cpu = 0;
+
+ if (freqs.old == freqs.new)
+ return ret;
+
+ cpufreq_notify_transition(&freqs, CPUFREQ_PRECHANGE);
+
+#ifdef CONFIG_CPU_FREQ_DEBUG
+ pr_info("cpufreq-omap: transition: %u --> %u\n", freqs.old, freqs.new);
+#endif
+ ret = clk_set_rate(mpu_clk, freqs.new * 1000);
+ if (!ret)
+ cpufreq_notify_transition(&freqs, CPUFREQ_POSTCHANGE);
+
+ return ret;
+}
+
+static int __init omap_cpu_init(struct cpufreq_policy *policy)
+{
+ int result = 0;
+
+ mpu_clk = clk_get(NULL, "mpu");
+ if (IS_ERR(mpu_clk))
+ return PTR_ERR(mpu_clk);
+
+ if (policy->cpu != 0)
+ return -EINVAL;
+
+ policy->cur = policy->min = policy->max = omap_getspeed(0);
+
+ clk_init_cpufreq_table(&freq_table);
+
+ if (freq_table) {
+ result = cpufreq_frequency_table_cpuinfo(policy, freq_table);
+ if (!result)
+ cpufreq_frequency_table_get_attr(freq_table,
+ policy->cpu);
+ } else {
+ policy->cpuinfo.min_freq = clk_round_rate(mpu_clk, 0) / 1000;
+ policy->cpuinfo.max_freq = clk_round_rate(mpu_clk,
+ VERY_HI_RATE) / 1000;
+ }
+
+ policy->min = policy->cpuinfo.min_freq;
+ policy->max = policy->cpuinfo.max_freq;
+ policy->cur = omap_getspeed(0);
+
+ /* FIXME: what's the actual transition time? */
+ policy->cpuinfo.transition_latency = 300 * 1000;
+
+ return 0;
+}
+
+static int omap_cpu_exit(struct cpufreq_policy *policy)
+{
+ clk_exit_cpufreq_table(&freq_table);
+ clk_put(mpu_clk);
+ return 0;
+}
+
+static struct freq_attr *omap_cpufreq_attr[] = {
+ &cpufreq_freq_attr_scaling_available_freqs,
+ NULL,
+};
+
+static struct cpufreq_driver omap_driver = {
+ .flags = CPUFREQ_STICKY,
+ .verify = omap_verify_speed,
+ .target = omap_target,
+ .get = omap_getspeed,
+ .init = omap_cpu_init,
+ .exit = omap_cpu_exit,
+ .name = "omap1",
+ .attr = omap_cpufreq_attr,
+};
+
+static int __init omap_cpufreq_init(void)
+{
+ return cpufreq_register_driver(&omap_driver);
+}
+
+static void __exit omap_cpufreq_exit(void)
+{
+ cpufreq_unregister_driver(&omap_driver);
+}
+
+MODULE_DESCRIPTION("cpufreq driver for OMAP1 SOCs");
+MODULE_LICENSE("GPL");
+module_init(omap_cpufreq_init);
+module_exit(omap_cpufreq_exit);
diff --git a/arch/arm/mach-omap1/pm.h b/arch/arm/mach-omap1/pm.h
index 56a647986ae..cd926dcb5e7 100644
--- a/arch/arm/mach-omap1/pm.h
+++ b/arch/arm/mach-omap1/pm.h
@@ -123,9 +123,9 @@ extern void allow_idle_sleep(void);
extern void omap1_pm_idle(void);
extern void omap1_pm_suspend(void);
-extern void omap7xx_cpu_suspend(unsigned short, unsigned short);
-extern void omap1510_cpu_suspend(unsigned short, unsigned short);
-extern void omap1610_cpu_suspend(unsigned short, unsigned short);
+extern void omap7xx_cpu_suspend(unsigned long, unsigned long);
+extern void omap1510_cpu_suspend(unsigned long, unsigned long);
+extern void omap1610_cpu_suspend(unsigned long, unsigned long);
extern void omap7xx_idle_loop_suspend(void);
extern void omap1510_idle_loop_suspend(void);
extern void omap1610_idle_loop_suspend(void);
diff --git a/arch/arm/mach-omap1/sleep.S b/arch/arm/mach-omap1/sleep.S
index ef771ce8b03..c875bdc902c 100644
--- a/arch/arm/mach-omap1/sleep.S
+++ b/arch/arm/mach-omap1/sleep.S
@@ -58,6 +58,7 @@
*/
#if defined(CONFIG_ARCH_OMAP730) || defined(CONFIG_ARCH_OMAP850)
+ .align 3
ENTRY(omap7xx_cpu_suspend)
@ save registers on stack
@@ -137,6 +138,7 @@ ENTRY(omap7xx_cpu_suspend_sz)
#endif /* CONFIG_ARCH_OMAP730 || CONFIG_ARCH_OMAP850 */
#ifdef CONFIG_ARCH_OMAP15XX
+ .align 3
ENTRY(omap1510_cpu_suspend)
@ save registers on stack
@@ -211,6 +213,7 @@ ENTRY(omap1510_cpu_suspend_sz)
#endif /* CONFIG_ARCH_OMAP15XX */
#if defined(CONFIG_ARCH_OMAP16XX)
+ .align 3
ENTRY(omap1610_cpu_suspend)
@ save registers on stack
diff --git a/arch/arm/mach-omap1/sram.S b/arch/arm/mach-omap1/sram.S
index 7724e520d07..692587d07ea 100644
--- a/arch/arm/mach-omap1/sram.S
+++ b/arch/arm/mach-omap1/sram.S
@@ -18,6 +18,7 @@
/*
* Reprograms ULPD and CKCTL.
*/
+ .align 3
ENTRY(omap1_sram_reprogram_clock)
stmfd sp!, {r0 - r12, lr} @ save registers on stack
diff --git a/arch/arm/mach-omap2/Makefile b/arch/arm/mach-omap2/Makefile
index 1c0c2b02d87..86a54ca1b6e 100644
--- a/arch/arm/mach-omap2/Makefile
+++ b/arch/arm/mach-omap2/Makefile
@@ -56,12 +56,15 @@ obj-$(CONFIG_ARCH_OMAP3) += opp3xxx_data.o
obj-$(CONFIG_ARCH_OMAP4) += opp4xxx_data.o
endif
+# CPUFREQ driver
+obj-$(CONFIG_CPU_FREQ) += omap2plus-cpufreq.o
+
# Power Management
ifeq ($(CONFIG_PM),y)
obj-$(CONFIG_ARCH_OMAP2) += pm24xx.o
obj-$(CONFIG_ARCH_OMAP2) += sleep24xx.o pm_bus.o voltage.o
obj-$(CONFIG_ARCH_OMAP3) += pm34xx.o sleep34xx.o voltage.o \
- cpuidle34xx.o pm_bus.o
+ cpuidle34xx.o pm_bus.o dvfs.o
obj-$(CONFIG_ARCH_OMAP4) += pm44xx.o voltage.o pm_bus.o
obj-$(CONFIG_PM_DEBUG) += pm-debug.o
obj-$(CONFIG_OMAP_SMARTREFLEX) += sr_device.o smartreflex.o
@@ -242,3 +245,6 @@ obj-y += $(smc91x-m) $(smc91x-y)
smsc911x-$(CONFIG_SMSC911X) := gpmc-smsc911x.o
obj-y += $(smsc911x-m) $(smsc911x-y)
+
+disp-$(CONFIG_OMAP2_DSS) := display.o
+obj-y += $(disp-m) $(disp-y)
diff --git a/arch/arm/mach-omap2/board-3430sdp.c b/arch/arm/mach-omap2/board-3430sdp.c
index d4e41ef86aa..33ff4f6ba12 100644
--- a/arch/arm/mach-omap2/board-3430sdp.c
+++ b/arch/arm/mach-omap2/board-3430sdp.c
@@ -307,22 +307,8 @@ static struct omap_dss_board_info sdp3430_dss_data = {
.default_device = &sdp3430_lcd_device,
};
-static struct platform_device sdp3430_dss_device = {
- .name = "omapdss",
- .id = -1,
- .dev = {
- .platform_data = &sdp3430_dss_data,
- },
-};
-
-static struct regulator_consumer_supply sdp3430_vdda_dac_supply = {
- .supply = "vdda_dac",
- .dev = &sdp3430_dss_device.dev,
-};
-
-static struct platform_device *sdp3430_devices[] __initdata = {
- &sdp3430_dss_device,
-};
+static struct regulator_consumer_supply sdp3430_vdda_dac_supply =
+ REGULATOR_SUPPLY("vdda_dac", "omap_venc");
static struct omap_board_config_kernel sdp3430_config[] __initdata = {
};
@@ -546,10 +532,8 @@ static struct regulator_init_data sdp3430_vdac = {
/* VPLL2 for digital video outputs */
static struct regulator_consumer_supply sdp3430_vpll2_supplies[] = {
- {
- .supply = "vdds_dsi",
- .dev = &sdp3430_dss_device.dev,
- }
+ REGULATOR_SUPPLY("vdds_dsi", "omap_display"),
+ REGULATOR_SUPPLY("vdds_dsi", "omap_dsi1"),
};
static struct regulator_init_data sdp3430_vpll2 = {
@@ -801,7 +785,7 @@ static void __init omap_3430sdp_init(void)
{
omap3_mux_init(board_mux, OMAP_PACKAGE_CBB);
omap3430_i2c_init();
- platform_add_devices(sdp3430_devices, ARRAY_SIZE(sdp3430_devices));
+ omap_display_init(&sdp3430_dss_data);
if (omap_rev() > OMAP3430_REV_ES1_0)
ts_gpio = SDP3430_TS_GPIO_IRQ_SDPV2;
else
diff --git a/arch/arm/mach-omap2/board-3630sdp.c b/arch/arm/mach-omap2/board-3630sdp.c
index 62645640f5e..8d05fc94f51 100644
--- a/arch/arm/mach-omap2/board-3630sdp.c
+++ b/arch/arm/mach-omap2/board-3630sdp.c
@@ -25,6 +25,24 @@
#include "board-flash.h"
#include "mux.h"
#include "sdram-hynix-h8mbx00u0mer-0em.h"
+#include "pm.h"
+
+static struct cpuidle_params omap36xx_cpuidle_params_table[] = {
+ /* C1 */
+ {1, 74, 78, 152},
+ /* C2 */
+ {0, 165, 90, 255},
+ /* C3 */
+ {1, 163, 180, 345},
+ /* C4 */
+ {0, 2852, 605, 3457},
+ /* C5 */
+ {1, 800, 366, 2120},
+ /* C6 */
+ {0, 4080, 801, 4881},
+ /* C7 */
+ {1, 4300, 8794, 159000},
+};
#if defined(CONFIG_SMC91X) || defined(CONFIG_SMC91X_MODULE)
@@ -212,6 +230,7 @@ static void __init omap_sdp_init(void)
board_flash_init(sdp_flash_partitions, chip_sel_sdp);
enable_board_wakeup_source();
usb_ehci_init(&ehci_pdata);
+ omap3_pm_init_cpuidle(omap36xx_cpuidle_params_table);
}
MACHINE_START(OMAP_3630SDP, "OMAP 3630SDP board")
diff --git a/arch/arm/mach-omap2/board-am3517evm.c b/arch/arm/mach-omap2/board-am3517evm.c
index 10d60b7743c..548f5245eda 100644
--- a/arch/arm/mach-omap2/board-am3517evm.c
+++ b/arch/arm/mach-omap2/board-am3517evm.c
@@ -378,24 +378,12 @@ static struct omap_dss_board_info am3517_evm_dss_data = {
.default_device = &am3517_evm_lcd_device,
};
-static struct platform_device am3517_evm_dss_device = {
- .name = "omapdss",
- .id = -1,
- .dev = {
- .platform_data = &am3517_evm_dss_data,
- },
-};
-
/*
* Board initialization
*/
static struct omap_board_config_kernel am3517_evm_config[] __initdata = {
};
-static struct platform_device *am3517_evm_devices[] __initdata = {
- &am3517_evm_dss_device,
-};
-
static void __init am3517_evm_init_irq(void)
{
omap_board_config = am3517_evm_config;
@@ -495,9 +483,7 @@ static void __init am3517_evm_init(void)
omap3_mux_init(board_mux, OMAP_PACKAGE_CBB);
am3517_evm_i2c_init();
- platform_add_devices(am3517_evm_devices,
- ARRAY_SIZE(am3517_evm_devices));
-
+ omap_display_init(&am3517_evm_dss_data);
omap_serial_init();
/* Configure GPIO for EHCI port */
diff --git a/arch/arm/mach-omap2/board-cm-t35.c b/arch/arm/mach-omap2/board-cm-t35.c
index dac14161066..2e9265ef3f9 100644
--- a/arch/arm/mach-omap2/board-cm-t35.c
+++ b/arch/arm/mach-omap2/board-cm-t35.c
@@ -401,14 +401,6 @@ static struct omap_dss_board_info cm_t35_dss_data = {
.default_device = &cm_t35_dvi_device,
};
-static struct platform_device cm_t35_dss_device = {
- .name = "omapdss",
- .id = -1,
- .dev = {
- .platform_data = &cm_t35_dss_data,
- },
-};
-
static struct omap2_mcspi_device_config tdo24m_mcspi_config = {
.turbo_mode = 0,
.single_channel = 1, /* 0: slave, 1: master */
@@ -468,7 +460,7 @@ static void __init cm_t35_init_display(void)
msleep(50);
gpio_set_value(lcd_en_gpio, 1);
- err = platform_device_register(&cm_t35_dss_device);
+ err = omap_display_init(&cm_t35_dss_data);
if (err) {
pr_err("CM-T35: failed to register DSS device\n");
goto err_dev_reg;
@@ -495,15 +487,11 @@ static struct regulator_consumer_supply cm_t35_vsim_supply = {
.supply = "vmmc_aux",
};
-static struct regulator_consumer_supply cm_t35_vdac_supply = {
- .supply = "vdda_dac",
- .dev = &cm_t35_dss_device.dev,
-};
+static struct regulator_consumer_supply cm_t35_vdac_supply =
+ REGULATOR_SUPPLY("vdda_dac", "omap_venc");
-static struct regulator_consumer_supply cm_t35_vdvi_supply = {
- .supply = "vdvi",
- .dev = &cm_t35_dss_device.dev,
-};
+static struct regulator_consumer_supply cm_t35_vdvi_supply =
+ REGULATOR_SUPPLY("vdvi", "omap_display");
/* VMMC1 for MMC1 pins CMD, CLK, DAT0..DAT3 (20 mA, plus card == max 220 mA) */
static struct regulator_init_data cm_t35_vmmc1 = {
diff --git a/arch/arm/mach-omap2/board-devkit8000.c b/arch/arm/mach-omap2/board-devkit8000.c
index 9a2a31e011c..d277143c425 100644
--- a/arch/arm/mach-omap2/board-devkit8000.c
+++ b/arch/arm/mach-omap2/board-devkit8000.c
@@ -195,16 +195,8 @@ static struct omap_dss_board_info devkit8000_dss_data = {
.default_device = &devkit8000_lcd_device,
};
-static struct platform_device devkit8000_dss_device = {
- .name = "omapdss",
- .id = -1,
- .dev = {
- .platform_data = &devkit8000_dss_data,
- },
-};
-
static struct regulator_consumer_supply devkit8000_vdda_dac_supply =
- REGULATOR_SUPPLY("vdda_dac", "omapdss");
+ REGULATOR_SUPPLY("vdda_dac", "omap_venc");
static uint32_t board_keymap[] = {
KEY(0, 0, KEY_1),
@@ -285,8 +277,10 @@ static struct twl4030_gpio_platform_data devkit8000_gpio_data = {
.setup = devkit8000_twl_gpio_setup,
};
-static struct regulator_consumer_supply devkit8000_vpll1_supply =
- REGULATOR_SUPPLY("vdds_dsi", "omapdss");
+static struct regulator_consumer_supply devkit8000_vpll1_supplies[] = {
+ REGULATOR_SUPPLY("vdds_dsi", "omap_display"),
+ REGULATOR_SUPPLY("vdds_dsi", "omap_dsi1"),
+};
/* VMMC1 for MMC1 pins CMD, CLK, DAT0..DAT3 (20 mA, plus card == max 220 mA) */
static struct regulator_init_data devkit8000_vmmc1 = {
@@ -327,8 +321,8 @@ static struct regulator_init_data devkit8000_vpll1 = {
.valid_ops_mask = REGULATOR_CHANGE_MODE
| REGULATOR_CHANGE_STATUS,
},
- .num_consumer_supplies = 1,
- .consumer_supplies = &devkit8000_vpll1_supply,
+ .num_consumer_supplies = ARRAY_SIZE(devkit8000_vpll1_supplies),
+ .consumer_supplies = devkit8000_vpll1_supplies,
};
/* VAUX4 for ads7846 and nubs */
@@ -575,7 +569,6 @@ static void __init omap_dm9000_init(void)
}
static struct platform_device *devkit8000_devices[] __initdata = {
- &devkit8000_dss_device,
&leds_gpio,
&keys_gpio,
&omap_dm9000_dev,
@@ -797,6 +790,7 @@ static void __init devkit8000_init(void)
platform_add_devices(devkit8000_devices,
ARRAY_SIZE(devkit8000_devices));
+ omap_display_init(&devkit8000_dss_data);
spi_register_board_info(devkit8000_spi_board_info,
ARRAY_SIZE(devkit8000_spi_board_info));
diff --git a/arch/arm/mach-omap2/board-igep0020.c b/arch/arm/mach-omap2/board-igep0020.c
index 3be85a1f55f..dfbe3a1eaa8 100644
--- a/arch/arm/mach-omap2/board-igep0020.c
+++ b/arch/arm/mach-omap2/board-igep0020.c
@@ -485,17 +485,9 @@ static struct omap_dss_board_info igep2_dss_data = {
.default_device = &igep2_dvi_device,
};
-static struct platform_device igep2_dss_device = {
- .name = "omapdss",
- .id = -1,
- .dev = {
- .platform_data = &igep2_dss_data,
- },
-};
-
-static struct regulator_consumer_supply igep2_vpll2_supply = {
- .supply = "vdds_dsi",
- .dev = &igep2_dss_device.dev,
+static struct regulator_consumer_supply igep2_vpll2_supplies[] = {
+ REGULATOR_SUPPLY("vdds_dsi", "omap_display"),
+ REGULATOR_SUPPLY("vdds_dsi", "omap_dsi1"),
};
static struct regulator_init_data igep2_vpll2 = {
@@ -509,8 +501,8 @@ static struct regulator_init_data igep2_vpll2 = {
.valid_ops_mask = REGULATOR_CHANGE_MODE
| REGULATOR_CHANGE_STATUS,
},
- .num_consumer_supplies = 1,
- .consumer_supplies = &igep2_vpll2_supply,
+ .num_consumer_supplies = ARRAY_SIZE(igep2_vpll2_supplies),
+ .consumer_supplies = igep2_vpll2_supplies,
};
static void __init igep2_display_init(void)
@@ -521,7 +513,6 @@ static void __init igep2_display_init(void)
}
static struct platform_device *igep2_devices[] __initdata = {
- &igep2_dss_device,
&igep2_vwlan_device,
};
@@ -697,6 +688,7 @@ static void __init igep2_init(void)
/* Register I2C busses and drivers */
igep2_i2c_init();
platform_add_devices(igep2_devices, ARRAY_SIZE(igep2_devices));
+ omap_display_init(&igep2_dss_data);
omap_serial_init();
usb_musb_init(&musb_board_data);
usb_ehci_init(&ehci_pdata);
diff --git a/arch/arm/mach-omap2/board-omap3beagle.c b/arch/arm/mach-omap2/board-omap3beagle.c
index 46d814ab565..caf6c8aedac 100644
--- a/arch/arm/mach-omap2/board-omap3beagle.c
+++ b/arch/arm/mach-omap2/board-omap3beagle.c
@@ -228,19 +228,13 @@ static struct omap_dss_board_info beagle_dss_data = {
.default_device = &beagle_dvi_device,
};
-static struct platform_device beagle_dss_device = {
- .name = "omapdss",
- .id = -1,
- .dev = {
- .platform_data = &beagle_dss_data,
- },
-};
-
static struct regulator_consumer_supply beagle_vdac_supply =
- REGULATOR_SUPPLY("vdda_dac", "omapdss");
+ REGULATOR_SUPPLY("vdda_dac", "omap_venc");
-static struct regulator_consumer_supply beagle_vdvi_supply =
- REGULATOR_SUPPLY("vdds_dsi", "omapdss");
+static struct regulator_consumer_supply beagle_vdvi_supplies[] = {
+ REGULATOR_SUPPLY("vdds_dsi", "omap_display"),
+ REGULATOR_SUPPLY("vdds_dsi", "omap_dsi1"),
+};
static void __init beagle_display_init(void)
{
@@ -427,8 +421,8 @@ static struct regulator_init_data beagle_vpll2 = {
.valid_ops_mask = REGULATOR_CHANGE_MODE
| REGULATOR_CHANGE_STATUS,
},
- .num_consumer_supplies = 1,
- .consumer_supplies = &beagle_vdvi_supply,
+ .num_consumer_supplies = ARRAY_SIZE(beagle_vdvi_supplies),
+ .consumer_supplies = beagle_vdvi_supplies,
};
static struct twl4030_usb_data beagle_usb_data = {
@@ -550,7 +544,6 @@ static void __init omap3_beagle_init_irq(void)
static struct platform_device *omap3_beagle_devices[] __initdata = {
&leds_gpio,
&keys_gpio,
- &beagle_dss_device,
};
static void __init omap3beagle_flash_init(void)
@@ -617,6 +610,7 @@ static void __init omap3_beagle_init(void)
omap3_beagle_i2c_init();
platform_add_devices(omap3_beagle_devices,
ARRAY_SIZE(omap3_beagle_devices));
+ omap_display_init(&beagle_dss_data);
omap_serial_init();
omap_mux_init_gpio(170, OMAP_PIN_INPUT);
diff --git a/arch/arm/mach-omap2/board-omap3evm.c b/arch/arm/mach-omap2/board-omap3evm.c
index 323c3809ce3..0c56b9edf65 100644
--- a/arch/arm/mach-omap2/board-omap3evm.c
+++ b/arch/arm/mach-omap2/board-omap3evm.c
@@ -328,14 +328,6 @@ static struct omap_dss_board_info omap3_evm_dss_data = {
.default_device = &omap3_evm_lcd_device,
};
-static struct platform_device omap3_evm_dss_device = {
- .name = "omapdss",
- .id = -1,
- .dev = {
- .platform_data = &omap3_evm_dss_data,
- },
-};
-
static struct regulator_consumer_supply omap3evm_vmmc1_supply = {
.supply = "vmmc",
};
@@ -500,10 +492,8 @@ static struct twl4030_codec_data omap3evm_codec_data = {
.audio = &omap3evm_audio_data,
};
-static struct regulator_consumer_supply omap3_evm_vdda_dac_supply = {
- .supply = "vdda_dac",
- .dev = &omap3_evm_dss_device.dev,
-};
+static struct regulator_consumer_supply omap3_evm_vdda_dac_supply =
+ REGULATOR_SUPPLY("vdda_dac", "omap_venc");
/* VDAC for DSS driving S-Video */
static struct regulator_init_data omap3_evm_vdac = {
@@ -521,8 +511,10 @@ static struct regulator_init_data omap3_evm_vdac = {
};
/* VPLL2 for digital video outputs */
-static struct regulator_consumer_supply omap3_evm_vpll2_supply =
- REGULATOR_SUPPLY("vdds_dsi", "omapdss");
+static struct regulator_consumer_supply omap3_evm_vpll2_supplies[] = {
+ REGULATOR_SUPPLY("vdds_dsi", "omap_display"),
+ REGULATOR_SUPPLY("vdds_dsi", "omap_dsi1"),
+};
static struct regulator_init_data omap3_evm_vpll2 = {
.constraints = {
@@ -534,8 +526,8 @@ static struct regulator_init_data omap3_evm_vpll2 = {
.valid_ops_mask = REGULATOR_CHANGE_MODE
| REGULATOR_CHANGE_STATUS,
},
- .num_consumer_supplies = 1,
- .consumer_supplies = &omap3_evm_vpll2_supply,
+ .num_consumer_supplies = ARRAY_SIZE(omap3_evm_vpll2_supplies),
+ .consumer_supplies = omap3_evm_vpll2_supplies,
};
static struct twl4030_platform_data omap3evm_twldata = {
@@ -634,10 +626,6 @@ static void __init omap3_evm_init_irq(void)
omap_init_irq();
}
-static struct platform_device *omap3_evm_devices[] __initdata = {
- &omap3_evm_dss_device,
-};
-
static struct ehci_hcd_omap_platform_data ehci_pdata __initdata = {
.port_mode[0] = EHCI_HCD_OMAP_MODE_UNKNOWN,
@@ -675,7 +663,7 @@ static void __init omap3_evm_init(void)
omap3_evm_i2c_init();
- platform_add_devices(omap3_evm_devices, ARRAY_SIZE(omap3_evm_devices));
+ omap_display_init(&omap3_evm_dss_data);
spi_register_board_info(omap3evm_spi_board_info,
ARRAY_SIZE(omap3evm_spi_board_info));
diff --git a/arch/arm/mach-omap2/board-omap3pandora.c b/arch/arm/mach-omap2/board-omap3pandora.c
index 0b34beded11..b430d2bce8f 100644
--- a/arch/arm/mach-omap2/board-omap3pandora.c
+++ b/arch/arm/mach-omap2/board-omap3pandora.c
@@ -253,14 +253,6 @@ static struct omap_dss_board_info pandora_dss_data = {
.default_device = &pandora_lcd_device,
};
-static struct platform_device pandora_dss_device = {
- .name = "omapdss",
- .id = -1,
- .dev = {
- .platform_data = &pandora_dss_data,
- },
-};
-
static void pandora_wl1251_init_card(struct mmc_card *card)
{
/*
@@ -350,11 +342,12 @@ static struct regulator_consumer_supply pandora_vmmc3_supply =
REGULATOR_SUPPLY("vmmc", "mmci-omap-hs.2");
static struct regulator_consumer_supply pandora_vdda_dac_supply =
- REGULATOR_SUPPLY("vdda_dac", "omapdss");
+ REGULATOR_SUPPLY("vdda_dac", "omap_venc");
static struct regulator_consumer_supply pandora_vdds_supplies[] = {
- REGULATOR_SUPPLY("vdds_sdi", "omapdss"),
- REGULATOR_SUPPLY("vdds_dsi", "omapdss"),
+ REGULATOR_SUPPLY("vdds_sdi", "omap_display"),
+ REGULATOR_SUPPLY("vdds_dsi", "omap_display"),
+ REGULATOR_SUPPLY("vdds_dsi", "omap_dsi1"),
};
static struct regulator_consumer_supply pandora_vcc_lcd_supply =
@@ -677,7 +670,6 @@ fail:
static struct platform_device *omap3pandora_devices[] __initdata = {
&pandora_leds_gpio,
&pandora_keys_gpio,
- &pandora_dss_device,
&pandora_vwlan_device,
};
@@ -712,6 +704,7 @@ static void __init omap3pandora_init(void)
pandora_wl1251_init();
platform_add_devices(omap3pandora_devices,
ARRAY_SIZE(omap3pandora_devices));
+ omap_display_init(&pandora_dss_data);
omap_serial_init();
spi_register_board_info(omap3pandora_spi_board_info,
ARRAY_SIZE(omap3pandora_spi_board_info));
diff --git a/arch/arm/mach-omap2/board-omap3stalker.c b/arch/arm/mach-omap2/board-omap3stalker.c
index 2a2dad447e8..b5e868044c1 100644
--- a/arch/arm/mach-omap2/board-omap3stalker.c
+++ b/arch/arm/mach-omap2/board-omap3stalker.c
@@ -240,14 +240,6 @@ static struct omap_dss_board_info omap3_stalker_dss_data = {
.default_device = &omap3_stalker_dvi_device,
};
-static struct platform_device omap3_stalker_dss_device = {
- .name = "omapdss",
- .id = -1,
- .dev = {
- .platform_data = &omap3_stalker_dss_data,
- },
-};
-
static struct regulator_consumer_supply omap3stalker_vmmc1_supply = {
.supply = "vmmc",
};
@@ -448,10 +440,8 @@ static struct twl4030_codec_data omap3stalker_codec_data = {
.audio = &omap3stalker_audio_data,
};
-static struct regulator_consumer_supply omap3_stalker_vdda_dac_supply = {
- .supply = "vdda_dac",
- .dev = &omap3_stalker_dss_device.dev,
-};
+static struct regulator_consumer_supply omap3_stalker_vdda_dac_supply =
+ REGULATOR_SUPPLY("vdda_dac", "omap_venc");
/* VDAC for DSS driving S-Video */
static struct regulator_init_data omap3_stalker_vdac = {
@@ -469,9 +459,9 @@ static struct regulator_init_data omap3_stalker_vdac = {
};
/* VPLL2 for digital video outputs */
-static struct regulator_consumer_supply omap3_stalker_vpll2_supply = {
- .supply = "vdds_dsi",
- .dev = &omap3_stalker_lcd_device.dev,
+static struct regulator_consumer_supply omap3_stalker_vpll2_supplies[] = {
+ REGULATOR_SUPPLY("vdds_dsi", "omap_display"),
+ REGULATOR_SUPPLY("vdds_dsi", "omap_dsi1"),
};
static struct regulator_init_data omap3_stalker_vpll2 = {
@@ -485,8 +475,8 @@ static struct regulator_init_data omap3_stalker_vpll2 = {
.valid_ops_mask = REGULATOR_CHANGE_MODE
| REGULATOR_CHANGE_STATUS,
},
- .num_consumer_supplies = 1,
- .consumer_supplies = &omap3_stalker_vpll2_supply,
+ .num_consumer_supplies = ARRAY_SIZE(omap3_stalker_vpll2_supplies),
+ .consumer_supplies = omap3_stalker_vpll2_supplies,
};
static struct twl4030_platform_data omap3stalker_twldata = {
@@ -604,7 +594,6 @@ static void __init omap3_stalker_init_irq(void)
}
static struct platform_device *omap3_stalker_devices[] __initdata = {
- &omap3_stalker_dss_device,
&keys_gpio,
};
@@ -644,6 +633,7 @@ static void __init omap3_stalker_init(void)
platform_add_devices(omap3_stalker_devices,
ARRAY_SIZE(omap3_stalker_devices));
+ omap_display_init(&omap3_stalker_dss_data);
spi_register_board_info(omap3stalker_spi_board_info,
ARRAY_SIZE(omap3stalker_spi_board_info));
diff --git a/arch/arm/mach-omap2/board-omap4panda.c b/arch/arm/mach-omap2/board-omap4panda.c
index e944025d5ef..b09d23925f4 100644
--- a/arch/arm/mach-omap2/board-omap4panda.c
+++ b/arch/arm/mach-omap2/board-omap4panda.c
@@ -37,6 +37,7 @@
#include <plat/common.h>
#include <plat/usb.h>
#include <plat/mmc.h>
+#include <plat/panel-generic-dpi.h>
#include "timer-gp.h"
#include "hsmmc.h"
@@ -76,6 +77,60 @@ static struct platform_device *panda_devices[] __initdata = {
&leds_gpio,
};
+/* Display DVI */
+#define PANDA_DVI_TFP410_POWER_DOWN_GPIO 0
+
+static int panda_enable_dvi(struct omap_dss_device *dssdev)
+{
+ gpio_set_value(dssdev->reset_gpio, 1);
+ return 0;
+}
+
+static void panda_disable_dvi(struct omap_dss_device *dssdev)
+{
+ gpio_set_value(dssdev->reset_gpio, 0);
+}
+
+/* Using generic display panel */
+static struct panel_generic_dpi_data dvi_panel = {
+ .name = "generic",
+ .platform_enable = panda_enable_dvi,
+ .platform_disable = panda_disable_dvi,
+};
+
+struct omap_dss_device panda_dvi_device = {
+ .type = OMAP_DISPLAY_TYPE_DPI,
+ .name = "dvi",
+ .driver_name = "generic_dpi_panel",
+ .data = &dvi_panel,
+ .phy.dpi.data_lines = 24,
+ .reset_gpio = PANDA_DVI_TFP410_POWER_DOWN_GPIO,
+ .channel = OMAP_DSS_CHANNEL_LCD2,
+};
+
+int __init panda_dvi_init(void)
+{
+ int r;
+
+ /* Requesting TFP410 DVI GPIO and disabling it, at bootup */
+ r = gpio_request_one(panda_dvi_device.reset_gpio,
+ GPIOF_OUT_INIT_LOW, "DVI PD");
+ if (r)
+ pr_err("Failed to get DVI powerdown GPIO\n");
+
+ return r;
+}
+
+static struct omap_dss_device *panda_dss_devices[] = {
+ &panda_dvi_device,
+};
+
+static struct omap_dss_board_info panda_dss_data = {
+ .num_devices = ARRAY_SIZE(panda_dss_devices),
+ .devices = panda_dss_devices,
+ .default_device = &panda_dvi_device,
+};
+
static void __init omap4_panda_init_irq(void)
{
omap2_init_common_infrastructure();
@@ -375,6 +430,17 @@ static struct i2c_board_info __initdata omap4_panda_i2c_boardinfo[] = {
.platform_data = &omap4_panda_twldata,
},
};
+
+/*
+ * Display monitor features are burnt in their EEPROM as EDID data. The EEPROM
+ * is connected as I2C slave device, and can be accessed at address 0x50
+ */
+static struct i2c_board_info __initdata panda_i2c_eeprom[] = {
+ {
+ I2C_BOARD_INFO("eeprom", 0x50),
+ },
+};
+
static int __init omap4_panda_i2c_init(void)
{
/*
@@ -384,13 +450,76 @@ static int __init omap4_panda_i2c_init(void)
omap_register_i2c_bus(1, 400, omap4_panda_i2c_boardinfo,
ARRAY_SIZE(omap4_panda_i2c_boardinfo));
omap_register_i2c_bus(2, 400, NULL, 0);
- omap_register_i2c_bus(3, 400, NULL, 0);
+ /*
+ * Bus 3 is attached to the DVI port where devices like the pico DLP
+ * projector don't work reliably with 400kHz
+ */
+ omap_register_i2c_bus(3, 100, panda_i2c_eeprom,
+ ARRAY_SIZE(panda_i2c_eeprom));
omap_register_i2c_bus(4, 400, NULL, 0);
return 0;
}
#ifdef CONFIG_OMAP_MUX
static struct omap_board_mux board_mux[] __initdata = {
+ /* gpio 0 - TFP410 PD */
+ OMAP4_MUX(KPD_COL1, OMAP_PIN_OUTPUT | OMAP_MUX_MODE3),
+ /* dispc2_data23 */
+ OMAP4_MUX(USBB2_ULPITLL_STP, OMAP_PIN_OUTPUT | OMAP_MUX_MODE5),
+ /* dispc2_data22 */
+ OMAP4_MUX(USBB2_ULPITLL_DIR, OMAP_PIN_OUTPUT | OMAP_MUX_MODE5),
+ /* dispc2_data21 */
+ OMAP4_MUX(USBB2_ULPITLL_NXT, OMAP_PIN_OUTPUT | OMAP_MUX_MODE5),
+ /* dispc2_data20 */
+ OMAP4_MUX(USBB2_ULPITLL_DAT0, OMAP_PIN_OUTPUT | OMAP_MUX_MODE5),
+ /* dispc2_data19 */
+ OMAP4_MUX(USBB2_ULPITLL_DAT1, OMAP_PIN_OUTPUT | OMAP_MUX_MODE5),
+ /* dispc2_data18 */
+ OMAP4_MUX(USBB2_ULPITLL_DAT2, OMAP_PIN_OUTPUT | OMAP_MUX_MODE5),
+ /* dispc2_data15 */
+ OMAP4_MUX(USBB2_ULPITLL_DAT3, OMAP_PIN_OUTPUT | OMAP_MUX_MODE5),
+ /* dispc2_data14 */
+ OMAP4_MUX(USBB2_ULPITLL_DAT4, OMAP_PIN_OUTPUT | OMAP_MUX_MODE5),
+ /* dispc2_data13 */
+ OMAP4_MUX(USBB2_ULPITLL_DAT5, OMAP_PIN_OUTPUT | OMAP_MUX_MODE5),
+ /* dispc2_data12 */
+ OMAP4_MUX(USBB2_ULPITLL_DAT6, OMAP_PIN_OUTPUT | OMAP_MUX_MODE5),
+ /* dispc2_data11 */
+ OMAP4_MUX(USBB2_ULPITLL_DAT7, OMAP_PIN_OUTPUT | OMAP_MUX_MODE5),
+ /* dispc2_data10 */
+ OMAP4_MUX(DPM_EMU3, OMAP_PIN_OUTPUT | OMAP_MUX_MODE5),
+ /* dispc2_data9 */
+ OMAP4_MUX(DPM_EMU4, OMAP_PIN_OUTPUT | OMAP_MUX_MODE5),
+ /* dispc2_data16 */
+ OMAP4_MUX(DPM_EMU5, OMAP_PIN_OUTPUT | OMAP_MUX_MODE5),
+ /* dispc2_data17 */
+ OMAP4_MUX(DPM_EMU6, OMAP_PIN_OUTPUT | OMAP_MUX_MODE5),
+ /* dispc2_hsync */
+ OMAP4_MUX(DPM_EMU7, OMAP_PIN_OUTPUT | OMAP_MUX_MODE5),
+ /* dispc2_pclk */
+ OMAP4_MUX(DPM_EMU8, OMAP_PIN_OUTPUT | OMAP_MUX_MODE5),
+ /* dispc2_vsync */
+ OMAP4_MUX(DPM_EMU9, OMAP_PIN_OUTPUT | OMAP_MUX_MODE5),
+ /* dispc2_de */
+ OMAP4_MUX(DPM_EMU10, OMAP_PIN_OUTPUT | OMAP_MUX_MODE5),
+ /* dispc2_data8 */
+ OMAP4_MUX(DPM_EMU11, OMAP_PIN_OUTPUT | OMAP_MUX_MODE5),
+ /* dispc2_data7 */
+ OMAP4_MUX(DPM_EMU12, OMAP_PIN_OUTPUT | OMAP_MUX_MODE5),
+ /* dispc2_data6 */
+ OMAP4_MUX(DPM_EMU13, OMAP_PIN_OUTPUT | OMAP_MUX_MODE5),
+ /* dispc2_data5 */
+ OMAP4_MUX(DPM_EMU14, OMAP_PIN_OUTPUT | OMAP_MUX_MODE5),
+ /* dispc2_data4 */
+ OMAP4_MUX(DPM_EMU15, OMAP_PIN_OUTPUT | OMAP_MUX_MODE5),
+ /* dispc2_data3 */
+ OMAP4_MUX(DPM_EMU16, OMAP_PIN_OUTPUT | OMAP_MUX_MODE5),
+ /* dispc2_data2 */
+ OMAP4_MUX(DPM_EMU17, OMAP_PIN_OUTPUT | OMAP_MUX_MODE5),
+ /* dispc2_data1 */
+ OMAP4_MUX(DPM_EMU18, OMAP_PIN_OUTPUT | OMAP_MUX_MODE5),
+ /* dispc2_data0 */
+ OMAP4_MUX(DPM_EMU19, OMAP_PIN_OUTPUT | OMAP_MUX_MODE5),
{ .reg_offset = OMAP_MUX_TERMINATOR },
};
#else
@@ -400,6 +529,7 @@ static struct omap_board_mux board_mux[] __initdata = {
static void __init omap4_panda_init(void)
{
int package = OMAP_PACKAGE_CBS;
+ int err;
if (omap_rev() == OMAP4430_REV_ES1_0)
package = OMAP_PACKAGE_CBL;
@@ -411,6 +541,11 @@ static void __init omap4_panda_init(void)
omap4_twl6030_hsmmc_init(mmc);
omap4_ehci_init();
usb_musb_init(&musb_board_data);
+
+ /* Enabling DVI Display */
+ err = panda_dvi_init();
+ if (!err)
+ omap_display_init(&panda_dss_data);
}
static void __init omap4_panda_map_io(void)
diff --git a/arch/arm/mach-omap2/board-overo.c b/arch/arm/mach-omap2/board-overo.c
index cb26e5d8268..90c256879ed 100644
--- a/arch/arm/mach-omap2/board-overo.c
+++ b/arch/arm/mach-omap2/board-overo.c
@@ -28,6 +28,7 @@
#include <linux/platform_device.h>
#include <linux/i2c/twl.h>
#include <linux/regulator/machine.h>
+#include <linux/spi/spi.h>
#include <linux/mtd/mtd.h>
#include <linux/mtd/nand.h>
@@ -41,10 +42,14 @@
#include <plat/board.h>
#include <plat/common.h>
+#include <plat/display.h>
+#include <plat/panel-generic-dpi.h>
#include <mach/gpio.h>
#include <plat/gpmc.h>
#include <mach/hardware.h>
#include <plat/nand.h>
+#include <plat/mcspi.h>
+#include <plat/mux.h>
#include <plat/usb.h>
#include "mux.h"
@@ -68,8 +73,6 @@
#if defined(CONFIG_TOUCHSCREEN_ADS7846) || \
defined(CONFIG_TOUCHSCREEN_ADS7846_MODULE)
-#include <plat/mcspi.h>
-#include <linux/spi/spi.h>
#include <linux/spi/ads7846.h>
static struct omap2_mcspi_device_config ads7846_mcspi_config = {
@@ -94,18 +97,6 @@ static struct ads7846_platform_data ads7846_config = {
.keep_vref_on = 1,
};
-static struct spi_board_info overo_spi_board_info[] __initdata = {
- {
- .modalias = "ads7846",
- .bus_num = 1,
- .chip_select = 0,
- .max_speed_hz = 1500000,
- .controller_data = &ads7846_mcspi_config,
- .irq = OMAP_GPIO_IRQ(OVERO_GPIO_PENDOWN),
- .platform_data = &ads7846_config,
- }
-};
-
static void __init overo_ads7846_init(void)
{
if ((gpio_request(OVERO_GPIO_PENDOWN, "ADS7846_PENDOWN") == 0) &&
@@ -115,9 +106,6 @@ static void __init overo_ads7846_init(void)
printk(KERN_ERR "could not obtain gpio for ADS7846_PENDOWN\n");
return;
}
-
- spi_register_board_info(overo_spi_board_info,
- ARRAY_SIZE(overo_spi_board_info));
}
#else
@@ -233,6 +221,140 @@ static inline void __init overo_init_smsc911x(void)
static inline void __init overo_init_smsc911x(void) { return; }
#endif
+/* DSS */
+static int lcd_enabled;
+static int dvi_enabled;
+
+#define OVERO_GPIO_LCD_EN 144
+#define OVERO_GPIO_LCD_BL 145
+
+static void __init overo_display_init(void)
+{
+ if ((gpio_request(OVERO_GPIO_LCD_EN, "OVERO_GPIO_LCD_EN") == 0) &&
+ (gpio_direction_output(OVERO_GPIO_LCD_EN, 1) == 0))
+ gpio_export(OVERO_GPIO_LCD_EN, 0);
+ else
+ printk(KERN_ERR "could not obtain gpio for "
+ "OVERO_GPIO_LCD_EN\n");
+
+ if ((gpio_request(OVERO_GPIO_LCD_BL, "OVERO_GPIO_LCD_BL") == 0) &&
+ (gpio_direction_output(OVERO_GPIO_LCD_BL, 1) == 0))
+ gpio_export(OVERO_GPIO_LCD_BL, 0);
+ else
+ printk(KERN_ERR "could not obtain gpio for "
+ "OVERO_GPIO_LCD_BL\n");
+}
+
+static int overo_panel_enable_dvi(struct omap_dss_device *dssdev)
+{
+ if (lcd_enabled) {
+ printk(KERN_ERR "cannot enable DVI, LCD is enabled\n");
+ return -EINVAL;
+ }
+ dvi_enabled = 1;
+
+ return 0;
+}
+
+static void overo_panel_disable_dvi(struct omap_dss_device *dssdev)
+{
+ dvi_enabled = 0;
+}
+
+static struct panel_generic_dpi_data dvi_panel = {
+ .name = "generic",
+ .platform_enable = overo_panel_enable_dvi,
+ .platform_disable = overo_panel_disable_dvi,
+};
+
+static struct omap_dss_device overo_dvi_device = {
+ .type = OMAP_DISPLAY_TYPE_DPI,
+ .name = "dvi",
+ .driver_name = "generic_dpi_panel",
+ .data = &dvi_panel,
+ .phy.dpi.data_lines = 24,
+ .reset_gpio = -EINVAL,
+};
+
+static struct omap_dss_device overo_tv_device = {
+ .name = "tv",
+ .driver_name = "venc",
+ .type = OMAP_DISPLAY_TYPE_VENC,
+ .phy.venc.type = OMAP_DSS_VENC_TYPE_SVIDEO,
+};
+
+static int overo_panel_enable_lcd(struct omap_dss_device *dssdev)
+{
+ if (dvi_enabled) {
+ printk(KERN_ERR "cannot enable LCD, DVI is enabled\n");
+ return -EINVAL;
+ }
+
+ gpio_set_value(OVERO_GPIO_LCD_EN, 1);
+ gpio_set_value(OVERO_GPIO_LCD_BL, 1);
+ lcd_enabled = 1;
+ return 0;
+}
+
+static void overo_panel_disable_lcd(struct omap_dss_device *dssdev)
+{
+ gpio_set_value(OVERO_GPIO_LCD_EN, 0);
+ gpio_set_value(OVERO_GPIO_LCD_BL, 0);
+ lcd_enabled = 0;
+}
+
+#if defined(CONFIG_PANEL_LGPHILIPS_LB035Q02) || \
+ defined(CONFIG_PANEL_LGPHILIPS_LB035Q02_MODULE)
+static struct omap_dss_device overo_lcd35_device = {
+ .type = OMAP_DISPLAY_TYPE_DPI,
+ .name = "lcd35",
+ .driver_name = "lgphilips_lb035q02_panel",
+ .phy.dpi.data_lines = 24,
+ .platform_enable = overo_panel_enable_lcd,
+ .platform_disable = overo_panel_disable_lcd,
+};
+#endif
+
+#if defined(CONFIG_PANEL_SAMSUNG_LTE430WQ_F0C) || \
+ defined(CONFIG_PANEL_SAMSUNG_LTE430WQ_F0C_MODULE)
+static struct omap_dss_device overo_lcd43_device = {
+ .type = OMAP_DISPLAY_TYPE_DPI,
+ .name = "lcd43",
+ .driver_name = "samsung_lte_panel",
+ .phy.dpi.data_lines = 24,
+ .platform_enable = overo_panel_enable_lcd,
+ .platform_disable = overo_panel_disable_lcd,
+};
+#endif
+
+static struct omap_dss_device *overo_dss_devices[] = {
+ &overo_dvi_device,
+ &overo_tv_device,
+#if defined(CONFIG_PANEL_LGPHILIPS_LB035Q02) || \
+ defined(CONFIG_PANEL_LGPHILIPS_LB035Q02_MODULE)
+ &overo_lcd35_device,
+#endif
+#if defined(CONFIG_PANEL_SAMSUNG_LTE430WQ_F0C) || \
+ defined(CONFIG_PANEL_SAMSUNG_LTE430WQ_F0C_MODULE)
+ &overo_lcd43_device,
+#endif
+};
+
+static struct omap_dss_board_info overo_dss_data = {
+ .num_devices = ARRAY_SIZE(overo_dss_devices),
+ .devices = overo_dss_devices,
+ .default_device = &overo_dvi_device,
+};
+
+static struct regulator_consumer_supply overo_vdda_dac_supply =
+ REGULATOR_SUPPLY("vdda_dac", "omap_venc");
+
+static struct regulator_consumer_supply overo_vdds_supplies[] = {
+ REGULATOR_SUPPLY("vdds_sdi", "omap_display"),
+ REGULATOR_SUPPLY("vdds_dsi", "omap_display"),
+ REGULATOR_SUPPLY("vdds_dsi", "omap_dsi1"),
+};
+
static struct mtd_partition overo_nand_partitions[] = {
{
.name = "xloader",
@@ -358,6 +480,37 @@ static struct regulator_init_data overo_vmmc1 = {
.consumer_supplies = &overo_vmmc1_supply,
};
+/* VDAC for DSS driving S-Video (8 mA unloaded, max 65 mA) */
+static struct regulator_init_data overo_vdac = {
+ .constraints = {
+ .min_uV = 1800000,
+ .max_uV = 1800000,
+ .valid_modes_mask = REGULATOR_MODE_NORMAL
+ | REGULATOR_MODE_STANDBY,
+ .valid_ops_mask = REGULATOR_CHANGE_MODE
+ | REGULATOR_CHANGE_STATUS,
+ },
+ .num_consumer_supplies = 1,
+ .consumer_supplies = &overo_vdda_dac_supply,
+};
+
+/* VPLL2 for digital video outputs */
+static struct regulator_init_data overo_vpll2 = {
+ .constraints = {
+ .name = "VDVI",
+ .min_uV = 1800000,
+ .max_uV = 1800000,
+ .valid_modes_mask = REGULATOR_MODE_NORMAL
+ | REGULATOR_MODE_STANDBY,
+ .valid_ops_mask = REGULATOR_CHANGE_MODE
+ | REGULATOR_CHANGE_STATUS,
+ },
+ .num_consumer_supplies = ARRAY_SIZE(overo_vdds_supplies),
+ .consumer_supplies = &overo_vdds_supplies,
+};
+
+/* mmc2 (WLAN) and Bluetooth don't use twl4030 regulators */
+
static struct twl4030_codec_audio_data overo_audio_data = {
.audio_mclk = 26000000,
};
@@ -376,6 +529,8 @@ static struct twl4030_platform_data overo_twldata = {
.usb = &overo_usb_data,
.codec = &overo_codec_data,
.vmmc1 = &overo_vmmc1,
+ .vdac = &overo_vdac,
+ .vpll2 = &overo_vpll2,
};
static struct i2c_board_info __initdata overo_i2c_boardinfo[] = {
@@ -396,33 +551,47 @@ static int __init overo_i2c_init(void)
return 0;
}
-static struct platform_device overo_lcd_device = {
- .name = "overo_lcd",
- .id = -1,
-};
-
-static struct omap_lcd_config overo_lcd_config __initdata = {
- .ctrl_name = "internal",
+static struct spi_board_info overo_spi_board_info[] __initdata = {
+#if defined(CONFIG_TOUCHSCREEN_ADS7846) || \
+ defined(CONFIG_TOUCHSCREEN_ADS7846_MODULE)
+ {
+ .modalias = "ads7846",
+ .bus_num = 1,
+ .chip_select = 0,
+ .max_speed_hz = 1500000,
+ .controller_data = &ads7846_mcspi_config,
+ .irq = OMAP_GPIO_IRQ(OVERO_GPIO_PENDOWN),
+ .platform_data = &ads7846_config,
+ },
+#endif
+#if defined(CONFIG_PANEL_LGPHILIPS_LB035Q02) || \
+ defined(CONFIG_PANEL_LGPHILIPS_LB035Q02_MODULE)
+ {
+ .modalias = "lgphilips_lb035q02_panel-spi",
+ .bus_num = 1,
+ .chip_select = 1,
+ .max_speed_hz = 500000,
+ .mode = SPI_MODE_3,
+ },
+#endif
};
-static struct omap_board_config_kernel overo_config[] __initdata = {
- { OMAP_TAG_LCD, &overo_lcd_config },
-};
+static int __init overo_spi_init(void)
+{
+ overo_ads7846_init();
+ spi_register_board_info(overo_spi_board_info,
+ ARRAY_SIZE(overo_spi_board_info));
+ return 0;
+}
static void __init overo_init_irq(void)
{
- omap_board_config = overo_config;
- omap_board_config_size = ARRAY_SIZE(overo_config);
omap2_init_common_infrastructure();
omap2_init_common_devices(mt46h32m32lf6_sdrc_params,
mt46h32m32lf6_sdrc_params);
omap_init_irq();
}
-static struct platform_device *overo_devices[] __initdata = {
- &overo_lcd_device,
-};
-
static const struct ehci_hcd_omap_platform_data ehci_pdata __initconst = {
.port_mode[0] = EHCI_HCD_OMAP_MODE_UNKNOWN,
.port_mode[1] = EHCI_HCD_OMAP_MODE_PHY,
@@ -450,13 +619,14 @@ static void __init overo_init(void)
{
omap3_mux_init(board_mux, OMAP_PACKAGE_CBB);
overo_i2c_init();
- platform_add_devices(overo_devices, ARRAY_SIZE(overo_devices));
+ omap_display_init(&overo_dss_data);
omap_serial_init();
overo_flash_init();
usb_musb_init(&musb_board_data);
usb_ehci_init(&ehci_pdata);
- overo_ads7846_init();
+ overo_spi_init();
overo_init_smsc911x();
+ overo_display_init();
/* Ensure SDRC pins are mux'd for self-refresh */
omap_mux_init_signal("sdrc_cke0", OMAP_PIN_OUTPUT);
diff --git a/arch/arm/mach-omap2/board-rx51-peripherals.c b/arch/arm/mach-omap2/board-rx51-peripherals.c
index e75e240cad6..b783854476b 100644
--- a/arch/arm/mach-omap2/board-rx51-peripherals.c
+++ b/arch/arm/mach-omap2/board-rx51-peripherals.c
@@ -360,11 +360,11 @@ static struct regulator_consumer_supply rx51_vio_supplies[] = {
};
static struct regulator_consumer_supply rx51_vaux1_consumers[] = {
- REGULATOR_SUPPLY("vdds_sdi", "omapdss"),
+ REGULATOR_SUPPLY("vdds_sdi", "omap_display"),
};
static struct regulator_consumer_supply rx51_vdac_supply[] = {
- REGULATOR_SUPPLY("vdda_dac", "omapdss"),
+ REGULATOR_SUPPLY("vdda_dac", "omap_venc"),
};
static struct regulator_init_data rx51_vaux1 = {
diff --git a/arch/arm/mach-omap2/board-rx51-video.c b/arch/arm/mach-omap2/board-rx51-video.c
index acd670054d9..89a66db8b77 100644
--- a/arch/arm/mach-omap2/board-rx51-video.c
+++ b/arch/arm/mach-omap2/board-rx51-video.c
@@ -66,18 +66,6 @@ static struct omap_dss_board_info rx51_dss_board_info = {
.default_device = &rx51_lcd_device,
};
-struct platform_device rx51_display_device = {
- .name = "omapdss",
- .id = -1,
- .dev = {
- .platform_data = &rx51_dss_board_info,
- },
-};
-
-static struct platform_device *rx51_video_devices[] __initdata = {
- &rx51_display_device,
-};
-
static int __init rx51_video_init(void)
{
if (!machine_is_nokia_rx51())
@@ -95,8 +83,7 @@ static int __init rx51_video_init(void)
gpio_direction_output(RX51_LCD_RESET_GPIO, 1);
- platform_add_devices(rx51_video_devices,
- ARRAY_SIZE(rx51_video_devices));
+ omap_display_init(&rx51_dss_board_info);
return 0;
}
diff --git a/arch/arm/mach-omap2/board-zoom-display.c b/arch/arm/mach-omap2/board-zoom-display.c
index 6bcd43657ae..37b84c2b850 100644
--- a/arch/arm/mach-omap2/board-zoom-display.c
+++ b/arch/arm/mach-omap2/board-zoom-display.c
@@ -130,14 +130,6 @@ static struct omap_dss_board_info zoom_dss_data = {
.default_device = &zoom_lcd_device,
};
-static struct platform_device zoom_dss_device = {
- .name = "omapdss",
- .id = -1,
- .dev = {
- .platform_data = &zoom_dss_data,
- },
-};
-
static struct omap2_mcspi_device_config dss_lcd_mcspi_config = {
.turbo_mode = 1,
.single_channel = 1, /* 0: slave, 1: master */
@@ -153,14 +145,9 @@ static struct spi_board_info nec_8048_spi_board_info[] __initdata = {
},
};
-static struct platform_device *zoom_display_devices[] __initdata = {
- &zoom_dss_device,
-};
-
void __init zoom_display_init(void)
{
- platform_add_devices(zoom_display_devices,
- ARRAY_SIZE(zoom_display_devices));
+ omap_display_init(&zoom_dss_data);
spi_register_board_info(nec_8048_spi_board_info,
ARRAY_SIZE(nec_8048_spi_board_info));
zoom_lcd_panel_init();
diff --git a/arch/arm/mach-omap2/board-zoom-peripherals.c b/arch/arm/mach-omap2/board-zoom-peripherals.c
index e0e040f34c6..780a99c4359 100644
--- a/arch/arm/mach-omap2/board-zoom-peripherals.c
+++ b/arch/arm/mach-omap2/board-zoom-peripherals.c
@@ -226,11 +226,13 @@ static struct omap2_hsmmc_info mmc[] = {
{} /* Terminator */
};
-static struct regulator_consumer_supply zoom_vpll2_supply =
- REGULATOR_SUPPLY("vdds_dsi", "omapdss");
+static struct regulator_consumer_supply zoom_vpll2_supplies[] = {
+ REGULATOR_SUPPLY("vdds_dsi", "omap_display"),
+ REGULATOR_SUPPLY("vdds_dsi", "omap_dsi1"),
+};
static struct regulator_consumer_supply zoom_vdda_dac_supply =
- REGULATOR_SUPPLY("vdda_dac", "omapdss");
+ REGULATOR_SUPPLY("vdda_dac", "omap_venc");
static struct regulator_init_data zoom_vpll2 = {
.constraints = {
@@ -241,8 +243,8 @@ static struct regulator_init_data zoom_vpll2 = {
.valid_ops_mask = REGULATOR_CHANGE_MODE
| REGULATOR_CHANGE_STATUS,
},
- .num_consumer_supplies = 1,
- .consumer_supplies = &zoom_vpll2_supply,
+ .num_consumer_supplies = ARRAY_SIZE(zoom_vpll2_supplies),
+ .consumer_supplies = zoom_vpll2_supplies,
};
static struct regulator_init_data zoom_vdac = {
diff --git a/arch/arm/mach-omap2/board-zoom.c b/arch/arm/mach-omap2/board-zoom.c
index e26754c24ee..6bd364afe66 100644
--- a/arch/arm/mach-omap2/board-zoom.c
+++ b/arch/arm/mach-omap2/board-zoom.c
@@ -30,6 +30,24 @@
#include "mux.h"
#include "sdram-micron-mt46h32m32lf-6.h"
#include "sdram-hynix-h8mbx00u0mer-0em.h"
+#include "pm.h"
+
+static struct cpuidle_params omap36xx_cpuidle_params_table[] = {
+ /* C1 */
+ {1, 74, 78, 152},
+ /* C2 */
+ {0, 165, 90, 255},
+ /* C3 */
+ {1, 163, 180, 345},
+ /* C4 */
+ {0, 2852, 605, 3457},
+ /* C5 */
+ {1, 800, 366, 2120},
+ /* C6 */
+ {0, 4080, 801, 4881},
+ /* C7 */
+ {1, 4300, 8794, 159000},
+};
#define ZOOM3_EHCI_RESET_GPIO 64
@@ -126,6 +144,7 @@ static void __init omap_zoom_init(void)
usb_ehci_init(&ehci_pdata);
}
+ omap3_pm_init_cpuidle(omap36xx_cpuidle_params_table);
board_nand_init(zoom_nand_partitions,
ARRAY_SIZE(zoom_nand_partitions), ZOOM_NAND_CS);
zoom_debugboard_init();
diff --git a/arch/arm/mach-omap2/clock2420_data.c b/arch/arm/mach-omap2/clock2420_data.c
index 0a992bc8d0d..dd9fd87a731 100644
--- a/arch/arm/mach-omap2/clock2420_data.c
+++ b/arch/arm/mach-omap2/clock2420_data.c
@@ -1786,10 +1786,10 @@ static struct omap_clk omap2420_clks[] = {
CLK(NULL, "gfx_2d_fck", &gfx_2d_fck, CK_242X),
CLK(NULL, "gfx_ick", &gfx_ick, CK_242X),
/* DSS domain clocks */
- CLK("omapdss", "ick", &dss_ick, CK_242X),
- CLK("omapdss", "dss1_fck", &dss1_fck, CK_242X),
- CLK("omapdss", "dss2_fck", &dss2_fck, CK_242X),
- CLK("omapdss", "tv_fck", &dss_54m_fck, CK_242X),
+ CLK("omap_dss", "ick", &dss_ick, CK_242X),
+ CLK("omap_dss", "fck", &dss1_fck, CK_242X),
+ CLK("omap_dss", "sys_clk", &dss2_fck, CK_242X),
+ CLK("omap_dss", "tv_clk", &dss_54m_fck, CK_242X),
/* L3 domain clocks */
CLK(NULL, "core_l3_ck", &core_l3_ck, CK_242X),
CLK(NULL, "ssi_fck", &ssi_ssr_sst_fck, CK_242X),
@@ -1799,6 +1799,7 @@ static struct omap_clk omap2420_clks[] = {
CLK(NULL, "ssi_l4_ick", &ssi_l4_ick, CK_242X),
/* virtual meta-group clock */
CLK(NULL, "virt_prcm_set", &virt_prcm_set, CK_242X),
+ CLK(NULL, "cpu_ck", &virt_prcm_set, CK_242X),
/* general l4 interface ck, multi-parent functional clk */
CLK(NULL, "gpt1_ick", &gpt1_ick, CK_242X),
CLK(NULL, "gpt1_fck", &gpt1_fck, CK_242X),
diff --git a/arch/arm/mach-omap2/clock2430_data.c b/arch/arm/mach-omap2/clock2430_data.c
index c047dcd007e..c698c1c8778 100644
--- a/arch/arm/mach-omap2/clock2430_data.c
+++ b/arch/arm/mach-omap2/clock2430_data.c
@@ -1890,10 +1890,10 @@ static struct omap_clk omap2430_clks[] = {
CLK(NULL, "mdm_ick", &mdm_ick, CK_243X),
CLK(NULL, "mdm_osc_ck", &mdm_osc_ck, CK_243X),
/* DSS domain clocks */
- CLK("omapdss", "ick", &dss_ick, CK_243X),
- CLK("omapdss", "dss1_fck", &dss1_fck, CK_243X),
- CLK("omapdss", "dss2_fck", &dss2_fck, CK_243X),
- CLK("omapdss", "tv_fck", &dss_54m_fck, CK_243X),
+ CLK("omap_dss", "ick", &dss_ick, CK_243X),
+ CLK("omap_dss", "fck", &dss1_fck, CK_243X),
+ CLK("omap_dss", "sys_clk", &dss2_fck, CK_243X),
+ CLK("omap_dss", "tv_clk", &dss_54m_fck, CK_243X),
/* L3 domain clocks */
CLK(NULL, "core_l3_ck", &core_l3_ck, CK_243X),
CLK(NULL, "ssi_fck", &ssi_ssr_sst_fck, CK_243X),
@@ -1903,6 +1903,7 @@ static struct omap_clk omap2430_clks[] = {
CLK(NULL, "ssi_l4_ick", &ssi_l4_ick, CK_243X),
/* virtual meta-group clock */
CLK(NULL, "virt_prcm_set", &virt_prcm_set, CK_243X),
+ CLK(NULL, "cpu_ck", &virt_prcm_set, CK_243X),
/* general l4 interface ck, multi-parent functional clk */
CLK(NULL, "gpt1_ick", &gpt1_ick, CK_243X),
CLK(NULL, "gpt1_fck", &gpt1_fck, CK_243X),
diff --git a/arch/arm/mach-omap2/clock3xxx_data.c b/arch/arm/mach-omap2/clock3xxx_data.c
index 403a4a1d3f9..b1c484cd891 100644
--- a/arch/arm/mach-omap2/clock3xxx_data.c
+++ b/arch/arm/mach-omap2/clock3xxx_data.c
@@ -3224,6 +3224,7 @@ static struct omap_clk omap3xxx_clks[] = {
CLK(NULL, "mcbsp_clks", &mcbsp_clks, CK_3XXX),
CLK(NULL, "sys_clkout1", &sys_clkout1, CK_3XXX),
CLK(NULL, "dpll1_ck", &dpll1_ck, CK_3XXX),
+ CLK(NULL, "cpu_ck", &dpll1_ck, CK_3XXX),
CLK(NULL, "dpll1_x2_ck", &dpll1_x2_ck, CK_3XXX),
CLK(NULL, "dpll1_x2m2_ck", &dpll1_x2m2_ck, CK_3XXX),
CLK(NULL, "dpll2_ck", &dpll2_ck, CK_34XX | CK_36XX),
@@ -3357,13 +3358,13 @@ static struct omap_clk omap3xxx_clks[] = {
CLK("omap_rng", "ick", &rng_ick, CK_34XX | CK_36XX),
CLK(NULL, "sha11_ick", &sha11_ick, CK_34XX | CK_36XX),
CLK(NULL, "des1_ick", &des1_ick, CK_34XX | CK_36XX),
- CLK("omapdss", "dss1_fck", &dss1_alwon_fck_3430es1, CK_3430ES1),
- CLK("omapdss", "dss1_fck", &dss1_alwon_fck_3430es2, CK_3430ES2PLUS | CK_AM35XX | CK_36XX),
- CLK("omapdss", "tv_fck", &dss_tv_fck, CK_3XXX),
- CLK("omapdss", "video_fck", &dss_96m_fck, CK_3XXX),
- CLK("omapdss", "dss2_fck", &dss2_alwon_fck, CK_3XXX),
- CLK("omapdss", "ick", &dss_ick_3430es1, CK_3430ES1),
- CLK("omapdss", "ick", &dss_ick_3430es2, CK_3430ES2PLUS | CK_AM35XX | CK_36XX),
+ CLK("omap_dss", "fck", &dss1_alwon_fck_3430es1, CK_3430ES1),
+ CLK("omap_dss", "fck", &dss1_alwon_fck_3430es2, CK_3430ES2PLUS | CK_AM35XX | CK_36XX),
+ CLK("omap_dss", "tv_clk", &dss_tv_fck, CK_3XXX),
+ CLK("omap_dss", "video_clk", &dss_96m_fck, CK_3XXX),
+ CLK("omap_dss", "sys_clk", &dss2_alwon_fck, CK_3XXX),
+ CLK("omap_dss", "ick", &dss_ick_3430es1, CK_3430ES1),
+ CLK("omap_dss", "ick", &dss_ick_3430es2, CK_3430ES2PLUS | CK_AM35XX | CK_36XX),
CLK(NULL, "cam_mclk", &cam_mclk, CK_34XX | CK_36XX),
CLK(NULL, "cam_ick", &cam_ick, CK_34XX | CK_36XX),
CLK(NULL, "csi2_96m_fck", &csi2_96m_fck, CK_34XX | CK_36XX),
diff --git a/arch/arm/mach-omap2/clock44xx_data.c b/arch/arm/mach-omap2/clock44xx_data.c
index de9ec8ddd2a..95f2c4c9503 100644
--- a/arch/arm/mach-omap2/clock44xx_data.c
+++ b/arch/arm/mach-omap2/clock44xx_data.c
@@ -3057,6 +3057,7 @@ static struct omap_clk omap44xx_clks[] = {
CLK(NULL, "dpll_iva_m4x2_ck", &dpll_iva_m4x2_ck, CK_443X),
CLK(NULL, "dpll_iva_m5x2_ck", &dpll_iva_m5x2_ck, CK_443X),
CLK(NULL, "dpll_mpu_ck", &dpll_mpu_ck, CK_443X),
+ CLK(NULL, "cpu_ck", &dpll_mpu_ck, CK_443X),
CLK(NULL, "dpll_mpu_m2_ck", &dpll_mpu_m2_ck, CK_443X),
CLK(NULL, "per_hs_clk_div_ck", &per_hs_clk_div_ck, CK_443X),
CLK(NULL, "per_hsd_byp_clk_mux_ck", &per_hsd_byp_clk_mux_ck, CK_443X),
@@ -3106,11 +3107,16 @@ static struct omap_clk omap44xx_clks[] = {
CLK(NULL, "dmic_sync_mux_ck", &dmic_sync_mux_ck, CK_443X),
CLK(NULL, "dmic_fck", &dmic_fck, CK_443X),
CLK(NULL, "dsp_fck", &dsp_fck, CK_443X),
- CLK(NULL, "dss_sys_clk", &dss_sys_clk, CK_443X),
- CLK(NULL, "dss_tv_clk", &dss_tv_clk, CK_443X),
- CLK(NULL, "dss_dss_clk", &dss_dss_clk, CK_443X),
- CLK(NULL, "dss_48mhz_clk", &dss_48mhz_clk, CK_443X),
- CLK(NULL, "dss_fck", &dss_fck, CK_443X),
+ CLK("omap_dss", "sys_clk", &dss_sys_clk, CK_443X),
+ CLK("omap_dss", "tv_clk", &dss_tv_clk, CK_443X),
+ CLK("omap_dss", "dss_clk", &dss_dss_clk, CK_443X),
+ CLK("omap_dss", "video_clk", &dss_48mhz_clk, CK_443X),
+ CLK("omap_dss", "fck", &dss_fck, CK_443X),
+ /*
+ * On OMAP4, DSS ick is a dummy clock; this is needed for compatibility
+ * with OMAP2/3.
+ */
+ CLK("omap_dss", "ick", &dummy_ck, CK_443X),
CLK(NULL, "efuse_ctrl_cust_fck", &efuse_ctrl_cust_fck, CK_443X),
CLK(NULL, "emif1_fck", &emif1_fck, CK_443X),
CLK(NULL, "emif2_fck", &emif2_fck, CK_443X),
diff --git a/arch/arm/mach-omap2/cpuidle34xx.c b/arch/arm/mach-omap2/cpuidle34xx.c
index f7b22a16f38..bc9bcac2ec0 100644
--- a/arch/arm/mach-omap2/cpuidle34xx.c
+++ b/arch/arm/mach-omap2/cpuidle34xx.c
@@ -51,6 +51,7 @@
struct omap3_processor_cx {
u8 valid;
+ u8 enabled;
u8 type;
u32 sleep_latency;
u32 wakeup_latency;
@@ -139,19 +140,9 @@ static int omap3_enter_idle(struct cpuidle_device *dev,
if (omap_irq_pending() || need_resched())
goto return_sleep_time;
- if (cx->type == OMAP3_STATE_C1) {
- pwrdm_for_each_clkdm(mpu_pd, _cpuidle_deny_idle);
- pwrdm_for_each_clkdm(core_pd, _cpuidle_deny_idle);
- }
-
/* Execute ARM wfi */
omap_sram_idle();
- if (cx->type == OMAP3_STATE_C1) {
- pwrdm_for_each_clkdm(mpu_pd, _cpuidle_allow_idle);
- pwrdm_for_each_clkdm(core_pd, _cpuidle_allow_idle);
- }
-
return_sleep_time:
getnstimeofday(&ts_postidle);
ts_idle = timespec_sub(ts_postidle, ts_preidle);
@@ -283,8 +274,18 @@ static int omap3_enter_idle_bm(struct cpuidle_device *dev,
select_state:
dev->last_state = new_state;
+
+ if (new_state == dev->safe_state) {
+ pwrdm_for_each_clkdm(mpu_pd, _cpuidle_deny_idle);
+ pwrdm_for_each_clkdm(core_pd, _cpuidle_deny_idle);
+ }
ret = omap3_enter_idle(dev, new_state);
+ if (new_state == dev->safe_state) {
+ pwrdm_for_each_clkdm(mpu_pd, _cpuidle_allow_idle);
+ pwrdm_for_each_clkdm(core_pd, _cpuidle_allow_idle);
+ }
+
/* Restore original PER state if it was modified */
if (per_next_state != per_saved_state)
pwrdm_set_next_pwrst(per_pd, per_saved_state);
@@ -309,12 +310,13 @@ void omap3_cpuidle_update_states(u32 mpu_deepest_state, u32 core_deepest_state)
for (i = OMAP3_STATE_C1; i < OMAP3_MAX_STATES; i++) {
struct omap3_processor_cx *cx = &omap3_power_states[i];
-
- if ((cx->mpu_state >= mpu_deepest_state) &&
- (cx->core_state >= core_deepest_state)) {
- cx->valid = 1;
- } else {
- cx->valid = 0;
+ if (cx->enabled) {
+ if ((cx->mpu_state >= mpu_deepest_state) &&
+ (cx->core_state >= core_deepest_state)) {
+ cx->valid = 1;
+ } else {
+ cx->valid = 0;
+ }
}
}
}
@@ -355,6 +357,8 @@ void omap_init_power_states(void)
/* C1 . MPU WFI + Core active */
omap3_power_states[OMAP3_STATE_C1].valid =
cpuidle_params_table[OMAP3_STATE_C1].valid;
+ omap3_power_states[OMAP3_STATE_C1].enabled =
+ cpuidle_params_table[OMAP3_STATE_C1].valid;
omap3_power_states[OMAP3_STATE_C1].type = OMAP3_STATE_C1;
omap3_power_states[OMAP3_STATE_C1].sleep_latency =
cpuidle_params_table[OMAP3_STATE_C1].sleep_latency;
@@ -369,6 +373,8 @@ void omap_init_power_states(void)
/* C2 . MPU WFI + Core inactive */
omap3_power_states[OMAP3_STATE_C2].valid =
cpuidle_params_table[OMAP3_STATE_C2].valid;
+ omap3_power_states[OMAP3_STATE_C2].enabled =
+ cpuidle_params_table[OMAP3_STATE_C2].valid;
omap3_power_states[OMAP3_STATE_C2].type = OMAP3_STATE_C2;
omap3_power_states[OMAP3_STATE_C2].sleep_latency =
cpuidle_params_table[OMAP3_STATE_C2].sleep_latency;
@@ -384,6 +390,8 @@ void omap_init_power_states(void)
/* C3 . MPU CSWR + Core inactive */
omap3_power_states[OMAP3_STATE_C3].valid =
cpuidle_params_table[OMAP3_STATE_C3].valid;
+ omap3_power_states[OMAP3_STATE_C3].enabled =
+ cpuidle_params_table[OMAP3_STATE_C3].valid;
omap3_power_states[OMAP3_STATE_C3].type = OMAP3_STATE_C3;
omap3_power_states[OMAP3_STATE_C3].sleep_latency =
cpuidle_params_table[OMAP3_STATE_C3].sleep_latency;
@@ -399,6 +407,8 @@ void omap_init_power_states(void)
/* C4 . MPU OFF + Core inactive */
omap3_power_states[OMAP3_STATE_C4].valid =
cpuidle_params_table[OMAP3_STATE_C4].valid;
+ omap3_power_states[OMAP3_STATE_C4].enabled =
+ cpuidle_params_table[OMAP3_STATE_C4].valid;
omap3_power_states[OMAP3_STATE_C4].type = OMAP3_STATE_C4;
omap3_power_states[OMAP3_STATE_C4].sleep_latency =
cpuidle_params_table[OMAP3_STATE_C4].sleep_latency;
@@ -414,6 +424,8 @@ void omap_init_power_states(void)
/* C5 . MPU CSWR + Core CSWR*/
omap3_power_states[OMAP3_STATE_C5].valid =
cpuidle_params_table[OMAP3_STATE_C5].valid;
+ omap3_power_states[OMAP3_STATE_C5].enabled =
+ cpuidle_params_table[OMAP3_STATE_C5].valid;
omap3_power_states[OMAP3_STATE_C5].type = OMAP3_STATE_C5;
omap3_power_states[OMAP3_STATE_C5].sleep_latency =
cpuidle_params_table[OMAP3_STATE_C5].sleep_latency;
@@ -429,6 +441,8 @@ void omap_init_power_states(void)
/* C6 . MPU OFF + Core CSWR */
omap3_power_states[OMAP3_STATE_C6].valid =
cpuidle_params_table[OMAP3_STATE_C6].valid;
+ omap3_power_states[OMAP3_STATE_C6].enabled =
+ cpuidle_params_table[OMAP3_STATE_C6].valid;
omap3_power_states[OMAP3_STATE_C6].type = OMAP3_STATE_C6;
omap3_power_states[OMAP3_STATE_C6].sleep_latency =
cpuidle_params_table[OMAP3_STATE_C6].sleep_latency;
@@ -444,6 +458,8 @@ void omap_init_power_states(void)
/* C7 . MPU OFF + Core OFF */
omap3_power_states[OMAP3_STATE_C7].valid =
cpuidle_params_table[OMAP3_STATE_C7].valid;
+ omap3_power_states[OMAP3_STATE_C7].enabled =
+ cpuidle_params_table[OMAP3_STATE_C7].valid;
omap3_power_states[OMAP3_STATE_C7].type = OMAP3_STATE_C7;
omap3_power_states[OMAP3_STATE_C7].sleep_latency =
cpuidle_params_table[OMAP3_STATE_C7].sleep_latency;
@@ -463,6 +479,7 @@ void omap_init_power_states(void)
*/
if (IS_PM34XX_ERRATUM(PM_SDRC_WAKEUP_ERRATUM_i583)) {
omap3_power_states[OMAP3_STATE_C7].valid = 0;
+ omap3_power_states[OMAP3_STATE_C7].enabled = 0;
cpuidle_params_table[OMAP3_STATE_C7].valid = 0;
WARN_ONCE(1, "%s: core off state C7 disabled due to i583\n",
__func__);
diff --git a/arch/arm/mach-omap2/display.c b/arch/arm/mach-omap2/display.c
new file mode 100644
index 00000000000..cc7b4f3070d
--- /dev/null
+++ b/arch/arm/mach-omap2/display.c
@@ -0,0 +1,103 @@
+/*
+ * OMAP2plus display device setup / initialization.
+ *
+ * Copyright (C) 2010 Texas Instruments Incorporated - http://www.ti.com/
+ * Senthilvadivu Guruswamy
+ * Sumit Semwal
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed "as is" WITHOUT ANY WARRANTY of any
+ * kind, whether express or implied; without even the implied warranty
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/platform_device.h>
+#include <linux/io.h>
+#include <linux/clk.h>
+#include <linux/err.h>
+
+#include <plat/display.h>
+#include <plat/omap_hwmod.h>
+#include <plat/omap_device.h>
+
+static struct platform_device omap_display_device = {
+ .name = "omap_display",
+ .id = -1,
+ .dev = {
+ .platform_data = NULL,
+ },
+};
+
+static struct omap_device_pm_latency omap_dss_latency[] = {
+ [0] = {
+ .deactivate_func = omap_device_idle_hwmods,
+ .activate_func = omap_device_enable_hwmods,
+ .flags = OMAP_DEVICE_LATENCY_AUTO_ADJUST,
+ },
+};
+
+int __init omap_display_init(struct omap_dss_board_info
+ *board_data)
+{
+ int r = 0;
+ struct omap_hwmod *oh;
+ struct omap_device *od;
+ int i;
+ struct omap_display_platform_data pdata;
+
+ /*
+ * omap: valid DSS hwmod names
+ * omap2,3,4: dss_core, dss_dispc, dss_rfbi, dss_venc
+ * omap3,4: dss_dsi1
+ * omap4: dss_dsi2, dss_hdmi
+ */
+ char *oh_name[] = {"dss_core", "dss_dispc", "dss_rfbi", "dss_venc", "dss_dsi1",
+ "dss_dsi2", "dss_hdmi"};
+ char *dev_name[] = {"omap_dss", "omap_dispc", "omap_rfbi", "omap_venc", "omap_dsi1",
+ "omap_dsi2", "omap_hdmi"};
+ int oh_count;
+
+ memset(&pdata, 0, sizeof(pdata));
+
+ if (cpu_is_omap24xx())
+ oh_count = ARRAY_SIZE(oh_name) - 3;
+ /* last 3 hwmod dev in oh_name are not available for omap2 */
+ else if (cpu_is_omap44xx())
+ oh_count = ARRAY_SIZE(oh_name);
+ else
+ oh_count = ARRAY_SIZE(oh_name) - 2;
+ /* last 2 hwmod dev in oh_name are not available for omap3 */
+
+
+ pdata.board_data = board_data;
+ pdata.board_data->get_last_off_on_transaction_id = NULL;
+
+ for (i = 0; i < oh_count; i++) {
+ oh = omap_hwmod_lookup(oh_name[i]);
+ if (!oh) {
+ pr_err("Could not look up %s\n", oh_name[i]);
+ return -ENODEV;
+ }
+ od = omap_device_build(dev_name[i], -1, oh, &pdata,
+ sizeof(struct omap_display_platform_data),
+ omap_dss_latency,
+ ARRAY_SIZE(omap_dss_latency), 0);
+
+ if (WARN((IS_ERR(od)), "Could not build omap_device for %s\n",
+ oh_name[i]))
+ return -ENODEV;
+ }
+ omap_display_device.dev.platform_data = board_data;
+
+ r = platform_device_register(&omap_display_device);
+ if (r < 0)
+ printk(KERN_ERR "Unable to register OMAP-Display device\n");
+
+ return r;
+}
diff --git a/arch/arm/mach-omap2/dvfs.c b/arch/arm/mach-omap2/dvfs.c
new file mode 100644
index 00000000000..fb9215cb927
--- /dev/null
+++ b/arch/arm/mach-omap2/dvfs.c
@@ -0,0 +1,770 @@
+/*
+ * OMAP3/OMAP4 DVFS Management Routines
+ *
+ * Author: Vishwanath BS <vishwanath.bs@ti.com>
+ *
+ * Copyright (C) 2011 Texas Instruments, Inc.
+ * Vishwanath BS <vishwanath.bs@ti.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/err.h>
+#include <linux/spinlock.h>
+#include <linux/plist.h>
+#include <linux/slab.h>
+#include <linux/opp.h>
+#include <plat/common.h>
+#include <plat/voltage.h>
+#include <plat/omap_device.h>
+#include <plat/smartreflex.h>
+
+/**
+ * struct omap_dev_user_list - Structure maitain userlist per device
+ *
+ * @dev: The device requesting for a particular frequency
+ * @node: The list head entry
+ * @freq: frequency being requested
+ *
+ * Using this structure, user list (requesting dev * and frequency) for
+ * each device is maintained. This is how we can have different devices
+ * at different frequencies (to support frequency locking and throttling).
+ * Even if one of the devices in a given vdd has locked it's frequency,
+ * other's can still scale their frequency using this list.
+ * If no one has placed a frequency request for a device, then device is
+ * set to the frequency from it's opp table.
+ */
+struct omap_dev_user_list {
+ struct device *dev;
+ struct plist_node node;
+ u32 freq;
+};
+
+/**
+ * struct omap_vdd_dev_list - Device list per vdd
+ *
+ * @dev: The device belonging to a particular vdd
+ * @node: The list head entry
+ */
+struct omap_vdd_dev_list {
+ struct device *dev;
+ struct list_head node;
+ struct plist_head user_list;
+ spinlock_t user_lock; /* spinlock for plist */
+};
+
+/**
+ * struct omap_vdd_user_list - The per vdd user list
+ *
+ * @dev: The device asking for the vdd to be set at a particular
+ * voltage
+ * @node: The list head entry
+ * @volt: The voltage requested by the device <dev>
+ */
+struct omap_vdd_user_list {
+ struct device *dev;
+ struct plist_node node;
+ u32 volt;
+};
+
+/**
+ * struct omap_vdd_dvfs_info - The per vdd dvfs info
+ *
+ * @user_lock: spinlock for plist operations
+ * @user_list: The vdd user list
+ * @scaling_mutex: Mutex for protecting dvfs data structures for a vdd
+ * @voltdm: Voltage domains for which dvfs info stored
+ *
+ * This is a fundamental structure used to store all the required
+ * DVFS related information for a vdd.
+ */
+struct omap_vdd_dvfs_info {
+ spinlock_t user_lock; /* spin lock */
+ struct plist_head user_list;
+ struct mutex scaling_mutex; /* dvfs mutex */
+ struct voltagedomain *voltdm;
+ struct list_head dev_list;
+ struct device vdd_device;
+};
+
+static struct omap_vdd_dvfs_info *omap_dvfs_info_list;
+static int omap_nr_vdd;
+
+static struct voltagedomain omap3_vdd[] = {
+ {
+ .name = "mpu",
+ },
+ {
+ .name = "core",
+ },
+};
+
+static struct voltagedomain omap4_vdd[] = {
+ {
+ .name = "mpu",
+ },
+ {
+ .name = "iva",
+ },
+ {
+ .name = "core",
+ },
+};
+
+static int omap_dvfs_voltage_scale(struct omap_vdd_dvfs_info *dvfs_info);
+
+static int __init omap_dvfs_init(void);
+
+static struct omap_vdd_dvfs_info *get_dvfs_info(struct voltagedomain *voltdm)
+{
+ int i;
+ if (!voltdm || !omap_dvfs_info_list)
+ return NULL;
+
+ for (i = 0; i < omap_nr_vdd; i++)
+ if (omap_dvfs_info_list[i].voltdm == voltdm)
+ return &omap_dvfs_info_list[i];
+
+ pr_warning("%s: unable find dvfs info for vdd %s\n",
+ __func__, voltdm->name);
+ return NULL;
+}
+
+/**
+ * omap_dvfs_find_voltage() - search for given voltage
+ * @dev: device pointer associated with the opp type
+ * @volt: voltage to search for
+ *
+ * Searches for exact match in the opp list and returns handle to the matching
+ * opp if found, else returns ERR_PTR in case of error and should be handled
+ * using IS_ERR. If there are multiple opps with same voltage, it will return
+ * the first available entry.
+ */
+static struct opp *omap_dvfs_find_voltage(struct device *dev,
+ unsigned long volt)
+{
+ struct opp *opp = ERR_PTR(-ENODEV);
+ unsigned long f = 0;
+
+ do {
+ opp = opp_find_freq_ceil(dev, &f);
+ if (IS_ERR(opp))
+ break;
+ if (opp_get_voltage(opp) >= volt)
+ break;
+ f++;
+ } while (1);
+
+ return opp;
+}
+
+/**
+ * omap_dvfs_add_vdd_user() - Add a voltage request
+ * @dvfs_info: omap_vdd_dvfs_info pointer for the required vdd
+ * @dev: device making the request
+ * @volt: requesting voltage in uV
+ *
+ * Adds the given devices' voltage request into corresponding
+ * vdd's omap_vdd_dvfs_info user list (plist). This list is used
+ * to find the maximum voltage request for a given vdd.
+ *
+ * Returns 0 on success.
+ */
+static int omap_dvfs_add_vdd_user(struct omap_vdd_dvfs_info *dvfs_info,
+ struct device *dev, unsigned long volt)
+{
+ struct omap_vdd_user_list *user = NULL, *temp_user;
+ struct plist_node *node;
+
+ if (!dvfs_info || IS_ERR(dvfs_info)) {
+ dev_warn(dev, "%s: VDD specified does not exist!\n", __func__);
+ return -EINVAL;
+ }
+
+ mutex_lock(&dvfs_info->scaling_mutex);
+
+ plist_for_each_entry(temp_user, &dvfs_info->user_list, node) {
+ if (temp_user->dev == dev) {
+ user = temp_user;
+ break;
+ }
+ }
+
+ if (!user) {
+ user = kzalloc(sizeof(struct omap_vdd_user_list), GFP_KERNEL);
+ if (!user) {
+ dev_err(dev, "%s: Unable to creat a new user for vdd_%s\n",
+ __func__, dvfs_info->voltdm->name);
+ mutex_unlock(&dvfs_info->scaling_mutex);
+ return -ENOMEM;
+ }
+ user->dev = dev;
+ } else {
+ plist_del(&user->node, &dvfs_info->user_list);
+ }
+
+ plist_node_init(&user->node, volt);
+ plist_add(&user->node, &dvfs_info->user_list);
+ node = plist_last(&dvfs_info->user_list);
+ user->volt = node->prio;
+
+ mutex_unlock(&dvfs_info->scaling_mutex);
+
+ return 0;
+}
+
+/**
+ * omap_dvfs_remove_vdd_user() - Remove a voltage request
+ * @dvfs_info: omap_vdd_dvfs_info pointer for the required vdd
+ * @dev: device making the request
+ *
+ * Removes the given devices' voltage request from corresponding
+ * vdd's omap_vdd_dvfs_info user list (plist).
+ *
+ * Returns 0 on success.
+ */
+static int omap_dvfs_remove_vdd_user(struct omap_vdd_dvfs_info *dvfs_info,
+ struct device *dev)
+{
+ struct omap_vdd_user_list *user = NULL, *temp_user;
+ int ret = 0;
+
+ if (!dvfs_info || IS_ERR(dvfs_info)) {
+ dev_err(dev, "%s: VDD specified does not exist!\n", __func__);
+ return -EINVAL;
+ }
+
+ mutex_lock(&dvfs_info->scaling_mutex);
+
+ plist_for_each_entry(temp_user, &dvfs_info->user_list, node) {
+ if (temp_user->dev == dev) {
+ user = temp_user;
+ break;
+ }
+ }
+
+ if (user)
+ plist_del(&user->node, &dvfs_info->user_list);
+ else {
+ dev_err(dev, "%s: Unable to find the user for vdd_%s\n",
+ __func__, dvfs_info->voltdm->name);
+ ret = -ENOMEM;
+ }
+ mutex_unlock(&dvfs_info->scaling_mutex);
+
+ return ret;
+}
+
+/**
+ * omap_dvfs_register_device - Add a device into voltage domain
+ * @voltdm: voltage domain to which the device is to be added
+ * @dev: Device to be added
+ *
+ * This API will add a given device into user_list of corresponding
+ * vdd's omap_vdd_dvfs_info strucure. This list is traversed to scale
+ * frequencies of all the devices on a given vdd. This api is called
+ * while hwmod db is built for an omap_device.
+ *
+ * Returns 0 on success.
+ */
+int omap_dvfs_register_device(struct voltagedomain *voltdm, struct device *dev)
+{
+ struct omap_vdd_dev_list *temp_dev;
+ struct omap_vdd_dvfs_info *dvfs_info = get_dvfs_info(voltdm);
+
+ if (!voltdm || IS_ERR(voltdm) || !dvfs_info) {
+ dev_warn(dev, "%s: VDD specified does not exist!\n", __func__);
+ return -EINVAL;
+ }
+
+ list_for_each_entry(temp_dev, &dvfs_info->dev_list, node) {
+ if (temp_dev->dev == dev) {
+ dev_warn(dev, "%s: Device already added to vdee_%s\n",
+ __func__, dvfs_info->voltdm->name);
+ return -EINVAL;
+ }
+ }
+
+ temp_dev = kzalloc(sizeof(struct omap_vdd_dev_list), GFP_KERNEL);
+ if (!temp_dev) {
+ dev_err(dev, "%s: Unable to creat a new device for vdd_%s\n",
+ __func__, dvfs_info->voltdm->name);
+ return -ENOMEM;
+ }
+
+ /* Initialize priority ordered list */
+ spin_lock_init(&temp_dev->user_lock);
+ plist_head_init(&temp_dev->user_list, &temp_dev->user_lock);
+
+ temp_dev->dev = dev;
+ list_add(&temp_dev->node, &dvfs_info->dev_list);
+
+ return 0;
+}
+
+/**
+ * omap_dvfs_add_freq_request() - add a requested device frequency
+ *
+ *
+ * @dvfs_info: omap_vdd_dvfs_info pointer for the required vdd
+ * @req_dev: device making the request
+ * @target_dev: target device for which frequency request is being made
+ * @freq: target device frequency
+ *
+ * This API adds a requested frequency into target's device frequency list.
+ *
+ * Returns 0 on success.
+ */
+static int omap_dvfs_add_freq_request(struct omap_vdd_dvfs_info *dvfs_info,
+ struct device *req_dev, struct device *target_dev, unsigned long freq)
+{
+ struct omap_dev_user_list *dev_user = NULL, *tmp_user;
+ struct omap_vdd_dev_list *temp_dev;
+
+ if (!dvfs_info || IS_ERR(dvfs_info)) {
+ dev_warn(target_dev, "%s: VDD specified does not exist!\n",
+ __func__);
+ return -EINVAL;
+ }
+
+ mutex_lock(&dvfs_info->scaling_mutex);
+
+ list_for_each_entry(temp_dev, &dvfs_info->dev_list, node) {
+ if (temp_dev->dev == target_dev)
+ break;
+ }
+
+ if (temp_dev->dev != target_dev) {
+ dev_warn(target_dev, "%s: target_dev does not exist!\n",
+ __func__);
+ mutex_unlock(&dvfs_info->scaling_mutex);
+ return -EINVAL;
+ }
+
+ plist_for_each_entry(tmp_user, &temp_dev->user_list, node) {
+ if (tmp_user->dev == req_dev) {
+ dev_user = tmp_user;
+ break;
+ }
+ }
+
+ if (!dev_user) {
+ dev_user = kzalloc(sizeof(struct omap_dev_user_list),
+ GFP_KERNEL);
+ if (!dev_user) {
+ dev_err(target_dev, "%s: Unable to creat a new user for vdd_%s\n",
+ __func__, dvfs_info->voltdm->name);
+ mutex_unlock(&dvfs_info->scaling_mutex);
+ return -ENOMEM;
+ }
+ dev_user->dev = req_dev;
+ } else {
+ plist_del(&dev_user->node, &temp_dev->user_list);
+ }
+
+ plist_node_init(&dev_user->node, freq);
+ plist_add(&dev_user->node, &temp_dev->user_list);
+
+ mutex_unlock(&dvfs_info->scaling_mutex);
+ return 0;
+}
+
+/**
+ * omap_dvfs_remove_freq_request() - Remove the requested device frequency
+ *
+ * @dvfs_info: omap_vdd_dvfs_info pointer for the required vdd
+ * @req_dev: device removing the request
+ * @target_dev: target device from which frequency request is being removed
+ *
+ * This API removes a requested frequency from target's device frequency list.
+ *
+ * Returns 0 on success.
+ */
+
+static int omap_dvfs_remove_freq_request(struct omap_vdd_dvfs_info *dvfs_info,
+ struct device *req_dev, struct device *target_dev)
+{
+ struct omap_dev_user_list *dev_user = NULL, *tmp_user;
+ int ret = 0;
+ struct omap_vdd_dev_list *temp_dev;
+
+ if (!dvfs_info || IS_ERR(dvfs_info)) {
+ dev_warn(target_dev, "%s: VDD specified does not exist!\n",
+ __func__);
+ return -EINVAL;
+ }
+
+ mutex_lock(&dvfs_info->scaling_mutex);
+
+ list_for_each_entry(temp_dev, &dvfs_info->dev_list, node) {
+ if (temp_dev->dev == target_dev)
+ break;
+ }
+
+ if (temp_dev->dev != target_dev) {
+ dev_warn(target_dev, "%s: target_dev does not exist!\n",
+ __func__);
+ mutex_unlock(&dvfs_info->scaling_mutex);
+ return -EINVAL;
+ }
+
+ plist_for_each_entry(tmp_user, &temp_dev->user_list, node) {
+ if (tmp_user->dev == req_dev) {
+ dev_user = tmp_user;
+ break;
+ }
+ }
+
+ if (dev_user)
+ plist_del(&dev_user->node, &temp_dev->user_list);
+ else {
+ dev_err(target_dev, "%s: Unable to remove the user for vdd_%s\n",
+ __func__, dvfs_info->voltdm->name);
+ ret = -EINVAL;
+ }
+
+ return ret;
+}
+
+/* Calculate dependency vdd voltage for given vdd voltage */
+static int calc_dep_vdd_volt(struct device *dev,
+ struct omap_vdd_info *main_vdd, unsigned long main_volt)
+{
+ struct omap_vdd_dep_info *dep_vdds;
+ int i, ret = 0;
+
+ if (!main_vdd->dep_vdd_info) {
+ pr_debug("%s: No dependent VDD's for vdd_%s\n",
+ __func__, main_vdd->voltdm.name);
+ return 0;
+ }
+
+ dep_vdds = main_vdd->dep_vdd_info;
+
+ for (i = 0; i < main_vdd->nr_dep_vdd; i++) {
+ struct omap_vdd_dep_volt *volt_table = dep_vdds[i].dep_table;
+ int nr_volt = 0;
+ unsigned long dep_volt = 0, act_volt = 0;
+
+ while (volt_table[nr_volt].main_vdd_volt != 0) {
+ if (volt_table[nr_volt].main_vdd_volt == main_volt) {
+ dep_volt = volt_table[nr_volt].dep_vdd_volt;
+ break;
+ }
+ nr_volt++;
+ }
+ if (!dep_volt) {
+ pr_warning("%s: Not able to find a matching volt for"
+ "vdd_%s corresponding to vdd_%s %ld volt\n",
+ __func__, dep_vdds[i].name,
+ main_vdd->voltdm.name, main_volt);
+ ret = -EINVAL;
+ continue;
+ }
+
+ if (!dep_vdds[i].voltdm)
+ dep_vdds[i].voltdm =
+ omap_voltage_domain_lookup(dep_vdds[i].name);
+
+ act_volt = dep_volt;
+
+ /* See if dep_volt is possible for the vdd*/
+ ret = omap_dvfs_add_vdd_user(get_dvfs_info(dep_vdds[i].voltdm),
+ dev, act_volt);
+ }
+
+ return ret;
+}
+
+/* Scale dependent VDD */
+static int scale_dep_vdd(struct omap_vdd_dvfs_info *vdd_info)
+{
+ struct omap_vdd_dep_info *dep_vdds;
+ int i;
+ struct omap_vdd_info *main_vdd;
+ struct voltagedomain *voltdm = vdd_info->voltdm;
+ main_vdd = container_of(voltdm, struct omap_vdd_info, voltdm);
+
+ if (!main_vdd->dep_vdd_info) {
+ pr_debug("%s: No dependent VDD's for vdd_%s\n",
+ __func__, main_vdd->voltdm.name);
+ return 0;
+ }
+
+ dep_vdds = main_vdd->dep_vdd_info;
+
+ for (i = 0; i < main_vdd->nr_dep_vdd; i++)
+ omap_dvfs_voltage_scale(get_dvfs_info(dep_vdds[i].voltdm));
+
+ return 0;
+}
+
+/**
+ * omap_dvfs_voltage_scale() : API to scale the devices associated with a
+ * voltage domain vdd voltage.
+ *
+ * @dvfs_info: omap_vdd_dvfs_info pointer for the required vdd
+ *
+ * This API runs through the list of devices associated with the
+ * voltage domain and scales the device rates to the one requested
+ * by the user or those corresponding to the new voltage of the
+ * voltage domain. Target voltage is the highest voltage in the vdd_user_list.
+ *
+ * Returns 0 on success
+ * else the error value.
+ */
+static int omap_dvfs_voltage_scale(struct omap_vdd_dvfs_info *dvfs_info)
+{
+ unsigned long curr_volt;
+ int is_volt_scaled = 0;
+ struct omap_vdd_dev_list *temp_dev;
+ struct plist_node *node;
+ int ret = 0;
+ struct voltagedomain *voltdm;
+ unsigned long volt;
+ struct omap_vdd_info *vdd;
+
+ if (!dvfs_info || IS_ERR(dvfs_info)) {
+ pr_warning("%s: VDD specified does not exist!\n", __func__);
+ return -EINVAL;
+ }
+
+ voltdm = dvfs_info->voltdm;
+ vdd = container_of(voltdm, struct omap_vdd_info, voltdm);
+
+ mutex_lock(&dvfs_info->scaling_mutex);
+
+ /* Find the highest voltage being requested */
+ node = plist_last(&dvfs_info->user_list);
+ volt = node->prio;
+
+ curr_volt = omap_voltage_get_nom_volt(voltdm);
+
+ /* Disable smartreflex module across voltage and frequency scaling */
+ omap_sr_disable(voltdm);
+
+ if (curr_volt == volt) {
+ is_volt_scaled = 1;
+ } else if (curr_volt < volt) {
+ ret = omap_voltage_scale_vdd(voltdm, volt);
+ if (ret) {
+ pr_warning("%s: Unable to scale the %s to %ld volt\n",
+ __func__, voltdm->name, volt);
+ omap_sr_enable(voltdm);
+ mutex_unlock(&dvfs_info->scaling_mutex);
+ return ret;
+ }
+ is_volt_scaled = 1;
+ }
+
+ list_for_each_entry(temp_dev, &dvfs_info->dev_list, node) {
+ struct device *dev;
+ struct opp *opp;
+ unsigned long freq;
+
+ dev = temp_dev->dev;
+ if (!plist_head_empty(&temp_dev->user_list)) {
+ node = plist_last(&temp_dev->user_list);
+ freq = node->prio;
+ } else {
+ opp = omap_dvfs_find_voltage(dev, volt);
+ if (IS_ERR(opp))
+ continue;
+ freq = opp_get_freq(opp);
+ }
+
+ if (freq == omap_device_get_rate(dev)) {
+ dev_dbg(dev, "%s: Already at the requested"
+ "rate %ld\n", __func__, freq);
+ continue;
+ }
+
+ ret |= omap_device_set_rate(dev, freq);
+ }
+
+ if (!is_volt_scaled && !ret)
+ omap_voltage_scale_vdd(voltdm, volt);
+
+ /* Enable Smartreflex module */
+ omap_sr_enable(voltdm);
+
+ mutex_unlock(&dvfs_info->scaling_mutex);
+
+ /* calculate the voltages for dependent vdd's */
+ if (calc_dep_vdd_volt(&dvfs_info->vdd_device, vdd, volt)) {
+ pr_warning("%s: Error in calculating dependent vdd voltages"
+ "for vdd_%s\n", __func__, voltdm->name);
+ return -EINVAL;
+ }
+
+ /* Scale dependent vdds */
+ scale_dep_vdd(dvfs_info);
+
+ return 0;
+}
+
+/**
+ * omap_device_scale() - Set a new rate at which the device is to operate
+ * @req_dev: pointer to the device requesting the scaling.
+ * @target_dev: pointer to the device that is to be scaled
+ * @rate: the rnew rate for the device.
+ *
+ * This API gets the device opp table associated with this device and
+ * tries putting the device to the requested rate and the voltage domain
+ * associated with the device to the voltage corresponding to the
+ * requested rate. Since multiple devices can be assocciated with a
+ * voltage domain this API finds out the possible voltage the
+ * voltage domain can enter and then decides on the final device
+ * rate. Return 0 on success else the error value
+ */
+int omap_device_scale(struct device *req_dev, struct device *target_dev,
+ unsigned long rate)
+{
+ struct opp *opp;
+ unsigned long volt, freq, min_freq, max_freq;
+ struct omap_vdd_dvfs_info *dvfs_info;
+ struct platform_device *pdev;
+ struct omap_device *od;
+ int ret = 0;
+
+ pdev = container_of(target_dev, struct platform_device, dev);
+ od = container_of(pdev, struct omap_device, pdev);
+
+ /*
+ * Figure out if the desired frquency lies between the
+ * maximum and minimum possible for the particular device
+ */
+ min_freq = 0;
+ if (IS_ERR(opp_find_freq_ceil(target_dev, &min_freq))) {
+ dev_err(target_dev, "%s: Unable to find lowest opp\n",
+ __func__);
+ return -ENODEV;
+ }
+
+ max_freq = ULONG_MAX;
+ if (IS_ERR(opp_find_freq_floor(target_dev, &max_freq))) {
+ dev_err(target_dev, "%s: Unable to find highest opp\n",
+ __func__);
+ return -ENODEV;
+ }
+
+ if (rate < min_freq)
+ freq = min_freq;
+ else if (rate > max_freq)
+ freq = max_freq;
+ else
+ freq = rate;
+
+ opp = opp_find_freq_ceil(target_dev, &freq);
+ if (IS_ERR(opp)) {
+ dev_err(target_dev, "%s: Unable to find OPP for freq%ld\n",
+ __func__, rate);
+ return -ENODEV;
+ }
+
+ /* Get the voltage corresponding to the requested frequency */
+ volt = opp_get_voltage(opp);
+
+ /*
+ * Call into the voltage layer to get the final voltage possible
+ * for the voltage domain associated with the device.
+ */
+
+ if (rate) {
+ dvfs_info = get_dvfs_info(od->hwmods[0]->voltdm);
+
+ ret = omap_dvfs_add_freq_request(dvfs_info, req_dev,
+ target_dev, freq);
+ if (ret) {
+ dev_err(target_dev, "%s: Unable to add frequency request\n",
+ __func__);
+ return ret;
+ }
+
+ ret = omap_dvfs_add_vdd_user(dvfs_info, req_dev, volt);
+ if (ret) {
+ dev_err(target_dev, "%s: Unable to add voltage request\n",
+ __func__);
+ omap_dvfs_remove_freq_request(dvfs_info, req_dev,
+ target_dev);
+ return ret;
+ }
+ } else {
+ dvfs_info = get_dvfs_info(od->hwmods[0]->voltdm);
+
+ ret = omap_dvfs_remove_freq_request(dvfs_info, req_dev,
+ target_dev);
+ if (ret) {
+ dev_err(target_dev, "%s: Unable to remove frequency request\n",
+ __func__);
+ return ret;
+ }
+
+ ret = omap_dvfs_remove_vdd_user(dvfs_info, req_dev);
+ if (ret) {
+ dev_err(target_dev, "%s: Unable to remove voltage request\n",
+ __func__);
+ return ret;
+ }
+ }
+
+ /* Do the actual scaling */
+ ret = omap_dvfs_voltage_scale(dvfs_info);
+ if (!ret)
+ if (omap_device_get_rate(target_dev) >= rate)
+ return 0;
+
+ return ret;
+}
+EXPORT_SYMBOL(omap_device_scale);
+
+/**
+ * omap_dvfs_init() - Initialize omap dvfs layer
+ *
+ * Initalizes omap dvfs layer. It basically allocates memory for
+ * omap_dvfs_info_list and populates voltdm pointer inside
+ * omap_vdd_dvfs_info structure for all the VDDs.
+ *
+ * Returns 0 on success.
+ */
+static int __init omap_dvfs_init()
+{
+ int i;
+ struct voltagedomain *vdd_list;
+ if (cpu_is_omap34xx()) {
+ omap_nr_vdd = 2;
+ vdd_list = omap3_vdd;
+ } else if (cpu_is_omap44xx()) {
+ omap_nr_vdd = 3;
+ vdd_list = omap4_vdd;
+ } else {
+ pr_warning("DVFS not supported\n");
+ return -EINVAL;
+ }
+
+ omap_dvfs_info_list = kzalloc(omap_nr_vdd *
+ sizeof(struct omap_vdd_dvfs_info), GFP_KERNEL);
+ if (!omap_dvfs_info_list) {
+ pr_warning("%s: Unable to allocate memory for vdd_list",
+ __func__);
+ return -ENOMEM;
+ }
+
+ for (i = 0; i < omap_nr_vdd; i++) {
+ omap_dvfs_info_list[i].voltdm =
+ omap_voltage_domain_lookup(vdd_list[i].name);
+ /* Init the plist */
+ spin_lock_init(&omap_dvfs_info_list[i].user_lock);
+ plist_head_init(&omap_dvfs_info_list[i].user_list,
+ &omap_dvfs_info_list[i].user_lock);
+ /* Init the DVFS mutex */
+ mutex_init(&omap_dvfs_info_list[i].scaling_mutex);
+ /* Init the device list */
+ INIT_LIST_HEAD(&omap_dvfs_info_list[i].dev_list);
+ }
+
+ return 0;
+}
+core_initcall(omap_dvfs_init);
diff --git a/arch/arm/mach-omap2/include/mach/debug-macro.S b/arch/arm/mach-omap2/include/mach/debug-macro.S
index 6a4d4136002..6049f465ec8 100644
--- a/arch/arm/mach-omap2/include/mach/debug-macro.S
+++ b/arch/arm/mach-omap2/include/mach/debug-macro.S
@@ -19,6 +19,9 @@
#define UART_OFFSET(addr) ((addr) & 0x00ffffff)
+#define omap_uart_v2p(x) ((x) - PAGE_OFFSET + PLAT_PHYS_OFFSET)
+#define omap_uart_p2v(x) ((x) - PLAT_PHYS_OFFSET + PAGE_OFFSET)
+
.pushsection .data
omap_uart_phys: .word 0
omap_uart_virt: .word 0
@@ -36,7 +39,7 @@ omap_uart_lsr: .word 0
/* Use omap_uart_phys/virt if already configured */
10: mrc p15, 0, \rp, c1, c0
tst \rp, #1 @ MMU enabled?
- ldreq \rp, =__virt_to_phys(omap_uart_phys) @ MMU not enabled
+ ldreq \rp, =omap_uart_v2p(omap_uart_phys) @ MMU disabled
ldrne \rp, =omap_uart_phys @ MMU enabled
add \rv, \rp, #4 @ omap_uart_virt
ldr \rp, [\rp, #0]
@@ -49,7 +52,7 @@ omap_uart_lsr: .word 0
mrc p15, 0, \rp, c1, c0
tst \rp, #1 @ MMU enabled?
ldreq \rp, =OMAP_UART_INFO @ MMU not enabled
- ldrne \rp, =__phys_to_virt(OMAP_UART_INFO) @ MMU enabled
+ ldrne \rp, =omap_uart_p2v(OMAP_UART_INFO) @ MMU enabled
ldr \rp, [\rp, #0]
/* Select the UART to use based on the UART1 scratchpad value */
@@ -94,7 +97,7 @@ omap_uart_lsr: .word 0
95: ldr \rp, =ZOOM_UART_BASE
mrc p15, 0, \rv, c1, c0
tst \rv, #1 @ MMU enabled?
- ldreq \rv, =__virt_to_phys(omap_uart_phys) @ MMU not enabled
+ ldreq \rv, =omap_uart_v2p(omap_uart_phys) @ MMU disabled
ldrne \rv, =omap_uart_phys @ MMU enabled
str \rp, [\rv, #0]
ldr \rp, =ZOOM_UART_VIRT
@@ -109,7 +112,7 @@ omap_uart_lsr: .word 0
98: add \rp, \rp, #0x48000000 @ phys base
mrc p15, 0, \rv, c1, c0
tst \rv, #1 @ MMU enabled?
- ldreq \rv, =__virt_to_phys(omap_uart_phys) @ MMU not enabled
+ ldreq \rv, =omap_uart_v2p(omap_uart_phys) @ MMU disabled
ldrne \rv, =omap_uart_phys @ MMU enabled
str \rp, [\rv, #0]
sub \rp, \rp, #0x48000000 @ phys base
@@ -131,7 +134,7 @@ omap_uart_lsr: .word 0
.macro busyuart,rd,rx
1001: mrc p15, 0, \rd, c1, c0
tst \rd, #1 @ MMU enabled?
- ldreq \rd, =__virt_to_phys(omap_uart_lsr) @ MMU not enabled
+ ldreq \rd, =omap_uart_v2p(omap_uart_lsr) @ MMU disabled
ldrne \rd, =omap_uart_lsr @ MMU enabled
ldr \rd, [\rd, #0]
ldrb \rd, [\rx, \rd]
diff --git a/arch/arm/mach-omap2/include/mach/omap4-common.h b/arch/arm/mach-omap2/include/mach/omap4-common.h
index 5b0270b2893..de441c05a6a 100644
--- a/arch/arm/mach-omap2/include/mach/omap4-common.h
+++ b/arch/arm/mach-omap2/include/mach/omap4-common.h
@@ -17,8 +17,12 @@
* wfi used in low power code. Directly opcode is used instead
* of instruction to avoid mulit-omap build break
*/
+#ifdef CONFIG_THUMB2_KERNEL
+#define do_wfi() __asm__ __volatile__ ("wfi" : : : "memory")
+#else
#define do_wfi() \
__asm__ __volatile__ (".word 0xe320f003" : : : "memory")
+#endif
#ifdef CONFIG_CACHE_L2X0
extern void __iomem *l2cache_base;
diff --git a/arch/arm/mach-omap2/omap-headsmp.S b/arch/arm/mach-omap2/omap-headsmp.S
index 6ae937a06cc..4ee6aeca885 100644
--- a/arch/arm/mach-omap2/omap-headsmp.S
+++ b/arch/arm/mach-omap2/omap-headsmp.S
@@ -45,5 +45,5 @@ hold: ldr r12,=0x103
* should now contain the SVC stack for this core
*/
b secondary_startup
-END(omap_secondary_startup)
+ENDPROC(omap_secondary_startup)
diff --git a/arch/arm/mach-omap2/omap2plus-cpufreq.c b/arch/arm/mach-omap2/omap2plus-cpufreq.c
new file mode 100644
index 00000000000..e982e13f2af
--- /dev/null
+++ b/arch/arm/mach-omap2/omap2plus-cpufreq.c
@@ -0,0 +1,250 @@
+/*
+ * OMAP2PLUS cpufreq driver
+ *
+ * CPU frequency scaling for OMAP
+ *
+ * Copyright (C) 2005 Nokia Corporation
+ * Written by Tony Lindgren <tony@atomide.com>
+ *
+ * Based on cpu-sa1110.c, Copyright (C) 2001 Russell King
+ *
+ * Copyright (C) 2007-2008 Texas Instruments, Inc.
+ * Updated to support OMAP3
+ * Rajendra Nayak <rnayak@ti.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+#include <linux/types.h>
+#include <linux/kernel.h>
+#include <linux/sched.h>
+#include <linux/cpufreq.h>
+#include <linux/delay.h>
+#include <linux/init.h>
+#include <linux/err.h>
+#include <linux/clk.h>
+#include <linux/io.h>
+#include <linux/opp.h>
+#include <linux/cpu.h>
+
+#include <asm/system.h>
+#include <asm/smp_plat.h>
+#include <asm/cpu.h>
+
+#include <plat/clock.h>
+#include <plat/omap-pm.h>
+#include <plat/common.h>
+
+#include <mach/hardware.h>
+#include <plat/dvfs.h>
+
+#define VERY_HI_RATE 900000000
+
+static struct cpufreq_frequency_table *freq_table;
+static struct clk *mpu_clk;
+
+static int omap_verify_speed(struct cpufreq_policy *policy)
+{
+ if (freq_table)
+ return cpufreq_frequency_table_verify(policy, freq_table);
+
+ if (policy->cpu)
+ return -EINVAL;
+
+ cpufreq_verify_within_limits(policy, policy->cpuinfo.min_freq,
+ policy->cpuinfo.max_freq);
+
+ policy->min = clk_round_rate(mpu_clk, policy->min * 1000) / 1000;
+ policy->max = clk_round_rate(mpu_clk, policy->max * 1000) / 1000;
+ cpufreq_verify_within_limits(policy, policy->cpuinfo.min_freq,
+ policy->cpuinfo.max_freq);
+ return 0;
+}
+
+static unsigned int omap_getspeed(unsigned int cpu)
+{
+ unsigned long rate;
+
+ if (cpu >= NR_CPUS)
+ return 0;
+
+ rate = clk_get_rate(mpu_clk) / 1000;
+ return rate;
+}
+
+static int omap_target(struct cpufreq_policy *policy,
+ unsigned int target_freq,
+ unsigned int relation)
+{
+ int i, ret = 0;
+ struct cpufreq_freqs freqs;
+ struct device *mpu_dev = omap2_get_mpuss_device();
+
+ /* Wait untill all CPU's are initialized */
+ if (is_smp() && (num_online_cpus() < NR_CPUS))
+ return ret;
+
+ /* Ensure desired rate is within allowed range. Some govenors
+ * (ondemand) will just pass target_freq=0 to get the minimum. */
+ if (target_freq < policy->min)
+ target_freq = policy->min;
+ if (target_freq > policy->max)
+ target_freq = policy->max;
+
+ freqs.old = omap_getspeed(policy->cpu);
+ freqs.new = clk_round_rate(mpu_clk, target_freq * 1000) / 1000;
+ freqs.cpu = policy->cpu;
+
+ if (freqs.old == freqs.new)
+ return ret;
+
+ if (!is_smp()) {
+ cpufreq_notify_transition(&freqs, CPUFREQ_PRECHANGE);
+ goto set_freq;
+ }
+
+ /* notifiers */
+ for_each_cpu(i, policy->cpus) {
+ freqs.cpu = i;
+ cpufreq_notify_transition(&freqs, CPUFREQ_PRECHANGE);
+ }
+
+set_freq:
+#ifdef CONFIG_CPU_FREQ_DEBUG
+ pr_info("cpufreq-omap: transition: %u --> %u\n", freqs.old, freqs.new);
+#endif
+
+ ret = omap_device_scale(mpu_dev, mpu_dev, freqs.new * 1000);
+ if (ret)
+ return ret;
+ freqs.new = omap_getspeed(policy->cpu);
+
+ /*
+ * Generic CPUFREQ driver jiffy update is under !SMP. So jiffies
+ * won't get updated when UP machine cpufreq build with
+ * CONFIG_SMP enabled. Below code is added only to manage that
+ * scenario
+ */
+ if (!is_smp()) {
+ loops_per_jiffy =
+ cpufreq_scale(loops_per_jiffy, freqs.old, freqs.new);
+ cpufreq_notify_transition(&freqs, CPUFREQ_POSTCHANGE);
+ goto skip_lpj;
+ }
+
+#ifdef CONFIG_SMP
+ /*
+ * Note that loops_per_jiffy is not updated on SMP systems in
+ * cpufreq driver. So, update the per-CPU loops_per_jiffy value
+ * on frequency transition. We need to update all dependent cpus
+ */
+ for_each_cpu(i, policy->cpus)
+ per_cpu(cpu_data, i).loops_per_jiffy =
+ cpufreq_scale(per_cpu(cpu_data, i).loops_per_jiffy,
+ freqs.old, freqs.new);
+#endif
+
+ /* notifiers */
+ for_each_cpu(i, policy->cpus) {
+ freqs.cpu = i;
+ cpufreq_notify_transition(&freqs, CPUFREQ_POSTCHANGE);
+ }
+
+skip_lpj:
+ return ret;
+}
+
+static int __init omap_cpu_init(struct cpufreq_policy *policy)
+{
+ int result = 0;
+ struct device *mpu_dev;
+ static cpumask_var_t cpumask;
+
+ mpu_clk = clk_get(NULL, "cpu_ck");
+ if (IS_ERR(mpu_clk))
+ return PTR_ERR(mpu_clk);
+
+ if (policy->cpu >= NR_CPUS)
+ return -EINVAL;
+
+ policy->cur = policy->min = policy->max = omap_getspeed(policy->cpu);
+
+ mpu_dev = omap2_get_mpuss_device();
+ if (!mpu_dev) {
+ pr_warning("%s: unable to get the mpu device\n", __func__);
+ return -EINVAL;
+ }
+ opp_init_cpufreq_table(mpu_dev, &freq_table);
+
+ if (freq_table) {
+ result = cpufreq_frequency_table_cpuinfo(policy, freq_table);
+ if (!result)
+ cpufreq_frequency_table_get_attr(freq_table,
+ policy->cpu);
+ } else {
+ policy->cpuinfo.min_freq = clk_round_rate(mpu_clk, 0) / 1000;
+ policy->cpuinfo.max_freq = clk_round_rate(mpu_clk,
+ VERY_HI_RATE) / 1000;
+ }
+
+ policy->min = policy->cpuinfo.min_freq;
+ policy->max = policy->cpuinfo.max_freq;
+ policy->cur = omap_getspeed(policy->cpu);
+
+ /*
+ * On OMAP SMP configuartion, both processors share the voltage
+ * and clock. So both CPUs needs to be scaled together and hence
+ * needs software co-ordination. Use cpufreq affected_cpus
+ * interface to handle this scenario. Additional is_smp() check
+ * is to keep SMP_ON_UP builf working.
+ */
+ if (is_smp()) {
+ policy->shared_type = CPUFREQ_SHARED_TYPE_ANY;
+ cpumask_or(cpumask, cpumask_of(policy->cpu), cpumask);
+ cpumask_copy(policy->cpus, cpumask);
+ }
+
+ /* FIXME: what's the actual transition time? */
+ policy->cpuinfo.transition_latency = 300 * 1000;
+
+ return 0;
+}
+
+static int omap_cpu_exit(struct cpufreq_policy *policy)
+{
+ clk_exit_cpufreq_table(&freq_table);
+ clk_put(mpu_clk);
+ return 0;
+}
+
+static struct freq_attr *omap_cpufreq_attr[] = {
+ &cpufreq_freq_attr_scaling_available_freqs,
+ NULL,
+};
+
+static struct cpufreq_driver omap_driver = {
+ .flags = CPUFREQ_STICKY,
+ .verify = omap_verify_speed,
+ .target = omap_target,
+ .get = omap_getspeed,
+ .init = omap_cpu_init,
+ .exit = omap_cpu_exit,
+ .name = "omap2plus",
+ .attr = omap_cpufreq_attr,
+};
+
+static int __init omap_cpufreq_init(void)
+{
+ return cpufreq_register_driver(&omap_driver);
+}
+
+static void __exit omap_cpufreq_exit(void)
+{
+ cpufreq_unregister_driver(&omap_driver);
+}
+
+MODULE_DESCRIPTION("cpufreq driver for OMAP2PLUS SOCs");
+MODULE_LICENSE("GPL");
+module_init(omap_cpufreq_init);
+module_exit(omap_cpufreq_exit);
diff --git a/arch/arm/mach-omap2/omap44xx-smc.S b/arch/arm/mach-omap2/omap44xx-smc.S
index 1980dc31a1a..e69d37d9520 100644
--- a/arch/arm/mach-omap2/omap44xx-smc.S
+++ b/arch/arm/mach-omap2/omap44xx-smc.S
@@ -29,7 +29,7 @@ ENTRY(omap_smc1)
dsb
smc #0
ldmfd sp!, {r2-r12, pc}
-END(omap_smc1)
+ENDPROC(omap_smc1)
ENTRY(omap_modify_auxcoreboot0)
stmfd sp!, {r1-r12, lr}
@@ -37,7 +37,7 @@ ENTRY(omap_modify_auxcoreboot0)
dsb
smc #0
ldmfd sp!, {r1-r12, pc}
-END(omap_modify_auxcoreboot0)
+ENDPROC(omap_modify_auxcoreboot0)
ENTRY(omap_auxcoreboot_addr)
stmfd sp!, {r2-r12, lr}
@@ -45,7 +45,7 @@ ENTRY(omap_auxcoreboot_addr)
dsb
smc #0
ldmfd sp!, {r2-r12, pc}
-END(omap_auxcoreboot_addr)
+ENDPROC(omap_auxcoreboot_addr)
ENTRY(omap_read_auxcoreboot0)
stmfd sp!, {r2-r12, lr}
@@ -54,4 +54,4 @@ ENTRY(omap_read_auxcoreboot0)
smc #0
mov r0, r0, lsr #9
ldmfd sp!, {r2-r12, pc}
-END(omap_read_auxcoreboot0)
+ENDPROC(omap_read_auxcoreboot0)
diff --git a/arch/arm/mach-omap2/omap_hwmod_2420_data.c b/arch/arm/mach-omap2/omap_hwmod_2420_data.c
index b85c630b64d..21014dee5e3 100644
--- a/arch/arm/mach-omap2/omap_hwmod_2420_data.c
+++ b/arch/arm/mach-omap2/omap_hwmod_2420_data.c
@@ -18,7 +18,8 @@
#include <plat/serial.h>
#include <plat/i2c.h>
#include <plat/gpio.h>
-
+#include <plat/l3_2xxx.h>
+#include <plat/l4_2xxx.h>
#include "omap_hwmod_common_data.h"
#include "cm-regbits-24xx.h"
@@ -38,6 +39,10 @@ static struct omap_hwmod omap2420_mpu_hwmod;
static struct omap_hwmod omap2420_iva_hwmod;
static struct omap_hwmod omap2420_l3_main_hwmod;
static struct omap_hwmod omap2420_l4_core_hwmod;
+static struct omap_hwmod omap2420_dss_core_hwmod;
+static struct omap_hwmod omap2420_dss_dispc_hwmod;
+static struct omap_hwmod omap2420_dss_rfbi_hwmod;
+static struct omap_hwmod omap2420_dss_venc_hwmod;
static struct omap_hwmod omap2420_wd_timer2_hwmod;
static struct omap_hwmod omap2420_gpio1_hwmod;
static struct omap_hwmod omap2420_gpio2_hwmod;
@@ -64,6 +69,19 @@ static struct omap_hwmod_ocp_if *omap2420_l3_main_slaves[] = {
&omap2420_mpu__l3_main,
};
+/* DSS -> l3 */
+static struct omap_hwmod_ocp_if omap2420_dss__l3 = {
+ .master = &omap2420_dss_core_hwmod,
+ .slave = &omap2420_l3_main_hwmod,
+ .fw = {
+ .omap2 = {
+ .l3_perm_bit = OMAP2_L3_CORE_FW_CONNID_DSS,
+ .flags = OMAP_FIREWALL_L3,
+ }
+ },
+ .user = OCP_USER_MPU | OCP_USER_SDMA,
+};
+
/* Master interfaces on the L3 interconnect */
static struct omap_hwmod_ocp_if *omap2420_l3_main_masters[] = {
&omap2420_l3_main__l4_core,
@@ -470,6 +488,291 @@ static struct omap_hwmod omap2420_uart3_hwmod = {
.omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP2420),
};
+/*
+ * 'dss' class
+ * display sub-system
+ */
+
+static struct omap_hwmod_class_sysconfig omap2420_dss_sysc = {
+ .rev_offs = 0x0000,
+ .sysc_offs = 0x0010,
+ .syss_offs = 0x0014,
+ .sysc_flags = (SYSC_HAS_SOFTRESET | SYSC_HAS_AUTOIDLE),
+ .sysc_fields = &omap_hwmod_sysc_type1,
+};
+
+static struct omap_hwmod_class omap2420_dss_hwmod_class = {
+ .name = "dss",
+ .sysc = &omap2420_dss_sysc,
+};
+
+/* dss */
+static struct omap_hwmod_irq_info omap2420_dss_irqs[] = {
+ { .irq = 25 },
+};
+
+static struct omap_hwmod_dma_info omap2420_dss_sdma_chs[] = {
+ { .name = "dispc", .dma_req = 5 },
+};
+
+/* dss */
+/* dss master ports */
+static struct omap_hwmod_ocp_if *omap2420_dss_masters[] = {
+ &omap2420_dss__l3,
+};
+
+static struct omap_hwmod_addr_space omap2420_dss_addrs[] = {
+ {
+ .pa_start = 0x48050000,
+ .pa_end = 0x480503FF,
+ .flags = ADDR_TYPE_RT
+ },
+};
+
+/* l4_core -> dss */
+static struct omap_hwmod_ocp_if omap2420_l4_core__dss = {
+ .master = &omap2420_l4_core_hwmod,
+ .slave = &omap2420_dss_core_hwmod,
+ .clk = "dss_ick",
+ .addr = omap2420_dss_addrs,
+ .addr_cnt = ARRAY_SIZE(omap2420_dss_addrs),
+ .fw = {
+ .omap2 = {
+ .l4_fw_region = OMAP2420_L4_CORE_FW_DSS_CORE_REGION,
+ .flags = OMAP_FIREWALL_L4,
+ }
+ },
+ .user = OCP_USER_MPU | OCP_USER_SDMA,
+};
+
+/* dss slave ports */
+static struct omap_hwmod_ocp_if *omap2420_dss_slaves[] = {
+ &omap2420_l4_core__dss,
+};
+
+static struct omap_hwmod_opt_clk dss_opt_clks[] = {
+ { .role = "tv_clk", .clk = "dss_54m_fck" },
+ { .role = "sys_clk", .clk = "dss2_fck" },
+};
+
+static struct omap_hwmod omap2420_dss_core_hwmod = {
+ .name = "dss_core",
+ .class = &omap2420_dss_hwmod_class,
+ .main_clk = "dss1_fck", /* instead of dss_fck */
+ .mpu_irqs = omap2420_dss_irqs,
+ .mpu_irqs_cnt = ARRAY_SIZE(omap2420_dss_irqs),
+ .sdma_reqs = omap2420_dss_sdma_chs,
+ .sdma_reqs_cnt = ARRAY_SIZE(omap2420_dss_sdma_chs),
+ .prcm = {
+ .omap2 = {
+ .prcm_reg_id = 1,
+ .module_bit = OMAP24XX_EN_DSS1_SHIFT,
+ .module_offs = CORE_MOD,
+ .idlest_reg_id = 1,
+ .idlest_stdby_bit = OMAP24XX_ST_DSS_SHIFT,
+ },
+ },
+ .opt_clks = dss_opt_clks,
+ .opt_clks_cnt = ARRAY_SIZE(dss_opt_clks),
+ .slaves = omap2420_dss_slaves,
+ .slaves_cnt = ARRAY_SIZE(omap2420_dss_slaves),
+ .masters = omap2420_dss_masters,
+ .masters_cnt = ARRAY_SIZE(omap2420_dss_masters),
+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP2420),
+ .flags = HWMOD_NO_IDLEST,
+};
+
+/*
+ * 'dispc' class
+ * display controller
+ */
+
+static struct omap_hwmod_class_sysconfig omap2420_dispc_sysc = {
+ .rev_offs = 0x0000,
+ .sysc_offs = 0x0010,
+ .syss_offs = 0x0014,
+ .sysc_flags = (SYSC_HAS_SIDLEMODE | SYSC_HAS_MIDLEMODE |
+ SYSC_HAS_SOFTRESET | SYSC_HAS_AUTOIDLE),
+ .idlemodes = (SIDLE_FORCE | SIDLE_NO | SIDLE_SMART |
+ MSTANDBY_FORCE | MSTANDBY_NO | MSTANDBY_SMART),
+ .sysc_fields = &omap_hwmod_sysc_type1,
+};
+
+static struct omap_hwmod_class omap2420_dispc_hwmod_class = {
+ .name = "dispc",
+ .sysc = &omap2420_dispc_sysc,
+};
+
+static struct omap_hwmod_addr_space omap2420_dss_dispc_addrs[] = {
+ {
+ .pa_start = 0x48050400,
+ .pa_end = 0x480507FF,
+ .flags = ADDR_TYPE_RT
+ },
+};
+
+/* l4_core -> dss_dispc */
+static struct omap_hwmod_ocp_if omap2420_l4_core__dss_dispc = {
+ .master = &omap2420_l4_core_hwmod,
+ .slave = &omap2420_dss_dispc_hwmod,
+ .clk = "dss_ick",
+ .addr = omap2420_dss_dispc_addrs,
+ .addr_cnt = ARRAY_SIZE(omap2420_dss_dispc_addrs),
+ .fw = {
+ .omap2 = {
+ .l4_fw_region = OMAP2420_L4_CORE_FW_DSS_DISPC_REGION,
+ .flags = OMAP_FIREWALL_L4,
+ }
+ },
+ .user = OCP_USER_MPU | OCP_USER_SDMA,
+};
+
+/* dss_dispc slave ports */
+static struct omap_hwmod_ocp_if *omap2420_dss_dispc_slaves[] = {
+ &omap2420_l4_core__dss_dispc,
+};
+
+static struct omap_hwmod omap2420_dss_dispc_hwmod = {
+ .name = "dss_dispc",
+ .class = &omap2420_dispc_hwmod_class,
+ .main_clk = "dss1_fck",
+ .prcm = {
+ .omap2 = {
+ .prcm_reg_id = 1,
+ .module_bit = OMAP24XX_EN_DSS1_SHIFT,
+ .module_offs = CORE_MOD,
+ .idlest_reg_id = 1,
+ .idlest_stdby_bit = OMAP24XX_ST_DSS_SHIFT,
+ },
+ },
+ .slaves = omap2420_dss_dispc_slaves,
+ .slaves_cnt = ARRAY_SIZE(omap2420_dss_dispc_slaves),
+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP2420),
+ .flags = HWMOD_NO_IDLEST,
+};
+
+/*
+ * 'rfbi' class
+ * remote frame buffer interface
+ */
+
+static struct omap_hwmod_class_sysconfig omap2420_rfbi_sysc = {
+ .rev_offs = 0x0000,
+ .sysc_offs = 0x0010,
+ .syss_offs = 0x0014,
+ .sysc_flags = (SYSC_HAS_SIDLEMODE | SYSC_HAS_SOFTRESET |
+ SYSC_HAS_AUTOIDLE),
+ .idlemodes = (SIDLE_FORCE | SIDLE_NO | SIDLE_SMART),
+ .sysc_fields = &omap_hwmod_sysc_type1,
+};
+
+static struct omap_hwmod_class omap2420_rfbi_hwmod_class = {
+ .name = "rfbi",
+ .sysc = &omap2420_rfbi_sysc,
+};
+
+static struct omap_hwmod_addr_space omap2420_dss_rfbi_addrs[] = {
+ {
+ .pa_start = 0x48050800,
+ .pa_end = 0x48050BFF,
+ .flags = ADDR_TYPE_RT
+ },
+};
+
+/* l4_core -> dss_rfbi */
+static struct omap_hwmod_ocp_if omap2420_l4_core__dss_rfbi = {
+ .master = &omap2420_l4_core_hwmod,
+ .slave = &omap2420_dss_rfbi_hwmod,
+ .clk = "dss_ick",
+ .addr = omap2420_dss_rfbi_addrs,
+ .addr_cnt = ARRAY_SIZE(omap2420_dss_rfbi_addrs),
+ .fw = {
+ .omap2 = {
+ .l4_fw_region = OMAP2420_L4_CORE_FW_DSS_CORE_REGION,
+ .flags = OMAP_FIREWALL_L4,
+ }
+ },
+ .user = OCP_USER_MPU | OCP_USER_SDMA,
+};
+
+/* dss_rfbi slave ports */
+static struct omap_hwmod_ocp_if *omap2420_dss_rfbi_slaves[] = {
+ &omap2420_l4_core__dss_rfbi,
+};
+
+static struct omap_hwmod omap2420_dss_rfbi_hwmod = {
+ .name = "dss_rfbi",
+ .class = &omap2420_rfbi_hwmod_class,
+ .main_clk = "dss1_fck",
+ .prcm = {
+ .omap2 = {
+ .prcm_reg_id = 1,
+ .module_bit = OMAP24XX_EN_DSS1_SHIFT,
+ .module_offs = CORE_MOD,
+ },
+ },
+ .slaves = omap2420_dss_rfbi_slaves,
+ .slaves_cnt = ARRAY_SIZE(omap2420_dss_rfbi_slaves),
+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP2420),
+ .flags = HWMOD_NO_IDLEST,
+};
+
+/*
+ * 'venc' class
+ * video encoder
+ */
+
+static struct omap_hwmod_class omap2420_venc_hwmod_class = {
+ .name = "venc",
+};
+
+/* dss_venc */
+static struct omap_hwmod_addr_space omap2420_dss_venc_addrs[] = {
+ {
+ .pa_start = 0x48050C00,
+ .pa_end = 0x48050FFF,
+ .flags = ADDR_TYPE_RT
+ },
+};
+
+/* l4_core -> dss_venc */
+static struct omap_hwmod_ocp_if omap2420_l4_core__dss_venc = {
+ .master = &omap2420_l4_core_hwmod,
+ .slave = &omap2420_dss_venc_hwmod,
+ .clk = "dss_54m_fck",
+ .addr = omap2420_dss_venc_addrs,
+ .addr_cnt = ARRAY_SIZE(omap2420_dss_venc_addrs),
+ .fw = {
+ .omap2 = {
+ .l4_fw_region = OMAP2420_L4_CORE_FW_DSS_VENC_REGION,
+ .flags = OMAP_FIREWALL_L4,
+ }
+ },
+ .user = OCP_USER_MPU | OCP_USER_SDMA,
+};
+
+/* dss_venc slave ports */
+static struct omap_hwmod_ocp_if *omap2420_dss_venc_slaves[] = {
+ &omap2420_l4_core__dss_venc,
+};
+
+static struct omap_hwmod omap2420_dss_venc_hwmod = {
+ .name = "dss_venc",
+ .class = &omap2420_venc_hwmod_class,
+ .main_clk = "dss1_fck",
+ .prcm = {
+ .omap2 = {
+ .prcm_reg_id = 1,
+ .module_bit = OMAP24XX_EN_DSS1_SHIFT,
+ .module_offs = CORE_MOD,
+ },
+ },
+ .slaves = omap2420_dss_venc_slaves,
+ .slaves_cnt = ARRAY_SIZE(omap2420_dss_venc_slaves),
+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP2420),
+ .flags = HWMOD_NO_IDLEST,
+};
+
/* I2C common */
static struct omap_hwmod_class_sysconfig i2c_sysc = {
.rev_offs = 0x00,
@@ -874,6 +1177,12 @@ static __initdata struct omap_hwmod *omap2420_hwmods[] = {
&omap2420_uart1_hwmod,
&omap2420_uart2_hwmod,
&omap2420_uart3_hwmod,
+ /* dss class */
+ &omap2420_dss_core_hwmod,
+ &omap2420_dss_dispc_hwmod,
+ &omap2420_dss_rfbi_hwmod,
+ &omap2420_dss_venc_hwmod,
+ /* i2c class */
&omap2420_i2c1_hwmod,
&omap2420_i2c2_hwmod,
diff --git a/arch/arm/mach-omap2/omap_hwmod_2430_data.c b/arch/arm/mach-omap2/omap_hwmod_2430_data.c
index 8ecfbcde13b..1ef3f3fd862 100644
--- a/arch/arm/mach-omap2/omap_hwmod_2430_data.c
+++ b/arch/arm/mach-omap2/omap_hwmod_2430_data.c
@@ -18,6 +18,7 @@
#include <plat/serial.h>
#include <plat/i2c.h>
#include <plat/gpio.h>
+#include <plat/l3_2xxx.h>
#include "omap_hwmod_common_data.h"
@@ -38,6 +39,10 @@ static struct omap_hwmod omap2430_mpu_hwmod;
static struct omap_hwmod omap2430_iva_hwmod;
static struct omap_hwmod omap2430_l3_main_hwmod;
static struct omap_hwmod omap2430_l4_core_hwmod;
+static struct omap_hwmod omap2430_dss_core_hwmod;
+static struct omap_hwmod omap2430_dss_dispc_hwmod;
+static struct omap_hwmod omap2430_dss_rfbi_hwmod;
+static struct omap_hwmod omap2430_dss_venc_hwmod;
static struct omap_hwmod omap2430_wd_timer2_hwmod;
static struct omap_hwmod omap2430_gpio1_hwmod;
static struct omap_hwmod omap2430_gpio2_hwmod;
@@ -65,6 +70,19 @@ static struct omap_hwmod_ocp_if *omap2430_l3_main_slaves[] = {
&omap2430_mpu__l3_main,
};
+/* DSS -> l3 */
+static struct omap_hwmod_ocp_if omap2430_dss__l3 = {
+ .master = &omap2430_dss_core_hwmod,
+ .slave = &omap2430_l3_main_hwmod,
+ .fw = {
+ .omap2 = {
+ .l3_perm_bit = OMAP2_L3_CORE_FW_CONNID_DSS,
+ .flags = OMAP_FIREWALL_L3,
+ }
+ },
+ .user = OCP_USER_MPU | OCP_USER_SDMA,
+};
+
/* Master interfaces on the L3 interconnect */
static struct omap_hwmod_ocp_if *omap2430_l3_main_masters[] = {
&omap2430_l3_main__l4_core,
@@ -469,6 +487,266 @@ static struct omap_hwmod omap2430_uart3_hwmod = {
.omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP2430),
};
+/*
+ * 'dss' class
+ * display sub-system
+ */
+
+static struct omap_hwmod_class_sysconfig omap2430_dss_sysc = {
+ .rev_offs = 0x0000,
+ .sysc_offs = 0x0010,
+ .syss_offs = 0x0014,
+ .sysc_flags = (SYSC_HAS_SOFTRESET | SYSC_HAS_AUTOIDLE),
+ .sysc_fields = &omap_hwmod_sysc_type1,
+};
+
+static struct omap_hwmod_class omap2430_dss_hwmod_class = {
+ .name = "dss",
+ .sysc = &omap2430_dss_sysc,
+};
+
+/* dss */
+static struct omap_hwmod_irq_info omap2430_dss_irqs[] = {
+ { .irq = 25 },
+};
+static struct omap_hwmod_dma_info omap2430_dss_sdma_chs[] = {
+ { .name = "dispc", .dma_req = 5 },
+};
+
+/* dss */
+/* dss master ports */
+static struct omap_hwmod_ocp_if *omap2430_dss_masters[] = {
+ &omap2430_dss__l3,
+};
+
+static struct omap_hwmod_addr_space omap2430_dss_addrs[] = {
+ {
+ .pa_start = 0x48050000,
+ .pa_end = 0x480503FF,
+ .flags = ADDR_TYPE_RT
+ },
+};
+
+/* l4_core -> dss */
+static struct omap_hwmod_ocp_if omap2430_l4_core__dss = {
+ .master = &omap2430_l4_core_hwmod,
+ .slave = &omap2430_dss_core_hwmod,
+ .clk = "dss_ick",
+ .addr = omap2430_dss_addrs,
+ .addr_cnt = ARRAY_SIZE(omap2430_dss_addrs),
+ .user = OCP_USER_MPU | OCP_USER_SDMA,
+};
+
+/* dss slave ports */
+static struct omap_hwmod_ocp_if *omap2430_dss_slaves[] = {
+ &omap2430_l4_core__dss,
+};
+
+static struct omap_hwmod_opt_clk dss_opt_clks[] = {
+ { .role = "tv_clk", .clk = "dss_54m_fck" },
+ { .role = "sys_clk", .clk = "dss2_fck" },
+};
+
+static struct omap_hwmod omap2430_dss_core_hwmod = {
+ .name = "dss_core",
+ .class = &omap2430_dss_hwmod_class,
+ .main_clk = "dss1_fck", /* instead of dss_fck */
+ .mpu_irqs = omap2430_dss_irqs,
+ .mpu_irqs_cnt = ARRAY_SIZE(omap2430_dss_irqs),
+ .sdma_reqs = omap2430_dss_sdma_chs,
+ .sdma_reqs_cnt = ARRAY_SIZE(omap2430_dss_sdma_chs),
+ .prcm = {
+ .omap2 = {
+ .prcm_reg_id = 1,
+ .module_bit = OMAP24XX_EN_DSS1_SHIFT,
+ .module_offs = CORE_MOD,
+ .idlest_reg_id = 1,
+ .idlest_stdby_bit = OMAP24XX_ST_DSS_SHIFT,
+ },
+ },
+ .opt_clks = dss_opt_clks,
+ .opt_clks_cnt = ARRAY_SIZE(dss_opt_clks),
+ .slaves = omap2430_dss_slaves,
+ .slaves_cnt = ARRAY_SIZE(omap2430_dss_slaves),
+ .masters = omap2430_dss_masters,
+ .masters_cnt = ARRAY_SIZE(omap2430_dss_masters),
+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP2430),
+ .flags = HWMOD_NO_IDLEST,
+};
+
+/*
+ * 'dispc' class
+ * display controller
+ */
+
+static struct omap_hwmod_class_sysconfig omap2430_dispc_sysc = {
+ .rev_offs = 0x0000,
+ .sysc_offs = 0x0010,
+ .syss_offs = 0x0014,
+ .sysc_flags = (SYSC_HAS_SIDLEMODE | SYSC_HAS_MIDLEMODE |
+ SYSC_HAS_SOFTRESET | SYSC_HAS_AUTOIDLE),
+ .idlemodes = (SIDLE_FORCE | SIDLE_NO | SIDLE_SMART |
+ MSTANDBY_FORCE | MSTANDBY_NO | MSTANDBY_SMART),
+ .sysc_fields = &omap_hwmod_sysc_type1,
+};
+
+static struct omap_hwmod_class omap2430_dispc_hwmod_class = {
+ .name = "dispc",
+ .sysc = &omap2430_dispc_sysc,
+};
+
+static struct omap_hwmod_addr_space omap2430_dss_dispc_addrs[] = {
+ {
+ .pa_start = 0x48050400,
+ .pa_end = 0x480507FF,
+ .flags = ADDR_TYPE_RT
+ },
+};
+
+/* l4_core -> dss_dispc */
+static struct omap_hwmod_ocp_if omap2430_l4_core__dss_dispc = {
+ .master = &omap2430_l4_core_hwmod,
+ .slave = &omap2430_dss_dispc_hwmod,
+ .clk = "dss_ick",
+ .addr = omap2430_dss_dispc_addrs,
+ .addr_cnt = ARRAY_SIZE(omap2430_dss_dispc_addrs),
+ .user = OCP_USER_MPU | OCP_USER_SDMA,
+};
+
+/* dss_dispc slave ports */
+static struct omap_hwmod_ocp_if *omap2430_dss_dispc_slaves[] = {
+ &omap2430_l4_core__dss_dispc,
+};
+
+static struct omap_hwmod omap2430_dss_dispc_hwmod = {
+ .name = "dss_dispc",
+ .class = &omap2430_dispc_hwmod_class,
+ .main_clk = "dss1_fck",
+ .prcm = {
+ .omap2 = {
+ .prcm_reg_id = 1,
+ .module_bit = OMAP24XX_EN_DSS1_SHIFT,
+ .module_offs = CORE_MOD,
+ .idlest_reg_id = 1,
+ .idlest_stdby_bit = OMAP24XX_ST_DSS_SHIFT,
+ },
+ },
+ .slaves = omap2430_dss_dispc_slaves,
+ .slaves_cnt = ARRAY_SIZE(omap2430_dss_dispc_slaves),
+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP2430),
+ .flags = HWMOD_NO_IDLEST,
+};
+
+/*
+ * 'rfbi' class
+ * remote frame buffer interface
+ */
+
+static struct omap_hwmod_class_sysconfig omap2430_rfbi_sysc = {
+ .rev_offs = 0x0000,
+ .sysc_offs = 0x0010,
+ .syss_offs = 0x0014,
+ .sysc_flags = (SYSC_HAS_SIDLEMODE | SYSC_HAS_SOFTRESET |
+ SYSC_HAS_AUTOIDLE),
+ .idlemodes = (SIDLE_FORCE | SIDLE_NO | SIDLE_SMART),
+ .sysc_fields = &omap_hwmod_sysc_type1,
+};
+
+static struct omap_hwmod_class omap2430_rfbi_hwmod_class = {
+ .name = "rfbi",
+ .sysc = &omap2430_rfbi_sysc,
+};
+
+static struct omap_hwmod_addr_space omap2430_dss_rfbi_addrs[] = {
+ {
+ .pa_start = 0x48050800,
+ .pa_end = 0x48050BFF,
+ .flags = ADDR_TYPE_RT
+ },
+};
+
+/* l4_core -> dss_rfbi */
+static struct omap_hwmod_ocp_if omap2430_l4_core__dss_rfbi = {
+ .master = &omap2430_l4_core_hwmod,
+ .slave = &omap2430_dss_rfbi_hwmod,
+ .clk = "dss_ick",
+ .addr = omap2430_dss_rfbi_addrs,
+ .addr_cnt = ARRAY_SIZE(omap2430_dss_rfbi_addrs),
+ .user = OCP_USER_MPU | OCP_USER_SDMA,
+};
+
+/* dss_rfbi slave ports */
+static struct omap_hwmod_ocp_if *omap2430_dss_rfbi_slaves[] = {
+ &omap2430_l4_core__dss_rfbi,
+};
+
+static struct omap_hwmod omap2430_dss_rfbi_hwmod = {
+ .name = "dss_rfbi",
+ .class = &omap2430_rfbi_hwmod_class,
+ .main_clk = "dss1_fck",
+ .prcm = {
+ .omap2 = {
+ .prcm_reg_id = 1,
+ .module_bit = OMAP24XX_EN_DSS1_SHIFT,
+ .module_offs = CORE_MOD,
+ },
+ },
+ .slaves = omap2430_dss_rfbi_slaves,
+ .slaves_cnt = ARRAY_SIZE(omap2430_dss_rfbi_slaves),
+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP2430),
+ .flags = HWMOD_NO_IDLEST,
+};
+
+/*
+ * 'venc' class
+ * video encoder
+ */
+
+static struct omap_hwmod_class omap2430_venc_hwmod_class = {
+ .name = "venc",
+};
+
+/* dss_venc */
+static struct omap_hwmod_addr_space omap2430_dss_venc_addrs[] = {
+ {
+ .pa_start = 0x48050C00,
+ .pa_end = 0x48050FFF,
+ .flags = ADDR_TYPE_RT
+ },
+};
+
+/* l4_core -> dss_venc */
+static struct omap_hwmod_ocp_if omap2430_l4_core__dss_venc = {
+ .master = &omap2430_l4_core_hwmod,
+ .slave = &omap2430_dss_venc_hwmod,
+ .clk = "dss_54m_fck",
+ .addr = omap2430_dss_venc_addrs,
+ .addr_cnt = ARRAY_SIZE(omap2430_dss_venc_addrs),
+ .user = OCP_USER_MPU | OCP_USER_SDMA,
+};
+
+/* dss_venc slave ports */
+static struct omap_hwmod_ocp_if *omap2430_dss_venc_slaves[] = {
+ &omap2430_l4_core__dss_venc,
+};
+
+static struct omap_hwmod omap2430_dss_venc_hwmod = {
+ .name = "dss_venc",
+ .class = &omap2430_venc_hwmod_class,
+ .main_clk = "dss1_fck",
+ .prcm = {
+ .omap2 = {
+ .prcm_reg_id = 1,
+ .module_bit = OMAP24XX_EN_DSS1_SHIFT,
+ .module_offs = CORE_MOD,
+ },
+ },
+ .slaves = omap2430_dss_venc_slaves,
+ .slaves_cnt = ARRAY_SIZE(omap2430_dss_venc_slaves),
+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP2430),
+ .flags = HWMOD_NO_IDLEST,
+};
+
/* I2C common */
static struct omap_hwmod_class_sysconfig i2c_sysc = {
.rev_offs = 0x00,
@@ -929,6 +1207,12 @@ static __initdata struct omap_hwmod *omap2430_hwmods[] = {
&omap2430_uart1_hwmod,
&omap2430_uart2_hwmod,
&omap2430_uart3_hwmod,
+ /* dss class */
+ &omap2430_dss_core_hwmod,
+ &omap2430_dss_dispc_hwmod,
+ &omap2430_dss_rfbi_hwmod,
+ &omap2430_dss_venc_hwmod,
+ /* i2c class */
&omap2430_i2c1_hwmod,
&omap2430_i2c2_hwmod,
diff --git a/arch/arm/mach-omap2/omap_hwmod_3xxx_data.c b/arch/arm/mach-omap2/omap_hwmod_3xxx_data.c
index 8d8181334f8..5cff284b7a2 100644
--- a/arch/arm/mach-omap2/omap_hwmod_3xxx_data.c
+++ b/arch/arm/mach-omap2/omap_hwmod_3xxx_data.c
@@ -18,6 +18,7 @@
#include <plat/cpu.h>
#include <plat/dma.h>
#include <plat/serial.h>
+#include <plat/l3_3xxx.h>
#include <plat/l4_3xxx.h>
#include <plat/i2c.h>
#include <plat/gpio.h>
@@ -44,6 +45,12 @@ static struct omap_hwmod omap3xxx_l3_main_hwmod;
static struct omap_hwmod omap3xxx_l4_core_hwmod;
static struct omap_hwmod omap3xxx_l4_per_hwmod;
static struct omap_hwmod omap3xxx_wd_timer2_hwmod;
+static struct omap_hwmod omap3430es1_dss_core_hwmod;
+static struct omap_hwmod omap3xxx_dss_core_hwmod;
+static struct omap_hwmod omap3xxx_dss_dispc_hwmod;
+static struct omap_hwmod omap3xxx_dss_dsi1_hwmod;
+static struct omap_hwmod omap3xxx_dss_rfbi_hwmod;
+static struct omap_hwmod omap3xxx_dss_venc_hwmod;
static struct omap_hwmod omap3xxx_i2c1_hwmod;
static struct omap_hwmod omap3xxx_i2c2_hwmod;
static struct omap_hwmod omap3xxx_i2c3_hwmod;
@@ -84,6 +91,19 @@ static struct omap_hwmod_ocp_if *omap3xxx_l3_main_slaves[] = {
&omap3xxx_mpu__l3_main,
};
+/* DSS -> l3 */
+static struct omap_hwmod_ocp_if omap3xxx_dss__l3 = {
+ .master = &omap3xxx_dss_core_hwmod,
+ .slave = &omap3xxx_l3_main_hwmod,
+ .fw = {
+ .omap2 = {
+ .l3_perm_bit = OMAP3_L3_CORE_FW_INIT_ID_DSS,
+ .flags = OMAP_FIREWALL_L3,
+ }
+ },
+ .user = OCP_USER_MPU | OCP_USER_SDMA,
+};
+
/* Master interfaces on the L3 interconnect */
static struct omap_hwmod_ocp_if *omap3xxx_l3_main_masters[] = {
&omap3xxx_l3_main__l4_core,
@@ -94,6 +114,7 @@ static struct omap_hwmod_ocp_if *omap3xxx_l3_main_masters[] = {
static struct omap_hwmod omap3xxx_l3_main_hwmod = {
.name = "l3_main",
.class = &l3_hwmod_class,
+ .vdd_name = "core",
.masters = omap3xxx_l3_main_masters,
.masters_cnt = ARRAY_SIZE(omap3xxx_l3_main_masters),
.slaves = omap3xxx_l3_main_slaves,
@@ -384,6 +405,7 @@ static struct omap_hwmod omap3xxx_mpu_hwmod = {
.name = "mpu",
.class = &mpu_hwmod_class,
.main_clk = "arm_fck",
+ .vdd_name = "mpu",
.masters = omap3xxx_mpu_masters,
.masters_cnt = ARRAY_SIZE(omap3xxx_mpu_masters),
.omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP3430),
@@ -412,6 +434,7 @@ static struct omap_hwmod_ocp_if *omap3xxx_iva_masters[] = {
static struct omap_hwmod omap3xxx_iva_hwmod = {
.name = "iva",
.class = &iva_hwmod_class,
+ .vdd_name = "mpu",
.masters = omap3xxx_iva_masters,
.masters_cnt = ARRAY_SIZE(omap3xxx_iva_masters),
.omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP3430)
@@ -664,6 +687,410 @@ static struct omap_hwmod_class i2c_class = {
.sysc = &i2c_sysc,
};
+/*
+ * 'dss' class
+ * display sub-system
+ */
+
+static struct omap_hwmod_class_sysconfig omap3xxx_dss_sysc = {
+ .rev_offs = 0x0000,
+ .sysc_offs = 0x0010,
+ .syss_offs = 0x0014,
+ .sysc_flags = (SYSC_HAS_SOFTRESET | SYSC_HAS_AUTOIDLE),
+ .sysc_fields = &omap_hwmod_sysc_type1,
+};
+
+static struct omap_hwmod_class omap3xxx_dss_hwmod_class = {
+ .name = "dss",
+ .sysc = &omap3xxx_dss_sysc,
+};
+
+/* dss */
+static struct omap_hwmod_irq_info omap3xxx_dss_irqs[] = {
+ { .irq = 25 },
+};
+
+static struct omap_hwmod_dma_info omap3xxx_dss_sdma_chs[] = {
+ { .name = "dispc", .dma_req = 5 },
+ { .name = "dsi1", .dma_req = 74 },
+};
+
+/* dss */
+/* dss master ports */
+static struct omap_hwmod_ocp_if *omap3xxx_dss_masters[] = {
+ &omap3xxx_dss__l3,
+};
+
+static struct omap_hwmod_addr_space omap3xxx_dss_addrs[] = {
+ {
+ .pa_start = 0x48050000,
+ .pa_end = 0x480503FF,
+ .flags = ADDR_TYPE_RT
+ },
+};
+
+/* l4_core -> dss */
+static struct omap_hwmod_ocp_if omap3430es1_l4_core__dss = {
+ .master = &omap3xxx_l4_core_hwmod,
+ .slave = &omap3430es1_dss_core_hwmod,
+ .clk = "dss_ick",
+ .addr = omap3xxx_dss_addrs,
+ .addr_cnt = ARRAY_SIZE(omap3xxx_dss_addrs),
+ .fw = {
+ .omap2 = {
+ .l4_fw_region = OMAP3ES1_L4_CORE_FW_DSS_CORE_REGION,
+ .l4_prot_group = OMAP3_L4_CORE_FW_DSS_PROT_GROUP,
+ .flags = OMAP_FIREWALL_L4,
+ }
+ },
+ .user = OCP_USER_MPU | OCP_USER_SDMA,
+};
+
+static struct omap_hwmod_ocp_if omap3xxx_l4_core__dss = {
+ .master = &omap3xxx_l4_core_hwmod,
+ .slave = &omap3xxx_dss_core_hwmod,
+ .clk = "dss_ick",
+ .addr = omap3xxx_dss_addrs,
+ .addr_cnt = ARRAY_SIZE(omap3xxx_dss_addrs),
+ .fw = {
+ .omap2 = {
+ .l4_fw_region = OMAP3_L4_CORE_FW_DSS_CORE_REGION,
+ .l4_prot_group = OMAP3_L4_CORE_FW_DSS_PROT_GROUP,
+ .flags = OMAP_FIREWALL_L4,
+ }
+ },
+ .user = OCP_USER_MPU | OCP_USER_SDMA,
+};
+
+/* dss slave ports */
+static struct omap_hwmod_ocp_if *omap3430es1_dss_slaves[] = {
+ &omap3430es1_l4_core__dss,
+};
+
+static struct omap_hwmod_ocp_if *omap3xxx_dss_slaves[] = {
+ &omap3xxx_l4_core__dss,
+};
+
+static struct omap_hwmod_opt_clk dss_opt_clks[] = {
+ { .role = "tv_clk", .clk = "dss_tv_fck" },
+ { .role = "video_clk", .clk = "dss_96m_fck" },
+ { .role = "sys_clk", .clk = "dss2_alwon_fck" },
+};
+
+static struct omap_hwmod omap3430es1_dss_core_hwmod = {
+ .name = "dss_core",
+ .class = &omap3xxx_dss_hwmod_class,
+ .main_clk = "dss1_alwon_fck", /* instead of dss_fck */
+ .mpu_irqs = omap3xxx_dss_irqs,
+ .mpu_irqs_cnt = ARRAY_SIZE(omap3xxx_dss_irqs),
+ .sdma_reqs = omap3xxx_dss_sdma_chs,
+ .sdma_reqs_cnt = ARRAY_SIZE(omap3xxx_dss_sdma_chs),
+
+ .prcm = {
+ .omap2 = {
+ .prcm_reg_id = 1,
+ .module_bit = OMAP3430_EN_DSS1_SHIFT,
+ .module_offs = OMAP3430_DSS_MOD,
+ .idlest_reg_id = 1,
+ .idlest_stdby_bit = OMAP3430ES1_ST_DSS_SHIFT,
+ },
+ },
+ .opt_clks = dss_opt_clks,
+ .opt_clks_cnt = ARRAY_SIZE(dss_opt_clks),
+ .slaves = omap3430es1_dss_slaves,
+ .slaves_cnt = ARRAY_SIZE(omap3430es1_dss_slaves),
+ .masters = omap3xxx_dss_masters,
+ .masters_cnt = ARRAY_SIZE(omap3xxx_dss_masters),
+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP3430ES1),
+ .flags = HWMOD_NO_IDLEST,
+};
+
+static struct omap_hwmod omap3xxx_dss_core_hwmod = {
+ .name = "dss_core",
+ .class = &omap3xxx_dss_hwmod_class,
+ .main_clk = "dss1_alwon_fck", /* instead of dss_fck */
+ .mpu_irqs = omap3xxx_dss_irqs,
+ .mpu_irqs_cnt = ARRAY_SIZE(omap3xxx_dss_irqs),
+ .sdma_reqs = omap3xxx_dss_sdma_chs,
+ .sdma_reqs_cnt = ARRAY_SIZE(omap3xxx_dss_sdma_chs),
+
+ .prcm = {
+ .omap2 = {
+ .prcm_reg_id = 1,
+ .module_bit = OMAP3430_EN_DSS1_SHIFT,
+ .module_offs = OMAP3430_DSS_MOD,
+ .idlest_reg_id = 1,
+ .idlest_idle_bit = OMAP3430ES2_ST_DSS_IDLE_SHIFT,
+ .idlest_stdby_bit = OMAP3430ES2_ST_DSS_STDBY_SHIFT,
+ },
+ },
+ .opt_clks = dss_opt_clks,
+ .opt_clks_cnt = ARRAY_SIZE(dss_opt_clks),
+ .slaves = omap3xxx_dss_slaves,
+ .slaves_cnt = ARRAY_SIZE(omap3xxx_dss_slaves),
+ .masters = omap3xxx_dss_masters,
+ .masters_cnt = ARRAY_SIZE(omap3xxx_dss_masters),
+ .omap_chip = OMAP_CHIP_INIT(CHIP_GE_OMAP3430ES2 |
+ CHIP_IS_OMAP3630ES1 | CHIP_GE_OMAP3630ES1_1),
+};
+
+/*
+ * 'dispc' class
+ * display controller
+ */
+
+static struct omap_hwmod_class_sysconfig omap3xxx_dispc_sysc = {
+ .rev_offs = 0x0000,
+ .sysc_offs = 0x0010,
+ .syss_offs = 0x0014,
+ .sysc_flags = (SYSC_HAS_SIDLEMODE | SYSC_HAS_CLOCKACTIVITY |
+ SYSC_HAS_MIDLEMODE | SYSC_HAS_ENAWAKEUP |
+ SYSC_HAS_SOFTRESET | SYSC_HAS_AUTOIDLE),
+ .idlemodes = (SIDLE_FORCE | SIDLE_NO | SIDLE_SMART |
+ MSTANDBY_FORCE | MSTANDBY_NO | MSTANDBY_SMART),
+ .sysc_fields = &omap_hwmod_sysc_type1,
+};
+
+static struct omap_hwmod_class omap3xxx_dispc_hwmod_class = {
+ .name = "dispc",
+ .sysc = &omap3xxx_dispc_sysc,
+};
+
+static struct omap_hwmod_addr_space omap3xxx_dss_dispc_addrs[] = {
+ {
+ .pa_start = 0x48050400,
+ .pa_end = 0x480507FF,
+ .flags = ADDR_TYPE_RT
+ },
+};
+
+/* l4_core -> dss_dispc */
+static struct omap_hwmod_ocp_if omap3xxx_l4_core__dss_dispc = {
+ .master = &omap3xxx_l4_core_hwmod,
+ .slave = &omap3xxx_dss_dispc_hwmod,
+ .clk = "dss_ick",
+ .addr = omap3xxx_dss_dispc_addrs,
+ .addr_cnt = ARRAY_SIZE(omap3xxx_dss_dispc_addrs),
+ .fw = {
+ .omap2 = {
+ .l4_fw_region = OMAP3_L4_CORE_FW_DSS_DISPC_REGION,
+ .l4_prot_group = OMAP3_L4_CORE_FW_DSS_PROT_GROUP,
+ .flags = OMAP_FIREWALL_L4,
+ }
+ },
+ .user = OCP_USER_MPU | OCP_USER_SDMA,
+};
+
+/* dss_dispc slave ports */
+static struct omap_hwmod_ocp_if *omap3xxx_dss_dispc_slaves[] = {
+ &omap3xxx_l4_core__dss_dispc,
+};
+
+static struct omap_hwmod omap3xxx_dss_dispc_hwmod = {
+ .name = "dss_dispc",
+ .class = &omap3xxx_dispc_hwmod_class,
+ .main_clk = "dss1_alwon_fck",
+ .prcm = {
+ .omap2 = {
+ .prcm_reg_id = 1,
+ .module_bit = OMAP3430_EN_DSS1_SHIFT,
+ .module_offs = OMAP3430_DSS_MOD,
+ },
+ },
+ .slaves = omap3xxx_dss_dispc_slaves,
+ .slaves_cnt = ARRAY_SIZE(omap3xxx_dss_dispc_slaves),
+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP3430ES1 |
+ CHIP_GE_OMAP3430ES2 | CHIP_IS_OMAP3630ES1 |
+ CHIP_GE_OMAP3630ES1_1),
+ .flags = HWMOD_NO_IDLEST,
+};
+
+/*
+ * 'dsi' class
+ * display serial interface controller
+ */
+
+static struct omap_hwmod_class omap3xxx_dsi_hwmod_class = {
+ .name = "dsi",
+};
+
+/* dss_dsi1 */
+static struct omap_hwmod_addr_space omap3xxx_dss_dsi1_addrs[] = {
+ {
+ .pa_start = 0x4804FC00,
+ .pa_end = 0x4804FFFF,
+ .flags = ADDR_TYPE_RT
+ },
+};
+
+/* l4_core -> dss_dsi1 */
+static struct omap_hwmod_ocp_if omap3xxx_l4_core__dss_dsi1 = {
+ .master = &omap3xxx_l4_core_hwmod,
+ .slave = &omap3xxx_dss_dsi1_hwmod,
+ .addr = omap3xxx_dss_dsi1_addrs,
+ .addr_cnt = ARRAY_SIZE(omap3xxx_dss_dsi1_addrs),
+ .fw = {
+ .omap2 = {
+ .l4_fw_region = OMAP3_L4_CORE_FW_DSS_DSI_REGION,
+ .l4_prot_group = OMAP3_L4_CORE_FW_DSS_PROT_GROUP,
+ .flags = OMAP_FIREWALL_L4,
+ }
+ },
+ .user = OCP_USER_MPU | OCP_USER_SDMA,
+};
+
+/* dss_dsi1 slave ports */
+static struct omap_hwmod_ocp_if *omap3xxx_dss_dsi1_slaves[] = {
+ &omap3xxx_l4_core__dss_dsi1,
+};
+
+static struct omap_hwmod omap3xxx_dss_dsi1_hwmod = {
+ .name = "dss_dsi1",
+ .class = &omap3xxx_dsi_hwmod_class,
+ .main_clk = "dss1_alwon_fck",
+ .prcm = {
+ .omap2 = {
+ .prcm_reg_id = 1,
+ .module_bit = OMAP3430_EN_DSS1_SHIFT,
+ .module_offs = OMAP3430_DSS_MOD,
+ },
+ },
+ .slaves = omap3xxx_dss_dsi1_slaves,
+ .slaves_cnt = ARRAY_SIZE(omap3xxx_dss_dsi1_slaves),
+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP3430ES1 |
+ CHIP_GE_OMAP3430ES2 | CHIP_IS_OMAP3630ES1 |
+ CHIP_GE_OMAP3630ES1_1),
+ .flags = HWMOD_NO_IDLEST,
+};
+
+/*
+ * 'rfbi' class
+ * remote frame buffer interface
+ */
+
+static struct omap_hwmod_class_sysconfig omap3xxx_rfbi_sysc = {
+ .rev_offs = 0x0000,
+ .sysc_offs = 0x0010,
+ .syss_offs = 0x0014,
+ .sysc_flags = (SYSC_HAS_SIDLEMODE | SYSC_HAS_SOFTRESET |
+ SYSC_HAS_AUTOIDLE),
+ .idlemodes = (SIDLE_FORCE | SIDLE_NO | SIDLE_SMART),
+ .sysc_fields = &omap_hwmod_sysc_type1,
+};
+
+static struct omap_hwmod_class omap3xxx_rfbi_hwmod_class = {
+ .name = "rfbi",
+ .sysc = &omap3xxx_rfbi_sysc,
+};
+
+static struct omap_hwmod_addr_space omap3xxx_dss_rfbi_addrs[] = {
+ {
+ .pa_start = 0x48050800,
+ .pa_end = 0x48050BFF,
+ .flags = ADDR_TYPE_RT
+ },
+};
+
+/* l4_core -> dss_rfbi */
+static struct omap_hwmod_ocp_if omap3xxx_l4_core__dss_rfbi = {
+ .master = &omap3xxx_l4_core_hwmod,
+ .slave = &omap3xxx_dss_rfbi_hwmod,
+ .clk = "dss_ick",
+ .addr = omap3xxx_dss_rfbi_addrs,
+ .addr_cnt = ARRAY_SIZE(omap3xxx_dss_rfbi_addrs),
+ .fw = {
+ .omap2 = {
+ .l4_fw_region = OMAP3_L4_CORE_FW_DSS_RFBI_REGION,
+ .l4_prot_group = OMAP3_L4_CORE_FW_DSS_PROT_GROUP ,
+ .flags = OMAP_FIREWALL_L4,
+ }
+ },
+ .user = OCP_USER_MPU | OCP_USER_SDMA,
+};
+
+/* dss_rfbi slave ports */
+static struct omap_hwmod_ocp_if *omap3xxx_dss_rfbi_slaves[] = {
+ &omap3xxx_l4_core__dss_rfbi,
+};
+
+static struct omap_hwmod omap3xxx_dss_rfbi_hwmod = {
+ .name = "dss_rfbi",
+ .class = &omap3xxx_rfbi_hwmod_class,
+ .main_clk = "dss1_alwon_fck",
+ .prcm = {
+ .omap2 = {
+ .prcm_reg_id = 1,
+ .module_bit = OMAP3430_EN_DSS1_SHIFT,
+ .module_offs = OMAP3430_DSS_MOD,
+ },
+ },
+ .slaves = omap3xxx_dss_rfbi_slaves,
+ .slaves_cnt = ARRAY_SIZE(omap3xxx_dss_rfbi_slaves),
+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP3430ES1 |
+ CHIP_GE_OMAP3430ES2 | CHIP_IS_OMAP3630ES1 |
+ CHIP_GE_OMAP3630ES1_1),
+ .flags = HWMOD_NO_IDLEST,
+};
+
+/*
+ * 'venc' class
+ * video encoder
+ */
+
+static struct omap_hwmod_class omap3xxx_venc_hwmod_class = {
+ .name = "venc",
+};
+
+/* dss_venc */
+static struct omap_hwmod_addr_space omap3xxx_dss_venc_addrs[] = {
+ {
+ .pa_start = 0x48050C00,
+ .pa_end = 0x48050FFF,
+ .flags = ADDR_TYPE_RT
+ },
+};
+
+/* l4_core -> dss_venc */
+static struct omap_hwmod_ocp_if omap3xxx_l4_core__dss_venc = {
+ .master = &omap3xxx_l4_core_hwmod,
+ .slave = &omap3xxx_dss_venc_hwmod,
+ .clk = "dss_tv_fck",
+ .addr = omap3xxx_dss_venc_addrs,
+ .addr_cnt = ARRAY_SIZE(omap3xxx_dss_venc_addrs),
+ .fw = {
+ .omap2 = {
+ .l4_fw_region = OMAP3_L4_CORE_FW_DSS_VENC_REGION,
+ .l4_prot_group = OMAP3_L4_CORE_FW_DSS_PROT_GROUP,
+ .flags = OMAP_FIREWALL_L4,
+ }
+ },
+ .user = OCP_USER_MPU | OCP_USER_SDMA,
+};
+
+/* dss_venc slave ports */
+static struct omap_hwmod_ocp_if *omap3xxx_dss_venc_slaves[] = {
+ &omap3xxx_l4_core__dss_venc,
+};
+
+static struct omap_hwmod omap3xxx_dss_venc_hwmod = {
+ .name = "dss_venc",
+ .class = &omap3xxx_venc_hwmod_class,
+ .main_clk = "dss1_alwon_fck",
+ .prcm = {
+ .omap2 = {
+ .prcm_reg_id = 1,
+ .module_bit = OMAP3430_EN_DSS1_SHIFT,
+ .module_offs = OMAP3430_DSS_MOD,
+ },
+ },
+ .slaves = omap3xxx_dss_venc_slaves,
+ .slaves_cnt = ARRAY_SIZE(omap3xxx_dss_venc_slaves),
+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP3430ES1 |
+ CHIP_GE_OMAP3430ES2 | CHIP_IS_OMAP3630ES1 |
+ CHIP_GE_OMAP3630ES1_1),
+ .flags = HWMOD_NO_IDLEST,
+};
+
/* I2C1 */
static struct omap_i2c_dev_attr i2c1_dev_attr = {
@@ -1368,6 +1795,15 @@ static __initdata struct omap_hwmod *omap3xxx_hwmods[] = {
&omap3xxx_uart2_hwmod,
&omap3xxx_uart3_hwmod,
&omap3xxx_uart4_hwmod,
+ /* dss class */
+ &omap3430es1_dss_core_hwmod,
+ &omap3xxx_dss_core_hwmod,
+ &omap3xxx_dss_dispc_hwmod,
+ &omap3xxx_dss_dsi1_hwmod,
+ &omap3xxx_dss_rfbi_hwmod,
+ &omap3xxx_dss_venc_hwmod,
+
+ /* i2c class */
&omap3xxx_i2c1_hwmod,
&omap3xxx_i2c2_hwmod,
&omap3xxx_i2c3_hwmod,
diff --git a/arch/arm/mach-omap2/omap_hwmod_44xx_data.c b/arch/arm/mach-omap2/omap_hwmod_44xx_data.c
index c2806bd11fb..93d441798d1 100644
--- a/arch/arm/mach-omap2/omap_hwmod_44xx_data.c
+++ b/arch/arm/mach-omap2/omap_hwmod_44xx_data.c
@@ -43,6 +43,13 @@
static struct omap_hwmod omap44xx_dma_system_hwmod;
static struct omap_hwmod omap44xx_dmm_hwmod;
static struct omap_hwmod omap44xx_dsp_hwmod;
+static struct omap_hwmod omap44xx_dss_core_hwmod;
+static struct omap_hwmod omap44xx_dss_dispc_hwmod;
+static struct omap_hwmod omap44xx_dss_dsi1_hwmod;
+static struct omap_hwmod omap44xx_dss_dsi2_hwmod;
+static struct omap_hwmod omap44xx_dss_hdmi_hwmod;
+static struct omap_hwmod omap44xx_dss_rfbi_hwmod;
+static struct omap_hwmod omap44xx_dss_venc_hwmod;
static struct omap_hwmod omap44xx_emif_fw_hwmod;
static struct omap_hwmod omap44xx_iva_hwmod;
static struct omap_hwmod omap44xx_l3_instr_hwmod;
@@ -237,12 +244,21 @@ static struct omap_hwmod_ocp_if omap44xx_mpu__l3_main_1 = {
.user = OCP_USER_MPU | OCP_USER_SDMA,
};
+/* dss -> l3_main_1 */
+static struct omap_hwmod_ocp_if omap44xx_dss__l3_main_1 = {
+ .master = &omap44xx_dss_core_hwmod,
+ .slave = &omap44xx_l3_main_1_hwmod,
+ .clk = "l3_div_ck",
+ .user = OCP_USER_MPU | OCP_USER_SDMA,
+};
+
/* l3_main_1 slave ports */
static struct omap_hwmod_ocp_if *omap44xx_l3_main_1_slaves[] = {
&omap44xx_dsp__l3_main_1,
&omap44xx_l3_main_2__l3_main_1,
&omap44xx_l4_cfg__l3_main_1,
&omap44xx_mpu__l3_main_1,
+ &omap44xx_dss__l3_main_1,
};
static struct omap_hwmod omap44xx_l3_main_1_hwmod = {
@@ -746,6 +762,584 @@ static struct omap_hwmod omap44xx_dsp_hwmod = {
.omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430),
};
+/* ==== DSS related classes ==== */
+ /*
+ * 'dispc' class
+ * display controller
+ */
+
+static struct omap_hwmod_class_sysconfig omap44xx_dispc_sysc = {
+ .rev_offs = 0x0000,
+ .sysc_offs = 0x0010,
+ .syss_offs = 0x0014,
+ .sysc_flags = (SYSC_HAS_AUTOIDLE | SYSC_HAS_CLOCKACTIVITY |
+ SYSC_HAS_ENAWAKEUP | SYSC_HAS_MIDLEMODE |
+ SYSC_HAS_SIDLEMODE | SYSC_HAS_SOFTRESET |
+ SYSS_HAS_RESET_STATUS),
+ .idlemodes = (SIDLE_FORCE | SIDLE_NO | SIDLE_SMART |
+ MSTANDBY_FORCE | MSTANDBY_NO | MSTANDBY_SMART),
+ .sysc_fields = &omap_hwmod_sysc_type1,
+};
+
+static struct omap_hwmod_class omap44xx_dispc_hwmod_class = {
+ .name = "dispc",
+ .sysc = &omap44xx_dispc_sysc,
+};
+
+/* dss_dispc */
+static struct omap_hwmod_irq_info omap44xx_dss_dispc_irqs[] = {
+ { .irq = 25 + OMAP44XX_IRQ_GIC_START },
+};
+
+static struct omap_hwmod_dma_info omap44xx_dss_dispc_sdma_reqs[] = {
+ { .dma_req = 5 + OMAP44XX_DMA_REQ_START },
+};
+
+static struct omap_hwmod_addr_space omap44xx_dss_dispc_addrs[] = {
+ {
+ .pa_start = 0x48041000,
+ .pa_end = 0x48041fff,
+ .flags = ADDR_TYPE_RT
+ },
+};
+
+/* l4_per -> dss_dispc */
+static struct omap_hwmod_ocp_if omap44xx_l4_per__dss_dispc = {
+ .master = &omap44xx_l4_per_hwmod,
+ .slave = &omap44xx_dss_dispc_hwmod,
+ .clk = "l4_div_ck",
+ .addr = omap44xx_dss_dispc_addrs,
+ .addr_cnt = ARRAY_SIZE(omap44xx_dss_dispc_addrs),
+ .user = OCP_USER_MPU,
+};
+
+static struct omap_hwmod_addr_space omap44xx_dss_dispc_dma_addrs[] = {
+ {
+ .pa_start = 0x58001000,
+ .pa_end = 0x58001fff,
+ .flags = ADDR_TYPE_RT
+ },
+};
+
+/* l3_main_2 -> dss_dispc */
+static struct omap_hwmod_ocp_if omap44xx_l3_main_2__dss_dispc = {
+ .master = &omap44xx_l3_main_2_hwmod,
+ .slave = &omap44xx_dss_dispc_hwmod,
+ .clk = "l3_div_ck",
+ .addr = omap44xx_dss_dispc_dma_addrs,
+ .addr_cnt = ARRAY_SIZE(omap44xx_dss_dispc_dma_addrs),
+ .user = OCP_USER_SDMA,
+};
+
+/* dss_dispc slave ports */
+static struct omap_hwmod_ocp_if *omap44xx_dss_dispc_slaves[] = {
+ &omap44xx_l3_main_2__dss_dispc,
+ &omap44xx_l4_per__dss_dispc,
+};
+
+static struct omap_hwmod omap44xx_dss_dispc_hwmod = {
+ .name = "dss_dispc",
+ .class = &omap44xx_dispc_hwmod_class,
+ .mpu_irqs = omap44xx_dss_dispc_irqs,
+ .mpu_irqs_cnt = ARRAY_SIZE(omap44xx_dss_dispc_irqs),
+ .sdma_reqs = omap44xx_dss_dispc_sdma_reqs,
+ .sdma_reqs_cnt = ARRAY_SIZE(omap44xx_dss_dispc_sdma_reqs),
+ .main_clk = "dss_fck",
+ .prcm = {
+ .omap4 = {
+ .clkctrl_reg = OMAP4430_CM_DSS_DSS_CLKCTRL,
+ },
+ },
+ .slaves = omap44xx_dss_dispc_slaves,
+ .slaves_cnt = ARRAY_SIZE(omap44xx_dss_dispc_slaves),
+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430),
+};
+
+/*
+ * 'dsi' class
+ * display serial interface controller
+ */
+static struct omap_hwmod_class_sysconfig omap44xx_dsi_sysc = {
+ .rev_offs = 0x0000,
+ .sysc_offs = 0x0010,
+ .syss_offs = 0x0014,
+ .sysc_flags = (SYSC_HAS_AUTOIDLE | SYSC_HAS_CLOCKACTIVITY |
+ SYSC_HAS_ENAWAKEUP | SYSC_HAS_SIDLEMODE |
+ SYSC_HAS_SOFTRESET | SYSS_HAS_RESET_STATUS),
+ .idlemodes = (SIDLE_FORCE | SIDLE_NO | SIDLE_SMART),
+ .sysc_fields = &omap_hwmod_sysc_type1,
+};
+
+static struct omap_hwmod_class omap44xx_dsi_hwmod_class = {
+ .name = "dsi",
+ .sysc = &omap44xx_dsi_sysc,
+};
+
+/* dss_dsi1 */
+static struct omap_hwmod_irq_info omap44xx_dss_dsi1_irqs[] = {
+ { .irq = 53 + OMAP44XX_IRQ_GIC_START },
+};
+
+static struct omap_hwmod_dma_info omap44xx_dss_dsi1_sdma_reqs[] = {
+ { .dma_req = 74 + OMAP44XX_DMA_REQ_START },
+};
+
+static struct omap_hwmod_addr_space omap44xx_dss_dsi1_addrs[] = {
+ {
+ .pa_start = 0x48044000,
+ .pa_end = 0x480440ff,
+ .flags = ADDR_TYPE_RT
+ },
+};
+
+/* l4_per -> dss_dsi1 */
+static struct omap_hwmod_ocp_if omap44xx_l4_per__dss_dsi1 = {
+ .master = &omap44xx_l4_per_hwmod,
+ .slave = &omap44xx_dss_dsi1_hwmod,
+ .clk = "l4_div_ck",
+ .addr = omap44xx_dss_dsi1_addrs,
+ .addr_cnt = ARRAY_SIZE(omap44xx_dss_dsi1_addrs),
+ .user = OCP_USER_MPU,
+};
+
+static struct omap_hwmod_addr_space omap44xx_dss_dsi1_dma_addrs[] = {
+ {
+ .pa_start = 0x58004000,
+ .pa_end = 0x580040ff,
+ .flags = ADDR_TYPE_RT
+ },
+};
+
+/* l3_main_2 -> dss_dsi1 */
+static struct omap_hwmod_ocp_if omap44xx_l3_main_2__dss_dsi1 = {
+ .master = &omap44xx_l3_main_2_hwmod,
+ .slave = &omap44xx_dss_dsi1_hwmod,
+ .clk = "l3_div_ck",
+ .addr = omap44xx_dss_dsi1_dma_addrs,
+ .addr_cnt = ARRAY_SIZE(omap44xx_dss_dsi1_dma_addrs),
+ .user = OCP_USER_SDMA,
+};
+
+/* dss_dsi1 slave ports */
+static struct omap_hwmod_ocp_if *omap44xx_dss_dsi1_slaves[] = {
+ &omap44xx_l3_main_2__dss_dsi1,
+ &omap44xx_l4_per__dss_dsi1,
+};
+
+static struct omap_hwmod omap44xx_dss_dsi1_hwmod = {
+ .name = "dss_dsi1",
+ .class = &omap44xx_dsi_hwmod_class,
+ .mpu_irqs = omap44xx_dss_dsi1_irqs,
+ .mpu_irqs_cnt = ARRAY_SIZE(omap44xx_dss_dsi1_irqs),
+ .sdma_reqs = omap44xx_dss_dsi1_sdma_reqs,
+ .sdma_reqs_cnt = ARRAY_SIZE(omap44xx_dss_dsi1_sdma_reqs),
+ .main_clk = "dss_fck",
+ .prcm = {
+ .omap4 = {
+ .clkctrl_reg = OMAP4430_CM_DSS_DSS_CLKCTRL,
+ },
+ },
+ .slaves = omap44xx_dss_dsi1_slaves,
+ .slaves_cnt = ARRAY_SIZE(omap44xx_dss_dsi1_slaves),
+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430),
+};
+
+/* dss_dsi2 */
+static struct omap_hwmod_irq_info omap44xx_dss_dsi2_irqs[] = {
+ { .irq = 84 + OMAP44XX_IRQ_GIC_START },
+};
+
+static struct omap_hwmod_dma_info omap44xx_dss_dsi2_sdma_reqs[] = {
+ { .dma_req = 83 + OMAP44XX_DMA_REQ_START },
+};
+
+static struct omap_hwmod_addr_space omap44xx_dss_dsi2_addrs[] = {
+ {
+ .pa_start = 0x48045000,
+ .pa_end = 0x480450ff,
+ .flags = ADDR_TYPE_RT
+ },
+};
+
+/* l4_per -> dss_dsi2 */
+static struct omap_hwmod_ocp_if omap44xx_l4_per__dss_dsi2 = {
+ .master = &omap44xx_l4_per_hwmod,
+ .slave = &omap44xx_dss_dsi2_hwmod,
+ .clk = "l4_div_ck",
+ .addr = omap44xx_dss_dsi2_addrs,
+ .addr_cnt = ARRAY_SIZE(omap44xx_dss_dsi2_addrs),
+ .user = OCP_USER_MPU,
+};
+
+static struct omap_hwmod_addr_space omap44xx_dss_dsi2_dma_addrs[] = {
+ {
+ .pa_start = 0x58005000,
+ .pa_end = 0x580050ff,
+ .flags = ADDR_TYPE_RT
+ },
+};
+
+/* l3_main_2 -> dss_dsi2 */
+static struct omap_hwmod_ocp_if omap44xx_l3_main_2__dss_dsi2 = {
+ .master = &omap44xx_l3_main_2_hwmod,
+ .slave = &omap44xx_dss_dsi2_hwmod,
+ .clk = "l3_div_ck",
+ .addr = omap44xx_dss_dsi2_dma_addrs,
+ .addr_cnt = ARRAY_SIZE(omap44xx_dss_dsi2_dma_addrs),
+ .user = OCP_USER_SDMA,
+};
+
+/* dss_dsi2 slave ports */
+static struct omap_hwmod_ocp_if *omap44xx_dss_dsi2_slaves[] = {
+ &omap44xx_l3_main_2__dss_dsi2,
+ &omap44xx_l4_per__dss_dsi2,
+};
+
+static struct omap_hwmod omap44xx_dss_dsi2_hwmod = {
+ .name = "dss_dsi2",
+ .class = &omap44xx_dsi_hwmod_class,
+ .mpu_irqs = omap44xx_dss_dsi2_irqs,
+ .mpu_irqs_cnt = ARRAY_SIZE(omap44xx_dss_dsi2_irqs),
+ .sdma_reqs = omap44xx_dss_dsi2_sdma_reqs,
+ .sdma_reqs_cnt = ARRAY_SIZE(omap44xx_dss_dsi2_sdma_reqs),
+ .main_clk = "dss_fck",
+ .prcm = {
+ .omap4 = {
+ .clkctrl_reg = OMAP4430_CM_DSS_DSS_CLKCTRL,
+ },
+ },
+ .slaves = omap44xx_dss_dsi2_slaves,
+ .slaves_cnt = ARRAY_SIZE(omap44xx_dss_dsi2_slaves),
+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430),
+};
+
+/*
+ * 'dss' class
+ * display sub-system
+ */
+static struct omap_hwmod_class_sysconfig omap44xx_dss_sysc = {
+ .rev_offs = 0x0000,
+ .syss_offs = 0x0014,
+ .sysc_flags = SYSS_HAS_RESET_STATUS,
+ .idlemodes = (SIDLE_FORCE | SIDLE_NO | SIDLE_SMART),
+};
+
+static struct omap_hwmod_class omap44xx_dss_hwmod_class = {
+ .name = "dss",
+ .sysc = &omap44xx_dss_sysc,
+};
+
+/* dss */
+/* dss master ports */
+static struct omap_hwmod_ocp_if *omap44xx_dss_masters[] = {
+ &omap44xx_dss__l3_main_1,
+};
+
+static struct omap_hwmod_irq_info omap44xx_dss_irqs[] = {
+ { .irq = 25 + OMAP44XX_IRQ_GIC_START },
+};
+
+static struct omap_hwmod_addr_space omap44xx_dss_addrs[] = {
+ {
+ .pa_start = 0x48040000,
+ .pa_end = 0x4804007f,
+ .flags = ADDR_TYPE_RT
+ },
+};
+
+/* l4_per -> dss */
+static struct omap_hwmod_ocp_if omap44xx_l4_per__dss = {
+ .master = &omap44xx_l4_per_hwmod,
+ .slave = &omap44xx_dss_core_hwmod,
+ .clk = "l4_div_ck",
+ .addr = omap44xx_dss_addrs,
+ .addr_cnt = ARRAY_SIZE(omap44xx_dss_addrs),
+ .user = OCP_USER_MPU,
+};
+
+static struct omap_hwmod_addr_space omap44xx_dss_dma_addrs[] = {
+ {
+ .pa_start = 0x58000000,
+ .pa_end = 0x5800007f,
+ .flags = ADDR_TYPE_RT
+ },
+};
+
+/* l3_main_2 -> dss */
+static struct omap_hwmod_ocp_if omap44xx_l3_main_2__dss = {
+ .master = &omap44xx_l3_main_2_hwmod,
+ .slave = &omap44xx_dss_core_hwmod,
+ .clk = "l3_div_ck",
+ .addr = omap44xx_dss_dma_addrs,
+ .addr_cnt = ARRAY_SIZE(omap44xx_dss_dma_addrs),
+ .user = OCP_USER_SDMA,
+};
+
+/* dss slave ports */
+static struct omap_hwmod_ocp_if *omap44xx_dss_slaves[] = {
+ &omap44xx_l3_main_2__dss,
+ &omap44xx_l4_per__dss,
+};
+
+static struct omap_hwmod_opt_clk dss_opt_clks[] = {
+ { .role = "sys_clk", .clk = "dss_sys_clk" },
+ { .role = "tv_clk", .clk = "dss_tv_clk" },
+ { .role = "dss_clk", .clk = "dss_dss_clk" },
+ { .role = "video_clk", .clk = "dss_48mhz_clk" },
+};
+
+static struct omap_hwmod omap44xx_dss_core_hwmod = {
+ .name = "dss_core",
+ .class = &omap44xx_dss_hwmod_class,
+ .mpu_irqs = omap44xx_dss_irqs,
+ .mpu_irqs_cnt = ARRAY_SIZE(omap44xx_dss_irqs),
+ .main_clk = "dss_fck",
+ .prcm = {
+ .omap4 = {
+ .clkctrl_reg = OMAP4430_CM_DSS_DSS_CLKCTRL,
+ },
+ },
+ .opt_clks = dss_opt_clks,
+ .opt_clks_cnt = ARRAY_SIZE(dss_opt_clks),
+ .slaves = omap44xx_dss_slaves,
+ .slaves_cnt = ARRAY_SIZE(omap44xx_dss_slaves),
+ .masters = omap44xx_dss_masters,
+ .masters_cnt = ARRAY_SIZE(omap44xx_dss_masters),
+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430),
+};
+
+/*
+ * 'hdmi' class
+ * hdmi controller
+ */
+
+static struct omap_hwmod_class omap44xx_hdmi_hwmod_class = {
+ .name = "hdmi",
+};
+
+/* dss_hdmi */
+static struct omap_hwmod_irq_info omap44xx_dss_hdmi_irqs[] = {
+ { .irq = 101 + OMAP44XX_IRQ_GIC_START },
+};
+
+static struct omap_hwmod_dma_info omap44xx_dss_hdmi_sdma_reqs[] = {
+ { .dma_req = 75 + OMAP44XX_DMA_REQ_START },
+};
+
+static struct omap_hwmod_addr_space omap44xx_dss_hdmi_addrs[] = {
+ {
+ .pa_start = 0x48046000,
+ .pa_end = 0x48046fff,
+ .flags = ADDR_TYPE_RT
+ },
+};
+
+/* l4_per -> dss_hdmi */
+static struct omap_hwmod_ocp_if omap44xx_l4_per__dss_hdmi = {
+ .master = &omap44xx_l4_per_hwmod,
+ .slave = &omap44xx_dss_hdmi_hwmod,
+ .clk = "l4_div_ck",
+ .addr = omap44xx_dss_hdmi_addrs,
+ .addr_cnt = ARRAY_SIZE(omap44xx_dss_hdmi_addrs),
+ .user = OCP_USER_MPU,
+};
+
+static struct omap_hwmod_addr_space omap44xx_dss_hdmi_dma_addrs[] = {
+ {
+ .pa_start = 0x58006000,
+ .pa_end = 0x58006fff,
+ .flags = ADDR_TYPE_RT
+ },
+};
+
+/* l3_main_2 -> dss_hdmi */
+static struct omap_hwmod_ocp_if omap44xx_l3_main_2__dss_hdmi = {
+ .master = &omap44xx_l3_main_2_hwmod,
+ .slave = &omap44xx_dss_hdmi_hwmod,
+ .clk = "l3_div_ck",
+ .addr = omap44xx_dss_hdmi_dma_addrs,
+ .addr_cnt = ARRAY_SIZE(omap44xx_dss_hdmi_dma_addrs),
+ .user = OCP_USER_SDMA,
+};
+
+/* dss_hdmi slave ports */
+static struct omap_hwmod_ocp_if *omap44xx_dss_hdmi_slaves[] = {
+ &omap44xx_l3_main_2__dss_hdmi,
+ &omap44xx_l4_per__dss_hdmi,
+};
+
+static struct omap_hwmod omap44xx_dss_hdmi_hwmod = {
+ .name = "dss_hdmi",
+ .class = &omap44xx_hdmi_hwmod_class,
+ .mpu_irqs = omap44xx_dss_hdmi_irqs,
+ .mpu_irqs_cnt = ARRAY_SIZE(omap44xx_dss_hdmi_irqs),
+ .sdma_reqs = omap44xx_dss_hdmi_sdma_reqs,
+ .sdma_reqs_cnt = ARRAY_SIZE(omap44xx_dss_hdmi_sdma_reqs),
+ .main_clk = "dss_fck",
+ .prcm = {
+ .omap4 = {
+ .clkctrl_reg = OMAP4430_CM_DSS_DSS_CLKCTRL,
+ },
+ },
+ .slaves = omap44xx_dss_hdmi_slaves,
+ .slaves_cnt = ARRAY_SIZE(omap44xx_dss_hdmi_slaves),
+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430),
+};
+
+ /*
+ * 'rfbi' class
+ * remote frame buffer interface
+ */
+
+static struct omap_hwmod_class_sysconfig omap44xx_rfbi_sysc = {
+ .rev_offs = 0x0000,
+ .sysc_offs = 0x0010,
+ .syss_offs = 0x0014,
+ .sysc_flags = (SYSC_HAS_AUTOIDLE | SYSC_HAS_SIDLEMODE |
+ SYSC_HAS_SOFTRESET | SYSS_HAS_RESET_STATUS),
+ .idlemodes = (SIDLE_FORCE | SIDLE_NO | SIDLE_SMART),
+ .sysc_fields = &omap_hwmod_sysc_type1,
+};
+
+static struct omap_hwmod_class omap44xx_rfbi_hwmod_class = {
+ .name = "rfbi",
+ .sysc = &omap44xx_rfbi_sysc,
+};
+
+/* dss_rfbi */
+static struct omap_hwmod_dma_info omap44xx_dss_rfbi_sdma_reqs[] = {
+ { .dma_req = 13 + OMAP44XX_DMA_REQ_START },
+};
+
+static struct omap_hwmod_addr_space omap44xx_dss_rfbi_addrs[] = {
+ {
+ .pa_start = 0x48042000,
+ .pa_end = 0x480420ff,
+ .flags = ADDR_TYPE_RT
+ },
+};
+
+/* l4_per -> dss_rfbi */
+static struct omap_hwmod_ocp_if omap44xx_l4_per__dss_rfbi = {
+ .master = &omap44xx_l4_per_hwmod,
+ .slave = &omap44xx_dss_rfbi_hwmod,
+ .clk = "l4_div_ck",
+ .addr = omap44xx_dss_rfbi_addrs,
+ .addr_cnt = ARRAY_SIZE(omap44xx_dss_rfbi_addrs),
+ .user = OCP_USER_MPU,
+};
+
+static struct omap_hwmod_addr_space omap44xx_dss_rfbi_dma_addrs[] = {
+ {
+ .pa_start = 0x58002000,
+ .pa_end = 0x580020ff,
+ .flags = ADDR_TYPE_RT
+ },
+};
+
+/* l3_main_2 -> dss_rfbi */
+static struct omap_hwmod_ocp_if omap44xx_l3_main_2__dss_rfbi = {
+ .master = &omap44xx_l3_main_2_hwmod,
+ .slave = &omap44xx_dss_rfbi_hwmod,
+ .clk = "l3_div_ck",
+ .addr = omap44xx_dss_rfbi_dma_addrs,
+ .addr_cnt = ARRAY_SIZE(omap44xx_dss_rfbi_dma_addrs),
+ .user = OCP_USER_SDMA,
+};
+
+/* dss_rfbi slave ports */
+static struct omap_hwmod_ocp_if *omap44xx_dss_rfbi_slaves[] = {
+ &omap44xx_l3_main_2__dss_rfbi,
+ &omap44xx_l4_per__dss_rfbi,
+};
+
+static struct omap_hwmod omap44xx_dss_rfbi_hwmod = {
+ .name = "dss_rfbi",
+ .class = &omap44xx_rfbi_hwmod_class,
+ .sdma_reqs = omap44xx_dss_rfbi_sdma_reqs,
+ .sdma_reqs_cnt = ARRAY_SIZE(omap44xx_dss_rfbi_sdma_reqs),
+ .main_clk = "dss_fck",
+ .prcm = {
+ .omap4 = {
+ .clkctrl_reg = OMAP4430_CM_DSS_DSS_CLKCTRL,
+ },
+ },
+ .slaves = omap44xx_dss_rfbi_slaves,
+ .slaves_cnt = ARRAY_SIZE(omap44xx_dss_rfbi_slaves),
+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430),
+};
+
+/*
+ * 'venc' class
+ * video encoder
+ */
+
+static struct omap_hwmod_class_sysconfig omap44xx_venc_sysc = {
+ .idlemodes = (SIDLE_FORCE | SIDLE_NO | SIDLE_SMART),
+};
+
+static struct omap_hwmod_class omap44xx_venc_hwmod_class = {
+ .name = "venc",
+ .sysc = &omap44xx_venc_sysc,
+};
+
+/* dss_venc */
+static struct omap_hwmod_addr_space omap44xx_dss_venc_addrs[] = {
+ {
+ .pa_start = 0x48043000,
+ .pa_end = 0x480430ff,
+ .flags = ADDR_TYPE_RT
+ },
+};
+
+/* l4_per -> dss_venc */
+static struct omap_hwmod_ocp_if omap44xx_l4_per__dss_venc = {
+ .master = &omap44xx_l4_per_hwmod,
+ .slave = &omap44xx_dss_venc_hwmod,
+ .clk = "l4_div_ck",
+ .addr = omap44xx_dss_venc_addrs,
+ .addr_cnt = ARRAY_SIZE(omap44xx_dss_venc_addrs),
+ .user = OCP_USER_MPU,
+};
+
+static struct omap_hwmod_addr_space omap44xx_dss_venc_dma_addrs[] = {
+ {
+ .pa_start = 0x58003000,
+ .pa_end = 0x580030ff,
+ .flags = ADDR_TYPE_RT
+ },
+};
+
+/* l3_main_2 -> dss_venc */
+static struct omap_hwmod_ocp_if omap44xx_l3_main_2__dss_venc = {
+ .master = &omap44xx_l3_main_2_hwmod,
+ .slave = &omap44xx_dss_venc_hwmod,
+ .clk = "l3_div_ck",
+ .addr = omap44xx_dss_venc_dma_addrs,
+ .addr_cnt = ARRAY_SIZE(omap44xx_dss_venc_dma_addrs),
+ .user = OCP_USER_SDMA,
+};
+
+/* dss_venc slave ports */
+static struct omap_hwmod_ocp_if *omap44xx_dss_venc_slaves[] = {
+ &omap44xx_l3_main_2__dss_venc,
+ &omap44xx_l4_per__dss_venc,
+};
+
+static struct omap_hwmod omap44xx_dss_venc_hwmod = {
+ .name = "dss_venc",
+ .class = &omap44xx_venc_hwmod_class,
+ .prcm = {
+ .omap4 = {
+ .clkctrl_reg = OMAP4430_CM_DSS_DSS_CLKCTRL,
+ },
+ },
+ .slaves = omap44xx_dss_venc_slaves,
+ .slaves_cnt = ARRAY_SIZE(omap44xx_dss_venc_slaves),
+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430),
+};
+
+
/*
* 'gpio' class
* general purpose io module
@@ -1464,6 +2058,7 @@ static struct omap_hwmod omap44xx_mpu_hwmod = {
.mpu_irqs = omap44xx_mpu_irqs,
.mpu_irqs_cnt = ARRAY_SIZE(omap44xx_mpu_irqs),
.main_clk = "dpll_mpu_m2_ck",
+ .vdd_name = "mpu",
.prcm = {
.omap4 = {
.clkctrl_reg = OMAP4430_CM_MPU_MPU_CLKCTRL,
@@ -2031,6 +2626,15 @@ static __initdata struct omap_hwmod *omap44xx_hwmods[] = {
&omap44xx_dsp_hwmod,
&omap44xx_dsp_c0_hwmod,
+ /* dss class */
+ &omap44xx_dss_core_hwmod,
+ &omap44xx_dss_dispc_hwmod,
+ &omap44xx_dss_dsi1_hwmod,
+ &omap44xx_dss_dsi2_hwmod,
+ &omap44xx_dss_hdmi_hwmod,
+ &omap44xx_dss_rfbi_hwmod,
+ &omap44xx_dss_venc_hwmod,
+
/* gpio class */
&omap44xx_gpio1_hwmod,
&omap44xx_gpio2_hwmod,
diff --git a/arch/arm/mach-omap2/omap_twl.c b/arch/arm/mach-omap2/omap_twl.c
index 00e1d2b5368..5100125bc2f 100644
--- a/arch/arm/mach-omap2/omap_twl.c
+++ b/arch/arm/mach-omap2/omap_twl.c
@@ -59,8 +59,15 @@
static bool is_offset_valid;
static u8 smps_offset;
+/*
+ * Flag to ensure Smartreflex bit in TWL
+ * being cleared in board file is not overwritten.
+ */
+static bool __initdata twl_sr_enable_autoinit;
+#define TWL4030_DCDC_GLOBAL_CFG 0x06
#define REG_SMPS_OFFSET 0xE0
+#define SMARTREFLEX_ENABLE BIT(3)
static unsigned long twl4030_vsel_to_uv(const u8 vsel)
{
@@ -269,6 +276,18 @@ int __init omap3_twl_init(void)
omap3_core_volt_info.vp_vddmax = OMAP3630_VP2_VLIMITTO_VDDMAX;
}
+ /*
+ * The smartreflex bit on twl4030 specifies if the setting of voltage
+ * is done over the I2C_SR path. Since this setting is independent of
+ * the actual usage of smartreflex AVS module, we enable TWL SR bit
+ * by default irrespective of whether smartreflex AVS module is enabled
+ * on the OMAP side or not. This is because without this bit enabled,
+ * the voltage scaling through vp forceupdate/bypass mechanism of
+ * voltage scaling will not function on TWL over I2C_SR.
+ */
+ if (!twl_sr_enable_autoinit)
+ omap3_twl_set_sr_bit(true);
+
voltdm = omap_voltage_domain_lookup("mpu");
omap_voltage_register_pmic(voltdm, &omap3_mpu_volt_info);
@@ -277,3 +296,44 @@ int __init omap3_twl_init(void)
return 0;
}
+
+/**
+ * omap3_twl_set_sr_bit() - Set/Clear SR bit on TWL
+ * @enable: enable SR mode in twl or not
+ *
+ * If 'enable' is true, enables Smartreflex bit on TWL 4030 to make sure
+ * voltage scaling through OMAP SR works. Else, the smartreflex bit
+ * on twl4030 is cleared as there are platforms which use OMAP3 and T2 but
+ * use Synchronized Scaling Hardware Strategy (ENABLE_VMODE=1) and Direct
+ * Strategy Software Scaling Mode (ENABLE_VMODE=0), for setting the voltages,
+ * in those scenarios this bit is to be cleared (enable = false).
+ *
+ * Returns 0 on sucess, error is returned if I2C read/write fails.
+ */
+int __init omap3_twl_set_sr_bit(bool enable)
+{
+ u8 temp;
+ int ret;
+ if (twl_sr_enable_autoinit)
+ pr_warning("%s: unexpected multiple calls\n", __func__);
+
+ ret = twl_i2c_read_u8(TWL4030_MODULE_PM_RECEIVER, &temp,
+ TWL4030_DCDC_GLOBAL_CFG);
+ if (ret)
+ goto err;
+
+ if (enable)
+ temp |= SMARTREFLEX_ENABLE;
+ else
+ temp &= ~SMARTREFLEX_ENABLE;
+
+ ret = twl_i2c_write_u8(TWL4030_MODULE_PM_RECEIVER, temp,
+ TWL4030_DCDC_GLOBAL_CFG);
+ if (!ret) {
+ twl_sr_enable_autoinit = true;
+ return 0;
+ }
+err:
+ pr_err("%s: Error access to TWL4030 (%d)\n", __func__, ret);
+ return ret;
+}
diff --git a/arch/arm/mach-omap2/opp3xxx_data.c b/arch/arm/mach-omap2/opp3xxx_data.c
index 0486fce8a92..eefd6aff3f2 100644
--- a/arch/arm/mach-omap2/opp3xxx_data.c
+++ b/arch/arm/mach-omap2/opp3xxx_data.c
@@ -19,20 +19,21 @@
#include <linux/module.h>
#include <plat/cpu.h>
+#include <plat/voltage.h>
#include "omap_opp_data.h"
static struct omap_opp_def __initdata omap34xx_opp_def_list[] = {
/* MPU OPP1 */
- OPP_INITIALIZER("mpu", true, 125000000, 975000),
+ OPP_INITIALIZER("mpu", true, 125000000, OMAP3430_VDD_MPU_OPP1_UV),
/* MPU OPP2 */
- OPP_INITIALIZER("mpu", true, 250000000, 1075000),
+ OPP_INITIALIZER("mpu", true, 250000000, OMAP3430_VDD_MPU_OPP2_UV),
/* MPU OPP3 */
- OPP_INITIALIZER("mpu", true, 500000000, 1200000),
+ OPP_INITIALIZER("mpu", true, 500000000, OMAP3430_VDD_MPU_OPP3_UV),
/* MPU OPP4 */
- OPP_INITIALIZER("mpu", true, 550000000, 1270000),
+ OPP_INITIALIZER("mpu", true, 550000000, OMAP3430_VDD_MPU_OPP4_UV),
/* MPU OPP5 */
- OPP_INITIALIZER("mpu", true, 600000000, 1350000),
+ OPP_INITIALIZER("mpu", true, 600000000, OMAP3430_VDD_MPU_OPP5_UV),
/*
* L3 OPP1 - 41.5 MHz is disabled because: The voltage for that OPP is
@@ -42,47 +43,47 @@ static struct omap_opp_def __initdata omap34xx_opp_def_list[] = {
* impact that frequency will do to the MPU and the whole system in
* general.
*/
- OPP_INITIALIZER("l3_main", false, 41500000, 975000),
+ OPP_INITIALIZER("l3_main", false, 41500000, OMAP3430_VDD_CORE_OPP1_UV),
/* L3 OPP2 */
- OPP_INITIALIZER("l3_main", true, 83000000, 1050000),
+ OPP_INITIALIZER("l3_main", true, 83000000, OMAP3430_VDD_CORE_OPP2_UV),
/* L3 OPP3 */
- OPP_INITIALIZER("l3_main", true, 166000000, 1150000),
+ OPP_INITIALIZER("l3_main", true, 166000000, OMAP3430_VDD_CORE_OPP3_UV),
/* DSP OPP1 */
- OPP_INITIALIZER("iva", true, 90000000, 975000),
+ OPP_INITIALIZER("iva", true, 90000000, OMAP3430_VDD_MPU_OPP1_UV),
/* DSP OPP2 */
- OPP_INITIALIZER("iva", true, 180000000, 1075000),
+ OPP_INITIALIZER("iva", true, 180000000, OMAP3430_VDD_MPU_OPP2_UV),
/* DSP OPP3 */
- OPP_INITIALIZER("iva", true, 360000000, 1200000),
+ OPP_INITIALIZER("iva", true, 360000000, OMAP3430_VDD_MPU_OPP3_UV),
/* DSP OPP4 */
- OPP_INITIALIZER("iva", true, 400000000, 1270000),
+ OPP_INITIALIZER("iva", true, 400000000, OMAP3430_VDD_MPU_OPP4_UV),
/* DSP OPP5 */
- OPP_INITIALIZER("iva", true, 430000000, 1350000),
+ OPP_INITIALIZER("iva", true, 430000000, OMAP3430_VDD_MPU_OPP5_UV),
};
static struct omap_opp_def __initdata omap36xx_opp_def_list[] = {
/* MPU OPP1 - OPP50 */
- OPP_INITIALIZER("mpu", true, 300000000, 1012500),
+ OPP_INITIALIZER("mpu", true, 300000000, OMAP3630_VDD_MPU_OPP50_UV),
/* MPU OPP2 - OPP100 */
- OPP_INITIALIZER("mpu", true, 600000000, 1200000),
+ OPP_INITIALIZER("mpu", true, 600000000, OMAP3630_VDD_MPU_OPP100_UV),
/* MPU OPP3 - OPP-Turbo */
- OPP_INITIALIZER("mpu", false, 800000000, 1325000),
+ OPP_INITIALIZER("mpu", false, 800000000, OMAP3630_VDD_MPU_OPP120_UV),
/* MPU OPP4 - OPP-SB */
- OPP_INITIALIZER("mpu", false, 1000000000, 1375000),
+ OPP_INITIALIZER("mpu", false, 1000000000, OMAP3630_VDD_MPU_OPP1G_UV),
/* L3 OPP1 - OPP50 */
- OPP_INITIALIZER("l3_main", true, 100000000, 1000000),
+ OPP_INITIALIZER("l3_main", true, 100000000, OMAP3630_VDD_CORE_OPP50_UV),
/* L3 OPP2 - OPP100, OPP-Turbo, OPP-SB */
- OPP_INITIALIZER("l3_main", true, 200000000, 1200000),
+ OPP_INITIALIZER("l3_main", true, 200000000, OMAP3630_VDD_CORE_OPP100_UV),
/* DSP OPP1 - OPP50 */
- OPP_INITIALIZER("iva", true, 260000000, 1012500),
+ OPP_INITIALIZER("iva", true, 260000000, OMAP3630_VDD_MPU_OPP50_UV),
/* DSP OPP2 - OPP100 */
- OPP_INITIALIZER("iva", true, 520000000, 1200000),
+ OPP_INITIALIZER("iva", true, 520000000, OMAP3630_VDD_MPU_OPP100_UV),
/* DSP OPP3 - OPP-Turbo */
- OPP_INITIALIZER("iva", false, 660000000, 1325000),
+ OPP_INITIALIZER("iva", false, 660000000, OMAP3630_VDD_MPU_OPP120_UV),
/* DSP OPP4 - OPP-SB */
- OPP_INITIALIZER("iva", false, 800000000, 1375000),
+ OPP_INITIALIZER("iva", false, 800000000, OMAP3630_VDD_MPU_OPP1G_UV),
};
/**
diff --git a/arch/arm/mach-omap2/opp4xxx_data.c b/arch/arm/mach-omap2/opp4xxx_data.c
index a11fa566d8e..2e8bb8a6ba9 100644
--- a/arch/arm/mach-omap2/opp4xxx_data.c
+++ b/arch/arm/mach-omap2/opp4xxx_data.c
@@ -20,22 +20,23 @@
#include <linux/module.h>
#include <plat/cpu.h>
+#include <plat/voltage.h>
#include "omap_opp_data.h"
static struct omap_opp_def __initdata omap44xx_opp_def_list[] = {
/* MPU OPP1 - OPP50 */
- OPP_INITIALIZER("mpu", true, 300000000, 1100000),
+ OPP_INITIALIZER("mpu", true, 300000000, OMAP4430_VDD_MPU_OPP50_UV),
/* MPU OPP2 - OPP100 */
- OPP_INITIALIZER("mpu", true, 600000000, 1200000),
+ OPP_INITIALIZER("mpu", true, 600000000, OMAP4430_VDD_MPU_OPP100_UV),
/* MPU OPP3 - OPP-Turbo */
- OPP_INITIALIZER("mpu", false, 800000000, 1260000),
+ OPP_INITIALIZER("mpu", true, 800000000, OMAP4430_VDD_MPU_OPPTURBO_UV),
/* MPU OPP4 - OPP-SB */
- OPP_INITIALIZER("mpu", false, 1008000000, 1350000),
+ OPP_INITIALIZER("mpu", true, 1008000000, OMAP4430_VDD_MPU_OPPNITRO_UV),
/* L3 OPP1 - OPP50 */
- OPP_INITIALIZER("l3_main_1", true, 100000000, 930000),
+ OPP_INITIALIZER("l3_main_1", true, 100000000, OMAP4430_VDD_CORE_OPP50_UV),
/* L3 OPP2 - OPP100, OPP-Turbo, OPP-SB */
- OPP_INITIALIZER("l3_main_1", true, 200000000, 1100000),
+ OPP_INITIALIZER("l3_main_1", true, 200000000, OMAP4430_VDD_CORE_OPP100_UV),
/* TODO: add IVA, DSP, aess, fdif, gpu */
};
diff --git a/arch/arm/mach-omap2/pm.c b/arch/arm/mach-omap2/pm.c
index d5a102c7198..51b0dcdef60 100644
--- a/arch/arm/mach-omap2/pm.c
+++ b/arch/arm/mach-omap2/pm.c
@@ -23,6 +23,9 @@
#include "powerdomain.h"
#include "clockdomain.h"
#include "pm.h"
+#include "cm2xxx_3xxx.h"
+#include "cm-regbits-34xx.h"
+#include "prm.h"
static struct omap_device_pm_latency *pm_lats;
@@ -31,6 +34,8 @@ static struct device *iva_dev;
static struct device *l3_dev;
static struct device *dsp_dev;
+static struct clk *dpll1_clk, *dpll2_clk, *dpll3_clk;
+
struct device *omap2_get_mpuss_device(void)
{
WARN_ON_ONCE(!mpu_dev);
@@ -77,6 +82,73 @@ static int _init_omap_device(char *name, struct device **new_dev)
return 0;
}
+static unsigned long omap3_mpu_get_rate(struct device *dev)
+{
+ return dpll1_clk->rate;
+}
+
+static int omap3_mpu_set_rate(struct device *dev, unsigned long rate)
+{
+ int ret;
+
+ ret = clk_set_rate(dpll1_clk, rate);
+ if (ret) {
+ dev_warn(dev, "%s: Unable to set rate to %ld\n",
+ __func__, rate);
+ return ret;
+ }
+
+ return 0;
+}
+
+static int omap3_iva_set_rate(struct device *dev, unsigned long rate)
+{
+ return clk_set_rate(dpll2_clk, rate);
+}
+
+static unsigned long omap3_iva_get_rate(struct device *dev)
+{
+ return dpll2_clk->rate;
+}
+
+static int omap3_l3_set_rate(struct device *dev, unsigned long rate)
+{
+ int l3_div;
+
+ l3_div = omap2_cm_read_mod_reg(CORE_MOD, CM_CLKSEL) &
+ OMAP3430_CLKSEL_L3_MASK;
+
+ return clk_set_rate(dpll3_clk, rate * l3_div);
+}
+
+static unsigned long omap3_l3_get_rate(struct device *dev)
+{
+ int l3_div;
+
+ l3_div = omap2_cm_read_mod_reg(CORE_MOD, CM_CLKSEL) &
+ OMAP3430_CLKSEL_L3_MASK;
+ return dpll3_clk->rate / l3_div;
+}
+
+static int omap4_mpu_set_rate(struct device *dev, unsigned long rate)
+{
+ int ret;
+
+ ret = clk_set_rate(dpll1_clk, rate);
+ if (ret) {
+ dev_warn(dev, "%s: Unable to set rate to %ld\n",
+ __func__, rate);
+ return ret;
+ }
+
+ return 0;
+}
+
+static unsigned long omap4_mpu_get_rate(struct device *dev)
+{
+ return dpll1_clk->rate;
+}
+
/*
* Build omap_devices for processors and bus.
*/
@@ -90,6 +162,30 @@ static void omap2_init_processor_devices(void)
} else {
_init_omap_device("l3_main", &l3_dev);
}
+
+ if (cpu_is_omap34xx()) {
+ dpll1_clk = clk_get(NULL, "dpll1_ck");
+ dpll2_clk = clk_get(NULL, "dpll2_ck");
+ dpll3_clk = clk_get(NULL, "dpll3_m2_ck");
+
+ if (mpu_dev)
+ omap_device_register_dvfs_callbacks(mpu_dev,
+ omap3_mpu_set_rate, omap3_mpu_get_rate);
+ if (iva_dev)
+ omap_device_register_dvfs_callbacks(iva_dev,
+ omap3_iva_set_rate, omap3_iva_get_rate);
+ if (l3_dev)
+ omap_device_register_dvfs_callbacks(l3_dev,
+ omap3_l3_set_rate, omap3_l3_get_rate);
+
+ } else if (cpu_is_omap44xx()) {
+ dpll1_clk = clk_get(NULL, "dpll_mpu_ck");
+
+ if (mpu_dev)
+ omap_device_register_dvfs_callbacks(mpu_dev,
+ omap4_mpu_set_rate, omap4_mpu_get_rate);
+ }
+
}
/* Types of sleep_switch used in omap_set_pwrdm_state */
diff --git a/arch/arm/mach-omap2/pm.h b/arch/arm/mach-omap2/pm.h
index 1c1b0ab5b97..797bfd12b64 100644
--- a/arch/arm/mach-omap2/pm.h
+++ b/arch/arm/mach-omap2/pm.h
@@ -92,7 +92,7 @@ extern void omap24xx_idle_loop_suspend(void);
extern void omap24xx_cpu_suspend(u32 dll_ctrl, void __iomem *sdrc_dlla_ctrl,
void __iomem *sdrc_power);
extern void omap34xx_cpu_suspend(u32 *addr, int save_state);
-extern void save_secure_ram_context(u32 *addr);
+extern int save_secure_ram_context(u32 *addr);
extern void omap3_save_scratchpad_contents(void);
extern unsigned int omap24xx_idle_loop_suspend_sz;
@@ -127,6 +127,7 @@ static inline void omap_enable_smartreflex_on_init(void) {}
#ifdef CONFIG_TWL4030_CORE
extern int omap3_twl_init(void);
extern int omap4_twl_init(void);
+extern int omap3_twl_set_sr_bit(bool enable);
#else
static inline int omap3_twl_init(void)
{
diff --git a/arch/arm/mach-omap2/sleep24xx.S b/arch/arm/mach-omap2/sleep24xx.S
index c7780cc8d91..b5071a47ec3 100644
--- a/arch/arm/mach-omap2/sleep24xx.S
+++ b/arch/arm/mach-omap2/sleep24xx.S
@@ -47,6 +47,7 @@
* Note: This code get's copied to internal SRAM at boot. When the OMAP
* wakes up it continues execution at the point it went to sleep.
*/
+ .align 3
ENTRY(omap24xx_idle_loop_suspend)
stmfd sp!, {r0, lr} @ save registers on stack
mov r0, #0 @ clear for mcr setup
@@ -82,6 +83,7 @@ ENTRY(omap24xx_idle_loop_suspend_sz)
* The DLL load value is not kept in RETENTION or OFF. It needs to be restored
* at wake
*/
+ .align 3
ENTRY(omap24xx_cpu_suspend)
stmfd sp!, {r0 - r12, lr} @ save registers on stack
mov r3, #0x0 @ clear for mcr call
diff --git a/arch/arm/mach-omap2/sleep34xx.S b/arch/arm/mach-omap2/sleep34xx.S
index 98d8232808b..6147088e6bc 100644
--- a/arch/arm/mach-omap2/sleep34xx.S
+++ b/arch/arm/mach-omap2/sleep34xx.S
@@ -64,6 +64,11 @@
#define SDRC_DLLA_STATUS_V OMAP34XX_SDRC_REGADDR(SDRC_DLLA_STATUS)
#define SDRC_DLLA_CTRL_V OMAP34XX_SDRC_REGADDR(SDRC_DLLA_CTRL)
+/*
+ * This file needs be built unconditionally as ARM to interoperate correctly
+ * with non-Thumb-2-capable firmware.
+ */
+ .arm
/*
* API functions
@@ -82,6 +87,8 @@ ENTRY(get_restore_pointer)
stmfd sp!, {lr} @ save registers on stack
adr r0, restore
ldmfd sp!, {pc} @ restore regs and return
+ENDPROC(get_restore_pointer)
+ .align
ENTRY(get_restore_pointer_sz)
.word . - get_restore_pointer
@@ -91,6 +98,8 @@ ENTRY(get_omap3630_restore_pointer)
stmfd sp!, {lr} @ save registers on stack
adr r0, restore_3630
ldmfd sp!, {pc} @ restore regs and return
+ENDPROC(get_omap3630_restore_pointer)
+ .align
ENTRY(get_omap3630_restore_pointer_sz)
.word . - get_omap3630_restore_pointer
@@ -100,6 +109,8 @@ ENTRY(get_es3_restore_pointer)
stmfd sp!, {lr} @ save registers on stack
adr r0, restore_es3
ldmfd sp!, {pc} @ restore regs and return
+ENDPROC(get_es3_restore_pointer)
+ .align
ENTRY(get_es3_restore_pointer_sz)
.word . - get_es3_restore_pointer
@@ -113,11 +124,14 @@ ENTRY(enable_omap3630_toggle_l2_on_restore)
stmfd sp!, {lr} @ save registers on stack
/* Setup so that we will disable and enable l2 */
mov r1, #0x1
- str r1, l2dis_3630
+ adrl r2, l2dis_3630 @ may be too distant for plain adr
+ str r1, [r2]
ldmfd sp!, {pc} @ restore regs and return
+ENDPROC(enable_omap3630_toggle_l2_on_restore)
.text
/* Function to call rom code to save secure ram context */
+ .align 3
ENTRY(save_secure_ram_context)
stmfd sp!, {r1-r12, lr} @ save registers on stack
adr r3, api_params @ r3 points to parameters
@@ -133,18 +147,20 @@ ENTRY(save_secure_ram_context)
mov r6, #0xff
mcr p15, 0, r0, c7, c10, 4 @ data write barrier
mcr p15, 0, r0, c7, c10, 5 @ data memory barrier
- .word 0xE1600071 @ call SMI monitor (smi #1)
+ smc #1 @ call SMI monitor (smi #1)
nop
nop
nop
nop
ldmfd sp!, {r1-r12, pc}
+ .align
sram_phy_addr_mask:
.word SRAM_BASE_P
high_mask:
.word 0xffff
api_params:
.word 0x4, 0x0, 0x0, 0x1, 0x1
+ENDPROC(save_secure_ram_context)
ENTRY(save_secure_ram_context_sz)
.word . - save_secure_ram_context
@@ -169,6 +185,7 @@ ENTRY(save_secure_ram_context_sz)
* depending on the low power mode (non-OFF vs OFF modes),
* cf. 'Resume path for xxx mode' comments.
*/
+ .align 3
ENTRY(omap34xx_cpu_suspend)
stmfd sp!, {r0-r12, lr} @ save registers on stack
@@ -279,8 +296,18 @@ clean_l2:
* - 'might' have to copy address, load and jump to it
*/
ldr r1, kernel_flush
- mov lr, pc
- bx r1
+ blx r1
+ /*
+ * The kernel doesn't interwork: v7_flush_dcache_all in particluar will
+ * always return in Thumb state when CONFIG_THUMB2_KERNEL is enabled.
+ * This sequence switches back to ARM. Note that .align may insert a
+ * nop: bx pc needs to be word-aligned in order to work.
+ */
+ THUMB( .thumb )
+ THUMB( .align )
+ THUMB( bx pc )
+ THUMB( nop )
+ .arm
omap3_do_wfi:
ldr r4, sdrc_power @ read the SDRC_POWER register
@@ -346,9 +373,9 @@ restore_es3:
and r4, r4, #0x3
cmp r4, #0x0 @ Check if previous power state of CORE is OFF
bne restore
- adr r0, es3_sdrc_fix
+ adr r0, _es3_sdrc_fix
ldr r1, sram_base
- ldr r2, es3_sdrc_fix_sz
+ ldr r2, _es3_sdrc_fix_sz
mov r2, r2, ror #2
copy_to_sram:
ldmia r0!, {r3} @ val = *src
@@ -408,7 +435,7 @@ skipl2dis:
adr r3, l2_inv_api_params @ r3 points to dummy parameters
mcr p15, 0, r0, c7, c10, 4 @ data write barrier
mcr p15, 0, r0, c7, c10, 5 @ data memory barrier
- .word 0xE1600071 @ call SMI monitor (smi #1)
+ smc #1 @ call SMI monitor (smi #1)
/* Write to Aux control register to set some bits */
mov r0, #42 @ set service ID for PPA
mov r12, r0 @ copy secure Service ID in r12
@@ -419,7 +446,7 @@ skipl2dis:
ldr r3, [r4, #0xBC] @ r3 points to parameters
mcr p15, 0, r0, c7, c10, 4 @ data write barrier
mcr p15, 0, r0, c7, c10, 5 @ data memory barrier
- .word 0xE1600071 @ call SMI monitor (smi #1)
+ smc #1 @ call SMI monitor (smi #1)
#ifdef CONFIG_OMAP3_L2_AUX_SECURE_SAVE_RESTORE
/* Restore L2 aux control register */
@@ -434,27 +461,28 @@ skipl2dis:
adds r3, r3, #8 @ r3 points to parameters
mcr p15, 0, r0, c7, c10, 4 @ data write barrier
mcr p15, 0, r0, c7, c10, 5 @ data memory barrier
- .word 0xE1600071 @ call SMI monitor (smi #1)
+ smc #1 @ call SMI monitor (smi #1)
#endif
b logic_l1_restore
+ .align
l2_inv_api_params:
.word 0x1, 0x00
l2_inv_gp:
/* Execute smi to invalidate L2 cache */
mov r12, #0x1 @ set up to invalidate L2
- .word 0xE1600070 @ Call SMI monitor (smieq)
+ smc #0 @ Call SMI monitor (smieq)
/* Write to Aux control register to set some bits */
ldr r4, scratchpad_base
ldr r3, [r4,#0xBC]
ldr r0, [r3,#4]
mov r12, #0x3
- .word 0xE1600070 @ Call SMI monitor (smieq)
+ smc #0 @ Call SMI monitor (smieq)
ldr r4, scratchpad_base
ldr r3, [r4,#0xBC]
ldr r0, [r3,#12]
mov r12, #0x2
- .word 0xE1600070 @ Call SMI monitor (smieq)
+ smc #0 @ Call SMI monitor (smieq)
logic_l1_restore:
ldr r1, l2dis_3630
cmp r1, #0x1 @ Test if L2 re-enable needed on 3630
@@ -607,6 +635,9 @@ usettbr0:
/* This function implements the erratum ID i443 WA, applies to 34xx >= ES3.0 */
.text
+ .align 3
+.type _es3_sdrc_fix, %function
+_es3_sdrc_fix:
ENTRY(es3_sdrc_fix)
ldr r4, sdrc_syscfg @ get config addr
ldr r5, [r4] @ get value
@@ -634,6 +665,7 @@ ENTRY(es3_sdrc_fix)
str r5, [r4] @ kick off refreshes
bx lr
+ .align
sdrc_syscfg:
.word SDRC_SYSCONFIG_P
sdrc_mr_0:
@@ -648,6 +680,8 @@ sdrc_emr2_1:
.word SDRC_EMR2_1_P
sdrc_manual_1:
.word SDRC_MANUAL_1_P
+ENDPROC(es3_sdrc_fix)
+_es3_sdrc_fix_sz:
ENTRY(es3_sdrc_fix_sz)
.word . - es3_sdrc_fix
@@ -682,6 +716,12 @@ wait_sdrc_ready:
bic r5, r5, #0x40
str r5, [r4]
+/*
+ * PC-relative stores lead to undefined behaviour in Thumb-2: use a r7 as a
+ * base instead.
+ * Be careful not to clobber r7 when maintaining this code.
+ */
+
is_dll_in_lock_mode:
/* Is dll in lock mode? */
ldr r4, sdrc_dlla_ctrl
@@ -689,10 +729,11 @@ is_dll_in_lock_mode:
tst r5, #0x4
bxne lr @ Return if locked
/* wait till dll locks */
+ adr r7, kick_counter
wait_dll_lock_timed:
ldr r4, wait_dll_lock_counter
add r4, r4, #1
- str r4, wait_dll_lock_counter
+ str r4, [r7, #wait_dll_lock_counter - kick_counter]
ldr r4, sdrc_dlla_status
/* Wait 20uS for lock */
mov r6, #8
@@ -718,9 +759,10 @@ kick_dll:
dsb
ldr r4, kick_counter
add r4, r4, #1
- str r4, kick_counter
+ str r4, [r7] @ kick_counter
b wait_dll_lock_timed
+ .align
cm_idlest1_core:
.word CM_IDLEST1_CORE_V
cm_idlest_ckgen:
@@ -763,6 +805,7 @@ kick_counter:
.word 0
wait_dll_lock_counter:
.word 0
+ENDPROC(omap34xx_cpu_suspend)
ENTRY(omap34xx_cpu_suspend_sz)
.word . - omap34xx_cpu_suspend
diff --git a/arch/arm/mach-omap2/sram242x.S b/arch/arm/mach-omap2/sram242x.S
index 055310cc77d..ff9b9dbcb30 100644
--- a/arch/arm/mach-omap2/sram242x.S
+++ b/arch/arm/mach-omap2/sram242x.S
@@ -39,6 +39,7 @@
.text
+ .align 3
ENTRY(omap242x_sram_ddr_init)
stmfd sp!, {r0 - r12, lr} @ save registers on stack
@@ -143,6 +144,7 @@ ENTRY(omap242x_sram_ddr_init_sz)
* r0 = [PRCM_FULL | PRCM_HALF] r1 = SDRC_DLLA_CTRL value r2 = [DDR | SDR]
* PRCM_FULL = 2, PRCM_HALF = 1, DDR = 1, SDR = 0
*/
+ .align 3
ENTRY(omap242x_sram_reprogram_sdrc)
stmfd sp!, {r0 - r10, lr} @ save registers on stack
mov r3, #0x0 @ clear for mrc call
@@ -238,6 +240,7 @@ ENTRY(omap242x_sram_reprogram_sdrc_sz)
/*
* Set dividers and pll. Also recalculate DLL value for DDR and unlock mode.
*/
+ .align 3
ENTRY(omap242x_sram_set_prcm)
stmfd sp!, {r0-r12, lr} @ regs to stack
adr r4, pbegin @ addr of preload start
diff --git a/arch/arm/mach-omap2/sram243x.S b/arch/arm/mach-omap2/sram243x.S
index f9007580aea..76730209fa0 100644
--- a/arch/arm/mach-omap2/sram243x.S
+++ b/arch/arm/mach-omap2/sram243x.S
@@ -39,6 +39,7 @@
.text
+ .align 3
ENTRY(omap243x_sram_ddr_init)
stmfd sp!, {r0 - r12, lr} @ save registers on stack
@@ -143,6 +144,7 @@ ENTRY(omap243x_sram_ddr_init_sz)
* r0 = [PRCM_FULL | PRCM_HALF] r1 = SDRC_DLLA_CTRL value r2 = [DDR | SDR]
* PRCM_FULL = 2, PRCM_HALF = 1, DDR = 1, SDR = 0
*/
+ .align 3
ENTRY(omap243x_sram_reprogram_sdrc)
stmfd sp!, {r0 - r10, lr} @ save registers on stack
mov r3, #0x0 @ clear for mrc call
@@ -238,6 +240,7 @@ ENTRY(omap243x_sram_reprogram_sdrc_sz)
/*
* Set dividers and pll. Also recalculate DLL value for DDR and unlock mode.
*/
+ .align 3
ENTRY(omap243x_sram_set_prcm)
stmfd sp!, {r0-r12, lr} @ regs to stack
adr r4, pbegin @ addr of preload start
diff --git a/arch/arm/mach-omap2/sram34xx.S b/arch/arm/mach-omap2/sram34xx.S
index 7f893a29d50..13a8eba81d6 100644
--- a/arch/arm/mach-omap2/sram34xx.S
+++ b/arch/arm/mach-omap2/sram34xx.S
@@ -34,6 +34,12 @@
#include "sdrc.h"
#include "cm2xxx_3xxx.h"
+/*
+ * This file needs be built unconditionally as ARM to interoperate correctly
+ * with non-Thumb-2-capable firmware.
+ */
+ .arm
+
.text
/* r1 parameters */
@@ -111,29 +117,42 @@
* since it will cause the ARM MMU to attempt to walk the page tables.
* These crashes may be intermittent.
*/
+ .align 3
ENTRY(omap3_sram_configure_core_dpll)
stmfd sp!, {r1-r12, lr} @ store regs to stack
@ pull the extra args off the stack
@ and store them in SRAM
+
+/*
+ * PC-relative stores are deprecated in ARMv7 and lead to undefined behaviour
+ * in Thumb-2: use a r7 as a base instead.
+ * Be careful not to clobber r7 when maintaing this file.
+ */
+ THUMB( adr r7, omap3_sram_configure_core_dpll )
+ .macro strtext Rt:req, label:req
+ ARM( str \Rt, \label )
+ THUMB( str \Rt, [r7, \label - omap3_sram_configure_core_dpll] )
+ .endm
+
ldr r4, [sp, #52]
- str r4, omap_sdrc_rfr_ctrl_0_val
+ strtext r4, omap_sdrc_rfr_ctrl_0_val
ldr r4, [sp, #56]
- str r4, omap_sdrc_actim_ctrl_a_0_val
+ strtext r4, omap_sdrc_actim_ctrl_a_0_val
ldr r4, [sp, #60]
- str r4, omap_sdrc_actim_ctrl_b_0_val
+ strtext r4, omap_sdrc_actim_ctrl_b_0_val
ldr r4, [sp, #64]
- str r4, omap_sdrc_mr_0_val
+ strtext r4, omap_sdrc_mr_0_val
ldr r4, [sp, #68]
- str r4, omap_sdrc_rfr_ctrl_1_val
+ strtext r4, omap_sdrc_rfr_ctrl_1_val
cmp r4, #0 @ if SDRC_RFR_CTRL_1 is 0,
beq skip_cs1_params @ do not use cs1 params
ldr r4, [sp, #72]
- str r4, omap_sdrc_actim_ctrl_a_1_val
+ strtext r4, omap_sdrc_actim_ctrl_a_1_val
ldr r4, [sp, #76]
- str r4, omap_sdrc_actim_ctrl_b_1_val
+ strtext r4, omap_sdrc_actim_ctrl_b_1_val
ldr r4, [sp, #80]
- str r4, omap_sdrc_mr_1_val
+ strtext r4, omap_sdrc_mr_1_val
skip_cs1_params:
mrc p15, 0, r8, c1, c0, 0 @ read ctrl register
bic r10, r8, #0x800 @ clear Z-bit, disable branch prediction
@@ -271,6 +290,7 @@ skip_cs1_prog:
ldr r12, [r11] @ posted-write barrier for SDRC
bx lr
+ .align
omap3_sdrc_power:
.word OMAP34XX_SDRC_REGADDR(SDRC_POWER)
omap3_cm_clksel1_pll:
@@ -319,6 +339,7 @@ omap3_sdrc_dlla_ctrl:
.word OMAP34XX_SDRC_REGADDR(SDRC_DLLA_CTRL)
core_m2_mask_val:
.word 0x07FFFFFF
+ENDPROC(omap3_sram_configure_core_dpll)
ENTRY(omap3_sram_configure_core_dpll_sz)
.word . - omap3_sram_configure_core_dpll
diff --git a/arch/arm/mach-omap2/voltage.c b/arch/arm/mach-omap2/voltage.c
index 12be525b8df..f5d591a5088 100644
--- a/arch/arm/mach-omap2/voltage.c
+++ b/arch/arm/mach-omap2/voltage.c
@@ -39,123 +39,6 @@
#define VP_TRANXDONE_TIMEOUT 300
#define VOLTAGE_DIR_SIZE 16
-/* Voltage processor register offsets */
-struct vp_reg_offs {
- u8 vpconfig;
- u8 vstepmin;
- u8 vstepmax;
- u8 vlimitto;
- u8 vstatus;
- u8 voltage;
-};
-
-/* Voltage Processor bit field values, shifts and masks */
-struct vp_reg_val {
- /* PRM module */
- u16 prm_mod;
- /* VPx_VPCONFIG */
- u32 vpconfig_erroroffset;
- u16 vpconfig_errorgain;
- u32 vpconfig_errorgain_mask;
- u8 vpconfig_errorgain_shift;
- u32 vpconfig_initvoltage_mask;
- u8 vpconfig_initvoltage_shift;
- u32 vpconfig_timeouten;
- u32 vpconfig_initvdd;
- u32 vpconfig_forceupdate;
- u32 vpconfig_vpenable;
- /* VPx_VSTEPMIN */
- u8 vstepmin_stepmin;
- u16 vstepmin_smpswaittimemin;
- u8 vstepmin_stepmin_shift;
- u8 vstepmin_smpswaittimemin_shift;
- /* VPx_VSTEPMAX */
- u8 vstepmax_stepmax;
- u16 vstepmax_smpswaittimemax;
- u8 vstepmax_stepmax_shift;
- u8 vstepmax_smpswaittimemax_shift;
- /* VPx_VLIMITTO */
- u8 vlimitto_vddmin;
- u8 vlimitto_vddmax;
- u16 vlimitto_timeout;
- u8 vlimitto_vddmin_shift;
- u8 vlimitto_vddmax_shift;
- u8 vlimitto_timeout_shift;
- /* PRM_IRQSTATUS*/
- u32 tranxdone_status;
-};
-
-/* Voltage controller registers and offsets */
-struct vc_reg_info {
- /* PRM module */
- u16 prm_mod;
- /* VC register offsets */
- u8 smps_sa_reg;
- u8 smps_volra_reg;
- u8 bypass_val_reg;
- u8 cmdval_reg;
- u8 voltsetup_reg;
- /*VC_SMPS_SA*/
- u8 smps_sa_shift;
- u32 smps_sa_mask;
- /* VC_SMPS_VOL_RA */
- u8 smps_volra_shift;
- u32 smps_volra_mask;
- /* VC_BYPASS_VAL */
- u8 data_shift;
- u8 slaveaddr_shift;
- u8 regaddr_shift;
- u32 valid;
- /* VC_CMD_VAL */
- u8 cmd_on_shift;
- u8 cmd_onlp_shift;
- u8 cmd_ret_shift;
- u8 cmd_off_shift;
- u32 cmd_on_mask;
- /* PRM_VOLTSETUP */
- u8 voltsetup_shift;
- u32 voltsetup_mask;
-};
-
-/**
- * omap_vdd_info - Per Voltage Domain info
- *
- * @volt_data : voltage table having the distinct voltages supported
- * by the domain and other associated per voltage data.
- * @pmic_info : pmic specific parameters which should be populted by
- * the pmic drivers.
- * @vp_offs : structure containing the offsets for various
- * vp registers
- * @vp_reg : the register values, shifts, masks for various
- * vp registers
- * @vc_reg : structure containing various various vc registers,
- * shifts, masks etc.
- * @voltdm : pointer to the voltage domain structure
- * @debug_dir : debug directory for this voltage domain.
- * @curr_volt : current voltage for this vdd.
- * @ocp_mod : The prm module for accessing the prm irqstatus reg.
- * @prm_irqst_reg : prm irqstatus register.
- * @vp_enabled : flag to keep track of whether vp is enabled or not
- * @volt_scale : API to scale the voltage of the vdd.
- */
-struct omap_vdd_info {
- struct omap_volt_data *volt_data;
- struct omap_volt_pmic_info *pmic_info;
- struct vp_reg_offs vp_offs;
- struct vp_reg_val vp_reg;
- struct vc_reg_info vc_reg;
- struct voltagedomain voltdm;
- struct dentry *debug_dir;
- u32 curr_volt;
- u16 ocp_mod;
- u8 prm_irqst_reg;
- bool vp_enabled;
- u32 (*read_reg) (u16 mod, u8 offset);
- void (*write_reg) (u32 val, u16 mod, u8 offset);
- int (*volt_scale) (struct omap_vdd_info *vdd,
- unsigned long target_volt);
-};
-
static struct omap_vdd_info *vdd_info;
/*
* Number of scalable voltage domains.
@@ -308,6 +191,39 @@ static struct omap_volt_data omap44xx_vdd_core_volt_data[] = {
VOLT_DATA_DEFINE(0, 0, 0, 0),
};
+/* OMAP 3430 MPU Core VDD dependency table */
+static struct omap_vdd_dep_volt omap34xx_vdd1_vdd2_data[] = {
+ {.main_vdd_volt = OMAP3430_VDD_MPU_OPP1_UV, .dep_vdd_volt = OMAP3430_VDD_CORE_OPP2_UV},
+ {.main_vdd_volt = OMAP3430_VDD_MPU_OPP2_UV, .dep_vdd_volt = OMAP3430_VDD_CORE_OPP2_UV},
+ {.main_vdd_volt = OMAP3430_VDD_MPU_OPP3_UV, .dep_vdd_volt = OMAP3430_VDD_CORE_OPP3_UV},
+ {.main_vdd_volt = OMAP3430_VDD_MPU_OPP4_UV, .dep_vdd_volt = OMAP3430_VDD_CORE_OPP3_UV},
+ {.main_vdd_volt = OMAP3430_VDD_MPU_OPP5_UV, .dep_vdd_volt = OMAP3430_VDD_CORE_OPP3_UV},
+ {.main_vdd_volt = 0, .dep_vdd_volt = 0},
+};
+
+static struct omap_vdd_dep_info omap34xx_vdd1_dep_info[] = {
+ {
+ .name = "core",
+ .dep_table = omap34xx_vdd1_vdd2_data,
+ },
+};
+
+/* OMAP 3630 MPU Core VDD dependency table */
+static struct omap_vdd_dep_volt omap36xx_vdd1_vdd2_data[] = {
+ {.main_vdd_volt = OMAP3630_VDD_MPU_OPP50_UV, .dep_vdd_volt = OMAP3630_VDD_CORE_OPP50_UV},
+ {.main_vdd_volt = OMAP3630_VDD_MPU_OPP100_UV, .dep_vdd_volt = OMAP3630_VDD_CORE_OPP100_UV},
+ {.main_vdd_volt = OMAP3630_VDD_MPU_OPP120_UV, .dep_vdd_volt = OMAP3630_VDD_CORE_OPP100_UV},
+ {.main_vdd_volt = OMAP3630_VDD_MPU_OPP1G_UV, .dep_vdd_volt = OMAP3630_VDD_CORE_OPP100_UV},
+ {.main_vdd_volt = 0, .dep_vdd_volt = 0},
+};
+
+static struct omap_vdd_dep_info omap36xx_vdd1_dep_info[] = {
+ {
+ .name = "core",
+ .dep_table = omap36xx_vdd1_vdd2_data,
+ },
+};
+
static struct dentry *voltage_dir;
/* Init function pointers */
@@ -814,10 +730,15 @@ static int __init omap3_vdd_data_configure(struct omap_vdd_info *vdd)
}
if (!strcmp(vdd->voltdm.name, "mpu")) {
- if (cpu_is_omap3630())
+ if (cpu_is_omap3630()) {
vdd->volt_data = omap36xx_vddmpu_volt_data;
- else
+ vdd->dep_vdd_info = omap36xx_vdd1_dep_info;
+ vdd->nr_dep_vdd = ARRAY_SIZE(omap36xx_vdd1_dep_info);
+ } else {
vdd->volt_data = omap34xx_vddmpu_volt_data;
+ vdd->dep_vdd_info = omap34xx_vdd1_dep_info;
+ vdd->nr_dep_vdd = ARRAY_SIZE(omap34xx_vdd1_dep_info);
+ }
vdd->vp_reg.tranxdone_status = OMAP3430_VP1_TRANXDONE_ST_MASK;
vdd->vc_reg.cmdval_reg = OMAP3_PRM_VC_CMD_VAL_0_OFFSET;
diff --git a/arch/arm/mach-orion5x/include/mach/memory.h b/arch/arm/mach-orion5x/include/mach/memory.h
index 52a2955d0f8..6769917882f 100644
--- a/arch/arm/mach-orion5x/include/mach/memory.h
+++ b/arch/arm/mach-orion5x/include/mach/memory.h
@@ -7,6 +7,6 @@
#ifndef __ASM_ARCH_MEMORY_H
#define __ASM_ARCH_MEMORY_H
-#define PHYS_OFFSET UL(0x00000000)
+#define PLAT_PHYS_OFFSET UL(0x00000000)
#endif
diff --git a/arch/arm/mach-pnx4008/include/mach/memory.h b/arch/arm/mach-pnx4008/include/mach/memory.h
index 0e877008105..1275db61cee 100644
--- a/arch/arm/mach-pnx4008/include/mach/memory.h
+++ b/arch/arm/mach-pnx4008/include/mach/memory.h
@@ -16,6 +16,6 @@
/*
* Physical DRAM offset.
*/
-#define PHYS_OFFSET UL(0x80000000)
+#define PLAT_PHYS_OFFSET UL(0x80000000)
#endif
diff --git a/arch/arm/mach-pxa/balloon3.c b/arch/arm/mach-pxa/balloon3.c
index a134a1413e0..e194d928cda 100644
--- a/arch/arm/mach-pxa/balloon3.c
+++ b/arch/arm/mach-pxa/balloon3.c
@@ -829,5 +829,5 @@ MACHINE_START(BALLOON3, "Balloon3")
.init_irq = balloon3_init_irq,
.timer = &pxa_timer,
.init_machine = balloon3_init,
- .boot_params = PHYS_OFFSET + 0x100,
+ .boot_params = PLAT_PHYS_OFFSET + 0x100,
MACHINE_END
diff --git a/arch/arm/mach-pxa/include/mach/memory.h b/arch/arm/mach-pxa/include/mach/memory.h
index 92361a66b22..7f68724dcc2 100644
--- a/arch/arm/mach-pxa/include/mach/memory.h
+++ b/arch/arm/mach-pxa/include/mach/memory.h
@@ -15,7 +15,7 @@
/*
* Physical DRAM offset.
*/
-#define PHYS_OFFSET UL(0xa0000000)
+#define PLAT_PHYS_OFFSET UL(0xa0000000)
#if !defined(__ASSEMBLY__) && defined(CONFIG_MACH_ARMCORE) && defined(CONFIG_PCI)
void cmx2xx_pci_adjust_zones(unsigned long *size, unsigned long *holes);
diff --git a/arch/arm/mach-pxa/pxa25x.c b/arch/arm/mach-pxa/pxa25x.c
index fbc5b775f89..b166b1d845d 100644
--- a/arch/arm/mach-pxa/pxa25x.c
+++ b/arch/arm/mach-pxa/pxa25x.c
@@ -347,6 +347,7 @@ static struct platform_device *pxa25x_devices[] __initdata = {
&pxa25x_device_assp,
&pxa25x_device_pwm0,
&pxa25x_device_pwm1,
+ &pxa_device_asoc_platform,
};
static struct sys_device pxa25x_sysdev[] = {
diff --git a/arch/arm/mach-pxa/tosa-bt.c b/arch/arm/mach-pxa/tosa-bt.c
index c31e601eb49..b9b1e5c2b29 100644
--- a/arch/arm/mach-pxa/tosa-bt.c
+++ b/arch/arm/mach-pxa/tosa-bt.c
@@ -81,8 +81,6 @@ static int tosa_bt_probe(struct platform_device *dev)
goto err_rfk_alloc;
}
- rfkill_set_led_trigger_name(rfk, "tosa-bt");
-
rc = rfkill_register(rfk);
if (rc)
goto err_rfkill;
diff --git a/arch/arm/mach-pxa/tosa.c b/arch/arm/mach-pxa/tosa.c
index af152e70cfc..f2582ec300d 100644
--- a/arch/arm/mach-pxa/tosa.c
+++ b/arch/arm/mach-pxa/tosa.c
@@ -875,6 +875,11 @@ static struct platform_device sharpsl_rom_device = {
.dev.platform_data = &sharpsl_rom_data,
};
+static struct platform_device wm9712_device = {
+ .name = "wm9712-codec",
+ .id = -1,
+};
+
static struct platform_device *devices[] __initdata = {
&tosascoop_device,
&tosascoop_jc_device,
@@ -885,6 +890,7 @@ static struct platform_device *devices[] __initdata = {
&tosaled_device,
&tosa_bt_device,
&sharpsl_rom_device,
+ &wm9712_device,
};
static void tosa_poweroff(void)
diff --git a/arch/arm/mach-realview/Kconfig b/arch/arm/mach-realview/Kconfig
index 7ca138a943a..b9a9805e482 100644
--- a/arch/arm/mach-realview/Kconfig
+++ b/arch/arm/mach-realview/Kconfig
@@ -19,7 +19,7 @@ config REALVIEW_EB_A9MP
config REALVIEW_EB_ARM11MP
bool "Support ARM11MPCore Tile"
depends on MACH_REALVIEW_EB
- select CPU_V6
+ select CPU_V6K
select ARCH_HAS_BARRIERS if SMP
help
Enable support for the ARM11MPCore tile fitted to the Realview(R)
@@ -36,7 +36,7 @@ config REALVIEW_EB_ARM11MP_REVB
config MACH_REALVIEW_PB11MP
bool "Support RealView(R) Platform Baseboard for ARM11MPCore"
- select CPU_V6
+ select CPU_V6K
select ARM_GIC
select HAVE_PATA_PLATFORM
select ARCH_HAS_BARRIERS if SMP
@@ -45,6 +45,7 @@ config MACH_REALVIEW_PB11MP
the ARM11MPCore. This platform has an on-board ARM11MPCore and has
support for PCI-E and Compact Flash.
+# ARMv6 CPU without K extensions, but does have the new exclusive ops
config MACH_REALVIEW_PB1176
bool "Support RealView(R) Platform Baseboard for ARM1176JZF-S"
select CPU_V6
diff --git a/arch/arm/mach-realview/include/mach/memory.h b/arch/arm/mach-realview/include/mach/memory.h
index 5dafc157b27..e05fc2c4c08 100644
--- a/arch/arm/mach-realview/include/mach/memory.h
+++ b/arch/arm/mach-realview/include/mach/memory.h
@@ -24,9 +24,9 @@
* Physical DRAM offset.
*/
#ifdef CONFIG_REALVIEW_HIGH_PHYS_OFFSET
-#define PHYS_OFFSET UL(0x70000000)
+#define PLAT_PHYS_OFFSET UL(0x70000000)
#else
-#define PHYS_OFFSET UL(0x00000000)
+#define PLAT_PHYS_OFFSET UL(0x00000000)
#endif
#if !defined(__ASSEMBLY__) && defined(CONFIG_ZONE_DMA)
diff --git a/arch/arm/mach-realview/realview_eb.c b/arch/arm/mach-realview/realview_eb.c
index 6ef5c5e528b..8ede983b861 100644
--- a/arch/arm/mach-realview/realview_eb.c
+++ b/arch/arm/mach-realview/realview_eb.c
@@ -484,7 +484,7 @@ static void __init realview_eb_init(void)
MACHINE_START(REALVIEW_EB, "ARM-RealView EB")
/* Maintainer: ARM Ltd/Deep Blue Solutions Ltd */
- .boot_params = PHYS_OFFSET + 0x00000100,
+ .boot_params = PLAT_PHYS_OFFSET + 0x00000100,
.fixup = realview_fixup,
.map_io = realview_eb_map_io,
.init_irq = gic_init_irq,
diff --git a/arch/arm/mach-realview/realview_pb1176.c b/arch/arm/mach-realview/realview_pb1176.c
index cbdc97a5685..9f26369555c 100644
--- a/arch/arm/mach-realview/realview_pb1176.c
+++ b/arch/arm/mach-realview/realview_pb1176.c
@@ -379,7 +379,7 @@ static void __init realview_pb1176_init(void)
MACHINE_START(REALVIEW_PB1176, "ARM-RealView PB1176")
/* Maintainer: ARM Ltd/Deep Blue Solutions Ltd */
- .boot_params = PHYS_OFFSET + 0x00000100,
+ .boot_params = PLAT_PHYS_OFFSET + 0x00000100,
.fixup = realview_pb1176_fixup,
.map_io = realview_pb1176_map_io,
.init_irq = gic_init_irq,
diff --git a/arch/arm/mach-realview/realview_pb11mp.c b/arch/arm/mach-realview/realview_pb11mp.c
index 8e8ab7d29a6..dea06b2da3a 100644
--- a/arch/arm/mach-realview/realview_pb11mp.c
+++ b/arch/arm/mach-realview/realview_pb11mp.c
@@ -381,7 +381,7 @@ static void __init realview_pb11mp_init(void)
MACHINE_START(REALVIEW_PB11MP, "ARM-RealView PB11MPCore")
/* Maintainer: ARM Ltd/Deep Blue Solutions Ltd */
- .boot_params = PHYS_OFFSET + 0x00000100,
+ .boot_params = PLAT_PHYS_OFFSET + 0x00000100,
.fixup = realview_fixup,
.map_io = realview_pb11mp_map_io,
.init_irq = gic_init_irq,
diff --git a/arch/arm/mach-realview/realview_pba8.c b/arch/arm/mach-realview/realview_pba8.c
index 841118e3e11..7d0f1734a21 100644
--- a/arch/arm/mach-realview/realview_pba8.c
+++ b/arch/arm/mach-realview/realview_pba8.c
@@ -331,7 +331,7 @@ static void __init realview_pba8_init(void)
MACHINE_START(REALVIEW_PBA8, "ARM-RealView PB-A8")
/* Maintainer: ARM Ltd/Deep Blue Solutions Ltd */
- .boot_params = PHYS_OFFSET + 0x00000100,
+ .boot_params = PLAT_PHYS_OFFSET + 0x00000100,
.fixup = realview_fixup,
.map_io = realview_pba8_map_io,
.init_irq = gic_init_irq,
diff --git a/arch/arm/mach-realview/realview_pbx.c b/arch/arm/mach-realview/realview_pbx.c
index 02b755b009d..b89e28f8853 100644
--- a/arch/arm/mach-realview/realview_pbx.c
+++ b/arch/arm/mach-realview/realview_pbx.c
@@ -414,7 +414,7 @@ static void __init realview_pbx_init(void)
MACHINE_START(REALVIEW_PBX, "ARM-RealView PBX")
/* Maintainer: ARM Ltd/Deep Blue Solutions Ltd */
- .boot_params = PHYS_OFFSET + 0x00000100,
+ .boot_params = PLAT_PHYS_OFFSET + 0x00000100,
.fixup = realview_pbx_fixup,
.map_io = realview_pbx_map_io,
.init_irq = gic_init_irq,
diff --git a/arch/arm/mach-rpc/include/mach/memory.h b/arch/arm/mach-rpc/include/mach/memory.h
index 78191bf2519..18a221093bf 100644
--- a/arch/arm/mach-rpc/include/mach/memory.h
+++ b/arch/arm/mach-rpc/include/mach/memory.h
@@ -21,7 +21,7 @@
/*
* Physical DRAM offset.
*/
-#define PHYS_OFFSET UL(0x10000000)
+#define PLAT_PHYS_OFFSET UL(0x10000000)
/*
* Cache flushing area - ROM
diff --git a/arch/arm/mach-s3c2400/include/mach/memory.h b/arch/arm/mach-s3c2400/include/mach/memory.h
index cf5901ffd38..3f33670dd01 100644
--- a/arch/arm/mach-s3c2400/include/mach/memory.h
+++ b/arch/arm/mach-s3c2400/include/mach/memory.h
@@ -15,6 +15,6 @@
#ifndef __ASM_ARCH_MEMORY_H
#define __ASM_ARCH_MEMORY_H
-#define PHYS_OFFSET UL(0x0C000000)
+#define PLAT_PHYS_OFFSET UL(0x0C000000)
#endif
diff --git a/arch/arm/mach-s3c2410/include/mach/memory.h b/arch/arm/mach-s3c2410/include/mach/memory.h
index 6f1e5871ae4..f92b97b89c0 100644
--- a/arch/arm/mach-s3c2410/include/mach/memory.h
+++ b/arch/arm/mach-s3c2410/include/mach/memory.h
@@ -11,6 +11,6 @@
#ifndef __ASM_ARCH_MEMORY_H
#define __ASM_ARCH_MEMORY_H
-#define PHYS_OFFSET UL(0x30000000)
+#define PLAT_PHYS_OFFSET UL(0x30000000)
#endif
diff --git a/arch/arm/mach-s3c2410/mach-bast.c b/arch/arm/mach-s3c2410/mach-bast.c
index 2970ea9f7c2..18187a48a55 100644
--- a/arch/arm/mach-s3c2410/mach-bast.c
+++ b/arch/arm/mach-s3c2410/mach-bast.c
@@ -213,7 +213,7 @@ static struct s3c2410_uartcfg bast_uartcfgs[] __initdata = {
/* NAND Flash on BAST board */
-#ifdef CONFIG_PM
+#ifdef CONFIG_SUSPEND
static int bast_pm_suspend(struct sys_device *sd, pm_message_t state)
{
/* ensure that an nRESET is not generated on resume. */
diff --git a/arch/arm/mach-s3c2412/mach-jive.c b/arch/arm/mach-s3c2412/mach-jive.c
index 923e01bdf01..10643ef84eb 100644
--- a/arch/arm/mach-s3c2412/mach-jive.c
+++ b/arch/arm/mach-s3c2412/mach-jive.c
@@ -485,7 +485,7 @@ static struct s3c2410_udc_mach_info jive_udc_cfg __initdata = {
/* Jive power management device */
-#ifdef CONFIG_PM
+#ifdef CONFIG_SUSPEND
static int jive_pm_suspend(struct sys_device *sd, pm_message_t state)
{
/* Write the magic value u-boot uses to check for resume into
diff --git a/arch/arm/mach-s3c2440/mach-osiris.c b/arch/arm/mach-s3c2440/mach-osiris.c
index 14dc6789775..06d115aae7d 100644
--- a/arch/arm/mach-s3c2440/mach-osiris.c
+++ b/arch/arm/mach-s3c2440/mach-osiris.c
@@ -281,7 +281,7 @@ static struct platform_device osiris_pcmcia = {
/* Osiris power management device */
-#ifdef CONFIG_PM
+#ifdef CONFIG_SUSPEND
static unsigned char pm_osiris_ctrl0;
static int osiris_pm_suspend(struct sys_device *sd, pm_message_t state)
diff --git a/arch/arm/mach-s3c2440/s3c244x.c b/arch/arm/mach-s3c2440/s3c244x.c
index 90c1707b9c9..7e693a082f4 100644
--- a/arch/arm/mach-s3c2440/s3c244x.c
+++ b/arch/arm/mach-s3c2440/s3c244x.c
@@ -134,7 +134,7 @@ void __init s3c244x_init_clocks(int xtal)
s3c2410_baseclk_add();
}
-#ifdef CONFIG_PM
+#ifdef CONFIG_SUSPEND
static struct sleep_save s3c244x_sleep[] = {
SAVE_ITEM(S3C2440_DSC0),
diff --git a/arch/arm/mach-s3c24a0/include/mach/memory.h b/arch/arm/mach-s3c24a0/include/mach/memory.h
index 7d74fd5c8d6..7d208a71b17 100644
--- a/arch/arm/mach-s3c24a0/include/mach/memory.h
+++ b/arch/arm/mach-s3c24a0/include/mach/memory.h
@@ -11,7 +11,7 @@
#ifndef __ASM_ARCH_24A0_MEMORY_H
#define __ASM_ARCH_24A0_MEMORY_H __FILE__
-#define PHYS_OFFSET UL(0x10000000)
+#define PLAT_PHYS_OFFSET UL(0x10000000)
#define __virt_to_bus(x) __virt_to_phys(x)
#define __bus_to_virt(x) __phys_to_virt(x)
diff --git a/arch/arm/mach-s3c64xx/Makefile b/arch/arm/mach-s3c64xx/Makefile
index 4657363f067..183ebb395ed 100644
--- a/arch/arm/mach-s3c64xx/Makefile
+++ b/arch/arm/mach-s3c64xx/Makefile
@@ -43,9 +43,9 @@ obj-$(CONFIG_S3C64XX_SETUP_SDHCI_GPIO) += setup-sdhci-gpio.o
# PM
-obj-$(CONFIG_PM) += pm.o
-obj-$(CONFIG_PM) += sleep.o
-obj-$(CONFIG_PM) += irq-pm.o
+obj-$(CONFIG_SUSPEND) += pm.o
+obj-$(CONFIG_SUSPEND) += sleep.o
+obj-$(CONFIG_SUSPEND) += irq-pm.o
# Machine support
diff --git a/arch/arm/mach-s3c64xx/include/mach/memory.h b/arch/arm/mach-s3c64xx/include/mach/memory.h
index 42cc54e2ee3..4760cdae1eb 100644
--- a/arch/arm/mach-s3c64xx/include/mach/memory.h
+++ b/arch/arm/mach-s3c64xx/include/mach/memory.h
@@ -13,7 +13,7 @@
#ifndef __ASM_ARCH_MEMORY_H
#define __ASM_ARCH_MEMORY_H
-#define PHYS_OFFSET UL(0x50000000)
+#define PLAT_PHYS_OFFSET UL(0x50000000)
#define CONSISTENT_DMA_SIZE SZ_8M
diff --git a/arch/arm/mach-s5p6442/include/mach/memory.h b/arch/arm/mach-s5p6442/include/mach/memory.h
index 9ddd877ba2e..cfe259dded3 100644
--- a/arch/arm/mach-s5p6442/include/mach/memory.h
+++ b/arch/arm/mach-s5p6442/include/mach/memory.h
@@ -13,7 +13,7 @@
#ifndef __ASM_ARCH_MEMORY_H
#define __ASM_ARCH_MEMORY_H
-#define PHYS_OFFSET UL(0x20000000)
+#define PLAT_PHYS_OFFSET UL(0x20000000)
#define CONSISTENT_DMA_SIZE SZ_8M
#endif /* __ASM_ARCH_MEMORY_H */
diff --git a/arch/arm/mach-s5p64x0/include/mach/memory.h b/arch/arm/mach-s5p64x0/include/mach/memory.h
index 1b036b0a24c..365a6eb4b88 100644
--- a/arch/arm/mach-s5p64x0/include/mach/memory.h
+++ b/arch/arm/mach-s5p64x0/include/mach/memory.h
@@ -13,7 +13,7 @@
#ifndef __ASM_ARCH_MEMORY_H
#define __ASM_ARCH_MEMORY_H __FILE__
-#define PHYS_OFFSET UL(0x20000000)
+#define PLAT_PHYS_OFFSET UL(0x20000000)
#define CONSISTENT_DMA_SIZE SZ_8M
#endif /* __ASM_ARCH_MEMORY_H */
diff --git a/arch/arm/mach-s5pc100/include/mach/memory.h b/arch/arm/mach-s5pc100/include/mach/memory.h
index 4b60d18179f..bda4e79fd5f 100644
--- a/arch/arm/mach-s5pc100/include/mach/memory.h
+++ b/arch/arm/mach-s5pc100/include/mach/memory.h
@@ -13,6 +13,6 @@
#ifndef __ASM_ARCH_MEMORY_H
#define __ASM_ARCH_MEMORY_H
-#define PHYS_OFFSET UL(0x20000000)
+#define PLAT_PHYS_OFFSET UL(0x20000000)
#endif
diff --git a/arch/arm/mach-s5pv210/cpufreq.c b/arch/arm/mach-s5pv210/cpufreq.c
index a6f22920a2c..7e697cdf698 100644
--- a/arch/arm/mach-s5pv210/cpufreq.c
+++ b/arch/arm/mach-s5pv210/cpufreq.c
@@ -389,7 +389,7 @@ static int s5pv210_target(struct cpufreq_policy *policy,
return 0;
}
-#ifdef CONFIG_PM
+#ifdef CONFIG_SUSPEND
static int s5pv210_cpufreq_suspend(struct cpufreq_policy *policy,
pm_message_t pmsg)
{
@@ -470,7 +470,7 @@ static struct cpufreq_driver s5pv210_driver = {
.get = s5pv210_getspeed,
.init = s5pv210_cpu_init,
.name = "s5pv210",
-#ifdef CONFIG_PM
+#ifdef CONFIG_SUSPEND
.suspend = s5pv210_cpufreq_suspend,
.resume = s5pv210_cpufreq_resume,
#endif
diff --git a/arch/arm/mach-s5pv210/include/mach/memory.h b/arch/arm/mach-s5pv210/include/mach/memory.h
index d503e0c4ce4..7b5fcf0da0c 100644
--- a/arch/arm/mach-s5pv210/include/mach/memory.h
+++ b/arch/arm/mach-s5pv210/include/mach/memory.h
@@ -13,7 +13,7 @@
#ifndef __ASM_ARCH_MEMORY_H
#define __ASM_ARCH_MEMORY_H
-#define PHYS_OFFSET UL(0x20000000)
+#define PLAT_PHYS_OFFSET UL(0x20000000)
#define CONSISTENT_DMA_SIZE (SZ_8M + SZ_4M + SZ_2M)
/*
diff --git a/arch/arm/mach-s5pv210/sleep.S b/arch/arm/mach-s5pv210/sleep.S
index d4d222b716b..27376223ea9 100644
--- a/arch/arm/mach-s5pv210/sleep.S
+++ b/arch/arm/mach-s5pv210/sleep.S
@@ -65,7 +65,7 @@ resume_with_mmu:
/*
* After MMU is turned on, restore the previous MMU table.
*/
- ldr r9 , =(PAGE_OFFSET - PHYS_OFFSET)
+ ldr r9 , =(PAGE_OFFSET - PLAT_PHYS_OFFSET)
add r4, r4, r9
str r12, [r4]
diff --git a/arch/arm/mach-s5pv310/cpufreq.c b/arch/arm/mach-s5pv310/cpufreq.c
index b04cbc73112..8493b6d05fb 100644
--- a/arch/arm/mach-s5pv310/cpufreq.c
+++ b/arch/arm/mach-s5pv310/cpufreq.c
@@ -457,7 +457,7 @@ static int s5pv310_target(struct cpufreq_policy *policy,
return 0;
}
-#ifdef CONFIG_PM
+#ifdef CONFIG_SUSPEND
static int s5pv310_cpufreq_suspend(struct cpufreq_policy *policy,
pm_message_t pmsg)
{
@@ -497,7 +497,7 @@ static struct cpufreq_driver s5pv310_driver = {
.get = s5pv310_getspeed,
.init = s5pv310_cpufreq_cpu_init,
.name = "s5pv310_cpufreq",
-#ifdef CONFIG_PM
+#ifdef CONFIG_SUSPEND
.suspend = s5pv310_cpufreq_suspend,
.resume = s5pv310_cpufreq_resume,
#endif
diff --git a/arch/arm/mach-s5pv310/include/mach/memory.h b/arch/arm/mach-s5pv310/include/mach/memory.h
index 1dffb482324..470b01bf861 100644
--- a/arch/arm/mach-s5pv310/include/mach/memory.h
+++ b/arch/arm/mach-s5pv310/include/mach/memory.h
@@ -13,7 +13,7 @@
#ifndef __ASM_ARCH_MEMORY_H
#define __ASM_ARCH_MEMORY_H __FILE__
-#define PHYS_OFFSET UL(0x40000000)
+#define PLAT_PHYS_OFFSET UL(0x40000000)
/* Maximum of 256MiB in one bank */
#define MAX_PHYSMEM_BITS 32
diff --git a/arch/arm/mach-s5pv310/irq-eint.c b/arch/arm/mach-s5pv310/irq-eint.c
index 477bd9e97f0..39c7f7b2d7b 100644
--- a/arch/arm/mach-s5pv310/irq-eint.c
+++ b/arch/arm/mach-s5pv310/irq-eint.c
@@ -152,7 +152,7 @@ static struct irq_chip s5pv310_irq_eint = {
.irq_mask_ack = s5pv310_irq_eint_maskack,
.irq_ack = s5pv310_irq_eint_ack,
.irq_set_type = s5pv310_irq_eint_set_type,
-#ifdef CONFIG_PM
+#ifdef CONFIG_SUSPEND
.irq_set_wake = s3c_irqext_wake,
#endif
};
diff --git a/arch/arm/mach-sa1100/include/mach/memory.h b/arch/arm/mach-sa1100/include/mach/memory.h
index 128a1dfa96b..a44da6a2916 100644
--- a/arch/arm/mach-sa1100/include/mach/memory.h
+++ b/arch/arm/mach-sa1100/include/mach/memory.h
@@ -12,7 +12,7 @@
/*
* Physical DRAM offset is 0xc0000000 on the SA1100
*/
-#define PHYS_OFFSET UL(0xc0000000)
+#define PLAT_PHYS_OFFSET UL(0xc0000000)
#ifndef __ASSEMBLY__
diff --git a/arch/arm/mach-shark/include/mach/memory.h b/arch/arm/mach-shark/include/mach/memory.h
index d9c4812f1c3..9afb1700000 100644
--- a/arch/arm/mach-shark/include/mach/memory.h
+++ b/arch/arm/mach-shark/include/mach/memory.h
@@ -15,7 +15,7 @@
/*
* Physical DRAM offset.
*/
-#define PHYS_OFFSET UL(0x08000000)
+#define PLAT_PHYS_OFFSET UL(0x08000000)
#ifndef __ASSEMBLY__
diff --git a/arch/arm/mach-shmobile/include/mach/memory.h b/arch/arm/mach-shmobile/include/mach/memory.h
index 377584e57e0..ad00c3c258f 100644
--- a/arch/arm/mach-shmobile/include/mach/memory.h
+++ b/arch/arm/mach-shmobile/include/mach/memory.h
@@ -1,7 +1,7 @@
#ifndef __ASM_MACH_MEMORY_H
#define __ASM_MACH_MEMORY_H
-#define PHYS_OFFSET UL(CONFIG_MEMORY_START)
+#define PLAT_PHYS_OFFSET UL(CONFIG_MEMORY_START)
#define MEM_SIZE UL(CONFIG_MEMORY_SIZE)
/* DMA memory at 0xf6000000 - 0xffdfffff */
diff --git a/arch/arm/mach-tcc8k/board-tcc8000-sdk.c b/arch/arm/mach-tcc8k/board-tcc8000-sdk.c
index 7991415e666..fb6426ddeb7 100644
--- a/arch/arm/mach-tcc8k/board-tcc8000-sdk.c
+++ b/arch/arm/mach-tcc8k/board-tcc8000-sdk.c
@@ -54,7 +54,7 @@ static void __init tcc8k_map_io(void)
}
MACHINE_START(TCC8000_SDK, "Telechips TCC8000-SDK Demo Board")
- .boot_params = PHYS_OFFSET + 0x00000100,
+ .boot_params = PLAT_PHYS_OFFSET + 0x00000100,
.map_io = tcc8k_map_io,
.init_irq = tcc8k_init_irq,
.init_machine = tcc8k_init,
diff --git a/arch/arm/mach-tegra/board-harmony.c b/arch/arm/mach-tegra/board-harmony.c
index b9dbdb1289d..99884e9dd69 100644
--- a/arch/arm/mach-tegra/board-harmony.c
+++ b/arch/arm/mach-tegra/board-harmony.c
@@ -113,6 +113,11 @@ static void __init tegra_harmony_init(void)
platform_add_devices(harmony_devices, ARRAY_SIZE(harmony_devices));
}
+static const char * tegra_harmony_board_compat[] = {
+ "nvidia,harmony",
+ NULL
+};
+
MACHINE_START(HARMONY, "harmony")
.boot_params = 0x00000100,
.fixup = tegra_harmony_fixup,
@@ -120,4 +125,5 @@ MACHINE_START(HARMONY, "harmony")
.init_machine = tegra_harmony_init,
.map_io = tegra_map_common_io,
.timer = &tegra_timer,
+ .dt_compat = tegra_harmony_board_compat,
MACHINE_END
diff --git a/arch/arm/mach-tegra/include/mach/memory.h b/arch/arm/mach-tegra/include/mach/memory.h
index 6151bab62af..537db3aa81a 100644
--- a/arch/arm/mach-tegra/include/mach/memory.h
+++ b/arch/arm/mach-tegra/include/mach/memory.h
@@ -22,7 +22,7 @@
#define __MACH_TEGRA_MEMORY_H
/* physical offset of RAM */
-#define PHYS_OFFSET UL(0)
+#define PLAT_PHYS_OFFSET UL(0)
#endif
diff --git a/arch/arm/mach-u300/include/mach/memory.h b/arch/arm/mach-u300/include/mach/memory.h
index bf134bcc129..888e2e351ee 100644
--- a/arch/arm/mach-u300/include/mach/memory.h
+++ b/arch/arm/mach-u300/include/mach/memory.h
@@ -15,17 +15,17 @@
#ifdef CONFIG_MACH_U300_DUAL_RAM
-#define PHYS_OFFSET UL(0x48000000)
+#define PLAT_PHYS_OFFSET UL(0x48000000)
#define BOOT_PARAMS_OFFSET (PHYS_OFFSET + 0x100)
#else
#ifdef CONFIG_MACH_U300_2MB_ALIGNMENT_FIX
-#define PHYS_OFFSET (0x28000000 + \
+#define PLAT_PHYS_OFFSET (0x28000000 + \
(CONFIG_MACH_U300_ACCESS_MEM_SIZE - \
(CONFIG_MACH_U300_ACCESS_MEM_SIZE & 1))*1024*1024)
#else
-#define PHYS_OFFSET (0x28000000 + \
+#define PLAT_PHYS_OFFSET (0x28000000 + \
(CONFIG_MACH_U300_ACCESS_MEM_SIZE + \
(CONFIG_MACH_U300_ACCESS_MEM_SIZE & 1))*1024*1024)
#endif
diff --git a/arch/arm/mach-u300/u300.c b/arch/arm/mach-u300/u300.c
index 07c35a84642..48b3b7f3996 100644
--- a/arch/arm/mach-u300/u300.c
+++ b/arch/arm/mach-u300/u300.c
@@ -19,9 +19,9 @@
#include <linux/io.h>
#include <mach/hardware.h>
#include <mach/platform.h>
-#include <mach/memory.h>
#include <asm/mach-types.h>
#include <asm/mach/arch.h>
+#include <asm/memory.h>
static void __init u300_reserve(void)
{
diff --git a/arch/arm/mach-ux500/board-mop500-sdi.c b/arch/arm/mach-ux500/board-mop500-sdi.c
index 4b996676594..4ba3d930a06 100644
--- a/arch/arm/mach-ux500/board-mop500-sdi.c
+++ b/arch/arm/mach-ux500/board-mop500-sdi.c
@@ -106,8 +106,8 @@ void mop500_sdi_tc35892_init(void)
if (ret)
return;
- gpio_direction_output(GPIO_SDMMC_1V8_3V_SEL, 1);
- gpio_direction_output(GPIO_SDMMC_EN, 0);
+ gpio_direction_output(GPIO_SDMMC_1V8_3V_SEL, 0);
+ gpio_direction_output(GPIO_SDMMC_EN, 1);
db8500_add_sdi0(&mop500_sdi0_data);
}
diff --git a/arch/arm/mach-ux500/board-mop500.c b/arch/arm/mach-ux500/board-mop500.c
index a393f57ed2a..9119565f159 100644
--- a/arch/arm/mach-ux500/board-mop500.c
+++ b/arch/arm/mach-ux500/board-mop500.c
@@ -224,3 +224,13 @@ MACHINE_START(U8500, "ST-Ericsson MOP500 platform")
.timer = &ux500_timer,
.init_machine = u8500_init_machine,
MACHINE_END
+
+MACHINE_START(NOMADIK, "ST-Ericsson MOP500 platform")
+ /* Maintainer: Srinidhi Kasagar <srinidhi.kasagar@stericsson.com> */
+ .boot_params = 0x100,
+ .map_io = u8500_map_io,
+ .init_irq = ux500_init_irq,
+ /* we re-use nomadik timer here */
+ .timer = &ux500_timer,
+ .init_machine = u8500_init_machine,
+MACHINE_END
diff --git a/arch/arm/mach-ux500/clock.c b/arch/arm/mach-ux500/clock.c
index b2b0a3b9be8..9a0a6ed9cd5 100644
--- a/arch/arm/mach-ux500/clock.c
+++ b/arch/arm/mach-ux500/clock.c
@@ -313,7 +313,7 @@ static DEFINE_PRCMU_CLK_RATE(uartclk, 0x0, 5, UARTCLK, 38400000);
static DEFINE_PRCMU_CLK(msp02clk, 0x0, 6, MSP02CLK);
static DEFINE_PRCMU_CLK(msp1clk, 0x0, 7, MSP1CLK); /* v1 */
static DEFINE_PRCMU_CLK_RATE(i2cclk, 0x0, 8, I2CCLK, 48000000);
-static DEFINE_PRCMU_CLK_RATE(sdmmcclk, 0x0, 9, SDMMCCLK, 50000000);
+static DEFINE_PRCMU_CLK_RATE(sdmmcclk, 0x0, 9, SDMMCCLK, 100000000);
static DEFINE_PRCMU_CLK(slimclk, 0x0, 10, SLIMCLK);
static DEFINE_PRCMU_CLK(per1clk, 0x0, 11, PER1CLK);
static DEFINE_PRCMU_CLK(per2clk, 0x0, 12, PER2CLK);
diff --git a/arch/arm/mach-ux500/cpu-db8500.c b/arch/arm/mach-ux500/cpu-db8500.c
index 1748fbc5853..5c0fabf5fa0 100644
--- a/arch/arm/mach-ux500/cpu-db8500.c
+++ b/arch/arm/mach-ux500/cpu-db8500.c
@@ -12,22 +12,20 @@
#include <linux/init.h>
#include <linux/device.h>
#include <linux/amba/bus.h>
+#include <linux/interrupt.h>
#include <linux/irq.h>
#include <linux/gpio.h>
#include <linux/platform_device.h>
#include <linux/io.h>
#include <asm/mach/map.h>
+#include <asm/pmu.h>
#include <mach/hardware.h>
#include <mach/setup.h>
#include <mach/devices.h>
#include "devices-db8500.h"
-static struct platform_device *platform_devs[] __initdata = {
- &u8500_dma40_device,
-};
-
/* minimum static i/o mapping required to boot U8500 platforms */
static struct map_desc u8500_uart_io_desc[] __initdata = {
__IO_DEV_DESC(U8500_UART0_BASE, SZ_4K),
@@ -89,6 +87,51 @@ void __init u8500_map_io(void)
iotable_init(u8500_v2_io_desc, ARRAY_SIZE(u8500_v2_io_desc));
}
+static struct resource db8500_pmu_resources[] = {
+ [0] = {
+ .start = IRQ_DB8500_PMU,
+ .end = IRQ_DB8500_PMU,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+/*
+ * The PMU IRQ lines of two cores are wired together into a single interrupt.
+ * Bounce the interrupt to the other core if it's not ours.
+ */
+static irqreturn_t db8500_pmu_handler(int irq, void *dev, irq_handler_t handler)
+{
+ irqreturn_t ret = handler(irq, dev);
+ int other = !smp_processor_id();
+
+ if (ret == IRQ_NONE && cpu_online(other))
+ irq_set_affinity(irq, cpumask_of(other));
+
+ /*
+ * We should be able to get away with the amount of IRQ_NONEs we give,
+ * while still having the spurious IRQ detection code kick in if the
+ * interrupt really starts hitting spuriously.
+ */
+ return ret;
+}
+
+static struct arm_pmu_platdata db8500_pmu_platdata = {
+ .handle_irq = db8500_pmu_handler,
+};
+
+static struct platform_device db8500_pmu_device = {
+ .name = "arm-pmu",
+ .id = ARM_PMU_DEVICE_CPU,
+ .num_resources = ARRAY_SIZE(db8500_pmu_resources),
+ .resource = db8500_pmu_resources,
+ .dev.platform_data = &db8500_pmu_platdata,
+};
+
+static struct platform_device *platform_devs[] __initdata = {
+ &u8500_dma40_device,
+ &db8500_pmu_device,
+};
+
static resource_size_t __initdata db8500_gpio_base[] = {
U8500_GPIOBANK0_BASE,
U8500_GPIOBANK1_BASE,
diff --git a/arch/arm/mach-ux500/include/mach/memory.h b/arch/arm/mach-ux500/include/mach/memory.h
index 510571a59e2..2ef697a6700 100644
--- a/arch/arm/mach-ux500/include/mach/memory.h
+++ b/arch/arm/mach-ux500/include/mach/memory.h
@@ -12,7 +12,7 @@
/*
* Physical DRAM offset.
*/
-#define PHYS_OFFSET UL(0x00000000)
+#define PLAT_PHYS_OFFSET UL(0x00000000)
#define BUS_OFFSET UL(0x00000000)
#endif
diff --git a/arch/arm/mach-versatile/include/mach/memory.h b/arch/arm/mach-versatile/include/mach/memory.h
index 79aeab86b90..dacc9d8e4e6 100644
--- a/arch/arm/mach-versatile/include/mach/memory.h
+++ b/arch/arm/mach-versatile/include/mach/memory.h
@@ -23,6 +23,6 @@
/*
* Physical DRAM offset.
*/
-#define PHYS_OFFSET UL(0x00000000)
+#define PLAT_PHYS_OFFSET UL(0x00000000)
#endif
diff --git a/arch/arm/mach-versatile/versatile_ab.c b/arch/arm/mach-versatile/versatile_ab.c
index aa9730fb13b..62053dfd54c 100644
--- a/arch/arm/mach-versatile/versatile_ab.c
+++ b/arch/arm/mach-versatile/versatile_ab.c
@@ -33,6 +33,11 @@
#include "core.h"
+static const char *versatile_ab_match[] __initdata = {
+ "arm,versatile-ab",
+ NULL,
+};
+
MACHINE_START(VERSATILE_AB, "ARM-Versatile AB")
/* Maintainer: ARM Ltd/Deep Blue Solutions Ltd */
.boot_params = 0x00000100,
@@ -40,4 +45,5 @@ MACHINE_START(VERSATILE_AB, "ARM-Versatile AB")
.init_irq = versatile_init_irq,
.timer = &versatile_timer,
.init_machine = versatile_init,
+ .dt_compat = versatile_ab_match,
MACHINE_END
diff --git a/arch/arm/mach-versatile/versatile_pb.c b/arch/arm/mach-versatile/versatile_pb.c
index bf469642a3f..eba12fa1db0 100644
--- a/arch/arm/mach-versatile/versatile_pb.c
+++ b/arch/arm/mach-versatile/versatile_pb.c
@@ -106,6 +106,11 @@ static void __init versatile_pb_init(void)
}
}
+static const char *versatile_pb_match[] __initdata = {
+ "arm,versatile-pb",
+ NULL,
+};
+
MACHINE_START(VERSATILE_PB, "ARM-Versatile PB")
/* Maintainer: ARM Ltd/Deep Blue Solutions Ltd */
.boot_params = 0x00000100,
@@ -113,4 +118,5 @@ MACHINE_START(VERSATILE_PB, "ARM-Versatile PB")
.init_irq = versatile_init_irq,
.timer = &versatile_timer,
.init_machine = versatile_pb_init,
+ .dt_compat = versatile_pb_match,
MACHINE_END
diff --git a/arch/arm/mach-vexpress/Kconfig b/arch/arm/mach-vexpress/Kconfig
index 3f19b660a16..931148487f0 100644
--- a/arch/arm/mach-vexpress/Kconfig
+++ b/arch/arm/mach-vexpress/Kconfig
@@ -5,5 +5,8 @@ config ARCH_VEXPRESS_CA9X4
bool "Versatile Express Cortex-A9x4 tile"
select CPU_V7
select ARM_GIC
+ select ARM_ERRATA_720789
+ select ARM_ERRATA_751472
+ select ARM_ERRATA_753970
endmenu
diff --git a/arch/arm/mach-vexpress/ct-ca9x4.c b/arch/arm/mach-vexpress/ct-ca9x4.c
index e628402b754..e9bccc5230c 100644
--- a/arch/arm/mach-vexpress/ct-ca9x4.c
+++ b/arch/arm/mach-vexpress/ct-ca9x4.c
@@ -243,7 +243,7 @@ static void __init ct_ca9x4_init(void)
}
MACHINE_START(VEXPRESS, "ARM-Versatile Express CA9x4")
- .boot_params = PHYS_OFFSET + 0x00000100,
+ .boot_params = PLAT_PHYS_OFFSET + 0x00000100,
.map_io = ct_ca9x4_map_io,
.init_irq = ct_ca9x4_init_irq,
#if 0
diff --git a/arch/arm/mach-vexpress/include/mach/memory.h b/arch/arm/mach-vexpress/include/mach/memory.h
index be28232ae63..5b7fcd439d8 100644
--- a/arch/arm/mach-vexpress/include/mach/memory.h
+++ b/arch/arm/mach-vexpress/include/mach/memory.h
@@ -20,6 +20,6 @@
#ifndef __ASM_ARCH_MEMORY_H
#define __ASM_ARCH_MEMORY_H
-#define PHYS_OFFSET UL(0x60000000)
+#define PLAT_PHYS_OFFSET UL(0x60000000)
#endif
diff --git a/arch/arm/mach-w90x900/include/mach/memory.h b/arch/arm/mach-w90x900/include/mach/memory.h
index 971b80702c2..f02905ba774 100644
--- a/arch/arm/mach-w90x900/include/mach/memory.h
+++ b/arch/arm/mach-w90x900/include/mach/memory.h
@@ -18,6 +18,6 @@
#ifndef __ASM_ARCH_MEMORY_H
#define __ASM_ARCH_MEMORY_H
-#define PHYS_OFFSET UL(0x00000000)
+#define PLAT_PHYS_OFFSET UL(0x00000000)
#endif
diff --git a/arch/arm/mm/Kconfig b/arch/arm/mm/Kconfig
index e4509bae8fc..89266382b53 100644
--- a/arch/arm/mm/Kconfig
+++ b/arch/arm/mm/Kconfig
@@ -390,7 +390,7 @@ config CPU_PJ4
# ARMv6
config CPU_V6
- bool "Support ARM V6 processor" if ARCH_INTEGRATOR || MACH_REALVIEW_EB || MACH_REALVIEW_PBX || ARCH_DOVE
+ bool "Support ARM V6 processor" if ARCH_INTEGRATOR || MACH_REALVIEW_EB || MACH_REALVIEW_PBX
select CPU_32v6
select CPU_ABRT_EV6
select CPU_PABRT_V6
@@ -402,16 +402,18 @@ config CPU_V6
select CPU_TLB_V6 if MMU
# ARMv6k
-config CPU_32v6K
- bool "Support ARM V6K processor extensions" if !SMP
- depends on CPU_V6 || CPU_V7
- default y if SMP
- help
- Say Y here if your ARMv6 processor supports the 'K' extension.
- This enables the kernel to use some instructions not present
- on previous processors, and as such a kernel build with this
- enabled will not boot on processors with do not support these
- instructions.
+config CPU_V6K
+ bool "Support ARM V6K processor" if ARCH_INTEGRATOR || MACH_REALVIEW_EB || MACH_REALVIEW_PBX
+ select CPU_32v6
+ select CPU_32v6K
+ select CPU_ABRT_EV6
+ select CPU_PABRT_V6
+ select CPU_CACHE_V6
+ select CPU_CACHE_VIPT
+ select CPU_CP15_MMU
+ select CPU_HAS_ASID if MMU
+ select CPU_COPY_V6 if MMU
+ select CPU_TLB_V6 if MMU
# ARMv7
config CPU_V7
@@ -433,25 +435,33 @@ config CPU_32v3
bool
select TLS_REG_EMUL if SMP || !MMU
select NEEDS_SYSCALL_FOR_CMPXCHG if SMP
+ select CPU_USE_DOMAINS if MMU
config CPU_32v4
bool
select TLS_REG_EMUL if SMP || !MMU
select NEEDS_SYSCALL_FOR_CMPXCHG if SMP
+ select CPU_USE_DOMAINS if MMU
config CPU_32v4T
bool
select TLS_REG_EMUL if SMP || !MMU
select NEEDS_SYSCALL_FOR_CMPXCHG if SMP
+ select CPU_USE_DOMAINS if MMU
config CPU_32v5
bool
select TLS_REG_EMUL if SMP || !MMU
select NEEDS_SYSCALL_FOR_CMPXCHG if SMP
+ select CPU_USE_DOMAINS if MMU
config CPU_32v6
bool
select TLS_REG_EMUL if !CPU_32v6K && !MMU
+ select CPU_USE_DOMAINS if CPU_V6 && MMU
+
+config CPU_32v6K
+ bool
config CPU_32v7
bool
@@ -607,8 +617,6 @@ config CPU_CP15_MPU
config CPU_USE_DOMAINS
bool
- depends on MMU
- default y if !CPU_32v6K
help
This option enables or disables the use of domain switching
via the set_fs() function.
@@ -623,7 +631,7 @@ comment "Processor Features"
config ARM_THUMB
bool "Support Thumb user binaries"
- depends on CPU_ARM720T || CPU_ARM740T || CPU_ARM920T || CPU_ARM922T || CPU_ARM925T || CPU_ARM926T || CPU_ARM940T || CPU_ARM946E || CPU_ARM1020 || CPU_ARM1020E || CPU_ARM1022 || CPU_ARM1026 || CPU_XSCALE || CPU_XSC3 || CPU_MOHAWK || CPU_V6 || CPU_V7 || CPU_FEROCEON
+ depends on CPU_ARM720T || CPU_ARM740T || CPU_ARM920T || CPU_ARM922T || CPU_ARM925T || CPU_ARM926T || CPU_ARM940T || CPU_ARM946E || CPU_ARM1020 || CPU_ARM1020E || CPU_ARM1022 || CPU_ARM1026 || CPU_XSCALE || CPU_XSC3 || CPU_MOHAWK || CPU_V6 || CPU_V6K || CPU_V7 || CPU_FEROCEON
default y
help
Say Y if you want to include kernel support for running user space
@@ -644,7 +652,7 @@ config ARM_THUMBEE
config SWP_EMULATE
bool "Emulate SWP/SWPB instructions"
- depends on !CPU_USE_DOMAINS && CPU_V7 && !CPU_V6
+ depends on !CPU_USE_DOMAINS && CPU_V7
select HAVE_PROC_CPU if PROC_FS
default y if SMP
help
@@ -681,7 +689,7 @@ config CPU_BIG_ENDIAN
config CPU_ENDIAN_BE8
bool
depends on CPU_BIG_ENDIAN
- default CPU_V6 || CPU_V7
+ default CPU_V6 || CPU_V6K || CPU_V7
help
Support for the BE-8 (big-endian) mode on ARMv6 and ARMv7 processors.
@@ -747,7 +755,7 @@ config CPU_CACHE_ROUND_ROBIN
config CPU_BPREDICT_DISABLE
bool "Disable branch prediction"
- depends on CPU_ARM1020 || CPU_V6 || CPU_MOHAWK || CPU_XSC3 || CPU_V7 || CPU_FA526
+ depends on CPU_ARM1020 || CPU_V6 || CPU_V6K || CPU_MOHAWK || CPU_XSC3 || CPU_V7 || CPU_FA526
help
Say Y here to disable branch prediction. If unsure, say N.
@@ -767,7 +775,7 @@ config NEEDS_SYSCALL_FOR_CMPXCHG
config DMA_CACHE_RWFO
bool "Enable read/write for ownership DMA cache maintenance"
- depends on CPU_V6 && SMP
+ depends on CPU_V6K && SMP
default y
help
The Snoop Control Unit on ARM11MPCore does not detect the
@@ -823,7 +831,7 @@ config CACHE_L2X0
config CACHE_PL310
bool
depends on CACHE_L2X0
- default y if CPU_V7 && !CPU_V6
+ default y if CPU_V7 && !(CPU_V6 || CPU_V6K)
help
This option enables optimisations for the PL310 cache
controller.
@@ -845,16 +853,21 @@ config CACHE_XSC3L2
help
This option enables the L2 cache on XScale3.
+config ARM_L1_CACHE_SHIFT_6
+ bool
+ help
+ Setting ARM L1 cache line size to 64 Bytes.
+
config ARM_L1_CACHE_SHIFT
int
default 6 if ARM_L1_CACHE_SHIFT_6
default 5
config ARM_DMA_MEM_BUFFERABLE
- bool "Use non-cacheable memory for DMA" if CPU_V6 && !CPU_V7
+ bool "Use non-cacheable memory for DMA" if (CPU_V6 || CPU_V6K) && !CPU_V7
depends on !(MACH_REALVIEW_PB1176 || REALVIEW_EB_ARM11MP || \
MACH_REALVIEW_PB11MP)
- default y if CPU_V6 || CPU_V7
+ default y if CPU_V6 || CPU_V6K || CPU_V7
help
Historically, the kernel has used strongly ordered mappings to
provide DMA coherent memory. With the advent of ARMv7, mapping
diff --git a/arch/arm/mm/Makefile b/arch/arm/mm/Makefile
index 00d74a04af3..bca7e61928c 100644
--- a/arch/arm/mm/Makefile
+++ b/arch/arm/mm/Makefile
@@ -90,6 +90,7 @@ obj-$(CONFIG_CPU_XSC3) += proc-xsc3.o
obj-$(CONFIG_CPU_MOHAWK) += proc-mohawk.o
obj-$(CONFIG_CPU_FEROCEON) += proc-feroceon.o
obj-$(CONFIG_CPU_V6) += proc-v6.o
+obj-$(CONFIG_CPU_V6K) += proc-v6.o
obj-$(CONFIG_CPU_V7) += proc-v7.o
AFLAGS_proc-v6.o :=-Wa,-march=armv6
diff --git a/arch/arm/mm/abort-ev6.S b/arch/arm/mm/abort-ev6.S
index f332df7f0d3..1478aa52214 100644
--- a/arch/arm/mm/abort-ev6.S
+++ b/arch/arm/mm/abort-ev6.S
@@ -20,11 +20,11 @@
*/
.align 5
ENTRY(v6_early_abort)
-#ifdef CONFIG_CPU_32v6K
- clrex
-#else
+#ifdef CONFIG_CPU_V6
sub r1, sp, #4 @ Get unused stack location
strex r0, r1, [r1] @ Clear the exclusive monitor
+#elif defined(CONFIG_CPU_32v6K)
+ clrex
#endif
mrc p15, 0, r1, c5, c0, 0 @ get FSR
mrc p15, 0, r0, c6, c0, 0 @ get FAR
diff --git a/arch/arm/mm/init.c b/arch/arm/mm/init.c
index cddd684364d..8e3387cadaf 100644
--- a/arch/arm/mm/init.c
+++ b/arch/arm/mm/init.c
@@ -15,12 +15,14 @@
#include <linux/mman.h>
#include <linux/nodemask.h>
#include <linux/initrd.h>
+#include <linux/of_fdt.h>
#include <linux/highmem.h>
#include <linux/gfp.h>
#include <linux/memblock.h>
#include <linux/sort.h>
#include <asm/mach-types.h>
+#include <asm/prom.h>
#include <asm/sections.h>
#include <asm/setup.h>
#include <asm/sizes.h>
@@ -71,6 +73,14 @@ static int __init parse_tag_initrd2(const struct tag *tag)
__tagtable(ATAG_INITRD2, parse_tag_initrd2);
+#ifdef CONFIG_OF_FLATTREE
+void __init early_init_dt_setup_initrd_arch(unsigned long start, unsigned long end)
+{
+ phys_initrd_start = start;
+ phys_initrd_size = end - start + 1;
+}
+#endif /* CONFIG_OF_FLATTREE */
+
/*
* This keeps memory configuration data used by a couple memory
* initialization functions, as well as show_mem() for the skipping
@@ -313,6 +323,7 @@ void __init arm_memblock_init(struct meminfo *mi, struct machine_desc *mdesc)
#endif
arm_mm_memblock_reserve();
+ arm_dt_memblock_reserve();
/* reserve any platform specific memblock areas */
if (mdesc->reserve)
diff --git a/arch/arm/mm/mmap.c b/arch/arm/mm/mmap.c
index b0a98305055..afe209e1e1f 100644
--- a/arch/arm/mm/mmap.c
+++ b/arch/arm/mm/mmap.c
@@ -31,7 +31,7 @@ arch_get_unmapped_area(struct file *filp, unsigned long addr,
struct mm_struct *mm = current->mm;
struct vm_area_struct *vma;
unsigned long start_addr;
-#ifdef CONFIG_CPU_V6
+#if defined(CONFIG_CPU_V6) || defined(CONFIG_CPU_V6K)
unsigned int cache_type;
int do_align = 0, aliasing = 0;
diff --git a/arch/arm/mm/mmu.c b/arch/arm/mm/mmu.c
index 3c67e92f7d5..ff7b43b5885 100644
--- a/arch/arm/mm/mmu.c
+++ b/arch/arm/mm/mmu.c
@@ -827,16 +827,6 @@ static void __init sanity_check_meminfo(void)
* rather difficult.
*/
reason = "with VIPT aliasing cache";
- } else if (is_smp() && tlb_ops_need_broadcast()) {
- /*
- * kmap_high needs to occasionally flush TLB entries,
- * however, if the TLB entries need to be broadcast
- * we may deadlock:
- * kmap_high(irqs off)->flush_all_zero_pkmaps->
- * flush_tlb_kernel_range->smp_call_function_many
- * (must not be called with irqs off)
- */
- reason = "without hardware TLB ops broadcasting";
}
if (reason) {
printk(KERN_CRIT "HIGHMEM is not supported %s, ignoring high memory\n",
diff --git a/arch/arm/mm/vmregion.c b/arch/arm/mm/vmregion.c
index 935993e1b1e..036fdbfdd62 100644
--- a/arch/arm/mm/vmregion.c
+++ b/arch/arm/mm/vmregion.c
@@ -38,7 +38,7 @@ struct arm_vmregion *
arm_vmregion_alloc(struct arm_vmregion_head *head, size_t align,
size_t size, gfp_t gfp)
{
- unsigned long addr = head->vm_start, end = head->vm_end - size;
+ unsigned long start = head->vm_start, addr = head->vm_end;
unsigned long flags;
struct arm_vmregion *c, *new;
@@ -54,21 +54,20 @@ arm_vmregion_alloc(struct arm_vmregion_head *head, size_t align,
spin_lock_irqsave(&head->vm_lock, flags);
- list_for_each_entry(c, &head->vm_list, vm_list) {
- if ((addr + size) < addr)
- goto nospc;
- if ((addr + size) <= c->vm_start)
+ addr = rounddown(addr - size, align);
+ list_for_each_entry_reverse(c, &head->vm_list, vm_list) {
+ if (addr >= c->vm_end)
goto found;
- addr = ALIGN(c->vm_end, align);
- if (addr > end)
+ addr = rounddown(c->vm_start - size, align);
+ if (addr < start)
goto nospc;
}
found:
/*
- * Insert this entry _before_ the one we found.
+ * Insert this entry after the one we found.
*/
- list_add_tail(&new->vm_list, &c->vm_list);
+ list_add(&new->vm_list, &c->vm_list);
new->vm_start = addr;
new->vm_end = addr + size;
new->vm_active = 1;
diff --git a/arch/arm/plat-mxc/Kconfig b/arch/arm/plat-mxc/Kconfig
index 389f2179501..a97f7334bc7 100644
--- a/arch/arm/plat-mxc/Kconfig
+++ b/arch/arm/plat-mxc/Kconfig
@@ -119,4 +119,10 @@ config IRAM_ALLOC
bool
select GENERIC_ALLOCATOR
+config CLK_DEBUG
+ bool "clock debug information export to user space"
+ depends on PM_DEBUG && DEBUG_FS
+ default n
+ help
+ export clk debug information to user space
endif
diff --git a/arch/arm/plat-mxc/clock.c b/arch/arm/plat-mxc/clock.c
index 2ed3ab173ad..190bce1221a 100644
--- a/arch/arm/plat-mxc/clock.c
+++ b/arch/arm/plat-mxc/clock.c
@@ -37,6 +37,8 @@
#include <linux/proc_fs.h>
#include <linux/semaphore.h>
#include <linux/string.h>
+#include <linux/slab.h>
+#include <linux/debugfs.h>
#include <mach/clock.h>
#include <mach/hardware.h>
@@ -244,3 +246,122 @@ unsigned long mxc_decode_pll(unsigned int reg_val, u32 freq)
return ll;
}
+
+#ifdef CONFIG_CLK_DEBUG
+/*
+ * debugfs support to trace clock tree hierarchy and attributes
+ */
+static int clk_debug_rate_get(void *data, u64 *val)
+{
+ struct clk *clk = data;
+
+ *val = (u64)clk_get_rate(clk);
+ return 0;
+}
+DEFINE_SIMPLE_ATTRIBUTE(clk_debug_rate_fops, clk_debug_rate_get, NULL,
+ "%llu\n");
+
+
+static struct dentry *clk_root;
+static int clk_debug_register_one(struct clk *clk)
+{
+ int err;
+ struct dentry *d, *child, *child_tmp;
+ struct clk *pa = clk_get_parent(clk);
+
+ if (pa && !IS_ERR(pa))
+ d = debugfs_create_dir(clk->name, pa->dentry);
+ else {
+ if (!clk_root)
+ clk_root = debugfs_create_dir("clock", NULL);
+ if (!clk_root)
+ return -ENOMEM;
+ d = debugfs_create_dir(clk->name, clk_root);
+ }
+
+ if (!d)
+ return -ENOMEM;
+
+ clk->dentry = d;
+
+ d = debugfs_create_u32("enable_count", S_IRUGO, clk->dentry,
+ (u32 *)&clk->usecount);
+ if (!d) {
+ err = -ENOMEM;
+ goto err_out;
+ }
+
+ d = debugfs_create_file("rate", S_IRUGO, clk->dentry, (void *)clk,
+ &clk_debug_rate_fops);
+ if (!d) {
+ err = -ENOMEM;
+ goto err_out;
+ }
+
+ return 0;
+
+err_out:
+ d = clk->dentry;
+ list_for_each_entry_safe(child, child_tmp, &d->d_subdirs, d_u.d_child)
+ debugfs_remove(child);
+ debugfs_remove(clk->dentry);
+ return err;
+}
+
+struct preinit_clk {
+ struct list_head list;
+ struct clk *clk;
+};
+static LIST_HEAD(preinit_clks);
+static DEFINE_MUTEX(preinit_lock);
+static int init_done;
+
+void clk_debug_register(struct clk *clk)
+{
+ int err;
+ struct clk *pa;
+
+ if (init_done) {
+ pa = clk_get_parent(clk);
+
+ if (pa && !IS_ERR(pa) && !pa->dentry)
+ clk_debug_register(pa);
+
+ if (!clk->dentry) {
+ err = clk_debug_register_one(clk);
+ if (err)
+ return;
+ }
+ } else {
+ struct preinit_clk *p;
+ mutex_lock(&preinit_lock);
+ p = kmalloc(sizeof(*p), GFP_KERNEL);
+ if (p) {
+ p->clk = clk;
+ list_add(&p->list, &preinit_clks);
+ }
+ mutex_unlock(&preinit_lock);
+ }
+}
+EXPORT_SYMBOL_GPL(clk_debug_register);
+
+static int __init clk_debugfs_init(void)
+{
+ struct preinit_clk *pclk, *tmp;
+
+ init_done = 1;
+
+ mutex_lock(&preinit_lock);
+ list_for_each_entry(pclk, &preinit_clks, list) {
+ clk_debug_register(pclk->clk);
+ }
+
+ list_for_each_entry_safe(pclk, tmp, &preinit_clks, list) {
+ list_del(&pclk->list);
+ kfree(pclk);
+ }
+ mutex_unlock(&preinit_lock);
+ return 0;
+}
+late_initcall(clk_debugfs_init);
+#endif
diff --git a/arch/arm/plat-mxc/include/mach/clock.h b/arch/arm/plat-mxc/include/mach/clock.h
index 753a5988d85..fb0e0bd3f51 100644
--- a/arch/arm/plat-mxc/include/mach/clock.h
+++ b/arch/arm/plat-mxc/include/mach/clock.h
@@ -23,9 +23,14 @@
#ifndef __ASSEMBLY__
#include <linux/list.h>
+#define CLK_NAME_LEN 32
struct module;
struct clk {
+#ifdef CONFIG_CLK_DEBUG
+ char name[CLK_NAME_LEN];
+ struct dentry *dentry;
+#endif
int id;
/* Source clock this clk depends on */
struct clk *parent;
@@ -62,5 +67,11 @@ void clk_unregister(struct clk *clk);
unsigned long mxc_decode_pll(unsigned int pll, u32 f_ref);
+#ifdef CONFIG_CLK_DEBUG
+void clk_debug_register(struct clk *clk);
+#else
+static inline void clk_debug_register(struct clk *clk) {}
+#endif
+
#endif /* __ASSEMBLY__ */
#endif /* __ASM_ARCH_MXC_CLOCK_H__ */
diff --git a/arch/arm/plat-mxc/include/mach/memory.h b/arch/arm/plat-mxc/include/mach/memory.h
index 83861408133..5d51cbb9889 100644
--- a/arch/arm/plat-mxc/include/mach/memory.h
+++ b/arch/arm/plat-mxc/include/mach/memory.h
@@ -23,23 +23,23 @@
#if !defined(CONFIG_RUNTIME_PHYS_OFFSET)
# if defined CONFIG_ARCH_MX1
-# define PHYS_OFFSET MX1_PHYS_OFFSET
+# define PLAT_PHYS_OFFSET MX1_PHYS_OFFSET
# elif defined CONFIG_MACH_MX21
-# define PHYS_OFFSET MX21_PHYS_OFFSET
+# define PLAT_PHYS_OFFSET MX21_PHYS_OFFSET
# elif defined CONFIG_ARCH_MX25
-# define PHYS_OFFSET MX25_PHYS_OFFSET
+# define PLAT_PHYS_OFFSET MX25_PHYS_OFFSET
# elif defined CONFIG_MACH_MX27
-# define PHYS_OFFSET MX27_PHYS_OFFSET
+# define PLAT_PHYS_OFFSET MX27_PHYS_OFFSET
# elif defined CONFIG_ARCH_MX3
-# define PHYS_OFFSET MX3x_PHYS_OFFSET
+# define PLAT_PHYS_OFFSET MX3x_PHYS_OFFSET
# elif defined CONFIG_ARCH_MXC91231
-# define PHYS_OFFSET MXC91231_PHYS_OFFSET
+# define PLAT_PHYS_OFFSET MXC91231_PHYS_OFFSET
# elif defined CONFIG_ARCH_MX50
-# define PHYS_OFFSET MX50_PHYS_OFFSET
+# define PLAT_PHYS_OFFSET MX50_PHYS_OFFSET
# elif defined CONFIG_ARCH_MX51
-# define PHYS_OFFSET MX51_PHYS_OFFSET
+# define PLAT_PHYS_OFFSET MX51_PHYS_OFFSET
# elif defined CONFIG_ARCH_MX53
-# define PHYS_OFFSET MX53_PHYS_OFFSET
+# define PLAT_PHYS_OFFSET MX53_PHYS_OFFSET
# endif
#endif
diff --git a/arch/arm/plat-omap/Makefile b/arch/arm/plat-omap/Makefile
index a4a12859fdd..ec7862e9149 100644
--- a/arch/arm/plat-omap/Makefile
+++ b/arch/arm/plat-omap/Makefile
@@ -21,7 +21,6 @@ obj-$(CONFIG_OMAP_MCBSP) += mcbsp.o
obj-$(CONFIG_OMAP_IOMMU) += iommu.o iovmm.o
obj-$(CONFIG_OMAP_IOMMU_DEBUG) += iommu-debug.o
-obj-$(CONFIG_CPU_FREQ) += cpu-omap.o
obj-$(CONFIG_OMAP_DM_TIMER) += dmtimer.o
obj-$(CONFIG_OMAP_DEBUG_DEVICES) += debug-devices.o
obj-$(CONFIG_OMAP_DEBUG_LEDS) += debug-leds.o
diff --git a/arch/arm/plat-omap/include/plat/display.h b/arch/arm/plat-omap/include/plat/display.h
index 537f4e449f5..2fb057e1cb9 100644
--- a/arch/arm/plat-omap/include/plat/display.h
+++ b/arch/arm/plat-omap/include/plat/display.h
@@ -23,6 +23,7 @@
#include <linux/list.h>
#include <linux/kobject.h>
#include <linux/device.h>
+#include <linux/platform_device.h>
#include <asm/atomic.h>
#define DISPC_IRQ_FRAMEDONE (1 << 0)
@@ -226,6 +227,21 @@ struct omap_dss_board_info {
struct omap_dss_device *default_device;
};
+#if defined(CONFIG_OMAP2_DSS_MODULE) || defined(CONFIG_OMAP2_DSS)
+/* Init with the board info */
+extern int omap_display_init(struct omap_dss_board_info *board_data);
+#else
+static inline int omap_display_init(struct omap_dss_board_info *board_data)
+{
+ return 0;
+}
+#endif
+
+struct omap_display_platform_data {
+ struct omap_dss_board_info *board_data;
+ /* TODO: Additional members to be added when PM is considered */
+};
+
struct omap_video_timings {
/* Unit: pixels */
u16 x_res;
diff --git a/arch/arm/plat-omap/include/plat/dvfs.h b/arch/arm/plat-omap/include/plat/dvfs.h
new file mode 100644
index 00000000000..1be2b9d8bd3
--- /dev/null
+++ b/arch/arm/plat-omap/include/plat/dvfs.h
@@ -0,0 +1,34 @@
+/*
+ * OMAP3/OMAP4 DVFS Management Routines
+ *
+ * Author: Vishwanath BS <vishwanath.bs@ti.com>
+ *
+ * Copyright (C) 2011 Texas Instruments, Inc.
+ * Vishwanath BS <vishwanath.bs@ti.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#ifndef __ARCH_ARM_MACH_OMAP2_DVFS_H
+#define __ARCH_ARM_MACH_OMAP2_DVFS_H
+#include <plat/voltage.h>
+
+#ifdef CONFIG_PM
+int omap_dvfs_register_device(struct voltagedomain *voltdm, struct device *dev);
+int omap_device_scale(struct device *req_dev, struct device *dev,
+ unsigned long rate);
+#else
+static inline int omap_dvfs_register_device(struct voltagedomain *voltdm,
+ struct device *dev)
+{
+ return -EINVAL;
+}
+static inline int omap_device_scale(struct device *req_dev, struct devices
+ *target_dev, unsigned long rate);
+{
+ return -EINVAL;
+}
+#endif
+#endif
diff --git a/arch/arm/plat-omap/include/plat/l3_2xxx.h b/arch/arm/plat-omap/include/plat/l3_2xxx.h
new file mode 100644
index 00000000000..b8b5641379b
--- /dev/null
+++ b/arch/arm/plat-omap/include/plat/l3_2xxx.h
@@ -0,0 +1,20 @@
+/*
+ * arch/arm/plat-omap/include/plat/l3_2xxx.h - L3 firewall definitions
+ *
+ * Copyright (C) 2010 Texas Instruments Incorporated - http://www.ti.com/
+ * Sumit Semwal
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ */
+#ifndef __ARCH_ARM_PLAT_OMAP_INCLUDE_PLAT_L3_2XXX_H
+#define __ARCH_ARM_PLAT_OMAP_INCLUDE_PLAT_L3_2XXX_H
+
+/* L3 CONNIDs */
+/* Display Sub system (DSS) */
+#define OMAP2_L3_CORE_FW_CONNID_DSS 8
+
+#endif
diff --git a/arch/arm/plat-omap/include/plat/l3_3xxx.h b/arch/arm/plat-omap/include/plat/l3_3xxx.h
new file mode 100644
index 00000000000..cde1938c5f8
--- /dev/null
+++ b/arch/arm/plat-omap/include/plat/l3_3xxx.h
@@ -0,0 +1,20 @@
+/*
+ * arch/arm/plat-omap/include/plat/l3_3xxx.h - L3 firewall definitions
+ *
+ * Copyright (C) 2010 Texas Instruments Incorporated - http://www.ti.com/
+ * Sumit Semwal
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ */
+#ifndef __ARCH_ARM_PLAT_OMAP_INCLUDE_PLAT_L3_3XXX_H
+#define __ARCH_ARM_PLAT_OMAP_INCLUDE_PLAT_L3_3XXX_H
+
+/* L3 Initiator IDs */
+/* Display Sub system (DSS) */
+#define OMAP3_L3_CORE_FW_INIT_ID_DSS 29
+
+#endif
diff --git a/arch/arm/plat-omap/include/plat/l4_2xxx.h b/arch/arm/plat-omap/include/plat/l4_2xxx.h
new file mode 100644
index 00000000000..3f39cf8a35c
--- /dev/null
+++ b/arch/arm/plat-omap/include/plat/l4_2xxx.h
@@ -0,0 +1,24 @@
+/*
+ * arch/arm/plat-omap/include/plat/l4_2xxx.h - L4 firewall definitions
+ *
+ * Copyright (C) 2010 Texas Instruments Incorporated - http://www.ti.com/
+ * Sumit Semwal
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ */
+#ifndef __ARCH_ARM_PLAT_OMAP_INCLUDE_PLAT_L4_2XXX_H
+#define __ARCH_ARM_PLAT_OMAP_INCLUDE_PLAT_L4_2XXX_H
+
+/* L4 CORE */
+/* Display Sub system (DSS) */
+#define OMAP2420_L4_CORE_FW_DSS_CORE_REGION 28
+#define OMAP2420_L4_CORE_FW_DSS_DISPC_REGION 29
+#define OMAP2420_L4_CORE_FW_DSS_RFBI_REGION 30
+#define OMAP2420_L4_CORE_FW_DSS_VENC_REGION 31
+#define OMAP2420_L4_CORE_FW_DSS_TA_REGION 32
+
+#endif
diff --git a/arch/arm/plat-omap/include/plat/l4_3xxx.h b/arch/arm/plat-omap/include/plat/l4_3xxx.h
index 5e194937542..881a858b1ff 100644
--- a/arch/arm/plat-omap/include/plat/l4_3xxx.h
+++ b/arch/arm/plat-omap/include/plat/l4_3xxx.h
@@ -21,4 +21,14 @@
#define OMAP3_L4_CORE_FW_I2C3_REGION 73
#define OMAP3_L4_CORE_FW_I2C3_TA_REGION 74
+/* Display Sub system (DSS) */
+#define OMAP3_L4_CORE_FW_DSS_PROT_GROUP 2
+
+#define OMAP3_L4_CORE_FW_DSS_DSI_REGION 104
+#define OMAP3ES1_L4_CORE_FW_DSS_CORE_REGION 3
+#define OMAP3_L4_CORE_FW_DSS_CORE_REGION 4
+#define OMAP3_L4_CORE_FW_DSS_DISPC_REGION 4
+#define OMAP3_L4_CORE_FW_DSS_RFBI_REGION 5
+#define OMAP3_L4_CORE_FW_DSS_VENC_REGION 6
+#define OMAP3_L4_CORE_FW_DSS_TA_REGION 7
#endif
diff --git a/arch/arm/plat-omap/include/plat/memory.h b/arch/arm/plat-omap/include/plat/memory.h
index f8d922fb558..e6720aa2d55 100644
--- a/arch/arm/plat-omap/include/plat/memory.h
+++ b/arch/arm/plat-omap/include/plat/memory.h
@@ -37,9 +37,9 @@
* Physical DRAM offset.
*/
#if defined(CONFIG_ARCH_OMAP1)
-#define PHYS_OFFSET UL(0x10000000)
+#define PLAT_PHYS_OFFSET UL(0x10000000)
#else
-#define PHYS_OFFSET UL(0x80000000)
+#define PLAT_PHYS_OFFSET UL(0x80000000)
#endif
/*
diff --git a/arch/arm/plat-omap/include/plat/omap_device.h b/arch/arm/plat-omap/include/plat/omap_device.h
index e4c349ff9fd..204fb0a9b2f 100644
--- a/arch/arm/plat-omap/include/plat/omap_device.h
+++ b/arch/arm/plat-omap/include/plat/omap_device.h
@@ -50,6 +50,8 @@ extern struct device omap_device_parent;
* @hwmods: (one .. many per omap_device)
* @hwmods_cnt: ARRAY_SIZE() of @hwmods
* @pm_lats: ptr to an omap_device_pm_latency table
+ * @set_rate: fn ptr to change the operating rate.
+ * @get_rate: fn ptr to retrieve the current operating rate.
* @pm_lats_cnt: ARRAY_SIZE() of what is passed to @pm_lats
* @pm_lat_level: array index of the last odpl entry executed - -1 if never
* @dev_wakeup_lat: dev wakeup latency in nanoseconds
@@ -73,6 +75,8 @@ struct omap_device {
s8 pm_lat_level;
u8 hwmods_cnt;
u8 _state;
+ int (*set_rate)(struct device *dev, unsigned long rate);
+ unsigned long (*get_rate) (struct device *dev);
};
/* Device driver interface (call via platform_data fn ptrs) */
@@ -107,6 +111,11 @@ void __iomem *omap_device_get_rt_va(struct omap_device *od);
int omap_device_align_pm_lat(struct platform_device *pdev,
u32 new_wakeup_lat_limit);
struct powerdomain *omap_device_get_pwrdm(struct omap_device *od);
+int omap_device_set_rate(struct device *dev, unsigned long freq);
+unsigned long omap_device_get_rate(struct device *dev);
+void omap_device_register_dvfs_callbacks(struct device *dev,
+ int (*set_rate)(struct device *dev, unsigned long rate),
+ unsigned long (*get_rate) (struct device *dev));
u32 omap_device_get_context_loss_count(struct platform_device *pdev);
/* Other */
diff --git a/arch/arm/plat-omap/include/plat/serial.h b/arch/arm/plat-omap/include/plat/serial.h
index cec5d56db2e..8ff605c83ac 100644
--- a/arch/arm/plat-omap/include/plat/serial.h
+++ b/arch/arm/plat-omap/include/plat/serial.h
@@ -27,7 +27,7 @@
* 2. We assume printascii is called at least once before paging_init,
* and addruart has a chance to read OMAP_UART_INFO
*/
-#define OMAP_UART_INFO (PHYS_OFFSET + 0x3ffc)
+#define OMAP_UART_INFO (PLAT_PHYS_OFFSET + 0x3ffc)
/* OMAP1 serial ports */
#define OMAP1_UART1_BASE 0xfffb0000
diff --git a/arch/arm/plat-omap/include/plat/sram.h b/arch/arm/plat-omap/include/plat/sram.h
index 9967d5e855c..f500fc34d06 100644
--- a/arch/arm/plat-omap/include/plat/sram.h
+++ b/arch/arm/plat-omap/include/plat/sram.h
@@ -12,7 +12,19 @@
#define __ARCH_ARM_OMAP_SRAM_H
#ifndef __ASSEMBLY__
-extern void * omap_sram_push(void * start, unsigned long size);
+#include <asm/fncpy.h>
+
+extern void *omap_sram_push_address(unsigned long size);
+
+/* Macro to push a function to the internal SRAM, using the fncpy API */
+#define omap_sram_push(funcp, size) ({ \
+ typeof(&(funcp)) _res = NULL; \
+ void *_sram_address = omap_sram_push_address(size); \
+ if (_sram_address) \
+ _res = fncpy(_sram_address, &(funcp), size); \
+ _res; \
+})
+
extern void omap_sram_reprogram_clock(u32 dpllctl, u32 ckctl);
extern void omap2_sram_ddr_init(u32 *slow_dll_ctrl, u32 fast_dll_ctrl,
diff --git a/arch/arm/plat-omap/include/plat/voltage.h b/arch/arm/plat-omap/include/plat/voltage.h
index 5bd204e55c3..e0b7f22155d 100644
--- a/arch/arm/plat-omap/include/plat/voltage.h
+++ b/arch/arm/plat-omap/include/plat/voltage.h
@@ -113,6 +113,154 @@ struct omap_volt_pmic_info {
u8 (*uv_to_vsel) (unsigned long uV);
};
+/* Voltage processor register offsets */
+struct vp_reg_offs {
+ u8 vpconfig;
+ u8 vstepmin;
+ u8 vstepmax;
+ u8 vlimitto;
+ u8 vstatus;
+ u8 voltage;
+};
+
+/* Voltage Processor bit field values, shifts and masks */
+struct vp_reg_val {
+ /* PRM module */
+ u16 prm_mod;
+ /* VPx_VPCONFIG */
+ u32 vpconfig_erroroffset;
+ u16 vpconfig_errorgain;
+ u32 vpconfig_errorgain_mask;
+ u8 vpconfig_errorgain_shift;
+ u32 vpconfig_initvoltage_mask;
+ u8 vpconfig_initvoltage_shift;
+ u32 vpconfig_timeouten;
+ u32 vpconfig_initvdd;
+ u32 vpconfig_forceupdate;
+ u32 vpconfig_vpenable;
+ /* VPx_VSTEPMIN */
+ u8 vstepmin_stepmin;
+ u16 vstepmin_smpswaittimemin;
+ u8 vstepmin_stepmin_shift;
+ u8 vstepmin_smpswaittimemin_shift;
+ /* VPx_VSTEPMAX */
+ u8 vstepmax_stepmax;
+ u16 vstepmax_smpswaittimemax;
+ u8 vstepmax_stepmax_shift;
+ u8 vstepmax_smpswaittimemax_shift;
+ /* VPx_VLIMITTO */
+ u8 vlimitto_vddmin;
+ u8 vlimitto_vddmax;
+ u16 vlimitto_timeout;
+ u8 vlimitto_vddmin_shift;
+ u8 vlimitto_vddmax_shift;
+ u8 vlimitto_timeout_shift;
+ /* PRM_IRQSTATUS*/
+ u32 tranxdone_status;
+};
+
+/* Voltage controller registers and offsets */
+struct vc_reg_info {
+ /* PRM module */
+ u16 prm_mod;
+ /* VC register offsets */
+ u8 smps_sa_reg;
+ u8 smps_volra_reg;
+ u8 bypass_val_reg;
+ u8 cmdval_reg;
+ u8 voltsetup_reg;
+ /*VC_SMPS_SA*/
+ u8 smps_sa_shift;
+ u32 smps_sa_mask;
+ /* VC_SMPS_VOL_RA */
+ u8 smps_volra_shift;
+ u32 smps_volra_mask;
+ /* VC_BYPASS_VAL */
+ u8 data_shift;
+ u8 slaveaddr_shift;
+ u8 regaddr_shift;
+ u32 valid;
+ /* VC_CMD_VAL */
+ u8 cmd_on_shift;
+ u8 cmd_onlp_shift;
+ u8 cmd_ret_shift;
+ u8 cmd_off_shift;
+ u32 cmd_on_mask;
+ /* PRM_VOLTSETUP */
+ u8 voltsetup_shift;
+ u32 voltsetup_mask;
+};
+
+
+/**
+ * omap_vdd_dep_volt - Table containing the parent vdd voltage and the
+ * dependent vdd voltage corresponding to it.
+ *
+ * @main_vdd_volt : The main vdd voltage
+ * @dep_vdd_volt : The voltage at which the dependent vdd should be
+ * when the main vdd is at <main_vdd_volt> voltage
+ */
+struct omap_vdd_dep_volt {
+ u32 main_vdd_volt;
+ u32 dep_vdd_volt;
+};
+
+/**
+ * omap_vdd_dep_info - Dependent vdd info
+ *
+ * @name : Dependent vdd name
+ * @voltdm : Dependent vdd pointer
+ * @dep_table : Table containing the dependent vdd voltage
+ * corresponding to every main vdd voltage.
+ */
+struct omap_vdd_dep_info {
+ char *name;
+ struct voltagedomain *voltdm;
+ struct omap_vdd_dep_volt *dep_table;
+};
+
+
+/**
+ * omap_vdd_info - Per Voltage Domain info
+ *
+ * @volt_data : voltage table having the distinct voltages supported
+ * by the domain and other associated per voltage data.
+ * @pmic_info : pmic specific parameters which should be populted by
+ * the pmic drivers.
+ * @vp_offs : structure containing the offsets for various
+ * vp registers
+ * @vp_reg : the register values, shifts, masks for various
+ * vp registers
+ * @vc_reg : structure containing various various vc registers,
+ * shifts, masks etc.
+ * @voltdm : pointer to the voltage domain structure
+ * @debug_dir : debug directory for this voltage domain.
+ * @curr_volt : current voltage for this vdd.
+ * @ocp_mod : The prm module for accessing the prm irqstatus reg.
+ * @prm_irqst_reg : prm irqstatus register.
+ * @vp_enabled : flag to keep track of whether vp is enabled or not
+ * @volt_scale : API to scale the voltage of the vdd.
+ */
+struct omap_vdd_info {
+ struct omap_volt_data *volt_data;
+ struct omap_volt_pmic_info *pmic_info;
+ struct vp_reg_offs vp_offs;
+ struct vp_reg_val vp_reg;
+ struct vc_reg_info vc_reg;
+ struct voltagedomain voltdm;
+ struct omap_vdd_dep_info *dep_vdd_info;
+ int nr_dep_vdd;
+ struct dentry *debug_dir;
+ u32 curr_volt;
+ u16 ocp_mod;
+ u8 prm_irqst_reg;
+ bool vp_enabled;
+ u32 (*read_reg) (u16 mod, u8 offset);
+ void (*write_reg) (u32 val, u16 mod, u8 offset);
+ int (*volt_scale) (struct omap_vdd_info *vdd,
+ unsigned long target_volt);
+};
+
unsigned long omap_vp_get_curr_volt(struct voltagedomain *voltdm);
void omap_vp_enable(struct voltagedomain *voltdm);
void omap_vp_disable(struct voltagedomain *voltdm);
diff --git a/arch/arm/plat-omap/omap_device.c b/arch/arm/plat-omap/omap_device.c
index 57adb270767..4cee430c40d 100644
--- a/arch/arm/plat-omap/omap_device.c
+++ b/arch/arm/plat-omap/omap_device.c
@@ -86,6 +86,7 @@
#include <plat/omap_device.h>
#include <plat/omap_hwmod.h>
+#include <plat/dvfs.h>
/* These parameters are passed to _omap_device_{de,}activate() */
#define USE_WAKEUP_LAT 0
@@ -481,6 +482,14 @@ struct omap_device *omap_device_build_ss(const char *pdev_name, int pdev_id,
for (i = 0; i < oh_cnt; i++) {
hwmods[i]->od = od;
_add_optional_clock_alias(od, hwmods[i]);
+ if (!is_early_device && hwmods[i]->vdd_name) {
+ struct omap_hwmod *oh = hwmods[i];
+ struct voltagedomain *voltdm;
+
+ voltdm = omap_voltage_domain_lookup(oh->vdd_name);
+ if (!omap_dvfs_register_device(voltdm, &od->pdev.dev))
+ oh->voltdm = voltdm;
+ }
}
if (ret)
@@ -801,6 +810,55 @@ int omap_device_enable_clocks(struct omap_device *od)
return 0;
}
+int omap_device_set_rate(struct device *dev, unsigned long freq)
+{
+ struct platform_device *pdev;
+ struct omap_device *od;
+
+ pdev = container_of(dev, struct platform_device, dev);
+ od = _find_by_pdev(pdev);
+
+ if (!od->set_rate) {
+ dev_err(dev, "%s: No set_rate API for scaling device\n",
+ __func__);
+ return -ENODATA;
+ }
+
+ return od->set_rate(dev, freq);
+}
+
+unsigned long omap_device_get_rate(struct device *dev)
+{
+ struct platform_device *pdev;
+ struct omap_device *od;
+
+ pdev = container_of(dev, struct platform_device, dev);
+ od = _find_by_pdev(pdev);
+
+
+ if (!od->get_rate) {
+ dev_err(dev, "%s: No get rate API for the device\n",
+ __func__);
+ return 0;
+ }
+
+ return od->get_rate(dev);
+}
+
+void omap_device_register_dvfs_callbacks(struct device *dev,
+ int (*set_rate)(struct device *dev, unsigned long rate),
+ unsigned long (*get_rate) (struct device *dev))
+{
+ struct platform_device *pdev;
+ struct omap_device *od;
+
+ pdev = container_of(dev, struct platform_device, dev);
+ od = _find_by_pdev(pdev);
+
+ od->set_rate = set_rate;
+ od->get_rate = get_rate;
+}
+
struct device omap_device_parent = {
.init_name = "omap",
.parent = &platform_bus,
diff --git a/arch/arm/plat-omap/sram.c b/arch/arm/plat-omap/sram.c
index e26e50487d6..68fcc7dc56e 100644
--- a/arch/arm/plat-omap/sram.c
+++ b/arch/arm/plat-omap/sram.c
@@ -242,7 +242,14 @@ static void __init omap_map_sram(void)
omap_sram_size - SRAM_BOOTLOADER_SZ);
}
-void * omap_sram_push(void * start, unsigned long size)
+/*
+ * Memory allocator for SRAM: calculates the new ceiling address
+ * for pushing a function using the fncpy API.
+ *
+ * Note that fncpy requires the returned address to be aligned
+ * to an 8-byte boundary.
+ */
+void *omap_sram_push_address(unsigned long size)
{
if (size > (omap_sram_ceil - (omap_sram_base + SRAM_BOOTLOADER_SZ))) {
printk(KERN_ERR "Not enough space in SRAM\n");
@@ -250,10 +257,7 @@ void * omap_sram_push(void * start, unsigned long size)
}
omap_sram_ceil -= size;
- omap_sram_ceil = ROUND_DOWN(omap_sram_ceil, sizeof(void *));
- memcpy((void *)omap_sram_ceil, start, size);
- flush_icache_range((unsigned long)omap_sram_ceil,
- (unsigned long)(omap_sram_ceil + size));
+ omap_sram_ceil = ROUND_DOWN(omap_sram_ceil, FNCPY_ALIGN);
return (void *)omap_sram_ceil;
}
diff --git a/arch/arm/plat-s3c24xx/Makefile b/arch/arm/plat-s3c24xx/Makefile
index c2064c30871..763b7bb44c9 100644
--- a/arch/arm/plat-s3c24xx/Makefile
+++ b/arch/arm/plat-s3c24xx/Makefile
@@ -26,9 +26,9 @@ obj-$(CONFIG_CPU_FREQ_S3C24XX_DEBUGFS) += cpu-freq-debugfs.o
# Architecture dependant builds
obj-$(CONFIG_PM_SIMTEC) += pm-simtec.o
-obj-$(CONFIG_PM) += pm.o
-obj-$(CONFIG_PM) += irq-pm.o
-obj-$(CONFIG_PM) += sleep.o
+obj-$(CONFIG_SUSPEND) += pm.o
+obj-$(CONFIG_SUSPEND) += irq-pm.o
+obj-$(CONFIG_SUSPEND) += sleep.o
obj-$(CONFIG_S3C2410_CLOCK) += s3c2410-clock.o
obj-$(CONFIG_S3C2443_CLOCK) += s3c2443-clock.o
obj-$(CONFIG_S3C2410_DMA) += dma.o
diff --git a/arch/arm/plat-s3c24xx/cpu-freq.c b/arch/arm/plat-s3c24xx/cpu-freq.c
index 25a8fc7f512..1d38db56971 100644
--- a/arch/arm/plat-s3c24xx/cpu-freq.c
+++ b/arch/arm/plat-s3c24xx/cpu-freq.c
@@ -429,7 +429,7 @@ static int s3c_cpufreq_verify(struct cpufreq_policy *policy)
return 0;
}
-#ifdef CONFIG_PM
+#ifdef CONFIG_SUSPEND
static struct cpufreq_frequency_table suspend_pll;
static unsigned int suspend_freq;
diff --git a/arch/arm/plat-s3c24xx/dma.c b/arch/arm/plat-s3c24xx/dma.c
index 6ad274e7593..6199b6e419a 100644
--- a/arch/arm/plat-s3c24xx/dma.c
+++ b/arch/arm/plat-s3c24xx/dma.c
@@ -1202,7 +1202,7 @@ static inline struct s3c2410_dma_chan *to_dma_chan(struct sys_device *dev)
/* system device class */
-#ifdef CONFIG_PM
+#ifdef CONFIG_SUSPEND
static int s3c2410_dma_suspend(struct sys_device *dev, pm_message_t state)
{
diff --git a/arch/arm/plat-s3c24xx/include/plat/irq.h b/arch/arm/plat-s3c24xx/include/plat/irq.h
index ec087d6054b..ca6354ff7ec 100644
--- a/arch/arm/plat-s3c24xx/include/plat/irq.h
+++ b/arch/arm/plat-s3c24xx/include/plat/irq.h
@@ -106,7 +106,7 @@ s3c_irqsub_ack(unsigned int irqno, unsigned int parentmask, unsigned int group)
/* exported for use in arch/arm/mach-s3c2410 */
-#ifdef CONFIG_PM
+#ifdef CONFIG_SUSPEND
extern int s3c_irq_wake(struct irq_data *data, unsigned int state);
#else
#define s3c_irq_wake NULL
diff --git a/arch/arm/plat-s5p/Makefile b/arch/arm/plat-s5p/Makefile
index 4bd5cf90897..ce5a0a77964 100644
--- a/arch/arm/plat-s5p/Makefile
+++ b/arch/arm/plat-s5p/Makefile
@@ -20,8 +20,8 @@ obj-y += irq.o
obj-$(CONFIG_S5P_EXT_INT) += irq-eint.o
obj-$(CONFIG_S5P_GPIO_INT) += irq-gpioint.o
obj-$(CONFIG_S5P_SYSTEM_MMU) += sysmmu.o
-obj-$(CONFIG_PM) += pm.o
-obj-$(CONFIG_PM) += irq-pm.o
+obj-$(CONFIG_SUSPEND) += pm.o
+obj-$(CONFIG_SUSPEND) += irq-pm.o
# devices
diff --git a/arch/arm/plat-s5p/irq-eint.c b/arch/arm/plat-s5p/irq-eint.c
index 225aa25405d..e203a656de2 100644
--- a/arch/arm/plat-s5p/irq-eint.c
+++ b/arch/arm/plat-s5p/irq-eint.c
@@ -125,7 +125,7 @@ static struct irq_chip s5p_irq_eint = {
.irq_mask_ack = s5p_irq_eint_maskack,
.irq_ack = s5p_irq_eint_ack,
.irq_set_type = s5p_irq_eint_set_type,
-#ifdef CONFIG_PM
+#ifdef CONFIG_SUSPEND
.irq_set_wake = s3c_irqext_wake,
#endif
};
@@ -195,7 +195,7 @@ static struct irq_chip s5p_irq_vic_eint = {
.irq_mask_ack = s5p_irq_vic_eint_maskack,
.irq_ack = s5p_irq_vic_eint_ack,
.irq_set_type = s5p_irq_eint_set_type,
-#ifdef CONFIG_PM
+#ifdef CONFIG_SUSPEND
.irq_set_wake = s3c_irqext_wake,
#endif
};
diff --git a/arch/arm/plat-samsung/Makefile b/arch/arm/plat-samsung/Makefile
index 29932f88a8d..7e92457915b 100644
--- a/arch/arm/plat-samsung/Makefile
+++ b/arch/arm/plat-samsung/Makefile
@@ -68,8 +68,8 @@ obj-$(CONFIG_S3C_PL330_DMA) += s3c-pl330.o
# PM support
-obj-$(CONFIG_PM) += pm.o
-obj-$(CONFIG_PM) += pm-gpio.o
+obj-$(CONFIG_SUSPEND) += pm.o
+obj-$(CONFIG_SUSPEND) += pm-gpio.o
obj-$(CONFIG_SAMSUNG_PM_CHECK) += pm-check.o
obj-$(CONFIG_SAMSUNG_WAKEMASK) += wakeup-mask.o
diff --git a/arch/arm/plat-samsung/adc.c b/arch/arm/plat-samsung/adc.c
index e8f2be2d67f..d818405eea0 100644
--- a/arch/arm/plat-samsung/adc.c
+++ b/arch/arm/plat-samsung/adc.c
@@ -412,7 +412,7 @@ static int __devexit s3c_adc_remove(struct platform_device *pdev)
return 0;
}
-#ifdef CONFIG_PM
+#ifdef CONFIG_SUSPEND
static int s3c_adc_suspend(struct platform_device *pdev, pm_message_t state)
{
struct adc_device *adc = platform_get_drvdata(pdev);
diff --git a/arch/arm/plat-samsung/gpio.c b/arch/arm/plat-samsung/gpio.c
index 7743c4b8b2f..4f3700f9a69 100644
--- a/arch/arm/plat-samsung/gpio.c
+++ b/arch/arm/plat-samsung/gpio.c
@@ -143,7 +143,7 @@ __init void s3c_gpiolib_add(struct s3c_gpio_chip *chip)
if (!gc->get)
gc->get = s3c_gpiolib_get;
-#ifdef CONFIG_PM
+#ifdef CONFIG_SUSPEND
if (chip->pm != NULL) {
if (!chip->pm->save || !chip->pm->resume)
printk(KERN_ERR "gpio: %s has missing PM functions\n",
diff --git a/arch/arm/plat-samsung/include/plat/gpio-core.h b/arch/arm/plat-samsung/include/plat/gpio-core.h
index dac35d0a711..8b5209baa99 100644
--- a/arch/arm/plat-samsung/include/plat/gpio-core.h
+++ b/arch/arm/plat-samsung/include/plat/gpio-core.h
@@ -68,7 +68,7 @@ struct s3c_gpio_chip {
int irq_base;
int group;
spinlock_t lock;
-#ifdef CONFIG_PM
+#ifdef CONFIG_SUSPEND
u32 pm_save[4];
#endif
};
@@ -153,7 +153,7 @@ static inline struct s3c_gpio_chip *s3c_gpiolib_getchip(unsigned int chip)
static inline void s3c_gpiolib_track(struct s3c_gpio_chip *chip) { }
#endif
-#ifdef CONFIG_PM
+#ifdef CONFIG_SUSPEND
extern struct s3c_gpio_pm s3c_gpio_pm_1bit;
extern struct s3c_gpio_pm s3c_gpio_pm_2bit;
extern struct s3c_gpio_pm s3c_gpio_pm_4bit;
@@ -164,7 +164,7 @@ extern struct s3c_gpio_pm s3c_gpio_pm_4bit;
#define s3c_gpio_pm_4bit NULL
#define __gpio_pm(x) NULL
-#endif /* CONFIG_PM */
+#endif /* CONFIG_SUSPEND */
/* locking wrappers to deal with multiple access to the same gpio bank */
#define s3c_gpio_lock(_oc, _fl) spin_lock_irqsave(&(_oc)->lock, _fl)
diff --git a/arch/arm/plat-samsung/include/plat/pm.h b/arch/arm/plat-samsung/include/plat/pm.h
index 30518cc9a67..69f4cc8b31f 100644
--- a/arch/arm/plat-samsung/include/plat/pm.h
+++ b/arch/arm/plat-samsung/include/plat/pm.h
@@ -19,7 +19,7 @@
struct sys_device;
-#ifdef CONFIG_PM
+#ifdef CONFIG_SUSPEND
extern __init int s3c_pm_init(void);
@@ -103,7 +103,7 @@ extern void s3c_pm_do_save(struct sleep_save *ptr, int count);
extern void s3c_pm_do_restore(struct sleep_save *ptr, int count);
extern void s3c_pm_do_restore_core(struct sleep_save *ptr, int count);
-#ifdef CONFIG_PM
+#ifdef CONFIG_SUSPEND
extern int s3c_irqext_wake(struct irq_data *data, unsigned int state);
extern int s3c24xx_irq_suspend(struct sys_device *dev, pm_message_t state);
extern int s3c24xx_irq_resume(struct sys_device *dev);
diff --git a/arch/arm/plat-samsung/pwm.c b/arch/arm/plat-samsung/pwm.c
index 2eeb49fa056..926f08d331c 100644
--- a/arch/arm/plat-samsung/pwm.c
+++ b/arch/arm/plat-samsung/pwm.c
@@ -380,7 +380,7 @@ static int __devexit s3c_pwm_remove(struct platform_device *pdev)
return 0;
}
-#ifdef CONFIG_PM
+#ifdef CONFIG_SUSPEND
static int s3c_pwm_suspend(struct platform_device *pdev, pm_message_t state)
{
struct pwm_device *pwm = platform_get_drvdata(pdev);
diff --git a/arch/arm/plat-spear/include/plat/memory.h b/arch/arm/plat-spear/include/plat/memory.h
index 27a4aba7734..7e3599e1104 100644
--- a/arch/arm/plat-spear/include/plat/memory.h
+++ b/arch/arm/plat-spear/include/plat/memory.h
@@ -15,6 +15,6 @@
#define __PLAT_MEMORY_H
/* Physical DRAM offset */
-#define PHYS_OFFSET UL(0x00000000)
+#define PLAT_PHYS_OFFSET UL(0x00000000)
#endif /* __PLAT_MEMORY_H */
diff --git a/arch/arm/plat-stmp3xxx/include/mach/memory.h b/arch/arm/plat-stmp3xxx/include/mach/memory.h
index 7b875a07a1a..61fa54882e1 100644
--- a/arch/arm/plat-stmp3xxx/include/mach/memory.h
+++ b/arch/arm/plat-stmp3xxx/include/mach/memory.h
@@ -17,6 +17,6 @@
/*
* Physical DRAM offset.
*/
-#define PHYS_OFFSET UL(0x40000000)
+#define PLAT_PHYS_OFFSET UL(0x40000000)
#endif
diff --git a/arch/arm/plat-tcc/include/mach/memory.h b/arch/arm/plat-tcc/include/mach/memory.h
index cd91ba8a670..28a6e0cd13b 100644
--- a/arch/arm/plat-tcc/include/mach/memory.h
+++ b/arch/arm/plat-tcc/include/mach/memory.h
@@ -13,6 +13,6 @@
/*
* Physical DRAM offset.
*/
-#define PHYS_OFFSET UL(0x20000000)
+#define PLAT_PHYS_OFFSET UL(0x20000000)
#endif
diff --git a/arch/arm/vfp/vfpmodule.c b/arch/arm/vfp/vfpmodule.c
index 0797cb528b4..bbf3da012af 100644
--- a/arch/arm/vfp/vfpmodule.c
+++ b/arch/arm/vfp/vfpmodule.c
@@ -153,7 +153,7 @@ static struct notifier_block vfp_notifier_block = {
* Raise a SIGFPE for the current process.
* sicode describes the signal being raised.
*/
-void vfp_raise_sigfpe(unsigned int sicode, struct pt_regs *regs)
+static void vfp_raise_sigfpe(unsigned int sicode, struct pt_regs *regs)
{
siginfo_t info;
@@ -489,8 +489,11 @@ void vfp_flush_hwstate(struct thread_info *thread)
/*
* VFP hardware can lose all context when a CPU goes offline.
- * Safely clear our held state when a CPU has been killed, and
- * re-enable access to VFP when the CPU comes back online.
+ * As we will be running in SMP mode with CPU hotplug, we will save the
+ * hardware state at every thread switch. We clear our held state when
+ * a CPU has been killed, indicating that the VFP hardware doesn't contain
+ * a threads VFP state. When a CPU starts up, we re-enable access to the
+ * VFP hardware.
*
* Both CPU_DYING and CPU_STARTING are called on the CPU which
* is being offlined/onlined.
diff --git a/drivers/amba/bus.c b/drivers/amba/bus.c
index e7df019d29d..43088996a07 100644
--- a/drivers/amba/bus.c
+++ b/drivers/amba/bus.c
@@ -21,8 +21,8 @@
#define to_amba_device(d) container_of(d, struct amba_device, dev)
#define to_amba_driver(d) container_of(d, struct amba_driver, drv)
-static struct amba_id *
-amba_lookup(struct amba_id *table, struct amba_device *dev)
+static const struct amba_id *
+amba_lookup(const struct amba_id *table, struct amba_device *dev)
{
int ret = 0;
@@ -106,7 +106,7 @@ static struct device_attribute amba_dev_attrs[] = {
* Primecells are part of the Advanced Microcontroller Bus Architecture,
* so we call the bus "amba".
*/
-static struct bus_type amba_bustype = {
+struct bus_type amba_bustype = {
.name = "amba",
.dev_attrs = amba_dev_attrs,
.match = amba_match,
@@ -188,7 +188,7 @@ static int amba_probe(struct device *dev)
{
struct amba_device *pcdev = to_amba_device(dev);
struct amba_driver *pcdrv = to_amba_driver(dev->driver);
- struct amba_id *id = amba_lookup(pcdrv->id_table, pcdev);
+ const struct amba_id *id = amba_lookup(pcdrv->id_table, pcdev);
int ret;
do {
diff --git a/drivers/char/hw_random/nomadik-rng.c b/drivers/char/hw_random/nomadik-rng.c
index a348c7e9aa0..dd1d143eb8e 100644
--- a/drivers/char/hw_random/nomadik-rng.c
+++ b/drivers/char/hw_random/nomadik-rng.c
@@ -39,7 +39,7 @@ static struct hwrng nmk_rng = {
.read = nmk_rng_read,
};
-static int nmk_rng_probe(struct amba_device *dev, struct amba_id *id)
+static int nmk_rng_probe(struct amba_device *dev, const struct amba_id *id)
{
void __iomem *base;
int ret;
diff --git a/drivers/dma/amba-pl08x.c b/drivers/dma/amba-pl08x.c
index 07bca4970e5..e6d7228b147 100644
--- a/drivers/dma/amba-pl08x.c
+++ b/drivers/dma/amba-pl08x.c
@@ -1845,7 +1845,7 @@ static inline void init_pl08x_debugfs(struct pl08x_driver_data *pl08x)
}
#endif
-static int pl08x_probe(struct amba_device *adev, struct amba_id *id)
+static int pl08x_probe(struct amba_device *adev, const struct amba_id *id)
{
struct pl08x_driver_data *pl08x;
const struct vendor_data *vd = id->data;
diff --git a/drivers/dma/pl330.c b/drivers/dma/pl330.c
index 7c50f6dfd3f..6abe1ec1f2c 100644
--- a/drivers/dma/pl330.c
+++ b/drivers/dma/pl330.c
@@ -657,7 +657,7 @@ static irqreturn_t pl330_irq_handler(int irq, void *data)
}
static int __devinit
-pl330_probe(struct amba_device *adev, struct amba_id *id)
+pl330_probe(struct amba_device *adev, const struct amba_id *id)
{
struct dma_pl330_platdata *pdat;
struct dma_pl330_dmac *pdmac;
diff --git a/drivers/gpio/pl061.c b/drivers/gpio/pl061.c
index 2975d22daff..838ddbdf90c 100644
--- a/drivers/gpio/pl061.c
+++ b/drivers/gpio/pl061.c
@@ -232,7 +232,7 @@ static void pl061_irq_handler(unsigned irq, struct irq_desc *desc)
desc->irq_data.chip->irq_unmask(&desc->irq_data);
}
-static int pl061_probe(struct amba_device *dev, struct amba_id *id)
+static int pl061_probe(struct amba_device *dev, const struct amba_id *id)
{
struct pl061_platform_data *pdata;
struct pl061_gpio *chip;
diff --git a/drivers/input/serio/ambakmi.c b/drivers/input/serio/ambakmi.c
index 92563a681d6..12abc50508e 100644
--- a/drivers/input/serio/ambakmi.c
+++ b/drivers/input/serio/ambakmi.c
@@ -107,7 +107,8 @@ static void amba_kmi_close(struct serio *io)
clk_disable(kmi->clk);
}
-static int __devinit amba_kmi_probe(struct amba_device *dev, struct amba_id *id)
+static int __devinit amba_kmi_probe(struct amba_device *dev,
+ const struct amba_id *id)
{
struct amba_kmi_port *kmi;
struct serio *io;
diff --git a/drivers/mmc/host/mmci.c b/drivers/mmc/host/mmci.c
index 2d6de3e03e2..67f17d61b97 100644
--- a/drivers/mmc/host/mmci.c
+++ b/drivers/mmc/host/mmci.c
@@ -713,7 +713,8 @@ static const struct mmc_host_ops mmci_ops = {
.get_cd = mmci_get_cd,
};
-static int __devinit mmci_probe(struct amba_device *dev, struct amba_id *id)
+static int __devinit mmci_probe(struct amba_device *dev,
+ const struct amba_id *id)
{
struct mmci_platform_data *plat = dev->dev.platform_data;
struct variant_data *variant = id->data;
diff --git a/drivers/pcmcia/pxa2xx_colibri.c b/drivers/pcmcia/pxa2xx_colibri.c
index c3f72192af6..a52039564e7 100644
--- a/drivers/pcmcia/pxa2xx_colibri.c
+++ b/drivers/pcmcia/pxa2xx_colibri.c
@@ -181,6 +181,9 @@ static int __init colibri_pcmcia_init(void)
{
int ret;
+ if (!machine_is_colibri() && !machine_is_colibri320())
+ return -ENODEV;
+
colibri_pcmcia_device = platform_device_alloc("pxa2xx-pcmcia", -1);
if (!colibri_pcmcia_device)
return -ENOMEM;
diff --git a/drivers/rtc/rtc-pl030.c b/drivers/rtc/rtc-pl030.c
index bbdb2f02798..baff724cd40 100644
--- a/drivers/rtc/rtc-pl030.c
+++ b/drivers/rtc/rtc-pl030.c
@@ -103,7 +103,7 @@ static const struct rtc_class_ops pl030_ops = {
.set_alarm = pl030_set_alarm,
};
-static int pl030_probe(struct amba_device *dev, struct amba_id *id)
+static int pl030_probe(struct amba_device *dev, const struct amba_id *id)
{
struct pl030_rtc *rtc;
int ret;
diff --git a/drivers/rtc/rtc-pl031.c b/drivers/rtc/rtc-pl031.c
index b7a6690e5b3..6568f4b37e1 100644
--- a/drivers/rtc/rtc-pl031.c
+++ b/drivers/rtc/rtc-pl031.c
@@ -358,7 +358,7 @@ static int pl031_remove(struct amba_device *adev)
return 0;
}
-static int pl031_probe(struct amba_device *adev, struct amba_id *id)
+static int pl031_probe(struct amba_device *adev, const struct amba_id *id)
{
int ret;
struct pl031_local *ldata;
diff --git a/drivers/spi/amba-pl022.c b/drivers/spi/amba-pl022.c
index 71a1219a995..95e58c70a2c 100644
--- a/drivers/spi/amba-pl022.c
+++ b/drivers/spi/amba-pl022.c
@@ -2021,7 +2021,7 @@ static void pl022_cleanup(struct spi_device *spi)
static int __devinit
-pl022_probe(struct amba_device *adev, struct amba_id *id)
+pl022_probe(struct amba_device *adev, const struct amba_id *id)
{
struct device *dev = &adev->dev;
struct pl022_ssp_controller *platform_info = adev->dev.platform_data;
diff --git a/drivers/tty/serial/amba-pl010.c b/drivers/tty/serial/amba-pl010.c
index 2904aa04412..d742dd2c525 100644
--- a/drivers/tty/serial/amba-pl010.c
+++ b/drivers/tty/serial/amba-pl010.c
@@ -676,7 +676,7 @@ static struct uart_driver amba_reg = {
.cons = AMBA_CONSOLE,
};
-static int pl010_probe(struct amba_device *dev, struct amba_id *id)
+static int pl010_probe(struct amba_device *dev, const struct amba_id *id)
{
struct uart_amba_port *uap;
void __iomem *base;
diff --git a/drivers/tty/serial/amba-pl011.c b/drivers/tty/serial/amba-pl011.c
index e76d7d00012..0dae46f9102 100644
--- a/drivers/tty/serial/amba-pl011.c
+++ b/drivers/tty/serial/amba-pl011.c
@@ -1349,7 +1349,7 @@ static struct uart_driver amba_reg = {
.cons = AMBA_CONSOLE,
};
-static int pl011_probe(struct amba_device *dev, struct amba_id *id)
+static int pl011_probe(struct amba_device *dev, const struct amba_id *id)
{
struct uart_amba_port *uap;
struct vendor_data *vendor = id->data;
diff --git a/drivers/video/amba-clcd.c b/drivers/video/amba-clcd.c
index 1c2c68356ea..013c8ce5720 100644
--- a/drivers/video/amba-clcd.c
+++ b/drivers/video/amba-clcd.c
@@ -461,7 +461,7 @@ static int clcdfb_register(struct clcd_fb *fb)
return ret;
}
-static int clcdfb_probe(struct amba_device *dev, struct amba_id *id)
+static int clcdfb_probe(struct amba_device *dev, const struct amba_id *id)
{
struct clcd_board *board = dev->dev.platform_data;
struct clcd_fb *fb;
diff --git a/drivers/video/omap2/dss/Kconfig b/drivers/video/omap2/dss/Kconfig
index 43b64403eaa..0d031b2ad3e 100644
--- a/drivers/video/omap2/dss/Kconfig
+++ b/drivers/video/omap2/dss/Kconfig
@@ -1,8 +1,8 @@
menuconfig OMAP2_DSS
- tristate "OMAP2/3 Display Subsystem support (EXPERIMENTAL)"
- depends on ARCH_OMAP2 || ARCH_OMAP3
+ tristate "OMAP2+ Display Subsystem support (EXPERIMENTAL)"
+ depends on ARCH_OMAP2PLUS
help
- OMAP2/3 Display Subsystem support.
+ OMAP2+ Display Subsystem support.
if OMAP2_DSS
diff --git a/drivers/video/omap2/dss/core.c b/drivers/video/omap2/dss/core.c
index 8e89f604928..3c4ad3a66f3 100644
--- a/drivers/video/omap2/dss/core.c
+++ b/drivers/video/omap2/dss/core.c
@@ -34,32 +34,17 @@
#include <linux/regulator/consumer.h>
#include <plat/display.h>
-#include <plat/clock.h>
#include "dss.h"
#include "dss_features.h"
static struct {
struct platform_device *pdev;
- int ctx_id;
-
- struct clk *dss_ick;
- struct clk *dss1_fck;
- struct clk *dss2_fck;
- struct clk *dss_54m_fck;
- struct clk *dss_96m_fck;
- unsigned num_clks_enabled;
struct regulator *vdds_dsi_reg;
struct regulator *vdds_sdi_reg;
- struct regulator *vdda_dac_reg;
} core;
-static void dss_clk_enable_all_no_ctx(void);
-static void dss_clk_disable_all_no_ctx(void);
-static void dss_clk_enable_no_ctx(enum dss_clock clks);
-static void dss_clk_disable_no_ctx(enum dss_clock clks);
-
static char *def_disp_name;
module_param_named(def_disp, def_disp_name, charp, 0);
MODULE_PARM_DESC(def_disp_name, "default display name");
@@ -69,297 +54,6 @@ unsigned int dss_debug;
module_param_named(debug, dss_debug, bool, 0644);
#endif
-/* CONTEXT */
-static int dss_get_ctx_id(void)
-{
- struct omap_dss_board_info *pdata = core.pdev->dev.platform_data;
- int r;
-
- if (!pdata->get_last_off_on_transaction_id)
- return 0;
- r = pdata->get_last_off_on_transaction_id(&core.pdev->dev);
- if (r < 0) {
- dev_err(&core.pdev->dev, "getting transaction ID failed, "
- "will force context restore\n");
- r = -1;
- }
- return r;
-}
-
-int dss_need_ctx_restore(void)
-{
- int id = dss_get_ctx_id();
-
- if (id < 0 || id != core.ctx_id) {
- DSSDBG("ctx id %d -> id %d\n",
- core.ctx_id, id);
- core.ctx_id = id;
- return 1;
- } else {
- return 0;
- }
-}
-
-static void save_all_ctx(void)
-{
- DSSDBG("save context\n");
-
- dss_clk_enable_no_ctx(DSS_CLK_ICK | DSS_CLK_FCK1);
-
- dss_save_context();
- dispc_save_context();
-#ifdef CONFIG_OMAP2_DSS_DSI
- dsi_save_context();
-#endif
-
- dss_clk_disable_no_ctx(DSS_CLK_ICK | DSS_CLK_FCK1);
-}
-
-static void restore_all_ctx(void)
-{
- DSSDBG("restore context\n");
-
- dss_clk_enable_all_no_ctx();
-
- dss_restore_context();
- dispc_restore_context();
-#ifdef CONFIG_OMAP2_DSS_DSI
- dsi_restore_context();
-#endif
-
- dss_clk_disable_all_no_ctx();
-}
-
-#if defined(CONFIG_DEBUG_FS) && defined(CONFIG_OMAP2_DSS_DEBUG_SUPPORT)
-/* CLOCKS */
-static void core_dump_clocks(struct seq_file *s)
-{
- int i;
- struct clk *clocks[5] = {
- core.dss_ick,
- core.dss1_fck,
- core.dss2_fck,
- core.dss_54m_fck,
- core.dss_96m_fck
- };
-
- seq_printf(s, "- CORE -\n");
-
- seq_printf(s, "internal clk count\t\t%u\n", core.num_clks_enabled);
-
- for (i = 0; i < 5; i++) {
- if (!clocks[i])
- continue;
- seq_printf(s, "%-15s\t%lu\t%d\n",
- clocks[i]->name,
- clk_get_rate(clocks[i]),
- clocks[i]->usecount);
- }
-}
-#endif /* defined(CONFIG_DEBUG_FS) && defined(CONFIG_OMAP2_DSS_DEBUG_SUPPORT) */
-
-static int dss_get_clock(struct clk **clock, const char *clk_name)
-{
- struct clk *clk;
-
- clk = clk_get(&core.pdev->dev, clk_name);
-
- if (IS_ERR(clk)) {
- DSSERR("can't get clock %s", clk_name);
- return PTR_ERR(clk);
- }
-
- *clock = clk;
-
- DSSDBG("clk %s, rate %ld\n", clk_name, clk_get_rate(clk));
-
- return 0;
-}
-
-static int dss_get_clocks(void)
-{
- int r;
-
- core.dss_ick = NULL;
- core.dss1_fck = NULL;
- core.dss2_fck = NULL;
- core.dss_54m_fck = NULL;
- core.dss_96m_fck = NULL;
-
- r = dss_get_clock(&core.dss_ick, "ick");
- if (r)
- goto err;
-
- r = dss_get_clock(&core.dss1_fck, "dss1_fck");
- if (r)
- goto err;
-
- r = dss_get_clock(&core.dss2_fck, "dss2_fck");
- if (r)
- goto err;
-
- r = dss_get_clock(&core.dss_54m_fck, "tv_fck");
- if (r)
- goto err;
-
- r = dss_get_clock(&core.dss_96m_fck, "video_fck");
- if (r)
- goto err;
-
- return 0;
-
-err:
- if (core.dss_ick)
- clk_put(core.dss_ick);
- if (core.dss1_fck)
- clk_put(core.dss1_fck);
- if (core.dss2_fck)
- clk_put(core.dss2_fck);
- if (core.dss_54m_fck)
- clk_put(core.dss_54m_fck);
- if (core.dss_96m_fck)
- clk_put(core.dss_96m_fck);
-
- return r;
-}
-
-static void dss_put_clocks(void)
-{
- if (core.dss_96m_fck)
- clk_put(core.dss_96m_fck);
- clk_put(core.dss_54m_fck);
- clk_put(core.dss1_fck);
- clk_put(core.dss2_fck);
- clk_put(core.dss_ick);
-}
-
-unsigned long dss_clk_get_rate(enum dss_clock clk)
-{
- switch (clk) {
- case DSS_CLK_ICK:
- return clk_get_rate(core.dss_ick);
- case DSS_CLK_FCK1:
- return clk_get_rate(core.dss1_fck);
- case DSS_CLK_FCK2:
- return clk_get_rate(core.dss2_fck);
- case DSS_CLK_54M:
- return clk_get_rate(core.dss_54m_fck);
- case DSS_CLK_96M:
- return clk_get_rate(core.dss_96m_fck);
- }
-
- BUG();
- return 0;
-}
-
-static unsigned count_clk_bits(enum dss_clock clks)
-{
- unsigned num_clks = 0;
-
- if (clks & DSS_CLK_ICK)
- ++num_clks;
- if (clks & DSS_CLK_FCK1)
- ++num_clks;
- if (clks & DSS_CLK_FCK2)
- ++num_clks;
- if (clks & DSS_CLK_54M)
- ++num_clks;
- if (clks & DSS_CLK_96M)
- ++num_clks;
-
- return num_clks;
-}
-
-static void dss_clk_enable_no_ctx(enum dss_clock clks)
-{
- unsigned num_clks = count_clk_bits(clks);
-
- if (clks & DSS_CLK_ICK)
- clk_enable(core.dss_ick);
- if (clks & DSS_CLK_FCK1)
- clk_enable(core.dss1_fck);
- if (clks & DSS_CLK_FCK2)
- clk_enable(core.dss2_fck);
- if (clks & DSS_CLK_54M)
- clk_enable(core.dss_54m_fck);
- if (clks & DSS_CLK_96M)
- clk_enable(core.dss_96m_fck);
-
- core.num_clks_enabled += num_clks;
-}
-
-void dss_clk_enable(enum dss_clock clks)
-{
- bool check_ctx = core.num_clks_enabled == 0;
-
- dss_clk_enable_no_ctx(clks);
-
- if (check_ctx && cpu_is_omap34xx() && dss_need_ctx_restore())
- restore_all_ctx();
-}
-
-static void dss_clk_disable_no_ctx(enum dss_clock clks)
-{
- unsigned num_clks = count_clk_bits(clks);
-
- if (clks & DSS_CLK_ICK)
- clk_disable(core.dss_ick);
- if (clks & DSS_CLK_FCK1)
- clk_disable(core.dss1_fck);
- if (clks & DSS_CLK_FCK2)
- clk_disable(core.dss2_fck);
- if (clks & DSS_CLK_54M)
- clk_disable(core.dss_54m_fck);
- if (clks & DSS_CLK_96M)
- clk_disable(core.dss_96m_fck);
-
- core.num_clks_enabled -= num_clks;
-}
-
-void dss_clk_disable(enum dss_clock clks)
-{
- if (cpu_is_omap34xx()) {
- unsigned num_clks = count_clk_bits(clks);
-
- BUG_ON(core.num_clks_enabled < num_clks);
-
- if (core.num_clks_enabled == num_clks)
- save_all_ctx();
- }
-
- dss_clk_disable_no_ctx(clks);
-}
-
-static void dss_clk_enable_all_no_ctx(void)
-{
- enum dss_clock clks;
-
- clks = DSS_CLK_ICK | DSS_CLK_FCK1 | DSS_CLK_FCK2 | DSS_CLK_54M;
- if (cpu_is_omap34xx())
- clks |= DSS_CLK_96M;
- dss_clk_enable_no_ctx(clks);
-}
-
-static void dss_clk_disable_all_no_ctx(void)
-{
- enum dss_clock clks;
-
- clks = DSS_CLK_ICK | DSS_CLK_FCK1 | DSS_CLK_FCK2 | DSS_CLK_54M;
- if (cpu_is_omap34xx())
- clks |= DSS_CLK_96M;
- dss_clk_disable_no_ctx(clks);
-}
-
-static void dss_clk_disable_all(void)
-{
- enum dss_clock clks;
-
- clks = DSS_CLK_ICK | DSS_CLK_FCK1 | DSS_CLK_FCK2 | DSS_CLK_54M;
- if (cpu_is_omap34xx())
- clks |= DSS_CLK_96M;
- dss_clk_disable(clks);
-}
-
/* REGULATORS */
struct regulator *dss_get_vdds_dsi(void)
@@ -390,32 +84,7 @@ struct regulator *dss_get_vdds_sdi(void)
return reg;
}
-struct regulator *dss_get_vdda_dac(void)
-{
- struct regulator *reg;
-
- if (core.vdda_dac_reg != NULL)
- return core.vdda_dac_reg;
-
- reg = regulator_get(&core.pdev->dev, "vdda_dac");
- if (!IS_ERR(reg))
- core.vdda_dac_reg = reg;
-
- return reg;
-}
-
-/* DEBUGFS */
#if defined(CONFIG_DEBUG_FS) && defined(CONFIG_OMAP2_DSS_DEBUG_SUPPORT)
-static void dss_debug_dump_clocks(struct seq_file *s)
-{
- core_dump_clocks(s);
- dss_dump_clocks(s);
- dispc_dump_clocks(s);
-#ifdef CONFIG_OMAP2_DSS_DSI
- dsi_dump_clocks(s);
-#endif
-}
-
static int dss_debug_show(struct seq_file *s, void *unused)
{
void (*func)(struct seq_file *) = s->private;
@@ -508,30 +177,18 @@ static int omap_dss_probe(struct platform_device *pdev)
dss_init_overlay_managers(pdev);
dss_init_overlays(pdev);
- r = dss_get_clocks();
- if (r)
- goto err_clocks;
-
- dss_clk_enable_all_no_ctx();
-
- core.ctx_id = dss_get_ctx_id();
- DSSDBG("initial ctx id %u\n", core.ctx_id);
-
-#ifdef CONFIG_FB_OMAP_BOOTLOADER_INIT
- /* DISPC_CONTROL */
- if (omap_readl(0x48050440) & 1) /* LCD enabled? */
- skip_init = 1;
-#endif
-
- r = dss_init(skip_init);
+ r = dss_init_platform_driver();
if (r) {
- DSSERR("Failed to initialize DSS\n");
+ DSSERR("Failed to initialize DSS platform driver\n");
goto err_dss;
}
- r = rfbi_init();
+ /* keep clocks enabled to prevent context saves/restores during init */
+ dss_clk_enable(DSS_CLK_ICK | DSS_CLK_FCK);
+
+ r = rfbi_init_platform_driver();
if (r) {
- DSSERR("Failed to initialize rfbi\n");
+ DSSERR("Failed to initialize rfbi platform driver\n");
goto err_rfbi;
}
@@ -541,18 +198,23 @@ static int omap_dss_probe(struct platform_device *pdev)
goto err_dpi;
}
- r = dispc_init();
+ r = dispc_init_platform_driver();
if (r) {
- DSSERR("Failed to initialize dispc\n");
+ DSSERR("Failed to initialize dispc platform driver\n");
goto err_dispc;
}
- r = venc_init(pdev);
+ r = venc_init_platform_driver();
if (r) {
- DSSERR("Failed to initialize venc\n");
+ DSSERR("Failed to initialize venc platform driver\n");
goto err_venc;
}
+#ifdef CONFIG_FB_OMAP_BOOTLOADER_INIT
+ /* DISPC_CONTROL */
+ if (omap_readl(0x48050440) & 1) /* LCD enabled? */
+ skip_init = 1;
+#endif
if (cpu_is_omap34xx()) {
r = sdi_init(skip_init);
if (r) {
@@ -560,9 +222,9 @@ static int omap_dss_probe(struct platform_device *pdev)
goto err_sdi;
}
- r = dsi_init(pdev);
+ r = dsi_init_platform_driver();
if (r) {
- DSSERR("Failed to initialize DSI\n");
+ DSSERR("Failed to initialize DSI platform driver\n");
goto err_dsi;
}
}
@@ -589,7 +251,7 @@ static int omap_dss_probe(struct platform_device *pdev)
pdata->default_device = dssdev;
}
- dss_clk_disable_all();
+ dss_clk_disable(DSS_CLK_ICK | DSS_CLK_FCK);
return 0;
@@ -597,24 +259,21 @@ err_register:
dss_uninitialize_debugfs();
err_debugfs:
if (cpu_is_omap34xx())
- dsi_exit();
+ dsi_uninit_platform_driver();
err_dsi:
if (cpu_is_omap34xx())
sdi_exit();
err_sdi:
- venc_exit();
+ venc_uninit_platform_driver();
err_venc:
- dispc_exit();
+ dispc_uninit_platform_driver();
err_dispc:
dpi_exit();
err_dpi:
- rfbi_exit();
+ rfbi_uninit_platform_driver();
err_rfbi:
- dss_exit();
+ dss_uninit_platform_driver();
err_dss:
- dss_clk_disable_all_no_ctx();
- dss_put_clocks();
-err_clocks:
return r;
}
@@ -623,61 +282,19 @@ static int omap_dss_remove(struct platform_device *pdev)
{
struct omap_dss_board_info *pdata = pdev->dev.platform_data;
int i;
- int c;
dss_uninitialize_debugfs();
- venc_exit();
- dispc_exit();
+ venc_uninit_platform_driver();
+ dispc_uninit_platform_driver();
dpi_exit();
- rfbi_exit();
+ rfbi_uninit_platform_driver();
if (cpu_is_omap34xx()) {
- dsi_exit();
+ dsi_uninit_platform_driver();
sdi_exit();
}
- dss_exit();
-
- /* these should be removed at some point */
- c = core.dss_ick->usecount;
- if (c > 0) {
- DSSERR("warning: dss_ick usecount %d, disabling\n", c);
- while (c-- > 0)
- clk_disable(core.dss_ick);
- }
-
- c = core.dss1_fck->usecount;
- if (c > 0) {
- DSSERR("warning: dss1_fck usecount %d, disabling\n", c);
- while (c-- > 0)
- clk_disable(core.dss1_fck);
- }
-
- c = core.dss2_fck->usecount;
- if (c > 0) {
- DSSERR("warning: dss2_fck usecount %d, disabling\n", c);
- while (c-- > 0)
- clk_disable(core.dss2_fck);
- }
-
- c = core.dss_54m_fck->usecount;
- if (c > 0) {
- DSSERR("warning: dss_54m_fck usecount %d, disabling\n", c);
- while (c-- > 0)
- clk_disable(core.dss_54m_fck);
- }
-
- if (core.dss_96m_fck) {
- c = core.dss_96m_fck->usecount;
- if (c > 0) {
- DSSERR("warning: dss_96m_fck usecount %d, disabling\n",
- c);
- while (c-- > 0)
- clk_disable(core.dss_96m_fck);
- }
- }
-
- dss_put_clocks();
+ dss_uninit_platform_driver();
dss_uninit_overlays(pdev);
dss_uninit_overlay_managers(pdev);
@@ -715,7 +332,7 @@ static struct platform_driver omap_dss_driver = {
.suspend = omap_dss_suspend,
.resume = omap_dss_resume,
.driver = {
- .name = "omapdss",
+ .name = "omap_display",
.owner = THIS_MODULE,
},
};
@@ -965,11 +582,6 @@ static void __exit omap_dss_exit(void)
core.vdds_sdi_reg = NULL;
}
- if (core.vdda_dac_reg != NULL) {
- regulator_put(core.vdda_dac_reg);
- core.vdda_dac_reg = NULL;
- }
-
platform_driver_unregister(&omap_dss_driver);
omap_dss_bus_unregister();
diff --git a/drivers/video/omap2/dss/dispc.c b/drivers/video/omap2/dss/dispc.c
index 9f8c69f16e6..cda1d2e9ac4 100644
--- a/drivers/video/omap2/dss/dispc.c
+++ b/drivers/video/omap2/dss/dispc.c
@@ -42,8 +42,6 @@
#include "dss_features.h"
/* DISPC */
-#define DISPC_BASE 0x48050400
-
#define DISPC_SZ_REGS SZ_4K
struct dispc_reg { u16 idx; };
@@ -74,7 +72,12 @@ struct dispc_reg { u16 idx; };
#define DISPC_TIMING_H(ch) DISPC_REG(ch != 2 ? 0x0064 : 0x0400)
#define DISPC_TIMING_V(ch) DISPC_REG(ch != 2 ? 0x0068 : 0x0404)
#define DISPC_POL_FREQ(ch) DISPC_REG(ch != 2 ? 0x006C : 0x0408)
-#define DISPC_DIVISOR(ch) DISPC_REG(ch != 2 ? 0x0070 : 0x040C)
+/*
+ * Use DISPC_DIVISORo(ch) when DISPC_DIVISOR1 or DISPC_DIVISOR2 has to be
+ * configured. OMAP4 TRM uses DISPC_DIVISORo generically to refer DISPC_DIVISOR1
+ * and DISPC_DIVISOR2
+ */
+#define DISPC_DIVISORo(ch) DISPC_REG(ch != 2 ? 0x0070 : 0x040C)
#define DISPC_GLOBAL_ALPHA DISPC_REG(0x0074)
#define DISPC_SIZE_DIG DISPC_REG(0x0078)
#define DISPC_SIZE_LCD(ch) DISPC_REG(ch != 2 ? 0x007C : 0x03CC)
@@ -129,6 +132,17 @@ struct dispc_reg { u16 idx; };
#define DISPC_VID_PRELOAD(n) DISPC_REG(0x230 + (n)*0x04)
+/*
+ * The OMAP4 DISPC_DIVISOR1 is backward compatible to OMAP3xxx DISPC_DIVISOR.
+ * However DISPC_DIVISOR is also provided in OMAP4, to control DISPC_CORE_CLK.
+ * This allows DISPC_CORE_CLK to be independent of logical clock dividers (lcd)
+ * of LCD1 (primary) and LCD2 (secondary) displays.
+ *
+ * To derive pixel clocks for Primary and Secondary LCD channels, configure the
+ * lcd and pcd in DISPC_DIVISOR1 and DISPC_DIVISOR2 respectively, using the
+ * DISPC_DIVISORo(ch).
+ */
+#define DISPC_DIVISOR DISPC_REG(0x0804)
#define DISPC_IRQ_MASK_ERROR (DISPC_IRQ_GFX_FIFO_UNDERFLOW | \
DISPC_IRQ_OCP_ERR | \
@@ -178,6 +192,7 @@ struct dispc_irq_stats {
};
static struct {
+ struct platform_device *pdev;
void __iomem *base;
u32 fifo_size[3];
@@ -230,7 +245,7 @@ void dispc_save_context(void)
SR(TIMING_H(0));
SR(TIMING_V(0));
SR(POL_FREQ(0));
- SR(DIVISOR(0));
+ SR(DIVISORo(0));
SR(GLOBAL_ALPHA);
SR(SIZE_DIG);
SR(SIZE_LCD(0));
@@ -242,7 +257,7 @@ void dispc_save_context(void)
SR(TIMING_H(2));
SR(TIMING_V(2));
SR(POL_FREQ(2));
- SR(DIVISOR(2));
+ SR(DIVISORo(2));
SR(CONFIG2);
}
@@ -373,6 +388,9 @@ void dispc_save_context(void)
SR(VID_FIR_COEF_V(1, 7));
SR(VID_PRELOAD(1));
+
+ if (dss_has_feature(FEAT_CORE_CLK_DIV))
+ SR(DIVISOR);
}
void dispc_restore_context(void)
@@ -389,7 +407,7 @@ void dispc_restore_context(void)
RR(TIMING_H(0));
RR(TIMING_V(0));
RR(POL_FREQ(0));
- RR(DIVISOR(0));
+ RR(DIVISORo(0));
RR(GLOBAL_ALPHA);
RR(SIZE_DIG);
RR(SIZE_LCD(0));
@@ -400,7 +418,7 @@ void dispc_restore_context(void)
RR(TIMING_H(2));
RR(TIMING_V(2));
RR(POL_FREQ(2));
- RR(DIVISOR(2));
+ RR(DIVISORo(2));
RR(CONFIG2);
}
@@ -532,6 +550,9 @@ void dispc_restore_context(void)
RR(VID_PRELOAD(1));
+ if (dss_has_feature(FEAT_CORE_CLK_DIV))
+ RR(DIVISOR);
+
/* enable last, because LCD & DIGIT enable are here */
RR(CONTROL);
if (dss_has_feature(FEAT_MGR_LCD2))
@@ -552,9 +573,9 @@ void dispc_restore_context(void)
static inline void enable_clocks(bool enable)
{
if (enable)
- dss_clk_enable(DSS_CLK_ICK | DSS_CLK_FCK1);
+ dss_clk_enable(DSS_CLK_ICK | DSS_CLK_FCK);
else
- dss_clk_disable(DSS_CLK_ICK | DSS_CLK_FCK1);
+ dss_clk_disable(DSS_CLK_ICK | DSS_CLK_FCK);
}
bool dispc_go_busy(enum omap_channel channel)
@@ -2293,7 +2314,7 @@ static void dispc_set_lcd_divisor(enum omap_channel channel, u16 lck_div,
BUG_ON(pck_div < 2);
enable_clocks(1);
- dispc_write_reg(DISPC_DIVISOR(channel),
+ dispc_write_reg(DISPC_DIVISORo(channel),
FLD_VAL(lck_div, 23, 16) | FLD_VAL(pck_div, 7, 0));
enable_clocks(0);
}
@@ -2302,7 +2323,7 @@ static void dispc_get_lcd_divisor(enum omap_channel channel, int *lck_div,
int *pck_div)
{
u32 l;
- l = dispc_read_reg(DISPC_DIVISOR(channel));
+ l = dispc_read_reg(DISPC_DIVISORo(channel));
*lck_div = FLD_GET(l, 23, 16);
*pck_div = FLD_GET(l, 7, 0);
}
@@ -2312,7 +2333,7 @@ unsigned long dispc_fclk_rate(void)
unsigned long r = 0;
if (dss_get_dispc_clk_source() == DSS_SRC_DSS1_ALWON_FCLK)
- r = dss_clk_get_rate(DSS_CLK_FCK1);
+ r = dss_clk_get_rate(DSS_CLK_FCK);
else
#ifdef CONFIG_OMAP2_DSS_DSI
r = dsi_get_dsi1_pll_rate();
@@ -2328,7 +2349,7 @@ unsigned long dispc_lclk_rate(enum omap_channel channel)
unsigned long r;
u32 l;
- l = dispc_read_reg(DISPC_DIVISOR(channel));
+ l = dispc_read_reg(DISPC_DIVISORo(channel));
lcd = FLD_GET(l, 23, 16);
@@ -2343,7 +2364,7 @@ unsigned long dispc_pclk_rate(enum omap_channel channel)
unsigned long r;
u32 l;
- l = dispc_read_reg(DISPC_DIVISOR(channel));
+ l = dispc_read_reg(DISPC_DIVISORo(channel));
lcd = FLD_GET(l, 23, 16);
pcd = FLD_GET(l, 7, 0);
@@ -2440,7 +2461,7 @@ void dispc_dump_regs(struct seq_file *s)
{
#define DUMPREG(r) seq_printf(s, "%-35s %08x\n", #r, dispc_read_reg(r))
- dss_clk_enable(DSS_CLK_ICK | DSS_CLK_FCK1);
+ dss_clk_enable(DSS_CLK_ICK | DSS_CLK_FCK);
DUMPREG(DISPC_REVISION);
DUMPREG(DISPC_SYSCONFIG);
@@ -2459,7 +2480,7 @@ void dispc_dump_regs(struct seq_file *s)
DUMPREG(DISPC_TIMING_H(0));
DUMPREG(DISPC_TIMING_V(0));
DUMPREG(DISPC_POL_FREQ(0));
- DUMPREG(DISPC_DIVISOR(0));
+ DUMPREG(DISPC_DIVISORo(0));
DUMPREG(DISPC_GLOBAL_ALPHA);
DUMPREG(DISPC_SIZE_DIG);
DUMPREG(DISPC_SIZE_LCD(0));
@@ -2471,7 +2492,7 @@ void dispc_dump_regs(struct seq_file *s)
DUMPREG(DISPC_TIMING_H(2));
DUMPREG(DISPC_TIMING_V(2));
DUMPREG(DISPC_POL_FREQ(2));
- DUMPREG(DISPC_DIVISOR(2));
+ DUMPREG(DISPC_DIVISORo(2));
DUMPREG(DISPC_SIZE_LCD(2));
}
@@ -2597,7 +2618,7 @@ void dispc_dump_regs(struct seq_file *s)
DUMPREG(DISPC_VID_PRELOAD(0));
DUMPREG(DISPC_VID_PRELOAD(1));
- dss_clk_disable(DSS_CLK_ICK | DSS_CLK_FCK1);
+ dss_clk_disable(DSS_CLK_ICK | DSS_CLK_FCK);
#undef DUMPREG
}
@@ -2713,8 +2734,8 @@ int dispc_get_clock_div(enum omap_channel channel,
fck = dispc_fclk_rate();
- cinfo->lck_div = REG_GET(DISPC_DIVISOR(channel), 23, 16);
- cinfo->pck_div = REG_GET(DISPC_DIVISOR(channel), 7, 0);
+ cinfo->lck_div = REG_GET(DISPC_DIVISORo(channel), 23, 16);
+ cinfo->pck_div = REG_GET(DISPC_DIVISORo(channel), 7, 0);
cinfo->lck = fck / cinfo->lck_div;
cinfo->pck = cinfo->lck / cinfo->pck_div;
@@ -3253,6 +3274,15 @@ static void _omap_dispc_initial_config(void)
l = FLD_MOD(l, 1, 0, 0); /* AUTOIDLE */
dispc_write_reg(DISPC_SYSCONFIG, l);
+ /* Exclusively enable DISPC_CORE_CLK and set divider to 1 */
+ if (dss_has_feature(FEAT_CORE_CLK_DIV)) {
+ l = dispc_read_reg(DISPC_DIVISOR);
+ /* Use DISPC_DIVISOR.LCD, instead of DISPC_DIVISOR1.LCD */
+ l = FLD_MOD(l, 1, 0, 0);
+ l = FLD_MOD(l, 1, 23, 16);
+ dispc_write_reg(DISPC_DIVISOR, l);
+ }
+
/* FUNCGATED */
if (dss_has_feature(FEAT_FUNCGATED))
REG_FLD_MOD(DISPC_CONFIG, 1, 9, 9);
@@ -3269,47 +3299,6 @@ static void _omap_dispc_initial_config(void)
dispc_read_plane_fifo_sizes();
}
-int dispc_init(void)
-{
- u32 rev;
-
- spin_lock_init(&dispc.irq_lock);
-
-#ifdef CONFIG_OMAP2_DSS_COLLECT_IRQ_STATS
- spin_lock_init(&dispc.irq_stats_lock);
- dispc.irq_stats.last_reset = jiffies;
-#endif
-
- INIT_WORK(&dispc.error_work, dispc_error_worker);
-
- dispc.base = ioremap(DISPC_BASE, DISPC_SZ_REGS);
- if (!dispc.base) {
- DSSERR("can't ioremap DISPC\n");
- return -ENOMEM;
- }
-
- enable_clocks(1);
-
- _omap_dispc_initial_config();
-
- _omap_dispc_initialize_irq();
-
- dispc_save_context();
-
- rev = dispc_read_reg(DISPC_REVISION);
- printk(KERN_INFO "OMAP DISPC rev %d.%d\n",
- FLD_GET(rev, 7, 4), FLD_GET(rev, 3, 0));
-
- enable_clocks(0);
-
- return 0;
-}
-
-void dispc_exit(void)
-{
- iounmap(dispc.base);
-}
-
int dispc_enable_plane(enum omap_plane plane, bool enable)
{
DSSDBG("dispc_enable_plane %d, %d\n", plane, enable);
@@ -3359,3 +3348,73 @@ int dispc_setup_plane(enum omap_plane plane,
return r;
}
+
+/* DISPC HW IP initialisation */
+static int omap_dispchw_probe(struct platform_device *pdev)
+{
+ u32 rev;
+ struct resource *dispc_mem;
+
+ dispc.pdev = pdev;
+
+ spin_lock_init(&dispc.irq_lock);
+
+#ifdef CONFIG_OMAP2_DSS_COLLECT_IRQ_STATS
+ spin_lock_init(&dispc.irq_stats_lock);
+ dispc.irq_stats.last_reset = jiffies;
+#endif
+
+ INIT_WORK(&dispc.error_work, dispc_error_worker);
+
+ dispc_mem = platform_get_resource(dispc.pdev, IORESOURCE_MEM, 0);
+ if (!dispc_mem) {
+ DSSERR("can't get IORESOURCE_MEM DISPC\n");
+ return -EINVAL;
+ }
+ dispc.base = ioremap(dispc_mem->start, resource_size(dispc_mem));
+ if (!dispc.base) {
+ DSSERR("can't ioremap DISPC\n");
+ return -ENOMEM;
+ }
+
+ enable_clocks(1);
+
+ _omap_dispc_initial_config();
+
+ _omap_dispc_initialize_irq();
+
+ dispc_save_context();
+
+ rev = dispc_read_reg(DISPC_REVISION);
+ dev_dbg(&pdev->dev, "OMAP DISPC rev %d.%d\n",
+ FLD_GET(rev, 7, 4), FLD_GET(rev, 3, 0));
+
+ enable_clocks(0);
+
+ return 0;
+}
+
+static int omap_dispchw_remove(struct platform_device *pdev)
+{
+ iounmap(dispc.base);
+ return 0;
+}
+
+static struct platform_driver omap_dispchw_driver = {
+ .probe = omap_dispchw_probe,
+ .remove = omap_dispchw_remove,
+ .driver = {
+ .name = "omap_dispc",
+ .owner = THIS_MODULE,
+ },
+};
+
+int dispc_init_platform_driver(void)
+{
+ return platform_driver_register(&omap_dispchw_driver);
+}
+
+void dispc_uninit_platform_driver(void)
+{
+ return platform_driver_unregister(&omap_dispchw_driver);
+}
diff --git a/drivers/video/omap2/dss/dpi.c b/drivers/video/omap2/dss/dpi.c
index 75fb0a51543..746f1b6dd89 100644
--- a/drivers/video/omap2/dss/dpi.c
+++ b/drivers/video/omap2/dss/dpi.c
@@ -107,7 +107,7 @@ static int dpi_set_mode(struct omap_dss_device *dssdev)
bool is_tft;
int r = 0;
- dss_clk_enable(DSS_CLK_ICK | DSS_CLK_FCK1);
+ dss_clk_enable(DSS_CLK_ICK | DSS_CLK_FCK);
dispc_set_pol_freq(dssdev->manager->id, dssdev->panel.config,
dssdev->panel.acbi, dssdev->panel.acb);
@@ -137,7 +137,7 @@ static int dpi_set_mode(struct omap_dss_device *dssdev)
dispc_set_lcd_timings(dssdev->manager->id, t);
err0:
- dss_clk_disable(DSS_CLK_ICK | DSS_CLK_FCK1);
+ dss_clk_disable(DSS_CLK_ICK | DSS_CLK_FCK);
return r;
}
@@ -173,14 +173,14 @@ int omapdss_dpi_display_enable(struct omap_dss_device *dssdev)
goto err1;
}
- dss_clk_enable(DSS_CLK_ICK | DSS_CLK_FCK1);
+ dss_clk_enable(DSS_CLK_ICK | DSS_CLK_FCK);
r = dpi_basic_init(dssdev);
if (r)
goto err2;
#ifdef CONFIG_OMAP2_DSS_USE_DSI_PLL
- dss_clk_enable(DSS_CLK_FCK2);
+ dss_clk_enable(DSS_CLK_SYSCK);
r = dsi_pll_init(dssdev, 0, 1);
if (r)
goto err3;
@@ -199,10 +199,10 @@ err4:
#ifdef CONFIG_OMAP2_DSS_USE_DSI_PLL
dsi_pll_uninit();
err3:
- dss_clk_disable(DSS_CLK_FCK2);
+ dss_clk_disable(DSS_CLK_SYSCK);
#endif
err2:
- dss_clk_disable(DSS_CLK_ICK | DSS_CLK_FCK1);
+ dss_clk_disable(DSS_CLK_ICK | DSS_CLK_FCK);
if (cpu_is_omap34xx())
regulator_disable(dpi.vdds_dsi_reg);
err1:
@@ -219,10 +219,10 @@ void omapdss_dpi_display_disable(struct omap_dss_device *dssdev)
#ifdef CONFIG_OMAP2_DSS_USE_DSI_PLL
dss_select_dispc_clk_source(DSS_SRC_DSS1_ALWON_FCLK);
dsi_pll_uninit();
- dss_clk_disable(DSS_CLK_FCK2);
+ dss_clk_disable(DSS_CLK_SYSCK);
#endif
- dss_clk_disable(DSS_CLK_ICK | DSS_CLK_FCK1);
+ dss_clk_disable(DSS_CLK_ICK | DSS_CLK_FCK);
if (cpu_is_omap34xx())
regulator_disable(dpi.vdds_dsi_reg);
diff --git a/drivers/video/omap2/dss/dsi.c b/drivers/video/omap2/dss/dsi.c
index ddf3a056082..1802057cbed 100644
--- a/drivers/video/omap2/dss/dsi.c
+++ b/drivers/video/omap2/dss/dsi.c
@@ -42,8 +42,6 @@
/*#define VERBOSE_IRQ*/
#define DSI_CATCH_MISSING_TE
-#define DSI_BASE 0x4804FC00
-
struct dsi_reg { u16 idx; };
#define DSI_REG(idx) ((const struct dsi_reg) { idx })
@@ -222,6 +220,7 @@ struct dsi_irq_stats {
static struct
{
+ struct platform_device *pdev;
void __iomem *base;
struct dsi_clock_info current_cinfo;
@@ -292,6 +291,20 @@ static inline u32 dsi_read_reg(const struct dsi_reg idx)
return __raw_readl(dsi.base + idx.idx);
}
+static struct regulator *dsi_get_vdds_dsi(void)
+{
+ struct regulator *reg;
+
+ if (dsi.vdds_dsi_reg != NULL)
+ return dsi.vdds_dsi_reg;
+
+ reg = regulator_get(&dsi.pdev->dev, "vdds_dsi");
+ if (!IS_ERR(reg))
+ dsi.vdds_dsi_reg = reg;
+
+ return reg;
+}
+
void dsi_save_context(void)
{
@@ -641,18 +654,18 @@ static void dsi_vc_disable_bta_irq(int channel)
static inline void enable_clocks(bool enable)
{
if (enable)
- dss_clk_enable(DSS_CLK_ICK | DSS_CLK_FCK1);
+ dss_clk_enable(DSS_CLK_ICK | DSS_CLK_FCK);
else
- dss_clk_disable(DSS_CLK_ICK | DSS_CLK_FCK1);
+ dss_clk_disable(DSS_CLK_ICK | DSS_CLK_FCK);
}
/* source clock for DSI PLL. this could also be PCLKFREE */
static inline void dsi_enable_pll_clock(bool enable)
{
if (enable)
- dss_clk_enable(DSS_CLK_FCK2);
+ dss_clk_enable(DSS_CLK_SYSCK);
else
- dss_clk_disable(DSS_CLK_FCK2);
+ dss_clk_disable(DSS_CLK_SYSCK);
if (enable && dsi.pll_locked) {
if (wait_for_bit_change(DSI_PLL_STATUS, 1, 1) != 1)
@@ -728,7 +741,7 @@ static unsigned long dsi_fclk_rate(void)
if (dss_get_dsi_clk_source() == DSS_SRC_DSS1_ALWON_FCLK) {
/* DSI FCLK source is DSS1_ALWON_FCK, which is dss1_fck */
- r = dss_clk_get_rate(DSS_CLK_FCK1);
+ r = dss_clk_get_rate(DSS_CLK_FCK);
} else {
/* DSI FCLK source is DSI2_PLL_FCLK */
r = dsi_get_dsi2_pll_rate();
@@ -808,7 +821,7 @@ static int dsi_calc_clock_rates(struct omap_dss_device *dssdev,
return -EINVAL;
if (cinfo->use_dss2_fck) {
- cinfo->clkin = dss_clk_get_rate(DSS_CLK_FCK2);
+ cinfo->clkin = dss_clk_get_rate(DSS_CLK_SYSCK);
/* XXX it is unclear if highfreq should be used
* with DSS2_FCK source also */
cinfo->highfreq = 0;
@@ -854,7 +867,7 @@ int dsi_pll_calc_clock_div_pck(bool is_tft, unsigned long req_pck,
int match = 0;
unsigned long dss_clk_fck2;
- dss_clk_fck2 = dss_clk_get_rate(DSS_CLK_FCK2);
+ dss_clk_fck2 = dss_clk_get_rate(DSS_CLK_SYSCK);
if (req_pck == dsi.cache_req_pck &&
dsi.cache_cinfo.clkin == dss_clk_fck2) {
@@ -1306,7 +1319,7 @@ void dsi_dump_regs(struct seq_file *s)
{
#define DUMPREG(r) seq_printf(s, "%-35s %08x\n", #r, dsi_read_reg(r))
- dss_clk_enable(DSS_CLK_ICK | DSS_CLK_FCK1);
+ dss_clk_enable(DSS_CLK_ICK | DSS_CLK_FCK);
DUMPREG(DSI_REVISION);
DUMPREG(DSI_SYSCONFIG);
@@ -1378,7 +1391,7 @@ void dsi_dump_regs(struct seq_file *s)
DUMPREG(DSI_PLL_CONFIGURATION1);
DUMPREG(DSI_PLL_CONFIGURATION2);
- dss_clk_disable(DSS_CLK_ICK | DSS_CLK_FCK1);
+ dss_clk_disable(DSS_CLK_ICK | DSS_CLK_FCK);
#undef DUMPREG
}
@@ -3238,10 +3251,11 @@ void dsi_wait_dsi2_pll_active(void)
DSSERR("DSI2 PLL clock not active\n");
}
-int dsi_init(struct platform_device *pdev)
+static int dsi_init(struct platform_device *pdev)
{
u32 rev;
int r;
+ struct resource *dsi_mem;
spin_lock_init(&dsi.errors_lock);
dsi.errors = 0;
@@ -3268,14 +3282,20 @@ int dsi_init(struct platform_device *pdev)
dsi.te_timer.function = dsi_te_timeout;
dsi.te_timer.data = 0;
#endif
- dsi.base = ioremap(DSI_BASE, DSI_SZ_REGS);
+ dsi_mem = platform_get_resource(dsi.pdev, IORESOURCE_MEM, 0);
+ if (!dsi_mem) {
+ DSSERR("can't get IORESOURCE_MEM DSI\n");
+ r = -EINVAL;
+ goto err0;
+ }
+ dsi.base = ioremap(dsi_mem->start, resource_size(dsi_mem));
if (!dsi.base) {
DSSERR("can't ioremap DSI\n");
r = -ENOMEM;
goto err1;
}
- dsi.vdds_dsi_reg = dss_get_vdds_dsi();
+ dsi.vdds_dsi_reg = dsi_get_vdds_dsi();
if (IS_ERR(dsi.vdds_dsi_reg)) {
DSSERR("can't get VDDS_DSI regulator\n");
r = PTR_ERR(dsi.vdds_dsi_reg);
@@ -3285,7 +3305,7 @@ int dsi_init(struct platform_device *pdev)
enable_clocks(1);
rev = dsi_read_reg(DSI_REVISION);
- printk(KERN_INFO "OMAP DSI rev %d.%d\n",
+ dev_dbg(&pdev->dev, "OMAP DSI rev %d.%d\n",
FLD_GET(rev, 7, 4), FLD_GET(rev, 3, 0));
enable_clocks(0);
@@ -3295,11 +3315,17 @@ err2:
iounmap(dsi.base);
err1:
destroy_workqueue(dsi.workqueue);
+err0:
return r;
}
-void dsi_exit(void)
+static void dsi_exit(void)
{
+ if (dsi.vdds_dsi_reg != NULL) {
+ regulator_put(dsi.vdds_dsi_reg);
+ dsi.vdds_dsi_reg = NULL;
+ }
+
iounmap(dsi.base);
destroy_workqueue(dsi.workqueue);
@@ -3307,3 +3333,41 @@ void dsi_exit(void)
DSSDBG("omap_dsi_exit\n");
}
+/* DSI1 HW IP initialisation */
+static int omap_dsi1hw_probe(struct platform_device *pdev)
+{
+ int r;
+ dsi.pdev = pdev;
+ r = dsi_init(pdev);
+ if (r) {
+ DSSERR("Failed to initialize DSI\n");
+ goto err_dsi;
+ }
+err_dsi:
+ return r;
+}
+
+static int omap_dsi1hw_remove(struct platform_device *pdev)
+{
+ dsi_exit();
+ return 0;
+}
+
+static struct platform_driver omap_dsi1hw_driver = {
+ .probe = omap_dsi1hw_probe,
+ .remove = omap_dsi1hw_remove,
+ .driver = {
+ .name = "omap_dsi1",
+ .owner = THIS_MODULE,
+ },
+};
+
+int dsi_init_platform_driver(void)
+{
+ return platform_driver_register(&omap_dsi1hw_driver);
+}
+
+void dsi_uninit_platform_driver(void)
+{
+ return platform_driver_unregister(&omap_dsi1hw_driver);
+}
diff --git a/drivers/video/omap2/dss/dss.c b/drivers/video/omap2/dss/dss.c
index 77c3621c917..d76bc2678c5 100644
--- a/drivers/video/omap2/dss/dss.c
+++ b/drivers/video/omap2/dss/dss.c
@@ -31,9 +31,9 @@
#include <linux/clk.h>
#include <plat/display.h>
+#include <plat/clock.h>
#include "dss.h"
-
-#define DSS_BASE 0x48050000
+#include "dss_features.h"
#define DSS_SZ_REGS SZ_512
@@ -59,9 +59,19 @@ struct dss_reg {
dss_write_reg(idx, FLD_MOD(dss_read_reg(idx), val, start, end))
static struct {
+ struct platform_device *pdev;
void __iomem *base;
-
- struct clk *dpll4_m4_ck;
+ int ctx_id;
+ int irq;
+
+ /* Points to DPLL4_M4 in OMAP3xxx, and DPLL_PER_M5 in OMAP44xx */
+ struct clk *dpll_per_mx_ck;
+ struct clk *dss_ick;
+ struct clk *dss_fck;
+ struct clk *dss_sys_clk;
+ struct clk *dss_tv_fck;
+ struct clk *dss_video_fck;
+ unsigned num_clks_enabled;
unsigned long cache_req_pck;
unsigned long cache_prate;
@@ -74,6 +84,11 @@ static struct {
u32 ctx[DSS_SZ_REGS / sizeof(u32)];
} dss;
+static void dss_clk_enable_all_no_ctx(void);
+static void dss_clk_disable_all_no_ctx(void);
+static void dss_clk_enable_no_ctx(enum dss_clock clks);
+static void dss_clk_disable_no_ctx(enum dss_clock clks);
+
static int _omap_dss_wait_reset(void);
static inline void dss_write_reg(const struct dss_reg idx, u32 val)
@@ -211,37 +226,37 @@ void dss_sdi_disable(void)
void dss_dump_clocks(struct seq_file *s)
{
- unsigned long dpll4_ck_rate;
- unsigned long dpll4_m4_ck_rate;
+ unsigned long dpll_per_ck_rate;
+ unsigned long dpll_per_mx_ck_rate;
- dss_clk_enable(DSS_CLK_ICK | DSS_CLK_FCK1);
+ dss_clk_enable(DSS_CLK_ICK | DSS_CLK_FCK);
- dpll4_ck_rate = clk_get_rate(clk_get_parent(dss.dpll4_m4_ck));
- dpll4_m4_ck_rate = clk_get_rate(dss.dpll4_m4_ck);
+ dpll_per_ck_rate = clk_get_rate(clk_get_parent(dss.dpll_per_mx_ck));
+ dpll_per_mx_ck_rate = clk_get_rate(dss.dpll_per_mx_ck);
seq_printf(s, "- DSS -\n");
- seq_printf(s, "dpll4_ck %lu\n", dpll4_ck_rate);
+ seq_printf(s, "dpll_per_ck %lu\n", dpll_per_ck_rate);
if (cpu_is_omap3630())
seq_printf(s, "dss1_alwon_fclk = %lu / %lu = %lu\n",
- dpll4_ck_rate,
- dpll4_ck_rate / dpll4_m4_ck_rate,
- dss_clk_get_rate(DSS_CLK_FCK1));
+ dpll_per_ck_rate,
+ dpll_per_ck_rate / dpll_per_mx_ck_rate,
+ dss_clk_get_rate(DSS_CLK_FCK));
else
seq_printf(s, "dss1_alwon_fclk = %lu / %lu * 2 = %lu\n",
- dpll4_ck_rate,
- dpll4_ck_rate / dpll4_m4_ck_rate,
- dss_clk_get_rate(DSS_CLK_FCK1));
+ dpll_per_ck_rate,
+ dpll_per_ck_rate / dpll_per_mx_ck_rate,
+ dss_clk_get_rate(DSS_CLK_FCK));
- dss_clk_disable(DSS_CLK_ICK | DSS_CLK_FCK1);
+ dss_clk_disable(DSS_CLK_ICK | DSS_CLK_FCK);
}
void dss_dump_regs(struct seq_file *s)
{
#define DUMPREG(r) seq_printf(s, "%-35s %08x\n", #r, dss_read_reg(r))
- dss_clk_enable(DSS_CLK_ICK | DSS_CLK_FCK1);
+ dss_clk_enable(DSS_CLK_ICK | DSS_CLK_FCK);
DUMPREG(DSS_REVISION);
DUMPREG(DSS_SYSCONFIG);
@@ -252,7 +267,7 @@ void dss_dump_regs(struct seq_file *s)
DUMPREG(DSS_PLL_CONTROL);
DUMPREG(DSS_SDI_STATUS);
- dss_clk_disable(DSS_CLK_ICK | DSS_CLK_FCK1);
+ dss_clk_disable(DSS_CLK_ICK | DSS_CLK_FCK);
#undef DUMPREG
}
@@ -305,11 +320,12 @@ int dss_calc_clock_rates(struct dss_clock_info *cinfo)
{
unsigned long prate;
- if (cinfo->fck_div > (cpu_is_omap3630() ? 32 : 16) ||
- cinfo->fck_div == 0)
+ if (cinfo->fck_div >
+ (dss_has_feature(FEAT_DPLL_FCK_32_DIV) ? 32 : 16) ||
+ cinfo->fck_div == 0)
return -EINVAL;
- prate = clk_get_rate(clk_get_parent(dss.dpll4_m4_ck));
+ prate = clk_get_rate(clk_get_parent(dss.dpll_per_mx_ck));
cinfo->fck = prate / cinfo->fck_div;
@@ -321,11 +337,11 @@ int dss_set_clock_div(struct dss_clock_info *cinfo)
unsigned long prate;
int r;
- if (cpu_is_omap34xx()) {
- prate = clk_get_rate(clk_get_parent(dss.dpll4_m4_ck));
- DSSDBG("dpll4_m4 = %ld\n", prate);
+ if (dss_has_feature(FEAT_VAR_DPLL_FCK)) {
+ prate = clk_get_rate(clk_get_parent(dss.dpll_per_mx_ck));
+ DSSDBG("dpll_per_mx parent rate = %ld\n", prate);
- r = clk_set_rate(dss.dpll4_m4_ck, prate / cinfo->fck_div);
+ r = clk_set_rate(dss.dpll_per_mx_ck, prate / cinfo->fck_div);
if (r)
return r;
}
@@ -337,12 +353,12 @@ int dss_set_clock_div(struct dss_clock_info *cinfo)
int dss_get_clock_div(struct dss_clock_info *cinfo)
{
- cinfo->fck = dss_clk_get_rate(DSS_CLK_FCK1);
+ cinfo->fck = dss_clk_get_rate(DSS_CLK_FCK);
- if (cpu_is_omap34xx()) {
+ if (dss_has_feature(FEAT_VAR_DPLL_FCK)) {
unsigned long prate;
- prate = clk_get_rate(clk_get_parent(dss.dpll4_m4_ck));
- if (cpu_is_omap3630())
+ prate = clk_get_rate(clk_get_parent(dss.dpll_per_mx_ck));
+ if (dss_has_feature(FEAT_DPLL_FCK_32_DIV))
cinfo->fck_div = prate / (cinfo->fck);
else
cinfo->fck_div = prate / (cinfo->fck / 2);
@@ -353,10 +369,10 @@ int dss_get_clock_div(struct dss_clock_info *cinfo)
return 0;
}
-unsigned long dss_get_dpll4_rate(void)
+unsigned long dss_get_dpll_per_rate(void)
{
- if (cpu_is_omap34xx())
- return clk_get_rate(clk_get_parent(dss.dpll4_m4_ck));
+ if (dss_has_feature(FEAT_VAR_DPLL_FCK))
+ return clk_get_rate(clk_get_parent(dss.dpll_per_mx_ck));
else
return 0;
}
@@ -376,12 +392,13 @@ int dss_calc_clock_div(bool is_tft, unsigned long req_pck,
int match = 0;
int min_fck_per_pck;
- prate = dss_get_dpll4_rate();
+ prate = dss_get_dpll_per_rate();
- fck = dss_clk_get_rate(DSS_CLK_FCK1);
+ fck = dss_clk_get_rate(DSS_CLK_FCK);
if (req_pck == dss.cache_req_pck &&
- ((cpu_is_omap34xx() && prate == dss.cache_prate) ||
- dss.cache_dss_cinfo.fck == fck)) {
+ ((dss_has_feature(FEAT_VAR_DPLL_FCK) &&
+ prate == dss.cache_prate) ||
+ dss.cache_dss_cinfo.fck == fck)) {
DSSDBG("dispc clock info found from cache.\n");
*dss_cinfo = dss.cache_dss_cinfo;
*dispc_cinfo = dss.cache_dispc_cinfo;
@@ -402,10 +419,10 @@ retry:
memset(&best_dss, 0, sizeof(best_dss));
memset(&best_dispc, 0, sizeof(best_dispc));
- if (cpu_is_omap24xx()) {
+ if (!dss_has_feature(FEAT_VAR_DPLL_FCK)) {
struct dispc_clock_info cur_dispc;
/* XXX can we change the clock on omap2? */
- fck = dss_clk_get_rate(DSS_CLK_FCK1);
+ fck = dss_clk_get_rate(DSS_CLK_FCK);
fck_div = 1;
dispc_find_clk_divs(is_tft, req_pck, fck, &cur_dispc);
@@ -417,12 +434,13 @@ retry:
best_dispc = cur_dispc;
goto found;
- } else if (cpu_is_omap34xx()) {
- for (fck_div = (cpu_is_omap3630() ? 32 : 16);
- fck_div > 0; --fck_div) {
+ } else {
+ for (fck_div =
+ (dss_has_feature(FEAT_DPLL_FCK_32_DIV) ? 32 : 16);
+ fck_div > 0; --fck_div) {
struct dispc_clock_info cur_dispc;
- if (cpu_is_omap3630())
+ if (dss_has_feature(FEAT_DPLL_FCK_32_DIV))
fck = prate / fck_div;
else
fck = prate / fck_div * 2;
@@ -450,8 +468,6 @@ retry:
goto found;
}
}
- } else {
- BUG();
}
found:
@@ -482,28 +498,22 @@ found:
return 0;
}
-
-
-static irqreturn_t dss_irq_handler_omap2(int irq, void *arg)
-{
- dispc_irq_handler();
-
- return IRQ_HANDLED;
-}
-
-static irqreturn_t dss_irq_handler_omap3(int irq, void *arg)
+static irqreturn_t dss_irq_handler(int irq, void *arg)
{
- u32 irqstatus;
+ if (dss_has_feature(FEAT_COMMON_IRQ_DISPC_DSI)) {
+ u32 irqstatus;
- irqstatus = dss_read_reg(DSS_IRQSTATUS);
+ irqstatus = dss_read_reg(DSS_IRQSTATUS);
- if (irqstatus & (1<<0)) /* DISPC_IRQ */
- dispc_irq_handler();
+ if (irqstatus & (1<<0)) /* DISPC_IRQ */
+ dispc_irq_handler();
#ifdef CONFIG_OMAP2_DSS_DSI
- if (irqstatus & (1<<1)) /* DSI_IRQ */
- dsi_irq_handler();
+ if (irqstatus & (1<<1)) /* DSI_IRQ */
+ dsi_irq_handler();
#endif
-
+ } else {
+ dispc_irq_handler();
+ }
return IRQ_HANDLED;
}
@@ -549,12 +559,19 @@ void dss_set_dac_pwrdn_bgz(bool enable)
REG_FLD_MOD(DSS_CONTROL, enable, 5, 5); /* DAC Power-Down Control */
}
-int dss_init(bool skip_init)
+static int dss_init(bool skip_init)
{
int r;
u32 rev;
+ struct resource *dss_mem;
- dss.base = ioremap(DSS_BASE, DSS_SZ_REGS);
+ dss_mem = platform_get_resource(dss.pdev, IORESOURCE_MEM, 0);
+ if (!dss_mem) {
+ DSSERR("can't get IORESOURCE_MEM DSS\n");
+ r = -EINVAL;
+ goto fail0;
+ }
+ dss.base = ioremap(dss_mem->start, resource_size(dss_mem));
if (!dss.base) {
DSSERR("can't ioremap DSS\n");
r = -ENOMEM;
@@ -590,11 +607,14 @@ int dss_init(bool skip_init)
REG_FLD_MOD(DSS_CONTROL, 0, 2, 2); /* venc clock mode = normal */
#endif
- r = request_irq(INT_24XX_DSS_IRQ,
- cpu_is_omap24xx()
- ? dss_irq_handler_omap2
- : dss_irq_handler_omap3,
- 0, "OMAP DSS", NULL);
+ dss.irq = platform_get_irq(dss.pdev, 0);
+ if (dss.irq < 0) {
+ DSSERR("omap2 dss: platform_get_irq failed\n");
+ r = -ENODEV;
+ goto fail1;
+ }
+
+ r = request_irq(dss.irq, dss_irq_handler, 0, "OMAP DSS", NULL);
if (r < 0) {
DSSERR("omap2 dss: request_irq failed\n");
@@ -602,10 +622,17 @@ int dss_init(bool skip_init)
}
if (cpu_is_omap34xx()) {
- dss.dpll4_m4_ck = clk_get(NULL, "dpll4_m4_ck");
- if (IS_ERR(dss.dpll4_m4_ck)) {
+ dss.dpll_per_mx_ck = clk_get(NULL, "dpll4_m4_ck");
+ if (IS_ERR(dss.dpll_per_mx_ck)) {
DSSERR("Failed to get dpll4_m4_ck\n");
- r = PTR_ERR(dss.dpll4_m4_ck);
+ r = PTR_ERR(dss.dpll_per_mx_ck);
+ goto fail2;
+ }
+ } else if (cpu_is_omap44xx()) {
+ dss.dpll_per_mx_ck = clk_get(NULL, "dpll_per_m5x2_ck");
+ if (IS_ERR(dss.dpll_per_mx_ck)) {
+ DSSERR("Failed to get dpll_per_mx_ck\n");
+ r = PTR_ERR(dss.dpll_per_mx_ck);
goto fail2;
}
}
@@ -622,20 +649,389 @@ int dss_init(bool skip_init)
return 0;
fail2:
- free_irq(INT_24XX_DSS_IRQ, NULL);
+ free_irq(dss.irq, NULL);
fail1:
iounmap(dss.base);
fail0:
return r;
}
-void dss_exit(void)
+static void dss_exit(void)
{
- if (cpu_is_omap34xx())
- clk_put(dss.dpll4_m4_ck);
+ if (dss_has_feature(FEAT_VAR_DPLL_FCK))
+ clk_put(dss.dpll_per_mx_ck);
- free_irq(INT_24XX_DSS_IRQ, NULL);
+ free_irq(dss.irq, NULL);
iounmap(dss.base);
}
+/* CONTEXT */
+static int dss_get_ctx_id(void)
+{
+ struct omap_display_platform_data *pdata = dss.pdev->dev.platform_data;
+ int r;
+
+ if (!pdata->board_data->get_last_off_on_transaction_id)
+ return 0;
+ r = pdata->board_data->get_last_off_on_transaction_id(&dss.pdev->dev);
+ if (r < 0) {
+ dev_err(&dss.pdev->dev, "getting transaction ID failed, "
+ "will force context restore\n");
+ r = -1;
+ }
+ return r;
+}
+
+int dss_need_ctx_restore(void)
+{
+ int id = dss_get_ctx_id();
+
+ if (id < 0 || id != dss.ctx_id) {
+ DSSDBG("ctx id %d -> id %d\n",
+ dss.ctx_id, id);
+ dss.ctx_id = id;
+ return 1;
+ } else {
+ return 0;
+ }
+}
+
+static void save_all_ctx(void)
+{
+ DSSDBG("save context\n");
+
+ dss_clk_enable_no_ctx(DSS_CLK_ICK | DSS_CLK_FCK);
+
+ dss_save_context();
+ dispc_save_context();
+#ifdef CONFIG_OMAP2_DSS_DSI
+ dsi_save_context();
+#endif
+
+ dss_clk_disable_no_ctx(DSS_CLK_ICK | DSS_CLK_FCK);
+}
+
+static void restore_all_ctx(void)
+{
+ DSSDBG("restore context\n");
+
+ dss_clk_enable_all_no_ctx();
+
+ dss_restore_context();
+ dispc_restore_context();
+#ifdef CONFIG_OMAP2_DSS_DSI
+ dsi_restore_context();
+#endif
+
+ dss_clk_disable_all_no_ctx();
+}
+
+static int dss_get_clock(struct clk **clock, const char *clk_name)
+{
+ struct clk *clk;
+
+ clk = clk_get(&dss.pdev->dev, clk_name);
+
+ if (IS_ERR(clk)) {
+ DSSERR("can't get clock %s", clk_name);
+ return PTR_ERR(clk);
+ }
+
+ *clock = clk;
+
+ DSSDBG("clk %s, rate %ld\n", clk_name, clk_get_rate(clk));
+
+ return 0;
+}
+
+static int dss_get_clocks(void)
+{
+ int r;
+
+ dss.dss_ick = NULL;
+ dss.dss_fck = NULL;
+ dss.dss_sys_clk = NULL;
+ dss.dss_tv_fck = NULL;
+ dss.dss_video_fck = NULL;
+
+ r = dss_get_clock(&dss.dss_ick, "ick");
+ if (r)
+ goto err;
+
+ r = dss_get_clock(&dss.dss_fck, "fck");
+ if (r)
+ goto err;
+
+ r = dss_get_clock(&dss.dss_sys_clk, "sys_clk");
+ if (r)
+ goto err;
+
+ r = dss_get_clock(&dss.dss_tv_fck, "tv_clk");
+ if (r)
+ goto err;
+
+ r = dss_get_clock(&dss.dss_video_fck, "video_clk");
+ if (r)
+ goto err;
+
+ return 0;
+
+err:
+ if (dss.dss_ick)
+ clk_put(dss.dss_ick);
+ if (dss.dss_fck)
+ clk_put(dss.dss_fck);
+ if (dss.dss_sys_clk)
+ clk_put(dss.dss_sys_clk);
+ if (dss.dss_tv_fck)
+ clk_put(dss.dss_tv_fck);
+ if (dss.dss_video_fck)
+ clk_put(dss.dss_video_fck);
+
+ return r;
+}
+
+static void dss_put_clocks(void)
+{
+ if (dss.dss_video_fck)
+ clk_put(dss.dss_video_fck);
+ clk_put(dss.dss_tv_fck);
+ clk_put(dss.dss_fck);
+ clk_put(dss.dss_sys_clk);
+ clk_put(dss.dss_ick);
+}
+
+unsigned long dss_clk_get_rate(enum dss_clock clk)
+{
+ switch (clk) {
+ case DSS_CLK_ICK:
+ return clk_get_rate(dss.dss_ick);
+ case DSS_CLK_FCK:
+ return clk_get_rate(dss.dss_fck);
+ case DSS_CLK_SYSCK:
+ return clk_get_rate(dss.dss_sys_clk);
+ case DSS_CLK_TVFCK:
+ return clk_get_rate(dss.dss_tv_fck);
+ case DSS_CLK_VIDFCK:
+ return clk_get_rate(dss.dss_video_fck);
+ }
+
+ BUG();
+ return 0;
+}
+
+static unsigned count_clk_bits(enum dss_clock clks)
+{
+ unsigned num_clks = 0;
+
+ if (clks & DSS_CLK_ICK)
+ ++num_clks;
+ if (clks & DSS_CLK_FCK)
+ ++num_clks;
+ if (clks & DSS_CLK_SYSCK)
+ ++num_clks;
+ if (clks & DSS_CLK_TVFCK)
+ ++num_clks;
+ if (clks & DSS_CLK_VIDFCK)
+ ++num_clks;
+
+ return num_clks;
+}
+
+static void dss_clk_enable_no_ctx(enum dss_clock clks)
+{
+ unsigned num_clks = count_clk_bits(clks);
+
+ if (clks & DSS_CLK_ICK)
+ clk_enable(dss.dss_ick);
+ if (clks & DSS_CLK_FCK)
+ clk_enable(dss.dss_fck);
+ if (clks & DSS_CLK_SYSCK)
+ clk_enable(dss.dss_sys_clk);
+ if (clks & DSS_CLK_TVFCK)
+ clk_enable(dss.dss_tv_fck);
+ if (clks & DSS_CLK_VIDFCK)
+ clk_enable(dss.dss_video_fck);
+
+ dss.num_clks_enabled += num_clks;
+}
+
+void dss_clk_enable(enum dss_clock clks)
+{
+ bool check_ctx = dss.num_clks_enabled == 0;
+
+ dss_clk_enable_no_ctx(clks);
+
+ if (check_ctx && cpu_is_omap34xx() && dss_need_ctx_restore())
+ restore_all_ctx();
+}
+
+static void dss_clk_disable_no_ctx(enum dss_clock clks)
+{
+ unsigned num_clks = count_clk_bits(clks);
+
+ if (clks & DSS_CLK_ICK)
+ clk_disable(dss.dss_ick);
+ if (clks & DSS_CLK_FCK)
+ clk_disable(dss.dss_fck);
+ if (clks & DSS_CLK_SYSCK)
+ clk_disable(dss.dss_sys_clk);
+ if (clks & DSS_CLK_TVFCK)
+ clk_disable(dss.dss_tv_fck);
+ if (clks & DSS_CLK_VIDFCK)
+ clk_disable(dss.dss_video_fck);
+
+ dss.num_clks_enabled -= num_clks;
+}
+
+void dss_clk_disable(enum dss_clock clks)
+{
+ if (cpu_is_omap34xx()) {
+ unsigned num_clks = count_clk_bits(clks);
+
+ BUG_ON(dss.num_clks_enabled < num_clks);
+
+ if (dss.num_clks_enabled == num_clks)
+ save_all_ctx();
+ }
+
+ dss_clk_disable_no_ctx(clks);
+}
+
+static void dss_clk_enable_all_no_ctx(void)
+{
+ enum dss_clock clks;
+
+ clks = DSS_CLK_ICK | DSS_CLK_FCK | DSS_CLK_SYSCK | DSS_CLK_TVFCK;
+ if (cpu_is_omap34xx())
+ clks |= DSS_CLK_VIDFCK;
+ dss_clk_enable_no_ctx(clks);
+}
+
+static void dss_clk_disable_all_no_ctx(void)
+{
+ enum dss_clock clks;
+
+ clks = DSS_CLK_ICK | DSS_CLK_FCK | DSS_CLK_SYSCK | DSS_CLK_TVFCK;
+ if (cpu_is_omap34xx())
+ clks |= DSS_CLK_VIDFCK;
+ dss_clk_disable_no_ctx(clks);
+}
+
+#if defined(CONFIG_DEBUG_FS) && defined(CONFIG_OMAP2_DSS_DEBUG_SUPPORT)
+/* CLOCKS */
+static void core_dump_clocks(struct seq_file *s)
+{
+ int i;
+ struct clk *clocks[5] = {
+ dss.dss_ick,
+ dss.dss_fck,
+ dss.dss_sys_clk,
+ dss.dss_tv_fck,
+ dss.dss_video_fck
+ };
+
+ seq_printf(s, "- CORE -\n");
+
+ seq_printf(s, "internal clk count\t\t%u\n", dss.num_clks_enabled);
+
+ for (i = 0; i < 5; i++) {
+ if (!clocks[i])
+ continue;
+ seq_printf(s, "%-15s\t%lu\t%d\n",
+ clocks[i]->name,
+ clk_get_rate(clocks[i]),
+ clocks[i]->usecount);
+ }
+}
+#endif /* defined(CONFIG_DEBUG_FS) && defined(CONFIG_OMAP2_DSS_DEBUG_SUPPORT) */
+
+/* DEBUGFS */
+#if defined(CONFIG_DEBUG_FS) && defined(CONFIG_OMAP2_DSS_DEBUG_SUPPORT)
+void dss_debug_dump_clocks(struct seq_file *s)
+{
+ core_dump_clocks(s);
+ dss_dump_clocks(s);
+ dispc_dump_clocks(s);
+#ifdef CONFIG_OMAP2_DSS_DSI
+ dsi_dump_clocks(s);
+#endif
+}
+#endif
+
+
+/* DSS HW IP initialisation */
+static int omap_dsshw_probe(struct platform_device *pdev)
+{
+ int r;
+ int skip_init = 0;
+
+ dss.pdev = pdev;
+
+ r = dss_get_clocks();
+ if (r)
+ goto err_clocks;
+
+ dss_clk_enable_all_no_ctx();
+
+ dss.ctx_id = dss_get_ctx_id();
+ DSSDBG("initial ctx id %u\n", dss.ctx_id);
+
+#ifdef CONFIG_FB_OMAP_BOOTLOADER_INIT
+ /* DISPC_CONTROL */
+ if (omap_readl(0x48050440) & 1) /* LCD enabled? */
+ skip_init = 1;
+#endif
+
+ r = dss_init(skip_init);
+ if (r) {
+ DSSERR("Failed to initialize DSS\n");
+ goto err_dss;
+ }
+
+ dss_clk_disable_all_no_ctx();
+ return 0;
+
+err_dss:
+ dss_clk_disable_all_no_ctx();
+ dss_put_clocks();
+err_clocks:
+ return r;
+}
+
+static int omap_dsshw_remove(struct platform_device *pdev)
+{
+
+ dss_exit();
+
+ /*
+ * As part of hwmod changes, DSS is not the only controller of dss
+ * clocks; hwmod framework itself will also enable clocks during hwmod
+ * init for dss, and autoidle is set in h/w for DSS. Hence, there's no
+ * need to disable clocks if their usecounts > 1.
+ */
+ WARN_ON(dss.num_clks_enabled > 0);
+
+ dss_put_clocks();
+ return 0;
+}
+
+static struct platform_driver omap_dsshw_driver = {
+ .probe = omap_dsshw_probe,
+ .remove = omap_dsshw_remove,
+ .driver = {
+ .name = "omap_dss",
+ .owner = THIS_MODULE,
+ },
+};
+
+int dss_init_platform_driver(void)
+{
+ return platform_driver_register(&omap_dsshw_driver);
+}
+
+void dss_uninit_platform_driver(void)
+{
+ return platform_driver_unregister(&omap_dsshw_driver);
+}
diff --git a/drivers/video/omap2/dss/dss.h b/drivers/video/omap2/dss/dss.h
index b394951120a..4b02e079f20 100644
--- a/drivers/video/omap2/dss/dss.h
+++ b/drivers/video/omap2/dss/dss.h
@@ -112,11 +112,11 @@ enum omap_parallel_interface_mode {
};
enum dss_clock {
- DSS_CLK_ICK = 1 << 0,
- DSS_CLK_FCK1 = 1 << 1,
- DSS_CLK_FCK2 = 1 << 2,
- DSS_CLK_54M = 1 << 3,
- DSS_CLK_96M = 1 << 4,
+ DSS_CLK_ICK = 1 << 0, /* DSS_L3_ICLK and DSS_L4_ICLK */
+ DSS_CLK_FCK = 1 << 1, /* DSS1_ALWON_FCLK */
+ DSS_CLK_SYSCK = 1 << 2, /* DSS2_ALWON_FCLK */
+ DSS_CLK_TVFCK = 1 << 3, /* DSS_TV_FCLK */
+ DSS_CLK_VIDFCK = 1 << 4, /* DSS_96M_FCLK*/
};
enum dss_clk_source {
@@ -169,15 +169,9 @@ struct seq_file;
struct platform_device;
/* core */
-void dss_clk_enable(enum dss_clock clks);
-void dss_clk_disable(enum dss_clock clks);
-unsigned long dss_clk_get_rate(enum dss_clock clk);
-int dss_need_ctx_restore(void);
-void dss_dump_clocks(struct seq_file *s);
struct bus_type *dss_get_bus(void);
struct regulator *dss_get_vdds_dsi(void);
struct regulator *dss_get_vdds_sdi(void);
-struct regulator *dss_get_vdda_dac(void);
/* display */
int dss_suspend_all_devices(void);
@@ -214,13 +208,21 @@ void dss_overlay_setup_l4_manager(struct omap_overlay_manager *mgr);
void dss_recheck_connections(struct omap_dss_device *dssdev, bool force);
/* DSS */
-int dss_init(bool skip_init);
-void dss_exit(void);
+int dss_init_platform_driver(void);
+void dss_uninit_platform_driver(void);
void dss_save_context(void);
void dss_restore_context(void);
+void dss_clk_enable(enum dss_clock clks);
+void dss_clk_disable(enum dss_clock clks);
+unsigned long dss_clk_get_rate(enum dss_clock clk);
+int dss_need_ctx_restore(void);
+void dss_dump_clocks(struct seq_file *s);
void dss_dump_regs(struct seq_file *s);
+#if defined(CONFIG_DEBUG_FS) && defined(CONFIG_OMAP2_DSS_DEBUG_SUPPORT)
+void dss_debug_dump_clocks(struct seq_file *s);
+#endif
void dss_sdi_init(u8 datapairs);
int dss_sdi_enable(void);
@@ -259,8 +261,8 @@ static inline void sdi_exit(void)
/* DSI */
#ifdef CONFIG_OMAP2_DSS_DSI
-int dsi_init(struct platform_device *pdev);
-void dsi_exit(void);
+int dsi_init_platform_driver(void);
+void dsi_uninit_platform_driver(void);
void dsi_dump_clocks(struct seq_file *s);
void dsi_dump_irqs(struct seq_file *s);
@@ -285,11 +287,11 @@ void dsi_get_overlay_fifo_thresholds(enum omap_plane plane,
void dsi_wait_dsi1_pll_active(void);
void dsi_wait_dsi2_pll_active(void);
#else
-static inline int dsi_init(struct platform_device *pdev)
+static inline int dsi_init_platform_driver(void)
{
return 0;
}
-static inline void dsi_exit(void)
+static inline void dsi_uninit_platform_driver(void)
{
}
static inline void dsi_wait_dsi1_pll_active(void)
@@ -316,8 +318,8 @@ static inline void dpi_exit(void)
#endif
/* DISPC */
-int dispc_init(void);
-void dispc_exit(void);
+int dispc_init_platform_driver(void);
+void dispc_uninit_platform_driver(void);
void dispc_dump_clocks(struct seq_file *s);
void dispc_dump_irqs(struct seq_file *s);
void dispc_dump_regs(struct seq_file *s);
@@ -409,24 +411,24 @@ int dispc_get_clock_div(enum omap_channel channel,
/* VENC */
#ifdef CONFIG_OMAP2_DSS_VENC
-int venc_init(struct platform_device *pdev);
-void venc_exit(void);
+int venc_init_platform_driver(void);
+void venc_uninit_platform_driver(void);
void venc_dump_regs(struct seq_file *s);
int venc_init_display(struct omap_dss_device *display);
#else
-static inline int venc_init(struct platform_device *pdev)
+static inline int venc_init_platform_driver(void)
{
return 0;
}
-static inline void venc_exit(void)
+static inline void venc_uninit_platform_driver(void)
{
}
#endif
/* RFBI */
#ifdef CONFIG_OMAP2_DSS_RFBI
-int rfbi_init(void);
-void rfbi_exit(void);
+int rfbi_init_platform_driver(void);
+void rfbi_uninit_platform_driver(void);
void rfbi_dump_regs(struct seq_file *s);
int rfbi_configure(int rfbi_module, int bpp, int lines);
@@ -437,11 +439,11 @@ void rfbi_set_timings(int rfbi_module, struct rfbi_timings *t);
unsigned long rfbi_get_max_tx_rate(void);
int rfbi_init_display(struct omap_dss_device *display);
#else
-static inline int rfbi_init(void)
+static inline int rfbi_init_platform_driver(void)
{
return 0;
}
-static inline void rfbi_exit(void)
+static inline void rfbi_uninit_platform_driver(void)
{
}
#endif
diff --git a/drivers/video/omap2/dss/dss_features.c b/drivers/video/omap2/dss/dss_features.c
index cf3ef696e14..39864f6bb46 100644
--- a/drivers/video/omap2/dss/dss_features.c
+++ b/drivers/video/omap2/dss/dss_features.c
@@ -157,7 +157,8 @@ static struct omap_dss_features omap3430_dss_features = {
.has_feature =
FEAT_GLOBAL_ALPHA | FEAT_LCDENABLEPOL |
FEAT_LCDENABLESIGNAL | FEAT_PCKFREEENABLE |
- FEAT_FUNCGATED,
+ FEAT_FUNCGATED | FEAT_COMMON_IRQ_DISPC_DSI |
+ FEAT_VAR_DPLL_FCK,
.num_mgrs = 2,
.num_ovls = 3,
@@ -172,7 +173,9 @@ static struct omap_dss_features omap3630_dss_features = {
.has_feature =
FEAT_GLOBAL_ALPHA | FEAT_LCDENABLEPOL |
FEAT_LCDENABLESIGNAL | FEAT_PCKFREEENABLE |
- FEAT_PRE_MULT_ALPHA | FEAT_FUNCGATED,
+ FEAT_PRE_MULT_ALPHA | FEAT_FUNCGATED |
+ FEAT_COMMON_IRQ_DISPC_DSI | FEAT_VAR_DPLL_FCK |
+ FEAT_DPLL_FCK_32_DIV,
.num_mgrs = 2,
.num_ovls = 3,
@@ -187,7 +190,8 @@ static struct omap_dss_features omap4_dss_features = {
.has_feature =
FEAT_GLOBAL_ALPHA | FEAT_PRE_MULT_ALPHA |
- FEAT_MGR_LCD2,
+ FEAT_MGR_LCD2 | FEAT_VAR_DPLL_FCK |
+ FEAT_DPLL_FCK_32_DIV | FEAT_CORE_CLK_DIV,
.num_mgrs = 3,
.num_ovls = 3,
diff --git a/drivers/video/omap2/dss/dss_features.h b/drivers/video/omap2/dss/dss_features.h
index b9c70be9258..ed5c880a276 100644
--- a/drivers/video/omap2/dss/dss_features.h
+++ b/drivers/video/omap2/dss/dss_features.h
@@ -25,14 +25,20 @@
/* DSS has feature id */
enum dss_feat_id {
- FEAT_GLOBAL_ALPHA = 1 << 0,
- FEAT_GLOBAL_ALPHA_VID1 = 1 << 1,
- FEAT_PRE_MULT_ALPHA = 1 << 2,
- FEAT_LCDENABLEPOL = 1 << 3,
- FEAT_LCDENABLESIGNAL = 1 << 4,
- FEAT_PCKFREEENABLE = 1 << 5,
- FEAT_FUNCGATED = 1 << 6,
- FEAT_MGR_LCD2 = 1 << 7,
+ FEAT_GLOBAL_ALPHA = 1 << 0,
+ FEAT_GLOBAL_ALPHA_VID1 = 1 << 1,
+ FEAT_PRE_MULT_ALPHA = 1 << 2,
+ FEAT_LCDENABLEPOL = 1 << 3,
+ FEAT_LCDENABLESIGNAL = 1 << 4,
+ FEAT_PCKFREEENABLE = 1 << 5,
+ FEAT_FUNCGATED = 1 << 6,
+ FEAT_MGR_LCD2 = 1 << 7,
+ FEAT_COMMON_IRQ_DISPC_DSI = 1 << 8,
+ FEAT_VAR_DPLL_FCK = 1 << 9, /* Variable DPLL Func CLK */
+ /* DPLL FCLK has max divider value 32 */
+ FEAT_DPLL_FCK_32_DIV = 1 << 10,
+ /* Independent core clk divider */
+ FEAT_CORE_CLK_DIV = 1 << 11,
};
/* DSS register field id */
diff --git a/drivers/video/omap2/dss/manager.c b/drivers/video/omap2/dss/manager.c
index 172d4e69730..1f53bf20b6c 100644
--- a/drivers/video/omap2/dss/manager.c
+++ b/drivers/video/omap2/dss/manager.c
@@ -1394,7 +1394,7 @@ static int omap_dss_mgr_apply(struct omap_overlay_manager *mgr)
}
r = 0;
- dss_clk_enable(DSS_CLK_ICK | DSS_CLK_FCK1);
+ dss_clk_enable(DSS_CLK_ICK | DSS_CLK_FCK);
if (!dss_cache.irq_enabled) {
u32 mask;
@@ -1407,7 +1407,7 @@ static int omap_dss_mgr_apply(struct omap_overlay_manager *mgr)
dss_cache.irq_enabled = true;
}
configure_dispc();
- dss_clk_disable(DSS_CLK_ICK | DSS_CLK_FCK1);
+ dss_clk_disable(DSS_CLK_ICK | DSS_CLK_FCK);
spin_unlock_irqrestore(&dss_cache.lock, flags);
diff --git a/drivers/video/omap2/dss/overlay.c b/drivers/video/omap2/dss/overlay.c
index 456efef03c2..996e9a4f677 100644
--- a/drivers/video/omap2/dss/overlay.c
+++ b/drivers/video/omap2/dss/overlay.c
@@ -490,7 +490,7 @@ static int omap_dss_set_manager(struct omap_overlay *ovl,
ovl->manager = mgr;
- dss_clk_enable(DSS_CLK_ICK | DSS_CLK_FCK1);
+ dss_clk_enable(DSS_CLK_ICK | DSS_CLK_FCK);
/* XXX: on manual update display, in auto update mode, a bug happens
* here. When an overlay is first enabled on LCD, then it's disabled,
* and the manager is changed to TV, we sometimes get SYNC_LOST_DIGIT
@@ -499,7 +499,7 @@ static int omap_dss_set_manager(struct omap_overlay *ovl,
* but I don't understand how or why. */
msleep(40);
dispc_set_channel_out(ovl->id, mgr->id);
- dss_clk_disable(DSS_CLK_ICK | DSS_CLK_FCK1);
+ dss_clk_disable(DSS_CLK_ICK | DSS_CLK_FCK);
return 0;
}
diff --git a/drivers/video/omap2/dss/rfbi.c b/drivers/video/omap2/dss/rfbi.c
index 10a2ffe0288..9e0f196a983 100644
--- a/drivers/video/omap2/dss/rfbi.c
+++ b/drivers/video/omap2/dss/rfbi.c
@@ -36,8 +36,6 @@
#include <plat/display.h>
#include "dss.h"
-#define RFBI_BASE 0x48050800
-
struct rfbi_reg { u16 idx; };
#define RFBI_REG(idx) ((const struct rfbi_reg) { idx })
@@ -100,6 +98,7 @@ static int rfbi_convert_timings(struct rfbi_timings *t);
static void rfbi_get_clk_info(u32 *clk_period, u32 *max_clk_div);
static struct {
+ struct platform_device *pdev;
void __iomem *base;
unsigned long l4_khz;
@@ -142,9 +141,9 @@ static inline u32 rfbi_read_reg(const struct rfbi_reg idx)
static void rfbi_enable_clocks(bool enable)
{
if (enable)
- dss_clk_enable(DSS_CLK_ICK | DSS_CLK_FCK1);
+ dss_clk_enable(DSS_CLK_ICK | DSS_CLK_FCK);
else
- dss_clk_disable(DSS_CLK_ICK | DSS_CLK_FCK1);
+ dss_clk_disable(DSS_CLK_ICK | DSS_CLK_FCK);
}
void omap_rfbi_write_command(const void *buf, u32 len)
@@ -497,7 +496,7 @@ unsigned long rfbi_get_max_tx_rate(void)
};
l4_rate = rfbi.l4_khz / 1000;
- dss1_rate = dss_clk_get_rate(DSS_CLK_FCK1) / 1000000;
+ dss1_rate = dss_clk_get_rate(DSS_CLK_FCK) / 1000000;
for (i = 0; i < ARRAY_SIZE(ftab); i++) {
/* Use a window instead of an exact match, to account
@@ -922,7 +921,7 @@ void rfbi_dump_regs(struct seq_file *s)
{
#define DUMPREG(r) seq_printf(s, "%-35s %08x\n", #r, rfbi_read_reg(r))
- dss_clk_enable(DSS_CLK_ICK | DSS_CLK_FCK1);
+ dss_clk_enable(DSS_CLK_ICK | DSS_CLK_FCK);
DUMPREG(RFBI_REVISION);
DUMPREG(RFBI_SYSCONFIG);
@@ -953,54 +952,10 @@ void rfbi_dump_regs(struct seq_file *s)
DUMPREG(RFBI_VSYNC_WIDTH);
DUMPREG(RFBI_HSYNC_WIDTH);
- dss_clk_disable(DSS_CLK_ICK | DSS_CLK_FCK1);
+ dss_clk_disable(DSS_CLK_ICK | DSS_CLK_FCK);
#undef DUMPREG
}
-int rfbi_init(void)
-{
- u32 rev;
- u32 l;
-
- spin_lock_init(&rfbi.cmd_lock);
-
- init_completion(&rfbi.cmd_done);
- atomic_set(&rfbi.cmd_fifo_full, 0);
- atomic_set(&rfbi.cmd_pending, 0);
-
- rfbi.base = ioremap(RFBI_BASE, SZ_256);
- if (!rfbi.base) {
- DSSERR("can't ioremap RFBI\n");
- return -ENOMEM;
- }
-
- rfbi_enable_clocks(1);
-
- msleep(10);
-
- rfbi.l4_khz = dss_clk_get_rate(DSS_CLK_ICK) / 1000;
-
- /* Enable autoidle and smart-idle */
- l = rfbi_read_reg(RFBI_SYSCONFIG);
- l |= (1 << 0) | (2 << 3);
- rfbi_write_reg(RFBI_SYSCONFIG, l);
-
- rev = rfbi_read_reg(RFBI_REVISION);
- printk(KERN_INFO "OMAP RFBI rev %d.%d\n",
- FLD_GET(rev, 7, 4), FLD_GET(rev, 3, 0));
-
- rfbi_enable_clocks(0);
-
- return 0;
-}
-
-void rfbi_exit(void)
-{
- DSSDBG("rfbi_exit\n");
-
- iounmap(rfbi.base);
-}
-
int omapdss_rfbi_display_enable(struct omap_dss_device *dssdev)
{
int r;
@@ -1056,3 +1011,74 @@ int rfbi_init_display(struct omap_dss_device *dssdev)
dssdev->caps = OMAP_DSS_DISPLAY_CAP_MANUAL_UPDATE;
return 0;
}
+
+/* RFBI HW IP initialisation */
+static int omap_rfbihw_probe(struct platform_device *pdev)
+{
+ u32 rev;
+ u32 l;
+ struct resource *rfbi_mem;
+
+ rfbi.pdev = pdev;
+
+ spin_lock_init(&rfbi.cmd_lock);
+
+ init_completion(&rfbi.cmd_done);
+ atomic_set(&rfbi.cmd_fifo_full, 0);
+ atomic_set(&rfbi.cmd_pending, 0);
+
+ rfbi_mem = platform_get_resource(rfbi.pdev, IORESOURCE_MEM, 0);
+ if (!rfbi_mem) {
+ DSSERR("can't get IORESOURCE_MEM RFBI\n");
+ return -EINVAL;
+ }
+ rfbi.base = ioremap(rfbi_mem->start, resource_size(rfbi_mem));
+ if (!rfbi.base) {
+ DSSERR("can't ioremap RFBI\n");
+ return -ENOMEM;
+ }
+
+ rfbi_enable_clocks(1);
+
+ msleep(10);
+
+ rfbi.l4_khz = dss_clk_get_rate(DSS_CLK_ICK) / 1000;
+
+ /* Enable autoidle and smart-idle */
+ l = rfbi_read_reg(RFBI_SYSCONFIG);
+ l |= (1 << 0) | (2 << 3);
+ rfbi_write_reg(RFBI_SYSCONFIG, l);
+
+ rev = rfbi_read_reg(RFBI_REVISION);
+ dev_dbg(&pdev->dev, "OMAP RFBI rev %d.%d\n",
+ FLD_GET(rev, 7, 4), FLD_GET(rev, 3, 0));
+
+ rfbi_enable_clocks(0);
+
+ return 0;
+}
+
+static int omap_rfbihw_remove(struct platform_device *pdev)
+{
+ iounmap(rfbi.base);
+ return 0;
+}
+
+static struct platform_driver omap_rfbihw_driver = {
+ .probe = omap_rfbihw_probe,
+ .remove = omap_rfbihw_remove,
+ .driver = {
+ .name = "omap_rfbi",
+ .owner = THIS_MODULE,
+ },
+};
+
+int rfbi_init_platform_driver(void)
+{
+ return platform_driver_register(&omap_rfbihw_driver);
+}
+
+void rfbi_uninit_platform_driver(void)
+{
+ return platform_driver_unregister(&omap_rfbihw_driver);
+}
diff --git a/drivers/video/omap2/dss/sdi.c b/drivers/video/omap2/dss/sdi.c
index b64adf7dfc8..8272fc1f327 100644
--- a/drivers/video/omap2/dss/sdi.c
+++ b/drivers/video/omap2/dss/sdi.c
@@ -70,7 +70,7 @@ int omapdss_sdi_display_enable(struct omap_dss_device *dssdev)
/* In case of skip_init sdi_init has already enabled the clocks */
if (!sdi.skip_init)
- dss_clk_enable(DSS_CLK_ICK | DSS_CLK_FCK1);
+ dss_clk_enable(DSS_CLK_ICK | DSS_CLK_FCK);
sdi_basic_init(dssdev);
@@ -130,7 +130,7 @@ int omapdss_sdi_display_enable(struct omap_dss_device *dssdev)
return 0;
err2:
- dss_clk_disable(DSS_CLK_ICK | DSS_CLK_FCK1);
+ dss_clk_disable(DSS_CLK_ICK | DSS_CLK_FCK);
regulator_disable(sdi.vdds_sdi_reg);
err1:
omap_dss_stop_device(dssdev);
@@ -145,7 +145,7 @@ void omapdss_sdi_display_disable(struct omap_dss_device *dssdev)
dss_sdi_disable();
- dss_clk_disable(DSS_CLK_ICK | DSS_CLK_FCK1);
+ dss_clk_disable(DSS_CLK_ICK | DSS_CLK_FCK);
regulator_disable(sdi.vdds_sdi_reg);
@@ -175,7 +175,7 @@ int sdi_init(bool skip_init)
* of them until sdi_display_enable is called.
*/
if (skip_init)
- dss_clk_enable(DSS_CLK_ICK | DSS_CLK_FCK1);
+ dss_clk_enable(DSS_CLK_ICK | DSS_CLK_FCK);
return 0;
}
diff --git a/drivers/video/omap2/dss/venc.c b/drivers/video/omap2/dss/venc.c
index eff35050e28..2adae129f4d 100644
--- a/drivers/video/omap2/dss/venc.c
+++ b/drivers/video/omap2/dss/venc.c
@@ -39,8 +39,6 @@
#include "dss.h"
-#define VENC_BASE 0x48050C00
-
/* Venc registers */
#define VENC_REV_ID 0x00
#define VENC_STATUS 0x04
@@ -289,6 +287,7 @@ const struct omap_video_timings omap_dss_ntsc_timings = {
EXPORT_SYMBOL(omap_dss_ntsc_timings);
static struct {
+ struct platform_device *pdev;
void __iomem *base;
struct mutex venc_lock;
u32 wss_data;
@@ -306,6 +305,17 @@ static inline u32 venc_read_reg(int idx)
return l;
}
+static struct regulator *venc_get_vdda_dac(void)
+{
+ struct regulator *reg;
+
+ reg = regulator_get(&venc.pdev->dev, "vdda_dac");
+ if (!IS_ERR(reg))
+ venc.vdda_dac_reg = reg;
+
+ return reg;
+}
+
static void venc_write_config(const struct venc_config *config)
{
DSSDBG("write venc conf\n");
@@ -381,11 +391,11 @@ static void venc_reset(void)
static void venc_enable_clocks(int enable)
{
if (enable)
- dss_clk_enable(DSS_CLK_ICK | DSS_CLK_FCK1 | DSS_CLK_54M |
- DSS_CLK_96M);
+ dss_clk_enable(DSS_CLK_ICK | DSS_CLK_FCK | DSS_CLK_TVFCK |
+ DSS_CLK_VIDFCK);
else
- dss_clk_disable(DSS_CLK_ICK | DSS_CLK_FCK1 | DSS_CLK_54M |
- DSS_CLK_96M);
+ dss_clk_disable(DSS_CLK_ICK | DSS_CLK_FCK | DSS_CLK_TVFCK |
+ DSS_CLK_VIDFCK);
}
static const struct venc_config *venc_timings_to_config(
@@ -641,46 +651,6 @@ static struct omap_dss_driver venc_driver = {
};
/* driver end */
-
-
-int venc_init(struct platform_device *pdev)
-{
- u8 rev_id;
-
- mutex_init(&venc.venc_lock);
-
- venc.wss_data = 0;
-
- venc.base = ioremap(VENC_BASE, SZ_1K);
- if (!venc.base) {
- DSSERR("can't ioremap VENC\n");
- return -ENOMEM;
- }
-
- venc.vdda_dac_reg = dss_get_vdda_dac();
- if (IS_ERR(venc.vdda_dac_reg)) {
- iounmap(venc.base);
- DSSERR("can't get VDDA_DAC regulator\n");
- return PTR_ERR(venc.vdda_dac_reg);
- }
-
- venc_enable_clocks(1);
-
- rev_id = (u8)(venc_read_reg(VENC_REV_ID) & 0xff);
- printk(KERN_INFO "OMAP VENC rev %d\n", rev_id);
-
- venc_enable_clocks(0);
-
- return omap_dss_register_driver(&venc_driver);
-}
-
-void venc_exit(void)
-{
- omap_dss_unregister_driver(&venc_driver);
-
- iounmap(venc.base);
-}
-
int venc_init_display(struct omap_dss_device *dssdev)
{
DSSDBG("init_display\n");
@@ -740,3 +710,74 @@ void venc_dump_regs(struct seq_file *s)
#undef DUMPREG
}
+
+/* VENC HW IP initialisation */
+static int omap_venchw_probe(struct platform_device *pdev)
+{
+ u8 rev_id;
+ struct resource *venc_mem;
+
+ venc.pdev = pdev;
+
+ mutex_init(&venc.venc_lock);
+
+ venc.wss_data = 0;
+
+ venc_mem = platform_get_resource(venc.pdev, IORESOURCE_MEM, 0);
+ if (!venc_mem) {
+ DSSERR("can't get IORESOURCE_MEM VENC\n");
+ return -EINVAL;
+ }
+ venc.base = ioremap(venc_mem->start, resource_size(venc_mem));
+ if (!venc.base) {
+ DSSERR("can't ioremap VENC\n");
+ return -ENOMEM;
+ }
+
+ venc.vdda_dac_reg = venc_get_vdda_dac();
+ if (IS_ERR(venc.vdda_dac_reg)) {
+ iounmap(venc.base);
+ DSSERR("can't get VDDA_DAC regulator\n");
+ return PTR_ERR(venc.vdda_dac_reg);
+ }
+
+ venc_enable_clocks(1);
+
+ rev_id = (u8)(venc_read_reg(VENC_REV_ID) & 0xff);
+ dev_dbg(&pdev->dev, "OMAP VENC rev %d\n", rev_id);
+
+ venc_enable_clocks(0);
+
+ return omap_dss_register_driver(&venc_driver);
+}
+
+static int omap_venchw_remove(struct platform_device *pdev)
+{
+ if (venc.vdda_dac_reg != NULL) {
+ regulator_put(venc.vdda_dac_reg);
+ venc.vdda_dac_reg = NULL;
+ }
+ omap_dss_unregister_driver(&venc_driver);
+
+ iounmap(venc.base);
+ return 0;
+}
+
+static struct platform_driver omap_venchw_driver = {
+ .probe = omap_venchw_probe,
+ .remove = omap_venchw_remove,
+ .driver = {
+ .name = "omap_venc",
+ .owner = THIS_MODULE,
+ },
+};
+
+int venc_init_platform_driver(void)
+{
+ return platform_driver_register(&omap_venchw_driver);
+}
+
+void venc_uninit_platform_driver(void)
+{
+ return platform_driver_unregister(&omap_venchw_driver);
+}
diff --git a/drivers/video/omap2/omapfb/Kconfig b/drivers/video/omap2/omapfb/Kconfig
index 65149b22cf3..1da712e9e71 100644
--- a/drivers/video/omap2/omapfb/Kconfig
+++ b/drivers/video/omap2/omapfb/Kconfig
@@ -1,5 +1,5 @@
menuconfig FB_OMAP2
- tristate "OMAP2/3 frame buffer support (EXPERIMENTAL)"
+ tristate "OMAP2+ frame buffer support (EXPERIMENTAL)"
depends on FB && OMAP2_DSS
select OMAP2_VRAM
@@ -8,10 +8,10 @@ menuconfig FB_OMAP2
select FB_CFB_COPYAREA
select FB_CFB_IMAGEBLIT
help
- Frame buffer driver for OMAP2/3 based boards.
+ Frame buffer driver for OMAP2+ based boards.
config FB_OMAP2_DEBUG_SUPPORT
- bool "Debug support for OMAP2/3 FB"
+ bool "Debug support for OMAP2+ FB"
default y
depends on FB_OMAP2
help
diff --git a/drivers/watchdog/sp805_wdt.c b/drivers/watchdog/sp805_wdt.c
index 9127eda2145..0a0efe713bc 100644
--- a/drivers/watchdog/sp805_wdt.c
+++ b/drivers/watchdog/sp805_wdt.c
@@ -278,7 +278,7 @@ static struct miscdevice sp805_wdt_miscdev = {
};
static int __devinit
-sp805_wdt_probe(struct amba_device *adev, struct amba_id *id)
+sp805_wdt_probe(struct amba_device *adev, const struct amba_id *id)
{
int ret = 0;
diff --git a/include/linux/amba/bus.h b/include/linux/amba/bus.h
index 9e7f259346e..227d590cd8d 100644
--- a/include/linux/amba/bus.h
+++ b/include/linux/amba/bus.h
@@ -43,12 +43,12 @@ struct amba_id {
struct amba_driver {
struct device_driver drv;
- int (*probe)(struct amba_device *, struct amba_id *);
+ int (*probe)(struct amba_device *, const struct amba_id *);
int (*remove)(struct amba_device *);
void (*shutdown)(struct amba_device *);
int (*suspend)(struct amba_device *, pm_message_t);
int (*resume)(struct amba_device *);
- struct amba_id *id_table;
+ const struct amba_id *id_table;
};
enum amba_vendor {
@@ -56,6 +56,8 @@ enum amba_vendor {
AMBA_VENDOR_ST = 0x80,
};
+extern struct bus_type amba_bustype;
+
#define amba_get_drvdata(d) dev_get_drvdata(&d->dev)
#define amba_set_drvdata(d,p) dev_set_drvdata(&d->dev, p)
diff --git a/sound/arm/aaci.c b/sound/arm/aaci.c
index 7c1fc64cb53..d0821f8974a 100644
--- a/sound/arm/aaci.c
+++ b/sound/arm/aaci.c
@@ -1011,7 +1011,8 @@ static unsigned int __devinit aaci_size_fifo(struct aaci *aaci)
return i;
}
-static int __devinit aaci_probe(struct amba_device *dev, struct amba_id *id)
+static int __devinit aaci_probe(struct amba_device *dev,
+ const struct amba_id *id)
{
struct aaci *aaci;
int ret, i;