summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Documentation/devicetree/bindings/arm/fsl.txt19
-rw-r--r--Documentation/devicetree/bindings/arm/omap/dsp.txt14
-rw-r--r--Documentation/devicetree/bindings/arm/omap/iva.txt19
-rw-r--r--Documentation/devicetree/bindings/arm/omap/l3-noc.txt19
-rw-r--r--Documentation/devicetree/bindings/arm/omap/mpu.txt27
-rw-r--r--Documentation/devicetree/bindings/arm/omap/omap.txt43
-rw-r--r--Documentation/devicetree/bindings/tty/serial/msm_serial.txt27
-rw-r--r--Documentation/kernel-parameters.txt7
-rw-r--r--Documentation/networking/scaling.txt10
-rw-r--r--MAINTAINERS8
-rw-r--r--Makefile2
-rw-r--r--arch/arm/boot/dts/at91sam9g20.dtsi119
-rw-r--r--arch/arm/boot/dts/at91sam9g45.dtsi106
-rw-r--r--arch/arm/boot/dts/at91sam9m10g45ek.dts35
-rw-r--r--arch/arm/boot/dts/imx51-babbage.dts135
-rw-r--r--arch/arm/boot/dts/imx51.dtsi246
-rw-r--r--arch/arm/boot/dts/imx53-ard.dts113
-rw-r--r--arch/arm/boot/dts/imx53-evk.dts120
-rw-r--r--arch/arm/boot/dts/imx53-qsb.dts125
-rw-r--r--arch/arm/boot/dts/imx53-smd.dts169
-rw-r--r--arch/arm/boot/dts/imx53.dtsi301
-rw-r--r--arch/arm/boot/dts/msm8660-surf.dts24
-rw-r--r--arch/arm/boot/dts/omap3-beagle.dts29
-rw-r--r--arch/arm/boot/dts/omap3.dtsi63
-rw-r--r--arch/arm/boot/dts/omap4-panda.dts29
-rw-r--r--arch/arm/boot/dts/omap4-sdp.dts29
-rw-r--r--arch/arm/boot/dts/omap4.dtsi103
-rw-r--r--arch/arm/boot/dts/usb_a9g20.dts30
-rw-r--r--arch/arm/common/vic.c1
-rw-r--r--arch/arm/include/asm/device.h5
-rw-r--r--arch/arm/include/asm/localtimer.h1
-rw-r--r--arch/arm/kernel/perf_event_v7.c4
-rw-r--r--arch/arm/mach-at91/Kconfig11
-rw-r--r--arch/arm/mach-at91/Makefile3
-rw-r--r--arch/arm/mach-at91/Makefile.boot2
-rw-r--r--arch/arm/mach-at91/at91sam9260.c8
-rw-r--r--arch/arm/mach-at91/at91sam9g45.c6
-rw-r--r--arch/arm/mach-at91/board-dt.c123
-rw-r--r--arch/arm/mach-msm/board-msm8x60.c58
-rw-r--r--arch/arm/mach-mx5/Kconfig21
-rw-r--r--arch/arm/mach-mx5/Makefile3
-rw-r--r--arch/arm/mach-mx5/board-mx51_babbage.c9
-rw-r--r--arch/arm/mach-mx5/board-mx53_ard.c12
-rw-r--r--arch/arm/mach-mx5/board-mx53_evk.c9
-rw-r--r--arch/arm/mach-mx5/board-mx53_loco.c9
-rw-r--r--arch/arm/mach-mx5/board-mx53_smd.c9
-rw-r--r--arch/arm/mach-mx5/clock-mx51-mx53.c39
-rw-r--r--arch/arm/mach-mx5/imx51-dt.c116
-rw-r--r--arch/arm/mach-mx5/imx53-dt.c126
-rw-r--r--arch/arm/mach-omap1/Makefile2
-rw-r--r--arch/arm/mach-omap1/mcbsp.c45
-rw-r--r--arch/arm/mach-omap1/timer.c173
-rw-r--r--arch/arm/mach-omap2/Kconfig8
-rw-r--r--arch/arm/mach-omap2/Makefile88
-rw-r--r--arch/arm/mach-omap2/board-2430sdp.c20
-rw-r--r--arch/arm/mach-omap2/board-3430sdp.c9
-rw-r--r--arch/arm/mach-omap2/board-3630sdp.c11
-rw-r--r--arch/arm/mach-omap2/board-4430sdp.c19
-rw-r--r--arch/arm/mach-omap2/board-am3517crane.c9
-rw-r--r--arch/arm/mach-omap2/board-am3517evm.c8
-rw-r--r--arch/arm/mach-omap2/board-apollon.c17
-rw-r--r--arch/arm/mach-omap2/board-cm-t35.c13
-rw-r--r--arch/arm/mach-omap2/board-cm-t3517.c9
-rw-r--r--arch/arm/mach-omap2/board-devkit8000.c19
-rw-r--r--arch/arm/mach-omap2/board-flash.c5
-rw-r--r--arch/arm/mach-omap2/board-flash.h19
-rw-r--r--arch/arm/mach-omap2/board-generic.c160
-rw-r--r--arch/arm/mach-omap2/board-h4.c24
-rw-r--r--arch/arm/mach-omap2/board-igep0020.c13
-rw-r--r--arch/arm/mach-omap2/board-ldp.c9
-rw-r--r--arch/arm/mach-omap2/board-n8x0.c25
-rw-r--r--arch/arm/mach-omap2/board-omap3beagle.c15
-rw-r--r--arch/arm/mach-omap2/board-omap3evm.c9
-rw-r--r--arch/arm/mach-omap2/board-omap3logic.c11
-rw-r--r--arch/arm/mach-omap2/board-omap3pandora.c11
-rw-r--r--arch/arm/mach-omap2/board-omap3stalker.c16
-rw-r--r--arch/arm/mach-omap2/board-omap3touchbook.c18
-rw-r--r--arch/arm/mach-omap2/board-omap4panda.c17
-rw-r--r--arch/arm/mach-omap2/board-overo.c11
-rw-r--r--arch/arm/mach-omap2/board-rm680.c25
-rw-r--r--arch/arm/mach-omap2/board-rx51.c25
-rw-r--r--arch/arm/mach-omap2/board-ti8168evm.c9
-rw-r--r--arch/arm/mach-omap2/board-zoom.c23
-rw-r--r--arch/arm/mach-omap2/clock2420_data.c48
-rw-r--r--arch/arm/mach-omap2/clock2430_data.c48
-rw-r--r--arch/arm/mach-omap2/clock3xxx_data.c47
-rw-r--r--arch/arm/mach-omap2/clock44xx_data.c33
-rw-r--r--arch/arm/mach-omap2/clockdomain.c149
-rw-r--r--arch/arm/mach-omap2/clockdomain.h22
-rw-r--r--arch/arm/mach-omap2/clockdomain2xxx_3xxx.c4
-rw-r--r--arch/arm/mach-omap2/clockdomain44xx.c2
-rw-r--r--arch/arm/mach-omap2/clockdomains2420_data.c154
-rw-r--r--arch/arm/mach-omap2/clockdomains2430_data.c181
-rw-r--r--arch/arm/mach-omap2/clockdomains2xxx_3xxx_data.c803
-rw-r--r--arch/arm/mach-omap2/clockdomains3xxx_data.c398
-rw-r--r--arch/arm/mach-omap2/clockdomains44xx_data.c409
-rw-r--r--arch/arm/mach-omap2/common.c18
-rw-r--r--arch/arm/mach-omap2/devices.c91
-rw-r--r--arch/arm/mach-omap2/display.c17
-rw-r--r--arch/arm/mach-omap2/dma.c25
-rw-r--r--arch/arm/mach-omap2/gpio.c22
-rw-r--r--arch/arm/mach-omap2/hsmmc.c38
-rw-r--r--arch/arm/mach-omap2/hwspinlock.c18
-rw-r--r--arch/arm/mach-omap2/id.c191
-rw-r--r--arch/arm/mach-omap2/io.c57
-rw-r--r--arch/arm/mach-omap2/irq.c4
-rw-r--r--arch/arm/mach-omap2/mcbsp.c120
-rw-r--r--arch/arm/mach-omap2/omap_hwmod.c3
-rw-r--r--arch/arm/mach-omap2/omap_hwmod_2420_data.c59
-rw-r--r--arch/arm/mach-omap2/omap_hwmod_2430_data.c67
-rw-r--r--arch/arm/mach-omap2/omap_hwmod_3xxx_data.c200
-rw-r--r--arch/arm/mach-omap2/omap_hwmod_44xx_data.c104
-rw-r--r--arch/arm/mach-omap2/omap_l3_noc.c147
-rw-r--r--arch/arm/mach-omap2/omap_l3_noc.h224
-rw-r--r--arch/arm/mach-omap2/omap_l3_smx.c91
-rw-r--r--arch/arm/mach-omap2/omap_l3_smx.h164
-rw-r--r--arch/arm/mach-omap2/omap_twl.c107
-rw-r--r--arch/arm/mach-omap2/opp.c2
-rw-r--r--arch/arm/mach-omap2/pm.c104
-rw-r--r--arch/arm/mach-omap2/pm24xx.c27
-rw-r--r--arch/arm/mach-omap2/pm34xx.c2
-rw-r--r--arch/arm/mach-omap2/powerdomain-common.c7
-rw-r--r--arch/arm/mach-omap2/powerdomain.c110
-rw-r--r--arch/arm/mach-omap2/powerdomain.h19
-rw-r--r--arch/arm/mach-omap2/powerdomain2xxx_3xxx.c2
-rw-r--r--arch/arm/mach-omap2/powerdomains2xxx_3xxx_data.c21
-rw-r--r--arch/arm/mach-omap2/powerdomains2xxx_data.c48
-rw-r--r--arch/arm/mach-omap2/powerdomains3xxx_data.c97
-rw-r--r--arch/arm/mach-omap2/powerdomains44xx_data.c36
-rw-r--r--arch/arm/mach-omap2/prm2xxx_3xxx.c56
-rw-r--r--arch/arm/mach-omap2/prm2xxx_3xxx.h12
-rw-r--r--arch/arm/mach-omap2/prm44xx.c71
-rw-r--r--arch/arm/mach-omap2/prm44xx.h12
-rw-r--r--arch/arm/mach-omap2/serial.c39
-rw-r--r--arch/arm/mach-omap2/smartreflex-class3.c4
-rw-r--r--arch/arm/mach-omap2/smartreflex.c29
-rw-r--r--arch/arm/mach-omap2/sr_device.c19
-rw-r--r--arch/arm/mach-omap2/timer.c194
-rw-r--r--arch/arm/mach-omap2/usb-musb.c29
-rw-r--r--arch/arm/mach-omap2/vc.c367
-rw-r--r--arch/arm/mach-omap2/vc.h88
-rw-r--r--arch/arm/mach-omap2/vc3xxx_data.c31
-rw-r--r--arch/arm/mach-omap2/vc44xx_data.c44
-rw-r--r--arch/arm/mach-omap2/voltage.c1088
-rw-r--r--arch/arm/mach-omap2/voltage.h150
-rw-r--r--arch/arm/mach-omap2/voltagedomains2xxx_data.c32
-rw-r--r--arch/arm/mach-omap2/voltagedomains3xxx_data.c83
-rw-r--r--arch/arm/mach-omap2/voltagedomains44xx_data.c99
-rw-r--r--arch/arm/mach-omap2/vp.c278
-rw-r--r--arch/arm/mach-omap2/vp.h133
-rw-r--r--arch/arm/mach-omap2/vp3xxx_data.c35
-rw-r--r--arch/arm/mach-omap2/vp44xx_data.c47
-rw-r--r--arch/arm/mach-s3c2410/s3c2410.c2
-rw-r--r--arch/arm/mach-s3c2412/s3c2412.c2
-rw-r--r--arch/arm/mach-s3c2416/s3c2416.c2
-rw-r--r--arch/arm/mach-s3c2440/s3c2440.c2
-rw-r--r--arch/arm/mach-s3c2440/s3c2442.c2
-rw-r--r--arch/arm/mach-tegra/cpu-tegra.c1
-rw-r--r--arch/arm/mach-ux500/Kconfig1
-rw-r--r--arch/arm/mm/init.c7
-rw-r--r--arch/arm/plat-mxc/include/mach/common.h8
-rw-r--r--arch/arm/plat-omap/devices.c46
-rw-r--r--arch/arm/plat-omap/dmtimer.c713
-rw-r--r--arch/arm/plat-omap/i2c.c18
-rw-r--r--arch/arm/plat-omap/include/plat/clock.h2
-rw-r--r--arch/arm/plat-omap/include/plat/common.h13
-rw-r--r--arch/arm/plat-omap/include/plat/cpu.h108
-rw-r--r--arch/arm/plat-omap/include/plat/dmtimer.h233
-rw-r--r--arch/arm/plat-omap/include/plat/io.h6
-rw-r--r--arch/arm/plat-omap/include/plat/mcbsp.h208
-rw-r--r--arch/arm/plat-omap/include/plat/omap_device.h31
-rw-r--r--arch/arm/plat-omap/include/plat/omap_hwmod.h3
-rw-r--r--arch/arm/plat-omap/include/plat/voltage.h20
-rw-r--r--arch/arm/plat-omap/mcbsp.c385
-rw-r--r--arch/arm/plat-omap/omap_device.c450
-rw-r--r--arch/arm/plat-s5p/irq-gpioint.c6
-rw-r--r--arch/mips/Kconfig6
-rw-r--r--arch/mips/alchemy/common/platform.c2
-rw-r--r--arch/mips/alchemy/common/power.c22
-rw-r--r--arch/mips/alchemy/devboards/bcsr.c4
-rw-r--r--arch/mips/alchemy/devboards/db1200/setup.c7
-rw-r--r--arch/mips/ar7/irq.c3
-rw-r--r--arch/mips/bcm63xx/irq.c1
-rw-r--r--arch/mips/cobalt/irq.c1
-rw-r--r--arch/mips/dec/setup.c4
-rw-r--r--arch/mips/emma/markeins/irq.c2
-rw-r--r--arch/mips/include/asm/mach-cavium-octeon/cpu-feature-overrides.h1
-rw-r--r--arch/mips/include/asm/mach-powertv/dma-coherence.h1
-rw-r--r--arch/mips/include/asm/stackframe.h4
-rw-r--r--arch/mips/jz4740/gpio.c52
-rw-r--r--arch/mips/kernel/ftrace.c39
-rw-r--r--arch/mips/kernel/i8259.c3
-rw-r--r--arch/mips/kernel/linux32.c7
-rw-r--r--arch/mips/kernel/scall64-n32.S2
-rw-r--r--arch/mips/kernel/scall64-o32.S2
-rw-r--r--arch/mips/kernel/signal.c3
-rw-r--r--arch/mips/kernel/traps.c16
-rw-r--r--arch/mips/kernel/vpe.c2
-rw-r--r--arch/mips/lantiq/irq.c6
-rw-r--r--arch/mips/lantiq/xway/ebu.c1
-rw-r--r--arch/mips/lantiq/xway/pmu.c1
-rw-r--r--arch/mips/lasat/interrupt.c1
-rw-r--r--arch/mips/loongson/fuloong-2e/irq.c1
-rw-r--r--arch/mips/loongson/lemote-2f/irq.c3
-rw-r--r--arch/mips/mm/mmap.c48
-rw-r--r--arch/mips/mm/tlbex.c6
-rw-r--r--arch/mips/mti-malta/malta-int.c6
-rw-r--r--arch/mips/netlogic/xlr/Makefile2
-rw-r--r--arch/mips/pci/pci-lantiq.c9
-rw-r--r--arch/mips/pci/pci-rc32434.c2
-rw-r--r--arch/mips/pmc-sierra/msp71xx/msp_irq.c6
-rw-r--r--arch/mips/pnx8550/common/int.c2
-rw-r--r--arch/mips/sgi-ip22/ip22-int.c10
-rw-r--r--arch/mips/sni/rm200.c1
-rw-r--r--arch/mips/vr41xx/common/irq.c1
-rw-r--r--arch/sparc/include/asm/pgtsrmmu.h2
-rw-r--r--arch/sparc/kernel/pci.c3
-rw-r--r--arch/sparc/kernel/signal32.c21
-rw-r--r--arch/sparc/kernel/signal_32.c32
-rw-r--r--arch/sparc/kernel/signal_64.c32
-rw-r--r--arch/sparc/mm/leon_mm.c2
-rw-r--r--arch/tile/kernel/intvec_32.S2
-rw-r--r--arch/tile/lib/atomic_asm_32.S2
-rw-r--r--arch/x86/kernel/vsyscall_64.c2
-rw-r--r--arch/x86/mm/init.c3
-rw-r--r--arch/x86/pci/acpi.c11
-rw-r--r--arch/x86/platform/mrst/mrst.c22
-rw-r--r--crypto/ghash-generic.c6
-rw-r--r--drivers/gpio/gpio-omap.c2
-rw-r--r--drivers/gpio/gpio-pca953x.c1
-rw-r--r--drivers/gpu/drm/radeon/atom.c15
-rw-r--r--drivers/gpu/drm/radeon/atom.h1
-rw-r--r--drivers/gpu/drm/radeon/atombios_crtc.c2
-rw-r--r--drivers/gpu/drm/radeon/atombios_dp.c12
-rw-r--r--drivers/gpu/drm/radeon/radeon_connectors.c21
-rw-r--r--drivers/gpu/drm/radeon/radeon_encoders.c26
-rw-r--r--drivers/gpu/drm/ttm/ttm_bo_util.c2
-rw-r--r--drivers/hwmon/w83627ehf.c20
-rw-r--r--drivers/ide/Kconfig24
-rw-r--r--drivers/input/tablet/wacom_wac.c7
-rw-r--r--drivers/iommu/intel-iommu.c75
-rw-r--r--drivers/md/dm-crypt.c2
-rw-r--r--drivers/md/dm-flakey.c4
-rw-r--r--drivers/md/dm-kcopyd.c1
-rw-r--r--drivers/md/dm-raid.c2
-rw-r--r--drivers/md/dm-table.c32
-rw-r--r--drivers/md/md.c22
-rw-r--r--drivers/md/md.h2
-rw-r--r--drivers/md/multipath.c3
-rw-r--r--drivers/md/raid1.c3
-rw-r--r--drivers/md/raid10.c5
-rw-r--r--drivers/md/raid5.c6
-rw-r--r--drivers/media/video/v4l2-dev.c2
-rw-r--r--drivers/net/bnx2x/bnx2x.h18
-rw-r--r--drivers/net/bnx2x/bnx2x_cmn.h2
-rw-r--r--drivers/net/bonding/bond_main.c7
-rw-r--r--drivers/net/can/mscan/mscan.c11
-rw-r--r--drivers/net/macvlan.c2
-rw-r--r--drivers/net/mlx4/en_tx.c6
-rw-r--r--drivers/net/netconsole.c5
-rw-r--r--drivers/net/pptp.c22
-rw-r--r--drivers/net/r8169.c90
-rw-r--r--drivers/net/smsc911x.c2
-rw-r--r--drivers/net/tg3.c2
-rw-r--r--drivers/of/base.c84
-rw-r--r--drivers/scsi/libsas/sas_expander.c10
-rw-r--r--drivers/scsi/qla2xxx/qla_os.c9
-rw-r--r--drivers/staging/octeon/ethernet-rx.c3
-rw-r--r--drivers/tty/serial/lantiq.c4
-rw-r--r--drivers/tty/serial/msm_serial.c30
-rw-r--r--fs/btrfs/ioctl.c11
-rw-r--r--fs/cifs/connect.c2
-rw-r--r--fs/xfs/xfs_buf_item.c3
-rw-r--r--fs/xfs/xfs_dquot_item.c10
-rw-r--r--fs/xfs/xfs_inode_item.c10
-rw-r--r--fs/xfs/xfs_linux.h2
-rw-r--r--fs/xfs/xfs_super.c13
-rw-r--r--fs/xfs/xfs_trans.h2
-rw-r--r--fs/xfs/xfs_trans_ail.c83
-rw-r--r--fs/xfs/xfs_trans_priv.h8
-rw-r--r--include/linux/device-mapper.h5
-rw-r--r--include/linux/of.h18
-rw-r--r--include/net/ip_vs.h1
-rw-r--r--include/net/udplite.h63
-rw-r--r--kernel/posix-cpu-timers.c7
-rw-r--r--kernel/sys.c2
-rw-r--r--mm/migrate.c8
-rw-r--r--net/bluetooth/l2cap_sock.c4
-rw-r--r--net/bluetooth/rfcomm/sock.c3
-rw-r--r--net/bluetooth/sco.c5
-rw-r--r--net/bridge/br_device.c3
-rw-r--r--net/bridge/br_if.c9
-rw-r--r--net/bridge/br_netlink.c1
-rw-r--r--net/bridge/br_private.h1
-rw-r--r--net/core/fib_rules.c5
-rw-r--r--net/ipv4/tcp_input.c4
-rw-r--r--net/ipv4/tcp_ipv4.c11
-rw-r--r--net/ipv4/tcp_minisocks.c1
-rw-r--r--net/ipv6/af_inet6.c1
-rw-r--r--net/ipv6/tcp_ipv6.c8
-rw-r--r--net/l2tp/l2tp_core.c4
-rw-r--r--net/netfilter/ipvs/ip_vs_ctl.c133
-rw-r--r--net/netfilter/ipvs/ip_vs_sync.c6
-rw-r--r--net/netfilter/nf_conntrack_proto_gre.c4
-rw-r--r--net/x25/af_x25.c40
-rw-r--r--net/x25/x25_dev.c6
-rw-r--r--net/x25/x25_facilities.c10
-rw-r--r--net/x25/x25_in.c43
-rw-r--r--net/x25/x25_link.c3
-rw-r--r--net/x25/x25_subr.c14
-rw-r--r--security/security.c1
-rw-r--r--sound/pci/hda/hda_intel.c1
-rw-r--r--sound/pci/hda/patch_conexant.c1
313 files changed, 9125 insertions, 5664 deletions
diff --git a/Documentation/devicetree/bindings/arm/fsl.txt b/Documentation/devicetree/bindings/arm/fsl.txt
new file mode 100644
index 000000000000..e2401cd632ab
--- /dev/null
+++ b/Documentation/devicetree/bindings/arm/fsl.txt
@@ -0,0 +1,19 @@
+i.MX51 Babbage Board
+Required root node properties:
+ - compatible = "fsl,imx51-babbage", "fsl,imx51";
+
+i.MX53 Automotive Reference Design Board
+Required root node properties:
+ - compatible = "fsl,imx53-ard", "fsl,imx53";
+
+i.MX53 Evaluation Kit
+Required root node properties:
+ - compatible = "fsl,imx53-evk", "fsl,imx53";
+
+i.MX53 Quick Start Board
+Required root node properties:
+ - compatible = "fsl,imx53-qsb", "fsl,imx53";
+
+i.MX53 Smart Mobile Reference Design Board
+Required root node properties:
+ - compatible = "fsl,imx53-smd", "fsl,imx53";
diff --git a/Documentation/devicetree/bindings/arm/omap/dsp.txt b/Documentation/devicetree/bindings/arm/omap/dsp.txt
new file mode 100644
index 000000000000..d3830a32ce08
--- /dev/null
+++ b/Documentation/devicetree/bindings/arm/omap/dsp.txt
@@ -0,0 +1,14 @@
+* TI - DSP (Digital Signal Processor)
+
+TI DSP included in OMAP SoC
+
+Required properties:
+- compatible : Should be "ti,omap3-c64" for OMAP3 & 4
+- ti,hwmods: "dsp"
+
+Examples:
+
+dsp {
+ compatible = "ti,omap3-c64";
+ ti,hwmods = "dsp";
+};
diff --git a/Documentation/devicetree/bindings/arm/omap/iva.txt b/Documentation/devicetree/bindings/arm/omap/iva.txt
new file mode 100644
index 000000000000..6d6295171358
--- /dev/null
+++ b/Documentation/devicetree/bindings/arm/omap/iva.txt
@@ -0,0 +1,19 @@
+* TI - IVA (Imaging and Video Accelerator) subsystem
+
+The IVA contain various audio, video or imaging HW accelerator
+depending of the version.
+
+Required properties:
+- compatible : Should be:
+ - "ti,ivahd" for OMAP4
+ - "ti,iva2.2" for OMAP3
+ - "ti,iva2.1" for OMAP2430
+ - "ti,iva1" for OMAP2420
+- ti,hwmods: "iva"
+
+Examples:
+
+iva {
+ compatible = "ti,ivahd", "ti,iva";
+ ti,hwmods = "iva";
+};
diff --git a/Documentation/devicetree/bindings/arm/omap/l3-noc.txt b/Documentation/devicetree/bindings/arm/omap/l3-noc.txt
new file mode 100644
index 000000000000..6888a5efc860
--- /dev/null
+++ b/Documentation/devicetree/bindings/arm/omap/l3-noc.txt
@@ -0,0 +1,19 @@
+* TI - L3 Network On Chip (NoC)
+
+This version is an implementation of the generic NoC IP
+provided by Arteris.
+
+Required properties:
+- compatible : Should be "ti,omap3-l3-smx" for OMAP3 family
+ Should be "ti,omap4-l3-noc" for OMAP4 family
+- ti,hwmods: "l3_main_1", ... One hwmod for each noc domain.
+
+Examples:
+
+ocp {
+ compatible = "ti,omap4-l3-noc", "simple-bus";
+ #address-cells = <1>;
+ #size-cells = <1>;
+ ranges;
+ ti,hwmods = "l3_main_1", "l3_main_2", "l3_main_3";
+};
diff --git a/Documentation/devicetree/bindings/arm/omap/mpu.txt b/Documentation/devicetree/bindings/arm/omap/mpu.txt
new file mode 100644
index 000000000000..1a5a42ce21bb
--- /dev/null
+++ b/Documentation/devicetree/bindings/arm/omap/mpu.txt
@@ -0,0 +1,27 @@
+* TI - MPU (Main Processor Unit) subsystem
+
+The MPU subsystem contain one or several ARM cores
+depending of the version.
+The MPU contain CPUs, GIC, L2 cache and a local PRCM.
+
+Required properties:
+- compatible : Should be "ti,omap3-mpu" for OMAP3
+ Should be "ti,omap4-mpu" for OMAP4
+- ti,hwmods: "mpu"
+
+Examples:
+
+- For an OMAP4 SMP system:
+
+mpu {
+ compatible = "ti,omap4-mpu";
+ ti,hwmods = "mpu";
+};
+
+
+- For an OMAP3 monocore system:
+
+mpu {
+ compatible = "ti,omap3-mpu";
+ ti,hwmods = "mpu";
+};
diff --git a/Documentation/devicetree/bindings/arm/omap/omap.txt b/Documentation/devicetree/bindings/arm/omap/omap.txt
new file mode 100644
index 000000000000..dbdab40ed3a6
--- /dev/null
+++ b/Documentation/devicetree/bindings/arm/omap/omap.txt
@@ -0,0 +1,43 @@
+* Texas Instruments OMAP
+
+OMAP is currently using a static file per SoC family to describe the
+IPs present in the SoC.
+On top of that an omap_device is created to extend the platform_device
+capabilities and to allow binding with one or several hwmods.
+The hwmods will contain all the information to build the device:
+adresse range, irq lines, dma lines, interconnect, PRCM register,
+clock domain, input clocks.
+For the moment just point to the existing hwmod, the next step will be
+to move data from hwmod to device-tree representation.
+
+
+Required properties:
+- compatible: Every devices present in OMAP SoC should be in the
+ form: "ti,XXX"
+- ti,hwmods: list of hwmod names (ascii strings), that comes from the OMAP
+ HW documentation, attached to a device. Must contain at least
+ one hwmod.
+
+Optional properties:
+- ti,no_idle_on_suspend: When present, it prevents the PM to idle the module
+ during suspend.
+
+
+Example:
+
+spinlock@1 {
+ compatible = "ti,omap4-spinlock";
+ ti,hwmods = "spinlock";
+};
+
+
+Boards:
+
+- OMAP3 BeagleBoard : Low cost community board
+ compatible = "ti,omap3-beagle", "ti,omap3"
+
+- OMAP4 SDP : Software Developement Board
+ compatible = "ti,omap4-sdp", "ti,omap4430"
+
+- OMAP4 PandaBoard : Low cost community board
+ compatible = "ti,omap4-panda", "ti,omap4430"
diff --git a/Documentation/devicetree/bindings/tty/serial/msm_serial.txt b/Documentation/devicetree/bindings/tty/serial/msm_serial.txt
new file mode 100644
index 000000000000..aef383eb8876
--- /dev/null
+++ b/Documentation/devicetree/bindings/tty/serial/msm_serial.txt
@@ -0,0 +1,27 @@
+* Qualcomm MSM UART
+
+Required properties:
+- compatible :
+ - "qcom,msm-uart", and one of "qcom,msm-hsuart" or
+ "qcom,msm-lsuart".
+- reg : offset and length of the register set for the device
+ for the hsuart operating in compatible mode, there should be a
+ second pair describing the gsbi registers.
+- interrupts : should contain the uart interrupt.
+
+There are two different UART blocks used in MSM devices,
+"qcom,msm-hsuart" and "qcom,msm-lsuart". The msm-serial driver is
+able to handle both of these, and matches against the "qcom,msm-uart"
+as the compatibility.
+
+The registers for the "qcom,msm-hsuart" device need to specify both
+register blocks, even for the common driver.
+
+Example:
+
+ uart@19c400000 {
+ compatible = "qcom,msm-hsuart", "qcom,msm-uart";
+ reg = <0x19c40000 0x1000>,
+ <0x19c00000 0x1000>;
+ interrupts = <195>;
+ };
diff --git a/Documentation/kernel-parameters.txt b/Documentation/kernel-parameters.txt
index 854ed5ca7e3f..d6e6724446c8 100644
--- a/Documentation/kernel-parameters.txt
+++ b/Documentation/kernel-parameters.txt
@@ -2706,10 +2706,11 @@ bytes respectively. Such letter suffixes can also be entirely omitted.
functions are at fixed addresses, they make nice
targets for exploits that can control RIP.
- emulate [default] Vsyscalls turn into traps and are
- emulated reasonably safely.
+ emulate Vsyscalls turn into traps and are emulated
+ reasonably safely.
- native Vsyscalls are native syscall instructions.
+ native [default] Vsyscalls are native syscall
+ instructions.
This is a little bit faster than trapping
and makes a few dynamic recompilers work
better than they would in emulation mode.
diff --git a/Documentation/networking/scaling.txt b/Documentation/networking/scaling.txt
index 8ce7c30e7230..fe67b5c79f0f 100644
--- a/Documentation/networking/scaling.txt
+++ b/Documentation/networking/scaling.txt
@@ -27,7 +27,7 @@ applying a filter to each packet that assigns it to one of a small number
of logical flows. Packets for each flow are steered to a separate receive
queue, which in turn can be processed by separate CPUs. This mechanism is
generally known as “Receive-side Scaling” (RSS). The goal of RSS and
-the other scaling techniques to increase performance uniformly.
+the other scaling techniques is to increase performance uniformly.
Multi-queue distribution can also be used for traffic prioritization, but
that is not the focus of these techniques.
@@ -186,10 +186,10 @@ are steered using plain RPS. Multiple table entries may point to the
same CPU. Indeed, with many flows and few CPUs, it is very likely that
a single application thread handles flows with many different flow hashes.
-rps_sock_table is a global flow table that contains the *desired* CPU for
-flows: the CPU that is currently processing the flow in userspace. Each
-table value is a CPU index that is updated during calls to recvmsg and
-sendmsg (specifically, inet_recvmsg(), inet_sendmsg(), inet_sendpage()
+rps_sock_flow_table is a global flow table that contains the *desired* CPU
+for flows: the CPU that is currently processing the flow in userspace.
+Each table value is a CPU index that is updated during calls to recvmsg
+and sendmsg (specifically, inet_recvmsg(), inet_sendmsg(), inet_sendpage()
and tcp_splice_read()).
When the scheduler moves a thread to a new CPU while it has outstanding
diff --git a/MAINTAINERS b/MAINTAINERS
index ace8f9c81b96..6185d0513584 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -2460,7 +2460,7 @@ S: Supported
F: drivers/infiniband/hw/ehca/
EHEA (IBM pSeries eHEA 10Gb ethernet adapter) DRIVER
-M: Breno Leitao <leitao@linux.vnet.ibm.com>
+M: Thadeu Lima de Souza Cascardo <cascardo@linux.vnet.ibm.com>
L: netdev@vger.kernel.org
S: Maintained
F: drivers/net/ehea/
@@ -3313,7 +3313,7 @@ M: David Woodhouse <dwmw2@infradead.org>
L: iommu@lists.linux-foundation.org
T: git git://git.infradead.org/iommu-2.6.git
S: Supported
-F: drivers/pci/intel-iommu.c
+F: drivers/iommu/intel-iommu.c
F: include/linux/intel-iommu.h
INTEL IOP-ADMA DMA DRIVER
@@ -6366,10 +6366,10 @@ F: net/ipv4/tcp_lp.c
TEGRA SUPPORT
M: Colin Cross <ccross@android.com>
-M: Erik Gilling <konkers@android.com>
M: Olof Johansson <olof@lixom.net>
+M: Stephen Warren <swarren@nvidia.com>
L: linux-tegra@vger.kernel.org
-T: git git://android.git.kernel.org/kernel/tegra.git
+T: git git://git.kernel.org/pub/scm/linux/kernel/git/olof/tegra.git
S: Supported
F: arch/arm/mach-tegra
diff --git a/Makefile b/Makefile
index 31f967c31e7f..07bc92544e9c 100644
--- a/Makefile
+++ b/Makefile
@@ -1,7 +1,7 @@
VERSION = 3
PATCHLEVEL = 1
SUBLEVEL = 0
-EXTRAVERSION = -rc9
+EXTRAVERSION =
NAME = "Divemaster Edition"
# *DOCUMENTATION*
diff --git a/arch/arm/boot/dts/at91sam9g20.dtsi b/arch/arm/boot/dts/at91sam9g20.dtsi
new file mode 100644
index 000000000000..aeef04269cf8
--- /dev/null
+++ b/arch/arm/boot/dts/at91sam9g20.dtsi
@@ -0,0 +1,119 @@
+/*
+ * at91sam9g20.dtsi - Device Tree Include file for AT91SAM9G20 family SoC
+ *
+ * Copyright (C) 2011 Atmel,
+ * 2011 Nicolas Ferre <nicolas.ferre@atmel.com>,
+ * 2011 Jean-Christophe PLAGNIOL-VILLARD <plagnioj@jcrosoft.com>
+ *
+ * Licensed under GPLv2 or later.
+ */
+
+/include/ "skeleton.dtsi"
+
+/ {
+ model = "Atmel AT91SAM9G20 family SoC";
+ compatible = "atmel,at91sam9g20";
+ interrupt-parent = <&aic>;
+
+ aliases {
+ serial0 = &dbgu;
+ serial1 = &usart0;
+ serial2 = &usart1;
+ serial3 = &usart2;
+ serial4 = &usart3;
+ serial5 = &usart4;
+ serial6 = &usart5;
+ };
+ cpus {
+ cpu@0 {
+ compatible = "arm,arm926ejs";
+ };
+ };
+
+ memory@20000000 {
+ reg = <0x20000000 0x08000000>;
+ };
+
+ ahb {
+ compatible = "simple-bus";
+ #address-cells = <1>;
+ #size-cells = <1>;
+ ranges;
+
+ apb {
+ compatible = "simple-bus";
+ #address-cells = <1>;
+ #size-cells = <1>;
+ ranges;
+
+ aic: interrupt-controller@fffff000 {
+ #interrupt-cells = <1>;
+ compatible = "atmel,at91rm9200-aic";
+ interrupt-controller;
+ interrupt-parent;
+ reg = <0xfffff000 0x200>;
+ };
+
+ dbgu: serial@fffff200 {
+ compatible = "atmel,at91sam9260-usart";
+ reg = <0xfffff200 0x200>;
+ interrupts = <1>;
+ status = "disabled";
+ };
+
+ usart0: serial@fffb0000 {
+ compatible = "atmel,at91sam9260-usart";
+ reg = <0xfffb0000 0x200>;
+ interrupts = <6>;
+ atmel,use-dma-rx;
+ atmel,use-dma-tx;
+ status = "disabled";
+ };
+
+ usart1: serial@fffb4000 {
+ compatible = "atmel,at91sam9260-usart";
+ reg = <0xfffb4000 0x200>;
+ interrupts = <7>;
+ atmel,use-dma-rx;
+ atmel,use-dma-tx;
+ status = "disabled";
+ };
+
+ usart2: serial@fffb8000 {
+ compatible = "atmel,at91sam9260-usart";
+ reg = <0xfffb8000 0x200>;
+ interrupts = <8>;
+ atmel,use-dma-rx;
+ atmel,use-dma-tx;
+ status = "disabled";
+ };
+
+ usart3: serial@fffd0000 {
+ compatible = "atmel,at91sam9260-usart";
+ reg = <0xfffd0000 0x200>;
+ interrupts = <23>;
+ atmel,use-dma-rx;
+ atmel,use-dma-tx;
+ status = "disabled";
+ };
+
+ usart4: serial@fffd4000 {
+ compatible = "atmel,at91sam9260-usart";
+ reg = <0xfffd4000 0x200>;
+ interrupts = <24>;
+ atmel,use-dma-rx;
+ atmel,use-dma-tx;
+ status = "disabled";
+ };
+
+ usart5: serial@fffd8000 {
+ compatible = "atmel,at91sam9260-usart";
+ reg = <0xfffd8000 0x200>;
+ interrupts = <25>;
+ atmel,use-dma-rx;
+ atmel,use-dma-tx;
+ status = "disabled";
+ };
+ };
+ };
+};
diff --git a/arch/arm/boot/dts/at91sam9g45.dtsi b/arch/arm/boot/dts/at91sam9g45.dtsi
new file mode 100644
index 000000000000..db6a45202f26
--- /dev/null
+++ b/arch/arm/boot/dts/at91sam9g45.dtsi
@@ -0,0 +1,106 @@
+/*
+ * at91sam9g45.dtsi - Device Tree Include file for AT91SAM9G45 family SoC
+ * applies to AT91SAM9G45, AT91SAM9M10,
+ * AT91SAM9G46, AT91SAM9M11 SoC
+ *
+ * Copyright (C) 2011 Atmel,
+ * 2011 Nicolas Ferre <nicolas.ferre@atmel.com>
+ *
+ * Licensed under GPLv2 or later.
+ */
+
+/include/ "skeleton.dtsi"
+
+/ {
+ model = "Atmel AT91SAM9G45 family SoC";
+ compatible = "atmel,at91sam9g45";
+ interrupt-parent = <&aic>;
+
+ aliases {
+ serial0 = &dbgu;
+ serial1 = &usart0;
+ serial2 = &usart1;
+ serial3 = &usart2;
+ serial4 = &usart3;
+ };
+ cpus {
+ cpu@0 {
+ compatible = "arm,arm926ejs";
+ };
+ };
+
+ memory@70000000 {
+ reg = <0x70000000 0x10000000>;
+ };
+
+ ahb {
+ compatible = "simple-bus";
+ #address-cells = <1>;
+ #size-cells = <1>;
+ ranges;
+
+ apb {
+ compatible = "simple-bus";
+ #address-cells = <1>;
+ #size-cells = <1>;
+ ranges;
+
+ aic: interrupt-controller@fffff000 {
+ #interrupt-cells = <1>;
+ compatible = "atmel,at91rm9200-aic";
+ interrupt-controller;
+ interrupt-parent;
+ reg = <0xfffff000 0x200>;
+ };
+
+ dma: dma-controller@ffffec00 {
+ compatible = "atmel,at91sam9g45-dma";
+ reg = <0xffffec00 0x200>;
+ interrupts = <21>;
+ };
+
+ dbgu: serial@ffffee00 {
+ compatible = "atmel,at91sam9260-usart";
+ reg = <0xffffee00 0x200>;
+ interrupts = <1>;
+ status = "disabled";
+ };
+
+ usart0: serial@fff8c000 {
+ compatible = "atmel,at91sam9260-usart";
+ reg = <0xfff8c000 0x200>;
+ interrupts = <7>;
+ atmel,use-dma-rx;
+ atmel,use-dma-tx;
+ status = "disabled";
+ };
+
+ usart1: serial@fff90000 {
+ compatible = "atmel,at91sam9260-usart";
+ reg = <0xfff90000 0x200>;
+ interrupts = <8>;
+ atmel,use-dma-rx;
+ atmel,use-dma-tx;
+ status = "disabled";
+ };
+
+ usart2: serial@fff94000 {
+ compatible = "atmel,at91sam9260-usart";
+ reg = <0xfff94000 0x200>;
+ interrupts = <9>;
+ atmel,use-dma-rx;
+ atmel,use-dma-tx;
+ status = "disabled";
+ };
+
+ usart3: serial@fff98000 {
+ compatible = "atmel,at91sam9260-usart";
+ reg = <0xfff98000 0x200>;
+ interrupts = <10>;
+ atmel,use-dma-rx;
+ atmel,use-dma-tx;
+ status = "disabled";
+ };
+ };
+ };
+};
diff --git a/arch/arm/boot/dts/at91sam9m10g45ek.dts b/arch/arm/boot/dts/at91sam9m10g45ek.dts
new file mode 100644
index 000000000000..85b34f59cd82
--- /dev/null
+++ b/arch/arm/boot/dts/at91sam9m10g45ek.dts
@@ -0,0 +1,35 @@
+/*
+ * at91sam9m10g45ek.dts - Device Tree file for AT91SAM9M10G45-EK board
+ *
+ * Copyright (C) 2011 Atmel,
+ * 2011 Nicolas Ferre <nicolas.ferre@atmel.com>
+ *
+ * Licensed under GPLv2 or later.
+ */
+/dts-v1/;
+/include/ "at91sam9g45.dtsi"
+
+/ {
+ model = "Atmel AT91SAM9M10G45-EK";
+ compatible = "atmel,at91sam9m10g45ek", "atmel,at91sam9g45", "atmel,at91sam9";
+
+ chosen {
+ bootargs = "mem=64M console=ttyS0,115200 mtdparts=atmel_nand:4M(bootstrap/uboot/kernel)ro,60M(rootfs),-(data) root=/dev/mtdblock1 rw rootfstype=jffs2";
+ };
+
+ memory@70000000 {
+ reg = <0x70000000 0x4000000>;
+ };
+
+ ahb {
+ apb {
+ dbgu: serial@ffffee00 {
+ status = "okay";
+ };
+
+ usart1: serial@fff90000 {
+ status = "okay";
+ };
+ };
+ };
+};
diff --git a/arch/arm/boot/dts/imx51-babbage.dts b/arch/arm/boot/dts/imx51-babbage.dts
new file mode 100644
index 000000000000..f8766af11215
--- /dev/null
+++ b/arch/arm/boot/dts/imx51-babbage.dts
@@ -0,0 +1,135 @@
+/*
+ * Copyright 2011 Freescale Semiconductor, Inc.
+ * Copyright 2011 Linaro Ltd.
+ *
+ * The code contained herein is licensed under the GNU General Public
+ * License. You may obtain a copy of the GNU General Public License
+ * Version 2 or later at the following locations:
+ *
+ * http://www.opensource.org/licenses/gpl-license.html
+ * http://www.gnu.org/copyleft/gpl.html
+ */
+
+/dts-v1/;
+/include/ "imx51.dtsi"
+
+/ {
+ model = "Freescale i.MX51 Babbage Board";
+ compatible = "fsl,imx51-babbage", "fsl,imx51";
+
+ chosen {
+ bootargs = "console=ttymxc0,115200 root=/dev/mmcblk0p3 rootwait";
+ };
+
+ memory {
+ reg = <0x90000000 0x20000000>;
+ };
+
+ soc {
+ aips@70000000 { /* aips-1 */
+ spba@70000000 {
+ esdhc@70004000 { /* ESDHC1 */
+ fsl,cd-internal;
+ fsl,wp-internal;
+ status = "okay";
+ };
+
+ esdhc@70008000 { /* ESDHC2 */
+ cd-gpios = <&gpio0 6 0>; /* GPIO1_6 */
+ wp-gpios = <&gpio0 5 0>; /* GPIO1_5 */
+ status = "okay";
+ };
+
+ uart2: uart@7000c000 { /* UART3 */
+ fsl,uart-has-rtscts;
+ status = "okay";
+ };
+
+ ecspi@70010000 { /* ECSPI1 */
+ fsl,spi-num-chipselects = <2>;
+ cs-gpios = <&gpio3 24 0>, /* GPIO4_24 */
+ <&gpio3 25 0>; /* GPIO4_25 */
+ status = "okay";
+
+ pmic: mc13892@0 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ compatible = "fsl,mc13892";
+ spi-max-frequency = <6000000>;
+ reg = <0>;
+ mc13xxx-irq-gpios = <&gpio0 8 0>; /* GPIO1_8 */
+ fsl,mc13xxx-uses-regulator;
+ };
+
+ flash: at45db321d@1 {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ compatible = "atmel,at45db321d", "atmel,at45", "atmel,dataflash";
+ spi-max-frequency = <25000000>;
+ reg = <1>;
+
+ partition@0 {
+ label = "U-Boot";
+ reg = <0x0 0x40000>;
+ read-only;
+ };
+
+ partition@40000 {
+ label = "Kernel";
+ reg = <0x40000 0x3c0000>;
+ };
+ };
+ };
+ };
+
+ wdog@73f98000 { /* WDOG1 */
+ status = "okay";
+ };
+
+ iomuxc@73fa8000 {
+ compatible = "fsl,imx51-iomuxc-babbage";
+ reg = <0x73fa8000 0x4000>;
+ };
+
+ uart0: uart@73fbc000 {
+ fsl,uart-has-rtscts;
+ status = "okay";
+ };
+
+ uart1: uart@73fc0000 {
+ status = "okay";
+ };
+ };
+
+ aips@80000000 { /* aips-2 */
+ sdma@83fb0000 {
+ fsl,sdma-ram-script-name = "imx/sdma/sdma-imx51.bin";
+ };
+
+ i2c@83fc4000 { /* I2C2 */
+ status = "okay";
+
+ codec: sgtl5000@0a {
+ compatible = "fsl,sgtl5000";
+ reg = <0x0a>;
+ };
+ };
+
+ fec@83fec000 {
+ phy-mode = "mii";
+ status = "okay";
+ };
+ };
+ };
+
+ gpio-keys {
+ compatible = "gpio-keys";
+
+ power {
+ label = "Power Button";
+ gpios = <&gpio1 21 0>;
+ linux,code = <116>; /* KEY_POWER */
+ gpio-key,wakeup;
+ };
+ };
+};
diff --git a/arch/arm/boot/dts/imx51.dtsi b/arch/arm/boot/dts/imx51.dtsi
new file mode 100644
index 000000000000..327ab8e3a4c8
--- /dev/null
+++ b/arch/arm/boot/dts/imx51.dtsi
@@ -0,0 +1,246 @@
+/*
+ * Copyright 2011 Freescale Semiconductor, Inc.
+ * Copyright 2011 Linaro Ltd.
+ *
+ * The code contained herein is licensed under the GNU General Public
+ * License. You may obtain a copy of the GNU General Public License
+ * Version 2 or later at the following locations:
+ *
+ * http://www.opensource.org/licenses/gpl-license.html
+ * http://www.gnu.org/copyleft/gpl.html
+ */
+
+/include/ "skeleton.dtsi"
+
+/ {
+ aliases {
+ serial0 = &uart0;
+ serial1 = &uart1;
+ serial2 = &uart2;
+ };
+
+ tzic: tz-interrupt-controller@e0000000 {
+ compatible = "fsl,imx51-tzic", "fsl,tzic";
+ interrupt-controller;
+ #interrupt-cells = <1>;
+ reg = <0xe0000000 0x4000>;
+ };
+
+ clocks {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ ckil {
+ compatible = "fsl,imx-ckil", "fixed-clock";
+ clock-frequency = <32768>;
+ };
+
+ ckih1 {
+ compatible = "fsl,imx-ckih1", "fixed-clock";
+ clock-frequency = <22579200>;
+ };
+
+ ckih2 {
+ compatible = "fsl,imx-ckih2", "fixed-clock";
+ clock-frequency = <0>;
+ };
+
+ osc {
+ compatible = "fsl,imx-osc", "fixed-clock";
+ clock-frequency = <24000000>;
+ };
+ };
+
+ soc {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ compatible = "simple-bus";
+ interrupt-parent = <&tzic>;
+ ranges;
+
+ aips@70000000 { /* AIPS1 */
+ compatible = "fsl,aips-bus", "simple-bus";
+ #address-cells = <1>;
+ #size-cells = <1>;
+ reg = <0x70000000 0x10000000>;
+ ranges;
+
+ spba@70000000 {
+ compatible = "fsl,spba-bus", "simple-bus";
+ #address-cells = <1>;
+ #size-cells = <1>;
+ reg = <0x70000000 0x40000>;
+ ranges;
+
+ esdhc@70004000 { /* ESDHC1 */
+ compatible = "fsl,imx51-esdhc";
+ reg = <0x70004000 0x4000>;
+ interrupts = <1>;
+ status = "disabled";
+ };
+
+ esdhc@70008000 { /* ESDHC2 */
+ compatible = "fsl,imx51-esdhc";
+ reg = <0x70008000 0x4000>;
+ interrupts = <2>;
+ status = "disabled";
+ };
+
+ uart2: uart@7000c000 { /* UART3 */
+ compatible = "fsl,imx51-uart", "fsl,imx21-uart";
+ reg = <0x7000c000 0x4000>;
+ interrupts = <33>;
+ status = "disabled";
+ };
+
+ ecspi@70010000 { /* ECSPI1 */
+ #address-cells = <1>;
+ #size-cells = <0>;
+ compatible = "fsl,imx51-ecspi";
+ reg = <0x70010000 0x4000>;
+ interrupts = <36>;
+ status = "disabled";
+ };
+
+ esdhc@70020000 { /* ESDHC3 */
+ compatible = "fsl,imx51-esdhc";
+ reg = <0x70020000 0x4000>;
+ interrupts = <3>;
+ status = "disabled";
+ };
+
+ esdhc@70024000 { /* ESDHC4 */
+ compatible = "fsl,imx51-esdhc";
+ reg = <0x70024000 0x4000>;
+ interrupts = <4>;
+ status = "disabled";
+ };
+ };
+
+ gpio0: gpio@73f84000 { /* GPIO1 */
+ compatible = "fsl,imx51-gpio", "fsl,imx31-gpio";
+ reg = <0x73f84000 0x4000>;
+ interrupts = <50 51>;
+ gpio-controller;
+ #gpio-cells = <2>;
+ interrupt-controller;
+ #interrupt-cells = <1>;
+ };
+
+ gpio1: gpio@73f88000 { /* GPIO2 */
+ compatible = "fsl,imx51-gpio", "fsl,imx31-gpio";
+ reg = <0x73f88000 0x4000>;
+ interrupts = <52 53>;
+ gpio-controller;
+ #gpio-cells = <2>;
+ interrupt-controller;
+ #interrupt-cells = <1>;
+ };
+
+ gpio2: gpio@73f8c000 { /* GPIO3 */
+ compatible = "fsl,imx51-gpio", "fsl,imx31-gpio";
+ reg = <0x73f8c000 0x4000>;
+ interrupts = <54 55>;
+ gpio-controller;
+ #gpio-cells = <2>;
+ interrupt-controller;
+ #interrupt-cells = <1>;
+ };
+
+ gpio3: gpio@73f90000 { /* GPIO4 */
+ compatible = "fsl,imx51-gpio", "fsl,imx31-gpio";
+ reg = <0x73f90000 0x4000>;
+ interrupts = <56 57>;
+ gpio-controller;
+ #gpio-cells = <2>;
+ interrupt-controller;
+ #interrupt-cells = <1>;
+ };
+
+ wdog@73f98000 { /* WDOG1 */
+ compatible = "fsl,imx51-wdt", "fsl,imx21-wdt";
+ reg = <0x73f98000 0x4000>;
+ interrupts = <58>;
+ status = "disabled";
+ };
+
+ wdog@73f9c000 { /* WDOG2 */
+ compatible = "fsl,imx51-wdt", "fsl,imx21-wdt";
+ reg = <0x73f9c000 0x4000>;
+ interrupts = <59>;
+ status = "disabled";
+ };
+
+ uart0: uart@73fbc000 {
+ compatible = "fsl,imx51-uart", "fsl,imx21-uart";
+ reg = <0x73fbc000 0x4000>;
+ interrupts = <31>;
+ status = "disabled";
+ };
+
+ uart1: uart@73fc0000 {
+ compatible = "fsl,imx51-uart", "fsl,imx21-uart";
+ reg = <0x73fc0000 0x4000>;
+ interrupts = <32>;
+ status = "disabled";
+ };
+ };
+
+ aips@80000000 { /* AIPS2 */
+ compatible = "fsl,aips-bus", "simple-bus";
+ #address-cells = <1>;
+ #size-cells = <1>;
+ reg = <0x80000000 0x10000000>;
+ ranges;
+
+ ecspi@83fac000 { /* ECSPI2 */
+ #address-cells = <1>;
+ #size-cells = <0>;
+ compatible = "fsl,imx51-ecspi";
+ reg = <0x83fac000 0x4000>;
+ interrupts = <37>;
+ status = "disabled";
+ };
+
+ sdma@83fb0000 {
+ compatible = "fsl,imx51-sdma", "fsl,imx35-sdma";
+ reg = <0x83fb0000 0x4000>;
+ interrupts = <6>;
+ };
+
+ cspi@83fc0000 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ compatible = "fsl,imx51-cspi", "fsl,imx35-cspi";
+ reg = <0x83fc0000 0x4000>;
+ interrupts = <38>;
+ status = "disabled";
+ };
+
+ i2c@83fc4000 { /* I2C2 */
+ #address-cells = <1>;
+ #size-cells = <0>;
+ compatible = "fsl,imx51-i2c", "fsl,imx1-i2c";
+ reg = <0x83fc4000 0x4000>;
+ interrupts = <63>;
+ status = "disabled";
+ };
+
+ i2c@83fc8000 { /* I2C1 */
+ #address-cells = <1>;
+ #size-cells = <0>;
+ compatible = "fsl,imx51-i2c", "fsl,imx1-i2c";
+ reg = <0x83fc8000 0x4000>;
+ interrupts = <62>;
+ status = "disabled";
+ };
+
+ fec@83fec000 {
+ compatible = "fsl,imx51-fec", "fsl,imx27-fec";
+ reg = <0x83fec000 0x4000>;
+ interrupts = <87>;
+ status = "disabled";
+ };
+ };
+ };
+};
diff --git a/arch/arm/boot/dts/imx53-ard.dts b/arch/arm/boot/dts/imx53-ard.dts
new file mode 100644
index 000000000000..2ab7f80a0a35
--- /dev/null
+++ b/arch/arm/boot/dts/imx53-ard.dts
@@ -0,0 +1,113 @@
+/*
+ * Copyright 2011 Freescale Semiconductor, Inc.
+ * Copyright 2011 Linaro Ltd.
+ *
+ * The code contained herein is licensed under the GNU General Public
+ * License. You may obtain a copy of the GNU General Public License
+ * Version 2 or later at the following locations:
+ *
+ * http://www.opensource.org/licenses/gpl-license.html
+ * http://www.gnu.org/copyleft/gpl.html
+ */
+
+/dts-v1/;
+/include/ "imx53.dtsi"
+
+/ {
+ model = "Freescale i.MX53 Automotive Reference Design Board";
+ compatible = "fsl,imx53-ard", "fsl,imx53";
+
+ chosen {
+ bootargs = "console=ttymxc0,115200 root=/dev/mmcblk0p3 rootwait";
+ };
+
+ memory {
+ reg = <0x70000000 0x40000000>;
+ };
+
+ soc {
+ aips@50000000 { /* AIPS1 */
+ spba@50000000 {
+ esdhc@50004000 { /* ESDHC1 */
+ cd-gpios = <&gpio0 1 0>; /* GPIO1_1 */
+ wp-gpios = <&gpio0 9 0>; /* GPIO1_9 */
+ status = "okay";
+ };
+ };
+
+ wdog@53f98000 { /* WDOG1 */
+ status = "okay";
+ };
+
+ iomuxc@53fa8000 {
+ compatible = "fsl,imx53-iomuxc-ard";
+ reg = <0x53fa8000 0x4000>;
+ };
+
+ uart0: uart@53fbc000 { /* UART1 */
+ status = "okay";
+ };
+ };
+
+ aips@60000000 { /* AIPS2 */
+ sdma@63fb0000 {
+ fsl,sdma-ram-script-name = "imx/sdma/sdma-imx53.bin";
+ };
+ };
+ };
+
+ eim-cs1@f4000000 {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ compatible = "fsl,eim-bus", "simple-bus";
+ reg = <0xf4000000 0x3ff0000>;
+ ranges;
+
+ lan9220@f4000000 {
+ compatible = "smsc,lan9220", "smsc,lan9115";
+ reg = <0xf4000000 0x2000000>;
+ phy-mode = "mii";
+ interrupt-parent = <&gpio1>;
+ interrupts = <31>;
+ reg-io-width = <4>;
+ smsc,irq-push-pull;
+ };
+ };
+
+ gpio-keys {
+ compatible = "gpio-keys";
+
+ home {
+ label = "Home";
+ gpios = <&gpio4 10 0>; /* GPIO5_10 */
+ linux,code = <102>; /* KEY_HOME */
+ gpio-key,wakeup;
+ };
+
+ back {
+ label = "Back";
+ gpios = <&gpio4 11 0>; /* GPIO5_11 */
+ linux,code = <158>; /* KEY_BACK */
+ gpio-key,wakeup;
+ };
+
+ program {
+ label = "Program";
+ gpios = <&gpio4 12 0>; /* GPIO5_12 */
+ linux,code = <362>; /* KEY_PROGRAM */
+ gpio-key,wakeup;
+ };
+
+ volume-up {
+ label = "Volume Up";
+ gpios = <&gpio4 13 0>; /* GPIO5_13 */
+ linux,code = <115>; /* KEY_VOLUMEUP */
+ };
+
+ volume-down {
+ label = "Volume Down";
+ gpios = <&gpio3 0 0>; /* GPIO4_0 */
+ linux,code = <114>; /* KEY_VOLUMEDOWN */
+ };
+ };
+};
diff --git a/arch/arm/boot/dts/imx53-evk.dts b/arch/arm/boot/dts/imx53-evk.dts
new file mode 100644
index 000000000000..3f3a88185ff8
--- /dev/null
+++ b/arch/arm/boot/dts/imx53-evk.dts
@@ -0,0 +1,120 @@
+/*
+ * Copyright 2011 Freescale Semiconductor, Inc.
+ * Copyright 2011 Linaro Ltd.
+ *
+ * The code contained herein is licensed under the GNU General Public
+ * License. You may obtain a copy of the GNU General Public License
+ * Version 2 or later at the following locations:
+ *
+ * http://www.opensource.org/licenses/gpl-license.html
+ * http://www.gnu.org/copyleft/gpl.html
+ */
+
+/dts-v1/;
+/include/ "imx53.dtsi"
+
+/ {
+ model = "Freescale i.MX53 Evaluation Kit";
+ compatible = "fsl,imx53-evk", "fsl,imx53";
+
+ chosen {
+ bootargs = "console=ttymxc0,115200 root=/dev/mmcblk0p3 rootwait";
+ };
+
+ memory {
+ reg = <0x70000000 0x80000000>;
+ };
+
+ soc {
+ aips@50000000 { /* AIPS1 */
+ spba@50000000 {
+ esdhc@50004000 { /* ESDHC1 */
+ cd-gpios = <&gpio2 13 0>; /* GPIO3_13 */
+ wp-gpios = <&gpio2 14 0>; /* GPIO3_14 */
+ status = "okay";
+ };
+
+ ecspi@50010000 { /* ECSPI1 */
+ fsl,spi-num-chipselects = <2>;
+ cs-gpios = <&gpio1 30 0>, /* GPIO2_30 */
+ <&gpio2 19 0>; /* GPIO3_19 */
+ status = "okay";
+
+ flash: at45db321d@1 {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ compatible = "atmel,at45db321d", "atmel,at45", "atmel,dataflash";
+ spi-max-frequency = <25000000>;
+ reg = <1>;
+
+ partition@0 {
+ label = "U-Boot";
+ reg = <0x0 0x40000>;
+ read-only;
+ };
+
+ partition@40000 {
+ label = "Kernel";
+ reg = <0x40000 0x3c0000>;
+ };
+ };
+ };
+
+ esdhc@50020000 { /* ESDHC3 */
+ cd-gpios = <&gpio2 11 0>; /* GPIO3_11 */
+ wp-gpios = <&gpio2 12 0>; /* GPIO3_12 */
+ status = "okay";
+ };
+ };
+
+ wdog@53f98000 { /* WDOG1 */
+ status = "okay";
+ };
+
+ iomuxc@53fa8000 {
+ compatible = "fsl,imx53-iomuxc-evk";
+ reg = <0x53fa8000 0x4000>;
+ };
+
+ uart0: uart@53fbc000 { /* UART1 */
+ status = "okay";
+ };
+ };
+
+ aips@60000000 { /* AIPS2 */
+ sdma@63fb0000 {
+ fsl,sdma-ram-script-name = "imx/sdma/sdma-imx53.bin";
+ };
+
+ i2c@63fc4000 { /* I2C2 */
+ status = "okay";
+
+ pmic: mc13892@08 {
+ compatible = "fsl,mc13892", "fsl,mc13xxx";
+ reg = <0x08>;
+ };
+
+ codec: sgtl5000@0a {
+ compatible = "fsl,sgtl5000";
+ reg = <0x0a>;
+ };
+ };
+
+ fec@63fec000 {
+ phy-mode = "rmii";
+ phy-reset-gpios = <&gpio6 6 0>; /* GPIO7_6 */
+ status = "okay";
+ };
+ };
+ };
+
+ leds {
+ compatible = "gpio-leds";
+
+ green {
+ label = "Heartbeat";
+ gpios = <&gpio6 7 0>; /* GPIO7_7 */
+ linux,default-trigger = "heartbeat";
+ };
+ };
+};
diff --git a/arch/arm/boot/dts/imx53-qsb.dts b/arch/arm/boot/dts/imx53-qsb.dts
new file mode 100644
index 000000000000..ae6de6d0c3f1
--- /dev/null
+++ b/arch/arm/boot/dts/imx53-qsb.dts
@@ -0,0 +1,125 @@
+/*
+ * Copyright 2011 Freescale Semiconductor, Inc.
+ * Copyright 2011 Linaro Ltd.
+ *
+ * The code contained herein is licensed under the GNU General Public
+ * License. You may obtain a copy of the GNU General Public License
+ * Version 2 or later at the following locations:
+ *
+ * http://www.opensource.org/licenses/gpl-license.html
+ * http://www.gnu.org/copyleft/gpl.html
+ */
+
+/dts-v1/;
+/include/ "imx53.dtsi"
+
+/ {
+ model = "Freescale i.MX53 Quick Start Board";
+ compatible = "fsl,imx53-qsb", "fsl,imx53";
+
+ chosen {
+ bootargs = "console=ttymxc0,115200 root=/dev/mmcblk0p3 rootwait";
+ };
+
+ memory {
+ reg = <0x70000000 0x40000000>;
+ };
+
+ soc {
+ aips@50000000 { /* AIPS1 */
+ spba@50000000 {
+ esdhc@50004000 { /* ESDHC1 */
+ cd-gpios = <&gpio2 13 0>; /* GPIO3_13 */
+ status = "okay";
+ };
+
+ esdhc@50020000 { /* ESDHC3 */
+ cd-gpios = <&gpio2 11 0>; /* GPIO3_11 */
+ wp-gpios = <&gpio2 12 0>; /* GPIO3_12 */
+ status = "okay";
+ };
+ };
+
+ wdog@53f98000 { /* WDOG1 */
+ status = "okay";
+ };
+
+ iomuxc@53fa8000 {
+ compatible = "fsl,imx53-iomuxc-qsb";
+ reg = <0x53fa8000 0x4000>;
+ };
+
+ uart0: uart@53fbc000 { /* UART1 */
+ status = "okay";
+ };
+ };
+
+ aips@60000000 { /* AIPS2 */
+ sdma@63fb0000 {
+ fsl,sdma-ram-script-name = "imx/sdma/sdma-imx53.bin";
+ };
+
+ i2c@63fc4000 { /* I2C2 */
+ status = "okay";
+
+ codec: sgtl5000@0a {
+ compatible = "fsl,sgtl5000";
+ reg = <0x0a>;
+ };
+ };
+
+ i2c@63fc8000 { /* I2C1 */
+ status = "okay";
+
+ accelerometer: mma8450@1c {
+ compatible = "fsl,mma8450";
+ reg = <0x1c>;
+ };
+
+ pmic: dialog@48 {
+ compatible = "dialog,da9053", "dialog,da9052";
+ reg = <0x48>;
+ };
+ };
+
+ fec@63fec000 {
+ phy-mode = "rmii";
+ phy-reset-gpios = <&gpio6 6 0>; /* GPIO7_6 */
+ status = "okay";
+ };
+ };
+ };
+
+ gpio-keys {
+ compatible = "gpio-keys";
+
+ power {
+ label = "Power Button";
+ gpios = <&gpio0 8 0>; /* GPIO1_8 */
+ linux,code = <116>; /* KEY_POWER */
+ gpio-key,wakeup;
+ };
+
+ volume-up {
+ label = "Volume Up";
+ gpios = <&gpio1 14 0>; /* GPIO2_14 */
+ linux,code = <115>; /* KEY_VOLUMEUP */
+ };
+
+ volume-down {
+ label = "Volume Down";
+ gpios = <&gpio1 15 0>; /* GPIO2_15 */
+ linux,code = <114>; /* KEY_VOLUMEDOWN */
+ };
+ };
+
+ leds {
+ compatible = "gpio-leds";
+
+ user {
+ label = "Heartbeat";
+ gpios = <&gpio6 7 0>; /* GPIO7_7 */
+ linux,default-trigger = "heartbeat";
+ };
+ };
+};
diff --git a/arch/arm/boot/dts/imx53-smd.dts b/arch/arm/boot/dts/imx53-smd.dts
new file mode 100644
index 000000000000..b1c062eea715
--- /dev/null
+++ b/arch/arm/boot/dts/imx53-smd.dts
@@ -0,0 +1,169 @@
+/*
+ * Copyright 2011 Freescale Semiconductor, Inc.
+ * Copyright 2011 Linaro Ltd.
+ *
+ * The code contained herein is licensed under the GNU General Public
+ * License. You may obtain a copy of the GNU General Public License
+ * Version 2 or later at the following locations:
+ *
+ * http://www.opensource.org/licenses/gpl-license.html
+ * http://www.gnu.org/copyleft/gpl.html
+ */
+
+/dts-v1/;
+/include/ "imx53.dtsi"
+
+/ {
+ model = "Freescale i.MX53 Smart Mobile Reference Design Board";
+ compatible = "fsl,imx53-smd", "fsl,imx53";
+
+ chosen {
+ bootargs = "console=ttymxc0,115200 root=/dev/mmcblk0p3 rootwait";
+ };
+
+ memory {
+ reg = <0x70000000 0x40000000>;
+ };
+
+ soc {
+ aips@50000000 { /* AIPS1 */
+ spba@50000000 {
+ esdhc@50004000 { /* ESDHC1 */
+ cd-gpios = <&gpio2 13 0>; /* GPIO3_13 */
+ wp-gpios = <&gpio3 11 0>; /* GPIO4_11 */
+ status = "okay";
+ };
+
+ esdhc@50008000 { /* ESDHC2 */
+ fsl,card-wired;
+ status = "okay";
+ };
+
+ uart2: uart@5000c000 { /* UART3 */
+ fsl,uart-has-rtscts;
+ status = "okay";
+ };
+
+ ecspi@50010000 { /* ECSPI1 */
+ fsl,spi-num-chipselects = <2>;
+ cs-gpios = <&gpio1 30 0>, /* GPIO2_30 */
+ <&gpio2 19 0>; /* GPIO3_19 */
+ status = "okay";
+
+ zigbee: mc1323@0 {
+ compatible = "fsl,mc1323";
+ spi-max-frequency = <8000000>;
+ reg = <0>;
+ };
+
+ flash: m25p32@1 {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ compatible = "st,m25p32", "st,m25p";
+ spi-max-frequency = <20000000>;
+ reg = <1>;
+
+ partition@0 {
+ label = "U-Boot";
+ reg = <0x0 0x40000>;
+ read-only;
+ };
+
+ partition@40000 {
+ label = "Kernel";
+ reg = <0x40000 0x3c0000>;
+ };
+ };
+ };
+
+ esdhc@50020000 { /* ESDHC3 */
+ fsl,card-wired;
+ status = "okay";
+ };
+ };
+
+ wdog@53f98000 { /* WDOG1 */
+ status = "okay";
+ };
+
+ iomuxc@53fa8000 {
+ compatible = "fsl,imx53-iomuxc-smd";
+ reg = <0x53fa8000 0x4000>;
+ };
+
+ uart0: uart@53fbc000 { /* UART1 */
+ status = "okay";
+ };
+
+ uart1: uart@53fc0000 { /* UART2 */
+ status = "okay";
+ };
+ };
+
+ aips@60000000 { /* AIPS2 */
+ sdma@63fb0000 {
+ fsl,sdma-ram-script-name = "imx/sdma/sdma-imx53.bin";
+ };
+
+ i2c@63fc4000 { /* I2C2 */
+ status = "okay";
+
+ codec: sgtl5000@0a {
+ compatible = "fsl,sgtl5000";
+ reg = <0x0a>;
+ };
+
+ magnetometer: mag3110@0e {
+ compatible = "fsl,mag3110";
+ reg = <0x0e>;
+ };
+
+ touchkey: mpr121@5a {
+ compatible = "fsl,mpr121";
+ reg = <0x5a>;
+ };
+ };
+
+ i2c@63fc8000 { /* I2C1 */
+ status = "okay";
+
+ accelerometer: mma8450@1c {
+ compatible = "fsl,mma8450";
+ reg = <0x1c>;
+ };
+
+ camera: ov5642@3c {
+ compatible = "ovti,ov5642";
+ reg = <0x3c>;
+ };
+
+ pmic: dialog@48 {
+ compatible = "dialog,da9053", "dialog,da9052";
+ reg = <0x48>;
+ };
+ };
+
+ fec@63fec000 {
+ phy-mode = "rmii";
+ phy-reset-gpios = <&gpio6 6 0>; /* GPIO7_6 */
+ status = "okay";
+ };
+ };
+ };
+
+ gpio-keys {
+ compatible = "gpio-keys";
+
+ volume-up {
+ label = "Volume Up";
+ gpios = <&gpio1 14 0>; /* GPIO2_14 */
+ linux,code = <115>; /* KEY_VOLUMEUP */
+ };
+
+ volume-down {
+ label = "Volume Down";
+ gpios = <&gpio1 15 0>; /* GPIO2_15 */
+ linux,code = <114>; /* KEY_VOLUMEDOWN */
+ };
+ };
+};
diff --git a/arch/arm/boot/dts/imx53.dtsi b/arch/arm/boot/dts/imx53.dtsi
new file mode 100644
index 000000000000..099cd84ee372
--- /dev/null
+++ b/arch/arm/boot/dts/imx53.dtsi
@@ -0,0 +1,301 @@
+/*
+ * Copyright 2011 Freescale Semiconductor, Inc.
+ * Copyright 2011 Linaro Ltd.
+ *
+ * The code contained herein is licensed under the GNU General Public
+ * License. You may obtain a copy of the GNU General Public License
+ * Version 2 or later at the following locations:
+ *
+ * http://www.opensource.org/licenses/gpl-license.html
+ * http://www.gnu.org/copyleft/gpl.html
+ */
+
+/include/ "skeleton.dtsi"
+
+/ {
+ aliases {
+ serial0 = &uart0;
+ serial1 = &uart1;
+ serial2 = &uart2;
+ serial3 = &uart3;
+ serial4 = &uart4;
+ };
+
+ tzic: tz-interrupt-controller@0fffc000 {
+ compatible = "fsl,imx53-tzic", "fsl,tzic";
+ interrupt-controller;
+ #interrupt-cells = <1>;
+ reg = <0x0fffc000 0x4000>;
+ };
+
+ clocks {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ ckil {
+ compatible = "fsl,imx-ckil", "fixed-clock";
+ clock-frequency = <32768>;
+ };
+
+ ckih1 {
+ compatible = "fsl,imx-ckih1", "fixed-clock";
+ clock-frequency = <22579200>;
+ };
+
+ ckih2 {
+ compatible = "fsl,imx-ckih2", "fixed-clock";
+ clock-frequency = <0>;
+ };
+
+ osc {
+ compatible = "fsl,imx-osc", "fixed-clock";
+ clock-frequency = <24000000>;
+ };
+ };
+
+ soc {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ compatible = "simple-bus";
+ interrupt-parent = <&tzic>;
+ ranges;
+
+ aips@50000000 { /* AIPS1 */
+ compatible = "fsl,aips-bus", "simple-bus";
+ #address-cells = <1>;
+ #size-cells = <1>;
+ reg = <0x50000000 0x10000000>;
+ ranges;
+
+ spba@50000000 {
+ compatible = "fsl,spba-bus", "simple-bus";
+ #address-cells = <1>;
+ #size-cells = <1>;
+ reg = <0x50000000 0x40000>;
+ ranges;
+
+ esdhc@50004000 { /* ESDHC1 */
+ compatible = "fsl,imx53-esdhc";
+ reg = <0x50004000 0x4000>;
+ interrupts = <1>;
+ status = "disabled";
+ };
+
+ esdhc@50008000 { /* ESDHC2 */
+ compatible = "fsl,imx53-esdhc";
+ reg = <0x50008000 0x4000>;
+ interrupts = <2>;
+ status = "disabled";
+ };
+
+ uart2: uart@5000c000 { /* UART3 */
+ compatible = "fsl,imx53-uart", "fsl,imx21-uart";
+ reg = <0x5000c000 0x4000>;
+ interrupts = <33>;
+ status = "disabled";
+ };
+
+ ecspi@50010000 { /* ECSPI1 */
+ #address-cells = <1>;
+ #size-cells = <0>;
+ compatible = "fsl,imx53-ecspi", "fsl,imx51-ecspi";
+ reg = <0x50010000 0x4000>;
+ interrupts = <36>;
+ status = "disabled";
+ };
+
+ esdhc@50020000 { /* ESDHC3 */
+ compatible = "fsl,imx53-esdhc";
+ reg = <0x50020000 0x4000>;
+ interrupts = <3>;
+ status = "disabled";
+ };
+
+ esdhc@50024000 { /* ESDHC4 */
+ compatible = "fsl,imx53-esdhc";
+ reg = <0x50024000 0x4000>;
+ interrupts = <4>;
+ status = "disabled";
+ };
+ };
+
+ gpio0: gpio@53f84000 { /* GPIO1 */
+ compatible = "fsl,imx53-gpio", "fsl,imx31-gpio";
+ reg = <0x53f84000 0x4000>;
+ interrupts = <50 51>;
+ gpio-controller;
+ #gpio-cells = <2>;
+ interrupt-controller;
+ #interrupt-cells = <1>;
+ };
+
+ gpio1: gpio@53f88000 { /* GPIO2 */
+ compatible = "fsl,imx53-gpio", "fsl,imx31-gpio";
+ reg = <0x53f88000 0x4000>;
+ interrupts = <52 53>;
+ gpio-controller;
+ #gpio-cells = <2>;
+ interrupt-controller;
+ #interrupt-cells = <1>;
+ };
+
+ gpio2: gpio@53f8c000 { /* GPIO3 */
+ compatible = "fsl,imx53-gpio", "fsl,imx31-gpio";
+ reg = <0x53f8c000 0x4000>;
+ interrupts = <54 55>;
+ gpio-controller;
+ #gpio-cells = <2>;
+ interrupt-controller;
+ #interrupt-cells = <1>;
+ };
+
+ gpio3: gpio@53f90000 { /* GPIO4 */
+ compatible = "fsl,imx53-gpio", "fsl,imx31-gpio";
+ reg = <0x53f90000 0x4000>;
+ interrupts = <56 57>;
+ gpio-controller;
+ #gpio-cells = <2>;
+ interrupt-controller;
+ #interrupt-cells = <1>;
+ };
+
+ wdog@53f98000 { /* WDOG1 */
+ compatible = "fsl,imx53-wdt", "fsl,imx21-wdt";
+ reg = <0x53f98000 0x4000>;
+ interrupts = <58>;
+ status = "disabled";
+ };
+
+ wdog@53f9c000 { /* WDOG2 */
+ compatible = "fsl,imx53-wdt", "fsl,imx21-wdt";
+ reg = <0x53f9c000 0x4000>;
+ interrupts = <59>;
+ status = "disabled";
+ };
+
+ uart0: uart@53fbc000 { /* UART1 */
+ compatible = "fsl,imx53-uart", "fsl,imx21-uart";
+ reg = <0x53fbc000 0x4000>;
+ interrupts = <31>;
+ status = "disabled";
+ };
+
+ uart1: uart@53fc0000 { /* UART2 */
+ compatible = "fsl,imx53-uart", "fsl,imx21-uart";
+ reg = <0x53fc0000 0x4000>;
+ interrupts = <32>;
+ status = "disabled";
+ };
+
+ gpio4: gpio@53fdc000 { /* GPIO5 */
+ compatible = "fsl,imx53-gpio", "fsl,imx31-gpio";
+ reg = <0x53fdc000 0x4000>;
+ interrupts = <103 104>;
+ gpio-controller;
+ #gpio-cells = <2>;
+ interrupt-controller;
+ #interrupt-cells = <1>;
+ };
+
+ gpio5: gpio@53fe0000 { /* GPIO6 */
+ compatible = "fsl,imx53-gpio", "fsl,imx31-gpio";
+ reg = <0x53fe0000 0x4000>;
+ interrupts = <105 106>;
+ gpio-controller;
+ #gpio-cells = <2>;
+ interrupt-controller;
+ #interrupt-cells = <1>;
+ };
+
+ gpio6: gpio@53fe4000 { /* GPIO7 */
+ compatible = "fsl,imx53-gpio", "fsl,imx31-gpio";
+ reg = <0x53fe4000 0x4000>;
+ interrupts = <107 108>;
+ gpio-controller;
+ #gpio-cells = <2>;
+ interrupt-controller;
+ #interrupt-cells = <1>;
+ };
+
+ i2c@53fec000 { /* I2C3 */
+ #address-cells = <1>;
+ #size-cells = <0>;
+ compatible = "fsl,imx53-i2c", "fsl,imx1-i2c";
+ reg = <0x53fec000 0x4000>;
+ interrupts = <64>;
+ status = "disabled";
+ };
+
+ uart3: uart@53ff0000 { /* UART4 */
+ compatible = "fsl,imx53-uart", "fsl,imx21-uart";
+ reg = <0x53ff0000 0x4000>;
+ interrupts = <13>;
+ status = "disabled";
+ };
+ };
+
+ aips@60000000 { /* AIPS2 */
+ compatible = "fsl,aips-bus", "simple-bus";
+ #address-cells = <1>;
+ #size-cells = <1>;
+ reg = <0x60000000 0x10000000>;
+ ranges;
+
+ uart4: uart@63f90000 { /* UART5 */
+ compatible = "fsl,imx53-uart", "fsl,imx21-uart";
+ reg = <0x63f90000 0x4000>;
+ interrupts = <86>;
+ status = "disabled";
+ };
+
+ ecspi@63fac000 { /* ECSPI2 */
+ #address-cells = <1>;
+ #size-cells = <0>;
+ compatible = "fsl,imx53-ecspi", "fsl,imx51-ecspi";
+ reg = <0x63fac000 0x4000>;
+ interrupts = <37>;
+ status = "disabled";
+ };
+
+ sdma@63fb0000 {
+ compatible = "fsl,imx53-sdma", "fsl,imx35-sdma";
+ reg = <0x63fb0000 0x4000>;
+ interrupts = <6>;
+ };
+
+ cspi@63fc0000 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ compatible = "fsl,imx53-cspi", "fsl,imx35-cspi";
+ reg = <0x63fc0000 0x4000>;
+ interrupts = <38>;
+ status = "disabled";
+ };
+
+ i2c@63fc4000 { /* I2C2 */
+ #address-cells = <1>;
+ #size-cells = <0>;
+ compatible = "fsl,imx53-i2c", "fsl,imx1-i2c";
+ reg = <0x63fc4000 0x4000>;
+ interrupts = <63>;
+ status = "disabled";
+ };
+
+ i2c@63fc8000 { /* I2C1 */
+ #address-cells = <1>;
+ #size-cells = <0>;
+ compatible = "fsl,imx53-i2c", "fsl,imx1-i2c";
+ reg = <0x63fc8000 0x4000>;
+ interrupts = <62>;
+ status = "disabled";
+ };
+
+ fec@63fec000 {
+ compatible = "fsl,imx53-fec", "fsl,imx25-fec";
+ reg = <0x63fec000 0x4000>;
+ interrupts = <87>;
+ status = "disabled";
+ };
+ };
+ };
+};
diff --git a/arch/arm/boot/dts/msm8660-surf.dts b/arch/arm/boot/dts/msm8660-surf.dts
new file mode 100644
index 000000000000..15ded0deaa79
--- /dev/null
+++ b/arch/arm/boot/dts/msm8660-surf.dts
@@ -0,0 +1,24 @@
+/dts-v1/;
+
+/include/ "skeleton.dtsi"
+
+/ {
+ model = "Qualcomm MSM8660 SURF";
+ compatible = "qcom,msm8660-surf", "qcom,msm8660";
+ interrupt-parent = <&intc>;
+
+ intc: interrupt-controller@02080000 {
+ compatible = "qcom,msm-8660-qgic";
+ interrupt-controller;
+ #interrupt-cells = <1>;
+ reg = < 0x02080000 0x1000 >,
+ < 0x02081000 0x1000 >;
+ };
+
+ serial@19c400000 {
+ compatible = "qcom,msm-hsuart", "qcom,msm-uart";
+ reg = <0x19c40000 0x1000>,
+ <0x19c00000 0x1000>;
+ interrupts = <195>;
+ };
+};
diff --git a/arch/arm/boot/dts/omap3-beagle.dts b/arch/arm/boot/dts/omap3-beagle.dts
new file mode 100644
index 000000000000..9486be62bcdd
--- /dev/null
+++ b/arch/arm/boot/dts/omap3-beagle.dts
@@ -0,0 +1,29 @@
+/*
+ * Copyright (C) 2011 Texas Instruments Incorporated - http://www.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.
+ */
+/dts-v1/;
+
+/include/ "omap3.dtsi"
+
+/ {
+ model = "TI OMAP3 BeagleBoard";
+ compatible = "ti,omap3-beagle", "ti,omap3";
+
+ /*
+ * Since the initial device tree board file does not create any
+ * devices (MMC, network...), the only way to boot is to provide a
+ * ramdisk.
+ */
+ chosen {
+ bootargs = "root=/dev/ram0 rw console=ttyO2,115200n8 initrd=0x81600000,20M ramdisk_size=20480 no_console_suspend debug earlyprintk";
+ };
+
+ memory {
+ device_type = "memory";
+ reg = <0x80000000 0x20000000>; /* 512 MB */
+ };
+};
diff --git a/arch/arm/boot/dts/omap3.dtsi b/arch/arm/boot/dts/omap3.dtsi
new file mode 100644
index 000000000000..d202bb5ec7ef
--- /dev/null
+++ b/arch/arm/boot/dts/omap3.dtsi
@@ -0,0 +1,63 @@
+/*
+ * Device Tree Source for OMAP3 SoC
+ *
+ * Copyright (C) 2011 Texas Instruments Incorporated - http://www.ti.com/
+ *
+ * This file is licensed under the terms of the GNU General Public License
+ * version 2. This program is licensed "as is" without any warranty of any
+ * kind, whether express or implied.
+ */
+
+/include/ "skeleton.dtsi"
+
+/ {
+ compatible = "ti,omap3430", "ti,omap3";
+
+ cpus {
+ cpu@0 {
+ compatible = "arm,cortex-a8";
+ };
+ };
+
+ /*
+ * The soc node represents the soc top level view. It is uses for IPs
+ * that are not memory mapped in the MPU view or for the MPU itself.
+ */
+ soc {
+ compatible = "ti,omap-infra";
+ mpu {
+ compatible = "ti,omap3-mpu";
+ ti,hwmods = "mpu";
+ };
+
+ iva {
+ compatible = "ti,iva2.2";
+ ti,hwmods = "iva";
+
+ dsp {
+ compatible = "ti,omap3-c64";
+ };
+ };
+ };
+
+ /*
+ * XXX: Use a flat representation of the OMAP3 interconnect.
+ * The real OMAP interconnect network is quite complex.
+ * Since that will not bring real advantage to represent that in DT for
+ * the moment, just use a fake OCP bus entry to represent the whole bus
+ * hierarchy.
+ */
+ ocp {
+ compatible = "simple-bus";
+ #address-cells = <1>;
+ #size-cells = <1>;
+ ranges;
+ ti,hwmods = "l3_main";
+
+ intc: interrupt-controller@1 {
+ compatible = "ti,omap3-intc";
+ interrupt-controller;
+ #interrupt-cells = <1>;
+ };
+ };
+};
diff --git a/arch/arm/boot/dts/omap4-panda.dts b/arch/arm/boot/dts/omap4-panda.dts
new file mode 100644
index 000000000000..c7026578ce7d
--- /dev/null
+++ b/arch/arm/boot/dts/omap4-panda.dts
@@ -0,0 +1,29 @@
+/*
+ * Copyright (C) 2011 Texas Instruments Incorporated - http://www.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.
+ */
+/dts-v1/;
+
+/include/ "omap4.dtsi"
+
+/ {
+ model = "TI OMAP4 PandaBoard";
+ compatible = "ti,omap4-panda", "ti,omap4430", "ti,omap4";
+
+ /*
+ * Since the initial device tree board file does not create any
+ * devices (MMC, network...), the only way to boot is to provide a
+ * ramdisk.
+ */
+ chosen {
+ bootargs = "root=/dev/ram0 rw console=ttyO2,115200n8 initrd=0x81600000,20M ramdisk_size=20480 no_console_suspend debug";
+ };
+
+ memory {
+ device_type = "memory";
+ reg = <0x80000000 0x40000000>; /* 1 GB */
+ };
+};
diff --git a/arch/arm/boot/dts/omap4-sdp.dts b/arch/arm/boot/dts/omap4-sdp.dts
new file mode 100644
index 000000000000..066e28c90328
--- /dev/null
+++ b/arch/arm/boot/dts/omap4-sdp.dts
@@ -0,0 +1,29 @@
+/*
+ * Copyright (C) 2011 Texas Instruments Incorporated - http://www.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.
+ */
+/dts-v1/;
+
+/include/ "omap4.dtsi"
+
+/ {
+ model = "TI OMAP4 SDP board";
+ compatible = "ti,omap4-sdp", "ti,omap4430", "ti,omap4";
+
+ /*
+ * Since the initial device tree board file does not create any
+ * devices (MMC, network...), the only way to boot is to provide a
+ * ramdisk.
+ */
+ chosen {
+ bootargs = "root=/dev/ram0 rw console=ttyO2,115200n8 initrd=0x81600000,20M ramdisk_size=20480 no_console_suspend debug";
+ };
+
+ memory {
+ device_type = "memory";
+ reg = <0x80000000 0x40000000>; /* 1 GB */
+ };
+};
diff --git a/arch/arm/boot/dts/omap4.dtsi b/arch/arm/boot/dts/omap4.dtsi
new file mode 100644
index 000000000000..4c61c829043a
--- /dev/null
+++ b/arch/arm/boot/dts/omap4.dtsi
@@ -0,0 +1,103 @@
+/*
+ * Copyright (C) 2011 Texas Instruments Incorporated - http://www.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.
+ */
+
+/*
+ * Carveout for multimedia usecases
+ * It should be the last 48MB of the first 512MB memory part
+ * In theory, it should not even exist. That zone should be reserved
+ * dynamically during the .reserve callback.
+ */
+/memreserve/ 0x9d000000 0x03000000;
+
+/include/ "skeleton.dtsi"
+
+/ {
+ compatible = "ti,omap4430", "ti,omap4";
+ interrupt-parent = <&gic>;
+
+ aliases {
+ };
+
+ cpus {
+ cpu@0 {
+ compatible = "arm,cortex-a9";
+ };
+ cpu@1 {
+ compatible = "arm,cortex-a9";
+ };
+ };
+
+ /*
+ * The soc node represents the soc top level view. It is uses for IPs
+ * that are not memory mapped in the MPU view or for the MPU itself.
+ */
+ soc {
+ compatible = "ti,omap-infra";
+ mpu {
+ compatible = "ti,omap4-mpu";
+ ti,hwmods = "mpu";
+ };
+
+ dsp {
+ compatible = "ti,omap3-c64";
+ ti,hwmods = "dsp";
+ };
+
+ iva {
+ compatible = "ti,ivahd";
+ ti,hwmods = "iva";
+ };
+ };
+
+ /*
+ * XXX: Use a flat representation of the OMAP4 interconnect.
+ * The real OMAP interconnect network is quite complex.
+ *
+ * MPU -+-- MPU_PRIVATE - GIC, L2
+ * |
+ * +----------------+----------+
+ * | | |
+ * + +- EMIF - DDR |
+ * | | |
+ * | + +--------+
+ * | | |
+ * | +- L4_ABE - AESS, MCBSP, TIMERs...
+ * | |
+ * +- L3_MAIN --+- L4_CORE - IPs...
+ * |
+ * +- L4_PER - IPs...
+ * |
+ * +- L4_CFG -+- L4_WKUP - IPs...
+ * | |
+ * | +- IPs...
+ * +- IPU ----+
+ * | |
+ * +- DSP ----+
+ * | |
+ * +- DSS ----+
+ *
+ * Since that will not bring real advantage to represent that in DT for
+ * the moment, just use a fake OCP bus entry to represent the whole bus
+ * hierarchy.
+ */
+ ocp {
+ compatible = "ti,omap4-l3-noc", "simple-bus";
+ #address-cells = <1>;
+ #size-cells = <1>;
+ ranges;
+ ti,hwmods = "l3_main_1", "l3_main_2", "l3_main_3";
+
+ gic: interrupt-controller@48241000 {
+ compatible = "arm,cortex-a9-gic";
+ interrupt-controller;
+ #interrupt-cells = <1>;
+ reg = <0x48241000 0x1000>,
+ <0x48240100 0x0100>;
+ };
+ };
+};
diff --git a/arch/arm/boot/dts/usb_a9g20.dts b/arch/arm/boot/dts/usb_a9g20.dts
new file mode 100644
index 000000000000..d66e2c00ac35
--- /dev/null
+++ b/arch/arm/boot/dts/usb_a9g20.dts
@@ -0,0 +1,30 @@
+/*
+ * usb_a9g20.dts - Device Tree file for Caloa USB A9G20 board
+ *
+ * Copyright (C) 2011 Jean-Christophe PLAGNIOL-VILLARD <plagnioj@jcrosoft.com>
+ *
+ * Licensed under GPLv2 or later.
+ */
+/dts-v1/;
+/include/ "at91sam9g20.dtsi"
+
+/ {
+ model = "Calao USB A9G20";
+ compatible = "calao,usb-a9g20", "atmel,at91sam9g20", "atmel,at91sam9";
+
+ chosen {
+ bootargs = "mem=64M console=ttyS0,115200 mtdparts=atmel_nand:128k(at91bootstrap),256k(barebox)ro,128k(bareboxenv),128k(bareboxenv2),4M(kernel),120M(rootfs),-(data) root=/dev/mtdblock5 rw rootfstype=ubifs";
+ };
+
+ memory@20000000 {
+ reg = <0x20000000 0x4000000>;
+ };
+
+ ahb {
+ apb {
+ dbgu: serial@fffff200 {
+ status = "okay";
+ };
+ };
+ };
+};
diff --git a/arch/arm/common/vic.c b/arch/arm/common/vic.c
index 7aa4262ada7a..197f81c77351 100644
--- a/arch/arm/common/vic.c
+++ b/arch/arm/common/vic.c
@@ -259,7 +259,6 @@ static void __init vic_disable(void __iomem *base)
writel(0, base + VIC_INT_SELECT);
writel(0, base + VIC_INT_ENABLE);
writel(~0, base + VIC_INT_ENABLE_CLEAR);
- writel(0, base + VIC_IRQ_STATUS);
writel(0, base + VIC_ITCR);
writel(~0, base + VIC_INT_SOFT_CLEAR);
}
diff --git a/arch/arm/include/asm/device.h b/arch/arm/include/asm/device.h
index 9f390ce335cb..b5c9f5b1f6a3 100644
--- a/arch/arm/include/asm/device.h
+++ b/arch/arm/include/asm/device.h
@@ -12,7 +12,12 @@ struct dev_archdata {
#endif
};
+struct omap_device;
+
struct pdev_archdata {
+#ifdef CONFIG_ARCH_OMAP
+ struct omap_device *od;
+#endif
};
#endif
diff --git a/arch/arm/include/asm/localtimer.h b/arch/arm/include/asm/localtimer.h
index f5e1cec7e35c..c6a18424888e 100644
--- a/arch/arm/include/asm/localtimer.h
+++ b/arch/arm/include/asm/localtimer.h
@@ -10,6 +10,7 @@
#ifndef __ASM_ARM_LOCALTIMER_H
#define __ASM_ARM_LOCALTIMER_H
+#include <linux/errno.h>
#include <linux/interrupt.h>
struct clock_event_device;
diff --git a/arch/arm/kernel/perf_event_v7.c b/arch/arm/kernel/perf_event_v7.c
index 98b75738345e..1ef6d0034b85 100644
--- a/arch/arm/kernel/perf_event_v7.c
+++ b/arch/arm/kernel/perf_event_v7.c
@@ -324,8 +324,8 @@ static const unsigned armv7_a9_perf_map[PERF_COUNT_HW_MAX] = {
[PERF_COUNT_HW_CPU_CYCLES] = ARMV7_PERFCTR_CPU_CYCLES,
[PERF_COUNT_HW_INSTRUCTIONS] =
ARMV7_PERFCTR_INST_OUT_OF_RENAME_STAGE,
- [PERF_COUNT_HW_CACHE_REFERENCES] = ARMV7_PERFCTR_COHERENT_LINE_HIT,
- [PERF_COUNT_HW_CACHE_MISSES] = ARMV7_PERFCTR_COHERENT_LINE_MISS,
+ [PERF_COUNT_HW_CACHE_REFERENCES] = ARMV7_PERFCTR_DCACHE_ACCESS,
+ [PERF_COUNT_HW_CACHE_MISSES] = ARMV7_PERFCTR_DCACHE_REFILL,
[PERF_COUNT_HW_BRANCH_INSTRUCTIONS] = ARMV7_PERFCTR_PC_WRITE,
[PERF_COUNT_HW_BRANCH_MISSES] = ARMV7_PERFCTR_PC_BRANCH_MIS_PRED,
[PERF_COUNT_HW_BUS_CYCLES] = ARMV7_PERFCTR_CLOCK_CYCLES,
diff --git a/arch/arm/mach-at91/Kconfig b/arch/arm/mach-at91/Kconfig
index 22484670e7ba..4b59d96e1cd8 100644
--- a/arch/arm/mach-at91/Kconfig
+++ b/arch/arm/mach-at91/Kconfig
@@ -442,6 +442,17 @@ endif
# ----------------------------------------------------------
+comment "Generic Board Type"
+
+config MACH_AT91SAM_DT
+ bool "Atmel AT91SAM Evaluation Kits with device-tree support"
+ select USE_OF
+ help
+ Select this if you want to experiment device-tree with
+ an Atmel Evaluation Kit.
+
+# ----------------------------------------------------------
+
comment "AT91 Board Options"
config MTD_AT91_DATAFLASH_CARD
diff --git a/arch/arm/mach-at91/Makefile b/arch/arm/mach-at91/Makefile
index bf57e8b1c9d0..3ff245ebcad1 100644
--- a/arch/arm/mach-at91/Makefile
+++ b/arch/arm/mach-at91/Makefile
@@ -74,6 +74,9 @@ obj-$(CONFIG_MACH_SNAPPER_9260) += board-snapper9260.o
# AT91SAM9G45 board-specific support
obj-$(CONFIG_MACH_AT91SAM9M10G45EK) += board-sam9m10g45ek.o
+# AT91SAM board with device-tree
+obj-$(CONFIG_MACH_AT91SAM_DT) += board-dt.o
+
# AT91CAP9 board-specific support
obj-$(CONFIG_MACH_AT91CAP9ADK) += board-cap9adk.o
diff --git a/arch/arm/mach-at91/Makefile.boot b/arch/arm/mach-at91/Makefile.boot
index 3462b815054a..08c665affde4 100644
--- a/arch/arm/mach-at91/Makefile.boot
+++ b/arch/arm/mach-at91/Makefile.boot
@@ -16,3 +16,5 @@ else
params_phys-y := 0x20000100
initrd_phys-y := 0x20410000
endif
+
+dtb-$(CONFIG_MACH_AT91SAM_DT) += at91sam9m10g45ek.dtb usb_a9g20.dtb
diff --git a/arch/arm/mach-at91/at91sam9260.c b/arch/arm/mach-at91/at91sam9260.c
index cb397be14448..f4518b49cb82 100644
--- a/arch/arm/mach-at91/at91sam9260.c
+++ b/arch/arm/mach-at91/at91sam9260.c
@@ -199,6 +199,14 @@ static struct clk_lookup periph_clocks_lookups[] = {
CLKDEV_CON_DEV_ID("t4_clk", "atmel_tcb.1", &tc4_clk),
CLKDEV_CON_DEV_ID("t5_clk", "atmel_tcb.1", &tc5_clk),
CLKDEV_CON_DEV_ID("pclk", "ssc.0", &ssc_clk),
+ /* more usart lookup table for DT entries */
+ CLKDEV_CON_DEV_ID("usart", "fffff200.serial", &mck),
+ CLKDEV_CON_DEV_ID("usart", "fffb0000.serial", &usart0_clk),
+ CLKDEV_CON_DEV_ID("usart", "fffb4000.serial", &usart1_clk),
+ CLKDEV_CON_DEV_ID("usart", "fffb8000.serial", &usart2_clk),
+ CLKDEV_CON_DEV_ID("usart", "fffd0000.serial", &usart3_clk),
+ CLKDEV_CON_DEV_ID("usart", "fffd4000.serial", &usart4_clk),
+ CLKDEV_CON_DEV_ID("usart", "fffd8000.serial", &usart5_clk),
};
static struct clk_lookup usart_clocks_lookups[] = {
diff --git a/arch/arm/mach-at91/at91sam9g45.c b/arch/arm/mach-at91/at91sam9g45.c
index 1532b508c814..0fe1c305e082 100644
--- a/arch/arm/mach-at91/at91sam9g45.c
+++ b/arch/arm/mach-at91/at91sam9g45.c
@@ -216,6 +216,12 @@ static struct clk_lookup periph_clocks_lookups[] = {
CLKDEV_CON_DEV_ID("t0_clk", "atmel_tcb.1", &tcb0_clk),
CLKDEV_CON_DEV_ID("pclk", "ssc.0", &ssc0_clk),
CLKDEV_CON_DEV_ID("pclk", "ssc.1", &ssc1_clk),
+ /* more usart lookup table for DT entries */
+ CLKDEV_CON_DEV_ID("usart", "ffffee00.serial", &mck),
+ CLKDEV_CON_DEV_ID("usart", "fff8c000.serial", &usart0_clk),
+ CLKDEV_CON_DEV_ID("usart", "fff90000.serial", &usart1_clk),
+ CLKDEV_CON_DEV_ID("usart", "fff94000.serial", &usart2_clk),
+ CLKDEV_CON_DEV_ID("usart", "fff98000.serial", &usart3_clk),
};
static struct clk_lookup usart_clocks_lookups[] = {
diff --git a/arch/arm/mach-at91/board-dt.c b/arch/arm/mach-at91/board-dt.c
new file mode 100644
index 000000000000..0b7d32778210
--- /dev/null
+++ b/arch/arm/mach-at91/board-dt.c
@@ -0,0 +1,123 @@
+/*
+ * Setup code for AT91SAM Evaluation Kits with Device Tree support
+ *
+ * Covers: * AT91SAM9G45-EKES board
+ * * AT91SAM9M10-EKES board
+ * * AT91SAM9M10G45-EK board
+ *
+ * Copyright (C) 2011 Atmel,
+ * 2011 Nicolas Ferre <nicolas.ferre@atmel.com>
+ *
+ * Licensed under GPLv2 or later.
+ */
+
+#include <linux/types.h>
+#include <linux/init.h>
+#include <linux/module.h>
+#include <linux/gpio.h>
+#include <linux/irqdomain.h>
+#include <linux/of_irq.h>
+#include <linux/of_platform.h>
+
+#include <mach/hardware.h>
+#include <mach/board.h>
+#include <mach/system_rev.h>
+#include <mach/at91sam9_smc.h>
+
+#include <asm/setup.h>
+#include <asm/irq.h>
+#include <asm/mach/arch.h>
+#include <asm/mach/map.h>
+#include <asm/mach/irq.h>
+
+#include "sam9_smc.h"
+#include "generic.h"
+
+
+static void __init ek_init_early(void)
+{
+ /* Initialize processor: 12.000 MHz crystal */
+ at91_initialize(12000000);
+
+ /* DGBU on ttyS0. (Rx & Tx only) */
+ at91_register_uart(0, 0, 0);
+
+ /* set serial console to ttyS0 (ie, DBGU) */
+ at91_set_serial_console(0);
+}
+
+/* det_pin is not connected */
+static struct atmel_nand_data __initdata ek_nand_data = {
+ .ale = 21,
+ .cle = 22,
+ .rdy_pin = AT91_PIN_PC8,
+ .enable_pin = AT91_PIN_PC14,
+};
+
+static struct sam9_smc_config __initdata ek_nand_smc_config = {
+ .ncs_read_setup = 0,
+ .nrd_setup = 2,
+ .ncs_write_setup = 0,
+ .nwe_setup = 2,
+
+ .ncs_read_pulse = 4,
+ .nrd_pulse = 4,
+ .ncs_write_pulse = 4,
+ .nwe_pulse = 4,
+
+ .read_cycle = 7,
+ .write_cycle = 7,
+
+ .mode = AT91_SMC_READMODE | AT91_SMC_WRITEMODE | AT91_SMC_EXNWMODE_DISABLE,
+ .tdf_cycles = 3,
+};
+
+static void __init ek_add_device_nand(void)
+{
+ ek_nand_data.bus_width_16 = board_have_nand_16bit();
+ /* setup bus-width (8 or 16) */
+ if (ek_nand_data.bus_width_16)
+ ek_nand_smc_config.mode |= AT91_SMC_DBW_16;
+ else
+ ek_nand_smc_config.mode |= AT91_SMC_DBW_8;
+
+ /* configure chip-select 3 (NAND) */
+ sam9_smc_configure(3, &ek_nand_smc_config);
+
+ at91_add_device_nand(&ek_nand_data);
+}
+
+static const struct of_device_id aic_of_match[] __initconst = {
+ { .compatible = "atmel,at91rm9200-aic", },
+ {},
+};
+
+static void __init at91_dt_init_irq(void)
+{
+ irq_domain_generate_simple(aic_of_match, 0xfffff000, 0);
+ at91_init_irq_default();
+}
+
+static void __init at91_dt_device_init(void)
+{
+ of_platform_populate(NULL, of_default_bus_match_table, NULL, NULL);
+
+ /* NAND */
+ ek_add_device_nand();
+}
+
+static const char *at91_dt_board_compat[] __initdata = {
+ "atmel,at91sam9m10g45ek",
+ "calao,usb-a9g20",
+ NULL
+};
+
+DT_MACHINE_START(at91sam_dt, "Atmel AT91SAM (Device Tree)")
+ /* Maintainer: Atmel */
+ .timer = &at91sam926x_timer,
+ .map_io = at91_map_io,
+ .init_early = ek_init_early,
+ .init_irq = at91_dt_init_irq,
+ .init_machine = at91_dt_device_init,
+ .dt_compat = at91_dt_board_compat,
+MACHINE_END
diff --git a/arch/arm/mach-msm/board-msm8x60.c b/arch/arm/mach-msm/board-msm8x60.c
index 106170fb1844..cf38e2284fa9 100644
--- a/arch/arm/mach-msm/board-msm8x60.c
+++ b/arch/arm/mach-msm/board-msm8x60.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2010, 2011, Code Aurora Forum. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
@@ -8,18 +8,16 @@
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
- * 02110-1301, USA.
- *
*/
#include <linux/kernel.h>
#include <linux/platform_device.h>
#include <linux/io.h>
#include <linux/irq.h>
+#include <linux/irqdomain.h>
+#include <linux/of.h>
+#include <linux/of_address.h>
+#include <linux/of_platform.h>
#include <linux/memblock.h>
#include <asm/mach-types.h>
@@ -70,6 +68,41 @@ static void __init msm8x60_init(void)
{
}
+#ifdef CONFIG_OF
+static struct of_dev_auxdata msm_auxdata_lookup[] __initdata = {
+ {}
+};
+
+static struct of_device_id msm_dt_gic_match[] __initdata = {
+ { .compatible = "qcom,msm-8660-qgic", },
+ {}
+};
+
+static void __init msm8x60_dt_init(void)
+{
+ struct device_node *node;
+
+ node = of_find_matching_node_by_address(NULL, msm_dt_gic_match,
+ MSM8X60_QGIC_DIST_PHYS);
+ if (node)
+ irq_domain_add_simple(node, GIC_SPI_START);
+
+ if (of_machine_is_compatible("qcom,msm8660-surf")) {
+ printk(KERN_INFO "Init surf UART registers\n");
+ msm8x60_init_uart12dm();
+ }
+
+ of_platform_populate(NULL, of_default_bus_match_table,
+ msm_auxdata_lookup, NULL);
+}
+
+static const char *msm8x60_fluid_match[] __initdata = {
+ "qcom,msm8660-fluid",
+ "qcom,msm8660-surf",
+ NULL
+};
+#endif /* CONFIG_OF */
+
MACHINE_START(MSM8X60_RUMI3, "QCT MSM8X60 RUMI3")
.fixup = msm8x60_fixup,
.reserve = msm8x60_reserve,
@@ -105,3 +138,14 @@ MACHINE_START(MSM8X60_FFA, "QCT MSM8X60 FFA")
.init_machine = msm8x60_init,
.timer = &msm_timer,
MACHINE_END
+
+#ifdef CONFIG_OF
+/* TODO: General device tree support for all MSM. */
+DT_MACHINE_START(MSM_DT, "Qualcomm MSM (Flattened Device Tree)")
+ .map_io = msm8x60_map_io,
+ .init_irq = msm8x60_init_irq,
+ .init_machine = msm8x60_dt_init,
+ .timer = &msm_timer,
+ .dt_compat = msm8x60_fluid_match,
+MACHINE_END
+#endif /* CONFIG_OF */
diff --git a/arch/arm/mach-mx5/Kconfig b/arch/arm/mach-mx5/Kconfig
index b4e7c58bbb38..bda12e84429a 100644
--- a/arch/arm/mach-mx5/Kconfig
+++ b/arch/arm/mach-mx5/Kconfig
@@ -62,6 +62,15 @@ endif # ARCH_MX50_SUPPORTED
if ARCH_MX51
comment "i.MX51 machines:"
+config MACH_IMX51_DT
+ bool "Support i.MX51 platforms from device tree"
+ select SOC_IMX51
+ select USE_OF
+ select MACH_MX51_BABBAGE
+ help
+ Include support for Freescale i.MX51 based platforms
+ using the device tree for discovery
+
config MACH_MX51_BABBAGE
bool "Support MX51 BABBAGE platforms"
select SOC_IMX51
@@ -172,6 +181,18 @@ endif # ARCH_MX51
if ARCH_MX53_SUPPORTED
comment "i.MX53 machines:"
+config MACH_IMX53_DT
+ bool "Support i.MX53 platforms from device tree"
+ select SOC_IMX53
+ select USE_OF
+ select MACH_MX53_ARD
+ select MACH_MX53_EVK
+ select MACH_MX53_LOCO
+ select MACH_MX53_SMD
+ help
+ Include support for Freescale i.MX53 based platforms
+ using the device tree for discovery
+
config MACH_MX53_EVK
bool "Support MX53 EVK platforms"
select SOC_IMX53
diff --git a/arch/arm/mach-mx5/Makefile b/arch/arm/mach-mx5/Makefile
index 383e7cd3fbcb..a3c75f368f4b 100644
--- a/arch/arm/mach-mx5/Makefile
+++ b/arch/arm/mach-mx5/Makefile
@@ -22,3 +22,6 @@ obj-$(CONFIG_MX51_EFIKA_COMMON) += mx51_efika.o
obj-$(CONFIG_MACH_MX51_EFIKAMX) += board-mx51_efikamx.o
obj-$(CONFIG_MACH_MX51_EFIKASB) += board-mx51_efikasb.o
obj-$(CONFIG_MACH_MX50_RDP) += board-mx50_rdp.o
+
+obj-$(CONFIG_MACH_IMX51_DT) += imx51-dt.o
+obj-$(CONFIG_MACH_IMX53_DT) += imx53-dt.o
diff --git a/arch/arm/mach-mx5/board-mx51_babbage.c b/arch/arm/mach-mx5/board-mx51_babbage.c
index 468926a48fe0..4e692dc836a8 100644
--- a/arch/arm/mach-mx5/board-mx51_babbage.c
+++ b/arch/arm/mach-mx5/board-mx51_babbage.c
@@ -351,6 +351,12 @@ static const struct esdhc_platform_data mx51_babbage_sd2_data __initconst = {
.wp_type = ESDHC_WP_GPIO,
};
+void __init imx51_babbage_common_init(void)
+{
+ mxc_iomux_v3_setup_multiple_pads(mx51babbage_pads,
+ ARRAY_SIZE(mx51babbage_pads));
+}
+
/*
* Board specific initialization.
*/
@@ -365,8 +371,7 @@ static void __init mx51_babbage_init(void)
#if defined(CONFIG_CPU_FREQ_IMX)
get_cpu_op = mx51_get_cpu_op;
#endif
- mxc_iomux_v3_setup_multiple_pads(mx51babbage_pads,
- ARRAY_SIZE(mx51babbage_pads));
+ imx51_babbage_common_init();
imx51_add_imx_uart(0, &uart_pdata);
imx51_add_imx_uart(1, NULL);
diff --git a/arch/arm/mach-mx5/board-mx53_ard.c b/arch/arm/mach-mx5/board-mx53_ard.c
index 76a67c4a2a0b..9b4395d7a07c 100644
--- a/arch/arm/mach-mx5/board-mx53_ard.c
+++ b/arch/arm/mach-mx5/board-mx53_ard.c
@@ -171,9 +171,6 @@ static struct imxi2c_platform_data mx53_ard_i2c3_data = {
static void __init mx53_ard_io_init(void)
{
- mxc_iomux_v3_setup_multiple_pads(mx53_ard_pads,
- ARRAY_SIZE(mx53_ard_pads));
-
gpio_request(ARD_ETHERNET_INT_B, "eth-int-b");
gpio_direction_input(ARD_ETHERNET_INT_B);
@@ -216,6 +213,13 @@ static int weim_cs_config(void)
return 0;
}
+void __init imx53_ard_common_init(void)
+{
+ mxc_iomux_v3_setup_multiple_pads(mx53_ard_pads,
+ ARRAY_SIZE(mx53_ard_pads));
+ weim_cs_config();
+}
+
static struct platform_device *devices[] __initdata = {
&ard_smsc_lan9220_device,
};
@@ -225,8 +229,8 @@ static void __init mx53_ard_board_init(void)
imx53_soc_init();
imx53_add_imx_uart(0, NULL);
+ imx53_ard_common_init();
mx53_ard_io_init();
- weim_cs_config();
platform_add_devices(devices, ARRAY_SIZE(devices));
imx53_add_sdhci_esdhc_imx(0, &mx53_ard_sd1_data);
diff --git a/arch/arm/mach-mx5/board-mx53_evk.c b/arch/arm/mach-mx5/board-mx53_evk.c
index 1b417b06b736..7663905d5c6d 100644
--- a/arch/arm/mach-mx5/board-mx53_evk.c
+++ b/arch/arm/mach-mx5/board-mx53_evk.c
@@ -131,12 +131,17 @@ static const struct spi_imx_master mx53_evk_spi_data __initconst = {
.num_chipselect = ARRAY_SIZE(mx53_evk_spi_cs),
};
+void __init imx53_evk_common_init(void)
+{
+ mxc_iomux_v3_setup_multiple_pads(mx53_evk_pads,
+ ARRAY_SIZE(mx53_evk_pads));
+}
+
static void __init mx53_evk_board_init(void)
{
imx53_soc_init();
+ imx53_evk_common_init();
- mxc_iomux_v3_setup_multiple_pads(mx53_evk_pads,
- ARRAY_SIZE(mx53_evk_pads));
mx53_evk_init_uart();
mx53_evk_fec_reset();
imx53_add_fec(&mx53_evk_fec_pdata);
diff --git a/arch/arm/mach-mx5/board-mx53_loco.c b/arch/arm/mach-mx5/board-mx53_loco.c
index 4e1d51d252dc..3922cd5ea854 100644
--- a/arch/arm/mach-mx5/board-mx53_loco.c
+++ b/arch/arm/mach-mx5/board-mx53_loco.c
@@ -257,12 +257,17 @@ static const struct gpio_led_platform_data mx53loco_leds_data __initconst = {
.num_leds = ARRAY_SIZE(mx53loco_leds),
};
+void __init imx53_qsb_common_init(void)
+{
+ mxc_iomux_v3_setup_multiple_pads(mx53_loco_pads,
+ ARRAY_SIZE(mx53_loco_pads));
+}
+
static void __init mx53_loco_board_init(void)
{
imx53_soc_init();
+ imx53_qsb_common_init();
- mxc_iomux_v3_setup_multiple_pads(mx53_loco_pads,
- ARRAY_SIZE(mx53_loco_pads));
imx53_add_imx_uart(0, NULL);
mx53_loco_fec_reset();
imx53_add_fec(&mx53_loco_fec_data);
diff --git a/arch/arm/mach-mx5/board-mx53_smd.c b/arch/arm/mach-mx5/board-mx53_smd.c
index bc02894eafef..b10c89982fbc 100644
--- a/arch/arm/mach-mx5/board-mx53_smd.c
+++ b/arch/arm/mach-mx5/board-mx53_smd.c
@@ -111,12 +111,17 @@ static const struct imxi2c_platform_data mx53_smd_i2c_data __initconst = {
.bitrate = 100000,
};
+void __init imx53_smd_common_init(void)
+{
+ mxc_iomux_v3_setup_multiple_pads(mx53_smd_pads,
+ ARRAY_SIZE(mx53_smd_pads));
+}
+
static void __init mx53_smd_board_init(void)
{
imx53_soc_init();
+ imx53_smd_common_init();
- mxc_iomux_v3_setup_multiple_pads(mx53_smd_pads,
- ARRAY_SIZE(mx53_smd_pads));
mx53_smd_init_uart();
mx53_smd_fec_reset();
imx53_add_fec(&mx53_smd_fec_data);
diff --git a/arch/arm/mach-mx5/clock-mx51-mx53.c b/arch/arm/mach-mx5/clock-mx51-mx53.c
index f7bf996f463b..cc3547c88261 100644
--- a/arch/arm/mach-mx5/clock-mx51-mx53.c
+++ b/arch/arm/mach-mx5/clock-mx51-mx53.c
@@ -15,6 +15,7 @@
#include <linux/clk.h>
#include <linux/io.h>
#include <linux/clkdev.h>
+#include <linux/of.h>
#include <asm/div64.h>
@@ -1609,3 +1610,41 @@ int __init mx53_clocks_init(unsigned long ckil, unsigned long osc,
MX53_INT_GPT);
return 0;
}
+
+static void __init clk_get_freq_dt(unsigned long *ckil, unsigned long *osc,
+ unsigned long *ckih1, unsigned long *ckih2)
+{
+ struct device_node *np;
+
+ /* retrieve the freqency of fixed clocks from device tree */
+ for_each_compatible_node(np, NULL, "fixed-clock") {
+ u32 rate;
+ if (of_property_read_u32(np, "clock-frequency", &rate))
+ continue;
+
+ if (of_device_is_compatible(np, "fsl,imx-ckil"))
+ *ckil = rate;
+ else if (of_device_is_compatible(np, "fsl,imx-osc"))
+ *osc = rate;
+ else if (of_device_is_compatible(np, "fsl,imx-ckih1"))
+ *ckih1 = rate;
+ else if (of_device_is_compatible(np, "fsl,imx-ckih2"))
+ *ckih2 = rate;
+ }
+}
+
+int __init mx51_clocks_init_dt(void)
+{
+ unsigned long ckil, osc, ckih1, ckih2;
+
+ clk_get_freq_dt(&ckil, &osc, &ckih1, &ckih2);
+ return mx51_clocks_init(ckil, osc, ckih1, ckih2);
+}
+
+int __init mx53_clocks_init_dt(void)
+{
+ unsigned long ckil, osc, ckih1, ckih2;
+
+ clk_get_freq_dt(&ckil, &osc, &ckih1, &ckih2);
+ return mx53_clocks_init(ckil, osc, ckih1, ckih2);
+}
diff --git a/arch/arm/mach-mx5/imx51-dt.c b/arch/arm/mach-mx5/imx51-dt.c
new file mode 100644
index 000000000000..ccc61585659b
--- /dev/null
+++ b/arch/arm/mach-mx5/imx51-dt.c
@@ -0,0 +1,116 @@
+/*
+ * Copyright 2011 Freescale Semiconductor, Inc. All Rights Reserved.
+ * Copyright 2011 Linaro Ltd.
+ *
+ * The code contained herein is licensed under the GNU General Public
+ * License. You may obtain a copy of the GNU General Public License
+ * Version 2 or later at the following locations:
+ *
+ * http://www.opensource.org/licenses/gpl-license.html
+ * http://www.gnu.org/copyleft/gpl.html
+ */
+
+#include <linux/irq.h>
+#include <linux/irqdomain.h>
+#include <linux/of_irq.h>
+#include <linux/of_platform.h>
+#include <asm/mach/arch.h>
+#include <asm/mach/time.h>
+#include <mach/common.h>
+#include <mach/mx51.h>
+
+/*
+ * Lookup table for attaching a specific name and platform_data pointer to
+ * devices as they get created by of_platform_populate(). Ideally this table
+ * would not exist, but the current clock implementation depends on some devices
+ * having a specific name.
+ */
+static const struct of_dev_auxdata imx51_auxdata_lookup[] __initconst = {
+ OF_DEV_AUXDATA("fsl,imx51-uart", MX51_UART1_BASE_ADDR, "imx21-uart.0", NULL),
+ OF_DEV_AUXDATA("fsl,imx51-uart", MX51_UART2_BASE_ADDR, "imx21-uart.1", NULL),
+ OF_DEV_AUXDATA("fsl,imx51-uart", MX51_UART3_BASE_ADDR, "imx21-uart.2", NULL),
+ OF_DEV_AUXDATA("fsl,imx51-fec", MX51_FEC_BASE_ADDR, "imx27-fec.0", NULL),
+ OF_DEV_AUXDATA("fsl,imx51-esdhc", MX51_ESDHC1_BASE_ADDR, "sdhci-esdhc-imx51.0", NULL),
+ OF_DEV_AUXDATA("fsl,imx51-esdhc", MX51_ESDHC2_BASE_ADDR, "sdhci-esdhc-imx51.1", NULL),
+ OF_DEV_AUXDATA("fsl,imx51-esdhc", MX51_ESDHC3_BASE_ADDR, "sdhci-esdhc-imx51.2", NULL),
+ OF_DEV_AUXDATA("fsl,imx51-esdhc", MX51_ESDHC4_BASE_ADDR, "sdhci-esdhc-imx51.3", NULL),
+ OF_DEV_AUXDATA("fsl,imx51-ecspi", MX51_ECSPI1_BASE_ADDR, "imx51-ecspi.0", NULL),
+ OF_DEV_AUXDATA("fsl,imx51-ecspi", MX51_ECSPI2_BASE_ADDR, "imx51-ecspi.1", NULL),
+ OF_DEV_AUXDATA("fsl,imx51-cspi", MX51_CSPI_BASE_ADDR, "imx35-cspi.0", NULL),
+ OF_DEV_AUXDATA("fsl,imx51-i2c", MX51_I2C1_BASE_ADDR, "imx-i2c.0", NULL),
+ OF_DEV_AUXDATA("fsl,imx51-i2c", MX51_I2C2_BASE_ADDR, "imx-i2c.1", NULL),
+ OF_DEV_AUXDATA("fsl,imx51-sdma", MX51_SDMA_BASE_ADDR, "imx35-sdma", NULL),
+ OF_DEV_AUXDATA("fsl,imx51-wdt", MX51_WDOG1_BASE_ADDR, "imx2-wdt.0", NULL),
+ { /* sentinel */ }
+};
+
+static void __init imx51_tzic_add_irq_domain(struct device_node *np,
+ struct device_node *interrupt_parent)
+{
+ irq_domain_add_simple(np, 0);
+}
+
+static void __init imx51_gpio_add_irq_domain(struct device_node *np,
+ struct device_node *interrupt_parent)
+{
+ static int gpio_irq_base = MXC_GPIO_IRQ_START + ARCH_NR_GPIOS -
+ 32 * 4; /* imx51 gets 4 gpio ports */
+
+ irq_domain_add_simple(np, gpio_irq_base);
+ gpio_irq_base += 32;
+}
+
+static const struct of_device_id imx51_irq_match[] __initconst = {
+ { .compatible = "fsl,imx51-tzic", .data = imx51_tzic_add_irq_domain, },
+ { .compatible = "fsl,imx51-gpio", .data = imx51_gpio_add_irq_domain, },
+ { /* sentinel */ }
+};
+
+static const struct of_device_id imx51_iomuxc_of_match[] __initconst = {
+ { .compatible = "fsl,imx51-iomuxc-babbage", .data = imx51_babbage_common_init, },
+ { /* sentinel */ }
+};
+
+static void __init imx51_dt_init(void)
+{
+ struct device_node *node;
+ const struct of_device_id *of_id;
+ void (*func)(void);
+
+ of_irq_init(imx51_irq_match);
+
+ node = of_find_matching_node(NULL, imx51_iomuxc_of_match);
+ if (node) {
+ of_id = of_match_node(imx51_iomuxc_of_match, node);
+ func = of_id->data;
+ func();
+ of_node_put(node);
+ }
+
+ of_platform_populate(NULL, of_default_bus_match_table,
+ imx51_auxdata_lookup, NULL);
+}
+
+static void __init imx51_timer_init(void)
+{
+ mx51_clocks_init_dt();
+}
+
+static struct sys_timer imx51_timer = {
+ .init = imx51_timer_init,
+};
+
+static const char *imx51_dt_board_compat[] __initdata = {
+ "fsl,imx51-babbage",
+ NULL
+};
+
+DT_MACHINE_START(IMX51_DT, "Freescale i.MX51 (Device Tree Support)")
+ .map_io = mx51_map_io,
+ .init_early = imx51_init_early,
+ .init_irq = mx51_init_irq,
+ .handle_irq = imx51_handle_irq,
+ .timer = &imx51_timer,
+ .init_machine = imx51_dt_init,
+ .dt_compat = imx51_dt_board_compat,
+MACHINE_END
diff --git a/arch/arm/mach-mx5/imx53-dt.c b/arch/arm/mach-mx5/imx53-dt.c
new file mode 100644
index 000000000000..ccaa0b81b768
--- /dev/null
+++ b/arch/arm/mach-mx5/imx53-dt.c
@@ -0,0 +1,126 @@
+/*
+ * Copyright 2011 Freescale Semiconductor, Inc. All Rights Reserved.
+ * Copyright 2011 Linaro Ltd.
+ *
+ * The code contained herein is licensed under the GNU General Public
+ * License. You may obtain a copy of the GNU General Public License
+ * Version 2 or later at the following locations:
+ *
+ * http://www.opensource.org/licenses/gpl-license.html
+ * http://www.gnu.org/copyleft/gpl.html
+ */
+
+#include <linux/io.h>
+#include <linux/irq.h>
+#include <linux/irqdomain.h>
+#include <linux/of_irq.h>
+#include <linux/of_platform.h>
+#include <asm/mach/arch.h>
+#include <asm/mach/time.h>
+#include <mach/common.h>
+#include <mach/mx53.h>
+
+/*
+ * Lookup table for attaching a specific name and platform_data pointer to
+ * devices as they get created by of_platform_populate(). Ideally this table
+ * would not exist, but the current clock implementation depends on some devices
+ * having a specific name.
+ */
+static const struct of_dev_auxdata imx53_auxdata_lookup[] __initconst = {
+ OF_DEV_AUXDATA("fsl,imx53-uart", MX53_UART1_BASE_ADDR, "imx21-uart.0", NULL),
+ OF_DEV_AUXDATA("fsl,imx53-uart", MX53_UART2_BASE_ADDR, "imx21-uart.1", NULL),
+ OF_DEV_AUXDATA("fsl,imx53-uart", MX53_UART3_BASE_ADDR, "imx21-uart.2", NULL),
+ OF_DEV_AUXDATA("fsl,imx53-uart", MX53_UART4_BASE_ADDR, "imx21-uart.3", NULL),
+ OF_DEV_AUXDATA("fsl,imx53-uart", MX53_UART5_BASE_ADDR, "imx21-uart.4", NULL),
+ OF_DEV_AUXDATA("fsl,imx53-fec", MX53_FEC_BASE_ADDR, "imx25-fec.0", NULL),
+ OF_DEV_AUXDATA("fsl,imx53-esdhc", MX53_ESDHC1_BASE_ADDR, "sdhci-esdhc-imx53.0", NULL),
+ OF_DEV_AUXDATA("fsl,imx53-esdhc", MX53_ESDHC2_BASE_ADDR, "sdhci-esdhc-imx53.1", NULL),
+ OF_DEV_AUXDATA("fsl,imx53-esdhc", MX53_ESDHC3_BASE_ADDR, "sdhci-esdhc-imx53.2", NULL),
+ OF_DEV_AUXDATA("fsl,imx53-esdhc", MX53_ESDHC4_BASE_ADDR, "sdhci-esdhc-imx53.3", NULL),
+ OF_DEV_AUXDATA("fsl,imx53-ecspi", MX53_ECSPI1_BASE_ADDR, "imx51-ecspi.0", NULL),
+ OF_DEV_AUXDATA("fsl,imx53-ecspi", MX53_ECSPI2_BASE_ADDR, "imx51-ecspi.1", NULL),
+ OF_DEV_AUXDATA("fsl,imx53-cspi", MX53_CSPI_BASE_ADDR, "imx35-cspi.0", NULL),
+ OF_DEV_AUXDATA("fsl,imx53-i2c", MX53_I2C1_BASE_ADDR, "imx-i2c.0", NULL),
+ OF_DEV_AUXDATA("fsl,imx53-i2c", MX53_I2C2_BASE_ADDR, "imx-i2c.1", NULL),
+ OF_DEV_AUXDATA("fsl,imx53-i2c", MX53_I2C3_BASE_ADDR, "imx-i2c.2", NULL),
+ OF_DEV_AUXDATA("fsl,imx53-sdma", MX53_SDMA_BASE_ADDR, "imx35-sdma", NULL),
+ OF_DEV_AUXDATA("fsl,imx53-wdt", MX53_WDOG1_BASE_ADDR, "imx2-wdt.0", NULL),
+ { /* sentinel */ }
+};
+
+static void __init imx53_tzic_add_irq_domain(struct device_node *np,
+ struct device_node *interrupt_parent)
+{
+ irq_domain_add_simple(np, 0);
+}
+
+static void __init imx53_gpio_add_irq_domain(struct device_node *np,
+ struct device_node *interrupt_parent)
+{
+ static int gpio_irq_base = MXC_GPIO_IRQ_START + ARCH_NR_GPIOS -
+ 32 * 7; /* imx53 gets 7 gpio ports */
+
+ irq_domain_add_simple(np, gpio_irq_base);
+ gpio_irq_base += 32;
+}
+
+static const struct of_device_id imx53_irq_match[] __initconst = {
+ { .compatible = "fsl,imx53-tzic", .data = imx53_tzic_add_irq_domain, },
+ { .compatible = "fsl,imx53-gpio", .data = imx53_gpio_add_irq_domain, },
+ { /* sentinel */ }
+};
+
+static const struct of_device_id imx53_iomuxc_of_match[] __initconst = {
+ { .compatible = "fsl,imx53-iomuxc-ard", .data = imx53_ard_common_init, },
+ { .compatible = "fsl,imx53-iomuxc-evk", .data = imx53_evk_common_init, },
+ { .compatible = "fsl,imx53-iomuxc-qsb", .data = imx53_qsb_common_init, },
+ { .compatible = "fsl,imx53-iomuxc-smd", .data = imx53_smd_common_init, },
+ { /* sentinel */ }
+};
+
+static void __init imx53_dt_init(void)
+{
+ struct device_node *node;
+ const struct of_device_id *of_id;
+ void (*func)(void);
+
+ of_irq_init(imx53_irq_match);
+
+ node = of_find_matching_node(NULL, imx53_iomuxc_of_match);
+ if (node) {
+ of_id = of_match_node(imx53_iomuxc_of_match, node);
+ func = of_id->data;
+ func();
+ of_node_put(node);
+ }
+
+ of_platform_populate(NULL, of_default_bus_match_table,
+ imx53_auxdata_lookup, NULL);
+}
+
+static void __init imx53_timer_init(void)
+{
+ mx53_clocks_init_dt();
+}
+
+static struct sys_timer imx53_timer = {
+ .init = imx53_timer_init,
+};
+
+static const char *imx53_dt_board_compat[] __initdata = {
+ "fsl,imx53-ard",
+ "fsl,imx53-evk",
+ "fsl,imx53-qsb",
+ "fsl,imx53-smd",
+ NULL
+};
+
+DT_MACHINE_START(IMX53_DT, "Freescale i.MX53 (Device Tree Support)")
+ .map_io = mx53_map_io,
+ .init_early = imx53_init_early,
+ .init_irq = mx53_init_irq,
+ .handle_irq = imx53_handle_irq,
+ .timer = &imx53_timer,
+ .init_machine = imx53_dt_init,
+ .dt_compat = imx53_dt_board_compat,
+MACHINE_END
diff --git a/arch/arm/mach-omap1/Makefile b/arch/arm/mach-omap1/Makefile
index 5b114d1558c8..11c85cd2731a 100644
--- a/arch/arm/mach-omap1/Makefile
+++ b/arch/arm/mach-omap1/Makefile
@@ -4,7 +4,7 @@
# Common support
obj-y := io.o id.o sram.o time.o irq.o mux.o flash.o serial.o devices.o dma.o
-obj-y += clock.o clock_data.o opp_data.o reset.o pm_bus.o
+obj-y += clock.o clock_data.o opp_data.o reset.o pm_bus.o timer.o
obj-$(CONFIG_OMAP_MCBSP) += mcbsp.o
diff --git a/arch/arm/mach-omap1/mcbsp.c b/arch/arm/mach-omap1/mcbsp.c
index ab7395d84bc8..91f9abbd3250 100644
--- a/arch/arm/mach-omap1/mcbsp.c
+++ b/arch/arm/mach-omap1/mcbsp.c
@@ -31,6 +31,7 @@
static int dsp_use;
static struct clk *api_clk;
static struct clk *dsp_clk;
+static struct platform_device **omap_mcbsp_devices;
static void omap1_mcbsp_request(unsigned int id)
{
@@ -78,6 +79,17 @@ static struct omap_mcbsp_ops omap1_mcbsp_ops = {
.free = omap1_mcbsp_free,
};
+#define OMAP7XX_MCBSP1_BASE 0xfffb1000
+#define OMAP7XX_MCBSP2_BASE 0xfffb1800
+
+#define OMAP1510_MCBSP1_BASE 0xe1011800
+#define OMAP1510_MCBSP2_BASE 0xfffb1000
+#define OMAP1510_MCBSP3_BASE 0xe1017000
+
+#define OMAP1610_MCBSP1_BASE 0xe1011800
+#define OMAP1610_MCBSP2_BASE 0xfffb1000
+#define OMAP1610_MCBSP3_BASE 0xe1017000
+
#if defined(CONFIG_ARCH_OMAP730) || defined(CONFIG_ARCH_OMAP850)
struct resource omap7xx_mcbsp_res[][6] = {
{
@@ -369,6 +381,39 @@ static struct omap_mcbsp_platform_data omap16xx_mcbsp_pdata[] = {
#define OMAP16XX_MCBSP_COUNT 0
#endif
+static void omap_mcbsp_register_board_cfg(struct resource *res, int res_count,
+ struct omap_mcbsp_platform_data *config, int size)
+{
+ int i;
+
+ omap_mcbsp_devices = kzalloc(size * sizeof(struct platform_device *),
+ GFP_KERNEL);
+ if (!omap_mcbsp_devices) {
+ printk(KERN_ERR "Could not register McBSP devices\n");
+ return;
+ }
+
+ for (i = 0; i < size; i++) {
+ struct platform_device *new_mcbsp;
+ int ret;
+
+ new_mcbsp = platform_device_alloc("omap-mcbsp", i + 1);
+ if (!new_mcbsp)
+ continue;
+ platform_device_add_resources(new_mcbsp, &res[i * res_count],
+ res_count);
+ config[i].reg_size = 2;
+ config[i].reg_step = 2;
+ new_mcbsp->dev.platform_data = &config[i];
+ ret = platform_device_add(new_mcbsp);
+ if (ret) {
+ platform_device_put(new_mcbsp);
+ continue;
+ }
+ omap_mcbsp_devices[i] = new_mcbsp;
+ }
+}
+
static int __init omap1_mcbsp_init(void)
{
if (!cpu_class_is_omap1())
diff --git a/arch/arm/mach-omap1/timer.c b/arch/arm/mach-omap1/timer.c
new file mode 100644
index 000000000000..6e90665a7c47
--- /dev/null
+++ b/arch/arm/mach-omap1/timer.c
@@ -0,0 +1,173 @@
+/**
+ * OMAP1 Dual-Mode Timers - platform device registration
+ *
+ * Contains first level initialization routines which internally
+ * generates timer device information and registers with linux
+ * device model. It also has low level function to chnage the timer
+ * input clock source.
+ *
+ * Copyright (C) 2011 Texas Instruments Incorporated - http://www.ti.com/
+ * Tarun Kanti DebBarma <tarun.kanti@ti.com>
+ * Thara Gopinath <thara@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.
+ *
+ * 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/clk.h>
+#include <linux/io.h>
+#include <linux/err.h>
+#include <linux/slab.h>
+#include <linux/platform_device.h>
+
+#include <mach/irqs.h>
+
+#include <plat/dmtimer.h>
+
+#define OMAP1610_GPTIMER1_BASE 0xfffb1400
+#define OMAP1610_GPTIMER2_BASE 0xfffb1c00
+#define OMAP1610_GPTIMER3_BASE 0xfffb2400
+#define OMAP1610_GPTIMER4_BASE 0xfffb2c00
+#define OMAP1610_GPTIMER5_BASE 0xfffb3400
+#define OMAP1610_GPTIMER6_BASE 0xfffb3c00
+#define OMAP1610_GPTIMER7_BASE 0xfffb7400
+#define OMAP1610_GPTIMER8_BASE 0xfffbd400
+
+#define OMAP1_DM_TIMER_COUNT 8
+
+static int omap1_dm_timer_set_src(struct platform_device *pdev,
+ int source)
+{
+ int n = (pdev->id - 1) << 1;
+ u32 l;
+
+ l = __raw_readl(MOD_CONF_CTRL_1) & ~(0x03 << n);
+ l |= source << n;
+ __raw_writel(l, MOD_CONF_CTRL_1);
+
+ return 0;
+}
+
+
+int __init omap1_dm_timer_init(void)
+{
+ int i;
+ int ret;
+ struct dmtimer_platform_data *pdata;
+ struct platform_device *pdev;
+
+ if (!cpu_is_omap16xx())
+ return 0;
+
+ for (i = 1; i <= OMAP1_DM_TIMER_COUNT; i++) {
+ struct resource res[2];
+ u32 base, irq;
+
+ switch (i) {
+ case 1:
+ base = OMAP1610_GPTIMER1_BASE;
+ irq = INT_1610_GPTIMER1;
+ break;
+ case 2:
+ base = OMAP1610_GPTIMER2_BASE;
+ irq = INT_1610_GPTIMER2;
+ break;
+ case 3:
+ base = OMAP1610_GPTIMER3_BASE;
+ irq = INT_1610_GPTIMER3;
+ break;
+ case 4:
+ base = OMAP1610_GPTIMER4_BASE;
+ irq = INT_1610_GPTIMER4;
+ break;
+ case 5:
+ base = OMAP1610_GPTIMER5_BASE;
+ irq = INT_1610_GPTIMER5;
+ break;
+ case 6:
+ base = OMAP1610_GPTIMER6_BASE;
+ irq = INT_1610_GPTIMER6;
+ break;
+ case 7:
+ base = OMAP1610_GPTIMER7_BASE;
+ irq = INT_1610_GPTIMER7;
+ break;
+ case 8:
+ base = OMAP1610_GPTIMER8_BASE;
+ irq = INT_1610_GPTIMER8;
+ break;
+ default:
+ /*
+ * not supposed to reach here.
+ * this is to remove warning.
+ */
+ return -EINVAL;
+ }
+
+ pdev = platform_device_alloc("omap_timer", i);
+ if (!pdev) {
+ pr_err("%s: Failed to device alloc for dmtimer%d\n",
+ __func__, i);
+ return -ENOMEM;
+ }
+
+ memset(res, 0, 2 * sizeof(struct resource));
+ res[0].start = base;
+ res[0].end = base + 0x46;
+ res[0].flags = IORESOURCE_MEM;
+ res[1].start = irq;
+ res[1].end = irq;
+ res[1].flags = IORESOURCE_IRQ;
+ ret = platform_device_add_resources(pdev, res,
+ ARRAY_SIZE(res));
+ if (ret) {
+ dev_err(&pdev->dev, "%s: Failed to add resources.\n",
+ __func__);
+ goto err_free_pdev;
+ }
+
+ pdata = kzalloc(sizeof(*pdata), GFP_KERNEL);
+ if (!pdata) {
+ dev_err(&pdev->dev, "%s: Failed to allocate pdata.\n",
+ __func__);
+ ret = -ENOMEM;
+ goto err_free_pdata;
+ }
+
+ pdata->set_timer_src = omap1_dm_timer_set_src;
+ pdata->needs_manual_reset = 1;
+
+ ret = platform_device_add_data(pdev, pdata, sizeof(*pdata));
+ if (ret) {
+ dev_err(&pdev->dev, "%s: Failed to add platform data.\n",
+ __func__);
+ goto err_free_pdata;
+ }
+
+ ret = platform_device_add(pdev);
+ if (ret) {
+ dev_err(&pdev->dev, "%s: Failed to add platform device.\n",
+ __func__);
+ goto err_free_pdata;
+ }
+
+ dev_dbg(&pdev->dev, " Registered.\n");
+ }
+
+ return 0;
+
+err_free_pdata:
+ kfree(pdata);
+
+err_free_pdev:
+ platform_device_unregister(pdev);
+
+ return ret;
+}
+arch_initcall(omap1_dm_timer_init);
diff --git a/arch/arm/mach-omap2/Kconfig b/arch/arm/mach-omap2/Kconfig
index 57b66d590c52..e0a318df95bc 100644
--- a/arch/arm/mach-omap2/Kconfig
+++ b/arch/arm/mach-omap2/Kconfig
@@ -106,9 +106,13 @@ comment "OMAP Board Type"
depends on ARCH_OMAP2PLUS
config MACH_OMAP_GENERIC
- bool "Generic OMAP board"
- depends on ARCH_OMAP2
+ bool "Generic OMAP2+ board"
+ depends on ARCH_OMAP2PLUS
+ select USE_OF
default y
+ help
+ Support for generic TI OMAP2+ boards using Flattened Device Tree.
+ More information at Documentation/devicetree
config MACH_OMAP2_TUSB6010
bool
diff --git a/arch/arm/mach-omap2/Makefile b/arch/arm/mach-omap2/Makefile
index f34336560437..512978586b2b 100644
--- a/arch/arm/mach-omap2/Makefile
+++ b/arch/arm/mach-omap2/Makefile
@@ -89,14 +89,13 @@ obj-$(CONFIG_ARCH_OMAP4) += prcm.o cm2xxx_3xxx.o cminst44xx.o \
vp44xx_data.o
# OMAP voltage domains
-ifeq ($(CONFIG_PM),y)
-voltagedomain-common := voltage.o
-obj-$(CONFIG_ARCH_OMAP2) += $(voltagedomain-common)
+voltagedomain-common := voltage.o vc.o vp.o
+obj-$(CONFIG_ARCH_OMAP2) += $(voltagedomain-common) \
+ voltagedomains2xxx_data.o
obj-$(CONFIG_ARCH_OMAP3) += $(voltagedomain-common) \
voltagedomains3xxx_data.o
obj-$(CONFIG_ARCH_OMAP4) += $(voltagedomain-common) \
voltagedomains44xx_data.o
-endif
# OMAP powerdomain framework
powerdomain-common += powerdomain.o powerdomain-common.o
@@ -116,9 +115,12 @@ obj-$(CONFIG_ARCH_OMAP4) += $(powerdomain-common) \
obj-$(CONFIG_ARCH_OMAP2) += clockdomain.o \
clockdomain2xxx_3xxx.o \
clockdomains2xxx_3xxx_data.o
+obj-$(CONFIG_SOC_OMAP2420) += clockdomains2420_data.o
+obj-$(CONFIG_SOC_OMAP2430) += clockdomains2430_data.o
obj-$(CONFIG_ARCH_OMAP3) += clockdomain.o \
clockdomain2xxx_3xxx.o \
- clockdomains2xxx_3xxx_data.o
+ clockdomains2xxx_3xxx_data.o \
+ clockdomains3xxx_data.o
obj-$(CONFIG_ARCH_OMAP4) += clockdomain.o \
clockdomain44xx.o \
clockdomains44xx_data.o
@@ -185,78 +187,66 @@ endif
# Specific board support
obj-$(CONFIG_MACH_OMAP_GENERIC) += board-generic.o
obj-$(CONFIG_MACH_OMAP_H4) += board-h4.o
-obj-$(CONFIG_MACH_OMAP_2430SDP) += board-2430sdp.o \
- hsmmc.o
+obj-$(CONFIG_MACH_OMAP_2430SDP) += board-2430sdp.o
obj-$(CONFIG_MACH_OMAP_APOLLON) += board-apollon.o
-obj-$(CONFIG_MACH_OMAP3_BEAGLE) += board-omap3beagle.o \
- hsmmc.o
-obj-$(CONFIG_MACH_DEVKIT8000) += board-devkit8000.o \
- hsmmc.o
-obj-$(CONFIG_MACH_OMAP_LDP) += board-ldp.o \
- board-flash.o \
- hsmmc.o
-obj-$(CONFIG_MACH_OMAP3530_LV_SOM) += board-omap3logic.o \
- hsmmc.o
-obj-$(CONFIG_MACH_OMAP3_TORPEDO) += board-omap3logic.o \
- hsmmc.o
-obj-$(CONFIG_MACH_OVERO) += board-overo.o \
- hsmmc.o
-obj-$(CONFIG_MACH_OMAP3EVM) += board-omap3evm.o \
- hsmmc.o
-obj-$(CONFIG_MACH_OMAP3_PANDORA) += board-omap3pandora.o \
- hsmmc.o
-obj-$(CONFIG_MACH_OMAP_3430SDP) += board-3430sdp.o \
- hsmmc.o \
- board-flash.o
+obj-$(CONFIG_MACH_OMAP3_BEAGLE) += board-omap3beagle.o
+obj-$(CONFIG_MACH_DEVKIT8000) += board-devkit8000.o
+obj-$(CONFIG_MACH_OMAP_LDP) += board-ldp.o
+obj-$(CONFIG_MACH_OMAP3530_LV_SOM) += board-omap3logic.o
+obj-$(CONFIG_MACH_OMAP3_TORPEDO) += board-omap3logic.o
+obj-$(CONFIG_MACH_ENCORE) += board-omap3encore.o
+obj-$(CONFIG_MACH_OVERO) += board-overo.o
+obj-$(CONFIG_MACH_OMAP3EVM) += board-omap3evm.o
+obj-$(CONFIG_MACH_OMAP3_PANDORA) += board-omap3pandora.o
+obj-$(CONFIG_MACH_OMAP_3430SDP) += board-3430sdp.o
obj-$(CONFIG_MACH_NOKIA_N8X0) += board-n8x0.o
obj-$(CONFIG_MACH_NOKIA_RM680) += board-rm680.o \
- sdram-nokia.o \
- hsmmc.o
+ sdram-nokia.o
obj-$(CONFIG_MACH_NOKIA_RX51) += board-rx51.o \
sdram-nokia.o \
board-rx51-peripherals.o \
- board-rx51-video.o \
- hsmmc.o
+ board-rx51-video.o
obj-$(CONFIG_MACH_OMAP_ZOOM2) += board-zoom.o \
board-zoom-peripherals.o \
board-zoom-display.o \
- board-flash.o \
- hsmmc.o \
board-zoom-debugboard.o
obj-$(CONFIG_MACH_OMAP_ZOOM3) += board-zoom.o \
board-zoom-peripherals.o \
board-zoom-display.o \
- board-flash.o \
- hsmmc.o \
board-zoom-debugboard.o
obj-$(CONFIG_MACH_OMAP_3630SDP) += board-3630sdp.o \
board-zoom-peripherals.o \
- board-zoom-display.o \
- board-flash.o \
- hsmmc.o
-obj-$(CONFIG_MACH_CM_T35) += board-cm-t35.o \
- hsmmc.o
+ board-zoom-display.o
+obj-$(CONFIG_MACH_CM_T35) += board-cm-t35.o
obj-$(CONFIG_MACH_CM_T3517) += board-cm-t3517.o
-obj-$(CONFIG_MACH_IGEP0020) += board-igep0020.o \
- hsmmc.o
-obj-$(CONFIG_MACH_OMAP3_TOUCHBOOK) += board-omap3touchbook.o \
- hsmmc.o
+obj-$(CONFIG_MACH_IGEP0020) += board-igep0020.o
+obj-$(CONFIG_MACH_OMAP3_TOUCHBOOK) += board-omap3touchbook.o
obj-$(CONFIG_MACH_OMAP_4430SDP) += board-4430sdp.o \
- hsmmc.o \
omap_phy_internal.o
obj-$(CONFIG_MACH_OMAP4_PANDA) += board-omap4panda.o \
- hsmmc.o \
+ omap_phy_internal.o
+
+obj-$(CONFIG_MACH_PCM049) += board-omap4pcm049.o \
omap_phy_internal.o
obj-$(CONFIG_MACH_OMAP3517EVM) += board-am3517evm.o \
- omap_phy_internal.o \
+ omap_phy_internal.o
obj-$(CONFIG_MACH_CRANEBOARD) += board-am3517crane.o
-obj-$(CONFIG_MACH_SBC3530) += board-omap3stalker.o \
- hsmmc.o
+obj-$(CONFIG_MACH_SBC3530) += board-omap3stalker.o
obj-$(CONFIG_MACH_TI8168EVM) += board-ti8168evm.o
+
# Platform specific device init code
+
+omap-flash-$(CONFIG_MTD_NAND_OMAP2) := board-flash.o
+omap-flash-$(CONFIG_MTD_ONENAND_OMAP2) := board-flash.o
+obj-y += $(omap-flash-y) $(omap-flash-m)
+
+omap-hsmmc-$(CONFIG_MMC_OMAP_HS) := hsmmc.o
+obj-y += $(omap-hsmmc-m) $(omap-hsmmc-y)
+
+
usbfs-$(CONFIG_ARCH_OMAP_OTG) := usb-fs.o
obj-y += $(usbfs-m) $(usbfs-y)
obj-y += usb-musb.o
diff --git a/arch/arm/mach-omap2/board-2430sdp.c b/arch/arm/mach-omap2/board-2430sdp.c
index 195157da21e6..638cecb9ea1a 100644
--- a/arch/arm/mach-omap2/board-2430sdp.c
+++ b/arch/arm/mach-omap2/board-2430sdp.c
@@ -141,12 +141,6 @@ static struct omap_board_config_kernel sdp2430_config[] __initdata = {
{OMAP_TAG_LCD, &sdp2430_lcd_config},
};
-static void __init omap_2430sdp_init_early(void)
-{
- omap2_init_common_infrastructure();
- omap2_init_common_devices(NULL, NULL);
-}
-
static struct regulator_consumer_supply sdp2430_vmmc1_supplies[] = {
REGULATOR_SUPPLY("vmmc", "omap_hsmmc.0"),
};
@@ -193,7 +187,8 @@ static int __init omap2430_i2c_init(void)
{
omap_register_i2c_bus(1, 100, sdp2430_i2c1_boardinfo,
ARRAY_SIZE(sdp2430_i2c1_boardinfo));
- omap2_pmic_init("twl4030", &sdp2430_twldata);
+ omap_pmic_init(2, 100, "twl4030", INT_24XX_SYS_NIRQ,
+ &sdp2430_twldata);
return 0;
}
@@ -235,6 +230,7 @@ static void __init omap_2430sdp_init(void)
platform_add_devices(sdp2430_devices, ARRAY_SIZE(sdp2430_devices));
omap_serial_init();
+ omap_sdrc_init(NULL, NULL);
omap2_hsmmc_init(mmc);
omap2_usbfs_init(&sdp2430_usb_config);
@@ -248,18 +244,12 @@ static void __init omap_2430sdp_init(void)
"Secondary LCD backlight");
}
-static void __init omap_2430sdp_map_io(void)
-{
- omap2_set_globals_243x();
- omap243x_map_common_io();
-}
-
MACHINE_START(OMAP_2430SDP, "OMAP2430 sdp2430 board")
/* Maintainer: Syed Khasim - Texas Instruments Inc */
.atag_offset = 0x100,
.reserve = omap_reserve,
- .map_io = omap_2430sdp_map_io,
- .init_early = omap_2430sdp_init_early,
+ .map_io = omap243x_map_io,
+ .init_early = omap2430_init_early,
.init_irq = omap2_init_irq,
.init_machine = omap_2430sdp_init,
.timer = &omap2_timer,
diff --git a/arch/arm/mach-omap2/board-3430sdp.c b/arch/arm/mach-omap2/board-3430sdp.c
index 2430531b2239..5b5999caf71d 100644
--- a/arch/arm/mach-omap2/board-3430sdp.c
+++ b/arch/arm/mach-omap2/board-3430sdp.c
@@ -225,12 +225,6 @@ static struct omap_dss_board_info sdp3430_dss_data = {
static struct omap_board_config_kernel sdp3430_config[] __initdata = {
};
-static void __init omap_3430sdp_init_early(void)
-{
- omap2_init_common_infrastructure();
- omap2_init_common_devices(hyb18m512160af6_sdrc_params, NULL);
-}
-
static struct omap2_hsmmc_info mmc[] = {
{
.mmc = 1,
@@ -719,6 +713,7 @@ static void __init omap_3430sdp_init(void)
gpio_pendown = SDP3430_TS_GPIO_IRQ_SDPV1;
omap_ads7846_init(1, gpio_pendown, 310, NULL);
board_serial_init();
+ omap_sdrc_init(hyb18m512160af6_sdrc_params, NULL);
usb_musb_init(NULL);
board_smc91x_init();
board_flash_init(sdp_flash_partitions, chip_sel_3430, 0);
@@ -732,7 +727,7 @@ MACHINE_START(OMAP_3430SDP, "OMAP3430 3430SDP board")
.atag_offset = 0x100,
.reserve = omap_reserve,
.map_io = omap3_map_io,
- .init_early = omap_3430sdp_init_early,
+ .init_early = omap3430_init_early,
.init_irq = omap3_init_irq,
.init_machine = omap_3430sdp_init,
.timer = &omap3_timer,
diff --git a/arch/arm/mach-omap2/board-3630sdp.c b/arch/arm/mach-omap2/board-3630sdp.c
index 8b5b5aa751ed..f552305162fc 100644
--- a/arch/arm/mach-omap2/board-3630sdp.c
+++ b/arch/arm/mach-omap2/board-3630sdp.c
@@ -70,13 +70,6 @@ static const struct usbhs_omap_board_data usbhs_bdata __initconst = {
static struct omap_board_config_kernel sdp_config[] __initdata = {
};
-static void __init omap_sdp_init_early(void)
-{
- omap2_init_common_infrastructure();
- omap2_init_common_devices(h8mbx00u0mer0em_sdrc_params,
- h8mbx00u0mer0em_sdrc_params);
-}
-
#ifdef CONFIG_OMAP_MUX
static struct omap_board_mux board_mux[] __initdata = {
{ .reg_offset = OMAP_MUX_TERMINATOR },
@@ -207,6 +200,8 @@ static void __init omap_sdp_init(void)
omap_board_config = sdp_config;
omap_board_config_size = ARRAY_SIZE(sdp_config);
zoom_peripherals_init();
+ omap_sdrc_init(h8mbx00u0mer0em_sdrc_params,
+ h8mbx00u0mer0em_sdrc_params);
zoom_display_init();
board_smc91x_init();
board_flash_init(sdp_flash_partitions, chip_sel_sdp, NAND_BUSWIDTH_16);
@@ -218,7 +213,7 @@ MACHINE_START(OMAP_3630SDP, "OMAP 3630SDP board")
.atag_offset = 0x100,
.reserve = omap_reserve,
.map_io = omap3_map_io,
- .init_early = omap_sdp_init_early,
+ .init_early = omap3630_init_early,
.init_irq = omap3_init_irq,
.init_machine = omap_sdp_init,
.timer = &omap3_timer,
diff --git a/arch/arm/mach-omap2/board-4430sdp.c b/arch/arm/mach-omap2/board-4430sdp.c
index be931105d681..6d2b61409c1b 100644
--- a/arch/arm/mach-omap2/board-4430sdp.c
+++ b/arch/arm/mach-omap2/board-4430sdp.c
@@ -129,7 +129,7 @@ static const int sdp4430_keymap[] = {
KEY(7, 6, KEY_OK),
KEY(7, 7, KEY_DOWN),
};
-static struct omap_device_pad keypad_pads[] __initdata = {
+static struct omap_device_pad keypad_pads[] = {
{ .name = "kpd_col1.kpd_col1",
.enable = OMAP_WAKEUP_EN | OMAP_MUX_MODE1,
},
@@ -389,12 +389,6 @@ static struct omap_board_config_kernel sdp4430_config[] __initdata = {
{ OMAP_TAG_LCD, &sdp4430_lcd_config },
};
-static void __init omap_4430sdp_init_early(void)
-{
- omap2_init_common_infrastructure();
- omap2_init_common_devices(NULL, NULL);
-}
-
static struct omap_musb_board_data musb_board_data = {
.interface_type = MUSB_INTERFACE_UTMI,
.mode = MUSB_OTG,
@@ -809,6 +803,7 @@ static void __init omap_4430sdp_init(void)
omap_sfh7741prox_init();
platform_add_devices(sdp4430_devices, ARRAY_SIZE(sdp4430_devices));
board_serial_init();
+ omap_sdrc_init(NULL, NULL);
omap4_sdp4430_wifi_init();
omap4_twl6030_hsmmc_init(mmc);
@@ -830,18 +825,12 @@ static void __init omap_4430sdp_init(void)
omap_4430sdp_display_init();
}
-static void __init omap_4430sdp_map_io(void)
-{
- omap2_set_globals_443x();
- omap44xx_map_common_io();
-}
-
MACHINE_START(OMAP_4430SDP, "OMAP4430 4430SDP board")
/* Maintainer: Santosh Shilimkar - Texas Instruments Inc */
.atag_offset = 0x100,
.reserve = omap_reserve,
- .map_io = omap_4430sdp_map_io,
- .init_early = omap_4430sdp_init_early,
+ .map_io = omap4_map_io,
+ .init_early = omap4430_init_early,
.init_irq = gic_init_irq,
.init_machine = omap_4430sdp_init,
.timer = &omap4_timer,
diff --git a/arch/arm/mach-omap2/board-am3517crane.c b/arch/arm/mach-omap2/board-am3517crane.c
index db110fdb8b2c..7834536ab416 100644
--- a/arch/arm/mach-omap2/board-am3517crane.c
+++ b/arch/arm/mach-omap2/board-am3517crane.c
@@ -47,12 +47,6 @@ static struct omap_board_mux board_mux[] __initdata = {
};
#endif
-static void __init am3517_crane_init_early(void)
-{
- omap2_init_common_infrastructure();
- omap2_init_common_devices(NULL, NULL);
-}
-
static struct usbhs_omap_board_data usbhs_bdata __initdata = {
.port_mode[0] = OMAP_EHCI_PORT_MODE_PHY,
.port_mode[1] = OMAP_USBHS_PORT_MODE_UNUSED,
@@ -70,6 +64,7 @@ static void __init am3517_crane_init(void)
omap3_mux_init(board_mux, OMAP_PACKAGE_CBB);
omap_serial_init();
+ omap_sdrc_init(NULL, NULL);
omap_board_config = am3517_crane_config;
omap_board_config_size = ARRAY_SIZE(am3517_crane_config);
@@ -101,7 +96,7 @@ MACHINE_START(CRANEBOARD, "AM3517/05 CRANEBOARD")
.atag_offset = 0x100,
.reserve = omap_reserve,
.map_io = omap3_map_io,
- .init_early = am3517_crane_init_early,
+ .init_early = am35xx_init_early,
.init_irq = omap3_init_irq,
.init_machine = am3517_crane_init,
.timer = &omap3_timer,
diff --git a/arch/arm/mach-omap2/board-am3517evm.c b/arch/arm/mach-omap2/board-am3517evm.c
index 1325085e453d..65a5912278ac 100644
--- a/arch/arm/mach-omap2/board-am3517evm.c
+++ b/arch/arm/mach-omap2/board-am3517evm.c
@@ -362,11 +362,6 @@ static struct omap_dss_board_info am3517_evm_dss_data = {
/*
* Board initialization
*/
-static void __init am3517_evm_init_early(void)
-{
- omap2_init_common_infrastructure();
- omap2_init_common_devices(NULL, NULL);
-}
static struct omap_musb_board_data musb_board_data = {
.interface_type = MUSB_INTERFACE_ULPI,
@@ -469,6 +464,7 @@ static void __init am3517_evm_init(void)
am3517_evm_i2c_init();
omap_display_init(&am3517_evm_dss_data);
omap_serial_init();
+ omap_sdrc_init(NULL, NULL);
/* Configure GPIO for EHCI port */
omap_mux_init_gpio(57, OMAP_PIN_OUTPUT);
@@ -493,7 +489,7 @@ MACHINE_START(OMAP3517EVM, "OMAP3517/AM3517 EVM")
.atag_offset = 0x100,
.reserve = omap_reserve,
.map_io = omap3_map_io,
- .init_early = am3517_evm_init_early,
+ .init_early = am35xx_init_early,
.init_irq = omap3_init_irq,
.init_machine = am3517_evm_init,
.timer = &omap3_timer,
diff --git a/arch/arm/mach-omap2/board-apollon.c b/arch/arm/mach-omap2/board-apollon.c
index 67800e647d7a..29c409b68b52 100644
--- a/arch/arm/mach-omap2/board-apollon.c
+++ b/arch/arm/mach-omap2/board-apollon.c
@@ -273,12 +273,6 @@ static struct omap_board_config_kernel apollon_config[] __initdata = {
{ OMAP_TAG_LCD, &apollon_lcd_config },
};
-static void __init omap_apollon_init_early(void)
-{
- omap2_init_common_infrastructure();
- omap2_init_common_devices(NULL, NULL);
-}
-
static struct gpio apollon_gpio_leds[] __initdata = {
{ LED0_GPIO13, GPIOF_OUT_INIT_LOW, "LED0" }, /* LED0 - AA10 */
{ LED1_GPIO14, GPIOF_OUT_INIT_LOW, "LED1" }, /* LED1 - AA6 */
@@ -340,20 +334,15 @@ static void __init omap_apollon_init(void)
*/
platform_add_devices(apollon_devices, ARRAY_SIZE(apollon_devices));
omap_serial_init();
-}
-
-static void __init omap_apollon_map_io(void)
-{
- omap2_set_globals_242x();
- omap242x_map_common_io();
+ omap_sdrc_init(NULL, NULL);
}
MACHINE_START(OMAP_APOLLON, "OMAP24xx Apollon")
/* Maintainer: Kyungmin Park <kyungmin.park@samsung.com> */
.atag_offset = 0x100,
.reserve = omap_reserve,
- .map_io = omap_apollon_map_io,
- .init_early = omap_apollon_init_early,
+ .map_io = omap242x_map_io,
+ .init_early = omap2420_init_early,
.init_irq = omap2_init_irq,
.init_machine = omap_apollon_init,
.timer = &omap2_timer,
diff --git a/arch/arm/mach-omap2/board-cm-t35.c b/arch/arm/mach-omap2/board-cm-t35.c
index 38179c175503..5665e688bd26 100644
--- a/arch/arm/mach-omap2/board-cm-t35.c
+++ b/arch/arm/mach-omap2/board-cm-t35.c
@@ -471,13 +471,6 @@ static void __init cm_t35_init_i2c(void)
omap3_pmic_init("tps65930", &cm_t35_twldata);
}
-static void __init cm_t35_init_early(void)
-{
- omap2_init_common_infrastructure();
- omap2_init_common_devices(mt46h32m32lf6_sdrc_params,
- mt46h32m32lf6_sdrc_params);
-}
-
#ifdef CONFIG_OMAP_MUX
static struct omap_board_mux board_mux[] __initdata = {
/* nCS and IRQ for CM-T35 ethernet */
@@ -610,6 +603,8 @@ static void __init cm_t3x_common_init(void)
omap_board_config_size = ARRAY_SIZE(cm_t35_config);
omap3_mux_init(board_mux, OMAP_PACKAGE_CUS);
omap_serial_init();
+ omap_sdrc_init(mt46h32m32lf6_sdrc_params,
+ mt46h32m32lf6_sdrc_params);
cm_t35_init_i2c();
omap_ads7846_init(1, CM_T35_GPIO_PENDOWN, 0, NULL);
cm_t35_init_ethernet();
@@ -637,7 +632,7 @@ MACHINE_START(CM_T35, "Compulab CM-T35")
.atag_offset = 0x100,
.reserve = omap_reserve,
.map_io = omap3_map_io,
- .init_early = cm_t35_init_early,
+ .init_early = omap35xx_init_early,
.init_irq = omap3_init_irq,
.init_machine = cm_t35_init,
.timer = &omap3_timer,
@@ -647,7 +642,7 @@ MACHINE_START(CM_T3730, "Compulab CM-T3730")
.atag_offset = 0x100,
.reserve = omap_reserve,
.map_io = omap3_map_io,
- .init_early = cm_t35_init_early,
+ .init_early = omap3630_init_early,
.init_irq = omap3_init_irq,
.init_machine = cm_t3730_init,
.timer = &omap3_timer,
diff --git a/arch/arm/mach-omap2/board-cm-t3517.c b/arch/arm/mach-omap2/board-cm-t3517.c
index aed9c29f9fae..3f4dc6626845 100644
--- a/arch/arm/mach-omap2/board-cm-t3517.c
+++ b/arch/arm/mach-omap2/board-cm-t3517.c
@@ -251,12 +251,6 @@ static inline void cm_t3517_init_nand(void) {}
static struct omap_board_config_kernel cm_t3517_config[] __initdata = {
};
-static void __init cm_t3517_init_early(void)
-{
- omap2_init_common_infrastructure();
- omap2_init_common_devices(NULL, NULL);
-}
-
#ifdef CONFIG_OMAP_MUX
static struct omap_board_mux board_mux[] __initdata = {
/* GPIO186 - Green LED */
@@ -289,6 +283,7 @@ static void __init cm_t3517_init(void)
{
omap3_mux_init(board_mux, OMAP_PACKAGE_CBB);
omap_serial_init();
+ omap_sdrc_init(NULL, NULL);
omap_board_config = cm_t3517_config;
omap_board_config_size = ARRAY_SIZE(cm_t3517_config);
cm_t3517_init_leds();
@@ -302,7 +297,7 @@ MACHINE_START(CM_T3517, "Compulab CM-T3517")
.atag_offset = 0x100,
.reserve = omap_reserve,
.map_io = omap3_map_io,
- .init_early = cm_t3517_init_early,
+ .init_early = am35xx_init_early,
.init_irq = omap3_init_irq,
.init_machine = cm_t3517_init,
.timer = &omap3_timer,
diff --git a/arch/arm/mach-omap2/board-devkit8000.c b/arch/arm/mach-omap2/board-devkit8000.c
index 99a42432ac93..556df32d88ea 100644
--- a/arch/arm/mach-omap2/board-devkit8000.c
+++ b/arch/arm/mach-omap2/board-devkit8000.c
@@ -397,19 +397,6 @@ static struct platform_device keys_gpio = {
},
};
-
-static void __init devkit8000_init_early(void)
-{
- omap2_init_common_infrastructure();
- omap2_init_common_devices(mt46h32m32lf6_sdrc_params,
- mt46h32m32lf6_sdrc_params);
-}
-
-static void __init devkit8000_init_irq(void)
-{
- omap3_init_irq();
-}
-
#define OMAP_DM9000_BASE 0x2c000000
static struct resource omap_dm9000_resources[] = {
@@ -645,6 +632,8 @@ static void __init devkit8000_init(void)
{
omap3_mux_init(board_mux, OMAP_PACKAGE_CUS);
omap_serial_init();
+ omap_sdrc_init(mt46h32m32lf6_sdrc_params,
+ mt46h32m32lf6_sdrc_params);
omap_dm9000_init();
@@ -670,8 +659,8 @@ MACHINE_START(DEVKIT8000, "OMAP3 Devkit8000")
.atag_offset = 0x100,
.reserve = omap_reserve,
.map_io = omap3_map_io,
- .init_early = devkit8000_init_early,
- .init_irq = devkit8000_init_irq,
+ .init_early = omap35xx_init_early,
+ .init_irq = omap3_init_irq,
.init_machine = devkit8000_init,
.timer = &omap3_secure_timer,
MACHINE_END
diff --git a/arch/arm/mach-omap2/board-flash.c b/arch/arm/mach-omap2/board-flash.c
index aa1b0cbe19d2..30a6f527510c 100644
--- a/arch/arm/mach-omap2/board-flash.c
+++ b/arch/arm/mach-omap2/board-flash.c
@@ -148,11 +148,6 @@ __init board_nand_init(struct mtd_partition *nand_parts,
board_nand_data.gpmc_irq = OMAP_GPMC_IRQ_BASE + cs;
gpmc_nand_init(&board_nand_data);
}
-#else
-void
-__init board_nand_init(struct mtd_partition *nand_parts, u8 nr_parts, u8 cs, int nand_type)
-{
-}
#endif /* CONFIG_MTD_NAND_OMAP2 || CONFIG_MTD_NAND_OMAP2_MODULE */
/**
diff --git a/arch/arm/mach-omap2/board-flash.h b/arch/arm/mach-omap2/board-flash.h
index c240a3f8d163..d25503a98417 100644
--- a/arch/arm/mach-omap2/board-flash.h
+++ b/arch/arm/mach-omap2/board-flash.h
@@ -24,7 +24,26 @@ struct flash_partitions {
int nr_parts;
};
+#if defined(CONFIG_MTD_NAND_OMAP2) || \
+ defined(CONFIG_MTD_NAND_OMAP2_MODULE) || \
+ defined(CONFIG_MTD_ONENAND_OMAP2) || \
+ defined(CONFIG_MTD_ONENAND_OMAP2_MODULE)
extern void board_flash_init(struct flash_partitions [],
char chip_sel[][GPMC_CS_NUM], int nand_type);
+#else
+static inline void board_flash_init(struct flash_partitions part[],
+ char chip_sel[][GPMC_CS_NUM], int nand_type)
+{
+}
+#endif
+
+#if defined(CONFIG_MTD_NAND_OMAP2) || \
+ defined(CONFIG_MTD_NAND_OMAP2_MODULE)
extern void board_nand_init(struct mtd_partition *nand_parts,
u8 nr_parts, u8 cs, int nand_type);
+#else
+static inline void board_nand_init(struct mtd_partition *nand_parts,
+ u8 nr_parts, u8 cs, int nand_type)
+{
+}
+#endif
diff --git a/arch/arm/mach-omap2/board-generic.c b/arch/arm/mach-omap2/board-generic.c
index 25642697281b..0c427976d62f 100644
--- a/arch/arm/mach-omap2/board-generic.c
+++ b/arch/arm/mach-omap2/board-generic.c
@@ -1,76 +1,158 @@
/*
- * linux/arch/arm/mach-omap2/board-generic.c
- *
* Copyright (C) 2005 Nokia Corporation
* Author: Paul Mundt <paul.mundt@nokia.com>
*
- * Modified from mach-omap/omap1/board-generic.c
+ * Copyright (C) 2011 Texas Instruments Incorporated - http://www.ti.com/
*
- * Code for generic OMAP2 board. Should work on many OMAP2 systems where
- * the bootloader passes the board-specific data to the kernel.
- * Do not put any board specific code to this file; create a new machine
- * type if you need custom low-level initializations.
+ * Modified from the original mach-omap/omap2/board-generic.c did by Paul
+ * to support the OMAP2+ device tree boards with an unique board file.
*
* 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/kernel.h>
-#include <linux/init.h>
-#include <linux/device.h>
+#include <linux/io.h>
+#include <linux/of_platform.h>
+#include <linux/irqdomain.h>
+#include <linux/i2c/twl.h>
#include <mach/hardware.h>
-#include <asm/mach-types.h>
#include <asm/mach/arch.h>
-#include <asm/mach/map.h>
-#include <mach/gpio.h>
-#include <plat/usb.h>
#include <plat/board.h>
#include <plat/common.h>
+#include <mach/omap4-common.h>
+#include "common-board-devices.h"
+
+/*
+ * XXX: Still needed to boot until the i2c & twl driver is adapted to
+ * device-tree
+ */
+static struct twl4030_platform_data sdp4430_twldata = {
+ .irq_base = TWL6030_IRQ_BASE,
+ .irq_end = TWL6030_IRQ_END,
+};
-static struct omap_board_config_kernel generic_config[] = {
+static void __init omap4_i2c_init(void)
+{
+ omap4_pmic_init("twl6030", &sdp4430_twldata);
+}
+
+static struct twl4030_platform_data beagle_twldata = {
+ .irq_base = TWL4030_IRQ_BASE,
+ .irq_end = TWL4030_IRQ_END,
};
-static void __init omap_generic_init_early(void)
+static void __init omap3_i2c_init(void)
{
- omap2_init_common_infrastructure();
- omap2_init_common_devices(NULL, NULL);
+ omap3_pmic_init("twl4030", &beagle_twldata);
}
+static struct of_device_id omap_dt_match_table[] __initdata = {
+ { .compatible = "simple-bus", },
+ { .compatible = "ti,omap-infra", },
+ { }
+};
+
+static struct of_device_id intc_match[] __initdata = {
+ { .compatible = "ti,omap3-intc", },
+ { .compatible = "arm,cortex-a9-gic", },
+ { }
+};
+
static void __init omap_generic_init(void)
{
+ struct device_node *node = of_find_matching_node(NULL, intc_match);
+ if (node)
+ irq_domain_add_simple(node, 0);
+
omap_serial_init();
- omap_board_config = generic_config;
- omap_board_config_size = ARRAY_SIZE(generic_config);
+ omap_sdrc_init(NULL, NULL);
+
+ of_platform_populate(NULL, omap_dt_match_table, NULL, NULL);
+}
+
+static void __init omap4_init(void)
+{
+ omap4_i2c_init();
+ omap_generic_init();
}
-static void __init omap_generic_map_io(void)
+static void __init omap3_init(void)
{
- if (cpu_is_omap242x()) {
- omap2_set_globals_242x();
- omap242x_map_common_io();
- } else if (cpu_is_omap243x()) {
- omap2_set_globals_243x();
- omap243x_map_common_io();
- } else if (cpu_is_omap34xx()) {
- omap2_set_globals_3xxx();
- omap34xx_map_common_io();
- } else if (cpu_is_omap44xx()) {
- omap2_set_globals_443x();
- omap44xx_map_common_io();
- }
+ omap3_i2c_init();
+ omap_generic_init();
}
-/* XXX This machine entry name should be updated */
-MACHINE_START(OMAP_GENERIC, "Generic OMAP24xx")
- /* Maintainer: Paul Mundt <paul.mundt@nokia.com> */
+#if defined(CONFIG_SOC_OMAP2420)
+static const char *omap242x_boards_compat[] __initdata = {
+ "ti,omap2420",
+ NULL,
+};
+
+DT_MACHINE_START(OMAP242X_DT, "Generic OMAP2420 (Flattened Device Tree)")
+ .atag_offset = 0x100,
+ .reserve = omap_reserve,
+ .map_io = omap242x_map_io,
+ .init_early = omap2420_init_early,
+ .init_irq = omap2_init_irq,
+ .init_machine = omap_generic_init,
+ .timer = &omap2_timer,
+ .dt_compat = omap242x_boards_compat,
+MACHINE_END
+#endif
+
+#if defined(CONFIG_SOC_OMAP2430)
+static const char *omap243x_boards_compat[] __initdata = {
+ "ti,omap2430",
+ NULL,
+};
+
+DT_MACHINE_START(OMAP243X_DT, "Generic OMAP2430 (Flattened Device Tree)")
.atag_offset = 0x100,
.reserve = omap_reserve,
- .map_io = omap_generic_map_io,
- .init_early = omap_generic_init_early,
+ .map_io = omap243x_map_io,
+ .init_early = omap2430_init_early,
.init_irq = omap2_init_irq,
.init_machine = omap_generic_init,
.timer = &omap2_timer,
+ .dt_compat = omap243x_boards_compat,
+MACHINE_END
+#endif
+
+#if defined(CONFIG_ARCH_OMAP3)
+static const char *omap3_boards_compat[] __initdata = {
+ "ti,omap3",
+ NULL,
+};
+
+DT_MACHINE_START(OMAP3_DT, "Generic OMAP3 (Flattened Device Tree)")
+ .atag_offset = 0x100,
+ .reserve = omap_reserve,
+ .map_io = omap3_map_io,
+ .init_early = omap3430_init_early,
+ .init_irq = omap3_init_irq,
+ .init_machine = omap3_init,
+ .timer = &omap3_timer,
+ .dt_compat = omap3_boards_compat,
+MACHINE_END
+#endif
+
+#if defined(CONFIG_ARCH_OMAP4)
+static const char *omap4_boards_compat[] __initdata = {
+ "ti,omap4",
+ NULL,
+};
+
+DT_MACHINE_START(OMAP4_DT, "Generic OMAP4 (Flattened Device Tree)")
+ .atag_offset = 0x100,
+ .reserve = omap_reserve,
+ .map_io = omap4_map_io,
+ .init_early = omap4430_init_early,
+ .init_irq = gic_init_irq,
+ .init_machine = omap4_init,
+ .timer = &omap4_timer,
+ .dt_compat = omap4_boards_compat,
MACHINE_END
+#endif
diff --git a/arch/arm/mach-omap2/board-h4.c b/arch/arm/mach-omap2/board-h4.c
index a58c6ba06f7f..fe75c195f69f 100644
--- a/arch/arm/mach-omap2/board-h4.c
+++ b/arch/arm/mach-omap2/board-h4.c
@@ -290,17 +290,6 @@ static struct omap_board_config_kernel h4_config[] __initdata = {
{ OMAP_TAG_LCD, &h4_lcd_config },
};
-static void __init omap_h4_init_early(void)
-{
- omap2_init_common_infrastructure();
- omap2_init_common_devices(NULL, NULL);
-}
-
-static void __init omap_h4_init_irq(void)
-{
- omap2_init_irq();
-}
-
static struct at24_platform_data m24c01 = {
.byte_len = SZ_1K / 8,
.page_size = 16,
@@ -371,22 +360,17 @@ static void __init omap_h4_init(void)
platform_add_devices(h4_devices, ARRAY_SIZE(h4_devices));
omap2_usbfs_init(&h4_usb_config);
omap_serial_init();
+ omap_sdrc_init(NULL, NULL);
h4_init_flash();
}
-static void __init omap_h4_map_io(void)
-{
- omap2_set_globals_242x();
- omap242x_map_common_io();
-}
-
MACHINE_START(OMAP_H4, "OMAP2420 H4 board")
/* Maintainer: Paul Mundt <paul.mundt@nokia.com> */
.atag_offset = 0x100,
.reserve = omap_reserve,
- .map_io = omap_h4_map_io,
- .init_early = omap_h4_init_early,
- .init_irq = omap_h4_init_irq,
+ .map_io = omap242x_map_io,
+ .init_early = omap2420_init_early,
+ .init_irq = omap2_init_irq,
.init_machine = omap_h4_init,
.timer = &omap2_timer,
MACHINE_END
diff --git a/arch/arm/mach-omap2/board-igep0020.c b/arch/arm/mach-omap2/board-igep0020.c
index 7040352b16b4..e20cad6a0835 100644
--- a/arch/arm/mach-omap2/board-igep0020.c
+++ b/arch/arm/mach-omap2/board-igep0020.c
@@ -491,13 +491,6 @@ static struct platform_device *igep_devices[] __initdata = {
&igep_vwlan_device,
};
-static void __init igep_init_early(void)
-{
- omap2_init_common_infrastructure();
- omap2_init_common_devices(m65kxxxxam_sdrc_params,
- m65kxxxxam_sdrc_params);
-}
-
static int igep2_keymap[] = {
KEY(0, 0, KEY_LEFT),
KEY(0, 1, KEY_RIGHT),
@@ -650,6 +643,8 @@ static void __init igep_init(void)
igep_i2c_init();
platform_add_devices(igep_devices, ARRAY_SIZE(igep_devices));
omap_serial_init();
+ omap_sdrc_init(m65kxxxxam_sdrc_params,
+ m65kxxxxam_sdrc_params);
usb_musb_init(NULL);
igep_flash_init();
@@ -675,7 +670,7 @@ MACHINE_START(IGEP0020, "IGEP v2 board")
.atag_offset = 0x100,
.reserve = omap_reserve,
.map_io = omap3_map_io,
- .init_early = igep_init_early,
+ .init_early = omap35xx_init_early,
.init_irq = omap3_init_irq,
.init_machine = igep_init,
.timer = &omap3_timer,
@@ -685,7 +680,7 @@ MACHINE_START(IGEP0030, "IGEP OMAP3 module")
.atag_offset = 0x100,
.reserve = omap_reserve,
.map_io = omap3_map_io,
- .init_early = igep_init_early,
+ .init_early = omap35xx_init_early,
.init_irq = omap3_init_irq,
.init_machine = igep_init,
.timer = &omap3_timer,
diff --git a/arch/arm/mach-omap2/board-ldp.c b/arch/arm/mach-omap2/board-ldp.c
index edf752bb24b1..0fa28be2cfda 100644
--- a/arch/arm/mach-omap2/board-ldp.c
+++ b/arch/arm/mach-omap2/board-ldp.c
@@ -193,12 +193,6 @@ static struct omap_board_config_kernel ldp_config[] __initdata = {
{ OMAP_TAG_LCD, &ldp_lcd_config },
};
-static void __init omap_ldp_init_early(void)
-{
- omap2_init_common_infrastructure();
- omap2_init_common_devices(NULL, NULL);
-}
-
static struct twl4030_gpio_platform_data ldp_gpio_data = {
.gpio_base = OMAP_MAX_GPIO_LINES,
.irq_base = TWL4030_GPIO_IRQ_BASE,
@@ -325,6 +319,7 @@ static void __init omap_ldp_init(void)
platform_add_devices(ldp_devices, ARRAY_SIZE(ldp_devices));
omap_ads7846_init(1, 54, 310, NULL);
omap_serial_init();
+ omap_sdrc_init(NULL, NULL);
usb_musb_init(NULL);
board_nand_init(ldp_nand_partitions,
ARRAY_SIZE(ldp_nand_partitions), ZOOM_NAND_CS, 0);
@@ -336,7 +331,7 @@ MACHINE_START(OMAP_LDP, "OMAP LDP board")
.atag_offset = 0x100,
.reserve = omap_reserve,
.map_io = omap3_map_io,
- .init_early = omap_ldp_init_early,
+ .init_early = omap3430_init_early,
.init_irq = omap3_init_irq,
.init_machine = omap_ldp_init,
.timer = &omap3_timer,
diff --git a/arch/arm/mach-omap2/board-n8x0.c b/arch/arm/mach-omap2/board-n8x0.c
index 6ce748154f24..e9d5f4a3d064 100644
--- a/arch/arm/mach-omap2/board-n8x0.c
+++ b/arch/arm/mach-omap2/board-n8x0.c
@@ -616,18 +616,6 @@ static struct i2c_board_info n810_i2c_board_info_2[] __initdata = {
},
};
-static void __init n8x0_map_io(void)
-{
- omap2_set_globals_242x();
- omap242x_map_common_io();
-}
-
-static void __init n8x0_init_early(void)
-{
- omap2_init_common_infrastructure();
- omap2_init_common_devices(NULL, NULL);
-}
-
#ifdef CONFIG_OMAP_MUX
static struct omap_board_mux board_mux[] __initdata = {
/* I2S codec port pins for McBSP block */
@@ -689,6 +677,7 @@ static void __init n8x0_init_machine(void)
i2c_register_board_info(2, n810_i2c_board_info_2,
ARRAY_SIZE(n810_i2c_board_info_2));
board_serial_init();
+ omap_sdrc_init(NULL, NULL);
gpmc_onenand_init(board_onenand_data);
n8x0_mmc_init();
n8x0_usb_init();
@@ -697,8 +686,8 @@ static void __init n8x0_init_machine(void)
MACHINE_START(NOKIA_N800, "Nokia N800")
.atag_offset = 0x100,
.reserve = omap_reserve,
- .map_io = n8x0_map_io,
- .init_early = n8x0_init_early,
+ .map_io = omap242x_map_io,
+ .init_early = omap2420_init_early,
.init_irq = omap2_init_irq,
.init_machine = n8x0_init_machine,
.timer = &omap2_timer,
@@ -707,8 +696,8 @@ MACHINE_END
MACHINE_START(NOKIA_N810, "Nokia N810")
.atag_offset = 0x100,
.reserve = omap_reserve,
- .map_io = n8x0_map_io,
- .init_early = n8x0_init_early,
+ .map_io = omap242x_map_io,
+ .init_early = omap2420_init_early,
.init_irq = omap2_init_irq,
.init_machine = n8x0_init_machine,
.timer = &omap2_timer,
@@ -717,8 +706,8 @@ MACHINE_END
MACHINE_START(NOKIA_N810_WIMAX, "Nokia N810 WiMAX")
.atag_offset = 0x100,
.reserve = omap_reserve,
- .map_io = n8x0_map_io,
- .init_early = n8x0_init_early,
+ .map_io = omap242x_map_io,
+ .init_early = omap2420_init_early,
.init_irq = omap2_init_irq,
.init_machine = n8x0_init_machine,
.timer = &omap2_timer,
diff --git a/arch/arm/mach-omap2/board-omap3beagle.c b/arch/arm/mach-omap2/board-omap3beagle.c
index 1fde8a0474bb..0b8e0fc03aab 100644
--- a/arch/arm/mach-omap2/board-omap3beagle.c
+++ b/arch/arm/mach-omap2/board-omap3beagle.c
@@ -447,13 +447,6 @@ static struct platform_device keys_gpio = {
static void __init omap3_beagle_init_early(void)
{
omap2_init_common_infrastructure();
- omap2_init_common_devices(mt46h32m32lf6_sdrc_params,
- mt46h32m32lf6_sdrc_params);
-}
-
-static void __init omap3_beagle_init_irq(void)
-{
- omap3_init_irq();
}
static struct platform_device *omap3_beagle_devices[] __initdata = {
@@ -493,8 +486,8 @@ static void __init beagle_opp_init(void)
if (cpu_is_omap3630()) {
struct device *mpu_dev, *iva_dev;
- mpu_dev = omap2_get_mpuss_device();
- iva_dev = omap2_get_iva_device();
+ mpu_dev = omap_device_get_by_hwmod_name("mpu");
+ iva_dev = omap_device_get_by_hwmod_name("iva");
if (!mpu_dev || !iva_dev) {
pr_err("%s: Aiee.. no mpu/dsp devices? %p %p\n",
@@ -534,6 +527,8 @@ static void __init omap3_beagle_init(void)
ARRAY_SIZE(omap3_beagle_devices));
omap_display_init(&beagle_dss_data);
omap_serial_init();
+ omap_sdrc_init(mt46h32m32lf6_sdrc_params,
+ mt46h32m32lf6_sdrc_params);
omap_mux_init_gpio(170, OMAP_PIN_INPUT);
/* REVISIT leave DVI powered down until it's needed ... */
@@ -561,7 +556,7 @@ MACHINE_START(OMAP3_BEAGLE, "OMAP3 Beagle Board")
.reserve = omap_reserve,
.map_io = omap3_map_io,
.init_early = omap3_beagle_init_early,
- .init_irq = omap3_beagle_init_irq,
+ .init_irq = omap3_init_irq,
.init_machine = omap3_beagle_init,
.timer = &omap3_secure_timer,
MACHINE_END
diff --git a/arch/arm/mach-omap2/board-omap3evm.c b/arch/arm/mach-omap2/board-omap3evm.c
index 15c69a0c1ce5..aa6a9351ce48 100644
--- a/arch/arm/mach-omap2/board-omap3evm.c
+++ b/arch/arm/mach-omap2/board-omap3evm.c
@@ -520,12 +520,6 @@ static int __init omap3_evm_i2c_init(void)
static struct omap_board_config_kernel omap3_evm_config[] __initdata = {
};
-static void __init omap3_evm_init_early(void)
-{
- omap2_init_common_infrastructure();
- omap2_init_common_devices(mt46h32m32lf6_sdrc_params, NULL);
-}
-
static struct usbhs_omap_board_data usbhs_bdata __initdata = {
.port_mode[0] = OMAP_USBHS_PORT_MODE_UNUSED,
@@ -640,6 +634,7 @@ static void __init omap3_evm_init(void)
omap_display_init(&omap3_evm_dss_data);
omap_serial_init();
+ omap_sdrc_init(mt46h32m32lf6_sdrc_params, NULL);
/* OMAP3EVM uses ISP1504 phy and so register nop transceiver */
usb_nop_xceiv_register();
@@ -684,7 +679,7 @@ MACHINE_START(OMAP3EVM, "OMAP3 EVM")
.atag_offset = 0x100,
.reserve = omap_reserve,
.map_io = omap3_map_io,
- .init_early = omap3_evm_init_early,
+ .init_early = omap35xx_init_early,
.init_irq = omap3_init_irq,
.init_machine = omap3_evm_init,
.timer = &omap3_timer,
diff --git a/arch/arm/mach-omap2/board-omap3logic.c b/arch/arm/mach-omap2/board-omap3logic.c
index 01354a214caf..7c0f193f246d 100644
--- a/arch/arm/mach-omap2/board-omap3logic.c
+++ b/arch/arm/mach-omap2/board-omap3logic.c
@@ -182,12 +182,6 @@ static inline void __init board_smsc911x_init(void)
gpmc_smsc911x_init(&board_smsc911x_data);
}
-static void __init omap3logic_init_early(void)
-{
- omap2_init_common_infrastructure();
- omap2_init_common_devices(NULL, NULL);
-}
-
#ifdef CONFIG_OMAP_MUX
static struct omap_board_mux board_mux[] __initdata = {
{ .reg_offset = OMAP_MUX_TERMINATOR },
@@ -200,6 +194,7 @@ static void __init omap3logic_init(void)
omap3torpedo_fix_pbias_voltage();
omap3logic_i2c_init();
omap_serial_init();
+ omap_sdrc_init(NULL, NULL);
board_mmc_init();
board_smsc911x_init();
@@ -211,7 +206,7 @@ static void __init omap3logic_init(void)
MACHINE_START(OMAP3_TORPEDO, "Logic OMAP3 Torpedo board")
.atag_offset = 0x100,
.map_io = omap3_map_io,
- .init_early = omap3logic_init_early,
+ .init_early = omap35xx_init_early,
.init_irq = omap3_init_irq,
.init_machine = omap3logic_init,
.timer = &omap3_timer,
@@ -220,7 +215,7 @@ MACHINE_END
MACHINE_START(OMAP3530_LV_SOM, "OMAP Logic 3530 LV SOM board")
.atag_offset = 0x100,
.map_io = omap3_map_io,
- .init_early = omap3logic_init_early,
+ .init_early = omap35xx_init_early,
.init_irq = omap3_init_irq,
.init_machine = omap3logic_init,
.timer = &omap3_timer,
diff --git a/arch/arm/mach-omap2/board-omap3pandora.c b/arch/arm/mach-omap2/board-omap3pandora.c
index ace56938dd3b..fed2f7dfdf8b 100644
--- a/arch/arm/mach-omap2/board-omap3pandora.c
+++ b/arch/arm/mach-omap2/board-omap3pandora.c
@@ -525,13 +525,6 @@ static struct spi_board_info omap3pandora_spi_board_info[] __initdata = {
}
};
-static void __init omap3pandora_init_early(void)
-{
- omap2_init_common_infrastructure();
- omap2_init_common_devices(mt46h32m32lf6_sdrc_params,
- mt46h32m32lf6_sdrc_params);
-}
-
static void __init pandora_wl1251_init(void)
{
struct wl12xx_platform_data pandora_wl1251_pdata;
@@ -593,6 +586,8 @@ static void __init omap3pandora_init(void)
ARRAY_SIZE(omap3pandora_devices));
omap_display_init(&pandora_dss_data);
omap_serial_init();
+ omap_sdrc_init(mt46h32m32lf6_sdrc_params,
+ mt46h32m32lf6_sdrc_params);
spi_register_board_info(omap3pandora_spi_board_info,
ARRAY_SIZE(omap3pandora_spi_board_info));
omap_ads7846_init(1, OMAP3_PANDORA_TS_GPIO, 0, NULL);
@@ -609,7 +604,7 @@ MACHINE_START(OMAP3_PANDORA, "Pandora Handheld Console")
.atag_offset = 0x100,
.reserve = omap_reserve,
.map_io = omap3_map_io,
- .init_early = omap3pandora_init_early,
+ .init_early = omap35xx_init_early,
.init_irq = omap3_init_irq,
.init_machine = omap3pandora_init,
.timer = &omap3_timer,
diff --git a/arch/arm/mach-omap2/board-omap3stalker.c b/arch/arm/mach-omap2/board-omap3stalker.c
index ba13e1d5d0ab..170e1ebd6e62 100644
--- a/arch/arm/mach-omap2/board-omap3stalker.c
+++ b/arch/arm/mach-omap2/board-omap3stalker.c
@@ -428,17 +428,6 @@ static int __init omap3_stalker_i2c_init(void)
static struct omap_board_config_kernel omap3_stalker_config[] __initdata = {
};
-static void __init omap3_stalker_init_early(void)
-{
- omap2_init_common_infrastructure();
- omap2_init_common_devices(mt46h32m32lf6_sdrc_params, NULL);
-}
-
-static void __init omap3_stalker_init_irq(void)
-{
- omap3_init_irq();
-}
-
static struct platform_device *omap3_stalker_devices[] __initdata = {
&keys_gpio,
};
@@ -478,6 +467,7 @@ static void __init omap3_stalker_init(void)
omap_display_init(&omap3_stalker_dss_data);
omap_serial_init();
+ omap_sdrc_init(mt46h32m32lf6_sdrc_params, NULL);
usb_musb_init(NULL);
usbhs_init(&usbhs_bdata);
omap_ads7846_init(1, OMAP3_STALKER_TS_GPIO, 310, NULL);
@@ -496,8 +486,8 @@ MACHINE_START(SBC3530, "OMAP3 STALKER")
/* Maintainer: Jason Lam -lzg@ema-tech.com */
.atag_offset = 0x100,
.map_io = omap3_map_io,
- .init_early = omap3_stalker_init_early,
- .init_irq = omap3_stalker_init_irq,
+ .init_early = omap35xx_init_early,
+ .init_irq = omap3_init_irq,
.init_machine = omap3_stalker_init,
.timer = &omap3_secure_timer,
MACHINE_END
diff --git a/arch/arm/mach-omap2/board-omap3touchbook.c b/arch/arm/mach-omap2/board-omap3touchbook.c
index 49e4bd207cb6..c2d5348f5422 100644
--- a/arch/arm/mach-omap2/board-omap3touchbook.c
+++ b/arch/arm/mach-omap2/board-omap3touchbook.c
@@ -326,18 +326,6 @@ static struct omap_board_mux board_mux[] __initdata = {
};
#endif
-static void __init omap3_touchbook_init_early(void)
-{
- omap2_init_common_infrastructure();
- omap2_init_common_devices(mt46h32m32lf6_sdrc_params,
- mt46h32m32lf6_sdrc_params);
-}
-
-static void __init omap3_touchbook_init_irq(void)
-{
- omap3_init_irq();
-}
-
static struct platform_device *omap3_touchbook_devices[] __initdata = {
&omap3_touchbook_lcd_device,
&leds_gpio,
@@ -385,6 +373,8 @@ static void __init omap3_touchbook_init(void)
platform_add_devices(omap3_touchbook_devices,
ARRAY_SIZE(omap3_touchbook_devices));
omap_serial_init();
+ omap_sdrc_init(mt46h32m32lf6_sdrc_params,
+ mt46h32m32lf6_sdrc_params);
omap_mux_init_gpio(170, OMAP_PIN_INPUT);
/* REVISIT leave DVI powered down until it's needed ... */
@@ -407,8 +397,8 @@ MACHINE_START(TOUCHBOOK, "OMAP3 touchbook Board")
.atag_offset = 0x100,
.reserve = omap_reserve,
.map_io = omap3_map_io,
- .init_early = omap3_touchbook_init_early,
- .init_irq = omap3_touchbook_init_irq,
+ .init_early = omap3430_init_early,
+ .init_irq = omap3_init_irq,
.init_machine = omap3_touchbook_init,
.timer = &omap3_secure_timer,
MACHINE_END
diff --git a/arch/arm/mach-omap2/board-omap4panda.c b/arch/arm/mach-omap2/board-omap4panda.c
index 683bede73d54..2141894eb9f3 100644
--- a/arch/arm/mach-omap2/board-omap4panda.c
+++ b/arch/arm/mach-omap2/board-omap4panda.c
@@ -95,12 +95,6 @@ static struct platform_device *panda_devices[] __initdata = {
&wl1271_device,
};
-static void __init omap4_panda_init_early(void)
-{
- omap2_init_common_infrastructure();
- omap2_init_common_devices(NULL, NULL);
-}
-
static const struct usbhs_omap_board_data usbhs_bdata __initconst = {
.port_mode[0] = OMAP_EHCI_PORT_MODE_PHY,
.port_mode[1] = OMAP_USBHS_PORT_MODE_UNUSED,
@@ -569,24 +563,19 @@ static void __init omap4_panda_init(void)
platform_add_devices(panda_devices, ARRAY_SIZE(panda_devices));
platform_device_register(&omap_vwlan_device);
board_serial_init();
+ omap_sdrc_init(NULL, NULL);
omap4_twl6030_hsmmc_init(mmc);
omap4_ehci_init();
usb_musb_init(&musb_board_data);
omap4_panda_display_init();
}
-static void __init omap4_panda_map_io(void)
-{
- omap2_set_globals_443x();
- omap44xx_map_common_io();
-}
-
MACHINE_START(OMAP4_PANDA, "OMAP4 Panda board")
/* Maintainer: David Anders - Texas Instruments Inc */
.atag_offset = 0x100,
.reserve = omap_reserve,
- .map_io = omap4_panda_map_io,
- .init_early = omap4_panda_init_early,
+ .map_io = omap4_map_io,
+ .init_early = omap4430_init_early,
.init_irq = gic_init_irq,
.init_machine = omap4_panda_init,
.timer = &omap4_timer,
diff --git a/arch/arm/mach-omap2/board-overo.c b/arch/arm/mach-omap2/board-overo.c
index e592fb134c4e..9f13dc22df77 100644
--- a/arch/arm/mach-omap2/board-overo.c
+++ b/arch/arm/mach-omap2/board-overo.c
@@ -478,13 +478,6 @@ static int __init overo_spi_init(void)
return 0;
}
-static void __init overo_init_early(void)
-{
- omap2_init_common_infrastructure();
- omap2_init_common_devices(mt46h32m32lf6_sdrc_params,
- mt46h32m32lf6_sdrc_params);
-}
-
static const struct usbhs_omap_board_data usbhs_bdata __initconst = {
.port_mode[0] = OMAP_USBHS_PORT_MODE_UNUSED,
.port_mode[1] = OMAP_EHCI_PORT_MODE_PHY,
@@ -514,6 +507,8 @@ static void __init overo_init(void)
overo_i2c_init();
omap_display_init(&overo_dss_data);
omap_serial_init();
+ omap_sdrc_init(mt46h32m32lf6_sdrc_params,
+ mt46h32m32lf6_sdrc_params);
omap_nand_flash_init(0, overo_nand_partitions,
ARRAY_SIZE(overo_nand_partitions));
usb_musb_init(NULL);
@@ -564,7 +559,7 @@ MACHINE_START(OVERO, "Gumstix Overo")
.atag_offset = 0x100,
.reserve = omap_reserve,
.map_io = omap3_map_io,
- .init_early = overo_init_early,
+ .init_early = omap35xx_init_early,
.init_irq = omap3_init_irq,
.init_machine = overo_init,
.timer = &omap3_timer,
diff --git a/arch/arm/mach-omap2/board-rm680.c b/arch/arm/mach-omap2/board-rm680.c
index 9a8ce239ba9e..616fb39763b0 100644
--- a/arch/arm/mach-omap2/board-rm680.c
+++ b/arch/arm/mach-omap2/board-rm680.c
@@ -123,15 +123,6 @@ static void __init rm680_peripherals_init(void)
omap2_hsmmc_init(mmc);
}
-static void __init rm680_init_early(void)
-{
- struct omap_sdrc_params *sdrc_params;
-
- omap2_init_common_infrastructure();
- sdrc_params = nokia_get_sdram_timings();
- omap2_init_common_devices(sdrc_params, sdrc_params);
-}
-
#ifdef CONFIG_OMAP_MUX
static struct omap_board_mux board_mux[] __initdata = {
{ .reg_offset = OMAP_MUX_TERMINATOR },
@@ -140,23 +131,23 @@ static struct omap_board_mux board_mux[] __initdata = {
static void __init rm680_init(void)
{
+ struct omap_sdrc_params *sdrc_params;
+
omap3_mux_init(board_mux, OMAP_PACKAGE_CBB);
omap_serial_init();
+
+ sdrc_params = nokia_get_sdram_timings();
+ omap_sdrc_init(sdrc_params, sdrc_params);
+
usb_musb_init(NULL);
rm680_peripherals_init();
}
-static void __init rm680_map_io(void)
-{
- omap2_set_globals_3xxx();
- omap34xx_map_common_io();
-}
-
MACHINE_START(NOKIA_RM680, "Nokia RM-680 board")
.atag_offset = 0x100,
.reserve = omap_reserve,
- .map_io = rm680_map_io,
- .init_early = rm680_init_early,
+ .map_io = omap3_map_io,
+ .init_early = omap3630_init_early,
.init_irq = omap3_init_irq,
.init_machine = rm680_init,
.timer = &omap3_timer,
diff --git a/arch/arm/mach-omap2/board-rx51.c b/arch/arm/mach-omap2/board-rx51.c
index a6c473bbb3d6..74c8aadc0a19 100644
--- a/arch/arm/mach-omap2/board-rx51.c
+++ b/arch/arm/mach-omap2/board-rx51.c
@@ -102,15 +102,6 @@ static struct omap_board_config_kernel rx51_config[] = {
{ OMAP_TAG_LCD, &rx51_lcd_config },
};
-static void __init rx51_init_early(void)
-{
- struct omap_sdrc_params *sdrc_params;
-
- omap2_init_common_infrastructure();
- sdrc_params = nokia_get_sdram_timings();
- omap2_init_common_devices(sdrc_params, sdrc_params);
-}
-
extern void __init rx51_peripherals_init(void);
#ifdef CONFIG_OMAP_MUX
@@ -127,11 +118,17 @@ static struct omap_musb_board_data musb_board_data = {
static void __init rx51_init(void)
{
+ struct omap_sdrc_params *sdrc_params;
+
omap3_mux_init(board_mux, OMAP_PACKAGE_CBB);
omap_board_config = rx51_config;
omap_board_config_size = ARRAY_SIZE(rx51_config);
omap3_pm_init_cpuidle(rx51_cpuidle_params);
omap_serial_init();
+
+ sdrc_params = nokia_get_sdram_timings();
+ omap_sdrc_init(sdrc_params, sdrc_params);
+
usb_musb_init(&musb_board_data);
rx51_peripherals_init();
@@ -142,12 +139,6 @@ static void __init rx51_init(void)
platform_device_register(&leds_gpio);
}
-static void __init rx51_map_io(void)
-{
- omap2_set_globals_3xxx();
- omap34xx_map_common_io();
-}
-
static void __init rx51_reserve(void)
{
rx51_video_mem_init();
@@ -158,8 +149,8 @@ MACHINE_START(NOKIA_RX51, "Nokia RX-51 board")
/* Maintainer: Lauri Leukkunen <lauri.leukkunen@nokia.com> */
.atag_offset = 0x100,
.reserve = rx51_reserve,
- .map_io = rx51_map_io,
- .init_early = rx51_init_early,
+ .map_io = omap3_map_io,
+ .init_early = omap3430_init_early,
.init_irq = omap3_init_irq,
.init_machine = rx51_init,
.timer = &omap3_timer,
diff --git a/arch/arm/mach-omap2/board-ti8168evm.c b/arch/arm/mach-omap2/board-ti8168evm.c
index e41958acb6b6..e26c79cb6ce9 100644
--- a/arch/arm/mach-omap2/board-ti8168evm.c
+++ b/arch/arm/mach-omap2/board-ti8168evm.c
@@ -27,15 +27,10 @@
static struct omap_board_config_kernel ti8168_evm_config[] __initdata = {
};
-static void __init ti8168_init_early(void)
-{
- omap2_init_common_infrastructure();
- omap2_init_common_devices(NULL, NULL);
-}
-
static void __init ti8168_evm_init(void)
{
omap_serial_init();
+ omap_sdrc_init(NULL, NULL);
omap_board_config = ti8168_evm_config;
omap_board_config_size = ARRAY_SIZE(ti8168_evm_config);
}
@@ -50,7 +45,7 @@ MACHINE_START(TI8168EVM, "ti8168evm")
/* Maintainer: Texas Instruments */
.atag_offset = 0x100,
.map_io = ti8168_evm_map_io,
- .init_early = ti8168_init_early,
+ .init_early = ti816x_init_early,
.init_irq = ti816x_init_irq,
.timer = &omap3_timer,
.init_machine = ti8168_evm_init,
diff --git a/arch/arm/mach-omap2/board-zoom.c b/arch/arm/mach-omap2/board-zoom.c
index 72f1db4863e5..be6684dc4f55 100644
--- a/arch/arm/mach-omap2/board-zoom.c
+++ b/arch/arm/mach-omap2/board-zoom.c
@@ -34,17 +34,6 @@
#define ZOOM3_EHCI_RESET_GPIO 64
-static void __init omap_zoom_init_early(void)
-{
- omap2_init_common_infrastructure();
- if (machine_is_omap_zoom2())
- omap2_init_common_devices(mt46h32m32lf6_sdrc_params,
- mt46h32m32lf6_sdrc_params);
- else if (machine_is_omap_zoom3())
- omap2_init_common_devices(h8mbx00u0mer0em_sdrc_params,
- h8mbx00u0mer0em_sdrc_params);
-}
-
#ifdef CONFIG_OMAP_MUX
static struct omap_board_mux board_mux[] __initdata = {
/* WLAN IRQ - GPIO 162 */
@@ -129,6 +118,14 @@ static void __init omap_zoom_init(void)
ZOOM_NAND_CS, NAND_BUSWIDTH_16);
zoom_debugboard_init();
zoom_peripherals_init();
+
+ if (machine_is_omap_zoom2())
+ omap_sdrc_init(mt46h32m32lf6_sdrc_params,
+ mt46h32m32lf6_sdrc_params);
+ else if (machine_is_omap_zoom3())
+ omap_sdrc_init(h8mbx00u0mer0em_sdrc_params,
+ h8mbx00u0mer0em_sdrc_params);
+
zoom_display_init();
}
@@ -136,7 +133,7 @@ MACHINE_START(OMAP_ZOOM2, "OMAP Zoom2 board")
.atag_offset = 0x100,
.reserve = omap_reserve,
.map_io = omap3_map_io,
- .init_early = omap_zoom_init_early,
+ .init_early = omap3430_init_early,
.init_irq = omap3_init_irq,
.init_machine = omap_zoom_init,
.timer = &omap3_timer,
@@ -146,7 +143,7 @@ MACHINE_START(OMAP_ZOOM3, "OMAP Zoom3 board")
.atag_offset = 0x100,
.reserve = omap_reserve,
.map_io = omap3_map_io,
- .init_early = omap_zoom_init_early,
+ .init_early = omap3630_init_early,
.init_irq = omap3_init_irq,
.init_machine = omap_zoom_init,
.timer = &omap3_timer,
diff --git a/arch/arm/mach-omap2/clock2420_data.c b/arch/arm/mach-omap2/clock2420_data.c
index debc040872f1..14a6277dd184 100644
--- a/arch/arm/mach-omap2/clock2420_data.c
+++ b/arch/arm/mach-omap2/clock2420_data.c
@@ -1898,6 +1898,54 @@ static struct omap_clk omap2420_clks[] = {
CLK(NULL, "pka_ick", &pka_ick, CK_242X),
CLK(NULL, "usb_fck", &usb_fck, CK_242X),
CLK("musb-hdrc", "fck", &osc_ck, CK_242X),
+ CLK("omap_timer.1", "fck", &gpt1_fck, CK_242X),
+ CLK("omap_timer.2", "fck", &gpt2_fck, CK_242X),
+ CLK("omap_timer.3", "fck", &gpt3_fck, CK_242X),
+ CLK("omap_timer.4", "fck", &gpt4_fck, CK_242X),
+ CLK("omap_timer.5", "fck", &gpt5_fck, CK_242X),
+ CLK("omap_timer.6", "fck", &gpt6_fck, CK_242X),
+ CLK("omap_timer.7", "fck", &gpt7_fck, CK_242X),
+ CLK("omap_timer.8", "fck", &gpt8_fck, CK_242X),
+ CLK("omap_timer.9", "fck", &gpt9_fck, CK_242X),
+ CLK("omap_timer.10", "fck", &gpt10_fck, CK_242X),
+ CLK("omap_timer.11", "fck", &gpt11_fck, CK_242X),
+ CLK("omap_timer.12", "fck", &gpt12_fck, CK_242X),
+ CLK("omap_timer.1", "32k_ck", &func_32k_ck, CK_243X),
+ CLK("omap_timer.2", "32k_ck", &func_32k_ck, CK_243X),
+ CLK("omap_timer.3", "32k_ck", &func_32k_ck, CK_243X),
+ CLK("omap_timer.4", "32k_ck", &func_32k_ck, CK_243X),
+ CLK("omap_timer.5", "32k_ck", &func_32k_ck, CK_243X),
+ CLK("omap_timer.6", "32k_ck", &func_32k_ck, CK_243X),
+ CLK("omap_timer.7", "32k_ck", &func_32k_ck, CK_243X),
+ CLK("omap_timer.8", "32k_ck", &func_32k_ck, CK_243X),
+ CLK("omap_timer.9", "32k_ck", &func_32k_ck, CK_243X),
+ CLK("omap_timer.10", "32k_ck", &func_32k_ck, CK_243X),
+ CLK("omap_timer.11", "32k_ck", &func_32k_ck, CK_243X),
+ CLK("omap_timer.12", "32k_ck", &func_32k_ck, CK_243X),
+ CLK("omap_timer.1", "sys_ck", &sys_ck, CK_243X),
+ CLK("omap_timer.2", "sys_ck", &sys_ck, CK_243X),
+ CLK("omap_timer.3", "sys_ck", &sys_ck, CK_243X),
+ CLK("omap_timer.4", "sys_ck", &sys_ck, CK_243X),
+ CLK("omap_timer.5", "sys_ck", &sys_ck, CK_243X),
+ CLK("omap_timer.6", "sys_ck", &sys_ck, CK_243X),
+ CLK("omap_timer.7", "sys_ck", &sys_ck, CK_243X),
+ CLK("omap_timer.8", "sys_ck", &sys_ck, CK_243X),
+ CLK("omap_timer.9", "sys_ck", &sys_ck, CK_243X),
+ CLK("omap_timer.10", "sys_ck", &sys_ck, CK_243X),
+ CLK("omap_timer.11", "sys_ck", &sys_ck, CK_243X),
+ CLK("omap_timer.12", "sys_ck", &sys_ck, CK_243X),
+ CLK("omap_timer.1", "alt_ck", &alt_ck, CK_243X),
+ CLK("omap_timer.2", "alt_ck", &alt_ck, CK_243X),
+ CLK("omap_timer.3", "alt_ck", &alt_ck, CK_243X),
+ CLK("omap_timer.4", "alt_ck", &alt_ck, CK_243X),
+ CLK("omap_timer.5", "alt_ck", &alt_ck, CK_243X),
+ CLK("omap_timer.6", "alt_ck", &alt_ck, CK_243X),
+ CLK("omap_timer.7", "alt_ck", &alt_ck, CK_243X),
+ CLK("omap_timer.8", "alt_ck", &alt_ck, CK_243X),
+ CLK("omap_timer.9", "alt_ck", &alt_ck, CK_243X),
+ CLK("omap_timer.10", "alt_ck", &alt_ck, CK_243X),
+ CLK("omap_timer.11", "alt_ck", &alt_ck, CK_243X),
+ CLK("omap_timer.12", "alt_ck", &alt_ck, CK_243X),
};
/*
diff --git a/arch/arm/mach-omap2/clock2430_data.c b/arch/arm/mach-omap2/clock2430_data.c
index 96a942e42db1..ea6717cfa3c8 100644
--- a/arch/arm/mach-omap2/clock2430_data.c
+++ b/arch/arm/mach-omap2/clock2430_data.c
@@ -1998,6 +1998,54 @@ static struct omap_clk omap2430_clks[] = {
CLK(NULL, "mdm_intc_ick", &mdm_intc_ick, CK_243X),
CLK("omap_hsmmc.0", "mmchsdb_fck", &mmchsdb1_fck, CK_243X),
CLK("omap_hsmmc.1", "mmchsdb_fck", &mmchsdb2_fck, CK_243X),
+ CLK("omap_timer.1", "fck", &gpt1_fck, CK_243X),
+ CLK("omap_timer.2", "fck", &gpt2_fck, CK_243X),
+ CLK("omap_timer.3", "fck", &gpt3_fck, CK_243X),
+ CLK("omap_timer.4", "fck", &gpt4_fck, CK_243X),
+ CLK("omap_timer.5", "fck", &gpt5_fck, CK_243X),
+ CLK("omap_timer.6", "fck", &gpt6_fck, CK_243X),
+ CLK("omap_timer.7", "fck", &gpt7_fck, CK_243X),
+ CLK("omap_timer.8", "fck", &gpt8_fck, CK_243X),
+ CLK("omap_timer.9", "fck", &gpt9_fck, CK_243X),
+ CLK("omap_timer.10", "fck", &gpt10_fck, CK_243X),
+ CLK("omap_timer.11", "fck", &gpt11_fck, CK_243X),
+ CLK("omap_timer.12", "fck", &gpt12_fck, CK_243X),
+ CLK("omap_timer.1", "32k_ck", &func_32k_ck, CK_243X),
+ CLK("omap_timer.2", "32k_ck", &func_32k_ck, CK_243X),
+ CLK("omap_timer.3", "32k_ck", &func_32k_ck, CK_243X),
+ CLK("omap_timer.4", "32k_ck", &func_32k_ck, CK_243X),
+ CLK("omap_timer.5", "32k_ck", &func_32k_ck, CK_243X),
+ CLK("omap_timer.6", "32k_ck", &func_32k_ck, CK_243X),
+ CLK("omap_timer.7", "32k_ck", &func_32k_ck, CK_243X),
+ CLK("omap_timer.8", "32k_ck", &func_32k_ck, CK_243X),
+ CLK("omap_timer.9", "32k_ck", &func_32k_ck, CK_243X),
+ CLK("omap_timer.10", "32k_ck", &func_32k_ck, CK_243X),
+ CLK("omap_timer.11", "32k_ck", &func_32k_ck, CK_243X),
+ CLK("omap_timer.12", "32k_ck", &func_32k_ck, CK_243X),
+ CLK("omap_timer.1", "sys_ck", &sys_ck, CK_243X),
+ CLK("omap_timer.2", "sys_ck", &sys_ck, CK_243X),
+ CLK("omap_timer.3", "sys_ck", &sys_ck, CK_243X),
+ CLK("omap_timer.4", "sys_ck", &sys_ck, CK_243X),
+ CLK("omap_timer.5", "sys_ck", &sys_ck, CK_243X),
+ CLK("omap_timer.6", "sys_ck", &sys_ck, CK_243X),
+ CLK("omap_timer.7", "sys_ck", &sys_ck, CK_243X),
+ CLK("omap_timer.8", "sys_ck", &sys_ck, CK_243X),
+ CLK("omap_timer.9", "sys_ck", &sys_ck, CK_243X),
+ CLK("omap_timer.10", "sys_ck", &sys_ck, CK_243X),
+ CLK("omap_timer.11", "sys_ck", &sys_ck, CK_243X),
+ CLK("omap_timer.12", "sys_ck", &sys_ck, CK_243X),
+ CLK("omap_timer.1", "alt_ck", &alt_ck, CK_243X),
+ CLK("omap_timer.2", "alt_ck", &alt_ck, CK_243X),
+ CLK("omap_timer.3", "alt_ck", &alt_ck, CK_243X),
+ CLK("omap_timer.4", "alt_ck", &alt_ck, CK_243X),
+ CLK("omap_timer.5", "alt_ck", &alt_ck, CK_243X),
+ CLK("omap_timer.6", "alt_ck", &alt_ck, CK_243X),
+ CLK("omap_timer.7", "alt_ck", &alt_ck, CK_243X),
+ CLK("omap_timer.8", "alt_ck", &alt_ck, CK_243X),
+ CLK("omap_timer.9", "alt_ck", &alt_ck, CK_243X),
+ CLK("omap_timer.10", "alt_ck", &alt_ck, CK_243X),
+ CLK("omap_timer.11", "alt_ck", &alt_ck, CK_243X),
+ CLK("omap_timer.12", "alt_ck", &alt_ck, CK_243X),
};
/*
diff --git a/arch/arm/mach-omap2/clock3xxx_data.c b/arch/arm/mach-omap2/clock3xxx_data.c
index b9b844683147..65dd363163bc 100644
--- a/arch/arm/mach-omap2/clock3xxx_data.c
+++ b/arch/arm/mach-omap2/clock3xxx_data.c
@@ -3464,6 +3464,42 @@ static struct omap_clk omap3xxx_clks[] = {
CLK("musb-am35x", "fck", &hsotgusb_fck_am35xx, CK_AM35XX),
CLK(NULL, "hecc_ck", &hecc_ck, CK_AM35XX),
CLK(NULL, "uart4_ick", &uart4_ick_am35xx, CK_AM35XX),
+ CLK("omap_timer.1", "fck", &gpt1_fck, CK_3XXX),
+ CLK("omap_timer.2", "fck", &gpt2_fck, CK_3XXX),
+ CLK("omap_timer.3", "fck", &gpt3_fck, CK_3XXX),
+ CLK("omap_timer.4", "fck", &gpt4_fck, CK_3XXX),
+ CLK("omap_timer.5", "fck", &gpt5_fck, CK_3XXX),
+ CLK("omap_timer.6", "fck", &gpt6_fck, CK_3XXX),
+ CLK("omap_timer.7", "fck", &gpt7_fck, CK_3XXX),
+ CLK("omap_timer.8", "fck", &gpt8_fck, CK_3XXX),
+ CLK("omap_timer.9", "fck", &gpt9_fck, CK_3XXX),
+ CLK("omap_timer.10", "fck", &gpt10_fck, CK_3XXX),
+ CLK("omap_timer.11", "fck", &gpt11_fck, CK_3XXX),
+ CLK("omap_timer.12", "fck", &gpt12_fck, CK_3XXX),
+ CLK("omap_timer.1", "32k_ck", &omap_32k_fck, CK_3XXX),
+ CLK("omap_timer.2", "32k_ck", &omap_32k_fck, CK_3XXX),
+ CLK("omap_timer.3", "32k_ck", &omap_32k_fck, CK_3XXX),
+ CLK("omap_timer.4", "32k_ck", &omap_32k_fck, CK_3XXX),
+ CLK("omap_timer.5", "32k_ck", &omap_32k_fck, CK_3XXX),
+ CLK("omap_timer.6", "32k_ck", &omap_32k_fck, CK_3XXX),
+ CLK("omap_timer.7", "32k_ck", &omap_32k_fck, CK_3XXX),
+ CLK("omap_timer.8", "32k_ck", &omap_32k_fck, CK_3XXX),
+ CLK("omap_timer.9", "32k_ck", &omap_32k_fck, CK_3XXX),
+ CLK("omap_timer.10", "32k_ck", &omap_32k_fck, CK_3XXX),
+ CLK("omap_timer.11", "32k_ck", &omap_32k_fck, CK_3XXX),
+ CLK("omap_timer.12", "32k_ck", &omap_32k_fck, CK_3XXX),
+ CLK("omap_timer.1", "sys_ck", &sys_ck, CK_3XXX),
+ CLK("omap_timer.2", "sys_ck", &sys_ck, CK_3XXX),
+ CLK("omap_timer.3", "sys_ck", &sys_ck, CK_3XXX),
+ CLK("omap_timer.4", "sys_ck", &sys_ck, CK_3XXX),
+ CLK("omap_timer.5", "sys_ck", &sys_ck, CK_3XXX),
+ CLK("omap_timer.6", "sys_ck", &sys_ck, CK_3XXX),
+ CLK("omap_timer.7", "sys_ck", &sys_ck, CK_3XXX),
+ CLK("omap_timer.8", "sys_ck", &sys_ck, CK_3XXX),
+ CLK("omap_timer.9", "sys_ck", &sys_ck, CK_3XXX),
+ CLK("omap_timer.10", "sys_ck", &sys_ck, CK_3XXX),
+ CLK("omap_timer.11", "sys_ck", &sys_ck, CK_3XXX),
+ CLK("omap_timer.12", "sys_ck", &sys_ck, CK_3XXX),
};
@@ -3472,7 +3508,16 @@ int __init omap3xxx_clk_init(void)
struct omap_clk *c;
u32 cpu_clkflg = 0;
- if (cpu_is_omap3517()) {
+ /*
+ * 3505 must be tested before 3517, since 3517 returns true
+ * for both AM3517 chips and AM3517 family chips, which
+ * includes 3505. Unfortunately there's no obvious family
+ * test for 3517/3505 :-(
+ */
+ if (cpu_is_omap3505()) {
+ cpu_mask = RATE_IN_34XX;
+ cpu_clkflg = CK_3505;
+ } else if (cpu_is_omap3517()) {
cpu_mask = RATE_IN_34XX;
cpu_clkflg = CK_3517;
} else if (cpu_is_omap3505()) {
diff --git a/arch/arm/mach-omap2/clock44xx_data.c b/arch/arm/mach-omap2/clock44xx_data.c
index c0b6fbda3408..946bf04a956d 100644
--- a/arch/arm/mach-omap2/clock44xx_data.c
+++ b/arch/arm/mach-omap2/clock44xx_data.c
@@ -3363,6 +3363,39 @@ static struct omap_clk omap44xx_clks[] = {
CLK("usbhs-omap.0", "usbhost_ick", &dummy_ck, CK_443X),
CLK("usbhs-omap.0", "usbtll_fck", &dummy_ck, CK_443X),
CLK("omap_wdt", "ick", &dummy_ck, CK_443X),
+ CLK("omap_timer.1", "fck", &timer1_fck, CK_443X),
+ CLK("omap_timer.2", "fck", &timer2_fck, CK_443X),
+ CLK("omap_timer.3", "fck", &timer3_fck, CK_443X),
+ CLK("omap_timer.4", "fck", &timer4_fck, CK_443X),
+ CLK("omap_timer.5", "fck", &timer5_fck, CK_443X),
+ CLK("omap_timer.6", "fck", &timer6_fck, CK_443X),
+ CLK("omap_timer.7", "fck", &timer7_fck, CK_443X),
+ CLK("omap_timer.8", "fck", &timer8_fck, CK_443X),
+ CLK("omap_timer.9", "fck", &timer9_fck, CK_443X),
+ CLK("omap_timer.10", "fck", &timer10_fck, CK_443X),
+ CLK("omap_timer.11", "fck", &timer11_fck, CK_443X),
+ CLK("omap_timer.1", "32k_ck", &sys_32k_ck, CK_443X),
+ CLK("omap_timer.2", "32k_ck", &sys_32k_ck, CK_443X),
+ CLK("omap_timer.3", "32k_ck", &sys_32k_ck, CK_443X),
+ CLK("omap_timer.4", "32k_ck", &sys_32k_ck, CK_443X),
+ CLK("omap_timer.5", "32k_ck", &sys_32k_ck, CK_443X),
+ CLK("omap_timer.6", "32k_ck", &sys_32k_ck, CK_443X),
+ CLK("omap_timer.7", "32k_ck", &sys_32k_ck, CK_443X),
+ CLK("omap_timer.8", "32k_ck", &sys_32k_ck, CK_443X),
+ CLK("omap_timer.9", "32k_ck", &sys_32k_ck, CK_443X),
+ CLK("omap_timer.10", "32k_ck", &sys_32k_ck, CK_443X),
+ CLK("omap_timer.11", "32k_ck", &sys_32k_ck, CK_443X),
+ CLK("omap_timer.1", "sys_ck", &sys_clkin_ck, CK_443X),
+ CLK("omap_timer.2", "sys_ck", &sys_clkin_ck, CK_443X),
+ CLK("omap_timer.3", "sys_ck", &sys_clkin_ck, CK_443X),
+ CLK("omap_timer.4", "sys_ck", &sys_clkin_ck, CK_443X),
+ CLK("omap_timer.9", "sys_ck", &sys_clkin_ck, CK_443X),
+ CLK("omap_timer.10", "sys_ck", &sys_clkin_ck, CK_443X),
+ CLK("omap_timer.11", "sys_ck", &sys_clkin_ck, CK_443X),
+ CLK("omap_timer.5", "sys_ck", &syc_clk_div_ck, CK_443X),
+ CLK("omap_timer.6", "sys_ck", &syc_clk_div_ck, CK_443X),
+ CLK("omap_timer.7", "sys_ck", &syc_clk_div_ck, CK_443X),
+ CLK("omap_timer.8", "sys_ck", &syc_clk_div_ck, CK_443X),
};
int __init omap4xxx_clk_init(void)
diff --git a/arch/arm/mach-omap2/clockdomain.c b/arch/arm/mach-omap2/clockdomain.c
index 8f0890685d7b..8480ee4344ea 100644
--- a/arch/arm/mach-omap2/clockdomain.c
+++ b/arch/arm/mach-omap2/clockdomain.c
@@ -73,9 +73,6 @@ static int _clkdm_register(struct clockdomain *clkdm)
if (!clkdm || !clkdm->name)
return -EINVAL;
- if (!omap_chip_is(clkdm->omap_chip))
- return -EINVAL;
-
pwrdm = pwrdm_lookup(clkdm->pwrdm.name);
if (!pwrdm) {
pr_err("clockdomain: %s: powerdomain %s does not exist\n",
@@ -105,13 +102,10 @@ static struct clkdm_dep *_clkdm_deps_lookup(struct clockdomain *clkdm,
{
struct clkdm_dep *cd;
- if (!clkdm || !deps || !omap_chip_is(clkdm->omap_chip))
+ if (!clkdm || !deps)
return ERR_PTR(-EINVAL);
for (cd = deps; cd->clkdm_name; cd++) {
- if (!omap_chip_is(cd->omap_chip))
- continue;
-
if (!cd->clkdm && cd->clkdm_name)
cd->clkdm = _clkdm_lookup(cd->clkdm_name);
@@ -148,9 +142,6 @@ static void _autodep_lookup(struct clkdm_autodep *autodep)
if (!autodep)
return;
- if (!omap_chip_is(autodep->omap_chip))
- return;
-
clkdm = clkdm_lookup(autodep->clkdm.name);
if (!clkdm) {
pr_err("clockdomain: autodeps: clockdomain %s does not exist\n",
@@ -182,9 +173,6 @@ void _clkdm_add_autodeps(struct clockdomain *clkdm)
if (IS_ERR(autodep->clkdm.ptr))
continue;
- if (!omap_chip_is(autodep->omap_chip))
- continue;
-
pr_debug("clockdomain: adding %s sleepdep/wkdep for "
"clkdm %s\n", autodep->clkdm.ptr->name,
clkdm->name);
@@ -216,9 +204,6 @@ void _clkdm_del_autodeps(struct clockdomain *clkdm)
if (IS_ERR(autodep->clkdm.ptr))
continue;
- if (!omap_chip_is(autodep->omap_chip))
- continue;
-
pr_debug("clockdomain: removing %s sleepdep/wkdep for "
"clkdm %s\n", autodep->clkdm.ptr->name,
clkdm->name);
@@ -243,8 +228,6 @@ static void _resolve_clkdm_deps(struct clockdomain *clkdm,
struct clkdm_dep *cd;
for (cd = clkdm_deps; cd && cd->clkdm_name; cd++) {
- if (!omap_chip_is(cd->omap_chip))
- continue;
if (cd->clkdm)
continue;
cd->clkdm = _clkdm_lookup(cd->clkdm_name);
@@ -257,43 +240,113 @@ static void _resolve_clkdm_deps(struct clockdomain *clkdm,
/* Public functions */
/**
- * clkdm_init - set up the clockdomain layer
- * @clkdms: optional pointer to an array of clockdomains to register
- * @init_autodeps: optional pointer to an array of autodeps to register
- * @custom_funcs: func pointers for arch specific implementations
- *
- * Set up internal state. If a pointer to an array of clockdomains
- * @clkdms was supplied, loop through the list of clockdomains,
- * register all that are available on the current platform. Similarly,
- * if a pointer to an array of clockdomain autodependencies
- * @init_autodeps was provided, register those. No return value.
+ * clkdm_register_platform_funcs - register clockdomain implementation fns
+ * @co: func pointers for arch specific implementations
+ *
+ * Register the list of function pointers used to implement the
+ * clockdomain functions on different OMAP SoCs. Should be called
+ * before any other clkdm_register*() function. Returns -EINVAL if
+ * @co is null, -EEXIST if platform functions have already been
+ * registered, or 0 upon success.
+ */
+int clkdm_register_platform_funcs(struct clkdm_ops *co)
+{
+ if (!co)
+ return -EINVAL;
+
+ if (arch_clkdm)
+ return -EEXIST;
+
+ arch_clkdm = co;
+
+ return 0;
+};
+
+/**
+ * clkdm_register_clkdms - register SoC clockdomains
+ * @cs: pointer to an array of struct clockdomain to register
+ *
+ * Register the clockdomains available on a particular OMAP SoC. Must
+ * be called after clkdm_register_platform_funcs(). May be called
+ * multiple times. Returns -EACCES if called before
+ * clkdm_register_platform_funcs(); -EINVAL if the argument @cs is
+ * null; or 0 upon success.
*/
-void clkdm_init(struct clockdomain **clkdms,
- struct clkdm_autodep *init_autodeps,
- struct clkdm_ops *custom_funcs)
+int clkdm_register_clkdms(struct clockdomain **cs)
{
struct clockdomain **c = NULL;
- struct clockdomain *clkdm;
- struct clkdm_autodep *autodep = NULL;
- if (!custom_funcs)
- WARN(1, "No custom clkdm functions registered\n");
- else
- arch_clkdm = custom_funcs;
+ if (!arch_clkdm)
+ return -EACCES;
+
+ if (!cs)
+ return -EINVAL;
+
+ for (c = cs; *c; c++)
+ _clkdm_register(*c);
+
+ return 0;
+}
+
+/**
+ * clkdm_register_autodeps - register autodeps (if required)
+ * @ia: pointer to a static array of struct clkdm_autodep to register
+ *
+ * Register clockdomain "automatic dependencies." These are
+ * clockdomain wakeup and sleep dependencies that are automatically
+ * added whenever the first clock inside a clockdomain is enabled, and
+ * removed whenever the last clock inside a clockdomain is disabled.
+ * These are currently only used on OMAP3 devices, and are deprecated,
+ * since they waste energy. However, until the OMAP2/3 IP block
+ * enable/disable sequence can be converted to match the OMAP4
+ * sequence, they are needed.
+ *
+ * Must be called only after all of the SoC clockdomains are
+ * registered, since the function will resolve autodep clockdomain
+ * names into clockdomain pointers.
+ *
+ * The struct clkdm_autodep @ia array must be static, as this function
+ * does not copy the array elements.
+ *
+ * Returns -EACCES if called before any clockdomains have been
+ * registered, -EINVAL if called with a null @ia argument, -EEXIST if
+ * autodeps have already been registered, or 0 upon success.
+ */
+int clkdm_register_autodeps(struct clkdm_autodep *ia)
+{
+ struct clkdm_autodep *a = NULL;
- if (clkdms)
- for (c = clkdms; *c; c++)
- _clkdm_register(*c);
+ if (list_empty(&clkdm_list))
+ return -EACCES;
+
+ if (!ia)
+ return -EINVAL;
- autodeps = init_autodeps;
if (autodeps)
- for (autodep = autodeps; autodep->clkdm.ptr; autodep++)
- _autodep_lookup(autodep);
+ return -EEXIST;
+
+ autodeps = ia;
+ for (a = autodeps; a->clkdm.ptr; a++)
+ _autodep_lookup(a);
+
+ return 0;
+}
+
+/**
+ * clkdm_complete_init - set up the clockdomain layer
+ *
+ * Put all clockdomains into software-supervised mode; PM code should
+ * later enable hardware-supervised mode as appropriate. Must be
+ * called after clkdm_register_clkdms(). Returns -EACCES if called
+ * before clkdm_register_clkdms(), or 0 upon success.
+ */
+int clkdm_complete_init(void)
+{
+ struct clockdomain *clkdm;
+
+ if (list_empty(&clkdm_list))
+ return -EACCES;
- /*
- * Put all clockdomains into software-supervised mode; PM code
- * should later enable hardware-supervised mode as appropriate
- */
list_for_each_entry(clkdm, &clkdm_list, node) {
if (clkdm->flags & CLKDM_CAN_FORCE_WAKEUP)
clkdm_wakeup(clkdm);
@@ -306,6 +359,8 @@ void clkdm_init(struct clockdomain **clkdms,
_resolve_clkdm_deps(clkdm, clkdm->sleepdep_srcs);
clkdm_clear_all_sleepdeps(clkdm);
}
+
+ return 0;
}
/**
diff --git a/arch/arm/mach-omap2/clockdomain.h b/arch/arm/mach-omap2/clockdomain.h
index 1e50c88b8a07..f7b58609bad8 100644
--- a/arch/arm/mach-omap2/clockdomain.h
+++ b/arch/arm/mach-omap2/clockdomain.h
@@ -45,7 +45,6 @@
/**
* struct clkdm_autodep - clkdm deps to add when entering/exiting hwsup mode
* @clkdm: clockdomain to add wkdep+sleepdep on - set name member only
- * @omap_chip: OMAP chip types that this autodep is valid on
*
* A clockdomain that should have wkdeps and sleepdeps added when a
* clockdomain should stay active in hwsup mode; and conversely,
@@ -60,14 +59,12 @@ struct clkdm_autodep {
const char *name;
struct clockdomain *ptr;
} clkdm;
- const struct omap_chip_id omap_chip;
};
/**
* struct clkdm_dep - encode dependencies between clockdomains
* @clkdm_name: clockdomain name
* @clkdm: pointer to the struct clockdomain of @clkdm_name
- * @omap_chip: OMAP chip types that this dependency is valid on
* @wkdep_usecount: Number of wakeup dependencies causing this clkdm to wake
* @sleepdep_usecount: Number of sleep deps that could prevent clkdm from idle
*
@@ -81,7 +78,6 @@ struct clkdm_dep {
struct clockdomain *clkdm;
atomic_t wkdep_usecount;
atomic_t sleepdep_usecount;
- const struct omap_chip_id omap_chip;
};
/* Possible flags for struct clockdomain._flags */
@@ -101,7 +97,6 @@ struct clkdm_dep {
* @clkdm_offs: (OMAP4 only) CM clockdomain register offset
* @wkdep_srcs: Clockdomains that can be told to wake this powerdomain up
* @sleepdep_srcs: Clockdomains that can be told to keep this clkdm from inact
- * @omap_chip: OMAP chip types that this clockdomain is valid on
* @usecount: Usecount tracking
* @node: list_head to link all clockdomains together
*
@@ -126,7 +121,6 @@ struct clockdomain {
const u16 clkdm_offs;
struct clkdm_dep *wkdep_srcs;
struct clkdm_dep *sleepdep_srcs;
- const struct omap_chip_id omap_chip;
atomic_t usecount;
struct list_head node;
spinlock_t lock;
@@ -166,8 +160,11 @@ struct clkdm_ops {
int (*clkdm_clk_disable)(struct clockdomain *clkdm);
};
-void clkdm_init(struct clockdomain **clkdms, struct clkdm_autodep *autodeps,
- struct clkdm_ops *custom_funcs);
+int clkdm_register_platform_funcs(struct clkdm_ops *co);
+int clkdm_register_autodeps(struct clkdm_autodep *ia);
+int clkdm_register_clkdms(struct clockdomain **c);
+int clkdm_complete_init(void);
+
struct clockdomain *clkdm_lookup(const char *name);
int clkdm_for_each(int (*fn)(struct clockdomain *clkdm, void *user),
@@ -195,7 +192,8 @@ int clkdm_clk_disable(struct clockdomain *clkdm, struct clk *clk);
int clkdm_hwmod_enable(struct clockdomain *clkdm, struct omap_hwmod *oh);
int clkdm_hwmod_disable(struct clockdomain *clkdm, struct omap_hwmod *oh);
-extern void __init omap2xxx_clockdomains_init(void);
+extern void __init omap242x_clockdomains_init(void);
+extern void __init omap243x_clockdomains_init(void);
extern void __init omap3xxx_clockdomains_init(void);
extern void __init omap44xx_clockdomains_init(void);
extern void _clkdm_add_autodeps(struct clockdomain *clkdm);
@@ -205,4 +203,10 @@ extern struct clkdm_ops omap2_clkdm_operations;
extern struct clkdm_ops omap3_clkdm_operations;
extern struct clkdm_ops omap4_clkdm_operations;
+extern struct clkdm_dep gfx_24xx_wkdeps[];
+extern struct clkdm_dep dsp_24xx_wkdeps[];
+extern struct clockdomain wkup_common_clkdm;
+extern struct clockdomain prm_common_clkdm;
+extern struct clockdomain cm_common_clkdm;
+
#endif
diff --git a/arch/arm/mach-omap2/clockdomain2xxx_3xxx.c b/arch/arm/mach-omap2/clockdomain2xxx_3xxx.c
index f740edb111f4..a0d68dbecfa3 100644
--- a/arch/arm/mach-omap2/clockdomain2xxx_3xxx.c
+++ b/arch/arm/mach-omap2/clockdomain2xxx_3xxx.c
@@ -52,8 +52,6 @@ static int omap2_clkdm_clear_all_wkdeps(struct clockdomain *clkdm)
u32 mask = 0;
for (cd = clkdm->wkdep_srcs; cd && cd->clkdm_name; cd++) {
- if (!omap_chip_is(cd->omap_chip))
- continue;
if (!cd->clkdm)
continue; /* only happens if data is erroneous */
@@ -98,8 +96,6 @@ static int omap3_clkdm_clear_all_sleepdeps(struct clockdomain *clkdm)
u32 mask = 0;
for (cd = clkdm->sleepdep_srcs; cd && cd->clkdm_name; cd++) {
- if (!omap_chip_is(cd->omap_chip))
- continue;
if (!cd->clkdm)
continue; /* only happens if data is erroneous */
diff --git a/arch/arm/mach-omap2/clockdomain44xx.c b/arch/arm/mach-omap2/clockdomain44xx.c
index b43706aa08bd..935c7f03dab9 100644
--- a/arch/arm/mach-omap2/clockdomain44xx.c
+++ b/arch/arm/mach-omap2/clockdomain44xx.c
@@ -52,8 +52,6 @@ static int omap4_clkdm_clear_all_wkup_sleep_deps(struct clockdomain *clkdm)
u32 mask = 0;
for (cd = clkdm->wkdep_srcs; cd && cd->clkdm_name; cd++) {
- if (!omap_chip_is(cd->omap_chip))
- continue;
if (!cd->clkdm)
continue; /* only happens if data is erroneous */
diff --git a/arch/arm/mach-omap2/clockdomains2420_data.c b/arch/arm/mach-omap2/clockdomains2420_data.c
new file mode 100644
index 000000000000..0ab8e46d5b2b
--- /dev/null
+++ b/arch/arm/mach-omap2/clockdomains2420_data.c
@@ -0,0 +1,154 @@
+/*
+ * OMAP2420 clockdomains
+ *
+ * Copyright (C) 2008-2011 Texas Instruments, Inc.
+ * Copyright (C) 2008-2010 Nokia Corporation
+ *
+ * Paul Walmsley, Jouni Högander
+ *
+ * This file contains clockdomains and clockdomain wakeup dependencies
+ * for OMAP2420 chips. Some notes:
+ *
+ * A useful validation rule for struct clockdomain: Any clockdomain
+ * referenced by a wkdep_srcs must have a dep_bit assigned. So
+ * wkdep_srcs are really just software-controllable dependencies.
+ * Non-software-controllable dependencies do exist, but they are not
+ * encoded below (yet).
+ *
+ * 24xx does not support programmable sleep dependencies (SLEEPDEP)
+ *
+ * The overly-specific dep_bit names are due to a bit name collision
+ * with CM_FCLKEN_{DSP,IVA2}. The DSP/IVA2 PM_WKDEP and CM_SLEEPDEP shift
+ * value are the same for all powerdomains: 2
+ *
+ * XXX should dep_bit be a mask, so we can test to see if it is 0 as a
+ * sanity check?
+ * XXX encode hardware fixed wakeup dependencies -- esp. for 3430 CORE
+ */
+
+/*
+ * To-Do List
+ * -> Port the Sleep/Wakeup dependencies for the domains
+ * from the Power domain framework
+ */
+
+#include <linux/kernel.h>
+#include <linux/io.h>
+
+#include "clockdomain.h"
+#include "prm2xxx_3xxx.h"
+#include "cm2xxx_3xxx.h"
+#include "cm-regbits-24xx.h"
+#include "prm-regbits-24xx.h"
+
+/*
+ * Clockdomain dependencies for wkdeps
+ *
+ * XXX Hardware dependencies (e.g., dependencies that cannot be
+ * changed in software) are not included here yet, but should be.
+ */
+
+/* Wakeup dependency source arrays */
+
+/* 2420-specific possible wakeup dependencies */
+
+/* 2420 PM_WKDEP_MPU: CORE, DSP, WKUP */
+static struct clkdm_dep mpu_2420_wkdeps[] = {
+ { .clkdm_name = "core_l3_clkdm" },
+ { .clkdm_name = "core_l4_clkdm" },
+ { .clkdm_name = "dsp_clkdm" },
+ { .clkdm_name = "wkup_clkdm" },
+ { NULL },
+};
+
+/* 2420 PM_WKDEP_CORE: DSP, GFX, MPU, WKUP */
+static struct clkdm_dep core_2420_wkdeps[] = {
+ { .clkdm_name = "dsp_clkdm" },
+ { .clkdm_name = "gfx_clkdm" },
+ { .clkdm_name = "mpu_clkdm" },
+ { .clkdm_name = "wkup_clkdm" },
+ { NULL },
+};
+
+/*
+ * 2420-only clockdomains
+ */
+
+static struct clockdomain mpu_2420_clkdm = {
+ .name = "mpu_clkdm",
+ .pwrdm = { .name = "mpu_pwrdm" },
+ .flags = CLKDM_CAN_HWSUP,
+ .wkdep_srcs = mpu_2420_wkdeps,
+ .clktrctrl_mask = OMAP24XX_AUTOSTATE_MPU_MASK,
+};
+
+static struct clockdomain iva1_2420_clkdm = {
+ .name = "iva1_clkdm",
+ .pwrdm = { .name = "dsp_pwrdm" },
+ .flags = CLKDM_CAN_HWSUP_SWSUP,
+ .dep_bit = OMAP24XX_PM_WKDEP_MPU_EN_DSP_SHIFT,
+ .wkdep_srcs = dsp_24xx_wkdeps,
+ .clktrctrl_mask = OMAP2420_AUTOSTATE_IVA_MASK,
+};
+
+static struct clockdomain dsp_2420_clkdm = {
+ .name = "dsp_clkdm",
+ .pwrdm = { .name = "dsp_pwrdm" },
+ .flags = CLKDM_CAN_HWSUP_SWSUP,
+ .clktrctrl_mask = OMAP24XX_AUTOSTATE_DSP_MASK,
+};
+
+static struct clockdomain gfx_2420_clkdm = {
+ .name = "gfx_clkdm",
+ .pwrdm = { .name = "gfx_pwrdm" },
+ .flags = CLKDM_CAN_HWSUP_SWSUP,
+ .wkdep_srcs = gfx_24xx_wkdeps,
+ .clktrctrl_mask = OMAP24XX_AUTOSTATE_GFX_MASK,
+};
+
+static struct clockdomain core_l3_2420_clkdm = {
+ .name = "core_l3_clkdm",
+ .pwrdm = { .name = "core_pwrdm" },
+ .flags = CLKDM_CAN_HWSUP,
+ .wkdep_srcs = core_2420_wkdeps,
+ .clktrctrl_mask = OMAP24XX_AUTOSTATE_L3_MASK,
+};
+
+static struct clockdomain core_l4_2420_clkdm = {
+ .name = "core_l4_clkdm",
+ .pwrdm = { .name = "core_pwrdm" },
+ .flags = CLKDM_CAN_HWSUP,
+ .wkdep_srcs = core_2420_wkdeps,
+ .clktrctrl_mask = OMAP24XX_AUTOSTATE_L4_MASK,
+};
+
+static struct clockdomain dss_2420_clkdm = {
+ .name = "dss_clkdm",
+ .pwrdm = { .name = "core_pwrdm" },
+ .flags = CLKDM_CAN_HWSUP,
+ .clktrctrl_mask = OMAP24XX_AUTOSTATE_DSS_MASK,
+};
+
+static struct clockdomain *clockdomains_omap242x[] __initdata = {
+ &wkup_common_clkdm,
+ &cm_common_clkdm,
+ &prm_common_clkdm,
+ &mpu_2420_clkdm,
+ &iva1_2420_clkdm,
+ &dsp_2420_clkdm,
+ &gfx_2420_clkdm,
+ &core_l3_2420_clkdm,
+ &core_l4_2420_clkdm,
+ &dss_2420_clkdm,
+ NULL,
+};
+
+void __init omap242x_clockdomains_init(void)
+{
+ if (!cpu_is_omap242x())
+ return;
+
+ clkdm_register_platform_funcs(&omap2_clkdm_operations);
+ clkdm_register_clkdms(clockdomains_omap242x);
+ clkdm_complete_init();
+}
diff --git a/arch/arm/mach-omap2/clockdomains2430_data.c b/arch/arm/mach-omap2/clockdomains2430_data.c
new file mode 100644
index 000000000000..3645ed044890
--- /dev/null
+++ b/arch/arm/mach-omap2/clockdomains2430_data.c
@@ -0,0 +1,181 @@
+/*
+ * OMAP2xxx clockdomains
+ *
+ * Copyright (C) 2008-2009 Texas Instruments, Inc.
+ * Copyright (C) 2008-2010 Nokia Corporation
+ *
+ * Paul Walmsley, Jouni Högander
+ *
+ * This file contains clockdomains and clockdomain wakeup dependencies
+ * for OMAP2xxx chips. Some notes:
+ *
+ * A useful validation rule for struct clockdomain: Any clockdomain
+ * referenced by a wkdep_srcs must have a dep_bit assigned. So
+ * wkdep_srcs are really just software-controllable dependencies.
+ * Non-software-controllable dependencies do exist, but they are not
+ * encoded below (yet).
+ *
+ * 24xx does not support programmable sleep dependencies (SLEEPDEP)
+ *
+ * The overly-specific dep_bit names are due to a bit name collision
+ * with CM_FCLKEN_{DSP,IVA2}. The DSP/IVA2 PM_WKDEP and CM_SLEEPDEP shift
+ * value are the same for all powerdomains: 2
+ *
+ * XXX should dep_bit be a mask, so we can test to see if it is 0 as a
+ * sanity check?
+ * XXX encode hardware fixed wakeup dependencies -- esp. for 3430 CORE
+ */
+
+/*
+ * To-Do List
+ * -> Port the Sleep/Wakeup dependencies for the domains
+ * from the Power domain framework
+ */
+
+#include <linux/kernel.h>
+#include <linux/io.h>
+
+#include "clockdomain.h"
+#include "prm2xxx_3xxx.h"
+#include "cm2xxx_3xxx.h"
+#include "cm-regbits-24xx.h"
+#include "prm-regbits-24xx.h"
+
+/*
+ * Clockdomain dependencies for wkdeps
+ *
+ * XXX Hardware dependencies (e.g., dependencies that cannot be
+ * changed in software) are not included here yet, but should be.
+ */
+
+/* Wakeup dependency source arrays */
+
+/* 2430-specific possible wakeup dependencies */
+
+/* 2430 PM_WKDEP_CORE: DSP, GFX, MPU, WKUP, MDM */
+static struct clkdm_dep core_2430_wkdeps[] = {
+ { .clkdm_name = "dsp_clkdm" },
+ { .clkdm_name = "gfx_clkdm" },
+ { .clkdm_name = "mpu_clkdm" },
+ { .clkdm_name = "wkup_clkdm" },
+ { .clkdm_name = "mdm_clkdm" },
+ { NULL },
+};
+
+/* 2430 PM_WKDEP_MPU: CORE, DSP, WKUP, MDM */
+static struct clkdm_dep mpu_2430_wkdeps[] = {
+ { .clkdm_name = "core_l3_clkdm" },
+ { .clkdm_name = "core_l4_clkdm" },
+ { .clkdm_name = "dsp_clkdm" },
+ { .clkdm_name = "wkup_clkdm" },
+ { .clkdm_name = "mdm_clkdm" },
+ { NULL },
+};
+
+/* 2430 PM_WKDEP_MDM: CORE, MPU, WKUP */
+static struct clkdm_dep mdm_2430_wkdeps[] = {
+ { .clkdm_name = "core_l3_clkdm" },
+ { .clkdm_name = "core_l4_clkdm" },
+ { .clkdm_name = "mpu_clkdm" },
+ { .clkdm_name = "wkup_clkdm" },
+ { NULL },
+};
+
+/*
+ * 2430-only clockdomains
+ */
+
+static struct clockdomain mpu_2430_clkdm = {
+ .name = "mpu_clkdm",
+ .pwrdm = { .name = "mpu_pwrdm" },
+ .flags = CLKDM_CAN_HWSUP_SWSUP,
+ .wkdep_srcs = mpu_2430_wkdeps,
+ .clktrctrl_mask = OMAP24XX_AUTOSTATE_MPU_MASK,
+};
+
+/* Another case of bit name collisions between several registers: EN_MDM */
+static struct clockdomain mdm_clkdm = {
+ .name = "mdm_clkdm",
+ .pwrdm = { .name = "mdm_pwrdm" },
+ .flags = CLKDM_CAN_HWSUP_SWSUP,
+ .dep_bit = OMAP2430_PM_WKDEP_MPU_EN_MDM_SHIFT,
+ .wkdep_srcs = mdm_2430_wkdeps,
+ .clktrctrl_mask = OMAP2430_AUTOSTATE_MDM_MASK,
+};
+
+static struct clockdomain dsp_2430_clkdm = {
+ .name = "dsp_clkdm",
+ .pwrdm = { .name = "dsp_pwrdm" },
+ .flags = CLKDM_CAN_HWSUP_SWSUP,
+ .dep_bit = OMAP24XX_PM_WKDEP_MPU_EN_DSP_SHIFT,
+ .wkdep_srcs = dsp_24xx_wkdeps,
+ .clktrctrl_mask = OMAP24XX_AUTOSTATE_DSP_MASK,
+};
+
+static struct clockdomain gfx_2430_clkdm = {
+ .name = "gfx_clkdm",
+ .pwrdm = { .name = "gfx_pwrdm" },
+ .flags = CLKDM_CAN_HWSUP_SWSUP,
+ .wkdep_srcs = gfx_24xx_wkdeps,
+ .clktrctrl_mask = OMAP24XX_AUTOSTATE_GFX_MASK,
+};
+
+/*
+ * XXX add usecounting for clkdm dependencies, otherwise the presence
+ * of a single dep bit for core_l3_24xx_clkdm and core_l4_24xx_clkdm
+ * could cause trouble
+ */
+static struct clockdomain core_l3_2430_clkdm = {
+ .name = "core_l3_clkdm",
+ .pwrdm = { .name = "core_pwrdm" },
+ .flags = CLKDM_CAN_HWSUP,
+ .dep_bit = OMAP24XX_EN_CORE_SHIFT,
+ .wkdep_srcs = core_2430_wkdeps,
+ .clktrctrl_mask = OMAP24XX_AUTOSTATE_L3_MASK,
+};
+
+/*
+ * XXX add usecounting for clkdm dependencies, otherwise the presence
+ * of a single dep bit for core_l3_24xx_clkdm and core_l4_24xx_clkdm
+ * could cause trouble
+ */
+static struct clockdomain core_l4_2430_clkdm = {
+ .name = "core_l4_clkdm",
+ .pwrdm = { .name = "core_pwrdm" },
+ .flags = CLKDM_CAN_HWSUP,
+ .dep_bit = OMAP24XX_EN_CORE_SHIFT,
+ .wkdep_srcs = core_2430_wkdeps,
+ .clktrctrl_mask = OMAP24XX_AUTOSTATE_L4_MASK,
+};
+
+static struct clockdomain dss_2430_clkdm = {
+ .name = "dss_clkdm",
+ .pwrdm = { .name = "core_pwrdm" },
+ .flags = CLKDM_CAN_HWSUP,
+ .clktrctrl_mask = OMAP24XX_AUTOSTATE_DSS_MASK,
+};
+
+static struct clockdomain *clockdomains_omap243x[] __initdata = {
+ &wkup_common_clkdm,
+ &cm_common_clkdm,
+ &prm_common_clkdm,
+ &mpu_2430_clkdm,
+ &mdm_clkdm,
+ &dsp_2430_clkdm,
+ &gfx_2430_clkdm,
+ &core_l3_2430_clkdm,
+ &core_l4_2430_clkdm,
+ &dss_2430_clkdm,
+ NULL,
+};
+
+void __init omap243x_clockdomains_init(void)
+{
+ if (!cpu_is_omap243x())
+ return;
+
+ clkdm_register_platform_funcs(&omap2_clkdm_operations);
+ clkdm_register_clkdms(clockdomains_omap243x);
+ clkdm_complete_init();
+}
+
diff --git a/arch/arm/mach-omap2/clockdomains2xxx_3xxx_data.c b/arch/arm/mach-omap2/clockdomains2xxx_3xxx_data.c
index 13bde95b6790..0a6a04897d89 100644
--- a/arch/arm/mach-omap2/clockdomains2xxx_3xxx_data.c
+++ b/arch/arm/mach-omap2/clockdomains2xxx_3xxx_data.c
@@ -1,7 +1,7 @@
/*
- * OMAP2/3 clockdomains
+ * OMAP2/3 clockdomain common data
*
- * Copyright (C) 2008-2009 Texas Instruments, Inc.
+ * Copyright (C) 2008-2011 Texas Instruments, Inc.
* Copyright (C) 2008-2010 Nokia Corporation
*
* Paul Walmsley, Jouni Högander
@@ -51,374 +51,28 @@
* changed in software) are not included here yet, but should be.
*/
-/* OMAP2/3-common wakeup dependencies */
-
-/*
- * 2420/2430 PM_WKDEP_GFX: CORE, MPU, WKUP
- * 3430ES1 PM_WKDEP_GFX: adds IVA2, removes CORE
- * 3430ES2 PM_WKDEP_SGX: adds IVA2, removes CORE
- * These can share data since they will never be present simultaneously
- * on the same device.
- */
-static struct clkdm_dep gfx_sgx_wkdeps[] = {
- {
- .clkdm_name = "core_l3_clkdm",
- .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP24XX)
- },
- {
- .clkdm_name = "core_l4_clkdm",
- .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP24XX)
- },
- {
- .clkdm_name = "iva2_clkdm",
- .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP3430)
- },
- {
- .clkdm_name = "mpu_clkdm",
- .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP24XX |
- CHIP_IS_OMAP3430)
- },
- {
- .clkdm_name = "wkup_clkdm",
- .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP24XX |
- CHIP_IS_OMAP3430)
- },
- { NULL },
-};
-
-
-/* 24XX-specific possible dependencies */
-
-#ifdef CONFIG_ARCH_OMAP2
-
/* Wakeup dependency source arrays */
-/* 2420/2430 PM_WKDEP_DSP: CORE, MPU, WKUP */
-static struct clkdm_dep dsp_24xx_wkdeps[] = {
- {
- .clkdm_name = "core_l3_clkdm",
- .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP24XX)
- },
- {
- .clkdm_name = "core_l4_clkdm",
- .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP24XX)
- },
- {
- .clkdm_name = "mpu_clkdm",
- .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP24XX)
- },
- {
- .clkdm_name = "wkup_clkdm",
- .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP24XX)
- },
- { NULL },
-};
-
-/*
- * 2420 PM_WKDEP_MPU: CORE, DSP, WKUP
- * 2430 adds MDM
- */
-static struct clkdm_dep mpu_24xx_wkdeps[] = {
- {
- .clkdm_name = "core_l3_clkdm",
- .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP24XX)
- },
- {
- .clkdm_name = "core_l4_clkdm",
- .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP24XX)
- },
- {
- .clkdm_name = "dsp_clkdm",
- .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP24XX)
- },
- {
- .clkdm_name = "wkup_clkdm",
- .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP24XX)
- },
- {
- .clkdm_name = "mdm_clkdm",
- .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP2430)
- },
- { NULL },
-};
-
-/*
- * 2420 PM_WKDEP_CORE: DSP, GFX, MPU, WKUP
- * 2430 adds MDM
- */
-static struct clkdm_dep core_24xx_wkdeps[] = {
- {
- .clkdm_name = "dsp_clkdm",
- .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP24XX)
- },
- {
- .clkdm_name = "gfx_clkdm",
- .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP24XX)
- },
- {
- .clkdm_name = "mpu_clkdm",
- .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP24XX)
- },
- {
- .clkdm_name = "wkup_clkdm",
- .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP24XX)
- },
- {
- .clkdm_name = "mdm_clkdm",
- .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP2430)
- },
- { NULL },
-};
-
-#endif /* CONFIG_ARCH_OMAP2 */
-
-/* 2430-specific possible wakeup dependencies */
+/* 2xxx-specific possible dependencies */
-#ifdef CONFIG_SOC_OMAP2430
-
-/* 2430 PM_WKDEP_MDM: CORE, MPU, WKUP */
-static struct clkdm_dep mdm_2430_wkdeps[] = {
- {
- .clkdm_name = "core_l3_clkdm",
- .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP24XX)
- },
- {
- .clkdm_name = "core_l4_clkdm",
- .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP24XX)
- },
- {
- .clkdm_name = "mpu_clkdm",
- .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP24XX)
- },
- {
- .clkdm_name = "wkup_clkdm",
- .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP24XX)
- },
- { NULL },
-};
-
-#endif /* CONFIG_SOC_OMAP2430 */
-
-
-/* OMAP3-specific possible dependencies */
-
-#ifdef CONFIG_ARCH_OMAP3
-
-/* 3430: PM_WKDEP_PER: CORE, IVA2, MPU, WKUP */
-static struct clkdm_dep per_wkdeps[] = {
- {
- .clkdm_name = "core_l3_clkdm",
- .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP3430)
- },
- {
- .clkdm_name = "core_l4_clkdm",
- .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP3430)
- },
- {
- .clkdm_name = "iva2_clkdm",
- .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP3430)
- },
- {
- .clkdm_name = "mpu_clkdm",
- .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP3430)
- },
- {
- .clkdm_name = "wkup_clkdm",
- .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP3430)
- },
- { NULL },
-};
-
-/* 3430ES2: PM_WKDEP_USBHOST: CORE, IVA2, MPU, WKUP */
-static struct clkdm_dep usbhost_wkdeps[] = {
- {
- .clkdm_name = "core_l3_clkdm",
- .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP3430)
- },
- {
- .clkdm_name = "core_l4_clkdm",
- .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP3430)
- },
- {
- .clkdm_name = "iva2_clkdm",
- .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP3430)
- },
- {
- .clkdm_name = "mpu_clkdm",
- .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP3430)
- },
- {
- .clkdm_name = "wkup_clkdm",
- .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP3430)
- },
+/* 2xxx PM_WKDEP_GFX: CORE, MPU, WKUP */
+struct clkdm_dep gfx_24xx_wkdeps[] = {
+ { .clkdm_name = "core_l3_clkdm" },
+ { .clkdm_name = "core_l4_clkdm" },
+ { .clkdm_name = "mpu_clkdm" },
+ { .clkdm_name = "wkup_clkdm" },
{ NULL },
};
-/* 3430 PM_WKDEP_MPU: CORE, IVA2, DSS, PER */
-static struct clkdm_dep mpu_3xxx_wkdeps[] = {
- {
- .clkdm_name = "core_l3_clkdm",
- .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP3430)
- },
- {
- .clkdm_name = "core_l4_clkdm",
- .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP3430)
- },
- {
- .clkdm_name = "iva2_clkdm",
- .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP3430)
- },
- {
- .clkdm_name = "dss_clkdm",
- .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP3430)
- },
- {
- .clkdm_name = "per_clkdm",
- .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP3430)
- },
+/* 2xxx PM_WKDEP_DSP: CORE, MPU, WKUP */
+struct clkdm_dep dsp_24xx_wkdeps[] = {
+ { .clkdm_name = "core_l3_clkdm" },
+ { .clkdm_name = "core_l4_clkdm" },
+ { .clkdm_name = "mpu_clkdm" },
+ { .clkdm_name = "wkup_clkdm" },
{ NULL },
};
-/* 3430 PM_WKDEP_IVA2: CORE, MPU, WKUP, DSS, PER */
-static struct clkdm_dep iva2_wkdeps[] = {
- {
- .clkdm_name = "core_l3_clkdm",
- .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP3430)
- },
- {
- .clkdm_name = "core_l4_clkdm",
- .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP3430)
- },
- {
- .clkdm_name = "mpu_clkdm",
- .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP3430)
- },
- {
- .clkdm_name = "wkup_clkdm",
- .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP3430)
- },
- {
- .clkdm_name = "dss_clkdm",
- .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP3430)
- },
- {
- .clkdm_name = "per_clkdm",
- .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP3430)
- },
- { NULL },
-};
-
-
-/* 3430 PM_WKDEP_CAM: IVA2, MPU, WKUP */
-static struct clkdm_dep cam_wkdeps[] = {
- {
- .clkdm_name = "iva2_clkdm",
- .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP3430)
- },
- {
- .clkdm_name = "mpu_clkdm",
- .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP3430)
- },
- {
- .clkdm_name = "wkup_clkdm",
- .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP3430)
- },
- { NULL },
-};
-
-/* 3430 PM_WKDEP_DSS: IVA2, MPU, WKUP */
-static struct clkdm_dep dss_wkdeps[] = {
- {
- .clkdm_name = "iva2_clkdm",
- .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP3430)
- },
- {
- .clkdm_name = "mpu_clkdm",
- .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP3430)
- },
- {
- .clkdm_name = "wkup_clkdm",
- .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP3430)
- },
- { NULL },
-};
-
-/* 3430: PM_WKDEP_NEON: MPU */
-static struct clkdm_dep neon_wkdeps[] = {
- {
- .clkdm_name = "mpu_clkdm",
- .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP3430)
- },
- { NULL },
-};
-
-
-/* Sleep dependency source arrays for OMAP3-specific clkdms */
-
-/* 3430: CM_SLEEPDEP_DSS: MPU, IVA */
-static struct clkdm_dep dss_sleepdeps[] = {
- {
- .clkdm_name = "mpu_clkdm",
- .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP3430)
- },
- {
- .clkdm_name = "iva2_clkdm",
- .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP3430)
- },
- { NULL },
-};
-
-/* 3430: CM_SLEEPDEP_PER: MPU, IVA */
-static struct clkdm_dep per_sleepdeps[] = {
- {
- .clkdm_name = "mpu_clkdm",
- .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP3430)
- },
- {
- .clkdm_name = "iva2_clkdm",
- .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP3430)
- },
- { NULL },
-};
-
-/* 3430ES2: CM_SLEEPDEP_USBHOST: MPU, IVA */
-static struct clkdm_dep usbhost_sleepdeps[] = {
- {
- .clkdm_name = "mpu_clkdm",
- .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP3430)
- },
- {
- .clkdm_name = "iva2_clkdm",
- .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP3430)
- },
- { NULL },
-};
-
-/* 3430: CM_SLEEPDEP_CAM: MPU */
-static struct clkdm_dep cam_sleepdeps[] = {
- {
- .clkdm_name = "mpu_clkdm",
- .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP3430)
- },
- { NULL },
-};
-
-/*
- * 3430ES1: CM_SLEEPDEP_GFX: MPU
- * 3430ES2: CM_SLEEPDEP_SGX: MPU
- * These can share data since they will never be present simultaneously
- * on the same device.
- */
-static struct clkdm_dep gfx_sgx_sleepdeps[] = {
- {
- .clkdm_name = "mpu_clkdm",
- .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP3430)
- },
- { NULL },
-};
-
-#endif /* CONFIG_ARCH_OMAP3 */
-
/*
* OMAP2/3-common clockdomains
@@ -430,439 +84,18 @@ static struct clkdm_dep gfx_sgx_sleepdeps[] = {
*/
/* This is an implicit clockdomain - it is never defined as such in TRM */
-static struct clockdomain wkup_clkdm = {
+struct clockdomain wkup_common_clkdm = {
.name = "wkup_clkdm",
.pwrdm = { .name = "wkup_pwrdm" },
.dep_bit = OMAP_EN_WKUP_SHIFT,
- .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP24XX | CHIP_IS_OMAP3430),
};
-static struct clockdomain prm_clkdm = {
+struct clockdomain prm_common_clkdm = {
.name = "prm_clkdm",
.pwrdm = { .name = "wkup_pwrdm" },
- .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP24XX | CHIP_IS_OMAP3430),
};
-static struct clockdomain cm_clkdm = {
+struct clockdomain cm_common_clkdm = {
.name = "cm_clkdm",
.pwrdm = { .name = "core_pwrdm" },
- .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP24XX | CHIP_IS_OMAP3430),
};
-
-/*
- * 2420-only clockdomains
- */
-
-#if defined(CONFIG_SOC_OMAP2420)
-
-static struct clockdomain mpu_2420_clkdm = {
- .name = "mpu_clkdm",
- .pwrdm = { .name = "mpu_pwrdm" },
- .flags = CLKDM_CAN_HWSUP,
- .wkdep_srcs = mpu_24xx_wkdeps,
- .clktrctrl_mask = OMAP24XX_AUTOSTATE_MPU_MASK,
- .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP2420),
-};
-
-static struct clockdomain iva1_2420_clkdm = {
- .name = "iva1_clkdm",
- .pwrdm = { .name = "dsp_pwrdm" },
- .flags = CLKDM_CAN_HWSUP_SWSUP,
- .dep_bit = OMAP24XX_PM_WKDEP_MPU_EN_DSP_SHIFT,
- .wkdep_srcs = dsp_24xx_wkdeps,
- .clktrctrl_mask = OMAP2420_AUTOSTATE_IVA_MASK,
- .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP2420),
-};
-
-static struct clockdomain dsp_2420_clkdm = {
- .name = "dsp_clkdm",
- .pwrdm = { .name = "dsp_pwrdm" },
- .flags = CLKDM_CAN_HWSUP_SWSUP,
- .clktrctrl_mask = OMAP24XX_AUTOSTATE_DSP_MASK,
- .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP2420),
-};
-
-static struct clockdomain gfx_2420_clkdm = {
- .name = "gfx_clkdm",
- .pwrdm = { .name = "gfx_pwrdm" },
- .flags = CLKDM_CAN_HWSUP_SWSUP,
- .wkdep_srcs = gfx_sgx_wkdeps,
- .clktrctrl_mask = OMAP24XX_AUTOSTATE_GFX_MASK,
- .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP2420),
-};
-
-static struct clockdomain core_l3_2420_clkdm = {
- .name = "core_l3_clkdm",
- .pwrdm = { .name = "core_pwrdm" },
- .flags = CLKDM_CAN_HWSUP,
- .wkdep_srcs = core_24xx_wkdeps,
- .clktrctrl_mask = OMAP24XX_AUTOSTATE_L3_MASK,
- .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP2420),
-};
-
-static struct clockdomain core_l4_2420_clkdm = {
- .name = "core_l4_clkdm",
- .pwrdm = { .name = "core_pwrdm" },
- .flags = CLKDM_CAN_HWSUP,
- .wkdep_srcs = core_24xx_wkdeps,
- .clktrctrl_mask = OMAP24XX_AUTOSTATE_L4_MASK,
- .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP2420),
-};
-
-static struct clockdomain dss_2420_clkdm = {
- .name = "dss_clkdm",
- .pwrdm = { .name = "core_pwrdm" },
- .flags = CLKDM_CAN_HWSUP,
- .clktrctrl_mask = OMAP24XX_AUTOSTATE_DSS_MASK,
- .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP2420),
-};
-
-#endif /* CONFIG_SOC_OMAP2420 */
-
-
-/*
- * 2430-only clockdomains
- */
-
-#if defined(CONFIG_SOC_OMAP2430)
-
-static struct clockdomain mpu_2430_clkdm = {
- .name = "mpu_clkdm",
- .pwrdm = { .name = "mpu_pwrdm" },
- .flags = CLKDM_CAN_HWSUP_SWSUP,
- .wkdep_srcs = mpu_24xx_wkdeps,
- .clktrctrl_mask = OMAP24XX_AUTOSTATE_MPU_MASK,
- .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP2430),
-};
-
-/* Another case of bit name collisions between several registers: EN_MDM */
-static struct clockdomain mdm_clkdm = {
- .name = "mdm_clkdm",
- .pwrdm = { .name = "mdm_pwrdm" },
- .flags = CLKDM_CAN_HWSUP_SWSUP,
- .dep_bit = OMAP2430_PM_WKDEP_MPU_EN_MDM_SHIFT,
- .wkdep_srcs = mdm_2430_wkdeps,
- .clktrctrl_mask = OMAP2430_AUTOSTATE_MDM_MASK,
- .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP2430),
-};
-
-static struct clockdomain dsp_2430_clkdm = {
- .name = "dsp_clkdm",
- .pwrdm = { .name = "dsp_pwrdm" },
- .flags = CLKDM_CAN_HWSUP_SWSUP,
- .dep_bit = OMAP24XX_PM_WKDEP_MPU_EN_DSP_SHIFT,
- .wkdep_srcs = dsp_24xx_wkdeps,
- .clktrctrl_mask = OMAP24XX_AUTOSTATE_DSP_MASK,
- .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP2430),
-};
-
-static struct clockdomain gfx_2430_clkdm = {
- .name = "gfx_clkdm",
- .pwrdm = { .name = "gfx_pwrdm" },
- .flags = CLKDM_CAN_HWSUP_SWSUP,
- .wkdep_srcs = gfx_sgx_wkdeps,
- .clktrctrl_mask = OMAP24XX_AUTOSTATE_GFX_MASK,
- .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP2430),
-};
-
-/*
- * XXX add usecounting for clkdm dependencies, otherwise the presence
- * of a single dep bit for core_l3_24xx_clkdm and core_l4_24xx_clkdm
- * could cause trouble
- */
-static struct clockdomain core_l3_2430_clkdm = {
- .name = "core_l3_clkdm",
- .pwrdm = { .name = "core_pwrdm" },
- .flags = CLKDM_CAN_HWSUP,
- .dep_bit = OMAP24XX_EN_CORE_SHIFT,
- .wkdep_srcs = core_24xx_wkdeps,
- .clktrctrl_mask = OMAP24XX_AUTOSTATE_L3_MASK,
- .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP2430),
-};
-
-/*
- * XXX add usecounting for clkdm dependencies, otherwise the presence
- * of a single dep bit for core_l3_24xx_clkdm and core_l4_24xx_clkdm
- * could cause trouble
- */
-static struct clockdomain core_l4_2430_clkdm = {
- .name = "core_l4_clkdm",
- .pwrdm = { .name = "core_pwrdm" },
- .flags = CLKDM_CAN_HWSUP,
- .dep_bit = OMAP24XX_EN_CORE_SHIFT,
- .wkdep_srcs = core_24xx_wkdeps,
- .clktrctrl_mask = OMAP24XX_AUTOSTATE_L4_MASK,
- .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP2430),
-};
-
-static struct clockdomain dss_2430_clkdm = {
- .name = "dss_clkdm",
- .pwrdm = { .name = "core_pwrdm" },
- .flags = CLKDM_CAN_HWSUP,
- .clktrctrl_mask = OMAP24XX_AUTOSTATE_DSS_MASK,
- .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP2430),
-};
-
-#endif /* CONFIG_SOC_OMAP2430 */
-
-
-/*
- * OMAP3 clockdomains
- */
-
-#if defined(CONFIG_ARCH_OMAP3)
-
-static struct clockdomain mpu_3xxx_clkdm = {
- .name = "mpu_clkdm",
- .pwrdm = { .name = "mpu_pwrdm" },
- .flags = CLKDM_CAN_HWSUP | CLKDM_CAN_FORCE_WAKEUP,
- .dep_bit = OMAP3430_EN_MPU_SHIFT,
- .wkdep_srcs = mpu_3xxx_wkdeps,
- .clktrctrl_mask = OMAP3430_CLKTRCTRL_MPU_MASK,
- .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP3430),
-};
-
-static struct clockdomain neon_clkdm = {
- .name = "neon_clkdm",
- .pwrdm = { .name = "neon_pwrdm" },
- .flags = CLKDM_CAN_HWSUP_SWSUP,
- .wkdep_srcs = neon_wkdeps,
- .clktrctrl_mask = OMAP3430_CLKTRCTRL_NEON_MASK,
- .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP3430),
-};
-
-static struct clockdomain iva2_clkdm = {
- .name = "iva2_clkdm",
- .pwrdm = { .name = "iva2_pwrdm" },
- .flags = CLKDM_CAN_HWSUP_SWSUP,
- .dep_bit = OMAP3430_PM_WKDEP_MPU_EN_IVA2_SHIFT,
- .wkdep_srcs = iva2_wkdeps,
- .clktrctrl_mask = OMAP3430_CLKTRCTRL_IVA2_MASK,
- .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP3430),
-};
-
-static struct clockdomain gfx_3430es1_clkdm = {
- .name = "gfx_clkdm",
- .pwrdm = { .name = "gfx_pwrdm" },
- .flags = CLKDM_CAN_HWSUP_SWSUP,
- .wkdep_srcs = gfx_sgx_wkdeps,
- .sleepdep_srcs = gfx_sgx_sleepdeps,
- .clktrctrl_mask = OMAP3430ES1_CLKTRCTRL_GFX_MASK,
- .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP3430ES1),
-};
-
-static struct clockdomain sgx_clkdm = {
- .name = "sgx_clkdm",
- .pwrdm = { .name = "sgx_pwrdm" },
- .flags = CLKDM_CAN_HWSUP_SWSUP,
- .wkdep_srcs = gfx_sgx_wkdeps,
- .sleepdep_srcs = gfx_sgx_sleepdeps,
- .clktrctrl_mask = OMAP3430ES2_CLKTRCTRL_SGX_MASK,
- .omap_chip = OMAP_CHIP_INIT(CHIP_GE_OMAP3430ES2),
-};
-
-/*
- * The die-to-die clockdomain was documented in the 34xx ES1 TRM, but
- * then that information was removed from the 34xx ES2+ TRM. It is
- * unclear whether the core is still there, but the clockdomain logic
- * is there, and must be programmed to an appropriate state if the
- * CORE clockdomain is to become inactive.
- */
-static struct clockdomain d2d_clkdm = {
- .name = "d2d_clkdm",
- .pwrdm = { .name = "core_pwrdm" },
- .flags = CLKDM_CAN_HWSUP_SWSUP,
- .clktrctrl_mask = OMAP3430ES1_CLKTRCTRL_D2D_MASK,
- .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP3430),
-};
-
-/*
- * XXX add usecounting for clkdm dependencies, otherwise the presence
- * of a single dep bit for core_l3_3xxx_clkdm and core_l4_3xxx_clkdm
- * could cause trouble
- */
-static struct clockdomain core_l3_3xxx_clkdm = {
- .name = "core_l3_clkdm",
- .pwrdm = { .name = "core_pwrdm" },
- .flags = CLKDM_CAN_HWSUP,
- .dep_bit = OMAP3430_EN_CORE_SHIFT,
- .clktrctrl_mask = OMAP3430_CLKTRCTRL_L3_MASK,
- .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP3430),
-};
-
-/*
- * XXX add usecounting for clkdm dependencies, otherwise the presence
- * of a single dep bit for core_l3_3xxx_clkdm and core_l4_3xxx_clkdm
- * could cause trouble
- */
-static struct clockdomain core_l4_3xxx_clkdm = {
- .name = "core_l4_clkdm",
- .pwrdm = { .name = "core_pwrdm" },
- .flags = CLKDM_CAN_HWSUP,
- .dep_bit = OMAP3430_EN_CORE_SHIFT,
- .clktrctrl_mask = OMAP3430_CLKTRCTRL_L4_MASK,
- .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP3430),
-};
-
-/* Another case of bit name collisions between several registers: EN_DSS */
-static struct clockdomain dss_3xxx_clkdm = {
- .name = "dss_clkdm",
- .pwrdm = { .name = "dss_pwrdm" },
- .flags = CLKDM_CAN_HWSUP_SWSUP,
- .dep_bit = OMAP3430_PM_WKDEP_MPU_EN_DSS_SHIFT,
- .wkdep_srcs = dss_wkdeps,
- .sleepdep_srcs = dss_sleepdeps,
- .clktrctrl_mask = OMAP3430_CLKTRCTRL_DSS_MASK,
- .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP3430),
-};
-
-static struct clockdomain cam_clkdm = {
- .name = "cam_clkdm",
- .pwrdm = { .name = "cam_pwrdm" },
- .flags = CLKDM_CAN_HWSUP_SWSUP,
- .wkdep_srcs = cam_wkdeps,
- .sleepdep_srcs = cam_sleepdeps,
- .clktrctrl_mask = OMAP3430_CLKTRCTRL_CAM_MASK,
- .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP3430),
-};
-
-static struct clockdomain usbhost_clkdm = {
- .name = "usbhost_clkdm",
- .pwrdm = { .name = "usbhost_pwrdm" },
- .flags = CLKDM_CAN_HWSUP_SWSUP,
- .wkdep_srcs = usbhost_wkdeps,
- .sleepdep_srcs = usbhost_sleepdeps,
- .clktrctrl_mask = OMAP3430ES2_CLKTRCTRL_USBHOST_MASK,
- .omap_chip = OMAP_CHIP_INIT(CHIP_GE_OMAP3430ES2),
-};
-
-static struct clockdomain per_clkdm = {
- .name = "per_clkdm",
- .pwrdm = { .name = "per_pwrdm" },
- .flags = CLKDM_CAN_HWSUP_SWSUP,
- .dep_bit = OMAP3430_EN_PER_SHIFT,
- .wkdep_srcs = per_wkdeps,
- .sleepdep_srcs = per_sleepdeps,
- .clktrctrl_mask = OMAP3430_CLKTRCTRL_PER_MASK,
- .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP3430),
-};
-
-/*
- * Disable hw supervised mode for emu_clkdm, because emu_pwrdm is
- * switched of even if sdti is in use
- */
-static struct clockdomain emu_clkdm = {
- .name = "emu_clkdm",
- .pwrdm = { .name = "emu_pwrdm" },
- .flags = /* CLKDM_CAN_ENABLE_AUTO | */CLKDM_CAN_SWSUP,
- .clktrctrl_mask = OMAP3430_CLKTRCTRL_EMU_MASK,
- .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP3430),
-};
-
-static struct clockdomain dpll1_clkdm = {
- .name = "dpll1_clkdm",
- .pwrdm = { .name = "dpll1_pwrdm" },
- .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP3430),
-};
-
-static struct clockdomain dpll2_clkdm = {
- .name = "dpll2_clkdm",
- .pwrdm = { .name = "dpll2_pwrdm" },
- .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP3430),
-};
-
-static struct clockdomain dpll3_clkdm = {
- .name = "dpll3_clkdm",
- .pwrdm = { .name = "dpll3_pwrdm" },
- .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP3430),
-};
-
-static struct clockdomain dpll4_clkdm = {
- .name = "dpll4_clkdm",
- .pwrdm = { .name = "dpll4_pwrdm" },
- .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP3430),
-};
-
-static struct clockdomain dpll5_clkdm = {
- .name = "dpll5_clkdm",
- .pwrdm = { .name = "dpll5_pwrdm" },
- .omap_chip = OMAP_CHIP_INIT(CHIP_GE_OMAP3430ES2),
-};
-
-#endif /* CONFIG_ARCH_OMAP3 */
-
-/*
- * Clockdomain hwsup dependencies (OMAP3 only)
- */
-
-static struct clkdm_autodep clkdm_autodeps[] = {
- {
- .clkdm = { .name = "mpu_clkdm" },
- .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP3430)
- },
- {
- .clkdm = { .name = "iva2_clkdm" },
- .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP3430)
- },
- {
- .clkdm = { .name = NULL },
- }
-};
-
-static struct clockdomain *clockdomains_omap2[] __initdata = {
- &wkup_clkdm,
- &cm_clkdm,
- &prm_clkdm,
-
-#ifdef CONFIG_SOC_OMAP2420
- &mpu_2420_clkdm,
- &iva1_2420_clkdm,
- &dsp_2420_clkdm,
- &gfx_2420_clkdm,
- &core_l3_2420_clkdm,
- &core_l4_2420_clkdm,
- &dss_2420_clkdm,
-#endif
-
-#ifdef CONFIG_SOC_OMAP2430
- &mpu_2430_clkdm,
- &mdm_clkdm,
- &dsp_2430_clkdm,
- &gfx_2430_clkdm,
- &core_l3_2430_clkdm,
- &core_l4_2430_clkdm,
- &dss_2430_clkdm,
-#endif
-
-#ifdef CONFIG_ARCH_OMAP3
- &mpu_3xxx_clkdm,
- &neon_clkdm,
- &iva2_clkdm,
- &gfx_3430es1_clkdm,
- &sgx_clkdm,
- &d2d_clkdm,
- &core_l3_3xxx_clkdm,
- &core_l4_3xxx_clkdm,
- &dss_3xxx_clkdm,
- &cam_clkdm,
- &usbhost_clkdm,
- &per_clkdm,
- &emu_clkdm,
- &dpll1_clkdm,
- &dpll2_clkdm,
- &dpll3_clkdm,
- &dpll4_clkdm,
- &dpll5_clkdm,
-#endif
- NULL,
-};
-
-void __init omap2xxx_clockdomains_init(void)
-{
- clkdm_init(clockdomains_omap2, clkdm_autodeps, &omap2_clkdm_operations);
-}
-
-void __init omap3xxx_clockdomains_init(void)
-{
- clkdm_init(clockdomains_omap2, clkdm_autodeps, &omap3_clkdm_operations);
-}
diff --git a/arch/arm/mach-omap2/clockdomains3xxx_data.c b/arch/arm/mach-omap2/clockdomains3xxx_data.c
new file mode 100644
index 000000000000..b84e138d99c8
--- /dev/null
+++ b/arch/arm/mach-omap2/clockdomains3xxx_data.c
@@ -0,0 +1,398 @@
+/*
+ * OMAP3xxx clockdomains
+ *
+ * Copyright (C) 2008-2011 Texas Instruments, Inc.
+ * Copyright (C) 2008-2010 Nokia Corporation
+ *
+ * Paul Walmsley, Jouni Högander
+ *
+ * This file contains clockdomains and clockdomain wakeup/sleep
+ * dependencies for the OMAP3xxx chips. Some notes:
+ *
+ * A useful validation rule for struct clockdomain: Any clockdomain
+ * referenced by a wkdep_srcs or sleepdep_srcs array must have a
+ * dep_bit assigned. So wkdep_srcs/sleepdep_srcs are really just
+ * software-controllable dependencies. Non-software-controllable
+ * dependencies do exist, but they are not encoded below (yet).
+ *
+ * The overly-specific dep_bit names are due to a bit name collision
+ * with CM_FCLKEN_{DSP,IVA2}. The DSP/IVA2 PM_WKDEP and CM_SLEEPDEP shift
+ * value are the same for all powerdomains: 2
+ *
+ * XXX should dep_bit be a mask, so we can test to see if it is 0 as a
+ * sanity check?
+ * XXX encode hardware fixed wakeup dependencies -- esp. for 3430 CORE
+ */
+
+/*
+ * To-Do List
+ * -> Port the Sleep/Wakeup dependencies for the domains
+ * from the Power domain framework
+ */
+
+#include <linux/kernel.h>
+#include <linux/io.h>
+
+#include "clockdomain.h"
+#include "prm2xxx_3xxx.h"
+#include "cm2xxx_3xxx.h"
+#include "cm-regbits-34xx.h"
+#include "prm-regbits-34xx.h"
+
+/*
+ * Clockdomain dependencies for wkdeps/sleepdeps
+ *
+ * XXX Hardware dependencies (e.g., dependencies that cannot be
+ * changed in software) are not included here yet, but should be.
+ */
+
+/* OMAP3-specific possible dependencies */
+
+/*
+ * 3430ES1 PM_WKDEP_GFX: adds IVA2, removes CORE
+ * 3430ES2 PM_WKDEP_SGX: adds IVA2, removes CORE
+ */
+static struct clkdm_dep gfx_sgx_3xxx_wkdeps[] = {
+ { .clkdm_name = "iva2_clkdm", },
+ { .clkdm_name = "mpu_clkdm", },
+ { .clkdm_name = "wkup_clkdm", },
+ { NULL },
+};
+
+/* 3430: PM_WKDEP_PER: CORE, IVA2, MPU, WKUP */
+static struct clkdm_dep per_wkdeps[] = {
+ { .clkdm_name = "core_l3_clkdm" },
+ { .clkdm_name = "core_l4_clkdm" },
+ { .clkdm_name = "iva2_clkdm" },
+ { .clkdm_name = "mpu_clkdm" },
+ { .clkdm_name = "wkup_clkdm" },
+ { NULL },
+};
+
+/* 3430ES2: PM_WKDEP_USBHOST: CORE, IVA2, MPU, WKUP */
+static struct clkdm_dep usbhost_wkdeps[] = {
+ { .clkdm_name = "core_l3_clkdm" },
+ { .clkdm_name = "core_l4_clkdm" },
+ { .clkdm_name = "iva2_clkdm" },
+ { .clkdm_name = "mpu_clkdm" },
+ { .clkdm_name = "wkup_clkdm" },
+ { NULL },
+};
+
+/* 3430 PM_WKDEP_MPU: CORE, IVA2, DSS, PER */
+static struct clkdm_dep mpu_3xxx_wkdeps[] = {
+ { .clkdm_name = "core_l3_clkdm" },
+ { .clkdm_name = "core_l4_clkdm" },
+ { .clkdm_name = "iva2_clkdm" },
+ { .clkdm_name = "dss_clkdm" },
+ { .clkdm_name = "per_clkdm" },
+ { NULL },
+};
+
+/* 3430 PM_WKDEP_IVA2: CORE, MPU, WKUP, DSS, PER */
+static struct clkdm_dep iva2_wkdeps[] = {
+ { .clkdm_name = "core_l3_clkdm" },
+ { .clkdm_name = "core_l4_clkdm" },
+ { .clkdm_name = "mpu_clkdm" },
+ { .clkdm_name = "wkup_clkdm" },
+ { .clkdm_name = "dss_clkdm" },
+ { .clkdm_name = "per_clkdm" },
+ { NULL },
+};
+
+/* 3430 PM_WKDEP_CAM: IVA2, MPU, WKUP */
+static struct clkdm_dep cam_wkdeps[] = {
+ { .clkdm_name = "iva2_clkdm" },
+ { .clkdm_name = "mpu_clkdm" },
+ { .clkdm_name = "wkup_clkdm" },
+ { NULL },
+};
+
+/* 3430 PM_WKDEP_DSS: IVA2, MPU, WKUP */
+static struct clkdm_dep dss_wkdeps[] = {
+ { .clkdm_name = "iva2_clkdm" },
+ { .clkdm_name = "mpu_clkdm" },
+ { .clkdm_name = "wkup_clkdm" },
+ { NULL },
+};
+
+/* 3430: PM_WKDEP_NEON: MPU */
+static struct clkdm_dep neon_wkdeps[] = {
+ { .clkdm_name = "mpu_clkdm" },
+ { NULL },
+};
+
+/* Sleep dependency source arrays for OMAP3-specific clkdms */
+
+/* 3430: CM_SLEEPDEP_DSS: MPU, IVA */
+static struct clkdm_dep dss_sleepdeps[] = {
+ { .clkdm_name = "mpu_clkdm" },
+ { .clkdm_name = "iva2_clkdm" },
+ { NULL },
+};
+
+/* 3430: CM_SLEEPDEP_PER: MPU, IVA */
+static struct clkdm_dep per_sleepdeps[] = {
+ { .clkdm_name = "mpu_clkdm" },
+ { .clkdm_name = "iva2_clkdm" },
+ { NULL },
+};
+
+/* 3430ES2: CM_SLEEPDEP_USBHOST: MPU, IVA */
+static struct clkdm_dep usbhost_sleepdeps[] = {
+ { .clkdm_name = "mpu_clkdm" },
+ { .clkdm_name = "iva2_clkdm" },
+ { NULL },
+};
+
+/* 3430: CM_SLEEPDEP_CAM: MPU */
+static struct clkdm_dep cam_sleepdeps[] = {
+ { .clkdm_name = "mpu_clkdm" },
+ { NULL },
+};
+
+/*
+ * 3430ES1: CM_SLEEPDEP_GFX: MPU
+ * 3430ES2: CM_SLEEPDEP_SGX: MPU
+ * These can share data since they will never be present simultaneously
+ * on the same device.
+ */
+static struct clkdm_dep gfx_sgx_sleepdeps[] = {
+ { .clkdm_name = "mpu_clkdm" },
+ { NULL },
+};
+
+/*
+ * OMAP3 clockdomains
+ */
+
+static struct clockdomain mpu_3xxx_clkdm = {
+ .name = "mpu_clkdm",
+ .pwrdm = { .name = "mpu_pwrdm" },
+ .flags = CLKDM_CAN_HWSUP | CLKDM_CAN_FORCE_WAKEUP,
+ .dep_bit = OMAP3430_EN_MPU_SHIFT,
+ .wkdep_srcs = mpu_3xxx_wkdeps,
+ .clktrctrl_mask = OMAP3430_CLKTRCTRL_MPU_MASK,
+};
+
+static struct clockdomain neon_clkdm = {
+ .name = "neon_clkdm",
+ .pwrdm = { .name = "neon_pwrdm" },
+ .flags = CLKDM_CAN_HWSUP_SWSUP,
+ .wkdep_srcs = neon_wkdeps,
+ .clktrctrl_mask = OMAP3430_CLKTRCTRL_NEON_MASK,
+};
+
+static struct clockdomain iva2_clkdm = {
+ .name = "iva2_clkdm",
+ .pwrdm = { .name = "iva2_pwrdm" },
+ .flags = CLKDM_CAN_HWSUP_SWSUP,
+ .dep_bit = OMAP3430_PM_WKDEP_MPU_EN_IVA2_SHIFT,
+ .wkdep_srcs = iva2_wkdeps,
+ .clktrctrl_mask = OMAP3430_CLKTRCTRL_IVA2_MASK,
+};
+
+static struct clockdomain gfx_3430es1_clkdm = {
+ .name = "gfx_clkdm",
+ .pwrdm = { .name = "gfx_pwrdm" },
+ .flags = CLKDM_CAN_HWSUP_SWSUP,
+ .wkdep_srcs = gfx_sgx_3xxx_wkdeps,
+ .sleepdep_srcs = gfx_sgx_sleepdeps,
+ .clktrctrl_mask = OMAP3430ES1_CLKTRCTRL_GFX_MASK,
+};
+
+static struct clockdomain sgx_clkdm = {
+ .name = "sgx_clkdm",
+ .pwrdm = { .name = "sgx_pwrdm" },
+ .flags = CLKDM_CAN_HWSUP_SWSUP,
+ .wkdep_srcs = gfx_sgx_3xxx_wkdeps,
+ .sleepdep_srcs = gfx_sgx_sleepdeps,
+ .clktrctrl_mask = OMAP3430ES2_CLKTRCTRL_SGX_MASK,
+};
+
+/*
+ * The die-to-die clockdomain was documented in the 34xx ES1 TRM, but
+ * then that information was removed from the 34xx ES2+ TRM. It is
+ * unclear whether the core is still there, but the clockdomain logic
+ * is there, and must be programmed to an appropriate state if the
+ * CORE clockdomain is to become inactive.
+ */
+static struct clockdomain d2d_clkdm = {
+ .name = "d2d_clkdm",
+ .pwrdm = { .name = "core_pwrdm" },
+ .flags = CLKDM_CAN_HWSUP_SWSUP,
+ .clktrctrl_mask = OMAP3430ES1_CLKTRCTRL_D2D_MASK,
+};
+
+/*
+ * XXX add usecounting for clkdm dependencies, otherwise the presence
+ * of a single dep bit for core_l3_3xxx_clkdm and core_l4_3xxx_clkdm
+ * could cause trouble
+ */
+static struct clockdomain core_l3_3xxx_clkdm = {
+ .name = "core_l3_clkdm",
+ .pwrdm = { .name = "core_pwrdm" },
+ .flags = CLKDM_CAN_HWSUP,
+ .dep_bit = OMAP3430_EN_CORE_SHIFT,
+ .clktrctrl_mask = OMAP3430_CLKTRCTRL_L3_MASK,
+};
+
+/*
+ * XXX add usecounting for clkdm dependencies, otherwise the presence
+ * of a single dep bit for core_l3_3xxx_clkdm and core_l4_3xxx_clkdm
+ * could cause trouble
+ */
+static struct clockdomain core_l4_3xxx_clkdm = {
+ .name = "core_l4_clkdm",
+ .pwrdm = { .name = "core_pwrdm" },
+ .flags = CLKDM_CAN_HWSUP,
+ .dep_bit = OMAP3430_EN_CORE_SHIFT,
+ .clktrctrl_mask = OMAP3430_CLKTRCTRL_L4_MASK,
+};
+
+/* Another case of bit name collisions between several registers: EN_DSS */
+static struct clockdomain dss_3xxx_clkdm = {
+ .name = "dss_clkdm",
+ .pwrdm = { .name = "dss_pwrdm" },
+ .flags = CLKDM_CAN_HWSUP_SWSUP,
+ .dep_bit = OMAP3430_PM_WKDEP_MPU_EN_DSS_SHIFT,
+ .wkdep_srcs = dss_wkdeps,
+ .sleepdep_srcs = dss_sleepdeps,
+ .clktrctrl_mask = OMAP3430_CLKTRCTRL_DSS_MASK,
+};
+
+static struct clockdomain cam_clkdm = {
+ .name = "cam_clkdm",
+ .pwrdm = { .name = "cam_pwrdm" },
+ .flags = CLKDM_CAN_HWSUP_SWSUP,
+ .wkdep_srcs = cam_wkdeps,
+ .sleepdep_srcs = cam_sleepdeps,
+ .clktrctrl_mask = OMAP3430_CLKTRCTRL_CAM_MASK,
+};
+
+static struct clockdomain usbhost_clkdm = {
+ .name = "usbhost_clkdm",
+ .pwrdm = { .name = "usbhost_pwrdm" },
+ .flags = CLKDM_CAN_HWSUP_SWSUP,
+ .wkdep_srcs = usbhost_wkdeps,
+ .sleepdep_srcs = usbhost_sleepdeps,
+ .clktrctrl_mask = OMAP3430ES2_CLKTRCTRL_USBHOST_MASK,
+};
+
+static struct clockdomain per_clkdm = {
+ .name = "per_clkdm",
+ .pwrdm = { .name = "per_pwrdm" },
+ .flags = CLKDM_CAN_HWSUP_SWSUP,
+ .dep_bit = OMAP3430_EN_PER_SHIFT,
+ .wkdep_srcs = per_wkdeps,
+ .sleepdep_srcs = per_sleepdeps,
+ .clktrctrl_mask = OMAP3430_CLKTRCTRL_PER_MASK,
+};
+
+/*
+ * Disable hw supervised mode for emu_clkdm, because emu_pwrdm is
+ * switched of even if sdti is in use
+ */
+static struct clockdomain emu_clkdm = {
+ .name = "emu_clkdm",
+ .pwrdm = { .name = "emu_pwrdm" },
+ .flags = /* CLKDM_CAN_ENABLE_AUTO | */CLKDM_CAN_SWSUP,
+ .clktrctrl_mask = OMAP3430_CLKTRCTRL_EMU_MASK,
+};
+
+static struct clockdomain dpll1_clkdm = {
+ .name = "dpll1_clkdm",
+ .pwrdm = { .name = "dpll1_pwrdm" },
+};
+
+static struct clockdomain dpll2_clkdm = {
+ .name = "dpll2_clkdm",
+ .pwrdm = { .name = "dpll2_pwrdm" },
+};
+
+static struct clockdomain dpll3_clkdm = {
+ .name = "dpll3_clkdm",
+ .pwrdm = { .name = "dpll3_pwrdm" },
+};
+
+static struct clockdomain dpll4_clkdm = {
+ .name = "dpll4_clkdm",
+ .pwrdm = { .name = "dpll4_pwrdm" },
+};
+
+static struct clockdomain dpll5_clkdm = {
+ .name = "dpll5_clkdm",
+ .pwrdm = { .name = "dpll5_pwrdm" },
+};
+
+/*
+ * Clockdomain hwsup dependencies
+ */
+
+static struct clkdm_autodep clkdm_autodeps[] = {
+ {
+ .clkdm = { .name = "mpu_clkdm" },
+ },
+ {
+ .clkdm = { .name = "iva2_clkdm" },
+ },
+ {
+ .clkdm = { .name = NULL },
+ }
+};
+
+/*
+ *
+ */
+
+static struct clockdomain *clockdomains_omap3430_common[] __initdata = {
+ &wkup_common_clkdm,
+ &cm_common_clkdm,
+ &prm_common_clkdm,
+ &mpu_3xxx_clkdm,
+ &neon_clkdm,
+ &iva2_clkdm,
+ &d2d_clkdm,
+ &core_l3_3xxx_clkdm,
+ &core_l4_3xxx_clkdm,
+ &dss_3xxx_clkdm,
+ &cam_clkdm,
+ &per_clkdm,
+ &emu_clkdm,
+ &dpll1_clkdm,
+ &dpll2_clkdm,
+ &dpll3_clkdm,
+ &dpll4_clkdm,
+ NULL
+};
+
+static struct clockdomain *clockdomains_omap3430es1[] __initdata = {
+ &gfx_3430es1_clkdm,
+ NULL,
+};
+
+static struct clockdomain *clockdomains_omap3430es2plus[] __initdata = {
+ &sgx_clkdm,
+ &dpll5_clkdm,
+ &usbhost_clkdm,
+ NULL,
+};
+
+void __init omap3xxx_clockdomains_init(void)
+{
+ struct clockdomain **sc;
+
+ if (!cpu_is_omap34xx())
+ return;
+
+ clkdm_register_platform_funcs(&omap3_clkdm_operations);
+ clkdm_register_clkdms(clockdomains_omap3430_common);
+
+ sc = (omap_rev() == OMAP3430_REV_ES1_0) ? clockdomains_omap3430es1 :
+ clockdomains_omap3430es2plus;
+
+ clkdm_register_clkdms(sc);
+
+ clkdm_register_autodeps(clkdm_autodeps);
+ clkdm_complete_init();
+}
diff --git a/arch/arm/mach-omap2/clockdomains44xx_data.c b/arch/arm/mach-omap2/clockdomains44xx_data.c
index dccc651fa0d0..9299ac291d28 100644
--- a/arch/arm/mach-omap2/clockdomains44xx_data.c
+++ b/arch/arm/mach-omap2/clockdomains44xx_data.c
@@ -34,350 +34,122 @@
/* Static Dependencies for OMAP4 Clock Domains */
static struct clkdm_dep d2d_wkup_sleep_deps[] = {
- {
- .clkdm_name = "abe_clkdm",
- .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430)
- },
- {
- .clkdm_name = "ivahd_clkdm",
- .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430)
- },
- {
- .clkdm_name = "l3_1_clkdm",
- .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430)
- },
- {
- .clkdm_name = "l3_2_clkdm",
- .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430)
- },
- {
- .clkdm_name = "l3_emif_clkdm",
- .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430)
- },
- {
- .clkdm_name = "l3_init_clkdm",
- .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430)
- },
- {
- .clkdm_name = "l4_cfg_clkdm",
- .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430)
- },
- {
- .clkdm_name = "l4_per_clkdm",
- .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430)
- },
+ { .clkdm_name = "abe_clkdm" },
+ { .clkdm_name = "ivahd_clkdm" },
+ { .clkdm_name = "l3_1_clkdm" },
+ { .clkdm_name = "l3_2_clkdm" },
+ { .clkdm_name = "l3_emif_clkdm" },
+ { .clkdm_name = "l3_init_clkdm" },
+ { .clkdm_name = "l4_cfg_clkdm" },
+ { .clkdm_name = "l4_per_clkdm" },
{ NULL },
};
static struct clkdm_dep ducati_wkup_sleep_deps[] = {
- {
- .clkdm_name = "abe_clkdm",
- .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430)
- },
- {
- .clkdm_name = "ivahd_clkdm",
- .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430)
- },
- {
- .clkdm_name = "l3_1_clkdm",
- .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430)
- },
- {
- .clkdm_name = "l3_2_clkdm",
- .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430)
- },
- {
- .clkdm_name = "l3_dss_clkdm",
- .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430)
- },
- {
- .clkdm_name = "l3_emif_clkdm",
- .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430)
- },
- {
- .clkdm_name = "l3_gfx_clkdm",
- .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430)
- },
- {
- .clkdm_name = "l3_init_clkdm",
- .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430)
- },
- {
- .clkdm_name = "l4_cfg_clkdm",
- .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430)
- },
- {
- .clkdm_name = "l4_per_clkdm",
- .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430)
- },
- {
- .clkdm_name = "l4_secure_clkdm",
- .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430)
- },
- {
- .clkdm_name = "l4_wkup_clkdm",
- .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430)
- },
- {
- .clkdm_name = "tesla_clkdm",
- .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430)
- },
+ { .clkdm_name = "abe_clkdm" },
+ { .clkdm_name = "ivahd_clkdm" },
+ { .clkdm_name = "l3_1_clkdm" },
+ { .clkdm_name = "l3_2_clkdm" },
+ { .clkdm_name = "l3_dss_clkdm" },
+ { .clkdm_name = "l3_emif_clkdm" },
+ { .clkdm_name = "l3_gfx_clkdm" },
+ { .clkdm_name = "l3_init_clkdm" },
+ { .clkdm_name = "l4_cfg_clkdm" },
+ { .clkdm_name = "l4_per_clkdm" },
+ { .clkdm_name = "l4_secure_clkdm" },
+ { .clkdm_name = "l4_wkup_clkdm" },
+ { .clkdm_name = "tesla_clkdm" },
{ NULL },
};
static struct clkdm_dep iss_wkup_sleep_deps[] = {
- {
- .clkdm_name = "ivahd_clkdm",
- .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430)
- },
- {
- .clkdm_name = "l3_1_clkdm",
- .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430)
- },
- {
- .clkdm_name = "l3_emif_clkdm",
- .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430)
- },
+ { .clkdm_name = "ivahd_clkdm" },
+ { .clkdm_name = "l3_1_clkdm" },
+ { .clkdm_name = "l3_emif_clkdm" },
{ NULL },
};
static struct clkdm_dep ivahd_wkup_sleep_deps[] = {
- {
- .clkdm_name = "l3_1_clkdm",
- .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430)
- },
- {
- .clkdm_name = "l3_emif_clkdm",
- .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430)
- },
+ { .clkdm_name = "l3_1_clkdm" },
+ { .clkdm_name = "l3_emif_clkdm" },
{ NULL },
};
static struct clkdm_dep l3_dma_wkup_sleep_deps[] = {
- {
- .clkdm_name = "abe_clkdm",
- .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430)
- },
- {
- .clkdm_name = "ducati_clkdm",
- .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430)
- },
- {
- .clkdm_name = "ivahd_clkdm",
- .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430)
- },
- {
- .clkdm_name = "l3_1_clkdm",
- .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430)
- },
- {
- .clkdm_name = "l3_dss_clkdm",
- .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430)
- },
- {
- .clkdm_name = "l3_emif_clkdm",
- .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430)
- },
- {
- .clkdm_name = "l3_init_clkdm",
- .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430)
- },
- {
- .clkdm_name = "l4_cfg_clkdm",
- .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430)
- },
- {
- .clkdm_name = "l4_per_clkdm",
- .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430)
- },
- {
- .clkdm_name = "l4_secure_clkdm",
- .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430)
- },
- {
- .clkdm_name = "l4_wkup_clkdm",
- .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430)
- },
+ { .clkdm_name = "abe_clkdm" },
+ { .clkdm_name = "ducati_clkdm" },
+ { .clkdm_name = "ivahd_clkdm" },
+ { .clkdm_name = "l3_1_clkdm" },
+ { .clkdm_name = "l3_dss_clkdm" },
+ { .clkdm_name = "l3_emif_clkdm" },
+ { .clkdm_name = "l3_init_clkdm" },
+ { .clkdm_name = "l4_cfg_clkdm" },
+ { .clkdm_name = "l4_per_clkdm" },
+ { .clkdm_name = "l4_secure_clkdm" },
+ { .clkdm_name = "l4_wkup_clkdm" },
{ NULL },
};
static struct clkdm_dep l3_dss_wkup_sleep_deps[] = {
- {
- .clkdm_name = "ivahd_clkdm",
- .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430)
- },
- {
- .clkdm_name = "l3_2_clkdm",
- .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430)
- },
- {
- .clkdm_name = "l3_emif_clkdm",
- .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430)
- },
+ { .clkdm_name = "ivahd_clkdm" },
+ { .clkdm_name = "l3_2_clkdm" },
+ { .clkdm_name = "l3_emif_clkdm" },
{ NULL },
};
static struct clkdm_dep l3_gfx_wkup_sleep_deps[] = {
- {
- .clkdm_name = "ivahd_clkdm",
- .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430)
- },
- {
- .clkdm_name = "l3_1_clkdm",
- .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430)
- },
- {
- .clkdm_name = "l3_emif_clkdm",
- .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430)
- },
+ { .clkdm_name = "ivahd_clkdm" },
+ { .clkdm_name = "l3_1_clkdm" },
+ { .clkdm_name = "l3_emif_clkdm" },
{ NULL },
};
static struct clkdm_dep l3_init_wkup_sleep_deps[] = {
- {
- .clkdm_name = "abe_clkdm",
- .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430)
- },
- {
- .clkdm_name = "ivahd_clkdm",
- .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430)
- },
- {
- .clkdm_name = "l3_emif_clkdm",
- .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430)
- },
- {
- .clkdm_name = "l4_cfg_clkdm",
- .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430)
- },
- {
- .clkdm_name = "l4_per_clkdm",
- .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430)
- },
- {
- .clkdm_name = "l4_secure_clkdm",
- .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430)
- },
- {
- .clkdm_name = "l4_wkup_clkdm",
- .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430)
- },
+ { .clkdm_name = "abe_clkdm" },
+ { .clkdm_name = "ivahd_clkdm" },
+ { .clkdm_name = "l3_emif_clkdm" },
+ { .clkdm_name = "l4_cfg_clkdm" },
+ { .clkdm_name = "l4_per_clkdm" },
+ { .clkdm_name = "l4_secure_clkdm" },
+ { .clkdm_name = "l4_wkup_clkdm" },
{ NULL },
};
static struct clkdm_dep l4_secure_wkup_sleep_deps[] = {
- {
- .clkdm_name = "l3_1_clkdm",
- .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430)
- },
- {
- .clkdm_name = "l3_emif_clkdm",
- .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430)
- },
- {
- .clkdm_name = "l4_per_clkdm",
- .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430)
- },
+ { .clkdm_name = "l3_1_clkdm" },
+ { .clkdm_name = "l3_emif_clkdm" },
+ { .clkdm_name = "l4_per_clkdm" },
{ NULL },
};
static struct clkdm_dep mpu_wkup_sleep_deps[] = {
- {
- .clkdm_name = "abe_clkdm",
- .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430)
- },
- {
- .clkdm_name = "ducati_clkdm",
- .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430)
- },
- {
- .clkdm_name = "ivahd_clkdm",
- .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430)
- },
- {
- .clkdm_name = "l3_1_clkdm",
- .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430)
- },
- {
- .clkdm_name = "l3_2_clkdm",
- .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430)
- },
- {
- .clkdm_name = "l3_dss_clkdm",
- .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430)
- },
- {
- .clkdm_name = "l3_emif_clkdm",
- .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430)
- },
- {
- .clkdm_name = "l3_gfx_clkdm",
- .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430)
- },
- {
- .clkdm_name = "l3_init_clkdm",
- .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430)
- },
- {
- .clkdm_name = "l4_cfg_clkdm",
- .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430)
- },
- {
- .clkdm_name = "l4_per_clkdm",
- .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430)
- },
- {
- .clkdm_name = "l4_secure_clkdm",
- .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430)
- },
- {
- .clkdm_name = "l4_wkup_clkdm",
- .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430)
- },
- {
- .clkdm_name = "tesla_clkdm",
- .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430)
- },
+ { .clkdm_name = "abe_clkdm" },
+ { .clkdm_name = "ducati_clkdm" },
+ { .clkdm_name = "ivahd_clkdm" },
+ { .clkdm_name = "l3_1_clkdm" },
+ { .clkdm_name = "l3_2_clkdm" },
+ { .clkdm_name = "l3_dss_clkdm" },
+ { .clkdm_name = "l3_emif_clkdm" },
+ { .clkdm_name = "l3_gfx_clkdm" },
+ { .clkdm_name = "l3_init_clkdm" },
+ { .clkdm_name = "l4_cfg_clkdm" },
+ { .clkdm_name = "l4_per_clkdm" },
+ { .clkdm_name = "l4_secure_clkdm" },
+ { .clkdm_name = "l4_wkup_clkdm" },
+ { .clkdm_name = "tesla_clkdm" },
{ NULL },
};
static struct clkdm_dep tesla_wkup_sleep_deps[] = {
- {
- .clkdm_name = "abe_clkdm",
- .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430)
- },
- {
- .clkdm_name = "ivahd_clkdm",
- .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430)
- },
- {
- .clkdm_name = "l3_1_clkdm",
- .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430)
- },
- {
- .clkdm_name = "l3_2_clkdm",
- .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430)
- },
- {
- .clkdm_name = "l3_emif_clkdm",
- .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430)
- },
- {
- .clkdm_name = "l3_init_clkdm",
- .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430)
- },
- {
- .clkdm_name = "l4_cfg_clkdm",
- .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430)
- },
- {
- .clkdm_name = "l4_per_clkdm",
- .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430)
- },
- {
- .clkdm_name = "l4_wkup_clkdm",
- .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430)
- },
+ { .clkdm_name = "abe_clkdm" },
+ { .clkdm_name = "ivahd_clkdm" },
+ { .clkdm_name = "l3_1_clkdm" },
+ { .clkdm_name = "l3_2_clkdm" },
+ { .clkdm_name = "l3_emif_clkdm" },
+ { .clkdm_name = "l3_init_clkdm" },
+ { .clkdm_name = "l4_cfg_clkdm" },
+ { .clkdm_name = "l4_per_clkdm" },
+ { .clkdm_name = "l4_wkup_clkdm" },
{ NULL },
};
@@ -388,7 +160,6 @@ static struct clockdomain l4_cefuse_44xx_clkdm = {
.cm_inst = OMAP4430_CM2_CEFUSE_INST,
.clkdm_offs = OMAP4430_CM2_CEFUSE_CEFUSE_CDOFFS,
.flags = CLKDM_CAN_FORCE_WAKEUP | CLKDM_CAN_HWSUP,
- .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430),
};
static struct clockdomain l4_cfg_44xx_clkdm = {
@@ -399,7 +170,6 @@ static struct clockdomain l4_cfg_44xx_clkdm = {
.clkdm_offs = OMAP4430_CM2_CORE_L4CFG_CDOFFS,
.dep_bit = OMAP4430_L4CFG_STATDEP_SHIFT,
.flags = CLKDM_CAN_HWSUP,
- .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430),
};
static struct clockdomain tesla_44xx_clkdm = {
@@ -412,7 +182,6 @@ static struct clockdomain tesla_44xx_clkdm = {
.wkdep_srcs = tesla_wkup_sleep_deps,
.sleepdep_srcs = tesla_wkup_sleep_deps,
.flags = CLKDM_CAN_HWSUP_SWSUP,
- .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430),
};
static struct clockdomain l3_gfx_44xx_clkdm = {
@@ -425,7 +194,6 @@ static struct clockdomain l3_gfx_44xx_clkdm = {
.wkdep_srcs = l3_gfx_wkup_sleep_deps,
.sleepdep_srcs = l3_gfx_wkup_sleep_deps,
.flags = CLKDM_CAN_HWSUP_SWSUP,
- .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430),
};
static struct clockdomain ivahd_44xx_clkdm = {
@@ -438,7 +206,6 @@ static struct clockdomain ivahd_44xx_clkdm = {
.wkdep_srcs = ivahd_wkup_sleep_deps,
.sleepdep_srcs = ivahd_wkup_sleep_deps,
.flags = CLKDM_CAN_HWSUP_SWSUP,
- .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430),
};
static struct clockdomain l4_secure_44xx_clkdm = {
@@ -451,7 +218,6 @@ static struct clockdomain l4_secure_44xx_clkdm = {
.wkdep_srcs = l4_secure_wkup_sleep_deps,
.sleepdep_srcs = l4_secure_wkup_sleep_deps,
.flags = CLKDM_CAN_HWSUP_SWSUP,
- .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430),
};
static struct clockdomain l4_per_44xx_clkdm = {
@@ -462,7 +228,6 @@ static struct clockdomain l4_per_44xx_clkdm = {
.clkdm_offs = OMAP4430_CM2_L4PER_L4PER_CDOFFS,
.dep_bit = OMAP4430_L4PER_STATDEP_SHIFT,
.flags = CLKDM_CAN_HWSUP_SWSUP,
- .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430),
};
static struct clockdomain abe_44xx_clkdm = {
@@ -473,7 +238,6 @@ static struct clockdomain abe_44xx_clkdm = {
.clkdm_offs = OMAP4430_CM1_ABE_ABE_CDOFFS,
.dep_bit = OMAP4430_ABE_STATDEP_SHIFT,
.flags = CLKDM_CAN_HWSUP_SWSUP,
- .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430),
};
static struct clockdomain l3_instr_44xx_clkdm = {
@@ -482,7 +246,6 @@ static struct clockdomain l3_instr_44xx_clkdm = {
.prcm_partition = OMAP4430_CM2_PARTITION,
.cm_inst = OMAP4430_CM2_CORE_INST,
.clkdm_offs = OMAP4430_CM2_CORE_L3INSTR_CDOFFS,
- .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430),
};
static struct clockdomain l3_init_44xx_clkdm = {
@@ -495,7 +258,6 @@ static struct clockdomain l3_init_44xx_clkdm = {
.wkdep_srcs = l3_init_wkup_sleep_deps,
.sleepdep_srcs = l3_init_wkup_sleep_deps,
.flags = CLKDM_CAN_HWSUP_SWSUP,
- .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430),
};
static struct clockdomain d2d_44xx_clkdm = {
@@ -507,7 +269,6 @@ static struct clockdomain d2d_44xx_clkdm = {
.wkdep_srcs = d2d_wkup_sleep_deps,
.sleepdep_srcs = d2d_wkup_sleep_deps,
.flags = CLKDM_CAN_FORCE_WAKEUP | CLKDM_CAN_HWSUP,
- .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430),
};
static struct clockdomain mpu0_44xx_clkdm = {
@@ -517,7 +278,6 @@ static struct clockdomain mpu0_44xx_clkdm = {
.cm_inst = OMAP4430_PRCM_MPU_CPU0_INST,
.clkdm_offs = OMAP4430_PRCM_MPU_CPU0_CPU0_CDOFFS,
.flags = CLKDM_CAN_FORCE_WAKEUP | CLKDM_CAN_HWSUP,
- .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430),
};
static struct clockdomain mpu1_44xx_clkdm = {
@@ -527,7 +287,6 @@ static struct clockdomain mpu1_44xx_clkdm = {
.cm_inst = OMAP4430_PRCM_MPU_CPU1_INST,
.clkdm_offs = OMAP4430_PRCM_MPU_CPU1_CPU1_CDOFFS,
.flags = CLKDM_CAN_FORCE_WAKEUP | CLKDM_CAN_HWSUP,
- .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430),
};
static struct clockdomain l3_emif_44xx_clkdm = {
@@ -538,7 +297,6 @@ static struct clockdomain l3_emif_44xx_clkdm = {
.clkdm_offs = OMAP4430_CM2_CORE_MEMIF_CDOFFS,
.dep_bit = OMAP4430_MEMIF_STATDEP_SHIFT,
.flags = CLKDM_CAN_FORCE_WAKEUP | CLKDM_CAN_HWSUP,
- .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430),
};
static struct clockdomain l4_ao_44xx_clkdm = {
@@ -548,7 +306,6 @@ static struct clockdomain l4_ao_44xx_clkdm = {
.cm_inst = OMAP4430_CM2_ALWAYS_ON_INST,
.clkdm_offs = OMAP4430_CM2_ALWAYS_ON_ALWON_CDOFFS,
.flags = CLKDM_CAN_FORCE_WAKEUP | CLKDM_CAN_HWSUP,
- .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430),
};
static struct clockdomain ducati_44xx_clkdm = {
@@ -561,7 +318,6 @@ static struct clockdomain ducati_44xx_clkdm = {
.wkdep_srcs = ducati_wkup_sleep_deps,
.sleepdep_srcs = ducati_wkup_sleep_deps,
.flags = CLKDM_CAN_HWSUP_SWSUP,
- .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430),
};
static struct clockdomain mpu_44xx_clkdm = {
@@ -573,7 +329,6 @@ static struct clockdomain mpu_44xx_clkdm = {
.wkdep_srcs = mpu_wkup_sleep_deps,
.sleepdep_srcs = mpu_wkup_sleep_deps,
.flags = CLKDM_CAN_FORCE_WAKEUP | CLKDM_CAN_HWSUP,
- .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430),
};
static struct clockdomain l3_2_44xx_clkdm = {
@@ -584,7 +339,6 @@ static struct clockdomain l3_2_44xx_clkdm = {
.clkdm_offs = OMAP4430_CM2_CORE_L3_2_CDOFFS,
.dep_bit = OMAP4430_L3_2_STATDEP_SHIFT,
.flags = CLKDM_CAN_HWSUP,
- .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430),
};
static struct clockdomain l3_1_44xx_clkdm = {
@@ -595,7 +349,6 @@ static struct clockdomain l3_1_44xx_clkdm = {
.clkdm_offs = OMAP4430_CM2_CORE_L3_1_CDOFFS,
.dep_bit = OMAP4430_L3_1_STATDEP_SHIFT,
.flags = CLKDM_CAN_HWSUP,
- .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430),
};
static struct clockdomain iss_44xx_clkdm = {
@@ -607,7 +360,6 @@ static struct clockdomain iss_44xx_clkdm = {
.wkdep_srcs = iss_wkup_sleep_deps,
.sleepdep_srcs = iss_wkup_sleep_deps,
.flags = CLKDM_CAN_HWSUP_SWSUP,
- .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430),
};
static struct clockdomain l3_dss_44xx_clkdm = {
@@ -620,7 +372,6 @@ static struct clockdomain l3_dss_44xx_clkdm = {
.wkdep_srcs = l3_dss_wkup_sleep_deps,
.sleepdep_srcs = l3_dss_wkup_sleep_deps,
.flags = CLKDM_CAN_HWSUP_SWSUP,
- .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430),
};
static struct clockdomain l4_wkup_44xx_clkdm = {
@@ -631,7 +382,6 @@ static struct clockdomain l4_wkup_44xx_clkdm = {
.clkdm_offs = OMAP4430_PRM_WKUP_CM_WKUP_CDOFFS,
.dep_bit = OMAP4430_L4WKUP_STATDEP_SHIFT,
.flags = CLKDM_CAN_HWSUP,
- .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430),
};
static struct clockdomain emu_sys_44xx_clkdm = {
@@ -641,7 +391,6 @@ static struct clockdomain emu_sys_44xx_clkdm = {
.cm_inst = OMAP4430_PRM_EMU_CM_INST,
.clkdm_offs = OMAP4430_PRM_EMU_CM_EMU_CDOFFS,
.flags = CLKDM_CAN_HWSUP,
- .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430),
};
static struct clockdomain l3_dma_44xx_clkdm = {
@@ -653,7 +402,6 @@ static struct clockdomain l3_dma_44xx_clkdm = {
.wkdep_srcs = l3_dma_wkup_sleep_deps,
.sleepdep_srcs = l3_dma_wkup_sleep_deps,
.flags = CLKDM_CAN_FORCE_WAKEUP | CLKDM_CAN_HWSUP,
- .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430),
};
/* As clockdomains are added or removed above, this list must also be changed */
@@ -685,7 +433,10 @@ static struct clockdomain *clockdomains_omap44xx[] __initdata = {
NULL
};
+
void __init omap44xx_clockdomains_init(void)
{
- clkdm_init(clockdomains_omap44xx, NULL, &omap4_clkdm_operations);
+ clkdm_register_platform_funcs(&omap4_clkdm_operations);
+ clkdm_register_clkdms(clockdomains_omap44xx);
+ clkdm_complete_init();
}
diff --git a/arch/arm/mach-omap2/common.c b/arch/arm/mach-omap2/common.c
index 3f20cbb9967b..de61f15c48e2 100644
--- a/arch/arm/mach-omap2/common.c
+++ b/arch/arm/mach-omap2/common.c
@@ -56,6 +56,12 @@ void __init omap2_set_globals_242x(void)
{
__omap2_set_globals(&omap242x_globals);
}
+
+void __init omap242x_map_io(void)
+{
+ omap2_set_globals_242x();
+ omap242x_map_common_io();
+}
#endif
#if defined(CONFIG_SOC_OMAP2430)
@@ -74,6 +80,12 @@ void __init omap2_set_globals_243x(void)
{
__omap2_set_globals(&omap243x_globals);
}
+
+void __init omap243x_map_io(void)
+{
+ omap2_set_globals_243x();
+ omap243x_map_common_io();
+}
#endif
#if defined(CONFIG_ARCH_OMAP3)
@@ -138,5 +150,11 @@ void __init omap2_set_globals_443x(void)
omap2_set_globals_control(&omap4_globals);
omap2_set_globals_prcm(&omap4_globals);
}
+
+void __init omap4_map_io(void)
+{
+ omap2_set_globals_443x();
+ omap44xx_map_common_io();
+}
#endif
diff --git a/arch/arm/mach-omap2/devices.c b/arch/arm/mach-omap2/devices.c
index 1077ad663f93..0f8e0eb18166 100644
--- a/arch/arm/mach-omap2/devices.c
+++ b/arch/arm/mach-omap2/devices.c
@@ -16,6 +16,7 @@
#include <linux/clk.h>
#include <linux/err.h>
#include <linux/slab.h>
+#include <linux/of.h>
#include <mach/hardware.h>
#include <mach/irqs.h>
@@ -44,7 +45,7 @@ static int __init omap3_l3_init(void)
{
int l;
struct omap_hwmod *oh;
- struct omap_device *od;
+ struct platform_device *pdev;
char oh_name[L3_MODULES_MAX_LEN];
/*
@@ -61,12 +62,12 @@ static int __init omap3_l3_init(void)
if (!oh)
pr_err("could not look up %s\n", oh_name);
- od = omap_device_build("omap_l3_smx", 0, oh, NULL, 0,
+ pdev = omap_device_build("omap_l3_smx", 0, oh, NULL, 0,
NULL, 0, 0);
- WARN(IS_ERR(od), "could not build omap_device for %s\n", oh_name);
+ WARN(IS_ERR(pdev), "could not build omap_device for %s\n", oh_name);
- return IS_ERR(od) ? PTR_ERR(od) : 0;
+ return IS_ERR(pdev) ? PTR_ERR(pdev) : 0;
}
postcore_initcall(omap3_l3_init);
@@ -74,9 +75,13 @@ static int __init omap4_l3_init(void)
{
int l, i;
struct omap_hwmod *oh[3];
- struct omap_device *od;
+ struct platform_device *pdev;
char oh_name[L3_MODULES_MAX_LEN];
+ /* If dtb is there, the devices will be created dynamically */
+ if (of_have_populated_dt())
+ return -ENODEV;
+
/*
* To avoid code running on other OMAPs in
* multi-omap builds
@@ -92,12 +97,12 @@ static int __init omap4_l3_init(void)
pr_err("could not look up %s\n", oh_name);
}
- od = omap_device_build_ss("omap_l3_noc", 0, oh, 3, NULL,
+ pdev = omap_device_build_ss("omap_l3_noc", 0, oh, 3, NULL,
0, NULL, 0, 0);
- WARN(IS_ERR(od), "could not build omap_device for %s\n", oh_name);
+ WARN(IS_ERR(pdev), "could not build omap_device for %s\n", oh_name);
- return IS_ERR(od) ? PTR_ERR(od) : 0;
+ return IS_ERR(pdev) ? PTR_ERR(pdev) : 0;
}
postcore_initcall(omap4_l3_init);
@@ -221,18 +226,10 @@ static inline void omap_init_camera(void)
#endif
}
-struct omap_device_pm_latency omap_keyboard_latency[] = {
- {
- .deactivate_func = omap_device_idle_hwmods,
- .activate_func = omap_device_enable_hwmods,
- .flags = OMAP_DEVICE_LATENCY_AUTO_ADJUST,
- },
-};
-
int __init omap4_keyboard_init(struct omap4_keypad_platform_data
*sdp4430_keypad_data, struct omap_board_data *bdata)
{
- struct omap_device *od;
+ struct platform_device *pdev;
struct omap_hwmod *oh;
struct omap4_keypad_platform_data *keypad_data;
unsigned int id = -1;
@@ -247,15 +244,13 @@ int __init omap4_keyboard_init(struct omap4_keypad_platform_data
keypad_data = sdp4430_keypad_data;
- od = omap_device_build(name, id, oh, keypad_data,
- sizeof(struct omap4_keypad_platform_data),
- omap_keyboard_latency,
- ARRAY_SIZE(omap_keyboard_latency), 0);
+ pdev = omap_device_build(name, id, oh, keypad_data,
+ sizeof(struct omap4_keypad_platform_data), NULL, 0, 0);
- if (IS_ERR(od)) {
+ if (IS_ERR(pdev)) {
WARN(1, "Can't build omap_device for %s:%s.\n",
name, oh->name);
- return PTR_ERR(od);
+ return PTR_ERR(pdev);
}
oh->mux = omap_hwmod_mux_init(bdata->pads, bdata->pads_cnt);
@@ -263,18 +258,10 @@ int __init omap4_keyboard_init(struct omap4_keypad_platform_data
}
#if defined(CONFIG_OMAP_MBOX_FWK) || defined(CONFIG_OMAP_MBOX_FWK_MODULE)
-static struct omap_device_pm_latency mbox_latencies[] = {
- [0] = {
- .activate_func = omap_device_enable_hwmods,
- .deactivate_func = omap_device_idle_hwmods,
- .flags = OMAP_DEVICE_LATENCY_AUTO_ADJUST,
- },
-};
-
static inline void omap_init_mbox(void)
{
struct omap_hwmod *oh;
- struct omap_device *od;
+ struct platform_device *pdev;
oh = omap_hwmod_lookup("mailbox");
if (!oh) {
@@ -282,10 +269,9 @@ static inline void omap_init_mbox(void)
return;
}
- od = omap_device_build("omap-mailbox", -1, oh, NULL, 0,
- mbox_latencies, ARRAY_SIZE(mbox_latencies), 0);
- WARN(IS_ERR(od), "%s: could not build device, err %ld\n",
- __func__, PTR_ERR(od));
+ pdev = omap_device_build("omap-mailbox", -1, oh, NULL, 0, NULL, 0, 0);
+ WARN(IS_ERR(pdev), "%s: could not build device, err %ld\n",
+ __func__, PTR_ERR(pdev));
}
#else
static inline void omap_init_mbox(void) { }
@@ -334,17 +320,9 @@ static inline void omap_init_audio(void) {}
#include <plat/mcspi.h>
-struct omap_device_pm_latency omap_mcspi_latency[] = {
- [0] = {
- .deactivate_func = omap_device_idle_hwmods,
- .activate_func = omap_device_enable_hwmods,
- .flags = OMAP_DEVICE_LATENCY_AUTO_ADJUST,
- },
-};
-
static int omap_mcspi_init(struct omap_hwmod *oh, void *unused)
{
- struct omap_device *od;
+ struct platform_device *pdev;
char *name = "omap2_mcspi";
struct omap2_mcspi_platform_config *pdata;
static int spi_num;
@@ -371,10 +349,9 @@ static int omap_mcspi_init(struct omap_hwmod *oh, void *unused)
}
spi_num++;
- od = omap_device_build(name, spi_num, oh, pdata,
- sizeof(*pdata), omap_mcspi_latency,
- ARRAY_SIZE(omap_mcspi_latency), 0);
- WARN(IS_ERR(od), "Can't build omap_device for %s:%s\n",
+ pdev = omap_device_build(name, spi_num, oh, pdata,
+ sizeof(*pdata), NULL, 0, 0);
+ WARN(IS_ERR(pdev), "Can't build omap_device for %s:%s\n",
name, oh->name);
kfree(pdata);
return 0;
@@ -698,18 +675,10 @@ static int __init omap2_init_devices(void)
arch_initcall(omap2_init_devices);
#if defined(CONFIG_OMAP_WATCHDOG) || defined(CONFIG_OMAP_WATCHDOG_MODULE)
-static struct omap_device_pm_latency omap_wdt_latency[] = {
- [0] = {
- .deactivate_func = omap_device_idle_hwmods,
- .activate_func = omap_device_enable_hwmods,
- .flags = OMAP_DEVICE_LATENCY_AUTO_ADJUST,
- },
-};
-
static int __init omap_init_wdt(void)
{
int id = -1;
- struct omap_device *od;
+ struct platform_device *pdev;
struct omap_hwmod *oh;
char *oh_name = "wd_timer2";
char *dev_name = "omap_wdt";
@@ -723,10 +692,8 @@ static int __init omap_init_wdt(void)
return -EINVAL;
}
- od = omap_device_build(dev_name, id, oh, NULL, 0,
- omap_wdt_latency,
- ARRAY_SIZE(omap_wdt_latency), 0);
- WARN(IS_ERR(od), "Can't build omap_device for %s:%s.\n",
+ pdev = omap_device_build(dev_name, id, oh, NULL, 0, NULL, 0, 0);
+ WARN(IS_ERR(pdev), "Can't build omap_device for %s:%s.\n",
dev_name, oh->name);
return 0;
}
diff --git a/arch/arm/mach-omap2/display.c b/arch/arm/mach-omap2/display.c
index a5b7a236aa5b..8ad0a2f0367d 100644
--- a/arch/arm/mach-omap2/display.c
+++ b/arch/arm/mach-omap2/display.c
@@ -35,14 +35,6 @@ static struct platform_device omap_display_device = {
},
};
-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,
- },
-};
-
struct omap_dss_hwmod_data {
const char *oh_name;
const char *dev_name;
@@ -78,7 +70,7 @@ int __init omap_display_init(struct omap_dss_board_info *board_data)
{
int r = 0;
struct omap_hwmod *oh;
- struct omap_device *od;
+ struct platform_device *pdev;
int i, oh_count;
struct omap_display_platform_data pdata;
const struct omap_dss_hwmod_data *curr_dss_hwmod;
@@ -108,13 +100,12 @@ int __init omap_display_init(struct omap_dss_board_info *board_data)
return -ENODEV;
}
- od = omap_device_build(curr_dss_hwmod[i].dev_name,
+ pdev = omap_device_build(curr_dss_hwmod[i].dev_name,
curr_dss_hwmod[i].id, oh, &pdata,
sizeof(struct omap_display_platform_data),
- omap_dss_latency,
- ARRAY_SIZE(omap_dss_latency), 0);
+ NULL, 0, 0);
- if (WARN((IS_ERR(od)), "Could not build omap_device for %s\n",
+ if (WARN((IS_ERR(pdev)), "Could not build omap_device for %s\n",
curr_dss_hwmod[i].oh_name))
return -ENODEV;
}
diff --git a/arch/arm/mach-omap2/dma.c b/arch/arm/mach-omap2/dma.c
index c9ff0e79703d..a59a45a0096e 100644
--- a/arch/arm/mach-omap2/dma.c
+++ b/arch/arm/mach-omap2/dma.c
@@ -87,14 +87,6 @@ static u16 reg_map[] = {
[CCDN] = 0xd8,
};
-static struct omap_device_pm_latency omap2_dma_latency[] = {
- {
- .deactivate_func = omap_device_idle_hwmods,
- .activate_func = omap_device_enable_hwmods,
- .flags = OMAP_DEVICE_LATENCY_AUTO_ADJUST,
- },
-};
-
static void __iomem *dma_base;
static inline void dma_write(u32 val, int reg, int lch)
{
@@ -228,7 +220,7 @@ static u32 configure_dma_errata(void)
/* One time initializations */
static int __init omap2_system_dma_init_dev(struct omap_hwmod *oh, void *unused)
{
- struct omap_device *od;
+ struct platform_device *pdev;
struct omap_system_dma_plat_info *p;
struct resource *mem;
char *name = "omap_dma_system";
@@ -258,23 +250,22 @@ static int __init omap2_system_dma_init_dev(struct omap_hwmod *oh, void *unused)
p->errata = configure_dma_errata();
- od = omap_device_build(name, 0, oh, p, sizeof(*p),
- omap2_dma_latency, ARRAY_SIZE(omap2_dma_latency), 0);
+ pdev = omap_device_build(name, 0, oh, p, sizeof(*p), NULL, 0, 0);
kfree(p);
- if (IS_ERR(od)) {
+ if (IS_ERR(pdev)) {
pr_err("%s: Can't build omap_device for %s:%s.\n",
__func__, name, oh->name);
- return PTR_ERR(od);
+ return PTR_ERR(pdev);
}
- mem = platform_get_resource(&od->pdev, IORESOURCE_MEM, 0);
+ mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
if (!mem) {
- dev_err(&od->pdev.dev, "%s: no mem resource\n", __func__);
+ dev_err(&pdev->dev, "%s: no mem resource\n", __func__);
return -EINVAL;
}
dma_base = ioremap(mem->start, resource_size(mem));
if (!dma_base) {
- dev_err(&od->pdev.dev, "%s: ioremap fail\n", __func__);
+ dev_err(&pdev->dev, "%s: ioremap fail\n", __func__);
return -ENOMEM;
}
@@ -283,7 +274,7 @@ static int __init omap2_system_dma_init_dev(struct omap_hwmod *oh, void *unused)
(d->lch_count), GFP_KERNEL);
if (!d->chan) {
- dev_err(&od->pdev.dev, "%s: kzalloc fail\n", __func__);
+ dev_err(&pdev->dev, "%s: kzalloc fail\n", __func__);
return -ENOMEM;
}
return 0;
diff --git a/arch/arm/mach-omap2/gpio.c b/arch/arm/mach-omap2/gpio.c
index 2765cdc3152d..8cbfbc2918ce 100644
--- a/arch/arm/mach-omap2/gpio.c
+++ b/arch/arm/mach-omap2/gpio.c
@@ -24,17 +24,9 @@
#include <plat/omap_hwmod.h>
#include <plat/omap_device.h>
-static struct omap_device_pm_latency omap_gpio_latency[] = {
- [0] = {
- .deactivate_func = omap_device_idle_hwmods,
- .activate_func = omap_device_enable_hwmods,
- .flags = OMAP_DEVICE_LATENCY_AUTO_ADJUST,
- },
-};
-
static int omap2_gpio_dev_init(struct omap_hwmod *oh, void *unused)
{
- struct omap_device *od;
+ struct platform_device *pdev;
struct omap_gpio_platform_data *pdata;
struct omap_gpio_dev_attr *dev_attr;
char *name = "omap_gpio";
@@ -107,19 +99,17 @@ static int omap2_gpio_dev_init(struct omap_hwmod *oh, void *unused)
return -EINVAL;
}
- od = omap_device_build(name, id - 1, oh, pdata,
- sizeof(*pdata), omap_gpio_latency,
- ARRAY_SIZE(omap_gpio_latency),
- false);
+ pdev = omap_device_build(name, id - 1, oh, pdata,
+ sizeof(*pdata), NULL, 0, false);
kfree(pdata);
- if (IS_ERR(od)) {
+ if (IS_ERR(pdev)) {
WARN(1, "Can't build omap_device for %s:%s.\n",
name, oh->name);
- return PTR_ERR(od);
+ return PTR_ERR(pdev);
}
- omap_device_disable_idle_on_suspend(od);
+ omap_device_disable_idle_on_suspend(pdev);
gpio_bank_count++;
return 0;
diff --git a/arch/arm/mach-omap2/hsmmc.c b/arch/arm/mach-omap2/hsmmc.c
index a9b45c76e1d3..77085847e4e7 100644
--- a/arch/arm/mach-omap2/hsmmc.c
+++ b/arch/arm/mach-omap2/hsmmc.c
@@ -137,8 +137,7 @@ static void omap4_hsmmc1_before_set_reg(struct device *dev, int slot,
*/
reg = omap4_ctrl_pad_readl(control_pbias_offset);
reg &= ~(OMAP4_MMC1_PBIASLITE_PWRDNZ_MASK |
- OMAP4_MMC1_PWRDNZ_MASK |
- OMAP4_USBC1_ICUSB_PWRDNZ_MASK);
+ OMAP4_MMC1_PWRDNZ_MASK);
omap4_ctrl_pad_writel(reg, control_pbias_offset);
}
@@ -156,8 +155,7 @@ static void omap4_hsmmc1_after_set_reg(struct device *dev, int slot,
else
reg |= OMAP4_MMC1_PBIASLITE_VMODE_MASK;
reg |= (OMAP4_MMC1_PBIASLITE_PWRDNZ_MASK |
- OMAP4_MMC1_PWRDNZ_MASK |
- OMAP4_USBC1_ICUSB_PWRDNZ_MASK);
+ OMAP4_MMC1_PWRDNZ_MASK);
omap4_ctrl_pad_writel(reg, control_pbias_offset);
timeout = jiffies + msecs_to_jiffies(5);
@@ -171,16 +169,14 @@ static void omap4_hsmmc1_after_set_reg(struct device *dev, int slot,
if (reg & OMAP4_MMC1_PBIASLITE_VMODE_ERROR_MASK) {
pr_err("Pbias Voltage is not same as LDO\n");
/* Caution : On VMODE_ERROR Power Down MMC IO */
- reg &= ~(OMAP4_MMC1_PWRDNZ_MASK |
- OMAP4_USBC1_ICUSB_PWRDNZ_MASK);
+ reg &= ~(OMAP4_MMC1_PWRDNZ_MASK);
omap4_ctrl_pad_writel(reg, control_pbias_offset);
}
} else {
reg = omap4_ctrl_pad_readl(control_pbias_offset);
reg |= (OMAP4_MMC1_PBIASLITE_PWRDNZ_MASK |
OMAP4_MMC1_PWRDNZ_MASK |
- OMAP4_MMC1_PBIASLITE_VMODE_MASK |
- OMAP4_USBC1_ICUSB_PWRDNZ_MASK);
+ OMAP4_MMC1_PBIASLITE_VMODE_MASK);
omap4_ctrl_pad_writel(reg, control_pbias_offset);
}
}
@@ -413,31 +409,17 @@ static int __init omap_hsmmc_pdata_init(struct omap2_hsmmc_info *c,
return 0;
}
-static struct omap_device_pm_latency omap_hsmmc_latency[] = {
- [0] = {
- .deactivate_func = omap_device_idle_hwmods,
- .activate_func = omap_device_enable_hwmods,
- .flags = OMAP_DEVICE_LATENCY_AUTO_ADJUST,
- },
- /*
- * XXX There should also be an entry here to power off/on the
- * MMC regulators/PBIAS cells, etc.
- */
-};
-
#define MAX_OMAP_MMC_HWMOD_NAME_LEN 16
void __init omap_init_hsmmc(struct omap2_hsmmc_info *hsmmcinfo, int ctrl_nr)
{
struct omap_hwmod *oh;
- struct omap_device *od;
- struct omap_device_pm_latency *ohl;
+ struct platform_device *pdev;
char oh_name[MAX_OMAP_MMC_HWMOD_NAME_LEN];
struct omap_mmc_platform_data *mmc_data;
struct omap_mmc_dev_attr *mmc_dev_attr;
char *name;
int l;
- int ohl_cnt = 0;
mmc_data = kzalloc(sizeof(struct omap_mmc_platform_data), GFP_KERNEL);
if (!mmc_data) {
@@ -452,8 +434,6 @@ void __init omap_init_hsmmc(struct omap2_hsmmc_info *hsmmcinfo, int ctrl_nr)
omap_hsmmc_mux(mmc_data, (ctrl_nr - 1));
name = "omap_hsmmc";
- ohl = omap_hsmmc_latency;
- ohl_cnt = ARRAY_SIZE(omap_hsmmc_latency);
l = snprintf(oh_name, MAX_OMAP_MMC_HWMOD_NAME_LEN,
"mmc%d", ctrl_nr);
@@ -471,9 +451,9 @@ void __init omap_init_hsmmc(struct omap2_hsmmc_info *hsmmcinfo, int ctrl_nr)
mmc_data->controller_flags = mmc_dev_attr->flags;
}
- od = omap_device_build(name, ctrl_nr - 1, oh, mmc_data,
- sizeof(struct omap_mmc_platform_data), ohl, ohl_cnt, false);
- if (IS_ERR(od)) {
+ pdev = omap_device_build(name, ctrl_nr - 1, oh, mmc_data,
+ sizeof(struct omap_mmc_platform_data), NULL, 0, false);
+ if (IS_ERR(pdev)) {
WARN(1, "Can't build omap_device for %s:%s.\n", name, oh->name);
kfree(mmc_data->slots[0].name);
goto done;
@@ -482,7 +462,7 @@ void __init omap_init_hsmmc(struct omap2_hsmmc_info *hsmmcinfo, int ctrl_nr)
* return device handle to board setup code
* required to populate for regulator framework structure
*/
- hsmmcinfo->dev = &od->pdev.dev;
+ hsmmcinfo->dev = &pdev->dev;
done:
kfree(mmc_data);
diff --git a/arch/arm/mach-omap2/hwspinlock.c b/arch/arm/mach-omap2/hwspinlock.c
index 06d4a80660a5..36e21091b06a 100644
--- a/arch/arm/mach-omap2/hwspinlock.c
+++ b/arch/arm/mach-omap2/hwspinlock.c
@@ -23,19 +23,11 @@
#include <plat/omap_hwmod.h>
#include <plat/omap_device.h>
-struct omap_device_pm_latency omap_spinlock_latency[] = {
- {
- .deactivate_func = omap_device_idle_hwmods,
- .activate_func = omap_device_enable_hwmods,
- .flags = OMAP_DEVICE_LATENCY_AUTO_ADJUST,
- }
-};
-
int __init hwspinlocks_init(void)
{
int retval = 0;
struct omap_hwmod *oh;
- struct omap_device *od;
+ struct platform_device *pdev;
const char *oh_name = "spinlock";
const char *dev_name = "omap_hwspinlock";
@@ -48,13 +40,11 @@ int __init hwspinlocks_init(void)
if (oh == NULL)
return -EINVAL;
- od = omap_device_build(dev_name, 0, oh, NULL, 0,
- omap_spinlock_latency,
- ARRAY_SIZE(omap_spinlock_latency), false);
- if (IS_ERR(od)) {
+ pdev = omap_device_build(dev_name, 0, oh, NULL, 0, NULL, 0, false);
+ if (IS_ERR(pdev)) {
pr_err("Can't build omap_device for %s:%s\n", dev_name,
oh_name);
- retval = PTR_ERR(od);
+ retval = PTR_ERR(pdev);
}
return retval;
diff --git a/arch/arm/mach-omap2/id.c b/arch/arm/mach-omap2/id.c
index 37efb8696927..d27daf921c7e 100644
--- a/arch/arm/mach-omap2/id.c
+++ b/arch/arm/mach-omap2/id.c
@@ -28,7 +28,6 @@
#include "control.h"
-static struct omap_chip_id omap_chip;
static unsigned int omap_revision;
u32 omap_features;
@@ -39,19 +38,6 @@ unsigned int omap_rev(void)
}
EXPORT_SYMBOL(omap_rev);
-/**
- * omap_chip_is - test whether currently running OMAP matches a chip type
- * @oc: omap_chip_t to test against
- *
- * Test whether the currently-running OMAP chip matches the supplied
- * chip type 'oc'. Returns 1 upon a match; 0 upon failure.
- */
-int omap_chip_is(struct omap_chip_id oci)
-{
- return (oci.oc & omap_chip.oc) ? 1 : 0;
-}
-EXPORT_SYMBOL(omap_chip_is);
-
int omap_type(void)
{
u32 val = 0;
@@ -242,14 +228,12 @@ static void __init ti816x_check_features(void)
omap_features = OMAP3_HAS_NEON;
}
-static void __init omap3_check_revision(void)
+static void __init omap3_check_revision(const char **cpu_rev)
{
u32 cpuid, idcode;
u16 hawkeye;
u8 rev;
- omap_chip.oc = CHIP_IS_OMAP3430;
-
/*
* We cannot access revision registers on ES1.0.
* If the processor type is Cortex-A8 and the revision is 0x0
@@ -258,7 +242,7 @@ static void __init omap3_check_revision(void)
cpuid = read_cpuid(CPUID_ID);
if ((((cpuid >> 4) & 0xfff) == 0xc08) && ((cpuid & 0xf) == 0x0)) {
omap_revision = OMAP3430_REV_ES1_0;
- omap_chip.oc |= CHIP_IS_OMAP3430ES1;
+ *cpu_rev = "1.0";
return;
}
@@ -279,77 +263,85 @@ static void __init omap3_check_revision(void)
case 0: /* Take care of early samples */
case 1:
omap_revision = OMAP3430_REV_ES2_0;
- omap_chip.oc |= CHIP_IS_OMAP3430ES2;
+ *cpu_rev = "2.0";
break;
case 2:
omap_revision = OMAP3430_REV_ES2_1;
- omap_chip.oc |= CHIP_IS_OMAP3430ES2;
+ *cpu_rev = "2.1";
break;
case 3:
omap_revision = OMAP3430_REV_ES3_0;
- omap_chip.oc |= CHIP_IS_OMAP3430ES3_0;
+ *cpu_rev = "3.0";
break;
case 4:
omap_revision = OMAP3430_REV_ES3_1;
- omap_chip.oc |= CHIP_IS_OMAP3430ES3_1;
+ *cpu_rev = "3.1";
break;
case 7:
/* FALLTHROUGH */
default:
/* Use the latest known revision as default */
omap_revision = OMAP3430_REV_ES3_1_2;
-
- /* REVISIT: Add CHIP_IS_OMAP3430ES3_1_2? */
- omap_chip.oc |= CHIP_IS_OMAP3430ES3_1;
+ *cpu_rev = "3.1.2";
}
break;
case 0xb868:
- /* Handle OMAP35xx/AM35xx devices
+ /*
+ * Handle OMAP/AM 3505/3517 devices
*
- * Set the device to be OMAP3505 here. Actual device
+ * Set the device to be OMAP3517 here. Actual device
* is identified later based on the features.
- *
- * REVISIT: AM3505/AM3517 should have their own CHIP_IS
*/
- omap_revision = OMAP3505_REV(rev);
- omap_chip.oc |= CHIP_IS_OMAP3430ES3_1;
+ switch (rev) {
+ case 0:
+ omap_revision = OMAP3517_REV_ES1_0;
+ *cpu_rev = "1.0";
+ break;
+ case 1:
+ /* FALLTHROUGH */
+ default:
+ omap_revision = OMAP3517_REV_ES1_1;
+ *cpu_rev = "1.1";
+ }
break;
case 0xb891:
/* Handle 36xx devices */
- omap_chip.oc |= CHIP_IS_OMAP3630ES1;
switch(rev) {
case 0: /* Take care of early samples */
omap_revision = OMAP3630_REV_ES1_0;
+ *cpu_rev = "1.0";
break;
case 1:
omap_revision = OMAP3630_REV_ES1_1;
- omap_chip.oc |= CHIP_IS_OMAP3630ES1_1;
+ *cpu_rev = "1.1";
break;
case 2:
+ /* FALLTHROUGH */
default:
- omap_revision = OMAP3630_REV_ES1_2;
- omap_chip.oc |= CHIP_IS_OMAP3630ES1_2;
+ omap_revision = OMAP3630_REV_ES1_2;
+ *cpu_rev = "1.2";
}
break;
case 0xb81e:
- omap_chip.oc = CHIP_IS_TI816X;
-
switch (rev) {
case 0:
omap_revision = TI8168_REV_ES1_0;
+ *cpu_rev = "1.0";
break;
case 1:
+ /* FALLTHROUGH */
+ default:
omap_revision = TI8168_REV_ES1_1;
+ *cpu_rev = "1.1";
break;
- default:
- omap_revision = TI8168_REV_ES1_1;
}
break;
default:
- /* Unknown default to latest silicon rev as default*/
- omap_revision = OMAP3630_REV_ES1_2;
- omap_chip.oc |= CHIP_IS_OMAP3630ES1_2;
+ /* Unknown default to latest silicon rev as default */
+ omap_revision = OMAP3630_REV_ES1_2;
+ *cpu_rev = "1.2";
+ pr_warn("Warning: unknown chip type; assuming OMAP3630ES1.2\n");
}
}
@@ -382,24 +374,20 @@ static void __init omap4_check_revision(void)
switch (rev) {
case 0:
omap_revision = OMAP4430_REV_ES1_0;
- omap_chip.oc |= CHIP_IS_OMAP4430ES1;
break;
case 1:
default:
omap_revision = OMAP4430_REV_ES2_0;
- omap_chip.oc |= CHIP_IS_OMAP4430ES2;
}
break;
case 0xb95c:
switch (rev) {
case 3:
omap_revision = OMAP4430_REV_ES2_1;
- omap_chip.oc |= CHIP_IS_OMAP4430ES2_1;
break;
case 4:
default:
omap_revision = OMAP4430_REV_ES2_2;
- omap_chip.oc |= CHIP_IS_OMAP4430ES2_2;
}
break;
case 0xb94e:
@@ -407,14 +395,12 @@ static void __init omap4_check_revision(void)
case 0:
default:
omap_revision = OMAP4460_REV_ES1_0;
- omap_chip.oc |= CHIP_IS_OMAP4460ES1_0;
break;
}
break;
default:
/* Unknown default to latest silicon rev as default */
omap_revision = OMAP4430_REV_ES2_2;
- omap_chip.oc |= CHIP_IS_OMAP4430ES2_2;
}
pr_info("OMAP%04x ES%d.%d\n", omap_rev() >> 16,
@@ -425,94 +411,33 @@ static void __init omap4_check_revision(void)
if (omap3_has_ ##feat()) \
printk(#feat" ");
-static void __init omap3_cpuinfo(void)
+static void __init omap3_cpuinfo(const char *cpu_rev)
{
- u8 rev = GET_OMAP_REVISION();
- char cpu_name[16], cpu_rev[16];
+ const char *cpu_name;
- /* OMAP3430 and OMAP3530 are assumed to be same.
+ /*
+ * OMAP3430 and OMAP3530 are assumed to be same.
*
* OMAP3525, OMAP3515 and OMAP3503 can be detected only based
* on available features. Upon detection, update the CPU id
* and CPU class bits.
*/
if (cpu_is_omap3630()) {
- strcpy(cpu_name, "OMAP3630");
- } else if (cpu_is_omap3505()) {
- /*
- * AM35xx devices
- */
- if (omap3_has_sgx()) {
- omap_revision = OMAP3517_REV(rev);
- strcpy(cpu_name, "AM3517");
- } else {
- /* Already set in omap3_check_revision() */
- strcpy(cpu_name, "AM3505");
- }
+ cpu_name = "OMAP3630";
+ } else if (cpu_is_omap3517()) {
+ /* AM35xx devices */
+ cpu_name = (omap3_has_sgx()) ? "AM3517" : "AM3505";
} else if (cpu_is_ti816x()) {
- strcpy(cpu_name, "TI816X");
+ cpu_name = "TI816X";
} else if (omap3_has_iva() && omap3_has_sgx()) {
/* OMAP3430, OMAP3525, OMAP3515, OMAP3503 devices */
- strcpy(cpu_name, "OMAP3430/3530");
+ cpu_name = "OMAP3430/3530";
} else if (omap3_has_iva()) {
- omap_revision = OMAP3525_REV(rev);
- strcpy(cpu_name, "OMAP3525");
+ cpu_name = "OMAP3525";
} else if (omap3_has_sgx()) {
- omap_revision = OMAP3515_REV(rev);
- strcpy(cpu_name, "OMAP3515");
+ cpu_name = "OMAP3515";
} else {
- omap_revision = OMAP3503_REV(rev);
- strcpy(cpu_name, "OMAP3503");
- }
-
- if (cpu_is_omap3630() || cpu_is_ti816x()) {
- switch (rev) {
- case OMAP_REVBITS_00:
- strcpy(cpu_rev, "1.0");
- break;
- case OMAP_REVBITS_01:
- strcpy(cpu_rev, "1.1");
- break;
- case OMAP_REVBITS_02:
- /* FALLTHROUGH */
- default:
- /* Use the latest known revision as default */
- strcpy(cpu_rev, "1.2");
- }
- } else if (cpu_is_omap3505() || cpu_is_omap3517()) {
- switch (rev) {
- case OMAP_REVBITS_00:
- strcpy(cpu_rev, "1.0");
- break;
- case OMAP_REVBITS_01:
- /* FALLTHROUGH */
- default:
- /* Use the latest known revision as default */
- strcpy(cpu_rev, "1.1");
- }
- } else {
- switch (rev) {
- case OMAP_REVBITS_00:
- strcpy(cpu_rev, "1.0");
- break;
- case OMAP_REVBITS_01:
- strcpy(cpu_rev, "2.0");
- break;
- case OMAP_REVBITS_02:
- strcpy(cpu_rev, "2.1");
- break;
- case OMAP_REVBITS_03:
- strcpy(cpu_rev, "3.0");
- break;
- case OMAP_REVBITS_04:
- strcpy(cpu_rev, "3.1");
- break;
- case OMAP_REVBITS_05:
- /* FALLTHROUGH */
- default:
- /* Use the latest known revision as default */
- strcpy(cpu_rev, "3.1.2");
- }
+ cpu_name = "OMAP3503";
}
/* Print verbose information */
@@ -533,6 +458,8 @@ static void __init omap3_cpuinfo(void)
*/
void __init omap2_check_revision(void)
{
+ const char *cpu_rev;
+
/*
* At this point we have an idea about the processor revision set
* earlier with omap2_set_globals_tap().
@@ -540,7 +467,7 @@ void __init omap2_check_revision(void)
if (cpu_is_omap24xx()) {
omap24xx_check_revision();
} else if (cpu_is_omap34xx()) {
- omap3_check_revision();
+ omap3_check_revision(&cpu_rev);
/* TI816X doesn't have feature register */
if (!cpu_is_ti816x())
@@ -548,7 +475,7 @@ void __init omap2_check_revision(void)
else
ti816x_check_features();
- omap3_cpuinfo();
+ omap3_cpuinfo(cpu_rev);
return;
} else if (cpu_is_omap44xx()) {
omap4_check_revision();
@@ -557,22 +484,6 @@ void __init omap2_check_revision(void)
} else {
pr_err("OMAP revision unknown, please fix!\n");
}
-
- /*
- * OK, now we know the exact revision. Initialize omap_chip bits
- * for powerdowmain and clockdomain code.
- */
- if (cpu_is_omap243x()) {
- /* Currently only supports 2430ES2.1 and 2430-all */
- omap_chip.oc |= CHIP_IS_OMAP2430;
- return;
- } else if (cpu_is_omap242x()) {
- /* Currently only supports 2420ES2.1.1 and 2420-all */
- omap_chip.oc |= CHIP_IS_OMAP2420;
- return;
- }
-
- pr_err("Uninitialized omap_chip, please fix!\n");
}
/*
diff --git a/arch/arm/mach-omap2/io.c b/arch/arm/mach-omap2/io.c
index d6d01cb7f28a..f01273006e4d 100644
--- a/arch/arm/mach-omap2/io.c
+++ b/arch/arm/mach-omap2/io.c
@@ -37,6 +37,7 @@
#include "io.h"
#include <plat/omap-pm.h>
+#include "voltage.h"
#include "powerdomain.h"
#include "clockdomain.h"
@@ -341,18 +342,22 @@ void __init omap2_init_common_infrastructure(void)
u8 postsetup_state;
if (cpu_is_omap242x()) {
- omap2xxx_powerdomains_init();
- omap2xxx_clockdomains_init();
+ omap2xxx_voltagedomains_init();
+ omap242x_powerdomains_init();
+ omap242x_clockdomains_init();
omap2420_hwmod_init();
} else if (cpu_is_omap243x()) {
- omap2xxx_powerdomains_init();
- omap2xxx_clockdomains_init();
+ omap2xxx_voltagedomains_init();
+ omap243x_powerdomains_init();
+ omap243x_clockdomains_init();
omap2430_hwmod_init();
} else if (cpu_is_omap34xx()) {
+ omap3xxx_voltagedomains_init();
omap3xxx_powerdomains_init();
omap3xxx_clockdomains_init();
omap3xxx_hwmod_init();
} else if (cpu_is_omap44xx()) {
+ omap44xx_voltagedomains_init();
omap44xx_powerdomains_init();
omap44xx_clockdomains_init();
omap44xx_hwmod_init();
@@ -376,7 +381,7 @@ void __init omap2_init_common_infrastructure(void)
* omap_hwmod_late_init(), so boards that desire full watchdog
* coverage of kernel initialization can reprogram the
* postsetup_state between the calls to
- * omap2_init_common_infra() and omap2_init_common_devices().
+ * omap2_init_common_infra() and omap_sdrc_init().
*
* XXX ideally we could detect whether the MPU WDT was currently
* enabled here and make this conditional
@@ -400,7 +405,47 @@ void __init omap2_init_common_infrastructure(void)
pr_err("Could not init clock framework - unknown SoC\n");
}
-void __init omap2_init_common_devices(struct omap_sdrc_params *sdrc_cs0,
+void __init omap2420_init_early(void)
+{
+ omap2_init_common_infrastructure();
+}
+
+void __init omap2430_init_early(void)
+{
+ omap2_init_common_infrastructure();
+}
+
+void __init omap3430_init_early(void)
+{
+ omap2_init_common_infrastructure();
+}
+
+void __init omap35xx_init_early(void)
+{
+ omap2_init_common_infrastructure();
+}
+
+void __init omap3630_init_early(void)
+{
+ omap2_init_common_infrastructure();
+}
+
+void __init am35xx_init_early(void)
+{
+ omap2_init_common_infrastructure();
+}
+
+void __init ti816x_init_early(void)
+{
+ omap2_init_common_infrastructure();
+}
+
+void __init omap4430_init_early(void)
+{
+ omap2_init_common_infrastructure();
+}
+
+void __init omap_sdrc_init(struct omap_sdrc_params *sdrc_cs0,
struct omap_sdrc_params *sdrc_cs1)
{
if (cpu_is_omap24xx() || omap3_has_sdrc()) {
diff --git a/arch/arm/mach-omap2/irq.c b/arch/arm/mach-omap2/irq.c
index 3a12f7586a4c..65f1be6a182c 100644
--- a/arch/arm/mach-omap2/irq.c
+++ b/arch/arm/mach-omap2/irq.c
@@ -165,8 +165,8 @@ static void __init omap_init_irq(u32 base, int nr_irqs)
omap_irq_bank_init_one(bank);
- for (i = 0, j = 0; i < bank->nr_irqs; i += 32, j += 0x20)
- omap_alloc_gc(bank->base_reg + j, i, 32);
+ for (j = 0; j < bank->nr_irqs; j += 32)
+ omap_alloc_gc(bank->base_reg + j, j, 32);
nr_of_irqs += bank->nr_irqs;
nr_banks++;
diff --git a/arch/arm/mach-omap2/mcbsp.c b/arch/arm/mach-omap2/mcbsp.c
index 4a6ef6ab8458..292eee3be15f 100644
--- a/arch/arm/mach-omap2/mcbsp.c
+++ b/arch/arm/mach-omap2/mcbsp.c
@@ -27,66 +27,69 @@
#include "control.h"
-/* McBSP internal signal muxing functions */
+/*
+ * FIXME: Find a mechanism to enable/disable runtime the McBSP ICLK autoidle.
+ * Sidetone needs non-gated ICLK and sidetone autoidle is broken.
+ */
+#include "cm2xxx_3xxx.h"
+#include "cm-regbits-34xx.h"
-void omap2_mcbsp1_mux_clkr_src(u8 mux)
+/* McBSP internal signal muxing function */
+static int omap2_mcbsp1_mux_rx_clk(struct device *dev, const char *signal,
+ const char *src)
{
u32 v;
v = omap_ctrl_readl(OMAP2_CONTROL_DEVCONF0);
- if (mux == CLKR_SRC_CLKR)
- v &= ~OMAP2_MCBSP1_CLKR_MASK;
- else if (mux == CLKR_SRC_CLKX)
- v |= OMAP2_MCBSP1_CLKR_MASK;
- omap_ctrl_writel(v, OMAP2_CONTROL_DEVCONF0);
-}
-EXPORT_SYMBOL(omap2_mcbsp1_mux_clkr_src);
-void omap2_mcbsp1_mux_fsr_src(u8 mux)
-{
- u32 v;
+ if (!strcmp(signal, "clkr")) {
+ if (!strcmp(src, "clkr"))
+ v &= ~OMAP2_MCBSP1_CLKR_MASK;
+ else if (!strcmp(src, "clkx"))
+ v |= OMAP2_MCBSP1_CLKR_MASK;
+ else
+ return -EINVAL;
+ } else if (!strcmp(signal, "fsr")) {
+ if (!strcmp(src, "fsr"))
+ v &= ~OMAP2_MCBSP1_FSR_MASK;
+ else if (!strcmp(src, "fsx"))
+ v |= OMAP2_MCBSP1_FSR_MASK;
+ else
+ return -EINVAL;
+ } else {
+ return -EINVAL;
+ }
- v = omap_ctrl_readl(OMAP2_CONTROL_DEVCONF0);
- if (mux == FSR_SRC_FSR)
- v &= ~OMAP2_MCBSP1_FSR_MASK;
- else if (mux == FSR_SRC_FSX)
- v |= OMAP2_MCBSP1_FSR_MASK;
omap_ctrl_writel(v, OMAP2_CONTROL_DEVCONF0);
+
+ return 0;
}
-EXPORT_SYMBOL(omap2_mcbsp1_mux_fsr_src);
/* McBSP CLKS source switching function */
-
-int omap2_mcbsp_set_clks_src(u8 id, u8 fck_src_id)
+static int omap2_mcbsp_set_clk_src(struct device *dev, struct clk *clk,
+ const char *src)
{
- struct omap_mcbsp *mcbsp;
struct clk *fck_src;
char *fck_src_name;
int r;
- if (!omap_mcbsp_check_valid_id(id)) {
- pr_err("%s: Invalid id (%d)\n", __func__, id + 1);
- return -EINVAL;
- }
- mcbsp = id_to_mcbsp_ptr(id);
-
- if (fck_src_id == MCBSP_CLKS_PAD_SRC)
+ if (!strcmp(src, "clks_ext"))
fck_src_name = "pad_fck";
- else if (fck_src_id == MCBSP_CLKS_PRCM_SRC)
+ else if (!strcmp(src, "clks_fclk"))
fck_src_name = "prcm_fck";
else
return -EINVAL;
- fck_src = clk_get(mcbsp->dev, fck_src_name);
+ fck_src = clk_get(dev, fck_src_name);
if (IS_ERR_OR_NULL(fck_src)) {
pr_err("omap-mcbsp: %s: could not clk_get() %s\n", "clks",
fck_src_name);
return -EINVAL;
}
- pm_runtime_put_sync(mcbsp->dev);
+ pm_runtime_put_sync(dev);
- r = clk_set_parent(mcbsp->fclk, fck_src);
+ r = clk_set_parent(clk, fck_src);
if (IS_ERR_VALUE(r)) {
pr_err("omap-mcbsp: %s: could not clk_set_parent() to %s\n",
"clks", fck_src_name);
@@ -94,21 +97,30 @@ int omap2_mcbsp_set_clks_src(u8 id, u8 fck_src_id)
return -EINVAL;
}
- pm_runtime_get_sync(mcbsp->dev);
+ pm_runtime_get_sync(dev);
clk_put(fck_src);
return 0;
}
-EXPORT_SYMBOL(omap2_mcbsp_set_clks_src);
-struct omap_device_pm_latency omap2_mcbsp_latency[] = {
- {
- .deactivate_func = omap_device_idle_hwmods,
- .activate_func = omap_device_enable_hwmods,
- .flags = OMAP_DEVICE_LATENCY_AUTO_ADJUST,
- },
-};
+static int omap3_enable_st_clock(unsigned int id, bool enable)
+{
+ unsigned int w;
+
+ /*
+ * Sidetone uses McBSP ICLK - which must not idle when sidetones
+ * are enabled or sidetones start sounding ugly.
+ */
+ w = omap2_cm_read_mod_reg(OMAP3430_PER_MOD, CM_AUTOIDLE);
+ if (enable)
+ w &= ~(1 << (id - 2));
+ else
+ w |= 1 << (id - 2);
+ omap2_cm_write_mod_reg(w, OMAP3430_PER_MOD, CM_AUTOIDLE);
+
+ return 0;
+}
static int omap_init_mcbsp(struct omap_hwmod *oh, void *unused)
{
@@ -116,7 +128,7 @@ static int omap_init_mcbsp(struct omap_hwmod *oh, void *unused)
char *name = "omap-mcbsp";
struct omap_hwmod *oh_device[2];
struct omap_mcbsp_platform_data *pdata = NULL;
- struct omap_device *od;
+ struct platform_device *pdev;
sscanf(oh->name, "mcbsp%d", &id);
@@ -126,7 +138,13 @@ static int omap_init_mcbsp(struct omap_hwmod *oh, void *unused)
return -ENOMEM;
}
- pdata->mcbsp_config_type = oh->class->rev;
+ pdata->reg_step = 4;
+ if (oh->class->rev < MCBSP_CONFIG_TYPE2) {
+ pdata->reg_size = 2;
+ } else {
+ pdata->reg_size = 4;
+ pdata->has_ccr = true;
+ }
if (oh->class->rev == MCBSP_CONFIG_TYPE3) {
if (id == 2)
@@ -137,22 +155,28 @@ static int omap_init_mcbsp(struct omap_hwmod *oh, void *unused)
pdata->buffer_size = 0x80;
}
+ if (oh->class->rev >= MCBSP_CONFIG_TYPE3)
+ pdata->has_wakeup = true;
+
oh_device[0] = oh;
if (oh->dev_attr) {
oh_device[1] = omap_hwmod_lookup((
(struct omap_mcbsp_dev_attr *)(oh->dev_attr))->sidetone);
+ pdata->enable_st_clock = omap3_enable_st_clock;
count++;
}
- od = omap_device_build_ss(name, id, oh_device, count, pdata,
- sizeof(*pdata), omap2_mcbsp_latency,
- ARRAY_SIZE(omap2_mcbsp_latency), false);
+ pdev = omap_device_build_ss(name, id, oh_device, count, pdata,
+ sizeof(*pdata), NULL, 0, false);
kfree(pdata);
- if (IS_ERR(od)) {
+ if (IS_ERR(pdev)) {
pr_err("%s: Can't build omap_device for %s:%s.\n", __func__,
name, oh->name);
- return PTR_ERR(od);
+ return PTR_ERR(pdev);
}
+ pdata->set_clk_src = omap2_mcbsp_set_clk_src;
+ if (id == 1)
+ pdata->mux_signal = omap2_mcbsp1_mux_rx_clk;
omap_mcbsp_count++;
return 0;
}
diff --git a/arch/arm/mach-omap2/omap_hwmod.c b/arch/arm/mach-omap2/omap_hwmod.c
index 84cc0bdda3ae..d71380705080 100644
--- a/arch/arm/mach-omap2/omap_hwmod.c
+++ b/arch/arm/mach-omap2/omap_hwmod.c
@@ -1954,9 +1954,6 @@ int __init omap_hwmod_register(struct omap_hwmod **ohs)
i = 0;
do {
- if (!omap_chip_is(ohs[i]->omap_chip))
- continue;
-
r = _register(ohs[i]);
WARN(r, "omap_hwmod: %s: _register returned %d\n", ohs[i]->name,
r);
diff --git a/arch/arm/mach-omap2/omap_hwmod_2420_data.c b/arch/arm/mach-omap2/omap_hwmod_2420_data.c
index a015c69068f6..6d7206213525 100644
--- a/arch/arm/mach-omap2/omap_hwmod_2420_data.c
+++ b/arch/arm/mach-omap2/omap_hwmod_2420_data.c
@@ -100,7 +100,6 @@ static struct omap_hwmod omap2420_l3_main_hwmod = {
.masters_cnt = ARRAY_SIZE(omap2420_l3_main_masters),
.slaves = omap2420_l3_main_slaves,
.slaves_cnt = ARRAY_SIZE(omap2420_l3_main_slaves),
- .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP2420),
.flags = HWMOD_NO_IDLEST,
};
@@ -206,7 +205,6 @@ static struct omap_hwmod omap2420_l4_core_hwmod = {
.masters_cnt = ARRAY_SIZE(omap2420_l4_core_masters),
.slaves = omap2420_l4_core_slaves,
.slaves_cnt = ARRAY_SIZE(omap2420_l4_core_slaves),
- .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP2420),
.flags = HWMOD_NO_IDLEST,
};
@@ -227,7 +225,6 @@ static struct omap_hwmod omap2420_l4_wkup_hwmod = {
.masters_cnt = ARRAY_SIZE(omap2420_l4_wkup_masters),
.slaves = omap2420_l4_wkup_slaves,
.slaves_cnt = ARRAY_SIZE(omap2420_l4_wkup_slaves),
- .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP2420),
.flags = HWMOD_NO_IDLEST,
};
@@ -243,7 +240,6 @@ static struct omap_hwmod omap2420_mpu_hwmod = {
.main_clk = "mpu_ck",
.masters = omap2420_mpu_masters,
.masters_cnt = ARRAY_SIZE(omap2420_mpu_masters),
- .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP2420),
};
/*
@@ -271,7 +267,16 @@ static struct omap_hwmod omap2420_iva_hwmod = {
.class = &iva_hwmod_class,
.masters = omap2420_iva_masters,
.masters_cnt = ARRAY_SIZE(omap2420_iva_masters),
- .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP2420)
+};
+
+/* always-on timers dev attribute */
+static struct omap_timer_capability_dev_attr capability_alwon_dev_attr = {
+ .timer_capability = OMAP_TIMER_ALWON,
+};
+
+/* pwm timers dev attribute */
+static struct omap_timer_capability_dev_attr capability_pwm_dev_attr = {
+ .timer_capability = OMAP_TIMER_HAS_PWM,
};
/* timer1 */
@@ -314,10 +319,10 @@ static struct omap_hwmod omap2420_timer1_hwmod = {
.idlest_idle_bit = OMAP24XX_ST_GPT1_SHIFT,
},
},
+ .dev_attr = &capability_alwon_dev_attr,
.slaves = omap2420_timer1_slaves,
.slaves_cnt = ARRAY_SIZE(omap2420_timer1_slaves),
.class = &omap2xxx_timer_hwmod_class,
- .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP2420)
};
/* timer2 */
@@ -351,10 +356,10 @@ static struct omap_hwmod omap2420_timer2_hwmod = {
.idlest_idle_bit = OMAP24XX_ST_GPT2_SHIFT,
},
},
+ .dev_attr = &capability_alwon_dev_attr,
.slaves = omap2420_timer2_slaves,
.slaves_cnt = ARRAY_SIZE(omap2420_timer2_slaves),
.class = &omap2xxx_timer_hwmod_class,
- .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP2420)
};
/* timer3 */
@@ -388,10 +393,10 @@ static struct omap_hwmod omap2420_timer3_hwmod = {
.idlest_idle_bit = OMAP24XX_ST_GPT3_SHIFT,
},
},
+ .dev_attr = &capability_alwon_dev_attr,
.slaves = omap2420_timer3_slaves,
.slaves_cnt = ARRAY_SIZE(omap2420_timer3_slaves),
.class = &omap2xxx_timer_hwmod_class,
- .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP2420)
};
/* timer4 */
@@ -425,10 +430,10 @@ static struct omap_hwmod omap2420_timer4_hwmod = {
.idlest_idle_bit = OMAP24XX_ST_GPT4_SHIFT,
},
},
+ .dev_attr = &capability_alwon_dev_attr,
.slaves = omap2420_timer4_slaves,
.slaves_cnt = ARRAY_SIZE(omap2420_timer4_slaves),
.class = &omap2xxx_timer_hwmod_class,
- .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP2420)
};
/* timer5 */
@@ -462,10 +467,10 @@ static struct omap_hwmod omap2420_timer5_hwmod = {
.idlest_idle_bit = OMAP24XX_ST_GPT5_SHIFT,
},
},
+ .dev_attr = &capability_alwon_dev_attr,
.slaves = omap2420_timer5_slaves,
.slaves_cnt = ARRAY_SIZE(omap2420_timer5_slaves),
.class = &omap2xxx_timer_hwmod_class,
- .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP2420)
};
@@ -500,10 +505,10 @@ static struct omap_hwmod omap2420_timer6_hwmod = {
.idlest_idle_bit = OMAP24XX_ST_GPT6_SHIFT,
},
},
+ .dev_attr = &capability_alwon_dev_attr,
.slaves = omap2420_timer6_slaves,
.slaves_cnt = ARRAY_SIZE(omap2420_timer6_slaves),
.class = &omap2xxx_timer_hwmod_class,
- .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP2420)
};
/* timer7 */
@@ -537,10 +542,10 @@ static struct omap_hwmod omap2420_timer7_hwmod = {
.idlest_idle_bit = OMAP24XX_ST_GPT7_SHIFT,
},
},
+ .dev_attr = &capability_alwon_dev_attr,
.slaves = omap2420_timer7_slaves,
.slaves_cnt = ARRAY_SIZE(omap2420_timer7_slaves),
.class = &omap2xxx_timer_hwmod_class,
- .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP2420)
};
/* timer8 */
@@ -574,10 +579,10 @@ static struct omap_hwmod omap2420_timer8_hwmod = {
.idlest_idle_bit = OMAP24XX_ST_GPT8_SHIFT,
},
},
+ .dev_attr = &capability_alwon_dev_attr,
.slaves = omap2420_timer8_slaves,
.slaves_cnt = ARRAY_SIZE(omap2420_timer8_slaves),
.class = &omap2xxx_timer_hwmod_class,
- .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP2420)
};
/* timer9 */
@@ -611,10 +616,10 @@ static struct omap_hwmod omap2420_timer9_hwmod = {
.idlest_idle_bit = OMAP24XX_ST_GPT9_SHIFT,
},
},
+ .dev_attr = &capability_pwm_dev_attr,
.slaves = omap2420_timer9_slaves,
.slaves_cnt = ARRAY_SIZE(omap2420_timer9_slaves),
.class = &omap2xxx_timer_hwmod_class,
- .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP2420)
};
/* timer10 */
@@ -648,10 +653,10 @@ static struct omap_hwmod omap2420_timer10_hwmod = {
.idlest_idle_bit = OMAP24XX_ST_GPT10_SHIFT,
},
},
+ .dev_attr = &capability_pwm_dev_attr,
.slaves = omap2420_timer10_slaves,
.slaves_cnt = ARRAY_SIZE(omap2420_timer10_slaves),
.class = &omap2xxx_timer_hwmod_class,
- .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP2420)
};
/* timer11 */
@@ -685,10 +690,10 @@ static struct omap_hwmod omap2420_timer11_hwmod = {
.idlest_idle_bit = OMAP24XX_ST_GPT11_SHIFT,
},
},
+ .dev_attr = &capability_pwm_dev_attr,
.slaves = omap2420_timer11_slaves,
.slaves_cnt = ARRAY_SIZE(omap2420_timer11_slaves),
.class = &omap2xxx_timer_hwmod_class,
- .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP2420)
};
/* timer12 */
@@ -722,10 +727,10 @@ static struct omap_hwmod omap2420_timer12_hwmod = {
.idlest_idle_bit = OMAP24XX_ST_GPT12_SHIFT,
},
},
+ .dev_attr = &capability_pwm_dev_attr,
.slaves = omap2420_timer12_slaves,
.slaves_cnt = ARRAY_SIZE(omap2420_timer12_slaves),
.class = &omap2xxx_timer_hwmod_class,
- .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP2420)
};
/* l4_wkup -> wd_timer2 */
@@ -766,7 +771,6 @@ static struct omap_hwmod omap2420_wd_timer2_hwmod = {
},
.slaves = omap2420_wd_timer2_slaves,
.slaves_cnt = ARRAY_SIZE(omap2420_wd_timer2_slaves),
- .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP2420),
};
/* UART1 */
@@ -792,7 +796,6 @@ static struct omap_hwmod omap2420_uart1_hwmod = {
.slaves = omap2420_uart1_slaves,
.slaves_cnt = ARRAY_SIZE(omap2420_uart1_slaves),
.class = &omap2_uart_class,
- .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP2420),
};
/* UART2 */
@@ -818,7 +821,6 @@ static struct omap_hwmod omap2420_uart2_hwmod = {
.slaves = omap2420_uart2_slaves,
.slaves_cnt = ARRAY_SIZE(omap2420_uart2_slaves),
.class = &omap2_uart_class,
- .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP2420),
};
/* UART3 */
@@ -844,7 +846,6 @@ static struct omap_hwmod omap2420_uart3_hwmod = {
.slaves = omap2420_uart3_slaves,
.slaves_cnt = ARRAY_SIZE(omap2420_uart3_slaves),
.class = &omap2_uart_class,
- .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP2420),
};
/* dss */
@@ -898,7 +899,6 @@ static struct omap_hwmod omap2420_dss_core_hwmod = {
.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,
};
@@ -938,7 +938,6 @@ static struct omap_hwmod omap2420_dss_dispc_hwmod = {
},
.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,
};
@@ -975,7 +974,6 @@ static struct omap_hwmod omap2420_dss_rfbi_hwmod = {
},
.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,
};
@@ -1013,7 +1011,6 @@ static struct omap_hwmod omap2420_dss_venc_hwmod = {
},
.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,
};
@@ -1064,7 +1061,6 @@ static struct omap_hwmod omap2420_i2c1_hwmod = {
.slaves_cnt = ARRAY_SIZE(omap2420_i2c1_slaves),
.class = &i2c_class,
.dev_attr = &i2c_dev_attr,
- .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP2420),
.flags = HWMOD_16BIT_REG,
};
@@ -1092,7 +1088,6 @@ static struct omap_hwmod omap2420_i2c2_hwmod = {
.slaves_cnt = ARRAY_SIZE(omap2420_i2c2_slaves),
.class = &i2c_class,
.dev_attr = &i2c_dev_attr,
- .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP2420),
.flags = HWMOD_16BIT_REG,
};
@@ -1197,7 +1192,6 @@ static struct omap_hwmod omap2420_gpio1_hwmod = {
.slaves_cnt = ARRAY_SIZE(omap2420_gpio1_slaves),
.class = &omap2xxx_gpio_hwmod_class,
.dev_attr = &gpio_dev_attr,
- .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP2420),
};
/* gpio2 */
@@ -1223,7 +1217,6 @@ static struct omap_hwmod omap2420_gpio2_hwmod = {
.slaves_cnt = ARRAY_SIZE(omap2420_gpio2_slaves),
.class = &omap2xxx_gpio_hwmod_class,
.dev_attr = &gpio_dev_attr,
- .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP2420),
};
/* gpio3 */
@@ -1249,7 +1242,6 @@ static struct omap_hwmod omap2420_gpio3_hwmod = {
.slaves_cnt = ARRAY_SIZE(omap2420_gpio3_slaves),
.class = &omap2xxx_gpio_hwmod_class,
.dev_attr = &gpio_dev_attr,
- .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP2420),
};
/* gpio4 */
@@ -1275,7 +1267,6 @@ static struct omap_hwmod omap2420_gpio4_hwmod = {
.slaves_cnt = ARRAY_SIZE(omap2420_gpio4_slaves),
.class = &omap2xxx_gpio_hwmod_class,
.dev_attr = &gpio_dev_attr,
- .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP2420),
};
/* dma attributes */
@@ -1322,7 +1313,6 @@ static struct omap_hwmod omap2420_dma_system_hwmod = {
.masters = omap2420_dma_system_masters,
.masters_cnt = ARRAY_SIZE(omap2420_dma_system_masters),
.dev_attr = &dma_dev_attr,
- .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP2420),
.flags = HWMOD_NO_IDLEST,
};
@@ -1363,7 +1353,6 @@ static struct omap_hwmod omap2420_mailbox_hwmod = {
},
.slaves = omap2420_mailbox_slaves,
.slaves_cnt = ARRAY_SIZE(omap2420_mailbox_slaves),
- .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP2420),
};
/* mcspi1 */
@@ -1393,7 +1382,6 @@ static struct omap_hwmod omap2420_mcspi1_hwmod = {
.slaves_cnt = ARRAY_SIZE(omap2420_mcspi1_slaves),
.class = &omap2xxx_mcspi_class,
.dev_attr = &omap_mcspi1_dev_attr,
- .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP2420),
};
/* mcspi2 */
@@ -1423,7 +1411,6 @@ static struct omap_hwmod omap2420_mcspi2_hwmod = {
.slaves_cnt = ARRAY_SIZE(omap2420_mcspi2_slaves),
.class = &omap2xxx_mcspi_class,
.dev_attr = &omap_mcspi2_dev_attr,
- .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP2420),
};
/*
@@ -1473,7 +1460,6 @@ static struct omap_hwmod omap2420_mcbsp1_hwmod = {
},
.slaves = omap2420_mcbsp1_slaves,
.slaves_cnt = ARRAY_SIZE(omap2420_mcbsp1_slaves),
- .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP2420),
};
/* mcbsp2 */
@@ -1514,7 +1500,6 @@ static struct omap_hwmod omap2420_mcbsp2_hwmod = {
},
.slaves = omap2420_mcbsp2_slaves,
.slaves_cnt = ARRAY_SIZE(omap2420_mcbsp2_slaves),
- .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP2420),
};
static __initdata struct omap_hwmod *omap2420_hwmods[] = {
diff --git a/arch/arm/mach-omap2/omap_hwmod_2430_data.c b/arch/arm/mach-omap2/omap_hwmod_2430_data.c
index 408193d8e044..a2580d01c3ff 100644
--- a/arch/arm/mach-omap2/omap_hwmod_2430_data.c
+++ b/arch/arm/mach-omap2/omap_hwmod_2430_data.c
@@ -110,7 +110,6 @@ static struct omap_hwmod omap2430_l3_main_hwmod = {
.masters_cnt = ARRAY_SIZE(omap2430_l3_main_masters),
.slaves = omap2430_l3_main_slaves,
.slaves_cnt = ARRAY_SIZE(omap2430_l3_main_slaves),
- .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP2430),
.flags = HWMOD_NO_IDLEST,
};
@@ -250,7 +249,6 @@ static struct omap_hwmod omap2430_l4_core_hwmod = {
.masters_cnt = ARRAY_SIZE(omap2430_l4_core_masters),
.slaves = omap2430_l4_core_slaves,
.slaves_cnt = ARRAY_SIZE(omap2430_l4_core_slaves),
- .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP2430),
.flags = HWMOD_NO_IDLEST,
};
@@ -301,7 +299,6 @@ static struct omap_hwmod omap2430_l4_wkup_hwmod = {
.masters_cnt = ARRAY_SIZE(omap2430_l4_wkup_masters),
.slaves = omap2430_l4_wkup_slaves,
.slaves_cnt = ARRAY_SIZE(omap2430_l4_wkup_slaves),
- .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP2430),
.flags = HWMOD_NO_IDLEST,
};
@@ -317,7 +314,6 @@ static struct omap_hwmod omap2430_mpu_hwmod = {
.main_clk = "mpu_ck",
.masters = omap2430_mpu_masters,
.masters_cnt = ARRAY_SIZE(omap2430_mpu_masters),
- .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP2430),
};
/*
@@ -345,7 +341,16 @@ static struct omap_hwmod omap2430_iva_hwmod = {
.class = &iva_hwmod_class,
.masters = omap2430_iva_masters,
.masters_cnt = ARRAY_SIZE(omap2430_iva_masters),
- .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP2430)
+};
+
+/* always-on timers dev attribute */
+static struct omap_timer_capability_dev_attr capability_alwon_dev_attr = {
+ .timer_capability = OMAP_TIMER_ALWON,
+};
+
+/* pwm timers dev attribute */
+static struct omap_timer_capability_dev_attr capability_pwm_dev_attr = {
+ .timer_capability = OMAP_TIMER_HAS_PWM,
};
/* timer1 */
@@ -388,10 +393,10 @@ static struct omap_hwmod omap2430_timer1_hwmod = {
.idlest_idle_bit = OMAP24XX_ST_GPT1_SHIFT,
},
},
+ .dev_attr = &capability_alwon_dev_attr,
.slaves = omap2430_timer1_slaves,
.slaves_cnt = ARRAY_SIZE(omap2430_timer1_slaves),
.class = &omap2xxx_timer_hwmod_class,
- .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP2430)
};
/* timer2 */
@@ -425,10 +430,10 @@ static struct omap_hwmod omap2430_timer2_hwmod = {
.idlest_idle_bit = OMAP24XX_ST_GPT2_SHIFT,
},
},
+ .dev_attr = &capability_alwon_dev_attr,
.slaves = omap2430_timer2_slaves,
.slaves_cnt = ARRAY_SIZE(omap2430_timer2_slaves),
.class = &omap2xxx_timer_hwmod_class,
- .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP2430)
};
/* timer3 */
@@ -462,10 +467,10 @@ static struct omap_hwmod omap2430_timer3_hwmod = {
.idlest_idle_bit = OMAP24XX_ST_GPT3_SHIFT,
},
},
+ .dev_attr = &capability_alwon_dev_attr,
.slaves = omap2430_timer3_slaves,
.slaves_cnt = ARRAY_SIZE(omap2430_timer3_slaves),
.class = &omap2xxx_timer_hwmod_class,
- .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP2430)
};
/* timer4 */
@@ -499,10 +504,10 @@ static struct omap_hwmod omap2430_timer4_hwmod = {
.idlest_idle_bit = OMAP24XX_ST_GPT4_SHIFT,
},
},
+ .dev_attr = &capability_alwon_dev_attr,
.slaves = omap2430_timer4_slaves,
.slaves_cnt = ARRAY_SIZE(omap2430_timer4_slaves),
.class = &omap2xxx_timer_hwmod_class,
- .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP2430)
};
/* timer5 */
@@ -536,10 +541,10 @@ static struct omap_hwmod omap2430_timer5_hwmod = {
.idlest_idle_bit = OMAP24XX_ST_GPT5_SHIFT,
},
},
+ .dev_attr = &capability_alwon_dev_attr,
.slaves = omap2430_timer5_slaves,
.slaves_cnt = ARRAY_SIZE(omap2430_timer5_slaves),
.class = &omap2xxx_timer_hwmod_class,
- .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP2430)
};
/* timer6 */
@@ -573,10 +578,10 @@ static struct omap_hwmod omap2430_timer6_hwmod = {
.idlest_idle_bit = OMAP24XX_ST_GPT6_SHIFT,
},
},
+ .dev_attr = &capability_alwon_dev_attr,
.slaves = omap2430_timer6_slaves,
.slaves_cnt = ARRAY_SIZE(omap2430_timer6_slaves),
.class = &omap2xxx_timer_hwmod_class,
- .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP2430)
};
/* timer7 */
@@ -610,10 +615,10 @@ static struct omap_hwmod omap2430_timer7_hwmod = {
.idlest_idle_bit = OMAP24XX_ST_GPT7_SHIFT,
},
},
+ .dev_attr = &capability_alwon_dev_attr,
.slaves = omap2430_timer7_slaves,
.slaves_cnt = ARRAY_SIZE(omap2430_timer7_slaves),
.class = &omap2xxx_timer_hwmod_class,
- .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP2430)
};
/* timer8 */
@@ -647,10 +652,10 @@ static struct omap_hwmod omap2430_timer8_hwmod = {
.idlest_idle_bit = OMAP24XX_ST_GPT8_SHIFT,
},
},
+ .dev_attr = &capability_alwon_dev_attr,
.slaves = omap2430_timer8_slaves,
.slaves_cnt = ARRAY_SIZE(omap2430_timer8_slaves),
.class = &omap2xxx_timer_hwmod_class,
- .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP2430)
};
/* timer9 */
@@ -684,10 +689,10 @@ static struct omap_hwmod omap2430_timer9_hwmod = {
.idlest_idle_bit = OMAP24XX_ST_GPT9_SHIFT,
},
},
+ .dev_attr = &capability_pwm_dev_attr,
.slaves = omap2430_timer9_slaves,
.slaves_cnt = ARRAY_SIZE(omap2430_timer9_slaves),
.class = &omap2xxx_timer_hwmod_class,
- .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP2430)
};
/* timer10 */
@@ -721,10 +726,10 @@ static struct omap_hwmod omap2430_timer10_hwmod = {
.idlest_idle_bit = OMAP24XX_ST_GPT10_SHIFT,
},
},
+ .dev_attr = &capability_pwm_dev_attr,
.slaves = omap2430_timer10_slaves,
.slaves_cnt = ARRAY_SIZE(omap2430_timer10_slaves),
.class = &omap2xxx_timer_hwmod_class,
- .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP2430)
};
/* timer11 */
@@ -758,10 +763,10 @@ static struct omap_hwmod omap2430_timer11_hwmod = {
.idlest_idle_bit = OMAP24XX_ST_GPT11_SHIFT,
},
},
+ .dev_attr = &capability_pwm_dev_attr,
.slaves = omap2430_timer11_slaves,
.slaves_cnt = ARRAY_SIZE(omap2430_timer11_slaves),
.class = &omap2xxx_timer_hwmod_class,
- .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP2430)
};
/* timer12 */
@@ -795,10 +800,10 @@ static struct omap_hwmod omap2430_timer12_hwmod = {
.idlest_idle_bit = OMAP24XX_ST_GPT12_SHIFT,
},
},
+ .dev_attr = &capability_pwm_dev_attr,
.slaves = omap2430_timer12_slaves,
.slaves_cnt = ARRAY_SIZE(omap2430_timer12_slaves),
.class = &omap2xxx_timer_hwmod_class,
- .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP2430)
};
/* l4_wkup -> wd_timer2 */
@@ -839,7 +844,6 @@ static struct omap_hwmod omap2430_wd_timer2_hwmod = {
},
.slaves = omap2430_wd_timer2_slaves,
.slaves_cnt = ARRAY_SIZE(omap2430_wd_timer2_slaves),
- .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP2430),
};
/* UART1 */
@@ -865,7 +869,6 @@ static struct omap_hwmod omap2430_uart1_hwmod = {
.slaves = omap2430_uart1_slaves,
.slaves_cnt = ARRAY_SIZE(omap2430_uart1_slaves),
.class = &omap2_uart_class,
- .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP2430),
};
/* UART2 */
@@ -891,7 +894,6 @@ static struct omap_hwmod omap2430_uart2_hwmod = {
.slaves = omap2430_uart2_slaves,
.slaves_cnt = ARRAY_SIZE(omap2430_uart2_slaves),
.class = &omap2_uart_class,
- .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP2430),
};
/* UART3 */
@@ -917,7 +919,6 @@ static struct omap_hwmod omap2430_uart3_hwmod = {
.slaves = omap2430_uart3_slaves,
.slaves_cnt = ARRAY_SIZE(omap2430_uart3_slaves),
.class = &omap2_uart_class,
- .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP2430),
};
/* dss */
@@ -965,7 +966,6 @@ static struct omap_hwmod omap2430_dss_core_hwmod = {
.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,
};
@@ -999,7 +999,6 @@ static struct omap_hwmod omap2430_dss_dispc_hwmod = {
},
.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,
};
@@ -1030,7 +1029,6 @@ static struct omap_hwmod omap2430_dss_rfbi_hwmod = {
},
.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,
};
@@ -1062,7 +1060,6 @@ static struct omap_hwmod omap2430_dss_venc_hwmod = {
},
.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,
};
@@ -1123,7 +1120,6 @@ static struct omap_hwmod omap2430_i2c1_hwmod = {
.slaves_cnt = ARRAY_SIZE(omap2430_i2c1_slaves),
.class = &i2c_class,
.dev_attr = &i2c_dev_attr,
- .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP2430),
};
/* I2C2 */
@@ -1151,7 +1147,6 @@ static struct omap_hwmod omap2430_i2c2_hwmod = {
.slaves_cnt = ARRAY_SIZE(omap2430_i2c2_slaves),
.class = &i2c_class,
.dev_attr = &i2c_dev_attr,
- .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP2430),
};
/* l4_wkup -> gpio1 */
@@ -1273,7 +1268,6 @@ static struct omap_hwmod omap2430_gpio1_hwmod = {
.slaves_cnt = ARRAY_SIZE(omap2430_gpio1_slaves),
.class = &omap2xxx_gpio_hwmod_class,
.dev_attr = &gpio_dev_attr,
- .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP2430),
};
/* gpio2 */
@@ -1299,7 +1293,6 @@ static struct omap_hwmod omap2430_gpio2_hwmod = {
.slaves_cnt = ARRAY_SIZE(omap2430_gpio2_slaves),
.class = &omap2xxx_gpio_hwmod_class,
.dev_attr = &gpio_dev_attr,
- .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP2430),
};
/* gpio3 */
@@ -1325,7 +1318,6 @@ static struct omap_hwmod omap2430_gpio3_hwmod = {
.slaves_cnt = ARRAY_SIZE(omap2430_gpio3_slaves),
.class = &omap2xxx_gpio_hwmod_class,
.dev_attr = &gpio_dev_attr,
- .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP2430),
};
/* gpio4 */
@@ -1351,7 +1343,6 @@ static struct omap_hwmod omap2430_gpio4_hwmod = {
.slaves_cnt = ARRAY_SIZE(omap2430_gpio4_slaves),
.class = &omap2xxx_gpio_hwmod_class,
.dev_attr = &gpio_dev_attr,
- .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP2430),
};
/* gpio5 */
@@ -1382,7 +1373,6 @@ static struct omap_hwmod omap2430_gpio5_hwmod = {
.slaves_cnt = ARRAY_SIZE(omap2430_gpio5_slaves),
.class = &omap2xxx_gpio_hwmod_class,
.dev_attr = &gpio_dev_attr,
- .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP2430),
};
/* dma attributes */
@@ -1429,7 +1419,6 @@ static struct omap_hwmod omap2430_dma_system_hwmod = {
.masters = omap2430_dma_system_masters,
.masters_cnt = ARRAY_SIZE(omap2430_dma_system_masters),
.dev_attr = &dma_dev_attr,
- .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP2430),
.flags = HWMOD_NO_IDLEST,
};
@@ -1469,7 +1458,6 @@ static struct omap_hwmod omap2430_mailbox_hwmod = {
},
.slaves = omap2430_mailbox_slaves,
.slaves_cnt = ARRAY_SIZE(omap2430_mailbox_slaves),
- .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP2430),
};
/* mcspi1 */
@@ -1499,7 +1487,6 @@ static struct omap_hwmod omap2430_mcspi1_hwmod = {
.slaves_cnt = ARRAY_SIZE(omap2430_mcspi1_slaves),
.class = &omap2xxx_mcspi_class,
.dev_attr = &omap_mcspi1_dev_attr,
- .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP2430),
};
/* mcspi2 */
@@ -1529,7 +1516,6 @@ static struct omap_hwmod omap2430_mcspi2_hwmod = {
.slaves_cnt = ARRAY_SIZE(omap2430_mcspi2_slaves),
.class = &omap2xxx_mcspi_class,
.dev_attr = &omap_mcspi2_dev_attr,
- .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP2430),
};
/* mcspi3 */
@@ -1572,7 +1558,6 @@ static struct omap_hwmod omap2430_mcspi3_hwmod = {
.slaves_cnt = ARRAY_SIZE(omap2430_mcspi3_slaves),
.class = &omap2xxx_mcspi_class,
.dev_attr = &omap_mcspi3_dev_attr,
- .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP2430),
};
/*
@@ -1628,7 +1613,6 @@ static struct omap_hwmod omap2430_usbhsotg_hwmod = {
*/
.flags = HWMOD_NO_OCP_AUTOIDLE | HWMOD_SWSUP_SIDLE
| HWMOD_SWSUP_MSTANDBY,
- .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP2430)
};
/*
@@ -1689,7 +1673,6 @@ static struct omap_hwmod omap2430_mcbsp1_hwmod = {
},
.slaves = omap2430_mcbsp1_slaves,
.slaves_cnt = ARRAY_SIZE(omap2430_mcbsp1_slaves),
- .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP2430),
};
/* mcbsp2 */
@@ -1731,7 +1714,6 @@ static struct omap_hwmod omap2430_mcbsp2_hwmod = {
},
.slaves = omap2430_mcbsp2_slaves,
.slaves_cnt = ARRAY_SIZE(omap2430_mcbsp2_slaves),
- .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP2430),
};
/* mcbsp3 */
@@ -1783,7 +1765,6 @@ static struct omap_hwmod omap2430_mcbsp3_hwmod = {
},
.slaves = omap2430_mcbsp3_slaves,
.slaves_cnt = ARRAY_SIZE(omap2430_mcbsp3_slaves),
- .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP2430),
};
/* mcbsp4 */
@@ -1841,7 +1822,6 @@ static struct omap_hwmod omap2430_mcbsp4_hwmod = {
},
.slaves = omap2430_mcbsp4_slaves,
.slaves_cnt = ARRAY_SIZE(omap2430_mcbsp4_slaves),
- .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP2430),
};
/* mcbsp5 */
@@ -1899,7 +1879,6 @@ static struct omap_hwmod omap2430_mcbsp5_hwmod = {
},
.slaves = omap2430_mcbsp5_slaves,
.slaves_cnt = ARRAY_SIZE(omap2430_mcbsp5_slaves),
- .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP2430),
};
/* MMC/SD/SDIO common */
@@ -1966,7 +1945,6 @@ static struct omap_hwmod omap2430_mmc1_hwmod = {
.slaves = omap2430_mmc1_slaves,
.slaves_cnt = ARRAY_SIZE(omap2430_mmc1_slaves),
.class = &omap2430_mmc_class,
- .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP2430),
};
/* MMC/SD/SDIO2 */
@@ -2010,7 +1988,6 @@ static struct omap_hwmod omap2430_mmc2_hwmod = {
.slaves = omap2430_mmc2_slaves,
.slaves_cnt = ARRAY_SIZE(omap2430_mmc2_slaves),
.class = &omap2430_mmc_class,
- .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP2430),
};
static __initdata struct omap_hwmod *omap2430_hwmods[] = {
diff --git a/arch/arm/mach-omap2/omap_hwmod_3xxx_data.c b/arch/arm/mach-omap2/omap_hwmod_3xxx_data.c
index 25bf43b5a4ec..3008e1672c7a 100644
--- a/arch/arm/mach-omap2/omap_hwmod_3xxx_data.c
+++ b/arch/arm/mach-omap2/omap_hwmod_3xxx_data.c
@@ -156,7 +156,6 @@ static struct omap_hwmod omap3xxx_l3_main_hwmod = {
.masters_cnt = ARRAY_SIZE(omap3xxx_l3_main_masters),
.slaves = omap3xxx_l3_main_slaves,
.slaves_cnt = ARRAY_SIZE(omap3xxx_l3_main_slaves),
- .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP3430),
.flags = HWMOD_NO_IDLEST,
};
@@ -459,7 +458,6 @@ static struct omap_hwmod omap3xxx_l4_core_hwmod = {
.class = &l4_hwmod_class,
.slaves = omap3xxx_l4_core_slaves,
.slaves_cnt = ARRAY_SIZE(omap3xxx_l4_core_slaves),
- .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP3430),
.flags = HWMOD_NO_IDLEST,
};
@@ -474,7 +472,6 @@ static struct omap_hwmod omap3xxx_l4_per_hwmod = {
.class = &l4_hwmod_class,
.slaves = omap3xxx_l4_per_slaves,
.slaves_cnt = ARRAY_SIZE(omap3xxx_l4_per_slaves),
- .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP3430),
.flags = HWMOD_NO_IDLEST,
};
@@ -489,7 +486,6 @@ static struct omap_hwmod omap3xxx_l4_wkup_hwmod = {
.class = &l4_hwmod_class,
.slaves = omap3xxx_l4_wkup_slaves,
.slaves_cnt = ARRAY_SIZE(omap3xxx_l4_wkup_slaves),
- .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP3430),
.flags = HWMOD_NO_IDLEST,
};
@@ -505,7 +501,6 @@ static struct omap_hwmod omap3xxx_mpu_hwmod = {
.main_clk = "arm_fck",
.masters = omap3xxx_mpu_masters,
.masters_cnt = ARRAY_SIZE(omap3xxx_mpu_masters),
- .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP3430),
};
/*
@@ -533,7 +528,6 @@ static struct omap_hwmod omap3xxx_iva_hwmod = {
.class = &iva_hwmod_class,
.masters = omap3xxx_iva_masters,
.masters_cnt = ARRAY_SIZE(omap3xxx_iva_masters),
- .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP3430)
};
/* timer class */
@@ -570,6 +564,21 @@ static struct omap_hwmod_class omap3xxx_timer_hwmod_class = {
.rev = OMAP_TIMER_IP_VERSION_1,
};
+/* secure timers dev attribute */
+static struct omap_timer_capability_dev_attr capability_secure_dev_attr = {
+ .timer_capability = OMAP_TIMER_SECURE,
+};
+
+/* always-on timers dev attribute */
+static struct omap_timer_capability_dev_attr capability_alwon_dev_attr = {
+ .timer_capability = OMAP_TIMER_ALWON,
+};
+
+/* pwm timers dev attribute */
+static struct omap_timer_capability_dev_attr capability_pwm_dev_attr = {
+ .timer_capability = OMAP_TIMER_HAS_PWM,
+};
+
/* timer1 */
static struct omap_hwmod omap3xxx_timer1_hwmod;
@@ -610,10 +619,10 @@ static struct omap_hwmod omap3xxx_timer1_hwmod = {
.idlest_idle_bit = OMAP3430_ST_GPT1_SHIFT,
},
},
+ .dev_attr = &capability_alwon_dev_attr,
.slaves = omap3xxx_timer1_slaves,
.slaves_cnt = ARRAY_SIZE(omap3xxx_timer1_slaves),
.class = &omap3xxx_timer_1ms_hwmod_class,
- .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP3430)
};
/* timer2 */
@@ -656,10 +665,10 @@ static struct omap_hwmod omap3xxx_timer2_hwmod = {
.idlest_idle_bit = OMAP3430_ST_GPT2_SHIFT,
},
},
+ .dev_attr = &capability_alwon_dev_attr,
.slaves = omap3xxx_timer2_slaves,
.slaves_cnt = ARRAY_SIZE(omap3xxx_timer2_slaves),
.class = &omap3xxx_timer_1ms_hwmod_class,
- .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP3430)
};
/* timer3 */
@@ -702,10 +711,10 @@ static struct omap_hwmod omap3xxx_timer3_hwmod = {
.idlest_idle_bit = OMAP3430_ST_GPT3_SHIFT,
},
},
+ .dev_attr = &capability_alwon_dev_attr,
.slaves = omap3xxx_timer3_slaves,
.slaves_cnt = ARRAY_SIZE(omap3xxx_timer3_slaves),
.class = &omap3xxx_timer_hwmod_class,
- .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP3430)
};
/* timer4 */
@@ -748,10 +757,10 @@ static struct omap_hwmod omap3xxx_timer4_hwmod = {
.idlest_idle_bit = OMAP3430_ST_GPT4_SHIFT,
},
},
+ .dev_attr = &capability_alwon_dev_attr,
.slaves = omap3xxx_timer4_slaves,
.slaves_cnt = ARRAY_SIZE(omap3xxx_timer4_slaves),
.class = &omap3xxx_timer_hwmod_class,
- .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP3430)
};
/* timer5 */
@@ -794,10 +803,10 @@ static struct omap_hwmod omap3xxx_timer5_hwmod = {
.idlest_idle_bit = OMAP3430_ST_GPT5_SHIFT,
},
},
+ .dev_attr = &capability_alwon_dev_attr,
.slaves = omap3xxx_timer5_slaves,
.slaves_cnt = ARRAY_SIZE(omap3xxx_timer5_slaves),
.class = &omap3xxx_timer_hwmod_class,
- .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP3430)
};
/* timer6 */
@@ -840,10 +849,10 @@ static struct omap_hwmod omap3xxx_timer6_hwmod = {
.idlest_idle_bit = OMAP3430_ST_GPT6_SHIFT,
},
},
+ .dev_attr = &capability_alwon_dev_attr,
.slaves = omap3xxx_timer6_slaves,
.slaves_cnt = ARRAY_SIZE(omap3xxx_timer6_slaves),
.class = &omap3xxx_timer_hwmod_class,
- .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP3430)
};
/* timer7 */
@@ -886,10 +895,10 @@ static struct omap_hwmod omap3xxx_timer7_hwmod = {
.idlest_idle_bit = OMAP3430_ST_GPT7_SHIFT,
},
},
+ .dev_attr = &capability_alwon_dev_attr,
.slaves = omap3xxx_timer7_slaves,
.slaves_cnt = ARRAY_SIZE(omap3xxx_timer7_slaves),
.class = &omap3xxx_timer_hwmod_class,
- .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP3430)
};
/* timer8 */
@@ -932,10 +941,10 @@ static struct omap_hwmod omap3xxx_timer8_hwmod = {
.idlest_idle_bit = OMAP3430_ST_GPT8_SHIFT,
},
},
+ .dev_attr = &capability_pwm_dev_attr,
.slaves = omap3xxx_timer8_slaves,
.slaves_cnt = ARRAY_SIZE(omap3xxx_timer8_slaves),
.class = &omap3xxx_timer_hwmod_class,
- .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP3430)
};
/* timer9 */
@@ -978,10 +987,10 @@ static struct omap_hwmod omap3xxx_timer9_hwmod = {
.idlest_idle_bit = OMAP3430_ST_GPT9_SHIFT,
},
},
+ .dev_attr = &capability_pwm_dev_attr,
.slaves = omap3xxx_timer9_slaves,
.slaves_cnt = ARRAY_SIZE(omap3xxx_timer9_slaves),
.class = &omap3xxx_timer_hwmod_class,
- .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP3430)
};
/* timer10 */
@@ -1015,10 +1024,10 @@ static struct omap_hwmod omap3xxx_timer10_hwmod = {
.idlest_idle_bit = OMAP3430_ST_GPT10_SHIFT,
},
},
+ .dev_attr = &capability_pwm_dev_attr,
.slaves = omap3xxx_timer10_slaves,
.slaves_cnt = ARRAY_SIZE(omap3xxx_timer10_slaves),
.class = &omap3xxx_timer_1ms_hwmod_class,
- .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP3430)
};
/* timer11 */
@@ -1052,10 +1061,10 @@ static struct omap_hwmod omap3xxx_timer11_hwmod = {
.idlest_idle_bit = OMAP3430_ST_GPT11_SHIFT,
},
},
+ .dev_attr = &capability_pwm_dev_attr,
.slaves = omap3xxx_timer11_slaves,
.slaves_cnt = ARRAY_SIZE(omap3xxx_timer11_slaves),
.class = &omap3xxx_timer_hwmod_class,
- .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP3430)
};
/* timer12*/
@@ -1102,10 +1111,10 @@ static struct omap_hwmod omap3xxx_timer12_hwmod = {
.idlest_idle_bit = OMAP3430_ST_GPT12_SHIFT,
},
},
+ .dev_attr = &capability_secure_dev_attr,
.slaves = omap3xxx_timer12_slaves,
.slaves_cnt = ARRAY_SIZE(omap3xxx_timer12_slaves),
.class = &omap3xxx_timer_hwmod_class,
- .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP3430)
};
/* l4_wkup -> wd_timer2 */
@@ -1182,7 +1191,6 @@ static struct omap_hwmod omap3xxx_wd_timer2_hwmod = {
},
.slaves = omap3xxx_wd_timer2_slaves,
.slaves_cnt = ARRAY_SIZE(omap3xxx_wd_timer2_slaves),
- .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP3430),
/*
* XXX: Use software supervised mode, HW supervised smartidle seems to
* block CORE power domain idle transitions. Maybe a HW bug in wdt2?
@@ -1213,7 +1221,6 @@ static struct omap_hwmod omap3xxx_uart1_hwmod = {
.slaves = omap3xxx_uart1_slaves,
.slaves_cnt = ARRAY_SIZE(omap3xxx_uart1_slaves),
.class = &omap2_uart_class,
- .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP3430),
};
/* UART2 */
@@ -1239,7 +1246,6 @@ static struct omap_hwmod omap3xxx_uart2_hwmod = {
.slaves = omap3xxx_uart2_slaves,
.slaves_cnt = ARRAY_SIZE(omap3xxx_uart2_slaves),
.class = &omap2_uart_class,
- .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP3430),
};
/* UART3 */
@@ -1265,7 +1271,6 @@ static struct omap_hwmod omap3xxx_uart3_hwmod = {
.slaves = omap3xxx_uart3_slaves,
.slaves_cnt = ARRAY_SIZE(omap3xxx_uart3_slaves),
.class = &omap2_uart_class,
- .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP3430),
};
/* UART4 */
@@ -1302,7 +1307,6 @@ static struct omap_hwmod omap3xxx_uart4_hwmod = {
.slaves = omap3xxx_uart4_slaves,
.slaves_cnt = ARRAY_SIZE(omap3xxx_uart4_slaves),
.class = &omap2_uart_class,
- .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP3630ES1),
};
static struct omap_hwmod_class i2c_class = {
@@ -1390,7 +1394,6 @@ static struct omap_hwmod omap3430es1_dss_core_hwmod = {
.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,
};
@@ -1415,8 +1418,6 @@ static struct omap_hwmod omap3xxx_dss_core_hwmod = {
.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),
};
/* l4_core -> dss_dispc */
@@ -1454,9 +1455,6 @@ static struct omap_hwmod omap3xxx_dss_dispc_hwmod = {
},
.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,
};
@@ -1518,9 +1516,6 @@ static struct omap_hwmod omap3xxx_dss_dsi1_hwmod = {
},
.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,
};
@@ -1558,9 +1553,6 @@ static struct omap_hwmod omap3xxx_dss_rfbi_hwmod = {
},
.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,
};
@@ -1599,9 +1591,6 @@ static struct omap_hwmod omap3xxx_dss_venc_hwmod = {
},
.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,
};
@@ -1637,7 +1626,6 @@ static struct omap_hwmod omap3xxx_i2c1_hwmod = {
.slaves_cnt = ARRAY_SIZE(omap3xxx_i2c1_slaves),
.class = &i2c_class,
.dev_attr = &i2c1_dev_attr,
- .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP3430),
};
/* I2C2 */
@@ -1672,7 +1660,6 @@ static struct omap_hwmod omap3xxx_i2c2_hwmod = {
.slaves_cnt = ARRAY_SIZE(omap3xxx_i2c2_slaves),
.class = &i2c_class,
.dev_attr = &i2c2_dev_attr,
- .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP3430),
};
/* I2C3 */
@@ -1718,7 +1705,6 @@ static struct omap_hwmod omap3xxx_i2c3_hwmod = {
.slaves_cnt = ARRAY_SIZE(omap3xxx_i2c3_slaves),
.class = &i2c_class,
.dev_attr = &i2c3_dev_attr,
- .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP3430),
};
/* l4_wkup -> gpio1 */
@@ -1880,7 +1866,6 @@ static struct omap_hwmod omap3xxx_gpio1_hwmod = {
.slaves_cnt = ARRAY_SIZE(omap3xxx_gpio1_slaves),
.class = &omap3xxx_gpio_hwmod_class,
.dev_attr = &gpio_dev_attr,
- .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP3430),
};
/* gpio2 */
@@ -1912,7 +1897,6 @@ static struct omap_hwmod omap3xxx_gpio2_hwmod = {
.slaves_cnt = ARRAY_SIZE(omap3xxx_gpio2_slaves),
.class = &omap3xxx_gpio_hwmod_class,
.dev_attr = &gpio_dev_attr,
- .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP3430),
};
/* gpio3 */
@@ -1944,7 +1928,6 @@ static struct omap_hwmod omap3xxx_gpio3_hwmod = {
.slaves_cnt = ARRAY_SIZE(omap3xxx_gpio3_slaves),
.class = &omap3xxx_gpio_hwmod_class,
.dev_attr = &gpio_dev_attr,
- .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP3430),
};
/* gpio4 */
@@ -1976,7 +1959,6 @@ static struct omap_hwmod omap3xxx_gpio4_hwmod = {
.slaves_cnt = ARRAY_SIZE(omap3xxx_gpio4_slaves),
.class = &omap3xxx_gpio_hwmod_class,
.dev_attr = &gpio_dev_attr,
- .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP3430),
};
/* gpio5 */
@@ -2013,7 +1995,6 @@ static struct omap_hwmod omap3xxx_gpio5_hwmod = {
.slaves_cnt = ARRAY_SIZE(omap3xxx_gpio5_slaves),
.class = &omap3xxx_gpio_hwmod_class,
.dev_attr = &gpio_dev_attr,
- .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP3430),
};
/* gpio6 */
@@ -2050,7 +2031,6 @@ static struct omap_hwmod omap3xxx_gpio6_hwmod = {
.slaves_cnt = ARRAY_SIZE(omap3xxx_gpio6_slaves),
.class = &omap3xxx_gpio_hwmod_class,
.dev_attr = &gpio_dev_attr,
- .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP3430),
};
/* dma_system -> L3 */
@@ -2134,7 +2114,6 @@ static struct omap_hwmod omap3xxx_dma_system_hwmod = {
.masters = omap3xxx_dma_system_masters,
.masters_cnt = ARRAY_SIZE(omap3xxx_dma_system_masters),
.dev_attr = &dma_dev_attr,
- .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP3430),
.flags = HWMOD_NO_IDLEST,
};
@@ -2207,7 +2186,6 @@ static struct omap_hwmod omap3xxx_mcbsp1_hwmod = {
},
.slaves = omap3xxx_mcbsp1_slaves,
.slaves_cnt = ARRAY_SIZE(omap3xxx_mcbsp1_slaves),
- .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP3430),
};
/* mcbsp2 */
@@ -2264,7 +2242,6 @@ static struct omap_hwmod omap3xxx_mcbsp2_hwmod = {
.slaves = omap3xxx_mcbsp2_slaves,
.slaves_cnt = ARRAY_SIZE(omap3xxx_mcbsp2_slaves),
.dev_attr = &omap34xx_mcbsp2_dev_attr,
- .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP3430),
};
/* mcbsp3 */
@@ -2321,7 +2298,6 @@ static struct omap_hwmod omap3xxx_mcbsp3_hwmod = {
.slaves = omap3xxx_mcbsp3_slaves,
.slaves_cnt = ARRAY_SIZE(omap3xxx_mcbsp3_slaves),
.dev_attr = &omap34xx_mcbsp3_dev_attr,
- .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP3430),
};
/* mcbsp4 */
@@ -2379,7 +2355,6 @@ static struct omap_hwmod omap3xxx_mcbsp4_hwmod = {
},
.slaves = omap3xxx_mcbsp4_slaves,
.slaves_cnt = ARRAY_SIZE(omap3xxx_mcbsp4_slaves),
- .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP3430),
};
/* mcbsp5 */
@@ -2437,7 +2412,6 @@ static struct omap_hwmod omap3xxx_mcbsp5_hwmod = {
},
.slaves = omap3xxx_mcbsp5_slaves,
.slaves_cnt = ARRAY_SIZE(omap3xxx_mcbsp5_slaves),
- .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP3430),
};
/* 'mcbsp sidetone' class */
@@ -2498,7 +2472,6 @@ static struct omap_hwmod omap3xxx_mcbsp2_sidetone_hwmod = {
},
.slaves = omap3xxx_mcbsp2_sidetone_slaves,
.slaves_cnt = ARRAY_SIZE(omap3xxx_mcbsp2_sidetone_slaves),
- .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP3430),
};
/* mcbsp3_sidetone */
@@ -2547,7 +2520,6 @@ static struct omap_hwmod omap3xxx_mcbsp3_sidetone_hwmod = {
},
.slaves = omap3xxx_mcbsp3_sidetone_slaves,
.slaves_cnt = ARRAY_SIZE(omap3xxx_mcbsp3_sidetone_slaves),
- .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP3430),
};
@@ -2597,7 +2569,7 @@ static struct omap_hwmod omap34xx_sr1_hwmod = {
.name = "sr1_hwmod",
.class = &omap34xx_smartreflex_hwmod_class,
.main_clk = "sr1_fck",
- .vdd_name = "mpu",
+ .vdd_name = "mpu_iva",
.prcm = {
.omap2 = {
.prcm_reg_id = 1,
@@ -2609,9 +2581,6 @@ static struct omap_hwmod omap34xx_sr1_hwmod = {
},
.slaves = omap3_sr1_slaves,
.slaves_cnt = ARRAY_SIZE(omap3_sr1_slaves),
- .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP3430ES2 |
- CHIP_IS_OMAP3430ES3_0 |
- CHIP_IS_OMAP3430ES3_1),
.flags = HWMOD_SET_DEFAULT_CLOCKACT,
};
@@ -2619,7 +2588,7 @@ static struct omap_hwmod omap36xx_sr1_hwmod = {
.name = "sr1_hwmod",
.class = &omap36xx_smartreflex_hwmod_class,
.main_clk = "sr1_fck",
- .vdd_name = "mpu",
+ .vdd_name = "mpu_iva",
.prcm = {
.omap2 = {
.prcm_reg_id = 1,
@@ -2631,7 +2600,6 @@ static struct omap_hwmod omap36xx_sr1_hwmod = {
},
.slaves = omap3_sr1_slaves,
.slaves_cnt = ARRAY_SIZE(omap3_sr1_slaves),
- .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP3630ES1),
};
/* SR2 */
@@ -2655,9 +2623,6 @@ static struct omap_hwmod omap34xx_sr2_hwmod = {
},
.slaves = omap3_sr2_slaves,
.slaves_cnt = ARRAY_SIZE(omap3_sr2_slaves),
- .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP3430ES2 |
- CHIP_IS_OMAP3430ES3_0 |
- CHIP_IS_OMAP3430ES3_1),
.flags = HWMOD_SET_DEFAULT_CLOCKACT,
};
@@ -2677,7 +2642,6 @@ static struct omap_hwmod omap36xx_sr2_hwmod = {
},
.slaves = omap3_sr2_slaves,
.slaves_cnt = ARRAY_SIZE(omap3_sr2_slaves),
- .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP3630ES1),
};
/*
@@ -2745,7 +2709,6 @@ static struct omap_hwmod omap3xxx_mailbox_hwmod = {
},
.slaves = omap3xxx_mailbox_slaves,
.slaves_cnt = ARRAY_SIZE(omap3xxx_mailbox_slaves),
- .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP3430),
};
/* l4 core -> mcspi1 interface */
@@ -2843,7 +2806,6 @@ static struct omap_hwmod omap34xx_mcspi1 = {
.slaves_cnt = ARRAY_SIZE(omap34xx_mcspi1_slaves),
.class = &omap34xx_mcspi_class,
.dev_attr = &omap_mcspi1_dev_attr,
- .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP3430),
};
/* mcspi2 */
@@ -2873,7 +2835,6 @@ static struct omap_hwmod omap34xx_mcspi2 = {
.slaves_cnt = ARRAY_SIZE(omap34xx_mcspi2_slaves),
.class = &omap34xx_mcspi_class,
.dev_attr = &omap_mcspi2_dev_attr,
- .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP3430),
};
/* mcspi3 */
@@ -2916,7 +2877,6 @@ static struct omap_hwmod omap34xx_mcspi3 = {
.slaves_cnt = ARRAY_SIZE(omap34xx_mcspi3_slaves),
.class = &omap34xx_mcspi_class,
.dev_attr = &omap_mcspi3_dev_attr,
- .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP3430),
};
/* SPI4 */
@@ -2957,7 +2917,6 @@ static struct omap_hwmod omap34xx_mcspi4 = {
.slaves_cnt = ARRAY_SIZE(omap34xx_mcspi4_slaves),
.class = &omap34xx_mcspi_class,
.dev_attr = &omap_mcspi4_dev_attr,
- .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP3430),
};
/*
@@ -3014,7 +2973,6 @@ static struct omap_hwmod omap3xxx_usbhsotg_hwmod = {
*/
.flags = HWMOD_NO_OCP_AUTOIDLE | HWMOD_SWSUP_SIDLE
| HWMOD_SWSUP_MSTANDBY,
- .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP3430)
};
/* usb_otg_hs */
@@ -3042,7 +3000,6 @@ static struct omap_hwmod am35xx_usbhsotg_hwmod = {
.slaves = am35xx_usbhsotg_slaves,
.slaves_cnt = ARRAY_SIZE(am35xx_usbhsotg_slaves),
.class = &am35xx_usbotg_class,
- .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP3430ES3_1)
};
/* MMC/SD/SDIO common */
@@ -3108,7 +3065,6 @@ static struct omap_hwmod omap3xxx_mmc1_hwmod = {
.slaves = omap3xxx_mmc1_slaves,
.slaves_cnt = ARRAY_SIZE(omap3xxx_mmc1_slaves),
.class = &omap34xx_mmc_class,
- .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP3430),
};
/* MMC/SD/SDIO2 */
@@ -3151,7 +3107,6 @@ static struct omap_hwmod omap3xxx_mmc2_hwmod = {
.slaves = omap3xxx_mmc2_slaves,
.slaves_cnt = ARRAY_SIZE(omap3xxx_mmc2_slaves),
.class = &omap34xx_mmc_class,
- .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP3430),
};
/* MMC/SD/SDIO3 */
@@ -3193,7 +3148,6 @@ static struct omap_hwmod omap3xxx_mmc3_hwmod = {
.slaves = omap3xxx_mmc3_slaves,
.slaves_cnt = ARRAY_SIZE(omap3xxx_mmc3_slaves),
.class = &omap34xx_mmc_class,
- .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP3430),
};
static __initdata struct omap_hwmod *omap3xxx_hwmods[] = {
@@ -3224,10 +3178,7 @@ static __initdata struct omap_hwmod *omap3xxx_hwmods[] = {
&omap3xxx_uart1_hwmod,
&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,
@@ -3239,9 +3190,6 @@ static __initdata struct omap_hwmod *omap3xxx_hwmods[] = {
&omap3xxx_i2c3_hwmod,
&omap34xx_sr1_hwmod,
&omap34xx_sr2_hwmod,
- &omap36xx_sr1_hwmod,
- &omap36xx_sr2_hwmod,
-
/* gpio class */
&omap3xxx_gpio1_hwmod,
@@ -3272,16 +3220,96 @@ static __initdata struct omap_hwmod *omap3xxx_hwmods[] = {
&omap34xx_mcspi3,
&omap34xx_mcspi4,
- /* usbotg class */
+ NULL,
+};
+
+/* 3430ES1-only hwmods */
+static __initdata struct omap_hwmod *omap3430es1_hwmods[] = {
+ &omap3430es1_dss_core_hwmod,
+ NULL
+};
+
+/* 3430ES2+-only hwmods */
+static __initdata struct omap_hwmod *omap3430es2plus_hwmods[] = {
+ &omap3xxx_dss_core_hwmod,
&omap3xxx_usbhsotg_hwmod,
+ NULL
+};
- /* usbotg for am35x */
- &am35xx_usbhsotg_hwmod,
+/* 34xx-only hwmods (all ES revisions) */
+static __initdata struct omap_hwmod *omap34xx_hwmods[] = {
+ &omap34xx_sr1_hwmod,
+ &omap34xx_sr2_hwmod,
+ NULL
+};
- NULL,
+/* 36xx-only hwmods (all ES revisions) */
+static __initdata struct omap_hwmod *omap36xx_hwmods[] = {
+ &omap3xxx_uart4_hwmod,
+ &omap3xxx_dss_core_hwmod,
+ &omap36xx_sr1_hwmod,
+ &omap36xx_sr2_hwmod,
+ &omap3xxx_usbhsotg_hwmod,
+ NULL
+};
+
+static __initdata struct omap_hwmod *am35xx_hwmods[] = {
+ &omap3xxx_dss_core_hwmod, /* XXX ??? */
+ &am35xx_usbhsotg_hwmod,
+ NULL
};
int __init omap3xxx_hwmod_init(void)
{
- return omap_hwmod_register(omap3xxx_hwmods);
+ int r;
+ struct omap_hwmod **h = NULL;
+ unsigned int rev;
+
+ /* Register hwmods common to all OMAP3 */
+ r = omap_hwmod_register(omap3xxx_hwmods);
+ if (!r)
+ return r;
+
+ rev = omap_rev();
+
+ /*
+ * Register hwmods common to individual OMAP3 families, all
+ * silicon revisions (e.g., 34xx, or AM3505/3517, or 36xx)
+ * All possible revisions should be included in this conditional.
+ */
+ if (rev == OMAP3430_REV_ES1_0 || rev == OMAP3430_REV_ES2_0 ||
+ rev == OMAP3430_REV_ES2_1 || rev == OMAP3430_REV_ES3_0 ||
+ rev == OMAP3430_REV_ES3_1 || rev == OMAP3430_REV_ES3_1_2) {
+ h = omap34xx_hwmods;
+ } else if (rev == OMAP3517_REV_ES1_0 || rev == OMAP3517_REV_ES1_1) {
+ h = am35xx_hwmods;
+ } else if (rev == OMAP3630_REV_ES1_0 || rev == OMAP3630_REV_ES1_1 ||
+ rev == OMAP3630_REV_ES1_2) {
+ h = omap36xx_hwmods;
+ } else {
+ WARN(1, "OMAP3 hwmod family init: unknown chip type\n");
+ return -EINVAL;
+ };
+
+ r = omap_hwmod_register(h);
+ if (!r)
+ return r;
+
+ /*
+ * Register hwmods specific to certain ES levels of a
+ * particular family of silicon (e.g., 34xx ES1.0)
+ */
+ h = NULL;
+ if (rev == OMAP3430_REV_ES1_0) {
+ h = omap3430es1_hwmods;
+ } else if (rev == OMAP3430_REV_ES2_0 || rev == OMAP3430_REV_ES2_1 ||
+ rev == OMAP3430_REV_ES3_0 || rev == OMAP3430_REV_ES3_1 ||
+ rev == OMAP3430_REV_ES3_1_2) {
+ h = omap3430es2plus_hwmods;
+ };
+
+ if (h)
+ r = omap_hwmod_register(h);
+
+ return r;
}
diff --git a/arch/arm/mach-omap2/omap_hwmod_44xx_data.c b/arch/arm/mach-omap2/omap_hwmod_44xx_data.c
index 6201422c0606..393afac9caf6 100644
--- a/arch/arm/mach-omap2/omap_hwmod_44xx_data.c
+++ b/arch/arm/mach-omap2/omap_hwmod_44xx_data.c
@@ -29,6 +29,7 @@
#include <plat/mcbsp.h>
#include <plat/mmc.h>
#include <plat/i2c.h>
+#include <plat/dmtimer.h>
#include "omap_hwmod_common_data.h"
@@ -133,7 +134,6 @@ static struct omap_hwmod omap44xx_dmm_hwmod = {
.slaves = omap44xx_dmm_slaves,
.slaves_cnt = ARRAY_SIZE(omap44xx_dmm_slaves),
.mpu_irqs = omap44xx_dmm_irqs,
- .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430),
};
/*
@@ -189,7 +189,6 @@ static struct omap_hwmod omap44xx_emif_fw_hwmod = {
},
.slaves = omap44xx_emif_fw_slaves,
.slaves_cnt = ARRAY_SIZE(omap44xx_emif_fw_slaves),
- .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430),
};
/*
@@ -236,7 +235,6 @@ static struct omap_hwmod omap44xx_l3_instr_hwmod = {
},
.slaves = omap44xx_l3_instr_slaves,
.slaves_cnt = ARRAY_SIZE(omap44xx_l3_instr_slaves),
- .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430),
};
/* l3_main_1 */
@@ -336,7 +334,6 @@ static struct omap_hwmod omap44xx_l3_main_1_hwmod = {
},
.slaves = omap44xx_l3_main_1_slaves,
.slaves_cnt = ARRAY_SIZE(omap44xx_l3_main_1_slaves),
- .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430),
};
/* l3_main_2 */
@@ -438,7 +435,6 @@ static struct omap_hwmod omap44xx_l3_main_2_hwmod = {
},
.slaves = omap44xx_l3_main_2_slaves,
.slaves_cnt = ARRAY_SIZE(omap44xx_l3_main_2_slaves),
- .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430),
};
/* l3_main_3 */
@@ -496,7 +492,6 @@ static struct omap_hwmod omap44xx_l3_main_3_hwmod = {
},
.slaves = omap44xx_l3_main_3_slaves,
.slaves_cnt = ARRAY_SIZE(omap44xx_l3_main_3_slaves),
- .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430),
};
/*
@@ -559,7 +554,6 @@ static struct omap_hwmod omap44xx_l4_abe_hwmod = {
},
.slaves = omap44xx_l4_abe_slaves,
.slaves_cnt = ARRAY_SIZE(omap44xx_l4_abe_slaves),
- .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430),
};
/* l4_cfg */
@@ -588,7 +582,6 @@ static struct omap_hwmod omap44xx_l4_cfg_hwmod = {
},
.slaves = omap44xx_l4_cfg_slaves,
.slaves_cnt = ARRAY_SIZE(omap44xx_l4_cfg_slaves),
- .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430),
};
/* l4_per */
@@ -617,7 +610,6 @@ static struct omap_hwmod omap44xx_l4_per_hwmod = {
},
.slaves = omap44xx_l4_per_slaves,
.slaves_cnt = ARRAY_SIZE(omap44xx_l4_per_slaves),
- .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430),
};
/* l4_wkup */
@@ -646,7 +638,6 @@ static struct omap_hwmod omap44xx_l4_wkup_hwmod = {
},
.slaves = omap44xx_l4_wkup_slaves,
.slaves_cnt = ARRAY_SIZE(omap44xx_l4_wkup_slaves),
- .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430),
};
/*
@@ -677,7 +668,6 @@ static struct omap_hwmod omap44xx_mpu_private_hwmod = {
.clkdm_name = "mpuss_clkdm",
.slaves = omap44xx_mpu_private_slaves,
.slaves_cnt = ARRAY_SIZE(omap44xx_mpu_private_slaves),
- .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430),
};
/*
@@ -828,7 +818,6 @@ static struct omap_hwmod omap44xx_aess_hwmod = {
.slaves_cnt = ARRAY_SIZE(omap44xx_aess_slaves),
.masters = omap44xx_aess_masters,
.masters_cnt = ARRAY_SIZE(omap44xx_aess_masters),
- .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430),
};
/*
@@ -856,7 +845,6 @@ static struct omap_hwmod omap44xx_bandgap_hwmod = {
},
.opt_clks = bandgap_opt_clks,
.opt_clks_cnt = ARRAY_SIZE(bandgap_opt_clks),
- .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430),
};
/*
@@ -917,7 +905,6 @@ static struct omap_hwmod omap44xx_counter_32k_hwmod = {
},
.slaves = omap44xx_counter_32k_slaves,
.slaves_cnt = ARRAY_SIZE(omap44xx_counter_32k_slaves),
- .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430),
};
/*
@@ -1005,7 +992,6 @@ static struct omap_hwmod omap44xx_dma_system_hwmod = {
.slaves_cnt = ARRAY_SIZE(omap44xx_dma_system_slaves),
.masters = omap44xx_dma_system_masters,
.masters_cnt = ARRAY_SIZE(omap44xx_dma_system_masters),
- .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430),
};
/*
@@ -1098,7 +1084,6 @@ static struct omap_hwmod omap44xx_dmic_hwmod = {
},
.slaves = omap44xx_dmic_slaves,
.slaves_cnt = ARRAY_SIZE(omap44xx_dmic_slaves),
- .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430),
};
/*
@@ -1164,7 +1149,6 @@ static struct omap_hwmod omap44xx_dsp_c0_hwmod = {
.rstctrl_offs = OMAP4_RM_TESLA_RSTCTRL_OFFSET,
},
},
- .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430),
};
static struct omap_hwmod omap44xx_dsp_hwmod = {
@@ -1187,7 +1171,6 @@ static struct omap_hwmod omap44xx_dsp_hwmod = {
.slaves_cnt = ARRAY_SIZE(omap44xx_dsp_slaves),
.masters = omap44xx_dsp_masters,
.masters_cnt = ARRAY_SIZE(omap44xx_dsp_masters),
- .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430),
};
/*
@@ -1278,7 +1261,6 @@ static struct omap_hwmod omap44xx_dss_hwmod = {
.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),
};
/*
@@ -1381,7 +1363,6 @@ static struct omap_hwmod omap44xx_dss_dispc_hwmod = {
.opt_clks_cnt = ARRAY_SIZE(dss_dispc_opt_clks),
.slaves = omap44xx_dss_dispc_slaves,
.slaves_cnt = ARRAY_SIZE(omap44xx_dss_dispc_slaves),
- .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430),
};
/*
@@ -1480,7 +1461,6 @@ static struct omap_hwmod omap44xx_dss_dsi1_hwmod = {
.opt_clks_cnt = ARRAY_SIZE(dss_dsi1_opt_clks),
.slaves = omap44xx_dss_dsi1_slaves,
.slaves_cnt = ARRAY_SIZE(omap44xx_dss_dsi1_slaves),
- .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430),
};
/* dss_dsi2 */
@@ -1558,7 +1538,6 @@ static struct omap_hwmod omap44xx_dss_dsi2_hwmod = {
.opt_clks_cnt = ARRAY_SIZE(dss_dsi2_opt_clks),
.slaves = omap44xx_dss_dsi2_slaves,
.slaves_cnt = ARRAY_SIZE(omap44xx_dss_dsi2_slaves),
- .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430),
};
/*
@@ -1656,7 +1635,6 @@ static struct omap_hwmod omap44xx_dss_hdmi_hwmod = {
.opt_clks_cnt = ARRAY_SIZE(dss_hdmi_opt_clks),
.slaves = omap44xx_dss_hdmi_slaves,
.slaves_cnt = ARRAY_SIZE(omap44xx_dss_hdmi_slaves),
- .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430),
};
/*
@@ -1748,7 +1726,6 @@ static struct omap_hwmod omap44xx_dss_rfbi_hwmod = {
.opt_clks_cnt = ARRAY_SIZE(dss_rfbi_opt_clks),
.slaves = omap44xx_dss_rfbi_slaves,
.slaves_cnt = ARRAY_SIZE(omap44xx_dss_rfbi_slaves),
- .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430),
};
/*
@@ -1817,7 +1794,6 @@ static struct omap_hwmod omap44xx_dss_venc_hwmod = {
},
.slaves = omap44xx_dss_venc_slaves,
.slaves_cnt = ARRAY_SIZE(omap44xx_dss_venc_slaves),
- .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430),
};
/*
@@ -1901,7 +1877,6 @@ static struct omap_hwmod omap44xx_gpio1_hwmod = {
.dev_attr = &gpio_dev_attr,
.slaves = omap44xx_gpio1_slaves,
.slaves_cnt = ARRAY_SIZE(omap44xx_gpio1_slaves),
- .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430),
};
/* gpio2 */
@@ -1957,7 +1932,6 @@ static struct omap_hwmod omap44xx_gpio2_hwmod = {
.dev_attr = &gpio_dev_attr,
.slaves = omap44xx_gpio2_slaves,
.slaves_cnt = ARRAY_SIZE(omap44xx_gpio2_slaves),
- .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430),
};
/* gpio3 */
@@ -2013,7 +1987,6 @@ static struct omap_hwmod omap44xx_gpio3_hwmod = {
.dev_attr = &gpio_dev_attr,
.slaves = omap44xx_gpio3_slaves,
.slaves_cnt = ARRAY_SIZE(omap44xx_gpio3_slaves),
- .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430),
};
/* gpio4 */
@@ -2069,7 +2042,6 @@ static struct omap_hwmod omap44xx_gpio4_hwmod = {
.dev_attr = &gpio_dev_attr,
.slaves = omap44xx_gpio4_slaves,
.slaves_cnt = ARRAY_SIZE(omap44xx_gpio4_slaves),
- .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430),
};
/* gpio5 */
@@ -2125,7 +2097,6 @@ static struct omap_hwmod omap44xx_gpio5_hwmod = {
.dev_attr = &gpio_dev_attr,
.slaves = omap44xx_gpio5_slaves,
.slaves_cnt = ARRAY_SIZE(omap44xx_gpio5_slaves),
- .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430),
};
/* gpio6 */
@@ -2181,7 +2152,6 @@ static struct omap_hwmod omap44xx_gpio6_hwmod = {
.dev_attr = &gpio_dev_attr,
.slaves = omap44xx_gpio6_slaves,
.slaves_cnt = ARRAY_SIZE(omap44xx_gpio6_slaves),
- .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430),
};
/*
@@ -2261,7 +2231,6 @@ static struct omap_hwmod omap44xx_hsi_hwmod = {
.slaves_cnt = ARRAY_SIZE(omap44xx_hsi_slaves),
.masters = omap44xx_hsi_masters,
.masters_cnt = ARRAY_SIZE(omap44xx_hsi_masters),
- .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430),
};
/*
@@ -2345,7 +2314,6 @@ static struct omap_hwmod omap44xx_i2c1_hwmod = {
.slaves = omap44xx_i2c1_slaves,
.slaves_cnt = ARRAY_SIZE(omap44xx_i2c1_slaves),
.dev_attr = &i2c_dev_attr,
- .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430),
};
/* i2c2 */
@@ -2402,7 +2370,6 @@ static struct omap_hwmod omap44xx_i2c2_hwmod = {
.slaves = omap44xx_i2c2_slaves,
.slaves_cnt = ARRAY_SIZE(omap44xx_i2c2_slaves),
.dev_attr = &i2c_dev_attr,
- .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430),
};
/* i2c3 */
@@ -2459,7 +2426,6 @@ static struct omap_hwmod omap44xx_i2c3_hwmod = {
.slaves = omap44xx_i2c3_slaves,
.slaves_cnt = ARRAY_SIZE(omap44xx_i2c3_slaves),
.dev_attr = &i2c_dev_attr,
- .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430),
};
/* i2c4 */
@@ -2516,7 +2482,6 @@ static struct omap_hwmod omap44xx_i2c4_hwmod = {
.slaves = omap44xx_i2c4_slaves,
.slaves_cnt = ARRAY_SIZE(omap44xx_i2c4_slaves),
.dev_attr = &i2c_dev_attr,
- .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430),
};
/*
@@ -2577,7 +2542,6 @@ static struct omap_hwmod omap44xx_ipu_c0_hwmod = {
.rstctrl_offs = OMAP4_RM_DUCATI_RSTCTRL_OFFSET,
},
},
- .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430),
};
/* Pseudo hwmod for reset control purpose only */
@@ -2593,7 +2557,6 @@ static struct omap_hwmod omap44xx_ipu_c1_hwmod = {
.rstctrl_offs = OMAP4_RM_DUCATI_RSTCTRL_OFFSET,
},
},
- .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430),
};
static struct omap_hwmod omap44xx_ipu_hwmod = {
@@ -2616,7 +2579,6 @@ static struct omap_hwmod omap44xx_ipu_hwmod = {
.slaves_cnt = ARRAY_SIZE(omap44xx_ipu_slaves),
.masters = omap44xx_ipu_masters,
.masters_cnt = ARRAY_SIZE(omap44xx_ipu_masters),
- .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430),
};
/*
@@ -2706,7 +2668,6 @@ static struct omap_hwmod omap44xx_iss_hwmod = {
.slaves_cnt = ARRAY_SIZE(omap44xx_iss_slaves),
.masters = omap44xx_iss_masters,
.masters_cnt = ARRAY_SIZE(omap44xx_iss_masters),
- .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430),
};
/*
@@ -2781,7 +2742,6 @@ static struct omap_hwmod omap44xx_iva_seq0_hwmod = {
.rstctrl_offs = OMAP4_RM_IVAHD_RSTCTRL_OFFSET,
},
},
- .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430),
};
/* Pseudo hwmod for reset control purpose only */
@@ -2797,7 +2757,6 @@ static struct omap_hwmod omap44xx_iva_seq1_hwmod = {
.rstctrl_offs = OMAP4_RM_IVAHD_RSTCTRL_OFFSET,
},
},
- .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430),
};
static struct omap_hwmod omap44xx_iva_hwmod = {
@@ -2820,7 +2779,6 @@ static struct omap_hwmod omap44xx_iva_hwmod = {
.slaves_cnt = ARRAY_SIZE(omap44xx_iva_slaves),
.masters = omap44xx_iva_masters,
.masters_cnt = ARRAY_SIZE(omap44xx_iva_masters),
- .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430),
};
/*
@@ -2890,7 +2848,6 @@ static struct omap_hwmod omap44xx_kbd_hwmod = {
},
.slaves = omap44xx_kbd_slaves,
.slaves_cnt = ARRAY_SIZE(omap44xx_kbd_slaves),
- .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430),
};
/*
@@ -2956,7 +2913,6 @@ static struct omap_hwmod omap44xx_mailbox_hwmod = {
},
.slaves = omap44xx_mailbox_slaves,
.slaves_cnt = ARRAY_SIZE(omap44xx_mailbox_slaves),
- .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430),
};
/*
@@ -3051,7 +3007,6 @@ static struct omap_hwmod omap44xx_mcbsp1_hwmod = {
},
.slaves = omap44xx_mcbsp1_slaves,
.slaves_cnt = ARRAY_SIZE(omap44xx_mcbsp1_slaves),
- .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430),
};
/* mcbsp2 */
@@ -3127,7 +3082,6 @@ static struct omap_hwmod omap44xx_mcbsp2_hwmod = {
},
.slaves = omap44xx_mcbsp2_slaves,
.slaves_cnt = ARRAY_SIZE(omap44xx_mcbsp2_slaves),
- .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430),
};
/* mcbsp3 */
@@ -3203,7 +3157,6 @@ static struct omap_hwmod omap44xx_mcbsp3_hwmod = {
},
.slaves = omap44xx_mcbsp3_slaves,
.slaves_cnt = ARRAY_SIZE(omap44xx_mcbsp3_slaves),
- .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430),
};
/* mcbsp4 */
@@ -3258,7 +3211,6 @@ static struct omap_hwmod omap44xx_mcbsp4_hwmod = {
},
.slaves = omap44xx_mcbsp4_slaves,
.slaves_cnt = ARRAY_SIZE(omap44xx_mcbsp4_slaves),
- .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430),
};
/*
@@ -3353,7 +3305,6 @@ static struct omap_hwmod omap44xx_mcpdm_hwmod = {
},
.slaves = omap44xx_mcpdm_slaves,
.slaves_cnt = ARRAY_SIZE(omap44xx_mcpdm_slaves),
- .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430),
};
/*
@@ -3442,7 +3393,6 @@ static struct omap_hwmod omap44xx_mcspi1_hwmod = {
.dev_attr = &mcspi1_dev_attr,
.slaves = omap44xx_mcspi1_slaves,
.slaves_cnt = ARRAY_SIZE(omap44xx_mcspi1_slaves),
- .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430),
};
/* mcspi2 */
@@ -3505,7 +3455,6 @@ static struct omap_hwmod omap44xx_mcspi2_hwmod = {
.dev_attr = &mcspi2_dev_attr,
.slaves = omap44xx_mcspi2_slaves,
.slaves_cnt = ARRAY_SIZE(omap44xx_mcspi2_slaves),
- .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430),
};
/* mcspi3 */
@@ -3568,7 +3517,6 @@ static struct omap_hwmod omap44xx_mcspi3_hwmod = {
.dev_attr = &mcspi3_dev_attr,
.slaves = omap44xx_mcspi3_slaves,
.slaves_cnt = ARRAY_SIZE(omap44xx_mcspi3_slaves),
- .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430),
};
/* mcspi4 */
@@ -3629,7 +3577,6 @@ static struct omap_hwmod omap44xx_mcspi4_hwmod = {
.dev_attr = &mcspi4_dev_attr,
.slaves = omap44xx_mcspi4_slaves,
.slaves_cnt = ARRAY_SIZE(omap44xx_mcspi4_slaves),
- .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430),
};
/*
@@ -3718,7 +3665,6 @@ static struct omap_hwmod omap44xx_mmc1_hwmod = {
.slaves_cnt = ARRAY_SIZE(omap44xx_mmc1_slaves),
.masters = omap44xx_mmc1_masters,
.masters_cnt = ARRAY_SIZE(omap44xx_mmc1_masters),
- .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430),
};
/* mmc2 */
@@ -3779,7 +3725,6 @@ static struct omap_hwmod omap44xx_mmc2_hwmod = {
.slaves_cnt = ARRAY_SIZE(omap44xx_mmc2_slaves),
.masters = omap44xx_mmc2_masters,
.masters_cnt = ARRAY_SIZE(omap44xx_mmc2_masters),
- .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430),
};
/* mmc3 */
@@ -3834,7 +3779,6 @@ static struct omap_hwmod omap44xx_mmc3_hwmod = {
},
.slaves = omap44xx_mmc3_slaves,
.slaves_cnt = ARRAY_SIZE(omap44xx_mmc3_slaves),
- .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430),
};
/* mmc4 */
@@ -3890,7 +3834,6 @@ static struct omap_hwmod omap44xx_mmc4_hwmod = {
},
.slaves = omap44xx_mmc4_slaves,
.slaves_cnt = ARRAY_SIZE(omap44xx_mmc4_slaves),
- .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430),
};
/* mmc5 */
@@ -3945,7 +3888,6 @@ static struct omap_hwmod omap44xx_mmc5_hwmod = {
},
.slaves = omap44xx_mmc5_slaves,
.slaves_cnt = ARRAY_SIZE(omap44xx_mmc5_slaves),
- .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430),
};
/*
@@ -3987,7 +3929,6 @@ static struct omap_hwmod omap44xx_mpu_hwmod = {
},
.masters = omap44xx_mpu_masters,
.masters_cnt = ARRAY_SIZE(omap44xx_mpu_masters),
- .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430),
};
/*
@@ -4063,7 +4004,6 @@ static struct omap_hwmod omap44xx_smartreflex_core_hwmod = {
},
.slaves = omap44xx_smartreflex_core_slaves,
.slaves_cnt = ARRAY_SIZE(omap44xx_smartreflex_core_slaves),
- .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430),
};
/* smartreflex_iva */
@@ -4112,7 +4052,6 @@ static struct omap_hwmod omap44xx_smartreflex_iva_hwmod = {
},
.slaves = omap44xx_smartreflex_iva_slaves,
.slaves_cnt = ARRAY_SIZE(omap44xx_smartreflex_iva_slaves),
- .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430),
};
/* smartreflex_mpu */
@@ -4161,7 +4100,6 @@ static struct omap_hwmod omap44xx_smartreflex_mpu_hwmod = {
},
.slaves = omap44xx_smartreflex_mpu_slaves,
.slaves_cnt = ARRAY_SIZE(omap44xx_smartreflex_mpu_slaves),
- .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430),
};
/*
@@ -4224,7 +4162,6 @@ static struct omap_hwmod omap44xx_spinlock_hwmod = {
},
.slaves = omap44xx_spinlock_slaves,
.slaves_cnt = ARRAY_SIZE(omap44xx_spinlock_slaves),
- .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430),
};
/*
@@ -4265,6 +4202,16 @@ static struct omap_hwmod_class omap44xx_timer_hwmod_class = {
.sysc = &omap44xx_timer_sysc,
};
+/* always-on timers dev attribute */
+static struct omap_timer_capability_dev_attr capability_alwon_dev_attr = {
+ .timer_capability = OMAP_TIMER_ALWON,
+};
+
+/* pwm timers dev attribute */
+static struct omap_timer_capability_dev_attr capability_pwm_dev_attr = {
+ .timer_capability = OMAP_TIMER_HAS_PWM,
+};
+
/* timer1 */
static struct omap_hwmod omap44xx_timer1_hwmod;
static struct omap_hwmod_irq_info omap44xx_timer1_irqs[] = {
@@ -4308,9 +4255,9 @@ static struct omap_hwmod omap44xx_timer1_hwmod = {
.modulemode = MODULEMODE_SWCTRL,
},
},
+ .dev_attr = &capability_alwon_dev_attr,
.slaves = omap44xx_timer1_slaves,
.slaves_cnt = ARRAY_SIZE(omap44xx_timer1_slaves),
- .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430),
};
/* timer2 */
@@ -4356,9 +4303,9 @@ static struct omap_hwmod omap44xx_timer2_hwmod = {
.modulemode = MODULEMODE_SWCTRL,
},
},
+ .dev_attr = &capability_alwon_dev_attr,
.slaves = omap44xx_timer2_slaves,
.slaves_cnt = ARRAY_SIZE(omap44xx_timer2_slaves),
- .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430),
};
/* timer3 */
@@ -4404,9 +4351,9 @@ static struct omap_hwmod omap44xx_timer3_hwmod = {
.modulemode = MODULEMODE_SWCTRL,
},
},
+ .dev_attr = &capability_alwon_dev_attr,
.slaves = omap44xx_timer3_slaves,
.slaves_cnt = ARRAY_SIZE(omap44xx_timer3_slaves),
- .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430),
};
/* timer4 */
@@ -4452,9 +4399,9 @@ static struct omap_hwmod omap44xx_timer4_hwmod = {
.modulemode = MODULEMODE_SWCTRL,
},
},
+ .dev_attr = &capability_alwon_dev_attr,
.slaves = omap44xx_timer4_slaves,
.slaves_cnt = ARRAY_SIZE(omap44xx_timer4_slaves),
- .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430),
};
/* timer5 */
@@ -4519,9 +4466,9 @@ static struct omap_hwmod omap44xx_timer5_hwmod = {
.modulemode = MODULEMODE_SWCTRL,
},
},
+ .dev_attr = &capability_alwon_dev_attr,
.slaves = omap44xx_timer5_slaves,
.slaves_cnt = ARRAY_SIZE(omap44xx_timer5_slaves),
- .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430),
};
/* timer6 */
@@ -4587,9 +4534,9 @@ static struct omap_hwmod omap44xx_timer6_hwmod = {
.modulemode = MODULEMODE_SWCTRL,
},
},
+ .dev_attr = &capability_alwon_dev_attr,
.slaves = omap44xx_timer6_slaves,
.slaves_cnt = ARRAY_SIZE(omap44xx_timer6_slaves),
- .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430),
};
/* timer7 */
@@ -4654,9 +4601,9 @@ static struct omap_hwmod omap44xx_timer7_hwmod = {
.modulemode = MODULEMODE_SWCTRL,
},
},
+ .dev_attr = &capability_alwon_dev_attr,
.slaves = omap44xx_timer7_slaves,
.slaves_cnt = ARRAY_SIZE(omap44xx_timer7_slaves),
- .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430),
};
/* timer8 */
@@ -4721,9 +4668,9 @@ static struct omap_hwmod omap44xx_timer8_hwmod = {
.modulemode = MODULEMODE_SWCTRL,
},
},
+ .dev_attr = &capability_pwm_dev_attr,
.slaves = omap44xx_timer8_slaves,
.slaves_cnt = ARRAY_SIZE(omap44xx_timer8_slaves),
- .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430),
};
/* timer9 */
@@ -4769,9 +4716,9 @@ static struct omap_hwmod omap44xx_timer9_hwmod = {
.modulemode = MODULEMODE_SWCTRL,
},
},
+ .dev_attr = &capability_pwm_dev_attr,
.slaves = omap44xx_timer9_slaves,
.slaves_cnt = ARRAY_SIZE(omap44xx_timer9_slaves),
- .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430),
};
/* timer10 */
@@ -4817,9 +4764,9 @@ static struct omap_hwmod omap44xx_timer10_hwmod = {
.modulemode = MODULEMODE_SWCTRL,
},
},
+ .dev_attr = &capability_pwm_dev_attr,
.slaves = omap44xx_timer10_slaves,
.slaves_cnt = ARRAY_SIZE(omap44xx_timer10_slaves),
- .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430),
};
/* timer11 */
@@ -4865,9 +4812,9 @@ static struct omap_hwmod omap44xx_timer11_hwmod = {
.modulemode = MODULEMODE_SWCTRL,
},
},
+ .dev_attr = &capability_pwm_dev_attr,
.slaves = omap44xx_timer11_slaves,
.slaves_cnt = ARRAY_SIZE(omap44xx_timer11_slaves),
- .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430),
};
/*
@@ -4944,7 +4891,6 @@ static struct omap_hwmod omap44xx_uart1_hwmod = {
},
.slaves = omap44xx_uart1_slaves,
.slaves_cnt = ARRAY_SIZE(omap44xx_uart1_slaves),
- .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430),
};
/* uart2 */
@@ -4999,7 +4945,6 @@ static struct omap_hwmod omap44xx_uart2_hwmod = {
},
.slaves = omap44xx_uart2_slaves,
.slaves_cnt = ARRAY_SIZE(omap44xx_uart2_slaves),
- .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430),
};
/* uart3 */
@@ -5055,7 +5000,6 @@ static struct omap_hwmod omap44xx_uart3_hwmod = {
},
.slaves = omap44xx_uart3_slaves,
.slaves_cnt = ARRAY_SIZE(omap44xx_uart3_slaves),
- .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430),
};
/* uart4 */
@@ -5110,7 +5054,6 @@ static struct omap_hwmod omap44xx_uart4_hwmod = {
},
.slaves = omap44xx_uart4_slaves,
.slaves_cnt = ARRAY_SIZE(omap44xx_uart4_slaves),
- .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430),
};
/*
@@ -5195,7 +5138,6 @@ static struct omap_hwmod omap44xx_usb_otg_hs_hwmod = {
.slaves_cnt = ARRAY_SIZE(omap44xx_usb_otg_hs_slaves),
.masters = omap44xx_usb_otg_hs_masters,
.masters_cnt = ARRAY_SIZE(omap44xx_usb_otg_hs_masters),
- .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430),
};
/*
@@ -5266,7 +5208,6 @@ static struct omap_hwmod omap44xx_wd_timer2_hwmod = {
},
.slaves = omap44xx_wd_timer2_slaves,
.slaves_cnt = ARRAY_SIZE(omap44xx_wd_timer2_slaves),
- .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430),
};
/* wd_timer3 */
@@ -5333,7 +5274,6 @@ static struct omap_hwmod omap44xx_wd_timer3_hwmod = {
},
.slaves = omap44xx_wd_timer3_slaves,
.slaves_cnt = ARRAY_SIZE(omap44xx_wd_timer3_slaves),
- .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430),
};
static __initdata struct omap_hwmod *omap44xx_hwmods[] = {
diff --git a/arch/arm/mach-omap2/omap_l3_noc.c b/arch/arm/mach-omap2/omap_l3_noc.c
index 7b9f1909ddb2..c8b1bef92e5a 100644
--- a/arch/arm/mach-omap2/omap_l3_noc.c
+++ b/arch/arm/mach-omap2/omap_l3_noc.c
@@ -1,25 +1,25 @@
/*
- * OMAP4XXX L3 Interconnect error handling driver
- *
- * Copyright (C) 2011 Texas Corporation
- * Santosh Shilimkar <santosh.shilimkar@ti.com>
- * Sricharan <r.sricharan@ti.com>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
- * USA
- */
+ * OMAP4XXX L3 Interconnect error handling driver
+ *
+ * Copyright (C) 2011 Texas Corporation
+ * Santosh Shilimkar <santosh.shilimkar@ti.com>
+ * Sricharan <r.sricharan@ti.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
+ * USA
+ */
#include <linux/init.h>
#include <linux/io.h>
#include <linux/platform_device.h>
@@ -55,12 +55,12 @@
static irqreturn_t l3_interrupt_handler(int irq, void *_l3)
{
- struct omap4_l3 *l3 = _l3;
- int inttype, i, j;
+ struct omap4_l3 *l3 = _l3;
+ int inttype, i, k;
int err_src = 0;
- u32 std_err_main_addr, std_err_main, err_reg;
- u32 base, slave_addr, clear;
- char *source_name;
+ u32 std_err_main, err_reg, clear, masterid;
+ void __iomem *base, *l3_targ_base;
+ char *target_name, *master_name = "UN IDENTIFIED";
/* Get the Type of interrupt */
inttype = irq == l3->app_irq ? L3_APPLICATION_ERROR : L3_DEBUG_ERROR;
@@ -70,43 +70,50 @@ static irqreturn_t l3_interrupt_handler(int irq, void *_l3)
* Read the regerr register of the clock domain
* to determine the source
*/
- base = (u32)l3->l3_base[i];
- err_reg = readl(base + l3_flagmux[i] + (inttype << 3));
+ base = l3->l3_base[i];
+ err_reg = __raw_readl(base + l3_flagmux[i] +
+ + L3_FLAGMUX_REGERR0 + (inttype << 3));
/* Get the corresponding error and analyse */
if (err_reg) {
/* Identify the source from control status register */
- for (j = 0; !(err_reg & (1 << j)); j++)
- ;
+ err_src = __ffs(err_reg);
- err_src = j;
/* Read the stderrlog_main_source from clk domain */
- std_err_main_addr = base + *(l3_targ[i] + err_src);
- std_err_main = readl(std_err_main_addr);
+ l3_targ_base = base + *(l3_targ[i] + err_src);
+ std_err_main = __raw_readl(l3_targ_base +
+ L3_TARG_STDERRLOG_MAIN);
+ masterid = __raw_readl(l3_targ_base +
+ L3_TARG_STDERRLOG_MSTADDR);
switch (std_err_main & CUSTOM_ERROR) {
case STANDARD_ERROR:
- source_name =
- l3_targ_stderrlog_main_name[i][err_src];
-
- slave_addr = std_err_main_addr +
- L3_SLAVE_ADDRESS_OFFSET;
- WARN(true, "L3 standard error: SOURCE:%s at address 0x%x\n",
- source_name, readl(slave_addr));
+ target_name =
+ l3_targ_inst_name[i][err_src];
+ WARN(true, "L3 standard error: TARGET:%s at address 0x%x\n",
+ target_name,
+ __raw_readl(l3_targ_base +
+ L3_TARG_STDERRLOG_SLVOFSLSB));
/* clear the std error log*/
clear = std_err_main | CLEAR_STDERR_LOG;
- writel(clear, std_err_main_addr);
+ writel(clear, l3_targ_base +
+ L3_TARG_STDERRLOG_MAIN);
break;
case CUSTOM_ERROR:
- source_name =
- l3_targ_stderrlog_main_name[i][err_src];
-
- WARN(true, "CUSTOM SRESP error with SOURCE:%s\n",
- source_name);
+ target_name =
+ l3_targ_inst_name[i][err_src];
+ for (k = 0; k < NUM_OF_L3_MASTERS; k++) {
+ if (masterid == l3_masters[k].id)
+ master_name =
+ l3_masters[k].name;
+ }
+ WARN(true, "L3 custom error: MASTER:%s TARGET:%s\n",
+ master_name, target_name);
/* clear the std error log*/
clear = std_err_main | CLEAR_STDERR_LOG;
- writel(clear, std_err_main_addr);
+ writel(clear, l3_targ_base +
+ L3_TARG_STDERRLOG_MAIN);
break;
default:
@@ -120,12 +127,11 @@ static irqreturn_t l3_interrupt_handler(int irq, void *_l3)
return IRQ_HANDLED;
}
-static int __init omap4_l3_probe(struct platform_device *pdev)
+static int __devinit omap4_l3_probe(struct platform_device *pdev)
{
- static struct omap4_l3 *l3;
- struct resource *res;
- int ret;
- int irq;
+ static struct omap4_l3 *l3;
+ struct resource *res;
+ int ret;
l3 = kzalloc(sizeof(*l3), GFP_KERNEL);
if (!l3)
@@ -177,27 +183,25 @@ static int __init omap4_l3_probe(struct platform_device *pdev)
/*
* Setup interrupt Handlers
*/
- irq = platform_get_irq(pdev, 0);
- ret = request_irq(irq,
+ l3->debug_irq = platform_get_irq(pdev, 0);
+ ret = request_irq(l3->debug_irq,
l3_interrupt_handler,
IRQF_DISABLED, "l3-dbg-irq", l3);
if (ret) {
pr_crit("L3: request_irq failed to register for 0x%x\n",
- OMAP44XX_IRQ_L3_DBG);
+ OMAP44XX_IRQ_L3_DBG);
goto err3;
}
- l3->debug_irq = irq;
- irq = platform_get_irq(pdev, 1);
- ret = request_irq(irq,
+ l3->app_irq = platform_get_irq(pdev, 1);
+ ret = request_irq(l3->app_irq,
l3_interrupt_handler,
IRQF_DISABLED, "l3-app-irq", l3);
if (ret) {
pr_crit("L3: request_irq failed to register for 0x%x\n",
- OMAP44XX_IRQ_L3_APP);
+ OMAP44XX_IRQ_L3_APP);
goto err4;
}
- l3->app_irq = irq;
return 0;
@@ -214,9 +218,9 @@ err0:
return ret;
}
-static int __exit omap4_l3_remove(struct platform_device *pdev)
+static int __devexit omap4_l3_remove(struct platform_device *pdev)
{
- struct omap4_l3 *l3 = platform_get_drvdata(pdev);
+ struct omap4_l3 *l3 = platform_get_drvdata(pdev);
free_irq(l3->app_irq, l3);
free_irq(l3->debug_irq, l3);
@@ -228,16 +232,29 @@ static int __exit omap4_l3_remove(struct platform_device *pdev)
return 0;
}
+#if defined(CONFIG_OF)
+static const struct of_device_id l3_noc_match[] = {
+ {.compatible = "ti,omap4-l3-noc", },
+ {},
+}
+MODULE_DEVICE_TABLE(of, l3_noc_match);
+#else
+#define l3_noc_match NULL
+#endif
+
static struct platform_driver omap4_l3_driver = {
- .remove = __exit_p(omap4_l3_remove),
+ .probe = omap4_l3_probe,
+ .remove = __devexit_p(omap4_l3_remove),
.driver = {
- .name = "omap_l3_noc",
+ .name = "omap_l3_noc",
+ .owner = THIS_MODULE,
+ .of_match_table = l3_noc_match,
},
};
static int __init omap4_l3_init(void)
{
- return platform_driver_probe(&omap4_l3_driver, omap4_l3_probe);
+ return platform_driver_register(&omap4_l3_driver);
}
postcore_initcall_sync(omap4_l3_init);
diff --git a/arch/arm/mach-omap2/omap_l3_noc.h b/arch/arm/mach-omap2/omap_l3_noc.h
index 359b83348aed..90b50984cd2e 100644
--- a/arch/arm/mach-omap2/omap_l3_noc.h
+++ b/arch/arm/mach-omap2/omap_l3_noc.h
@@ -1,132 +1,162 @@
- /*
- * OMAP4XXX L3 Interconnect error handling driver header
- *
- * Copyright (C) 2011 Texas Corporation
- * Santosh Shilimkar <santosh.shilimkar@ti.com>
- * sricharan <r.sricharan@ti.com>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
- * USA
- */
+/*
+ * OMAP4XXX L3 Interconnect error handling driver header
+ *
+ * Copyright (C) 2011 Texas Corporation
+ * Santosh Shilimkar <santosh.shilimkar@ti.com>
+ * sricharan <r.sricharan@ti.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
+ * USA
+ */
#ifndef __ARCH_ARM_MACH_OMAP2_L3_INTERCONNECT_3XXX_H
#define __ARCH_ARM_MACH_OMAP2_L3_INTERCONNECT_3XXX_H
-/*
- * L3 register offsets
- */
#define L3_MODULES 3
#define CLEAR_STDERR_LOG (1 << 31)
#define CUSTOM_ERROR 0x2
#define STANDARD_ERROR 0x0
#define INBAND_ERROR 0x0
-#define EMIF_KERRLOG_OFFSET 0x10
-#define L3_SLAVE_ADDRESS_OFFSET 0x14
-#define LOGICAL_ADDR_ERRORLOG 0x4
#define L3_APPLICATION_ERROR 0x0
#define L3_DEBUG_ERROR 0x1
-u32 l3_flagmux[L3_MODULES] = {
- 0x50C,
- 0x100C,
- 0X020C
+/* L3 TARG register offsets */
+#define L3_TARG_STDERRLOG_MAIN 0x48
+#define L3_TARG_STDERRLOG_SLVOFSLSB 0x5c
+#define L3_TARG_STDERRLOG_MSTADDR 0x68
+#define L3_FLAGMUX_REGERR0 0xc
+
+#define NUM_OF_L3_MASTERS (sizeof(l3_masters)/sizeof(l3_masters[0]))
+
+static u32 l3_flagmux[L3_MODULES] = {
+ 0x500,
+ 0x1000,
+ 0X0200
};
-/*
- * L3 Target standard Error register offsets
- */
-u32 l3_targ_stderrlog_main_clk1[] = {
- 0x148, /* DMM1 */
- 0x248, /* DMM2 */
- 0x348, /* ABE */
- 0x448, /* L4CFG */
- 0x648 /* CLK2 PWR DISC */
+/* L3 Target standard Error register offsets */
+static u32 l3_targ_inst_clk1[] = {
+ 0x100, /* DMM1 */
+ 0x200, /* DMM2 */
+ 0x300, /* ABE */
+ 0x400, /* L4CFG */
+ 0x600 /* CLK2 PWR DISC */
};
-u32 l3_targ_stderrlog_main_clk2[] = {
- 0x548, /* CORTEX M3 */
- 0x348, /* DSS */
- 0x148, /* GPMC */
- 0x448, /* ISS */
- 0x748, /* IVAHD */
- 0xD48, /* missing in TRM corresponds to AES1*/
- 0x948, /* L4 PER0*/
- 0x248, /* OCMRAM */
- 0x148, /* missing in TRM corresponds to GPMC sERROR*/
- 0x648, /* SGX */
- 0x848, /* SL2 */
- 0x1648, /* C2C */
- 0x1148, /* missing in TRM corresponds PWR DISC CLK1*/
- 0xF48, /* missing in TRM corrsponds to SHA1*/
- 0xE48, /* missing in TRM corresponds to AES2*/
- 0xC48, /* L4 PER3 */
- 0xA48, /* L4 PER1*/
- 0xB48 /* L4 PER2*/
+static u32 l3_targ_inst_clk2[] = {
+ 0x500, /* CORTEX M3 */
+ 0x300, /* DSS */
+ 0x100, /* GPMC */
+ 0x400, /* ISS */
+ 0x700, /* IVAHD */
+ 0xD00, /* missing in TRM corresponds to AES1*/
+ 0x900, /* L4 PER0*/
+ 0x200, /* OCMRAM */
+ 0x100, /* missing in TRM corresponds to GPMC sERROR*/
+ 0x600, /* SGX */
+ 0x800, /* SL2 */
+ 0x1600, /* C2C */
+ 0x1100, /* missing in TRM corresponds PWR DISC CLK1*/
+ 0xF00, /* missing in TRM corrsponds to SHA1*/
+ 0xE00, /* missing in TRM corresponds to AES2*/
+ 0xC00, /* L4 PER3 */
+ 0xA00, /* L4 PER1*/
+ 0xB00 /* L4 PER2*/
};
-u32 l3_targ_stderrlog_main_clk3[] = {
- 0x0148 /* EMUSS */
+static u32 l3_targ_inst_clk3[] = {
+ 0x0100 /* EMUSS */
};
-char *l3_targ_stderrlog_main_name[L3_MODULES][18] = {
+static struct l3_masters_data {
+ u32 id;
+ char name[10];
+} l3_masters[] = {
+ { 0x0 , "MPU"},
+ { 0x10, "CS_ADP"},
+ { 0x14, "xxx"},
+ { 0x20, "DSP"},
+ { 0x30, "IVAHD"},
+ { 0x40, "ISS"},
+ { 0x44, "DucatiM3"},
+ { 0x48, "FaceDetect"},
+ { 0x50, "SDMA_Rd"},
+ { 0x54, "SDMA_Wr"},
+ { 0x58, "xxx"},
+ { 0x5C, "xxx"},
+ { 0x60, "SGX"},
+ { 0x70, "DSS"},
+ { 0x80, "C2C"},
+ { 0x88, "xxx"},
+ { 0x8C, "xxx"},
+ { 0x90, "HSI"},
+ { 0xA0, "MMC1"},
+ { 0xA4, "MMC2"},
+ { 0xA8, "MMC6"},
+ { 0xB0, "UNIPRO1"},
+ { 0xC0, "USBHOSTHS"},
+ { 0xC4, "USBOTGHS"},
+ { 0xC8, "USBHOSTFS"}
+};
+
+static char *l3_targ_inst_name[L3_MODULES][18] = {
{
- "DMM1",
- "DMM2",
- "ABE",
- "L4CFG",
- "CLK2 PWR DISC",
+ "DMM1",
+ "DMM2",
+ "ABE",
+ "L4CFG",
+ "CLK2 PWR DISC",
},
{
- "CORTEX M3" ,
- "DSS ",
- "GPMC ",
- "ISS ",
- "IVAHD ",
- "AES1",
- "L4 PER0",
- "OCMRAM ",
- "GPMC sERROR",
- "SGX ",
- "SL2 ",
- "C2C ",
- "PWR DISC CLK1",
- "SHA1",
- "AES2",
- "L4 PER3",
- "L4 PER1",
- "L4 PER2",
+ "CORTEX M3" ,
+ "DSS ",
+ "GPMC ",
+ "ISS ",
+ "IVAHD ",
+ "AES1",
+ "L4 PER0",
+ "OCMRAM ",
+ "GPMC sERROR",
+ "SGX ",
+ "SL2 ",
+ "C2C ",
+ "PWR DISC CLK1",
+ "SHA1",
+ "AES2",
+ "L4 PER3",
+ "L4 PER1",
+ "L4 PER2",
},
{
- "EMUSS",
+ "EMUSS",
},
};
-u32 *l3_targ[L3_MODULES] = {
- l3_targ_stderrlog_main_clk1,
- l3_targ_stderrlog_main_clk2,
- l3_targ_stderrlog_main_clk3,
+static u32 *l3_targ[L3_MODULES] = {
+ l3_targ_inst_clk1,
+ l3_targ_inst_clk2,
+ l3_targ_inst_clk3,
};
struct omap4_l3 {
- struct device *dev;
- struct clk *ick;
+ struct device *dev;
+ struct clk *ick;
/* memory base */
- void __iomem *l3_base[4];
+ void __iomem *l3_base[L3_MODULES];
- int debug_irq;
- int app_irq;
+ int debug_irq;
+ int app_irq;
};
-
#endif
diff --git a/arch/arm/mach-omap2/omap_l3_smx.c b/arch/arm/mach-omap2/omap_l3_smx.c
index 873c0e33b512..a05a62f9ee5b 100644
--- a/arch/arm/mach-omap2/omap_l3_smx.c
+++ b/arch/arm/mach-omap2/omap_l3_smx.c
@@ -1,26 +1,26 @@
- /*
- * OMAP3XXX L3 Interconnect Driver
- *
- * Copyright (C) 2011 Texas Corporation
- * Felipe Balbi <balbi@ti.com>
- * Santosh Shilimkar <santosh.shilimkar@ti.com>
- * Sricharan <r.sricharan@ti.com>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
- * USA
- */
+/*
+ * OMAP3XXX L3 Interconnect Driver
+ *
+ * Copyright (C) 2011 Texas Corporation
+ * Felipe Balbi <balbi@ti.com>
+ * Santosh Shilimkar <santosh.shilimkar@ti.com>
+ * Sricharan <r.sricharan@ti.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
+ * USA
+ */
#include <linux/kernel.h>
#include <linux/slab.h>
@@ -135,7 +135,7 @@ static char *omap3_l3_initiator_string(u8 initid)
}
}
-/**
+/*
* omap3_l3_block_irq - handles a register block's irq
* @l3: struct omap3_l3 *
* @base: register block base address
@@ -150,30 +150,29 @@ static char *omap3_l3_initiator_string(u8 initid)
static irqreturn_t omap3_l3_block_irq(struct omap3_l3 *l3,
u64 error, int error_addr)
{
- u8 code = omap3_l3_decode_error_code(error);
- u8 initid = omap3_l3_decode_initid(error);
- u8 multi = error & L3_ERROR_LOG_MULTI;
- u32 address = omap3_l3_decode_addr(error_addr);
+ u8 code = omap3_l3_decode_error_code(error);
+ u8 initid = omap3_l3_decode_initid(error);
+ u8 multi = error & L3_ERROR_LOG_MULTI;
+ u32 address = omap3_l3_decode_addr(error_addr);
WARN(true, "%s seen by %s %s at address %x\n",
- omap3_l3_code_string(code),
- omap3_l3_initiator_string(initid),
- multi ? "Multiple Errors" : "",
- address);
+ omap3_l3_code_string(code),
+ omap3_l3_initiator_string(initid),
+ multi ? "Multiple Errors" : "", address);
return IRQ_HANDLED;
}
static irqreturn_t omap3_l3_app_irq(int irq, void *_l3)
{
- struct omap3_l3 *l3 = _l3;
- u64 status, clear;
- u64 error;
- u64 error_addr;
- u64 err_source = 0;
- void __iomem *base;
- int int_type;
- irqreturn_t ret = IRQ_NONE;
+ struct omap3_l3 *l3 = _l3;
+ u64 status, clear;
+ u64 error;
+ u64 error_addr;
+ u64 err_source = 0;
+ void __iomem *base;
+ int int_type;
+ irqreturn_t ret = IRQ_NONE;
int_type = irq == l3->app_irq ? L3_APPLICATION_ERROR : L3_DEBUG_ERROR;
if (!int_type) {
@@ -191,14 +190,12 @@ static irqreturn_t omap3_l3_app_irq(int irq, void *_l3)
}
/* identify the error source */
- for (err_source = 0; !(status & (1 << err_source)); err_source++)
- ;
+ err_source = __ffs(status);
- base = l3->rt + *(omap3_l3_bases[int_type] + err_source);
+ base = l3->rt + omap3_l3_bases[int_type][err_source];
error = omap3_l3_readll(base, L3_ERROR_LOG);
if (error) {
error_addr = omap3_l3_readll(base, L3_ERROR_LOG_ADDR);
-
ret |= omap3_l3_block_irq(l3, error, error_addr);
}
@@ -215,9 +212,9 @@ static irqreturn_t omap3_l3_app_irq(int irq, void *_l3)
static int __init omap3_l3_probe(struct platform_device *pdev)
{
- struct omap3_l3 *l3;
- struct resource *res;
- int ret;
+ struct omap3_l3 *l3;
+ struct resource *res;
+ int ret;
l3 = kzalloc(sizeof(*l3), GFP_KERNEL);
if (!l3)
diff --git a/arch/arm/mach-omap2/omap_l3_smx.h b/arch/arm/mach-omap2/omap_l3_smx.h
index ba2ed9a850cc..4f3cebca4179 100644
--- a/arch/arm/mach-omap2/omap_l3_smx.h
+++ b/arch/arm/mach-omap2/omap_l3_smx.h
@@ -1,26 +1,26 @@
- /*
- * OMAP3XXX L3 Interconnect Driver header
- *
- * Copyright (C) 2011 Texas Corporation
- * Felipe Balbi <balbi@ti.com>
- * Santosh Shilimkar <santosh.shilimkar@ti.com>
- * sricharan <r.sricharan@ti.com>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
- * USA
- */
+/*
+ * OMAP3XXX L3 Interconnect Driver header
+ *
+ * Copyright (C) 2011 Texas Corporation
+ * Felipe Balbi <balbi@ti.com>
+ * Santosh Shilimkar <santosh.shilimkar@ti.com>
+ * sricharan <r.sricharan@ti.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
+ * USA
+ */
#ifndef __ARCH_ARM_MACH_OMAP2_L3_INTERCONNECT_3XXX_H
#define __ARCH_ARM_MACH_OMAP2_L3_INTERCONNECT_3XXX_H
@@ -40,7 +40,7 @@
#define L3_SI_CONTROL 0x020
#define L3_SI_FLAG_STATUS_0 0x510
-const u64 shift = 1;
+static const u64 shift = 1;
#define L3_STATUS_0_MPUIA_BRST (shift << 0)
#define L3_STATUS_0_MPUIA_RSP (shift << 1)
@@ -78,32 +78,32 @@ const u64 shift = 1;
#define L3_STATUS_0_L4EMUTA_REQ (shift << 60)
#define L3_STATUS_0_MAD2DTA_REQ (shift << 61)
-#define L3_STATUS_0_TIMEOUT_MASK (L3_STATUS_0_MPUIA_BRST \
- | L3_STATUS_0_MPUIA_RSP \
- | L3_STATUS_0_IVAIA_BRST \
- | L3_STATUS_0_IVAIA_RSP \
- | L3_STATUS_0_SGXIA_BRST \
- | L3_STATUS_0_SGXIA_RSP \
- | L3_STATUS_0_CAMIA_BRST \
- | L3_STATUS_0_CAMIA_RSP \
- | L3_STATUS_0_DISPIA_BRST \
- | L3_STATUS_0_DISPIA_RSP \
- | L3_STATUS_0_DMARDIA_BRST \
- | L3_STATUS_0_DMARDIA_RSP \
- | L3_STATUS_0_DMAWRIA_BRST \
- | L3_STATUS_0_DMAWRIA_RSP \
- | L3_STATUS_0_USBOTGIA_BRST \
- | L3_STATUS_0_USBOTGIA_RSP \
- | L3_STATUS_0_USBHOSTIA_BRST \
- | L3_STATUS_0_SMSTA_REQ \
- | L3_STATUS_0_GPMCTA_REQ \
- | L3_STATUS_0_OCMRAMTA_REQ \
- | L3_STATUS_0_OCMROMTA_REQ \
- | L3_STATUS_0_IVATA_REQ \
- | L3_STATUS_0_SGXTA_REQ \
- | L3_STATUS_0_L4CORETA_REQ \
- | L3_STATUS_0_L4PERTA_REQ \
- | L3_STATUS_0_L4EMUTA_REQ \
+#define L3_STATUS_0_TIMEOUT_MASK (L3_STATUS_0_MPUIA_BRST \
+ | L3_STATUS_0_MPUIA_RSP \
+ | L3_STATUS_0_IVAIA_BRST \
+ | L3_STATUS_0_IVAIA_RSP \
+ | L3_STATUS_0_SGXIA_BRST \
+ | L3_STATUS_0_SGXIA_RSP \
+ | L3_STATUS_0_CAMIA_BRST \
+ | L3_STATUS_0_CAMIA_RSP \
+ | L3_STATUS_0_DISPIA_BRST \
+ | L3_STATUS_0_DISPIA_RSP \
+ | L3_STATUS_0_DMARDIA_BRST \
+ | L3_STATUS_0_DMARDIA_RSP \
+ | L3_STATUS_0_DMAWRIA_BRST \
+ | L3_STATUS_0_DMAWRIA_RSP \
+ | L3_STATUS_0_USBOTGIA_BRST \
+ | L3_STATUS_0_USBOTGIA_RSP \
+ | L3_STATUS_0_USBHOSTIA_BRST \
+ | L3_STATUS_0_SMSTA_REQ \
+ | L3_STATUS_0_GPMCTA_REQ \
+ | L3_STATUS_0_OCMRAMTA_REQ \
+ | L3_STATUS_0_OCMROMTA_REQ \
+ | L3_STATUS_0_IVATA_REQ \
+ | L3_STATUS_0_SGXTA_REQ \
+ | L3_STATUS_0_L4CORETA_REQ \
+ | L3_STATUS_0_L4PERTA_REQ \
+ | L3_STATUS_0_L4EMUTA_REQ \
| L3_STATUS_0_MAD2DTA_REQ)
#define L3_SI_FLAG_STATUS_1 0x530
@@ -137,19 +137,19 @@ const u64 shift = 1;
enum omap3_l3_initiator_id {
/* LCD has 1 ID */
- OMAP_L3_LCD = 29,
+ OMAP_L3_LCD = 29,
/* SAD2D has 1 ID */
- OMAP_L3_SAD2D = 28,
+ OMAP_L3_SAD2D = 28,
/* MPU has 5 IDs */
- OMAP_L3_IA_MPU_SS_1 = 27,
- OMAP_L3_IA_MPU_SS_2 = 26,
- OMAP_L3_IA_MPU_SS_3 = 25,
- OMAP_L3_IA_MPU_SS_4 = 24,
- OMAP_L3_IA_MPU_SS_5 = 23,
+ OMAP_L3_IA_MPU_SS_1 = 27,
+ OMAP_L3_IA_MPU_SS_2 = 26,
+ OMAP_L3_IA_MPU_SS_3 = 25,
+ OMAP_L3_IA_MPU_SS_4 = 24,
+ OMAP_L3_IA_MPU_SS_5 = 23,
/* IVA2.2 SS has 3 IDs*/
- OMAP_L3_IA_IVA_SS_1 = 22,
- OMAP_L3_IA_IVA_SS_2 = 21,
- OMAP_L3_IA_IVA_SS_3 = 20,
+ OMAP_L3_IA_IVA_SS_1 = 22,
+ OMAP_L3_IA_IVA_SS_2 = 21,
+ OMAP_L3_IA_IVA_SS_3 = 20,
/* IVA 2.2 SS DMA has 6 IDS */
OMAP_L3_IA_IVA_SS_DMA_1 = 19,
OMAP_L3_IA_IVA_SS_DMA_2 = 18,
@@ -158,25 +158,25 @@ enum omap3_l3_initiator_id {
OMAP_L3_IA_IVA_SS_DMA_5 = 15,
OMAP_L3_IA_IVA_SS_DMA_6 = 14,
/* SGX has 1 ID */
- OMAP_L3_IA_SGX = 13,
+ OMAP_L3_IA_SGX = 13,
/* CAM has 3 ID */
- OMAP_L3_IA_CAM_1 = 12,
- OMAP_L3_IA_CAM_2 = 11,
- OMAP_L3_IA_CAM_3 = 10,
+ OMAP_L3_IA_CAM_1 = 12,
+ OMAP_L3_IA_CAM_2 = 11,
+ OMAP_L3_IA_CAM_3 = 10,
/* DAP has 1 ID */
- OMAP_L3_IA_DAP = 9,
+ OMAP_L3_IA_DAP = 9,
/* SDMA WR has 2 IDs */
- OMAP_L3_SDMA_WR_1 = 8,
- OMAP_L3_SDMA_WR_2 = 7,
+ OMAP_L3_SDMA_WR_1 = 8,
+ OMAP_L3_SDMA_WR_2 = 7,
/* SDMA RD has 4 IDs */
- OMAP_L3_SDMA_RD_1 = 6,
- OMAP_L3_SDMA_RD_2 = 5,
- OMAP_L3_SDMA_RD_3 = 4,
- OMAP_L3_SDMA_RD_4 = 3,
+ OMAP_L3_SDMA_RD_1 = 6,
+ OMAP_L3_SDMA_RD_2 = 5,
+ OMAP_L3_SDMA_RD_3 = 4,
+ OMAP_L3_SDMA_RD_4 = 3,
/* HSUSB OTG has 1 ID */
- OMAP_L3_USBOTG = 2,
+ OMAP_L3_USBOTG = 2,
/* HSUSB HOST has 1 ID */
- OMAP_L3_USBHOST = 1,
+ OMAP_L3_USBHOST = 1,
};
enum omap3_l3_code {
@@ -192,21 +192,21 @@ enum omap3_l3_code {
};
struct omap3_l3 {
- struct device *dev;
- struct clk *ick;
+ struct device *dev;
+ struct clk *ick;
/* memory base*/
- void __iomem *rt;
+ void __iomem *rt;
- int debug_irq;
- int app_irq;
+ int debug_irq;
+ int app_irq;
/* true when and inband functional error occurs */
- unsigned inband:1;
+ unsigned inband:1;
};
/* offsets for l3 agents in order with the Flag status register */
-unsigned int __iomem omap3_l3_app_bases[] = {
+static unsigned int omap3_l3_app_bases[] = {
/* MPU IA */
0x1400,
0x1400,
@@ -305,7 +305,7 @@ unsigned int __iomem omap3_l3_app_bases[] = {
0,
};
-unsigned int __iomem omap3_l3_debug_bases[] = {
+static unsigned int omap3_l3_debug_bases[] = {
/* MPU DATA IA */
0x1400,
/* RESERVED */
@@ -321,7 +321,7 @@ unsigned int __iomem omap3_l3_debug_bases[] = {
/* REST RESERVED */
};
-u32 *omap3_l3_bases[] = {
+static u32 *omap3_l3_bases[] = {
omap3_l3_app_bases,
omap3_l3_debug_bases,
};
diff --git a/arch/arm/mach-omap2/omap_twl.c b/arch/arm/mach-omap2/omap_twl.c
index 07d6140baa9d..f515a1a056d5 100644
--- a/arch/arm/mach-omap2/omap_twl.c
+++ b/arch/arm/mach-omap2/omap_twl.c
@@ -42,8 +42,11 @@
#define OMAP4_SRI2C_SLAVE_ADDR 0x12
#define OMAP4_VDD_MPU_SR_VOLT_REG 0x55
+#define OMAP4_VDD_MPU_SR_CMD_REG 0x56
#define OMAP4_VDD_IVA_SR_VOLT_REG 0x5B
+#define OMAP4_VDD_IVA_SR_CMD_REG 0x5C
#define OMAP4_VDD_CORE_SR_VOLT_REG 0x61
+#define OMAP4_VDD_CORE_SR_CMD_REG 0x62
#define OMAP4_VP_CONFIG_ERROROFFSET 0x00
#define OMAP4_VP_VSTEPMIN_VSTEPMIN 0x01
@@ -95,6 +98,8 @@ static unsigned long twl6030_vsel_to_uv(const u8 vsel)
is_offset_valid = true;
}
+ if (!vsel)
+ return 0;
/*
* There is no specific formula for voltage to vsel
* conversion above 1.3V. There are special hardcoded
@@ -106,9 +111,9 @@ static unsigned long twl6030_vsel_to_uv(const u8 vsel)
return 1350000;
if (smps_offset & 0x8)
- return ((((vsel - 1) * 125) + 7000)) * 100;
+ return ((((vsel - 1) * 1266) + 70900)) * 10;
else
- return ((((vsel - 1) * 125) + 6000)) * 100;
+ return ((((vsel - 1) * 1266) + 60770)) * 10;
}
static u8 twl6030_uv_to_vsel(unsigned long uv)
@@ -127,6 +132,8 @@ static u8 twl6030_uv_to_vsel(unsigned long uv)
is_offset_valid = true;
}
+ if (!uv)
+ return 0x00;
/*
* There is no specific formula for voltage to vsel
* conversion above 1.3V. There are special hardcoded
@@ -134,16 +141,21 @@ static u8 twl6030_uv_to_vsel(unsigned long uv)
* hardcoding only for 1.35 V which is used for 1GH OPP for
* OMAP4430.
*/
- if (uv == 1350000)
+ if (uv > twl6030_vsel_to_uv(0x39)) {
+ if (uv == 1350000)
+ return 0x3A;
+ pr_err("%s:OUT OF RANGE! non mapped vsel for %ld Vs max %ld\n",
+ __func__, uv, twl6030_vsel_to_uv(0x39));
return 0x3A;
+ }
if (smps_offset & 0x8)
- return DIV_ROUND_UP(uv - 700000, 12500) + 1;
+ return DIV_ROUND_UP(uv - 709000, 12660) + 1;
else
- return DIV_ROUND_UP(uv - 600000, 12500) + 1;
+ return DIV_ROUND_UP(uv - 607700, 12660) + 1;
}
-static struct omap_volt_pmic_info omap3_mpu_volt_info = {
+static struct omap_voltdm_pmic omap3_mpu_pmic = {
.slew_rate = 4000,
.step_size = 12500,
.on_volt = 1200000,
@@ -158,12 +170,13 @@ static struct omap_volt_pmic_info omap3_mpu_volt_info = {
.vp_vddmax = OMAP3430_VP1_VLIMITTO_VDDMAX,
.vp_timeout_us = OMAP3_VP_VLIMITTO_TIMEOUT_US,
.i2c_slave_addr = OMAP3_SRI2C_SLAVE_ADDR,
- .pmic_reg = OMAP3_VDD_MPU_SR_CONTROL_REG,
+ .volt_reg_addr = OMAP3_VDD_MPU_SR_CONTROL_REG,
+ .i2c_high_speed = true,
.vsel_to_uv = twl4030_vsel_to_uv,
.uv_to_vsel = twl4030_uv_to_vsel,
};
-static struct omap_volt_pmic_info omap3_core_volt_info = {
+static struct omap_voltdm_pmic omap3_core_pmic = {
.slew_rate = 4000,
.step_size = 12500,
.on_volt = 1200000,
@@ -178,18 +191,19 @@ static struct omap_volt_pmic_info omap3_core_volt_info = {
.vp_vddmax = OMAP3430_VP2_VLIMITTO_VDDMAX,
.vp_timeout_us = OMAP3_VP_VLIMITTO_TIMEOUT_US,
.i2c_slave_addr = OMAP3_SRI2C_SLAVE_ADDR,
- .pmic_reg = OMAP3_VDD_CORE_SR_CONTROL_REG,
+ .volt_reg_addr = OMAP3_VDD_CORE_SR_CONTROL_REG,
+ .i2c_high_speed = true,
.vsel_to_uv = twl4030_vsel_to_uv,
.uv_to_vsel = twl4030_uv_to_vsel,
};
-static struct omap_volt_pmic_info omap4_mpu_volt_info = {
+static struct omap_voltdm_pmic omap4_mpu_pmic = {
.slew_rate = 4000,
- .step_size = 12500,
- .on_volt = 1350000,
- .onlp_volt = 1350000,
- .ret_volt = 837500,
- .off_volt = 600000,
+ .step_size = 12660,
+ .on_volt = 1375000,
+ .onlp_volt = 1375000,
+ .ret_volt = 830000,
+ .off_volt = 0,
.volt_setup_time = 0,
.vp_erroroffset = OMAP4_VP_CONFIG_ERROROFFSET,
.vp_vstepmin = OMAP4_VP_VSTEPMIN_VSTEPMIN,
@@ -198,18 +212,20 @@ static struct omap_volt_pmic_info omap4_mpu_volt_info = {
.vp_vddmax = OMAP4_VP_MPU_VLIMITTO_VDDMAX,
.vp_timeout_us = OMAP4_VP_VLIMITTO_TIMEOUT_US,
.i2c_slave_addr = OMAP4_SRI2C_SLAVE_ADDR,
- .pmic_reg = OMAP4_VDD_MPU_SR_VOLT_REG,
+ .volt_reg_addr = OMAP4_VDD_MPU_SR_VOLT_REG,
+ .cmd_reg_addr = OMAP4_VDD_MPU_SR_CMD_REG,
+ .i2c_high_speed = true,
.vsel_to_uv = twl6030_vsel_to_uv,
.uv_to_vsel = twl6030_uv_to_vsel,
};
-static struct omap_volt_pmic_info omap4_iva_volt_info = {
+static struct omap_voltdm_pmic omap4_iva_pmic = {
.slew_rate = 4000,
- .step_size = 12500,
- .on_volt = 1100000,
- .onlp_volt = 1100000,
- .ret_volt = 837500,
- .off_volt = 600000,
+ .step_size = 12660,
+ .on_volt = 1188000,
+ .onlp_volt = 1188000,
+ .ret_volt = 830000,
+ .off_volt = 0,
.volt_setup_time = 0,
.vp_erroroffset = OMAP4_VP_CONFIG_ERROROFFSET,
.vp_vstepmin = OMAP4_VP_VSTEPMIN_VSTEPMIN,
@@ -218,18 +234,20 @@ static struct omap_volt_pmic_info omap4_iva_volt_info = {
.vp_vddmax = OMAP4_VP_IVA_VLIMITTO_VDDMAX,
.vp_timeout_us = OMAP4_VP_VLIMITTO_TIMEOUT_US,
.i2c_slave_addr = OMAP4_SRI2C_SLAVE_ADDR,
- .pmic_reg = OMAP4_VDD_IVA_SR_VOLT_REG,
+ .volt_reg_addr = OMAP4_VDD_IVA_SR_VOLT_REG,
+ .cmd_reg_addr = OMAP4_VDD_IVA_SR_CMD_REG,
+ .i2c_high_speed = true,
.vsel_to_uv = twl6030_vsel_to_uv,
.uv_to_vsel = twl6030_uv_to_vsel,
};
-static struct omap_volt_pmic_info omap4_core_volt_info = {
+static struct omap_voltdm_pmic omap4_core_pmic = {
.slew_rate = 4000,
- .step_size = 12500,
- .on_volt = 1100000,
- .onlp_volt = 1100000,
- .ret_volt = 837500,
- .off_volt = 600000,
+ .step_size = 12660,
+ .on_volt = 1200000,
+ .onlp_volt = 1200000,
+ .ret_volt = 830000,
+ .off_volt = 0,
.volt_setup_time = 0,
.vp_erroroffset = OMAP4_VP_CONFIG_ERROROFFSET,
.vp_vstepmin = OMAP4_VP_VSTEPMIN_VSTEPMIN,
@@ -238,7 +256,8 @@ static struct omap_volt_pmic_info omap4_core_volt_info = {
.vp_vddmax = OMAP4_VP_CORE_VLIMITTO_VDDMAX,
.vp_timeout_us = OMAP4_VP_VLIMITTO_TIMEOUT_US,
.i2c_slave_addr = OMAP4_SRI2C_SLAVE_ADDR,
- .pmic_reg = OMAP4_VDD_CORE_SR_VOLT_REG,
+ .volt_reg_addr = OMAP4_VDD_CORE_SR_VOLT_REG,
+ .cmd_reg_addr = OMAP4_VDD_CORE_SR_CMD_REG,
.vsel_to_uv = twl6030_vsel_to_uv,
.uv_to_vsel = twl6030_uv_to_vsel,
};
@@ -250,14 +269,14 @@ int __init omap4_twl_init(void)
if (!cpu_is_omap44xx())
return -ENODEV;
- voltdm = omap_voltage_domain_lookup("mpu");
- omap_voltage_register_pmic(voltdm, &omap4_mpu_volt_info);
+ voltdm = voltdm_lookup("mpu");
+ omap_voltage_register_pmic(voltdm, &omap4_mpu_pmic);
- voltdm = omap_voltage_domain_lookup("iva");
- omap_voltage_register_pmic(voltdm, &omap4_iva_volt_info);
+ voltdm = voltdm_lookup("iva");
+ omap_voltage_register_pmic(voltdm, &omap4_iva_pmic);
- voltdm = omap_voltage_domain_lookup("core");
- omap_voltage_register_pmic(voltdm, &omap4_core_volt_info);
+ voltdm = voltdm_lookup("core");
+ omap_voltage_register_pmic(voltdm, &omap4_core_pmic);
return 0;
}
@@ -270,10 +289,10 @@ int __init omap3_twl_init(void)
return -ENODEV;
if (cpu_is_omap3630()) {
- omap3_mpu_volt_info.vp_vddmin = OMAP3630_VP1_VLIMITTO_VDDMIN;
- omap3_mpu_volt_info.vp_vddmax = OMAP3630_VP1_VLIMITTO_VDDMAX;
- omap3_core_volt_info.vp_vddmin = OMAP3630_VP2_VLIMITTO_VDDMIN;
- omap3_core_volt_info.vp_vddmax = OMAP3630_VP2_VLIMITTO_VDDMAX;
+ omap3_mpu_pmic.vp_vddmin = OMAP3630_VP1_VLIMITTO_VDDMIN;
+ omap3_mpu_pmic.vp_vddmax = OMAP3630_VP1_VLIMITTO_VDDMAX;
+ omap3_core_pmic.vp_vddmin = OMAP3630_VP2_VLIMITTO_VDDMIN;
+ omap3_core_pmic.vp_vddmax = OMAP3630_VP2_VLIMITTO_VDDMAX;
}
/*
@@ -288,11 +307,11 @@ int __init omap3_twl_init(void)
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);
+ voltdm = voltdm_lookup("mpu_iva");
+ omap_voltage_register_pmic(voltdm, &omap3_mpu_pmic);
- voltdm = omap_voltage_domain_lookup("core");
- omap_voltage_register_pmic(voltdm, &omap3_core_volt_info);
+ voltdm = voltdm_lookup("core");
+ omap_voltage_register_pmic(voltdm, &omap3_core_pmic);
return 0;
}
diff --git a/arch/arm/mach-omap2/opp.c b/arch/arm/mach-omap2/opp.c
index ab8b35b780b5..9262a6b47702 100644
--- a/arch/arm/mach-omap2/opp.c
+++ b/arch/arm/mach-omap2/opp.c
@@ -69,7 +69,7 @@ int __init omap_init_opp_table(struct omap_opp_def *opp_def,
opp_def->hwmod_name, i);
return -EINVAL;
}
- dev = &oh->od->pdev.dev;
+ dev = &oh->od->pdev->dev;
r = opp_add(dev, opp_def->freq, opp_def->u_volt);
if (r) {
diff --git a/arch/arm/mach-omap2/pm.c b/arch/arm/mach-omap2/pm.c
index 472bf22d5e84..2ab7a9e17fe2 100644
--- a/arch/arm/mach-omap2/pm.c
+++ b/arch/arm/mach-omap2/pm.c
@@ -26,54 +26,21 @@
static struct omap_device_pm_latency *pm_lats;
-static struct device *mpu_dev;
-static struct device *iva_dev;
-static struct device *l3_dev;
-static struct device *dsp_dev;
-
-struct device *omap2_get_mpuss_device(void)
-{
- WARN_ON_ONCE(!mpu_dev);
- return mpu_dev;
-}
-
-struct device *omap2_get_iva_device(void)
-{
- WARN_ON_ONCE(!iva_dev);
- return iva_dev;
-}
-
-struct device *omap2_get_l3_device(void)
-{
- WARN_ON_ONCE(!l3_dev);
- return l3_dev;
-}
-
-struct device *omap4_get_dsp_device(void)
-{
- WARN_ON_ONCE(!dsp_dev);
- return dsp_dev;
-}
-EXPORT_SYMBOL(omap4_get_dsp_device);
-
-/* static int _init_omap_device(struct omap_hwmod *oh, void *user) */
-static int _init_omap_device(char *name, struct device **new_dev)
+static int _init_omap_device(char *name)
{
struct omap_hwmod *oh;
- struct omap_device *od;
+ struct platform_device *pdev;
oh = omap_hwmod_lookup(name);
if (WARN(!oh, "%s: could not find omap_hwmod for %s\n",
__func__, name))
return -ENODEV;
- od = omap_device_build(oh->name, 0, oh, NULL, 0, pm_lats, 0, false);
- if (WARN(IS_ERR(od), "%s: could not build omap_device for %s\n",
+ pdev = omap_device_build(oh->name, 0, oh, NULL, 0, pm_lats, 0, false);
+ if (WARN(IS_ERR(pdev), "%s: could not build omap_device for %s\n",
__func__, name))
return -ENODEV;
- *new_dev = &od->pdev.dev;
-
return 0;
}
@@ -82,16 +49,16 @@ static int _init_omap_device(char *name, struct device **new_dev)
*/
static void omap2_init_processor_devices(void)
{
- _init_omap_device("mpu", &mpu_dev);
+ _init_omap_device("mpu");
if (omap3_has_iva())
- _init_omap_device("iva", &iva_dev);
+ _init_omap_device("iva");
if (cpu_is_omap44xx()) {
- _init_omap_device("l3_main_1", &l3_dev);
- _init_omap_device("dsp", &dsp_dev);
- _init_omap_device("iva", &iva_dev);
+ _init_omap_device("l3_main_1");
+ _init_omap_device("dsp");
+ _init_omap_device("iva");
} else {
- _init_omap_device("l3_main", &l3_dev);
+ _init_omap_device("l3_main");
}
}
@@ -136,8 +103,8 @@ int omap_set_pwrdm_state(struct powerdomain *pwrdm, u32 state)
ret = pwrdm_set_next_pwrst(pwrdm, state);
if (ret) {
- printk(KERN_ERR "Unable to set state of powerdomain: %s\n",
- pwrdm->name);
+ pr_err("%s: unable to set state of powerdomain: %s\n",
+ __func__, pwrdm->name);
goto err;
}
@@ -161,37 +128,44 @@ err:
}
/*
- * This API is to be called during init to put the various voltage
+ * This API is to be called during init to set the various voltage
* domains to the voltage as per the opp table. Typically we boot up
* at the nominal voltage. So this function finds out the rate of
* the clock associated with the voltage domain, finds out the correct
- * opp entry and puts the voltage domain to the voltage specifies
+ * opp entry and sets the voltage domain to the voltage specified
* in the opp entry
*/
static int __init omap2_set_init_voltage(char *vdd_name, char *clk_name,
- struct device *dev)
+ const char *oh_name)
{
struct voltagedomain *voltdm;
struct clk *clk;
struct opp *opp;
unsigned long freq, bootup_volt;
+ struct device *dev;
+
+ if (!vdd_name || !clk_name || !oh_name) {
+ pr_err("%s: invalid parameters\n", __func__);
+ goto exit;
+ }
- if (!vdd_name || !clk_name || !dev) {
- printk(KERN_ERR "%s: Invalid parameters!\n", __func__);
+ dev = omap_device_get_by_hwmod_name(oh_name);
+ if (IS_ERR(dev)) {
+ pr_err("%s: Unable to get dev pointer for hwmod %s\n",
+ __func__, oh_name);
goto exit;
}
- voltdm = omap_voltage_domain_lookup(vdd_name);
+ voltdm = voltdm_lookup(vdd_name);
if (IS_ERR(voltdm)) {
- printk(KERN_ERR "%s: Unable to get vdd pointer for vdd_%s\n",
+ pr_err("%s: unable to get vdd pointer for vdd_%s\n",
__func__, vdd_name);
goto exit;
}
clk = clk_get(NULL, clk_name);
if (IS_ERR(clk)) {
- printk(KERN_ERR "%s: unable to get clk %s\n",
- __func__, clk_name);
+ pr_err("%s: unable to get clk %s\n", __func__, clk_name);
goto exit;
}
@@ -200,24 +174,23 @@ static int __init omap2_set_init_voltage(char *vdd_name, char *clk_name,
opp = opp_find_freq_ceil(dev, &freq);
if (IS_ERR(opp)) {
- printk(KERN_ERR "%s: unable to find boot up OPP for vdd_%s\n",
+ pr_err("%s: unable to find boot up OPP for vdd_%s\n",
__func__, vdd_name);
goto exit;
}
bootup_volt = opp_get_voltage(opp);
if (!bootup_volt) {
- printk(KERN_ERR "%s: unable to find voltage corresponding"
+ pr_err("%s: unable to find voltage corresponding "
"to the bootup OPP for vdd_%s\n", __func__, vdd_name);
goto exit;
}
- omap_voltage_scale_vdd(voltdm, bootup_volt);
+ voltdm_scale(voltdm, bootup_volt);
return 0;
exit:
- printk(KERN_ERR "%s: Unable to put vdd_%s to its init voltage\n\n",
- __func__, vdd_name);
+ pr_err("%s: unable to set vdd_%s\n", __func__, vdd_name);
return -EINVAL;
}
@@ -226,8 +199,8 @@ static void __init omap3_init_voltages(void)
if (!cpu_is_omap34xx())
return;
- omap2_set_init_voltage("mpu", "dpll1_ck", mpu_dev);
- omap2_set_init_voltage("core", "l3_ick", l3_dev);
+ omap2_set_init_voltage("mpu_iva", "dpll1_ck", "mpu");
+ omap2_set_init_voltage("core", "l3_ick", "l3_main");
}
static void __init omap4_init_voltages(void)
@@ -235,14 +208,15 @@ static void __init omap4_init_voltages(void)
if (!cpu_is_omap44xx())
return;
- omap2_set_init_voltage("mpu", "dpll_mpu_ck", mpu_dev);
- omap2_set_init_voltage("core", "l3_div_ck", l3_dev);
- omap2_set_init_voltage("iva", "dpll_iva_m5x2_ck", iva_dev);
+ omap2_set_init_voltage("mpu", "dpll_mpu_ck", "mpu");
+ omap2_set_init_voltage("core", "l3_div_ck", "l3_main_1");
+ omap2_set_init_voltage("iva", "dpll_iva_m5x2_ck", "iva");
}
static int __init omap2_common_pm_init(void)
{
- omap2_init_processor_devices();
+ if (!of_have_populated_dt())
+ omap2_init_processor_devices();
omap_pm_if_init();
return 0;
diff --git a/arch/arm/mach-omap2/pm24xx.c b/arch/arm/mach-omap2/pm24xx.c
index bf089e743ed9..cf0c216132ab 100644
--- a/arch/arm/mach-omap2/pm24xx.c
+++ b/arch/arm/mach-omap2/pm24xx.c
@@ -53,8 +53,6 @@
#include "powerdomain.h"
#include "clockdomain.h"
-static int omap2_pm_debug;
-
#ifdef CONFIG_SUSPEND
static suspend_state_t suspend_state = PM_SUSPEND_ON;
static inline bool is_suspending(void)
@@ -96,7 +94,6 @@ static int omap2_fclks_active(void)
static void omap2_enter_full_retention(void)
{
u32 l;
- struct timespec ts_preidle, ts_postidle, ts_idle;
/* There is 1 reference hold for all children of the oscillator
* clock, the following will remove it. If no one else uses the
@@ -124,10 +121,6 @@ static void omap2_enter_full_retention(void)
omap2_gpio_prepare_for_idle(0);
- if (omap2_pm_debug) {
- getnstimeofday(&ts_preidle);
- }
-
/* One last check for pending IRQs to avoid extra latency due
* to sleeping unnecessarily. */
if (omap_irq_pending())
@@ -155,13 +148,6 @@ static void omap2_enter_full_retention(void)
console_unlock();
no_sleep:
- if (omap2_pm_debug) {
- unsigned long long tmp;
-
- getnstimeofday(&ts_postidle);
- ts_idle = timespec_sub(ts_postidle, ts_preidle);
- tmp = timespec_to_ns(&ts_idle) * NSEC_PER_USEC;
- }
omap2_gpio_resume_after_idle();
clk_enable(osc_ck);
@@ -219,7 +205,6 @@ static int omap2_allow_mpu_retention(void)
static void omap2_enter_mpu_retention(void)
{
int only_idle = 0;
- struct timespec ts_preidle, ts_postidle, ts_idle;
/* Putting MPU into the WFI state while a transfer is active
* seems to cause the I2C block to timeout. Why? Good question. */
@@ -246,19 +231,7 @@ static void omap2_enter_mpu_retention(void)
only_idle = 1;
}
- if (omap2_pm_debug) {
- getnstimeofday(&ts_preidle);
- }
-
omap2_sram_idle();
-
- if (omap2_pm_debug) {
- unsigned long long tmp;
-
- getnstimeofday(&ts_postidle);
- ts_idle = timespec_sub(ts_postidle, ts_preidle);
- tmp = timespec_to_ns(&ts_idle) * NSEC_PER_USEC;
- }
}
static int omap2_can_sleep(void)
diff --git a/arch/arm/mach-omap2/pm34xx.c b/arch/arm/mach-omap2/pm34xx.c
index 7255d9bce868..c8cbd00a41af 100644
--- a/arch/arm/mach-omap2/pm34xx.c
+++ b/arch/arm/mach-omap2/pm34xx.c
@@ -55,7 +55,7 @@
static suspend_state_t suspend_state = PM_SUSPEND_ON;
static inline bool is_suspending(void)
{
- return (suspend_state != PM_SUSPEND_ON);
+ return (suspend_state != PM_SUSPEND_ON) && console_suspend_enabled;
}
#else
static inline bool is_suspending(void)
diff --git a/arch/arm/mach-omap2/powerdomain-common.c b/arch/arm/mach-omap2/powerdomain-common.c
index 171fccd208c7..f97afff68d6d 100644
--- a/arch/arm/mach-omap2/powerdomain-common.c
+++ b/arch/arm/mach-omap2/powerdomain-common.c
@@ -1,9 +1,8 @@
/*
- * linux/arch/arm/mach-omap2/powerdomain-common.c
- * Contains common powerdomain framework functions
+ * Common powerdomain framework functions
*
- * Copyright (C) 2010 Texas Instruments, Inc.
- * Copyright (C) 2010 Nokia Corporation
+ * Copyright (C) 2010-2011 Texas Instruments, Inc.
+ * Copyright (C) 2010 Nokia Corporation
*
* Derived from mach-omap2/powerdomain.c written by Paul Walmsley
*
diff --git a/arch/arm/mach-omap2/powerdomain.c b/arch/arm/mach-omap2/powerdomain.c
index ef71fdd40fc4..5164d587ef52 100644
--- a/arch/arm/mach-omap2/powerdomain.c
+++ b/arch/arm/mach-omap2/powerdomain.c
@@ -1,7 +1,7 @@
/*
* OMAP powerdomain control
*
- * Copyright (C) 2007-2008 Texas Instruments, Inc.
+ * Copyright (C) 2007-2008, 2011 Texas Instruments, Inc.
* Copyright (C) 2007-2011 Nokia Corporation
*
* Written by Paul Walmsley
@@ -77,13 +77,11 @@ static struct powerdomain *_pwrdm_lookup(const char *name)
static int _pwrdm_register(struct powerdomain *pwrdm)
{
int i;
+ struct voltagedomain *voltdm;
if (!pwrdm || !pwrdm->name)
return -EINVAL;
- if (!omap_chip_is(pwrdm->omap_chip))
- return -EINVAL;
-
if (cpu_is_omap44xx() &&
pwrdm->prcm_partition == OMAP4430_INVALID_PRCM_PARTITION) {
pr_err("powerdomain: %s: missing OMAP4 PRCM partition ID\n",
@@ -94,6 +92,16 @@ static int _pwrdm_register(struct powerdomain *pwrdm)
if (_pwrdm_lookup(pwrdm->name))
return -EEXIST;
+ voltdm = voltdm_lookup(pwrdm->voltdm.name);
+ if (!voltdm) {
+ pr_err("powerdomain: %s: voltagedomain %s does not exist\n",
+ pwrdm->name, pwrdm->voltdm.name);
+ return -EINVAL;
+ }
+ pwrdm->voltdm.ptr = voltdm;
+ INIT_LIST_HEAD(&pwrdm->voltdm_node);
+ voltdm_add_pwrdm(voltdm, pwrdm);
+
list_add(&pwrdm->node, &pwrdm_list);
/* Initialize the powerdomain's state counter */
@@ -194,36 +202,76 @@ static int _pwrdm_post_transition_cb(struct powerdomain *pwrdm, void *unused)
/* Public functions */
/**
- * pwrdm_init - set up the powerdomain layer
- * @pwrdms: array of struct powerdomain pointers to register
- * @custom_funcs: func pointers for arch specific implementations
+ * pwrdm_register_platform_funcs - register powerdomain implementation fns
+ * @po: func pointers for arch specific implementations
*
- * Loop through the array of powerdomains @pwrdms, registering all
- * that are available on the current CPU. Also, program all
- * powerdomain target state as ON; this is to prevent domains from
- * hitting low power states (if bootloader has target states set to
- * something other than ON) and potentially even losing context while
- * PM is not fully initialized. The PM late init code can then program
- * the desired target state for all the power domains. No return
- * value.
+ * Register the list of function pointers used to implement the
+ * powerdomain functions on different OMAP SoCs. Should be called
+ * before any other pwrdm_register*() function. Returns -EINVAL if
+ * @po is null, -EEXIST if platform functions have already been
+ * registered, or 0 upon success.
*/
-void pwrdm_init(struct powerdomain **pwrdms, struct pwrdm_ops *custom_funcs)
+int pwrdm_register_platform_funcs(struct pwrdm_ops *po)
+{
+ if (!po)
+ return -EINVAL;
+
+ if (arch_pwrdm)
+ return -EEXIST;
+
+ arch_pwrdm = po;
+
+ return 0;
+}
+
+/**
+ * pwrdm_register_pwrdms - register SoC powerdomains
+ * @ps: pointer to an array of struct powerdomain to register
+ *
+ * Register the powerdomains available on a particular OMAP SoC. Must
+ * be called after pwrdm_register_platform_funcs(). May be called
+ * multiple times. Returns -EACCES if called before
+ * pwrdm_register_platform_funcs(); -EINVAL if the argument @ps is
+ * null; or 0 upon success.
+ */
+int pwrdm_register_pwrdms(struct powerdomain **ps)
{
struct powerdomain **p = NULL;
- struct powerdomain *temp_p;
- if (!custom_funcs)
- WARN(1, "powerdomain: No custom pwrdm functions registered\n");
- else
- arch_pwrdm = custom_funcs;
+ if (!arch_pwrdm)
+ return -EEXIST;
- if (pwrdms) {
- for (p = pwrdms; *p; p++)
- _pwrdm_register(*p);
- }
+ if (!ps)
+ return -EINVAL;
+
+ for (p = ps; *p; p++)
+ _pwrdm_register(*p);
+
+ return 0;
+}
+
+/**
+ * pwrdm_complete_init - set up the powerdomain layer
+ *
+ * Do whatever is necessary to initialize registered powerdomains and
+ * powerdomain code. Currently, this programs the next power state
+ * for each powerdomain to ON. This prevents powerdomains from
+ * unexpectedly losing context or entering high wakeup latency modes
+ * with non-power-management-enabled kernels. Must be called after
+ * pwrdm_register_pwrdms(). Returns -EACCES if called before
+ * pwrdm_register_pwrdms(), or 0 upon success.
+ */
+int pwrdm_complete_init(void)
+{
+ struct powerdomain *temp_p;
+
+ if (list_empty(&pwrdm_list))
+ return -EACCES;
list_for_each_entry(temp_p, &pwrdm_list, node)
pwrdm_set_next_pwrst(temp_p, PWRDM_POWER_ON);
+
+ return 0;
}
/**
@@ -390,6 +438,18 @@ int pwrdm_for_each_clkdm(struct powerdomain *pwrdm,
}
/**
+ * pwrdm_get_voltdm - return a ptr to the voltdm that this pwrdm resides in
+ * @pwrdm: struct powerdomain *
+ *
+ * Return a pointer to the struct voltageomain that the specified powerdomain
+ * @pwrdm exists in.
+ */
+struct voltagedomain *pwrdm_get_voltdm(struct powerdomain *pwrdm)
+{
+ return pwrdm->voltdm.ptr;
+}
+
+/**
* pwrdm_get_mem_bank_count - get number of memory banks in this powerdomain
* @pwrdm: struct powerdomain *
*
diff --git a/arch/arm/mach-omap2/powerdomain.h b/arch/arm/mach-omap2/powerdomain.h
index d23d979b9c34..42e6dd8f2a78 100644
--- a/arch/arm/mach-omap2/powerdomain.h
+++ b/arch/arm/mach-omap2/powerdomain.h
@@ -24,6 +24,8 @@
#include <plat/cpu.h>
+#include "voltage.h"
+
/* Powerdomain basic power states */
#define PWRDM_POWER_OFF 0x0
#define PWRDM_POWER_RET 0x1
@@ -78,7 +80,7 @@ struct powerdomain;
/**
* struct powerdomain - OMAP powerdomain
* @name: Powerdomain name
- * @omap_chip: represents the OMAP chip types containing this pwrdm
+ * @voltdm: voltagedomain containing this powerdomain
* @prcm_offs: the address offset from CM_BASE/PRM_BASE
* @prcm_partition: (OMAP4 only) the PRCM partition ID containing @prcm_offs
* @pwrsts: Possible powerdomain power states
@@ -89,6 +91,7 @@ struct powerdomain;
* @pwrsts_mem_on: Possible memory bank pwrstates when pwrdm in ON
* @pwrdm_clkdms: Clockdomains in this powerdomain
* @node: list_head linking all powerdomains
+ * @voltdm_node: list_head linking all powerdomains in a voltagedomain
* @state:
* @state_counter:
* @timer:
@@ -98,7 +101,10 @@ struct powerdomain;
*/
struct powerdomain {
const char *name;
- const struct omap_chip_id omap_chip;
+ union {
+ const char *name;
+ struct voltagedomain *ptr;
+ } voltdm;
const s16 prcm_offs;
const u8 pwrsts;
const u8 pwrsts_logic_ret;
@@ -109,6 +115,7 @@ struct powerdomain {
const u8 prcm_partition;
struct clockdomain *pwrdm_clkdms[PWRDM_MAX_CLKDMS];
struct list_head node;
+ struct list_head voltdm_node;
int state;
unsigned state_counter[PWRDM_MAX_PWRSTS];
unsigned ret_logic_off_counter;
@@ -162,7 +169,9 @@ struct pwrdm_ops {
int (*pwrdm_wait_transition)(struct powerdomain *pwrdm);
};
-void pwrdm_init(struct powerdomain **pwrdm_list, struct pwrdm_ops *custom_funcs);
+int pwrdm_register_platform_funcs(struct pwrdm_ops *custom_funcs);
+int pwrdm_register_pwrdms(struct powerdomain **pwrdm_list);
+int pwrdm_complete_init(void);
struct powerdomain *pwrdm_lookup(const char *name);
@@ -176,6 +185,7 @@ int pwrdm_del_clkdm(struct powerdomain *pwrdm, struct clockdomain *clkdm);
int pwrdm_for_each_clkdm(struct powerdomain *pwrdm,
int (*fn)(struct powerdomain *pwrdm,
struct clockdomain *clkdm));
+struct voltagedomain *pwrdm_get_voltdm(struct powerdomain *pwrdm);
int pwrdm_get_mem_bank_count(struct powerdomain *pwrdm);
@@ -210,7 +220,8 @@ int pwrdm_set_lowpwrstchange(struct powerdomain *pwrdm);
u32 pwrdm_get_context_loss_count(struct powerdomain *pwrdm);
bool pwrdm_can_ever_lose_context(struct powerdomain *pwrdm);
-extern void omap2xxx_powerdomains_init(void);
+extern void omap242x_powerdomains_init(void);
+extern void omap243x_powerdomains_init(void);
extern void omap3xxx_powerdomains_init(void);
extern void omap44xx_powerdomains_init(void);
diff --git a/arch/arm/mach-omap2/powerdomain2xxx_3xxx.c b/arch/arm/mach-omap2/powerdomain2xxx_3xxx.c
index cf600e22bf8e..6a17e4ca1d79 100644
--- a/arch/arm/mach-omap2/powerdomain2xxx_3xxx.c
+++ b/arch/arm/mach-omap2/powerdomain2xxx_3xxx.c
@@ -1,7 +1,7 @@
/*
* OMAP2 and OMAP3 powerdomain control
*
- * Copyright (C) 2009-2010 Texas Instruments, Inc.
+ * Copyright (C) 2009-2011 Texas Instruments, Inc.
* Copyright (C) 2007-2009 Nokia Corporation
*
* Derived from mach-omap2/powerdomain.c written by Paul Walmsley
diff --git a/arch/arm/mach-omap2/powerdomains2xxx_3xxx_data.c b/arch/arm/mach-omap2/powerdomains2xxx_3xxx_data.c
index 4210c3399769..d3a5399091ad 100644
--- a/arch/arm/mach-omap2/powerdomains2xxx_3xxx_data.c
+++ b/arch/arm/mach-omap2/powerdomains2xxx_3xxx_data.c
@@ -1,7 +1,7 @@
/*
* OMAP2/3 common powerdomain definitions
*
- * Copyright (C) 2007-2008 Texas Instruments, Inc.
+ * Copyright (C) 2007-2008, 2011 Texas Instruments, Inc.
* Copyright (C) 2007-2011 Nokia Corporation
*
* Paul Walmsley, Jouni Högander
@@ -12,20 +12,6 @@
*/
/*
- * To Do List
- * -> Move the Sleep/Wakeup dependencies from Power Domain framework to
- * Clock Domain Framework
- */
-
-/*
- * This file contains all of the powerdomains that have some element
- * of software control for the OMAP24xx and OMAP34xx chips.
- *
- * This is not an exhaustive listing of powerdomains on the chips; only
- * powerdomains that can be controlled in software.
- */
-
-/*
* The names for the DSP/IVA2 powerdomains are confusing.
*
* Most OMAP chips have an on-board DSP.
@@ -59,8 +45,6 @@
struct powerdomain gfx_omap2_pwrdm = {
.name = "gfx_pwrdm",
.prcm_offs = GFX_MOD,
- .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP24XX |
- CHIP_IS_OMAP3430ES1),
.pwrsts = PWRSTS_OFF_RET_ON,
.pwrsts_logic_ret = PWRSTS_RET,
.banks = 1,
@@ -70,11 +54,12 @@ struct powerdomain gfx_omap2_pwrdm = {
.pwrsts_mem_on = {
[0] = PWRSTS_ON, /* MEMONSTATE */
},
+ .voltdm = { .name = "core" },
};
struct powerdomain wkup_omap2_pwrdm = {
.name = "wkup_pwrdm",
.prcm_offs = WKUP_MOD,
- .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP24XX | CHIP_IS_OMAP3430),
.pwrsts = PWRSTS_ON,
+ .voltdm = { .name = "wakeup" },
};
diff --git a/arch/arm/mach-omap2/powerdomains2xxx_data.c b/arch/arm/mach-omap2/powerdomains2xxx_data.c
index cc389fb2005d..2385c1f009ee 100644
--- a/arch/arm/mach-omap2/powerdomains2xxx_data.c
+++ b/arch/arm/mach-omap2/powerdomains2xxx_data.c
@@ -1,7 +1,7 @@
/*
* OMAP2XXX powerdomain definitions
*
- * Copyright (C) 2007-2008 Texas Instruments, Inc.
+ * Copyright (C) 2007-2008, 2011 Texas Instruments, Inc.
* Copyright (C) 2007-2011 Nokia Corporation
*
* Paul Walmsley, Jouni Högander
@@ -28,7 +28,6 @@
static struct powerdomain dsp_pwrdm = {
.name = "dsp_pwrdm",
.prcm_offs = OMAP24XX_DSP_MOD,
- .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP24XX),
.pwrsts = PWRSTS_OFF_RET_ON,
.pwrsts_logic_ret = PWRSTS_RET,
.banks = 1,
@@ -38,12 +37,12 @@ static struct powerdomain dsp_pwrdm = {
.pwrsts_mem_on = {
[0] = PWRSTS_ON,
},
+ .voltdm = { .name = "core" },
};
static struct powerdomain mpu_24xx_pwrdm = {
.name = "mpu_pwrdm",
.prcm_offs = MPU_MOD,
- .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP24XX),
.pwrsts = PWRSTS_OFF_RET_ON,
.pwrsts_logic_ret = PWRSTS_OFF_RET,
.banks = 1,
@@ -53,12 +52,12 @@ static struct powerdomain mpu_24xx_pwrdm = {
.pwrsts_mem_on = {
[0] = PWRSTS_ON,
},
+ .voltdm = { .name = "core" },
};
static struct powerdomain core_24xx_pwrdm = {
.name = "core_pwrdm",
.prcm_offs = CORE_MOD,
- .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP24XX),
.pwrsts = PWRSTS_OFF_RET_ON,
.banks = 3,
.pwrsts_mem_ret = {
@@ -71,6 +70,7 @@ static struct powerdomain core_24xx_pwrdm = {
[1] = PWRSTS_OFF_RET_ON, /* MEM2ONSTATE */
[2] = PWRSTS_OFF_RET_ON, /* MEM3ONSTATE */
},
+ .voltdm = { .name = "core" },
};
@@ -78,14 +78,11 @@ static struct powerdomain core_24xx_pwrdm = {
* 2430-specific powerdomains
*/
-#ifdef CONFIG_SOC_OMAP2430
-
/* XXX 2430 KILLDOMAINWKUP bit? No current users apparently */
static struct powerdomain mdm_pwrdm = {
.name = "mdm_pwrdm",
.prcm_offs = OMAP2430_MDM_MOD,
- .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP2430),
.pwrsts = PWRSTS_OFF_RET_ON,
.pwrsts_logic_ret = PWRSTS_RET,
.banks = 1,
@@ -95,29 +92,44 @@ static struct powerdomain mdm_pwrdm = {
.pwrsts_mem_on = {
[0] = PWRSTS_ON, /* MEMONSTATE */
},
+ .voltdm = { .name = "core" },
};
-#endif /* CONFIG_SOC_OMAP2430 */
-
-/* As powerdomains are added or removed above, this list must also be changed */
-static struct powerdomain *powerdomains_omap2xxx[] __initdata = {
+/*
+ *
+ */
+static struct powerdomain *powerdomains_omap24xx[] __initdata = {
&wkup_omap2_pwrdm,
&gfx_omap2_pwrdm,
-
-#ifdef CONFIG_ARCH_OMAP2
&dsp_pwrdm,
&mpu_24xx_pwrdm,
&core_24xx_pwrdm,
-#endif
+ NULL
+};
-#ifdef CONFIG_SOC_OMAP2430
+static struct powerdomain *powerdomains_omap2430[] __initdata = {
&mdm_pwrdm,
-#endif
NULL
};
-void __init omap2xxx_powerdomains_init(void)
+void __init omap242x_powerdomains_init(void)
+{
+ if (!cpu_is_omap2420())
+ return;
+
+ pwrdm_register_platform_funcs(&omap2_pwrdm_operations);
+ pwrdm_register_pwrdms(powerdomains_omap24xx);
+ pwrdm_complete_init();
+}
+
+void __init omap243x_powerdomains_init(void)
{
- pwrdm_init(powerdomains_omap2xxx, &omap2_pwrdm_operations);
+ if (!cpu_is_omap2430())
+ return;
+
+ pwrdm_register_platform_funcs(&omap2_pwrdm_operations);
+ pwrdm_register_pwrdms(powerdomains_omap24xx);
+ pwrdm_register_pwrdms(powerdomains_omap2430);
+ pwrdm_complete_init();
}
diff --git a/arch/arm/mach-omap2/powerdomains3xxx_data.c b/arch/arm/mach-omap2/powerdomains3xxx_data.c
index 469a920a74dc..8ef26daeed68 100644
--- a/arch/arm/mach-omap2/powerdomains3xxx_data.c
+++ b/arch/arm/mach-omap2/powerdomains3xxx_data.c
@@ -1,7 +1,7 @@
/*
* OMAP3 powerdomain definitions
*
- * Copyright (C) 2007-2008 Texas Instruments, Inc.
+ * Copyright (C) 2007-2008, 2011 Texas Instruments, Inc.
* Copyright (C) 2007-2011 Nokia Corporation
*
* Paul Walmsley, Jouni Högander
@@ -14,6 +14,8 @@
#include <linux/kernel.h>
#include <linux/init.h>
+#include <plat/cpu.h>
+
#include "powerdomain.h"
#include "powerdomains2xxx_3xxx_data.h"
@@ -27,8 +29,6 @@
* 34XX-specific powerdomains, dependencies
*/
-#ifdef CONFIG_ARCH_OMAP3
-
/*
* Powerdomains
*/
@@ -36,7 +36,6 @@
static struct powerdomain iva2_pwrdm = {
.name = "iva2_pwrdm",
.prcm_offs = OMAP3430_IVA2_MOD,
- .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP3430),
.pwrsts = PWRSTS_OFF_RET_ON,
.pwrsts_logic_ret = PWRSTS_OFF_RET,
.banks = 4,
@@ -52,12 +51,12 @@ static struct powerdomain iva2_pwrdm = {
[2] = PWRSTS_OFF_ON,
[3] = PWRSTS_ON,
},
+ .voltdm = { .name = "mpu_iva" },
};
static struct powerdomain mpu_3xxx_pwrdm = {
.name = "mpu_pwrdm",
.prcm_offs = MPU_MOD,
- .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP3430),
.pwrsts = PWRSTS_OFF_RET_ON,
.pwrsts_logic_ret = PWRSTS_OFF_RET,
.flags = PWRDM_HAS_MPU_QUIRK,
@@ -68,6 +67,7 @@ static struct powerdomain mpu_3xxx_pwrdm = {
.pwrsts_mem_on = {
[0] = PWRSTS_OFF_ON,
},
+ .voltdm = { .name = "mpu_iva" },
};
/*
@@ -83,10 +83,6 @@ static struct powerdomain mpu_3xxx_pwrdm = {
static struct powerdomain core_3xxx_pre_es3_1_pwrdm = {
.name = "core_pwrdm",
.prcm_offs = CORE_MOD,
- .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP3430ES1 |
- CHIP_IS_OMAP3430ES2 |
- CHIP_IS_OMAP3430ES3_0 |
- CHIP_IS_OMAP3630ES1),
.pwrsts = PWRSTS_OFF_RET_ON,
.pwrsts_logic_ret = PWRSTS_OFF_RET,
.banks = 2,
@@ -98,13 +94,12 @@ static struct powerdomain core_3xxx_pre_es3_1_pwrdm = {
[0] = PWRSTS_OFF_RET_ON, /* MEM1ONSTATE */
[1] = PWRSTS_OFF_RET_ON, /* MEM2ONSTATE */
},
+ .voltdm = { .name = "core" },
};
static struct powerdomain core_3xxx_es3_1_pwrdm = {
.name = "core_pwrdm",
.prcm_offs = CORE_MOD,
- .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP3430ES3_1 |
- CHIP_GE_OMAP3630ES1_1),
.pwrsts = PWRSTS_OFF_RET_ON,
.pwrsts_logic_ret = PWRSTS_OFF_RET,
/*
@@ -121,11 +116,11 @@ static struct powerdomain core_3xxx_es3_1_pwrdm = {
[0] = PWRSTS_OFF_RET_ON, /* MEM1ONSTATE */
[1] = PWRSTS_OFF_RET_ON, /* MEM2ONSTATE */
},
+ .voltdm = { .name = "core" },
};
static struct powerdomain dss_pwrdm = {
.name = "dss_pwrdm",
- .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP3430),
.prcm_offs = OMAP3430_DSS_MOD,
.pwrsts = PWRSTS_OFF_RET_ON,
.pwrsts_logic_ret = PWRSTS_RET,
@@ -136,6 +131,7 @@ static struct powerdomain dss_pwrdm = {
.pwrsts_mem_on = {
[0] = PWRSTS_ON, /* MEMONSTATE */
},
+ .voltdm = { .name = "core" },
};
/*
@@ -146,7 +142,6 @@ static struct powerdomain dss_pwrdm = {
static struct powerdomain sgx_pwrdm = {
.name = "sgx_pwrdm",
.prcm_offs = OMAP3430ES2_SGX_MOD,
- .omap_chip = OMAP_CHIP_INIT(CHIP_GE_OMAP3430ES2),
/* XXX This is accurate for 3430 SGX, but what about GFX? */
.pwrsts = PWRSTS_OFF_ON,
.pwrsts_logic_ret = PWRSTS_RET,
@@ -157,11 +152,11 @@ static struct powerdomain sgx_pwrdm = {
.pwrsts_mem_on = {
[0] = PWRSTS_ON, /* MEMONSTATE */
},
+ .voltdm = { .name = "core" },
};
static struct powerdomain cam_pwrdm = {
.name = "cam_pwrdm",
- .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP3430),
.prcm_offs = OMAP3430_CAM_MOD,
.pwrsts = PWRSTS_OFF_RET_ON,
.pwrsts_logic_ret = PWRSTS_RET,
@@ -172,12 +167,12 @@ static struct powerdomain cam_pwrdm = {
.pwrsts_mem_on = {
[0] = PWRSTS_ON, /* MEMONSTATE */
},
+ .voltdm = { .name = "core" },
};
static struct powerdomain per_pwrdm = {
.name = "per_pwrdm",
.prcm_offs = OMAP3430_PER_MOD,
- .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP3430),
.pwrsts = PWRSTS_OFF_RET_ON,
.pwrsts_logic_ret = PWRSTS_OFF_RET,
.banks = 1,
@@ -187,26 +182,26 @@ static struct powerdomain per_pwrdm = {
.pwrsts_mem_on = {
[0] = PWRSTS_ON, /* MEMONSTATE */
},
+ .voltdm = { .name = "core" },
};
static struct powerdomain emu_pwrdm = {
.name = "emu_pwrdm",
.prcm_offs = OMAP3430_EMU_MOD,
- .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP3430),
+ .voltdm = { .name = "core" },
};
static struct powerdomain neon_pwrdm = {
.name = "neon_pwrdm",
.prcm_offs = OMAP3430_NEON_MOD,
- .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP3430),
.pwrsts = PWRSTS_OFF_RET_ON,
.pwrsts_logic_ret = PWRSTS_RET,
+ .voltdm = { .name = "mpu_iva" },
};
static struct powerdomain usbhost_pwrdm = {
.name = "usbhost_pwrdm",
.prcm_offs = OMAP3430ES2_USBHOST_MOD,
- .omap_chip = OMAP_CHIP_INIT(CHIP_GE_OMAP3430ES2),
.pwrsts = PWRSTS_OFF_RET_ON,
.pwrsts_logic_ret = PWRSTS_RET,
/*
@@ -223,65 +218,103 @@ static struct powerdomain usbhost_pwrdm = {
.pwrsts_mem_on = {
[0] = PWRSTS_ON, /* MEMONSTATE */
},
+ .voltdm = { .name = "core" },
};
static struct powerdomain dpll1_pwrdm = {
.name = "dpll1_pwrdm",
.prcm_offs = MPU_MOD,
- .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP3430),
+ .voltdm = { .name = "mpu_iva" },
};
static struct powerdomain dpll2_pwrdm = {
.name = "dpll2_pwrdm",
.prcm_offs = OMAP3430_IVA2_MOD,
- .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP3430),
+ .voltdm = { .name = "mpu_iva" },
};
static struct powerdomain dpll3_pwrdm = {
.name = "dpll3_pwrdm",
.prcm_offs = PLL_MOD,
- .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP3430),
+ .voltdm = { .name = "core" },
};
static struct powerdomain dpll4_pwrdm = {
.name = "dpll4_pwrdm",
.prcm_offs = PLL_MOD,
- .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP3430),
+ .voltdm = { .name = "core" },
};
static struct powerdomain dpll5_pwrdm = {
.name = "dpll5_pwrdm",
.prcm_offs = PLL_MOD,
- .omap_chip = OMAP_CHIP_INIT(CHIP_GE_OMAP3430ES2),
+ .voltdm = { .name = "core" },
};
/* As powerdomains are added or removed above, this list must also be changed */
-static struct powerdomain *powerdomains_omap3xxx[] __initdata = {
-
+static struct powerdomain *powerdomains_omap3430_common[] __initdata = {
&wkup_omap2_pwrdm,
- &gfx_omap2_pwrdm,
&iva2_pwrdm,
&mpu_3xxx_pwrdm,
&neon_pwrdm,
- &core_3xxx_pre_es3_1_pwrdm,
- &core_3xxx_es3_1_pwrdm,
&cam_pwrdm,
&dss_pwrdm,
&per_pwrdm,
&emu_pwrdm,
- &sgx_pwrdm,
- &usbhost_pwrdm,
&dpll1_pwrdm,
&dpll2_pwrdm,
&dpll3_pwrdm,
&dpll4_pwrdm,
+ NULL
+};
+
+static struct powerdomain *powerdomains_omap3430es1[] __initdata = {
+ &gfx_omap2_pwrdm,
+ &core_3xxx_pre_es3_1_pwrdm,
+ NULL
+};
+
+/* also includes 3630ES1.0 */
+static struct powerdomain *powerdomains_omap3430es2_es3_0[] __initdata = {
+ &core_3xxx_pre_es3_1_pwrdm,
+ &sgx_pwrdm,
+ &usbhost_pwrdm,
&dpll5_pwrdm,
-#endif
NULL
};
+/* also includes 3630ES1.1+ */
+static struct powerdomain *powerdomains_omap3430es3_1plus[] __initdata = {
+ &core_3xxx_es3_1_pwrdm,
+ &sgx_pwrdm,
+ &usbhost_pwrdm,
+ &dpll5_pwrdm,
+ NULL
+};
void __init omap3xxx_powerdomains_init(void)
{
- pwrdm_init(powerdomains_omap3xxx, &omap3_pwrdm_operations);
+ unsigned int rev;
+
+ if (!cpu_is_omap34xx())
+ return;
+
+ pwrdm_register_platform_funcs(&omap3_pwrdm_operations);
+ pwrdm_register_pwrdms(powerdomains_omap3430_common);
+
+ rev = omap_rev();
+
+ if (rev == OMAP3430_REV_ES1_0)
+ pwrdm_register_pwrdms(powerdomains_omap3430es1);
+ else if (rev == OMAP3430_REV_ES2_0 || rev == OMAP3430_REV_ES2_1 ||
+ rev == OMAP3430_REV_ES3_0 || rev == OMAP3630_REV_ES1_0)
+ pwrdm_register_pwrdms(powerdomains_omap3430es2_es3_0);
+ else if (rev == OMAP3430_REV_ES3_1 || rev == OMAP3430_REV_ES3_1_2 ||
+ rev == OMAP3517_REV_ES1_0 || rev == OMAP3517_REV_ES1_1 ||
+ rev == OMAP3630_REV_ES1_1 || rev == OMAP3630_REV_ES1_2)
+ pwrdm_register_pwrdms(powerdomains_omap3430es3_1plus);
+ else
+ WARN(1, "OMAP3 powerdomain init: unknown chip type\n");
+
+ pwrdm_complete_init();
}
diff --git a/arch/arm/mach-omap2/powerdomains44xx_data.c b/arch/arm/mach-omap2/powerdomains44xx_data.c
index 247e79495115..704664c0e259 100644
--- a/arch/arm/mach-omap2/powerdomains44xx_data.c
+++ b/arch/arm/mach-omap2/powerdomains44xx_data.c
@@ -33,9 +33,9 @@
/* core_44xx_pwrdm: CORE power domain */
static struct powerdomain core_44xx_pwrdm = {
.name = "core_pwrdm",
+ .voltdm = { .name = "core" },
.prcm_offs = OMAP4430_PRM_CORE_INST,
.prcm_partition = OMAP4430_PRM_PARTITION,
- .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430),
.pwrsts = PWRSTS_RET_ON,
.pwrsts_logic_ret = PWRSTS_OFF_RET,
.banks = 5,
@@ -59,9 +59,9 @@ static struct powerdomain core_44xx_pwrdm = {
/* gfx_44xx_pwrdm: 3D accelerator power domain */
static struct powerdomain gfx_44xx_pwrdm = {
.name = "gfx_pwrdm",
+ .voltdm = { .name = "core" },
.prcm_offs = OMAP4430_PRM_GFX_INST,
.prcm_partition = OMAP4430_PRM_PARTITION,
- .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430),
.pwrsts = PWRSTS_OFF_ON,
.banks = 1,
.pwrsts_mem_ret = {
@@ -76,9 +76,9 @@ static struct powerdomain gfx_44xx_pwrdm = {
/* abe_44xx_pwrdm: Audio back end power domain */
static struct powerdomain abe_44xx_pwrdm = {
.name = "abe_pwrdm",
+ .voltdm = { .name = "iva" },
.prcm_offs = OMAP4430_PRM_ABE_INST,
.prcm_partition = OMAP4430_PRM_PARTITION,
- .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430),
.pwrsts = PWRSTS_OFF_RET_ON,
.pwrsts_logic_ret = PWRSTS_OFF,
.banks = 2,
@@ -96,9 +96,9 @@ static struct powerdomain abe_44xx_pwrdm = {
/* dss_44xx_pwrdm: Display subsystem power domain */
static struct powerdomain dss_44xx_pwrdm = {
.name = "dss_pwrdm",
+ .voltdm = { .name = "core" },
.prcm_offs = OMAP4430_PRM_DSS_INST,
.prcm_partition = OMAP4430_PRM_PARTITION,
- .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430),
.pwrsts = PWRSTS_OFF_RET_ON,
.pwrsts_logic_ret = PWRSTS_OFF,
.banks = 1,
@@ -114,9 +114,9 @@ static struct powerdomain dss_44xx_pwrdm = {
/* tesla_44xx_pwrdm: Tesla processor power domain */
static struct powerdomain tesla_44xx_pwrdm = {
.name = "tesla_pwrdm",
+ .voltdm = { .name = "iva" },
.prcm_offs = OMAP4430_PRM_TESLA_INST,
.prcm_partition = OMAP4430_PRM_PARTITION,
- .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430),
.pwrsts = PWRSTS_OFF_RET_ON,
.pwrsts_logic_ret = PWRSTS_OFF_RET,
.banks = 3,
@@ -136,9 +136,9 @@ static struct powerdomain tesla_44xx_pwrdm = {
/* wkup_44xx_pwrdm: Wake-up power domain */
static struct powerdomain wkup_44xx_pwrdm = {
.name = "wkup_pwrdm",
+ .voltdm = { .name = "wakeup" },
.prcm_offs = OMAP4430_PRM_WKUP_INST,
.prcm_partition = OMAP4430_PRM_PARTITION,
- .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430),
.pwrsts = PWRSTS_ON,
.banks = 1,
.pwrsts_mem_ret = {
@@ -152,9 +152,9 @@ static struct powerdomain wkup_44xx_pwrdm = {
/* cpu0_44xx_pwrdm: MPU0 processor and Neon coprocessor power domain */
static struct powerdomain cpu0_44xx_pwrdm = {
.name = "cpu0_pwrdm",
+ .voltdm = { .name = "mpu" },
.prcm_offs = OMAP4430_PRCM_MPU_CPU0_INST,
.prcm_partition = OMAP4430_PRCM_MPU_PARTITION,
- .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430),
.pwrsts = PWRSTS_OFF_RET_ON,
.pwrsts_logic_ret = PWRSTS_OFF_RET,
.banks = 1,
@@ -169,9 +169,9 @@ static struct powerdomain cpu0_44xx_pwrdm = {
/* cpu1_44xx_pwrdm: MPU1 processor and Neon coprocessor power domain */
static struct powerdomain cpu1_44xx_pwrdm = {
.name = "cpu1_pwrdm",
+ .voltdm = { .name = "mpu" },
.prcm_offs = OMAP4430_PRCM_MPU_CPU1_INST,
.prcm_partition = OMAP4430_PRCM_MPU_PARTITION,
- .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430),
.pwrsts = PWRSTS_OFF_RET_ON,
.pwrsts_logic_ret = PWRSTS_OFF_RET,
.banks = 1,
@@ -186,9 +186,9 @@ static struct powerdomain cpu1_44xx_pwrdm = {
/* emu_44xx_pwrdm: Emulation power domain */
static struct powerdomain emu_44xx_pwrdm = {
.name = "emu_pwrdm",
+ .voltdm = { .name = "wakeup" },
.prcm_offs = OMAP4430_PRM_EMU_INST,
.prcm_partition = OMAP4430_PRM_PARTITION,
- .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430),
.pwrsts = PWRSTS_OFF_ON,
.banks = 1,
.pwrsts_mem_ret = {
@@ -202,9 +202,9 @@ static struct powerdomain emu_44xx_pwrdm = {
/* mpu_44xx_pwrdm: Modena processor and the Neon coprocessor power domain */
static struct powerdomain mpu_44xx_pwrdm = {
.name = "mpu_pwrdm",
+ .voltdm = { .name = "mpu" },
.prcm_offs = OMAP4430_PRM_MPU_INST,
.prcm_partition = OMAP4430_PRM_PARTITION,
- .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430),
.pwrsts = PWRSTS_RET_ON,
.pwrsts_logic_ret = PWRSTS_OFF_RET,
.banks = 3,
@@ -223,9 +223,9 @@ static struct powerdomain mpu_44xx_pwrdm = {
/* ivahd_44xx_pwrdm: IVA-HD power domain */
static struct powerdomain ivahd_44xx_pwrdm = {
.name = "ivahd_pwrdm",
+ .voltdm = { .name = "iva" },
.prcm_offs = OMAP4430_PRM_IVAHD_INST,
.prcm_partition = OMAP4430_PRM_PARTITION,
- .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430),
.pwrsts = PWRSTS_OFF_RET_ON,
.pwrsts_logic_ret = PWRSTS_OFF,
.banks = 4,
@@ -247,9 +247,9 @@ static struct powerdomain ivahd_44xx_pwrdm = {
/* cam_44xx_pwrdm: Camera subsystem power domain */
static struct powerdomain cam_44xx_pwrdm = {
.name = "cam_pwrdm",
+ .voltdm = { .name = "core" },
.prcm_offs = OMAP4430_PRM_CAM_INST,
.prcm_partition = OMAP4430_PRM_PARTITION,
- .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430),
.pwrsts = PWRSTS_OFF_ON,
.banks = 1,
.pwrsts_mem_ret = {
@@ -264,9 +264,9 @@ static struct powerdomain cam_44xx_pwrdm = {
/* l3init_44xx_pwrdm: L3 initators pheripherals power domain */
static struct powerdomain l3init_44xx_pwrdm = {
.name = "l3init_pwrdm",
+ .voltdm = { .name = "core" },
.prcm_offs = OMAP4430_PRM_L3INIT_INST,
.prcm_partition = OMAP4430_PRM_PARTITION,
- .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430),
.pwrsts = PWRSTS_RET_ON,
.pwrsts_logic_ret = PWRSTS_OFF_RET,
.banks = 1,
@@ -282,9 +282,9 @@ static struct powerdomain l3init_44xx_pwrdm = {
/* l4per_44xx_pwrdm: Target peripherals power domain */
static struct powerdomain l4per_44xx_pwrdm = {
.name = "l4per_pwrdm",
+ .voltdm = { .name = "core" },
.prcm_offs = OMAP4430_PRM_L4PER_INST,
.prcm_partition = OMAP4430_PRM_PARTITION,
- .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430),
.pwrsts = PWRSTS_RET_ON,
.pwrsts_logic_ret = PWRSTS_OFF_RET,
.banks = 2,
@@ -305,18 +305,18 @@ static struct powerdomain l4per_44xx_pwrdm = {
*/
static struct powerdomain always_on_core_44xx_pwrdm = {
.name = "always_on_core_pwrdm",
+ .voltdm = { .name = "core" },
.prcm_offs = OMAP4430_PRM_ALWAYS_ON_INST,
.prcm_partition = OMAP4430_PRM_PARTITION,
- .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430),
.pwrsts = PWRSTS_ON,
};
/* cefuse_44xx_pwrdm: Customer efuse controller power domain */
static struct powerdomain cefuse_44xx_pwrdm = {
.name = "cefuse_pwrdm",
+ .voltdm = { .name = "core" },
.prcm_offs = OMAP4430_PRM_CEFUSE_INST,
.prcm_partition = OMAP4430_PRM_PARTITION,
- .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430),
.pwrsts = PWRSTS_OFF_ON,
.flags = PWRDM_HAS_LOWPOWERSTATECHANGE,
};
@@ -352,5 +352,7 @@ static struct powerdomain *powerdomains_omap44xx[] __initdata = {
void __init omap44xx_powerdomains_init(void)
{
- pwrdm_init(powerdomains_omap44xx, &omap4_pwrdm_operations);
+ pwrdm_register_platform_funcs(&omap4_pwrdm_operations);
+ pwrdm_register_pwrdms(powerdomains_omap44xx);
+ pwrdm_complete_init();
}
diff --git a/arch/arm/mach-omap2/prm2xxx_3xxx.c b/arch/arm/mach-omap2/prm2xxx_3xxx.c
index 051213fbc346..f02d87f68e54 100644
--- a/arch/arm/mach-omap2/prm2xxx_3xxx.c
+++ b/arch/arm/mach-omap2/prm2xxx_3xxx.c
@@ -20,6 +20,8 @@
#include <plat/cpu.h>
#include <plat/prcm.h>
+#include "vp.h"
+
#include "prm2xxx_3xxx.h"
#include "cm2xxx_3xxx.h"
#include "prm-regbits-24xx.h"
@@ -156,3 +158,57 @@ int omap2_prm_deassert_hardreset(s16 prm_mod, u8 rst_shift, u8 st_shift)
return (c == MAX_MODULE_HARDRESET_WAIT) ? -EBUSY : 0;
}
+
+/* PRM VP */
+
+/*
+ * struct omap3_vp - OMAP3 VP register access description.
+ * @tranxdone_status: VP_TRANXDONE_ST bitmask in PRM_IRQSTATUS_MPU reg
+ */
+struct omap3_vp {
+ u32 tranxdone_status;
+};
+
+static struct omap3_vp omap3_vp[] = {
+ [OMAP3_VP_VDD_MPU_ID] = {
+ .tranxdone_status = OMAP3430_VP1_TRANXDONE_ST_MASK,
+ },
+ [OMAP3_VP_VDD_CORE_ID] = {
+ .tranxdone_status = OMAP3430_VP2_TRANXDONE_ST_MASK,
+ },
+};
+
+#define MAX_VP_ID ARRAY_SIZE(omap3_vp);
+
+u32 omap3_prm_vp_check_txdone(u8 vp_id)
+{
+ struct omap3_vp *vp = &omap3_vp[vp_id];
+ u32 irqstatus;
+
+ irqstatus = omap2_prm_read_mod_reg(OCP_MOD,
+ OMAP3_PRM_IRQSTATUS_MPU_OFFSET);
+ return irqstatus & vp->tranxdone_status;
+}
+
+void omap3_prm_vp_clear_txdone(u8 vp_id)
+{
+ struct omap3_vp *vp = &omap3_vp[vp_id];
+
+ omap2_prm_write_mod_reg(vp->tranxdone_status,
+ OCP_MOD, OMAP3_PRM_IRQSTATUS_MPU_OFFSET);
+}
+
+u32 omap3_prm_vcvp_read(u8 offset)
+{
+ return omap2_prm_read_mod_reg(OMAP3430_GR_MOD, offset);
+}
+
+void omap3_prm_vcvp_write(u32 val, u8 offset)
+{
+ omap2_prm_write_mod_reg(val, OMAP3430_GR_MOD, offset);
+}
+
+u32 omap3_prm_vcvp_rmw(u32 mask, u32 bits, u8 offset)
+{
+ return omap2_prm_rmw_mod_reg_bits(mask, bits, OMAP3430_GR_MOD, offset);
+}
diff --git a/arch/arm/mach-omap2/prm2xxx_3xxx.h b/arch/arm/mach-omap2/prm2xxx_3xxx.h
index a1fc62a39dbb..cef533df0861 100644
--- a/arch/arm/mach-omap2/prm2xxx_3xxx.h
+++ b/arch/arm/mach-omap2/prm2xxx_3xxx.h
@@ -303,7 +303,19 @@ extern int omap2_prm_is_hardreset_asserted(s16 prm_mod, u8 shift);
extern int omap2_prm_assert_hardreset(s16 prm_mod, u8 shift);
extern int omap2_prm_deassert_hardreset(s16 prm_mod, u8 rst_shift, u8 st_shift);
+/* OMAP3-specific VP functions */
+u32 omap3_prm_vp_check_txdone(u8 vp_id);
+void omap3_prm_vp_clear_txdone(u8 vp_id);
+
+/*
+ * OMAP3 access functions for voltage controller (VC) and
+ * voltage proccessor (VP) in the PRM.
+ */
+extern u32 omap3_prm_vcvp_read(u8 offset);
+extern void omap3_prm_vcvp_write(u32 val, u8 offset);
+extern u32 omap3_prm_vcvp_rmw(u32 mask, u32 bits, u8 offset);
#endif /* CONFIG_ARCH_OMAP4 */
+
#endif
/*
diff --git a/arch/arm/mach-omap2/prm44xx.c b/arch/arm/mach-omap2/prm44xx.c
index 00165558fc4d..495a31a7e8a7 100644
--- a/arch/arm/mach-omap2/prm44xx.c
+++ b/arch/arm/mach-omap2/prm44xx.c
@@ -21,8 +21,11 @@
#include <plat/cpu.h>
#include <plat/prcm.h>
+#include "vp.h"
#include "prm44xx.h"
#include "prm-regbits-44xx.h"
+#include "prcm44xx.h"
+#include "prminst44xx.h"
/* PRM low-level functions */
@@ -50,3 +53,71 @@ u32 omap4_prm_rmw_inst_reg_bits(u32 mask, u32 bits, s16 inst, s16 reg)
return v;
}
+
+/* PRM VP */
+
+/*
+ * struct omap4_vp - OMAP4 VP register access description.
+ * @irqstatus_mpu: offset to IRQSTATUS_MPU register for VP
+ * @tranxdone_status: VP_TRANXDONE_ST bitmask in PRM_IRQSTATUS_MPU reg
+ */
+struct omap4_vp {
+ u32 irqstatus_mpu;
+ u32 tranxdone_status;
+};
+
+static struct omap4_vp omap4_vp[] = {
+ [OMAP4_VP_VDD_MPU_ID] = {
+ .irqstatus_mpu = OMAP4_PRM_IRQSTATUS_MPU_2_OFFSET,
+ .tranxdone_status = OMAP4430_VP_MPU_TRANXDONE_ST_MASK,
+ },
+ [OMAP4_VP_VDD_IVA_ID] = {
+ .irqstatus_mpu = OMAP4_PRM_IRQSTATUS_MPU_OFFSET,
+ .tranxdone_status = OMAP4430_VP_IVA_TRANXDONE_ST_MASK,
+ },
+ [OMAP4_VP_VDD_CORE_ID] = {
+ .irqstatus_mpu = OMAP4_PRM_IRQSTATUS_MPU_OFFSET,
+ .tranxdone_status = OMAP4430_VP_CORE_TRANXDONE_ST_MASK,
+ },
+};
+
+u32 omap4_prm_vp_check_txdone(u8 vp_id)
+{
+ struct omap4_vp *vp = &omap4_vp[vp_id];
+ u32 irqstatus;
+
+ irqstatus = omap4_prminst_read_inst_reg(OMAP4430_PRM_PARTITION,
+ OMAP4430_PRM_OCP_SOCKET_INST,
+ vp->irqstatus_mpu);
+ return irqstatus & vp->tranxdone_status;
+}
+
+void omap4_prm_vp_clear_txdone(u8 vp_id)
+{
+ struct omap4_vp *vp = &omap4_vp[vp_id];
+
+ omap4_prminst_write_inst_reg(vp->tranxdone_status,
+ OMAP4430_PRM_PARTITION,
+ OMAP4430_PRM_OCP_SOCKET_INST,
+ vp->irqstatus_mpu);
+};
+
+u32 omap4_prm_vcvp_read(u8 offset)
+{
+ return omap4_prminst_read_inst_reg(OMAP4430_PRM_PARTITION,
+ OMAP4430_PRM_DEVICE_INST, offset);
+}
+
+void omap4_prm_vcvp_write(u32 val, u8 offset)
+{
+ omap4_prminst_write_inst_reg(val, OMAP4430_PRM_PARTITION,
+ OMAP4430_PRM_DEVICE_INST, offset);
+}
+
+u32 omap4_prm_vcvp_rmw(u32 mask, u32 bits, u8 offset)
+{
+ return omap4_prminst_rmw_inst_reg_bits(mask, bits,
+ OMAP4430_PRM_PARTITION,
+ OMAP4430_PRM_DEVICE_INST,
+ offset);
+}
diff --git a/arch/arm/mach-omap2/prm44xx.h b/arch/arm/mach-omap2/prm44xx.h
index 7dfa379b625d..3d66ccd849d2 100644
--- a/arch/arm/mach-omap2/prm44xx.h
+++ b/arch/arm/mach-omap2/prm44xx.h
@@ -751,6 +751,18 @@ extern u32 omap4_prm_read_inst_reg(s16 inst, u16 idx);
extern void omap4_prm_write_inst_reg(u32 val, s16 inst, u16 idx);
extern u32 omap4_prm_rmw_inst_reg_bits(u32 mask, u32 bits, s16 inst, s16 idx);
+/* OMAP4-specific VP functions */
+u32 omap4_prm_vp_check_txdone(u8 vp_id);
+void omap4_prm_vp_clear_txdone(u8 vp_id);
+
+/*
+ * OMAP4 access functions for voltage controller (VC) and
+ * voltage proccessor (VP) in the PRM.
+ */
+extern u32 omap4_prm_vcvp_read(u8 offset);
+extern void omap4_prm_vcvp_write(u32 val, u8 offset);
+extern u32 omap4_prm_vcvp_rmw(u32 mask, u32 bits, u8 offset);
+
# endif
#endif
diff --git a/arch/arm/mach-omap2/serial.c b/arch/arm/mach-omap2/serial.c
index 466fc722fa0f..9992dbfdfdb3 100644
--- a/arch/arm/mach-omap2/serial.c
+++ b/arch/arm/mach-omap2/serial.c
@@ -107,28 +107,6 @@ struct omap_uart_state {
static LIST_HEAD(uart_list);
static u8 num_uarts;
-static int uart_idle_hwmod(struct omap_device *od)
-{
- omap_hwmod_idle(od->hwmods[0]);
-
- return 0;
-}
-
-static int uart_enable_hwmod(struct omap_device *od)
-{
- omap_hwmod_enable(od->hwmods[0]);
-
- return 0;
-}
-
-static struct omap_device_pm_latency omap_uart_latency[] = {
- {
- .deactivate_func = uart_idle_hwmod,
- .activate_func = uart_enable_hwmod,
- .flags = OMAP_DEVICE_LATENCY_AUTO_ADJUST,
- },
-};
-
static inline unsigned int __serial_read_reg(struct uart_port *up,
int offset)
{
@@ -711,7 +689,7 @@ void __init omap_serial_init_port(struct omap_board_data *bdata)
{
struct omap_uart_state *uart;
struct omap_hwmod *oh;
- struct omap_device *od;
+ struct platform_device *pdev;
void *pdata = NULL;
u32 pdata_size = 0;
char *name;
@@ -799,20 +777,19 @@ void __init omap_serial_init_port(struct omap_board_data *bdata)
if (WARN_ON(!oh))
return;
- od = omap_device_build(name, uart->num, oh, pdata, pdata_size,
- omap_uart_latency,
- ARRAY_SIZE(omap_uart_latency), false);
- WARN(IS_ERR(od), "Could not build omap_device for %s: %s.\n",
+ pdev = omap_device_build(name, uart->num, oh, pdata, pdata_size,
+ NULL, 0, false);
+ WARN(IS_ERR(pdev), "Could not build omap_device for %s: %s.\n",
name, oh->name);
- omap_device_disable_idle_on_suspend(od);
+ omap_device_disable_idle_on_suspend(pdev);
oh->mux = omap_hwmod_mux_init(bdata->pads, bdata->pads_cnt);
uart->irq = oh->mpu_irqs[0].irq;
uart->regshift = 2;
uart->mapbase = oh->slaves[0]->addr->pa_start;
uart->membase = omap_hwmod_get_mpu_rt_va(oh);
- uart->pdev = &od->pdev;
+ uart->pdev = pdev;
oh->dev_attr = uart;
@@ -846,8 +823,8 @@ void __init omap_serial_init_port(struct omap_board_data *bdata)
if ((cpu_is_omap34xx() && uart->padconf) ||
(uart->wk_en && uart->wk_mask)) {
- device_init_wakeup(&od->pdev.dev, true);
- DEV_CREATE_FILE(&od->pdev.dev, &dev_attr_sleep_timeout);
+ device_init_wakeup(&pdev->dev, true);
+ DEV_CREATE_FILE(&pdev->dev, &dev_attr_sleep_timeout);
}
/* Enable the MDR1 errata for OMAP3 */
diff --git a/arch/arm/mach-omap2/smartreflex-class3.c b/arch/arm/mach-omap2/smartreflex-class3.c
index f438cf4d847b..53d9d0a5b39d 100644
--- a/arch/arm/mach-omap2/smartreflex-class3.c
+++ b/arch/arm/mach-omap2/smartreflex-class3.c
@@ -15,7 +15,7 @@
static int sr_class3_enable(struct voltagedomain *voltdm)
{
- unsigned long volt = omap_voltage_get_nom_volt(voltdm);
+ unsigned long volt = voltdm_get_voltage(voltdm);
if (!volt) {
pr_warning("%s: Curr voltage unknown. Cannot enable sr_%s\n",
@@ -32,7 +32,7 @@ static int sr_class3_disable(struct voltagedomain *voltdm, int is_volt_reset)
omap_vp_disable(voltdm);
sr_disable(voltdm);
if (is_volt_reset)
- omap_voltage_reset(voltdm);
+ voltdm_reset(voltdm);
return 0;
}
diff --git a/arch/arm/mach-omap2/smartreflex.c b/arch/arm/mach-omap2/smartreflex.c
index 34c01a7de810..bb606c9709b2 100644
--- a/arch/arm/mach-omap2/smartreflex.c
+++ b/arch/arm/mach-omap2/smartreflex.c
@@ -62,6 +62,7 @@ static LIST_HEAD(sr_list);
static struct omap_sr_class_data *sr_class;
static struct omap_sr_pmic_data *sr_pmic_data;
+static struct dentry *sr_dbg_dir;
static inline void sr_write_reg(struct omap_sr *sr, unsigned offset, u32 value)
{
@@ -826,9 +827,10 @@ static int __init omap_sr_probe(struct platform_device *pdev)
struct omap_sr *sr_info = kzalloc(sizeof(struct omap_sr), GFP_KERNEL);
struct omap_sr_data *pdata = pdev->dev.platform_data;
struct resource *mem, *irq;
- struct dentry *vdd_dbg_dir, *nvalue_dir;
+ struct dentry *nvalue_dir;
struct omap_volt_data *volt_data;
int i, ret = 0;
+ char *name;
if (!sr_info) {
dev_err(&pdev->dev, "%s: unable to allocate sr_info\n",
@@ -899,18 +901,25 @@ static int __init omap_sr_probe(struct platform_device *pdev)
}
dev_info(&pdev->dev, "%s: SmartReflex driver initialized\n", __func__);
+ if (!sr_dbg_dir) {
+ sr_dbg_dir = debugfs_create_dir("smartreflex", NULL);
+ if (!sr_dbg_dir) {
+ ret = PTR_ERR(sr_dbg_dir);
+ pr_err("%s:sr debugfs dir creation failed(%d)\n",
+ __func__, ret);
+ goto err_iounmap;
+ }
+ }
- /*
- * If the voltage domain debugfs directory is not created, do
- * not try to create rest of the debugfs entries.
- */
- vdd_dbg_dir = omap_voltage_get_dbgdir(sr_info->voltdm);
- if (!vdd_dbg_dir) {
- ret = -EINVAL;
+ name = kasprintf(GFP_KERNEL, "sr_%s", sr_info->voltdm->name);
+ if (!name) {
+ dev_err(&pdev->dev, "%s: Unable to alloc debugfs name\n",
+ __func__);
+ ret = -ENOMEM;
goto err_iounmap;
}
-
- sr_info->dbg_dir = debugfs_create_dir("smartreflex", vdd_dbg_dir);
+ sr_info->dbg_dir = debugfs_create_dir(name, sr_dbg_dir);
+ kfree(name);
if (IS_ERR(sr_info->dbg_dir)) {
dev_err(&pdev->dev, "%s: Unable to create debugfs directory\n",
__func__);
diff --git a/arch/arm/mach-omap2/sr_device.c b/arch/arm/mach-omap2/sr_device.c
index 10d3c5ee8018..9f43fcc05d3e 100644
--- a/arch/arm/mach-omap2/sr_device.c
+++ b/arch/arm/mach-omap2/sr_device.c
@@ -31,14 +31,6 @@
static bool sr_enable_on_init;
-static struct omap_device_pm_latency omap_sr_latency[] = {
- {
- .deactivate_func = omap_device_idle_hwmods,
- .activate_func = omap_device_enable_hwmods,
- .flags = OMAP_DEVICE_LATENCY_AUTO_ADJUST
- },
-};
-
/* Read EFUSE values from control registers for OMAP3430 */
static void __init sr_set_nvalues(struct omap_volt_data *volt_data,
struct omap_sr_data *sr_data)
@@ -80,7 +72,7 @@ static void __init sr_set_nvalues(struct omap_volt_data *volt_data,
static int sr_dev_init(struct omap_hwmod *oh, void *user)
{
struct omap_sr_data *sr_data;
- struct omap_device *od;
+ struct platform_device *pdev;
struct omap_volt_data *volt_data;
char *name = "smartreflex";
static int i;
@@ -102,7 +94,7 @@ static int sr_dev_init(struct omap_hwmod *oh, void *user)
sr_data->senn_mod = 0x1;
sr_data->senp_mod = 0x1;
- sr_data->voltdm = omap_voltage_domain_lookup(oh->vdd_name);
+ sr_data->voltdm = voltdm_lookup(oh->vdd_name);
if (IS_ERR(sr_data->voltdm)) {
pr_err("%s: Unable to get voltage domain pointer for VDD %s\n",
__func__, oh->vdd_name);
@@ -120,10 +112,9 @@ static int sr_dev_init(struct omap_hwmod *oh, void *user)
sr_data->enable_on_init = sr_enable_on_init;
- od = omap_device_build(name, i, oh, sr_data, sizeof(*sr_data),
- omap_sr_latency,
- ARRAY_SIZE(omap_sr_latency), 0);
- if (IS_ERR(od))
+ pdev = omap_device_build(name, i, oh, sr_data, sizeof(*sr_data),
+ NULL, 0, 0);
+ if (IS_ERR(pdev))
pr_warning("%s: Could not build omap_device for %s: %s.\n\n",
__func__, name, oh->name);
exit:
diff --git a/arch/arm/mach-omap2/timer.c b/arch/arm/mach-omap2/timer.c
index cf1de7d2630d..e49fc7be2229 100644
--- a/arch/arm/mach-omap2/timer.c
+++ b/arch/arm/mach-omap2/timer.c
@@ -35,6 +35,7 @@
#include <linux/irq.h>
#include <linux/clocksource.h>
#include <linux/clockchips.h>
+#include <linux/slab.h>
#include <asm/mach/time.h>
#include <plat/dmtimer.h>
@@ -42,6 +43,10 @@
#include <asm/sched_clock.h>
#include <plat/common.h>
#include <plat/omap_hwmod.h>
+#include <plat/omap_device.h>
+#include <plat/omap-pm.h>
+
+#include "powerdomain.h"
/* Parent clocks, eventually these will come from the clock framework */
@@ -67,7 +72,7 @@
/* MAX_GPTIMER_ID: number of GPTIMERs on the chip */
#define MAX_GPTIMER_ID 12
-u32 sys_timer_reserved;
+static u32 sys_timer_reserved;
/* Clockevent code */
@@ -78,7 +83,7 @@ static irqreturn_t omap2_gp_timer_interrupt(int irq, void *dev_id)
{
struct clock_event_device *evt = &clockevent_gpt;
- __omap_dm_timer_write_status(clkev.io_base, OMAP_TIMER_INT_OVERFLOW);
+ __omap_dm_timer_write_status(&clkev, OMAP_TIMER_INT_OVERFLOW);
evt->event_handler(evt);
return IRQ_HANDLED;
@@ -93,7 +98,7 @@ static struct irqaction omap2_gp_timer_irq = {
static int omap2_gp_timer_set_next_event(unsigned long cycles,
struct clock_event_device *evt)
{
- __omap_dm_timer_load_start(clkev.io_base, OMAP_TIMER_CTRL_ST,
+ __omap_dm_timer_load_start(&clkev, OMAP_TIMER_CTRL_ST,
0xffffffff - cycles, 1);
return 0;
@@ -104,16 +109,16 @@ static void omap2_gp_timer_set_mode(enum clock_event_mode mode,
{
u32 period;
- __omap_dm_timer_stop(clkev.io_base, 1, clkev.rate);
+ __omap_dm_timer_stop(&clkev, 1, clkev.rate);
switch (mode) {
case CLOCK_EVT_MODE_PERIODIC:
period = clkev.rate / HZ;
period -= 1;
/* Looks like we need to first set the load value separately */
- __omap_dm_timer_write(clkev.io_base, OMAP_TIMER_LOAD_REG,
+ __omap_dm_timer_write(&clkev, OMAP_TIMER_LOAD_REG,
0xffffffff - period, 1);
- __omap_dm_timer_load_start(clkev.io_base,
+ __omap_dm_timer_load_start(&clkev,
OMAP_TIMER_CTRL_AR | OMAP_TIMER_CTRL_ST,
0xffffffff - period, 1);
break;
@@ -189,7 +194,8 @@ static int __init omap_dm_timer_init_one(struct omap_dm_timer *timer,
clk_put(src);
}
}
- __omap_dm_timer_reset(timer->io_base, 1, 1);
+ __omap_dm_timer_init_regs(timer);
+ __omap_dm_timer_reset(timer, 1, 1);
timer->posted = 1;
timer->rate = clk_get_rate(timer->fclk);
@@ -210,7 +216,7 @@ static void __init omap2_gp_clockevent_init(int gptimer_id,
omap2_gp_timer_irq.dev_id = (void *)&clkev;
setup_irq(clkev.irq, &omap2_gp_timer_irq);
- __omap_dm_timer_int_enable(clkev.io_base, OMAP_TIMER_INT_OVERFLOW);
+ __omap_dm_timer_int_enable(&clkev, OMAP_TIMER_INT_OVERFLOW);
clockevent_gpt.mult = div_sc(clkev.rate, NSEC_PER_SEC,
clockevent_gpt.shift);
@@ -251,7 +257,7 @@ static struct omap_dm_timer clksrc;
static DEFINE_CLOCK_DATA(cd);
static cycle_t clocksource_read_cycles(struct clocksource *cs)
{
- return (cycle_t)__omap_dm_timer_read_counter(clksrc.io_base, 1);
+ return (cycle_t)__omap_dm_timer_read_counter(&clksrc, 1);
}
static struct clocksource clocksource_gpt = {
@@ -266,7 +272,7 @@ static void notrace dmtimer_update_sched_clock(void)
{
u32 cyc;
- cyc = __omap_dm_timer_read_counter(clksrc.io_base, 1);
+ cyc = __omap_dm_timer_read_counter(&clksrc, 1);
update_sched_clock(&cd, cyc, (u32)~0);
}
@@ -276,7 +282,7 @@ unsigned long long notrace sched_clock(void)
u32 cyc = 0;
if (clksrc.reserved)
- cyc = __omap_dm_timer_read_counter(clksrc.io_base, 1);
+ cyc = __omap_dm_timer_read_counter(&clksrc, 1);
return cyc_to_sched_clock(&cd, cyc, (u32)~0);
}
@@ -293,7 +299,7 @@ static void __init omap2_gp_clocksource_init(int gptimer_id,
pr_info("OMAP clocksource: GPTIMER%d at %lu Hz\n",
gptimer_id, clksrc.rate);
- __omap_dm_timer_load_start(clksrc.io_base,
+ __omap_dm_timer_load_start(&clksrc,
OMAP_TIMER_CTRL_ST | OMAP_TIMER_CTRL_AR, 0, 1);
init_sched_clock(&cd, dmtimer_update_sched_clock, 32, clksrc.rate);
@@ -341,3 +347,167 @@ static void __init omap4_timer_init(void)
}
OMAP_SYS_TIMER(4)
#endif
+
+/**
+ * omap2_dm_timer_set_src - change the timer input clock source
+ * @pdev: timer platform device pointer
+ * @source: array index of parent clock source
+ */
+static int omap2_dm_timer_set_src(struct platform_device *pdev, int source)
+{
+ int ret;
+ struct dmtimer_platform_data *pdata = pdev->dev.platform_data;
+ struct clk *fclk, *parent;
+ char *parent_name = NULL;
+
+ fclk = clk_get(&pdev->dev, "fck");
+ if (IS_ERR_OR_NULL(fclk)) {
+ dev_err(&pdev->dev, "%s: %d: clk_get() FAILED\n",
+ __func__, __LINE__);
+ return -EINVAL;
+ }
+
+ switch (source) {
+ case OMAP_TIMER_SRC_SYS_CLK:
+ parent_name = "sys_ck";
+ break;
+
+ case OMAP_TIMER_SRC_32_KHZ:
+ parent_name = "32k_ck";
+ break;
+
+ case OMAP_TIMER_SRC_EXT_CLK:
+ if (pdata->timer_ip_version == OMAP_TIMER_IP_VERSION_1) {
+ parent_name = "alt_ck";
+ break;
+ }
+ dev_err(&pdev->dev, "%s: %d: invalid clk src.\n",
+ __func__, __LINE__);
+ clk_put(fclk);
+ return -EINVAL;
+ }
+
+ parent = clk_get(&pdev->dev, parent_name);
+ if (IS_ERR_OR_NULL(parent)) {
+ dev_err(&pdev->dev, "%s: %d: clk_get() %s FAILED\n",
+ __func__, __LINE__, parent_name);
+ clk_put(fclk);
+ return -EINVAL;
+ }
+
+ ret = clk_set_parent(fclk, parent);
+ if (IS_ERR_VALUE(ret)) {
+ dev_err(&pdev->dev, "%s: clk_set_parent() to %s FAILED\n",
+ __func__, parent_name);
+ ret = -EINVAL;
+ }
+
+ clk_put(parent);
+ clk_put(fclk);
+
+ return ret;
+}
+
+struct omap_device_pm_latency omap2_dmtimer_latency[] = {
+ {
+ .deactivate_func = omap_device_idle_hwmods,
+ .activate_func = omap_device_enable_hwmods,
+ .flags = OMAP_DEVICE_LATENCY_AUTO_ADJUST,
+ },
+};
+
+/**
+ * omap_timer_init - build and register timer device with an
+ * associated timer hwmod
+ * @oh: timer hwmod pointer to be used to build timer device
+ * @user: parameter that can be passed from calling hwmod API
+ *
+ * Called by omap_hwmod_for_each_by_class to register each of the timer
+ * devices present in the system. The number of timer devices is known
+ * by parsing through the hwmod database for a given class name. At the
+ * end of function call memory is allocated for timer device and it is
+ * registered to the framework ready to be proved by the driver.
+ */
+static int __init omap_timer_init(struct omap_hwmod *oh, void *unused)
+{
+ int id;
+ int ret = 0;
+ char *name = "omap_timer";
+ struct dmtimer_platform_data *pdata;
+ struct platform_device *pdev;
+ struct omap_timer_capability_dev_attr *timer_dev_attr;
+ struct powerdomain *pwrdm;
+
+ pr_debug("%s: %s\n", __func__, oh->name);
+
+ /* on secure device, do not register secure timer */
+ timer_dev_attr = oh->dev_attr;
+ if (omap_type() != OMAP2_DEVICE_TYPE_GP && timer_dev_attr)
+ if (timer_dev_attr->timer_capability == OMAP_TIMER_SECURE)
+ return ret;
+
+ pdata = kzalloc(sizeof(*pdata), GFP_KERNEL);
+ if (!pdata) {
+ pr_err("%s: No memory for [%s]\n", __func__, oh->name);
+ return -ENOMEM;
+ }
+
+ /*
+ * Extract the IDs from name field in hwmod database
+ * and use the same for constructing ids' for the
+ * timer devices. In a way, we are avoiding usage of
+ * static variable witin the function to do the same.
+ * CAUTION: We have to be careful and make sure the
+ * name in hwmod database does not change in which case
+ * we might either make corresponding change here or
+ * switch back static variable mechanism.
+ */
+ sscanf(oh->name, "timer%2d", &id);
+
+ pdata->set_timer_src = omap2_dm_timer_set_src;
+ pdata->timer_ip_version = oh->class->rev;
+
+ /* Mark clocksource and clockevent timers as reserved */
+ if ((sys_timer_reserved >> (id - 1)) & 0x1)
+ pdata->reserved = 1;
+
+ pwrdm = omap_hwmod_get_pwrdm(oh);
+ pdata->loses_context = pwrdm_can_ever_lose_context(pwrdm);
+#ifdef CONFIG_PM
+ pdata->get_context_loss_count = omap_pm_get_dev_context_loss_count;
+#endif
+ pdev = omap_device_build(name, id, oh, pdata, sizeof(*pdata),
+ omap2_dmtimer_latency,
+ ARRAY_SIZE(omap2_dmtimer_latency),
+ 0);
+
+ if (IS_ERR(pdev)) {
+ pr_err("%s: Can't build omap_device for %s: %s.\n",
+ __func__, name, oh->name);
+ ret = -EINVAL;
+ }
+
+ kfree(pdata);
+
+ return ret;
+}
+
+/**
+ * omap2_dm_timer_init - top level regular device initialization
+ *
+ * Uses dedicated hwmod api to parse through hwmod database for
+ * given class name and then build and register the timer device.
+ */
+static int __init omap2_dm_timer_init(void)
+{
+ int ret;
+
+ ret = omap_hwmod_for_each_by_class("timer", omap_timer_init, NULL);
+ if (unlikely(ret)) {
+ pr_err("%s: device registration failed.\n", __func__);
+ return -EINVAL;
+ }
+
+ return 0;
+}
+arch_initcall(omap2_dm_timer_init);
diff --git a/arch/arm/mach-omap2/usb-musb.c b/arch/arm/mach-omap2/usb-musb.c
index a65145b02a55..47fb5d607630 100644
--- a/arch/arm/mach-omap2/usb-musb.c
+++ b/arch/arm/mach-omap2/usb-musb.c
@@ -60,14 +60,6 @@ static struct musb_hdrc_platform_data musb_plat = {
static u64 musb_dmamask = DMA_BIT_MASK(32);
-static struct omap_device_pm_latency omap_musb_latency[] = {
- {
- .deactivate_func = omap_device_idle_hwmods,
- .activate_func = omap_device_enable_hwmods,
- .flags = OMAP_DEVICE_LATENCY_AUTO_ADJUST,
- },
-};
-
static void usb_musb_mux_init(struct omap_musb_board_data *board_data)
{
switch (board_data->interface_type) {
@@ -115,7 +107,6 @@ static struct omap_musb_board_data musb_default_board_data = {
void __init usb_musb_init(struct omap_musb_board_data *musb_board_data)
{
struct omap_hwmod *oh;
- struct omap_device *od;
struct platform_device *pdev;
struct device *dev;
int bus_id = -1;
@@ -137,9 +128,6 @@ void __init usb_musb_init(struct omap_musb_board_data *musb_board_data)
musb_plat.mode = board_data->mode;
musb_plat.extvbus = board_data->extvbus;
- if (cpu_is_omap44xx())
- omap4430_phy_init(dev);
-
if (cpu_is_omap3517() || cpu_is_omap3505()) {
oh_name = "am35x_otg_hs";
name = "musb-am35x";
@@ -148,22 +136,19 @@ void __init usb_musb_init(struct omap_musb_board_data *musb_board_data)
name = "musb-omap2430";
}
- oh = omap_hwmod_lookup(oh_name);
- if (!oh) {
- pr_err("Could not look up %s\n", oh_name);
- return;
- }
+ oh = omap_hwmod_lookup(oh_name);
+ if (WARN(!oh, "%s: could not find omap_hwmod for %s\n",
+ __func__, oh_name))
+ return;
- od = omap_device_build(name, bus_id, oh, &musb_plat,
- sizeof(musb_plat), omap_musb_latency,
- ARRAY_SIZE(omap_musb_latency), false);
- if (IS_ERR(od)) {
+ pdev = omap_device_build(name, bus_id, oh, &musb_plat,
+ sizeof(musb_plat), NULL, 0, false);
+ if (IS_ERR(pdev)) {
pr_err("Could not build omap_device for %s %s\n",
name, oh_name);
return;
}
- pdev = &od->pdev;
dev = &pdev->dev;
get_device(dev);
dev->dma_mask = &musb_dmamask;
diff --git a/arch/arm/mach-omap2/vc.c b/arch/arm/mach-omap2/vc.c
new file mode 100644
index 000000000000..031d116fbf10
--- /dev/null
+++ b/arch/arm/mach-omap2/vc.c
@@ -0,0 +1,367 @@
+/*
+ * OMAP Voltage Controller (VC) interface
+ *
+ * Copyright (C) 2011 Texas Instruments, Inc.
+ *
+ * This file is licensed under the terms of the GNU General Public
+ * License version 2. This program is licensed "as is" without any
+ * warranty of any kind, whether express or implied.
+ */
+#include <linux/kernel.h>
+#include <linux/delay.h>
+#include <linux/init.h>
+
+#include <plat/cpu.h>
+
+#include "voltage.h"
+#include "vc.h"
+#include "prm-regbits-34xx.h"
+#include "prm-regbits-44xx.h"
+#include "prm44xx.h"
+
+/**
+ * struct omap_vc_channel_cfg - describe the cfg_channel bitfield
+ * @sa: bit for slave address
+ * @rav: bit for voltage configuration register
+ * @rac: bit for command configuration register
+ * @racen: enable bit for RAC
+ * @cmd: bit for command value set selection
+ *
+ * Channel configuration bits, common for OMAP3+
+ * OMAP3 register: PRM_VC_CH_CONF
+ * OMAP4 register: PRM_VC_CFG_CHANNEL
+ * OMAP5 register: PRM_VC_SMPS_<voltdm>_CONFIG
+ */
+struct omap_vc_channel_cfg {
+ u8 sa;
+ u8 rav;
+ u8 rac;
+ u8 racen;
+ u8 cmd;
+};
+
+static struct omap_vc_channel_cfg vc_default_channel_cfg = {
+ .sa = BIT(0),
+ .rav = BIT(1),
+ .rac = BIT(2),
+ .racen = BIT(3),
+ .cmd = BIT(4),
+};
+
+/*
+ * On OMAP3+, all VC channels have the above default bitfield
+ * configuration, except the OMAP4 MPU channel. This appears
+ * to be a freak accident as every other VC channel has the
+ * default configuration, thus creating a mutant channel config.
+ */
+static struct omap_vc_channel_cfg vc_mutant_channel_cfg = {
+ .sa = BIT(0),
+ .rav = BIT(2),
+ .rac = BIT(3),
+ .racen = BIT(4),
+ .cmd = BIT(1),
+};
+
+static struct omap_vc_channel_cfg *vc_cfg_bits;
+#define CFG_CHANNEL_MASK 0x1f
+
+/**
+ * omap_vc_config_channel - configure VC channel to PMIC mappings
+ * @voltdm: pointer to voltagdomain defining the desired VC channel
+ *
+ * Configures the VC channel to PMIC mappings for the following
+ * PMIC settings
+ * - i2c slave address (SA)
+ * - voltage configuration address (RAV)
+ * - command configuration address (RAC) and enable bit (RACEN)
+ * - command values for ON, ONLP, RET and OFF (CMD)
+ *
+ * This function currently only allows flexible configuration of the
+ * non-default channel. Starting with OMAP4, there are more than 2
+ * channels, with one defined as the default (on OMAP4, it's MPU.)
+ * Only the non-default channel can be configured.
+ */
+static int omap_vc_config_channel(struct voltagedomain *voltdm)
+{
+ struct omap_vc_channel *vc = voltdm->vc;
+
+ /*
+ * For default channel, the only configurable bit is RACEN.
+ * All others must stay at zero (see function comment above.)
+ */
+ if (vc->flags & OMAP_VC_CHANNEL_DEFAULT)
+ vc->cfg_channel &= vc_cfg_bits->racen;
+
+ voltdm->rmw(CFG_CHANNEL_MASK << vc->cfg_channel_sa_shift,
+ vc->cfg_channel << vc->cfg_channel_sa_shift,
+ vc->cfg_channel_reg);
+
+ return 0;
+}
+
+/* Voltage scale and accessory APIs */
+int omap_vc_pre_scale(struct voltagedomain *voltdm,
+ unsigned long target_volt,
+ u8 *target_vsel, u8 *current_vsel)
+{
+ struct omap_vc_channel *vc = voltdm->vc;
+ u32 vc_cmdval;
+
+ /* Check if sufficient pmic info is available for this vdd */
+ if (!voltdm->pmic) {
+ pr_err("%s: Insufficient pmic info to scale the vdd_%s\n",
+ __func__, voltdm->name);
+ return -EINVAL;
+ }
+
+ if (!voltdm->pmic->uv_to_vsel) {
+ pr_err("%s: PMIC function to convert voltage in uV to"
+ "vsel not registered. Hence unable to scale voltage"
+ "for vdd_%s\n", __func__, voltdm->name);
+ return -ENODATA;
+ }
+
+ if (!voltdm->read || !voltdm->write) {
+ pr_err("%s: No read/write API for accessing vdd_%s regs\n",
+ __func__, voltdm->name);
+ return -EINVAL;
+ }
+
+ *target_vsel = voltdm->pmic->uv_to_vsel(target_volt);
+ *current_vsel = voltdm->pmic->uv_to_vsel(voltdm->nominal_volt);
+
+ /* Setting the ON voltage to the new target voltage */
+ vc_cmdval = voltdm->read(vc->cmdval_reg);
+ vc_cmdval &= ~vc->common->cmd_on_mask;
+ vc_cmdval |= (*target_vsel << vc->common->cmd_on_shift);
+ voltdm->write(vc_cmdval, vc->cmdval_reg);
+
+ omap_vp_update_errorgain(voltdm, target_volt);
+
+ return 0;
+}
+
+void omap_vc_post_scale(struct voltagedomain *voltdm,
+ unsigned long target_volt,
+ u8 target_vsel, u8 current_vsel)
+{
+ u32 smps_steps = 0, smps_delay = 0;
+
+ smps_steps = abs(target_vsel - current_vsel);
+ /* SMPS slew rate / step size. 2us added as buffer. */
+ smps_delay = ((smps_steps * voltdm->pmic->step_size) /
+ voltdm->pmic->slew_rate) + 2;
+ udelay(smps_delay);
+}
+
+/* vc_bypass_scale - VC bypass method of voltage scaling */
+int omap_vc_bypass_scale(struct voltagedomain *voltdm,
+ unsigned long target_volt)
+{
+ struct omap_vc_channel *vc = voltdm->vc;
+ u32 loop_cnt = 0, retries_cnt = 0;
+ u32 vc_valid, vc_bypass_val_reg, vc_bypass_value;
+ u8 target_vsel, current_vsel;
+ int ret;
+
+ ret = omap_vc_pre_scale(voltdm, target_volt, &target_vsel, &current_vsel);
+ if (ret)
+ return ret;
+
+ vc_valid = vc->common->valid;
+ vc_bypass_val_reg = vc->common->bypass_val_reg;
+ vc_bypass_value = (target_vsel << vc->common->data_shift) |
+ (vc->volt_reg_addr << vc->common->regaddr_shift) |
+ (vc->i2c_slave_addr << vc->common->slaveaddr_shift);
+
+ voltdm->write(vc_bypass_value, vc_bypass_val_reg);
+ voltdm->write(vc_bypass_value | vc_valid, vc_bypass_val_reg);
+
+ vc_bypass_value = voltdm->read(vc_bypass_val_reg);
+ /*
+ * Loop till the bypass command is acknowledged from the SMPS.
+ * NOTE: This is legacy code. The loop count and retry count needs
+ * to be revisited.
+ */
+ while (!(vc_bypass_value & vc_valid)) {
+ loop_cnt++;
+
+ if (retries_cnt > 10) {
+ pr_warning("%s: Retry count exceeded\n", __func__);
+ return -ETIMEDOUT;
+ }
+
+ if (loop_cnt > 50) {
+ retries_cnt++;
+ loop_cnt = 0;
+ udelay(10);
+ }
+ vc_bypass_value = voltdm->read(vc_bypass_val_reg);
+ }
+
+ omap_vc_post_scale(voltdm, target_volt, target_vsel, current_vsel);
+ return 0;
+}
+
+static void __init omap3_vfsm_init(struct voltagedomain *voltdm)
+{
+ /*
+ * Voltage Manager FSM parameters init
+ * XXX This data should be passed in from the board file
+ */
+ voltdm->write(OMAP3_CLKSETUP, OMAP3_PRM_CLKSETUP_OFFSET);
+ voltdm->write(OMAP3_VOLTOFFSET, OMAP3_PRM_VOLTOFFSET_OFFSET);
+ voltdm->write(OMAP3_VOLTSETUP2, OMAP3_PRM_VOLTSETUP2_OFFSET);
+}
+
+static void __init omap3_vc_init_channel(struct voltagedomain *voltdm)
+{
+ static bool is_initialized;
+
+ if (is_initialized)
+ return;
+
+ omap3_vfsm_init(voltdm);
+
+ is_initialized = true;
+}
+
+
+/* OMAP4 specific voltage init functions */
+static void __init omap4_vc_init_channel(struct voltagedomain *voltdm)
+{
+ static bool is_initialized;
+ u32 vc_val;
+
+ if (is_initialized)
+ return;
+
+ /* XXX These are magic numbers and do not belong! */
+ vc_val = (0x60 << OMAP4430_SCLL_SHIFT | 0x26 << OMAP4430_SCLH_SHIFT);
+ voltdm->write(vc_val, OMAP4_PRM_VC_CFG_I2C_CLK_OFFSET);
+
+ is_initialized = true;
+}
+
+/**
+ * omap_vc_i2c_init - initialize I2C interface to PMIC
+ * @voltdm: voltage domain containing VC data
+ *
+ * Use PMIC supplied seetings for I2C high-speed mode and
+ * master code (if set) and program the VC I2C configuration
+ * register.
+ *
+ * The VC I2C configuration is common to all VC channels,
+ * so this function only configures I2C for the first VC
+ * channel registers. All other VC channels will use the
+ * same configuration.
+ */
+static void __init omap_vc_i2c_init(struct voltagedomain *voltdm)
+{
+ struct omap_vc_channel *vc = voltdm->vc;
+ static bool initialized;
+ static bool i2c_high_speed;
+ u8 mcode;
+
+ if (initialized) {
+ if (voltdm->pmic->i2c_high_speed != i2c_high_speed)
+ pr_warn("%s: I2C config for all channels must match.",
+ __func__);
+ return;
+ }
+
+ i2c_high_speed = voltdm->pmic->i2c_high_speed;
+ if (i2c_high_speed)
+ voltdm->rmw(vc->common->i2c_cfg_hsen_mask,
+ vc->common->i2c_cfg_hsen_mask,
+ vc->common->i2c_cfg_reg);
+
+ mcode = voltdm->pmic->i2c_mcode;
+ if (mcode)
+ voltdm->rmw(vc->common->i2c_mcode_mask,
+ mcode << __ffs(vc->common->i2c_mcode_mask),
+ vc->common->i2c_cfg_reg);
+
+ initialized = true;
+}
+
+void __init omap_vc_init_channel(struct voltagedomain *voltdm)
+{
+ struct omap_vc_channel *vc = voltdm->vc;
+ u8 on_vsel, onlp_vsel, ret_vsel, off_vsel;
+ u32 val;
+
+ if (!voltdm->pmic || !voltdm->pmic->uv_to_vsel) {
+ pr_err("%s: PMIC info requried to configure vc for"
+ "vdd_%s not populated.Hence cannot initialize vc\n",
+ __func__, voltdm->name);
+ return;
+ }
+
+ if (!voltdm->read || !voltdm->write) {
+ pr_err("%s: No read/write API for accessing vdd_%s regs\n",
+ __func__, voltdm->name);
+ return;
+ }
+
+ vc->cfg_channel = 0;
+ if (vc->flags & OMAP_VC_CHANNEL_CFG_MUTANT)
+ vc_cfg_bits = &vc_mutant_channel_cfg;
+ else
+ vc_cfg_bits = &vc_default_channel_cfg;
+
+ /* get PMIC/board specific settings */
+ vc->i2c_slave_addr = voltdm->pmic->i2c_slave_addr;
+ vc->volt_reg_addr = voltdm->pmic->volt_reg_addr;
+ vc->cmd_reg_addr = voltdm->pmic->cmd_reg_addr;
+ vc->setup_time = voltdm->pmic->volt_setup_time;
+
+ /* Configure the i2c slave address for this VC */
+ voltdm->rmw(vc->smps_sa_mask,
+ vc->i2c_slave_addr << __ffs(vc->smps_sa_mask),
+ vc->smps_sa_reg);
+ vc->cfg_channel |= vc_cfg_bits->sa;
+
+ /*
+ * Configure the PMIC register addresses.
+ */
+ voltdm->rmw(vc->smps_volra_mask,
+ vc->volt_reg_addr << __ffs(vc->smps_volra_mask),
+ vc->smps_volra_reg);
+ vc->cfg_channel |= vc_cfg_bits->rav;
+
+ if (vc->cmd_reg_addr) {
+ voltdm->rmw(vc->smps_cmdra_mask,
+ vc->cmd_reg_addr << __ffs(vc->smps_cmdra_mask),
+ vc->smps_cmdra_reg);
+ vc->cfg_channel |= vc_cfg_bits->rac | vc_cfg_bits->racen;
+ }
+
+ /* Set up the on, inactive, retention and off voltage */
+ on_vsel = voltdm->pmic->uv_to_vsel(voltdm->pmic->on_volt);
+ onlp_vsel = voltdm->pmic->uv_to_vsel(voltdm->pmic->onlp_volt);
+ ret_vsel = voltdm->pmic->uv_to_vsel(voltdm->pmic->ret_volt);
+ off_vsel = voltdm->pmic->uv_to_vsel(voltdm->pmic->off_volt);
+ val = ((on_vsel << vc->common->cmd_on_shift) |
+ (onlp_vsel << vc->common->cmd_onlp_shift) |
+ (ret_vsel << vc->common->cmd_ret_shift) |
+ (off_vsel << vc->common->cmd_off_shift));
+ voltdm->write(val, vc->cmdval_reg);
+ vc->cfg_channel |= vc_cfg_bits->cmd;
+
+ /* Channel configuration */
+ omap_vc_config_channel(voltdm);
+
+ /* Configure the setup times */
+ voltdm->rmw(voltdm->vfsm->voltsetup_mask,
+ vc->setup_time << __ffs(voltdm->vfsm->voltsetup_mask),
+ voltdm->vfsm->voltsetup_reg);
+
+ omap_vc_i2c_init(voltdm);
+
+ if (cpu_is_omap34xx())
+ omap3_vc_init_channel(voltdm);
+ else if (cpu_is_omap44xx())
+ omap4_vc_init_channel(voltdm);
+}
+
diff --git a/arch/arm/mach-omap2/vc.h b/arch/arm/mach-omap2/vc.h
index e7767771de49..478bf6b432c4 100644
--- a/arch/arm/mach-omap2/vc.h
+++ b/arch/arm/mach-omap2/vc.h
@@ -19,12 +19,12 @@
#include <linux/kernel.h>
+struct voltagedomain;
+
/**
- * struct omap_vc_common_data - per-VC register/bitfield data
+ * struct omap_vc_common - per-VC register/bitfield data
* @cmd_on_mask: ON bitmask in PRM_VC_CMD_VAL* register
* @valid: VALID bitmask in PRM_VC_BYPASS_VAL register
- * @smps_sa_reg: Offset of PRM_VC_SMPS_SA reg from PRM start
- * @smps_volra_reg: Offset of PRM_VC_SMPS_VOL_RA reg from PRM start
* @bypass_val_reg: Offset of PRM_VC_BYPASS_VAL reg from PRM start
* @data_shift: DATA field shift in PRM_VC_BYPASS_VAL register
* @slaveaddr_shift: SLAVEADDR field shift in PRM_VC_BYPASS_VAL register
@@ -33,15 +33,16 @@
* @cmd_onlp_shift: ONLP field shift in PRM_VC_CMD_VAL_* register
* @cmd_ret_shift: RET field shift in PRM_VC_CMD_VAL_* register
* @cmd_off_shift: OFF field shift in PRM_VC_CMD_VAL_* register
+ * @i2c_cfg_reg: I2C configuration register offset
+ * @i2c_cfg_hsen_mask: high-speed mode bit field mask in I2C config register
+ * @i2c_mcode_mask: MCODE field mask for I2C config register
*
* XXX One of cmd_on_mask and cmd_on_shift are not needed
* XXX VALID should probably be a shift, not a mask
*/
-struct omap_vc_common_data {
+struct omap_vc_common {
u32 cmd_on_mask;
u32 valid;
- u8 smps_sa_reg;
- u8 smps_volra_reg;
u8 bypass_val_reg;
u8 data_shift;
u8 slaveaddr_shift;
@@ -50,34 +51,75 @@ struct omap_vc_common_data {
u8 cmd_onlp_shift;
u8 cmd_ret_shift;
u8 cmd_off_shift;
+ u8 i2c_cfg_reg;
+ u8 i2c_cfg_hsen_mask;
+ u8 i2c_mcode_mask;
};
+/* omap_vc_channel.flags values */
+#define OMAP_VC_CHANNEL_DEFAULT BIT(0)
+#define OMAP_VC_CHANNEL_CFG_MUTANT BIT(1)
+
/**
- * struct omap_vc_instance_data - VC per-instance data
- * @vc_common: pointer to VC common data for this platform
- * @smps_sa_mask: SA* bitmask in the PRM_VC_SMPS_SA register
- * @smps_volra_mask: VOLRA* bitmask in the PRM_VC_VOL_RA register
- * @smps_sa_shift: SA* field shift in the PRM_VC_SMPS_SA register
- * @smps_volra_shift: VOLRA* field shift in the PRM_VC_VOL_RA register
+ * struct omap_vc_channel - VC per-instance data
+ * @i2c_slave_addr: I2C slave address of PMIC for this VC channel
+ * @volt_reg_addr: voltage configuration register address
+ * @cmd_reg_addr: command configuration register address
+ * @setup_time: setup time (in sys_clk cycles) of regulator for this channel
+ * @cfg_channel: current value of VC channel configuration register
+ * @i2c_high_speed: whether or not to use I2C high-speed mode
*
- * XXX It is not necessary to have both a *_mask and a *_shift -
- * remove one
+ * @common: pointer to VC common data for this platform
+ * @smps_sa_mask: i2c slave address bitmask in the PRM_VC_SMPS_SA register
+ * @smps_volra_mask: VOLRA* bitmask in the PRM_VC_VOL_RA register
+ * @smps_cmdra_mask: CMDRA* bitmask in the PRM_VC_CMD_RA register
+ * @cmdval_reg: register for on/ret/off voltage level values for this channel
+ * @smps_sa_reg: Offset of PRM_VC_SMPS_SA reg from PRM start
+ * @smps_volra_reg: Offset of PRM_VC_SMPS_VOL_RA reg from PRM start
+ * @smps_cmdra_reg: Offset of PRM_VC_SMPS_CMD_RA reg from PRM start
+ * @cfg_channel_reg: VC channel configuration register
+ * @cfg_channel_sa_shift: bit shift for slave address cfg_channel register
+ * @flags: VC channel-specific flags (optional)
*/
-struct omap_vc_instance_data {
- const struct omap_vc_common_data *vc_common;
+struct omap_vc_channel {
+ /* channel state */
+ u16 i2c_slave_addr;
+ u16 volt_reg_addr;
+ u16 cmd_reg_addr;
+ u16 setup_time;
+ u8 cfg_channel;
+ bool i2c_high_speed;
+
+ /* register access data */
+ const struct omap_vc_common *common;
u32 smps_sa_mask;
u32 smps_volra_mask;
+ u32 smps_cmdra_mask;
u8 cmdval_reg;
- u8 smps_sa_shift;
- u8 smps_volra_shift;
+ u8 smps_sa_reg;
+ u8 smps_volra_reg;
+ u8 smps_cmdra_reg;
+ u8 cfg_channel_reg;
+ u8 cfg_channel_sa_shift;
+ u8 flags;
};
-extern struct omap_vc_instance_data omap3_vc1_data;
-extern struct omap_vc_instance_data omap3_vc2_data;
+extern struct omap_vc_channel omap3_vc_mpu;
+extern struct omap_vc_channel omap3_vc_core;
+
+extern struct omap_vc_channel omap4_vc_mpu;
+extern struct omap_vc_channel omap4_vc_iva;
+extern struct omap_vc_channel omap4_vc_core;
-extern struct omap_vc_instance_data omap4_vc_mpu_data;
-extern struct omap_vc_instance_data omap4_vc_iva_data;
-extern struct omap_vc_instance_data omap4_vc_core_data;
+void omap_vc_init_channel(struct voltagedomain *voltdm);
+int omap_vc_pre_scale(struct voltagedomain *voltdm,
+ unsigned long target_volt,
+ u8 *target_vsel, u8 *current_vsel);
+void omap_vc_post_scale(struct voltagedomain *voltdm,
+ unsigned long target_volt,
+ u8 target_vsel, u8 current_vsel);
+int omap_vc_bypass_scale(struct voltagedomain *voltdm,
+ unsigned long target_volt);
#endif
diff --git a/arch/arm/mach-omap2/vc3xxx_data.c b/arch/arm/mach-omap2/vc3xxx_data.c
index f37dc4bc379a..cfe348e1af0e 100644
--- a/arch/arm/mach-omap2/vc3xxx_data.c
+++ b/arch/arm/mach-omap2/vc3xxx_data.c
@@ -29,9 +29,7 @@
* VC data common to 34xx/36xx chips
* XXX This stuff presumably belongs in the vc3xxx.c or vc.c file.
*/
-static struct omap_vc_common_data omap3_vc_common = {
- .smps_sa_reg = OMAP3_PRM_VC_SMPS_SA_OFFSET,
- .smps_volra_reg = OMAP3_PRM_VC_SMPS_VOL_RA_OFFSET,
+static struct omap_vc_common omap3_vc_common = {
.bypass_val_reg = OMAP3_PRM_VC_BYPASS_VAL_OFFSET,
.data_shift = OMAP3430_DATA_SHIFT,
.slaveaddr_shift = OMAP3430_SLAVEADDR_SHIFT,
@@ -42,22 +40,33 @@ static struct omap_vc_common_data omap3_vc_common = {
.cmd_onlp_shift = OMAP3430_VC_CMD_ONLP_SHIFT,
.cmd_ret_shift = OMAP3430_VC_CMD_RET_SHIFT,
.cmd_off_shift = OMAP3430_VC_CMD_OFF_SHIFT,
+ .i2c_cfg_hsen_mask = OMAP3430_HSEN_MASK,
+ .i2c_cfg_reg = OMAP3_PRM_VC_I2C_CFG_OFFSET,
+ .i2c_mcode_mask = OMAP3430_MCODE_MASK,
};
-struct omap_vc_instance_data omap3_vc1_data = {
- .vc_common = &omap3_vc_common,
+struct omap_vc_channel omap3_vc_mpu = {
+ .common = &omap3_vc_common,
+ .smps_sa_reg = OMAP3_PRM_VC_SMPS_SA_OFFSET,
+ .smps_volra_reg = OMAP3_PRM_VC_SMPS_VOL_RA_OFFSET,
+ .smps_cmdra_reg = OMAP3_PRM_VC_SMPS_CMD_RA_OFFSET,
+ .cfg_channel_reg = OMAP3_PRM_VC_CH_CONF_OFFSET,
.cmdval_reg = OMAP3_PRM_VC_CMD_VAL_0_OFFSET,
- .smps_sa_shift = OMAP3430_PRM_VC_SMPS_SA_SA0_SHIFT,
.smps_sa_mask = OMAP3430_PRM_VC_SMPS_SA_SA0_MASK,
- .smps_volra_shift = OMAP3430_VOLRA0_SHIFT,
.smps_volra_mask = OMAP3430_VOLRA0_MASK,
+ .smps_cmdra_mask = OMAP3430_CMDRA0_MASK,
+ .cfg_channel_sa_shift = OMAP3430_PRM_VC_SMPS_SA_SA0_SHIFT,
};
-struct omap_vc_instance_data omap3_vc2_data = {
- .vc_common = &omap3_vc_common,
+struct omap_vc_channel omap3_vc_core = {
+ .common = &omap3_vc_common,
+ .smps_sa_reg = OMAP3_PRM_VC_SMPS_SA_OFFSET,
+ .smps_volra_reg = OMAP3_PRM_VC_SMPS_VOL_RA_OFFSET,
+ .smps_cmdra_reg = OMAP3_PRM_VC_SMPS_CMD_RA_OFFSET,
+ .cfg_channel_reg = OMAP3_PRM_VC_CH_CONF_OFFSET,
.cmdval_reg = OMAP3_PRM_VC_CMD_VAL_1_OFFSET,
- .smps_sa_shift = OMAP3430_PRM_VC_SMPS_SA_SA1_SHIFT,
.smps_sa_mask = OMAP3430_PRM_VC_SMPS_SA_SA1_MASK,
- .smps_volra_shift = OMAP3430_VOLRA1_SHIFT,
.smps_volra_mask = OMAP3430_VOLRA1_MASK,
+ .smps_cmdra_mask = OMAP3430_CMDRA1_MASK,
+ .cfg_channel_sa_shift = OMAP3430_PRM_VC_SMPS_SA_SA1_SHIFT,
};
diff --git a/arch/arm/mach-omap2/vc44xx_data.c b/arch/arm/mach-omap2/vc44xx_data.c
index a98da8ddec52..2740a968145e 100644
--- a/arch/arm/mach-omap2/vc44xx_data.c
+++ b/arch/arm/mach-omap2/vc44xx_data.c
@@ -30,9 +30,7 @@
* VC data common to 44xx chips
* XXX This stuff presumably belongs in the vc3xxx.c or vc.c file.
*/
-static const struct omap_vc_common_data omap4_vc_common = {
- .smps_sa_reg = OMAP4_PRM_VC_SMPS_SA_OFFSET,
- .smps_volra_reg = OMAP4_PRM_VC_VAL_SMPS_RA_VOL_OFFSET,
+static const struct omap_vc_common omap4_vc_common = {
.bypass_val_reg = OMAP4_PRM_VC_VAL_BYPASS_OFFSET,
.data_shift = OMAP4430_DATA_SHIFT,
.slaveaddr_shift = OMAP4430_SLAVEADDR_SHIFT,
@@ -43,33 +41,49 @@ static const struct omap_vc_common_data omap4_vc_common = {
.cmd_onlp_shift = OMAP4430_ONLP_SHIFT,
.cmd_ret_shift = OMAP4430_RET_SHIFT,
.cmd_off_shift = OMAP4430_OFF_SHIFT,
+ .i2c_cfg_reg = OMAP4_PRM_VC_CFG_I2C_MODE_OFFSET,
+ .i2c_cfg_hsen_mask = OMAP4430_HSMODEEN_MASK,
+ .i2c_mcode_mask = OMAP4430_HSMCODE_MASK,
};
/* VC instance data for each controllable voltage line */
-struct omap_vc_instance_data omap4_vc_mpu_data = {
- .vc_common = &omap4_vc_common,
+struct omap_vc_channel omap4_vc_mpu = {
+ .flags = OMAP_VC_CHANNEL_DEFAULT | OMAP_VC_CHANNEL_CFG_MUTANT,
+ .common = &omap4_vc_common,
+ .smps_sa_reg = OMAP4_PRM_VC_SMPS_SA_OFFSET,
+ .smps_volra_reg = OMAP4_PRM_VC_VAL_SMPS_RA_VOL_OFFSET,
+ .smps_cmdra_reg = OMAP4_PRM_VC_VAL_SMPS_RA_CMD_OFFSET,
+ .cfg_channel_reg = OMAP4_PRM_VC_CFG_CHANNEL_OFFSET,
.cmdval_reg = OMAP4_PRM_VC_VAL_CMD_VDD_MPU_L_OFFSET,
- .smps_sa_shift = OMAP4430_SA_VDD_MPU_L_PRM_VC_SMPS_SA_SHIFT,
.smps_sa_mask = OMAP4430_SA_VDD_MPU_L_PRM_VC_SMPS_SA_MASK,
- .smps_volra_shift = OMAP4430_VOLRA_VDD_MPU_L_SHIFT,
.smps_volra_mask = OMAP4430_VOLRA_VDD_MPU_L_MASK,
+ .smps_cmdra_mask = OMAP4430_CMDRA_VDD_MPU_L_MASK,
+ .cfg_channel_sa_shift = OMAP4430_SA_VDD_MPU_L_SHIFT,
};
-struct omap_vc_instance_data omap4_vc_iva_data = {
- .vc_common = &omap4_vc_common,
+struct omap_vc_channel omap4_vc_iva = {
+ .common = &omap4_vc_common,
+ .smps_sa_reg = OMAP4_PRM_VC_SMPS_SA_OFFSET,
+ .smps_volra_reg = OMAP4_PRM_VC_VAL_SMPS_RA_VOL_OFFSET,
+ .smps_cmdra_reg = OMAP4_PRM_VC_VAL_SMPS_RA_CMD_OFFSET,
+ .cfg_channel_reg = OMAP4_PRM_VC_CFG_CHANNEL_OFFSET,
.cmdval_reg = OMAP4_PRM_VC_VAL_CMD_VDD_IVA_L_OFFSET,
- .smps_sa_shift = OMAP4430_SA_VDD_IVA_L_PRM_VC_SMPS_SA_SHIFT,
.smps_sa_mask = OMAP4430_SA_VDD_IVA_L_PRM_VC_SMPS_SA_MASK,
- .smps_volra_shift = OMAP4430_VOLRA_VDD_IVA_L_SHIFT,
.smps_volra_mask = OMAP4430_VOLRA_VDD_IVA_L_MASK,
+ .smps_cmdra_mask = OMAP4430_CMDRA_VDD_IVA_L_MASK,
+ .cfg_channel_sa_shift = OMAP4430_SA_VDD_IVA_L_SHIFT,
};
-struct omap_vc_instance_data omap4_vc_core_data = {
- .vc_common = &omap4_vc_common,
+struct omap_vc_channel omap4_vc_core = {
+ .common = &omap4_vc_common,
+ .smps_sa_reg = OMAP4_PRM_VC_SMPS_SA_OFFSET,
+ .smps_volra_reg = OMAP4_PRM_VC_VAL_SMPS_RA_VOL_OFFSET,
+ .smps_cmdra_reg = OMAP4_PRM_VC_VAL_SMPS_RA_CMD_OFFSET,
+ .cfg_channel_reg = OMAP4_PRM_VC_CFG_CHANNEL_OFFSET,
.cmdval_reg = OMAP4_PRM_VC_VAL_CMD_VDD_CORE_L_OFFSET,
- .smps_sa_shift = OMAP4430_SA_VDD_CORE_L_0_6_SHIFT,
.smps_sa_mask = OMAP4430_SA_VDD_CORE_L_0_6_MASK,
- .smps_volra_shift = OMAP4430_VOLRA_VDD_CORE_L_SHIFT,
.smps_volra_mask = OMAP4430_VOLRA_VDD_CORE_L_MASK,
+ .smps_cmdra_mask = OMAP4430_CMDRA_VDD_CORE_L_MASK,
+ .cfg_channel_sa_shift = OMAP4430_SA_VDD_CORE_L_SHIFT,
};
diff --git a/arch/arm/mach-omap2/voltage.c b/arch/arm/mach-omap2/voltage.c
index 9ef3789ded4b..64070ac1e761 100644
--- a/arch/arm/mach-omap2/voltage.c
+++ b/arch/arm/mach-omap2/voltage.c
@@ -21,10 +21,10 @@
#include <linux/delay.h>
#include <linux/io.h>
-#include <linux/clk.h>
#include <linux/err.h>
#include <linux/debugfs.h>
#include <linux/slab.h>
+#include <linux/clk.h>
#include <plat/common.h>
@@ -36,839 +36,88 @@
#include "control.h"
#include "voltage.h"
+#include "powerdomain.h"
#include "vc.h"
#include "vp.h"
-#define VOLTAGE_DIR_SIZE 16
-
-
-static struct omap_vdd_info **vdd_info;
-
-/*
- * Number of scalable voltage domains.
- */
-static int nr_scalable_vdd;
-
-/* XXX document */
-static s16 prm_mod_offs;
-static s16 prm_irqst_ocp_mod_offs;
-
-static struct dentry *voltage_dir;
-
-/* Init function pointers */
-static int vp_forceupdate_scale_voltage(struct omap_vdd_info *vdd,
- unsigned long target_volt);
-
-static u32 omap3_voltage_read_reg(u16 mod, u8 offset)
-{
- return omap2_prm_read_mod_reg(mod, offset);
-}
-
-static void omap3_voltage_write_reg(u32 val, u16 mod, u8 offset)
-{
- omap2_prm_write_mod_reg(val, mod, offset);
-}
-
-static u32 omap4_voltage_read_reg(u16 mod, u8 offset)
-{
- return omap4_prminst_read_inst_reg(OMAP4430_PRM_PARTITION,
- mod, offset);
-}
-
-static void omap4_voltage_write_reg(u32 val, u16 mod, u8 offset)
-{
- omap4_prminst_write_inst_reg(val, OMAP4430_PRM_PARTITION, mod, offset);
-}
-
-static int __init _config_common_vdd_data(struct omap_vdd_info *vdd)
-{
- char *sys_ck_name;
- struct clk *sys_ck;
- u32 sys_clk_speed, timeout_val, waittime;
-
- /*
- * XXX Clockfw should handle this, or this should be in a
- * struct record
- */
- if (cpu_is_omap24xx() || cpu_is_omap34xx())
- sys_ck_name = "sys_ck";
- else if (cpu_is_omap44xx())
- sys_ck_name = "sys_clkin_ck";
- else
- return -EINVAL;
-
- /*
- * Sys clk rate is require to calculate vp timeout value and
- * smpswaittimemin and smpswaittimemax.
- */
- sys_ck = clk_get(NULL, sys_ck_name);
- if (IS_ERR(sys_ck)) {
- pr_warning("%s: Could not get the sys clk to calculate"
- "various vdd_%s params\n", __func__, vdd->voltdm.name);
- return -EINVAL;
- }
- sys_clk_speed = clk_get_rate(sys_ck);
- clk_put(sys_ck);
- /* Divide to avoid overflow */
- sys_clk_speed /= 1000;
-
- /* Generic voltage parameters */
- vdd->volt_scale = vp_forceupdate_scale_voltage;
- vdd->vp_enabled = false;
-
- vdd->vp_rt_data.vpconfig_erroroffset =
- (vdd->pmic_info->vp_erroroffset <<
- vdd->vp_data->vp_common->vpconfig_erroroffset_shift);
-
- timeout_val = (sys_clk_speed * vdd->pmic_info->vp_timeout_us) / 1000;
- vdd->vp_rt_data.vlimitto_timeout = timeout_val;
- vdd->vp_rt_data.vlimitto_vddmin = vdd->pmic_info->vp_vddmin;
- vdd->vp_rt_data.vlimitto_vddmax = vdd->pmic_info->vp_vddmax;
-
- waittime = ((vdd->pmic_info->step_size / vdd->pmic_info->slew_rate) *
- sys_clk_speed) / 1000;
- vdd->vp_rt_data.vstepmin_smpswaittimemin = waittime;
- vdd->vp_rt_data.vstepmax_smpswaittimemax = waittime;
- vdd->vp_rt_data.vstepmin_stepmin = vdd->pmic_info->vp_vstepmin;
- vdd->vp_rt_data.vstepmax_stepmax = vdd->pmic_info->vp_vstepmax;
-
- return 0;
-}
-
-/* Voltage debugfs support */
-static int vp_volt_debug_get(void *data, u64 *val)
-{
- struct omap_vdd_info *vdd = (struct omap_vdd_info *) data;
- u8 vsel;
-
- if (!vdd) {
- pr_warning("Wrong paramater passed\n");
- return -EINVAL;
- }
-
- vsel = vdd->read_reg(prm_mod_offs, vdd->vp_data->voltage);
-
- if (!vdd->pmic_info->vsel_to_uv) {
- pr_warning("PMIC function to convert vsel to voltage"
- "in uV not registerd\n");
- return -EINVAL;
- }
-
- *val = vdd->pmic_info->vsel_to_uv(vsel);
- return 0;
-}
-
-static int nom_volt_debug_get(void *data, u64 *val)
-{
- struct omap_vdd_info *vdd = (struct omap_vdd_info *) data;
-
- if (!vdd) {
- pr_warning("Wrong paramater passed\n");
- return -EINVAL;
- }
-
- *val = omap_voltage_get_nom_volt(&vdd->voltdm);
-
- return 0;
-}
-
-DEFINE_SIMPLE_ATTRIBUTE(vp_volt_debug_fops, vp_volt_debug_get, NULL, "%llu\n");
-DEFINE_SIMPLE_ATTRIBUTE(nom_volt_debug_fops, nom_volt_debug_get, NULL,
- "%llu\n");
-static void vp_latch_vsel(struct omap_vdd_info *vdd)
-{
- u32 vpconfig;
- unsigned long uvdc;
- char vsel;
-
- uvdc = omap_voltage_get_nom_volt(&vdd->voltdm);
- if (!uvdc) {
- pr_warning("%s: unable to find current voltage for vdd_%s\n",
- __func__, vdd->voltdm.name);
- return;
- }
-
- if (!vdd->pmic_info || !vdd->pmic_info->uv_to_vsel) {
- pr_warning("%s: PMIC function to convert voltage in uV to"
- " vsel not registered\n", __func__);
- return;
- }
-
- vsel = vdd->pmic_info->uv_to_vsel(uvdc);
-
- vpconfig = vdd->read_reg(prm_mod_offs, vdd->vp_data->vpconfig);
- vpconfig &= ~(vdd->vp_data->vp_common->vpconfig_initvoltage_mask |
- vdd->vp_data->vp_common->vpconfig_initvdd);
- vpconfig |= vsel << vdd->vp_data->vp_common->vpconfig_initvoltage_shift;
-
- vdd->write_reg(vpconfig, prm_mod_offs, vdd->vp_data->vpconfig);
-
- /* Trigger initVDD value copy to voltage processor */
- vdd->write_reg((vpconfig | vdd->vp_data->vp_common->vpconfig_initvdd),
- prm_mod_offs, vdd->vp_data->vpconfig);
-
- /* Clear initVDD copy trigger bit */
- vdd->write_reg(vpconfig, prm_mod_offs, vdd->vp_data->vpconfig);
-}
-
-/* Generic voltage init functions */
-static void __init vp_init(struct omap_vdd_info *vdd)
-{
- u32 vp_val;
-
- if (!vdd->read_reg || !vdd->write_reg) {
- pr_err("%s: No read/write API for accessing vdd_%s regs\n",
- __func__, vdd->voltdm.name);
- return;
- }
-
- vp_val = vdd->vp_rt_data.vpconfig_erroroffset |
- (vdd->vp_rt_data.vpconfig_errorgain <<
- vdd->vp_data->vp_common->vpconfig_errorgain_shift) |
- vdd->vp_data->vp_common->vpconfig_timeouten;
- vdd->write_reg(vp_val, prm_mod_offs, vdd->vp_data->vpconfig);
-
- vp_val = ((vdd->vp_rt_data.vstepmin_smpswaittimemin <<
- vdd->vp_data->vp_common->vstepmin_smpswaittimemin_shift) |
- (vdd->vp_rt_data.vstepmin_stepmin <<
- vdd->vp_data->vp_common->vstepmin_stepmin_shift));
- vdd->write_reg(vp_val, prm_mod_offs, vdd->vp_data->vstepmin);
-
- vp_val = ((vdd->vp_rt_data.vstepmax_smpswaittimemax <<
- vdd->vp_data->vp_common->vstepmax_smpswaittimemax_shift) |
- (vdd->vp_rt_data.vstepmax_stepmax <<
- vdd->vp_data->vp_common->vstepmax_stepmax_shift));
- vdd->write_reg(vp_val, prm_mod_offs, vdd->vp_data->vstepmax);
-
- vp_val = ((vdd->vp_rt_data.vlimitto_vddmax <<
- vdd->vp_data->vp_common->vlimitto_vddmax_shift) |
- (vdd->vp_rt_data.vlimitto_vddmin <<
- vdd->vp_data->vp_common->vlimitto_vddmin_shift) |
- (vdd->vp_rt_data.vlimitto_timeout <<
- vdd->vp_data->vp_common->vlimitto_timeout_shift));
- vdd->write_reg(vp_val, prm_mod_offs, vdd->vp_data->vlimitto);
-}
-
-static void __init vdd_debugfs_init(struct omap_vdd_info *vdd)
-{
- char *name;
-
- name = kzalloc(VOLTAGE_DIR_SIZE, GFP_KERNEL);
- if (!name) {
- pr_warning("%s: Unable to allocate memory for debugfs"
- " directory name for vdd_%s",
- __func__, vdd->voltdm.name);
- return;
- }
- strcpy(name, "vdd_");
- strcat(name, vdd->voltdm.name);
-
- vdd->debug_dir = debugfs_create_dir(name, voltage_dir);
- kfree(name);
- if (IS_ERR(vdd->debug_dir)) {
- pr_warning("%s: Unable to create debugfs directory for"
- " vdd_%s\n", __func__, vdd->voltdm.name);
- vdd->debug_dir = NULL;
- return;
- }
-
- (void) debugfs_create_x16("vp_errorgain", S_IRUGO, vdd->debug_dir,
- &(vdd->vp_rt_data.vpconfig_errorgain));
- (void) debugfs_create_x16("vp_smpswaittimemin", S_IRUGO,
- vdd->debug_dir,
- &(vdd->vp_rt_data.vstepmin_smpswaittimemin));
- (void) debugfs_create_x8("vp_stepmin", S_IRUGO, vdd->debug_dir,
- &(vdd->vp_rt_data.vstepmin_stepmin));
- (void) debugfs_create_x16("vp_smpswaittimemax", S_IRUGO,
- vdd->debug_dir,
- &(vdd->vp_rt_data.vstepmax_smpswaittimemax));
- (void) debugfs_create_x8("vp_stepmax", S_IRUGO, vdd->debug_dir,
- &(vdd->vp_rt_data.vstepmax_stepmax));
- (void) debugfs_create_x8("vp_vddmax", S_IRUGO, vdd->debug_dir,
- &(vdd->vp_rt_data.vlimitto_vddmax));
- (void) debugfs_create_x8("vp_vddmin", S_IRUGO, vdd->debug_dir,
- &(vdd->vp_rt_data.vlimitto_vddmin));
- (void) debugfs_create_x16("vp_timeout", S_IRUGO, vdd->debug_dir,
- &(vdd->vp_rt_data.vlimitto_timeout));
- (void) debugfs_create_file("curr_vp_volt", S_IRUGO, vdd->debug_dir,
- (void *) vdd, &vp_volt_debug_fops);
- (void) debugfs_create_file("curr_nominal_volt", S_IRUGO,
- vdd->debug_dir, (void *) vdd,
- &nom_volt_debug_fops);
-}
-
-/* Voltage scale and accessory APIs */
-static int _pre_volt_scale(struct omap_vdd_info *vdd,
- unsigned long target_volt, u8 *target_vsel, u8 *current_vsel)
-{
- struct omap_volt_data *volt_data;
- const struct omap_vc_common_data *vc_common;
- const struct omap_vp_common_data *vp_common;
- u32 vc_cmdval, vp_errgain_val;
-
- vc_common = vdd->vc_data->vc_common;
- vp_common = vdd->vp_data->vp_common;
-
- /* Check if suffiecient pmic info is available for this vdd */
- if (!vdd->pmic_info) {
- pr_err("%s: Insufficient pmic info to scale the vdd_%s\n",
- __func__, vdd->voltdm.name);
- return -EINVAL;
- }
-
- if (!vdd->pmic_info->uv_to_vsel) {
- pr_err("%s: PMIC function to convert voltage in uV to"
- "vsel not registered. Hence unable to scale voltage"
- "for vdd_%s\n", __func__, vdd->voltdm.name);
- return -ENODATA;
- }
-
- if (!vdd->read_reg || !vdd->write_reg) {
- pr_err("%s: No read/write API for accessing vdd_%s regs\n",
- __func__, vdd->voltdm.name);
- return -EINVAL;
- }
-
- /* Get volt_data corresponding to target_volt */
- volt_data = omap_voltage_get_voltdata(&vdd->voltdm, target_volt);
- if (IS_ERR(volt_data))
- volt_data = NULL;
-
- *target_vsel = vdd->pmic_info->uv_to_vsel(target_volt);
- *current_vsel = vdd->read_reg(prm_mod_offs, vdd->vp_data->voltage);
-
- /* Setting the ON voltage to the new target voltage */
- vc_cmdval = vdd->read_reg(prm_mod_offs, vdd->vc_data->cmdval_reg);
- vc_cmdval &= ~vc_common->cmd_on_mask;
- vc_cmdval |= (*target_vsel << vc_common->cmd_on_shift);
- vdd->write_reg(vc_cmdval, prm_mod_offs, vdd->vc_data->cmdval_reg);
-
- /* Setting vp errorgain based on the voltage */
- if (volt_data) {
- vp_errgain_val = vdd->read_reg(prm_mod_offs,
- vdd->vp_data->vpconfig);
- vdd->vp_rt_data.vpconfig_errorgain = volt_data->vp_errgain;
- vp_errgain_val &= ~vp_common->vpconfig_errorgain_mask;
- vp_errgain_val |= vdd->vp_rt_data.vpconfig_errorgain <<
- vp_common->vpconfig_errorgain_shift;
- vdd->write_reg(vp_errgain_val, prm_mod_offs,
- vdd->vp_data->vpconfig);
- }
-
- return 0;
-}
-
-static void _post_volt_scale(struct omap_vdd_info *vdd,
- unsigned long target_volt, u8 target_vsel, u8 current_vsel)
-{
- u32 smps_steps = 0, smps_delay = 0;
-
- smps_steps = abs(target_vsel - current_vsel);
- /* SMPS slew rate / step size. 2us added as buffer. */
- smps_delay = ((smps_steps * vdd->pmic_info->step_size) /
- vdd->pmic_info->slew_rate) + 2;
- udelay(smps_delay);
-
- vdd->curr_volt = target_volt;
-}
-
-/* vc_bypass_scale_voltage - VC bypass method of voltage scaling */
-static int vc_bypass_scale_voltage(struct omap_vdd_info *vdd,
- unsigned long target_volt)
-{
- u32 loop_cnt = 0, retries_cnt = 0;
- u32 vc_valid, vc_bypass_val_reg, vc_bypass_value;
- u8 target_vsel, current_vsel;
- int ret;
-
- ret = _pre_volt_scale(vdd, target_volt, &target_vsel, &current_vsel);
- if (ret)
- return ret;
-
- vc_valid = vdd->vc_data->vc_common->valid;
- vc_bypass_val_reg = vdd->vc_data->vc_common->bypass_val_reg;
- vc_bypass_value = (target_vsel << vdd->vc_data->vc_common->data_shift) |
- (vdd->pmic_info->pmic_reg <<
- vdd->vc_data->vc_common->regaddr_shift) |
- (vdd->pmic_info->i2c_slave_addr <<
- vdd->vc_data->vc_common->slaveaddr_shift);
-
- vdd->write_reg(vc_bypass_value, prm_mod_offs, vc_bypass_val_reg);
- vdd->write_reg(vc_bypass_value | vc_valid, prm_mod_offs,
- vc_bypass_val_reg);
-
- vc_bypass_value = vdd->read_reg(prm_mod_offs, vc_bypass_val_reg);
- /*
- * Loop till the bypass command is acknowledged from the SMPS.
- * NOTE: This is legacy code. The loop count and retry count needs
- * to be revisited.
- */
- while (!(vc_bypass_value & vc_valid)) {
- loop_cnt++;
-
- if (retries_cnt > 10) {
- pr_warning("%s: Retry count exceeded\n", __func__);
- return -ETIMEDOUT;
- }
-
- if (loop_cnt > 50) {
- retries_cnt++;
- loop_cnt = 0;
- udelay(10);
- }
- vc_bypass_value = vdd->read_reg(prm_mod_offs,
- vc_bypass_val_reg);
- }
-
- _post_volt_scale(vdd, target_volt, target_vsel, current_vsel);
- return 0;
-}
-
-/* VP force update method of voltage scaling */
-static int vp_forceupdate_scale_voltage(struct omap_vdd_info *vdd,
- unsigned long target_volt)
-{
- u32 vpconfig;
- u8 target_vsel, current_vsel, prm_irqst_reg;
- int ret, timeout = 0;
-
- ret = _pre_volt_scale(vdd, target_volt, &target_vsel, &current_vsel);
- if (ret)
- return ret;
-
- prm_irqst_reg = vdd->vp_data->prm_irqst_data->prm_irqst_reg;
-
- /*
- * Clear all pending TransactionDone interrupt/status. Typical latency
- * is <3us
- */
- while (timeout++ < VP_TRANXDONE_TIMEOUT) {
- vdd->write_reg(vdd->vp_data->prm_irqst_data->tranxdone_status,
- prm_irqst_ocp_mod_offs, prm_irqst_reg);
- if (!(vdd->read_reg(prm_irqst_ocp_mod_offs, prm_irqst_reg) &
- vdd->vp_data->prm_irqst_data->tranxdone_status))
- break;
- udelay(1);
- }
- if (timeout >= VP_TRANXDONE_TIMEOUT) {
- pr_warning("%s: vdd_%s TRANXDONE timeout exceeded."
- "Voltage change aborted", __func__, vdd->voltdm.name);
- return -ETIMEDOUT;
- }
-
- /* Configure for VP-Force Update */
- vpconfig = vdd->read_reg(prm_mod_offs, vdd->vp_data->vpconfig);
- vpconfig &= ~(vdd->vp_data->vp_common->vpconfig_initvdd |
- vdd->vp_data->vp_common->vpconfig_forceupdate |
- vdd->vp_data->vp_common->vpconfig_initvoltage_mask);
- vpconfig |= ((target_vsel <<
- vdd->vp_data->vp_common->vpconfig_initvoltage_shift));
- vdd->write_reg(vpconfig, prm_mod_offs, vdd->vp_data->vpconfig);
-
- /* Trigger initVDD value copy to voltage processor */
- vpconfig |= vdd->vp_data->vp_common->vpconfig_initvdd;
- vdd->write_reg(vpconfig, prm_mod_offs, vdd->vp_data->vpconfig);
-
- /* Force update of voltage */
- vpconfig |= vdd->vp_data->vp_common->vpconfig_forceupdate;
- vdd->write_reg(vpconfig, prm_mod_offs, vdd->vp_data->vpconfig);
-
- /*
- * Wait for TransactionDone. Typical latency is <200us.
- * Depends on SMPSWAITTIMEMIN/MAX and voltage change
- */
- timeout = 0;
- omap_test_timeout((vdd->read_reg(prm_irqst_ocp_mod_offs, prm_irqst_reg) &
- vdd->vp_data->prm_irqst_data->tranxdone_status),
- VP_TRANXDONE_TIMEOUT, timeout);
- if (timeout >= VP_TRANXDONE_TIMEOUT)
- pr_err("%s: vdd_%s TRANXDONE timeout exceeded."
- "TRANXDONE never got set after the voltage update\n",
- __func__, vdd->voltdm.name);
-
- _post_volt_scale(vdd, target_volt, target_vsel, current_vsel);
-
- /*
- * Disable TransactionDone interrupt , clear all status, clear
- * control registers
- */
- timeout = 0;
- while (timeout++ < VP_TRANXDONE_TIMEOUT) {
- vdd->write_reg(vdd->vp_data->prm_irqst_data->tranxdone_status,
- prm_irqst_ocp_mod_offs, prm_irqst_reg);
- if (!(vdd->read_reg(prm_irqst_ocp_mod_offs, prm_irqst_reg) &
- vdd->vp_data->prm_irqst_data->tranxdone_status))
- break;
- udelay(1);
- }
-
- if (timeout >= VP_TRANXDONE_TIMEOUT)
- pr_warning("%s: vdd_%s TRANXDONE timeout exceeded while trying"
- "to clear the TRANXDONE status\n",
- __func__, vdd->voltdm.name);
-
- vpconfig = vdd->read_reg(prm_mod_offs, vdd->vp_data->vpconfig);
- /* Clear initVDD copy trigger bit */
- vpconfig &= ~vdd->vp_data->vp_common->vpconfig_initvdd;
- vdd->write_reg(vpconfig, prm_mod_offs, vdd->vp_data->vpconfig);
- /* Clear force bit */
- vpconfig &= ~vdd->vp_data->vp_common->vpconfig_forceupdate;
- vdd->write_reg(vpconfig, prm_mod_offs, vdd->vp_data->vpconfig);
-
- return 0;
-}
-
-static void __init omap3_vfsm_init(struct omap_vdd_info *vdd)
-{
- /*
- * Voltage Manager FSM parameters init
- * XXX This data should be passed in from the board file
- */
- vdd->write_reg(OMAP3_CLKSETUP, prm_mod_offs, OMAP3_PRM_CLKSETUP_OFFSET);
- vdd->write_reg(OMAP3_VOLTOFFSET, prm_mod_offs,
- OMAP3_PRM_VOLTOFFSET_OFFSET);
- vdd->write_reg(OMAP3_VOLTSETUP2, prm_mod_offs,
- OMAP3_PRM_VOLTSETUP2_OFFSET);
-}
-
-static void __init omap3_vc_init(struct omap_vdd_info *vdd)
-{
- static bool is_initialized;
- u8 on_vsel, onlp_vsel, ret_vsel, off_vsel;
- u32 vc_val;
-
- if (is_initialized)
- return;
-
- /* Set up the on, inactive, retention and off voltage */
- on_vsel = vdd->pmic_info->uv_to_vsel(vdd->pmic_info->on_volt);
- onlp_vsel = vdd->pmic_info->uv_to_vsel(vdd->pmic_info->onlp_volt);
- ret_vsel = vdd->pmic_info->uv_to_vsel(vdd->pmic_info->ret_volt);
- off_vsel = vdd->pmic_info->uv_to_vsel(vdd->pmic_info->off_volt);
- vc_val = ((on_vsel << vdd->vc_data->vc_common->cmd_on_shift) |
- (onlp_vsel << vdd->vc_data->vc_common->cmd_onlp_shift) |
- (ret_vsel << vdd->vc_data->vc_common->cmd_ret_shift) |
- (off_vsel << vdd->vc_data->vc_common->cmd_off_shift));
- vdd->write_reg(vc_val, prm_mod_offs, vdd->vc_data->cmdval_reg);
-
- /*
- * Generic VC parameters init
- * XXX This data should be abstracted out
- */
- vdd->write_reg(OMAP3430_CMD1_MASK | OMAP3430_RAV1_MASK, prm_mod_offs,
- OMAP3_PRM_VC_CH_CONF_OFFSET);
- vdd->write_reg(OMAP3430_MCODE_SHIFT | OMAP3430_HSEN_MASK, prm_mod_offs,
- OMAP3_PRM_VC_I2C_CFG_OFFSET);
-
- omap3_vfsm_init(vdd);
-
- is_initialized = true;
-}
-
-
-/* OMAP4 specific voltage init functions */
-static void __init omap4_vc_init(struct omap_vdd_info *vdd)
-{
- static bool is_initialized;
- u32 vc_val;
-
- if (is_initialized)
- return;
-
- /* TODO: Configure setup times and CMD_VAL values*/
-
- /*
- * Generic VC parameters init
- * XXX This data should be abstracted out
- */
- vc_val = (OMAP4430_RAV_VDD_MPU_L_MASK | OMAP4430_CMD_VDD_MPU_L_MASK |
- OMAP4430_RAV_VDD_IVA_L_MASK | OMAP4430_CMD_VDD_IVA_L_MASK |
- OMAP4430_RAV_VDD_CORE_L_MASK | OMAP4430_CMD_VDD_CORE_L_MASK);
- vdd->write_reg(vc_val, prm_mod_offs, OMAP4_PRM_VC_CFG_CHANNEL_OFFSET);
-
- /* XXX These are magic numbers and do not belong! */
- vc_val = (0x60 << OMAP4430_SCLL_SHIFT | 0x26 << OMAP4430_SCLH_SHIFT);
- vdd->write_reg(vc_val, prm_mod_offs, OMAP4_PRM_VC_CFG_I2C_CLK_OFFSET);
-
- is_initialized = true;
-}
-
-static void __init omap_vc_init(struct omap_vdd_info *vdd)
-{
- u32 vc_val;
-
- if (!vdd->pmic_info || !vdd->pmic_info->uv_to_vsel) {
- pr_err("%s: PMIC info requried to configure vc for"
- "vdd_%s not populated.Hence cannot initialize vc\n",
- __func__, vdd->voltdm.name);
- return;
- }
-
- if (!vdd->read_reg || !vdd->write_reg) {
- pr_err("%s: No read/write API for accessing vdd_%s regs\n",
- __func__, vdd->voltdm.name);
- return;
- }
-
- /* Set up the SMPS_SA(i2c slave address in VC */
- vc_val = vdd->read_reg(prm_mod_offs,
- vdd->vc_data->vc_common->smps_sa_reg);
- vc_val &= ~vdd->vc_data->smps_sa_mask;
- vc_val |= vdd->pmic_info->i2c_slave_addr << vdd->vc_data->smps_sa_shift;
- vdd->write_reg(vc_val, prm_mod_offs,
- vdd->vc_data->vc_common->smps_sa_reg);
-
- /* Setup the VOLRA(pmic reg addr) in VC */
- vc_val = vdd->read_reg(prm_mod_offs,
- vdd->vc_data->vc_common->smps_volra_reg);
- vc_val &= ~vdd->vc_data->smps_volra_mask;
- vc_val |= vdd->pmic_info->pmic_reg << vdd->vc_data->smps_volra_shift;
- vdd->write_reg(vc_val, prm_mod_offs,
- vdd->vc_data->vc_common->smps_volra_reg);
-
- /* Configure the setup times */
- vc_val = vdd->read_reg(prm_mod_offs, vdd->vfsm->voltsetup_reg);
- vc_val &= ~vdd->vfsm->voltsetup_mask;
- vc_val |= vdd->pmic_info->volt_setup_time <<
- vdd->vfsm->voltsetup_shift;
- vdd->write_reg(vc_val, prm_mod_offs, vdd->vfsm->voltsetup_reg);
-
- if (cpu_is_omap34xx())
- omap3_vc_init(vdd);
- else if (cpu_is_omap44xx())
- omap4_vc_init(vdd);
-}
-
-static int __init omap_vdd_data_configure(struct omap_vdd_info *vdd)
-{
- int ret = -EINVAL;
-
- if (!vdd->pmic_info) {
- pr_err("%s: PMIC info requried to configure vdd_%s not"
- "populated.Hence cannot initialize vdd_%s\n",
- __func__, vdd->voltdm.name, vdd->voltdm.name);
- goto ovdc_out;
- }
-
- if (IS_ERR_VALUE(_config_common_vdd_data(vdd)))
- goto ovdc_out;
-
- if (cpu_is_omap34xx()) {
- vdd->read_reg = omap3_voltage_read_reg;
- vdd->write_reg = omap3_voltage_write_reg;
- ret = 0;
- } else if (cpu_is_omap44xx()) {
- vdd->read_reg = omap4_voltage_read_reg;
- vdd->write_reg = omap4_voltage_write_reg;
- ret = 0;
- }
-
-ovdc_out:
- return ret;
-}
+static LIST_HEAD(voltdm_list);
/* Public functions */
/**
- * omap_voltage_get_nom_volt() - Gets the current non-auto-compensated voltage
- * @voltdm: pointer to the VDD for which current voltage info is needed
+ * voltdm_get_voltage() - Gets the current non-auto-compensated voltage
+ * @voltdm: pointer to the voltdm for which current voltage info is needed
*
- * API to get the current non-auto-compensated voltage for a VDD.
- * Returns 0 in case of error else returns the current voltage for the VDD.
+ * API to get the current non-auto-compensated voltage for a voltage domain.
+ * Returns 0 in case of error else returns the current voltage.
*/
-unsigned long omap_voltage_get_nom_volt(struct voltagedomain *voltdm)
+unsigned long voltdm_get_voltage(struct voltagedomain *voltdm)
{
- struct omap_vdd_info *vdd;
-
if (!voltdm || IS_ERR(voltdm)) {
pr_warning("%s: VDD specified does not exist!\n", __func__);
return 0;
}
- vdd = container_of(voltdm, struct omap_vdd_info, voltdm);
-
- return vdd->curr_volt;
+ return voltdm->nominal_volt;
}
/**
- * omap_vp_get_curr_volt() - API to get the current vp voltage.
- * @voltdm: pointer to the VDD.
- *
- * This API returns the current voltage for the specified voltage processor
- */
-unsigned long omap_vp_get_curr_volt(struct voltagedomain *voltdm)
-{
- struct omap_vdd_info *vdd;
- u8 curr_vsel;
-
- if (!voltdm || IS_ERR(voltdm)) {
- pr_warning("%s: VDD specified does not exist!\n", __func__);
- return 0;
- }
-
- vdd = container_of(voltdm, struct omap_vdd_info, voltdm);
- if (!vdd->read_reg) {
- pr_err("%s: No read API for reading vdd_%s regs\n",
- __func__, voltdm->name);
- return 0;
- }
-
- curr_vsel = vdd->read_reg(prm_mod_offs, vdd->vp_data->voltage);
-
- if (!vdd->pmic_info || !vdd->pmic_info->vsel_to_uv) {
- pr_warning("%s: PMIC function to convert vsel to voltage"
- "in uV not registerd\n", __func__);
- return 0;
- }
-
- return vdd->pmic_info->vsel_to_uv(curr_vsel);
-}
-
-/**
- * omap_vp_enable() - API to enable a particular VP
- * @voltdm: pointer to the VDD whose VP is to be enabled.
- *
- * This API enables a particular voltage processor. Needed by the smartreflex
- * class drivers.
- */
-void omap_vp_enable(struct voltagedomain *voltdm)
-{
- struct omap_vdd_info *vdd;
- u32 vpconfig;
-
- if (!voltdm || IS_ERR(voltdm)) {
- pr_warning("%s: VDD specified does not exist!\n", __func__);
- return;
- }
-
- vdd = container_of(voltdm, struct omap_vdd_info, voltdm);
- if (!vdd->read_reg || !vdd->write_reg) {
- pr_err("%s: No read/write API for accessing vdd_%s regs\n",
- __func__, voltdm->name);
- return;
- }
-
- /* If VP is already enabled, do nothing. Return */
- if (vdd->vp_enabled)
- return;
-
- vp_latch_vsel(vdd);
-
- /* Enable VP */
- vpconfig = vdd->read_reg(prm_mod_offs, vdd->vp_data->vpconfig);
- vpconfig |= vdd->vp_data->vp_common->vpconfig_vpenable;
- vdd->write_reg(vpconfig, prm_mod_offs, vdd->vp_data->vpconfig);
- vdd->vp_enabled = true;
-}
-
-/**
- * omap_vp_disable() - API to disable a particular VP
- * @voltdm: pointer to the VDD whose VP is to be disabled.
- *
- * This API disables a particular voltage processor. Needed by the smartreflex
- * class drivers.
- */
-void omap_vp_disable(struct voltagedomain *voltdm)
-{
- struct omap_vdd_info *vdd;
- u32 vpconfig;
- int timeout;
-
- if (!voltdm || IS_ERR(voltdm)) {
- pr_warning("%s: VDD specified does not exist!\n", __func__);
- return;
- }
-
- vdd = container_of(voltdm, struct omap_vdd_info, voltdm);
- if (!vdd->read_reg || !vdd->write_reg) {
- pr_err("%s: No read/write API for accessing vdd_%s regs\n",
- __func__, voltdm->name);
- return;
- }
-
- /* If VP is already disabled, do nothing. Return */
- if (!vdd->vp_enabled) {
- pr_warning("%s: Trying to disable VP for vdd_%s when"
- "it is already disabled\n", __func__, voltdm->name);
- return;
- }
-
- /* Disable VP */
- vpconfig = vdd->read_reg(prm_mod_offs, vdd->vp_data->vpconfig);
- vpconfig &= ~vdd->vp_data->vp_common->vpconfig_vpenable;
- vdd->write_reg(vpconfig, prm_mod_offs, vdd->vp_data->vpconfig);
-
- /*
- * Wait for VP idle Typical latency is <2us. Maximum latency is ~100us
- */
- omap_test_timeout((vdd->read_reg(prm_mod_offs, vdd->vp_data->vstatus)),
- VP_IDLE_TIMEOUT, timeout);
-
- if (timeout >= VP_IDLE_TIMEOUT)
- pr_warning("%s: vdd_%s idle timedout\n",
- __func__, voltdm->name);
-
- vdd->vp_enabled = false;
-
- return;
-}
-
-/**
- * omap_voltage_scale_vdd() - API to scale voltage of a particular
- * voltage domain.
- * @voltdm: pointer to the VDD which is to be scaled.
- * @target_volt: The target voltage of the voltage domain
+ * voltdm_scale() - API to scale voltage of a particular voltage domain.
+ * @voltdm: pointer to the voltage domain which is to be scaled.
+ * @target_volt: The target voltage of the voltage domain
*
* This API should be called by the kernel to do the voltage scaling
- * for a particular voltage domain during dvfs or any other situation.
+ * for a particular voltage domain during DVFS.
*/
-int omap_voltage_scale_vdd(struct voltagedomain *voltdm,
- unsigned long target_volt)
+int voltdm_scale(struct voltagedomain *voltdm,
+ unsigned long target_volt)
{
- struct omap_vdd_info *vdd;
+ int ret;
if (!voltdm || IS_ERR(voltdm)) {
pr_warning("%s: VDD specified does not exist!\n", __func__);
return -EINVAL;
}
- vdd = container_of(voltdm, struct omap_vdd_info, voltdm);
-
- if (!vdd->volt_scale) {
+ if (!voltdm->scale) {
pr_err("%s: No voltage scale API registered for vdd_%s\n",
__func__, voltdm->name);
return -ENODATA;
}
- return vdd->volt_scale(vdd, target_volt);
+ ret = voltdm->scale(voltdm, target_volt);
+ if (!ret)
+ voltdm->nominal_volt = target_volt;
+
+ return ret;
}
/**
- * omap_voltage_reset() - Resets the voltage of a particular voltage domain
- * to that of the current OPP.
- * @voltdm: pointer to the VDD whose voltage is to be reset.
+ * voltdm_reset() - Resets the voltage of a particular voltage domain
+ * to that of the current OPP.
+ * @voltdm: pointer to the voltage domain whose voltage is to be reset.
*
* This API finds out the correct voltage the voltage domain is supposed
* to be at and resets the voltage to that level. Should be used especially
* while disabling any voltage compensation modules.
*/
-void omap_voltage_reset(struct voltagedomain *voltdm)
+void voltdm_reset(struct voltagedomain *voltdm)
{
- unsigned long target_uvdc;
+ unsigned long target_volt;
if (!voltdm || IS_ERR(voltdm)) {
pr_warning("%s: VDD specified does not exist!\n", __func__);
return;
}
- target_uvdc = omap_voltage_get_nom_volt(voltdm);
- if (!target_uvdc) {
+ target_volt = voltdm_get_voltage(voltdm);
+ if (!target_volt) {
pr_err("%s: unable to find current voltage for vdd_%s\n",
__func__, voltdm->name);
return;
}
- omap_voltage_scale_vdd(voltdm, target_uvdc);
+ voltdm_scale(voltdm, target_volt);
}
/**
@@ -884,18 +133,14 @@ void omap_voltage_reset(struct voltagedomain *voltdm)
*
*/
void omap_voltage_get_volttable(struct voltagedomain *voltdm,
- struct omap_volt_data **volt_data)
+ struct omap_volt_data **volt_data)
{
- struct omap_vdd_info *vdd;
-
if (!voltdm || IS_ERR(voltdm)) {
pr_warning("%s: VDD specified does not exist!\n", __func__);
return;
}
- vdd = container_of(voltdm, struct omap_vdd_info, voltdm);
-
- *volt_data = vdd->volt_data;
+ *volt_data = voltdm->volt_data;
}
/**
@@ -914,9 +159,8 @@ void omap_voltage_get_volttable(struct voltagedomain *voltdm,
* domain or if there is no matching entry.
*/
struct omap_volt_data *omap_voltage_get_voltdata(struct voltagedomain *voltdm,
- unsigned long volt)
+ unsigned long volt)
{
- struct omap_vdd_info *vdd;
int i;
if (!voltdm || IS_ERR(voltdm)) {
@@ -924,17 +168,15 @@ struct omap_volt_data *omap_voltage_get_voltdata(struct voltagedomain *voltdm,
return ERR_PTR(-EINVAL);
}
- vdd = container_of(voltdm, struct omap_vdd_info, voltdm);
-
- if (!vdd->volt_data) {
+ if (!voltdm->volt_data) {
pr_warning("%s: voltage table does not exist for vdd_%s\n",
__func__, voltdm->name);
return ERR_PTR(-ENODATA);
}
- for (i = 0; vdd->volt_data[i].volt_nominal != 0; i++) {
- if (vdd->volt_data[i].volt_nominal == volt)
- return &vdd->volt_data[i];
+ for (i = 0; voltdm->volt_data[i].volt_nominal != 0; i++) {
+ if (voltdm->volt_data[i].volt_nominal == volt)
+ return &voltdm->volt_data[i];
}
pr_notice("%s: Unable to match the current voltage with the voltage"
@@ -947,54 +189,25 @@ struct omap_volt_data *omap_voltage_get_voltdata(struct voltagedomain *voltdm,
* omap_voltage_register_pmic() - API to register PMIC specific data
* @voltdm: pointer to the VDD for which the PMIC specific data is
* to be registered
- * @pmic_info: the structure containing pmic info
+ * @pmic: the structure containing pmic info
*
* This API is to be called by the SOC/PMIC file to specify the
- * pmic specific info as present in omap_volt_pmic_info structure.
+ * pmic specific info as present in omap_voltdm_pmic structure.
*/
int omap_voltage_register_pmic(struct voltagedomain *voltdm,
- struct omap_volt_pmic_info *pmic_info)
+ struct omap_voltdm_pmic *pmic)
{
- struct omap_vdd_info *vdd;
-
if (!voltdm || IS_ERR(voltdm)) {
pr_warning("%s: VDD specified does not exist!\n", __func__);
return -EINVAL;
}
- vdd = container_of(voltdm, struct omap_vdd_info, voltdm);
-
- vdd->pmic_info = pmic_info;
+ voltdm->pmic = pmic;
return 0;
}
/**
- * omap_voltage_get_dbgdir() - API to get pointer to the debugfs directory
- * corresponding to a voltage domain.
- *
- * @voltdm: pointer to the VDD whose debug directory is required.
- *
- * This API returns pointer to the debugfs directory corresponding
- * to the voltage domain. Should be used by drivers requiring to
- * add any debug entry for a particular voltage domain. Returns NULL
- * in case of error.
- */
-struct dentry *omap_voltage_get_dbgdir(struct voltagedomain *voltdm)
-{
- struct omap_vdd_info *vdd;
-
- if (!voltdm || IS_ERR(voltdm)) {
- pr_warning("%s: VDD specified does not exist!\n", __func__);
- return NULL;
- }
-
- vdd = container_of(voltdm, struct omap_vdd_info, voltdm);
-
- return vdd->debug_dir;
-}
-
-/**
* omap_change_voltscale_method() - API to change the voltage scaling method.
* @voltdm: pointer to the VDD whose voltage scaling method
* has to be changed.
@@ -1005,23 +218,19 @@ struct dentry *omap_voltage_get_dbgdir(struct voltagedomain *voltdm)
* defined in voltage.h
*/
void omap_change_voltscale_method(struct voltagedomain *voltdm,
- int voltscale_method)
+ int voltscale_method)
{
- struct omap_vdd_info *vdd;
-
if (!voltdm || IS_ERR(voltdm)) {
pr_warning("%s: VDD specified does not exist!\n", __func__);
return;
}
- vdd = container_of(voltdm, struct omap_vdd_info, voltdm);
-
switch (voltscale_method) {
case VOLTSCALE_VPFORCEUPDATE:
- vdd->volt_scale = vp_forceupdate_scale_voltage;
+ voltdm->scale = omap_vp_forceupdate_scale;
return;
case VOLTSCALE_VCBYPASS:
- vdd->volt_scale = vc_bypass_scale_voltage;
+ voltdm->scale = omap_vc_bypass_scale;
return;
default:
pr_warning("%s: Trying to change the method of voltage scaling"
@@ -1030,77 +239,192 @@ void omap_change_voltscale_method(struct voltagedomain *voltdm,
}
/**
- * omap_voltage_domain_lookup() - API to get the voltage domain pointer
- * @name: Name of the voltage domain
+ * omap_voltage_late_init() - Init the various voltage parameters
*
- * This API looks up in the global vdd_info struct for the
- * existence of voltage domain <name>. If it exists, the API returns
- * a pointer to the voltage domain structure corresponding to the
- * VDD<name>. Else retuns error pointer.
+ * This API is to be called in the later stages of the
+ * system boot to init the voltage controller and
+ * voltage processors.
*/
-struct voltagedomain *omap_voltage_domain_lookup(char *name)
+int __init omap_voltage_late_init(void)
{
- int i;
+ struct voltagedomain *voltdm;
- if (!vdd_info) {
- pr_err("%s: Voltage driver init not yet happened.Faulting!\n",
+ if (list_empty(&voltdm_list)) {
+ pr_err("%s: Voltage driver support not added\n",
__func__);
- return ERR_PTR(-EINVAL);
+ return -EINVAL;
}
- if (!name) {
- pr_err("%s: No name to get the votage domain!\n", __func__);
- return ERR_PTR(-EINVAL);
+ list_for_each_entry(voltdm, &voltdm_list, node) {
+ struct clk *sys_ck;
+
+ if (!voltdm->scalable)
+ continue;
+
+ sys_ck = clk_get(NULL, voltdm->sys_clk.name);
+ if (IS_ERR(sys_ck)) {
+ pr_warning("%s: Could not get sys clk.\n", __func__);
+ return -EINVAL;
+ }
+ voltdm->sys_clk.rate = clk_get_rate(sys_ck);
+ WARN_ON(!voltdm->sys_clk.rate);
+ clk_put(sys_ck);
+
+ if (voltdm->vc) {
+ voltdm->scale = omap_vc_bypass_scale;
+ omap_vc_init_channel(voltdm);
+ }
+
+ if (voltdm->vp) {
+ voltdm->scale = omap_vp_forceupdate_scale;
+ omap_vp_init(voltdm);
+ }
}
- for (i = 0; i < nr_scalable_vdd; i++) {
- if (!(strcmp(name, vdd_info[i]->voltdm.name)))
- return &vdd_info[i]->voltdm;
+ return 0;
+}
+
+static struct voltagedomain *_voltdm_lookup(const char *name)
+{
+ struct voltagedomain *voltdm, *temp_voltdm;
+
+ voltdm = NULL;
+
+ list_for_each_entry(temp_voltdm, &voltdm_list, node) {
+ if (!strcmp(name, temp_voltdm->name)) {
+ voltdm = temp_voltdm;
+ break;
+ }
}
- return ERR_PTR(-EINVAL);
+ return voltdm;
}
/**
- * omap_voltage_late_init() - Init the various voltage parameters
+ * voltdm_add_pwrdm - add a powerdomain to a voltagedomain
+ * @voltdm: struct voltagedomain * to add the powerdomain to
+ * @pwrdm: struct powerdomain * to associate with a voltagedomain
*
- * This API is to be called in the later stages of the
- * system boot to init the voltage controller and
- * voltage processors.
+ * Associate the powerdomain @pwrdm with a voltagedomain @voltdm. This
+ * enables the use of voltdm_for_each_pwrdm(). Returns -EINVAL if
+ * presented with invalid pointers; -ENOMEM if memory could not be allocated;
+ * or 0 upon success.
*/
-int __init omap_voltage_late_init(void)
+int voltdm_add_pwrdm(struct voltagedomain *voltdm, struct powerdomain *pwrdm)
{
- int i;
+ if (!voltdm || !pwrdm)
+ return -EINVAL;
- if (!vdd_info) {
- pr_err("%s: Voltage driver support not added\n",
- __func__);
+ pr_debug("voltagedomain: associating powerdomain %s with voltagedomain "
+ "%s\n", pwrdm->name, voltdm->name);
+
+ list_add(&pwrdm->voltdm_node, &voltdm->pwrdm_list);
+
+ return 0;
+}
+
+/**
+ * voltdm_for_each_pwrdm - call function for each pwrdm in a voltdm
+ * @voltdm: struct voltagedomain * to iterate over
+ * @fn: callback function *
+ *
+ * Call the supplied function @fn for each powerdomain in the
+ * voltagedomain @voltdm. Returns -EINVAL if presented with invalid
+ * pointers; or passes along the last return value of the callback
+ * function, which should be 0 for success or anything else to
+ * indicate failure.
+ */
+int voltdm_for_each_pwrdm(struct voltagedomain *voltdm,
+ int (*fn)(struct voltagedomain *voltdm,
+ struct powerdomain *pwrdm))
+{
+ struct powerdomain *pwrdm;
+ int ret = 0;
+
+ if (!fn)
return -EINVAL;
- }
- voltage_dir = debugfs_create_dir("voltage", NULL);
- if (IS_ERR(voltage_dir))
- pr_err("%s: Unable to create voltage debugfs main dir\n",
- __func__);
- for (i = 0; i < nr_scalable_vdd; i++) {
- if (omap_vdd_data_configure(vdd_info[i]))
- continue;
- omap_vc_init(vdd_info[i]);
- vp_init(vdd_info[i]);
- vdd_debugfs_init(vdd_info[i]);
+ list_for_each_entry(pwrdm, &voltdm->pwrdm_list, voltdm_node)
+ ret = (*fn)(voltdm, pwrdm);
+
+ return ret;
+}
+
+/**
+ * voltdm_for_each - call function on each registered voltagedomain
+ * @fn: callback function *
+ *
+ * Call the supplied function @fn for each registered voltagedomain.
+ * The callback function @fn can return anything but 0 to bail out
+ * early from the iterator. Returns the last return value of the
+ * callback function, which should be 0 for success or anything else
+ * to indicate failure; or -EINVAL if the function pointer is null.
+ */
+int voltdm_for_each(int (*fn)(struct voltagedomain *voltdm, void *user),
+ void *user)
+{
+ struct voltagedomain *temp_voltdm;
+ int ret = 0;
+
+ if (!fn)
+ return -EINVAL;
+
+ list_for_each_entry(temp_voltdm, &voltdm_list, node) {
+ ret = (*fn)(temp_voltdm, user);
+ if (ret)
+ break;
}
- return 0;
+ return ret;
}
-/* XXX document */
-int __init omap_voltage_early_init(s16 prm_mod, s16 prm_irqst_ocp_mod,
- struct omap_vdd_info *omap_vdd_array[],
- u8 omap_vdd_count)
+static int _voltdm_register(struct voltagedomain *voltdm)
{
- prm_mod_offs = prm_mod;
- prm_irqst_ocp_mod_offs = prm_irqst_ocp_mod;
- vdd_info = omap_vdd_array;
- nr_scalable_vdd = omap_vdd_count;
+ if (!voltdm || !voltdm->name)
+ return -EINVAL;
+
+ INIT_LIST_HEAD(&voltdm->pwrdm_list);
+ list_add(&voltdm->node, &voltdm_list);
+
+ pr_debug("voltagedomain: registered %s\n", voltdm->name);
+
return 0;
}
+
+/**
+ * voltdm_lookup - look up a voltagedomain by name, return a pointer
+ * @name: name of voltagedomain
+ *
+ * Find a registered voltagedomain by its name @name. Returns a pointer
+ * to the struct voltagedomain if found, or NULL otherwise.
+ */
+struct voltagedomain *voltdm_lookup(const char *name)
+{
+ struct voltagedomain *voltdm ;
+
+ if (!name)
+ return NULL;
+
+ voltdm = _voltdm_lookup(name);
+
+ return voltdm;
+}
+
+/**
+ * voltdm_init - set up the voltagedomain layer
+ * @voltdm_list: array of struct voltagedomain pointers to register
+ *
+ * Loop through the array of voltagedomains @voltdm_list, registering all
+ * that are available on the current CPU. If voltdm_list is supplied
+ * and not null, all of the referenced voltagedomains will be
+ * registered. No return value.
+ */
+void voltdm_init(struct voltagedomain **voltdms)
+{
+ struct voltagedomain **v;
+
+ if (voltdms) {
+ for (v = voltdms; *v; v++)
+ _voltdm_register(*v);
+ }
+}
diff --git a/arch/arm/mach-omap2/voltage.h b/arch/arm/mach-omap2/voltage.h
index e9f5408244e0..16a1b092cf36 100644
--- a/arch/arm/mach-omap2/voltage.h
+++ b/arch/arm/mach-omap2/voltage.h
@@ -19,6 +19,8 @@
#include "vc.h"
#include "vp.h"
+struct powerdomain;
+
/* XXX document */
#define VOLTSCALE_VPFORCEUPDATE 1
#define VOLTSCALE_VCBYPASS 2
@@ -32,29 +34,60 @@
#define OMAP3_VOLTSETUP2 0xff
/**
- * struct omap_vfsm_instance_data - per-voltage manager FSM register/bitfield
+ * struct omap_vfsm_instance - per-voltage manager FSM register/bitfield
* data
* @voltsetup_mask: SETUP_TIME* bitmask in the PRM_VOLTSETUP* register
* @voltsetup_reg: register offset of PRM_VOLTSETUP from PRM base
- * @voltsetup_shift: SETUP_TIME* field shift in the PRM_VOLTSETUP* register
*
* XXX What about VOLTOFFSET/VOLTCTRL?
- * XXX It is not necessary to have both a _mask and a _shift for the same
- * bitfield - remove one!
*/
-struct omap_vfsm_instance_data {
+struct omap_vfsm_instance {
u32 voltsetup_mask;
u8 voltsetup_reg;
- u8 voltsetup_shift;
};
/**
* struct voltagedomain - omap voltage domain global structure.
- * @name: Name of the voltage domain which can be used as a unique
- * identifier.
+ * @name: Name of the voltage domain which can be used as a unique identifier.
+ * @scalable: Whether or not this voltage domain is scalable
+ * @node: list_head linking all voltage domains
+ * @pwrdm_list: list_head linking all powerdomains in this voltagedomain
+ * @vc: pointer to VC channel associated with this voltagedomain
+ * @vp: pointer to VP associated with this voltagedomain
+ * @read: read a VC/VP register
+ * @write: write a VC/VP register
+ * @read: read-modify-write a VC/VP register
+ * @sys_clk: system clock name/frequency, used for various timing calculations
+ * @scale: function used to scale the voltage of the voltagedomain
+ * @nominal_volt: current nominal voltage for this voltage domain
+ * @volt_data: voltage table having the distinct voltages supported
+ * by the domain and other associated per voltage data.
*/
struct voltagedomain {
char *name;
+ bool scalable;
+ struct list_head node;
+ struct list_head pwrdm_list;
+ struct omap_vc_channel *vc;
+ const struct omap_vfsm_instance *vfsm;
+ struct omap_vp_instance *vp;
+ struct omap_voltdm_pmic *pmic;
+
+ /* VC/VP register access functions: SoC specific */
+ u32 (*read) (u8 offset);
+ void (*write) (u32 val, u8 offset);
+ u32 (*rmw)(u32 mask, u32 bits, u8 offset);
+
+ union {
+ const char *name;
+ u32 rate;
+ } sys_clk;
+
+ int (*scale) (struct voltagedomain *voltdm,
+ unsigned long target_volt);
+
+ u32 nominal_volt;
+ struct omap_volt_data *volt_data;
};
/**
@@ -77,13 +110,18 @@ struct omap_volt_data {
};
/**
- * struct omap_volt_pmic_info - PMIC specific data required by voltage driver.
+ * struct omap_voltdm_pmic - PMIC specific data required by voltage driver.
* @slew_rate: PMIC slew rate (in uv/us)
* @step_size: PMIC voltage step size (in uv)
+ * @i2c_slave_addr: I2C slave address of PMIC
+ * @volt_reg_addr: voltage configuration register address
+ * @cmd_reg_addr: command (on, on-LP, ret, off) configuration register address
+ * @i2c_high_speed: whether VC uses I2C high-speed mode to PMIC
+ * @i2c_mcode: master code value for I2C high-speed preamble transmission
* @vsel_to_uv: PMIC API to convert vsel value to actual voltage in uV.
* @uv_to_vsel: PMIC API to convert voltage in uV to vsel value.
*/
-struct omap_volt_pmic_info {
+struct omap_voltdm_pmic {
int slew_rate;
int step_size;
u32 on_volt;
@@ -91,94 +129,44 @@ struct omap_volt_pmic_info {
u32 ret_volt;
u32 off_volt;
u16 volt_setup_time;
+ u16 i2c_slave_addr;
+ u16 volt_reg_addr;
+ u16 cmd_reg_addr;
u8 vp_erroroffset;
u8 vp_vstepmin;
u8 vp_vstepmax;
u8 vp_vddmin;
u8 vp_vddmax;
u8 vp_timeout_us;
- u8 i2c_slave_addr;
- u8 pmic_reg;
+ bool i2c_high_speed;
+ u8 i2c_mcode;
unsigned long (*vsel_to_uv) (const u8 vsel);
u8 (*uv_to_vsel) (unsigned long uV);
};
-/**
- * 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_data : the register values, shifts, masks for various
- * vp registers
- * @vp_rt_data : VP data derived at runtime, not predefined
- * @vc_data : structure containing various various vc registers,
- * shifts, masks etc.
- * @vfsm : voltage manager FSM data
- * @voltdm : pointer to the voltage domain structure
- * @debug_dir : debug directory for this voltage domain.
- * @curr_volt : current voltage for this vdd.
- * @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 omap_vp_instance_data *vp_data;
- struct omap_vp_runtime_data vp_rt_data;
- struct omap_vc_instance_data *vc_data;
- const struct omap_vfsm_instance_data *vfsm;
- struct voltagedomain voltdm;
- struct dentry *debug_dir;
- u32 curr_volt;
- 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);
-int omap_voltage_scale_vdd(struct voltagedomain *voltdm,
- unsigned long target_volt);
-void omap_voltage_reset(struct voltagedomain *voltdm);
void omap_voltage_get_volttable(struct voltagedomain *voltdm,
struct omap_volt_data **volt_data);
struct omap_volt_data *omap_voltage_get_voltdata(struct voltagedomain *voltdm,
unsigned long volt);
-unsigned long omap_voltage_get_nom_volt(struct voltagedomain *voltdm);
-struct dentry *omap_voltage_get_dbgdir(struct voltagedomain *voltdm);
-int __init omap_voltage_early_init(s16 prm_mod, s16 prm_irqst_mod,
- struct omap_vdd_info *omap_vdd_array[],
- u8 omap_vdd_count);
-#ifdef CONFIG_PM
int omap_voltage_register_pmic(struct voltagedomain *voltdm,
- struct omap_volt_pmic_info *pmic_info);
+ struct omap_voltdm_pmic *pmic);
void omap_change_voltscale_method(struct voltagedomain *voltdm,
int voltscale_method);
-/* API to get the voltagedomain pointer */
-struct voltagedomain *omap_voltage_domain_lookup(char *name);
-
int omap_voltage_late_init(void);
-#else
-static inline int omap_voltage_register_pmic(struct voltagedomain *voltdm,
- struct omap_volt_pmic_info *pmic_info)
-{
- return -EINVAL;
-}
-static inline void omap_change_voltscale_method(struct voltagedomain *voltdm,
- int voltscale_method) {}
-static inline int omap_voltage_late_init(void)
-{
- return -EINVAL;
-}
-static inline struct voltagedomain *omap_voltage_domain_lookup(char *name)
-{
- return ERR_PTR(-EINVAL);
-}
-#endif
+extern void omap2xxx_voltagedomains_init(void);
+extern void omap3xxx_voltagedomains_init(void);
+extern void omap44xx_voltagedomains_init(void);
+
+struct voltagedomain *voltdm_lookup(const char *name);
+void voltdm_init(struct voltagedomain **voltdm_list);
+int voltdm_add_pwrdm(struct voltagedomain *voltdm, struct powerdomain *pwrdm);
+int voltdm_for_each(int (*fn)(struct voltagedomain *voltdm, void *user),
+ void *user);
+int voltdm_for_each_pwrdm(struct voltagedomain *voltdm,
+ int (*fn)(struct voltagedomain *voltdm,
+ struct powerdomain *pwrdm));
+int voltdm_scale(struct voltagedomain *voltdm, unsigned long target_volt);
+void voltdm_reset(struct voltagedomain *voltdm);
+unsigned long voltdm_get_voltage(struct voltagedomain *voltdm);
#endif
diff --git a/arch/arm/mach-omap2/voltagedomains2xxx_data.c b/arch/arm/mach-omap2/voltagedomains2xxx_data.c
new file mode 100644
index 000000000000..7a41349981e5
--- /dev/null
+++ b/arch/arm/mach-omap2/voltagedomains2xxx_data.c
@@ -0,0 +1,32 @@
+/*
+ * OMAP3 voltage domain data
+ *
+ * Copyright (C) 2011 Texas Instruments, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+#include <linux/kernel.h>
+#include <linux/init.h>
+
+#include "voltage.h"
+
+static struct voltagedomain omap2_voltdm_core = {
+ .name = "core",
+};
+
+static struct voltagedomain omap2_voltdm_wkup = {
+ .name = "wakeup",
+};
+
+static struct voltagedomain *voltagedomains_omap2[] __initdata = {
+ &omap2_voltdm_core,
+ &omap2_voltdm_wkup,
+ NULL,
+};
+
+void __init omap2xxx_voltagedomains_init(void)
+{
+ voltdm_init(voltagedomains_omap2);
+}
diff --git a/arch/arm/mach-omap2/voltagedomains3xxx_data.c b/arch/arm/mach-omap2/voltagedomains3xxx_data.c
index def230fd2fde..071101debbbc 100644
--- a/arch/arm/mach-omap2/voltagedomains3xxx_data.c
+++ b/arch/arm/mach-omap2/voltagedomains3xxx_data.c
@@ -31,65 +31,70 @@
* VDD data
*/
-static const struct omap_vfsm_instance_data omap3_vdd1_vfsm_data = {
+static const struct omap_vfsm_instance omap3_vdd1_vfsm = {
.voltsetup_reg = OMAP3_PRM_VOLTSETUP1_OFFSET,
- .voltsetup_shift = OMAP3430_SETUP_TIME1_SHIFT,
.voltsetup_mask = OMAP3430_SETUP_TIME1_MASK,
};
-static struct omap_vdd_info omap3_vdd1_info = {
- .vp_data = &omap3_vp1_data,
- .vc_data = &omap3_vc1_data,
- .vfsm = &omap3_vdd1_vfsm_data,
- .voltdm = {
- .name = "mpu",
- },
-};
-
-static const struct omap_vfsm_instance_data omap3_vdd2_vfsm_data = {
+static const struct omap_vfsm_instance omap3_vdd2_vfsm = {
.voltsetup_reg = OMAP3_PRM_VOLTSETUP1_OFFSET,
- .voltsetup_shift = OMAP3430_SETUP_TIME2_SHIFT,
.voltsetup_mask = OMAP3430_SETUP_TIME2_MASK,
};
-static struct omap_vdd_info omap3_vdd2_info = {
- .vp_data = &omap3_vp2_data,
- .vc_data = &omap3_vc2_data,
- .vfsm = &omap3_vdd2_vfsm_data,
- .voltdm = {
- .name = "core",
- },
+static struct voltagedomain omap3_voltdm_mpu = {
+ .name = "mpu_iva",
+ .scalable = true,
+ .read = omap3_prm_vcvp_read,
+ .write = omap3_prm_vcvp_write,
+ .rmw = omap3_prm_vcvp_rmw,
+ .vc = &omap3_vc_mpu,
+ .vfsm = &omap3_vdd1_vfsm,
+ .vp = &omap3_vp_mpu,
};
-/* OMAP3 VDD structures */
-static struct omap_vdd_info *omap3_vdd_info[] = {
- &omap3_vdd1_info,
- &omap3_vdd2_info,
+static struct voltagedomain omap3_voltdm_core = {
+ .name = "core",
+ .scalable = true,
+ .read = omap3_prm_vcvp_read,
+ .write = omap3_prm_vcvp_write,
+ .rmw = omap3_prm_vcvp_rmw,
+ .vc = &omap3_vc_core,
+ .vfsm = &omap3_vdd2_vfsm,
+ .vp = &omap3_vp_core,
};
-/* OMAP3 specific voltage init functions */
-static int __init omap3xxx_voltage_early_init(void)
-{
- s16 prm_mod = OMAP3430_GR_MOD;
- s16 prm_irqst_ocp_mod = OCP_MOD;
+static struct voltagedomain omap3_voltdm_wkup = {
+ .name = "wakeup",
+};
- if (!cpu_is_omap34xx())
- return 0;
+static struct voltagedomain *voltagedomains_omap3[] __initdata = {
+ &omap3_voltdm_mpu,
+ &omap3_voltdm_core,
+ &omap3_voltdm_wkup,
+ NULL,
+};
+
+static const char *sys_clk_name __initdata = "sys_ck";
+
+void __init omap3xxx_voltagedomains_init(void)
+{
+ struct voltagedomain *voltdm;
+ int i;
/*
* XXX Will depend on the process, validation, and binning
* for the currently-running IC
*/
if (cpu_is_omap3630()) {
- omap3_vdd1_info.volt_data = omap36xx_vddmpu_volt_data;
- omap3_vdd2_info.volt_data = omap36xx_vddcore_volt_data;
+ omap3_voltdm_mpu.volt_data = omap36xx_vddmpu_volt_data;
+ omap3_voltdm_core.volt_data = omap36xx_vddcore_volt_data;
} else {
- omap3_vdd1_info.volt_data = omap34xx_vddmpu_volt_data;
- omap3_vdd2_info.volt_data = omap34xx_vddcore_volt_data;
+ omap3_voltdm_mpu.volt_data = omap34xx_vddmpu_volt_data;
+ omap3_voltdm_core.volt_data = omap34xx_vddcore_volt_data;
}
- return omap_voltage_early_init(prm_mod, prm_irqst_ocp_mod,
- omap3_vdd_info,
- ARRAY_SIZE(omap3_vdd_info));
+ for (i = 0; voltdm = voltagedomains_omap3[i], voltdm; i++)
+ voltdm->sys_clk.name = sys_clk_name;
+
+ voltdm_init(voltagedomains_omap3);
};
-core_initcall(omap3xxx_voltage_early_init);
diff --git a/arch/arm/mach-omap2/voltagedomains44xx_data.c b/arch/arm/mach-omap2/voltagedomains44xx_data.c
index cb64996de0e1..c4584e9ac717 100644
--- a/arch/arm/mach-omap2/voltagedomains44xx_data.c
+++ b/arch/arm/mach-omap2/voltagedomains44xx_data.c
@@ -32,71 +32,80 @@
#include "vc.h"
#include "vp.h"
-static const struct omap_vfsm_instance_data omap4_vdd_mpu_vfsm_data = {
+static const struct omap_vfsm_instance omap4_vdd_mpu_vfsm = {
.voltsetup_reg = OMAP4_PRM_VOLTSETUP_MPU_RET_SLEEP_OFFSET,
};
-static struct omap_vdd_info omap4_vdd_mpu_info = {
- .vp_data = &omap4_vp_mpu_data,
- .vc_data = &omap4_vc_mpu_data,
- .vfsm = &omap4_vdd_mpu_vfsm_data,
- .voltdm = {
- .name = "mpu",
- },
+static const struct omap_vfsm_instance omap4_vdd_iva_vfsm = {
+ .voltsetup_reg = OMAP4_PRM_VOLTSETUP_IVA_RET_SLEEP_OFFSET,
};
-static const struct omap_vfsm_instance_data omap4_vdd_iva_vfsm_data = {
- .voltsetup_reg = OMAP4_PRM_VOLTSETUP_IVA_RET_SLEEP_OFFSET,
+static const struct omap_vfsm_instance omap4_vdd_core_vfsm = {
+ .voltsetup_reg = OMAP4_PRM_VOLTSETUP_CORE_RET_SLEEP_OFFSET,
};
-static struct omap_vdd_info omap4_vdd_iva_info = {
- .vp_data = &omap4_vp_iva_data,
- .vc_data = &omap4_vc_iva_data,
- .vfsm = &omap4_vdd_iva_vfsm_data,
- .voltdm = {
- .name = "iva",
- },
+static struct voltagedomain omap4_voltdm_mpu = {
+ .name = "mpu",
+ .scalable = true,
+ .read = omap4_prm_vcvp_read,
+ .write = omap4_prm_vcvp_write,
+ .rmw = omap4_prm_vcvp_rmw,
+ .vc = &omap4_vc_mpu,
+ .vfsm = &omap4_vdd_mpu_vfsm,
+ .vp = &omap4_vp_mpu,
};
-static const struct omap_vfsm_instance_data omap4_vdd_core_vfsm_data = {
- .voltsetup_reg = OMAP4_PRM_VOLTSETUP_CORE_RET_SLEEP_OFFSET,
+static struct voltagedomain omap4_voltdm_iva = {
+ .name = "iva",
+ .scalable = true,
+ .read = omap4_prm_vcvp_read,
+ .write = omap4_prm_vcvp_write,
+ .rmw = omap4_prm_vcvp_rmw,
+ .vc = &omap4_vc_iva,
+ .vfsm = &omap4_vdd_iva_vfsm,
+ .vp = &omap4_vp_iva,
};
-static struct omap_vdd_info omap4_vdd_core_info = {
- .vp_data = &omap4_vp_core_data,
- .vc_data = &omap4_vc_core_data,
- .vfsm = &omap4_vdd_core_vfsm_data,
- .voltdm = {
- .name = "core",
- },
+static struct voltagedomain omap4_voltdm_core = {
+ .name = "core",
+ .scalable = true,
+ .read = omap4_prm_vcvp_read,
+ .write = omap4_prm_vcvp_write,
+ .rmw = omap4_prm_vcvp_rmw,
+ .vc = &omap4_vc_core,
+ .vfsm = &omap4_vdd_core_vfsm,
+ .vp = &omap4_vp_core,
};
-/* OMAP4 VDD structures */
-static struct omap_vdd_info *omap4_vdd_info[] = {
- &omap4_vdd_mpu_info,
- &omap4_vdd_iva_info,
- &omap4_vdd_core_info,
+static struct voltagedomain omap4_voltdm_wkup = {
+ .name = "wakeup",
};
-/* OMAP4 specific voltage init functions */
-static int __init omap44xx_voltage_early_init(void)
-{
- s16 prm_mod = OMAP4430_PRM_DEVICE_INST;
- s16 prm_irqst_ocp_mod = OMAP4430_PRM_OCP_SOCKET_INST;
+static struct voltagedomain *voltagedomains_omap4[] __initdata = {
+ &omap4_voltdm_mpu,
+ &omap4_voltdm_iva,
+ &omap4_voltdm_core,
+ &omap4_voltdm_wkup,
+ NULL,
+};
+
+static const char *sys_clk_name __initdata = "sys_clkin_ck";
- if (!cpu_is_omap44xx())
- return 0;
+void __init omap44xx_voltagedomains_init(void)
+{
+ struct voltagedomain *voltdm;
+ int i;
/*
* XXX Will depend on the process, validation, and binning
* for the currently-running IC
*/
- omap4_vdd_mpu_info.volt_data = omap44xx_vdd_mpu_volt_data;
- omap4_vdd_iva_info.volt_data = omap44xx_vdd_iva_volt_data;
- omap4_vdd_core_info.volt_data = omap44xx_vdd_core_volt_data;
+ omap4_voltdm_mpu.volt_data = omap44xx_vdd_mpu_volt_data;
+ omap4_voltdm_iva.volt_data = omap44xx_vdd_iva_volt_data;
+ omap4_voltdm_core.volt_data = omap44xx_vdd_core_volt_data;
+
+ for (i = 0; voltdm = voltagedomains_omap4[i], voltdm; i++)
+ voltdm->sys_clk.name = sys_clk_name;
- return omap_voltage_early_init(prm_mod, prm_irqst_ocp_mod,
- omap4_vdd_info,
- ARRAY_SIZE(omap4_vdd_info));
+ voltdm_init(voltagedomains_omap4);
};
-core_initcall(omap44xx_voltage_early_init);
diff --git a/arch/arm/mach-omap2/vp.c b/arch/arm/mach-omap2/vp.c
new file mode 100644
index 000000000000..66bd700a2b98
--- /dev/null
+++ b/arch/arm/mach-omap2/vp.c
@@ -0,0 +1,278 @@
+#include <linux/kernel.h>
+#include <linux/init.h>
+
+#include <plat/common.h>
+
+#include "voltage.h"
+#include "vp.h"
+#include "prm-regbits-34xx.h"
+#include "prm-regbits-44xx.h"
+#include "prm44xx.h"
+
+static u32 _vp_set_init_voltage(struct voltagedomain *voltdm, u32 volt)
+{
+ struct omap_vp_instance *vp = voltdm->vp;
+ u32 vpconfig;
+ char vsel;
+
+ vsel = voltdm->pmic->uv_to_vsel(volt);
+
+ vpconfig = voltdm->read(vp->vpconfig);
+ vpconfig &= ~(vp->common->vpconfig_initvoltage_mask |
+ vp->common->vpconfig_forceupdate |
+ vp->common->vpconfig_initvdd);
+ vpconfig |= vsel << __ffs(vp->common->vpconfig_initvoltage_mask);
+ voltdm->write(vpconfig, vp->vpconfig);
+
+ /* Trigger initVDD value copy to voltage processor */
+ voltdm->write((vpconfig | vp->common->vpconfig_initvdd),
+ vp->vpconfig);
+
+ /* Clear initVDD copy trigger bit */
+ voltdm->write(vpconfig, vp->vpconfig);
+
+ return vpconfig;
+}
+
+/* Generic voltage init functions */
+void __init omap_vp_init(struct voltagedomain *voltdm)
+{
+ struct omap_vp_instance *vp = voltdm->vp;
+ u32 val, sys_clk_rate, timeout, waittime;
+ u32 vddmin, vddmax, vstepmin, vstepmax;
+
+ if (!voltdm->read || !voltdm->write) {
+ pr_err("%s: No read/write API for accessing vdd_%s regs\n",
+ __func__, voltdm->name);
+ return;
+ }
+
+ vp->enabled = false;
+
+ /* Divide to avoid overflow */
+ sys_clk_rate = voltdm->sys_clk.rate / 1000;
+
+ timeout = (sys_clk_rate * voltdm->pmic->vp_timeout_us) / 1000;
+ vddmin = voltdm->pmic->vp_vddmin;
+ vddmax = voltdm->pmic->vp_vddmax;
+
+ waittime = ((voltdm->pmic->step_size / voltdm->pmic->slew_rate) *
+ sys_clk_rate) / 1000;
+ vstepmin = voltdm->pmic->vp_vstepmin;
+ vstepmax = voltdm->pmic->vp_vstepmax;
+
+ /*
+ * VP_CONFIG: error gain is not set here, it will be updated
+ * on each scale, based on OPP.
+ */
+ val = (voltdm->pmic->vp_erroroffset <<
+ __ffs(voltdm->vp->common->vpconfig_erroroffset_mask)) |
+ vp->common->vpconfig_timeouten;
+ voltdm->write(val, vp->vpconfig);
+
+ /* VSTEPMIN */
+ val = (waittime << vp->common->vstepmin_smpswaittimemin_shift) |
+ (vstepmin << vp->common->vstepmin_stepmin_shift);
+ voltdm->write(val, vp->vstepmin);
+
+ /* VSTEPMAX */
+ val = (vstepmax << vp->common->vstepmax_stepmax_shift) |
+ (waittime << vp->common->vstepmax_smpswaittimemax_shift);
+ voltdm->write(val, vp->vstepmax);
+
+ /* VLIMITTO */
+ val = (vddmax << vp->common->vlimitto_vddmax_shift) |
+ (vddmin << vp->common->vlimitto_vddmin_shift) |
+ (timeout << vp->common->vlimitto_timeout_shift);
+ voltdm->write(val, vp->vlimitto);
+}
+
+int omap_vp_update_errorgain(struct voltagedomain *voltdm,
+ unsigned long target_volt)
+{
+ struct omap_volt_data *volt_data;
+
+ if (!voltdm->vp)
+ return -EINVAL;
+
+ /* Get volt_data corresponding to target_volt */
+ volt_data = omap_voltage_get_voltdata(voltdm, target_volt);
+ if (IS_ERR(volt_data))
+ return -EINVAL;
+
+ /* Setting vp errorgain based on the voltage */
+ voltdm->rmw(voltdm->vp->common->vpconfig_errorgain_mask,
+ volt_data->vp_errgain <<
+ __ffs(voltdm->vp->common->vpconfig_errorgain_mask),
+ voltdm->vp->vpconfig);
+
+ return 0;
+}
+
+/* VP force update method of voltage scaling */
+int omap_vp_forceupdate_scale(struct voltagedomain *voltdm,
+ unsigned long target_volt)
+{
+ struct omap_vp_instance *vp = voltdm->vp;
+ u32 vpconfig;
+ u8 target_vsel, current_vsel;
+ int ret, timeout = 0;
+
+ ret = omap_vc_pre_scale(voltdm, target_volt, &target_vsel, &current_vsel);
+ if (ret)
+ return ret;
+
+ /*
+ * Clear all pending TransactionDone interrupt/status. Typical latency
+ * is <3us
+ */
+ while (timeout++ < VP_TRANXDONE_TIMEOUT) {
+ vp->common->ops->clear_txdone(vp->id);
+ if (!vp->common->ops->check_txdone(vp->id))
+ break;
+ udelay(1);
+ }
+ if (timeout >= VP_TRANXDONE_TIMEOUT) {
+ pr_warning("%s: vdd_%s TRANXDONE timeout exceeded."
+ "Voltage change aborted", __func__, voltdm->name);
+ return -ETIMEDOUT;
+ }
+
+ vpconfig = _vp_set_init_voltage(voltdm, target_volt);
+
+ /* Force update of voltage */
+ voltdm->write(vpconfig | vp->common->vpconfig_forceupdate,
+ voltdm->vp->vpconfig);
+
+ /*
+ * Wait for TransactionDone. Typical latency is <200us.
+ * Depends on SMPSWAITTIMEMIN/MAX and voltage change
+ */
+ timeout = 0;
+ omap_test_timeout(vp->common->ops->check_txdone(vp->id),
+ VP_TRANXDONE_TIMEOUT, timeout);
+ if (timeout >= VP_TRANXDONE_TIMEOUT)
+ pr_err("%s: vdd_%s TRANXDONE timeout exceeded."
+ "TRANXDONE never got set after the voltage update\n",
+ __func__, voltdm->name);
+
+ omap_vc_post_scale(voltdm, target_volt, target_vsel, current_vsel);
+
+ /*
+ * Disable TransactionDone interrupt , clear all status, clear
+ * control registers
+ */
+ timeout = 0;
+ while (timeout++ < VP_TRANXDONE_TIMEOUT) {
+ vp->common->ops->clear_txdone(vp->id);
+ if (!vp->common->ops->check_txdone(vp->id))
+ break;
+ udelay(1);
+ }
+
+ if (timeout >= VP_TRANXDONE_TIMEOUT)
+ pr_warning("%s: vdd_%s TRANXDONE timeout exceeded while trying"
+ "to clear the TRANXDONE status\n",
+ __func__, voltdm->name);
+
+ /* Clear force bit */
+ voltdm->write(vpconfig, vp->vpconfig);
+
+ return 0;
+}
+
+/**
+ * omap_vp_enable() - API to enable a particular VP
+ * @voltdm: pointer to the VDD whose VP is to be enabled.
+ *
+ * This API enables a particular voltage processor. Needed by the smartreflex
+ * class drivers.
+ */
+void omap_vp_enable(struct voltagedomain *voltdm)
+{
+ struct omap_vp_instance *vp;
+ u32 vpconfig, volt;
+
+ if (!voltdm || IS_ERR(voltdm)) {
+ pr_warning("%s: VDD specified does not exist!\n", __func__);
+ return;
+ }
+
+ vp = voltdm->vp;
+ if (!voltdm->read || !voltdm->write) {
+ pr_err("%s: No read/write API for accessing vdd_%s regs\n",
+ __func__, voltdm->name);
+ return;
+ }
+
+ /* If VP is already enabled, do nothing. Return */
+ if (vp->enabled)
+ return;
+
+ volt = voltdm_get_voltage(voltdm);
+ if (!volt) {
+ pr_warning("%s: unable to find current voltage for %s\n",
+ __func__, voltdm->name);
+ return;
+ }
+
+ vpconfig = _vp_set_init_voltage(voltdm, volt);
+
+ /* Enable VP */
+ vpconfig |= vp->common->vpconfig_vpenable;
+ voltdm->write(vpconfig, vp->vpconfig);
+
+ vp->enabled = true;
+}
+
+/**
+ * omap_vp_disable() - API to disable a particular VP
+ * @voltdm: pointer to the VDD whose VP is to be disabled.
+ *
+ * This API disables a particular voltage processor. Needed by the smartreflex
+ * class drivers.
+ */
+void omap_vp_disable(struct voltagedomain *voltdm)
+{
+ struct omap_vp_instance *vp;
+ u32 vpconfig;
+ int timeout;
+
+ if (!voltdm || IS_ERR(voltdm)) {
+ pr_warning("%s: VDD specified does not exist!\n", __func__);
+ return;
+ }
+
+ vp = voltdm->vp;
+ if (!voltdm->read || !voltdm->write) {
+ pr_err("%s: No read/write API for accessing vdd_%s regs\n",
+ __func__, voltdm->name);
+ return;
+ }
+
+ /* If VP is already disabled, do nothing. Return */
+ if (!vp->enabled) {
+ pr_warning("%s: Trying to disable VP for vdd_%s when"
+ "it is already disabled\n", __func__, voltdm->name);
+ return;
+ }
+
+ /* Disable VP */
+ vpconfig = voltdm->read(vp->vpconfig);
+ vpconfig &= ~vp->common->vpconfig_vpenable;
+ voltdm->write(vpconfig, vp->vpconfig);
+
+ /*
+ * Wait for VP idle Typical latency is <2us. Maximum latency is ~100us
+ */
+ omap_test_timeout((voltdm->read(vp->vstatus)),
+ VP_IDLE_TIMEOUT, timeout);
+
+ if (timeout >= VP_IDLE_TIMEOUT)
+ pr_warning("%s: vdd_%s idle timedout\n",
+ __func__, voltdm->name);
+
+ vp->enabled = false;
+
+ return;
+}
diff --git a/arch/arm/mach-omap2/vp.h b/arch/arm/mach-omap2/vp.h
index 7ce134f7de79..7c155d248aa3 100644
--- a/arch/arm/mach-omap2/vp.h
+++ b/arch/arm/mach-omap2/vp.h
@@ -19,44 +19,60 @@
#include <linux/kernel.h>
+struct voltagedomain;
+
+/*
+ * Voltage Processor (VP) identifiers
+ */
+#define OMAP3_VP_VDD_MPU_ID 0
+#define OMAP3_VP_VDD_CORE_ID 1
+#define OMAP4_VP_VDD_CORE_ID 0
+#define OMAP4_VP_VDD_IVA_ID 1
+#define OMAP4_VP_VDD_MPU_ID 2
+
/* XXX document */
#define VP_IDLE_TIMEOUT 200
#define VP_TRANXDONE_TIMEOUT 300
+/**
+ * struct omap_vp_ops - per-VP operations
+ * @check_txdone: check for VP transaction done
+ * @clear_txdone: clear VP transaction done status
+ */
+struct omap_vp_ops {
+ u32 (*check_txdone)(u8 vp_id);
+ void (*clear_txdone)(u8 vp_id);
+};
/**
- * struct omap_vp_common_data - register data common to all VDDs
+ * struct omap_vp_common - register data common to all VDDs
+ * @vpconfig_erroroffset_mask: ERROROFFSET bitmask in the PRM_VP*_CONFIG reg
* @vpconfig_errorgain_mask: ERRORGAIN bitmask in the PRM_VP*_CONFIG reg
* @vpconfig_initvoltage_mask: INITVOLTAGE bitmask in the PRM_VP*_CONFIG reg
- * @vpconfig_timeouten_mask: TIMEOUT bitmask in the PRM_VP*_CONFIG reg
+ * @vpconfig_timeouten: TIMEOUT bitmask in the PRM_VP*_CONFIG reg
* @vpconfig_initvdd: INITVDD bitmask in the PRM_VP*_CONFIG reg
* @vpconfig_forceupdate: FORCEUPDATE bitmask in the PRM_VP*_CONFIG reg
* @vpconfig_vpenable: VPENABLE bitmask in the PRM_VP*_CONFIG reg
* @vpconfig_erroroffset_shift: ERROROFFSET field shift in PRM_VP*_CONFIG reg
* @vpconfig_errorgain_shift: ERRORGAIN field shift in PRM_VP*_CONFIG reg
* @vpconfig_initvoltage_shift: INITVOLTAGE field shift in PRM_VP*_CONFIG reg
- * @vpconfig_stepmin_shift: VSTEPMIN field shift in the PRM_VP*_VSTEPMIN reg
- * @vpconfig_smpswaittimemin_shift: SMPSWAITTIMEMIN field shift in PRM_VP*_VSTEPMIN reg
- * @vpconfig_stepmax_shift: VSTEPMAX field shift in the PRM_VP*_VSTEPMAX reg
- * @vpconfig_smpswaittimemax_shift: SMPSWAITTIMEMAX field shift in PRM_VP*_VSTEPMAX reg
- * @vpconfig_vlimitto_vddmin_shift: VDDMIN field shift in PRM_VP*_VLIMITTO reg
- * @vpconfig_vlimitto_vddmax_shift: VDDMAX field shift in PRM_VP*_VLIMITTO reg
- * @vpconfig_vlimitto_timeout_shift: TIMEOUT field shift in PRM_VP*_VLIMITTO reg
- *
- * XXX It it not necessary to have both a mask and a shift for the same
- * bitfield - remove one
- * XXX Many of these fields are wrongly named -- e.g., vpconfig_smps* -- fix!
+ * @vstepmin_stepmin_shift: VSTEPMIN field shift in the PRM_VP*_VSTEPMIN reg
+ * @vstepmin_smpswaittimemin_shift: SMPSWAITTIMEMIN field shift in PRM_VP*_VSTEPMIN reg
+ * @vstepmax_stepmax_shift: VSTEPMAX field shift in the PRM_VP*_VSTEPMAX reg
+ * @vstepmax_smpswaittimemax_shift: SMPSWAITTIMEMAX field shift in PRM_VP*_VSTEPMAX reg
+ * @vlimitto_vddmin_shift: VDDMIN field shift in PRM_VP*_VLIMITTO reg
+ * @vlimitto_vddmax_shift: VDDMAX field shift in PRM_VP*_VLIMITTO reg
+ * @vlimitto_timeout_shift: TIMEOUT field shift in PRM_VP*_VLIMITTO reg
+ * @vpvoltage_mask: VPVOLTAGE field mask in PRM_VP*_VOLTAGE reg
*/
-struct omap_vp_common_data {
+struct omap_vp_common {
+ u32 vpconfig_erroroffset_mask;
u32 vpconfig_errorgain_mask;
u32 vpconfig_initvoltage_mask;
- u32 vpconfig_timeouten;
- u32 vpconfig_initvdd;
- u32 vpconfig_forceupdate;
- u32 vpconfig_vpenable;
- u8 vpconfig_erroroffset_shift;
- u8 vpconfig_errorgain_shift;
- u8 vpconfig_initvoltage_shift;
+ u8 vpconfig_timeouten;
+ u8 vpconfig_initvdd;
+ u8 vpconfig_forceupdate;
+ u8 vpconfig_vpenable;
u8 vstepmin_stepmin_shift;
u8 vstepmin_smpswaittimemin_shift;
u8 vstepmax_stepmax_shift;
@@ -64,80 +80,49 @@ struct omap_vp_common_data {
u8 vlimitto_vddmin_shift;
u8 vlimitto_vddmax_shift;
u8 vlimitto_timeout_shift;
-};
+ u8 vpvoltage_mask;
-/**
- * struct omap_vp_prm_irqst_data - PRM_IRQSTATUS_MPU.VP_TRANXDONE_ST data
- * @prm_irqst_reg: reg offset for PRM_IRQSTATUS_MPU from top of PRM
- * @tranxdone_status: VP_TRANXDONE_ST bitmask in PRM_IRQSTATUS_MPU reg
- *
- * XXX prm_irqst_reg does not belong here
- * XXX Note that on OMAP3, VP_TRANXDONE interrupt may not work due to a
- * hardware bug
- * XXX This structure is probably not needed
- */
-struct omap_vp_prm_irqst_data {
- u8 prm_irqst_reg;
- u32 tranxdone_status;
+ const struct omap_vp_ops *ops;
};
/**
- * struct omap_vp_instance_data - VP register offsets (per-VDD)
- * @vp_common: pointer to struct omap_vp_common_data * for this SoC
- * @prm_irqst_data: pointer to struct omap_vp_prm_irqst_data for this VDD
+ * struct omap_vp_instance - VP register offsets (per-VDD)
+ * @common: pointer to struct omap_vp_common * for this SoC
* @vpconfig: PRM_VP*_CONFIG reg offset from PRM start
* @vstepmin: PRM_VP*_VSTEPMIN reg offset from PRM start
* @vlimitto: PRM_VP*_VLIMITTO reg offset from PRM start
* @vstatus: PRM_VP*_VSTATUS reg offset from PRM start
* @voltage: PRM_VP*_VOLTAGE reg offset from PRM start
+ * @id: Unique identifier for VP instance.
+ * @enabled: flag to keep track of whether vp is enabled or not
*
* XXX vp_common is probably not needed since it is per-SoC
*/
-struct omap_vp_instance_data {
- const struct omap_vp_common_data *vp_common;
- const struct omap_vp_prm_irqst_data *prm_irqst_data;
+struct omap_vp_instance {
+ const struct omap_vp_common *common;
u8 vpconfig;
u8 vstepmin;
u8 vstepmax;
u8 vlimitto;
u8 vstatus;
u8 voltage;
+ u8 id;
+ bool enabled;
};
-/**
- * struct omap_vp_runtime_data - VP data populated at runtime by code
- * @vpconfig_erroroffset: value of ERROROFFSET bitfield in PRM_VP*_CONFIG
- * @vpconfig_errorgain: value of ERRORGAIN bitfield in PRM_VP*_CONFIG
- * @vstepmin_smpswaittimemin: value of SMPSWAITTIMEMIN bitfield in PRM_VP*_VSTEPMIN
- * @vstepmax_smpswaittimemax: value of SMPSWAITTIMEMAX bitfield in PRM_VP*_VSTEPMAX
- * @vlimitto_timeout: value of TIMEOUT bitfield in PRM_VP*_VLIMITTO
- * @vstepmin_stepmin: value of VSTEPMIN bitfield in PRM_VP*_VSTEPMIN
- * @vstepmax_stepmax: value of VSTEPMAX bitfield in PRM_VP*_VSTEPMAX
- * @vlimitto_vddmin: value of VDDMIN bitfield in PRM_VP*_VLIMITTO
- * @vlimitto_vddmax: value of VDDMAX bitfield in PRM_VP*_VLIMITTO
- *
- * XXX Is this structure really needed? Why not just program the
- * device directly? They are in PRM space, therefore in the WKUP
- * powerdomain, so register contents should not be lost in off-mode.
- * XXX Some of these fields are incorrectly named, e.g., vstep*
- */
-struct omap_vp_runtime_data {
- u32 vpconfig_erroroffset;
- u16 vpconfig_errorgain;
- u16 vstepmin_smpswaittimemin;
- u16 vstepmax_smpswaittimemax;
- u16 vlimitto_timeout;
- u8 vstepmin_stepmin;
- u8 vstepmax_stepmax;
- u8 vlimitto_vddmin;
- u8 vlimitto_vddmax;
-};
+extern struct omap_vp_instance omap3_vp_mpu;
+extern struct omap_vp_instance omap3_vp_core;
-extern struct omap_vp_instance_data omap3_vp1_data;
-extern struct omap_vp_instance_data omap3_vp2_data;
+extern struct omap_vp_instance omap4_vp_mpu;
+extern struct omap_vp_instance omap4_vp_iva;
+extern struct omap_vp_instance omap4_vp_core;
-extern struct omap_vp_instance_data omap4_vp_mpu_data;
-extern struct omap_vp_instance_data omap4_vp_iva_data;
-extern struct omap_vp_instance_data omap4_vp_core_data;
+void omap_vp_init(struct voltagedomain *voltdm);
+void omap_vp_enable(struct voltagedomain *voltdm);
+void omap_vp_disable(struct voltagedomain *voltdm);
+int omap_vp_forceupdate_scale(struct voltagedomain *voltdm,
+ unsigned long target_volt);
+int omap_vp_update_errorgain(struct voltagedomain *voltdm,
+ unsigned long target_volt);
#endif
diff --git a/arch/arm/mach-omap2/vp3xxx_data.c b/arch/arm/mach-omap2/vp3xxx_data.c
index 645217094e51..260c554b1547 100644
--- a/arch/arm/mach-omap2/vp3xxx_data.c
+++ b/arch/arm/mach-omap2/vp3xxx_data.c
@@ -25,16 +25,20 @@
#include "voltage.h"
#include "vp.h"
+#include "prm2xxx_3xxx.h"
+
+static const struct omap_vp_ops omap3_vp_ops = {
+ .check_txdone = omap3_prm_vp_check_txdone,
+ .clear_txdone = omap3_prm_vp_clear_txdone,
+};
/*
* VP data common to 34xx/36xx chips
* XXX This stuff presumably belongs in the vp3xxx.c or vp.c file.
*/
-static const struct omap_vp_common_data omap3_vp_common = {
- .vpconfig_erroroffset_shift = OMAP3430_ERROROFFSET_SHIFT,
+static const struct omap_vp_common omap3_vp_common = {
+ .vpconfig_erroroffset_mask = OMAP3430_ERROROFFSET_MASK,
.vpconfig_errorgain_mask = OMAP3430_ERRORGAIN_MASK,
- .vpconfig_errorgain_shift = OMAP3430_ERRORGAIN_SHIFT,
- .vpconfig_initvoltage_shift = OMAP3430_INITVOLTAGE_SHIFT,
.vpconfig_initvoltage_mask = OMAP3430_INITVOLTAGE_MASK,
.vpconfig_timeouten = OMAP3430_TIMEOUTEN_MASK,
.vpconfig_initvdd = OMAP3430_INITVDD_MASK,
@@ -47,36 +51,29 @@ static const struct omap_vp_common_data omap3_vp_common = {
.vlimitto_vddmin_shift = OMAP3430_VDDMIN_SHIFT,
.vlimitto_vddmax_shift = OMAP3430_VDDMAX_SHIFT,
.vlimitto_timeout_shift = OMAP3430_TIMEOUT_SHIFT,
-};
+ .vpvoltage_mask = OMAP3430_VPVOLTAGE_MASK,
-static const struct omap_vp_prm_irqst_data omap3_vp1_prm_irqst_data = {
- .prm_irqst_reg = OMAP3_PRM_IRQSTATUS_MPU_OFFSET,
- .tranxdone_status = OMAP3430_VP1_TRANXDONE_ST_MASK,
+ .ops = &omap3_vp_ops,
};
-struct omap_vp_instance_data omap3_vp1_data = {
- .vp_common = &omap3_vp_common,
+struct omap_vp_instance omap3_vp_mpu = {
+ .id = OMAP3_VP_VDD_MPU_ID,
+ .common = &omap3_vp_common,
.vpconfig = OMAP3_PRM_VP1_CONFIG_OFFSET,
.vstepmin = OMAP3_PRM_VP1_VSTEPMIN_OFFSET,
.vstepmax = OMAP3_PRM_VP1_VSTEPMAX_OFFSET,
.vlimitto = OMAP3_PRM_VP1_VLIMITTO_OFFSET,
.vstatus = OMAP3_PRM_VP1_STATUS_OFFSET,
.voltage = OMAP3_PRM_VP1_VOLTAGE_OFFSET,
- .prm_irqst_data = &omap3_vp1_prm_irqst_data,
-};
-
-static const struct omap_vp_prm_irqst_data omap3_vp2_prm_irqst_data = {
- .prm_irqst_reg = OMAP3_PRM_IRQSTATUS_MPU_OFFSET,
- .tranxdone_status = OMAP3430_VP2_TRANXDONE_ST_MASK,
};
-struct omap_vp_instance_data omap3_vp2_data = {
- .vp_common = &omap3_vp_common,
+struct omap_vp_instance omap3_vp_core = {
+ .id = OMAP3_VP_VDD_CORE_ID,
+ .common = &omap3_vp_common,
.vpconfig = OMAP3_PRM_VP2_CONFIG_OFFSET,
.vstepmin = OMAP3_PRM_VP2_VSTEPMIN_OFFSET,
.vstepmax = OMAP3_PRM_VP2_VSTEPMAX_OFFSET,
.vlimitto = OMAP3_PRM_VP2_VLIMITTO_OFFSET,
.vstatus = OMAP3_PRM_VP2_STATUS_OFFSET,
.voltage = OMAP3_PRM_VP2_VOLTAGE_OFFSET,
- .prm_irqst_data = &omap3_vp2_prm_irqst_data,
};
diff --git a/arch/arm/mach-omap2/vp44xx_data.c b/arch/arm/mach-omap2/vp44xx_data.c
index 65d1ad63800a..b4e77044891e 100644
--- a/arch/arm/mach-omap2/vp44xx_data.c
+++ b/arch/arm/mach-omap2/vp44xx_data.c
@@ -27,15 +27,18 @@
#include "vp.h"
+static const struct omap_vp_ops omap4_vp_ops = {
+ .check_txdone = omap4_prm_vp_check_txdone,
+ .clear_txdone = omap4_prm_vp_clear_txdone,
+};
+
/*
* VP data common to 44xx chips
* XXX This stuff presumably belongs in the vp44xx.c or vp.c file.
*/
-static const struct omap_vp_common_data omap4_vp_common = {
- .vpconfig_erroroffset_shift = OMAP4430_ERROROFFSET_SHIFT,
+static const struct omap_vp_common omap4_vp_common = {
+ .vpconfig_erroroffset_mask = OMAP4430_ERROROFFSET_MASK,
.vpconfig_errorgain_mask = OMAP4430_ERRORGAIN_MASK,
- .vpconfig_errorgain_shift = OMAP4430_ERRORGAIN_SHIFT,
- .vpconfig_initvoltage_shift = OMAP4430_INITVOLTAGE_SHIFT,
.vpconfig_initvoltage_mask = OMAP4430_INITVOLTAGE_MASK,
.vpconfig_timeouten = OMAP4430_TIMEOUTEN_MASK,
.vpconfig_initvdd = OMAP4430_INITVDD_MASK,
@@ -48,53 +51,39 @@ static const struct omap_vp_common_data omap4_vp_common = {
.vlimitto_vddmin_shift = OMAP4430_VDDMIN_SHIFT,
.vlimitto_vddmax_shift = OMAP4430_VDDMAX_SHIFT,
.vlimitto_timeout_shift = OMAP4430_TIMEOUT_SHIFT,
+ .vpvoltage_mask = OMAP4430_VPVOLTAGE_MASK,
+ .ops = &omap4_vp_ops,
};
-static const struct omap_vp_prm_irqst_data omap4_vp_mpu_prm_irqst_data = {
- .prm_irqst_reg = OMAP4_PRM_IRQSTATUS_MPU_2_OFFSET,
- .tranxdone_status = OMAP4430_VP_MPU_TRANXDONE_ST_MASK,
-};
-
-struct omap_vp_instance_data omap4_vp_mpu_data = {
- .vp_common = &omap4_vp_common,
+struct omap_vp_instance omap4_vp_mpu = {
+ .id = OMAP4_VP_VDD_MPU_ID,
+ .common = &omap4_vp_common,
.vpconfig = OMAP4_PRM_VP_MPU_CONFIG_OFFSET,
.vstepmin = OMAP4_PRM_VP_MPU_VSTEPMIN_OFFSET,
.vstepmax = OMAP4_PRM_VP_MPU_VSTEPMAX_OFFSET,
.vlimitto = OMAP4_PRM_VP_MPU_VLIMITTO_OFFSET,
.vstatus = OMAP4_PRM_VP_MPU_STATUS_OFFSET,
.voltage = OMAP4_PRM_VP_MPU_VOLTAGE_OFFSET,
- .prm_irqst_data = &omap4_vp_mpu_prm_irqst_data,
};
-static const struct omap_vp_prm_irqst_data omap4_vp_iva_prm_irqst_data = {
- .prm_irqst_reg = OMAP4_PRM_IRQSTATUS_MPU_OFFSET,
- .tranxdone_status = OMAP4430_VP_IVA_TRANXDONE_ST_MASK,
-};
-
-struct omap_vp_instance_data omap4_vp_iva_data = {
- .vp_common = &omap4_vp_common,
+struct omap_vp_instance omap4_vp_iva = {
+ .id = OMAP4_VP_VDD_IVA_ID,
+ .common = &omap4_vp_common,
.vpconfig = OMAP4_PRM_VP_IVA_CONFIG_OFFSET,
.vstepmin = OMAP4_PRM_VP_IVA_VSTEPMIN_OFFSET,
.vstepmax = OMAP4_PRM_VP_IVA_VSTEPMAX_OFFSET,
.vlimitto = OMAP4_PRM_VP_IVA_VLIMITTO_OFFSET,
.vstatus = OMAP4_PRM_VP_IVA_STATUS_OFFSET,
.voltage = OMAP4_PRM_VP_IVA_VOLTAGE_OFFSET,
- .prm_irqst_data = &omap4_vp_iva_prm_irqst_data,
-};
-
-static const struct omap_vp_prm_irqst_data omap4_vp_core_prm_irqst_data = {
- .prm_irqst_reg = OMAP4_PRM_IRQSTATUS_MPU_OFFSET,
- .tranxdone_status = OMAP4430_VP_CORE_TRANXDONE_ST_MASK,
};
-struct omap_vp_instance_data omap4_vp_core_data = {
- .vp_common = &omap4_vp_common,
+struct omap_vp_instance omap4_vp_core = {
+ .id = OMAP4_VP_VDD_CORE_ID,
+ .common = &omap4_vp_common,
.vpconfig = OMAP4_PRM_VP_CORE_CONFIG_OFFSET,
.vstepmin = OMAP4_PRM_VP_CORE_VSTEPMIN_OFFSET,
.vstepmax = OMAP4_PRM_VP_CORE_VSTEPMAX_OFFSET,
.vlimitto = OMAP4_PRM_VP_CORE_VLIMITTO_OFFSET,
.vstatus = OMAP4_PRM_VP_CORE_STATUS_OFFSET,
.voltage = OMAP4_PRM_VP_CORE_VOLTAGE_OFFSET,
- .prm_irqst_data = &omap4_vp_core_prm_irqst_data,
};
-
diff --git a/arch/arm/mach-s3c2410/s3c2410.c b/arch/arm/mach-s3c2410/s3c2410.c
index f1d3bd8f6f17..343a540d86a9 100644
--- a/arch/arm/mach-s3c2410/s3c2410.c
+++ b/arch/arm/mach-s3c2410/s3c2410.c
@@ -170,7 +170,9 @@ int __init s3c2410_init(void)
{
printk("S3C2410: Initialising architecture\n");
+#ifdef CONFIG_PM
register_syscore_ops(&s3c2410_pm_syscore_ops);
+#endif
register_syscore_ops(&s3c24xx_irq_syscore_ops);
return sysdev_register(&s3c2410_sysdev);
diff --git a/arch/arm/mach-s3c2412/s3c2412.c b/arch/arm/mach-s3c2412/s3c2412.c
index ef0958d3e5c6..57a1e01e4e50 100644
--- a/arch/arm/mach-s3c2412/s3c2412.c
+++ b/arch/arm/mach-s3c2412/s3c2412.c
@@ -245,7 +245,9 @@ int __init s3c2412_init(void)
{
printk("S3C2412: Initialising architecture\n");
+#ifdef CONFIG_PM
register_syscore_ops(&s3c2412_pm_syscore_ops);
+#endif
register_syscore_ops(&s3c24xx_irq_syscore_ops);
return sysdev_register(&s3c2412_sysdev);
diff --git a/arch/arm/mach-s3c2416/s3c2416.c b/arch/arm/mach-s3c2416/s3c2416.c
index 494ce913dc95..20b3fdfb3051 100644
--- a/arch/arm/mach-s3c2416/s3c2416.c
+++ b/arch/arm/mach-s3c2416/s3c2416.c
@@ -97,7 +97,9 @@ int __init s3c2416_init(void)
s3c_fb_setname("s3c2443-fb");
+#ifdef CONFIG_PM
register_syscore_ops(&s3c2416_pm_syscore_ops);
+#endif
register_syscore_ops(&s3c24xx_irq_syscore_ops);
return sysdev_register(&s3c2416_sysdev);
diff --git a/arch/arm/mach-s3c2440/s3c2440.c b/arch/arm/mach-s3c2440/s3c2440.c
index ce99ff72838d..2270d3360216 100644
--- a/arch/arm/mach-s3c2440/s3c2440.c
+++ b/arch/arm/mach-s3c2440/s3c2440.c
@@ -55,7 +55,9 @@ int __init s3c2440_init(void)
/* register suspend/resume handlers */
+#ifdef CONFIG_PM
register_syscore_ops(&s3c2410_pm_syscore_ops);
+#endif
register_syscore_ops(&s3c244x_pm_syscore_ops);
register_syscore_ops(&s3c24xx_irq_syscore_ops);
diff --git a/arch/arm/mach-s3c2440/s3c2442.c b/arch/arm/mach-s3c2440/s3c2442.c
index 9ad99f8016a1..6f2b65e6e068 100644
--- a/arch/arm/mach-s3c2440/s3c2442.c
+++ b/arch/arm/mach-s3c2440/s3c2442.c
@@ -169,7 +169,9 @@ int __init s3c2442_init(void)
{
printk("S3C2442: Initialising architecture\n");
+#ifdef CONFIG_PM
register_syscore_ops(&s3c2410_pm_syscore_ops);
+#endif
register_syscore_ops(&s3c244x_pm_syscore_ops);
register_syscore_ops(&s3c24xx_irq_syscore_ops);
diff --git a/arch/arm/mach-tegra/cpu-tegra.c b/arch/arm/mach-tegra/cpu-tegra.c
index 0e1016a827ac..0e0fd4d889bd 100644
--- a/arch/arm/mach-tegra/cpu-tegra.c
+++ b/arch/arm/mach-tegra/cpu-tegra.c
@@ -32,7 +32,6 @@
#include <asm/system.h>
-#include <mach/hardware.h>
#include <mach/clk.h>
/* Frequency table index must be sequential starting at 0 */
diff --git a/arch/arm/mach-ux500/Kconfig b/arch/arm/mach-ux500/Kconfig
index 4210cb434dbc..a3e0c8692f0d 100644
--- a/arch/arm/mach-ux500/Kconfig
+++ b/arch/arm/mach-ux500/Kconfig
@@ -6,6 +6,7 @@ config UX500_SOC_COMMON
select ARM_GIC
select HAS_MTU
select ARM_ERRATA_753970
+ select ARM_ERRATA_754322
menu "Ux500 SoC"
diff --git a/arch/arm/mm/init.c b/arch/arm/mm/init.c
index 34409a08ba0d..04e9a92bb47a 100644
--- a/arch/arm/mm/init.c
+++ b/arch/arm/mm/init.c
@@ -496,6 +496,13 @@ static void __init free_unused_memmap(struct meminfo *mi)
*/
bank_start = min(bank_start,
ALIGN(prev_bank_end, PAGES_PER_SECTION));
+#else
+ /*
+ * Align down here since the VM subsystem insists that the
+ * memmap entries are valid from the bank start aligned to
+ * MAX_ORDER_NR_PAGES.
+ */
+ bank_start = round_down(bank_start, MAX_ORDER_NR_PAGES);
#endif
/*
* If we had a previous bank, and there is a space
diff --git a/arch/arm/plat-mxc/include/mach/common.h b/arch/arm/plat-mxc/include/mach/common.h
index 4e3d97890d69..d19703930ef6 100644
--- a/arch/arm/plat-mxc/include/mach/common.h
+++ b/arch/arm/plat-mxc/include/mach/common.h
@@ -64,6 +64,8 @@ extern int mx51_clocks_init(unsigned long ckil, unsigned long osc,
unsigned long ckih1, unsigned long ckih2);
extern int mx53_clocks_init(unsigned long ckil, unsigned long osc,
unsigned long ckih1, unsigned long ckih2);
+extern int mx51_clocks_init_dt(void);
+extern int mx53_clocks_init_dt(void);
extern struct platform_device *mxc_register_gpio(char *name, int id,
resource_size_t iobase, resource_size_t iosize, int irq, int irq_high);
extern int mxc_register_device(struct platform_device *pdev, void *data);
@@ -72,4 +74,10 @@ extern void mxc_arch_reset_init(void __iomem *);
extern void mx51_efikamx_reset(void);
extern int mx53_revision(void);
extern int mx53_display_revision(void);
+
+extern void imx51_babbage_common_init(void);
+extern void imx53_ard_common_init(void);
+extern void imx53_evk_common_init(void);
+extern void imx53_qsb_common_init(void);
+extern void imx53_smd_common_init(void);
#endif
diff --git a/arch/arm/plat-omap/devices.c b/arch/arm/plat-omap/devices.c
index ea28f98d5d6a..bd9a06b3ee89 100644
--- a/arch/arm/plat-omap/devices.c
+++ b/arch/arm/plat-omap/devices.c
@@ -26,54 +26,8 @@
#include <plat/mmc.h>
#include <mach/gpio.h>
#include <plat/menelaus.h>
-#include <plat/mcbsp.h>
#include <plat/omap44xx.h>
-/*-------------------------------------------------------------------------*/
-
-#if defined(CONFIG_OMAP_MCBSP) || defined(CONFIG_OMAP_MCBSP_MODULE)
-
-static struct platform_device **omap_mcbsp_devices;
-
-void omap_mcbsp_register_board_cfg(struct resource *res, int res_count,
- struct omap_mcbsp_platform_data *config, int size)
-{
- int i;
-
- omap_mcbsp_devices = kzalloc(size * sizeof(struct platform_device *),
- GFP_KERNEL);
- if (!omap_mcbsp_devices) {
- printk(KERN_ERR "Could not register McBSP devices\n");
- return;
- }
-
- for (i = 0; i < size; i++) {
- struct platform_device *new_mcbsp;
- int ret;
-
- new_mcbsp = platform_device_alloc("omap-mcbsp", i + 1);
- if (!new_mcbsp)
- continue;
- platform_device_add_resources(new_mcbsp, &res[i * res_count],
- res_count);
- new_mcbsp->dev.platform_data = &config[i];
- ret = platform_device_add(new_mcbsp);
- if (ret) {
- platform_device_put(new_mcbsp);
- continue;
- }
- omap_mcbsp_devices[i] = new_mcbsp;
- }
-}
-
-#else
-void omap_mcbsp_register_board_cfg(struct resource *res, int res_count,
- struct omap_mcbsp_platform_data *config, int size)
-{ }
-#endif
-
-/*-------------------------------------------------------------------------*/
-
#if defined(CONFIG_SND_OMAP_SOC_MCPDM) || \
defined(CONFIG_SND_OMAP_SOC_MCPDM_MODULE)
diff --git a/arch/arm/plat-omap/dmtimer.c b/arch/arm/plat-omap/dmtimer.c
index 75a847dd776a..de7896fd9b33 100644
--- a/arch/arm/plat-omap/dmtimer.c
+++ b/arch/arm/plat-omap/dmtimer.c
@@ -3,6 +3,12 @@
*
* OMAP Dual-Mode Timers
*
+ * Copyright (C) 2010 Texas Instruments Incorporated - http://www.ti.com/
+ * Tarun Kanti DebBarma <tarun.kanti@ti.com>
+ * Thara Gopinath <thara@ti.com>
+ *
+ * dmtimer adaptation to platform_driver.
+ *
* Copyright (C) 2005 Nokia Corporation
* OMAP2 support by Juha Yrjola
* API improvements and OMAP2 clock framework support by Timo Teras
@@ -29,168 +35,80 @@
* 675 Mass Ave, Cambridge, MA 02139, USA.
*/
-#include <linux/init.h>
-#include <linux/spinlock.h>
-#include <linux/errno.h>
-#include <linux/list.h>
-#include <linux/clk.h>
-#include <linux/delay.h>
#include <linux/io.h>
-#include <linux/module.h>
-#include <mach/hardware.h>
-#include <plat/dmtimer.h>
-#include <mach/irqs.h>
-
-static int dm_timer_count;
-
-#ifdef CONFIG_ARCH_OMAP1
-static struct omap_dm_timer omap1_dm_timers[] = {
- { .phys_base = 0xfffb1400, .irq = INT_1610_GPTIMER1 },
- { .phys_base = 0xfffb1c00, .irq = INT_1610_GPTIMER2 },
- { .phys_base = 0xfffb2400, .irq = INT_1610_GPTIMER3 },
- { .phys_base = 0xfffb2c00, .irq = INT_1610_GPTIMER4 },
- { .phys_base = 0xfffb3400, .irq = INT_1610_GPTIMER5 },
- { .phys_base = 0xfffb3c00, .irq = INT_1610_GPTIMER6 },
- { .phys_base = 0xfffb7400, .irq = INT_1610_GPTIMER7 },
- { .phys_base = 0xfffbd400, .irq = INT_1610_GPTIMER8 },
-};
-
-static const int omap1_dm_timer_count = ARRAY_SIZE(omap1_dm_timers);
-
-#else
-#define omap1_dm_timers NULL
-#define omap1_dm_timer_count 0
-#endif /* CONFIG_ARCH_OMAP1 */
-
-#ifdef CONFIG_ARCH_OMAP2
-static struct omap_dm_timer omap2_dm_timers[] = {
- { .phys_base = 0x48028000, .irq = INT_24XX_GPTIMER1 },
- { .phys_base = 0x4802a000, .irq = INT_24XX_GPTIMER2 },
- { .phys_base = 0x48078000, .irq = INT_24XX_GPTIMER3 },
- { .phys_base = 0x4807a000, .irq = INT_24XX_GPTIMER4 },
- { .phys_base = 0x4807c000, .irq = INT_24XX_GPTIMER5 },
- { .phys_base = 0x4807e000, .irq = INT_24XX_GPTIMER6 },
- { .phys_base = 0x48080000, .irq = INT_24XX_GPTIMER7 },
- { .phys_base = 0x48082000, .irq = INT_24XX_GPTIMER8 },
- { .phys_base = 0x48084000, .irq = INT_24XX_GPTIMER9 },
- { .phys_base = 0x48086000, .irq = INT_24XX_GPTIMER10 },
- { .phys_base = 0x48088000, .irq = INT_24XX_GPTIMER11 },
- { .phys_base = 0x4808a000, .irq = INT_24XX_GPTIMER12 },
-};
-
-static const char *omap2_dm_source_names[] __initdata = {
- "sys_ck",
- "func_32k_ck",
- "alt_ck",
- NULL
-};
-
-static struct clk *omap2_dm_source_clocks[3];
-static const int omap2_dm_timer_count = ARRAY_SIZE(omap2_dm_timers);
-
-#else
-#define omap2_dm_timers NULL
-#define omap2_dm_timer_count 0
-#define omap2_dm_source_names NULL
-#define omap2_dm_source_clocks NULL
-#endif /* CONFIG_ARCH_OMAP2 */
-
-#ifdef CONFIG_ARCH_OMAP3
-static struct omap_dm_timer omap3_dm_timers[] = {
- { .phys_base = 0x48318000, .irq = INT_24XX_GPTIMER1 },
- { .phys_base = 0x49032000, .irq = INT_24XX_GPTIMER2 },
- { .phys_base = 0x49034000, .irq = INT_24XX_GPTIMER3 },
- { .phys_base = 0x49036000, .irq = INT_24XX_GPTIMER4 },
- { .phys_base = 0x49038000, .irq = INT_24XX_GPTIMER5 },
- { .phys_base = 0x4903A000, .irq = INT_24XX_GPTIMER6 },
- { .phys_base = 0x4903C000, .irq = INT_24XX_GPTIMER7 },
- { .phys_base = 0x4903E000, .irq = INT_24XX_GPTIMER8 },
- { .phys_base = 0x49040000, .irq = INT_24XX_GPTIMER9 },
- { .phys_base = 0x48086000, .irq = INT_24XX_GPTIMER10 },
- { .phys_base = 0x48088000, .irq = INT_24XX_GPTIMER11 },
- { .phys_base = 0x48304000, .irq = INT_34XX_GPT12_IRQ },
-};
-
-static const char *omap3_dm_source_names[] __initdata = {
- "sys_ck",
- "omap_32k_fck",
- NULL
-};
-
-static struct clk *omap3_dm_source_clocks[2];
-static const int omap3_dm_timer_count = ARRAY_SIZE(omap3_dm_timers);
+#include <linux/slab.h>
+#include <linux/err.h>
+#include <linux/pm_runtime.h>
-#else
-#define omap3_dm_timers NULL
-#define omap3_dm_timer_count 0
-#define omap3_dm_source_names NULL
-#define omap3_dm_source_clocks NULL
-#endif /* CONFIG_ARCH_OMAP3 */
-
-#ifdef CONFIG_ARCH_OMAP4
-static struct omap_dm_timer omap4_dm_timers[] = {
- { .phys_base = 0x4a318000, .irq = OMAP44XX_IRQ_GPT1 },
- { .phys_base = 0x48032000, .irq = OMAP44XX_IRQ_GPT2 },
- { .phys_base = 0x48034000, .irq = OMAP44XX_IRQ_GPT3 },
- { .phys_base = 0x48036000, .irq = OMAP44XX_IRQ_GPT4 },
- { .phys_base = 0x40138000, .irq = OMAP44XX_IRQ_GPT5 },
- { .phys_base = 0x4013a000, .irq = OMAP44XX_IRQ_GPT6 },
- { .phys_base = 0x4013a000, .irq = OMAP44XX_IRQ_GPT7 },
- { .phys_base = 0x4013e000, .irq = OMAP44XX_IRQ_GPT8 },
- { .phys_base = 0x4803e000, .irq = OMAP44XX_IRQ_GPT9 },
- { .phys_base = 0x48086000, .irq = OMAP44XX_IRQ_GPT10 },
- { .phys_base = 0x48088000, .irq = OMAP44XX_IRQ_GPT11 },
- { .phys_base = 0x4a320000, .irq = OMAP44XX_IRQ_GPT12 },
-};
-static const char *omap4_dm_source_names[] __initdata = {
- "sys_clkin_ck",
- "sys_32k_ck",
- NULL
-};
-static struct clk *omap4_dm_source_clocks[2];
-static const int omap4_dm_timer_count = ARRAY_SIZE(omap4_dm_timers);
-
-#else
-#define omap4_dm_timers NULL
-#define omap4_dm_timer_count 0
-#define omap4_dm_source_names NULL
-#define omap4_dm_source_clocks NULL
-#endif /* CONFIG_ARCH_OMAP4 */
-
-static struct omap_dm_timer *dm_timers;
-static const char **dm_source_names;
-static struct clk **dm_source_clocks;
+#include <plat/dmtimer.h>
-static spinlock_t dm_timer_lock;
+static LIST_HEAD(omap_timer_list);
+static DEFINE_SPINLOCK(dm_timer_lock);
-/*
- * Reads timer registers in posted and non-posted mode. The posted mode bit
- * is encoded in reg. Note that in posted mode write pending bit must be
- * checked. Otherwise a read of a non completed write will produce an error.
+/**
+ * omap_dm_timer_read_reg - read timer registers in posted and non-posted mode
+ * @timer: timer pointer over which read operation to perform
+ * @reg: lowest byte holds the register offset
+ *
+ * The posted mode bit is encoded in reg. Note that in posted mode write
+ * pending bit must be checked. Otherwise a read of a non completed write
+ * will produce an error.
*/
static inline u32 omap_dm_timer_read_reg(struct omap_dm_timer *timer, u32 reg)
{
- return __omap_dm_timer_read(timer->io_base, reg, timer->posted);
+ WARN_ON((reg & 0xff) < _OMAP_TIMER_WAKEUP_EN_OFFSET);
+ return __omap_dm_timer_read(timer, reg, timer->posted);
}
-/*
- * Writes timer registers in posted and non-posted mode. The posted mode bit
- * is encoded in reg. Note that in posted mode the write pending bit must be
- * checked. Otherwise a write on a register which has a pending write will be
- * lost.
+/**
+ * omap_dm_timer_write_reg - write timer registers in posted and non-posted mode
+ * @timer: timer pointer over which write operation is to perform
+ * @reg: lowest byte holds the register offset
+ * @value: data to write into the register
+ *
+ * The posted mode bit is encoded in reg. Note that in posted mode the write
+ * pending bit must be checked. Otherwise a write on a register which has a
+ * pending write will be lost.
*/
static void omap_dm_timer_write_reg(struct omap_dm_timer *timer, u32 reg,
u32 value)
{
- __omap_dm_timer_write(timer->io_base, reg, value, timer->posted);
+ WARN_ON((reg & 0xff) < _OMAP_TIMER_WAKEUP_EN_OFFSET);
+ __omap_dm_timer_write(timer, reg, value, timer->posted);
+}
+
+static void omap_timer_restore_context(struct omap_dm_timer *timer)
+{
+ omap_dm_timer_write_reg(timer, OMAP_TIMER_OCP_CFG_OFFSET,
+ timer->context.tiocp_cfg);
+ if (timer->revision > 1)
+ __raw_writel(timer->context.tistat, timer->sys_stat);
+
+ __raw_writel(timer->context.tisr, timer->irq_stat);
+ omap_dm_timer_write_reg(timer, OMAP_TIMER_WAKEUP_EN_REG,
+ timer->context.twer);
+ omap_dm_timer_write_reg(timer, OMAP_TIMER_COUNTER_REG,
+ timer->context.tcrr);
+ omap_dm_timer_write_reg(timer, OMAP_TIMER_LOAD_REG,
+ timer->context.tldr);
+ omap_dm_timer_write_reg(timer, OMAP_TIMER_MATCH_REG,
+ timer->context.tmar);
+ omap_dm_timer_write_reg(timer, OMAP_TIMER_IF_CTRL_REG,
+ timer->context.tsicr);
+ __raw_writel(timer->context.tier, timer->irq_ena);
+ omap_dm_timer_write_reg(timer, OMAP_TIMER_CTRL_REG,
+ timer->context.tclr);
}
static void omap_dm_timer_wait_for_reset(struct omap_dm_timer *timer)
{
int c;
+ if (!timer->sys_stat)
+ return;
+
c = 0;
- while (!(omap_dm_timer_read_reg(timer, OMAP_TIMER_SYS_STAT_REG) & 1)) {
+ while (!(__raw_readl(timer->sys_stat) & 1)) {
c++;
if (c > 100000) {
printk(KERN_ERR "Timer failed to reset\n");
@@ -201,53 +119,65 @@ static void omap_dm_timer_wait_for_reset(struct omap_dm_timer *timer)
static void omap_dm_timer_reset(struct omap_dm_timer *timer)
{
- int autoidle = 0, wakeup = 0;
-
- if (!cpu_class_is_omap2() || timer != &dm_timers[0]) {
+ omap_dm_timer_enable(timer);
+ if (timer->pdev->id != 1) {
omap_dm_timer_write_reg(timer, OMAP_TIMER_IF_CTRL_REG, 0x06);
omap_dm_timer_wait_for_reset(timer);
}
- omap_dm_timer_set_source(timer, OMAP_TIMER_SRC_32_KHZ);
-
- /* Enable autoidle on OMAP2+ */
- if (cpu_class_is_omap2())
- autoidle = 1;
-
- /*
- * Enable wake-up on OMAP2 CPUs.
- */
- if (cpu_class_is_omap2())
- wakeup = 1;
- __omap_dm_timer_reset(timer->io_base, autoidle, wakeup);
+ __omap_dm_timer_reset(timer, 0, 0);
+ omap_dm_timer_disable(timer);
timer->posted = 1;
}
-void omap_dm_timer_prepare(struct omap_dm_timer *timer)
+int omap_dm_timer_prepare(struct omap_dm_timer *timer)
{
- omap_dm_timer_enable(timer);
- omap_dm_timer_reset(timer);
+ struct dmtimer_platform_data *pdata = timer->pdev->dev.platform_data;
+ int ret;
+
+ timer->fclk = clk_get(&timer->pdev->dev, "fck");
+ if (WARN_ON_ONCE(IS_ERR_OR_NULL(timer->fclk))) {
+ timer->fclk = NULL;
+ dev_err(&timer->pdev->dev, ": No fclk handle.\n");
+ return -EINVAL;
+ }
+
+ if (pdata->needs_manual_reset)
+ omap_dm_timer_reset(timer);
+
+ ret = omap_dm_timer_set_source(timer, OMAP_TIMER_SRC_32_KHZ);
+
+ timer->posted = 1;
+ return ret;
}
struct omap_dm_timer *omap_dm_timer_request(void)
{
- struct omap_dm_timer *timer = NULL;
+ struct omap_dm_timer *timer = NULL, *t;
unsigned long flags;
- int i;
+ int ret = 0;
spin_lock_irqsave(&dm_timer_lock, flags);
- for (i = 0; i < dm_timer_count; i++) {
- if (dm_timers[i].reserved)
+ list_for_each_entry(t, &omap_timer_list, node) {
+ if (t->reserved)
continue;
- timer = &dm_timers[i];
+ timer = t;
timer->reserved = 1;
break;
}
+
+ if (timer) {
+ ret = omap_dm_timer_prepare(timer);
+ if (ret) {
+ timer->reserved = 0;
+ timer = NULL;
+ }
+ }
spin_unlock_irqrestore(&dm_timer_lock, flags);
- if (timer != NULL)
- omap_dm_timer_prepare(timer);
+ if (!timer)
+ pr_debug("%s: timer request failed!\n", __func__);
return timer;
}
@@ -255,74 +185,65 @@ EXPORT_SYMBOL_GPL(omap_dm_timer_request);
struct omap_dm_timer *omap_dm_timer_request_specific(int id)
{
- struct omap_dm_timer *timer;
+ struct omap_dm_timer *timer = NULL, *t;
unsigned long flags;
+ int ret = 0;
spin_lock_irqsave(&dm_timer_lock, flags);
- if (id <= 0 || id > dm_timer_count || dm_timers[id-1].reserved) {
- spin_unlock_irqrestore(&dm_timer_lock, flags);
- printk("BUG: warning at %s:%d/%s(): unable to get timer %d\n",
- __FILE__, __LINE__, __func__, id);
- dump_stack();
- return NULL;
+ list_for_each_entry(t, &omap_timer_list, node) {
+ if (t->pdev->id == id && !t->reserved) {
+ timer = t;
+ timer->reserved = 1;
+ break;
+ }
}
- timer = &dm_timers[id-1];
- timer->reserved = 1;
+ if (timer) {
+ ret = omap_dm_timer_prepare(timer);
+ if (ret) {
+ timer->reserved = 0;
+ timer = NULL;
+ }
+ }
spin_unlock_irqrestore(&dm_timer_lock, flags);
- omap_dm_timer_prepare(timer);
+ if (!timer)
+ pr_debug("%s: timer%d request failed!\n", __func__, id);
return timer;
}
EXPORT_SYMBOL_GPL(omap_dm_timer_request_specific);
-void omap_dm_timer_free(struct omap_dm_timer *timer)
+int omap_dm_timer_free(struct omap_dm_timer *timer)
{
- omap_dm_timer_enable(timer);
- omap_dm_timer_reset(timer);
- omap_dm_timer_disable(timer);
+ if (unlikely(!timer))
+ return -EINVAL;
+
+ clk_put(timer->fclk);
WARN_ON(!timer->reserved);
timer->reserved = 0;
+ return 0;
}
EXPORT_SYMBOL_GPL(omap_dm_timer_free);
void omap_dm_timer_enable(struct omap_dm_timer *timer)
{
- if (timer->enabled)
- return;
-
-#ifdef CONFIG_ARCH_OMAP2PLUS
- if (cpu_class_is_omap2()) {
- clk_enable(timer->fclk);
- clk_enable(timer->iclk);
- }
-#endif
-
- timer->enabled = 1;
+ pm_runtime_get_sync(&timer->pdev->dev);
}
EXPORT_SYMBOL_GPL(omap_dm_timer_enable);
void omap_dm_timer_disable(struct omap_dm_timer *timer)
{
- if (!timer->enabled)
- return;
-
-#ifdef CONFIG_ARCH_OMAP2PLUS
- if (cpu_class_is_omap2()) {
- clk_disable(timer->iclk);
- clk_disable(timer->fclk);
- }
-#endif
-
- timer->enabled = 0;
+ pm_runtime_put(&timer->pdev->dev);
}
EXPORT_SYMBOL_GPL(omap_dm_timer_disable);
int omap_dm_timer_get_irq(struct omap_dm_timer *timer)
{
- return timer->irq;
+ if (timer)
+ return timer->irq;
+ return -EINVAL;
}
EXPORT_SYMBOL_GPL(omap_dm_timer_get_irq);
@@ -334,24 +255,29 @@ EXPORT_SYMBOL_GPL(omap_dm_timer_get_irq);
*/
__u32 omap_dm_timer_modify_idlect_mask(__u32 inputmask)
{
- int i;
+ int i = 0;
+ struct omap_dm_timer *timer = NULL;
+ unsigned long flags;
/* If ARMXOR cannot be idled this function call is unnecessary */
if (!(inputmask & (1 << 1)))
return inputmask;
/* If any active timer is using ARMXOR return modified mask */
- for (i = 0; i < dm_timer_count; i++) {
+ spin_lock_irqsave(&dm_timer_lock, flags);
+ list_for_each_entry(timer, &omap_timer_list, node) {
u32 l;
- l = omap_dm_timer_read_reg(&dm_timers[i], OMAP_TIMER_CTRL_REG);
+ l = omap_dm_timer_read_reg(timer, OMAP_TIMER_CTRL_REG);
if (l & OMAP_TIMER_CTRL_ST) {
if (((omap_readl(MOD_CONF_CTRL_1) >> (i * 2)) & 0x03) == 0)
inputmask &= ~(1 << 1);
else
inputmask &= ~(1 << 2);
}
+ i++;
}
+ spin_unlock_irqrestore(&dm_timer_lock, flags);
return inputmask;
}
@@ -361,7 +287,9 @@ EXPORT_SYMBOL_GPL(omap_dm_timer_modify_idlect_mask);
struct clk *omap_dm_timer_get_fclk(struct omap_dm_timer *timer)
{
- return timer->fclk;
+ if (timer)
+ return timer->fclk;
+ return NULL;
}
EXPORT_SYMBOL_GPL(omap_dm_timer_get_fclk);
@@ -375,70 +303,91 @@ EXPORT_SYMBOL_GPL(omap_dm_timer_modify_idlect_mask);
#endif
-void omap_dm_timer_trigger(struct omap_dm_timer *timer)
+int omap_dm_timer_trigger(struct omap_dm_timer *timer)
{
+ if (unlikely(!timer || pm_runtime_suspended(&timer->pdev->dev))) {
+ pr_err("%s: timer not available or enabled.\n", __func__);
+ return -EINVAL;
+ }
+
omap_dm_timer_write_reg(timer, OMAP_TIMER_TRIGGER_REG, 0);
+ return 0;
}
EXPORT_SYMBOL_GPL(omap_dm_timer_trigger);
-void omap_dm_timer_start(struct omap_dm_timer *timer)
+int omap_dm_timer_start(struct omap_dm_timer *timer)
{
u32 l;
+ if (unlikely(!timer))
+ return -EINVAL;
+
+ omap_dm_timer_enable(timer);
+
+ if (timer->loses_context) {
+ u32 ctx_loss_cnt_after =
+ timer->get_context_loss_count(&timer->pdev->dev);
+ if (ctx_loss_cnt_after != timer->ctx_loss_count)
+ omap_timer_restore_context(timer);
+ }
+
l = omap_dm_timer_read_reg(timer, OMAP_TIMER_CTRL_REG);
if (!(l & OMAP_TIMER_CTRL_ST)) {
l |= OMAP_TIMER_CTRL_ST;
omap_dm_timer_write_reg(timer, OMAP_TIMER_CTRL_REG, l);
}
+
+ /* Save the context */
+ timer->context.tclr = l;
+ return 0;
}
EXPORT_SYMBOL_GPL(omap_dm_timer_start);
-void omap_dm_timer_stop(struct omap_dm_timer *timer)
+int omap_dm_timer_stop(struct omap_dm_timer *timer)
{
unsigned long rate = 0;
+ struct dmtimer_platform_data *pdata = timer->pdev->dev.platform_data;
-#ifdef CONFIG_ARCH_OMAP2PLUS
- rate = clk_get_rate(timer->fclk);
-#endif
+ if (unlikely(!timer))
+ return -EINVAL;
- __omap_dm_timer_stop(timer->io_base, timer->posted, rate);
+ if (!pdata->needs_manual_reset)
+ rate = clk_get_rate(timer->fclk);
+
+ __omap_dm_timer_stop(timer, timer->posted, rate);
+
+ return 0;
}
EXPORT_SYMBOL_GPL(omap_dm_timer_stop);
-#ifdef CONFIG_ARCH_OMAP1
-
int omap_dm_timer_set_source(struct omap_dm_timer *timer, int source)
{
- int n = (timer - dm_timers) << 1;
- u32 l;
-
- l = omap_readl(MOD_CONF_CTRL_1) & ~(0x03 << n);
- l |= source << n;
- omap_writel(l, MOD_CONF_CTRL_1);
+ int ret;
+ struct dmtimer_platform_data *pdata;
- return 0;
-}
-EXPORT_SYMBOL_GPL(omap_dm_timer_set_source);
+ if (unlikely(!timer))
+ return -EINVAL;
-#else
+ pdata = timer->pdev->dev.platform_data;
-int omap_dm_timer_set_source(struct omap_dm_timer *timer, int source)
-{
if (source < 0 || source >= 3)
return -EINVAL;
- return __omap_dm_timer_set_source(timer->fclk,
- dm_source_clocks[source]);
+ ret = pdata->set_timer_src(timer->pdev, source);
+
+ return ret;
}
EXPORT_SYMBOL_GPL(omap_dm_timer_set_source);
-#endif
-
-void omap_dm_timer_set_load(struct omap_dm_timer *timer, int autoreload,
+int omap_dm_timer_set_load(struct omap_dm_timer *timer, int autoreload,
unsigned int load)
{
u32 l;
+ if (unlikely(!timer))
+ return -EINVAL;
+
+ omap_dm_timer_enable(timer);
l = omap_dm_timer_read_reg(timer, OMAP_TIMER_CTRL_REG);
if (autoreload)
l |= OMAP_TIMER_CTRL_AR;
@@ -448,15 +397,32 @@ void omap_dm_timer_set_load(struct omap_dm_timer *timer, int autoreload,
omap_dm_timer_write_reg(timer, OMAP_TIMER_LOAD_REG, load);
omap_dm_timer_write_reg(timer, OMAP_TIMER_TRIGGER_REG, 0);
+ /* Save the context */
+ timer->context.tclr = l;
+ timer->context.tldr = load;
+ omap_dm_timer_disable(timer);
+ return 0;
}
EXPORT_SYMBOL_GPL(omap_dm_timer_set_load);
/* Optimized set_load which removes costly spin wait in timer_start */
-void omap_dm_timer_set_load_start(struct omap_dm_timer *timer, int autoreload,
+int omap_dm_timer_set_load_start(struct omap_dm_timer *timer, int autoreload,
unsigned int load)
{
u32 l;
+ if (unlikely(!timer))
+ return -EINVAL;
+
+ omap_dm_timer_enable(timer);
+
+ if (timer->loses_context) {
+ u32 ctx_loss_cnt_after =
+ timer->get_context_loss_count(&timer->pdev->dev);
+ if (ctx_loss_cnt_after != timer->ctx_loss_count)
+ omap_timer_restore_context(timer);
+ }
+
l = omap_dm_timer_read_reg(timer, OMAP_TIMER_CTRL_REG);
if (autoreload) {
l |= OMAP_TIMER_CTRL_AR;
@@ -466,15 +432,25 @@ void omap_dm_timer_set_load_start(struct omap_dm_timer *timer, int autoreload,
}
l |= OMAP_TIMER_CTRL_ST;
- __omap_dm_timer_load_start(timer->io_base, l, load, timer->posted);
+ __omap_dm_timer_load_start(timer, l, load, timer->posted);
+
+ /* Save the context */
+ timer->context.tclr = l;
+ timer->context.tldr = load;
+ timer->context.tcrr = load;
+ return 0;
}
EXPORT_SYMBOL_GPL(omap_dm_timer_set_load_start);
-void omap_dm_timer_set_match(struct omap_dm_timer *timer, int enable,
+int omap_dm_timer_set_match(struct omap_dm_timer *timer, int enable,
unsigned int match)
{
u32 l;
+ if (unlikely(!timer))
+ return -EINVAL;
+
+ omap_dm_timer_enable(timer);
l = omap_dm_timer_read_reg(timer, OMAP_TIMER_CTRL_REG);
if (enable)
l |= OMAP_TIMER_CTRL_CE;
@@ -482,14 +458,24 @@ void omap_dm_timer_set_match(struct omap_dm_timer *timer, int enable,
l &= ~OMAP_TIMER_CTRL_CE;
omap_dm_timer_write_reg(timer, OMAP_TIMER_CTRL_REG, l);
omap_dm_timer_write_reg(timer, OMAP_TIMER_MATCH_REG, match);
+
+ /* Save the context */
+ timer->context.tclr = l;
+ timer->context.tmar = match;
+ omap_dm_timer_disable(timer);
+ return 0;
}
EXPORT_SYMBOL_GPL(omap_dm_timer_set_match);
-void omap_dm_timer_set_pwm(struct omap_dm_timer *timer, int def_on,
+int omap_dm_timer_set_pwm(struct omap_dm_timer *timer, int def_on,
int toggle, int trigger)
{
u32 l;
+ if (unlikely(!timer))
+ return -EINVAL;
+
+ omap_dm_timer_enable(timer);
l = omap_dm_timer_read_reg(timer, OMAP_TIMER_CTRL_REG);
l &= ~(OMAP_TIMER_CTRL_GPOCFG | OMAP_TIMER_CTRL_SCPWM |
OMAP_TIMER_CTRL_PT | (0x03 << 10));
@@ -499,13 +485,22 @@ void omap_dm_timer_set_pwm(struct omap_dm_timer *timer, int def_on,
l |= OMAP_TIMER_CTRL_PT;
l |= trigger << 10;
omap_dm_timer_write_reg(timer, OMAP_TIMER_CTRL_REG, l);
+
+ /* Save the context */
+ timer->context.tclr = l;
+ omap_dm_timer_disable(timer);
+ return 0;
}
EXPORT_SYMBOL_GPL(omap_dm_timer_set_pwm);
-void omap_dm_timer_set_prescaler(struct omap_dm_timer *timer, int prescaler)
+int omap_dm_timer_set_prescaler(struct omap_dm_timer *timer, int prescaler)
{
u32 l;
+ if (unlikely(!timer))
+ return -EINVAL;
+
+ omap_dm_timer_enable(timer);
l = omap_dm_timer_read_reg(timer, OMAP_TIMER_CTRL_REG);
l &= ~(OMAP_TIMER_CTRL_PRE | (0x07 << 2));
if (prescaler >= 0x00 && prescaler <= 0x07) {
@@ -513,13 +508,28 @@ void omap_dm_timer_set_prescaler(struct omap_dm_timer *timer, int prescaler)
l |= prescaler << 2;
}
omap_dm_timer_write_reg(timer, OMAP_TIMER_CTRL_REG, l);
+
+ /* Save the context */
+ timer->context.tclr = l;
+ omap_dm_timer_disable(timer);
+ return 0;
}
EXPORT_SYMBOL_GPL(omap_dm_timer_set_prescaler);
-void omap_dm_timer_set_int_enable(struct omap_dm_timer *timer,
+int omap_dm_timer_set_int_enable(struct omap_dm_timer *timer,
unsigned int value)
{
- __omap_dm_timer_int_enable(timer->io_base, value);
+ if (unlikely(!timer))
+ return -EINVAL;
+
+ omap_dm_timer_enable(timer);
+ __omap_dm_timer_int_enable(timer, value);
+
+ /* Save the context */
+ timer->context.tier = value;
+ timer->context.twer = value;
+ omap_dm_timer_disable(timer);
+ return 0;
}
EXPORT_SYMBOL_GPL(omap_dm_timer_set_int_enable);
@@ -527,40 +537,61 @@ unsigned int omap_dm_timer_read_status(struct omap_dm_timer *timer)
{
unsigned int l;
- l = omap_dm_timer_read_reg(timer, OMAP_TIMER_STAT_REG);
+ if (unlikely(!timer || pm_runtime_suspended(&timer->pdev->dev))) {
+ pr_err("%s: timer not available or enabled.\n", __func__);
+ return 0;
+ }
+
+ l = __raw_readl(timer->irq_stat);
return l;
}
EXPORT_SYMBOL_GPL(omap_dm_timer_read_status);
-void omap_dm_timer_write_status(struct omap_dm_timer *timer, unsigned int value)
+int omap_dm_timer_write_status(struct omap_dm_timer *timer, unsigned int value)
{
- __omap_dm_timer_write_status(timer->io_base, value);
+ if (unlikely(!timer || pm_runtime_suspended(&timer->pdev->dev)))
+ return -EINVAL;
+
+ __omap_dm_timer_write_status(timer, value);
+ /* Save the context */
+ timer->context.tisr = value;
+ return 0;
}
EXPORT_SYMBOL_GPL(omap_dm_timer_write_status);
unsigned int omap_dm_timer_read_counter(struct omap_dm_timer *timer)
{
- return __omap_dm_timer_read_counter(timer->io_base, timer->posted);
+ if (unlikely(!timer || pm_runtime_suspended(&timer->pdev->dev))) {
+ pr_err("%s: timer not iavailable or enabled.\n", __func__);
+ return 0;
+ }
+
+ return __omap_dm_timer_read_counter(timer, timer->posted);
}
EXPORT_SYMBOL_GPL(omap_dm_timer_read_counter);
-void omap_dm_timer_write_counter(struct omap_dm_timer *timer, unsigned int value)
+int omap_dm_timer_write_counter(struct omap_dm_timer *timer, unsigned int value)
{
+ if (unlikely(!timer || pm_runtime_suspended(&timer->pdev->dev))) {
+ pr_err("%s: timer not available or enabled.\n", __func__);
+ return -EINVAL;
+ }
+
omap_dm_timer_write_reg(timer, OMAP_TIMER_COUNTER_REG, value);
+
+ /* Save the context */
+ timer->context.tcrr = value;
+ return 0;
}
EXPORT_SYMBOL_GPL(omap_dm_timer_write_counter);
int omap_dm_timers_active(void)
{
- int i;
-
- for (i = 0; i < dm_timer_count; i++) {
- struct omap_dm_timer *timer;
-
- timer = &dm_timers[i];
+ struct omap_dm_timer *timer;
- if (!timer->enabled)
+ list_for_each_entry(timer, &omap_timer_list, node) {
+ if (!timer->reserved)
continue;
if (omap_dm_timer_read_reg(timer, OMAP_TIMER_CTRL_REG) &
@@ -572,69 +603,147 @@ int omap_dm_timers_active(void)
}
EXPORT_SYMBOL_GPL(omap_dm_timers_active);
-static int __init omap_dm_timer_init(void)
+/**
+ * omap_dm_timer_probe - probe function called for every registered device
+ * @pdev: pointer to current timer platform device
+ *
+ * Called by driver framework at the end of device registration for all
+ * timer devices.
+ */
+static int __devinit omap_dm_timer_probe(struct platform_device *pdev)
{
+ int ret;
+ unsigned long flags;
struct omap_dm_timer *timer;
- int i, map_size = SZ_8K; /* Module 4KB + L4 4KB except on omap1 */
+ struct resource *mem, *irq, *ioarea;
+ struct dmtimer_platform_data *pdata = pdev->dev.platform_data;
- if (!(cpu_is_omap16xx() || cpu_class_is_omap2()))
+ if (!pdata) {
+ dev_err(&pdev->dev, "%s: no platform data.\n", __func__);
return -ENODEV;
+ }
- spin_lock_init(&dm_timer_lock);
-
- if (cpu_class_is_omap1()) {
- dm_timers = omap1_dm_timers;
- dm_timer_count = omap1_dm_timer_count;
- map_size = SZ_2K;
- } else if (cpu_is_omap24xx()) {
- dm_timers = omap2_dm_timers;
- dm_timer_count = omap2_dm_timer_count;
- dm_source_names = omap2_dm_source_names;
- dm_source_clocks = omap2_dm_source_clocks;
- } else if (cpu_is_omap34xx()) {
- dm_timers = omap3_dm_timers;
- dm_timer_count = omap3_dm_timer_count;
- dm_source_names = omap3_dm_source_names;
- dm_source_clocks = omap3_dm_source_clocks;
- } else if (cpu_is_omap44xx()) {
- dm_timers = omap4_dm_timers;
- dm_timer_count = omap4_dm_timer_count;
- dm_source_names = omap4_dm_source_names;
- dm_source_clocks = omap4_dm_source_clocks;
+ irq = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
+ if (unlikely(!irq)) {
+ dev_err(&pdev->dev, "%s: no IRQ resource.\n", __func__);
+ return -ENODEV;
}
- if (cpu_class_is_omap2())
- for (i = 0; dm_source_names[i] != NULL; i++)
- dm_source_clocks[i] = clk_get(NULL, dm_source_names[i]);
+ mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+ if (unlikely(!mem)) {
+ dev_err(&pdev->dev, "%s: no memory resource.\n", __func__);
+ return -ENODEV;
+ }
- if (cpu_is_omap243x())
- dm_timers[0].phys_base = 0x49018000;
+ ioarea = request_mem_region(mem->start, resource_size(mem),
+ pdev->name);
+ if (!ioarea) {
+ dev_err(&pdev->dev, "%s: region already claimed.\n", __func__);
+ return -EBUSY;
+ }
- for (i = 0; i < dm_timer_count; i++) {
- timer = &dm_timers[i];
+ timer = kzalloc(sizeof(struct omap_dm_timer), GFP_KERNEL);
+ if (!timer) {
+ dev_err(&pdev->dev, "%s: no memory for omap_dm_timer.\n",
+ __func__);
+ ret = -ENOMEM;
+ goto err_free_ioregion;
+ }
- /* Static mapping, never released */
- timer->io_base = ioremap(timer->phys_base, map_size);
- BUG_ON(!timer->io_base);
+ timer->io_base = ioremap(mem->start, resource_size(mem));
+ if (!timer->io_base) {
+ dev_err(&pdev->dev, "%s: ioremap failed.\n", __func__);
+ ret = -ENOMEM;
+ goto err_free_mem;
+ }
-#ifdef CONFIG_ARCH_OMAP2PLUS
- if (cpu_class_is_omap2()) {
- char clk_name[16];
- sprintf(clk_name, "gpt%d_ick", i + 1);
- timer->iclk = clk_get(NULL, clk_name);
- sprintf(clk_name, "gpt%d_fck", i + 1);
- timer->fclk = clk_get(NULL, clk_name);
- }
+ timer->id = pdev->id;
+ timer->irq = irq->start;
+ timer->reserved = pdata->reserved;
+ timer->pdev = pdev;
+ timer->loses_context = pdata->loses_context;
+ timer->get_context_loss_count = pdata->get_context_loss_count;
+
+ /* Skip pm_runtime_enable for OMAP1 */
+ if (!pdata->needs_manual_reset) {
+ pm_runtime_enable(&pdev->dev);
+ pm_runtime_irq_safe(&pdev->dev);
+ }
- /* One or two timers may be set up early for sys_timer */
- if (sys_timer_reserved & (1 << i)) {
- timer->reserved = 1;
- timer->posted = 1;
- }
-#endif
+ if (!timer->reserved) {
+ pm_runtime_get_sync(&pdev->dev);
+ __omap_dm_timer_init_regs(timer);
+ pm_runtime_put(&pdev->dev);
}
+ /* add the timer element to the list */
+ spin_lock_irqsave(&dm_timer_lock, flags);
+ list_add_tail(&timer->node, &omap_timer_list);
+ spin_unlock_irqrestore(&dm_timer_lock, flags);
+
+ dev_dbg(&pdev->dev, "Device Probed.\n");
+
return 0;
+
+err_free_mem:
+ kfree(timer);
+
+err_free_ioregion:
+ release_mem_region(mem->start, resource_size(mem));
+
+ return ret;
}
-arch_initcall(omap_dm_timer_init);
+/**
+ * omap_dm_timer_remove - cleanup a registered timer device
+ * @pdev: pointer to current timer platform device
+ *
+ * Called by driver framework whenever a timer device is unregistered.
+ * In addition to freeing platform resources it also deletes the timer
+ * entry from the local list.
+ */
+static int __devexit omap_dm_timer_remove(struct platform_device *pdev)
+{
+ struct omap_dm_timer *timer;
+ unsigned long flags;
+ int ret = -EINVAL;
+
+ spin_lock_irqsave(&dm_timer_lock, flags);
+ list_for_each_entry(timer, &omap_timer_list, node)
+ if (timer->pdev->id == pdev->id) {
+ list_del(&timer->node);
+ kfree(timer);
+ ret = 0;
+ break;
+ }
+ spin_unlock_irqrestore(&dm_timer_lock, flags);
+
+ return ret;
+}
+
+static struct platform_driver omap_dm_timer_driver = {
+ .probe = omap_dm_timer_probe,
+ .remove = omap_dm_timer_remove,
+ .driver = {
+ .name = "omap_timer",
+ },
+};
+
+static int __init omap_dm_timer_driver_init(void)
+{
+ return platform_driver_register(&omap_dm_timer_driver);
+}
+
+static void __exit omap_dm_timer_driver_exit(void)
+{
+ platform_driver_unregister(&omap_dm_timer_driver);
+}
+
+early_platform_init("earlytimer", &omap_dm_timer_driver);
+module_init(omap_dm_timer_driver_init);
+module_exit(omap_dm_timer_driver_exit);
+
+MODULE_DESCRIPTION("OMAP Dual-Mode Timer Driver");
+MODULE_LICENSE("GPL");
+MODULE_ALIAS("platform:" DRIVER_NAME);
+MODULE_AUTHOR("Texas Instruments Inc");
diff --git a/arch/arm/plat-omap/i2c.c b/arch/arm/plat-omap/i2c.c
index 3341ca4703e9..c20beb8ed38b 100644
--- a/arch/arm/plat-omap/i2c.c
+++ b/arch/arm/plat-omap/i2c.c
@@ -123,19 +123,11 @@ static void omap_pm_set_max_mpu_wakeup_lat_compat(struct device *dev, long t)
omap_pm_set_max_mpu_wakeup_lat(dev, t);
}
-static struct omap_device_pm_latency omap_i2c_latency[] = {
- [0] = {
- .deactivate_func = omap_device_idle_hwmods,
- .activate_func = omap_device_enable_hwmods,
- .flags = OMAP_DEVICE_LATENCY_AUTO_ADJUST,
- },
-};
-
static inline int omap2_i2c_add_bus(int bus_id)
{
int l;
struct omap_hwmod *oh;
- struct omap_device *od;
+ struct platform_device *pdev;
char oh_name[MAX_OMAP_I2C_HWMOD_NAME_LEN];
struct omap_i2c_bus_platform_data *pdata;
@@ -160,12 +152,12 @@ static inline int omap2_i2c_add_bus(int bus_id)
*/
if (cpu_is_omap34xx())
pdata->set_mpu_wkup_lat = omap_pm_set_max_mpu_wakeup_lat_compat;
- od = omap_device_build(name, bus_id, oh, pdata,
+ pdev = omap_device_build(name, bus_id, oh, pdata,
sizeof(struct omap_i2c_bus_platform_data),
- omap_i2c_latency, ARRAY_SIZE(omap_i2c_latency), 0);
- WARN(IS_ERR(od), "Could not build omap_device for %s\n", name);
+ NULL, 0, 0);
+ WARN(IS_ERR(pdev), "Could not build omap_device for %s\n", name);
- return PTR_ERR(od);
+ return PTR_ERR(pdev);
}
#else
static inline int omap2_i2c_add_bus(int bus_id)
diff --git a/arch/arm/plat-omap/include/plat/clock.h b/arch/arm/plat-omap/include/plat/clock.h
index df4b9683f17f..197ca03c3f7d 100644
--- a/arch/arm/plat-omap/include/plat/clock.h
+++ b/arch/arm/plat-omap/include/plat/clock.h
@@ -80,8 +80,6 @@ struct clkops {
*
* @div is the divisor that should be applied to the parent clock's rate
* to produce the current clock's rate.
- *
- * XXX @flags probably should be replaced with an struct omap_chip.
*/
struct clksel_rate {
u32 val;
diff --git a/arch/arm/plat-omap/include/plat/common.h b/arch/arm/plat-omap/include/plat/common.h
index 4564cc697d7f..abda2c7e499b 100644
--- a/arch/arm/plat-omap/include/plat/common.h
+++ b/arch/arm/plat-omap/include/plat/common.h
@@ -45,6 +45,15 @@ extern unsigned long long notrace omap_32k_sched_clock(void);
extern void omap_reserve(void);
+void omap2420_init_early(void);
+void omap2430_init_early(void);
+void omap3430_init_early(void);
+void omap35xx_init_early(void);
+void omap3630_init_early(void);
+void am35xx_init_early(void);
+void ti816x_init_early(void);
+void omap4430_init_early(void);
+
/*
* IO bases for various OMAP processors
* Except the tap base, rest all the io bases
@@ -74,7 +83,11 @@ void omap2_set_globals_sdrc(struct omap_globals *);
void omap2_set_globals_control(struct omap_globals *);
void omap2_set_globals_prcm(struct omap_globals *);
+void omap242x_map_io(void);
+void omap243x_map_io(void);
void omap3_map_io(void);
+void omap4_map_io(void);
+
/**
* omap_test_timeout - busy-loop, testing a condition
diff --git a/arch/arm/plat-omap/include/plat/cpu.h b/arch/arm/plat-omap/include/plat/cpu.h
index 67b3d75884cd..2f9026942229 100644
--- a/arch/arm/plat-omap/include/plat/cpu.h
+++ b/arch/arm/plat-omap/include/plat/cpu.h
@@ -44,13 +44,6 @@
int omap_type(void);
-struct omap_chip_id {
- u16 oc;
- u8 type;
-};
-
-#define OMAP_CHIP_INIT(x) { .oc = x }
-
/*
* omap_rev bits:
* CPU id bits (0730, 1510, 1710, 2422...) [31:16]
@@ -60,19 +53,6 @@ struct omap_chip_id {
unsigned int omap_rev(void);
/*
- * Define CPU revision bits
- *
- * Verbose meaning of the revision bits may be different for a silicon
- * family. This difference can be handled separately.
- */
-#define OMAP_REVBITS_00 0x00
-#define OMAP_REVBITS_01 0x01
-#define OMAP_REVBITS_02 0x02
-#define OMAP_REVBITS_03 0x03
-#define OMAP_REVBITS_04 0x04
-#define OMAP_REVBITS_05 0x05
-
-/*
* Get the CPU revision for OMAP devices
*/
#define GET_OMAP_REVISION() ((omap_rev() >> 8) & 0xff)
@@ -262,7 +242,7 @@ IS_OMAP_TYPE(2422, 0x2422)
IS_OMAP_TYPE(2423, 0x2423)
IS_OMAP_TYPE(2430, 0x2430)
IS_OMAP_TYPE(3430, 0x3430)
-IS_OMAP_TYPE(3505, 0x3505)
+IS_OMAP_TYPE(3505, 0x3517)
IS_OMAP_TYPE(3517, 0x3517)
#define cpu_is_omap310() 0
@@ -354,8 +334,9 @@ IS_OMAP_TYPE(3517, 0x3517)
(!omap3_has_sgx()) && \
(omap3_has_iva()))
# define cpu_is_omap3530() (cpu_is_omap3430())
-# define cpu_is_omap3505() is_omap3505()
# define cpu_is_omap3517() is_omap3517()
+# define cpu_is_omap3505() (cpu_is_omap3517() && \
+ !omap3_has_sgx())
# undef cpu_is_omap3630
# define cpu_is_omap3630() is_omap363x()
# define cpu_is_ti816x() is_ti816x()
@@ -379,35 +360,31 @@ IS_OMAP_TYPE(3517, 0x3517)
/* Various silicon revisions for omap2 */
#define OMAP242X_CLASS 0x24200024
#define OMAP2420_REV_ES1_0 OMAP242X_CLASS
-#define OMAP2420_REV_ES2_0 (OMAP242X_CLASS | (OMAP_REVBITS_01 << 8))
+#define OMAP2420_REV_ES2_0 (OMAP242X_CLASS | (0x1 << 8))
#define OMAP243X_CLASS 0x24300024
#define OMAP2430_REV_ES1_0 OMAP243X_CLASS
#define OMAP343X_CLASS 0x34300034
#define OMAP3430_REV_ES1_0 OMAP343X_CLASS
-#define OMAP3430_REV_ES2_0 (OMAP343X_CLASS | (OMAP_REVBITS_01 << 8))
-#define OMAP3430_REV_ES2_1 (OMAP343X_CLASS | (OMAP_REVBITS_02 << 8))
-#define OMAP3430_REV_ES3_0 (OMAP343X_CLASS | (OMAP_REVBITS_03 << 8))
-#define OMAP3430_REV_ES3_1 (OMAP343X_CLASS | (OMAP_REVBITS_04 << 8))
-#define OMAP3430_REV_ES3_1_2 (OMAP343X_CLASS | (OMAP_REVBITS_05 << 8))
+#define OMAP3430_REV_ES2_0 (OMAP343X_CLASS | (0x1 << 8))
+#define OMAP3430_REV_ES2_1 (OMAP343X_CLASS | (0x2 << 8))
+#define OMAP3430_REV_ES3_0 (OMAP343X_CLASS | (0x3 << 8))
+#define OMAP3430_REV_ES3_1 (OMAP343X_CLASS | (0x4 << 8))
+#define OMAP3430_REV_ES3_1_2 (OMAP343X_CLASS | (0x5 << 8))
#define OMAP363X_CLASS 0x36300034
#define OMAP3630_REV_ES1_0 OMAP363X_CLASS
-#define OMAP3630_REV_ES1_1 (OMAP363X_CLASS | (OMAP_REVBITS_01 << 8))
-#define OMAP3630_REV_ES1_2 (OMAP363X_CLASS | (OMAP_REVBITS_02 << 8))
+#define OMAP3630_REV_ES1_1 (OMAP363X_CLASS | (0x1 << 8))
+#define OMAP3630_REV_ES1_2 (OMAP363X_CLASS | (0x2 << 8))
-#define OMAP35XX_CLASS 0x35000034
-#define OMAP3503_REV(v) (OMAP35XX_CLASS | (0x3503 << 16) | (v << 8))
-#define OMAP3515_REV(v) (OMAP35XX_CLASS | (0x3515 << 16) | (v << 8))
-#define OMAP3525_REV(v) (OMAP35XX_CLASS | (0x3525 << 16) | (v << 8))
-#define OMAP3530_REV(v) (OMAP35XX_CLASS | (0x3530 << 16) | (v << 8))
-#define OMAP3505_REV(v) (OMAP35XX_CLASS | (0x3505 << 16) | (v << 8))
-#define OMAP3517_REV(v) (OMAP35XX_CLASS | (0x3517 << 16) | (v << 8))
+#define OMAP3517_CLASS 0x35170034
+#define OMAP3517_REV_ES1_0 OMAP3517_CLASS
+#define OMAP3517_REV_ES1_1 (OMAP3517_CLASS | (0x1 << 8))
#define TI816X_CLASS 0x81600034
#define TI8168_REV_ES1_0 TI816X_CLASS
-#define TI8168_REV_ES1_1 (TI816X_CLASS | (OMAP_REVBITS_01 << 8))
+#define TI8168_REV_ES1_1 (TI816X_CLASS | (0x1 << 8))
#define OMAP443X_CLASS 0x44300044
#define OMAP4430_REV_ES1_0 (OMAP443X_CLASS | (0x10 << 8))
@@ -418,61 +395,6 @@ IS_OMAP_TYPE(3517, 0x3517)
#define OMAP446X_CLASS 0x44600044
#define OMAP4460_REV_ES1_0 (OMAP446X_CLASS | (0x10 << 8))
-/*
- * omap_chip bits
- *
- * CHIP_IS_OMAP{2420,2430,3430} indicate that a particular structure is
- * valid on all chips of that type. CHIP_IS_OMAP3430ES{1,2} indicates
- * something that is only valid on that particular ES revision.
- *
- * These bits may be ORed together to indicate structures that are
- * available on multiple chip types.
- *
- * To test whether a particular structure matches the current OMAP chip type,
- * use omap_chip_is().
- *
- */
-#define CHIP_IS_OMAP2420 (1 << 0)
-#define CHIP_IS_OMAP2430 (1 << 1)
-#define CHIP_IS_OMAP3430 (1 << 2)
-#define CHIP_IS_OMAP3430ES1 (1 << 3)
-#define CHIP_IS_OMAP3430ES2 (1 << 4)
-#define CHIP_IS_OMAP3430ES3_0 (1 << 5)
-#define CHIP_IS_OMAP3430ES3_1 (1 << 6)
-#define CHIP_IS_OMAP3630ES1 (1 << 7)
-#define CHIP_IS_OMAP4430ES1 (1 << 8)
-#define CHIP_IS_OMAP3630ES1_1 (1 << 9)
-#define CHIP_IS_OMAP3630ES1_2 (1 << 10)
-#define CHIP_IS_OMAP4430ES2 (1 << 11)
-#define CHIP_IS_OMAP4430ES2_1 (1 << 12)
-#define CHIP_IS_OMAP4430ES2_2 (1 << 13)
-#define CHIP_IS_TI816X (1 << 14)
-#define CHIP_IS_OMAP4460ES1_0 (1 << 15)
-
-#define CHIP_IS_OMAP24XX (CHIP_IS_OMAP2420 | CHIP_IS_OMAP2430)
-
-#define CHIP_IS_OMAP4430 (CHIP_IS_OMAP4430ES1 | \
- CHIP_IS_OMAP4430ES2 | \
- CHIP_IS_OMAP4430ES2_1 | \
- CHIP_IS_OMAP4430ES2_2 | \
- CHIP_IS_OMAP4460ES1_0)
-
-/*
- * "GE" here represents "greater than or equal to" in terms of ES
- * levels. So CHIP_GE_OMAP3430ES2 is intended to match all OMAP3430
- * chips at ES2 and beyond, but not, for example, any OMAP lines after
- * OMAP3.
- */
-#define CHIP_GE_OMAP3430ES2 (CHIP_IS_OMAP3430ES2 | \
- CHIP_IS_OMAP3430ES3_0 | \
- CHIP_GE_OMAP3430ES3_1)
-#define CHIP_GE_OMAP3430ES3_1 (CHIP_IS_OMAP3430ES3_1 | \
- CHIP_IS_OMAP3630ES1 | \
- CHIP_GE_OMAP3630ES1_1)
-#define CHIP_GE_OMAP3630ES1_1 (CHIP_IS_OMAP3630ES1_1 | \
- CHIP_IS_OMAP3630ES1_2)
-
-int omap_chip_is(struct omap_chip_id oci);
void omap2_check_revision(void);
/*
diff --git a/arch/arm/plat-omap/include/plat/dmtimer.h b/arch/arm/plat-omap/include/plat/dmtimer.h
index eb5d16c60cd9..d11025e6e7a4 100644
--- a/arch/arm/plat-omap/include/plat/dmtimer.h
+++ b/arch/arm/plat-omap/include/plat/dmtimer.h
@@ -1,5 +1,5 @@
/*
- * arch/arm/plat-omap/include/mach/dmtimer.h
+ * arch/arm/plat-omap/include/plat/dmtimer.h
*
* OMAP Dual-Mode Timers
*
@@ -35,6 +35,7 @@
#include <linux/clk.h>
#include <linux/delay.h>
#include <linux/io.h>
+#include <linux/platform_device.h>
#ifndef __ASM_ARCH_DMTIMER_H
#define __ASM_ARCH_DMTIMER_H
@@ -59,12 +60,56 @@
* in OMAP4 can be distinguished.
*/
#define OMAP_TIMER_IP_VERSION_1 0x1
+
+/* timer capabilities used in hwmod database */
+#define OMAP_TIMER_SECURE 0x80000000
+#define OMAP_TIMER_ALWON 0x40000000
+#define OMAP_TIMER_HAS_PWM 0x20000000
+
+struct omap_timer_capability_dev_attr {
+ u32 timer_capability;
+};
+
struct omap_dm_timer;
struct clk;
+struct timer_regs {
+ u32 tidr;
+ u32 tiocp_cfg;
+ u32 tistat;
+ u32 tisr;
+ u32 tier;
+ u32 twer;
+ u32 tclr;
+ u32 tcrr;
+ u32 tldr;
+ u32 ttrg;
+ u32 twps;
+ u32 tmar;
+ u32 tcar1;
+ u32 tsicr;
+ u32 tcar2;
+ u32 tpir;
+ u32 tnir;
+ u32 tcvr;
+ u32 tocr;
+ u32 towr;
+};
+
+struct dmtimer_platform_data {
+ int (*set_timer_src)(struct platform_device *pdev, int source);
+ int timer_ip_version;
+ u32 needs_manual_reset:1;
+ bool reserved;
+
+ bool loses_context;
+
+ u32 (*get_context_loss_count)(struct device *dev);
+};
+
struct omap_dm_timer *omap_dm_timer_request(void);
struct omap_dm_timer *omap_dm_timer_request_specific(int timer_id);
-void omap_dm_timer_free(struct omap_dm_timer *timer);
+int omap_dm_timer_free(struct omap_dm_timer *timer);
void omap_dm_timer_enable(struct omap_dm_timer *timer);
void omap_dm_timer_disable(struct omap_dm_timer *timer);
@@ -73,23 +118,23 @@ int omap_dm_timer_get_irq(struct omap_dm_timer *timer);
u32 omap_dm_timer_modify_idlect_mask(u32 inputmask);
struct clk *omap_dm_timer_get_fclk(struct omap_dm_timer *timer);
-void omap_dm_timer_trigger(struct omap_dm_timer *timer);
-void omap_dm_timer_start(struct omap_dm_timer *timer);
-void omap_dm_timer_stop(struct omap_dm_timer *timer);
+int omap_dm_timer_trigger(struct omap_dm_timer *timer);
+int omap_dm_timer_start(struct omap_dm_timer *timer);
+int omap_dm_timer_stop(struct omap_dm_timer *timer);
int omap_dm_timer_set_source(struct omap_dm_timer *timer, int source);
-void omap_dm_timer_set_load(struct omap_dm_timer *timer, int autoreload, unsigned int value);
-void omap_dm_timer_set_load_start(struct omap_dm_timer *timer, int autoreload, unsigned int value);
-void omap_dm_timer_set_match(struct omap_dm_timer *timer, int enable, unsigned int match);
-void omap_dm_timer_set_pwm(struct omap_dm_timer *timer, int def_on, int toggle, int trigger);
-void omap_dm_timer_set_prescaler(struct omap_dm_timer *timer, int prescaler);
+int omap_dm_timer_set_load(struct omap_dm_timer *timer, int autoreload, unsigned int value);
+int omap_dm_timer_set_load_start(struct omap_dm_timer *timer, int autoreload, unsigned int value);
+int omap_dm_timer_set_match(struct omap_dm_timer *timer, int enable, unsigned int match);
+int omap_dm_timer_set_pwm(struct omap_dm_timer *timer, int def_on, int toggle, int trigger);
+int omap_dm_timer_set_prescaler(struct omap_dm_timer *timer, int prescaler);
-void omap_dm_timer_set_int_enable(struct omap_dm_timer *timer, unsigned int value);
+int omap_dm_timer_set_int_enable(struct omap_dm_timer *timer, unsigned int value);
unsigned int omap_dm_timer_read_status(struct omap_dm_timer *timer);
-void omap_dm_timer_write_status(struct omap_dm_timer *timer, unsigned int value);
+int omap_dm_timer_write_status(struct omap_dm_timer *timer, unsigned int value);
unsigned int omap_dm_timer_read_counter(struct omap_dm_timer *timer);
-void omap_dm_timer_write_counter(struct omap_dm_timer *timer, unsigned int value);
+int omap_dm_timer_write_counter(struct omap_dm_timer *timer, unsigned int value);
int omap_dm_timers_active(void);
@@ -98,12 +143,30 @@ int omap_dm_timers_active(void);
* used by dmtimer.c and sys_timer related code.
*/
-/* register offsets */
-#define _OMAP_TIMER_ID_OFFSET 0x00
-#define _OMAP_TIMER_OCP_CFG_OFFSET 0x10
-#define _OMAP_TIMER_SYS_STAT_OFFSET 0x14
-#define _OMAP_TIMER_STAT_OFFSET 0x18
-#define _OMAP_TIMER_INT_EN_OFFSET 0x1c
+/*
+ * The interrupt registers are different between v1 and v2 ip.
+ * These registers are offsets from timer->iobase.
+ */
+#define OMAP_TIMER_ID_OFFSET 0x00
+#define OMAP_TIMER_OCP_CFG_OFFSET 0x10
+
+#define OMAP_TIMER_V1_SYS_STAT_OFFSET 0x14
+#define OMAP_TIMER_V1_STAT_OFFSET 0x18
+#define OMAP_TIMER_V1_INT_EN_OFFSET 0x1c
+
+#define OMAP_TIMER_V2_IRQSTATUS_RAW 0x24
+#define OMAP_TIMER_V2_IRQSTATUS 0x28
+#define OMAP_TIMER_V2_IRQENABLE_SET 0x2c
+#define OMAP_TIMER_V2_IRQENABLE_CLR 0x30
+
+/*
+ * The functional registers have a different base on v1 and v2 ip.
+ * These registers are offsets from timer->func_base. The func_base
+ * is samae as io_base for v1 and io_base + 0x14 for v2 ip.
+ *
+ */
+#define OMAP_TIMER_V2_FUNC_OFFSET 0x14
+
#define _OMAP_TIMER_WAKEUP_EN_OFFSET 0x20
#define _OMAP_TIMER_CTRL_OFFSET 0x24
#define OMAP_TIMER_CTRL_GPOCFG (1 << 14)
@@ -147,21 +210,6 @@ int omap_dm_timers_active(void);
/* register offsets with the write pending bit encoded */
#define WPSHIFT 16
-#define OMAP_TIMER_ID_REG (_OMAP_TIMER_ID_OFFSET \
- | (WP_NONE << WPSHIFT))
-
-#define OMAP_TIMER_OCP_CFG_REG (_OMAP_TIMER_OCP_CFG_OFFSET \
- | (WP_NONE << WPSHIFT))
-
-#define OMAP_TIMER_SYS_STAT_REG (_OMAP_TIMER_SYS_STAT_OFFSET \
- | (WP_NONE << WPSHIFT))
-
-#define OMAP_TIMER_STAT_REG (_OMAP_TIMER_STAT_OFFSET \
- | (WP_NONE << WPSHIFT))
-
-#define OMAP_TIMER_INT_EN_REG (_OMAP_TIMER_INT_EN_OFFSET \
- | (WP_NONE << WPSHIFT))
-
#define OMAP_TIMER_WAKEUP_EN_REG (_OMAP_TIMER_WAKEUP_EN_OFFSET \
| (WP_NONE << WPSHIFT))
@@ -209,49 +257,88 @@ int omap_dm_timers_active(void);
struct omap_dm_timer {
unsigned long phys_base;
+ int id;
int irq;
-#ifdef CONFIG_ARCH_OMAP2PLUS
struct clk *iclk, *fclk;
-#endif
- void __iomem *io_base;
+
+ void __iomem *io_base;
+ void __iomem *sys_stat; /* TISTAT timer status */
+ void __iomem *irq_stat; /* TISR/IRQSTATUS interrupt status */
+ void __iomem *irq_ena; /* irq enable */
+ void __iomem *irq_dis; /* irq disable, only on v2 ip */
+ void __iomem *pend; /* write pending */
+ void __iomem *func_base; /* function register base */
+
unsigned long rate;
unsigned reserved:1;
- unsigned enabled:1;
unsigned posted:1;
+ struct timer_regs context;
+ bool loses_context;
+ int ctx_loss_count;
+ int revision;
+ struct platform_device *pdev;
+ struct list_head node;
+
+ u32 (*get_context_loss_count)(struct device *dev);
};
-extern u32 sys_timer_reserved;
-void omap_dm_timer_prepare(struct omap_dm_timer *timer);
+int omap_dm_timer_prepare(struct omap_dm_timer *timer);
-static inline u32 __omap_dm_timer_read(void __iomem *base, u32 reg,
+static inline u32 __omap_dm_timer_read(struct omap_dm_timer *timer, u32 reg,
int posted)
{
if (posted)
- while (__raw_readl(base + (OMAP_TIMER_WRITE_PEND_REG & 0xff))
- & (reg >> WPSHIFT))
+ while (__raw_readl(timer->pend) & (reg >> WPSHIFT))
cpu_relax();
- return __raw_readl(base + (reg & 0xff));
+ return __raw_readl(timer->func_base + (reg & 0xff));
}
-static inline void __omap_dm_timer_write(void __iomem *base, u32 reg, u32 val,
- int posted)
+static inline void __omap_dm_timer_write(struct omap_dm_timer *timer,
+ u32 reg, u32 val, int posted)
{
if (posted)
- while (__raw_readl(base + (OMAP_TIMER_WRITE_PEND_REG & 0xff))
- & (reg >> WPSHIFT))
+ while (__raw_readl(timer->pend) & (reg >> WPSHIFT))
cpu_relax();
- __raw_writel(val, base + (reg & 0xff));
+ __raw_writel(val, timer->func_base + (reg & 0xff));
+}
+
+static inline void __omap_dm_timer_init_regs(struct omap_dm_timer *timer)
+{
+ u32 tidr;
+
+ /* Assume v1 ip if bits [31:16] are zero */
+ tidr = __raw_readl(timer->io_base);
+ if (!(tidr >> 16)) {
+ timer->revision = 1;
+ timer->sys_stat = timer->io_base +
+ OMAP_TIMER_V1_SYS_STAT_OFFSET;
+ timer->irq_stat = timer->io_base + OMAP_TIMER_V1_STAT_OFFSET;
+ timer->irq_ena = timer->io_base + OMAP_TIMER_V1_INT_EN_OFFSET;
+ timer->irq_dis = 0;
+ timer->pend = timer->io_base + _OMAP_TIMER_WRITE_PEND_OFFSET;
+ timer->func_base = timer->io_base;
+ } else {
+ timer->revision = 2;
+ timer->sys_stat = 0;
+ timer->irq_stat = timer->io_base + OMAP_TIMER_V2_IRQSTATUS;
+ timer->irq_ena = timer->io_base + OMAP_TIMER_V2_IRQENABLE_SET;
+ timer->irq_dis = timer->io_base + OMAP_TIMER_V2_IRQENABLE_CLR;
+ timer->pend = timer->io_base +
+ _OMAP_TIMER_WRITE_PEND_OFFSET +
+ OMAP_TIMER_V2_FUNC_OFFSET;
+ timer->func_base = timer->io_base + OMAP_TIMER_V2_FUNC_OFFSET;
+ }
}
/* Assumes the source clock has been set by caller */
-static inline void __omap_dm_timer_reset(void __iomem *base, int autoidle,
- int wakeup)
+static inline void __omap_dm_timer_reset(struct omap_dm_timer *timer,
+ int autoidle, int wakeup)
{
u32 l;
- l = __omap_dm_timer_read(base, OMAP_TIMER_OCP_CFG_REG, 0);
+ l = __raw_readl(timer->io_base + OMAP_TIMER_OCP_CFG_OFFSET);
l |= 0x02 << 3; /* Set to smart-idle mode */
l |= 0x2 << 8; /* Set clock activity to perserve f-clock on idle */
@@ -261,10 +348,10 @@ static inline void __omap_dm_timer_reset(void __iomem *base, int autoidle,
if (wakeup)
l |= 1 << 2;
- __omap_dm_timer_write(base, OMAP_TIMER_OCP_CFG_REG, l, 0);
+ __raw_writel(l, timer->io_base + OMAP_TIMER_OCP_CFG_OFFSET);
/* Match hardware reset default of posted mode */
- __omap_dm_timer_write(base, OMAP_TIMER_IF_CTRL_REG,
+ __omap_dm_timer_write(timer, OMAP_TIMER_IF_CTRL_REG,
OMAP_TIMER_CTRL_POSTED, 0);
}
@@ -286,18 +373,18 @@ static inline int __omap_dm_timer_set_source(struct clk *timer_fck,
return ret;
}
-static inline void __omap_dm_timer_stop(void __iomem *base, int posted,
- unsigned long rate)
+static inline void __omap_dm_timer_stop(struct omap_dm_timer *timer,
+ int posted, unsigned long rate)
{
u32 l;
- l = __omap_dm_timer_read(base, OMAP_TIMER_CTRL_REG, posted);
+ l = __omap_dm_timer_read(timer, OMAP_TIMER_CTRL_REG, posted);
if (l & OMAP_TIMER_CTRL_ST) {
l &= ~0x1;
- __omap_dm_timer_write(base, OMAP_TIMER_CTRL_REG, l, posted);
+ __omap_dm_timer_write(timer, OMAP_TIMER_CTRL_REG, l, posted);
#ifdef CONFIG_ARCH_OMAP2PLUS
/* Readback to make sure write has completed */
- __omap_dm_timer_read(base, OMAP_TIMER_CTRL_REG, posted);
+ __omap_dm_timer_read(timer, OMAP_TIMER_CTRL_REG, posted);
/*
* Wait for functional clock period x 3.5 to make sure that
* timer is stopped
@@ -307,34 +394,34 @@ static inline void __omap_dm_timer_stop(void __iomem *base, int posted,
}
/* Ack possibly pending interrupt */
- __omap_dm_timer_write(base, OMAP_TIMER_STAT_REG,
- OMAP_TIMER_INT_OVERFLOW, 0);
+ __raw_writel(OMAP_TIMER_INT_OVERFLOW, timer->irq_stat);
}
-static inline void __omap_dm_timer_load_start(void __iomem *base, u32 ctrl,
- unsigned int load, int posted)
+static inline void __omap_dm_timer_load_start(struct omap_dm_timer *timer,
+ u32 ctrl, unsigned int load,
+ int posted)
{
- __omap_dm_timer_write(base, OMAP_TIMER_COUNTER_REG, load, posted);
- __omap_dm_timer_write(base, OMAP_TIMER_CTRL_REG, ctrl, posted);
+ __omap_dm_timer_write(timer, OMAP_TIMER_COUNTER_REG, load, posted);
+ __omap_dm_timer_write(timer, OMAP_TIMER_CTRL_REG, ctrl, posted);
}
-static inline void __omap_dm_timer_int_enable(void __iomem *base,
+static inline void __omap_dm_timer_int_enable(struct omap_dm_timer *timer,
unsigned int value)
{
- __omap_dm_timer_write(base, OMAP_TIMER_INT_EN_REG, value, 0);
- __omap_dm_timer_write(base, OMAP_TIMER_WAKEUP_EN_REG, value, 0);
+ __raw_writel(value, timer->irq_ena);
+ __omap_dm_timer_write(timer, OMAP_TIMER_WAKEUP_EN_REG, value, 0);
}
-static inline unsigned int __omap_dm_timer_read_counter(void __iomem *base,
- int posted)
+static inline unsigned int
+__omap_dm_timer_read_counter(struct omap_dm_timer *timer, int posted)
{
- return __omap_dm_timer_read(base, OMAP_TIMER_COUNTER_REG, posted);
+ return __omap_dm_timer_read(timer, OMAP_TIMER_COUNTER_REG, posted);
}
-static inline void __omap_dm_timer_write_status(void __iomem *base,
+static inline void __omap_dm_timer_write_status(struct omap_dm_timer *timer,
unsigned int value)
{
- __omap_dm_timer_write(base, OMAP_TIMER_STAT_REG, value, 0);
+ __raw_writel(value, timer->irq_stat);
}
#endif /* __ASM_ARCH_DMTIMER_H */
diff --git a/arch/arm/plat-omap/include/plat/io.h b/arch/arm/plat-omap/include/plat/io.h
index ebe67ea8d068..7471521c9737 100644
--- a/arch/arm/plat-omap/include/plat/io.h
+++ b/arch/arm/plat-omap/include/plat/io.h
@@ -228,13 +228,13 @@
#define OMAP44XX_EMIF2_PHYS OMAP44XX_EMIF2_BASE
/* 0x4d000000 --> 0xfd200000 */
-#define OMAP44XX_EMIF2_VIRT (OMAP44XX_EMIF2_PHYS + OMAP4_L3_PER_IO_OFFSET)
#define OMAP44XX_EMIF2_SIZE SZ_1M
+#define OMAP44XX_EMIF2_VIRT (OMAP44XX_EMIF1_VIRT + OMAP44XX_EMIF1_SIZE)
#define OMAP44XX_DMM_PHYS OMAP44XX_DMM_BASE
/* 0x4e000000 --> 0xfd300000 */
-#define OMAP44XX_DMM_VIRT (OMAP44XX_DMM_PHYS + OMAP4_L3_PER_IO_OFFSET)
#define OMAP44XX_DMM_SIZE SZ_1M
+#define OMAP44XX_DMM_VIRT (OMAP44XX_EMIF2_VIRT + OMAP44XX_EMIF2_SIZE)
/*
* ----------------------------------------------------------------------------
* Omap specific register access
@@ -300,7 +300,7 @@ static inline void omap44xx_map_common_io(void)
#endif
extern void omap2_init_common_infrastructure(void);
-extern void omap2_init_common_devices(struct omap_sdrc_params *sdrc_cs0,
+extern void omap_sdrc_init(struct omap_sdrc_params *sdrc_cs0,
struct omap_sdrc_params *sdrc_cs1);
#define __arch_ioremap omap_ioremap
diff --git a/arch/arm/plat-omap/include/plat/mcbsp.h b/arch/arm/plat-omap/include/plat/mcbsp.h
index 9882c657b2d4..8fa74e2c9d6e 100644
--- a/arch/arm/plat-omap/include/plat/mcbsp.h
+++ b/arch/arm/plat-omap/include/plat/mcbsp.h
@@ -25,9 +25,7 @@
#define __ASM_ARCH_OMAP_MCBSP_H
#include <linux/spinlock.h>
-
-#include <mach/hardware.h>
-#include <plat/clock.h>
+#include <linux/clk.h>
/* macro for building platform_device for McBSP ports */
#define OMAP_MCBSP_PLATFORM_DEVICE(port_nr) \
@@ -40,104 +38,60 @@ static struct platform_device omap_mcbsp##port_nr = { \
#define MCBSP_CONFIG_TYPE3 0x3
#define MCBSP_CONFIG_TYPE4 0x4
-#define OMAP7XX_MCBSP1_BASE 0xfffb1000
-#define OMAP7XX_MCBSP2_BASE 0xfffb1800
-
-#define OMAP1510_MCBSP1_BASE 0xe1011800
-#define OMAP1510_MCBSP2_BASE 0xfffb1000
-#define OMAP1510_MCBSP3_BASE 0xe1017000
-
-#define OMAP1610_MCBSP1_BASE 0xe1011800
-#define OMAP1610_MCBSP2_BASE 0xfffb1000
-#define OMAP1610_MCBSP3_BASE 0xe1017000
-
-#ifdef CONFIG_ARCH_OMAP1
-
-#define OMAP_MCBSP_REG_DRR2 0x00
-#define OMAP_MCBSP_REG_DRR1 0x02
-#define OMAP_MCBSP_REG_DXR2 0x04
-#define OMAP_MCBSP_REG_DXR1 0x06
-#define OMAP_MCBSP_REG_DRR 0x02
-#define OMAP_MCBSP_REG_DXR 0x06
-#define OMAP_MCBSP_REG_SPCR2 0x08
-#define OMAP_MCBSP_REG_SPCR1 0x0a
-#define OMAP_MCBSP_REG_RCR2 0x0c
-#define OMAP_MCBSP_REG_RCR1 0x0e
-#define OMAP_MCBSP_REG_XCR2 0x10
-#define OMAP_MCBSP_REG_XCR1 0x12
-#define OMAP_MCBSP_REG_SRGR2 0x14
-#define OMAP_MCBSP_REG_SRGR1 0x16
-#define OMAP_MCBSP_REG_MCR2 0x18
-#define OMAP_MCBSP_REG_MCR1 0x1a
-#define OMAP_MCBSP_REG_RCERA 0x1c
-#define OMAP_MCBSP_REG_RCERB 0x1e
-#define OMAP_MCBSP_REG_XCERA 0x20
-#define OMAP_MCBSP_REG_XCERB 0x22
-#define OMAP_MCBSP_REG_PCR0 0x24
-#define OMAP_MCBSP_REG_RCERC 0x26
-#define OMAP_MCBSP_REG_RCERD 0x28
-#define OMAP_MCBSP_REG_XCERC 0x2A
-#define OMAP_MCBSP_REG_XCERD 0x2C
-#define OMAP_MCBSP_REG_RCERE 0x2E
-#define OMAP_MCBSP_REG_RCERF 0x30
-#define OMAP_MCBSP_REG_XCERE 0x32
-#define OMAP_MCBSP_REG_XCERF 0x34
-#define OMAP_MCBSP_REG_RCERG 0x36
-#define OMAP_MCBSP_REG_RCERH 0x38
-#define OMAP_MCBSP_REG_XCERG 0x3A
-#define OMAP_MCBSP_REG_XCERH 0x3C
-
-/* Dummy defines, these are not available on omap1 */
-#define OMAP_MCBSP_REG_XCCR 0x00
-#define OMAP_MCBSP_REG_RCCR 0x00
-
-#else
-
-#define OMAP_MCBSP_REG_DRR2 0x00
-#define OMAP_MCBSP_REG_DRR1 0x04
-#define OMAP_MCBSP_REG_DXR2 0x08
-#define OMAP_MCBSP_REG_DXR1 0x0C
-#define OMAP_MCBSP_REG_DRR 0x00
-#define OMAP_MCBSP_REG_DXR 0x08
-#define OMAP_MCBSP_REG_SPCR2 0x10
-#define OMAP_MCBSP_REG_SPCR1 0x14
-#define OMAP_MCBSP_REG_RCR2 0x18
-#define OMAP_MCBSP_REG_RCR1 0x1C
-#define OMAP_MCBSP_REG_XCR2 0x20
-#define OMAP_MCBSP_REG_XCR1 0x24
-#define OMAP_MCBSP_REG_SRGR2 0x28
-#define OMAP_MCBSP_REG_SRGR1 0x2C
-#define OMAP_MCBSP_REG_MCR2 0x30
-#define OMAP_MCBSP_REG_MCR1 0x34
-#define OMAP_MCBSP_REG_RCERA 0x38
-#define OMAP_MCBSP_REG_RCERB 0x3C
-#define OMAP_MCBSP_REG_XCERA 0x40
-#define OMAP_MCBSP_REG_XCERB 0x44
-#define OMAP_MCBSP_REG_PCR0 0x48
-#define OMAP_MCBSP_REG_RCERC 0x4C
-#define OMAP_MCBSP_REG_RCERD 0x50
-#define OMAP_MCBSP_REG_XCERC 0x54
-#define OMAP_MCBSP_REG_XCERD 0x58
-#define OMAP_MCBSP_REG_RCERE 0x5C
-#define OMAP_MCBSP_REG_RCERF 0x60
-#define OMAP_MCBSP_REG_XCERE 0x64
-#define OMAP_MCBSP_REG_XCERF 0x68
-#define OMAP_MCBSP_REG_RCERG 0x6C
-#define OMAP_MCBSP_REG_RCERH 0x70
-#define OMAP_MCBSP_REG_XCERG 0x74
-#define OMAP_MCBSP_REG_XCERH 0x78
-#define OMAP_MCBSP_REG_SYSCON 0x8C
-#define OMAP_MCBSP_REG_THRSH2 0x90
-#define OMAP_MCBSP_REG_THRSH1 0x94
-#define OMAP_MCBSP_REG_IRQST 0xA0
-#define OMAP_MCBSP_REG_IRQEN 0xA4
-#define OMAP_MCBSP_REG_WAKEUPEN 0xA8
-#define OMAP_MCBSP_REG_XCCR 0xAC
-#define OMAP_MCBSP_REG_RCCR 0xB0
-#define OMAP_MCBSP_REG_XBUFFSTAT 0xB4
-#define OMAP_MCBSP_REG_RBUFFSTAT 0xB8
-#define OMAP_MCBSP_REG_SSELCR 0xBC
+/* McBSP register numbers. Register address offset = num * reg_step */
+enum {
+ /* Common registers */
+ OMAP_MCBSP_REG_SPCR2 = 4,
+ OMAP_MCBSP_REG_SPCR1,
+ OMAP_MCBSP_REG_RCR2,
+ OMAP_MCBSP_REG_RCR1,
+ OMAP_MCBSP_REG_XCR2,
+ OMAP_MCBSP_REG_XCR1,
+ OMAP_MCBSP_REG_SRGR2,
+ OMAP_MCBSP_REG_SRGR1,
+ OMAP_MCBSP_REG_MCR2,
+ OMAP_MCBSP_REG_MCR1,
+ OMAP_MCBSP_REG_RCERA,
+ OMAP_MCBSP_REG_RCERB,
+ OMAP_MCBSP_REG_XCERA,
+ OMAP_MCBSP_REG_XCERB,
+ OMAP_MCBSP_REG_PCR0,
+ OMAP_MCBSP_REG_RCERC,
+ OMAP_MCBSP_REG_RCERD,
+ OMAP_MCBSP_REG_XCERC,
+ OMAP_MCBSP_REG_XCERD,
+ OMAP_MCBSP_REG_RCERE,
+ OMAP_MCBSP_REG_RCERF,
+ OMAP_MCBSP_REG_XCERE,
+ OMAP_MCBSP_REG_XCERF,
+ OMAP_MCBSP_REG_RCERG,
+ OMAP_MCBSP_REG_RCERH,
+ OMAP_MCBSP_REG_XCERG,
+ OMAP_MCBSP_REG_XCERH,
+
+ /* OMAP1-OMAP2420 registers */
+ OMAP_MCBSP_REG_DRR2 = 0,
+ OMAP_MCBSP_REG_DRR1,
+ OMAP_MCBSP_REG_DXR2,
+ OMAP_MCBSP_REG_DXR1,
+
+ /* OMAP2430 and onwards */
+ OMAP_MCBSP_REG_DRR = 0,
+ OMAP_MCBSP_REG_DXR = 2,
+ OMAP_MCBSP_REG_SYSCON = 35,
+ OMAP_MCBSP_REG_THRSH2,
+ OMAP_MCBSP_REG_THRSH1,
+ OMAP_MCBSP_REG_IRQST = 40,
+ OMAP_MCBSP_REG_IRQEN,
+ OMAP_MCBSP_REG_WAKEUPEN,
+ OMAP_MCBSP_REG_XCCR,
+ OMAP_MCBSP_REG_RCCR,
+ OMAP_MCBSP_REG_XBUFFSTAT,
+ OMAP_MCBSP_REG_RBUFFSTAT,
+ OMAP_MCBSP_REG_SSELCR,
+};
+/* OMAP3 sidetone control registers */
#define OMAP_ST_REG_REV 0x00
#define OMAP_ST_REG_SYSCONFIG 0x10
#define OMAP_ST_REG_IRQSTATUS 0x18
@@ -146,8 +100,6 @@ static struct platform_device omap_mcbsp##port_nr = { \
#define OMAP_ST_REG_SFIRCR 0x28
#define OMAP_ST_REG_SSELCR 0x2C
-#endif
-
/************************** McBSP SPCR1 bit definitions ***********************/
#define RRST 0x0001
#define RRDY 0x0002
@@ -344,20 +296,20 @@ typedef enum {
struct omap_mcbsp_ops {
void (*request)(unsigned int);
void (*free)(unsigned int);
- int (*set_clks_src)(u8, u8);
};
struct omap_mcbsp_platform_data {
- unsigned long phys_base;
- u8 dma_rx_sync, dma_tx_sync;
- u16 rx_irq, tx_irq;
struct omap_mcbsp_ops *ops;
-#ifdef CONFIG_ARCH_OMAP3
- /* Sidetone block for McBSP 2 and 3 */
- unsigned long phys_base_st;
-#endif
u16 buffer_size;
- unsigned int mcbsp_config_type;
+ u8 reg_size;
+ u8 reg_step;
+
+ /* McBSP platform and instance specific features */
+ bool has_wakeup; /* Wakeup capability */
+ bool has_ccr; /* Transceiver has configuration control registers */
+ int (*enable_st_clock)(unsigned int, bool);
+ int (*set_clk_src)(struct device *dev, struct clk *clk, const char *src);
+ int (*mux_signal)(struct device *dev, const char *signal, const char *src);
};
struct omap_mcbsp_st_data {
@@ -389,14 +341,12 @@ struct omap_mcbsp {
spinlock_t lock;
struct omap_mcbsp_platform_data *pdata;
struct clk *fclk;
-#ifdef CONFIG_ARCH_OMAP3
struct omap_mcbsp_st_data *st_data;
int dma_op_mode;
u16 max_tx_thres;
u16 max_rx_thres;
-#endif
void *reg_cache;
- unsigned int mcbsp_config_type;
+ int reg_cache_size;
};
/**
@@ -408,16 +358,10 @@ struct omap_mcbsp_dev_attr {
};
extern struct omap_mcbsp **mcbsp_ptr;
-extern int omap_mcbsp_count, omap_mcbsp_cache_size;
-
-#define omap_mcbsp_check_valid_id(id) (id < omap_mcbsp_count)
-#define id_to_mcbsp_ptr(id) mcbsp_ptr[id];
+extern int omap_mcbsp_count;
int omap_mcbsp_init(void);
-void omap_mcbsp_register_board_cfg(struct resource *res, int res_count,
- struct omap_mcbsp_platform_data *config, int size);
void omap_mcbsp_config(unsigned int id, const struct omap_mcbsp_reg_cfg * config);
-#ifdef CONFIG_ARCH_OMAP3
void omap_mcbsp_set_tx_threshold(unsigned int id, u16 threshold);
void omap_mcbsp_set_rx_threshold(unsigned int id, u16 threshold);
u16 omap_mcbsp_get_max_tx_threshold(unsigned int id);
@@ -426,18 +370,6 @@ u16 omap_mcbsp_get_fifo_size(unsigned int id);
u16 omap_mcbsp_get_tx_delay(unsigned int id);
u16 omap_mcbsp_get_rx_delay(unsigned int id);
int omap_mcbsp_get_dma_op_mode(unsigned int id);
-#else
-static inline void omap_mcbsp_set_tx_threshold(unsigned int id, u16 threshold)
-{ }
-static inline void omap_mcbsp_set_rx_threshold(unsigned int id, u16 threshold)
-{ }
-static inline u16 omap_mcbsp_get_max_tx_threshold(unsigned int id) { return 0; }
-static inline u16 omap_mcbsp_get_max_rx_threshold(unsigned int id) { return 0; }
-static inline u16 omap_mcbsp_get_fifo_size(unsigned int id) { return 0; }
-static inline u16 omap_mcbsp_get_tx_delay(unsigned int id) { return 0; }
-static inline u16 omap_mcbsp_get_rx_delay(unsigned int id) { return 0; }
-static inline int omap_mcbsp_get_dma_op_mode(unsigned int id) { return 0; }
-#endif
int omap_mcbsp_request(unsigned int id);
void omap_mcbsp_free(unsigned int id);
void omap_mcbsp_start(unsigned int id, int tx, int rx);
@@ -453,21 +385,11 @@ void omap2_mcbsp1_mux_fsr_src(u8 mux);
int omap_mcbsp_dma_ch_params(unsigned int id, unsigned int stream);
int omap_mcbsp_dma_reg_params(unsigned int id, unsigned int stream);
-#ifdef CONFIG_ARCH_OMAP3
/* Sidetone specific API */
int omap_st_set_chgain(unsigned int id, int channel, s16 chgain);
int omap_st_get_chgain(unsigned int id, int channel, s16 *chgain);
int omap_st_enable(unsigned int id);
int omap_st_disable(unsigned int id);
int omap_st_is_enabled(unsigned int id);
-#else
-static inline int omap_st_set_chgain(unsigned int id, int channel,
- s16 chgain) { return 0; }
-static inline int omap_st_get_chgain(unsigned int id, int channel,
- s16 *chgain) { return 0; }
-static inline int omap_st_enable(unsigned int id) { return 0; }
-static inline int omap_st_disable(unsigned int id) { return 0; }
-static inline int omap_st_is_enabled(unsigned int id) { return 0; }
-#endif
#endif
diff --git a/arch/arm/plat-omap/include/plat/omap_device.h b/arch/arm/plat-omap/include/plat/omap_device.h
index ee405b36df4b..12c5b0c345bf 100644
--- a/arch/arm/plat-omap/include/plat/omap_device.h
+++ b/arch/arm/plat-omap/include/plat/omap_device.h
@@ -68,7 +68,7 @@ extern struct device omap_device_parent;
*
*/
struct omap_device {
- struct platform_device pdev;
+ struct platform_device *pdev;
struct omap_hwmod **hwmods;
struct omap_device_pm_latency *pm_lats;
u32 dev_wakeup_lat;
@@ -88,25 +88,20 @@ int omap_device_shutdown(struct platform_device *pdev);
/* Core code interface */
-int omap_device_count_resources(struct omap_device *od);
-int omap_device_fill_resources(struct omap_device *od, struct resource *res);
-
-struct omap_device *omap_device_build(const char *pdev_name, int pdev_id,
+struct platform_device *omap_device_build(const char *pdev_name, int pdev_id,
struct omap_hwmod *oh, void *pdata,
int pdata_len,
struct omap_device_pm_latency *pm_lats,
int pm_lats_cnt, int is_early_device);
-struct omap_device *omap_device_build_ss(const char *pdev_name, int pdev_id,
+struct platform_device *omap_device_build_ss(const char *pdev_name, int pdev_id,
struct omap_hwmod **oh, int oh_cnt,
void *pdata, int pdata_len,
struct omap_device_pm_latency *pm_lats,
int pm_lats_cnt, int is_early_device);
-int omap_device_register(struct omap_device *od);
-int omap_early_device_register(struct omap_device *od);
-
void __iomem *omap_device_get_rt_va(struct omap_device *od);
+struct device *omap_device_get_by_hwmod_name(const char *oh_name);
/* OMAP PM interface */
int omap_device_align_pm_lat(struct platform_device *pdev,
@@ -122,11 +117,6 @@ int omap_device_enable_hwmods(struct omap_device *od);
int omap_device_disable_clocks(struct omap_device *od);
int omap_device_enable_clocks(struct omap_device *od);
-static inline void omap_device_disable_idle_on_suspend(struct omap_device *od)
-{
- od->flags |= OMAP_DEVICE_NO_IDLE_ON_SUSPEND;
-}
-
/*
* Entries should be kept in latency order ascending
*
@@ -157,6 +147,17 @@ struct omap_device_pm_latency {
#define OMAP_DEVICE_LATENCY_AUTO_ADJUST BIT(1)
/* Get omap_device pointer from platform_device pointer */
-#define to_omap_device(x) container_of((x), struct omap_device, pdev)
+static inline struct omap_device *to_omap_device(struct platform_device *pdev)
+{
+ return pdev ? pdev->archdata.od : NULL;
+}
+
+static inline
+void omap_device_disable_idle_on_suspend(struct platform_device *pdev)
+{
+ struct omap_device *od = to_omap_device(pdev);
+
+ od->flags |= OMAP_DEVICE_NO_IDLE_ON_SUSPEND;
+}
#endif
diff --git a/arch/arm/plat-omap/include/plat/omap_hwmod.h b/arch/arm/plat-omap/include/plat/omap_hwmod.h
index 0e329ca88a70..5419f1a2aaa4 100644
--- a/arch/arm/plat-omap/include/plat/omap_hwmod.h
+++ b/arch/arm/plat-omap/include/plat/omap_hwmod.h
@@ -496,7 +496,6 @@ struct omap_hwmod_class {
* @_state: internal-use hwmod state
* @_postsetup_state: internal-use state to leave the hwmod in after _setup()
* @flags: hwmod flags (documented below)
- * @omap_chip: OMAP chips this hwmod is present on
* @_lock: spinlock serializing operations on this hwmod
* @node: list node for hwmod list (internal use)
*
@@ -526,7 +525,6 @@ struct omap_hwmod {
char *clkdm_name;
struct clockdomain *clkdm;
char *vdd_name;
- struct voltagedomain *voltdm;
struct omap_hwmod_ocp_if **masters; /* connect to *_IA */
struct omap_hwmod_ocp_if **slaves; /* connect to *_TA */
void *dev_attr;
@@ -545,7 +543,6 @@ struct omap_hwmod {
u8 _int_flags;
u8 _state;
u8 _postsetup_state;
- const struct omap_chip_id omap_chip;
};
int omap_hwmod_register(struct omap_hwmod **ohs);
diff --git a/arch/arm/plat-omap/include/plat/voltage.h b/arch/arm/plat-omap/include/plat/voltage.h
new file mode 100644
index 000000000000..0a6a482ec014
--- /dev/null
+++ b/arch/arm/plat-omap/include/plat/voltage.h
@@ -0,0 +1,20 @@
+/*
+ * OMAP Voltage Management Routines
+ *
+ * Copyright (C) 2011, Texas Instruments, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#ifndef __ARCH_ARM_OMAP_VOLTAGE_H
+#define __ARCH_ARM_OMAP_VOLTAGE_H
+
+struct voltagedomain;
+
+struct voltagedomain *voltdm_lookup(const char *name);
+int voltdm_scale(struct voltagedomain *voltdm, unsigned long target_volt);
+unsigned long voltdm_get_voltage(struct voltagedomain *voltdm);
+
+#endif
diff --git a/arch/arm/plat-omap/mcbsp.c b/arch/arm/plat-omap/mcbsp.c
index 6c62af108710..4b15cd7926d7 100644
--- a/arch/arm/plat-omap/mcbsp.c
+++ b/arch/arm/plat-omap/mcbsp.c
@@ -24,45 +24,40 @@
#include <linux/slab.h>
#include <plat/mcbsp.h>
-#include <plat/omap_device.h>
#include <linux/pm_runtime.h>
-/* XXX These "sideways" includes are a sign that something is wrong */
-#include "../mach-omap2/cm2xxx_3xxx.h"
-#include "../mach-omap2/cm-regbits-34xx.h"
-
struct omap_mcbsp **mcbsp_ptr;
-int omap_mcbsp_count, omap_mcbsp_cache_size;
+int omap_mcbsp_count;
+
+#define omap_mcbsp_check_valid_id(id) (id < omap_mcbsp_count)
+#define id_to_mcbsp_ptr(id) mcbsp_ptr[id];
static void omap_mcbsp_write(struct omap_mcbsp *mcbsp, u16 reg, u32 val)
{
- if (cpu_class_is_omap1()) {
- ((u16 *)mcbsp->reg_cache)[reg / sizeof(u16)] = (u16)val;
- __raw_writew((u16)val, mcbsp->io_base + reg);
- } else if (cpu_is_omap2420()) {
- ((u16 *)mcbsp->reg_cache)[reg / sizeof(u32)] = (u16)val;
- __raw_writew((u16)val, mcbsp->io_base + reg);
+ void __iomem *addr = mcbsp->io_base + reg * mcbsp->pdata->reg_step;
+
+ if (mcbsp->pdata->reg_size == 2) {
+ ((u16 *)mcbsp->reg_cache)[reg] = (u16)val;
+ __raw_writew((u16)val, addr);
} else {
- ((u32 *)mcbsp->reg_cache)[reg / sizeof(u32)] = val;
- __raw_writel(val, mcbsp->io_base + reg);
+ ((u32 *)mcbsp->reg_cache)[reg] = val;
+ __raw_writel(val, addr);
}
}
static int omap_mcbsp_read(struct omap_mcbsp *mcbsp, u16 reg, bool from_cache)
{
- if (cpu_class_is_omap1()) {
- return !from_cache ? __raw_readw(mcbsp->io_base + reg) :
- ((u16 *)mcbsp->reg_cache)[reg / sizeof(u16)];
- } else if (cpu_is_omap2420()) {
- return !from_cache ? __raw_readw(mcbsp->io_base + reg) :
- ((u16 *)mcbsp->reg_cache)[reg / sizeof(u32)];
+ void __iomem *addr = mcbsp->io_base + reg * mcbsp->pdata->reg_step;
+
+ if (mcbsp->pdata->reg_size == 2) {
+ return !from_cache ? __raw_readw(addr) :
+ ((u16 *)mcbsp->reg_cache)[reg];
} else {
- return !from_cache ? __raw_readl(mcbsp->io_base + reg) :
- ((u32 *)mcbsp->reg_cache)[reg / sizeof(u32)];
+ return !from_cache ? __raw_readl(addr) :
+ ((u32 *)mcbsp->reg_cache)[reg];
}
}
-#ifdef CONFIG_ARCH_OMAP3
static void omap_mcbsp_st_write(struct omap_mcbsp *mcbsp, u16 reg, u32 val)
{
__raw_writel(val, mcbsp->st_data->io_base_st + reg);
@@ -72,7 +67,6 @@ static int omap_mcbsp_st_read(struct omap_mcbsp *mcbsp, u16 reg)
{
return __raw_readl(mcbsp->st_data->io_base_st + reg);
}
-#endif
#define MCBSP_READ(mcbsp, reg) \
omap_mcbsp_read(mcbsp, OMAP_MCBSP_REG_##reg, 0)
@@ -187,7 +181,7 @@ void omap_mcbsp_config(unsigned int id, const struct omap_mcbsp_reg_cfg *config)
MCBSP_WRITE(mcbsp, MCR2, config->mcr2);
MCBSP_WRITE(mcbsp, MCR1, config->mcr1);
MCBSP_WRITE(mcbsp, PCR0, config->pcr0);
- if (cpu_is_omap2430() || cpu_is_omap34xx() || cpu_is_omap44xx()) {
+ if (mcbsp->pdata->has_ccr) {
MCBSP_WRITE(mcbsp, XCCR, config->xccr);
MCBSP_WRITE(mcbsp, RCCR, config->rccr);
}
@@ -239,46 +233,28 @@ int omap_mcbsp_dma_reg_params(unsigned int id, unsigned int stream)
}
mcbsp = id_to_mcbsp_ptr(id);
- data_reg = mcbsp->phys_dma_base;
-
- if (mcbsp->mcbsp_config_type < MCBSP_CONFIG_TYPE2) {
+ if (mcbsp->pdata->reg_size == 2) {
if (stream)
- data_reg += OMAP_MCBSP_REG_DRR1;
+ data_reg = OMAP_MCBSP_REG_DRR1;
else
- data_reg += OMAP_MCBSP_REG_DXR1;
+ data_reg = OMAP_MCBSP_REG_DXR1;
} else {
if (stream)
- data_reg += OMAP_MCBSP_REG_DRR;
+ data_reg = OMAP_MCBSP_REG_DRR;
else
- data_reg += OMAP_MCBSP_REG_DXR;
+ data_reg = OMAP_MCBSP_REG_DXR;
}
- return data_reg;
+ return mcbsp->phys_dma_base + data_reg * mcbsp->pdata->reg_step;
}
EXPORT_SYMBOL(omap_mcbsp_dma_reg_params);
-#ifdef CONFIG_ARCH_OMAP3
-static struct omap_device *find_omap_device_by_dev(struct device *dev)
-{
- struct platform_device *pdev = container_of(dev,
- struct platform_device, dev);
- return container_of(pdev, struct omap_device, pdev);
-}
-
static void omap_st_on(struct omap_mcbsp *mcbsp)
{
unsigned int w;
- struct omap_device *od;
- od = find_omap_device_by_dev(mcbsp->dev);
-
- /*
- * Sidetone uses McBSP ICLK - which must not idle when sidetones
- * are enabled or sidetones start sounding ugly.
- */
- w = omap2_cm_read_mod_reg(OMAP3430_PER_MOD, CM_AUTOIDLE);
- w &= ~(1 << (mcbsp->id - 2));
- omap2_cm_write_mod_reg(w, OMAP3430_PER_MOD, CM_AUTOIDLE);
+ if (mcbsp->pdata->enable_st_clock)
+ mcbsp->pdata->enable_st_clock(mcbsp->id, 1);
/* Enable McBSP Sidetone */
w = MCBSP_READ(mcbsp, SSELCR);
@@ -292,9 +268,6 @@ static void omap_st_on(struct omap_mcbsp *mcbsp)
static void omap_st_off(struct omap_mcbsp *mcbsp)
{
unsigned int w;
- struct omap_device *od;
-
- od = find_omap_device_by_dev(mcbsp->dev);
w = MCBSP_ST_READ(mcbsp, SSELCR);
MCBSP_ST_WRITE(mcbsp, SSELCR, w & ~(ST_SIDETONEEN));
@@ -302,17 +275,13 @@ static void omap_st_off(struct omap_mcbsp *mcbsp)
w = MCBSP_READ(mcbsp, SSELCR);
MCBSP_WRITE(mcbsp, SSELCR, w & ~(SIDETONEEN));
- w = omap2_cm_read_mod_reg(OMAP3430_PER_MOD, CM_AUTOIDLE);
- w |= 1 << (mcbsp->id - 2);
- omap2_cm_write_mod_reg(w, OMAP3430_PER_MOD, CM_AUTOIDLE);
+ if (mcbsp->pdata->enable_st_clock)
+ mcbsp->pdata->enable_st_clock(mcbsp->id, 0);
}
static void omap_st_fir_write(struct omap_mcbsp *mcbsp, s16 *fir)
{
u16 val, i;
- struct omap_device *od;
-
- od = find_omap_device_by_dev(mcbsp->dev);
val = MCBSP_ST_READ(mcbsp, SSELCR);
@@ -340,9 +309,6 @@ static void omap_st_chgain(struct omap_mcbsp *mcbsp)
{
u16 w;
struct omap_mcbsp_st_data *st_data = mcbsp->st_data;
- struct omap_device *od;
-
- od = find_omap_device_by_dev(mcbsp->dev);
w = MCBSP_ST_READ(mcbsp, SSELCR);
@@ -525,14 +491,13 @@ void omap_mcbsp_set_tx_threshold(unsigned int id, u16 threshold)
{
struct omap_mcbsp *mcbsp;
- if (!cpu_is_omap34xx() && !cpu_is_omap44xx())
- return;
-
if (!omap_mcbsp_check_valid_id(id)) {
printk(KERN_ERR "%s: Invalid id (%d)\n", __func__, id + 1);
return;
}
mcbsp = id_to_mcbsp_ptr(id);
+ if (mcbsp->pdata->buffer_size == 0)
+ return;
if (threshold && threshold <= mcbsp->max_tx_thres)
MCBSP_WRITE(mcbsp, THRSH2, threshold - 1);
@@ -548,14 +513,13 @@ void omap_mcbsp_set_rx_threshold(unsigned int id, u16 threshold)
{
struct omap_mcbsp *mcbsp;
- if (!cpu_is_omap34xx() && !cpu_is_omap44xx())
- return;
-
if (!omap_mcbsp_check_valid_id(id)) {
printk(KERN_ERR "%s: Invalid id (%d)\n", __func__, id + 1);
return;
}
mcbsp = id_to_mcbsp_ptr(id);
+ if (mcbsp->pdata->buffer_size == 0)
+ return;
if (threshold && threshold <= mcbsp->max_rx_thres)
MCBSP_WRITE(mcbsp, THRSH1, threshold - 1);
@@ -625,6 +589,8 @@ u16 omap_mcbsp_get_tx_delay(unsigned int id)
return -ENODEV;
}
mcbsp = id_to_mcbsp_ptr(id);
+ if (mcbsp->pdata->buffer_size == 0)
+ return 0;
/* Returns the number of free locations in the buffer */
buffstat = MCBSP_READ(mcbsp, XBUFFSTAT);
@@ -648,6 +614,8 @@ u16 omap_mcbsp_get_rx_delay(unsigned int id)
return -ENODEV;
}
mcbsp = id_to_mcbsp_ptr(id);
+ if (mcbsp->pdata->buffer_size == 0)
+ return 0;
/* Returns the number of used locations in the buffer */
buffstat = MCBSP_READ(mcbsp, RBUFFSTAT);
@@ -683,46 +651,6 @@ int omap_mcbsp_get_dma_op_mode(unsigned int id)
}
EXPORT_SYMBOL(omap_mcbsp_get_dma_op_mode);
-static inline void omap34xx_mcbsp_request(struct omap_mcbsp *mcbsp)
-{
- struct omap_device *od;
-
- od = find_omap_device_by_dev(mcbsp->dev);
- /*
- * Enable wakup behavior, smart idle and all wakeups
- * REVISIT: some wakeups may be unnecessary
- */
- if (cpu_is_omap34xx() || cpu_is_omap44xx()) {
- MCBSP_WRITE(mcbsp, WAKEUPEN, XRDYEN | RRDYEN);
- }
-}
-
-static inline void omap34xx_mcbsp_free(struct omap_mcbsp *mcbsp)
-{
- struct omap_device *od;
-
- od = find_omap_device_by_dev(mcbsp->dev);
-
- /*
- * Disable wakup behavior, smart idle and all wakeups
- */
- if (cpu_is_omap34xx() || cpu_is_omap44xx()) {
- /*
- * HW bug workaround - If no_idle mode is taken, we need to
- * go to smart_idle before going to always_idle, or the
- * device will not hit retention anymore.
- */
-
- MCBSP_WRITE(mcbsp, WAKEUPEN, 0);
- }
-}
-#else
-static inline void omap34xx_mcbsp_request(struct omap_mcbsp *mcbsp) {}
-static inline void omap34xx_mcbsp_free(struct omap_mcbsp *mcbsp) {}
-static inline void omap_st_start(struct omap_mcbsp *mcbsp) {}
-static inline void omap_st_stop(struct omap_mcbsp *mcbsp) {}
-#endif
-
int omap_mcbsp_request(unsigned int id)
{
struct omap_mcbsp *mcbsp;
@@ -735,7 +663,7 @@ int omap_mcbsp_request(unsigned int id)
}
mcbsp = id_to_mcbsp_ptr(id);
- reg_cache = kzalloc(omap_mcbsp_cache_size, GFP_KERNEL);
+ reg_cache = kzalloc(mcbsp->reg_cache_size, GFP_KERNEL);
if (!reg_cache) {
return -ENOMEM;
}
@@ -757,8 +685,9 @@ int omap_mcbsp_request(unsigned int id)
pm_runtime_get_sync(mcbsp->dev);
- /* Do procedure specific to omap34xx arch, if applicable */
- omap34xx_mcbsp_request(mcbsp);
+ /* Enable wakeup behavior */
+ if (mcbsp->pdata->has_wakeup)
+ MCBSP_WRITE(mcbsp, WAKEUPEN, XRDYEN | RRDYEN);
/*
* Make sure that transmitter, receiver and sample-rate generator are
@@ -795,8 +724,9 @@ err_clk_disable:
if (mcbsp->pdata && mcbsp->pdata->ops && mcbsp->pdata->ops->free)
mcbsp->pdata->ops->free(id);
- /* Do procedure specific to omap34xx arch, if applicable */
- omap34xx_mcbsp_free(mcbsp);
+ /* Disable wakeup behavior */
+ if (mcbsp->pdata->has_wakeup)
+ MCBSP_WRITE(mcbsp, WAKEUPEN, 0);
pm_runtime_put_sync(mcbsp->dev);
@@ -825,8 +755,9 @@ void omap_mcbsp_free(unsigned int id)
if (mcbsp->pdata && mcbsp->pdata->ops && mcbsp->pdata->ops->free)
mcbsp->pdata->ops->free(id);
- /* Do procedure specific to omap34xx arch, if applicable */
- omap34xx_mcbsp_free(mcbsp);
+ /* Disable wakeup behavior */
+ if (mcbsp->pdata->has_wakeup)
+ MCBSP_WRITE(mcbsp, WAKEUPEN, 0);
pm_runtime_put_sync(mcbsp->dev);
@@ -866,7 +797,7 @@ void omap_mcbsp_start(unsigned int id, int tx, int rx)
}
mcbsp = id_to_mcbsp_ptr(id);
- if (cpu_is_omap34xx())
+ if (mcbsp->st_data)
omap_st_start(mcbsp);
/* Only enable SRG, if McBSP is master */
@@ -904,7 +835,7 @@ void omap_mcbsp_start(unsigned int id, int tx, int rx)
MCBSP_WRITE(mcbsp, SPCR2, w | (1 << 7));
}
- if (cpu_is_omap2430() || cpu_is_omap34xx() || cpu_is_omap44xx()) {
+ if (mcbsp->pdata->has_ccr) {
/* Release the transmitter and receiver */
w = MCBSP_READ_CACHE(mcbsp, XCCR);
w &= ~(tx ? XDISABLE : 0);
@@ -934,7 +865,7 @@ void omap_mcbsp_stop(unsigned int id, int tx, int rx)
/* Reset transmitter */
tx &= 1;
- if (cpu_is_omap2430() || cpu_is_omap34xx() || cpu_is_omap44xx()) {
+ if (mcbsp->pdata->has_ccr) {
w = MCBSP_READ_CACHE(mcbsp, XCCR);
w |= (tx ? XDISABLE : 0);
MCBSP_WRITE(mcbsp, XCCR, w);
@@ -944,7 +875,7 @@ void omap_mcbsp_stop(unsigned int id, int tx, int rx)
/* Reset receiver */
rx &= 1;
- if (cpu_is_omap2430() || cpu_is_omap34xx() || cpu_is_omap44xx()) {
+ if (mcbsp->pdata->has_ccr) {
w = MCBSP_READ_CACHE(mcbsp, RCCR);
w |= (rx ? RDISABLE : 0);
MCBSP_WRITE(mcbsp, RCCR, w);
@@ -961,39 +892,72 @@ void omap_mcbsp_stop(unsigned int id, int tx, int rx)
MCBSP_WRITE(mcbsp, SPCR2, w & ~(1 << 6));
}
- if (cpu_is_omap34xx())
+ if (mcbsp->st_data)
omap_st_stop(mcbsp);
}
EXPORT_SYMBOL(omap_mcbsp_stop);
-/*
- * The following functions are only required on an OMAP1-only build.
- * mach-omap2/mcbsp.c contains the real functions
- */
-#ifndef CONFIG_ARCH_OMAP2PLUS
int omap2_mcbsp_set_clks_src(u8 id, u8 fck_src_id)
{
- WARN(1, "%s: should never be called on an OMAP1-only kernel\n",
- __func__);
- return -EINVAL;
+ struct omap_mcbsp *mcbsp;
+ const char *src;
+
+ if (!omap_mcbsp_check_valid_id(id)) {
+ pr_err("%s: Invalid id (%d)\n", __func__, id + 1);
+ return -EINVAL;
+ }
+ mcbsp = id_to_mcbsp_ptr(id);
+
+ if (fck_src_id == MCBSP_CLKS_PAD_SRC)
+ src = "clks_ext";
+ else if (fck_src_id == MCBSP_CLKS_PRCM_SRC)
+ src = "clks_fclk";
+ else
+ return -EINVAL;
+
+ if (mcbsp->pdata->set_clk_src)
+ return mcbsp->pdata->set_clk_src(mcbsp->dev, mcbsp->fclk, src);
+ else
+ return -EINVAL;
}
+EXPORT_SYMBOL(omap2_mcbsp_set_clks_src);
void omap2_mcbsp1_mux_clkr_src(u8 mux)
{
- WARN(1, "%s: should never be called on an OMAP1-only kernel\n",
- __func__);
- return;
+ struct omap_mcbsp *mcbsp;
+ const char *src;
+
+ if (mux == CLKR_SRC_CLKR)
+ src = "clkr";
+ else if (mux == CLKR_SRC_CLKX)
+ src = "clkx";
+ else
+ return;
+
+ mcbsp = id_to_mcbsp_ptr(0);
+ if (mcbsp->pdata->mux_signal)
+ mcbsp->pdata->mux_signal(mcbsp->dev, "clkr", src);
}
+EXPORT_SYMBOL(omap2_mcbsp1_mux_clkr_src);
void omap2_mcbsp1_mux_fsr_src(u8 mux)
{
- WARN(1, "%s: should never be called on an OMAP1-only kernel\n",
- __func__);
- return;
+ struct omap_mcbsp *mcbsp;
+ const char *src;
+
+ if (mux == FSR_SRC_FSR)
+ src = "fsr";
+ else if (mux == FSR_SRC_FSX)
+ src = "fsx";
+ else
+ return;
+
+ mcbsp = id_to_mcbsp_ptr(0);
+ if (mcbsp->pdata->mux_signal)
+ mcbsp->pdata->mux_signal(mcbsp->dev, "fsr", src);
}
-#endif
+EXPORT_SYMBOL(omap2_mcbsp1_mux_fsr_src);
-#ifdef CONFIG_ARCH_OMAP3
#define max_thres(m) (mcbsp->pdata->buffer_size)
#define valid_threshold(m, val) ((val) <= max_thres(m))
#define THRESHOLD_PROP_BUILDER(prop) \
@@ -1084,6 +1048,17 @@ unlock:
static DEVICE_ATTR(dma_op_mode, 0644, dma_op_mode_show, dma_op_mode_store);
+static const struct attribute *additional_attrs[] = {
+ &dev_attr_max_tx_thres.attr,
+ &dev_attr_max_rx_thres.attr,
+ &dev_attr_dma_op_mode.attr,
+ NULL,
+};
+
+static const struct attribute_group additional_attr_group = {
+ .attrs = (struct attribute **)additional_attrs,
+};
+
static ssize_t st_taps_show(struct device *dev,
struct device_attribute *attr, char *buf)
{
@@ -1142,27 +1117,6 @@ out:
static DEVICE_ATTR(st_taps, 0644, st_taps_show, st_taps_store);
-static const struct attribute *additional_attrs[] = {
- &dev_attr_max_tx_thres.attr,
- &dev_attr_max_rx_thres.attr,
- &dev_attr_dma_op_mode.attr,
- NULL,
-};
-
-static const struct attribute_group additional_attr_group = {
- .attrs = (struct attribute **)additional_attrs,
-};
-
-static inline int __devinit omap_additional_add(struct device *dev)
-{
- return sysfs_create_group(&dev->kobj, &additional_attr_group);
-}
-
-static inline void __devexit omap_additional_remove(struct device *dev)
-{
- sysfs_remove_group(&dev->kobj, &additional_attr_group);
-}
-
static const struct attribute *sidetone_attrs[] = {
&dev_attr_st_taps.attr,
NULL,
@@ -1172,10 +1126,9 @@ static const struct attribute_group sidetone_attr_group = {
.attrs = (struct attribute **)sidetone_attrs,
};
-static int __devinit omap_st_add(struct omap_mcbsp *mcbsp)
+static int __devinit omap_st_add(struct omap_mcbsp *mcbsp,
+ struct resource *res)
{
- struct platform_device *pdev;
- struct resource *res;
struct omap_mcbsp_st_data *st_data;
int err;
@@ -1185,9 +1138,6 @@ static int __devinit omap_st_add(struct omap_mcbsp *mcbsp)
goto err1;
}
- pdev = container_of(mcbsp->dev, struct platform_device, dev);
-
- res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "sidetone");
st_data->io_base_st = ioremap(res->start, resource_size(res));
if (!st_data->io_base_st) {
err = -ENOMEM;
@@ -1214,59 +1164,10 @@ static void __devexit omap_st_remove(struct omap_mcbsp *mcbsp)
{
struct omap_mcbsp_st_data *st_data = mcbsp->st_data;
- if (st_data) {
- sysfs_remove_group(&mcbsp->dev->kobj, &sidetone_attr_group);
- iounmap(st_data->io_base_st);
- kfree(st_data);
- }
-}
-
-static inline void __devinit omap34xx_device_init(struct omap_mcbsp *mcbsp)
-{
- mcbsp->dma_op_mode = MCBSP_DMA_MODE_ELEMENT;
- if (cpu_is_omap34xx()) {
- /*
- * Initially configure the maximum thresholds to a safe value.
- * The McBSP FIFO usage with these values should not go under
- * 16 locations.
- * If the whole FIFO without safety buffer is used, than there
- * is a possibility that the DMA will be not able to push the
- * new data on time, causing channel shifts in runtime.
- */
- mcbsp->max_tx_thres = max_thres(mcbsp) - 0x10;
- mcbsp->max_rx_thres = max_thres(mcbsp) - 0x10;
- /*
- * REVISIT: Set dmap_op_mode to THRESHOLD as default
- * for mcbsp2 instances.
- */
- if (omap_additional_add(mcbsp->dev))
- dev_warn(mcbsp->dev,
- "Unable to create additional controls\n");
-
- if (mcbsp->id == 2 || mcbsp->id == 3)
- if (omap_st_add(mcbsp))
- dev_warn(mcbsp->dev,
- "Unable to create sidetone controls\n");
-
- } else {
- mcbsp->max_tx_thres = -EINVAL;
- mcbsp->max_rx_thres = -EINVAL;
- }
-}
-
-static inline void __devexit omap34xx_device_exit(struct omap_mcbsp *mcbsp)
-{
- if (cpu_is_omap34xx()) {
- omap_additional_remove(mcbsp->dev);
-
- if (mcbsp->id == 2 || mcbsp->id == 3)
- omap_st_remove(mcbsp);
- }
+ sysfs_remove_group(&mcbsp->dev->kobj, &sidetone_attr_group);
+ iounmap(st_data->io_base_st);
+ kfree(st_data);
}
-#else
-static inline void __devinit omap34xx_device_init(struct omap_mcbsp *mcbsp) {}
-static inline void __devexit omap34xx_device_exit(struct omap_mcbsp *mcbsp) {}
-#endif /* CONFIG_ARCH_OMAP3 */
/*
* McBSP1 and McBSP3 are directly mapped on 1610 and 1510.
@@ -1316,7 +1217,7 @@ static int __devinit omap_mcbsp_probe(struct platform_device *pdev)
}
}
mcbsp->phys_base = res->start;
- omap_mcbsp_cache_size = resource_size(res);
+ mcbsp->reg_cache_size = resource_size(res);
mcbsp->io_base = ioremap(res->start, resource_size(res));
if (!mcbsp->io_base) {
ret = -ENOMEM;
@@ -1364,15 +1265,52 @@ static int __devinit omap_mcbsp_probe(struct platform_device *pdev)
mcbsp->pdata = pdata;
mcbsp->dev = &pdev->dev;
mcbsp_ptr[id] = mcbsp;
- mcbsp->mcbsp_config_type = pdata->mcbsp_config_type;
platform_set_drvdata(pdev, mcbsp);
pm_runtime_enable(mcbsp->dev);
- /* Initialize mcbsp properties for OMAP34XX if needed / applicable */
- omap34xx_device_init(mcbsp);
+ mcbsp->dma_op_mode = MCBSP_DMA_MODE_ELEMENT;
+ if (mcbsp->pdata->buffer_size) {
+ /*
+ * Initially configure the maximum thresholds to a safe value.
+ * The McBSP FIFO usage with these values should not go under
+ * 16 locations.
+ * If the whole FIFO without safety buffer is used, than there
+ * is a possibility that the DMA will be not able to push the
+ * new data on time, causing channel shifts in runtime.
+ */
+ mcbsp->max_tx_thres = max_thres(mcbsp) - 0x10;
+ mcbsp->max_rx_thres = max_thres(mcbsp) - 0x10;
+
+ ret = sysfs_create_group(&mcbsp->dev->kobj,
+ &additional_attr_group);
+ if (ret) {
+ dev_err(mcbsp->dev,
+ "Unable to create additional controls\n");
+ goto err_thres;
+ }
+ } else {
+ mcbsp->max_tx_thres = -EINVAL;
+ mcbsp->max_rx_thres = -EINVAL;
+ }
+
+ res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "sidetone");
+ if (res) {
+ ret = omap_st_add(mcbsp, res);
+ if (ret) {
+ dev_err(mcbsp->dev,
+ "Unable to create sidetone controls\n");
+ goto err_st;
+ }
+ }
return 0;
+err_st:
+ if (mcbsp->pdata->buffer_size)
+ sysfs_remove_group(&mcbsp->dev->kobj,
+ &additional_attr_group);
+err_thres:
+ clk_put(mcbsp->fclk);
err_res:
iounmap(mcbsp->io_base);
err_ioremap:
@@ -1392,7 +1330,12 @@ static int __devexit omap_mcbsp_remove(struct platform_device *pdev)
mcbsp->pdata->ops->free)
mcbsp->pdata->ops->free(mcbsp->id);
- omap34xx_device_exit(mcbsp);
+ if (mcbsp->pdata->buffer_size)
+ sysfs_remove_group(&mcbsp->dev->kobj,
+ &additional_attr_group);
+
+ if (mcbsp->st_data)
+ omap_st_remove(mcbsp);
clk_put(mcbsp->fclk);
diff --git a/arch/arm/plat-omap/omap_device.c b/arch/arm/plat-omap/omap_device.c
index 02609eee0562..cd90bedd9306 100644
--- a/arch/arm/plat-omap/omap_device.c
+++ b/arch/arm/plat-omap/omap_device.c
@@ -85,6 +85,8 @@
#include <linux/clk.h>
#include <linux/clkdev.h>
#include <linux/pm_runtime.h>
+#include <linux/of.h>
+#include <linux/notifier.h>
#include <plat/omap_device.h>
#include <plat/omap_hwmod.h>
@@ -94,6 +96,23 @@
#define USE_WAKEUP_LAT 0
#define IGNORE_WAKEUP_LAT 1
+static int omap_device_register(struct platform_device *pdev);
+static int omap_early_device_register(struct platform_device *pdev);
+static struct omap_device *omap_device_alloc(struct platform_device *pdev,
+ struct omap_hwmod **ohs, int oh_cnt,
+ struct omap_device_pm_latency *pm_lats,
+ int pm_lats_cnt);
+static void omap_device_delete(struct omap_device *od);
+
+
+static struct omap_device_pm_latency omap_default_latency[] = {
+ {
+ .deactivate_func = omap_device_idle_hwmods,
+ .activate_func = omap_device_enable_hwmods,
+ .flags = OMAP_DEVICE_LATENCY_AUTO_ADJUST,
+ }
+};
+
/* Private functions */
/**
@@ -114,7 +133,7 @@ static int _omap_device_activate(struct omap_device *od, u8 ignore_lat)
{
struct timespec a, b, c;
- pr_debug("omap_device: %s: activating\n", od->pdev.name);
+ dev_dbg(&od->pdev->dev, "omap_device: activating\n");
while (od->pm_lat_level > 0) {
struct omap_device_pm_latency *odpl;
@@ -138,25 +157,24 @@ static int _omap_device_activate(struct omap_device *od, u8 ignore_lat)
c = timespec_sub(b, a);
act_lat = timespec_to_ns(&c);
- pr_debug("omap_device: %s: pm_lat %d: activate: elapsed time "
- "%llu nsec\n", od->pdev.name, od->pm_lat_level,
- act_lat);
+ dev_dbg(&od->pdev->dev,
+ "omap_device: pm_lat %d: activate: elapsed time "
+ "%llu nsec\n", od->pm_lat_level, act_lat);
if (act_lat > odpl->activate_lat) {
odpl->activate_lat_worst = act_lat;
if (odpl->flags & OMAP_DEVICE_LATENCY_AUTO_ADJUST) {
odpl->activate_lat = act_lat;
- pr_warning("omap_device: %s.%d: new worst case "
- "activate latency %d: %llu\n",
- od->pdev.name, od->pdev.id,
- od->pm_lat_level, act_lat);
+ dev_dbg(&od->pdev->dev,
+ "new worst case activate latency "
+ "%d: %llu\n",
+ od->pm_lat_level, act_lat);
} else
- pr_warning("omap_device: %s.%d: activate "
- "latency %d higher than exptected. "
- "(%llu > %d)\n",
- od->pdev.name, od->pdev.id,
- od->pm_lat_level, act_lat,
- odpl->activate_lat);
+ dev_warn(&od->pdev->dev,
+ "activate latency %d "
+ "higher than exptected. (%llu > %d)\n",
+ od->pm_lat_level, act_lat,
+ odpl->activate_lat);
}
od->dev_wakeup_lat -= odpl->activate_lat;
@@ -183,7 +201,7 @@ static int _omap_device_deactivate(struct omap_device *od, u8 ignore_lat)
{
struct timespec a, b, c;
- pr_debug("omap_device: %s: deactivating\n", od->pdev.name);
+ dev_dbg(&od->pdev->dev, "omap_device: deactivating\n");
while (od->pm_lat_level < od->pm_lats_cnt) {
struct omap_device_pm_latency *odpl;
@@ -206,28 +224,26 @@ static int _omap_device_deactivate(struct omap_device *od, u8 ignore_lat)
c = timespec_sub(b, a);
deact_lat = timespec_to_ns(&c);
- pr_debug("omap_device: %s: pm_lat %d: deactivate: elapsed time "
- "%llu nsec\n", od->pdev.name, od->pm_lat_level,
- deact_lat);
+ dev_dbg(&od->pdev->dev,
+ "omap_device: pm_lat %d: deactivate: elapsed time "
+ "%llu nsec\n", od->pm_lat_level, deact_lat);
if (deact_lat > odpl->deactivate_lat) {
odpl->deactivate_lat_worst = deact_lat;
if (odpl->flags & OMAP_DEVICE_LATENCY_AUTO_ADJUST) {
odpl->deactivate_lat = deact_lat;
- pr_warning("omap_device: %s.%d: new worst case "
- "deactivate latency %d: %llu\n",
- od->pdev.name, od->pdev.id,
- od->pm_lat_level, deact_lat);
+ dev_dbg(&od->pdev->dev,
+ "new worst case deactivate latency "
+ "%d: %llu\n",
+ od->pm_lat_level, deact_lat);
} else
- pr_warning("omap_device: %s.%d: deactivate "
- "latency %d higher than exptected. "
- "(%llu > %d)\n",
- od->pdev.name, od->pdev.id,
- od->pm_lat_level, deact_lat,
- odpl->deactivate_lat);
+ dev_warn(&od->pdev->dev,
+ "deactivate latency %d "
+ "higher than exptected. (%llu > %d)\n",
+ od->pm_lat_level, deact_lat,
+ odpl->deactivate_lat);
}
-
od->dev_wakeup_lat += odpl->activate_lat;
od->pm_lat_level++;
@@ -245,28 +261,27 @@ static void _add_clkdev(struct omap_device *od, const char *clk_alias,
if (!clk_alias || !clk_name)
return;
- pr_debug("omap_device: %s: Creating %s -> %s\n",
- dev_name(&od->pdev.dev), clk_alias, clk_name);
+ dev_dbg(&od->pdev->dev, "Creating %s -> %s\n", clk_alias, clk_name);
- r = clk_get_sys(dev_name(&od->pdev.dev), clk_alias);
+ r = clk_get_sys(dev_name(&od->pdev->dev), clk_alias);
if (!IS_ERR(r)) {
- pr_warning("omap_device: %s: alias %s already exists\n",
- dev_name(&od->pdev.dev), clk_alias);
+ dev_warn(&od->pdev->dev,
+ "alias %s already exists\n", clk_alias);
clk_put(r);
return;
}
r = omap_clk_get_by_name(clk_name);
if (IS_ERR(r)) {
- pr_err("omap_device: %s: omap_clk_get_by_name for %s failed\n",
- dev_name(&od->pdev.dev), clk_name);
+ dev_err(&od->pdev->dev,
+ "omap_clk_get_by_name for %s failed\n", clk_name);
return;
}
- l = clkdev_alloc(r, clk_alias, dev_name(&od->pdev.dev));
+ l = clkdev_alloc(r, clk_alias, dev_name(&od->pdev->dev));
if (!l) {
- pr_err("omap_device: %s: clkdev_alloc for %s failed\n",
- dev_name(&od->pdev.dev), clk_alias);
+ dev_err(&od->pdev->dev,
+ "clkdev_alloc for %s failed\n", clk_alias);
return;
}
@@ -304,6 +319,96 @@ static void _add_hwmod_clocks_clkdev(struct omap_device *od,
}
+static struct dev_pm_domain omap_device_pm_domain;
+
+/**
+ * omap_device_build_from_dt - build an omap_device with multiple hwmods
+ * @pdev_name: name of the platform_device driver to use
+ * @pdev_id: this platform_device's connection ID
+ * @oh: ptr to the single omap_hwmod that backs this omap_device
+ * @pdata: platform_data ptr to associate with the platform_device
+ * @pdata_len: amount of memory pointed to by @pdata
+ * @pm_lats: pointer to a omap_device_pm_latency array for this device
+ * @pm_lats_cnt: ARRAY_SIZE() of @pm_lats
+ * @is_early_device: should the device be registered as an early device or not
+ *
+ * Function for building an omap_device already registered from device-tree
+ *
+ * Returns 0 or PTR_ERR() on error.
+ */
+static int omap_device_build_from_dt(struct platform_device *pdev)
+{
+ struct omap_hwmod **hwmods;
+ struct omap_device *od;
+ struct omap_hwmod *oh;
+ struct device_node *node = pdev->dev.of_node;
+ const char *oh_name;
+ int oh_cnt, i, ret = 0;
+
+ oh_cnt = of_property_count_strings(node, "ti,hwmods");
+ if (!oh_cnt || IS_ERR_VALUE(oh_cnt)) {
+ dev_warn(&pdev->dev, "No 'hwmods' to build omap_device\n");
+ return -ENODEV;
+ }
+
+ hwmods = kzalloc(sizeof(struct omap_hwmod *) * oh_cnt, GFP_KERNEL);
+ if (!hwmods) {
+ ret = -ENOMEM;
+ goto odbfd_exit;
+ }
+
+ for (i = 0; i < oh_cnt; i++) {
+ of_property_read_string_index(node, "ti,hwmods", i, &oh_name);
+ oh = omap_hwmod_lookup(oh_name);
+ if (!oh) {
+ dev_err(&pdev->dev, "Cannot lookup hwmod '%s'\n",
+ oh_name);
+ ret = -EINVAL;
+ goto odbfd_exit1;
+ }
+ hwmods[i] = oh;
+ }
+
+ od = omap_device_alloc(pdev, hwmods, oh_cnt, NULL, 0);
+ if (!od) {
+ dev_err(&pdev->dev, "Cannot allocate omap_device for :%s\n",
+ oh_name);
+ ret = PTR_ERR(od);
+ goto odbfd_exit1;
+ }
+
+ if (of_get_property(node, "ti,no_idle_on_suspend", NULL))
+ omap_device_disable_idle_on_suspend(pdev);
+
+ pdev->dev.pm_domain = &omap_device_pm_domain;
+
+odbfd_exit1:
+ kfree(hwmods);
+odbfd_exit:
+ return ret;
+}
+
+static int _omap_device_notifier_call(struct notifier_block *nb,
+ unsigned long event, void *dev)
+{
+ struct platform_device *pdev = to_platform_device(dev);
+
+ switch (event) {
+ case BUS_NOTIFY_ADD_DEVICE:
+ if (pdev->dev.of_node)
+ omap_device_build_from_dt(pdev);
+ break;
+
+ case BUS_NOTIFY_DEL_DEVICE:
+ if (pdev->archdata.od)
+ omap_device_delete(pdev->archdata.od);
+ break;
+ }
+
+ return NOTIFY_DONE;
+}
+
+
/* Public functions for use by core code */
/**
@@ -343,7 +448,7 @@ u32 omap_device_get_context_loss_count(struct platform_device *pdev)
* much memory to allocate before calling
* omap_device_fill_resources(). Returns the count.
*/
-int omap_device_count_resources(struct omap_device *od)
+static int omap_device_count_resources(struct omap_device *od)
{
int c = 0;
int i;
@@ -352,7 +457,7 @@ int omap_device_count_resources(struct omap_device *od)
c += omap_hwmod_count_resources(od->hwmods[i]);
pr_debug("omap_device: %s: counted %d total resources across %d "
- "hwmods\n", od->pdev.name, c, od->hwmods_cnt);
+ "hwmods\n", od->pdev->name, c, od->hwmods_cnt);
return c;
}
@@ -374,7 +479,8 @@ int omap_device_count_resources(struct omap_device *od)
* functions to get device resources. Hacking around the existing
* platform_device code wastes memory. Returns 0.
*/
-int omap_device_fill_resources(struct omap_device *od, struct resource *res)
+static int omap_device_fill_resources(struct omap_device *od,
+ struct resource *res)
{
int c = 0;
int i, r;
@@ -389,6 +495,113 @@ int omap_device_fill_resources(struct omap_device *od, struct resource *res)
}
/**
+ * omap_device_alloc - allocate an omap_device
+ * @pdev: platform_device that will be included in this omap_device
+ * @oh: ptr to the single omap_hwmod that backs this omap_device
+ * @pdata: platform_data ptr to associate with the platform_device
+ * @pdata_len: amount of memory pointed to by @pdata
+ * @pm_lats: pointer to a omap_device_pm_latency array for this device
+ * @pm_lats_cnt: ARRAY_SIZE() of @pm_lats
+ *
+ * Convenience function for allocating an omap_device structure and filling
+ * hwmods, resources and pm_latency attributes.
+ *
+ * Returns an struct omap_device pointer or ERR_PTR() on error;
+ */
+static struct omap_device *omap_device_alloc(struct platform_device *pdev,
+ struct omap_hwmod **ohs, int oh_cnt,
+ struct omap_device_pm_latency *pm_lats,
+ int pm_lats_cnt)
+{
+ int ret = -ENOMEM;
+ struct omap_device *od;
+ struct resource *res = NULL;
+ int i, res_count;
+ struct omap_hwmod **hwmods;
+
+ od = kzalloc(sizeof(struct omap_device), GFP_KERNEL);
+ if (!od) {
+ ret = -ENOMEM;
+ goto oda_exit1;
+ }
+ od->hwmods_cnt = oh_cnt;
+
+ hwmods = kmemdup(ohs, sizeof(struct omap_hwmod *) * oh_cnt, GFP_KERNEL);
+ if (!hwmods)
+ goto oda_exit2;
+
+ od->hwmods = hwmods;
+ od->pdev = pdev;
+
+ /*
+ * HACK: Ideally the resources from DT should match, and hwmod
+ * should just add the missing ones. Since the name is not
+ * properly populated by DT, stick to hwmod resources only.
+ */
+ if (pdev->num_resources && pdev->resource)
+ dev_warn(&pdev->dev, "%s(): resources already allocated %d\n",
+ __func__, pdev->num_resources);
+
+ res_count = omap_device_count_resources(od);
+ if (res_count > 0) {
+ dev_dbg(&pdev->dev, "%s(): resources allocated from hwmod %d\n",
+ __func__, res_count);
+ res = kzalloc(sizeof(struct resource) * res_count, GFP_KERNEL);
+ if (!res)
+ goto oda_exit3;
+
+ omap_device_fill_resources(od, res);
+
+ ret = platform_device_add_resources(pdev, res, res_count);
+ kfree(res);
+
+ if (ret)
+ goto oda_exit3;
+ }
+
+ if (!pm_lats) {
+ pm_lats = omap_default_latency;
+ pm_lats_cnt = ARRAY_SIZE(omap_default_latency);
+ }
+
+ od->pm_lats_cnt = pm_lats_cnt;
+ od->pm_lats = kmemdup(pm_lats,
+ sizeof(struct omap_device_pm_latency) * pm_lats_cnt,
+ GFP_KERNEL);
+ if (!od->pm_lats)
+ goto oda_exit3;
+
+ pdev->archdata.od = od;
+
+ for (i = 0; i < oh_cnt; i++) {
+ hwmods[i]->od = od;
+ _add_hwmod_clocks_clkdev(od, hwmods[i]);
+ }
+
+ return od;
+
+oda_exit3:
+ kfree(hwmods);
+oda_exit2:
+ kfree(od);
+oda_exit1:
+ dev_err(&pdev->dev, "omap_device: build failed (%d)\n", ret);
+
+ return ERR_PTR(ret);
+}
+
+static void omap_device_delete(struct omap_device *od)
+{
+ if (!od)
+ return;
+
+ od->pdev->archdata.od = NULL;
+ kfree(od->pm_lats);
+ kfree(od->hwmods);
+ kfree(od);
+}
+
+/**
* omap_device_build - build and register an omap_device with one omap_hwmod
* @pdev_name: name of the platform_device driver to use
* @pdev_id: this platform_device's connection ID
@@ -405,7 +618,7 @@ int omap_device_fill_resources(struct omap_device *od, struct resource *res)
* information. Returns ERR_PTR(-EINVAL) if @oh is NULL; otherwise,
* passes along the return value of omap_device_build_ss().
*/
-struct omap_device *omap_device_build(const char *pdev_name, int pdev_id,
+struct platform_device *omap_device_build(const char *pdev_name, int pdev_id,
struct omap_hwmod *oh, void *pdata,
int pdata_len,
struct omap_device_pm_latency *pm_lats,
@@ -438,18 +651,15 @@ struct omap_device *omap_device_build(const char *pdev_name, int pdev_id,
* platform_device record. Returns an ERR_PTR() on error, or passes
* along the return value of omap_device_register().
*/
-struct omap_device *omap_device_build_ss(const char *pdev_name, int pdev_id,
+struct platform_device *omap_device_build_ss(const char *pdev_name, int pdev_id,
struct omap_hwmod **ohs, int oh_cnt,
void *pdata, int pdata_len,
struct omap_device_pm_latency *pm_lats,
int pm_lats_cnt, int is_early_device)
{
int ret = -ENOMEM;
+ struct platform_device *pdev;
struct omap_device *od;
- char *pdev_name2;
- struct resource *res = NULL;
- int i, res_count;
- struct omap_hwmod **hwmods;
if (!ohs || oh_cnt == 0 || !pdev_name)
return ERR_PTR(-EINVAL);
@@ -457,72 +667,40 @@ struct omap_device *omap_device_build_ss(const char *pdev_name, int pdev_id,
if (!pdata && pdata_len > 0)
return ERR_PTR(-EINVAL);
- pr_debug("omap_device: %s: building with %d hwmods\n", pdev_name,
- oh_cnt);
-
- od = kzalloc(sizeof(struct omap_device), GFP_KERNEL);
- if (!od)
- return ERR_PTR(-ENOMEM);
+ pdev = platform_device_alloc(pdev_name, pdev_id);
+ if (!pdev) {
+ ret = -ENOMEM;
+ goto odbs_exit;
+ }
- od->hwmods_cnt = oh_cnt;
+ /* Set the dev_name early to allow dev_xxx in omap_device_alloc */
+ if (pdev->id != -1)
+ dev_set_name(&pdev->dev, "%s.%d", pdev->name, pdev->id);
+ else
+ dev_set_name(&pdev->dev, "%s", pdev->name);
- hwmods = kzalloc(sizeof(struct omap_hwmod *) * oh_cnt,
- GFP_KERNEL);
- if (!hwmods)
+ od = omap_device_alloc(pdev, ohs, oh_cnt, pm_lats, pm_lats_cnt);
+ if (!od)
goto odbs_exit1;
- memcpy(hwmods, ohs, sizeof(struct omap_hwmod *) * oh_cnt);
- od->hwmods = hwmods;
-
- pdev_name2 = kzalloc(strlen(pdev_name) + 1, GFP_KERNEL);
- if (!pdev_name2)
- goto odbs_exit2;
- strcpy(pdev_name2, pdev_name);
-
- od->pdev.name = pdev_name2;
- od->pdev.id = pdev_id;
-
- res_count = omap_device_count_resources(od);
- if (res_count > 0) {
- res = kzalloc(sizeof(struct resource) * res_count, GFP_KERNEL);
- if (!res)
- goto odbs_exit3;
- }
- omap_device_fill_resources(od, res);
-
- od->pdev.num_resources = res_count;
- od->pdev.resource = res;
-
- ret = platform_device_add_data(&od->pdev, pdata, pdata_len);
+ ret = platform_device_add_data(pdev, pdata, pdata_len);
if (ret)
- goto odbs_exit4;
-
- od->pm_lats = pm_lats;
- od->pm_lats_cnt = pm_lats_cnt;
+ goto odbs_exit2;
if (is_early_device)
- ret = omap_early_device_register(od);
+ ret = omap_early_device_register(pdev);
else
- ret = omap_device_register(od);
-
- for (i = 0; i < oh_cnt; i++) {
- hwmods[i]->od = od;
- _add_hwmod_clocks_clkdev(od, hwmods[i]);
- }
-
+ ret = omap_device_register(pdev);
if (ret)
- goto odbs_exit4;
+ goto odbs_exit2;
- return od;
+ return pdev;
-odbs_exit4:
- kfree(res);
-odbs_exit3:
- kfree(pdev_name2);
odbs_exit2:
- kfree(hwmods);
+ omap_device_delete(od);
odbs_exit1:
- kfree(od);
+ platform_device_put(pdev);
+odbs_exit:
pr_err("omap_device: %s: build failed (%d)\n", pdev_name, ret);
@@ -538,11 +716,11 @@ odbs_exit1:
* platform_early_add_device() on the underlying platform_device.
* Returns 0 by default.
*/
-int omap_early_device_register(struct omap_device *od)
+static int omap_early_device_register(struct platform_device *pdev)
{
struct platform_device *devices[1];
- devices[0] = &(od->pdev);
+ devices[0] = pdev;
early_platform_add_devices(devices, 1);
return 0;
}
@@ -638,13 +816,13 @@ static struct dev_pm_domain omap_device_pm_domain = {
* platform_device_register() on the underlying platform_device.
* Returns the return value of platform_device_register().
*/
-int omap_device_register(struct omap_device *od)
+static int omap_device_register(struct platform_device *pdev)
{
- pr_debug("omap_device: %s: registering\n", od->pdev.name);
+ pr_debug("omap_device: %s: registering\n", pdev->name);
- od->pdev.dev.parent = &omap_device_parent;
- od->pdev.dev.pm_domain = &omap_device_pm_domain;
- return platform_device_register(&od->pdev);
+ pdev->dev.parent = &omap_device_parent;
+ pdev->dev.pm_domain = &omap_device_pm_domain;
+ return platform_device_add(pdev);
}
@@ -671,8 +849,9 @@ int omap_device_enable(struct platform_device *pdev)
od = to_omap_device(pdev);
if (od->_state == OMAP_DEVICE_STATE_ENABLED) {
- WARN(1, "omap_device: %s.%d: %s() called from invalid state %d\n",
- od->pdev.name, od->pdev.id, __func__, od->_state);
+ dev_warn(&pdev->dev,
+ "omap_device: %s() called from invalid state %d\n",
+ __func__, od->_state);
return -EINVAL;
}
@@ -710,8 +889,9 @@ int omap_device_idle(struct platform_device *pdev)
od = to_omap_device(pdev);
if (od->_state != OMAP_DEVICE_STATE_ENABLED) {
- WARN(1, "omap_device: %s.%d: %s() called from invalid state %d\n",
- od->pdev.name, od->pdev.id, __func__, od->_state);
+ dev_warn(&pdev->dev,
+ "omap_device: %s() called from invalid state %d\n",
+ __func__, od->_state);
return -EINVAL;
}
@@ -742,8 +922,9 @@ int omap_device_shutdown(struct platform_device *pdev)
if (od->_state != OMAP_DEVICE_STATE_ENABLED &&
od->_state != OMAP_DEVICE_STATE_IDLE) {
- WARN(1, "omap_device: %s.%d: %s() called from invalid state %d\n",
- od->pdev.name, od->pdev.id, __func__, od->_state);
+ dev_warn(&pdev->dev,
+ "omap_device: %s() called from invalid state %d\n",
+ __func__, od->_state);
return -EINVAL;
}
@@ -837,6 +1018,42 @@ void __iomem *omap_device_get_rt_va(struct omap_device *od)
return omap_hwmod_get_mpu_rt_va(od->hwmods[0]);
}
+/**
+ * omap_device_get_by_hwmod_name() - convert a hwmod name to
+ * device pointer.
+ * @oh_name: name of the hwmod device
+ *
+ * Returns back a struct device * pointer associated with a hwmod
+ * device represented by a hwmod_name
+ */
+struct device *omap_device_get_by_hwmod_name(const char *oh_name)
+{
+ struct omap_hwmod *oh;
+
+ if (!oh_name) {
+ WARN(1, "%s: no hwmod name!\n", __func__);
+ return ERR_PTR(-EINVAL);
+ }
+
+ oh = omap_hwmod_lookup(oh_name);
+ if (IS_ERR_OR_NULL(oh)) {
+ WARN(1, "%s: no hwmod for %s\n", __func__,
+ oh_name);
+ return ERR_PTR(oh ? PTR_ERR(oh) : -ENODEV);
+ }
+ if (IS_ERR_OR_NULL(oh->od)) {
+ WARN(1, "%s: no omap_device for %s\n", __func__,
+ oh_name);
+ return ERR_PTR(oh->od ? PTR_ERR(oh->od) : -ENODEV);
+ }
+
+ if (IS_ERR_OR_NULL(oh->od->pdev))
+ return ERR_PTR(oh->od->pdev ? PTR_ERR(oh->od->pdev) : -ENODEV);
+
+ return &oh->od->pdev->dev;
+}
+EXPORT_SYMBOL(omap_device_get_by_hwmod_name);
+
/*
* Public functions intended for use in omap_device_pm_latency
* .activate_func and .deactivate_func function pointers
@@ -917,8 +1134,13 @@ struct device omap_device_parent = {
.parent = &platform_bus,
};
+static struct notifier_block platform_nb = {
+ .notifier_call = _omap_device_notifier_call,
+};
+
static int __init omap_device_init(void)
{
+ bus_register_notifier(&platform_bus_type, &platform_nb);
return device_register(&omap_device_parent);
}
core_initcall(omap_device_init);
diff --git a/arch/arm/plat-s5p/irq-gpioint.c b/arch/arm/plat-s5p/irq-gpioint.c
index f88216d23991..c65eb791d1bb 100644
--- a/arch/arm/plat-s5p/irq-gpioint.c
+++ b/arch/arm/plat-s5p/irq-gpioint.c
@@ -163,9 +163,9 @@ static __init int s5p_gpioint_add(struct s3c_gpio_chip *chip)
ct->chip.irq_mask = irq_gc_mask_set_bit;
ct->chip.irq_unmask = irq_gc_mask_clr_bit;
ct->chip.irq_set_type = s5p_gpioint_set_type,
- ct->regs.ack = PEND_OFFSET + REG_OFFSET(chip->group);
- ct->regs.mask = MASK_OFFSET + REG_OFFSET(chip->group);
- ct->regs.type = CON_OFFSET + REG_OFFSET(chip->group);
+ ct->regs.ack = PEND_OFFSET + REG_OFFSET(group - bank->start);
+ ct->regs.mask = MASK_OFFSET + REG_OFFSET(group - bank->start);
+ ct->regs.type = CON_OFFSET + REG_OFFSET(group - bank->start);
irq_setup_generic_chip(gc, IRQ_MSK(chip->chip.ngpio),
IRQ_GC_INIT_MASK_CACHE,
IRQ_NOREQUEST | IRQ_NOPROBE, 0);
diff --git a/arch/mips/Kconfig b/arch/mips/Kconfig
index 177cdaf83564..b122adc8bdbb 100644
--- a/arch/mips/Kconfig
+++ b/arch/mips/Kconfig
@@ -24,6 +24,7 @@ config MIPS
select GENERIC_IRQ_PROBE
select GENERIC_IRQ_SHOW
select HAVE_ARCH_JUMP_LABEL
+ select IRQ_FORCED_THREADING
menu "Machine selection"
@@ -722,6 +723,7 @@ config CAVIUM_OCTEON_SIMULATOR
select SYS_SUPPORTS_HIGHMEM
select SYS_SUPPORTS_HOTPLUG_CPU
select SYS_HAS_CPU_CAVIUM_OCTEON
+ select HOLES_IN_ZONE
help
The Octeon simulator is software performance model of the Cavium
Octeon Processor. It supports simulating Octeon processors on x86
@@ -744,6 +746,7 @@ config CAVIUM_OCTEON_REFERENCE_BOARD
select ZONE_DMA32
select USB_ARCH_HAS_OHCI
select USB_ARCH_HAS_EHCI
+ select HOLES_IN_ZONE
help
This option supports all of the Octeon reference boards from Cavium
Networks. It builds a kernel that dynamically determines the Octeon
@@ -973,6 +976,9 @@ config ISA_DMA_API
config GENERIC_GPIO
bool
+config HOLES_IN_ZONE
+ bool
+
#
# Endianess selection. Sufficiently obscure so many users don't know what to
# answer,so we try hard to limit the available choices. Also the use of a
diff --git a/arch/mips/alchemy/common/platform.c b/arch/mips/alchemy/common/platform.c
index 3b2c18b14341..f72c48d4804c 100644
--- a/arch/mips/alchemy/common/platform.c
+++ b/arch/mips/alchemy/common/platform.c
@@ -492,7 +492,7 @@ static void __init alchemy_setup_macs(int ctype)
memcpy(au1xxx_eth0_platform_data.mac, ethaddr, 6);
ret = platform_device_register(&au1xxx_eth0_device);
- if (!ret)
+ if (ret)
printk(KERN_INFO "Alchemy: failed to register MAC0\n");
diff --git a/arch/mips/alchemy/common/power.c b/arch/mips/alchemy/common/power.c
index 647e518c90bc..b86324a42601 100644
--- a/arch/mips/alchemy/common/power.c
+++ b/arch/mips/alchemy/common/power.c
@@ -158,15 +158,21 @@ static void restore_core_regs(void)
void au_sleep(void)
{
- int cpuid = alchemy_get_cputype();
- if (cpuid != ALCHEMY_CPU_UNKNOWN) {
- save_core_regs();
- if (cpuid <= ALCHEMY_CPU_AU1500)
- alchemy_sleep_au1000();
- else if (cpuid <= ALCHEMY_CPU_AU1200)
- alchemy_sleep_au1550();
- restore_core_regs();
+ save_core_regs();
+
+ switch (alchemy_get_cputype()) {
+ case ALCHEMY_CPU_AU1000:
+ case ALCHEMY_CPU_AU1500:
+ case ALCHEMY_CPU_AU1100:
+ alchemy_sleep_au1000();
+ break;
+ case ALCHEMY_CPU_AU1550:
+ case ALCHEMY_CPU_AU1200:
+ alchemy_sleep_au1550();
+ break;
}
+
+ restore_core_regs();
}
#endif /* CONFIG_PM */
diff --git a/arch/mips/alchemy/devboards/bcsr.c b/arch/mips/alchemy/devboards/bcsr.c
index 596ad00e7f05..463d2c4d9441 100644
--- a/arch/mips/alchemy/devboards/bcsr.c
+++ b/arch/mips/alchemy/devboards/bcsr.c
@@ -89,8 +89,12 @@ static void bcsr_csc_handler(unsigned int irq, struct irq_desc *d)
{
unsigned short bisr = __raw_readw(bcsr_virt + BCSR_REG_INTSTAT);
+ disable_irq_nosync(irq);
+
for ( ; bisr; bisr &= bisr - 1)
generic_handle_irq(bcsr_csc_base + __ffs(bisr));
+
+ enable_irq(irq);
}
/* NOTE: both the enable and mask bits must be cleared, otherwise the
diff --git a/arch/mips/alchemy/devboards/db1200/setup.c b/arch/mips/alchemy/devboards/db1200/setup.c
index 1dac4f27d334..4a8980027ecf 100644
--- a/arch/mips/alchemy/devboards/db1200/setup.c
+++ b/arch/mips/alchemy/devboards/db1200/setup.c
@@ -23,13 +23,6 @@ void __init board_setup(void)
unsigned long freq0, clksrc, div, pfc;
unsigned short whoami;
- /* Set Config[OD] (disable overlapping bus transaction):
- * This gets rid of a _lot_ of spurious interrupts (especially
- * wrt. IDE); but incurs ~10% performance hit in some
- * cpu-bound applications.
- */
- set_c0_config(1 << 19);
-
bcsr_init(DB1200_BCSR_PHYS_ADDR,
DB1200_BCSR_PHYS_ADDR + DB1200_BCSR_HEXLED_OFS);
diff --git a/arch/mips/ar7/irq.c b/arch/mips/ar7/irq.c
index 03db3daadbd8..88c4babfdb5d 100644
--- a/arch/mips/ar7/irq.c
+++ b/arch/mips/ar7/irq.c
@@ -98,7 +98,8 @@ static struct irq_chip ar7_sec_irq_type = {
static struct irqaction ar7_cascade_action = {
.handler = no_action,
- .name = "AR7 cascade interrupt"
+ .name = "AR7 cascade interrupt",
+ .flags = IRQF_NO_THREAD,
};
static void __init ar7_irq_init(int base)
diff --git a/arch/mips/bcm63xx/irq.c b/arch/mips/bcm63xx/irq.c
index cea6021cb8d7..162e11b4ed75 100644
--- a/arch/mips/bcm63xx/irq.c
+++ b/arch/mips/bcm63xx/irq.c
@@ -222,6 +222,7 @@ static struct irq_chip bcm63xx_external_irq_chip = {
static struct irqaction cpu_ip2_cascade_action = {
.handler = no_action,
.name = "cascade_ip2",
+ .flags = IRQF_NO_THREAD,
};
void __init arch_init_irq(void)
diff --git a/arch/mips/cobalt/irq.c b/arch/mips/cobalt/irq.c
index cb9bf820fe53..965c777d3561 100644
--- a/arch/mips/cobalt/irq.c
+++ b/arch/mips/cobalt/irq.c
@@ -48,6 +48,7 @@ asmlinkage void plat_irq_dispatch(void)
static struct irqaction cascade = {
.handler = no_action,
.name = "cascade",
+ .flags = IRQF_NO_THREAD,
};
void __init arch_init_irq(void)
diff --git a/arch/mips/dec/setup.c b/arch/mips/dec/setup.c
index fa45e924be05..f7b7ba6d5c45 100644
--- a/arch/mips/dec/setup.c
+++ b/arch/mips/dec/setup.c
@@ -101,20 +101,24 @@ int cpu_fpu_mask = DEC_CPU_IRQ_MASK(DEC_CPU_INR_FPU);
static struct irqaction ioirq = {
.handler = no_action,
.name = "cascade",
+ .flags = IRQF_NO_THREAD,
};
static struct irqaction fpuirq = {
.handler = no_action,
.name = "fpu",
+ .flags = IRQF_NO_THREAD,
};
static struct irqaction busirq = {
.flags = IRQF_DISABLED,
.name = "bus error",
+ .flags = IRQF_NO_THREAD,
};
static struct irqaction haltirq = {
.handler = dec_intr_halt,
.name = "halt",
+ .flags = IRQF_NO_THREAD,
};
diff --git a/arch/mips/emma/markeins/irq.c b/arch/mips/emma/markeins/irq.c
index 3dbd7a5a6ad3..7798887a1288 100644
--- a/arch/mips/emma/markeins/irq.c
+++ b/arch/mips/emma/markeins/irq.c
@@ -169,7 +169,7 @@ void emma2rh_gpio_irq_init(void)
static struct irqaction irq_cascade = {
.handler = no_action,
- .flags = 0,
+ .flags = IRQF_NO_THREAD,
.name = "cascade",
.dev_id = NULL,
.next = NULL,
diff --git a/arch/mips/include/asm/mach-cavium-octeon/cpu-feature-overrides.h b/arch/mips/include/asm/mach-cavium-octeon/cpu-feature-overrides.h
index 0d5a42b5f47a..a58addb98cfd 100644
--- a/arch/mips/include/asm/mach-cavium-octeon/cpu-feature-overrides.h
+++ b/arch/mips/include/asm/mach-cavium-octeon/cpu-feature-overrides.h
@@ -54,7 +54,6 @@
#define cpu_has_mips_r2_exec_hazard 0
#define cpu_has_dsp 0
#define cpu_has_mipsmt 0
-#define cpu_has_userlocal 0
#define cpu_has_vint 0
#define cpu_has_veic 0
#define cpu_hwrena_impl_bits 0xc0000000
diff --git a/arch/mips/include/asm/mach-powertv/dma-coherence.h b/arch/mips/include/asm/mach-powertv/dma-coherence.h
index 62c094085947..35371641575d 100644
--- a/arch/mips/include/asm/mach-powertv/dma-coherence.h
+++ b/arch/mips/include/asm/mach-powertv/dma-coherence.h
@@ -13,7 +13,6 @@
#define __ASM_MACH_POWERTV_DMA_COHERENCE_H
#include <linux/sched.h>
-#include <linux/version.h>
#include <linux/device.h>
#include <asm/mach-powertv/asic.h>
diff --git a/arch/mips/include/asm/stackframe.h b/arch/mips/include/asm/stackframe.h
index b4ba2449444b..cb41af5f3406 100644
--- a/arch/mips/include/asm/stackframe.h
+++ b/arch/mips/include/asm/stackframe.h
@@ -195,9 +195,9 @@
* to cover the pipeline delay.
*/
.set mips32
- mfc0 v1, CP0_TCSTATUS
+ mfc0 k0, CP0_TCSTATUS
.set mips0
- LONG_S v1, PT_TCSTATUS(sp)
+ LONG_S k0, PT_TCSTATUS(sp)
#endif /* CONFIG_MIPS_MT_SMTC */
LONG_S $4, PT_R4(sp)
LONG_S $5, PT_R5(sp)
diff --git a/arch/mips/jz4740/gpio.c b/arch/mips/jz4740/gpio.c
index 73031f7fc827..4397972949fa 100644
--- a/arch/mips/jz4740/gpio.c
+++ b/arch/mips/jz4740/gpio.c
@@ -18,7 +18,7 @@
#include <linux/init.h>
#include <linux/spinlock.h>
-#include <linux/sysdev.h>
+#include <linux/syscore_ops.h>
#include <linux/io.h>
#include <linux/gpio.h>
#include <linux/delay.h>
@@ -86,7 +86,6 @@ struct jz_gpio_chip {
spinlock_t lock;
struct gpio_chip gpio_chip;
- struct sys_device sysdev;
};
static struct jz_gpio_chip jz4740_gpio_chips[];
@@ -459,49 +458,47 @@ static struct jz_gpio_chip jz4740_gpio_chips[] = {
JZ4740_GPIO_CHIP(D),
};
-static inline struct jz_gpio_chip *sysdev_to_chip(struct sys_device *dev)
+static void jz4740_gpio_suspend_chip(struct jz_gpio_chip *chip)
{
- return container_of(dev, struct jz_gpio_chip, sysdev);
+ chip->suspend_mask = readl(chip->base + JZ_REG_GPIO_MASK);
+ writel(~(chip->wakeup), chip->base + JZ_REG_GPIO_MASK_SET);
+ writel(chip->wakeup, chip->base + JZ_REG_GPIO_MASK_CLEAR);
}
-static int jz4740_gpio_suspend(struct sys_device *dev, pm_message_t state)
+static int jz4740_gpio_suspend(void)
{
- struct jz_gpio_chip *chip = sysdev_to_chip(dev);
+ int i;
- chip->suspend_mask = readl(chip->base + JZ_REG_GPIO_MASK);
- writel(~(chip->wakeup), chip->base + JZ_REG_GPIO_MASK_SET);
- writel(chip->wakeup, chip->base + JZ_REG_GPIO_MASK_CLEAR);
+ for (i = 0; i < ARRAY_SIZE(jz4740_gpio_chips); i++)
+ jz4740_gpio_suspend_chip(&jz4740_gpio_chips[i]);
return 0;
}
-static int jz4740_gpio_resume(struct sys_device *dev)
+static void jz4740_gpio_resume_chip(struct jz_gpio_chip *chip)
{
- struct jz_gpio_chip *chip = sysdev_to_chip(dev);
uint32_t mask = chip->suspend_mask;
writel(~mask, chip->base + JZ_REG_GPIO_MASK_CLEAR);
writel(mask, chip->base + JZ_REG_GPIO_MASK_SET);
+}
- return 0;
+static void jz4740_gpio_resume(void)
+{
+ int i;
+
+ for (i = ARRAY_SIZE(jz4740_gpio_chips) - 1; i >= 0 ; i--)
+ jz4740_gpio_resume_chip(&jz4740_gpio_chips[i]);
}
-static struct sysdev_class jz4740_gpio_sysdev_class = {
- .name = "gpio",
+static struct syscore_ops jz4740_gpio_syscore_ops = {
.suspend = jz4740_gpio_suspend,
.resume = jz4740_gpio_resume,
};
-static int jz4740_gpio_chip_init(struct jz_gpio_chip *chip, unsigned int id)
+static void jz4740_gpio_chip_init(struct jz_gpio_chip *chip, unsigned int id)
{
- int ret, irq;
-
- chip->sysdev.id = id;
- chip->sysdev.cls = &jz4740_gpio_sysdev_class;
- ret = sysdev_register(&chip->sysdev);
-
- if (ret)
- return ret;
+ int irq;
spin_lock_init(&chip->lock);
@@ -519,22 +516,17 @@ static int jz4740_gpio_chip_init(struct jz_gpio_chip *chip, unsigned int id)
irq_set_chip_and_handler(irq, &jz_gpio_irq_chip,
handle_level_irq);
}
-
- return 0;
}
static int __init jz4740_gpio_init(void)
{
unsigned int i;
- int ret;
-
- ret = sysdev_class_register(&jz4740_gpio_sysdev_class);
- if (ret)
- return ret;
for (i = 0; i < ARRAY_SIZE(jz4740_gpio_chips); ++i)
jz4740_gpio_chip_init(&jz4740_gpio_chips[i], i);
+ register_syscore_ops(&jz4740_gpio_syscore_ops);
+
printk(KERN_INFO "JZ4740 GPIO initialized\n");
return 0;
diff --git a/arch/mips/kernel/ftrace.c b/arch/mips/kernel/ftrace.c
index feb8021a305f..6a2d758dd8e9 100644
--- a/arch/mips/kernel/ftrace.c
+++ b/arch/mips/kernel/ftrace.c
@@ -19,6 +19,26 @@
#include <asm-generic/sections.h>
+#if defined(KBUILD_MCOUNT_RA_ADDRESS) && defined(CONFIG_32BIT)
+#define MCOUNT_OFFSET_INSNS 5
+#else
+#define MCOUNT_OFFSET_INSNS 4
+#endif
+
+/*
+ * Check if the address is in kernel space
+ *
+ * Clone core_kernel_text() from kernel/extable.c, but doesn't call
+ * init_kernel_text() for Ftrace doesn't trace functions in init sections.
+ */
+static inline int in_kernel_space(unsigned long ip)
+{
+ if (ip >= (unsigned long)_stext &&
+ ip <= (unsigned long)_etext)
+ return 1;
+ return 0;
+}
+
#ifdef CONFIG_DYNAMIC_FTRACE
#define JAL 0x0c000000 /* jump & link: ip --> ra, jump to target */
@@ -54,20 +74,6 @@ static inline void ftrace_dyn_arch_init_insns(void)
#endif
}
-/*
- * Check if the address is in kernel space
- *
- * Clone core_kernel_text() from kernel/extable.c, but doesn't call
- * init_kernel_text() for Ftrace doesn't trace functions in init sections.
- */
-static inline int in_kernel_space(unsigned long ip)
-{
- if (ip >= (unsigned long)_stext &&
- ip <= (unsigned long)_etext)
- return 1;
- return 0;
-}
-
static int ftrace_modify_code(unsigned long ip, unsigned int new_code)
{
int faulted;
@@ -112,11 +118,6 @@ static int ftrace_modify_code(unsigned long ip, unsigned int new_code)
* 1: offset = 4 instructions
*/
-#if defined(KBUILD_MCOUNT_RA_ADDRESS) && defined(CONFIG_32BIT)
-#define MCOUNT_OFFSET_INSNS 5
-#else
-#define MCOUNT_OFFSET_INSNS 4
-#endif
#define INSN_B_1F (0x10000000 | MCOUNT_OFFSET_INSNS)
int ftrace_make_nop(struct module *mod,
diff --git a/arch/mips/kernel/i8259.c b/arch/mips/kernel/i8259.c
index 5c74eb797f08..32b397b646ee 100644
--- a/arch/mips/kernel/i8259.c
+++ b/arch/mips/kernel/i8259.c
@@ -229,7 +229,7 @@ static void i8259A_shutdown(void)
*/
if (i8259A_auto_eoi >= 0) {
outb(0xff, PIC_MASTER_IMR); /* mask all of 8259A-1 */
- outb(0xff, PIC_SLAVE_IMR); /* mask all of 8259A-1 */
+ outb(0xff, PIC_SLAVE_IMR); /* mask all of 8259A-2 */
}
}
@@ -295,6 +295,7 @@ static void init_8259A(int auto_eoi)
static struct irqaction irq2 = {
.handler = no_action,
.name = "cascade",
+ .flags = IRQF_NO_THREAD,
};
static struct resource pic1_io_resource = {
diff --git a/arch/mips/kernel/linux32.c b/arch/mips/kernel/linux32.c
index 876a75cc376f..922a554cd108 100644
--- a/arch/mips/kernel/linux32.c
+++ b/arch/mips/kernel/linux32.c
@@ -349,3 +349,10 @@ SYSCALL_DEFINE6(32_fanotify_mark, int, fanotify_fd, unsigned int, flags,
return sys_fanotify_mark(fanotify_fd, flags, merge_64(a3, a4),
dfd, pathname);
}
+
+SYSCALL_DEFINE6(32_futex, u32 __user *, uaddr, int, op, u32, val,
+ struct compat_timespec __user *, utime, u32 __user *, uaddr2,
+ u32, val3)
+{
+ return compat_sys_futex(uaddr, op, val, utime, uaddr2, val3);
+}
diff --git a/arch/mips/kernel/scall64-n32.S b/arch/mips/kernel/scall64-n32.S
index f9296e894e46..6de1f598346e 100644
--- a/arch/mips/kernel/scall64-n32.S
+++ b/arch/mips/kernel/scall64-n32.S
@@ -315,7 +315,7 @@ EXPORT(sysn32_call_table)
PTR sys_fremovexattr
PTR sys_tkill
PTR sys_ni_syscall
- PTR compat_sys_futex
+ PTR sys_32_futex
PTR compat_sys_sched_setaffinity /* 6195 */
PTR compat_sys_sched_getaffinity
PTR sys_cacheflush
diff --git a/arch/mips/kernel/scall64-o32.S b/arch/mips/kernel/scall64-o32.S
index 4d7c9827706f..1d813169e453 100644
--- a/arch/mips/kernel/scall64-o32.S
+++ b/arch/mips/kernel/scall64-o32.S
@@ -441,7 +441,7 @@ sys_call_table:
PTR sys_fremovexattr /* 4235 */
PTR sys_tkill
PTR sys_sendfile64
- PTR compat_sys_futex
+ PTR sys_32_futex
PTR compat_sys_sched_setaffinity
PTR compat_sys_sched_getaffinity /* 4240 */
PTR compat_sys_io_setup
diff --git a/arch/mips/kernel/signal.c b/arch/mips/kernel/signal.c
index dbbe0ce48d89..f8524003676a 100644
--- a/arch/mips/kernel/signal.c
+++ b/arch/mips/kernel/signal.c
@@ -8,6 +8,7 @@
* Copyright (C) 1999, 2000 Silicon Graphics, Inc.
*/
#include <linux/cache.h>
+#include <linux/irqflags.h>
#include <linux/sched.h>
#include <linux/mm.h>
#include <linux/personality.h>
@@ -658,6 +659,8 @@ static void do_signal(struct pt_regs *regs)
asmlinkage void do_notify_resume(struct pt_regs *regs, void *unused,
__u32 thread_info_flags)
{
+ local_irq_enable();
+
/* deal with pending signal delivery */
if (thread_info_flags & (_TIF_SIGPENDING | _TIF_RESTORE_SIGMASK))
do_signal(regs);
diff --git a/arch/mips/kernel/traps.c b/arch/mips/kernel/traps.c
index b7517e3abc85..cbea618af0b4 100644
--- a/arch/mips/kernel/traps.c
+++ b/arch/mips/kernel/traps.c
@@ -14,6 +14,7 @@
#include <linux/bug.h>
#include <linux/compiler.h>
#include <linux/init.h>
+#include <linux/kernel.h>
#include <linux/mm.h>
#include <linux/module.h>
#include <linux/sched.h>
@@ -364,21 +365,26 @@ static int regs_to_trapnr(struct pt_regs *regs)
return (regs->cp0_cause >> 2) & 0x1f;
}
-static DEFINE_SPINLOCK(die_lock);
+static DEFINE_RAW_SPINLOCK(die_lock);
void __noreturn die(const char *str, struct pt_regs *regs)
{
static int die_counter;
int sig = SIGSEGV;
#ifdef CONFIG_MIPS_MT_SMTC
- unsigned long dvpret = dvpe();
+ unsigned long dvpret;
#endif /* CONFIG_MIPS_MT_SMTC */
+ oops_enter();
+
if (notify_die(DIE_OOPS, str, regs, 0, regs_to_trapnr(regs), SIGSEGV) == NOTIFY_STOP)
sig = 0;
console_verbose();
- spin_lock_irq(&die_lock);
+ raw_spin_lock_irq(&die_lock);
+#ifdef CONFIG_MIPS_MT_SMTC
+ dvpret = dvpe();
+#endif /* CONFIG_MIPS_MT_SMTC */
bust_spinlocks(1);
#ifdef CONFIG_MIPS_MT_SMTC
mips_mt_regdump(dvpret);
@@ -387,7 +393,9 @@ void __noreturn die(const char *str, struct pt_regs *regs)
printk("%s[#%d]:\n", str, ++die_counter);
show_registers(regs);
add_taint(TAINT_DIE);
- spin_unlock_irq(&die_lock);
+ raw_spin_unlock_irq(&die_lock);
+
+ oops_exit();
if (in_interrupt())
panic("Fatal exception in interrupt");
diff --git a/arch/mips/kernel/vpe.c b/arch/mips/kernel/vpe.c
index 2cd50ad0d5c6..3efcb065f78a 100644
--- a/arch/mips/kernel/vpe.c
+++ b/arch/mips/kernel/vpe.c
@@ -192,7 +192,7 @@ static struct tc *get_tc(int index)
}
spin_unlock(&vpecontrol.tc_list_lock);
- return NULL;
+ return res;
}
/* allocate a vpe and associate it with this minor (or index) */
diff --git a/arch/mips/lantiq/irq.c b/arch/mips/lantiq/irq.c
index fc89795cafdb..f9737bb3c5ab 100644
--- a/arch/mips/lantiq/irq.c
+++ b/arch/mips/lantiq/irq.c
@@ -123,11 +123,10 @@ void ltq_enable_irq(struct irq_data *d)
static unsigned int ltq_startup_eiu_irq(struct irq_data *d)
{
int i;
- int irq_nr = d->irq - INT_NUM_IRQ0;
ltq_enable_irq(d);
for (i = 0; i < MAX_EIU; i++) {
- if (irq_nr == ltq_eiu_irq[i]) {
+ if (d->irq == ltq_eiu_irq[i]) {
/* low level - we should really handle set_type */
ltq_eiu_w32(ltq_eiu_r32(LTQ_EIU_EXIN_C) |
(0x6 << (i * 4)), LTQ_EIU_EXIN_C);
@@ -147,11 +146,10 @@ static unsigned int ltq_startup_eiu_irq(struct irq_data *d)
static void ltq_shutdown_eiu_irq(struct irq_data *d)
{
int i;
- int irq_nr = d->irq - INT_NUM_IRQ0;
ltq_disable_irq(d);
for (i = 0; i < MAX_EIU; i++) {
- if (irq_nr == ltq_eiu_irq[i]) {
+ if (d->irq == ltq_eiu_irq[i]) {
/* disable */
ltq_eiu_w32(ltq_eiu_r32(LTQ_EIU_EXIN_INEN) & ~(1 << i),
LTQ_EIU_EXIN_INEN);
diff --git a/arch/mips/lantiq/xway/ebu.c b/arch/mips/lantiq/xway/ebu.c
index 66eb52fa50a1..033b3184c7a7 100644
--- a/arch/mips/lantiq/xway/ebu.c
+++ b/arch/mips/lantiq/xway/ebu.c
@@ -10,7 +10,6 @@
#include <linux/kernel.h>
#include <linux/module.h>
-#include <linux/version.h>
#include <linux/ioport.h>
#include <lantiq_soc.h>
diff --git a/arch/mips/lantiq/xway/pmu.c b/arch/mips/lantiq/xway/pmu.c
index 9d69f01e352b..39f0d2641cbf 100644
--- a/arch/mips/lantiq/xway/pmu.c
+++ b/arch/mips/lantiq/xway/pmu.c
@@ -8,7 +8,6 @@
#include <linux/kernel.h>
#include <linux/module.h>
-#include <linux/version.h>
#include <linux/ioport.h>
#include <lantiq_soc.h>
diff --git a/arch/mips/lasat/interrupt.c b/arch/mips/lasat/interrupt.c
index de4c165515d7..d608b6ef0edd 100644
--- a/arch/mips/lasat/interrupt.c
+++ b/arch/mips/lasat/interrupt.c
@@ -105,6 +105,7 @@ asmlinkage void plat_irq_dispatch(void)
static struct irqaction cascade = {
.handler = no_action,
.name = "cascade",
+ .flags = IRQF_NO_THREAD,
};
void __init arch_init_irq(void)
diff --git a/arch/mips/loongson/fuloong-2e/irq.c b/arch/mips/loongson/fuloong-2e/irq.c
index d61a04222b87..3cf1fef29f0e 100644
--- a/arch/mips/loongson/fuloong-2e/irq.c
+++ b/arch/mips/loongson/fuloong-2e/irq.c
@@ -42,6 +42,7 @@ asmlinkage void mach_irq_dispatch(unsigned int pending)
static struct irqaction cascade_irqaction = {
.handler = no_action,
.name = "cascade",
+ .flags = IRQF_NO_THREAD,
};
void __init mach_init_irq(void)
diff --git a/arch/mips/loongson/lemote-2f/irq.c b/arch/mips/loongson/lemote-2f/irq.c
index 081db102bb98..14b081841b6b 100644
--- a/arch/mips/loongson/lemote-2f/irq.c
+++ b/arch/mips/loongson/lemote-2f/irq.c
@@ -96,12 +96,13 @@ static irqreturn_t ip6_action(int cpl, void *dev_id)
struct irqaction ip6_irqaction = {
.handler = ip6_action,
.name = "cascade",
- .flags = IRQF_SHARED,
+ .flags = IRQF_SHARED | IRQF_NO_THREAD,
};
struct irqaction cascade_irqaction = {
.handler = no_action,
.name = "cascade",
+ .flags = IRQF_NO_THREAD,
};
void __init mach_init_irq(void)
diff --git a/arch/mips/mm/mmap.c b/arch/mips/mm/mmap.c
index 9ff5d0fac556..302d779d5b0d 100644
--- a/arch/mips/mm/mmap.c
+++ b/arch/mips/mm/mmap.c
@@ -6,6 +6,7 @@
* Copyright (C) 2011 Wind River Systems,
* written by Ralf Baechle <ralf@linux-mips.org>
*/
+#include <linux/compiler.h>
#include <linux/errno.h>
#include <linux/mm.h>
#include <linux/mman.h>
@@ -15,12 +16,11 @@
#include <linux/sched.h>
unsigned long shm_align_mask = PAGE_SIZE - 1; /* Sane caches */
-
EXPORT_SYMBOL(shm_align_mask);
/* gap between mmap and stack */
#define MIN_GAP (128*1024*1024UL)
-#define MAX_GAP ((TASK_SIZE)/6*5)
+#define MAX_GAP ((TASK_SIZE)/6*5)
static int mmap_is_legacy(void)
{
@@ -57,13 +57,13 @@ static inline unsigned long COLOUR_ALIGN_DOWN(unsigned long addr,
return base - off;
}
-#define COLOUR_ALIGN(addr,pgoff) \
+#define COLOUR_ALIGN(addr, pgoff) \
((((addr) + shm_align_mask) & ~shm_align_mask) + \
(((pgoff) << PAGE_SHIFT) & shm_align_mask))
enum mmap_allocation_direction {UP, DOWN};
-static unsigned long arch_get_unmapped_area_foo(struct file *filp,
+static unsigned long arch_get_unmapped_area_common(struct file *filp,
unsigned long addr0, unsigned long len, unsigned long pgoff,
unsigned long flags, enum mmap_allocation_direction dir)
{
@@ -103,16 +103,16 @@ static unsigned long arch_get_unmapped_area_foo(struct file *filp,
vma = find_vma(mm, addr);
if (TASK_SIZE - len >= addr &&
- (!vma || addr + len <= vma->vm_start))
+ (!vma || addr + len <= vma->vm_start))
return addr;
}
if (dir == UP) {
addr = mm->mmap_base;
- if (do_color_align)
- addr = COLOUR_ALIGN(addr, pgoff);
- else
- addr = PAGE_ALIGN(addr);
+ if (do_color_align)
+ addr = COLOUR_ALIGN(addr, pgoff);
+ else
+ addr = PAGE_ALIGN(addr);
for (vma = find_vma(current->mm, addr); ; vma = vma->vm_next) {
/* At this point: (!vma || addr < vma->vm_end). */
@@ -131,28 +131,30 @@ static unsigned long arch_get_unmapped_area_foo(struct file *filp,
mm->free_area_cache = mm->mmap_base;
}
- /* either no address requested or can't fit in requested address hole */
+ /*
+ * either no address requested, or the mapping can't fit into
+ * the requested address hole
+ */
addr = mm->free_area_cache;
- if (do_color_align) {
- unsigned long base =
- COLOUR_ALIGN_DOWN(addr - len, pgoff);
-
+ if (do_color_align) {
+ unsigned long base =
+ COLOUR_ALIGN_DOWN(addr - len, pgoff);
addr = base + len;
- }
+ }
/* make sure it can fit in the remaining address space */
if (likely(addr > len)) {
vma = find_vma(mm, addr - len);
if (!vma || addr <= vma->vm_start) {
- /* remember the address as a hint for next time */
- return mm->free_area_cache = addr-len;
+ /* cache the address as a hint for next time */
+ return mm->free_area_cache = addr - len;
}
}
if (unlikely(mm->mmap_base < len))
goto bottomup;
- addr = mm->mmap_base-len;
+ addr = mm->mmap_base - len;
if (do_color_align)
addr = COLOUR_ALIGN_DOWN(addr, pgoff);
@@ -163,8 +165,8 @@ static unsigned long arch_get_unmapped_area_foo(struct file *filp,
* return with success:
*/
vma = find_vma(mm, addr);
- if (likely(!vma || addr+len <= vma->vm_start)) {
- /* remember the address as a hint for next time */
+ if (likely(!vma || addr + len <= vma->vm_start)) {
+ /* cache the address as a hint for next time */
return mm->free_area_cache = addr;
}
@@ -173,7 +175,7 @@ static unsigned long arch_get_unmapped_area_foo(struct file *filp,
mm->cached_hole_size = vma->vm_start - addr;
/* try just below the current vma->vm_start */
- addr = vma->vm_start-len;
+ addr = vma->vm_start - len;
if (do_color_align)
addr = COLOUR_ALIGN_DOWN(addr, pgoff);
} while (likely(len < vma->vm_start));
@@ -201,7 +203,7 @@ bottomup:
unsigned long arch_get_unmapped_area(struct file *filp, unsigned long addr0,
unsigned long len, unsigned long pgoff, unsigned long flags)
{
- return arch_get_unmapped_area_foo(filp,
+ return arch_get_unmapped_area_common(filp,
addr0, len, pgoff, flags, UP);
}
@@ -213,7 +215,7 @@ unsigned long arch_get_unmapped_area_topdown(struct file *filp,
unsigned long addr0, unsigned long len, unsigned long pgoff,
unsigned long flags)
{
- return arch_get_unmapped_area_foo(filp,
+ return arch_get_unmapped_area_common(filp,
addr0, len, pgoff, flags, DOWN);
}
diff --git a/arch/mips/mm/tlbex.c b/arch/mips/mm/tlbex.c
index b6e1cff50667..e06370f58ef3 100644
--- a/arch/mips/mm/tlbex.c
+++ b/arch/mips/mm/tlbex.c
@@ -1759,14 +1759,13 @@ static void __cpuinit build_r3000_tlb_modify_handler(void)
u32 *p = handle_tlbm;
struct uasm_label *l = labels;
struct uasm_reloc *r = relocs;
- struct work_registers wr;
memset(handle_tlbm, 0, sizeof(handle_tlbm));
memset(labels, 0, sizeof(labels));
memset(relocs, 0, sizeof(relocs));
build_r3000_tlbchange_handler_head(&p, K0, K1);
- build_pte_modifiable(&p, &r, wr.r1, wr.r2, wr.r3, label_nopage_tlbm);
+ build_pte_modifiable(&p, &r, K0, K1, -1, label_nopage_tlbm);
uasm_i_nop(&p); /* load delay */
build_make_write(&p, &r, K0, K1);
build_r3000_pte_reload_tlbwi(&p, K0, K1);
@@ -1963,7 +1962,8 @@ static void __cpuinit build_r4000_tlb_load_handler(void)
uasm_i_andi(&p, wr.r3, wr.r3, 2);
uasm_il_beqz(&p, &r, wr.r3, label_tlbl_goaround2);
}
-
+ if (PM_DEFAULT_MASK == 0)
+ uasm_i_nop(&p);
/*
* We clobbered C0_PAGEMASK, restore it. On the other branch
* it is restored in build_huge_tlb_write_entry.
diff --git a/arch/mips/mti-malta/malta-int.c b/arch/mips/mti-malta/malta-int.c
index 1d36c511a7a5..d53ff91b277c 100644
--- a/arch/mips/mti-malta/malta-int.c
+++ b/arch/mips/mti-malta/malta-int.c
@@ -350,12 +350,14 @@ unsigned int plat_ipi_resched_int_xlate(unsigned int cpu)
static struct irqaction i8259irq = {
.handler = no_action,
- .name = "XT-PIC cascade"
+ .name = "XT-PIC cascade",
+ .flags = IRQF_NO_THREAD,
};
static struct irqaction corehi_irqaction = {
.handler = no_action,
- .name = "CoreHi"
+ .name = "CoreHi",
+ .flags = IRQF_NO_THREAD,
};
static msc_irqmap_t __initdata msc_irqmap[] = {
diff --git a/arch/mips/netlogic/xlr/Makefile b/arch/mips/netlogic/xlr/Makefile
index 9bd3f731f62e..2dca585dd2f7 100644
--- a/arch/mips/netlogic/xlr/Makefile
+++ b/arch/mips/netlogic/xlr/Makefile
@@ -2,4 +2,4 @@ obj-y += setup.o platform.o irq.o setup.o time.o
obj-$(CONFIG_SMP) += smp.o smpboot.o
obj-$(CONFIG_EARLY_PRINTK) += xlr_console.o
-EXTRA_CFLAGS += -Werror
+ccflags-y += -Werror
diff --git a/arch/mips/pci/pci-lantiq.c b/arch/mips/pci/pci-lantiq.c
index 603d7493e966..8656388b34bd 100644
--- a/arch/mips/pci/pci-lantiq.c
+++ b/arch/mips/pci/pci-lantiq.c
@@ -171,8 +171,13 @@ static int __devinit ltq_pci_startup(struct ltq_pci_data *conf)
u32 temp_buffer;
/* set clock to 33Mhz */
- ltq_cgu_w32(ltq_cgu_r32(LTQ_CGU_IFCCR) & ~0xf00000, LTQ_CGU_IFCCR);
- ltq_cgu_w32(ltq_cgu_r32(LTQ_CGU_IFCCR) | 0x800000, LTQ_CGU_IFCCR);
+ if (ltq_is_ar9()) {
+ ltq_cgu_w32(ltq_cgu_r32(LTQ_CGU_IFCCR) & ~0x1f00000, LTQ_CGU_IFCCR);
+ ltq_cgu_w32(ltq_cgu_r32(LTQ_CGU_IFCCR) | 0xe00000, LTQ_CGU_IFCCR);
+ } else {
+ ltq_cgu_w32(ltq_cgu_r32(LTQ_CGU_IFCCR) & ~0xf00000, LTQ_CGU_IFCCR);
+ ltq_cgu_w32(ltq_cgu_r32(LTQ_CGU_IFCCR) | 0x800000, LTQ_CGU_IFCCR);
+ }
/* external or internal clock ? */
if (conf->clock) {
diff --git a/arch/mips/pci/pci-rc32434.c b/arch/mips/pci/pci-rc32434.c
index 764362ce5e40..5f3a69cebad1 100644
--- a/arch/mips/pci/pci-rc32434.c
+++ b/arch/mips/pci/pci-rc32434.c
@@ -215,7 +215,7 @@ static int __init rc32434_pci_init(void)
rc32434_pcibridge_init();
io_map_base = ioremap(rc32434_res_pci_io1.start,
- resource_size(&rcrc32434_res_pci_io1));
+ resource_size(&rc32434_res_pci_io1));
if (!io_map_base)
return -ENOMEM;
diff --git a/arch/mips/pmc-sierra/msp71xx/msp_irq.c b/arch/mips/pmc-sierra/msp71xx/msp_irq.c
index 4531c4a514bc..d3c3d81757a5 100644
--- a/arch/mips/pmc-sierra/msp71xx/msp_irq.c
+++ b/arch/mips/pmc-sierra/msp71xx/msp_irq.c
@@ -108,12 +108,14 @@ asmlinkage void plat_irq_dispatch(struct pt_regs *regs)
static struct irqaction cic_cascade_msp = {
.handler = no_action,
- .name = "MSP CIC cascade"
+ .name = "MSP CIC cascade",
+ .flags = IRQF_NO_THREAD,
};
static struct irqaction per_cascade_msp = {
.handler = no_action,
- .name = "MSP PER cascade"
+ .name = "MSP PER cascade",
+ .flags = IRQF_NO_THREAD,
};
void __init arch_init_irq(void)
diff --git a/arch/mips/pnx8550/common/int.c b/arch/mips/pnx8550/common/int.c
index 6b93c81779c1..1ebe22bdadc8 100644
--- a/arch/mips/pnx8550/common/int.c
+++ b/arch/mips/pnx8550/common/int.c
@@ -167,7 +167,7 @@ static struct irq_chip level_irq_type = {
static struct irqaction gic_action = {
.handler = no_action,
- .flags = IRQF_DISABLED,
+ .flags = IRQF_DISABLED | IRQF_NO_THREAD,
.name = "GIC",
};
diff --git a/arch/mips/sgi-ip22/ip22-int.c b/arch/mips/sgi-ip22/ip22-int.c
index b4d08e4d2ea9..f72c336ea27b 100644
--- a/arch/mips/sgi-ip22/ip22-int.c
+++ b/arch/mips/sgi-ip22/ip22-int.c
@@ -155,32 +155,32 @@ static void __irq_entry indy_buserror_irq(void)
static struct irqaction local0_cascade = {
.handler = no_action,
- .flags = IRQF_DISABLED,
+ .flags = IRQF_DISABLED | IRQF_NO_THREAD,
.name = "local0 cascade",
};
static struct irqaction local1_cascade = {
.handler = no_action,
- .flags = IRQF_DISABLED,
+ .flags = IRQF_DISABLED | IRQF_NO_THREAD,
.name = "local1 cascade",
};
static struct irqaction buserr = {
.handler = no_action,
- .flags = IRQF_DISABLED,
+ .flags = IRQF_DISABLED | IRQF_NO_THREAD,
.name = "Bus Error",
};
static struct irqaction map0_cascade = {
.handler = no_action,
- .flags = IRQF_DISABLED,
+ .flags = IRQF_DISABLED | IRQF_NO_THREAD,
.name = "mapable0 cascade",
};
#ifdef USE_LIO3_IRQ
static struct irqaction map1_cascade = {
.handler = no_action,
- .flags = IRQF_DISABLED,
+ .flags = IRQF_DISABLED | IRQF_NO_THREAD,
.name = "mapable1 cascade",
};
#define SGI_INTERRUPTS SGINT_END
diff --git a/arch/mips/sni/rm200.c b/arch/mips/sni/rm200.c
index a7e5a6d917b1..3ab5b5d25b0a 100644
--- a/arch/mips/sni/rm200.c
+++ b/arch/mips/sni/rm200.c
@@ -359,6 +359,7 @@ void sni_rm200_init_8259A(void)
static struct irqaction sni_rm200_irq2 = {
.handler = no_action,
.name = "cascade",
+ .flags = IRQF_NO_THREAD,
};
static struct resource sni_rm200_pic1_resource = {
diff --git a/arch/mips/vr41xx/common/irq.c b/arch/mips/vr41xx/common/irq.c
index 70a3b85f3757..fad2bef432cd 100644
--- a/arch/mips/vr41xx/common/irq.c
+++ b/arch/mips/vr41xx/common/irq.c
@@ -34,6 +34,7 @@ static irq_cascade_t irq_cascade[NR_IRQS] __cacheline_aligned;
static struct irqaction cascade_irqaction = {
.handler = no_action,
.name = "cascade",
+ .flags = IRQF_NO_THREAD,
};
int cascade_irq(unsigned int irq, int (*get_irq)(unsigned int))
diff --git a/arch/sparc/include/asm/pgtsrmmu.h b/arch/sparc/include/asm/pgtsrmmu.h
index 1407c07bdade..f6ae2b2b6870 100644
--- a/arch/sparc/include/asm/pgtsrmmu.h
+++ b/arch/sparc/include/asm/pgtsrmmu.h
@@ -280,7 +280,7 @@ static inline unsigned long srmmu_hwprobe(unsigned long vaddr)
return retval;
}
#else
-#define srmmu_hwprobe(addr) (srmmu_swprobe(addr, 0) & SRMMU_PTE_PMASK)
+#define srmmu_hwprobe(addr) srmmu_swprobe(addr, 0)
#endif
static inline int
diff --git a/arch/sparc/kernel/pci.c b/arch/sparc/kernel/pci.c
index 1e94f946570e..8aa0d4408586 100644
--- a/arch/sparc/kernel/pci.c
+++ b/arch/sparc/kernel/pci.c
@@ -230,7 +230,8 @@ static void pci_parse_of_addrs(struct platform_device *op,
res = &dev->resource[(i - PCI_BASE_ADDRESS_0) >> 2];
} else if (i == dev->rom_base_reg) {
res = &dev->resource[PCI_ROM_RESOURCE];
- flags |= IORESOURCE_READONLY | IORESOURCE_CACHEABLE;
+ flags |= IORESOURCE_READONLY | IORESOURCE_CACHEABLE
+ | IORESOURCE_SIZEALIGN;
} else {
printk(KERN_ERR "PCI: bad cfg reg num 0x%x\n", i);
continue;
diff --git a/arch/sparc/kernel/signal32.c b/arch/sparc/kernel/signal32.c
index 1ba95aff5d59..2caa556db86d 100644
--- a/arch/sparc/kernel/signal32.c
+++ b/arch/sparc/kernel/signal32.c
@@ -273,10 +273,7 @@ void do_sigreturn32(struct pt_regs *regs)
case 1: set.sig[0] = seta[0] + (((long)seta[1]) << 32);
}
sigdelsetmask(&set, ~_BLOCKABLE);
- spin_lock_irq(&current->sighand->siglock);
- current->blocked = set;
- recalc_sigpending();
- spin_unlock_irq(&current->sighand->siglock);
+ set_current_blocked(&set);
return;
segv:
@@ -377,10 +374,7 @@ asmlinkage void do_rt_sigreturn32(struct pt_regs *regs)
case 1: set.sig[0] = seta.sig[0] + (((long)seta.sig[1]) << 32);
}
sigdelsetmask(&set, ~_BLOCKABLE);
- spin_lock_irq(&current->sighand->siglock);
- current->blocked = set;
- recalc_sigpending();
- spin_unlock_irq(&current->sighand->siglock);
+ set_current_blocked(&set);
return;
segv:
force_sig(SIGSEGV, current);
@@ -782,6 +776,7 @@ static inline int handle_signal32(unsigned long signr, struct k_sigaction *ka,
siginfo_t *info,
sigset_t *oldset, struct pt_regs *regs)
{
+ sigset_t blocked;
int err;
if (ka->sa.sa_flags & SA_SIGINFO)
@@ -792,12 +787,10 @@ static inline int handle_signal32(unsigned long signr, struct k_sigaction *ka,
if (err)
return err;
- spin_lock_irq(&current->sighand->siglock);
- sigorsets(&current->blocked,&current->blocked,&ka->sa.sa_mask);
+ sigorsets(&blocked, &current->blocked, &ka->sa.sa_mask);
if (!(ka->sa.sa_flags & SA_NOMASK))
- sigaddset(&current->blocked,signr);
- recalc_sigpending();
- spin_unlock_irq(&current->sighand->siglock);
+ sigaddset(&blocked, signr);
+ set_current_blocked(&blocked);
tracehook_signal_handler(signr, info, ka, regs, 0);
@@ -881,7 +874,7 @@ void do_signal32(sigset_t *oldset, struct pt_regs * regs,
*/
if (current_thread_info()->status & TS_RESTORE_SIGMASK) {
current_thread_info()->status &= ~TS_RESTORE_SIGMASK;
- sigprocmask(SIG_SETMASK, &current->saved_sigmask, NULL);
+ set_current_blocked(&current->saved_sigmask);
}
}
diff --git a/arch/sparc/kernel/signal_32.c b/arch/sparc/kernel/signal_32.c
index 04ede8f04add..8ce247ac04cc 100644
--- a/arch/sparc/kernel/signal_32.c
+++ b/arch/sparc/kernel/signal_32.c
@@ -62,12 +62,13 @@ struct rt_signal_frame {
static int _sigpause_common(old_sigset_t set)
{
- set &= _BLOCKABLE;
- spin_lock_irq(&current->sighand->siglock);
+ sigset_t blocked;
+
current->saved_sigmask = current->blocked;
- siginitset(&current->blocked, set);
- recalc_sigpending();
- spin_unlock_irq(&current->sighand->siglock);
+
+ set &= _BLOCKABLE;
+ siginitset(&blocked, set);
+ set_current_blocked(&blocked);
current->state = TASK_INTERRUPTIBLE;
schedule();
@@ -139,10 +140,7 @@ asmlinkage void do_sigreturn(struct pt_regs *regs)
goto segv_and_exit;
sigdelsetmask(&set, ~_BLOCKABLE);
- spin_lock_irq(&current->sighand->siglock);
- current->blocked = set;
- recalc_sigpending();
- spin_unlock_irq(&current->sighand->siglock);
+ set_current_blocked(&set);
return;
segv_and_exit:
@@ -209,10 +207,7 @@ asmlinkage void do_rt_sigreturn(struct pt_regs *regs)
}
sigdelsetmask(&set, ~_BLOCKABLE);
- spin_lock_irq(&current->sighand->siglock);
- current->blocked = set;
- recalc_sigpending();
- spin_unlock_irq(&current->sighand->siglock);
+ set_current_blocked(&set);
return;
segv:
force_sig(SIGSEGV, current);
@@ -470,6 +465,7 @@ static inline int
handle_signal(unsigned long signr, struct k_sigaction *ka,
siginfo_t *info, sigset_t *oldset, struct pt_regs *regs)
{
+ sigset_t blocked;
int err;
if (ka->sa.sa_flags & SA_SIGINFO)
@@ -480,12 +476,10 @@ handle_signal(unsigned long signr, struct k_sigaction *ka,
if (err)
return err;
- spin_lock_irq(&current->sighand->siglock);
- sigorsets(&current->blocked,&current->blocked,&ka->sa.sa_mask);
+ sigorsets(&blocked, &current->blocked, &ka->sa.sa_mask);
if (!(ka->sa.sa_flags & SA_NOMASK))
- sigaddset(&current->blocked, signr);
- recalc_sigpending();
- spin_unlock_irq(&current->sighand->siglock);
+ sigaddset(&blocked, signr);
+ set_current_blocked(&blocked);
tracehook_signal_handler(signr, info, ka, regs, 0);
@@ -581,7 +575,7 @@ static void do_signal(struct pt_regs *regs, unsigned long orig_i0)
*/
if (test_thread_flag(TIF_RESTORE_SIGMASK)) {
clear_thread_flag(TIF_RESTORE_SIGMASK);
- sigprocmask(SIG_SETMASK, &current->saved_sigmask, NULL);
+ set_current_blocked(&current->saved_sigmask);
}
}
diff --git a/arch/sparc/kernel/signal_64.c b/arch/sparc/kernel/signal_64.c
index 47509df3b893..a2b81598d905 100644
--- a/arch/sparc/kernel/signal_64.c
+++ b/arch/sparc/kernel/signal_64.c
@@ -70,10 +70,7 @@ asmlinkage void sparc64_set_context(struct pt_regs *regs)
goto do_sigsegv;
}
sigdelsetmask(&set, ~_BLOCKABLE);
- spin_lock_irq(&current->sighand->siglock);
- current->blocked = set;
- recalc_sigpending();
- spin_unlock_irq(&current->sighand->siglock);
+ set_current_blocked(&set);
}
if (test_thread_flag(TIF_32BIT)) {
pc &= 0xffffffff;
@@ -242,12 +239,13 @@ struct rt_signal_frame {
static long _sigpause_common(old_sigset_t set)
{
- set &= _BLOCKABLE;
- spin_lock_irq(&current->sighand->siglock);
+ sigset_t blocked;
+
current->saved_sigmask = current->blocked;
- siginitset(&current->blocked, set);
- recalc_sigpending();
- spin_unlock_irq(&current->sighand->siglock);
+
+ set &= _BLOCKABLE;
+ siginitset(&blocked, set);
+ set_current_blocked(&blocked);
current->state = TASK_INTERRUPTIBLE;
schedule();
@@ -327,10 +325,7 @@ void do_rt_sigreturn(struct pt_regs *regs)
pt_regs_clear_syscall(regs);
sigdelsetmask(&set, ~_BLOCKABLE);
- spin_lock_irq(&current->sighand->siglock);
- current->blocked = set;
- recalc_sigpending();
- spin_unlock_irq(&current->sighand->siglock);
+ set_current_blocked(&set);
return;
segv:
force_sig(SIGSEGV, current);
@@ -484,18 +479,17 @@ static inline int handle_signal(unsigned long signr, struct k_sigaction *ka,
siginfo_t *info,
sigset_t *oldset, struct pt_regs *regs)
{
+ sigset_t blocked;
int err;
err = setup_rt_frame(ka, regs, signr, oldset,
(ka->sa.sa_flags & SA_SIGINFO) ? info : NULL);
if (err)
return err;
- spin_lock_irq(&current->sighand->siglock);
- sigorsets(&current->blocked,&current->blocked,&ka->sa.sa_mask);
+ sigorsets(&blocked, &current->blocked, &ka->sa.sa_mask);
if (!(ka->sa.sa_flags & SA_NOMASK))
- sigaddset(&current->blocked,signr);
- recalc_sigpending();
- spin_unlock_irq(&current->sighand->siglock);
+ sigaddset(&blocked, signr);
+ set_current_blocked(&blocked);
tracehook_signal_handler(signr, info, ka, regs, 0);
@@ -601,7 +595,7 @@ static void do_signal(struct pt_regs *regs, unsigned long orig_i0)
*/
if (current_thread_info()->status & TS_RESTORE_SIGMASK) {
current_thread_info()->status &= ~TS_RESTORE_SIGMASK;
- sigprocmask(SIG_SETMASK, &current->saved_sigmask, NULL);
+ set_current_blocked(&current->saved_sigmask);
}
}
diff --git a/arch/sparc/mm/leon_mm.c b/arch/sparc/mm/leon_mm.c
index e485a6804998..13c2169822a8 100644
--- a/arch/sparc/mm/leon_mm.c
+++ b/arch/sparc/mm/leon_mm.c
@@ -162,7 +162,7 @@ ready:
printk(KERN_INFO "swprobe: padde %x\n", paddr_calc);
if (paddr)
*paddr = paddr_calc;
- return paddrbase;
+ return pte;
}
void leon_flush_icache_all(void)
diff --git a/arch/tile/kernel/intvec_32.S b/arch/tile/kernel/intvec_32.S
index fc94607f0bd5..aecc8ed5f39b 100644
--- a/arch/tile/kernel/intvec_32.S
+++ b/arch/tile/kernel/intvec_32.S
@@ -21,7 +21,7 @@
#include <asm/ptrace.h>
#include <asm/thread_info.h>
#include <asm/irqflags.h>
-#include <linux/atomic.h>
+#include <asm/atomic_32.h>
#include <asm/asm-offsets.h>
#include <hv/hypervisor.h>
#include <arch/abi.h>
diff --git a/arch/tile/lib/atomic_asm_32.S b/arch/tile/lib/atomic_asm_32.S
index 1f75a2a56101..30638042691d 100644
--- a/arch/tile/lib/atomic_asm_32.S
+++ b/arch/tile/lib/atomic_asm_32.S
@@ -70,7 +70,7 @@
*/
#include <linux/linkage.h>
-#include <linux/atomic.h>
+#include <asm/atomic_32.h>
#include <asm/page.h>
#include <asm/processor.h>
diff --git a/arch/x86/kernel/vsyscall_64.c b/arch/x86/kernel/vsyscall_64.c
index 18ae83dd1cd7..b56c65de384d 100644
--- a/arch/x86/kernel/vsyscall_64.c
+++ b/arch/x86/kernel/vsyscall_64.c
@@ -56,7 +56,7 @@ DEFINE_VVAR(struct vsyscall_gtod_data, vsyscall_gtod_data) =
.lock = __SEQLOCK_UNLOCKED(__vsyscall_gtod_data.lock),
};
-static enum { EMULATE, NATIVE, NONE } vsyscall_mode = EMULATE;
+static enum { EMULATE, NATIVE, NONE } vsyscall_mode = NATIVE;
static int __init vsyscall_setup(char *str)
{
diff --git a/arch/x86/mm/init.c b/arch/x86/mm/init.c
index 30326443ab81..87488b93a65c 100644
--- a/arch/x86/mm/init.c
+++ b/arch/x86/mm/init.c
@@ -63,9 +63,8 @@ static void __init find_early_table_space(unsigned long end, int use_pse,
#ifdef CONFIG_X86_32
/* for fixmap */
tables += roundup(__end_of_fixed_addresses * sizeof(pte_t), PAGE_SIZE);
-
- good_end = max_pfn_mapped << PAGE_SHIFT;
#endif
+ good_end = max_pfn_mapped << PAGE_SHIFT;
base = memblock_find_in_range(start, good_end, tables, PAGE_SIZE);
if (base == MEMBLOCK_ERROR)
diff --git a/arch/x86/pci/acpi.c b/arch/x86/pci/acpi.c
index 039d91315bc5..404f21a3ff9e 100644
--- a/arch/x86/pci/acpi.c
+++ b/arch/x86/pci/acpi.c
@@ -43,6 +43,17 @@ static const struct dmi_system_id pci_use_crs_table[] __initconst = {
DMI_MATCH(DMI_PRODUCT_NAME, "ALiveSATA2-GLAN"),
},
},
+ /* https://bugzilla.kernel.org/show_bug.cgi?id=30552 */
+ /* 2006 AMD HT/VIA system with two host bridges */
+ {
+ .callback = set_use_crs,
+ .ident = "ASUS M2V-MX SE",
+ .matches = {
+ DMI_MATCH(DMI_BOARD_VENDOR, "ASUSTeK Computer INC."),
+ DMI_MATCH(DMI_BOARD_NAME, "M2V-MX SE"),
+ DMI_MATCH(DMI_BIOS_VENDOR, "American Megatrends Inc."),
+ },
+ },
{}
};
diff --git a/arch/x86/platform/mrst/mrst.c b/arch/x86/platform/mrst/mrst.c
index 58425adc22c6..fe73276e026b 100644
--- a/arch/x86/platform/mrst/mrst.c
+++ b/arch/x86/platform/mrst/mrst.c
@@ -678,38 +678,40 @@ static int __init sfi_parse_devs(struct sfi_table_header *table)
pentry = (struct sfi_device_table_entry *)sb->pentry;
for (i = 0; i < num; i++, pentry++) {
- if (pentry->irq != (u8)0xff) { /* native RTE case */
+ int irq = pentry->irq;
+
+ if (irq != (u8)0xff) { /* native RTE case */
/* these SPI2 devices are not exposed to system as PCI
* devices, but they have separate RTE entry in IOAPIC
* so we have to enable them one by one here
*/
- ioapic = mp_find_ioapic(pentry->irq);
+ ioapic = mp_find_ioapic(irq);
irq_attr.ioapic = ioapic;
- irq_attr.ioapic_pin = pentry->irq;
+ irq_attr.ioapic_pin = irq;
irq_attr.trigger = 1;
irq_attr.polarity = 1;
- io_apic_set_pci_routing(NULL, pentry->irq, &irq_attr);
+ io_apic_set_pci_routing(NULL, irq, &irq_attr);
} else
- pentry->irq = 0; /* No irq */
+ irq = 0; /* No irq */
switch (pentry->type) {
case SFI_DEV_TYPE_IPC:
/* ID as IRQ is a hack that will go away */
- pdev = platform_device_alloc(pentry->name, pentry->irq);
+ pdev = platform_device_alloc(pentry->name, irq);
if (pdev == NULL) {
pr_err("out of memory for SFI platform device '%s'.\n",
pentry->name);
continue;
}
- install_irq_resource(pdev, pentry->irq);
+ install_irq_resource(pdev, irq);
pr_debug("info[%2d]: IPC bus, name = %16.16s, "
- "irq = 0x%2x\n", i, pentry->name, pentry->irq);
+ "irq = 0x%2x\n", i, pentry->name, irq);
sfi_handle_ipc_dev(pdev);
break;
case SFI_DEV_TYPE_SPI:
memset(&spi_info, 0, sizeof(spi_info));
strncpy(spi_info.modalias, pentry->name, SFI_NAME_LEN);
- spi_info.irq = pentry->irq;
+ spi_info.irq = irq;
spi_info.bus_num = pentry->host_num;
spi_info.chip_select = pentry->addr;
spi_info.max_speed_hz = pentry->max_freq;
@@ -726,7 +728,7 @@ static int __init sfi_parse_devs(struct sfi_table_header *table)
memset(&i2c_info, 0, sizeof(i2c_info));
bus = pentry->host_num;
strncpy(i2c_info.type, pentry->name, SFI_NAME_LEN);
- i2c_info.irq = pentry->irq;
+ i2c_info.irq = irq;
i2c_info.addr = pentry->addr;
pr_debug("info[%2d]: I2C bus = %d, name = %16.16s, "
"irq = 0x%2x, addr = 0x%x\n", i, bus,
diff --git a/crypto/ghash-generic.c b/crypto/ghash-generic.c
index be4425616931..7835b8fc94db 100644
--- a/crypto/ghash-generic.c
+++ b/crypto/ghash-generic.c
@@ -67,6 +67,9 @@ static int ghash_update(struct shash_desc *desc,
struct ghash_ctx *ctx = crypto_shash_ctx(desc->tfm);
u8 *dst = dctx->buffer;
+ if (!ctx->gf128)
+ return -ENOKEY;
+
if (dctx->bytes) {
int n = min(srclen, dctx->bytes);
u8 *pos = dst + (GHASH_BLOCK_SIZE - dctx->bytes);
@@ -119,6 +122,9 @@ static int ghash_final(struct shash_desc *desc, u8 *dst)
struct ghash_ctx *ctx = crypto_shash_ctx(desc->tfm);
u8 *buf = dctx->buffer;
+ if (!ctx->gf128)
+ return -ENOKEY;
+
ghash_flush(ctx, dctx);
memcpy(dst, buf, GHASH_BLOCK_SIZE);
diff --git a/drivers/gpio/gpio-omap.c b/drivers/gpio/gpio-omap.c
index 0599854e2217..118ec12d2d5f 100644
--- a/drivers/gpio/gpio-omap.c
+++ b/drivers/gpio/gpio-omap.c
@@ -34,8 +34,8 @@ struct gpio_bank {
u16 irq;
u16 virtual_irq_start;
int method;
-#if defined(CONFIG_ARCH_OMAP16XX) || defined(CONFIG_ARCH_OMAP2PLUS)
u32 suspend_wakeup;
+#if defined(CONFIG_ARCH_OMAP16XX) || defined(CONFIG_ARCH_OMAP2PLUS)
u32 saved_wakeup;
#endif
u32 non_wakeup_gpios;
diff --git a/drivers/gpio/gpio-pca953x.c b/drivers/gpio/gpio-pca953x.c
index c43b8ff626a7..0550dcb85814 100644
--- a/drivers/gpio/gpio-pca953x.c
+++ b/drivers/gpio/gpio-pca953x.c
@@ -577,6 +577,7 @@ pca953x_get_alt_pdata(struct i2c_client *client, int *gpio_base, int *invert)
void
pca953x_get_alt_pdata(struct i2c_client *client, int *gpio_base, int *invert)
{
+ *gpio_base = -1;
}
#endif
diff --git a/drivers/gpu/drm/radeon/atom.c b/drivers/gpu/drm/radeon/atom.c
index e88c64417a8a..14cc88aaf3a7 100644
--- a/drivers/gpu/drm/radeon/atom.c
+++ b/drivers/gpu/drm/radeon/atom.c
@@ -277,7 +277,12 @@ static uint32_t atom_get_src_int(atom_exec_context *ctx, uint8_t attr,
case ATOM_ARG_FB:
idx = U8(*ptr);
(*ptr)++;
- val = gctx->scratch[((gctx->fb_base + idx) / 4)];
+ if ((gctx->fb_base + (idx * 4)) > gctx->scratch_size_bytes) {
+ DRM_ERROR("ATOM: fb read beyond scratch region: %d vs. %d\n",
+ gctx->fb_base + (idx * 4), gctx->scratch_size_bytes);
+ val = 0;
+ } else
+ val = gctx->scratch[(gctx->fb_base / 4) + idx];
if (print)
DEBUG("FB[0x%02X]", idx);
break;
@@ -531,7 +536,11 @@ static void atom_put_dst(atom_exec_context *ctx, int arg, uint8_t attr,
case ATOM_ARG_FB:
idx = U8(*ptr);
(*ptr)++;
- gctx->scratch[((gctx->fb_base + idx) / 4)] = val;
+ if ((gctx->fb_base + (idx * 4)) > gctx->scratch_size_bytes) {
+ DRM_ERROR("ATOM: fb write beyond scratch region: %d vs. %d\n",
+ gctx->fb_base + (idx * 4), gctx->scratch_size_bytes);
+ } else
+ gctx->scratch[(gctx->fb_base / 4) + idx] = val;
DEBUG("FB[0x%02X]", idx);
break;
case ATOM_ARG_PLL:
@@ -1370,11 +1379,13 @@ int atom_allocate_fb_scratch(struct atom_context *ctx)
usage_bytes = firmware_usage->asFirmwareVramReserveInfo[0].usFirmwareUseInKb * 1024;
}
+ ctx->scratch_size_bytes = 0;
if (usage_bytes == 0)
usage_bytes = 20 * 1024;
/* allocate some scratch memory */
ctx->scratch = kzalloc(usage_bytes, GFP_KERNEL);
if (!ctx->scratch)
return -ENOMEM;
+ ctx->scratch_size_bytes = usage_bytes;
return 0;
}
diff --git a/drivers/gpu/drm/radeon/atom.h b/drivers/gpu/drm/radeon/atom.h
index a589a55b223e..93cfe2086ba0 100644
--- a/drivers/gpu/drm/radeon/atom.h
+++ b/drivers/gpu/drm/radeon/atom.h
@@ -137,6 +137,7 @@ struct atom_context {
int cs_equal, cs_above;
int io_mode;
uint32_t *scratch;
+ int scratch_size_bytes;
};
extern int atom_debug;
diff --git a/drivers/gpu/drm/radeon/atombios_crtc.c b/drivers/gpu/drm/radeon/atombios_crtc.c
index c742944d3805..a515b2a09d85 100644
--- a/drivers/gpu/drm/radeon/atombios_crtc.c
+++ b/drivers/gpu/drm/radeon/atombios_crtc.c
@@ -466,7 +466,7 @@ static void atombios_crtc_program_ss(struct drm_crtc *crtc,
return;
}
args.v2.ucEnable = enable;
- if ((ss->percentage == 0) || (ss->type & ATOM_EXTERNAL_SS_MASK))
+ if ((ss->percentage == 0) || (ss->type & ATOM_EXTERNAL_SS_MASK) || ASIC_IS_DCE41(rdev))
args.v2.ucEnable = ATOM_DISABLE;
} else if (ASIC_IS_DCE3(rdev)) {
args.v1.usSpreadSpectrumPercentage = cpu_to_le16(ss->percentage);
diff --git a/drivers/gpu/drm/radeon/atombios_dp.c b/drivers/gpu/drm/radeon/atombios_dp.c
index 4da23889fea6..79e8ebc05307 100644
--- a/drivers/gpu/drm/radeon/atombios_dp.c
+++ b/drivers/gpu/drm/radeon/atombios_dp.c
@@ -129,7 +129,9 @@ static int radeon_dp_aux_native_write(struct radeon_connector *radeon_connector,
for (retry = 0; retry < 4; retry++) {
ret = radeon_process_aux_ch(dig_connector->dp_i2c_bus,
msg, msg_bytes, NULL, 0, delay, &ack);
- if (ret < 0)
+ if (ret == -EBUSY)
+ continue;
+ else if (ret < 0)
return ret;
if ((ack & AUX_NATIVE_REPLY_MASK) == AUX_NATIVE_REPLY_ACK)
return send_bytes;
@@ -160,7 +162,9 @@ static int radeon_dp_aux_native_read(struct radeon_connector *radeon_connector,
for (retry = 0; retry < 4; retry++) {
ret = radeon_process_aux_ch(dig_connector->dp_i2c_bus,
msg, msg_bytes, recv, recv_bytes, delay, &ack);
- if (ret < 0)
+ if (ret == -EBUSY)
+ continue;
+ else if (ret < 0)
return ret;
if ((ack & AUX_NATIVE_REPLY_MASK) == AUX_NATIVE_REPLY_ACK)
return ret;
@@ -236,7 +240,9 @@ int radeon_dp_i2c_aux_ch(struct i2c_adapter *adapter, int mode,
for (retry = 0; retry < 4; retry++) {
ret = radeon_process_aux_ch(auxch,
msg, msg_bytes, reply, reply_bytes, 0, &ack);
- if (ret < 0) {
+ if (ret == -EBUSY)
+ continue;
+ else if (ret < 0) {
DRM_DEBUG_KMS("aux_ch failed %d\n", ret);
return ret;
}
diff --git a/drivers/gpu/drm/radeon/radeon_connectors.c b/drivers/gpu/drm/radeon/radeon_connectors.c
index bce63fd329d4..449c3d8c6836 100644
--- a/drivers/gpu/drm/radeon/radeon_connectors.c
+++ b/drivers/gpu/drm/radeon/radeon_connectors.c
@@ -1303,23 +1303,14 @@ radeon_dp_detect(struct drm_connector *connector, bool force)
/* get the DPCD from the bridge */
radeon_dp_getdpcd(radeon_connector);
- if (radeon_hpd_sense(rdev, radeon_connector->hpd.hpd))
- ret = connector_status_connected;
- else {
- /* need to setup ddc on the bridge */
- if (encoder)
- radeon_atom_ext_encoder_setup_ddc(encoder);
+ if (encoder) {
+ /* setup ddc on the bridge */
+ radeon_atom_ext_encoder_setup_ddc(encoder);
if (radeon_ddc_probe(radeon_connector,
- radeon_connector->requires_extended_probe))
+ radeon_connector->requires_extended_probe)) /* try DDC */
ret = connector_status_connected;
- }
-
- if ((ret == connector_status_disconnected) &&
- radeon_connector->dac_load_detect) {
- struct drm_encoder *encoder = radeon_best_single_encoder(connector);
- struct drm_encoder_helper_funcs *encoder_funcs;
- if (encoder) {
- encoder_funcs = encoder->helper_private;
+ else if (radeon_connector->dac_load_detect) { /* try load detection */
+ struct drm_encoder_helper_funcs *encoder_funcs = encoder->helper_private;
ret = encoder_funcs->detect(encoder, connector);
}
}
diff --git a/drivers/gpu/drm/radeon/radeon_encoders.c b/drivers/gpu/drm/radeon/radeon_encoders.c
index 13690f3eb4a4..eb3f6dc6df83 100644
--- a/drivers/gpu/drm/radeon/radeon_encoders.c
+++ b/drivers/gpu/drm/radeon/radeon_encoders.c
@@ -1638,7 +1638,17 @@ atombios_set_encoder_crtc_source(struct drm_encoder *encoder)
break;
case 2:
args.v2.ucCRTC = radeon_crtc->crtc_id;
- args.v2.ucEncodeMode = atombios_get_encoder_mode(encoder);
+ if (radeon_encoder_is_dp_bridge(encoder)) {
+ struct drm_connector *connector = radeon_get_connector_for_encoder(encoder);
+
+ if (connector->connector_type == DRM_MODE_CONNECTOR_LVDS)
+ args.v2.ucEncodeMode = ATOM_ENCODER_MODE_LVDS;
+ else if (connector->connector_type == DRM_MODE_CONNECTOR_VGA)
+ args.v2.ucEncodeMode = ATOM_ENCODER_MODE_CRT;
+ else
+ args.v2.ucEncodeMode = atombios_get_encoder_mode(encoder);
+ } else
+ args.v2.ucEncodeMode = atombios_get_encoder_mode(encoder);
switch (radeon_encoder->encoder_id) {
case ENCODER_OBJECT_ID_INTERNAL_UNIPHY:
case ENCODER_OBJECT_ID_INTERNAL_UNIPHY1:
@@ -1755,9 +1765,17 @@ static int radeon_atom_pick_dig_encoder(struct drm_encoder *encoder)
/* DCE4/5 */
if (ASIC_IS_DCE4(rdev)) {
dig = radeon_encoder->enc_priv;
- if (ASIC_IS_DCE41(rdev))
- return radeon_crtc->crtc_id;
- else {
+ if (ASIC_IS_DCE41(rdev)) {
+ /* ontario follows DCE4 */
+ if (rdev->family == CHIP_PALM) {
+ if (dig->linkb)
+ return 1;
+ else
+ return 0;
+ } else
+ /* llano follows DCE3.2 */
+ return radeon_crtc->crtc_id;
+ } else {
switch (radeon_encoder->encoder_id) {
case ENCODER_OBJECT_ID_INTERNAL_UNIPHY:
if (dig->linkb)
diff --git a/drivers/gpu/drm/ttm/ttm_bo_util.c b/drivers/gpu/drm/ttm/ttm_bo_util.c
index ae3c6f5dd2b7..082fcaea583f 100644
--- a/drivers/gpu/drm/ttm/ttm_bo_util.c
+++ b/drivers/gpu/drm/ttm/ttm_bo_util.c
@@ -321,7 +321,7 @@ int ttm_bo_move_memcpy(struct ttm_buffer_object *bo,
struct ttm_mem_type_manager *man = &bdev->man[new_mem->mem_type];
struct ttm_tt *ttm = bo->ttm;
struct ttm_mem_reg *old_mem = &bo->mem;
- struct ttm_mem_reg old_copy;
+ struct ttm_mem_reg old_copy = *old_mem;
void *old_iomap;
void *new_iomap;
int ret;
diff --git a/drivers/hwmon/w83627ehf.c b/drivers/hwmon/w83627ehf.c
index f2b377c56a3a..36d7f270b14d 100644
--- a/drivers/hwmon/w83627ehf.c
+++ b/drivers/hwmon/w83627ehf.c
@@ -390,7 +390,7 @@ temp_from_reg(u16 reg, s16 regval)
{
if (is_word_sized(reg))
return LM75_TEMP_FROM_REG(regval);
- return regval * 1000;
+ return ((s8)regval) * 1000;
}
static inline u16
@@ -398,7 +398,8 @@ temp_to_reg(u16 reg, long temp)
{
if (is_word_sized(reg))
return LM75_TEMP_TO_REG(temp);
- return DIV_ROUND_CLOSEST(SENSORS_LIMIT(temp, -127000, 128000), 1000);
+ return (s8)DIV_ROUND_CLOSEST(SENSORS_LIMIT(temp, -127000, 128000),
+ 1000);
}
/* Some of analog inputs have internal scaling (2x), 8mV is ADC LSB */
@@ -1715,7 +1716,8 @@ static void w83627ehf_device_remove_files(struct device *dev)
}
/* Get the monitoring functions started */
-static inline void __devinit w83627ehf_init_device(struct w83627ehf_data *data)
+static inline void __devinit w83627ehf_init_device(struct w83627ehf_data *data,
+ enum kinds kind)
{
int i;
u8 tmp, diode;
@@ -1746,10 +1748,16 @@ static inline void __devinit w83627ehf_init_device(struct w83627ehf_data *data)
w83627ehf_write_value(data, W83627EHF_REG_VBAT, tmp | 0x01);
/* Get thermal sensor types */
- diode = w83627ehf_read_value(data, W83627EHF_REG_DIODE);
+ switch (kind) {
+ case w83627ehf:
+ diode = w83627ehf_read_value(data, W83627EHF_REG_DIODE);
+ break;
+ default:
+ diode = 0x70;
+ }
for (i = 0; i < 3; i++) {
if ((tmp & (0x02 << i)))
- data->temp_type[i] = (diode & (0x10 << i)) ? 1 : 2;
+ data->temp_type[i] = (diode & (0x10 << i)) ? 1 : 3;
else
data->temp_type[i] = 4; /* thermistor */
}
@@ -2016,7 +2024,7 @@ static int __devinit w83627ehf_probe(struct platform_device *pdev)
}
/* Initialize the chip */
- w83627ehf_init_device(data);
+ w83627ehf_init_device(data, sio_data->kind);
data->vrm = vid_which_vrm();
superio_enter(sio_data->sioreg);
diff --git a/drivers/ide/Kconfig b/drivers/ide/Kconfig
index 9827c5e686cb..811dbbd9306c 100644
--- a/drivers/ide/Kconfig
+++ b/drivers/ide/Kconfig
@@ -327,7 +327,7 @@ config BLK_DEV_OPTI621
select BLK_DEV_IDEPCI
help
This is a driver for the OPTi 82C621 EIDE controller.
- Please read the comments at the top of <file:drivers/ide/pci/opti621.c>.
+ Please read the comments at the top of <file:drivers/ide/opti621.c>.
config BLK_DEV_RZ1000
tristate "RZ1000 chipset bugfix/support"
@@ -365,7 +365,7 @@ config BLK_DEV_ALI15X3
normal dual channel support.
Please read the comments at the top of
- <file:drivers/ide/pci/alim15x3.c>.
+ <file:drivers/ide/alim15x3.c>.
If unsure, say N.
@@ -528,7 +528,7 @@ config BLK_DEV_NS87415
This driver adds detection and support for the NS87415 chip
(used mainly on SPARC64 and PA-RISC machines).
- Please read the comments at the top of <file:drivers/ide/pci/ns87415.c>.
+ Please read the comments at the top of <file:drivers/ide/ns87415.c>.
config BLK_DEV_PDC202XX_OLD
tristate "PROMISE PDC202{46|62|65|67} support"
@@ -547,7 +547,7 @@ config BLK_DEV_PDC202XX_OLD
for more than one card.
Please read the comments at the top of
- <file:drivers/ide/pci/pdc202xx_old.c>.
+ <file:drivers/ide/pdc202xx_old.c>.
If unsure, say N.
@@ -593,7 +593,7 @@ config BLK_DEV_SIS5513
ATA100: SiS635, SiS645, SiS650, SiS730, SiS735, SiS740,
SiS745, SiS750
- Please read the comments at the top of <file:drivers/ide/pci/sis5513.c>.
+ Please read the comments at the top of <file:drivers/ide/sis5513.c>.
config BLK_DEV_SL82C105
tristate "Winbond SL82c105 support"
@@ -616,7 +616,7 @@ config BLK_DEV_SLC90E66
look-a-like to the PIIX4 it should be a nice addition.
Please read the comments at the top of
- <file:drivers/ide/pci/slc90e66.c>.
+ <file:drivers/ide/slc90e66.c>.
config BLK_DEV_TRM290
tristate "Tekram TRM290 chipset support"
@@ -625,7 +625,7 @@ config BLK_DEV_TRM290
This driver adds support for bus master DMA transfers
using the Tekram TRM290 PCI IDE chip. Volunteers are
needed for further tweaking and development.
- Please read the comments at the top of <file:drivers/ide/pci/trm290.c>.
+ Please read the comments at the top of <file:drivers/ide/trm290.c>.
config BLK_DEV_VIA82CXXX
tristate "VIA82CXXX chipset support"
@@ -836,7 +836,7 @@ config BLK_DEV_ALI14XX
of the ALI M1439/1443/1445/1487/1489 chipsets, and permits faster
I/O speeds to be set as well.
See the files <file:Documentation/ide/ide.txt> and
- <file:drivers/ide/legacy/ali14xx.c> for more info.
+ <file:drivers/ide/ali14xx.c> for more info.
config BLK_DEV_DTC2278
tristate "DTC-2278 support"
@@ -847,7 +847,7 @@ config BLK_DEV_DTC2278
boot parameter. It enables support for the secondary IDE interface
of the DTC-2278 card, and permits faster I/O speeds to be set as
well. See the <file:Documentation/ide/ide.txt> and
- <file:drivers/ide/legacy/dtc2278.c> files for more info.
+ <file:drivers/ide/dtc2278.c> files for more info.
config BLK_DEV_HT6560B
tristate "Holtek HT6560B support"
@@ -858,7 +858,7 @@ config BLK_DEV_HT6560B
boot parameter. It enables support for the secondary IDE interface
of the Holtek card, and permits faster I/O speeds to be set as well.
See the <file:Documentation/ide/ide.txt> and
- <file:drivers/ide/legacy/ht6560b.c> files for more info.
+ <file:drivers/ide/ht6560b.c> files for more info.
config BLK_DEV_QD65XX
tristate "QDI QD65xx support"
@@ -867,7 +867,7 @@ config BLK_DEV_QD65XX
help
This driver is enabled at runtime using the "qd65xx.probe" kernel
boot parameter. It permits faster I/O speeds to be set. See the
- <file:Documentation/ide/ide.txt> and <file:drivers/ide/legacy/qd65xx.c>
+ <file:Documentation/ide/ide.txt> and <file:drivers/ide/qd65xx.c>
for more info.
config BLK_DEV_UMC8672
@@ -879,7 +879,7 @@ config BLK_DEV_UMC8672
boot parameter. It enables support for the secondary IDE interface
of the UMC-8672, and permits faster I/O speeds to be set as well.
See the files <file:Documentation/ide/ide.txt> and
- <file:drivers/ide/legacy/umc8672.c> for more info.
+ <file:drivers/ide/umc8672.c> for more info.
endif
diff --git a/drivers/input/tablet/wacom_wac.c b/drivers/input/tablet/wacom_wac.c
index 0dc97ec15c28..9dea71849f40 100644
--- a/drivers/input/tablet/wacom_wac.c
+++ b/drivers/input/tablet/wacom_wac.c
@@ -1124,11 +1124,8 @@ void wacom_setup_input_capabilities(struct input_dev *input_dev,
for (i = 0; i < 8; i++)
__set_bit(BTN_0 + i, input_dev->keybit);
- if (wacom_wac->features.type != WACOM_21UX2) {
- input_set_abs_params(input_dev, ABS_RX, 0, 4096, 0, 0);
- input_set_abs_params(input_dev, ABS_RY, 0, 4096, 0, 0);
- }
-
+ input_set_abs_params(input_dev, ABS_RX, 0, 4096, 0, 0);
+ input_set_abs_params(input_dev, ABS_RY, 0, 4096, 0, 0);
input_set_abs_params(input_dev, ABS_Z, -900, 899, 0, 0);
__set_bit(INPUT_PROP_DIRECT, input_dev->propbit);
diff --git a/drivers/iommu/intel-iommu.c b/drivers/iommu/intel-iommu.c
index c621c98c99da..a88f3cbb100b 100644
--- a/drivers/iommu/intel-iommu.c
+++ b/drivers/iommu/intel-iommu.c
@@ -306,6 +306,11 @@ static inline bool dma_pte_present(struct dma_pte *pte)
return (pte->val & 3) != 0;
}
+static inline bool dma_pte_superpage(struct dma_pte *pte)
+{
+ return (pte->val & (1 << 7));
+}
+
static inline int first_pte_in_page(struct dma_pte *pte)
{
return !((unsigned long)pte & ~VTD_PAGE_MASK);
@@ -404,6 +409,9 @@ static int dmar_forcedac;
static int intel_iommu_strict;
static int intel_iommu_superpage = 1;
+int intel_iommu_gfx_mapped;
+EXPORT_SYMBOL_GPL(intel_iommu_gfx_mapped);
+
#define DUMMY_DEVICE_DOMAIN_INFO ((struct device_domain_info *)(-1))
static DEFINE_SPINLOCK(device_domain_lock);
static LIST_HEAD(device_domain_list);
@@ -577,17 +585,18 @@ static void domain_update_iommu_snooping(struct dmar_domain *domain)
static void domain_update_iommu_superpage(struct dmar_domain *domain)
{
- int i, mask = 0xf;
+ struct dmar_drhd_unit *drhd;
+ struct intel_iommu *iommu = NULL;
+ int mask = 0xf;
if (!intel_iommu_superpage) {
domain->iommu_superpage = 0;
return;
}
- domain->iommu_superpage = 4; /* 1TiB */
-
- for_each_set_bit(i, &domain->iommu_bmp, g_num_of_iommus) {
- mask |= cap_super_page_val(g_iommus[i]->cap);
+ /* set iommu_superpage to the smallest common denominator */
+ for_each_active_iommu(iommu, drhd) {
+ mask &= cap_super_page_val(iommu->cap);
if (!mask) {
break;
}
@@ -730,29 +739,23 @@ out:
}
static struct dma_pte *pfn_to_dma_pte(struct dmar_domain *domain,
- unsigned long pfn, int large_level)
+ unsigned long pfn, int target_level)
{
int addr_width = agaw_to_width(domain->agaw) - VTD_PAGE_SHIFT;
struct dma_pte *parent, *pte = NULL;
int level = agaw_to_level(domain->agaw);
- int offset, target_level;
+ int offset;
BUG_ON(!domain->pgd);
BUG_ON(addr_width < BITS_PER_LONG && pfn >> addr_width);
parent = domain->pgd;
- /* Search pte */
- if (!large_level)
- target_level = 1;
- else
- target_level = large_level;
-
while (level > 0) {
void *tmp_page;
offset = pfn_level_offset(pfn, level);
pte = &parent[offset];
- if (!large_level && (pte->val & DMA_PTE_LARGE_PAGE))
+ if (!target_level && (dma_pte_superpage(pte) || !dma_pte_present(pte)))
break;
if (level == target_level)
break;
@@ -816,13 +819,14 @@ static struct dma_pte *dma_pfn_level_pte(struct dmar_domain *domain,
}
/* clear last level pte, a tlb flush should be followed */
-static void dma_pte_clear_range(struct dmar_domain *domain,
+static int dma_pte_clear_range(struct dmar_domain *domain,
unsigned long start_pfn,
unsigned long last_pfn)
{
int addr_width = agaw_to_width(domain->agaw) - VTD_PAGE_SHIFT;
unsigned int large_page = 1;
struct dma_pte *first_pte, *pte;
+ int order;
BUG_ON(addr_width < BITS_PER_LONG && start_pfn >> addr_width);
BUG_ON(addr_width < BITS_PER_LONG && last_pfn >> addr_width);
@@ -846,6 +850,9 @@ static void dma_pte_clear_range(struct dmar_domain *domain,
(void *)pte - (void *)first_pte);
} while (start_pfn && start_pfn <= last_pfn);
+
+ order = (large_page - 1) * 9;
+ return order;
}
/* free page table pages. last level pte should already be cleared */
@@ -3226,9 +3233,6 @@ static void __init init_no_remapping_devices(void)
}
}
- if (dmar_map_gfx)
- return;
-
for_each_drhd_unit(drhd) {
int i;
if (drhd->ignored || drhd->include_all)
@@ -3236,18 +3240,23 @@ static void __init init_no_remapping_devices(void)
for (i = 0; i < drhd->devices_cnt; i++)
if (drhd->devices[i] &&
- !IS_GFX_DEVICE(drhd->devices[i]))
+ !IS_GFX_DEVICE(drhd->devices[i]))
break;
if (i < drhd->devices_cnt)
continue;
- /* bypass IOMMU if it is just for gfx devices */
- drhd->ignored = 1;
- for (i = 0; i < drhd->devices_cnt; i++) {
- if (!drhd->devices[i])
- continue;
- drhd->devices[i]->dev.archdata.iommu = DUMMY_DEVICE_DOMAIN_INFO;
+ /* This IOMMU has *only* gfx devices. Either bypass it or
+ set the gfx_mapped flag, as appropriate */
+ if (dmar_map_gfx) {
+ intel_iommu_gfx_mapped = 1;
+ } else {
+ drhd->ignored = 1;
+ for (i = 0; i < drhd->devices_cnt; i++) {
+ if (!drhd->devices[i])
+ continue;
+ drhd->devices[i]->dev.archdata.iommu = DUMMY_DEVICE_DOMAIN_INFO;
+ }
}
}
}
@@ -3568,6 +3577,8 @@ static void domain_remove_one_dev_info(struct dmar_domain *domain,
found = 1;
}
+ spin_unlock_irqrestore(&device_domain_lock, flags);
+
if (found == 0) {
unsigned long tmp_flags;
spin_lock_irqsave(&domain->iommu_lock, tmp_flags);
@@ -3584,8 +3595,6 @@ static void domain_remove_one_dev_info(struct dmar_domain *domain,
spin_unlock_irqrestore(&iommu->lock, tmp_flags);
}
}
-
- spin_unlock_irqrestore(&device_domain_lock, flags);
}
static void vm_domain_remove_all_dev_info(struct dmar_domain *domain)
@@ -3739,6 +3748,7 @@ static int intel_iommu_domain_init(struct iommu_domain *domain)
vm_domain_exit(dmar_domain);
return -ENOMEM;
}
+ domain_update_iommu_cap(dmar_domain);
domain->priv = dmar_domain;
return 0;
@@ -3864,14 +3874,15 @@ static int intel_iommu_unmap(struct iommu_domain *domain,
{
struct dmar_domain *dmar_domain = domain->priv;
size_t size = PAGE_SIZE << gfp_order;
+ int order;
- dma_pte_clear_range(dmar_domain, iova >> VTD_PAGE_SHIFT,
+ order = dma_pte_clear_range(dmar_domain, iova >> VTD_PAGE_SHIFT,
(iova + size - 1) >> VTD_PAGE_SHIFT);
if (dmar_domain->max_addr == iova + size)
dmar_domain->max_addr = iova;
- return gfp_order;
+ return order;
}
static phys_addr_t intel_iommu_iova_to_phys(struct iommu_domain *domain,
@@ -3950,7 +3961,11 @@ static void __devinit quirk_calpella_no_shadow_gtt(struct pci_dev *dev)
if (!(ggc & GGC_MEMORY_VT_ENABLED)) {
printk(KERN_INFO "DMAR: BIOS has allocated no shadow GTT; disabling IOMMU for graphics\n");
dmar_map_gfx = 0;
- }
+ } else if (dmar_map_gfx) {
+ /* we have to ensure the gfx device is idle before we flush */
+ printk(KERN_INFO "DMAR: Disabling batched IOTLB flush on Ironlake\n");
+ intel_iommu_strict = 1;
+ }
}
DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x0040, quirk_calpella_no_shadow_gtt);
DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x0044, quirk_calpella_no_shadow_gtt);
diff --git a/drivers/md/dm-crypt.c b/drivers/md/dm-crypt.c
index 49da55c1528a..8c2a000cf3f5 100644
--- a/drivers/md/dm-crypt.c
+++ b/drivers/md/dm-crypt.c
@@ -1698,6 +1698,8 @@ static int crypt_ctr(struct dm_target *ti, unsigned int argc, char **argv)
}
ti->num_flush_requests = 1;
+ ti->discard_zeroes_data_unsupported = 1;
+
return 0;
bad:
diff --git a/drivers/md/dm-flakey.c b/drivers/md/dm-flakey.c
index 89f73ca22cfa..f84c08029b21 100644
--- a/drivers/md/dm-flakey.c
+++ b/drivers/md/dm-flakey.c
@@ -81,8 +81,10 @@ static int parse_features(struct dm_arg_set *as, struct flakey_c *fc,
* corrupt_bio_byte <Nth_byte> <direction> <value> <bio_flags>
*/
if (!strcasecmp(arg_name, "corrupt_bio_byte")) {
- if (!argc)
+ if (!argc) {
ti->error = "Feature corrupt_bio_byte requires parameters";
+ return -EINVAL;
+ }
r = dm_read_arg(_args + 1, as, &fc->corrupt_bio_byte, &ti->error);
if (r)
diff --git a/drivers/md/dm-kcopyd.c b/drivers/md/dm-kcopyd.c
index f82147029636..32ac70861d66 100644
--- a/drivers/md/dm-kcopyd.c
+++ b/drivers/md/dm-kcopyd.c
@@ -628,6 +628,7 @@ void *dm_kcopyd_prepare_callback(struct dm_kcopyd_client *kc,
job->kc = kc;
job->fn = fn;
job->context = context;
+ job->master_job = job;
atomic_inc(&kc->nr_jobs);
diff --git a/drivers/md/dm-raid.c b/drivers/md/dm-raid.c
index a002dd85db1e..86df8b2cf927 100644
--- a/drivers/md/dm-raid.c
+++ b/drivers/md/dm-raid.c
@@ -449,7 +449,7 @@ static int parse_raid_params(struct raid_set *rs, char **argv,
rs->ti->error = "write_mostly option is only valid for RAID1";
return -EINVAL;
}
- if (value > rs->md.raid_disks) {
+ if (value >= rs->md.raid_disks) {
rs->ti->error = "Invalid write_mostly drive index given";
return -EINVAL;
}
diff --git a/drivers/md/dm-table.c b/drivers/md/dm-table.c
index 986b8754bb08..bc04518e9d8b 100644
--- a/drivers/md/dm-table.c
+++ b/drivers/md/dm-table.c
@@ -1238,14 +1238,15 @@ static void dm_table_set_integrity(struct dm_table *t)
return;
template_disk = dm_table_get_integrity_disk(t, true);
- if (!template_disk &&
- blk_integrity_is_initialized(dm_disk(t->md))) {
+ if (template_disk)
+ blk_integrity_register(dm_disk(t->md),
+ blk_get_integrity(template_disk));
+ else if (blk_integrity_is_initialized(dm_disk(t->md)))
DMWARN("%s: device no longer has a valid integrity profile",
dm_device_name(t->md));
- return;
- }
- blk_integrity_register(dm_disk(t->md),
- blk_get_integrity(template_disk));
+ else
+ DMWARN("%s: unable to establish an integrity profile",
+ dm_device_name(t->md));
}
static int device_flush_capable(struct dm_target *ti, struct dm_dev *dev,
@@ -1282,6 +1283,22 @@ static bool dm_table_supports_flush(struct dm_table *t, unsigned flush)
return 0;
}
+static bool dm_table_discard_zeroes_data(struct dm_table *t)
+{
+ struct dm_target *ti;
+ unsigned i = 0;
+
+ /* Ensure that all targets supports discard_zeroes_data. */
+ while (i < dm_table_get_num_targets(t)) {
+ ti = dm_table_get_target(t, i++);
+
+ if (ti->discard_zeroes_data_unsupported)
+ return 0;
+ }
+
+ return 1;
+}
+
void dm_table_set_restrictions(struct dm_table *t, struct request_queue *q,
struct queue_limits *limits)
{
@@ -1304,6 +1321,9 @@ void dm_table_set_restrictions(struct dm_table *t, struct request_queue *q,
}
blk_queue_flush(q, flush);
+ if (!dm_table_discard_zeroes_data(t))
+ q->limits.discard_zeroes_data = 0;
+
dm_table_set_integrity(t);
/*
diff --git a/drivers/md/md.c b/drivers/md/md.c
index 5404b2295820..5c95ccb59500 100644
--- a/drivers/md/md.c
+++ b/drivers/md/md.c
@@ -61,6 +61,11 @@
static void autostart_arrays(int part);
#endif
+/* pers_list is a list of registered personalities protected
+ * by pers_lock.
+ * pers_lock does extra service to protect accesses to
+ * mddev->thread when the mutex cannot be held.
+ */
static LIST_HEAD(pers_list);
static DEFINE_SPINLOCK(pers_lock);
@@ -739,7 +744,12 @@ static void mddev_unlock(mddev_t * mddev)
} else
mutex_unlock(&mddev->reconfig_mutex);
+ /* was we've dropped the mutex we need a spinlock to
+ * make sur the thread doesn't disappear
+ */
+ spin_lock(&pers_lock);
md_wakeup_thread(mddev->thread);
+ spin_unlock(&pers_lock);
}
static mdk_rdev_t * find_rdev_nr(mddev_t *mddev, int nr)
@@ -6429,11 +6439,18 @@ mdk_thread_t *md_register_thread(void (*run) (mddev_t *), mddev_t *mddev,
return thread;
}
-void md_unregister_thread(mdk_thread_t *thread)
+void md_unregister_thread(mdk_thread_t **threadp)
{
+ mdk_thread_t *thread = *threadp;
if (!thread)
return;
dprintk("interrupting MD-thread pid %d\n", task_pid_nr(thread->tsk));
+ /* Locking ensures that mddev_unlock does not wake_up a
+ * non-existent thread
+ */
+ spin_lock(&pers_lock);
+ *threadp = NULL;
+ spin_unlock(&pers_lock);
kthread_stop(thread->tsk);
kfree(thread);
@@ -7340,8 +7357,7 @@ static void reap_sync_thread(mddev_t *mddev)
mdk_rdev_t *rdev;
/* resync has finished, collect result */
- md_unregister_thread(mddev->sync_thread);
- mddev->sync_thread = NULL;
+ md_unregister_thread(&mddev->sync_thread);
if (!test_bit(MD_RECOVERY_INTR, &mddev->recovery) &&
!test_bit(MD_RECOVERY_REQUESTED, &mddev->recovery)) {
/* success...*/
diff --git a/drivers/md/md.h b/drivers/md/md.h
index 1e586bb4452e..0a309dc29b45 100644
--- a/drivers/md/md.h
+++ b/drivers/md/md.h
@@ -560,7 +560,7 @@ extern int register_md_personality(struct mdk_personality *p);
extern int unregister_md_personality(struct mdk_personality *p);
extern mdk_thread_t * md_register_thread(void (*run) (mddev_t *mddev),
mddev_t *mddev, const char *name);
-extern void md_unregister_thread(mdk_thread_t *thread);
+extern void md_unregister_thread(mdk_thread_t **threadp);
extern void md_wakeup_thread(mdk_thread_t *thread);
extern void md_check_recovery(mddev_t *mddev);
extern void md_write_start(mddev_t *mddev, struct bio *bi);
diff --git a/drivers/md/multipath.c b/drivers/md/multipath.c
index 3535c23af288..d5b5fb300171 100644
--- a/drivers/md/multipath.c
+++ b/drivers/md/multipath.c
@@ -514,8 +514,7 @@ static int multipath_stop (mddev_t *mddev)
{
multipath_conf_t *conf = mddev->private;
- md_unregister_thread(mddev->thread);
- mddev->thread = NULL;
+ md_unregister_thread(&mddev->thread);
blk_sync_queue(mddev->queue); /* the unplug fn references 'conf'*/
mempool_destroy(conf->pool);
kfree(conf->multipaths);
diff --git a/drivers/md/raid1.c b/drivers/md/raid1.c
index f4622dd8fc59..d9587dffe533 100644
--- a/drivers/md/raid1.c
+++ b/drivers/md/raid1.c
@@ -2562,8 +2562,7 @@ static int stop(mddev_t *mddev)
raise_barrier(conf);
lower_barrier(conf);
- md_unregister_thread(mddev->thread);
- mddev->thread = NULL;
+ md_unregister_thread(&mddev->thread);
if (conf->r1bio_pool)
mempool_destroy(conf->r1bio_pool);
kfree(conf->mirrors);
diff --git a/drivers/md/raid10.c b/drivers/md/raid10.c
index d7a8468ddeab..0cd9672cf9cb 100644
--- a/drivers/md/raid10.c
+++ b/drivers/md/raid10.c
@@ -2955,7 +2955,7 @@ static int run(mddev_t *mddev)
return 0;
out_free_conf:
- md_unregister_thread(mddev->thread);
+ md_unregister_thread(&mddev->thread);
if (conf->r10bio_pool)
mempool_destroy(conf->r10bio_pool);
safe_put_page(conf->tmppage);
@@ -2973,8 +2973,7 @@ static int stop(mddev_t *mddev)
raise_barrier(conf, 0);
lower_barrier(conf);
- md_unregister_thread(mddev->thread);
- mddev->thread = NULL;
+ md_unregister_thread(&mddev->thread);
blk_sync_queue(mddev->queue); /* the unplug fn references 'conf'*/
if (conf->r10bio_pool)
mempool_destroy(conf->r10bio_pool);
diff --git a/drivers/md/raid5.c b/drivers/md/raid5.c
index 43709fa6b6df..ac5e8b57e50f 100644
--- a/drivers/md/raid5.c
+++ b/drivers/md/raid5.c
@@ -4941,8 +4941,7 @@ static int run(mddev_t *mddev)
return 0;
abort:
- md_unregister_thread(mddev->thread);
- mddev->thread = NULL;
+ md_unregister_thread(&mddev->thread);
if (conf) {
print_raid5_conf(conf);
free_conf(conf);
@@ -4956,8 +4955,7 @@ static int stop(mddev_t *mddev)
{
raid5_conf_t *conf = mddev->private;
- md_unregister_thread(mddev->thread);
- mddev->thread = NULL;
+ md_unregister_thread(&mddev->thread);
if (mddev->queue)
mddev->queue->backing_dev_info.congested_fn = NULL;
free_conf(conf);
diff --git a/drivers/media/video/v4l2-dev.c b/drivers/media/video/v4l2-dev.c
index d72156517726..a5c9ed128b97 100644
--- a/drivers/media/video/v4l2-dev.c
+++ b/drivers/media/video/v4l2-dev.c
@@ -181,7 +181,7 @@ static void v4l2_device_release(struct device *cd)
* TODO: In the long run all drivers that use v4l2_device should use the
* v4l2_device release callback. This check will then be unnecessary.
*/
- if (v4l2_dev->release == NULL)
+ if (v4l2_dev && v4l2_dev->release == NULL)
v4l2_dev = NULL;
/* Release video_device and perform other
diff --git a/drivers/net/bnx2x/bnx2x.h b/drivers/net/bnx2x/bnx2x.h
index e46df5331c55..9a7eb3b36cf3 100644
--- a/drivers/net/bnx2x/bnx2x.h
+++ b/drivers/net/bnx2x/bnx2x.h
@@ -239,13 +239,19 @@ void bnx2x_int_disable(struct bnx2x *bp);
* FUNC_N_CLID_X = N * NUM_SPECIAL_CLIENTS + FUNC_0_CLID_X
*
*/
-/* iSCSI L2 */
-#define BNX2X_ISCSI_ETH_CL_ID_IDX 1
-#define BNX2X_ISCSI_ETH_CID 49
+enum {
+ BNX2X_ISCSI_ETH_CL_ID_IDX,
+ BNX2X_FCOE_ETH_CL_ID_IDX,
+ BNX2X_MAX_CNIC_ETH_CL_ID_IDX,
+};
-/* FCoE L2 */
-#define BNX2X_FCOE_ETH_CL_ID_IDX 2
-#define BNX2X_FCOE_ETH_CID 50
+#define BNX2X_CNIC_START_ETH_CID 48
+enum {
+ /* iSCSI L2 */
+ BNX2X_ISCSI_ETH_CID = BNX2X_CNIC_START_ETH_CID,
+ /* FCoE L2 */
+ BNX2X_FCOE_ETH_CID,
+};
/** Additional rings budgeting */
#ifdef BCM_CNIC
diff --git a/drivers/net/bnx2x/bnx2x_cmn.h b/drivers/net/bnx2x/bnx2x_cmn.h
index 223bfeebc597..2dc1199239d0 100644
--- a/drivers/net/bnx2x/bnx2x_cmn.h
+++ b/drivers/net/bnx2x/bnx2x_cmn.h
@@ -1297,7 +1297,7 @@ static inline void bnx2x_init_txdata(struct bnx2x *bp,
static inline u8 bnx2x_cnic_eth_cl_id(struct bnx2x *bp, u8 cl_idx)
{
return bp->cnic_base_cl_id + cl_idx +
- (bp->pf_num >> 1) * NON_ETH_CONTEXT_USE;
+ (bp->pf_num >> 1) * BNX2X_MAX_CNIC_ETH_CL_ID_IDX;
}
static inline u8 bnx2x_cnic_fw_sb_id(struct bnx2x *bp)
diff --git a/drivers/net/bonding/bond_main.c b/drivers/net/bonding/bond_main.c
index 6d79b78cfc75..de3d351ccb6b 100644
--- a/drivers/net/bonding/bond_main.c
+++ b/drivers/net/bonding/bond_main.c
@@ -1435,6 +1435,8 @@ static rx_handler_result_t bond_handle_frame(struct sk_buff **pskb)
struct sk_buff *skb = *pskb;
struct slave *slave;
struct bonding *bond;
+ void (*recv_probe)(struct sk_buff *, struct bonding *,
+ struct slave *);
skb = skb_share_check(skb, GFP_ATOMIC);
if (unlikely(!skb))
@@ -1448,11 +1450,12 @@ static rx_handler_result_t bond_handle_frame(struct sk_buff **pskb)
if (bond->params.arp_interval)
slave->dev->last_rx = jiffies;
- if (bond->recv_probe) {
+ recv_probe = ACCESS_ONCE(bond->recv_probe);
+ if (recv_probe) {
struct sk_buff *nskb = skb_clone(skb, GFP_ATOMIC);
if (likely(nskb)) {
- bond->recv_probe(nskb, bond, slave);
+ recv_probe(nskb, bond, slave);
dev_kfree_skb(nskb);
}
}
diff --git a/drivers/net/can/mscan/mscan.c b/drivers/net/can/mscan/mscan.c
index 92feac68b66e..4cc6f44c2ba2 100644
--- a/drivers/net/can/mscan/mscan.c
+++ b/drivers/net/can/mscan/mscan.c
@@ -261,11 +261,13 @@ static netdev_tx_t mscan_start_xmit(struct sk_buff *skb, struct net_device *dev)
void __iomem *data = &regs->tx.dsr1_0;
u16 *payload = (u16 *)frame->data;
- /* It is safe to write into dsr[dlc+1] */
- for (i = 0; i < (frame->can_dlc + 1) / 2; i++) {
+ for (i = 0; i < frame->can_dlc / 2; i++) {
out_be16(data, *payload++);
data += 2 + _MSCAN_RESERVED_DSR_SIZE;
}
+ /* write remaining byte if necessary */
+ if (frame->can_dlc & 1)
+ out_8(data, frame->data[frame->can_dlc - 1]);
}
out_8(&regs->tx.dlr, frame->can_dlc);
@@ -330,10 +332,13 @@ static void mscan_get_rx_frame(struct net_device *dev, struct can_frame *frame)
void __iomem *data = &regs->rx.dsr1_0;
u16 *payload = (u16 *)frame->data;
- for (i = 0; i < (frame->can_dlc + 1) / 2; i++) {
+ for (i = 0; i < frame->can_dlc / 2; i++) {
*payload++ = in_be16(data);
data += 2 + _MSCAN_RESERVED_DSR_SIZE;
}
+ /* read remaining byte if necessary */
+ if (frame->can_dlc & 1)
+ frame->data[frame->can_dlc - 1] = in_8(data);
}
out_8(&regs->canrflg, MSCAN_RXF);
diff --git a/drivers/net/macvlan.c b/drivers/net/macvlan.c
index 05172c39a0ce..376e3e94bae0 100644
--- a/drivers/net/macvlan.c
+++ b/drivers/net/macvlan.c
@@ -239,7 +239,7 @@ static int macvlan_queue_xmit(struct sk_buff *skb, struct net_device *dev)
dest = macvlan_hash_lookup(port, eth->h_dest);
if (dest && dest->mode == MACVLAN_MODE_BRIDGE) {
/* send to lowerdev first for its network taps */
- vlan->forward(vlan->lowerdev, skb);
+ dev_forward_skb(vlan->lowerdev, skb);
return NET_XMIT_SUCCESS;
}
diff --git a/drivers/net/mlx4/en_tx.c b/drivers/net/mlx4/en_tx.c
index 6e03de034ac7..f76ab6bf3096 100644
--- a/drivers/net/mlx4/en_tx.c
+++ b/drivers/net/mlx4/en_tx.c
@@ -172,7 +172,7 @@ int mlx4_en_activate_tx_ring(struct mlx4_en_priv *priv,
memset(ring->buf, 0, ring->buf_size);
ring->qp_state = MLX4_QP_STATE_RST;
- ring->doorbell_qpn = swab32(ring->qp.qpn << 8);
+ ring->doorbell_qpn = ring->qp.qpn << 8;
mlx4_en_fill_qp_context(priv, ring->size, ring->stride, 1, 0, ring->qpn,
ring->cqn, &ring->context);
@@ -791,7 +791,7 @@ netdev_tx_t mlx4_en_xmit(struct sk_buff *skb, struct net_device *dev)
skb_orphan(skb);
if (ring->bf_enabled && desc_size <= MAX_BF && !bounce && !vlan_tag) {
- *(u32 *) (&tx_desc->ctrl.vlan_tag) |= ring->doorbell_qpn;
+ *(__be32 *) (&tx_desc->ctrl.vlan_tag) |= cpu_to_be32(ring->doorbell_qpn);
op_own |= htonl((bf_index & 0xffff) << 8);
/* Ensure new descirptor hits memory
* before setting ownership of this descriptor to HW */
@@ -812,7 +812,7 @@ netdev_tx_t mlx4_en_xmit(struct sk_buff *skb, struct net_device *dev)
wmb();
tx_desc->ctrl.owner_opcode = op_own;
wmb();
- writel(ring->doorbell_qpn, ring->bf.uar->map + MLX4_SEND_DOORBELL);
+ iowrite32be(ring->doorbell_qpn, ring->bf.uar->map + MLX4_SEND_DOORBELL);
}
/* Poll CQ here */
diff --git a/drivers/net/netconsole.c b/drivers/net/netconsole.c
index ed2a3977c6e7..e8882023576b 100644
--- a/drivers/net/netconsole.c
+++ b/drivers/net/netconsole.c
@@ -307,6 +307,11 @@ static ssize_t store_enabled(struct netconsole_target *nt,
return err;
if (enabled < 0 || enabled > 1)
return -EINVAL;
+ if (enabled == nt->enabled) {
+ printk(KERN_INFO "netconsole: network logging has already %s\n",
+ nt->enabled ? "started" : "stopped");
+ return -EINVAL;
+ }
if (enabled) { /* 1 */
diff --git a/drivers/net/pptp.c b/drivers/net/pptp.c
index eae542a7e987..89f829f5f725 100644
--- a/drivers/net/pptp.c
+++ b/drivers/net/pptp.c
@@ -285,8 +285,10 @@ static int pptp_xmit(struct ppp_channel *chan, struct sk_buff *skb)
ip_send_check(iph);
ip_local_out(skb);
+ return 1;
tx_error:
+ kfree_skb(skb);
return 1;
}
@@ -305,11 +307,18 @@ static int pptp_rcv_core(struct sock *sk, struct sk_buff *skb)
}
header = (struct pptp_gre_header *)(skb->data);
+ headersize = sizeof(*header);
/* test if acknowledgement present */
if (PPTP_GRE_IS_A(header->ver)) {
- __u32 ack = (PPTP_GRE_IS_S(header->flags)) ?
- header->ack : header->seq; /* ack in different place if S = 0 */
+ __u32 ack;
+
+ if (!pskb_may_pull(skb, headersize))
+ goto drop;
+ header = (struct pptp_gre_header *)(skb->data);
+
+ /* ack in different place if S = 0 */
+ ack = PPTP_GRE_IS_S(header->flags) ? header->ack : header->seq;
ack = ntohl(ack);
@@ -318,21 +327,18 @@ static int pptp_rcv_core(struct sock *sk, struct sk_buff *skb)
/* also handle sequence number wrap-around */
if (WRAPPED(ack, opt->ack_recv))
opt->ack_recv = ack;
+ } else {
+ headersize -= sizeof(header->ack);
}
-
/* test if payload present */
if (!PPTP_GRE_IS_S(header->flags))
goto drop;
- headersize = sizeof(*header);
payload_len = ntohs(header->payload_len);
seq = ntohl(header->seq);
- /* no ack present? */
- if (!PPTP_GRE_IS_A(header->ver))
- headersize -= sizeof(header->ack);
/* check for incomplete packet (length smaller than expected) */
- if (skb->len - headersize < payload_len)
+ if (!pskb_may_pull(skb, headersize + payload_len))
goto drop;
payload = skb->data + headersize;
diff --git a/drivers/net/r8169.c b/drivers/net/r8169.c
index c23667017922..6d657cabb951 100644
--- a/drivers/net/r8169.c
+++ b/drivers/net/r8169.c
@@ -2859,7 +2859,7 @@ static void rtl8168e_2_hw_phy_config(struct rtl8169_private *tp)
rtl_writephy(tp, 0x1f, 0x0004);
rtl_writephy(tp, 0x1f, 0x0007);
rtl_writephy(tp, 0x1e, 0x0020);
- rtl_w1w0_phy(tp, 0x06, 0x0000, 0x0100);
+ rtl_w1w0_phy(tp, 0x15, 0x0000, 0x0100);
rtl_writephy(tp, 0x1f, 0x0002);
rtl_writephy(tp, 0x1f, 0x0000);
rtl_writephy(tp, 0x0d, 0x0007);
@@ -3316,6 +3316,37 @@ static void __devinit rtl_init_mdio_ops(struct rtl8169_private *tp)
}
}
+static void rtl_wol_suspend_quirk(struct rtl8169_private *tp)
+{
+ void __iomem *ioaddr = tp->mmio_addr;
+
+ switch (tp->mac_version) {
+ case RTL_GIGA_MAC_VER_29:
+ case RTL_GIGA_MAC_VER_30:
+ case RTL_GIGA_MAC_VER_32:
+ case RTL_GIGA_MAC_VER_33:
+ case RTL_GIGA_MAC_VER_34:
+ RTL_W32(RxConfig, RTL_R32(RxConfig) |
+ AcceptBroadcast | AcceptMulticast | AcceptMyPhys);
+ break;
+ default:
+ break;
+ }
+}
+
+static bool rtl_wol_pll_power_down(struct rtl8169_private *tp)
+{
+ if (!(__rtl8169_get_wol(tp) & WAKE_ANY))
+ return false;
+
+ rtl_writephy(tp, 0x1f, 0x0000);
+ rtl_writephy(tp, MII_BMCR, 0x0000);
+
+ rtl_wol_suspend_quirk(tp);
+
+ return true;
+}
+
static void r810x_phy_power_down(struct rtl8169_private *tp)
{
rtl_writephy(tp, 0x1f, 0x0000);
@@ -3330,18 +3361,8 @@ static void r810x_phy_power_up(struct rtl8169_private *tp)
static void r810x_pll_power_down(struct rtl8169_private *tp)
{
- void __iomem *ioaddr = tp->mmio_addr;
-
- if (__rtl8169_get_wol(tp) & WAKE_ANY) {
- rtl_writephy(tp, 0x1f, 0x0000);
- rtl_writephy(tp, MII_BMCR, 0x0000);
-
- if (tp->mac_version == RTL_GIGA_MAC_VER_29 ||
- tp->mac_version == RTL_GIGA_MAC_VER_30)
- RTL_W32(RxConfig, RTL_R32(RxConfig) | AcceptBroadcast |
- AcceptMulticast | AcceptMyPhys);
+ if (rtl_wol_pll_power_down(tp))
return;
- }
r810x_phy_power_down(tp);
}
@@ -3430,17 +3451,8 @@ static void r8168_pll_power_down(struct rtl8169_private *tp)
tp->mac_version == RTL_GIGA_MAC_VER_33)
rtl_ephy_write(ioaddr, 0x19, 0xff64);
- if (__rtl8169_get_wol(tp) & WAKE_ANY) {
- rtl_writephy(tp, 0x1f, 0x0000);
- rtl_writephy(tp, MII_BMCR, 0x0000);
-
- if (tp->mac_version == RTL_GIGA_MAC_VER_32 ||
- tp->mac_version == RTL_GIGA_MAC_VER_33 ||
- tp->mac_version == RTL_GIGA_MAC_VER_34)
- RTL_W32(RxConfig, RTL_R32(RxConfig) | AcceptBroadcast |
- AcceptMulticast | AcceptMyPhys);
+ if (rtl_wol_pll_power_down(tp))
return;
- }
r8168_phy_power_down(tp);
@@ -5788,11 +5800,30 @@ static const struct dev_pm_ops rtl8169_pm_ops = {
#endif /* !CONFIG_PM */
+static void rtl_wol_shutdown_quirk(struct rtl8169_private *tp)
+{
+ void __iomem *ioaddr = tp->mmio_addr;
+
+ /* WoL fails with 8168b when the receiver is disabled. */
+ switch (tp->mac_version) {
+ case RTL_GIGA_MAC_VER_11:
+ case RTL_GIGA_MAC_VER_12:
+ case RTL_GIGA_MAC_VER_17:
+ pci_clear_master(tp->pci_dev);
+
+ RTL_W8(ChipCmd, CmdRxEnb);
+ /* PCI commit */
+ RTL_R8(ChipCmd);
+ break;
+ default:
+ break;
+ }
+}
+
static void rtl_shutdown(struct pci_dev *pdev)
{
struct net_device *dev = pci_get_drvdata(pdev);
struct rtl8169_private *tp = netdev_priv(dev);
- void __iomem *ioaddr = tp->mmio_addr;
rtl8169_net_suspend(dev);
@@ -5806,16 +5837,9 @@ static void rtl_shutdown(struct pci_dev *pdev)
spin_unlock_irq(&tp->lock);
if (system_state == SYSTEM_POWER_OFF) {
- /* WoL fails with 8168b when the receiver is disabled. */
- if ((tp->mac_version == RTL_GIGA_MAC_VER_11 ||
- tp->mac_version == RTL_GIGA_MAC_VER_12 ||
- tp->mac_version == RTL_GIGA_MAC_VER_17) &&
- (tp->features & RTL_FEATURE_WOL)) {
- pci_clear_master(pdev);
-
- RTL_W8(ChipCmd, CmdRxEnb);
- /* PCI commit */
- RTL_R8(ChipCmd);
+ if (__rtl8169_get_wol(tp) & WAKE_ANY) {
+ rtl_wol_suspend_quirk(tp);
+ rtl_wol_shutdown_quirk(tp);
}
pci_wake_from_d3(pdev, true);
diff --git a/drivers/net/smsc911x.c b/drivers/net/smsc911x.c
index b9016a30cdc5..c90ddb61cc56 100644
--- a/drivers/net/smsc911x.c
+++ b/drivers/net/smsc911x.c
@@ -26,6 +26,7 @@
* LAN9215, LAN9216, LAN9217, LAN9218
* LAN9210, LAN9211
* LAN9220, LAN9221
+ * LAN89218
*
*/
@@ -1983,6 +1984,7 @@ static int __devinit smsc911x_init(struct net_device *dev)
case 0x01170000:
case 0x01160000:
case 0x01150000:
+ case 0x218A0000:
/* LAN911[5678] family */
pdata->generation = pdata->idrev & 0x0000FFFF;
break;
diff --git a/drivers/net/tg3.c b/drivers/net/tg3.c
index 4a1374df6084..c11a2b8327f3 100644
--- a/drivers/net/tg3.c
+++ b/drivers/net/tg3.c
@@ -15577,7 +15577,7 @@ static void __devexit tg3_remove_one(struct pci_dev *pdev)
cancel_work_sync(&tp->reset_task);
- if (!tg3_flag(tp, USE_PHYLIB)) {
+ if (tg3_flag(tp, USE_PHYLIB)) {
tg3_phy_fini(tp);
tg3_mdio_fini(tp);
}
diff --git a/drivers/of/base.c b/drivers/of/base.c
index 3ff22e32b602..f7239b33d762 100644
--- a/drivers/of/base.c
+++ b/drivers/of/base.c
@@ -662,6 +662,90 @@ int of_property_read_string(struct device_node *np, const char *propname,
EXPORT_SYMBOL_GPL(of_property_read_string);
/**
+ * of_property_read_string_index - Find and read a string from a multiple
+ * strings property.
+ * @np: device node from which the property value is to be read.
+ * @propname: name of the property to be searched.
+ * @index: index of the string in the list of strings
+ * @out_string: pointer to null terminated return string, modified only if
+ * return value is 0.
+ *
+ * Search for a property in a device tree node and retrieve a null
+ * terminated string value (pointer to data, not a copy) in the list of strings
+ * contained in that property.
+ * Returns 0 on success, -EINVAL if the property does not exist, -ENODATA if
+ * property does not have a value, and -EILSEQ if the string is not
+ * null-terminated within the length of the property data.
+ *
+ * The out_string pointer is modified only if a valid string can be decoded.
+ */
+int of_property_read_string_index(struct device_node *np, const char *propname,
+ int index, const char **output)
+{
+ struct property *prop = of_find_property(np, propname, NULL);
+ int i = 0;
+ size_t l = 0, total = 0;
+ const char *p;
+
+ if (!prop)
+ return -EINVAL;
+ if (!prop->value)
+ return -ENODATA;
+ if (strnlen(prop->value, prop->length) >= prop->length)
+ return -EILSEQ;
+
+ p = prop->value;
+
+ for (i = 0; total < prop->length; total += l, p += l) {
+ l = strlen(p) + 1;
+ if ((*p != 0) && (i++ == index)) {
+ *output = p;
+ return 0;
+ }
+ }
+ return -ENODATA;
+}
+EXPORT_SYMBOL_GPL(of_property_read_string_index);
+
+
+/**
+ * of_property_count_strings - Find and return the number of strings from a
+ * multiple strings property.
+ * @np: device node from which the property value is to be read.
+ * @propname: name of the property to be searched.
+ *
+ * Search for a property in a device tree node and retrieve the number of null
+ * terminated string contain in it. Returns the number of strings on
+ * success, -EINVAL if the property does not exist, -ENODATA if property
+ * does not have a value, and -EILSEQ if the string is not null-terminated
+ * within the length of the property data.
+ */
+int of_property_count_strings(struct device_node *np, const char *propname)
+{
+ struct property *prop = of_find_property(np, propname, NULL);
+ int i = 0;
+ size_t l = 0, total = 0;
+ const char *p;
+
+ if (!prop)
+ return -EINVAL;
+ if (!prop->value)
+ return -ENODATA;
+ if (strnlen(prop->value, prop->length) >= prop->length)
+ return -EILSEQ;
+
+ p = prop->value;
+
+ for (i = 0; total < prop->length; total += l, p += l) {
+ l = strlen(p) + 1;
+ if (*p != 0)
+ i++;
+ }
+ return i;
+}
+EXPORT_SYMBOL_GPL(of_property_count_strings);
+
+/**
* of_parse_phandle - Resolve a phandle property to a device_node pointer
* @np: Pointer to device node holding phandle property
* @phandle_name: Name of property holding a phandle value
diff --git a/drivers/scsi/libsas/sas_expander.c b/drivers/scsi/libsas/sas_expander.c
index c9e3dc024bc3..16ad97df5ba6 100644
--- a/drivers/scsi/libsas/sas_expander.c
+++ b/drivers/scsi/libsas/sas_expander.c
@@ -1769,10 +1769,12 @@ static void sas_unregister_devs_sas_addr(struct domain_device *parent,
sas_disable_routing(parent, phy->attached_sas_addr);
}
memset(phy->attached_sas_addr, 0, SAS_ADDR_SIZE);
- sas_port_delete_phy(phy->port, phy->phy);
- if (phy->port->num_phys == 0)
- sas_port_delete(phy->port);
- phy->port = NULL;
+ if (phy->port) {
+ sas_port_delete_phy(phy->port, phy->phy);
+ if (phy->port->num_phys == 0)
+ sas_port_delete(phy->port);
+ phy->port = NULL;
+ }
}
static int sas_discover_bfs_by_root_level(struct domain_device *root,
diff --git a/drivers/scsi/qla2xxx/qla_os.c b/drivers/scsi/qla2xxx/qla_os.c
index 4cace3f20c04..1e69527f1e4e 100644
--- a/drivers/scsi/qla2xxx/qla_os.c
+++ b/drivers/scsi/qla2xxx/qla_os.c
@@ -1328,10 +1328,9 @@ qla2x00_abort_all_cmds(scsi_qla_host_t *vha, int res)
qla2x00_sp_compl(ha, sp);
} else {
ctx = sp->ctx;
- if (ctx->type == SRB_LOGIN_CMD ||
- ctx->type == SRB_LOGOUT_CMD) {
- ctx->u.iocb_cmd->free(sp);
- } else {
+ if (ctx->type == SRB_ELS_CMD_RPT ||
+ ctx->type == SRB_ELS_CMD_HST ||
+ ctx->type == SRB_CT_CMD) {
struct fc_bsg_job *bsg_job =
ctx->u.bsg_job;
if (bsg_job->request->msgcode
@@ -1343,6 +1342,8 @@ qla2x00_abort_all_cmds(scsi_qla_host_t *vha, int res)
kfree(sp->ctx);
mempool_free(sp,
ha->srb_mempool);
+ } else {
+ ctx->u.iocb_cmd->free(sp);
}
}
}
diff --git a/drivers/staging/octeon/ethernet-rx.c b/drivers/staging/octeon/ethernet-rx.c
index 1a7c19ae766f..8b307b428791 100644
--- a/drivers/staging/octeon/ethernet-rx.c
+++ b/drivers/staging/octeon/ethernet-rx.c
@@ -411,7 +411,8 @@ static int cvm_oct_napi_poll(struct napi_struct *napi, int budget)
skb->protocol = eth_type_trans(skb, dev);
skb->dev = dev;
- if (unlikely(work->word2.s.not_IP || work->word2.s.IP_exc || work->word2.s.L4_error))
+ if (unlikely(work->word2.s.not_IP || work->word2.s.IP_exc ||
+ work->word2.s.L4_error || !work->word2.s.tcp_or_udp))
skb->ip_summed = CHECKSUM_NONE;
else
skb->ip_summed = CHECKSUM_UNNECESSARY;
diff --git a/drivers/tty/serial/lantiq.c b/drivers/tty/serial/lantiq.c
index 58cf279ed879..bc95f52cad8b 100644
--- a/drivers/tty/serial/lantiq.c
+++ b/drivers/tty/serial/lantiq.c
@@ -478,8 +478,10 @@ lqasc_set_termios(struct uart_port *port,
spin_unlock_irqrestore(&ltq_asc_lock, flags);
/* Don't rewrite B0 */
- if (tty_termios_baud_rate(new))
+ if (tty_termios_baud_rate(new))
tty_termios_encode_baud_rate(new, baud, baud);
+
+ uart_update_timeout(port, cflag, baud);
}
static const char*
diff --git a/drivers/tty/serial/msm_serial.c b/drivers/tty/serial/msm_serial.c
index e6ba83876508..776790272454 100644
--- a/drivers/tty/serial/msm_serial.c
+++ b/drivers/tty/serial/msm_serial.c
@@ -19,6 +19,7 @@
# define SUPPORT_SYSRQ
#endif
+#include <linux/atomic.h>
#include <linux/hrtimer.h>
#include <linux/module.h>
#include <linux/io.h>
@@ -33,6 +34,8 @@
#include <linux/clk.h>
#include <linux/platform_device.h>
#include <linux/delay.h>
+#include <linux/of.h>
+#include <linux/of_device.h>
#include "msm_serial.h"
@@ -589,9 +592,8 @@ static void msm_release_port(struct uart_port *port)
iowrite32(GSBI_PROTOCOL_IDLE, msm_port->gsbi_base +
GSBI_CONTROL);
- gsbi_resource = platform_get_resource_byname(pdev,
- IORESOURCE_MEM,
- "gsbi_resource");
+ gsbi_resource = platform_get_resource(pdev,
+ IORESOURCE_MEM, 1);
if (unlikely(!gsbi_resource))
return;
@@ -612,8 +614,7 @@ static int msm_request_port(struct uart_port *port)
resource_size_t size;
int ret;
- uart_resource = platform_get_resource_byname(pdev, IORESOURCE_MEM,
- "uart_resource");
+ uart_resource = platform_get_resource(pdev, IORESOURCE_MEM, 0);
if (unlikely(!uart_resource))
return -ENXIO;
@@ -628,8 +629,7 @@ static int msm_request_port(struct uart_port *port)
goto fail_release_port;
}
- gsbi_resource = platform_get_resource_byname(pdev, IORESOURCE_MEM,
- "gsbi_resource");
+ gsbi_resource = platform_get_resource(pdev, IORESOURCE_MEM, 1);
/* Is this a GSBI-based port? */
if (gsbi_resource) {
size = resource_size(gsbi_resource);
@@ -859,6 +859,8 @@ static struct uart_driver msm_uart_driver = {
.cons = MSM_CONSOLE,
};
+static atomic_t msm_uart_next_id = ATOMIC_INIT(0);
+
static int __init msm_serial_probe(struct platform_device *pdev)
{
struct msm_port *msm_port;
@@ -866,6 +868,9 @@ static int __init msm_serial_probe(struct platform_device *pdev)
struct uart_port *port;
int irq;
+ if (pdev->id == -1)
+ pdev->id = atomic_inc_return(&msm_uart_next_id) - 1;
+
if (unlikely(pdev->id < 0 || pdev->id >= UART_NR))
return -ENXIO;
@@ -875,7 +880,7 @@ static int __init msm_serial_probe(struct platform_device *pdev)
port->dev = &pdev->dev;
msm_port = UART_TO_MSM(port);
- if (platform_get_resource_byname(pdev, IORESOURCE_MEM, "gsbi_resource"))
+ if (platform_get_resource(pdev, IORESOURCE_MEM, 1))
msm_port->is_uartdm = 1;
else
msm_port->is_uartdm = 0;
@@ -899,8 +904,7 @@ static int __init msm_serial_probe(struct platform_device *pdev)
printk(KERN_INFO "uartclk = %d\n", port->uartclk);
- resource = platform_get_resource_byname(pdev, IORESOURCE_MEM,
- "uart_resource");
+ resource = platform_get_resource(pdev, IORESOURCE_MEM, 0);
if (unlikely(!resource))
return -ENXIO;
port->mapbase = resource->start;
@@ -924,11 +928,17 @@ static int __devexit msm_serial_remove(struct platform_device *pdev)
return 0;
}
+static struct of_device_id msm_match_table[] = {
+ { .compatible = "qcom,msm-uart" },
+ {}
+};
+
static struct platform_driver msm_platform_driver = {
.remove = msm_serial_remove,
.driver = {
.name = "msm_serial",
.owner = THIS_MODULE,
+ .of_match_table = msm_match_table,
},
};
diff --git a/fs/btrfs/ioctl.c b/fs/btrfs/ioctl.c
index 538f65a79ec5..dae5dfe41ba5 100644
--- a/fs/btrfs/ioctl.c
+++ b/fs/btrfs/ioctl.c
@@ -1047,7 +1047,16 @@ int btrfs_defrag_file(struct inode *inode, struct file *file,
if (!max_to_defrag)
max_to_defrag = last_index - 1;
- while (i <= last_index && defrag_count < max_to_defrag) {
+ /*
+ * make writeback starts from i, so the defrag range can be
+ * written sequentially.
+ */
+ if (i < inode->i_mapping->writeback_index)
+ inode->i_mapping->writeback_index = i;
+
+ while (i <= last_index && defrag_count < max_to_defrag &&
+ (i < (i_size_read(inode) + PAGE_CACHE_SIZE - 1) >>
+ PAGE_CACHE_SHIFT)) {
/*
* make sure we stop running if someone unmounts
* the FS
diff --git a/fs/cifs/connect.c b/fs/cifs/connect.c
index f4af4cc37500..71beb0201970 100644
--- a/fs/cifs/connect.c
+++ b/fs/cifs/connect.c
@@ -2018,7 +2018,7 @@ cifs_get_smb_ses(struct TCP_Server_Info *server, struct smb_vol *volume_info)
warned_on_ntlm = true;
cERROR(1, "default security mechanism requested. The default "
"security mechanism will be upgraded from ntlm to "
- "ntlmv2 in kernel release 3.1");
+ "ntlmv2 in kernel release 3.2");
}
ses->overrideSecFlg = volume_info->secFlg;
diff --git a/fs/xfs/xfs_buf_item.c b/fs/xfs/xfs_buf_item.c
index cac2ecfa6746..ef43fce519a1 100644
--- a/fs/xfs/xfs_buf_item.c
+++ b/fs/xfs/xfs_buf_item.c
@@ -629,7 +629,7 @@ xfs_buf_item_push(
* the xfsbufd to get this buffer written. We have to unlock the buffer
* to allow the xfsbufd to write it, too.
*/
-STATIC void
+STATIC bool
xfs_buf_item_pushbuf(
struct xfs_log_item *lip)
{
@@ -643,6 +643,7 @@ xfs_buf_item_pushbuf(
xfs_buf_delwri_promote(bp);
xfs_buf_relse(bp);
+ return true;
}
STATIC void
diff --git a/fs/xfs/xfs_dquot_item.c b/fs/xfs/xfs_dquot_item.c
index 9e0e2fa3f2c8..bb3f71d236d2 100644
--- a/fs/xfs/xfs_dquot_item.c
+++ b/fs/xfs/xfs_dquot_item.c
@@ -183,13 +183,14 @@ xfs_qm_dqunpin_wait(
* search the buffer cache can be a time consuming thing, and AIL lock is a
* spinlock.
*/
-STATIC void
+STATIC bool
xfs_qm_dquot_logitem_pushbuf(
struct xfs_log_item *lip)
{
struct xfs_dq_logitem *qlip = DQUOT_ITEM(lip);
struct xfs_dquot *dqp = qlip->qli_dquot;
struct xfs_buf *bp;
+ bool ret = true;
ASSERT(XFS_DQ_IS_LOCKED(dqp));
@@ -201,17 +202,20 @@ xfs_qm_dquot_logitem_pushbuf(
if (completion_done(&dqp->q_flush) ||
!(lip->li_flags & XFS_LI_IN_AIL)) {
xfs_dqunlock(dqp);
- return;
+ return true;
}
bp = xfs_incore(dqp->q_mount->m_ddev_targp, qlip->qli_format.qlf_blkno,
dqp->q_mount->m_quotainfo->qi_dqchunklen, XBF_TRYLOCK);
xfs_dqunlock(dqp);
if (!bp)
- return;
+ return true;
if (XFS_BUF_ISDELAYWRITE(bp))
xfs_buf_delwri_promote(bp);
+ if (xfs_buf_ispinned(bp))
+ ret = false;
xfs_buf_relse(bp);
+ return ret;
}
/*
diff --git a/fs/xfs/xfs_inode_item.c b/fs/xfs/xfs_inode_item.c
index 588406dc6a35..836ad80d4f2b 100644
--- a/fs/xfs/xfs_inode_item.c
+++ b/fs/xfs/xfs_inode_item.c
@@ -708,13 +708,14 @@ xfs_inode_item_committed(
* marked delayed write. If that's the case, we'll promote it and that will
* allow the caller to write the buffer by triggering the xfsbufd to run.
*/
-STATIC void
+STATIC bool
xfs_inode_item_pushbuf(
struct xfs_log_item *lip)
{
struct xfs_inode_log_item *iip = INODE_ITEM(lip);
struct xfs_inode *ip = iip->ili_inode;
struct xfs_buf *bp;
+ bool ret = true;
ASSERT(xfs_isilocked(ip, XFS_ILOCK_SHARED));
@@ -725,7 +726,7 @@ xfs_inode_item_pushbuf(
if (completion_done(&ip->i_flush) ||
!(lip->li_flags & XFS_LI_IN_AIL)) {
xfs_iunlock(ip, XFS_ILOCK_SHARED);
- return;
+ return true;
}
bp = xfs_incore(ip->i_mount->m_ddev_targp, iip->ili_format.ilf_blkno,
@@ -733,10 +734,13 @@ xfs_inode_item_pushbuf(
xfs_iunlock(ip, XFS_ILOCK_SHARED);
if (!bp)
- return;
+ return true;
if (XFS_BUF_ISDELAYWRITE(bp))
xfs_buf_delwri_promote(bp);
+ if (xfs_buf_ispinned(bp))
+ ret = false;
xfs_buf_relse(bp);
+ return ret;
}
/*
diff --git a/fs/xfs/xfs_linux.h b/fs/xfs/xfs_linux.h
index 1e8a45e74c3e..828662f70d64 100644
--- a/fs/xfs/xfs_linux.h
+++ b/fs/xfs/xfs_linux.h
@@ -68,6 +68,8 @@
#include <linux/ctype.h>
#include <linux/writeback.h>
#include <linux/capability.h>
+#include <linux/kthread.h>
+#include <linux/freezer.h>
#include <linux/list_sort.h>
#include <asm/page.h>
diff --git a/fs/xfs/xfs_super.c b/fs/xfs/xfs_super.c
index 2366c54cc4fa..5cf06b85fd9d 100644
--- a/fs/xfs/xfs_super.c
+++ b/fs/xfs/xfs_super.c
@@ -1652,24 +1652,13 @@ xfs_init_workqueues(void)
*/
xfs_syncd_wq = alloc_workqueue("xfssyncd", WQ_CPU_INTENSIVE, 8);
if (!xfs_syncd_wq)
- goto out;
-
- xfs_ail_wq = alloc_workqueue("xfsail", WQ_CPU_INTENSIVE, 8);
- if (!xfs_ail_wq)
- goto out_destroy_syncd;
-
+ return -ENOMEM;
return 0;
-
-out_destroy_syncd:
- destroy_workqueue(xfs_syncd_wq);
-out:
- return -ENOMEM;
}
STATIC void
xfs_destroy_workqueues(void)
{
- destroy_workqueue(xfs_ail_wq);
destroy_workqueue(xfs_syncd_wq);
}
diff --git a/fs/xfs/xfs_trans.h b/fs/xfs/xfs_trans.h
index 06a9759b6352..53597f4db9b5 100644
--- a/fs/xfs/xfs_trans.h
+++ b/fs/xfs/xfs_trans.h
@@ -350,7 +350,7 @@ typedef struct xfs_item_ops {
void (*iop_unlock)(xfs_log_item_t *);
xfs_lsn_t (*iop_committed)(xfs_log_item_t *, xfs_lsn_t);
void (*iop_push)(xfs_log_item_t *);
- void (*iop_pushbuf)(xfs_log_item_t *);
+ bool (*iop_pushbuf)(xfs_log_item_t *);
void (*iop_committing)(xfs_log_item_t *, xfs_lsn_t);
} xfs_item_ops_t;
diff --git a/fs/xfs/xfs_trans_ail.c b/fs/xfs/xfs_trans_ail.c
index c15aa29fa169..3a1e7ca54c2d 100644
--- a/fs/xfs/xfs_trans_ail.c
+++ b/fs/xfs/xfs_trans_ail.c
@@ -28,8 +28,6 @@
#include "xfs_trans_priv.h"
#include "xfs_error.h"
-struct workqueue_struct *xfs_ail_wq; /* AIL workqueue */
-
#ifdef DEBUG
/*
* Check that the list is sorted as it should be.
@@ -356,16 +354,10 @@ xfs_ail_delete(
xfs_trans_ail_cursor_clear(ailp, lip);
}
-/*
- * xfs_ail_worker does the work of pushing on the AIL. It will requeue itself
- * to run at a later time if there is more work to do to complete the push.
- */
-STATIC void
-xfs_ail_worker(
- struct work_struct *work)
+static long
+xfsaild_push(
+ struct xfs_ail *ailp)
{
- struct xfs_ail *ailp = container_of(to_delayed_work(work),
- struct xfs_ail, xa_work);
xfs_mount_t *mp = ailp->xa_mount;
struct xfs_ail_cursor cur;
xfs_log_item_t *lip;
@@ -427,8 +419,13 @@ xfs_ail_worker(
case XFS_ITEM_PUSHBUF:
XFS_STATS_INC(xs_push_ail_pushbuf);
- IOP_PUSHBUF(lip);
- ailp->xa_last_pushed_lsn = lsn;
+
+ if (!IOP_PUSHBUF(lip)) {
+ stuck++;
+ flush_log = 1;
+ } else {
+ ailp->xa_last_pushed_lsn = lsn;
+ }
push_xfsbufd = 1;
break;
@@ -440,7 +437,6 @@ xfs_ail_worker(
case XFS_ITEM_LOCKED:
XFS_STATS_INC(xs_push_ail_locked);
- ailp->xa_last_pushed_lsn = lsn;
stuck++;
break;
@@ -501,20 +497,6 @@ out_done:
/* We're past our target or empty, so idle */
ailp->xa_last_pushed_lsn = 0;
- /*
- * We clear the XFS_AIL_PUSHING_BIT first before checking
- * whether the target has changed. If the target has changed,
- * this pushes the requeue race directly onto the result of the
- * atomic test/set bit, so we are guaranteed that either the
- * the pusher that changed the target or ourselves will requeue
- * the work (but not both).
- */
- clear_bit(XFS_AIL_PUSHING_BIT, &ailp->xa_flags);
- smp_rmb();
- if (XFS_LSN_CMP(ailp->xa_target, target) == 0 ||
- test_and_set_bit(XFS_AIL_PUSHING_BIT, &ailp->xa_flags))
- return;
-
tout = 50;
} else if (XFS_LSN_CMP(lsn, target) >= 0) {
/*
@@ -537,9 +519,30 @@ out_done:
tout = 20;
}
- /* There is more to do, requeue us. */
- queue_delayed_work(xfs_syncd_wq, &ailp->xa_work,
- msecs_to_jiffies(tout));
+ return tout;
+}
+
+static int
+xfsaild(
+ void *data)
+{
+ struct xfs_ail *ailp = data;
+ long tout = 0; /* milliseconds */
+
+ while (!kthread_should_stop()) {
+ if (tout && tout <= 20)
+ __set_current_state(TASK_KILLABLE);
+ else
+ __set_current_state(TASK_INTERRUPTIBLE);
+ schedule_timeout(tout ?
+ msecs_to_jiffies(tout) : MAX_SCHEDULE_TIMEOUT);
+
+ try_to_freeze();
+
+ tout = xfsaild_push(ailp);
+ }
+
+ return 0;
}
/*
@@ -574,8 +577,9 @@ xfs_ail_push(
*/
smp_wmb();
xfs_trans_ail_copy_lsn(ailp, &ailp->xa_target, &threshold_lsn);
- if (!test_and_set_bit(XFS_AIL_PUSHING_BIT, &ailp->xa_flags))
- queue_delayed_work(xfs_syncd_wq, &ailp->xa_work, 0);
+ smp_wmb();
+
+ wake_up_process(ailp->xa_task);
}
/*
@@ -813,9 +817,18 @@ xfs_trans_ail_init(
INIT_LIST_HEAD(&ailp->xa_ail);
INIT_LIST_HEAD(&ailp->xa_cursors);
spin_lock_init(&ailp->xa_lock);
- INIT_DELAYED_WORK(&ailp->xa_work, xfs_ail_worker);
+
+ ailp->xa_task = kthread_run(xfsaild, ailp, "xfsaild/%s",
+ ailp->xa_mount->m_fsname);
+ if (IS_ERR(ailp->xa_task))
+ goto out_free_ailp;
+
mp->m_ail = ailp;
return 0;
+
+out_free_ailp:
+ kmem_free(ailp);
+ return ENOMEM;
}
void
@@ -824,6 +837,6 @@ xfs_trans_ail_destroy(
{
struct xfs_ail *ailp = mp->m_ail;
- cancel_delayed_work_sync(&ailp->xa_work);
+ kthread_stop(ailp->xa_task);
kmem_free(ailp);
}
diff --git a/fs/xfs/xfs_trans_priv.h b/fs/xfs/xfs_trans_priv.h
index 212946b97239..22750b5e4a8f 100644
--- a/fs/xfs/xfs_trans_priv.h
+++ b/fs/xfs/xfs_trans_priv.h
@@ -64,23 +64,17 @@ struct xfs_ail_cursor {
*/
struct xfs_ail {
struct xfs_mount *xa_mount;
+ struct task_struct *xa_task;
struct list_head xa_ail;
xfs_lsn_t xa_target;
struct list_head xa_cursors;
spinlock_t xa_lock;
- struct delayed_work xa_work;
xfs_lsn_t xa_last_pushed_lsn;
- unsigned long xa_flags;
};
-#define XFS_AIL_PUSHING_BIT 0
-
/*
* From xfs_trans_ail.c
*/
-
-extern struct workqueue_struct *xfs_ail_wq; /* AIL workqueue */
-
void xfs_trans_ail_update_bulk(struct xfs_ail *ailp,
struct xfs_ail_cursor *cur,
struct xfs_log_item **log_items, int nr_items,
diff --git a/include/linux/device-mapper.h b/include/linux/device-mapper.h
index 3fa1f3d90ce0..99e3e50b5c57 100644
--- a/include/linux/device-mapper.h
+++ b/include/linux/device-mapper.h
@@ -197,6 +197,11 @@ struct dm_target {
* whether or not its underlying devices have support.
*/
unsigned discards_supported:1;
+
+ /*
+ * Set if this target does not return zeroes on discarded blocks.
+ */
+ unsigned discard_zeroes_data_unsupported:1;
};
/* Each target can link one of these into the table */
diff --git a/include/linux/of.h b/include/linux/of.h
index 9180dc5cb00b..5dfe2d5a8b5d 100644
--- a/include/linux/of.h
+++ b/include/linux/of.h
@@ -203,6 +203,11 @@ extern int of_property_read_u32_array(const struct device_node *np,
extern int of_property_read_string(struct device_node *np,
const char *propname,
const char **out_string);
+extern int of_property_read_string_index(struct device_node *np,
+ const char *propname,
+ int index, const char **output);
+extern int of_property_count_strings(struct device_node *np,
+ const char *propname);
extern int of_device_is_compatible(const struct device_node *device,
const char *);
extern int of_device_is_available(const struct device_node *device);
@@ -256,6 +261,19 @@ static inline int of_property_read_string(struct device_node *np,
return -ENOSYS;
}
+static inline int of_property_read_string_index(struct device_node *np,
+ const char *propname, int index,
+ const char **out_string)
+{
+ return -ENOSYS;
+}
+
+static inline int of_property_count_strings(struct device_node *np,
+ const char *propname)
+{
+ return -ENOSYS;
+}
+
static inline const void *of_get_property(const struct device_node *node,
const char *name,
int *lenp)
diff --git a/include/net/ip_vs.h b/include/net/ip_vs.h
index 1aaf915656f3..8fa4430f99c1 100644
--- a/include/net/ip_vs.h
+++ b/include/net/ip_vs.h
@@ -900,6 +900,7 @@ struct netns_ipvs {
volatile int sync_state;
volatile int master_syncid;
volatile int backup_syncid;
+ struct mutex sync_mutex;
/* multicast interface name */
char master_mcast_ifn[IP_VS_IFNAME_MAXLEN];
char backup_mcast_ifn[IP_VS_IFNAME_MAXLEN];
diff --git a/include/net/udplite.h b/include/net/udplite.h
index 673a024c6b2a..5f097ca7d5c5 100644
--- a/include/net/udplite.h
+++ b/include/net/udplite.h
@@ -66,40 +66,34 @@ static inline int udplite_checksum_init(struct sk_buff *skb, struct udphdr *uh)
return 0;
}
-static inline int udplite_sender_cscov(struct udp_sock *up, struct udphdr *uh)
+/* Slow-path computation of checksum. Socket is locked. */
+static inline __wsum udplite_csum_outgoing(struct sock *sk, struct sk_buff *skb)
{
+ const struct udp_sock *up = udp_sk(skb->sk);
int cscov = up->len;
+ __wsum csum = 0;
- /*
- * Sender has set `partial coverage' option on UDP-Lite socket
- */
- if (up->pcflag & UDPLITE_SEND_CC) {
+ if (up->pcflag & UDPLITE_SEND_CC) {
+ /*
+ * Sender has set `partial coverage' option on UDP-Lite socket.
+ * The special case "up->pcslen == 0" signifies full coverage.
+ */
if (up->pcslen < up->len) {
- /* up->pcslen == 0 means that full coverage is required,
- * partial coverage only if 0 < up->pcslen < up->len */
- if (0 < up->pcslen) {
- cscov = up->pcslen;
- }
- uh->len = htons(up->pcslen);
+ if (0 < up->pcslen)
+ cscov = up->pcslen;
+ udp_hdr(skb)->len = htons(up->pcslen);
}
- /*
- * NOTE: Causes for the error case `up->pcslen > up->len':
- * (i) Application error (will not be penalized).
- * (ii) Payload too big for send buffer: data is split
- * into several packets, each with its own header.
- * In this case (e.g. last segment), coverage may
- * exceed packet length.
- * Since packets with coverage length > packet length are
- * illegal, we fall back to the defaults here.
- */
+ /*
+ * NOTE: Causes for the error case `up->pcslen > up->len':
+ * (i) Application error (will not be penalized).
+ * (ii) Payload too big for send buffer: data is split
+ * into several packets, each with its own header.
+ * In this case (e.g. last segment), coverage may
+ * exceed packet length.
+ * Since packets with coverage length > packet length are
+ * illegal, we fall back to the defaults here.
+ */
}
- return cscov;
-}
-
-static inline __wsum udplite_csum_outgoing(struct sock *sk, struct sk_buff *skb)
-{
- int cscov = udplite_sender_cscov(udp_sk(sk), udp_hdr(skb));
- __wsum csum = 0;
skb->ip_summed = CHECKSUM_NONE; /* no HW support for checksumming */
@@ -115,16 +109,21 @@ static inline __wsum udplite_csum_outgoing(struct sock *sk, struct sk_buff *skb)
return csum;
}
+/* Fast-path computation of checksum. Socket may not be locked. */
static inline __wsum udplite_csum(struct sk_buff *skb)
{
- struct sock *sk = skb->sk;
- int cscov = udplite_sender_cscov(udp_sk(sk), udp_hdr(skb));
+ const struct udp_sock *up = udp_sk(skb->sk);
const int off = skb_transport_offset(skb);
- const int len = skb->len - off;
+ int len = skb->len - off;
+ if ((up->pcflag & UDPLITE_SEND_CC) && up->pcslen < len) {
+ if (0 < up->pcslen)
+ len = up->pcslen;
+ udp_hdr(skb)->len = htons(up->pcslen);
+ }
skb->ip_summed = CHECKSUM_NONE; /* no HW support for checksumming */
- return skb_checksum(skb, off, min(cscov, len), 0);
+ return skb_checksum(skb, off, len, 0);
}
extern void udplite4_register(void);
diff --git a/kernel/posix-cpu-timers.c b/kernel/posix-cpu-timers.c
index c8008dd58ef2..640ded8f5c48 100644
--- a/kernel/posix-cpu-timers.c
+++ b/kernel/posix-cpu-timers.c
@@ -274,9 +274,7 @@ void thread_group_cputimer(struct task_struct *tsk, struct task_cputime *times)
struct task_cputime sum;
unsigned long flags;
- spin_lock_irqsave(&cputimer->lock, flags);
if (!cputimer->running) {
- cputimer->running = 1;
/*
* The POSIX timer interface allows for absolute time expiry
* values through the TIMER_ABSTIME flag, therefore we have
@@ -284,8 +282,11 @@ void thread_group_cputimer(struct task_struct *tsk, struct task_cputime *times)
* it.
*/
thread_group_cputime(tsk, &sum);
+ spin_lock_irqsave(&cputimer->lock, flags);
+ cputimer->running = 1;
update_gt_cputime(&cputimer->cputime, &sum);
- }
+ } else
+ spin_lock_irqsave(&cputimer->lock, flags);
*times = cputimer->cputime;
spin_unlock_irqrestore(&cputimer->lock, flags);
}
diff --git a/kernel/sys.c b/kernel/sys.c
index 18ee1d2f6474..1dbbe695a5ef 100644
--- a/kernel/sys.c
+++ b/kernel/sys.c
@@ -1172,7 +1172,7 @@ DECLARE_RWSEM(uts_sem);
static int override_release(char __user *release, int len)
{
int ret = 0;
- char buf[len];
+ char buf[65];
if (current->personality & UNAME26) {
char *rest = UTS_RELEASE;
diff --git a/mm/migrate.c b/mm/migrate.c
index 666e4e677414..14d0a6a632f6 100644
--- a/mm/migrate.c
+++ b/mm/migrate.c
@@ -120,10 +120,10 @@ static int remove_migration_pte(struct page *new, struct vm_area_struct *vma,
ptep = pte_offset_map(pmd, addr);
- if (!is_swap_pte(*ptep)) {
- pte_unmap(ptep);
- goto out;
- }
+ /*
+ * Peek to check is_swap_pte() before taking ptlock? No, we
+ * can race mremap's move_ptes(), which skips anon_vma lock.
+ */
ptl = pte_lockptr(mm, pmd);
}
diff --git a/net/bluetooth/l2cap_sock.c b/net/bluetooth/l2cap_sock.c
index 61f1f623091d..e8292369cdcf 100644
--- a/net/bluetooth/l2cap_sock.c
+++ b/net/bluetooth/l2cap_sock.c
@@ -26,6 +26,8 @@
/* Bluetooth L2CAP sockets. */
+#include <linux/security.h>
+
#include <net/bluetooth/bluetooth.h>
#include <net/bluetooth/hci_core.h>
#include <net/bluetooth/l2cap.h>
@@ -933,6 +935,8 @@ static void l2cap_sock_init(struct sock *sk, struct sock *parent)
chan->force_reliable = pchan->force_reliable;
chan->flushable = pchan->flushable;
chan->force_active = pchan->force_active;
+
+ security_sk_clone(parent, sk);
} else {
switch (sk->sk_type) {
diff --git a/net/bluetooth/rfcomm/sock.c b/net/bluetooth/rfcomm/sock.c
index 482722bbc7a0..5417f6127323 100644
--- a/net/bluetooth/rfcomm/sock.c
+++ b/net/bluetooth/rfcomm/sock.c
@@ -42,6 +42,7 @@
#include <linux/device.h>
#include <linux/debugfs.h>
#include <linux/seq_file.h>
+#include <linux/security.h>
#include <net/sock.h>
#include <asm/system.h>
@@ -264,6 +265,8 @@ static void rfcomm_sock_init(struct sock *sk, struct sock *parent)
pi->sec_level = rfcomm_pi(parent)->sec_level;
pi->role_switch = rfcomm_pi(parent)->role_switch;
+
+ security_sk_clone(parent, sk);
} else {
pi->dlc->defer_setup = 0;
diff --git a/net/bluetooth/sco.c b/net/bluetooth/sco.c
index 8270f05e3f1f..a324b009e34b 100644
--- a/net/bluetooth/sco.c
+++ b/net/bluetooth/sco.c
@@ -41,6 +41,7 @@
#include <linux/debugfs.h>
#include <linux/seq_file.h>
#include <linux/list.h>
+#include <linux/security.h>
#include <net/sock.h>
#include <asm/system.h>
@@ -403,8 +404,10 @@ static void sco_sock_init(struct sock *sk, struct sock *parent)
{
BT_DBG("sk %p", sk);
- if (parent)
+ if (parent) {
sk->sk_type = parent->sk_type;
+ security_sk_clone(parent, sk);
+ }
}
static struct proto sco_proto = {
diff --git a/net/bridge/br_device.c b/net/bridge/br_device.c
index 32b8f9f7f79e..ff3ed6086ce1 100644
--- a/net/bridge/br_device.c
+++ b/net/bridge/br_device.c
@@ -91,7 +91,6 @@ static int br_dev_open(struct net_device *dev)
{
struct net_bridge *br = netdev_priv(dev);
- netif_carrier_off(dev);
netdev_update_features(dev);
netif_start_queue(dev);
br_stp_enable_bridge(br);
@@ -108,8 +107,6 @@ static int br_dev_stop(struct net_device *dev)
{
struct net_bridge *br = netdev_priv(dev);
- netif_carrier_off(dev);
-
br_stp_disable_bridge(br);
br_multicast_stop(br);
diff --git a/net/bridge/br_if.c b/net/bridge/br_if.c
index e73815456adf..1d420f64ff27 100644
--- a/net/bridge/br_if.c
+++ b/net/bridge/br_if.c
@@ -161,9 +161,10 @@ static void del_nbp(struct net_bridge_port *p)
call_rcu(&p->rcu, destroy_nbp_rcu);
}
-/* called with RTNL */
-static void del_br(struct net_bridge *br, struct list_head *head)
+/* Delete bridge device */
+void br_dev_delete(struct net_device *dev, struct list_head *head)
{
+ struct net_bridge *br = netdev_priv(dev);
struct net_bridge_port *p, *n;
list_for_each_entry_safe(p, n, &br->port_list, list) {
@@ -268,7 +269,7 @@ int br_del_bridge(struct net *net, const char *name)
}
else
- del_br(netdev_priv(dev), NULL);
+ br_dev_delete(dev, NULL);
rtnl_unlock();
return ret;
@@ -449,7 +450,7 @@ void __net_exit br_net_exit(struct net *net)
rtnl_lock();
for_each_netdev(net, dev)
if (dev->priv_flags & IFF_EBRIDGE)
- del_br(netdev_priv(dev), &list);
+ br_dev_delete(dev, &list);
unregister_netdevice_many(&list);
rtnl_unlock();
diff --git a/net/bridge/br_netlink.c b/net/bridge/br_netlink.c
index 5b1ed1ba9aa7..e5f9ece3c9a0 100644
--- a/net/bridge/br_netlink.c
+++ b/net/bridge/br_netlink.c
@@ -210,6 +210,7 @@ static struct rtnl_link_ops br_link_ops __read_mostly = {
.priv_size = sizeof(struct net_bridge),
.setup = br_dev_setup,
.validate = br_validate,
+ .dellink = br_dev_delete,
};
int __init br_netlink_init(void)
diff --git a/net/bridge/br_private.h b/net/bridge/br_private.h
index 78cc364997d9..857a021deea9 100644
--- a/net/bridge/br_private.h
+++ b/net/bridge/br_private.h
@@ -294,6 +294,7 @@ static inline int br_is_root_bridge(const struct net_bridge *br)
/* br_device.c */
extern void br_dev_setup(struct net_device *dev);
+extern void br_dev_delete(struct net_device *dev, struct list_head *list);
extern netdev_tx_t br_dev_xmit(struct sk_buff *skb,
struct net_device *dev);
#ifdef CONFIG_NET_POLL_CONTROLLER
diff --git a/net/core/fib_rules.c b/net/core/fib_rules.c
index 3231b468bb72..27071ee2a4e1 100644
--- a/net/core/fib_rules.c
+++ b/net/core/fib_rules.c
@@ -475,8 +475,11 @@ static int fib_nl_delrule(struct sk_buff *skb, struct nlmsghdr* nlh, void *arg)
list_del_rcu(&rule->list);
- if (rule->action == FR_ACT_GOTO)
+ if (rule->action == FR_ACT_GOTO) {
ops->nr_goto_rules--;
+ if (rtnl_dereference(rule->ctarget) == NULL)
+ ops->unresolved_rules--;
+ }
/*
* Check if this rule is a target to any of them. If so,
diff --git a/net/ipv4/tcp_input.c b/net/ipv4/tcp_input.c
index 21fab3edb92c..d73aab3fbfc0 100644
--- a/net/ipv4/tcp_input.c
+++ b/net/ipv4/tcp_input.c
@@ -1389,9 +1389,7 @@ static int tcp_shifted_skb(struct sock *sk, struct sk_buff *skb,
BUG_ON(!pcount);
- /* Tweak before seqno plays */
- if (!tcp_is_fack(tp) && tcp_is_sack(tp) && tp->lost_skb_hint &&
- !before(TCP_SKB_CB(tp->lost_skb_hint)->seq, TCP_SKB_CB(skb)->seq))
+ if (skb == tp->lost_skb_hint)
tp->lost_cnt_hint += pcount;
TCP_SKB_CB(prev)->end_seq += shifted;
diff --git a/net/ipv4/tcp_ipv4.c b/net/ipv4/tcp_ipv4.c
index c34f01513945..7963e03f1068 100644
--- a/net/ipv4/tcp_ipv4.c
+++ b/net/ipv4/tcp_ipv4.c
@@ -927,18 +927,21 @@ int tcp_v4_md5_do_add(struct sock *sk, __be32 addr,
}
sk_nocaps_add(sk, NETIF_F_GSO_MASK);
}
- if (tcp_alloc_md5sig_pool(sk) == NULL) {
+
+ md5sig = tp->md5sig_info;
+ if (md5sig->entries4 == 0 &&
+ tcp_alloc_md5sig_pool(sk) == NULL) {
kfree(newkey);
return -ENOMEM;
}
- md5sig = tp->md5sig_info;
if (md5sig->alloced4 == md5sig->entries4) {
keys = kmalloc((sizeof(*keys) *
(md5sig->entries4 + 1)), GFP_ATOMIC);
if (!keys) {
kfree(newkey);
- tcp_free_md5sig_pool();
+ if (md5sig->entries4 == 0)
+ tcp_free_md5sig_pool();
return -ENOMEM;
}
@@ -982,6 +985,7 @@ int tcp_v4_md5_do_del(struct sock *sk, __be32 addr)
kfree(tp->md5sig_info->keys4);
tp->md5sig_info->keys4 = NULL;
tp->md5sig_info->alloced4 = 0;
+ tcp_free_md5sig_pool();
} else if (tp->md5sig_info->entries4 != i) {
/* Need to do some manipulation */
memmove(&tp->md5sig_info->keys4[i],
@@ -989,7 +993,6 @@ int tcp_v4_md5_do_del(struct sock *sk, __be32 addr)
(tp->md5sig_info->entries4 - i) *
sizeof(struct tcp4_md5sig_key));
}
- tcp_free_md5sig_pool();
return 0;
}
}
diff --git a/net/ipv4/tcp_minisocks.c b/net/ipv4/tcp_minisocks.c
index d2fe4e06b472..0ce3d06dce60 100644
--- a/net/ipv4/tcp_minisocks.c
+++ b/net/ipv4/tcp_minisocks.c
@@ -328,6 +328,7 @@ void tcp_time_wait(struct sock *sk, int state, int timeo)
struct tcp_timewait_sock *tcptw = tcp_twsk((struct sock *)tw);
const int rto = (icsk->icsk_rto << 2) - (icsk->icsk_rto >> 1);
+ tw->tw_transparent = inet_sk(sk)->transparent;
tw->tw_rcv_wscale = tp->rx_opt.rcv_wscale;
tcptw->tw_rcv_nxt = tp->rcv_nxt;
tcptw->tw_snd_nxt = tp->snd_nxt;
diff --git a/net/ipv6/af_inet6.c b/net/ipv6/af_inet6.c
index 3b5669a2582d..d27c797f9f05 100644
--- a/net/ipv6/af_inet6.c
+++ b/net/ipv6/af_inet6.c
@@ -875,6 +875,7 @@ static struct sk_buff **ipv6_gro_receive(struct sk_buff **head,
skb_reset_transport_header(skb);
__skb_push(skb, skb_gro_offset(skb));
+ ops = rcu_dereference(inet6_protos[proto]);
if (!ops || !ops->gro_receive)
goto out_unlock;
diff --git a/net/ipv6/tcp_ipv6.c b/net/ipv6/tcp_ipv6.c
index 79cc6469508d..7b8fc5794352 100644
--- a/net/ipv6/tcp_ipv6.c
+++ b/net/ipv6/tcp_ipv6.c
@@ -591,7 +591,8 @@ static int tcp_v6_md5_do_add(struct sock *sk, const struct in6_addr *peer,
}
sk_nocaps_add(sk, NETIF_F_GSO_MASK);
}
- if (tcp_alloc_md5sig_pool(sk) == NULL) {
+ if (tp->md5sig_info->entries6 == 0 &&
+ tcp_alloc_md5sig_pool(sk) == NULL) {
kfree(newkey);
return -ENOMEM;
}
@@ -600,8 +601,9 @@ static int tcp_v6_md5_do_add(struct sock *sk, const struct in6_addr *peer,
(tp->md5sig_info->entries6 + 1)), GFP_ATOMIC);
if (!keys) {
- tcp_free_md5sig_pool();
kfree(newkey);
+ if (tp->md5sig_info->entries6 == 0)
+ tcp_free_md5sig_pool();
return -ENOMEM;
}
@@ -647,6 +649,7 @@ static int tcp_v6_md5_do_del(struct sock *sk, const struct in6_addr *peer)
kfree(tp->md5sig_info->keys6);
tp->md5sig_info->keys6 = NULL;
tp->md5sig_info->alloced6 = 0;
+ tcp_free_md5sig_pool();
} else {
/* shrink the database */
if (tp->md5sig_info->entries6 != i)
@@ -655,7 +658,6 @@ static int tcp_v6_md5_do_del(struct sock *sk, const struct in6_addr *peer)
(tp->md5sig_info->entries6 - i)
* sizeof (tp->md5sig_info->keys6[0]));
}
- tcp_free_md5sig_pool();
return 0;
}
}
diff --git a/net/l2tp/l2tp_core.c b/net/l2tp/l2tp_core.c
index ad4ac2601a56..34b2ddeacb67 100644
--- a/net/l2tp/l2tp_core.c
+++ b/net/l2tp/l2tp_core.c
@@ -1045,8 +1045,10 @@ int l2tp_xmit_skb(struct l2tp_session *session, struct sk_buff *skb, int hdr_len
headroom = NET_SKB_PAD + sizeof(struct iphdr) +
uhlen + hdr_len;
old_headroom = skb_headroom(skb);
- if (skb_cow_head(skb, headroom))
+ if (skb_cow_head(skb, headroom)) {
+ dev_kfree_skb(skb);
goto abort;
+ }
new_headroom = skb_headroom(skb);
skb_orphan(skb);
diff --git a/net/netfilter/ipvs/ip_vs_ctl.c b/net/netfilter/ipvs/ip_vs_ctl.c
index 2b771dc708a3..e3be48bf4dcd 100644
--- a/net/netfilter/ipvs/ip_vs_ctl.c
+++ b/net/netfilter/ipvs/ip_vs_ctl.c
@@ -2283,6 +2283,7 @@ do_ip_vs_set_ctl(struct sock *sk, int cmd, void __user *user, unsigned int len)
struct ip_vs_service *svc;
struct ip_vs_dest_user *udest_compat;
struct ip_vs_dest_user_kern udest;
+ struct netns_ipvs *ipvs = net_ipvs(net);
if (!capable(CAP_NET_ADMIN))
return -EPERM;
@@ -2303,6 +2304,24 @@ do_ip_vs_set_ctl(struct sock *sk, int cmd, void __user *user, unsigned int len)
/* increase the module use count */
ip_vs_use_count_inc();
+ /* Handle daemons since they have another lock */
+ if (cmd == IP_VS_SO_SET_STARTDAEMON ||
+ cmd == IP_VS_SO_SET_STOPDAEMON) {
+ struct ip_vs_daemon_user *dm = (struct ip_vs_daemon_user *)arg;
+
+ if (mutex_lock_interruptible(&ipvs->sync_mutex)) {
+ ret = -ERESTARTSYS;
+ goto out_dec;
+ }
+ if (cmd == IP_VS_SO_SET_STARTDAEMON)
+ ret = start_sync_thread(net, dm->state, dm->mcast_ifn,
+ dm->syncid);
+ else
+ ret = stop_sync_thread(net, dm->state);
+ mutex_unlock(&ipvs->sync_mutex);
+ goto out_dec;
+ }
+
if (mutex_lock_interruptible(&__ip_vs_mutex)) {
ret = -ERESTARTSYS;
goto out_dec;
@@ -2316,15 +2335,6 @@ do_ip_vs_set_ctl(struct sock *sk, int cmd, void __user *user, unsigned int len)
/* Set timeout values for (tcp tcpfin udp) */
ret = ip_vs_set_timeout(net, (struct ip_vs_timeout_user *)arg);
goto out_unlock;
- } else if (cmd == IP_VS_SO_SET_STARTDAEMON) {
- struct ip_vs_daemon_user *dm = (struct ip_vs_daemon_user *)arg;
- ret = start_sync_thread(net, dm->state, dm->mcast_ifn,
- dm->syncid);
- goto out_unlock;
- } else if (cmd == IP_VS_SO_SET_STOPDAEMON) {
- struct ip_vs_daemon_user *dm = (struct ip_vs_daemon_user *)arg;
- ret = stop_sync_thread(net, dm->state);
- goto out_unlock;
}
usvc_compat = (struct ip_vs_service_user *)arg;
@@ -2584,6 +2594,33 @@ do_ip_vs_get_ctl(struct sock *sk, int cmd, void __user *user, int *len)
if (copy_from_user(arg, user, copylen) != 0)
return -EFAULT;
+ /*
+ * Handle daemons first since it has its own locking
+ */
+ if (cmd == IP_VS_SO_GET_DAEMON) {
+ struct ip_vs_daemon_user d[2];
+
+ memset(&d, 0, sizeof(d));
+ if (mutex_lock_interruptible(&ipvs->sync_mutex))
+ return -ERESTARTSYS;
+
+ if (ipvs->sync_state & IP_VS_STATE_MASTER) {
+ d[0].state = IP_VS_STATE_MASTER;
+ strlcpy(d[0].mcast_ifn, ipvs->master_mcast_ifn,
+ sizeof(d[0].mcast_ifn));
+ d[0].syncid = ipvs->master_syncid;
+ }
+ if (ipvs->sync_state & IP_VS_STATE_BACKUP) {
+ d[1].state = IP_VS_STATE_BACKUP;
+ strlcpy(d[1].mcast_ifn, ipvs->backup_mcast_ifn,
+ sizeof(d[1].mcast_ifn));
+ d[1].syncid = ipvs->backup_syncid;
+ }
+ if (copy_to_user(user, &d, sizeof(d)) != 0)
+ ret = -EFAULT;
+ mutex_unlock(&ipvs->sync_mutex);
+ return ret;
+ }
if (mutex_lock_interruptible(&__ip_vs_mutex))
return -ERESTARTSYS;
@@ -2681,28 +2718,6 @@ do_ip_vs_get_ctl(struct sock *sk, int cmd, void __user *user, int *len)
}
break;
- case IP_VS_SO_GET_DAEMON:
- {
- struct ip_vs_daemon_user d[2];
-
- memset(&d, 0, sizeof(d));
- if (ipvs->sync_state & IP_VS_STATE_MASTER) {
- d[0].state = IP_VS_STATE_MASTER;
- strlcpy(d[0].mcast_ifn, ipvs->master_mcast_ifn,
- sizeof(d[0].mcast_ifn));
- d[0].syncid = ipvs->master_syncid;
- }
- if (ipvs->sync_state & IP_VS_STATE_BACKUP) {
- d[1].state = IP_VS_STATE_BACKUP;
- strlcpy(d[1].mcast_ifn, ipvs->backup_mcast_ifn,
- sizeof(d[1].mcast_ifn));
- d[1].syncid = ipvs->backup_syncid;
- }
- if (copy_to_user(user, &d, sizeof(d)) != 0)
- ret = -EFAULT;
- }
- break;
-
default:
ret = -EINVAL;
}
@@ -3205,7 +3220,7 @@ static int ip_vs_genl_dump_daemons(struct sk_buff *skb,
struct net *net = skb_sknet(skb);
struct netns_ipvs *ipvs = net_ipvs(net);
- mutex_lock(&__ip_vs_mutex);
+ mutex_lock(&ipvs->sync_mutex);
if ((ipvs->sync_state & IP_VS_STATE_MASTER) && !cb->args[0]) {
if (ip_vs_genl_dump_daemon(skb, IP_VS_STATE_MASTER,
ipvs->master_mcast_ifn,
@@ -3225,7 +3240,7 @@ static int ip_vs_genl_dump_daemons(struct sk_buff *skb,
}
nla_put_failure:
- mutex_unlock(&__ip_vs_mutex);
+ mutex_unlock(&ipvs->sync_mutex);
return skb->len;
}
@@ -3271,13 +3286,9 @@ static int ip_vs_genl_set_config(struct net *net, struct nlattr **attrs)
return ip_vs_set_timeout(net, &t);
}
-static int ip_vs_genl_set_cmd(struct sk_buff *skb, struct genl_info *info)
+static int ip_vs_genl_set_daemon(struct sk_buff *skb, struct genl_info *info)
{
- struct ip_vs_service *svc = NULL;
- struct ip_vs_service_user_kern usvc;
- struct ip_vs_dest_user_kern udest;
int ret = 0, cmd;
- int need_full_svc = 0, need_full_dest = 0;
struct net *net;
struct netns_ipvs *ipvs;
@@ -3285,19 +3296,10 @@ static int ip_vs_genl_set_cmd(struct sk_buff *skb, struct genl_info *info)
ipvs = net_ipvs(net);
cmd = info->genlhdr->cmd;
- mutex_lock(&__ip_vs_mutex);
-
- if (cmd == IPVS_CMD_FLUSH) {
- ret = ip_vs_flush(net);
- goto out;
- } else if (cmd == IPVS_CMD_SET_CONFIG) {
- ret = ip_vs_genl_set_config(net, info->attrs);
- goto out;
- } else if (cmd == IPVS_CMD_NEW_DAEMON ||
- cmd == IPVS_CMD_DEL_DAEMON) {
-
+ if (cmd == IPVS_CMD_NEW_DAEMON || cmd == IPVS_CMD_DEL_DAEMON) {
struct nlattr *daemon_attrs[IPVS_DAEMON_ATTR_MAX + 1];
+ mutex_lock(&ipvs->sync_mutex);
if (!info->attrs[IPVS_CMD_ATTR_DAEMON] ||
nla_parse_nested(daemon_attrs, IPVS_DAEMON_ATTR_MAX,
info->attrs[IPVS_CMD_ATTR_DAEMON],
@@ -3310,6 +3312,33 @@ static int ip_vs_genl_set_cmd(struct sk_buff *skb, struct genl_info *info)
ret = ip_vs_genl_new_daemon(net, daemon_attrs);
else
ret = ip_vs_genl_del_daemon(net, daemon_attrs);
+out:
+ mutex_unlock(&ipvs->sync_mutex);
+ }
+ return ret;
+}
+
+static int ip_vs_genl_set_cmd(struct sk_buff *skb, struct genl_info *info)
+{
+ struct ip_vs_service *svc = NULL;
+ struct ip_vs_service_user_kern usvc;
+ struct ip_vs_dest_user_kern udest;
+ int ret = 0, cmd;
+ int need_full_svc = 0, need_full_dest = 0;
+ struct net *net;
+ struct netns_ipvs *ipvs;
+
+ net = skb_sknet(skb);
+ ipvs = net_ipvs(net);
+ cmd = info->genlhdr->cmd;
+
+ mutex_lock(&__ip_vs_mutex);
+
+ if (cmd == IPVS_CMD_FLUSH) {
+ ret = ip_vs_flush(net);
+ goto out;
+ } else if (cmd == IPVS_CMD_SET_CONFIG) {
+ ret = ip_vs_genl_set_config(net, info->attrs);
goto out;
} else if (cmd == IPVS_CMD_ZERO &&
!info->attrs[IPVS_CMD_ATTR_SERVICE]) {
@@ -3536,13 +3565,13 @@ static struct genl_ops ip_vs_genl_ops[] __read_mostly = {
.cmd = IPVS_CMD_NEW_DAEMON,
.flags = GENL_ADMIN_PERM,
.policy = ip_vs_cmd_policy,
- .doit = ip_vs_genl_set_cmd,
+ .doit = ip_vs_genl_set_daemon,
},
{
.cmd = IPVS_CMD_DEL_DAEMON,
.flags = GENL_ADMIN_PERM,
.policy = ip_vs_cmd_policy,
- .doit = ip_vs_genl_set_cmd,
+ .doit = ip_vs_genl_set_daemon,
},
{
.cmd = IPVS_CMD_GET_DAEMON,
@@ -3679,7 +3708,7 @@ int __net_init ip_vs_control_net_init(struct net *net)
int idx;
struct netns_ipvs *ipvs = net_ipvs(net);
- ipvs->rs_lock = __RW_LOCK_UNLOCKED(ipvs->rs_lock);
+ rwlock_init(&ipvs->rs_lock);
/* Initialize rs_table */
for (idx = 0; idx < IP_VS_RTAB_SIZE; idx++)
diff --git a/net/netfilter/ipvs/ip_vs_sync.c b/net/netfilter/ipvs/ip_vs_sync.c
index 7ee7215b8ba0..3cdd479f9b5d 100644
--- a/net/netfilter/ipvs/ip_vs_sync.c
+++ b/net/netfilter/ipvs/ip_vs_sync.c
@@ -61,6 +61,7 @@
#define SYNC_PROTO_VER 1 /* Protocol version in header */
+static struct lock_class_key __ipvs_sync_key;
/*
* IPVS sync connection entry
* Version 0, i.e. original version.
@@ -1545,6 +1546,7 @@ int start_sync_thread(struct net *net, int state, char *mcast_ifn, __u8 syncid)
IP_VS_DBG(7, "Each ip_vs_sync_conn entry needs %Zd bytes\n",
sizeof(struct ip_vs_sync_conn_v0));
+
if (state == IP_VS_STATE_MASTER) {
if (ipvs->master_thread)
return -EEXIST;
@@ -1667,6 +1669,7 @@ int __net_init ip_vs_sync_net_init(struct net *net)
{
struct netns_ipvs *ipvs = net_ipvs(net);
+ __mutex_init(&ipvs->sync_mutex, "ipvs->sync_mutex", &__ipvs_sync_key);
INIT_LIST_HEAD(&ipvs->sync_queue);
spin_lock_init(&ipvs->sync_lock);
spin_lock_init(&ipvs->sync_buff_lock);
@@ -1680,7 +1683,9 @@ int __net_init ip_vs_sync_net_init(struct net *net)
void ip_vs_sync_net_cleanup(struct net *net)
{
int retc;
+ struct netns_ipvs *ipvs = net_ipvs(net);
+ mutex_lock(&ipvs->sync_mutex);
retc = stop_sync_thread(net, IP_VS_STATE_MASTER);
if (retc && retc != -ESRCH)
pr_err("Failed to stop Master Daemon\n");
@@ -1688,4 +1693,5 @@ void ip_vs_sync_net_cleanup(struct net *net)
retc = stop_sync_thread(net, IP_VS_STATE_BACKUP);
if (retc && retc != -ESRCH)
pr_err("Failed to stop Backup Daemon\n");
+ mutex_unlock(&ipvs->sync_mutex);
}
diff --git a/net/netfilter/nf_conntrack_proto_gre.c b/net/netfilter/nf_conntrack_proto_gre.c
index cf616e55ca41..d69facdd9a7a 100644
--- a/net/netfilter/nf_conntrack_proto_gre.c
+++ b/net/netfilter/nf_conntrack_proto_gre.c
@@ -241,8 +241,8 @@ static int gre_packet(struct nf_conn *ct,
nf_ct_refresh_acct(ct, ctinfo, skb,
ct->proto.gre.stream_timeout);
/* Also, more likely to be important, and not a probe. */
- set_bit(IPS_ASSURED_BIT, &ct->status);
- nf_conntrack_event_cache(IPCT_ASSURED, ct);
+ if (!test_and_set_bit(IPS_ASSURED_BIT, &ct->status))
+ nf_conntrack_event_cache(IPCT_ASSURED, ct);
} else
nf_ct_refresh_acct(ct, ctinfo, skb,
ct->proto.gre.timeout);
diff --git a/net/x25/af_x25.c b/net/x25/af_x25.c
index d30615419b4d..5f03e4ea65bf 100644
--- a/net/x25/af_x25.c
+++ b/net/x25/af_x25.c
@@ -91,7 +91,7 @@ int x25_parse_address_block(struct sk_buff *skb,
int needed;
int rc;
- if (skb->len < 1) {
+ if (!pskb_may_pull(skb, 1)) {
/* packet has no address block */
rc = 0;
goto empty;
@@ -100,7 +100,7 @@ int x25_parse_address_block(struct sk_buff *skb,
len = *skb->data;
needed = 1 + (len >> 4) + (len & 0x0f);
- if (skb->len < needed) {
+ if (!pskb_may_pull(skb, needed)) {
/* packet is too short to hold the addresses it claims
to hold */
rc = -1;
@@ -295,7 +295,8 @@ static struct sock *x25_find_listener(struct x25_address *addr,
* Found a listening socket, now check the incoming
* call user data vs this sockets call user data
*/
- if(skb->len > 0 && x25_sk(s)->cudmatchlength > 0) {
+ if (x25_sk(s)->cudmatchlength > 0 &&
+ skb->len >= x25_sk(s)->cudmatchlength) {
if((memcmp(x25_sk(s)->calluserdata.cuddata,
skb->data,
x25_sk(s)->cudmatchlength)) == 0) {
@@ -951,14 +952,27 @@ int x25_rx_call_request(struct sk_buff *skb, struct x25_neigh *nb,
*
* Facilities length is mandatory in call request packets
*/
- if (skb->len < 1)
+ if (!pskb_may_pull(skb, 1))
goto out_clear_request;
len = skb->data[0] + 1;
- if (skb->len < len)
+ if (!pskb_may_pull(skb, len))
goto out_clear_request;
skb_pull(skb,len);
/*
+ * Ensure that the amount of call user data is valid.
+ */
+ if (skb->len > X25_MAX_CUD_LEN)
+ goto out_clear_request;
+
+ /*
+ * Get all the call user data so it can be used in
+ * x25_find_listener and skb_copy_from_linear_data up ahead.
+ */
+ if (!pskb_may_pull(skb, skb->len))
+ goto out_clear_request;
+
+ /*
* Find a listener for the particular address/cud pair.
*/
sk = x25_find_listener(&source_addr,skb);
@@ -1166,6 +1180,9 @@ static int x25_sendmsg(struct kiocb *iocb, struct socket *sock,
* byte of the user data is the logical value of the Q Bit.
*/
if (test_bit(X25_Q_BIT_FLAG, &x25->flags)) {
+ if (!pskb_may_pull(skb, 1))
+ goto out_kfree_skb;
+
qbit = skb->data[0];
skb_pull(skb, 1);
}
@@ -1244,7 +1261,9 @@ static int x25_recvmsg(struct kiocb *iocb, struct socket *sock,
struct x25_sock *x25 = x25_sk(sk);
struct sockaddr_x25 *sx25 = (struct sockaddr_x25 *)msg->msg_name;
size_t copied;
- int qbit;
+ int qbit, header_len = x25->neighbour->extended ?
+ X25_EXT_MIN_LEN : X25_STD_MIN_LEN;
+
struct sk_buff *skb;
unsigned char *asmptr;
int rc = -ENOTCONN;
@@ -1265,6 +1284,9 @@ static int x25_recvmsg(struct kiocb *iocb, struct socket *sock,
skb = skb_dequeue(&x25->interrupt_in_queue);
+ if (!pskb_may_pull(skb, X25_STD_MIN_LEN))
+ goto out_free_dgram;
+
skb_pull(skb, X25_STD_MIN_LEN);
/*
@@ -1285,10 +1307,12 @@ static int x25_recvmsg(struct kiocb *iocb, struct socket *sock,
if (!skb)
goto out;
+ if (!pskb_may_pull(skb, header_len))
+ goto out_free_dgram;
+
qbit = (skb->data[0] & X25_Q_BIT) == X25_Q_BIT;
- skb_pull(skb, x25->neighbour->extended ?
- X25_EXT_MIN_LEN : X25_STD_MIN_LEN);
+ skb_pull(skb, header_len);
if (test_bit(X25_Q_BIT_FLAG, &x25->flags)) {
asmptr = skb_push(skb, 1);
diff --git a/net/x25/x25_dev.c b/net/x25/x25_dev.c
index e547ca1578c3..fa2b41888bd9 100644
--- a/net/x25/x25_dev.c
+++ b/net/x25/x25_dev.c
@@ -32,6 +32,9 @@ static int x25_receive_data(struct sk_buff *skb, struct x25_neigh *nb)
unsigned short frametype;
unsigned int lci;
+ if (!pskb_may_pull(skb, X25_STD_MIN_LEN))
+ return 0;
+
frametype = skb->data[2];
lci = ((skb->data[0] << 8) & 0xF00) + ((skb->data[1] << 0) & 0x0FF);
@@ -115,6 +118,9 @@ int x25_lapb_receive_frame(struct sk_buff *skb, struct net_device *dev,
goto drop;
}
+ if (!pskb_may_pull(skb, 1))
+ return 0;
+
switch (skb->data[0]) {
case X25_IFACE_DATA:
diff --git a/net/x25/x25_facilities.c b/net/x25/x25_facilities.c
index f77e4e75f914..36384a1fa9f2 100644
--- a/net/x25/x25_facilities.c
+++ b/net/x25/x25_facilities.c
@@ -44,7 +44,7 @@
int x25_parse_facilities(struct sk_buff *skb, struct x25_facilities *facilities,
struct x25_dte_facilities *dte_facs, unsigned long *vc_fac_mask)
{
- unsigned char *p = skb->data;
+ unsigned char *p;
unsigned int len;
*vc_fac_mask = 0;
@@ -60,14 +60,16 @@ int x25_parse_facilities(struct sk_buff *skb, struct x25_facilities *facilities,
memset(dte_facs->called_ae, '\0', sizeof(dte_facs->called_ae));
memset(dte_facs->calling_ae, '\0', sizeof(dte_facs->calling_ae));
- if (skb->len < 1)
+ if (!pskb_may_pull(skb, 1))
return 0;
- len = *p++;
+ len = skb->data[0];
- if (len >= skb->len)
+ if (!pskb_may_pull(skb, 1 + len))
return -1;
+ p = skb->data + 1;
+
while (len > 0) {
switch (*p & X25_FAC_CLASS_MASK) {
case X25_FAC_CLASS_A:
diff --git a/net/x25/x25_in.c b/net/x25/x25_in.c
index 0b073b51b183..a49cd4ec551a 100644
--- a/net/x25/x25_in.c
+++ b/net/x25/x25_in.c
@@ -107,6 +107,8 @@ static int x25_state1_machine(struct sock *sk, struct sk_buff *skb, int frametyp
/*
* Parse the data in the frame.
*/
+ if (!pskb_may_pull(skb, X25_STD_MIN_LEN))
+ goto out_clear;
skb_pull(skb, X25_STD_MIN_LEN);
len = x25_parse_address_block(skb, &source_addr,
@@ -127,9 +129,11 @@ static int x25_state1_machine(struct sock *sk, struct sk_buff *skb, int frametyp
* Copy any Call User Data.
*/
if (skb->len > 0) {
- skb_copy_from_linear_data(skb,
- x25->calluserdata.cuddata,
- skb->len);
+ if (skb->len > X25_MAX_CUD_LEN)
+ goto out_clear;
+
+ skb_copy_bits(skb, 0, x25->calluserdata.cuddata,
+ skb->len);
x25->calluserdata.cudlength = skb->len;
}
if (!sock_flag(sk, SOCK_DEAD))
@@ -137,6 +141,9 @@ static int x25_state1_machine(struct sock *sk, struct sk_buff *skb, int frametyp
break;
}
case X25_CLEAR_REQUEST:
+ if (!pskb_may_pull(skb, X25_STD_MIN_LEN + 2))
+ goto out_clear;
+
x25_write_internal(sk, X25_CLEAR_CONFIRMATION);
x25_disconnect(sk, ECONNREFUSED, skb->data[3], skb->data[4]);
break;
@@ -164,6 +171,9 @@ static int x25_state2_machine(struct sock *sk, struct sk_buff *skb, int frametyp
switch (frametype) {
case X25_CLEAR_REQUEST:
+ if (!pskb_may_pull(skb, X25_STD_MIN_LEN + 2))
+ goto out_clear;
+
x25_write_internal(sk, X25_CLEAR_CONFIRMATION);
x25_disconnect(sk, 0, skb->data[3], skb->data[4]);
break;
@@ -177,6 +187,11 @@ static int x25_state2_machine(struct sock *sk, struct sk_buff *skb, int frametyp
}
return 0;
+
+out_clear:
+ x25_write_internal(sk, X25_CLEAR_REQUEST);
+ x25_start_t23timer(sk);
+ return 0;
}
/*
@@ -206,6 +221,9 @@ static int x25_state3_machine(struct sock *sk, struct sk_buff *skb, int frametyp
break;
case X25_CLEAR_REQUEST:
+ if (!pskb_may_pull(skb, X25_STD_MIN_LEN + 2))
+ goto out_clear;
+
x25_write_internal(sk, X25_CLEAR_CONFIRMATION);
x25_disconnect(sk, 0, skb->data[3], skb->data[4]);
break;
@@ -304,6 +322,12 @@ static int x25_state3_machine(struct sock *sk, struct sk_buff *skb, int frametyp
}
return queued;
+
+out_clear:
+ x25_write_internal(sk, X25_CLEAR_REQUEST);
+ x25->state = X25_STATE_2;
+ x25_start_t23timer(sk);
+ return 0;
}
/*
@@ -313,13 +337,13 @@ static int x25_state3_machine(struct sock *sk, struct sk_buff *skb, int frametyp
*/
static int x25_state4_machine(struct sock *sk, struct sk_buff *skb, int frametype)
{
+ struct x25_sock *x25 = x25_sk(sk);
+
switch (frametype) {
case X25_RESET_REQUEST:
x25_write_internal(sk, X25_RESET_CONFIRMATION);
case X25_RESET_CONFIRMATION: {
- struct x25_sock *x25 = x25_sk(sk);
-
x25_stop_timer(sk);
x25->condition = 0x00;
x25->va = 0;
@@ -331,6 +355,9 @@ static int x25_state4_machine(struct sock *sk, struct sk_buff *skb, int frametyp
break;
}
case X25_CLEAR_REQUEST:
+ if (!pskb_may_pull(skb, X25_STD_MIN_LEN + 2))
+ goto out_clear;
+
x25_write_internal(sk, X25_CLEAR_CONFIRMATION);
x25_disconnect(sk, 0, skb->data[3], skb->data[4]);
break;
@@ -340,6 +367,12 @@ static int x25_state4_machine(struct sock *sk, struct sk_buff *skb, int frametyp
}
return 0;
+
+out_clear:
+ x25_write_internal(sk, X25_CLEAR_REQUEST);
+ x25->state = X25_STATE_2;
+ x25_start_t23timer(sk);
+ return 0;
}
/* Higher level upcall for a LAPB frame */
diff --git a/net/x25/x25_link.c b/net/x25/x25_link.c
index 037958ff8eed..4acacf3c6617 100644
--- a/net/x25/x25_link.c
+++ b/net/x25/x25_link.c
@@ -90,6 +90,9 @@ void x25_link_control(struct sk_buff *skb, struct x25_neigh *nb,
break;
case X25_DIAGNOSTIC:
+ if (!pskb_may_pull(skb, X25_STD_MIN_LEN + 4))
+ break;
+
printk(KERN_WARNING "x25: diagnostic #%d - %02X %02X %02X\n",
skb->data[3], skb->data[4],
skb->data[5], skb->data[6]);
diff --git a/net/x25/x25_subr.c b/net/x25/x25_subr.c
index 24a342ebc7f5..5170d52bfd96 100644
--- a/net/x25/x25_subr.c
+++ b/net/x25/x25_subr.c
@@ -269,7 +269,11 @@ int x25_decode(struct sock *sk, struct sk_buff *skb, int *ns, int *nr, int *q,
int *d, int *m)
{
struct x25_sock *x25 = x25_sk(sk);
- unsigned char *frame = skb->data;
+ unsigned char *frame;
+
+ if (!pskb_may_pull(skb, X25_STD_MIN_LEN))
+ return X25_ILLEGAL;
+ frame = skb->data;
*ns = *nr = *q = *d = *m = 0;
@@ -294,6 +298,10 @@ int x25_decode(struct sock *sk, struct sk_buff *skb, int *ns, int *nr, int *q,
if (frame[2] == X25_RR ||
frame[2] == X25_RNR ||
frame[2] == X25_REJ) {
+ if (!pskb_may_pull(skb, X25_EXT_MIN_LEN))
+ return X25_ILLEGAL;
+ frame = skb->data;
+
*nr = (frame[3] >> 1) & 0x7F;
return frame[2];
}
@@ -308,6 +316,10 @@ int x25_decode(struct sock *sk, struct sk_buff *skb, int *ns, int *nr, int *q,
if (x25->neighbour->extended) {
if ((frame[2] & 0x01) == X25_DATA) {
+ if (!pskb_may_pull(skb, X25_EXT_MIN_LEN))
+ return X25_ILLEGAL;
+ frame = skb->data;
+
*q = (frame[0] & X25_Q_BIT) == X25_Q_BIT;
*d = (frame[0] & X25_D_BIT) == X25_D_BIT;
*m = (frame[3] & X25_EXT_M_BIT) == X25_EXT_M_BIT;
diff --git a/security/security.c b/security/security.c
index 0e4fccfef12c..d9e153390926 100644
--- a/security/security.c
+++ b/security/security.c
@@ -1097,6 +1097,7 @@ void security_sk_clone(const struct sock *sk, struct sock *newsk)
{
security_ops->sk_clone_security(sk, newsk);
}
+EXPORT_SYMBOL(security_sk_clone);
void security_sk_classify_flow(struct sock *sk, struct flowi *fl)
{
diff --git a/sound/pci/hda/hda_intel.c b/sound/pci/hda/hda_intel.c
index e9a2a8795d1b..191284a1c0ae 100644
--- a/sound/pci/hda/hda_intel.c
+++ b/sound/pci/hda/hda_intel.c
@@ -2370,6 +2370,7 @@ static int azx_dev_free(struct snd_device *device)
static struct snd_pci_quirk position_fix_list[] __devinitdata = {
SND_PCI_QUIRK(0x1028, 0x01cc, "Dell D820", POS_FIX_LPIB),
SND_PCI_QUIRK(0x1028, 0x01de, "Dell Precision 390", POS_FIX_LPIB),
+ SND_PCI_QUIRK(0x1028, 0x02c6, "Dell Inspiron 1010", POS_FIX_LPIB),
SND_PCI_QUIRK(0x103c, 0x306d, "HP dv3", POS_FIX_LPIB),
SND_PCI_QUIRK(0x1043, 0x813d, "ASUS P5AD2", POS_FIX_LPIB),
SND_PCI_QUIRK(0x1043, 0x81b3, "ASUS", POS_FIX_LPIB),
diff --git a/sound/pci/hda/patch_conexant.c b/sound/pci/hda/patch_conexant.c
index 7696d05b9356..76752d8ea733 100644
--- a/sound/pci/hda/patch_conexant.c
+++ b/sound/pci/hda/patch_conexant.c
@@ -3110,6 +3110,7 @@ static const struct snd_pci_quirk cxt5066_cfg_tbl[] = {
SND_PCI_QUIRK(0x17aa, 0x21c5, "Thinkpad Edge 13", CXT5066_THINKPAD),
SND_PCI_QUIRK(0x17aa, 0x21c6, "Thinkpad Edge 13", CXT5066_ASUS),
SND_PCI_QUIRK(0x17aa, 0x215e, "Lenovo Thinkpad", CXT5066_THINKPAD),
+ SND_PCI_QUIRK(0x17aa, 0x21cf, "Lenovo T520 & W520", CXT5066_AUTO),
SND_PCI_QUIRK(0x17aa, 0x21da, "Lenovo X220", CXT5066_THINKPAD),
SND_PCI_QUIRK(0x17aa, 0x21db, "Lenovo X220-tablet", CXT5066_THINKPAD),
SND_PCI_QUIRK(0x17aa, 0x3a0d, "Lenovo U350", CXT5066_ASUS),