Merge commit 'main-jb-2012.08.03-B4' into t114-0806
Pradeep Kumar [Mon, 6 Aug 2012 17:31:18 +0000 (22:31 +0530)]
Conflicts:
arch/arm/boot/compressed/Makefile
arch/arm/boot/compressed/atags_to_fdt.c
arch/arm/boot/compressed/head.S
arch/arm/boot/dts/tegra30.dtsi
arch/arm/include/asm/bug.h
arch/arm/kernel/traps.c
arch/arm/mach-tegra/Makefile.boot
arch/arm/mach-tegra/board-cardhu-sdhci.c
arch/arm/mach-tegra/board-cardhu.c
arch/arm/mach-tegra/board-enterprise-sdhci.c
arch/arm/mach-tegra/board-enterprise.c
arch/arm/mach-tegra/board-harmony.c
arch/arm/mach-tegra/board-kai-sdhci.c
arch/arm/mach-tegra/board-ventana.c
arch/arm/mach-tegra/board-whistler.c
arch/arm/mach-tegra/clock.h
arch/arm/mach-tegra/fuse.h
arch/arm/mach-tegra/tegra2_usb_phy.c
arch/arm/mach-tegra/tegra3_clocks.c
arch/arm/mach-tegra/tegra3_dvfs.c
arch/arm/mach-tegra/tegra3_speedo.c
arch/arm/mach-tegra/timer.c
arch/arm/mach-tegra/usb_phy.c
arch/arm/mach-tegra/wakeups-t3.c
drivers/cpufreq/cpufreq_interactive.c
drivers/input/touchscreen/atmel_mxt_ts.c
drivers/mfd/tps65090.c
drivers/mmc/core/mmc.c
drivers/mmc/host/sdhci-tegra.c
drivers/mmc/host/sdhci.c
drivers/net/wireless/bcmdhd/bcmsdh_sdmmc_linux.c
drivers/regulator/Kconfig
drivers/regulator/core.c
drivers/regulator/tps80031-regulator.c
drivers/spi/Makefile
drivers/staging/nvec/nvec.c
drivers/tty/serial/Makefile
include/linux/mmc/card.h
sound/soc/tegra/tegra_max98095.c
sound/usb/card.c

Change-Id: I65043bc6ce9e97d0592683462215a39e50f403fd
Reviewed-on: http://git-master/r/121392
Reviewed-by: Bo Yan <byan@nvidia.com>
Tested-by: Bo Yan <byan@nvidia.com>
Reviewed-by: Automatic_Commit_Validation_User

144 files changed:
arch/arm/Kconfig
arch/arm/boot/compressed/Makefile
arch/arm/boot/compressed/atags_to_fdt.c
arch/arm/boot/dts/tegra20-harmony.dts [moved from arch/arm/boot/dts/tegra-harmony.dts with 100% similarity]
arch/arm/boot/dts/tegra20-seaboard.dts [moved from arch/arm/boot/dts/tegra-seaboard.dts with 100% similarity]
arch/arm/boot/dts/tegra20-ventana.dts [new file with mode: 0644]
arch/arm/boot/dts/tegra20-whistler.dts [new file with mode: 0644]
arch/arm/boot/dts/tegra30-cardhu.dts [new file with mode: 0644]
arch/arm/boot/dts/tegra30-enterprise.dts [new file with mode: 0644]
arch/arm/configs/tegra3_android_defconfig
arch/arm/configs/tegra_android_defconfig
arch/arm/configs/tegra_p1852_android_defconfig [new file with mode: 0644]
arch/arm/configs/tegra_p1852_gnu_linux_defconfig
arch/arm/include/asm/bug.h
arch/arm/kernel/devtree.c
arch/arm/kernel/traps.c
arch/arm/kernel/vmlinux.lds.S
arch/arm/mach-tegra/baseband-xmm-power.c
arch/arm/mach-tegra/baseband-xmm-power.h
arch/arm/mach-tegra/baseband-xmm-power2.c
arch/arm/mach-tegra/board-aruba-panel.c
arch/arm/mach-tegra/board-aruba-sdhci.c
arch/arm/mach-tegra/board-aruba-sensors.c
arch/arm/mach-tegra/board-aruba.c
arch/arm/mach-tegra/board-cardhu-kbc.c
arch/arm/mach-tegra/board-cardhu-panel.c
arch/arm/mach-tegra/board-cardhu-power.c
arch/arm/mach-tegra/board-cardhu-sdhci.c
arch/arm/mach-tegra/board-cardhu.c
arch/arm/mach-tegra/board-cardhu.h
arch/arm/mach-tegra/board-enterprise-pinmux.c
arch/arm/mach-tegra/board-enterprise-power.c
arch/arm/mach-tegra/board-enterprise-sdhci.c
arch/arm/mach-tegra/board-enterprise.c
arch/arm/mach-tegra/board-harmony-panel.c
arch/arm/mach-tegra/board-harmony.c
arch/arm/mach-tegra/board-kai-sdhci.c
arch/arm/mach-tegra/board-p1852-pinmux.c
arch/arm/mach-tegra/board-p1852.c
arch/arm/mach-tegra/board-p1852.h
arch/arm/mach-tegra/board-touch-kai-synaptics-spi.c
arch/arm/mach-tegra/board-touch-raydium_spi.c
arch/arm/mach-tegra/board-ventana.c
arch/arm/mach-tegra/board-whistler.c
arch/arm/mach-tegra/clock.h
arch/arm/mach-tegra/common.c
arch/arm/mach-tegra/cpu-tegra3.c
arch/arm/mach-tegra/dvfs.c
arch/arm/mach-tegra/dvfs.h
arch/arm/mach-tegra/fuse.c
arch/arm/mach-tegra/fuse.h
arch/arm/mach-tegra/i2c_error_recovery.c
arch/arm/mach-tegra/include/mach/dc.h
arch/arm/mach-tegra/latency_allowance.c
arch/arm/mach-tegra/tegra2_usb_phy.c
arch/arm/mach-tegra/tegra3_clocks.c [new file with mode: 0644]
arch/arm/mach-tegra/tegra3_dvfs.c
arch/arm/mach-tegra/tegra3_speedo.c
arch/arm/mach-tegra/tegra3_usb_phy.c
arch/arm/mach-tegra/tegra_odm_fuses.c
arch/arm/mach-tegra/tegra_usb_modem_power.c
arch/arm/mach-tegra/tegra_usb_phy.h
arch/arm/mach-tegra/timer.c
arch/arm/mach-tegra/timer.h
arch/arm/mach-tegra/usb_phy.c
drivers/ata/Makefile
drivers/cpufreq/cpufreq_interactive.c
drivers/crypto/Makefile
drivers/gpio/Makefile
drivers/gpio/gpio-tegra.c
drivers/hwmon/Makefile
drivers/i2c/busses/Makefile
drivers/input/touchscreen/atmel_mxt_ts.c
drivers/iommu/Makefile
drivers/iommu/tegra-smmu.c
drivers/media/video/tegra/ad5816.c
drivers/media/video/tegra/nvavp/nvavp_dev.c
drivers/media/video/tegra/ov5650.c
drivers/media/video/tegra/ov9726.c
drivers/mfd/Kconfig
drivers/mfd/Makefile
drivers/mfd/tps65090.c
drivers/mfd/tps80031.c
drivers/misc/Kconfig
drivers/misc/Makefile
drivers/misc/inv_mpu/mpu6050/mldl_cfg.c
drivers/misc/tegra-baseband/bb-power.c
drivers/misc/tegra-cec/Makefile
drivers/misc/tegra-throughput.c [new file with mode: 0644]
drivers/mmc/host/Makefile
drivers/mmc/host/sdhci-tegra.c
drivers/mmc/host/sdhci.c
drivers/mtd/devices/Makefile
drivers/mtd/devices/tegra_nand.c
drivers/net/caif/Makefile
drivers/net/usb/cdc_ether.c
drivers/net/wireless/bcmdhd/bcmsdh_sdmmc.c
drivers/net/wireless/bcmdhd/bcmsdh_sdmmc_linux.c
drivers/power/Makefile
drivers/power/tps80031-charger.c
drivers/regulator/Kconfig
drivers/regulator/tps62360-regulator.c
drivers/regulator/tps65090-regulator.c
drivers/regulator/tps80031-regulator.c
drivers/rtc/Makefile
drivers/spi/Makefile
drivers/spi/spi-tegra.c
drivers/spi/spi_slave_tegra.c
drivers/staging/nvec/nvec.c
drivers/tty/serial/Makefile
drivers/usb/gadget/Makefile
drivers/usb/otg/Makefile
drivers/usb/otg/tegra-otg.c
drivers/video/backlight/Makefile
drivers/video/tegra/dc/dc.c
drivers/video/tegra/dc/dc_priv.h
drivers/video/tegra/dc/dsi.c
drivers/video/tegra/dc/ext/dev.c
drivers/video/tegra/dc/mode.c
drivers/video/tegra/host/bus.c
drivers/video/tegra/host/gr3d/scale3d.c
drivers/video/tegra/nvmap/nvmap_ioctl.c
drivers/w1/masters/Makefile
drivers/watchdog/Makefile
drivers/watchdog/tegra_wdt.c
include/linux/mfd/tps65090.h
include/linux/mfd/tps80031.h
include/linux/mmc/host.h
include/linux/nvhost.h
include/linux/platform_data/tegra_usb.h
include/linux/regulator/tps65090-regulator.h
include/linux/regulator/tps80031-regulator.h
include/linux/tegra_nvavp.h
include/linux/throughput_ioctl.h [new file with mode: 0644]
include/media/ov9726.h
include/trace/events/nvevent.h [new file with mode: 0644]
kernel/kthread.c
sound/pci/hda/hda_codec.c
sound/pci/hda/hda_codec.h
sound/pci/hda/hda_eld.c
sound/soc/codecs/max98088.c
sound/soc/tegra/tegra30_i2s.c
sound/soc/tegra/tegra_max98095.c
sound/usb/card.c

index 40589ce..9f140c0 100644 (file)
@@ -1,3 +1,16 @@
+# Copyright (c) 2012, NVIDIA CORPORATION.  All rights reserved.
+#
+# This program is free software; you can redistribute it and/or modify it
+# under the terms and conditions of the GNU General Public License,
+# version 2, as published by the Free Software Foundation.
+#
+# This program is distributed in the hope 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, see <http://www.gnu.org/licenses/>.
 config ARM
        bool
        default y
@@ -248,6 +261,10 @@ config GENERIC_BUG
        def_bool y
        depends on BUG
 
+config GENERIC_BUG
+       def_bool y
+       depends on BUG
+
 source "init/Kconfig"
 
 source "kernel/Kconfig.freezer"
index bb26756..cc67dd1 100644 (file)
@@ -111,6 +111,23 @@ ifeq ($(CONFIG_ARM_ATAG_DTB_COMPAT),y)
 OBJS   += $(libfdt_objs) atags_to_fdt.o
 endif
 
+# Borrowed libfdt files for the ATAG compatibility mode
+
+libfdt         := fdt_rw.c fdt_ro.c fdt_wip.c fdt.c
+libfdt_hdrs    := fdt.h libfdt.h libfdt_internal.h
+
+libfdt_objs    := $(addsuffix .o, $(basename $(libfdt)))
+
+$(addprefix $(obj)/,$(libfdt) $(libfdt_hdrs)): $(obj)/%: $(srctree)/scripts/dtc/libfdt/%
+       $(call cmd,shipped)
+
+$(addprefix $(obj)/,$(libfdt_objs) atags_to_fdt.o): \
+       $(addprefix $(obj)/,$(libfdt_hdrs))
+
+ifeq ($(CONFIG_ARM_ATAG_DTB_COMPAT),y)
+OBJS   += $(libfdt_objs) atags_to_fdt.o
+endif
+
 targets       := vmlinux vmlinux.lds \
                 piggy.$(suffix_y) piggy.$(suffix_y).o \
                 lib1funcs.o lib1funcs.S ashldi3.o ashldi3.S \
index 797f04b..e7a26fe 100644 (file)
@@ -89,6 +89,11 @@ int atags_to_fdt(void *atag_list, void *fdt, int total_space)
                                        initrd_start);
                        setprop_cell(fdt, "/chosen", "linux,initrd-end",
                                        initrd_start + initrd_size);
+               } else if (atag->hdr.tag == ATAG_SERIAL) {
+                       uint32_t serial[2];
+                       serial[0] = cpu_to_fdt32(atag->u.serialnr.high);
+                       serial[1] = cpu_to_fdt32(atag->u.serialnr.low);
+                       setprop(fdt, "/", "serial-num", serial, 8);
                }
        }
 
diff --git a/arch/arm/boot/dts/tegra20-ventana.dts b/arch/arm/boot/dts/tegra20-ventana.dts
new file mode 100644 (file)
index 0000000..39f1997
--- /dev/null
@@ -0,0 +1,8 @@
+/dts-v1/;
+
+/include/ "tegra20.dtsi"
+
+/ {
+       model = "NVIDIA Tegra2 Ventana evaluation board";
+       compatible = "nvidia,ventana", "nvidia,tegra20";
+};
diff --git a/arch/arm/boot/dts/tegra20-whistler.dts b/arch/arm/boot/dts/tegra20-whistler.dts
new file mode 100644 (file)
index 0000000..e3a5939
--- /dev/null
@@ -0,0 +1,8 @@
+/dts-v1/;
+
+/include/ "tegra20.dtsi"
+
+/ {
+       model = "NVIDIA Tegra20 Whistler evaluation board";
+       compatible = "nvidia,whistler", "nvidia,tegra20";
+};
diff --git a/arch/arm/boot/dts/tegra30-cardhu.dts b/arch/arm/boot/dts/tegra30-cardhu.dts
new file mode 100644 (file)
index 0000000..35dce0b
--- /dev/null
@@ -0,0 +1,8 @@
+/dts-v1/;
+
+/include/ "tegra30.dtsi"
+
+/ {
+       model = "NVIDIA Tegra30 Cardhu evaluation board";
+       compatible = "nvidia,cardhu", "nvidia,tegra30";
+};
diff --git a/arch/arm/boot/dts/tegra30-enterprise.dts b/arch/arm/boot/dts/tegra30-enterprise.dts
new file mode 100644 (file)
index 0000000..c78821c
--- /dev/null
@@ -0,0 +1,8 @@
+/dts-v1/;
+
+/include/ "tegra30.dtsi"
+
+/ {
+       model = "NVIDIA Tegra30 Enterprise evaluation board";
+       compatible = "nvidia,enterprise", "nvidia,tegra30";
+};
index b2ecba6..3d37c2f 100644 (file)
@@ -50,6 +50,7 @@ CONFIG_AEABI=y
 # CONFIG_OABI_COMPAT is not set
 CONFIG_HIGHMEM=y
 CONFIG_ARM_FLUSH_CONSOLE_ON_RESTART=y
+CONFIG_USE_OF=y
 CONFIG_ZBOOT_ROM_TEXT=0x0
 CONFIG_ZBOOT_ROM_BSS=0x0
 CONFIG_CPU_FREQ=y
@@ -179,6 +180,7 @@ CONFIG_CAIF=y
 CONFIG_NFC=y
 CONFIG_PN544_NFC=y
 # CONFIG_FIRMWARE_IN_KERNEL is not set
+CONFIG_PROC_DEVICETREE=y
 CONFIG_BLK_DEV_LOOP=y
 CONFIG_AD525X_DPOT=y
 CONFIG_AD525X_DPOT_I2C=y
index 19b1ec7..7571c44 100644 (file)
@@ -46,6 +46,7 @@ CONFIG_PREEMPT=y
 CONFIG_AEABI=y
 # CONFIG_OABI_COMPAT is not set
 CONFIG_HIGHMEM=y
+CONFIG_USE_OF=y
 CONFIG_ZBOOT_ROM_TEXT=0x0
 CONFIG_ZBOOT_ROM_BSS=0x0
 CONFIG_CPU_FREQ=y
@@ -166,6 +167,7 @@ CONFIG_CFG80211=y
 CONFIG_RFKILL=y
 CONFIG_RFKILL_GPIO=y
 # CONFIG_FIRMWARE_IN_KERNEL is not set
+CONFIG_PROC_DEVICETREE=y
 CONFIG_BLK_DEV_LOOP=y
 CONFIG_AD525X_DPOT=y
 CONFIG_AD525X_DPOT_I2C=y
diff --git a/arch/arm/configs/tegra_p1852_android_defconfig b/arch/arm/configs/tegra_p1852_android_defconfig
new file mode 100644 (file)
index 0000000..4550c9e
--- /dev/null
@@ -0,0 +1,339 @@
+CONFIG_EXPERIMENTAL=y
+CONFIG_CROSS_COMPILE="arm-eabi-"
+# CONFIG_LOCALVERSION_AUTO is not set
+# CONFIG_SWAP is not set
+CONFIG_SYSVIPC=y
+CONFIG_IKCONFIG=y
+CONFIG_IKCONFIG_PROC=y
+CONFIG_CGROUPS=y
+CONFIG_CGROUP_DEBUG=y
+CONFIG_CGROUP_FREEZER=y
+CONFIG_CGROUP_CPUACCT=y
+CONFIG_RESOURCE_COUNTERS=y
+CONFIG_CGROUP_SCHED=y
+CONFIG_RT_GROUP_SCHED=y
+CONFIG_BLK_DEV_INITRD=y
+CONFIG_PANIC_TIMEOUT=10
+# CONFIG_SYSCTL_SYSCALL is not set
+# CONFIG_ELF_CORE is not set
+CONFIG_ASHMEM=y
+CONFIG_EMBEDDED=y
+CONFIG_SLAB=y
+CONFIG_MODULES=y
+CONFIG_MODULE_UNLOAD=y
+CONFIG_MODULE_FORCE_UNLOAD=y
+# CONFIG_BLK_DEV_BSG is not set
+# CONFIG_IOSCHED_DEADLINE is not set
+# CONFIG_IOSCHED_CFQ is not set
+CONFIG_ARCH_TEGRA=y
+CONFIG_GPIO_PCA953X=y
+CONFIG_ARCH_TEGRA_3x_SOC=y
+CONFIG_MACH_P1852=y
+CONFIG_TEGRA_DEBUG_UARTB=y
+CONFIG_TEGRA_PWM=y
+# CONFIG_TEGRA_CPU_DVFS is not set
+CONFIG_TEGRA_CLOCK_DEBUG_WRITE=y
+CONFIG_USB_HOTPLUG=y
+CONFIG_ARM_ERRATA_743622=y
+CONFIG_ARM_ERRATA_751472=y
+CONFIG_ARM_ERRATA_752520=y
+CONFIG_NO_HZ=y
+CONFIG_HIGH_RES_TIMERS=y
+CONFIG_SMP=y
+CONFIG_PREEMPT=y
+CONFIG_AEABI=y
+# CONFIG_OABI_COMPAT is not set
+CONFIG_HIGHMEM=y
+CONFIG_ZBOOT_ROM_TEXT=0x0
+CONFIG_ZBOOT_ROM_BSS=0x0
+CONFIG_VFP=y
+CONFIG_NEON=y
+# CONFIG_SUSPEND is not set
+CONFIG_NET=y
+CONFIG_PACKET=y
+CONFIG_UNIX=y
+CONFIG_NET_KEY=y
+CONFIG_INET=y
+CONFIG_IP_ADVANCED_ROUTER=y
+CONFIG_IP_MULTIPLE_TABLES=y
+CONFIG_IP_PNP=y
+CONFIG_IP_PNP_DHCP=y
+CONFIG_IP_PNP_BOOTP=y
+CONFIG_IP_PNP_RARP=y
+CONFIG_INET_ESP=y
+# CONFIG_INET_XFRM_MODE_TUNNEL is not set
+# CONFIG_INET_XFRM_MODE_BEET is not set
+# CONFIG_INET_LRO is not set
+# CONFIG_INET_DIAG is not set
+CONFIG_IPV6=y
+CONFIG_IPV6_PRIVACY=y
+CONFIG_IPV6_ROUTER_PREF=y
+CONFIG_IPV6_OPTIMISTIC_DAD=y
+CONFIG_INET6_AH=y
+CONFIG_INET6_ESP=y
+CONFIG_INET6_IPCOMP=y
+CONFIG_IPV6_MIP6=y
+CONFIG_IPV6_TUNNEL=y
+CONFIG_IPV6_MULTIPLE_TABLES=y
+CONFIG_NETFILTER=y
+CONFIG_NETFILTER_NETLINK_LOG=y
+CONFIG_NF_CONNTRACK=y
+CONFIG_NF_CONNTRACK_EVENTS=y
+CONFIG_NF_CT_PROTO_DCCP=y
+CONFIG_NF_CT_PROTO_SCTP=y
+CONFIG_NF_CT_PROTO_UDPLITE=y
+CONFIG_NF_CONNTRACK_AMANDA=y
+CONFIG_NF_CONNTRACK_FTP=y
+CONFIG_NF_CONNTRACK_H323=y
+CONFIG_NF_CONNTRACK_IRC=y
+CONFIG_NF_CONNTRACK_NETBIOS_NS=y
+CONFIG_NF_CONNTRACK_PPTP=y
+CONFIG_NF_CONNTRACK_SANE=y
+CONFIG_NF_CONNTRACK_SIP=y
+CONFIG_NF_CONNTRACK_TFTP=y
+CONFIG_NETFILTER_TPROXY=y
+CONFIG_NETFILTER_XT_TARGET_CLASSIFY=y
+CONFIG_NETFILTER_XT_TARGET_CONNMARK=y
+CONFIG_NETFILTER_XT_TARGET_MARK=y
+CONFIG_NETFILTER_XT_TARGET_NFQUEUE=y
+CONFIG_NETFILTER_XT_MATCH_COMMENT=y
+CONFIG_NETFILTER_XT_MATCH_CONNBYTES=y
+CONFIG_NETFILTER_XT_MATCH_CONNLIMIT=y
+CONFIG_NETFILTER_XT_MATCH_CONNMARK=y
+CONFIG_NETFILTER_XT_MATCH_CONNTRACK=y
+CONFIG_NETFILTER_XT_MATCH_HASHLIMIT=y
+CONFIG_NETFILTER_XT_MATCH_HELPER=y
+CONFIG_NETFILTER_XT_MATCH_IPRANGE=y
+CONFIG_NETFILTER_XT_MATCH_LENGTH=y
+CONFIG_NETFILTER_XT_MATCH_LIMIT=y
+CONFIG_NETFILTER_XT_MATCH_MAC=y
+CONFIG_NETFILTER_XT_MATCH_MARK=y
+CONFIG_NETFILTER_XT_MATCH_POLICY=y
+CONFIG_NETFILTER_XT_MATCH_PKTTYPE=y
+CONFIG_NETFILTER_XT_MATCH_QTAGUID=y
+CONFIG_NETFILTER_XT_MATCH_QUOTA=y
+CONFIG_NETFILTER_XT_MATCH_SOCKET=y
+CONFIG_NETFILTER_XT_MATCH_STATE=y
+CONFIG_NETFILTER_XT_MATCH_STATISTIC=y
+CONFIG_NETFILTER_XT_MATCH_STRING=y
+CONFIG_NETFILTER_XT_MATCH_TIME=y
+CONFIG_NETFILTER_XT_MATCH_U32=y
+CONFIG_NF_CONNTRACK_IPV4=y
+CONFIG_IP_NF_IPTABLES=y
+CONFIG_IP_NF_MATCH_AH=y
+CONFIG_IP_NF_MATCH_ECN=y
+CONFIG_IP_NF_MATCH_TTL=y
+CONFIG_IP_NF_FILTER=y
+CONFIG_IP_NF_TARGET_REJECT=y
+CONFIG_IP_NF_TARGET_LOG=y
+CONFIG_NF_NAT=y
+CONFIG_IP_NF_TARGET_MASQUERADE=y
+CONFIG_IP_NF_TARGET_NETMAP=y
+CONFIG_IP_NF_TARGET_REDIRECT=y
+CONFIG_IP_NF_MANGLE=y
+CONFIG_IP_NF_ARPTABLES=y
+CONFIG_IP_NF_ARPFILTER=y
+CONFIG_IP_NF_ARP_MANGLE=y
+CONFIG_IP6_NF_IPTABLES=y
+CONFIG_NET_SCHED=y
+CONFIG_NET_SCH_HTB=y
+CONFIG_NET_SCH_INGRESS=y
+CONFIG_NET_CLS_U32=y
+CONFIG_NET_EMATCH=y
+CONFIG_NET_EMATCH_U32=y
+CONFIG_NET_CLS_ACT=y
+CONFIG_NET_ACT_POLICE=y
+CONFIG_NET_ACT_GACT=y
+CONFIG_NET_ACT_MIRRED=y
+# CONFIG_FIRMWARE_IN_KERNEL is not set
+CONFIG_MTD=y
+CONFIG_MTD_CMDLINE_PARTS=y
+CONFIG_MTD_CHAR=y
+CONFIG_MTD_BLOCK=y
+CONFIG_MTD_CFI=y
+CONFIG_MTD_CFI_INTELEXT=y
+CONFIG_MTD_CFI_AMDSTD=y
+CONFIG_MTD_CFI_STAA=y
+CONFIG_MTD_COMPLEX_MAPPINGS=y
+CONFIG_MTD_NAND_TEGRA=y
+CONFIG_MTD_NAND=y
+CONFIG_BLK_DEV_LOOP=y
+CONFIG_MISC_DEVICES=y
+CONFIG_AD525X_DPOT=y
+CONFIG_AD525X_DPOT_I2C=y
+CONFIG_APDS9802ALS=y
+CONFIG_SENSORS_NCT1008=y
+CONFIG_UID_STAT=y
+CONFIG_BCM4329_RFKILL=y
+CONFIG_TEGRA_CRYPTO_DEV=y
+CONFIG_MAX1749_VIBRATOR=y
+CONFIG_EEPROM_AT24=y
+CONFIG_TI_ST=y
+CONFIG_ST_GPS=m
+CONFIG_MPU_SENSORS_TIMERIRQ=y
+CONFIG_MPU_SENSORS_MPU3050=m
+CONFIG_MPU_SENSORS_MPU6050B1=m
+CONFIG_MPU_SENSORS_KXTF9=m
+CONFIG_MPU_SENSORS_MPU6050_ACCEL=m
+CONFIG_MPU_SENSORS_AK8963=m
+CONFIG_MPU_SENSORS_AK8975=m
+CONFIG_SCSI=y
+CONFIG_BLK_DEV_SD=y
+# CONFIG_SCSI_LOWLEVEL is not set
+CONFIG_MD=y
+CONFIG_BLK_DEV_DM=y
+CONFIG_DM_CRYPT=y
+CONFIG_DM_UEVENT=y
+CONFIG_NETDEVICES=y
+CONFIG_DUMMY=y
+# CONFIG_NETDEV_1000 is not set
+# CONFIG_NETDEV_10000 is not set
+# CONFIG_WLAN is not set
+CONFIG_USB_USBNET=y
+CONFIG_USB_NET_SMSC75XX=y
+CONFIG_USB_NET_SMSC95XX=y
+# CONFIG_USB_NET_NET1080 is not set
+# CONFIG_USB_NET_CDC_SUBSET is not set
+# CONFIG_USB_NET_ZAURUS is not set
+CONFIG_USB_NET_RAW_IP=y
+CONFIG_PPP=y
+CONFIG_PPP_FILTER=y
+CONFIG_PPP_ASYNC=y
+CONFIG_PPP_SYNC_TTY=y
+CONFIG_PPP_DEFLATE=y
+CONFIG_PPP_BSDCOMP=y
+CONFIG_PPP_MPPE=y
+CONFIG_PPPOLAC=y
+CONFIG_PPPOPNS=y
+CONFIG_INPUT_EVDEV=y
+# CONFIG_KEYBOARD_ATKBD is not set
+CONFIG_KEYBOARD_TEGRA=y
+# CONFIG_INPUT_MOUSE is not set
+# CONFIG_SERIO is not set
+# CONFIG_LEGACY_PTYS is not set
+CONFIG_SERIAL_8250=y
+CONFIG_SERIAL_8250_CONSOLE=y
+CONFIG_SERIAL_TEGRA=y
+# CONFIG_HW_RANDOM is not set
+CONFIG_I2C_CHARDEV=y
+CONFIG_I2C_MUX=y
+CONFIG_I2C_MUX_PCA954x=y
+CONFIG_I2C_TEGRA=y
+CONFIG_SPI=y
+CONFIG_SPI_TEGRA=y
+CONFIG_SPI_SLAVE_TEGRA=y
+CONFIG_SPI_SPIDEV=y
+CONFIG_GPIO_SYSFS=y
+CONFIG_POWER_SUPPLY=y
+CONFIG_PDA_POWER=y
+CONFIG_BATTERY_BQ20Z75=y
+CONFIG_BATTERY_BQ27x00=y
+CONFIG_CHARGER_SMB349=y
+CONFIG_BATTERY_MAX17048=y
+CONFIG_CHARGER_GPIO=y
+CONFIG_SENSORS_TEGRA_TSENSOR=y
+CONFIG_SENSORS_INA219=y
+CONFIG_THERMAL=y
+CONFIG_MFD_TPS6586X=y
+CONFIG_MFD_TPS65910=y
+CONFIG_MFD_MAX77663=y
+CONFIG_MFD_TPS6591X=y
+CONFIG_REGULATOR=y
+CONFIG_REGULATOR_FIXED_VOLTAGE=y
+CONFIG_REGULATOR_VIRTUAL_CONSUMER=y
+CONFIG_REGULATOR_TPS6591X=y
+CONFIG_MEDIA_SUPPORT=y
+CONFIG_VIDEO_DEV=y
+# CONFIG_TEGRA_AVP is not set
+# CONFIG_TEGRA_MEDIASERVER is not set
+CONFIG_TEGRA_NVAVP=y
+# CONFIG_VGA_ARB is not set
+CONFIG_VIDEO_OUTPUT_CONTROL=y
+CONFIG_FB=y
+CONFIG_TEGRA_GRHOST=y
+CONFIG_TEGRA_DC=y
+CONFIG_BACKLIGHT_LCD_SUPPORT=y
+CONFIG_LCD_CLASS_DEVICE=y
+CONFIG_BACKLIGHT_CLASS_DEVICE=y
+# CONFIG_BACKLIGHT_GENERIC is not set
+CONFIG_BACKLIGHT_PWM=y
+CONFIG_SOUND=y
+CONFIG_SND=y
+CONFIG_SND_SOC=y
+CONFIG_SND_SOC_TEGRA=y
+CONFIG_SND_SOC_TEGRA_P1852=y
+CONFIG_USB=y
+CONFIG_USB_ANNOUNCE_NEW_DEVICES=y
+CONFIG_USB_DEVICEFS=y
+CONFIG_USB_EHCI_HCD=y
+CONFIG_USB_ACM=y
+CONFIG_USB_WDM=y
+CONFIG_USB_STORAGE=y
+CONFIG_USB_LIBUSUAL=y
+CONFIG_USB_SERIAL=y
+CONFIG_USB_SERIAL_PL2303=y
+CONFIG_USB_SERIAL_OPTION=y
+CONFIG_USB_SERIAL_BASEBAND=m
+CONFIG_USB_GADGET=y
+CONFIG_USB_GADGET_VBUS_DRAW=500
+CONFIG_USB_TEGRA=y
+CONFIG_USB_G_ANDROID=y
+CONFIG_USB_TEGRA_OTG=y
+CONFIG_MMC=y
+CONFIG_MMC_UNSAFE_RESUME=y
+CONFIG_MMC_EMBEDDED_SDIO=y
+CONFIG_MMC_PARANOID_SD_INIT=y
+# CONFIG_MMC_BLOCK_BOUNCE is not set
+CONFIG_MMC_BLOCK_DEFERRED_RESUME=y
+CONFIG_MMC_SDHCI=y
+CONFIG_MMC_SDHCI_PLTFM=y
+CONFIG_MMC_SDHCI_TEGRA=y
+CONFIG_SWITCH=y
+CONFIG_RTC_CLASS=y
+CONFIG_RTC_DRV_TEGRA=y
+CONFIG_STAGING=y
+CONFIG_ANDROID=y
+CONFIG_ANDROID_BINDER_IPC=y
+CONFIG_ANDROID_LOGGER=y
+CONFIG_ANDROID_RAM_CONSOLE=y
+CONFIG_ANDROID_RAM_CONSOLE_ERROR_CORRECTION=y
+CONFIG_ANDROID_TIMED_GPIO=y
+CONFIG_ANDROID_LOW_MEMORY_KILLER=y
+CONFIG_IIO=y
+CONFIG_EXT2_FS=y
+CONFIG_EXT2_FS_XATTR=y
+CONFIG_EXT2_FS_POSIX_ACL=y
+CONFIG_EXT2_FS_SECURITY=y
+CONFIG_EXT3_FS=y
+# CONFIG_EXT3_DEFAULTS_TO_ORDERED is not set
+CONFIG_EXT3_FS_POSIX_ACL=y
+CONFIG_EXT3_FS_SECURITY=y
+CONFIG_EXT4_FS=y
+# CONFIG_DNOTIFY is not set
+CONFIG_FUSE_FS=y
+CONFIG_VFAT_FS=y
+CONFIG_TMPFS=y
+# CONFIG_MISC_FILESYSTEMS is not set
+CONFIG_NFS_FS=y
+CONFIG_NFS_V3=y
+CONFIG_NFS_V3_ACL=y
+CONFIG_ROOT_NFS=y
+CONFIG_PARTITION_ADVANCED=y
+CONFIG_EFI_PARTITION=y
+CONFIG_NLS_CODEPAGE_437=y
+CONFIG_NLS_ISO8859_1=y
+CONFIG_PRINTK_TIME=y
+CONFIG_MAGIC_SYSRQ=y
+CONFIG_DEBUG_FS=y
+CONFIG_LOCKUP_DETECTOR=y
+CONFIG_SCHEDSTATS=y
+CONFIG_TIMER_STATS=y
+# CONFIG_DEBUG_PREEMPT is not set
+CONFIG_DEBUG_INFO=y
+CONFIG_DEBUG_VM=y
+# CONFIG_ARM_UNWIND is not set
+CONFIG_DEBUG_LL=y
+CONFIG_EARLY_PRINTK=y
+CONFIG_CRYPTO_AES=y
+CONFIG_CRYPTO_TWOFISH=y
+# CONFIG_CRYPTO_ANSI_CPRNG is not set
index e6b401c..7e4f4ab 100644 (file)
@@ -192,6 +192,8 @@ CONFIG_EXT3_FS_SECURITY=y
 CONFIG_EXT4_FS=y
 # CONFIG_DNOTIFY is not set
 CONFIG_FUSE_FS=y
+CONFIG_ISO9660_FS=y
+CONFIG_JOLIET=y
 CONFIG_VFAT_FS=y
 CONFIG_TMPFS=y
 # CONFIG_MISC_FILESYSTEMS is not set
index 7af5c6c..deb6f14 100644 (file)
@@ -1,3 +1,20 @@
+/*
+ * arch/arm/include/asm/bug.h
+ *
+ * Copyright (c) 2012, NVIDIA CORPORATION.  All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope 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, see <http://www.gnu.org/licenses/>.
+ */
 #ifndef _ASMARM_BUG_H
 #define _ASMARM_BUG_H
 
index bee7f9d..0161982 100644 (file)
@@ -75,6 +75,9 @@ struct machine_desc * __init setup_machine_fdt(unsigned int dt_phys)
        unsigned int score, mdesc_score = ~1;
        unsigned long dt_root;
        const char *model;
+       __be32 *serial_prop;
+       u64 serial = 0;
+       unsigned long len;
 
        if (!dt_phys)
                return NULL;
@@ -118,7 +121,16 @@ struct machine_desc * __init setup_machine_fdt(unsigned int dt_phys)
                model = of_get_flat_dt_prop(dt_root, "compatible", NULL);
        if (!model)
                model = "<unknown>";
-       pr_info("Machine: %s, model: %s\n", mdesc_best->name, model);
+
+       serial_prop = of_get_flat_dt_prop(dt_root, "serial-num", &len);
+       if (serial_prop) {
+               serial = of_read_number(serial_prop, len / 4);
+       }
+       system_serial_high = serial >> 32;
+       system_serial_low = serial;
+
+       pr_info("Machine: %s, model: %s, serial: %llu\n", mdesc_best->name,
+               model, serial);
 
        /* Retrieve various information from the /chosen node */
        of_scan_flat_dt(early_init_dt_scan_chosen, boot_command_line);
index 3647170..13f606d 100644 (file)
@@ -4,6 +4,8 @@
  *  Copyright (C) 1995-2009 Russell King
  *  Fragments that appear the same as linux/arch/i386/kernel/traps.c (C) Linus Torvalds
  *
+ * Copyright (c) 2012, NVIDIA CORPORATION.  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 as
  * published by the Free Software Foundation.
index 43a31fb..432e112 100644 (file)
@@ -1,3 +1,21 @@
+/*
+ * arch/arm/kernel/vmlinux.lds.S
+ *
+ * Copyright (c) 2012, NVIDIA CORPORATION.  All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope 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, see <http://www.gnu.org/licenses/>.
+ */
+
 /* ld script to make ARM Linux kernel
  * taken from the i386 version by Russell King
  * Written by Martin Mares <mj@atrey.karlin.mff.cuni.cz>
index 31d3924..a1c6a9c 100644 (file)
@@ -77,18 +77,9 @@ static struct gpio tegra_baseband_gpios[] = {
        { -1, GPIOF_IN,            "IPC_HSIC_SUS_REQ" },
 };
 
-static enum {
-       IPC_AP_WAKE_UNINIT,
-       IPC_AP_WAKE_IRQ_READY,
-       IPC_AP_WAKE_INIT1,
-       IPC_AP_WAKE_INIT2,
-       IPC_AP_WAKE_L,
-       IPC_AP_WAKE_H,
-} ipc_ap_wake_state;
-
 static enum baseband_xmm_powerstate_t baseband_xmm_powerstate;
+static enum ipc_ap_wake_state_t ipc_ap_wake_state;
 static struct workqueue_struct *workqueue;
-static struct work_struct init1_work;
 static struct work_struct init2_work;
 static struct work_struct L2_resume_work;
 static struct work_struct autopm_resume_work;
@@ -256,7 +247,6 @@ static int xmm_power_on(struct platform_device *device)
        /* reset the state machine */
        baseband_xmm_powerstate = BBXMM_PS_INIT;
        modem_sleep_flag = false;
-       ipc_ap_wake_state = IPC_AP_WAKE_INIT2;
 
        pr_debug("%s wake_st(%d) modem version %lu\n", __func__,
                                ipc_ap_wake_state, modem_ver);
@@ -264,6 +254,8 @@ static int xmm_power_on(struct platform_device *device)
        /* register usb host controller */
        if (!modem_flash) {
                pr_debug("%s - %d\n", __func__, __LINE__);
+
+               ipc_ap_wake_state = IPC_AP_WAKE_INIT2;
                /* register usb host controller only once */
                if (register_hsic_device) {
                        pr_debug("%s: register usb host controller\n",
@@ -291,7 +283,7 @@ static int xmm_power_on(struct platform_device *device)
 
                pr_debug("%s: reset flash modem\n", __func__);
                modem_power_on = false;
-               ipc_ap_wake_state = IPC_AP_WAKE_INIT1;
+               ipc_ap_wake_state = IPC_AP_WAKE_IRQ_READY;
                gpio_set_value(pdata->modem.xmm.ipc_hsic_active, 0);
 
                xmm_power_reset_on(pdata);
@@ -552,41 +544,11 @@ void baseband_xmm_set_power_status(unsigned int status)
 }
 EXPORT_SYMBOL_GPL(baseband_xmm_set_power_status);
 
-irqreturn_t xmm_power_ipc_ap_wake_irq(int irq, void *dev_id)
+
+irqreturn_t xmm_power_ipc_ap_wake_irq(int value)
 {
        struct baseband_power_platform_data *data = xmm_power_drv_data.pdata;
        struct xmm_power_data *drv = &xmm_power_drv_data;
-       int value;
-
-       value = gpio_get_value(data->modem.xmm.ipc_ap_wake);
-       pr_debug("%s g(%d), wake_st(%d)\n", __func__, value, ipc_ap_wake_state);
-
-       /* modem initialization/bootup part*/
-       if (unlikely(ipc_ap_wake_state < IPC_AP_WAKE_IRQ_READY)) {
-               pr_err("%s - spurious irq\n", __func__);
-               return IRQ_HANDLED;
-       } else if (ipc_ap_wake_state == IPC_AP_WAKE_IRQ_READY) {
-               if (!value) {
-                       pr_debug("%s - IPC_AP_WAKE_INIT1"
-                                       " - got falling edge\n", __func__);
-                       /* go to IPC_AP_WAKE_INIT1 state */
-                       ipc_ap_wake_state = IPC_AP_WAKE_INIT1;
-                       queue_work(workqueue, &init1_work);
-               } else
-                       pr_debug("%s - IPC_AP_WAKE_INIT1"
-                               " - wait for falling edge\n", __func__);
-               return IRQ_HANDLED;
-       } else if (ipc_ap_wake_state == IPC_AP_WAKE_INIT1) {
-               if (!value) {
-                       pr_debug("%s - got falling edge at INIT1\n", __func__);
-                       /* go to IPC_AP_WAKE_INIT2 state */
-                       ipc_ap_wake_state = IPC_AP_WAKE_INIT2;
-                       queue_work(workqueue, &init2_work);
-               } else
-                       pr_debug("%s - IPC_AP_WAKE_INIT1"
-                                       " - got rising edge\n", __func__);
-               return IRQ_HANDLED;
-       }
 
        /* modem wakeup part */
        if (!value) {
@@ -646,41 +608,41 @@ irqreturn_t xmm_power_ipc_ap_wake_irq(int irq, void *dev_id)
                /* save gpio state */
                ipc_ap_wake_state = IPC_AP_WAKE_H;
        }
-
        return IRQ_HANDLED;
 }
 EXPORT_SYMBOL(xmm_power_ipc_ap_wake_irq);
 
-static void xmm_power_init1_work(struct work_struct *work)
+static irqreturn_t ipc_ap_wake_irq(int irq, void *dev_id)
 {
-       struct baseband_power_platform_data *pdata = xmm_power_drv_data.pdata;
+       struct baseband_power_platform_data *data = xmm_power_drv_data.pdata;
        int value;
 
-       pr_debug("%s {\n", __func__);
-
-       /* check if IPC_HSIC_ACTIVE high */
-       value = gpio_get_value(pdata->modem.xmm.ipc_hsic_active);
-       if (value != 1) {
-               pr_err("%s - expected IPC_HSIC_ACTIVE high!\n", __func__);
-               return;
-       }
-
-       /* wait 100 ms */
-       msleep(100);
-
-       /* set IPC_HSIC_ACTIVE low */
-       gpio_set_value(pdata->modem.xmm.ipc_hsic_active, 0);
-
-       /* wait 10 ms */
-       usleep_range(10000, 11000);
-
-       /* set IPC_HSIC_ACTIVE high */
-       gpio_set_value(pdata->modem.xmm.ipc_hsic_active, 1);
+       value = gpio_get_value(data->modem.xmm.ipc_ap_wake);
+       pr_debug("%s g(%d), wake_st(%d)\n", __func__, value, ipc_ap_wake_state);
 
-       /* wait 20 ms */
-       msleep(20);
+       /* modem wakeup part */
+       if (likely(ipc_ap_wake_state >= IPC_AP_WAKE_INIT2))
+               return xmm_power_ipc_ap_wake_irq(value);
 
-       pr_debug("%s }\n", __func__);
+       /* modem initialization/bootup part*/
+       if (unlikely(ipc_ap_wake_state < IPC_AP_WAKE_IRQ_READY)) {
+               pr_err("%s - spurious irq\n", __func__);
+       } else if (ipc_ap_wake_state == IPC_AP_WAKE_IRQ_READY) {
+               if (value) {
+                       /* make state ready for falling edge */
+                       ipc_ap_wake_state = IPC_AP_WAKE_INIT1;
+                       pr_debug("%s - got rising edge\n", __func__);
+               }
+       } else if (ipc_ap_wake_state == IPC_AP_WAKE_INIT1) {
+               if (!value) {
+                       pr_debug("%s - got falling edge at INIT1\n", __func__);
+                       /* go to IPC_AP_WAKE_INIT2 state */
+                       ipc_ap_wake_state = IPC_AP_WAKE_INIT2;
+                       queue_work(workqueue, &init2_work);
+               } else
+                       pr_debug("%s - unexpected rising edge\n", __func__);
+       }
+       return IRQ_HANDLED;
 }
 
 static void xmm_power_init2_work(struct work_struct *work)
@@ -960,7 +922,7 @@ static int xmm_power_driver_probe(struct platform_device *device)
                ipc_ap_wake_state = IPC_AP_WAKE_UNINIT;
                err = request_threaded_irq(
                                gpio_to_irq(pdata->modem.xmm.ipc_ap_wake),
-                               NULL, xmm_power_ipc_ap_wake_irq,
+                               NULL, ipc_ap_wake_irq,
                                IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING,
                                "IPC_AP_WAKE_IRQ", NULL);
                if (err < 0) {
@@ -973,9 +935,9 @@ static int xmm_power_driver_probe(struct platform_device *device)
                if (err < 0)
                        pr_err("%s: enable_irq_wake error\n", __func__);
 
-               pr_debug("%s: AP_WAKE_INIT1\n", __func__);
-               /* ver 1130 or later starts in INIT1 state */
-               ipc_ap_wake_state = IPC_AP_WAKE_INIT1;
+               pr_debug("%s: set state IPC_AP_WAKE_IRQ_READY\n", __func__);
+               /* ver 1130 or later start in IRQ_READY state */
+               ipc_ap_wake_state = IPC_AP_WAKE_IRQ_READY;
        }
 
        /* init work queue */
@@ -990,7 +952,6 @@ static int xmm_power_driver_probe(struct platform_device *device)
        queue_work(workqueue, &xmm_power_drv_data.work);
 
        /* init work objects */
-       INIT_WORK(&init1_work, xmm_power_init1_work);
        INIT_WORK(&init2_work, xmm_power_init2_work);
        INIT_WORK(&L2_resume_work, xmm_power_l2_resume_work);
        INIT_WORK(&autopm_resume_work, xmm_power_autopm_resume);
index 6914089..b9d85ea 100644 (file)
@@ -15,7 +15,7 @@
  */
 
 #ifndef BASEBAND_XMM_POWER_H
-#define BASREBAND_XMM_POWER_H
+#define BASEBAND_XMM_POWER_H
 
 #include <linux/pm.h>
 #include <linux/suspend.h>
@@ -102,9 +102,18 @@ enum baseband_xmm_powerstate_t {
        BBXMM_PS_LAST   = -1,
 };
 
-irqreturn_t xmm_power_ipc_ap_wake_irq(int irq, void *dev_id);
+enum ipc_ap_wake_state_t {
+       IPC_AP_WAKE_UNINIT,
+       IPC_AP_WAKE_IRQ_READY,
+       IPC_AP_WAKE_INIT1,
+       IPC_AP_WAKE_INIT2,
+       IPC_AP_WAKE_L,
+       IPC_AP_WAKE_H,
+};
+
+irqreturn_t xmm_power_ipc_ap_wake_irq(int value);
 
 void baseband_xmm_set_power_status(unsigned int status);
 extern struct xmm_power_data xmm_power_drv_data;
 
-#endif  /* BASREBAND_XMM_POWER_H */
+#endif  /* BASEBAND_XMM_POWER_H */
index 3c6285c..905759d 100644 (file)
@@ -49,16 +49,7 @@ MODULE_PARM_DESC(XYZ,
 
 static struct workqueue_struct *workqueue;
 static bool free_ipc_ap_wake_irq;
-
-static enum {
-       IPC_AP_WAKE_UNINIT,
-       IPC_AP_WAKE_IRQ_READY,
-       IPC_AP_WAKE_INIT1,
-       IPC_AP_WAKE_INIT2,
-       IPC_AP_WAKE_L,
-       IPC_AP_WAKE_H,
-} ipc_ap_wake_state;
-
+static enum ipc_ap_wake_state_t ipc_ap_wake_state;
 
 static irqreturn_t xmm_power2_ipc_ap_wake_irq(int irq, void *dev_id)
 {
@@ -66,8 +57,6 @@ static irqreturn_t xmm_power2_ipc_ap_wake_irq(int irq, void *dev_id)
        struct xmm_power_data *data = dev_id;
        struct baseband_power_platform_data *pdata = data->pdata;
 
-       pr_debug("%s\n", __func__);
-
        /* check for platform data */
        if (!pdata)
                return IRQ_HANDLED;
@@ -79,8 +68,8 @@ static irqreturn_t xmm_power2_ipc_ap_wake_irq(int irq, void *dev_id)
                pr_err("%s - spurious irq\n", __func__);
        else if (ipc_ap_wake_state == IPC_AP_WAKE_IRQ_READY) {
                if (!value) {
-                       pr_debug("%s: IPC_AP_WAKE_INIT1 got falling edge\n",
-                               __func__);
+                       pr_debug("%s: IPC_AP_WAKE_IRQ_READY got falling edge\n",
+                                               __func__);
                        /* go to IPC_AP_WAKE_INIT2 state */
                        ipc_ap_wake_state = IPC_AP_WAKE_INIT2;
                        /* queue work */
@@ -88,7 +77,7 @@ static irqreturn_t xmm_power2_ipc_ap_wake_irq(int irq, void *dev_id)
                                BBXMM_WORK_INIT_FLASHLESS_PM_STEP2;
                        queue_work(workqueue, &data->work);
                } else
-                       pr_debug("%s: IPC_AP_WAKE_INIT1"
+                       pr_debug("%s: IPC_AP_WAKE_IRQ_READY"
                                " wait for falling edge\n", __func__);
        } else {
                if (!value) {
@@ -98,7 +87,7 @@ static irqreturn_t xmm_power2_ipc_ap_wake_irq(int irq, void *dev_id)
                        pr_debug("%s - rising\n", __func__);
                        ipc_ap_wake_state = IPC_AP_WAKE_H;
                }
-               return xmm_power_ipc_ap_wake_irq(irq, dev_id);
+               return xmm_power_ipc_ap_wake_irq(value);
        }
 
        return IRQ_HANDLED;
index 01ade01..2f33d34 100644 (file)
@@ -50,8 +50,6 @@ static int aruba_backlight_init(struct device *dev) {
        ret = gpio_direction_output(aruba_bl_enb, 1);
        if (ret < 0)
                gpio_free(aruba_bl_enb);
-       else
-               tegra_gpio_enable(aruba_bl_enb);
 
        return ret;
 };
index 26b04a9..cf29137 100644 (file)
@@ -224,9 +224,6 @@ static int __init aruba_wifi_init(void)
        gpio_request(ARUBA_WLAN_PWR, "wlan_power");
        gpio_request(ARUBA_WLAN_RST, "wlan_rst");
 
-       tegra_gpio_enable(ARUBA_WLAN_PWR);
-       tegra_gpio_enable(ARUBA_WLAN_RST);
-
        gpio_direction_output(ARUBA_WLAN_PWR, 0);
        gpio_direction_output(ARUBA_WLAN_RST, 0);
 
index f5ba3d7..34891ae 100644 (file)
 
 static void aruba_isl29018_init(void)
 {
-       tegra_gpio_enable(ISL29018_IRQ_GPIO);
        gpio_request(ISL29018_IRQ_GPIO, "isl29018");
        gpio_direction_input(ISL29018_IRQ_GPIO);
 }
 
 static void aruba_akm8975_init(void)
 {
-       tegra_gpio_enable(AKM8975_IRQ_GPIO);
        gpio_request(AKM8975_IRQ_GPIO, "akm8975");
        gpio_direction_input(AKM8975_IRQ_GPIO);
 }
index 4cb9572..1d09f41 100644 (file)
@@ -463,14 +463,6 @@ static struct platform_device *aruba_devices[] __initdata = {
 #endif
 };
 
-static void aruba_keys_init(void)
-{
-       int i;
-
-       for (i = 0; i < ARRAY_SIZE(aruba_keys); i++)
-               tegra_gpio_enable(aruba_keys[i].gpio);
-}
-
 static int __init aruba_touch_init(void)
 {
        return 0;
@@ -523,7 +515,6 @@ static void __init tegra_aruba_init(void)
        aruba_i2c_init();
        aruba_regulator_init();
        aruba_touch_init();
-       aruba_keys_init();
        aruba_usb_init();
        aruba_panel_init();
        aruba_sensors_init();
index d83b19e..875b030 100644 (file)
@@ -123,6 +123,17 @@ int __init cardhu_scroll_init(void)
                .debounce_interval = 10,        \
        }
 
+#define GPIO_SW_KEY(_id, _gpio, _iswake)       \
+       {                                       \
+               .code = _id,                    \
+               .gpio = _gpio,                  \
+               .active_low = 1,                \
+               .desc = #_id,                   \
+               .type = EV_SW,                  \
+               .wakeup = _iswake,              \
+               .debounce_interval = 1,         \
+       }
+
 #define GPIO_IKEY(_id, _irq, _iswake, _deb)    \
        {                                       \
                .code = _id,                    \
@@ -166,6 +177,7 @@ static struct gpio_keys_button cardhu_keys_e1291[] = {
        [4] = GPIO_KEY(KEY_BACK, PQ0, 0),
        [5] = GPIO_KEY(KEY_MENU, PQ1, 0),
        [6] = GPIO_IKEY(KEY_POWER, TPS6591X_IRQ_BASE + TPS6591X_INT_PWRON, 1, 100),
+       [7] = GPIO_SW_KEY(SW_LID, TPS6591X_GPIO_5, 0),
 };
 
 static struct gpio_keys_button cardhu_keys_e1291_a04[] = {
@@ -177,6 +189,7 @@ static struct gpio_keys_button cardhu_keys_e1291_a04[] = {
        [5] = GPIO_KEY(KEY_MENU, PQ1, 0),
        [6] = GPIO_KEY(KEY_RESERVED, PV0, 1),
        [7] = GPIO_IKEY(KEY_POWER, TPS6591X_IRQ_BASE + TPS6591X_INT_PWRON, 1, 100),
+       [8] = GPIO_SW_KEY(SW_LID, TPS6591X_GPIO_5, 0),
 };
 
 static struct gpio_keys_platform_data cardhu_keys_e1291_pdata = {
index e7a1bb0..9595811 100644 (file)
@@ -875,13 +875,9 @@ static int cardhu_dsi_panel_disable(void)
        } else if (is_panel_218) {
                gpio_free(cardhu_dsi_pnl_reset);
        } else if (is_panel_1506) {
-               tegra_gpio_disable(e1506_bl_enb);
                gpio_free(e1506_bl_enb);
-               tegra_gpio_disable(cardhu_dsi_pnl_reset);
                gpio_free(cardhu_dsi_pnl_reset);
-               tegra_gpio_disable(e1506_panel_enb);
                gpio_free(e1506_panel_enb);
-               tegra_gpio_disable(e1506_dsi_vddio);
                gpio_free(e1506_dsi_vddio);
        }
        return err;
@@ -1219,6 +1215,9 @@ static void cardhu_panel_preinit(void)
                cardhu_disp1_out.n_modes = ARRAY_SIZE(cardhu_panel_modes);
                cardhu_disp1_out.enable = cardhu_panel_enable;
                cardhu_disp1_out.disable = cardhu_panel_disable;
+               /* Set height and width in mm. */
+               cardhu_disp1_out.height = 127;
+               cardhu_disp1_out.width = 216;
 
                cardhu_disp1_pdata.fb = &cardhu_fb_data;
        } else {
@@ -1255,9 +1254,13 @@ static void cardhu_panel_preinit(void)
                        cardhu_dsi.n_suspend_cmd =
                                ARRAY_SIZE(dsi_suspend_cmd_1506);
                        cardhu_dsi.dsi_suspend_cmd = dsi_suspend_cmd_1506;
-                       cardhu_dsi.panel_send_dc_frames = true,
+                       cardhu_dsi.panel_send_dc_frames = true;
+                       cardhu_dsi.suspend_aggr = DSI_HOST_SUSPEND_LV0;
                        cardhu_dsi_fb_data.xres = 720;
                        cardhu_dsi_fb_data.yres = 1280;
+                       /* Set height and width in mm. */
+                       cardhu_disp1_out.height = 95;
+                       cardhu_disp1_out.width = 53;
                }
 
                cardhu_disp1_pdata.fb = &cardhu_dsi_fb_data;
@@ -1317,6 +1320,9 @@ int __init cardhu_panel_init(void)
 #else
                cardhu_disp1_out.depth = 24;
 #endif
+               /* Set height and width in mm. */
+               cardhu_disp1_out.height = 127;
+               cardhu_disp1_out.width = 203;
                cardhu_fb_data.xres = 1920;
                cardhu_fb_data.yres = 1200;
 
@@ -1365,7 +1371,6 @@ skip_lvds:
        gpio_direction_input(cardhu_hdmi_hpd);
 
 #if !(DC_CTRL_MODE & TEGRA_DC_OUT_ONE_SHOT_MODE)
-       tegra_gpio_enable(e1506_lcd_te);
        gpio_request(e1506_lcd_te, "lcd_te");
        gpio_direction_input(e1506_lcd_te);
 #endif
index 4788894..fb1be89 100644 (file)
@@ -539,7 +539,10 @@ static struct regulator_consumer_supply fixed_reg_en_3v3_sys_supply[] = {
        REGULATOR_SUPPLY("hvdd_pex_pmu", NULL),
        REGULATOR_SUPPLY("avdd_hdmi", NULL),
        REGULATOR_SUPPLY("vpp_fuse", NULL),
-       REGULATOR_SUPPLY("avdd_usb", NULL),
+       REGULATOR_SUPPLY("avdd_usb", "tegra-udc.0"),
+       REGULATOR_SUPPLY("avdd_usb", "tegra-ehci.0"),
+       REGULATOR_SUPPLY("avdd_usb", "tegra-ehci.1"),
+       REGULATOR_SUPPLY("avdd_usb", "tegra-ehci.2"),
        REGULATOR_SUPPLY("vdd_ddr_rx", NULL),
        REGULATOR_SUPPLY("vcore_nand", NULL),
        REGULATOR_SUPPLY("hvdd_sata", NULL),
@@ -1159,25 +1162,30 @@ int __init cardhu_suspend_init(void)
                if (board_info.fab == BOARD_FAB_A03)
                        cardhu_suspend_data.corereq_high = true;
                if (board_info.fab < BOARD_FAB_A03)
-                       /* post E1291-A02 revisions WAKE19/USB1-VBUS wake supported */
+                       /* post E1291-A02 revisions VBUS wake supported */
                        tegra_disable_wake_source(TEGRA_WAKE_USB1_VBUS);
                break;
        case BOARD_E1198:
                if (board_info.fab < BOARD_FAB_A02)
-                       /* post E1198-A01 revisions WAKE19/USB1-VBUS wake supported */
+                       /* post E1198-A01 revisions VBUS wake supported */
                        tegra_disable_wake_source(TEGRA_WAKE_USB1_VBUS);
                break;
        case BOARD_PM269:
        case BOARD_PM305:
        case BOARD_PM311:
                break;
-       case BOARD_E1187:
-       case BOARD_E1186:
        case BOARD_E1256:
        case BOARD_E1257:
                cardhu_suspend_data.cpu_timer = 5000;
                cardhu_suspend_data.cpu_off_timer = 5000;
                break;
+       case BOARD_E1187:
+       case BOARD_E1186:
+               /* VBUS repeated wakeup seen on older E1186 boards */
+               tegra_disable_wake_source(TEGRA_WAKE_USB1_VBUS);
+               cardhu_suspend_data.cpu_timer = 5000;
+               cardhu_suspend_data.cpu_off_timer = 5000;
+               break;
        default:
                break;
        }
index 66876ab..284a0e7 100644 (file)
@@ -28,7 +28,7 @@
 #include <mach/irqs.h>
 #include <mach/iomap.h>
 #include <mach/sdhci.h>
-#include <mach/gpio-tegra.h>
+#include <mach/io_dpd.h>
 
 #include "gpio-names.h"
 #include "board.h"
@@ -241,11 +241,31 @@ static int cardhu_wifi_set_carddetect(int val)
 
 static int cardhu_wifi_power(int on)
 {
+       struct tegra_io_dpd *sd_dpd;
+
        pr_debug("%s: %d\n", __func__, on);
+
+       /*
+        * FIXME : we need to revisit IO DPD code
+        * on how should multiple pins under DPD get controlled
+        *
+        * cardhu GPIO WLAN enable is part of SDMMC3 pin group
+        */
+       sd_dpd = tegra_io_dpd_get(&tegra_sdhci_device2.dev);
+       if (sd_dpd) {
+               mutex_lock(&sd_dpd->delay_lock);
+               tegra_io_dpd_disable(sd_dpd);
+               mutex_unlock(&sd_dpd->delay_lock);
+       }
        gpio_set_value(CARDHU_WLAN_PWR, on);
        mdelay(100);
        gpio_set_value(CARDHU_WLAN_RST, on);
        mdelay(200);
+       if (sd_dpd) {
+               mutex_lock(&sd_dpd->delay_lock);
+               tegra_io_dpd_enable(sd_dpd);
+               mutex_unlock(&sd_dpd->delay_lock);
+       }
 
        return 0;
 }
index 37debb7..3888f3c 100644 (file)
@@ -1041,13 +1041,6 @@ static struct tegra_usb_platform_data tegra_ehci2_hsic_xmm_pdata = {
                .remote_wakeup_supported = false,
                .power_off_on_suspend = false,
        },
-       .u_cfg.hsic = {
-               .sync_start_delay = 9,
-               .idle_wait_delay = 17,
-               .term_range_adj = 0,
-               .elastic_underrun_limit = 16,
-               .elastic_overrun_limit = 16,
-       },
        .ops = &hsic_xmm_plat_ops,
 };
 #endif
@@ -1068,10 +1061,6 @@ void hsic_platform_open(void)
                gpio_direction_output(hsic_enable_gpio, 0 /* deasserted */);
        if (!reset_gpio)
                gpio_direction_output(hsic_reset_gpio, 0 /* asserted */);
-       if (!enable_gpio)
-               tegra_gpio_enable(hsic_enable_gpio);
-       if (!reset_gpio)
-               tegra_gpio_enable(hsic_reset_gpio);
        /* keep hsic reset asserted for 1 ms */
        udelay(1000);
        /* enable (power on) hsic */
@@ -1131,13 +1120,6 @@ static struct tegra_usb_platform_data tegra_ehci2_hsic_pdata = {
                .remote_wakeup_supported = false,
                .power_off_on_suspend = false,
        },
-       .u_cfg.hsic = {
-               .sync_start_delay = 9,
-               .idle_wait_delay = 17,
-               .term_range_adj = 0,
-               .elastic_underrun_limit = 16,
-               .elastic_overrun_limit = 16,
-       },
        .ops = &hsic_plat_ops,
 };
 
@@ -1457,6 +1439,11 @@ static void __init tegra_cardhu_reserve(void)
        tegra_ram_console_debug_reserve(SZ_1M);
 }
 
+static const char *cardhu_dt_board_compat[] = {
+       "nvidia,cardhu",
+       NULL
+};
+
 MACHINE_START(CARDHU, "cardhu")
        .atag_offset    = 0x100,
        .soc            = &tegra_soc_desc,
@@ -1468,4 +1455,5 @@ MACHINE_START(CARDHU, "cardhu")
        .timer          = &tegra_timer,
        .init_machine   = tegra_cardhu_init,
        .restart        = tegra_assert_system_reset,
-MACHINE_END
+       .dt_compat      = cardhu_dt_board_compat,
+MACHaNE_END
index d082076..759e69b 100644 (file)
@@ -231,7 +231,7 @@ extern struct tegra_uart_platform_data cardhu_irda_pdata;
 #define MPU_GYRO_BUS_NUM       2
 #define MPU_GYRO_ORIENTATION   { 0, -1, 0, -1, 0, 0, 0, 0, -1 }
 #define MPU_ACCEL_NAME         "kxtf9"
-#define MPU_ACCEL_IRQ_GPIO     TEGRA_GPIO_PL1
+#define MPU_ACCEL_IRQ_GPIO     0 /* DISABLE ACCELIRQ:  TEGRA_GPIO_PL1 */
 #define MPU_ACCEL_ADDR         0x0F
 #define MPU_ACCEL_BUS_NUM      2
 #define MPU_ACCEL_ORIENTATION  { 0, -1, 0, -1, 0, 0, 0, 0, -1 }
index 71aff6e..52da73c 100644 (file)
@@ -1,7 +1,7 @@
 /*
  * arch/arm/mach-tegra/board-enterprise-pinmux.c
  *
- * Copyright (C) 2011 NVIDIA Corporation
+ * Copyright (C) 2011-2012, NVIDIA CORPORATION. All rights reserved.
  *
  * This software is licensed under the terms of the GNU General Public
  * License version 2, as published by the Free Software Foundation, and
@@ -160,7 +160,6 @@ static __initdata struct tegra_pingroup_config enterprise_pinmux_common[] = {
 
        /* SDMMC4 pinmux */
        DEFAULT_PINMUX(SDMMC4_CLK,      SDMMC4,          NORMAL,     NORMAL,     INPUT),
-       DEFAULT_PINMUX(SDMMC4_CMD,      SDMMC4,          PULL_UP,    NORMAL,     INPUT),
        DEFAULT_PINMUX(SDMMC4_DAT0,     SDMMC4,          PULL_UP,    NORMAL,     INPUT),
        DEFAULT_PINMUX(SDMMC4_DAT1,     SDMMC4,          PULL_UP,    NORMAL,     INPUT),
        DEFAULT_PINMUX(SDMMC4_DAT2,     SDMMC4,          PULL_UP,    NORMAL,     INPUT),
@@ -199,47 +198,7 @@ static __initdata struct tegra_pingroup_config enterprise_pinmux_common[] = {
        DEFAULT_PINMUX(ULPI_DATA5,      ULPI,           NORMAL,    NORMAL,     INPUT),
        DEFAULT_PINMUX(ULPI_DATA6,      ULPI,           NORMAL,    NORMAL,     INPUT),
        DEFAULT_PINMUX(ULPI_DATA7,      ULPI,           NORMAL,    NORMAL,     INPUT),
-       DEFAULT_PINMUX(ULPI_CLK,        ULPI,           NORMAL,    NORMAL,     INPUT),
-       DEFAULT_PINMUX(ULPI_DIR,        ULPI,           NORMAL,    NORMAL,     OUTPUT),
-       DEFAULT_PINMUX(ULPI_NXT,        ULPI,           NORMAL,    NORMAL,     OUTPUT),
-       DEFAULT_PINMUX(ULPI_STP,        ULPI,           NORMAL,    NORMAL,     INPUT),
-       DEFAULT_PINMUX(DAP3_FS,         I2S2,            NORMAL,    NORMAL,     INPUT),
-       DEFAULT_PINMUX(DAP3_DIN,        I2S2,            NORMAL,    NORMAL,     INPUT),
-       DEFAULT_PINMUX(DAP3_DOUT,       I2S2,            NORMAL,    NORMAL,     INPUT),
-       DEFAULT_PINMUX(DAP3_SCLK,       I2S2,            NORMAL,    NORMAL,     INPUT),
        DEFAULT_PINMUX(GPIO_PV2,        RSVD1,           NORMAL,    NORMAL,     OUTPUT),
-       DEFAULT_PINMUX(GPIO_PV3,        RSVD1,           NORMAL,    NORMAL,     OUTPUT),
-       DEFAULT_PINMUX(LCD_PWR1,        DISPLAYA,        NORMAL,    NORMAL,     OUTPUT),
-       DEFAULT_PINMUX(LCD_PWR2,        DISPLAYA,        NORMAL,    NORMAL,     INPUT),
-       DEFAULT_PINMUX(LCD_CS0_N,       DISPLAYA,        NORMAL,    NORMAL,     INPUT),
-       DEFAULT_PINMUX(LCD_DC0,         DISPLAYA,        NORMAL,    NORMAL,     INPUT),
-       DEFAULT_PINMUX(LCD_DE,          DISPLAYA,        NORMAL,    NORMAL,     INPUT),
-       DEFAULT_PINMUX(LCD_D0,          DISPLAYA,        NORMAL,    NORMAL,     OUTPUT),
-       DEFAULT_PINMUX(LCD_D1,          DISPLAYA,        NORMAL,    NORMAL,     OUTPUT),
-       DEFAULT_PINMUX(LCD_D2,          DISPLAYA,        NORMAL,    NORMAL,     INPUT),
-       DEFAULT_PINMUX(LCD_D3,          DISPLAYA,        NORMAL,    NORMAL,     OUTPUT),
-       DEFAULT_PINMUX(LCD_D4,          DISPLAYA,        NORMAL,    NORMAL,     INPUT),
-       DEFAULT_PINMUX(LCD_D5,          DISPLAYA,        NORMAL,    NORMAL,     INPUT),
-       DEFAULT_PINMUX(LCD_D6,          RSVD1,           NORMAL,    NORMAL,     INPUT),
-       DEFAULT_PINMUX(LCD_D7,          RSVD1,           NORMAL,    NORMAL,     OUTPUT),
-       DEFAULT_PINMUX(LCD_D8,          DISPLAYA,        NORMAL,    TRISTATE,   INPUT),
-       DEFAULT_PINMUX(LCD_D9,          DISPLAYA,        NORMAL,    NORMAL,     INPUT),
-       DEFAULT_PINMUX(LCD_D11,         DISPLAYA,        NORMAL,    NORMAL,     INPUT),
-       DEFAULT_PINMUX(LCD_D12,         DISPLAYA,        NORMAL,    NORMAL,     INPUT),
-       DEFAULT_PINMUX(LCD_D13,         DISPLAYA,        NORMAL,    NORMAL,     INPUT),
-       DEFAULT_PINMUX(LCD_D14,         DISPLAYA,        NORMAL,    NORMAL,     INPUT),
-       DEFAULT_PINMUX(LCD_D15,         DISPLAYA,        NORMAL,    NORMAL,     INPUT),
-       DEFAULT_PINMUX(LCD_D16,         DISPLAYA,        NORMAL,    NORMAL,     INPUT),
-       DEFAULT_PINMUX(LCD_D17,         DISPLAYA,        NORMAL,    NORMAL,     INPUT),
-       DEFAULT_PINMUX(LCD_D18,         DISPLAYA,        NORMAL,    NORMAL,     INPUT),
-       DEFAULT_PINMUX(LCD_D19,         DISPLAYA,        NORMAL,    NORMAL,     INPUT),
-       DEFAULT_PINMUX(LCD_D20,         DISPLAYA,        NORMAL,    NORMAL,     INPUT),
-       DEFAULT_PINMUX(LCD_D21,         DISPLAYA,        NORMAL,    NORMAL,     INPUT),
-       DEFAULT_PINMUX(LCD_D22,         RSVD1,           NORMAL,    NORMAL,     INPUT),
-       DEFAULT_PINMUX(LCD_D23,         DISPLAYA,        NORMAL,    NORMAL,     INPUT),
-       DEFAULT_PINMUX(LCD_CS1_N,       DISPLAYA,        NORMAL,    NORMAL,     INPUT),
-       DEFAULT_PINMUX(LCD_M1,          DISPLAYA,        NORMAL,    NORMAL,     OUTPUT),
-       DEFAULT_PINMUX(LCD_DC1,         DISPLAYA,        NORMAL,    NORMAL,     INPUT),
        DEFAULT_PINMUX(VI_D0,           RSVD1,           NORMAL,    NORMAL,     INPUT),
        DEFAULT_PINMUX(VI_D1,           SDMMC2,          NORMAL,    NORMAL,     INPUT),
        DEFAULT_PINMUX(VI_D2,           SDMMC2,          NORMAL,    NORMAL,     INPUT),
@@ -250,84 +209,27 @@ static __initdata struct tegra_pingroup_config enterprise_pinmux_common[] = {
        DEFAULT_PINMUX(VI_D10,          RSVD1,           NORMAL,    NORMAL,     INPUT),
        DEFAULT_PINMUX(VI_MCLK,         VI,              PULL_UP,   NORMAL,     INPUT),
 
-       DEFAULT_PINMUX(UART2_RXD,       IRDA,            NORMAL,    NORMAL,     INPUT),
-       DEFAULT_PINMUX(UART2_TXD,       IRDA,            NORMAL,    NORMAL,     OUTPUT),
-       DEFAULT_PINMUX(UART2_RTS_N,     UARTB,           NORMAL,    NORMAL,     OUTPUT),
-       DEFAULT_PINMUX(UART2_CTS_N,     UARTB,           NORMAL,    NORMAL,     INPUT),
-       DEFAULT_PINMUX(UART3_TXD,       UARTC,           NORMAL,    NORMAL,     OUTPUT),
-       DEFAULT_PINMUX(UART3_RXD,       UARTC,           NORMAL,    NORMAL,     INPUT),
-       DEFAULT_PINMUX(UART3_CTS_N,     UARTC,           NORMAL,    NORMAL,     INPUT),
-       DEFAULT_PINMUX(UART3_RTS_N,     UARTC,           NORMAL,    NORMAL,     OUTPUT),
-       DEFAULT_PINMUX(GPIO_PU0,        UARTA,           NORMAL,    NORMAL,     OUTPUT),
-       DEFAULT_PINMUX(GPIO_PU1,        UARTA,           NORMAL,    NORMAL,     INPUT),
-       DEFAULT_PINMUX(GPIO_PU2,        UARTA,           NORMAL,    NORMAL,     INPUT),
-       DEFAULT_PINMUX(GPIO_PU3,        UARTA,           NORMAL,    NORMAL,     OUTPUT),
-       DEFAULT_PINMUX(GPIO_PU4,        PWM1,            NORMAL,    NORMAL,     OUTPUT),
-       DEFAULT_PINMUX(GPIO_PU5,        PWM2,            NORMAL,    NORMAL,     INPUT),
-       DEFAULT_PINMUX(GPIO_PU6,        PWM3,            NORMAL,    NORMAL,     INPUT),
-       DEFAULT_PINMUX(DAP4_FS,         I2S3,            NORMAL,    NORMAL,     INPUT),
-       DEFAULT_PINMUX(DAP4_DIN,        I2S3,            NORMAL,    NORMAL,     INPUT),
-       DEFAULT_PINMUX(DAP4_DOUT,       I2S3,            NORMAL,    NORMAL,     INPUT),
-       DEFAULT_PINMUX(DAP4_SCLK,       I2S3,            NORMAL,    NORMAL,     INPUT),
        DEFAULT_PINMUX(GMI_AD8,         PWM0,            NORMAL,    NORMAL,     OUTPUT),
        DEFAULT_PINMUX(GMI_AD9,         NAND,            NORMAL,    NORMAL,     OUTPUT),
        DEFAULT_PINMUX(GMI_AD10,        NAND,            NORMAL,    NORMAL,     OUTPUT),
 #if IS_EXTERNAL_PWM
        DEFAULT_PINMUX(GMI_AD11,        PWM3,            NORMAL,    NORMAL,     OUTPUT),
 #endif
-       DEFAULT_PINMUX(GMI_A16,         UARTD,           NORMAL,    NORMAL,     OUTPUT),
-       DEFAULT_PINMUX(GMI_A17,         UARTD,           NORMAL,    NORMAL,     INPUT),
-       DEFAULT_PINMUX(GMI_A18,         UARTD,           NORMAL,    NORMAL,     INPUT),
-       DEFAULT_PINMUX(GMI_A19,         UARTD,           NORMAL,    NORMAL,     OUTPUT),
-       DEFAULT_PINMUX(CAM_MCLK,        VI_ALT2,         NORMAL,    NORMAL,     INPUT),
-       DEFAULT_PINMUX(GPIO_PCC1,       RSVD1,           NORMAL,    NORMAL,     INPUT),
-       DEFAULT_PINMUX(GPIO_PBB0,       RSVD1,           NORMAL,    NORMAL,     INPUT),
-       DEFAULT_PINMUX(GPIO_PBB3,       VGP3,            NORMAL,    NORMAL,     INPUT),
-       DEFAULT_PINMUX(GPIO_PBB7,       I2S4,            NORMAL,    NORMAL,     INPUT),
-       DEFAULT_PINMUX(GPIO_PCC2,       I2S4,            NORMAL,    NORMAL,     INPUT),
        DEFAULT_PINMUX(JTAG_RTCK,       RTCK,            NORMAL,    NORMAL,     OUTPUT),
        DEFAULT_PINMUX(KB_ROW0,         KBC,             PULL_UP,   NORMAL,     INPUT),
        DEFAULT_PINMUX(KB_ROW1,         KBC,             PULL_UP,   NORMAL,     INPUT),
        DEFAULT_PINMUX(KB_ROW2,         KBC,             PULL_UP,   NORMAL,     INPUT),
        DEFAULT_PINMUX(KB_ROW3,         KBC,             PULL_UP,   NORMAL,     INPUT),
-       DEFAULT_PINMUX(KB_ROW10,        KBC,             NORMAL,    NORMAL,     INPUT),
-       DEFAULT_PINMUX(KB_ROW12,        KBC,             NORMAL,    NORMAL,     INPUT),
        DEFAULT_PINMUX(KB_COL0,         KBC,             PULL_UP,   NORMAL,     INPUT),
        DEFAULT_PINMUX(KB_COL1,         KBC,             PULL_UP,   NORMAL,     INPUT),
        DEFAULT_PINMUX(KB_COL2,         KBC,             PULL_UP,   NORMAL,     INPUT),
-       DEFAULT_PINMUX(KB_COL3,         KBC,             PULL_UP,   NORMAL,     INPUT),
        DEFAULT_PINMUX(KB_COL4,         KBC,             PULL_UP,   NORMAL,     INPUT),
        DEFAULT_PINMUX(KB_COL5,         KBC,             PULL_UP,   NORMAL,     INPUT),
-       DEFAULT_PINMUX(GPIO_PV0,        RSVD,            PULL_UP,   NORMAL,     INPUT),
        DEFAULT_PINMUX(CLK_32K_OUT,     BLINK,           PULL_DOWN, TRISTATE,   OUTPUT),
        DEFAULT_PINMUX(SYS_CLK_REQ,     SYSCLK,          NORMAL,    NORMAL,     OUTPUT),
        DEFAULT_PINMUX(OWR,             OWR,             NORMAL,    NORMAL,     INPUT),
-       DEFAULT_PINMUX(DAP1_FS,         I2S0,            NORMAL,    NORMAL,     INPUT),
-       DEFAULT_PINMUX(DAP1_DIN,        I2S0,            NORMAL,    NORMAL,     INPUT),
-       DEFAULT_PINMUX(DAP1_DOUT,       I2S0,            NORMAL,    NORMAL,     INPUT),
-       DEFAULT_PINMUX(DAP1_SCLK,       I2S0,            NORMAL,    NORMAL,     INPUT),
        DEFAULT_PINMUX(CLK1_REQ,        DAP,             NORMAL,    NORMAL,     INPUT),
-       DEFAULT_PINMUX(CLK1_OUT,        EXTPERIPH1,      NORMAL,    NORMAL,     INPUT),
-#if 0 /* For HDA realtek Codec */
-       DEFAULT_PINMUX(SPDIF_IN,        DAP2,            PULL_DOWN, NORMAL,     INPUT),
-#else
-       DEFAULT_PINMUX(SPDIF_IN,        SPDIF,           NORMAL,    NORMAL,     INPUT),
-#endif
-#if 0 /* For HDA realtek Codec */
-       DEFAULT_PINMUX(DAP2_FS,         HDA,             PULL_DOWN, NORMAL,     INPUT),
-       DEFAULT_PINMUX(DAP2_DIN,        HDA,             PULL_DOWN, NORMAL,     INPUT),
-       DEFAULT_PINMUX(DAP2_DOUT,       HDA,             PULL_DOWN, NORMAL,     INPUT),
-       DEFAULT_PINMUX(DAP2_SCLK,       HDA,             PULL_DOWN, NORMAL,     INPUT),
-#else
-       DEFAULT_PINMUX(DAP2_FS,         I2S1,            NORMAL,    NORMAL,     INPUT),
-       DEFAULT_PINMUX(DAP2_DIN,        I2S1,            NORMAL,    NORMAL,     INPUT),
-       DEFAULT_PINMUX(DAP2_DOUT,       I2S1,            NORMAL,    NORMAL,     INPUT),
-       DEFAULT_PINMUX(DAP2_SCLK,       I2S1,            NORMAL,    NORMAL,     INPUT),
-#endif
        DEFAULT_PINMUX(SPI2_CS1_N,      SPI2,            PULL_UP,   NORMAL,     INPUT),
-       DEFAULT_PINMUX(SPI1_MOSI,       SPI1,            NORMAL,    NORMAL,     INPUT),
-       DEFAULT_PINMUX(SPI1_SCK,        SPI1,            NORMAL,    NORMAL,     INPUT),
-       DEFAULT_PINMUX(SPI1_MISO,       SPI1,            NORMAL,    NORMAL,     INPUT),
        DEFAULT_PINMUX(PEX_L0_PRSNT_N,  PCIE,            NORMAL,    NORMAL,     INPUT),
        DEFAULT_PINMUX(PEX_L0_RST_N,    PCIE,            NORMAL,    NORMAL,     OUTPUT),
        DEFAULT_PINMUX(PEX_L0_CLKREQ_N, PCIE,            NORMAL,    NORMAL,     INPUT),
@@ -340,25 +242,8 @@ static __initdata struct tegra_pingroup_config enterprise_pinmux_common[] = {
        DEFAULT_PINMUX(PEX_L2_CLKREQ_N, PCIE,            NORMAL,    NORMAL,     INPUT),
        CEC_PINMUX(HDMI_CEC,            CEC,             NORMAL,    TRISTATE,   OUTPUT, DEFAULT, DISABLE),
        DEFAULT_PINMUX(HDMI_INT,        RSVD0,           NORMAL,    TRISTATE,   INPUT),
-
-       /* Gpios */
-       /* SDMMC1 CD gpio */
-       DEFAULT_PINMUX(GMI_IORDY,       RSVD1,           PULL_UP,   NORMAL,     INPUT),
-       /* SDMMC1 WP gpio */
        DEFAULT_PINMUX(VI_D11,          RSVD1,           PULL_UP,   NORMAL,     INPUT),
-
-       /* Touch panel GPIO */
-       /* Touch IRQ */
-       DEFAULT_PINMUX(GMI_AD12,        NAND,            NORMAL,    NORMAL,     INPUT),
-
-       /* Touch RESET */
-       DEFAULT_PINMUX(GMI_AD14,        NAND,            NORMAL,    NORMAL,     INPUT),
-
        DEFAULT_PINMUX(GMI_AD15,        NAND,            PULL_UP,   TRISTATE,   INPUT),
-
-       /* Power rails GPIO */
-       DEFAULT_PINMUX(KB_ROW8,         KBC,             PULL_UP,   NORMAL,     INPUT),
-
        VI_PINMUX(VI_D6,           VI,              NORMAL,    NORMAL,     OUTPUT, DISABLE, DISABLE),
        VI_PINMUX(VI_D8,           SDMMC2,          NORMAL,    NORMAL,     INPUT,  DISABLE, DISABLE),
        VI_PINMUX(VI_D9,           SDMMC2,          NORMAL,    NORMAL,     INPUT,  DISABLE, DISABLE),
@@ -370,6 +255,97 @@ static __initdata struct tegra_pingroup_config enterprise_pinmux_common[] = {
 static __initdata struct tegra_pingroup_config enterprise_pinmux_a03[] = {
        DEFAULT_PINMUX(LCD_PWR0,        DISPLAYA,        NORMAL,    NORMAL,     OUTPUT),
        DEFAULT_PINMUX(LCD_D10,         DISPLAYA,        NORMAL,    NORMAL,     OUTPUT),
+       DEFAULT_PINMUX(SDMMC4_CMD,      SDMMC4,          NORMAL,    NORMAL,     INPUT),
+       DEFAULT_PINMUX(ULPI_CLK,        ULPI,            NORMAL,    NORMAL,     INPUT),
+       DEFAULT_PINMUX(ULPI_DIR,        ULPI,            NORMAL,    NORMAL,     OUTPUT),
+       DEFAULT_PINMUX(ULPI_NXT,        ULPI,            NORMAL,    TRISTATE,   OUTPUT),
+       DEFAULT_PINMUX(ULPI_STP,        ULPI,            NORMAL,    NORMAL,     INPUT),
+       DEFAULT_PINMUX(DAP3_FS,         I2S2,            NORMAL,    NORMAL,   INPUT),
+       DEFAULT_PINMUX(DAP3_DIN,        I2S2,            NORMAL,    NORMAL,   INPUT),
+       DEFAULT_PINMUX(DAP3_DOUT,       I2S2,            NORMAL,    NORMAL,     OUTPUT),
+       DEFAULT_PINMUX(DAP3_SCLK,       I2S2,            NORMAL,    NORMAL,     INPUT),
+       DEFAULT_PINMUX(GPIO_PV3,        RSVD1,           PULL_DOWN, TRISTATE,   OUTPUT),
+       DEFAULT_PINMUX(LCD_PWR1,        DISPLAYA,        NORMAL,    TRISTATE,     OUTPUT),
+       DEFAULT_PINMUX(LCD_PWR2,        DISPLAYA,        NORMAL,    TRISTATE,     INPUT),
+       DEFAULT_PINMUX(LCD_CS0_N,       DISPLAYA,        NORMAL,    NORMAL,     OUTPUT),
+       DEFAULT_PINMUX(LCD_DC0,         DISPLAYA,        PULL_DOWN, TRISTATE,   OUTPUT),
+       DEFAULT_PINMUX(LCD_DE,          DISPLAYA,        NORMAL,    TRISTATE,   INPUT),
+       DEFAULT_PINMUX(LCD_D0,          DISPLAYA,        NORMAL,    NORMAL,     OUTPUT),
+       DEFAULT_PINMUX(LCD_D1,          DISPLAYA,        NORMAL,    NORMAL,     OUTPUT),
+       DEFAULT_PINMUX(LCD_D2,          DISPLAYA,        NORMAL,    NORMAL,     OUTPUT),
+       DEFAULT_PINMUX(LCD_D3,          DISPLAYA,        NORMAL,    NORMAL,     OUTPUT),
+       DEFAULT_PINMUX(LCD_D4,          DISPLAYA,        NORMAL,    NORMAL,     OUTPUT),
+       DEFAULT_PINMUX(LCD_D5,          DISPLAYA,        PULL_DOWN, TRISTATE,   OUTPUT),
+       DEFAULT_PINMUX(LCD_D6,          RSVD1,           NORMAL,    NORMAL,     OUTPUT),
+       DEFAULT_PINMUX(LCD_D7,          RSVD1,           NORMAL,    NORMAL,     OUTPUT),
+       DEFAULT_PINMUX(LCD_D8,          DISPLAYA,        NORMAL,    TRISTATE,   INPUT),
+       DEFAULT_PINMUX(LCD_D9,          DISPLAYA,        NORMAL,    NORMAL,     OUTPUT),
+       DEFAULT_PINMUX(LCD_D11,         DISPLAYA,        PULL_DOWN, TRISTATE,   OUTPUT),
+       DEFAULT_PINMUX(LCD_D12,         DISPLAYA,        NORMAL,    NORMAL,     OUTPUT),
+       DEFAULT_PINMUX(LCD_D13,         DISPLAYA,        NORMAL,    NORMAL,     OUTPUT),
+       DEFAULT_PINMUX(LCD_D14,         DISPLAYA,        NORMAL,    NORMAL,     OUTPUT),
+       DEFAULT_PINMUX(LCD_D15,         DISPLAYA,        NORMAL,    NORMAL,     OUTPUT),
+       DEFAULT_PINMUX(LCD_D16,         DISPLAYA,        NORMAL,    NORMAL,     OUTPUT),
+       DEFAULT_PINMUX(LCD_D17,         DISPLAYA,        NORMAL,    NORMAL,     OUTPUT),
+       DEFAULT_PINMUX(LCD_D18,         DISPLAYA,        NORMAL,    NORMAL,     OUTPUT),
+       DEFAULT_PINMUX(LCD_D19,         DISPLAYA,        NORMAL,    NORMAL,     OUTPUT),
+       DEFAULT_PINMUX(LCD_D20,         DISPLAYA,        PULL_DOWN, TRISTATE,   OUTPUT),
+       DEFAULT_PINMUX(LCD_D21,         DISPLAYA,        NORMAL,    NORMAL,     OUTPUT),
+       DEFAULT_PINMUX(LCD_D22,         RSVD1,           NORMAL,    NORMAL,     OUTPUT),
+       DEFAULT_PINMUX(LCD_D23,         DISPLAYA,        NORMAL,    NORMAL,     OUTPUT),
+       DEFAULT_PINMUX(LCD_CS1_N,       DISPLAYA,        NORMAL,    NORMAL,     OUTPUT),
+       DEFAULT_PINMUX(LCD_M1,          DISPLAYA,        NORMAL,    NORMAL,     OUTPUT),
+       DEFAULT_PINMUX(LCD_DC1,         DISPLAYA,        PULL_DOWN, TRISTATE,   OUTPUT),
+       DEFAULT_PINMUX(UART2_RXD,       IRDA,            NORMAL,    TRISTATE,   INPUT),
+       DEFAULT_PINMUX(UART2_TXD,       IRDA,            NORMAL,    NORMAL,     OUTPUT),
+       DEFAULT_PINMUX(UART2_RTS_N,     UARTB,           NORMAL,    NORMAL,     OUTPUT),
+       DEFAULT_PINMUX(UART2_CTS_N,     UARTB,           NORMAL,    TRISTATE,   INPUT),
+       DEFAULT_PINMUX(UART3_TXD,       UARTC,           NORMAL,    NORMAL,     OUTPUT),
+       DEFAULT_PINMUX(UART3_RXD,       UARTC,           NORMAL,    TRISTATE,   INPUT),
+       DEFAULT_PINMUX(UART3_CTS_N,     UARTC,           NORMAL,    TRISTATE,   INPUT),
+       DEFAULT_PINMUX(UART3_RTS_N,     UARTC,           NORMAL,    NORMAL,     OUTPUT),
+       DEFAULT_PINMUX(GPIO_PU0,        UARTA,           NORMAL,    NORMAL,     OUTPUT),
+       DEFAULT_PINMUX(GPIO_PU1,        UARTA,           NORMAL,    TRISTATE,   INPUT),
+       DEFAULT_PINMUX(GPIO_PU2,        UARTA,           NORMAL,    TRISTATE,   INPUT),
+       DEFAULT_PINMUX(GPIO_PU3,        UARTA,           NORMAL,    NORMAL,     OUTPUT),
+       DEFAULT_PINMUX(GPIO_PU4,        PWM1,            PULL_DOWN, TRISTATE,   OUTPUT),
+       DEFAULT_PINMUX(GPIO_PU5,        PWM2,            NORMAL,    TRISTATE,   INPUT),
+       DEFAULT_PINMUX(GPIO_PU6,        PWM3,            NORMAL,    TRISTATE,   INPUT),
+       DEFAULT_PINMUX(DAP4_FS,         I2S3,            NORMAL,    NORMAL,     OUTPUT),
+       DEFAULT_PINMUX(DAP4_DIN,        I2S3,            NORMAL,    TRISTATE,   INPUT),
+       DEFAULT_PINMUX(DAP4_DOUT,       I2S3,            NORMAL,    NORMAL,     OUTPUT),
+       DEFAULT_PINMUX(DAP4_SCLK,       I2S3,            NORMAL,    NORMAL,     OUTPUT),
+       DEFAULT_PINMUX(GMI_A16,         UARTD,           NORMAL,    NORMAL,     OUTPUT),
+       DEFAULT_PINMUX(GMI_A17,         UARTD,           NORMAL,    TRISTATE,   INPUT),
+       DEFAULT_PINMUX(GMI_A18,         UARTD,           NORMAL,    TRISTATE,   INPUT),
+       DEFAULT_PINMUX(GMI_A19,         UARTD,           NORMAL,    NORMAL,     OUTPUT),
+       DEFAULT_PINMUX(CAM_MCLK,        VI_ALT2,         NORMAL,    NORMAL,     OUTPUT),
+       DEFAULT_PINMUX(GPIO_PCC1,       I2S4,            NORMAL,    NORMAL,     INPUT),
+       DEFAULT_PINMUX(GPIO_PBB0,       I2S4,            NORMAL,    NORMAL,     INPUT),
+       DEFAULT_PINMUX(GPIO_PBB3,       VGP3,            NORMAL,    NORMAL,     OUTPUT),
+       DEFAULT_PINMUX(GPIO_PBB7,       I2S4,            NORMAL,    NORMAL,     INPUT),
+       DEFAULT_PINMUX(GPIO_PCC2,       I2S4,            NORMAL,    NORMAL,     INPUT),
+       DEFAULT_PINMUX(KB_ROW10,        KBC,             NORMAL,    TRISTATE,   INPUT),
+       DEFAULT_PINMUX(KB_ROW12,        KBC,             NORMAL,    TRISTATE,   INPUT),
+       DEFAULT_PINMUX(KB_COL3,         KBC,             PULL_DOWN, TRISTATE,   OUTPUT),
+       DEFAULT_PINMUX(GPIO_PV0,        RSVD,            PULL_UP,   TRISTATE,   INPUT),
+       DEFAULT_PINMUX(DAP1_FS,         I2S0,            NORMAL,    NORMAL,     INPUT),
+       DEFAULT_PINMUX(DAP1_DIN,        I2S0,            NORMAL,    TRISTATE,   INPUT),
+       DEFAULT_PINMUX(DAP1_DOUT,       I2S0,            NORMAL,    NORMAL,     OUTPUT),
+       DEFAULT_PINMUX(DAP1_SCLK,       I2S0,            NORMAL,    NORMAL,     INPUT),
+       DEFAULT_PINMUX(CLK1_OUT,        EXTPERIPH1,      NORMAL,    NORMAL,     OUTPUT),
+       DEFAULT_PINMUX(SPDIF_IN,        SPDIF,           NORMAL,    TRISTATE,   INPUT),
+       DEFAULT_PINMUX(DAP2_FS,         I2S1,            NORMAL,    NORMAL,     INPUT),
+       DEFAULT_PINMUX(DAP2_DIN,        I2S1,            NORMAL,    TRISTATE,   INPUT),
+       DEFAULT_PINMUX(DAP2_DOUT,       I2S1,            NORMAL,    NORMAL,     OUTPUT),
+       DEFAULT_PINMUX(DAP2_SCLK,       I2S1,            NORMAL,    NORMAL,     INPUT),
+       DEFAULT_PINMUX(SPI1_MOSI,       SPI1,            PULL_DOWN, TRISTATE,   OUTPUT),
+       DEFAULT_PINMUX(SPI1_SCK,        SPI1,            PULL_DOWN, TRISTATE,   OUTPUT),
+       DEFAULT_PINMUX(SPI1_MISO,       SPI1,            PULL_DOWN, TRISTATE,   OUTPUT),
+       DEFAULT_PINMUX(GMI_IORDY,       RSVD1,           PULL_UP,   TRISTATE,   INPUT),
+       DEFAULT_PINMUX(GMI_AD12,        NAND,            NORMAL,    TRISTATE,   INPUT),
+       DEFAULT_PINMUX(GMI_AD14,        NAND,            NORMAL,    TRISTATE,   INPUT),
+       DEFAULT_PINMUX(KB_ROW8,         KBC,             PULL_UP,   TRISTATE,   INPUT),
 };
 
 static __initdata struct tegra_pingroup_config enterprise_unused_pinmux_common[] = {
@@ -430,9 +406,100 @@ static __initdata struct tegra_pingroup_config enterprise_unused_pinmux_common[]
        DEFAULT_PINMUX(SPI2_MISO,       SPI2,            PULL_DOWN,    TRISTATE,  OUTPUT),
 };
 
-static __initdata struct tegra_pingroup_config enterprise_unused_pinmux_a02[] = {
-       DEFAULT_PINMUX(LCD_D10,         DISPLAYA,        PULL_DOWN,    TRISTATE,  OUTPUT),
-       DEFAULT_PINMUX(LCD_PWR0,        DISPLAYA,        PULL_DOWN,    TRISTATE,  OUTPUT),
+static __initdata struct tegra_pingroup_config enterprise_pinmux_a02[] = {
+       DEFAULT_PINMUX(LCD_D10,         DISPLAYA,        PULL_DOWN, TRISTATE,   OUTPUT),
+       DEFAULT_PINMUX(LCD_PWR0,        DISPLAYA,        PULL_DOWN, TRISTATE,   OUTPUT),
+       DEFAULT_PINMUX(SDMMC4_CMD,      SDMMC4,          PULL_UP,   NORMAL,     INPUT),
+       DEFAULT_PINMUX(ULPI_CLK,        ULPI,            NORMAL,    NORMAL,     INPUT),
+       DEFAULT_PINMUX(ULPI_DIR,        ULPI,            NORMAL,    NORMAL,     OUTPUT),
+       DEFAULT_PINMUX(ULPI_NXT,        ULPI,            NORMAL,    NORMAL,     OUTPUT),
+       DEFAULT_PINMUX(ULPI_STP,        ULPI,            NORMAL,    NORMAL,     INPUT),
+       DEFAULT_PINMUX(DAP3_FS,         I2S2,            NORMAL,    NORMAL,     INPUT),
+       DEFAULT_PINMUX(DAP3_DIN,        I2S2,            NORMAL,    NORMAL,     INPUT),
+       DEFAULT_PINMUX(DAP3_DOUT,       I2S2,            NORMAL,    NORMAL,     INPUT),
+       DEFAULT_PINMUX(DAP3_SCLK,       I2S2,            NORMAL,    NORMAL,     INPUT),
+       DEFAULT_PINMUX(GPIO_PV3,        RSVD1,           NORMAL,    NORMAL,     OUTPUT),
+       DEFAULT_PINMUX(LCD_PWR1,        DISPLAYA,        NORMAL,    NORMAL,     OUTPUT),
+       DEFAULT_PINMUX(LCD_PWR2,        DISPLAYA,        NORMAL,    NORMAL,     INPUT),
+       DEFAULT_PINMUX(LCD_CS0_N,       DISPLAYA,        NORMAL,    NORMAL,     INPUT),
+       DEFAULT_PINMUX(LCD_DC0,         DISPLAYA,        NORMAL,    NORMAL,     INPUT),
+       DEFAULT_PINMUX(LCD_DE,          DISPLAYA,        NORMAL,    NORMAL,     INPUT),
+       DEFAULT_PINMUX(LCD_D0,          DISPLAYA,        NORMAL,    NORMAL,     OUTPUT),
+       DEFAULT_PINMUX(LCD_D1,          DISPLAYA,        NORMAL,    NORMAL,     OUTPUT),
+       DEFAULT_PINMUX(LCD_D2,          DISPLAYA,        NORMAL,    NORMAL,     INPUT),
+       DEFAULT_PINMUX(LCD_D3,          DISPLAYA,        NORMAL,    NORMAL,     OUTPUT),
+       DEFAULT_PINMUX(LCD_D4,          DISPLAYA,        NORMAL,    NORMAL,     INPUT),
+       DEFAULT_PINMUX(LCD_D5,          DISPLAYA,        NORMAL,    NORMAL,     INPUT),
+       DEFAULT_PINMUX(LCD_D6,          RSVD1,           NORMAL,    NORMAL,     INPUT),
+       DEFAULT_PINMUX(LCD_D7,          RSVD1,           NORMAL,    NORMAL,     OUTPUT),
+       DEFAULT_PINMUX(LCD_D8,          DISPLAYA,        NORMAL,    TRISTATE,   INPUT),
+       DEFAULT_PINMUX(LCD_D9,          DISPLAYA,        NORMAL,    NORMAL,     INPUT),
+       DEFAULT_PINMUX(LCD_D11,         DISPLAYA,        NORMAL,    NORMAL,     INPUT),
+       DEFAULT_PINMUX(LCD_D12,         DISPLAYA,        NORMAL,    NORMAL,     INPUT),
+       DEFAULT_PINMUX(LCD_D13,         DISPLAYA,        NORMAL,    NORMAL,     INPUT),
+       DEFAULT_PINMUX(LCD_D14,         DISPLAYA,        NORMAL,    NORMAL,     INPUT),
+       DEFAULT_PINMUX(LCD_D15,         DISPLAYA,        NORMAL,    NORMAL,     INPUT),
+       DEFAULT_PINMUX(LCD_D16,         DISPLAYA,        NORMAL,    NORMAL,     INPUT),
+       DEFAULT_PINMUX(LCD_D17,         DISPLAYA,        NORMAL,    NORMAL,     INPUT),
+       DEFAULT_PINMUX(LCD_D18,         DISPLAYA,        NORMAL,    NORMAL,     INPUT),
+       DEFAULT_PINMUX(LCD_D19,         DISPLAYA,        NORMAL,    NORMAL,     INPUT),
+       DEFAULT_PINMUX(LCD_D20,         DISPLAYA,        NORMAL,    NORMAL,     INPUT),
+       DEFAULT_PINMUX(LCD_D21,         DISPLAYA,        NORMAL,    NORMAL,     INPUT),
+       DEFAULT_PINMUX(LCD_D22,         RSVD1,           NORMAL,    NORMAL,     INPUT),
+       DEFAULT_PINMUX(LCD_D23,         DISPLAYA,        NORMAL,    NORMAL,     INPUT),
+       DEFAULT_PINMUX(LCD_CS1_N,       DISPLAYA,        NORMAL,    NORMAL,     INPUT),
+       DEFAULT_PINMUX(LCD_M1,          DISPLAYA,        NORMAL,    NORMAL,     OUTPUT),
+       DEFAULT_PINMUX(LCD_DC1,         DISPLAYA,        NORMAL,    NORMAL,     INPUT),
+       DEFAULT_PINMUX(UART2_RXD,       IRDA,            NORMAL,    NORMAL,     INPUT),
+       DEFAULT_PINMUX(UART2_TXD,       IRDA,            NORMAL,    NORMAL,     OUTPUT),
+       DEFAULT_PINMUX(UART2_RTS_N,     UARTB,           NORMAL,    NORMAL,     OUTPUT),
+       DEFAULT_PINMUX(UART2_CTS_N,     UARTB,           NORMAL,    NORMAL,     INPUT),
+       DEFAULT_PINMUX(UART3_TXD,       UARTC,           NORMAL,    NORMAL,     OUTPUT),
+       DEFAULT_PINMUX(UART3_RXD,       UARTC,           NORMAL,    NORMAL,     INPUT),
+       DEFAULT_PINMUX(UART3_CTS_N,     UARTC,           NORMAL,    NORMAL,     INPUT),
+       DEFAULT_PINMUX(UART3_RTS_N,     UARTC,           NORMAL,    NORMAL,     OUTPUT),
+       DEFAULT_PINMUX(GPIO_PU0,        UARTA,           NORMAL,    NORMAL,     OUTPUT),
+       DEFAULT_PINMUX(GPIO_PU1,        UARTA,           NORMAL,    NORMAL,     INPUT),
+       DEFAULT_PINMUX(GPIO_PU2,        UARTA,           NORMAL,    NORMAL,     INPUT),
+       DEFAULT_PINMUX(GPIO_PU3,        UARTA,           NORMAL,    NORMAL,     OUTPUT),
+       DEFAULT_PINMUX(GPIO_PU4,        PWM1,            NORMAL,    NORMAL,     OUTPUT),
+       DEFAULT_PINMUX(GPIO_PU5,        PWM2,            NORMAL,    NORMAL,     INPUT),
+       DEFAULT_PINMUX(GPIO_PU6,        PWM3,            NORMAL,    NORMAL,     INPUT),
+       DEFAULT_PINMUX(DAP4_FS,         I2S3,            NORMAL,    NORMAL,     INPUT),
+       DEFAULT_PINMUX(DAP4_DIN,        I2S3,            NORMAL,    NORMAL,     INPUT),
+       DEFAULT_PINMUX(DAP4_DOUT,       I2S3,            NORMAL,    NORMAL,     INPUT),
+       DEFAULT_PINMUX(DAP4_SCLK,       I2S3,            NORMAL,    NORMAL,     INPUT),
+       DEFAULT_PINMUX(GMI_A16,         UARTD,           NORMAL,    NORMAL,     OUTPUT),
+       DEFAULT_PINMUX(GMI_A17,         UARTD,           NORMAL,    NORMAL,     INPUT),
+       DEFAULT_PINMUX(GMI_A18,         UARTD,           NORMAL,    NORMAL,     INPUT),
+       DEFAULT_PINMUX(GMI_A19,         UARTD,           NORMAL,    NORMAL,     OUTPUT),
+       DEFAULT_PINMUX(CAM_MCLK,        VI_ALT2,         NORMAL,    NORMAL,     INPUT),
+       DEFAULT_PINMUX(GPIO_PCC1,       RSVD1,           NORMAL,    NORMAL,     INPUT),
+       DEFAULT_PINMUX(GPIO_PBB0,       RSVD1,           NORMAL,    NORMAL,     INPUT),
+       DEFAULT_PINMUX(GPIO_PBB3,       VGP3,            NORMAL,    NORMAL,     INPUT),
+       DEFAULT_PINMUX(GPIO_PBB7,       I2S4,            NORMAL,    NORMAL,     INPUT),
+       DEFAULT_PINMUX(GPIO_PCC2,       I2S4,            NORMAL,    NORMAL,     INPUT),
+       DEFAULT_PINMUX(KB_ROW10,        KBC,             NORMAL,    NORMAL,     INPUT),
+       DEFAULT_PINMUX(KB_ROW12,        KBC,             NORMAL,    NORMAL,     INPUT),
+       DEFAULT_PINMUX(KB_COL3,         KBC,             PULL_UP,   NORMAL,     INPUT),
+       DEFAULT_PINMUX(GPIO_PV0,        RSVD,            PULL_UP,   NORMAL,     INPUT),
+       DEFAULT_PINMUX(DAP1_FS,         I2S0,            NORMAL,    NORMAL,     INPUT),
+       DEFAULT_PINMUX(DAP1_DIN,        I2S0,            NORMAL,    NORMAL,     INPUT),
+       DEFAULT_PINMUX(DAP1_DOUT,       I2S0,            NORMAL,    NORMAL,     INPUT),
+       DEFAULT_PINMUX(DAP1_SCLK,       I2S0,            NORMAL,    NORMAL,     INPUT),
+       DEFAULT_PINMUX(CLK1_OUT,        EXTPERIPH1,      NORMAL,    NORMAL,     INPUT),
+       DEFAULT_PINMUX(SPDIF_IN,        SPDIF,           NORMAL,    NORMAL,     INPUT),
+       DEFAULT_PINMUX(DAP2_FS,         I2S1,            NORMAL,    NORMAL,     INPUT),
+       DEFAULT_PINMUX(DAP2_DIN,        I2S1,            NORMAL,    NORMAL,     INPUT),
+       DEFAULT_PINMUX(DAP2_DOUT,       I2S1,            NORMAL,    NORMAL,     INPUT),
+       DEFAULT_PINMUX(DAP2_SCLK,       I2S1,            NORMAL,    NORMAL,     INPUT),
+       DEFAULT_PINMUX(SPI1_MOSI,       SPI1,            NORMAL,    NORMAL,     INPUT),
+       DEFAULT_PINMUX(SPI1_SCK,        SPI1,            NORMAL,    NORMAL,     INPUT),
+       DEFAULT_PINMUX(SPI1_MISO,       SPI1,            NORMAL,    NORMAL,     INPUT),
+       DEFAULT_PINMUX(GMI_IORDY,       RSVD1,           PULL_UP,   NORMAL,     INPUT),
+       DEFAULT_PINMUX(GMI_AD12,        NAND,            NORMAL,    NORMAL,     INPUT),
+       DEFAULT_PINMUX(GMI_AD14,        NAND,            NORMAL,    NORMAL,     INPUT),
+       DEFAULT_PINMUX(KB_ROW8,         KBC,             PULL_UP,   NORMAL,     INPUT),
 };
 
 static struct tegra_gpio_table gpio_table[] = {
@@ -519,6 +586,19 @@ static __initdata struct pin_info_low_power_mode enterprise_unused_gpio_pins_a02
        PIN_GPIO_LPM("LCD_PWR0",     TEGRA_GPIO_PB2,  0, 0),
 };
 
+static __initdata struct pin_info_low_power_mode enterprise_gpio_pins_a03[] = {
+       PIN_GPIO_LPM("GPIO_PV3",      TEGRA_GPIO_PV3,  0, 0),
+       PIN_GPIO_LPM("LCD_DC0",       TEGRA_GPIO_PN6,  0, 0),
+       PIN_GPIO_LPM("LCD_D5",        TEGRA_GPIO_PE5,  0, 0),
+       PIN_GPIO_LPM("LCD_D20",       TEGRA_GPIO_PM4,  0, 0),
+       PIN_GPIO_LPM("LCD_DC1",       TEGRA_GPIO_PD2,  0, 0),
+       PIN_GPIO_LPM("GPIO_PU4",      TEGRA_GPIO_PU4,  0, 0),
+       PIN_GPIO_LPM("KB_COL3",       TEGRA_GPIO_PQ3,  0, 0),
+       PIN_GPIO_LPM("SPI1_MOSI",     TEGRA_GPIO_PX4,  0, 0),
+       PIN_GPIO_LPM("SPI1_MISO",     TEGRA_GPIO_PX7,  0, 0),
+       PIN_GPIO_LPM("SPI1_SCK",      TEGRA_GPIO_PX5,  0, 0),
+};
+
 static void enterprise_set_unused_pin_gpio(struct pin_info_low_power_mode *lpm_pin_info,
                int list_count)
 {
@@ -569,13 +649,15 @@ int __init enterprise_pinmux_init(void)
                        ARRAY_SIZE(enterprise_unused_gpio_pins_common));
 
        if (board_info.fab < BOARD_FAB_A03) {
-               tegra_pinmux_config_table(enterprise_unused_pinmux_a02,
-                                         ARRAY_SIZE(enterprise_unused_pinmux_a02));
+               tegra_pinmux_config_table(enterprise_pinmux_a02,
+                                         ARRAY_SIZE(enterprise_pinmux_a02));
                enterprise_set_unused_pin_gpio(enterprise_unused_gpio_pins_a02,
                                               ARRAY_SIZE(enterprise_unused_gpio_pins_a02));
        } else {
                tegra_pinmux_config_table(enterprise_pinmux_a03,
                                          ARRAY_SIZE(enterprise_pinmux_a03));
+               enterprise_set_unused_pin_gpio(enterprise_gpio_pins_a03,
+                                              ARRAY_SIZE(enterprise_gpio_pins_a03));
        }
 
        return 0;
index 0c35b1a..857c893 100644 (file)
@@ -234,28 +234,30 @@ static struct regulator_consumer_supply tps80031_battery_charge_supply[] = {
        REGULATOR_SUPPLY("usb_bat_chg", NULL),
 };
 
-#define TPS_PDATA_INIT(_id, _sname, _minmv, _maxmv, _supply_reg, _always_on,           \
+#define TPS_PDATA_INIT(_reg_id, _id, _sname, _minmv, _maxmv, _supply_reg, _always_on,  \
        _boot_on, _apply_uv, _init_uV, _init_enable, _init_apply,                       \
        _flags, _ectrl, _delay)                                                         \
-       static struct tps80031_regulator_platform_data pdata_##_id##_##_sname = {       \
-               .regulator = {                                                          \
-                       .constraints = {                                                \
-                               .min_uV = (_minmv)*1000,                                \
-                               .max_uV = (_maxmv)*1000,                                \
-                               .valid_modes_mask = (REGULATOR_MODE_NORMAL |            \
-                                               REGULATOR_MODE_STANDBY),                \
-                               .valid_ops_mask = (REGULATOR_CHANGE_MODE |              \
-                                               REGULATOR_CHANGE_STATUS |               \
-                                               REGULATOR_CHANGE_VOLTAGE),              \
-                               .always_on = _always_on,                                \
-                               .boot_on = _boot_on,                                    \
-                               .apply_uV = _apply_uv,                                  \
-                       },                                                              \
-                       .num_consumer_supplies =                                        \
-                               ARRAY_SIZE(tps80031_##_id##_supply_##_sname),           \
-                       .consumer_supplies = tps80031_##_id##_supply_##_sname,          \
-                       .supply_regulator = _supply_reg,                                \
+       static struct regulator_init_data reg_idata_##_id##_##_sname = {                \
+               .constraints = {                                                        \
+                       .name = tps80031_rails(_id),                                    \
+                       .min_uV = (_minmv)*1000,                                        \
+                       .max_uV = (_maxmv)*1000,                                        \
+                       .valid_modes_mask = (REGULATOR_MODE_NORMAL |                    \
+                                       REGULATOR_MODE_STANDBY),                        \
+                       .valid_ops_mask = (REGULATOR_CHANGE_MODE |                      \
+                                       REGULATOR_CHANGE_STATUS |                       \
+                                       REGULATOR_CHANGE_VOLTAGE),                      \
+                       .always_on = _always_on,                                        \
+                       .boot_on = _boot_on,                                            \
+                       .apply_uV = _apply_uv,                                          \
                },                                                                      \
+               .num_consumer_supplies =                                                \
+                       ARRAY_SIZE(tps80031_##_id##_supply_##_sname),                   \
+               .consumer_supplies = tps80031_##_id##_supply_##_sname,                  \
+       };                                                                              \
+       static struct tps80031_regulator_platform_data pdata_##_id##_##_sname = {       \
+               .reg_init_data = &reg_idata_##_id##_##_sname,                           \
+               .regulator_id = TPS80031_REGULATOR_##_reg_id,                           \
                .init_uV =  _init_uV * 1000,                                            \
                .init_enable = _init_enable,                                            \
                .init_apply = _init_apply,                                              \
@@ -264,31 +266,31 @@ static struct regulator_consumer_supply tps80031_battery_charge_supply[] = {
                .delay_us = _delay,                                                     \
        }
 
-TPS_PDATA_INIT(vio, a02,   600, 2100, 0, 1, 0, 0, -1, 0, 0, 0, 0, 0);
-TPS_PDATA_INIT(vio, a03,   600, 2100, 0, 1, 0, 0, -1, 0, 0, 0, 0, 0);
-TPS_PDATA_INIT(smps1, common, 600, 2100, 0, 0, 0, 0, -1, 0, 0, 0, PWR_REQ_INPUT_PREQ2 | PWR_OFF_ON_SLEEP, 0);
-TPS_PDATA_INIT(smps2, common, 600, 2100, 0, 0, 0, 0, -1, 0, 0, 0, PWR_REQ_INPUT_PREQ1, 0);
-TPS_PDATA_INIT(smps3, common, 600, 2100, 0, 1, 0, 0, -1, 0, 0, 0, 0, 0);
-TPS_PDATA_INIT(smps4, a02, 600, 2100, 0, 0, 0, 0, -1, 0, 0, 0, PWR_REQ_INPUT_PREQ1, 0);
-TPS_PDATA_INIT(smps4, a03, 600, 2100, 0, 0, 0, 0, -1, 0, 0, 0, PWR_REQ_INPUT_PREQ1, 0);
-TPS_PDATA_INIT(ldo1, a02, 1000, 3300, tps80031_rails(VIO), 0, 0, 0, -1, 0, 0, 0, 0, 0);
-TPS_PDATA_INIT(ldo1, a03, 1000, 3300, tps80031_rails(VIO), 0, 0, 0, -1, 0, 0, 0, PWR_REQ_INPUT_PREQ1, 0);
-TPS_PDATA_INIT(ldo2, common, 1000, 3300, 0, 1, 1, 1, 1000, 1, 1, 0, 0, 0);
-TPS_PDATA_INIT(ldo3, common, 1000, 3300, tps80031_rails(VIO), 0, 0, 0, -1, 0, 0, 0, PWR_OFF_ON_SLEEP, 0);
-TPS_PDATA_INIT(ldo4, a02, 1000, 3300, 0, 0, 0, 0, -1, 0, 0, 0, 0, 0);
-TPS_PDATA_INIT(ldo4, a03, 1000, 3300, tps80031_rails(VIO), 0, 0, 0, -1, 0, 0, 0, PWR_REQ_INPUT_PREQ1, 0);
-TPS_PDATA_INIT(ldo5, common, 1000, 3300, 0, 0, 0, 0, -1, 0, 0, 0, 0, 0);
-TPS_PDATA_INIT(ldo6, a02, 1000, 3300, 0, 0, 0, 0, -1, 0, 0, 0, PWR_REQ_INPUT_PREQ1, 0);
-TPS_PDATA_INIT(ldo6, a03, 1000, 3300, 0, 0, 0, 0, -1, 0, 0, 0, PWR_REQ_INPUT_PREQ1, 0);
-TPS_PDATA_INIT(ldo7, a02, 1000, 3300, tps80031_rails(VIO), 0, 0, 0, -1, 0, 0, 0, PWR_REQ_INPUT_PREQ1, 0);
-TPS_PDATA_INIT(ldo7, a03, 1000, 3300, 0, 0, 0, 0, -1, 0, 0, 0, PWR_REQ_INPUT_PREQ1, 0);
-TPS_PDATA_INIT(ldoln, a02, 1000, 3300, tps80031_rails(SMPS3), 0, 0, 0, -1, 0, 0, 0, PWR_REQ_INPUT_PREQ1, 0);
-TPS_PDATA_INIT(ldoln, a03, 1000, 3300, tps80031_rails(VIO), 0, 0, 0, -1, 0, 0, 0, PWR_REQ_INPUT_PREQ1, 0);
-TPS_PDATA_INIT(ldousb, a02, 1000, 3300, 0, 0, 0, 0, -1, 0, 0, USBLDO_INPUT_VSYS, PWR_OFF_ON_SLEEP, 0);
-TPS_PDATA_INIT(ldousb, a03, 1000, 3300, 0, 0, 0, 0, -1, 0, 0, USBLDO_INPUT_VSYS, PWR_REQ_INPUT_PREQ1, 0);
-TPS_PDATA_INIT(vana, a02,  1000, 3300, 0, 0, 0, 0, -1, 0, 0, 0, 0, 0);
-TPS_PDATA_INIT(vana, a03,  1000, 3300, 0, 0, 0, 0, -1, 0, 1, 0, PWR_OFF_ON_SLEEP, 0);
-TPS_PDATA_INIT(vbus, common,  0, 5000, 0, 0, 0, 0, -1, 0, 0, (VBUS_SW_ONLY | VBUS_DISCHRG_EN_PDN), 0, 100000);
+TPS_PDATA_INIT(VIO, vio, a02,   600, 2100, 0, 1, 0, 0, -1, 0, 0, 0, 0, 0);
+TPS_PDATA_INIT(VIO, vio, a03,   600, 2100, 0, 1, 0, 0, -1, 0, 0, 0, 0, 0);
+TPS_PDATA_INIT(SMPS1, smps1, common, 600, 2100, 0, 0, 0, 0, -1, 0, 0, 0, PWR_REQ_INPUT_PREQ2 | PWR_OFF_ON_SLEEP, 0);
+TPS_PDATA_INIT(SMPS2, smps2, common, 600, 2100, 0, 0, 0, 0, -1, 0, 0, 0, PWR_REQ_INPUT_PREQ1, 0);
+TPS_PDATA_INIT(SMPS3, smps3, common, 600, 2100, 0, 1, 0, 0, -1, 0, 0, 0, 0, 0);
+TPS_PDATA_INIT(SMPS4, smps4, a02, 600, 2100, 0, 0, 0, 0, -1, 0, 0, 0, PWR_REQ_INPUT_PREQ1, 0);
+TPS_PDATA_INIT(SMPS4, smps4, a03, 600, 2100, 0, 0, 0, 0, -1, 0, 0, 0, PWR_REQ_INPUT_PREQ1, 0);
+TPS_PDATA_INIT(LDO1, ldo1, a02, 1000, 3300, tps80031_rails(vio), 0, 0, 0, -1, 0, 0, 0, 0, 0);
+TPS_PDATA_INIT(LDO1, ldo1, a03, 1000, 3300, tps80031_rails(vio), 0, 0, 0, -1, 0, 0, 0, PWR_REQ_INPUT_PREQ1, 0);
+TPS_PDATA_INIT(LDO2, ldo2, common, 1000, 1000, 0, 1, 1, 1, -1, 0, 0, 0, 0, 0);
+TPS_PDATA_INIT(LDO3, ldo3, common, 1000, 3300, tps80031_rails(vio), 0, 0, 0, -1, 0, 0, 0, PWR_OFF_ON_SLEEP, 0);
+TPS_PDATA_INIT(LDO4, ldo4, a02, 1000, 3300, 0, 0, 0, 0, -1, 0, 0, 0, 0, 0);
+TPS_PDATA_INIT(LDO4, ldo4, a03, 1000, 3300, tps80031_rails(vio), 0, 0, 0, -1, 0, 0, 0, PWR_REQ_INPUT_PREQ1, 0);
+TPS_PDATA_INIT(LDO5, ldo5, common, 1000, 3300, 0, 0, 0, 0, -1, 0, 0, 0, 0, 0);
+TPS_PDATA_INIT(LDO6, ldo6, a02, 1000, 3300, 0, 0, 0, 0, -1, 0, 0, 0, PWR_REQ_INPUT_PREQ1, 0);
+TPS_PDATA_INIT(LDO6, ldo6, a03, 1000, 3300, 0, 0, 0, 0, -1, 0, 0, 0, PWR_REQ_INPUT_PREQ1, 0);
+TPS_PDATA_INIT(LDO7, ldo7, a02, 1000, 3300, tps80031_rails(vio), 0, 0, 0, -1, 0, 0, 0, PWR_REQ_INPUT_PREQ1, 0);
+TPS_PDATA_INIT(LDO7, ldo7, a03, 1000, 3300, 0, 0, 0, 0, -1, 0, 0, 0, PWR_REQ_INPUT_PREQ1, 0);
+TPS_PDATA_INIT(LDOLN, ldoln, a02, 1000, 3300, tps80031_rails(smps3), 0, 0, 0, -1, 0, 0, 0, PWR_REQ_INPUT_PREQ1, 0);
+TPS_PDATA_INIT(LDOLN, ldoln, a03, 1000, 3300, tps80031_rails(vio), 0, 0, 0, -1, 0, 0, 0, PWR_REQ_INPUT_PREQ1, 0);
+TPS_PDATA_INIT(LDOUSB, ldousb, a02, 1000, 3300, 0, 0, 0, 0, -1, 0, 0, USBLDO_INPUT_VSYS, PWR_OFF_ON_SLEEP, 0);
+TPS_PDATA_INIT(LDOUSB, ldousb, a03, 1000, 3300, 0, 0, 0, 0, -1, 0, 0, USBLDO_INPUT_VSYS, PWR_REQ_INPUT_PREQ1, 0);
+TPS_PDATA_INIT(VANA, vana, a02,  1000, 3300, 0, 0, 0, 0, -1, 0, 0, 0, 0, 0);
+TPS_PDATA_INIT(VANA, vana, a03,  1000, 3300, 0, 0, 0, 0, -1, 0, 0, 0, PWR_OFF_ON_SLEEP, 0);
+TPS_PDATA_INIT(VBUS, vbus, common,  0, 5000, 0, 0, 0, 0, -1, 0, 0, (VBUS_SW_ONLY | VBUS_DISCHRG_EN_PDN), 0, 100000);
 
 static struct tps80031_rtc_platform_data rtc_data = {
        .irq = ENT_TPS80031_IRQ_BASE + TPS80031_INT_RTC_ALARM,
@@ -339,12 +341,6 @@ static struct tps80031_bg_platform_data battery_gauge_data = {
                .platform_data = &rtc_data,     \
        }
 
-#define TPS_REG(_id, _data, _sname)                            \
-       {                                                       \
-               .id      = TPS80031_ID_##_id,                   \
-               .name   = "tps80031-regulator",                 \
-               .platform_data  = &pdata_##_data##_##_sname,    \
-       }
 #define TPS_BATTERY()                                  \
        {                                               \
                .name   = "tps80031-charger",           \
@@ -361,45 +357,56 @@ static struct tps80031_bg_platform_data battery_gauge_data = {
        }
 
 #define TPS80031_DEVS_COMMON           \
-       TPS_REG(SMPS1, smps1, common),  \
-       TPS_REG(SMPS2, smps2, common),  \
-       TPS_REG(SMPS3, smps3, common),  \
-       TPS_REG(LDO2, ldo2, common),    \
-       TPS_REG(LDO3, ldo3, common),    \
-       TPS_REG(LDO5, ldo5, common),    \
-       TPS_REG(VBUS, vbus, common),    \
        TPS_RTC(),                      \
        TPS_BATTERY(),                  \
        TPS_BATTERY_GAUGE(),            \
        TPS_GPADC()
 
 
-static struct tps80031_subdev_info tps80031_devs_a02[] = {
-       TPS_REG(VIO, vio, a02),
-       TPS80031_DEVS_COMMON,
-       TPS_REG(SMPS4, smps4, a02),
-       TPS_REG(LDO1, ldo1, a02),
-       TPS_REG(LDO4, ldo4, a02),
-       TPS_REG(LDO6, ldo6, a02),
-       TPS_REG(LDO7, ldo7, a02),
-       TPS_REG(LDOLN, ldoln, a02),
-       TPS_REG(LDOUSB, ldousb, a02),
-       TPS_REG(VANA, vana, a02),
-
+static struct tps80031_subdev_info tps80031_devs[] = {
+       TPS_RTC(),
+       TPS_BATTERY(),
+       TPS_BATTERY_GAUGE(),
+       TPS_GPADC()
 };
 
-static struct tps80031_subdev_info tps80031_devs_a03[] = {
-       TPS_REG(VIO, vio, a03),
-       TPS80031_DEVS_COMMON,
-       TPS_REG(SMPS4, smps4, a03),
-       TPS_REG(LDO1, ldo1, a03),
-       TPS_REG(LDO4, ldo4, a03),
-       TPS_REG(LDO6, ldo6, a03),
-       TPS_REG(LDO7, ldo7, a03),
-       TPS_REG(LDOLN, ldoln, a03),
-       TPS_REG(LDOUSB, ldousb, a03),
-       TPS_REG(VANA, vana, a03),
-
+#define TPS_REG_PDATA(_id, _sname) &pdata_##_id##_##_sname
+static struct tps80031_regulator_platform_data *tps80031_reg_pdata_a02[] = {
+       TPS_REG_PDATA(vio, a02),
+       TPS_REG_PDATA(smps1, common),
+       TPS_REG_PDATA(smps2, common),
+       TPS_REG_PDATA(smps3, common),
+       TPS_REG_PDATA(ldo2, common),
+       TPS_REG_PDATA(ldo3, common),
+       TPS_REG_PDATA(ldo5, common),
+       TPS_REG_PDATA(vbus, common),
+       TPS_REG_PDATA(smps4, a02),
+       TPS_REG_PDATA(ldo1, a02),
+       TPS_REG_PDATA(ldo4, a02),
+       TPS_REG_PDATA(ldo6, a02),
+       TPS_REG_PDATA(ldo7, a02),
+       TPS_REG_PDATA(ldoln, a02),
+       TPS_REG_PDATA(ldousb, a02),
+       TPS_REG_PDATA(vana, a02),
+};
+
+static struct tps80031_regulator_platform_data *tps80031_reg_pdata_a03[] = {
+       TPS_REG_PDATA(vio, a03),
+       TPS_REG_PDATA(smps1, common),
+       TPS_REG_PDATA(smps2, common),
+       TPS_REG_PDATA(smps3, common),
+       TPS_REG_PDATA(ldo2, common),
+       TPS_REG_PDATA(ldo3, common),
+       TPS_REG_PDATA(ldo5, common),
+       TPS_REG_PDATA(vbus, common),
+       TPS_REG_PDATA(smps4, a03),
+       TPS_REG_PDATA(ldo1, a03),
+       TPS_REG_PDATA(ldo4, a03),
+       TPS_REG_PDATA(ldo6, a03),
+       TPS_REG_PDATA(ldo7, a03),
+       TPS_REG_PDATA(ldoln, a03),
+       TPS_REG_PDATA(ldousb, a03),
+       TPS_REG_PDATA(vana, a03),
 };
 
 static struct tps80031_clk32k_init_data clk32k_idata[] = {
@@ -595,7 +602,7 @@ static struct gpio gpio_reg_sdmmc3_vdd_sel_gpios[] = {
                },                                                      \
        }
 
-GPIO_REG(4, sdmmc3_vdd_sel,  tps80031_rails(SMPS4),
+GPIO_REG(4, sdmmc3_vdd_sel,  tps80031_rails(smps4),
                true, false, 0, 1000, 3300);
 
 /* Macro for defining fixed regulator sub device data */
@@ -752,14 +759,15 @@ int __init enterprise_regulator_init(void)
                battery_gauge_data.battery_present = 0;
        }
 
-       tegra_gpio_enable(TEGRA_GPIO_PF7);
+       tps_platform.num_subdevs = ARRAY_SIZE(tps80031_devs);
+       tps_platform.subdevs = tps80031_devs;
 
        if (board_info.fab < BOARD_FAB_A03) {
-               tps_platform.num_subdevs = ARRAY_SIZE(tps80031_devs_a02);
-               tps_platform.subdevs = tps80031_devs_a02;
+               tps_platform.num_regulator_pdata = ARRAY_SIZE(tps80031_reg_pdata_a02);
+               tps_platform.regulator_pdata = tps80031_reg_pdata_a02;
        } else {
-               tps_platform.num_subdevs = ARRAY_SIZE(tps80031_devs_a03);
-               tps_platform.subdevs = tps80031_devs_a03;
+               tps_platform.num_regulator_pdata = ARRAY_SIZE(tps80031_reg_pdata_a03);
+               tps_platform.regulator_pdata = tps80031_reg_pdata_a03;
                tps_platform.pupd_init_data = pupd_idata;
                tps_platform.pupd_init_data_size = ARRAY_SIZE(pupd_idata);
                tps_platform.gpio_init_data = gpio_idata_a03;
index 368e4d8..d06f6ff 100644 (file)
@@ -27,7 +27,7 @@
 #include <mach/irqs.h>
 #include <mach/iomap.h>
 #include <mach/sdhci.h>
-#include <mach/gpio-tegra.h>
+#include <mach/io_dpd.h>
 
 #include "gpio-names.h"
 #include "board.h"
@@ -220,11 +220,31 @@ static int enterprise_wifi_set_carddetect(int val)
 
 static int enterprise_wifi_power(int on)
 {
+       struct tegra_io_dpd *sd_dpd;
+
        pr_debug("%s: %d\n", __func__, on);
+
+       /*
+        * FIXME : we need to revisit IO DPD code
+        * on how should multiple pins under DPD get controlled
+        *
+        * enterprise GPIO WLAN enable is part of SDMMC1 pin group
+        */
+       sd_dpd = tegra_io_dpd_get(&tegra_sdhci_device0.dev);
+       if (sd_dpd) {
+               mutex_lock(&sd_dpd->delay_lock);
+               tegra_io_dpd_disable(sd_dpd);
+               mutex_unlock(&sd_dpd->delay_lock);
+       }
        gpio_set_value(ENTERPRISE_WLAN_PWR, on);
        mdelay(100);
        gpio_set_value(ENTERPRISE_WLAN_RST, on);
        mdelay(200);
+       if (sd_dpd) {
+               mutex_lock(&sd_dpd->delay_lock);
+               tegra_io_dpd_enable(sd_dpd);
+               mutex_unlock(&sd_dpd->delay_lock);
+       }
 
        return 0;
 }
index 3b7f90b..104fcb6 100644 (file)
@@ -1,7 +1,7 @@
 /*
  * arch/arm/mach-tegra/board-enterprise.c
  *
- * Copyright (c) 2011-2012, NVIDIA Corporation.
+ * Copyright (c) 2011-2012, NVIDIA CORPORATION. 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 as published by
@@ -190,7 +190,6 @@ static __initdata struct tegra_clk_init_table enterprise_clk_init_table[] = {
        { "blink",      "clk_32k",      32768,          true},
        { "i2s0",       "pll_a_out0",   0,              false},
        { "i2s1",       "pll_a_out0",   0,              false},
-       { "i2s2",       "pll_a_out0",   0,              false},
        { "i2s3",       "pll_a_out0",   0,              false},
        { "spdif_out",  "pll_a_out0",   0,              false},
        { "d_audio",    "clk_m",        12000000,       false},
@@ -203,6 +202,19 @@ static __initdata struct tegra_clk_init_table enterprise_clk_init_table[] = {
        { "audio3",     "i2s3_sync",    0,              false},
        { "vi",         "pll_p",        0,              false},
        { "vi_sensor",  "pll_p",        0,              false},
+       { "i2c5",       "pll_p",        3200000,        false},
+       { NULL,         NULL,           0,              0},
+};
+
+static __initdata struct tegra_clk_init_table enterprise_clk_i2s2_table[] = {
+       /* name         parent          rate            enabled */
+       { "i2s2",       "pll_a_out0",   0,              false},
+       { NULL,         NULL,           0,              0},
+};
+
+static __initdata struct tegra_clk_init_table enterprise_clk_i2s4_table[] = {
+       /* name         parent          rate            enabled */
+       { "i2s4",       "pll_a_out0",   0,              false},
        { NULL,         NULL,           0,              0},
 };
 
@@ -246,7 +258,7 @@ static struct tegra_i2c_platform_data enterprise_i2c4_platform_data = {
 static struct tegra_i2c_platform_data enterprise_i2c5_platform_data = {
        .adapter_nr     = 4,
        .bus_count      = 1,
-       .bus_clk_rate   = { 400000, 0 },
+       .bus_clk_rate   = { 390000, 0 },
        .scl_gpio               = {TEGRA_GPIO_PZ6, 0},
        .sda_gpio               = {TEGRA_GPIO_PZ7, 0},
        .arb_recovery = arb_lost_recovery,
@@ -510,14 +522,24 @@ static struct tegra_asoc_platform_data enterprise_audio_pdata = {
        .gpio_ext_mic_en        = -1,
        .debounce_time_hp = -1,
        /*defaults for Enterprise board*/
-       .audio_port_id          = {
-               [HIFI_CODEC] = 0,
-               [BASEBAND] = 2,
-               [BT_SCO] = 3,
+       .i2s_param[HIFI_CODEC]  = {
+               .audio_port_id  = 0,
+               .is_i2s_master  = 1,
+               .i2s_mode       = TEGRA_DAIFMT_I2S,
+               .sample_size    = 16,
        },
-       .baseband_param         = {
-               .rate = 8000,
-               .channels = 1,
+       .i2s_param[BASEBAND]    = {
+               .is_i2s_master  = 1,
+               .i2s_mode       = TEGRA_DAIFMT_DSP_A,
+               .sample_size    = 16,
+               .rate           = 8000,
+               .channels       = 1,
+       },
+       .i2s_param[BT_SCO]      = {  
+               .audio_port_id  = 3, 
+               .is_i2s_master  = 1, 
+               .i2s_mode       = TEGRA_DAIFMT_DSP_A,
+               .sample_size    = 16,
        },
 };
 
@@ -715,18 +737,9 @@ static struct tegra_usb_platform_data tegra_ehci2_hsic_xmm_pdata = {
                .remote_wakeup_supported = false,
                .power_off_on_suspend = false,
        },
-       .u_cfg.hsic = {
-               .sync_start_delay = 9,
-               .idle_wait_delay = 17,
-               .term_range_adj = 0,
-               .elastic_underrun_limit = 16,
-               .elastic_overrun_limit = 16,
-       },
        .ops = &hsic_xmm_plat_ops,
 };
 
-
-
 static struct tegra_usb_platform_data tegra_udc_pdata = {
        .port_otg = true,
        .has_hostpc = true,
@@ -839,7 +852,6 @@ static struct platform_device *enterprise_audio_devices[] __initdata = {
        &tegra_dam_device2,
        &tegra_i2s_device0,
        &tegra_i2s_device1,
-       &tegra_i2s_device2,
        &tegra_i2s_device3,
        &tegra_spdif_device,
        &spdif_dit_device,
@@ -857,7 +869,14 @@ static void enterprise_audio_init(void)
        tegra_get_board_info(&board_info);
 
        if (board_info.board_id == BOARD_E1197)
-               enterprise_audio_pdata.audio_port_id[HIFI_CODEC] = 1;
+               enterprise_audio_pdata.i2s_param[HIFI_CODEC].audio_port_id = 1;
+       else if (board_info.fab == BOARD_FAB_A04) {
+               enterprise_audio_pdata.i2s_param[BASEBAND].audio_port_id = 4;
+               platform_device_register(&tegra_i2s_device4);
+       } else {
+               enterprise_audio_pdata.i2s_param[BASEBAND].audio_port_id = 2;
+               platform_device_register(&tegra_i2s_device2);
+       }
 
        platform_add_devices(enterprise_audio_devices,
                        ARRAY_SIZE(enterprise_audio_devices));
@@ -968,6 +987,13 @@ static void enterprise_nfc_init(void)
 
 static void __init tegra_enterprise_init(void)
 {
+       struct board_info board_info;
+       tegra_get_board_info(&board_info);
+       if (board_info.fab == BOARD_FAB_A04)
+               tegra_clk_init_from_table(enterprise_clk_i2s4_table);
+       else
+               tegra_clk_init_from_table(enterprise_clk_i2s2_table);
+
        tegra_thermal_init(&thermal_data,
                                throttle_list,
                                ARRAY_SIZE(throttle_list));
@@ -1010,6 +1036,11 @@ static void __init tegra_enterprise_reserve(void)
        tegra_ram_console_debug_reserve(SZ_1M);
 }
 
+static const char *enterprise_dt_board_compat[] = {
+       "nvidia,enterprise",
+       NULL
+};
+
 MACHINE_START(TEGRA_ENTERPRISE, "tegra_enterprise")
        .atag_offset    = 0x100,
        .soc            = &tegra_soc_desc,
@@ -1021,4 +1052,5 @@ MACHINE_START(TEGRA_ENTERPRISE, "tegra_enterprise")
        .timer          = &tegra_timer,
        .init_machine   = tegra_enterprise_init,
        .restart        = tegra_assert_system_reset,
+       .dt_compat      = enterprise_dt_board_compat,
 MACHINE_END
index 932ad0b..5856d0b 100644 (file)
@@ -58,8 +58,6 @@ static int harmony_backlight_init(struct device *dev)
        ret = gpio_direction_output(harmony_bl_enb, 1);
        if (ret < 0)
                gpio_free(harmony_bl_enb);
-       else
-               tegra_gpio_enable(harmony_bl_enb);
 
        return ret;
 }
@@ -338,19 +336,15 @@ int __init harmony_panel_init(void)
 
        gpio_request(harmony_en_vdd_pnl, "en_vdd_pnl");
        gpio_direction_output(harmony_en_vdd_pnl, 1);
-       tegra_gpio_enable(harmony_en_vdd_pnl);
 
        gpio_request(harmony_bl_vdd, "bl_vdd");
        gpio_direction_output(harmony_bl_vdd, 1);
-       tegra_gpio_enable(harmony_bl_vdd);
 
        gpio_request(harmony_lvds_shutdown, "lvds_shdn");
        gpio_direction_output(harmony_lvds_shutdown, 1);
-       tegra_gpio_enable(harmony_lvds_shutdown);
 
        gpio_request(harmony_hdmi_hpd, "hdmi_hpd");
        gpio_direction_input(harmony_hdmi_hpd);
-       tegra_gpio_enable(harmony_hdmi_hpd);
 
 #if defined(CONFIG_TEGRA_NVMAP)
        harmony_carveouts[1].base = tegra_carveout_start;
index eaac241..6f71662 100644 (file)
@@ -225,14 +225,6 @@ static struct platform_device harmony_gpio_keys_device = {
        }
 };
 
-static void harmony_keys_init(void)
-{
-       int i;
-
-       for (i = 0; i < ARRAY_SIZE(harmony_gpio_keys_buttons); i++)
-               tegra_gpio_enable(harmony_gpio_keys_buttons[i].gpio);
-}
-
 static struct tegra_wm8903_platform_data harmony_audio_pdata = {
        .gpio_spkr_en           = TEGRA_GPIO_SPKR_EN,
        .gpio_hp_det            = TEGRA_GPIO_HP_DET,
@@ -492,8 +484,6 @@ static int __init harmony_wifi_prepower(void)
                 pr_warning("Unable to get gpio for WLAN Power and Reset\n");
         else {
 
-               tegra_gpio_enable(TEGRA_GPIO_WLAN_PWR_LOW);
-               tegra_gpio_enable(TEGRA_GPIO_WLAN_RST_LOW);
                 /* toggle in this order as per spec */
                 gpio_direction_output(TEGRA_GPIO_WLAN_PWR_LOW, 0);
                 gpio_direction_output(TEGRA_GPIO_WLAN_RST_LOW, 0);
@@ -520,8 +510,6 @@ static void __init tegra_harmony_init(void)
 
        harmony_pinmux_init();
 
-       harmony_keys_init();
-
        harmony_uart_init();
 
        tegra_sdhci_device1.dev.platform_data = &sdhci_pdata1;
index 6f35cff..3bfcc0e 100644 (file)
@@ -28,7 +28,7 @@
 #include <mach/irqs.h>
 #include <mach/iomap.h>
 #include <mach/sdhci.h>
-#include <mach/gpio-tegra.h>
+#include <mach/io_dpd.h>
 
 #include "gpio-names.h"
 #include "board.h"
@@ -202,8 +202,21 @@ static int kai_wifi_set_carddetect(int val)
 
 static int kai_wifi_power(int power_on)
 {
+       struct tegra_io_dpd *sd_dpd;
        pr_err("Powering %s wifi\n", (power_on ? "on" : "off"));
 
+       /*
+        * FIXME : we need to revisit IO DPD code
+        * on how should multiple pins under DPD get controlled
+        *
+        * kai GPIO WLAN enable is part of SDMMC3 pin group
+        */
+       sd_dpd = tegra_io_dpd_get(&tegra_sdhci_device2.dev);
+       if (sd_dpd) {
+               mutex_lock(&sd_dpd->delay_lock);
+               tegra_io_dpd_disable(sd_dpd);
+               mutex_unlock(&sd_dpd->delay_lock);
+       }
        if (power_on) {
                gpio_set_value(KAI_WLAN_EN, 1);
                mdelay(15);
@@ -214,6 +227,11 @@ static int kai_wifi_power(int power_on)
        } else {
                gpio_set_value(KAI_WLAN_EN, 0);
        }
+       if (sd_dpd) {
+               mutex_lock(&sd_dpd->delay_lock);
+               tegra_io_dpd_enable(sd_dpd);
+               mutex_unlock(&sd_dpd->delay_lock);
+       }
 
        return 0;
 }
index 21f310b..bb28e27 100644 (file)
@@ -119,13 +119,8 @@ static __initdata struct tegra_drive_pingroup_config p1852_drive_pinmux[] = {
        SET_DRIVE(GMH,  DISABLE, ENABLE, DIV_1, 0,  12, SLOWEST, SLOWEST),
 
        /* I2S/TDM */
-#ifdef CONFIG_TEGRA_MODS
        SET_DRIVE(DAP1, ENABLE, ENABLE, DIV_1, 20,  20, SLOWEST, SLOWEST),
        SET_DRIVE(DAP3, ENABLE, ENABLE, DIV_1, 20,  20, SLOWEST, SLOWEST),
-#else
-       SET_DRIVE(DAP1, ENABLE, ENABLE, DIV_1, 3,  3, SLOWEST, SLOWEST),
-       SET_DRIVE(DAP3, ENABLE, ENABLE, DIV_1, 3,  3, SLOWEST, SLOWEST),
-#endif
 
        /* SPI */
        SET_DRIVE(UAD,          DISABLE, ENABLE, DIV_1, 4, 1, SLOWEST, SLOWEST),
@@ -184,6 +179,9 @@ static __initdata struct tegra_drive_pingroup_config p1852_drive_pinmux[] = {
        }
 
 
+static __initdata struct tegra_pingroup_config p1852_pinmux_i2s4_master[] = {
+       DEFAULT_PINMUX(SDMMC4_CLK,    NAND,   PULL_UP,    NORMAL, INPUT),
+};
 
 static __initdata struct tegra_pingroup_config p1852_pinmux_common[] = {
        /* SDMMC1 pinmux */
@@ -291,10 +289,10 @@ static __initdata struct tegra_pingroup_config p1852_pinmux_common[] = {
        DEFAULT_PINMUX(DAP3_SCLK,       I2S2,           NORMAL,         NORMAL,         INPUT),
 
        /* DAP3 */
-       LVPAD_PINMUX(SDMMC4_DAT4,       I2S4,           NORMAL,         NORMAL,         INPUT,  DISABLE,        DISABLE),
-       LVPAD_PINMUX(SDMMC4_DAT5,       I2S4,           NORMAL,         NORMAL,         INPUT,  DISABLE,        DISABLE),
-       LVPAD_PINMUX(SDMMC4_DAT6,       I2S4,           NORMAL,         NORMAL,         INPUT,  DISABLE,        DISABLE),
-       LVPAD_PINMUX(SDMMC4_DAT7,       I2S4,           NORMAL,         NORMAL,         INPUT,  DISABLE,        DISABLE),
+       DEFAULT_PINMUX(SDMMC4_DAT4,     I2S4,           NORMAL,         NORMAL,         INPUT),
+       DEFAULT_PINMUX(SDMMC4_DAT5,     I2S4,           NORMAL,         NORMAL,         INPUT),
+       DEFAULT_PINMUX(SDMMC4_DAT6,     I2S4,           NORMAL,         NORMAL,         INPUT),
+       DEFAULT_PINMUX(SDMMC4_DAT7,     I2S4,           NORMAL,         NORMAL,         INPUT),
 
        /* NOR pinmux */
        DEFAULT_PINMUX(GMI_AD0,         GMI,            NORMAL,         NORMAL,         INPUT),
@@ -427,7 +425,7 @@ static __initdata struct tegra_pingroup_config p1852_pinmux_common[] = {
        DEFAULT_PINMUX(GPIO_PV2,        RSVD1,  NORMAL, NORMAL, INPUT),
        DEFAULT_PINMUX(GPIO_PV3,        RSVD1,  NORMAL, NORMAL, INPUT),
        DEFAULT_PINMUX(SDMMC3_DAT7,     SDMMC3, NORMAL, NORMAL, INPUT),
-       LVPAD_PINMUX(SDMMC4_CLK,        NAND,   NORMAL, NORMAL, INPUT,  DISABLE,        DISABLE),
+       DEFAULT_PINMUX(SDMMC4_CLK,      NAND,   NORMAL, NORMAL, INPUT),
        DEFAULT_PINMUX(SDMMC3_CMD,      SDMMC3, NORMAL, NORMAL, INPUT),
        DEFAULT_PINMUX(SDMMC3_DAT3,     RSVD0,  NORMAL, NORMAL, INPUT),
        DEFAULT_PINMUX(VI_D1,           RSVD1,  NORMAL, NORMAL, INPUT),
@@ -445,6 +443,12 @@ int __init p1852_pinmux_init(void)
        return 0;
 }
 
+int p1852_pinmux_set_i2s4_master(void)
+{
+       tegra_pinmux_config_table(p1852_pinmux_i2s4_master,
+                                       ARRAY_SIZE(p1852_pinmux_i2s4_master));
+       return 0;
+}
 #define GPIO_INIT_PIN_MODE(_gpio, _is_input, _value)   \
        {                                       \
                .gpio_nr        = _gpio,        \
index 751ca49..e3c0174 100644 (file)
@@ -199,7 +199,6 @@ static void __init p1852_uart_init(void)
        platform_add_devices(p1852_uart_devices,
                                ARRAY_SIZE(p1852_uart_devices));
 }
-
 #if defined(CONFIG_TEGRA_P1852_TDM)
 static struct tegra_p1852_platform_data p1852_audio_tdm_pdata = {
        .codec_info[0] = {
@@ -242,6 +241,7 @@ static struct tegra_p1852_platform_data p1852_audio_i2s_pdata = {
                .name = "tegra-i2s-1",
                .pcm_driver = "tegra-pcm-audio",
                .i2s_format = format_i2s,
+               /* Defines whether the Audio codec chip is master or slave */
                .master = 1,
        },
        .codec_info[1] = {
@@ -251,6 +251,7 @@ static struct tegra_p1852_platform_data p1852_audio_i2s_pdata = {
                .name = "tegra-i2s-2",
                .pcm_driver = "tegra-pcm-audio",
                .i2s_format = format_i2s,
+               /* Defines whether the Audio codec chip is master or slave */
                .master = 0,
        },
 };
@@ -278,6 +279,8 @@ static struct platform_device tegra_snd_p1852 = {
 
 static void p1852_i2s_audio_init(void)
 {
+       struct tegra_p1852_platform_data *pdata;
+
        platform_device_register(&tegra_pcm_device);
        platform_device_register(&tegra_tdm_pcm_device);
        platform_device_register(&generic_codec_1);
@@ -286,6 +289,11 @@ static void p1852_i2s_audio_init(void)
        platform_device_register(&tegra_i2s_device4);
        platform_device_register(&tegra_ahub_device);
        platform_device_register(&tegra_snd_p1852);
+
+       /* Change pinmux of I2S4 for master mode */
+       pdata = tegra_snd_p1852.dev.platform_data;
+       if (!pdata->codec_info[1].master)
+               p1852_pinmux_set_i2s4_master();
 }
 
 
@@ -450,9 +458,6 @@ static __initdata struct tegra_clk_init_table spi_clk_init_table[] = {
 
 static int __init p1852_touch_init(void)
 {
-       tegra_gpio_enable(TOUCH_GPIO_IRQ_ATMEL_T9);
-       tegra_gpio_enable(TOUCH_GPIO_RST_ATMEL_T9);
-
        gpio_request(TOUCH_GPIO_IRQ_ATMEL_T9, "atmel-irq");
        gpio_direction_input(TOUCH_GPIO_IRQ_ATMEL_T9);
 
@@ -472,6 +477,32 @@ static int __init p1852_touch_init(void)
 
 #endif // CONFIG_TOUCHSCREEN_ATMEL_MXT
 
+#if defined(CONFIG_USB_G_ANDROID)
+static struct tegra_usb_platform_data tegra_udc_pdata = {
+       .port_otg = false,
+       .has_hostpc = true,
+       .phy_intf = TEGRA_USB_PHY_INTF_UTMI,
+       .op_mode = TEGRA_USB_OPMODE_DEVICE,
+       .u_data.dev = {
+               .vbus_pmu_irq = 0,
+               .vbus_gpio = -1,
+               .charging_supported = false,
+               .remote_wakeup_supported = false,
+       },
+       .u_cfg.utmi = {
+               .hssync_start_delay = 0,
+               .idle_wait_delay = 17,
+               .elastic_limit = 16,
+               .term_range_adj = 6,
+               .xcvr_setup = 63,
+               .xcvr_setup_offset = 6,
+               .xcvr_use_fuses = 1,
+               .xcvr_lsfslew = 2,
+               .xcvr_lsrslew = 2,
+               .xcvr_use_lsb = 1,
+       },
+};
+#else
 static struct tegra_usb_platform_data tegra_ehci1_utmi_pdata = {
        .port_otg = false,
        .has_hostpc = true,
@@ -497,6 +528,7 @@ static struct tegra_usb_platform_data tegra_ehci1_utmi_pdata = {
                .xcvr_use_lsb = 1,
        },
 };
+#endif
 
 static struct tegra_usb_platform_data tegra_ehci2_utmi_pdata = {
        .port_otg = false,
@@ -552,9 +584,16 @@ static struct tegra_usb_platform_data tegra_ehci3_utmi_pdata = {
 
 static void p1852_usb_init(void)
 {
+       /* Need to parse sku info to decide host/device mode */
+
+       /* G_ANDROID require device mode */
+#if defined(CONFIG_USB_G_ANDROID)
+       tegra_udc_device.dev.platform_data = &tegra_udc_pdata;
+       platform_device_register(&tegra_udc_device);
+#else
        tegra_ehci1_device.dev.platform_data = &tegra_ehci1_utmi_pdata;
        platform_device_register(&tegra_ehci1_device);
-
+#endif
        tegra_ehci2_device.dev.platform_data = &tegra_ehci2_utmi_pdata;
        platform_device_register(&tegra_ehci2_device);
 
index 529bd38..7de6a6b 100644 (file)
 
 int p1852_sdhci_init(void);
 int p1852_pinmux_init(void);
+int p1852_pinmux_set_i2s4_master(void);
 int p1852_panel_init(void);
 int p1852_gpio_init(void);
 int p1852_pins_state_init(void);
index 4bad72f..f9b4344 100644 (file)
@@ -41,11 +41,9 @@ static struct rmi_f19_button_map synaptics_button_map = {
 static int synaptics_touchpad_gpio_setup(void *gpio_data, bool configure)
 {
        if (configure) {
-               tegra_gpio_enable(SYNAPTICS_ATTN_GPIO);
                gpio_request(SYNAPTICS_ATTN_GPIO, "synaptics-irq");
                gpio_direction_input(SYNAPTICS_ATTN_GPIO);
 
-               tegra_gpio_enable(SYNAPTICS_RESET_GPIO);
                gpio_request(SYNAPTICS_RESET_GPIO, "synaptics-reset");
                gpio_direction_output(SYNAPTICS_RESET_GPIO, 0);
 
@@ -55,8 +53,6 @@ static int synaptics_touchpad_gpio_setup(void *gpio_data, bool configure)
        } else {
                gpio_free(SYNAPTICS_ATTN_GPIO);
                gpio_free(SYNAPTICS_RESET_GPIO);
-               tegra_gpio_disable(SYNAPTICS_ATTN_GPIO);
-               tegra_gpio_disable(SYNAPTICS_RESET_GPIO);
        }
        return 0;
 }
index 6fd9f0f..6015418 100644 (file)
@@ -203,11 +203,9 @@ struct spi_board_info rm31080a_spi_board[1] = {
 int __init touch_init_raydium(int irq_gpio, int reset_gpio, int platform)
 {
        int err = 0;
-       tegra_gpio_enable(irq_gpio);
        gpio_request(irq_gpio, "raydium-irq");
        gpio_direction_input(irq_gpio);
 
-       tegra_gpio_enable(reset_gpio);
        gpio_request(reset_gpio, "raydium-reset");
        gpio_direction_output(reset_gpio, 0);
 
index 3dd44ad..00fc459 100644 (file)
@@ -416,9 +416,6 @@ static struct i2c_board_info __initdata i2c_info[] = {
 static int __init ventana_touch_init_atmel(void)
 {
        i2c_info[0].irq = gpio_to_irq(TEGRA_GPIO_PV6);
-       tegra_gpio_enable(TEGRA_GPIO_PV6);
-       tegra_gpio_enable(TEGRA_GPIO_PQ7);
-
        gpio_request(TEGRA_GPIO_PV6, "atmel-irq");
        gpio_direction_input(TEGRA_GPIO_PV6);
 
@@ -446,9 +443,6 @@ static struct i2c_board_info __initdata ventana_i2c_bus1_touch_info[] = {
 
 static int __init ventana_touch_init_panjit(void)
 {
-       tegra_gpio_enable(TEGRA_GPIO_PV6);
-       tegra_gpio_enable(TEGRA_GPIO_PQ7);
-
        ventana_i2c_bus1_touch_info[0].irq = gpio_to_irq(TEGRA_GPIO_PV6);
        i2c_register_board_info(0, ventana_i2c_bus1_touch_info, 1);
 
@@ -463,7 +457,6 @@ static int __init ventana_gps_init(void)
                clk_enable(clk32);
        }
 
-       tegra_gpio_enable(TEGRA_GPIO_PZ3);
        return 0;
 }
 
@@ -520,9 +513,6 @@ static void ulpi_link_platform_open(void)
 
        gpio_request(reset_gpio, "ulpi_phy_reset");
        gpio_direction_output(reset_gpio, 0);
-       tegra_gpio_enable(reset_gpio);
-
-       gpio_direction_output(reset_gpio, 0);
        msleep(5);
        gpio_direction_output(reset_gpio, 1);
 }
@@ -655,6 +645,11 @@ void __init tegra_ventana_reserve(void)
        tegra_ram_console_debug_reserve(SZ_1M);
 }
 
+static const char *ventana_dt_board_compat[] = {
+       "nvidia,ventana",
+       NULL
+};
+
 MACHINE_START(VENTANA, "ventana")
        .atag_offset    = 0x100,
        .soc            = &tegra_soc_desc,
@@ -666,4 +661,5 @@ MACHINE_START(VENTANA, "ventana")
        .timer          = &tegra_timer,
        .init_machine   = tegra_ventana_init,
        .restart        = tegra_assert_system_reset,
+       .dt_compat      = ventana_dt_board_compat,
 MACHINE_END
index 33fe754..bc83df6 100644 (file)
@@ -529,6 +529,11 @@ void __init tegra_whistler_reserve(void)
        tegra_ram_console_debug_reserve(SZ_1M);
 }
 
+static const char *whistler_dt_board_compat[] = {
+       "nvidia,whistler",
+       NULL
+};
+
 MACHINE_START(WHISTLER, "whistler")
        .atag_offset    = 0x100,
        .soc            = &tegra_soc_desc,
@@ -540,4 +545,5 @@ MACHINE_START(WHISTLER, "whistler")
        .timer          = &tegra_timer,
        .init_machine   = tegra_whistler_init,
        .restart        = tegra_assert_system_reset,
+       .dt_compat      = whistler_dt_board_compat,
 MACHINE_END
index bece0b0..9ed65fa 100644 (file)
@@ -41,7 +41,7 @@ struct clk;
 #define USE_PLL_LOCK_BITS 1    /* Use lock bits for PLL stabiliation */
 #define USE_PLLE_SS 1          /* Use spread spectrum coefficients for PLLE */
 #ifdef CONFIG_ARCH_TEGRA_3x_SOC
-#define PLL_POST_LOCK_DELAY 2  /* Safety delay after lock is detected */
+#define PLL_POST_LOCK_DELAY 50 /* Safety delay after lock is detected */
 #else
 #define PLL_POST_LOCK_DELAY 10 /* Safety delay after lock is detected */
 #endif
index ac4536b..a268033 100644 (file)
@@ -30,6 +30,7 @@
 #include <linux/bitops.h>
 #include <linux/sched.h>
 #include <linux/cpufreq.h>
+#include <linux/of.h>
 
 #include <asm/soc.h>
 #include <asm/hardware/cache-l2x0.h>
@@ -849,11 +850,54 @@ __setup("audio_codec=", tegra_audio_codec_type);
 
 void tegra_get_board_info(struct board_info *bi)
 {
-       bi->board_id = (system_serial_high >> 16) & 0xFFFF;
-       bi->sku = (system_serial_high) & 0xFFFF;
-       bi->fab = (system_serial_low >> 24) & 0xFF;
-       bi->major_revision = (system_serial_low >> 16) & 0xFF;
-       bi->minor_revision = (system_serial_low >> 8) & 0xFF;
+#ifdef CONFIG_OF
+       struct device_node *board_info;
+       u32 prop_val;
+       int err;
+
+       board_info = of_find_node_by_path("/chosen/board_info");
+       if (!IS_ERR_OR_NULL(board_info)) {
+               memset(bi, 0, sizeof(*bi));
+
+               err = of_property_read_u32(board_info, "id", &prop_val);
+               if (err)
+                       pr_err("failed to read /chosen/board_info/id\n");
+               else
+                       bi->board_id = prop_val;
+
+               err = of_property_read_u32(board_info, "sku", &prop_val);
+               if (err)
+                       pr_err("failed to read /chosen/board_info/sku\n");
+               else
+                       bi->sku = prop_val;
+
+               err = of_property_read_u32(board_info, "fab", &prop_val);
+               if (err)
+                       pr_err("failed to read /chosen/board_info/fab\n");
+               else
+                       bi->fab = prop_val;
+
+               err = of_property_read_u32(board_info, "major_revision", &prop_val);
+               if (err)
+                       pr_err("failed to read /chosen/board_info/major_revision\n");
+               else
+                       bi->major_revision = prop_val;
+
+               err = of_property_read_u32(board_info, "minor_revision", &prop_val);
+               if (err)
+                       pr_err("failed to read /chosen/board_info/minor_revision\n");
+               else
+                       bi->minor_revision = prop_val;
+       } else {
+#endif
+               bi->board_id = (system_serial_high >> 16) & 0xFFFF;
+               bi->sku = (system_serial_high) & 0xFFFF;
+               bi->fab = (system_serial_low >> 24) & 0xFF;
+               bi->major_revision = (system_serial_low >> 16) & 0xFF;
+               bi->minor_revision = (system_serial_low >> 8) & 0xFF;
+#ifdef CONFIG_OF
+       }
+#endif
 }
 
 static int __init tegra_pmu_board_info(char *info)
index 830a664..46e73d8 100644 (file)
@@ -3,7 +3,7 @@
  *
  * CPU auto-hotplug for Tegra3 CPUs
  *
- * Copyright (c) 2011-2012, NVIDIA Corporation.
+ * Copyright (c) 2011-2012, NVIDIA Corporation. 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 as published by
@@ -41,7 +41,7 @@
 #define INITIAL_STATE          TEGRA_HP_DISABLED
 #define UP2G0_DELAY_MS         70
 #define UP2Gn_DELAY_MS         100
-#define DOWN_DELAY_MS          500
+#define DOWN_DELAY_MS          2000
 
 static struct mutex *tegra3_cpu_lock;
 
@@ -189,10 +189,38 @@ enum {
 };
 
 #define NR_FSHIFT      2
-static unsigned int nr_run_thresholds[] = {
+
+static unsigned int rt_profile_sel;
+
+/* avg run threads * 4 (e.g., 9 = 2.25 threads) */
+
+static unsigned int rt_profile_default[] = {
 /*      1,  2,  3,  4 - on-line cpus target */
-       5,  9, 10, UINT_MAX /* avg run threads * 4 (e.g., 9 = 2.25 threads) */
+       5,  9, 10, UINT_MAX
+};
+
+static unsigned int rt_profile_1[] = {
+/*      1,  2,  3,  4 - on-line cpus target */
+       8,  9, 10, UINT_MAX
+};
+
+static unsigned int rt_profile_2[] = {
+/*      1,  2,  3,  4 - on-line cpus target */
+       5,  13, 14, UINT_MAX
+};
+
+static unsigned int rt_profile_off[] = { /* disables runable thread */
+       0,  0,  0, UINT_MAX
+};
+
+static unsigned int *rt_profiles[] = {
+       rt_profile_default,
+       rt_profile_1,
+       rt_profile_2,
+       rt_profile_off
 };
+
+
 static unsigned int nr_run_hysteresis = 2;     /* 0.5 thread */
 static unsigned int nr_run_last;
 
@@ -216,8 +244,10 @@ static noinline int tegra_cpu_speed_balance(void)
         * TEGRA_CPU_SPEED_BIASED to keep CPU core composition unchanged
         * TEGRA_CPU_SPEED_SKEWED to remove CPU core off-line
         */
-       for (nr_run = 1; nr_run < ARRAY_SIZE(nr_run_thresholds); nr_run++) {
-               unsigned int nr_threshold = nr_run_thresholds[nr_run - 1];
+
+       unsigned int *current_profile = rt_profiles[rt_profile_sel];
+       for (nr_run = 1; nr_run < ARRAY_SIZE(rt_profile_default); nr_run++) {
+               unsigned int nr_threshold = current_profile[nr_run - 1];
                if (nr_run_last <= nr_run)
                        nr_threshold += nr_run_hysteresis;
                if (avg_nr_run <= (nr_threshold << (FSHIFT - NR_FSHIFT)))
@@ -527,6 +557,25 @@ static const struct file_operations hp_stats_fops = {
        .release        = single_release,
 };
 
+static int rt_bias_get(void *data, u64 *val)
+{
+       *val = rt_profile_sel;
+       return 0;
+}
+static int rt_bias_set(void *data, u64 val)
+{
+       if (val < ARRAY_SIZE(rt_profiles))
+               rt_profile_sel = (u32)val;
+
+       pr_debug("rt_profile_sel set to %d\nthresholds are now [%d, %d, %d]\n",
+               rt_profile_sel,
+               rt_profiles[rt_profile_sel][0],
+               rt_profiles[rt_profile_sel][1],
+               rt_profiles[rt_profile_sel][2]);
+       return 0;
+}
+DEFINE_SIMPLE_ATTRIBUTE(rt_bias_fops, rt_bias_get, rt_bias_set, "%llu\n");
+
 static int min_cpus_get(void *data, u64 *val)
 {
        *val = pm_qos_request(PM_QOS_MIN_ONLINE_CPUS);
@@ -577,6 +626,10 @@ static int __init tegra_auto_hotplug_debug_init(void)
                "stats", S_IRUGO, hp_debugfs_root, NULL, &hp_stats_fops))
                goto err_out;
 
+       if (!debugfs_create_file(
+               "core_bias", S_IRUGO, hp_debugfs_root, NULL, &rt_bias_fops))
+               goto err_out;
+
        return 0;
 
 err_out:
index ee535b2..07f9dc8 100644 (file)
@@ -38,6 +38,7 @@
 #include "board.h"
 #include "clock.h"
 #include "dvfs.h"
+#include "timer.h"
 
 #define DVFS_RAIL_STATS_BIN    25
 #define DVFS_RAIL_STATS_SCALE  2
@@ -308,6 +309,13 @@ static int dvfs_rail_connect_to_regulator(struct dvfs_rail *rail)
                rail->reg = reg;
        }
 
+       v = regulator_enable(rail->reg);
+       if (v < 0) {
+               pr_err("tegra_dvfs: failed on enabling regulator %s\n, err %d",
+                       rail->reg_id, v);
+               return v;
+       }
+
        v = regulator_get_voltage(rail->reg);
        if (v < 0) {
                pr_err("tegra_dvfs: failed initial get %s voltage\n",
@@ -681,9 +689,13 @@ int __init tegra_dvfs_late_init(void)
 {
        bool connected = true;
        struct dvfs_rail *rail;
+       int cur_linear_age = tegra_get_linear_age();
 
        mutex_lock(&dvfs_lock);
 
+       if (cur_linear_age >= 0)
+               tegra_dvfs_age_cpu(cur_linear_age);
+
        list_for_each_entry(rail, &dvfs_rail_list, node)
                if (dvfs_rail_connect_to_regulator(rail))
                        connected = false;
index 5aae435..6a7c6bd 100644 (file)
@@ -22,7 +22,7 @@
 #define _TEGRA_DVFS_H_
 
 #define MAX_DVFS_FREQS 40
-#define DVFS_RAIL_STATS_TOP_BIN        40
+#define DVFS_RAIL_STATS_TOP_BIN        42
 
 struct clk;
 struct dvfs_rail;
@@ -126,11 +126,14 @@ int tegra_cpu_dvfs_alter(int edp_thermal_index, const cpumask_t *cpus,
 #ifndef CONFIG_ARCH_TEGRA_2x_SOC
 int tegra_dvfs_rail_disable_prepare(struct dvfs_rail *rail);
 int tegra_dvfs_rail_post_enable(struct dvfs_rail *rail);
+void tegra_dvfs_age_cpu(int cur_linear_age);
 #else
 static inline int tegra_dvfs_rail_disable_prepare(struct dvfs_rail *rail)
 { return 0; }
 static inline int tegra_dvfs_rail_post_enable(struct dvfs_rail *rail)
 { return 0; }
+static inline void tegra_dvfs_age_cpu(int cur_linear_age)
+{ return; }
 #endif
 
 #endif
index 5a9b47e..30e3844 100644 (file)
 
 #endif
 
+#define TEGRA_AGE_0_6 0x2cc /*Spare bit 34*/
+#define TEGRA_AGE_1_6 0x308 /*Spare bit 49*/
+#define TEGRA_AGE_0_5 0x2c8 /*Spare bit 33*/
+#define TEGRA_AGE_1_5 0x304 /*Spare bit 48*/
+#define TEGRA_AGE_0_4 0x2c4 /*Spare bit 32*/
+#define TEGRA_AGE_1_4 0x300 /*Spare bit 47*/
+#define TEGRA_AGE_0_3 0x2c0 /*Spare bit 31*/
+#define TEGRA_AGE_1_3 0x2fc /*Spare bit 46*/
+#define TEGRA_AGE_0_2 0x2bc /*Spare bit 30*/
+#define TEGRA_AGE_1_2 0x2f8 /*Spare bit 45*/
+#define TEGRA_AGE_0_1 0x2b8 /*Spare bit 29*/
+#define TEGRA_AGE_1_1 0x2f4 /*Spare bit 44*/
+#define TEGRA_AGE_0_0 0x2b4 /*Spare bit 28*/
+#define TEGRA_AGE_1_0 0x2f0 /*Spare bit 43*/
+
 struct tegra_id {
        enum tegra_chipid chipid;
        unsigned int major, minor, netlist, patch;
@@ -187,6 +202,35 @@ int tegra_fuse_get_cpu_iddq_mA(u32 *iddq)
 }
 #endif
 
+#define TEGRA_READ_AGE_BIT(n, bit, age) {\
+       bit = tegra_fuse_readl(TEGRA_AGE_0_##n);\
+       bit |= tegra_fuse_readl(TEGRA_AGE_1_##n);\
+       bit = bit << n;\
+       age |= bit;\
+}
+
+int tegra_get_age(void)
+{
+       int linear_age, age_bit;
+       linear_age = age_bit = 0;
+
+       TEGRA_READ_AGE_BIT(6, age_bit, linear_age);
+       TEGRA_READ_AGE_BIT(5, age_bit, linear_age);
+       TEGRA_READ_AGE_BIT(4, age_bit, linear_age);
+       TEGRA_READ_AGE_BIT(3, age_bit, linear_age);
+       TEGRA_READ_AGE_BIT(2, age_bit, linear_age);
+       TEGRA_READ_AGE_BIT(1, age_bit, linear_age);
+       TEGRA_READ_AGE_BIT(0, age_bit, linear_age);
+
+       /*Default Aug, 2012*/
+       if (linear_age <= 0)
+               linear_age = 8;
+
+       pr_info("TEGRA: Linear age: %d\n", linear_age);
+
+       return linear_age;
+}
+
 unsigned long long tegra_chip_uid(void)
 {
 #if defined(CONFIG_ARCH_TEGRA_2x_SOC)
index 2e12d91..9a084d8 100644 (file)
@@ -50,6 +50,7 @@ int tegra_soc_speedo_id(void);
 void tegra_init_speedo_data(void);
 int tegra_cpu_process_id(void);
 int tegra_core_process_id(void);
+int tegra_get_age(void);
 
 #ifndef CONFIG_ARCH_TEGRA_2x_SOC
 int tegra_package_id(void);
index 3b9bb98..3a9a682 100644 (file)
@@ -46,7 +46,6 @@ int arb_lost_recovery(int scl_gpio, int sda_gpio)
                        scl_gpio, ret);\r
                return -EINVAL;;\r
        }\r
-       tegra_gpio_enable(scl_gpio);\r
 \r
        ret = gpio_request(sda_gpio, "sda_gpio");\r
        if (ret < 0) {\r
@@ -54,7 +53,6 @@ int arb_lost_recovery(int scl_gpio, int sda_gpio)
                        sda_gpio, ret);\r
                goto err;\r
        }\r
-       tegra_gpio_enable(sda_gpio);\r
        gpio_direction_input(sda_gpio);\r
 \r
        while (retry--) {\r
@@ -84,9 +82,7 @@ int arb_lost_recovery(int scl_gpio, int sda_gpio)
        }\r
 \r
        gpio_free(scl_gpio);\r
-       tegra_gpio_disable(scl_gpio);\r
        gpio_free(sda_gpio);\r
-       tegra_gpio_disable(sda_gpio);\r
 \r
        if (likely(recovered_successfully)) {\r
                pr_err("arbitration lost recovered by re-try-count 0x%08x\n",\r
@@ -99,7 +95,6 @@ int arb_lost_recovery(int scl_gpio, int sda_gpio)
 \r
 err:\r
        gpio_free(scl_gpio);\r
-       tegra_gpio_disable(scl_gpio);\r
        return ret;\r
 }\r
 \r
index 2c825f0..92b0e07 100644 (file)
@@ -25,6 +25,7 @@
 #include <linux/pm.h>
 #include <linux/types.h>
 #include <drm/drm_fixed.h>
+#include <linux/notifier.h>
 
 #define TEGRA_MAX_DC           2
 #define DC_N_WINDOWS           3
@@ -645,4 +646,8 @@ struct tegra_dc_edid {
 struct tegra_dc_edid *tegra_dc_get_edid(struct tegra_dc *dc);
 void tegra_dc_put_edid(struct tegra_dc_edid *edid);
 
+int tegra_dc_register_flip_notifier(struct notifier_block *nb);
+int tegra_dc_unregister_flip_notifier(struct notifier_block *nb);
+int tegra_dc_get_panel_sync_rate(void);
+
 #endif
index 27fd033..91eeed3 100644 (file)
@@ -1,7 +1,7 @@
 /*
  * arch/arm/mach-tegra/latency_allowance.c
  *
- * Copyright (C) 2011 NVIDIA Corporation
+ * Copyright (C) 2011-2012, NVIDIA CORPORATION. All rights reserved.
  *
  * This software is licensed under the terms of the GNU General Public
  * License version 2, as published by the Free Software Foundation, and
                printk(KERN_INFO pr_fmt(fmt), ##__VA_ARGS__); \
        }
 
+/* Bug 995270 */
+#define HACK_LA_FIFO 1
+
 static struct dentry *latency_debug_dir;
 
 struct la_client_info {
@@ -387,7 +390,9 @@ int tegra_set_latency_allowance(enum tegra_la_id id,
        int la_to_set;
        unsigned long reg_read;
        unsigned long reg_write;
+       unsigned int fifo_size_in_atoms;
        int bytes_per_atom = normal_atom_size;
+       const int fifo_scale = 4;               /* 25% of the FIFO */
        struct la_client_info *ci;
 
        VALIDATE_ID(id);
@@ -397,11 +402,19 @@ int tegra_set_latency_allowance(enum tegra_la_id id,
                bytes_per_atom = fdc_atom_size;
 
        ci = &la_info[id];
+       fifo_size_in_atoms = ci->fifo_size_in_atoms;
+
+#if HACK_LA_FIFO
+       /* pretend that our FIFO is only as deep as the lowest fullness
+        * we expect to see */
+       if (id >= ID(DISPLAY_0A) && id <= ID(DISPLAY_HCB))
+               fifo_size_in_atoms /= fifo_scale;
+#endif
 
        if (bandwidth_in_mbps == 0) {
                la_to_set = MC_LA_MAX_VALUE;
        } else {
-               ideal_la = (ci->fifo_size_in_atoms * bytes_per_atom * 1000) /
+               ideal_la = (fifo_size_in_atoms * bytes_per_atom * 1000) /
                           (bandwidth_in_mbps * ns_per_tick);
                la_to_set = ideal_la - (ci->expiration_in_ns/ns_per_tick) - 1;
        }
@@ -412,11 +425,6 @@ int tegra_set_latency_allowance(enum tegra_la_id id,
        la_to_set = (la_to_set > MC_LA_MAX_VALUE) ? MC_LA_MAX_VALUE : la_to_set;
        scaling_info[id].actual_la_to_set = la_to_set;
 
-       /* until display can use latency allowance scaling, use a more
-        * aggressive LA setting. Bug 862709 */
-       if (id >= ID(DISPLAY_0A) && id <= ID(DISPLAY_HCB))
-               la_to_set /= 3;
-
        spin_lock(&safety_lock);
        reg_read = readl(ci->reg_addr);
        reg_write = (reg_read & ~ci->mask) |
index 39e2899..ddab299 100644 (file)
 #define   USB_USBSTS_SRI       (1 << 7)
 #define   USB_USBSTS_HCH       (1 << 12)
 
+#define USB_USBINTR            0x148
+
 #define USB_ASYNCLISTADDR      0x158
 
 #define USB_TXFILLTUNING               0x164
 #define USB_FIFO_TXFILL_THRES(x)   (((x) & 0x1f) << 16)
-#define USB_FIFO_TXFILL_MASK   0x1f0000
+#define USB_FIFO_TXFILL_MASK   0x3f0000
 
 #define ULPI_VIEWPORT          0x170
 #define   ULPI_WAKEUP          (1 << 31)
@@ -72,6 +74,7 @@
 #define   USB_PORTSC_PP        (1 << 12)
 #define   USB_PORTSC_LS(x) (((x) & 0x3) << 10)
 #define   USB_PORTSC_SUSP      (1 << 7)
+#define   USB_PORTSC_RESUME    (1 << 6)
 #define   USB_PORTSC_OCC       (1 << 5)
 #define   USB_PORTSC_PEC       (1 << 3)
 #define   USB_PORTSC_PE                (1 << 2)
 #define DBG(stuff...)  do {} while (0)
 #endif
 
+/* define HSIC phy params */
+#define HSIC_SYNC_START_DELAY          9
+#define HSIC_IDLE_WAIT_DELAY           17
+#define HSIC_ELASTIC_UNDERRUN_LIMIT    16
+#define HSIC_ELASTIC_OVERRUN_LIMIT     16
 
 static DEFINE_SPINLOCK(utmip_pad_lock);
 static int utmip_pad_count;
@@ -721,7 +729,8 @@ static int utmi_phy_power_off(struct tegra_usb_phy *phy)
                        val |= USB_PHY_CLK_VALID_INT_ENB;
                        writel(val, base + USB_SUSP_CTRL);
                } else {
-                       /* Disable PHY clock valid interrupts while going into suspend*/
+                       /* Disable PHY clock valid interrupts
+                               while going into suspend*/
                        val = readl(base + USB_SUSP_CTRL);
                        val &= ~USB_PHY_CLK_VALID_INT_ENB;
                        writel(val, base + USB_SUSP_CTRL);
@@ -943,7 +952,8 @@ static int utmi_phy_resume(struct tegra_usb_phy *phy)
 
                        if (usb_phy_reg_status_wait(base + USB_USBCMD,
                                USB_USBCMD_RESET, 0, 2500) < 0) {
-                               pr_err("%s: timeout waiting for reset\n", __func__);
+                               pr_err("%s: timeout waiting for reset\n",
+                                       __func__);
                        }
 
                        val = readl(base + USB_USBMODE_REG_OFFSET);
@@ -960,7 +970,8 @@ static int utmi_phy_resume(struct tegra_usb_phy *phy)
 
                        if (usb_phy_reg_status_wait(base + USB_USBCMD,
                                USB_USBCMD_RS, USB_USBCMD_RS, 2500) < 0) {
-                               pr_err("%s: timeout waiting for run bit\n", __func__);
+                               pr_err("%s: timeout waiting for run bit\n",
+                                       __func__);
                        }
 
                        /* Enable Port Power */
@@ -970,7 +981,8 @@ static int utmi_phy_resume(struct tegra_usb_phy *phy)
                        udelay(10);
 
                        DBG("USB_USBSTS[0x%x] USB_PORTSC[0x%x]\n",
-                               readl(base + USB_USBSTS), readl(base + USB_PORTSC));
+                               readl(base + USB_USBSTS),
+                               readl(base + USB_PORTSC));
                }
        } else {
                /* Restoring the pad powers */
@@ -1062,7 +1074,6 @@ static int uhsic_phy_power_on(struct tegra_usb_phy *phy)
 {
        unsigned long val;
        void __iomem *base = phy->regs;
-       struct tegra_hsic_config *config = &phy->pdata->u_cfg.hsic;
 
        DBG("%s(%d) inst:[%d]\n", __func__, __LINE__, phy->inst);
        if (phy->phy_clk_on) {
@@ -1088,13 +1099,13 @@ static int uhsic_phy_power_on(struct tegra_usb_phy *phy)
        writel(val, base + USB_SUSP_CTRL);
 
        val = readl(base + UTMIP_XCVR_UHSIC_HSRX_CFG0);
-       val |= UHSIC_IDLE_WAIT(config->idle_wait_delay);
-       val |= UHSIC_ELASTIC_UNDERRUN_LIMIT(config->elastic_underrun_limit);
-       val |= UHSIC_ELASTIC_OVERRUN_LIMIT(config->elastic_overrun_limit);
+       val |= UHSIC_IDLE_WAIT(HSIC_IDLE_WAIT_DELAY);
+       val |= UHSIC_ELASTIC_UNDERRUN_LIMIT(HSIC_ELASTIC_UNDERRUN_LIMIT);
+       val |= UHSIC_ELASTIC_OVERRUN_LIMIT(HSIC_ELASTIC_OVERRUN_LIMIT);
        writel(val, base + UTMIP_XCVR_UHSIC_HSRX_CFG0);
 
        val = readl(base + UHSIC_HSRX_CFG1);
-       val |= UHSIC_HS_SYNC_START_DLY(config->sync_start_delay);
+       val |= UHSIC_HS_SYNC_START_DLY(HSIC_SYNC_START_DELAY);
        writel(val, base + UHSIC_HSRX_CFG1);
 
        val = readl(base + UHSIC_MISC_CFG0);
@@ -1365,7 +1376,7 @@ static int ulpi_link_phy_open(struct tegra_usb_phy *phy)
 
        phy->ulpi_vp = otg_ulpi_create(&ulpi_viewport_access_ops, 0);
        phy->ulpi_vp->io_priv = phy->regs + ULPI_VIEWPORT;
-
+       phy->linkphy_init = true;
        return err;
 }
 
@@ -1461,49 +1472,74 @@ static int ulpi_link_phy_power_on(struct tegra_usb_phy *phy)
        }
 
        val = readl(base + USB_SUSP_CTRL);
-       val |= UHSIC_RESET;
-       writel(val, base + USB_SUSP_CTRL);
 
-       val = readl(base + ULPI_TIMING_CTRL_0);
-       val |= ULPI_OUTPUT_PINMUX_BYP | ULPI_CLKOUT_PINMUX_BYP;
-       writel(val, base + ULPI_TIMING_CTRL_0);
+       /* Case for lp0 */
+       if (!(val & UHSIC_RESET)) {
+               val |= UHSIC_RESET;
+               writel(val, base + USB_SUSP_CTRL);
 
-       val = readl(base + USB_SUSP_CTRL);
-       val |= ULPI_PHY_ENABLE;
-       writel(val, base + USB_SUSP_CTRL);
+               val = 0;
+               writel(val, base + ULPI_TIMING_CTRL_1);
 
-       val = readl(base + USB_SUSP_CTRL);
-       val |= USB_SUSP_CLR;
-       writel(val, base + USB_SUSP_CTRL);
+               ulpi_set_trimmer(phy);
 
-       if (usb_phy_reg_status_wait(base + USB_SUSP_CTRL, USB_PHY_CLK_VALID,
-                                               USB_PHY_CLK_VALID, 2500))
-               pr_err("%s: timeout waiting for phy to stabilize\n", __func__);
+               val = readl(base + ULPI_TIMING_CTRL_0);
+               val |= ULPI_OUTPUT_PINMUX_BYP | ULPI_CLKOUT_PINMUX_BYP;
+               writel(val, base + ULPI_TIMING_CTRL_0);
+#ifdef CONFIG_ARCH_TEGRA_2x_SOC
+               tegra_pinmux_set_tristate(TEGRA_PINGROUP_UAA, TEGRA_TRI_NORMAL);
+               tegra_pinmux_set_tristate(TEGRA_PINGROUP_UAB, TEGRA_TRI_NORMAL);
+               tegra_pinmux_set_tristate(TEGRA_PINGROUP_UDA, TEGRA_TRI_NORMAL);
+#endif
+               val = readl(base + USB_SUSP_CTRL);
+               val |= ULPI_PHY_ENABLE;
+               writel(val, base + USB_SUSP_CTRL);
 
-       if (usb_phy_reg_status_wait(base + USB_SUSP_CTRL, USB_CLKEN,
-                                               USB_CLKEN, 2500))
-               pr_err("%s: timeout waiting for AHB clock\n", __func__);
+               if (usb_phy_reg_status_wait(base + USB_SUSP_CTRL,
+                       USB_PHY_CLK_VALID, USB_PHY_CLK_VALID, 2500) < 0)
+                       pr_err("%s: timeout waiting for phy" \
+                       "to stabilize\n", __func__);
 
-       val = readl(base + USB_SUSP_CTRL);
-       val &= ~USB_SUSP_CLR;
-       writel(val, base + USB_SUSP_CTRL);
+               val = readl(base + USB_TXFILLTUNING);
+               if ((val & USB_FIFO_TXFILL_MASK) !=
+                               USB_FIFO_TXFILL_THRES(0x10)) {
+                       val = USB_FIFO_TXFILL_THRES(0x10);
+                       writel(val, base + USB_TXFILLTUNING);
+               }
+       } else {
+       /* Case for auto resume*/
+               val = readl(base + USB_SUSP_CTRL);
+               val |= USB_SUSP_CLR;
+               writel(val, base + USB_SUSP_CTRL);
 
-       val = 0;
-       writel(val, base + ULPI_TIMING_CTRL_1);
+               if (usb_phy_reg_status_wait(base + USB_SUSP_CTRL,
+                       USB_PHY_CLK_VALID, USB_PHY_CLK_VALID, 2500) < 0)
+                       pr_err("%s: timeout waiting for phy" \
+                                       "to stabilize\n", __func__);
 
-       ulpi_set_trimmer(phy);
+               if (usb_phy_reg_status_wait(base + USB_SUSP_CTRL,
+                       USB_CLKEN, USB_CLKEN, 2500) < 0)
+                       pr_err("%s: timeout waiting for AHB clock\n", __func__);
 
-       /* Fix VbusInvalid due to floating VBUS */
-       ret = usb_phy_io_write(phy->ulpi_vp, 0x40, 0x08);
-       if (ret) {
-               pr_err("%s: ulpi write failed\n", __func__);
-               return ret;
+               val = readl(base + USB_SUSP_CTRL);
+               val &= ~USB_SUSP_CLR;
+               writel(val, base + USB_SUSP_CTRL);
        }
+       if (phy->linkphy_init) {
+               /* To be done only incase of coldboot*/
+               /* Fix VbusInvalid due to floating VBUS */
+               ret = usb_phy_io_write(phy->ulpi_vp, 0x40, 0x08);
+               if (ret) {
+                       pr_err("%s: ulpi write failed\n", __func__);
+                       return ret;
+               }
 
-       ret = usb_phy_io_write(phy->ulpi_vp, 0x80, 0x0B);
-       if (ret) {
-               pr_err("%s: ulpi write failed\n", __func__);
-               return ret;
+               ret = usb_phy_io_write(phy->ulpi_vp, 0x80, 0x0B);
+               if (ret) {
+                       pr_err("%s: ulpi write failed\n", __func__);
+                       return ret;
+               }
+               phy->linkphy_init = false;
        }
 
        val = readl(base + USB_PORTSC);
@@ -1521,6 +1557,7 @@ static inline void ulpi_link_phy_set_tristate(bool enable)
 #ifdef CONFIG_ARCH_TEGRA_2x_SOC
        int tristate = (enable) ? TEGRA_TRI_TRISTATE : TEGRA_TRI_NORMAL;
 
+       tegra_pinmux_set_tristate(TEGRA_PINGROUP_CDEV2, tristate);
        tegra_pinmux_set_tristate(TEGRA_PINGROUP_UAA, tristate);
        tegra_pinmux_set_tristate(TEGRA_PINGROUP_UAB, tristate);
        tegra_pinmux_set_tristate(TEGRA_PINGROUP_UDA, tristate);
@@ -1546,6 +1583,7 @@ static void ulpi_link_phy_restore_end(struct tegra_usb_phy *phy)
 {
        unsigned long val;
        void __iomem *base = phy->regs;
+       int ret;
 
        DBG("%s(%d) inst:[%d]\n", __func__, __LINE__, phy->inst);
 
@@ -1554,6 +1592,13 @@ static void ulpi_link_phy_restore_end(struct tegra_usb_phy *phy)
        writel(val, base + ULPI_TIMING_CTRL_0);
 
        ulpi_link_phy_set_tristate(false);
+
+       udelay(10);
+       ret = usb_phy_io_write(phy->ulpi_vp, 0x55, 0x04);
+       if (ret) {
+               pr_err("%s: ulpi write failed\n", __func__);
+               return;
+       }
 }
 
 static int ulpi_link_phy_resume(struct tegra_usb_phy *phy)
@@ -1573,7 +1618,70 @@ static int ulpi_link_phy_resume(struct tegra_usb_phy *phy)
        return status;
 }
 
-static inline void ulpi_pinmux_bypass(struct tegra_usb_phy *phy, bool enable)
+static int ulpi_link_phy_pre_resume(struct tegra_usb_phy *phy,
+                       bool remote_wakeup)
+{
+       int status = 0;
+       unsigned long val;
+       void __iomem *base = phy->regs;
+       DBG("%s(%d) inst:[%d]\n", __func__, __LINE__, phy->inst);
+
+       val = readl(base + USB_PORTSC);
+       if (val & USB_PORTSC_RESUME) {
+
+               val = readl(base + USB_USBCMD);
+               val &= ~USB_USBCMD_RS;
+               writel(val, base + USB_USBCMD);
+
+               /* detect remote wakeup */
+               msleep(20);
+
+               val = readl(base + USB_PORTSC);
+
+               /* Poll until the controller clears RESUME and SUSPEND */
+               if (usb_phy_reg_status_wait(base + USB_SUSP_CTRL,
+                       USB_PORTSC_RESUME, 0, 2500))
+                       pr_err("%s: timeout waiting for RESUME\n", __func__);
+               if (usb_phy_reg_status_wait(base + USB_SUSP_CTRL,
+                       USB_PORTSC_SUSP, 0, 2500))
+                       pr_err("%s: timeout waiting for SUSPEND\n", __func__);
+
+               /* Since we skip remote wakeup event,
+               put controller in suspend again and
+               resume port later */
+               val = readl(base + USB_PORTSC);
+               val |= USB_PORTSC_SUSP;
+               writel(val, base + USB_PORTSC);
+               mdelay(4);
+               /* Wait until port suspend completes */
+               if (usb_phy_reg_status_wait(base + USB_SUSP_CTRL,
+                       USB_PORTSC_SUSP, USB_PORTSC_SUSP, 2500))
+                       pr_err("%s: timeout waiting for" \
+                               "PORT_SUSPEND\n", __func__);
+
+               /* Disable interrupts */
+               writel(0, base + USB_USBINTR);
+               /* Clear the run bit to stop SOFs - 2LS WAR */
+               val = readl(base + USB_USBCMD);
+               val &= ~USB_USBCMD_RS;
+               writel(val, base + USB_USBCMD);
+               if (usb_phy_reg_status_wait(base + USB_USBSTS,
+                       USB_USBSTS_HCH, USB_USBSTS_HCH, 2000)) {
+                       pr_err("%s: timeout waiting for" \
+                               "USB_USBSTS_HCH\n", __func__);
+               }
+               usb_phy_wait_for_sof(phy);
+
+               val = readl(base + USB_USBCMD);
+               val |= USB_USBCMD_RS;
+               writel(val, base + USB_USBCMD);
+       }
+       return status;
+}
+
+
+static inline void ulpi_pinmux_bypass(struct tegra_usb_phy *phy,
+       bool enable)
 {
        unsigned long val;
        void __iomem *base = phy->regs;
@@ -1806,7 +1914,8 @@ static int ulpi_null_phy_power_on(struct tegra_usb_phy *phy)
        val = readl(base + ULPIS2S_CTRL);
        val |= ULPIS2S_ENA;
        val |= ULPIS2S_SUPPORT_DISCONNECT;
-       val |= ULPIS2S_SPARE((phy->pdata->op_mode == TEGRA_USB_OPMODE_HOST) ? 3 : 1);
+       val |= ULPIS2S_SPARE((phy->pdata->op_mode == TEGRA_USB_OPMODE_HOST)
+                               ? 3 : 1);
        val |= ULPIS2S_PLLU_MASTER_BLASTER60;
        writel(val, base + ULPIS2S_CTRL);
 
@@ -1920,6 +2029,7 @@ static struct tegra_usb_phy_ops ulpi_link_phy_ops = {
        .power_off      = ulpi_link_phy_power_off,
        .resume         = ulpi_link_phy_resume,
        .post_suspend   = phy_post_suspend,
+       .pre_resume     = ulpi_link_phy_pre_resume,
 };
 
 static struct tegra_usb_phy_ops ulpi_null_phy_ops = {
diff --git a/arch/arm/mach-tegra/tegra3_clocks.c b/arch/arm/mach-tegra/tegra3_clocks.c
new file mode 100644 (file)
index 0000000..828a806
--- /dev/null
@@ -0,0 +1,5489 @@
+/*
+ * arch/arm/mach-tegra/tegra3_clocks.c
+ *
+ * Copyright (C) 2010-2012 NVIDIA CORPORATION. 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 as published by
+ * the Free Software Foundation; version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ *
+ */
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/list.h>
+#include <linux/spinlock.h>
+#include <linux/delay.h>
+#include <linux/err.h>
+#include <linux/io.h>
+#include <linux/clk.h>
+#include <linux/cpufreq.h>
+#include <linux/syscore_ops.h>
+
+#include <asm/clkdev.h>
+
+#include <mach/iomap.h>
+#include <mach/edp.h>
+
+#include "clock.h"
+#include "fuse.h"
+#include "dvfs.h"
+#include "pm.h"
+#include "sleep.h"
+#include "tegra3_emc.h"
+
+#define RST_DEVICES_L                  0x004
+#define RST_DEVICES_H                  0x008
+#define RST_DEVICES_U                  0x00C
+#define RST_DEVICES_V                  0x358
+#define RST_DEVICES_W                  0x35C
+#define RST_DEVICES_SET_L              0x300
+#define RST_DEVICES_CLR_L              0x304
+#define RST_DEVICES_SET_V              0x430
+#define RST_DEVICES_CLR_V              0x434
+#define RST_DEVICES_NUM                        5
+
+#define CLK_OUT_ENB_L                  0x010
+#define CLK_OUT_ENB_H                  0x014
+#define CLK_OUT_ENB_U                  0x018
+#define CLK_OUT_ENB_V                  0x360
+#define CLK_OUT_ENB_W                  0x364
+#define CLK_OUT_ENB_SET_L              0x320
+#define CLK_OUT_ENB_CLR_L              0x324
+#define CLK_OUT_ENB_SET_V              0x440
+#define CLK_OUT_ENB_CLR_V              0x444
+#define CLK_OUT_ENB_NUM                        5
+
+#define RST_DEVICES_V_SWR_CPULP_RST_DIS        (0x1 << 1)
+#define CLK_OUT_ENB_V_CLK_ENB_CPULP_EN (0x1 << 1)
+
+#define PERIPH_CLK_TO_BIT(c)           (1 << (c->u.periph.clk_num % 32))
+#define PERIPH_CLK_TO_RST_REG(c)       \
+       periph_clk_to_reg((c), RST_DEVICES_L, RST_DEVICES_V, 4)
+#define PERIPH_CLK_TO_RST_SET_REG(c)   \
+       periph_clk_to_reg((c), RST_DEVICES_SET_L, RST_DEVICES_SET_V, 8)
+#define PERIPH_CLK_TO_RST_CLR_REG(c)   \
+       periph_clk_to_reg((c), RST_DEVICES_CLR_L, RST_DEVICES_CLR_V, 8)
+
+#define PERIPH_CLK_TO_ENB_REG(c)       \
+       periph_clk_to_reg((c), CLK_OUT_ENB_L, CLK_OUT_ENB_V, 4)
+#define PERIPH_CLK_TO_ENB_SET_REG(c)   \
+       periph_clk_to_reg((c), CLK_OUT_ENB_SET_L, CLK_OUT_ENB_SET_V, 8)
+#define PERIPH_CLK_TO_ENB_CLR_REG(c)   \
+       periph_clk_to_reg((c), CLK_OUT_ENB_CLR_L, CLK_OUT_ENB_CLR_V, 8)
+
+#define CLK_MASK_ARM                   0x44
+#define MISC_CLK_ENB                   0x48
+
+#define OSC_CTRL                       0x50
+#define OSC_CTRL_OSC_FREQ_MASK         (0xF<<28)
+#define OSC_CTRL_OSC_FREQ_13MHZ                (0x0<<28)
+#define OSC_CTRL_OSC_FREQ_19_2MHZ      (0x4<<28)
+#define OSC_CTRL_OSC_FREQ_12MHZ                (0x8<<28)
+#define OSC_CTRL_OSC_FREQ_26MHZ                (0xC<<28)
+#define OSC_CTRL_OSC_FREQ_16_8MHZ      (0x1<<28)
+#define OSC_CTRL_OSC_FREQ_38_4MHZ      (0x5<<28)
+#define OSC_CTRL_OSC_FREQ_48MHZ                (0x9<<28)
+#define OSC_CTRL_MASK                  (0x3f2 | OSC_CTRL_OSC_FREQ_MASK)
+
+#define OSC_CTRL_PLL_REF_DIV_MASK      (3<<26)
+#define OSC_CTRL_PLL_REF_DIV_1         (0<<26)
+#define OSC_CTRL_PLL_REF_DIV_2         (1<<26)
+#define OSC_CTRL_PLL_REF_DIV_4         (2<<26)
+
+#define PERIPH_CLK_SOURCE_I2S1         0x100
+#define PERIPH_CLK_SOURCE_EMC          0x19c
+#define PERIPH_CLK_SOURCE_OSC          0x1fc
+#define PERIPH_CLK_SOURCE_NUM1 \
+       ((PERIPH_CLK_SOURCE_OSC - PERIPH_CLK_SOURCE_I2S1) / 4)
+
+#define PERIPH_CLK_SOURCE_G3D2         0x3b0
+#define PERIPH_CLK_SOURCE_SE           0x42c
+#define PERIPH_CLK_SOURCE_NUM2 \
+       ((PERIPH_CLK_SOURCE_SE - PERIPH_CLK_SOURCE_G3D2) / 4 + 1)
+
+#define AUDIO_DLY_CLK                  0x49c
+#define AUDIO_SYNC_CLK_SPDIF           0x4b4
+#define PERIPH_CLK_SOURCE_NUM3 \
+       ((AUDIO_SYNC_CLK_SPDIF - AUDIO_DLY_CLK) / 4 + 1)
+
+#define PERIPH_CLK_SOURCE_NUM          (PERIPH_CLK_SOURCE_NUM1 + \
+                                        PERIPH_CLK_SOURCE_NUM2 + \
+                                        PERIPH_CLK_SOURCE_NUM3)
+
+#define CPU_SOFTRST_CTRL               0x380
+
+#define PERIPH_CLK_SOURCE_DIVU71_MASK  0xFF
+#define PERIPH_CLK_SOURCE_DIVU16_MASK  0xFFFF
+#define PERIPH_CLK_SOURCE_DIV_SHIFT    0
+#define PERIPH_CLK_SOURCE_DIVIDLE_SHIFT        8
+#define PERIPH_CLK_SOURCE_DIVIDLE_VAL  50
+#define PERIPH_CLK_UART_DIV_ENB                (1<<24)
+#define PERIPH_CLK_VI_SEL_EX_SHIFT     24
+#define PERIPH_CLK_VI_SEL_EX_MASK      (0x3<<PERIPH_CLK_VI_SEL_EX_SHIFT)
+#define PERIPH_CLK_NAND_DIV_EX_ENB     (1<<8)
+#define PERIPH_CLK_DTV_POLARITY_INV    (1<<25)
+
+#define AUDIO_SYNC_SOURCE_MASK         0x0F
+#define AUDIO_SYNC_DISABLE_BIT         0x10
+#define AUDIO_SYNC_TAP_NIBBLE_SHIFT(c) ((c->reg_shift - 24) * 4)
+
+#define PLL_BASE                       0x0
+#define PLL_BASE_BYPASS                        (1<<31)
+#define PLL_BASE_ENABLE                        (1<<30)
+#define PLL_BASE_REF_ENABLE            (1<<29)
+#define PLL_BASE_OVERRIDE              (1<<28)
+#define PLL_BASE_LOCK                  (1<<27)
+#define PLL_BASE_DIVP_MASK             (0x7<<20)
+#define PLL_BASE_DIVP_SHIFT            20
+#define PLL_BASE_DIVN_MASK             (0x3FF<<8)
+#define PLL_BASE_DIVN_SHIFT            8
+#define PLL_BASE_DIVM_MASK             (0x1F)
+#define PLL_BASE_DIVM_SHIFT            0
+
+#define PLL_OUT_RATIO_MASK             (0xFF<<8)
+#define PLL_OUT_RATIO_SHIFT            8
+#define PLL_OUT_OVERRIDE               (1<<2)
+#define PLL_OUT_CLKEN                  (1<<1)
+#define PLL_OUT_RESET_DISABLE          (1<<0)
+
+#define PLL_MISC(c)                    \
+       (((c)->flags & PLL_ALT_MISC_REG) ? 0x4 : 0xc)
+#define PLL_MISC_LOCK_ENABLE(c)        \
+       (((c)->flags & (PLLU | PLLD)) ? (1<<22) : (1<<18))
+
+#define PLL_MISC_DCCON_SHIFT           20
+#define PLL_MISC_CPCON_SHIFT           8
+#define PLL_MISC_CPCON_MASK            (0xF<<PLL_MISC_CPCON_SHIFT)
+#define PLL_MISC_LFCON_SHIFT           4
+#define PLL_MISC_LFCON_MASK            (0xF<<PLL_MISC_LFCON_SHIFT)
+#define PLL_MISC_VCOCON_SHIFT          0
+#define PLL_MISC_VCOCON_MASK           (0xF<<PLL_MISC_VCOCON_SHIFT)
+#define PLLD_MISC_CLKENABLE            (1<<30)
+
+#define PLLU_BASE_POST_DIV             (1<<20)
+
+#define PLLD_BASE_DSIB_MUX_SHIFT       25
+#define PLLD_BASE_DSIB_MUX_MASK                (1<<PLLD_BASE_DSIB_MUX_SHIFT)
+#define PLLD_BASE_CSI_CLKENABLE                (1<<26)
+#define PLLD_MISC_DSI_CLKENABLE                (1<<30)
+#define PLLD_MISC_DIV_RST              (1<<23)
+#define PLLD_MISC_DCCON_SHIFT          12
+
+#define PLLDU_LFCON_SET_DIVN           600
+
+/* FIXME: OUT_OF_TABLE_CPCON per pll */
+#define OUT_OF_TABLE_CPCON             0x8
+
+#define SUPER_CLK_MUX                  0x00
+#define SUPER_STATE_SHIFT              28
+#define SUPER_STATE_MASK               (0xF << SUPER_STATE_SHIFT)
+#define SUPER_STATE_STANDBY            (0x0 << SUPER_STATE_SHIFT)
+#define SUPER_STATE_IDLE               (0x1 << SUPER_STATE_SHIFT)
+#define SUPER_STATE_RUN                        (0x2 << SUPER_STATE_SHIFT)
+#define SUPER_STATE_IRQ                        (0x3 << SUPER_STATE_SHIFT)
+#define SUPER_STATE_FIQ                        (0x4 << SUPER_STATE_SHIFT)
+#define SUPER_LP_DIV2_BYPASS           (0x1 << 16)
+#define SUPER_SOURCE_MASK              0xF
+#define        SUPER_FIQ_SOURCE_SHIFT          12
+#define        SUPER_IRQ_SOURCE_SHIFT          8
+#define        SUPER_RUN_SOURCE_SHIFT          4
+#define        SUPER_IDLE_SOURCE_SHIFT         0
+
+#define SUPER_CLK_DIVIDER              0x04
+#define SUPER_CLOCK_SKIP_ENABLE                (0x1 << 31)
+#define SUPER_CLOCK_DIV_U71_SHIFT      16
+#define SUPER_CLOCK_DIV_U71_MASK       (0xff << SUPER_CLOCK_DIV_U71_SHIFT)
+#define SUPER_CLOCK_SKIP_MUL_SHIFT     8
+#define SUPER_CLOCK_SKIP_MUL_MASK      (0xff << SUPER_CLOCK_SKIP_MUL_SHIFT)
+#define SUPER_CLOCK_SKIP_DIV_SHIFT     0
+#define SUPER_CLOCK_SKIP_DIV_MASK      (0xff << SUPER_CLOCK_SKIP_DIV_SHIFT)
+#define SUPER_CLOCK_SKIP_MASK          \
+       (SUPER_CLOCK_SKIP_MUL_MASK | SUPER_CLOCK_SKIP_DIV_MASK)
+#define SUPER_CLOCK_SKIP_TERM_MAX      256
+
+#define BUS_CLK_DISABLE                        (1<<3)
+#define BUS_CLK_DIV_MASK               0x3
+
+#define PMC_CTRL                       0x0
+ #define PMC_CTRL_BLINK_ENB            (1 << 7)
+
+#define PMC_DPD_PADS_ORIDE             0x1c
+ #define PMC_DPD_PADS_ORIDE_BLINK_ENB  (1 << 20)
+
+#define PMC_BLINK_TIMER_DATA_ON_SHIFT  0
+#define PMC_BLINK_TIMER_DATA_ON_MASK   0x7fff
+#define PMC_BLINK_TIMER_ENB            (1 << 15)
+#define PMC_BLINK_TIMER_DATA_OFF_SHIFT 16
+#define PMC_BLINK_TIMER_DATA_OFF_MASK  0xffff
+
+#define PMC_PLLP_WB0_OVERRIDE                          0xf8
+#define PMC_PLLP_WB0_OVERRIDE_PLLM_ENABLE              (1 << 12)
+#define PMC_PLLP_WB0_OVERRIDE_PLLM_OVERRIDE            (1 << 11)
+#define PMC_PLLM_WB0_OVERRIDE                          0x1dc
+#define PMC_PLLM_WB0_OVERRIDE_DIVP_MASK                        (0x7<<15)
+#define PMC_PLLM_WB0_OVERRIDE_DIVP_SHIFT               15
+#define PMC_PLLM_WB0_OVERRIDE_DIVN_MASK                        (0x3FF<<5)
+#define PMC_PLLM_WB0_OVERRIDE_DIVN_SHIFT               5
+#define PMC_PLLM_WB0_OVERRIDE_DIVM_MASK                        (0x1F)
+#define PMC_PLLM_WB0_OVERRIDE_DIVM_SHIFT               0
+
+#define UTMIP_PLL_CFG2                                 0x488
+#define UTMIP_PLL_CFG2_STABLE_COUNT(x)                 (((x) & 0xfff) << 6)
+#define UTMIP_PLL_CFG2_ACTIVE_DLY_COUNT(x)             (((x) & 0x3f) << 18)
+#define UTMIP_PLL_CFG2_FORCE_PD_SAMP_A_POWERDOWN       (1 << 0)
+#define UTMIP_PLL_CFG2_FORCE_PD_SAMP_B_POWERDOWN       (1 << 2)
+#define UTMIP_PLL_CFG2_FORCE_PD_SAMP_C_POWERDOWN       (1 << 4)
+
+#define UTMIP_PLL_CFG1                                 0x484
+#define UTMIP_PLL_CFG1_ENABLE_DLY_COUNT(x)             (((x) & 0x1f) << 27)
+#define UTMIP_PLL_CFG1_XTAL_FREQ_COUNT(x)              (((x) & 0xfff) << 0)
+#define UTMIP_PLL_CFG1_FORCE_PLL_ENABLE_POWERDOWN      (1 << 14)
+#define UTMIP_PLL_CFG1_FORCE_PLL_ACTIVE_POWERDOWN      (1 << 12)
+#define UTMIP_PLL_CFG1_FORCE_PLLU_POWERDOWN            (1 << 16)
+
+#define PLLE_BASE_CML_ENABLE           (1<<31)
+#define PLLE_BASE_ENABLE               (1<<30)
+#define PLLE_BASE_DIVCML_SHIFT         24
+#define PLLE_BASE_DIVCML_MASK          (0xf<<PLLE_BASE_DIVCML_SHIFT)
+#define PLLE_BASE_DIVP_SHIFT           16
+#define PLLE_BASE_DIVP_MASK            (0x3f<<PLLE_BASE_DIVP_SHIFT)
+#define PLLE_BASE_DIVN_SHIFT           8
+#define PLLE_BASE_DIVN_MASK            (0xFF<<PLLE_BASE_DIVN_SHIFT)
+#define PLLE_BASE_DIVM_SHIFT           0
+#define PLLE_BASE_DIVM_MASK            (0xFF<<PLLE_BASE_DIVM_SHIFT)
+#define PLLE_BASE_DIV_MASK             \
+       (PLLE_BASE_DIVCML_MASK | PLLE_BASE_DIVP_MASK | \
+        PLLE_BASE_DIVN_MASK | PLLE_BASE_DIVM_MASK)
+#define PLLE_BASE_DIV(m, n, p, cml)            \
+        (((cml)<<PLLE_BASE_DIVCML_SHIFT) | ((p)<<PLLE_BASE_DIVP_SHIFT) | \
+         ((n)<<PLLE_BASE_DIVN_SHIFT) | ((m)<<PLLE_BASE_DIVM_SHIFT))
+
+#define PLLE_MISC_SETUP_BASE_SHIFT     16
+#define PLLE_MISC_SETUP_BASE_MASK      (0xFFFF<<PLLE_MISC_SETUP_BASE_SHIFT)
+#define PLLE_MISC_READY                        (1<<15)
+#define PLLE_MISC_LOCK                 (1<<11)
+#define PLLE_MISC_LOCK_ENABLE          (1<<9)
+#define PLLE_MISC_SETUP_EX_SHIFT       2
+#define PLLE_MISC_SETUP_EX_MASK                (0x3<<PLLE_MISC_SETUP_EX_SHIFT)
+#define PLLE_MISC_SETUP_MASK           \
+         (PLLE_MISC_SETUP_BASE_MASK | PLLE_MISC_SETUP_EX_MASK)
+#define PLLE_MISC_SETUP_VALUE          \
+         ((0x7<<PLLE_MISC_SETUP_BASE_SHIFT) | (0x0<<PLLE_MISC_SETUP_EX_SHIFT))
+
+#define PLLE_SS_CTRL                   0x68
+#define        PLLE_SS_INCINTRV_SHIFT          24
+#define        PLLE_SS_INCINTRV_MASK           (0x3f<<PLLE_SS_INCINTRV_SHIFT)
+#define        PLLE_SS_INC_SHIFT               16
+#define        PLLE_SS_INC_MASK                (0xff<<PLLE_SS_INC_SHIFT)
+#define        PLLE_SS_MAX_SHIFT               0
+#define        PLLE_SS_MAX_MASK                (0x1ff<<PLLE_SS_MAX_SHIFT)
+#define PLLE_SS_COEFFICIENTS_MASK      \
+       (PLLE_SS_INCINTRV_MASK | PLLE_SS_INC_MASK | PLLE_SS_MAX_MASK)
+#define PLLE_SS_COEFFICIENTS_12MHZ     \
+       ((0x18<<PLLE_SS_INCINTRV_SHIFT) | (0x1<<PLLE_SS_INC_SHIFT) | \
+        (0x24<<PLLE_SS_MAX_SHIFT))
+#define PLLE_SS_DISABLE                        ((1<<14) | (1<<12) | (1<<11) | (1<<10))
+
+#define PLLE_AUX                       0x48c
+#define PLLE_AUX_PLLP_SEL              (1<<2)
+#define PLLE_AUX_CML_SATA_ENABLE       (1<<1)
+#define PLLE_AUX_CML_PCIE_ENABLE       (1<<0)
+
+#define        PMC_SATA_PWRGT                  0x1ac
+#define PMC_SATA_PWRGT_PLLE_IDDQ_VALUE (1<<5)
+#define PMC_SATA_PWRGT_PLLE_IDDQ_SWCTL (1<<4)
+
+#define ROUND_DIVIDER_UP       0
+#define ROUND_DIVIDER_DOWN     1
+
+/* PLLP default fixed rate in h/w controlled mode */
+#define PLLP_DEFAULT_FIXED_RATE                216000000
+
+/* Threshold to engage CPU clock skipper during CPU rate change */
+#define SKIPPER_ENGAGE_RATE             800000000
+
+static void tegra3_pllp_init_dependencies(unsigned long pllp_rate);
+static int tegra3_clk_shared_bus_update(struct clk *bus);
+static int tegra3_emc_relock_set_rate(struct clk *emc, unsigned long old_rate,
+       unsigned long new_rate, unsigned long new_pll_rate);
+
+static unsigned long cpu_stay_on_backup_max;
+static struct clk *emc_bridge;
+static struct clk *cpu_mode_sclk;
+
+static bool detach_shared_bus;
+module_param(detach_shared_bus, bool, 0644);
+
+static int skipper_delay = 10;
+module_param(skipper_delay, int, 0644);
+
+void tegra3_set_cpu_skipper_delay(int delay)
+{
+       skipper_delay = delay;
+}
+
+/**
+* Structure defining the fields for USB UTMI clocks Parameters.
+*/
+struct utmi_clk_param
+{
+       /* Oscillator Frequency in KHz */
+       u32 osc_frequency;
+       /* UTMIP PLL Enable Delay Count  */
+       u8 enable_delay_count;
+       /* UTMIP PLL Stable count */
+       u8 stable_count;
+       /*  UTMIP PLL Active delay count */
+       u8 active_delay_count;
+       /* UTMIP PLL Xtal frequency count */
+       u8 xtal_freq_count;
+};
+
+static const struct utmi_clk_param utmi_parameters[] =
+{
+/*     OSC_FREQUENCY,  ENABLE_DLY,     STABLE_CNT,     ACTIVE_DLY,     XTAL_FREQ_CNT */
+       {13000000,      0x02,           0x33,           0x05,           0x7F},
+       {19200000,      0x03,           0x4B,           0x06,           0xBB},
+       {12000000,      0x02,           0x2F,           0x04,           0x76},
+       {26000000,      0x04,           0x66,           0x09,           0xFE},
+       {16800000,      0x03,           0x41,           0x0A,           0xA4},
+};
+
+static void __iomem *reg_clk_base = IO_ADDRESS(TEGRA_CLK_RESET_BASE);
+static void __iomem *reg_pmc_base = IO_ADDRESS(TEGRA_PMC_BASE);
+static void __iomem *misc_gp_hidrev_base = IO_ADDRESS(TEGRA_APB_MISC_BASE);
+
+#define MISC_GP_HIDREV                  0x804
+
+/*
+ * Some peripheral clocks share an enable bit, so refcount the enable bits
+ * in registers CLK_ENABLE_L, ... CLK_ENABLE_W, and protect refcount updates
+ * with lock
+ */
+static DEFINE_SPINLOCK(periph_refcount_lock);
+static int tegra_periph_clk_enable_refcount[CLK_OUT_ENB_NUM * 32];
+
+#define clk_writel(value, reg) \
+       __raw_writel(value, (u32)reg_clk_base + (reg))
+#define clk_readl(reg) \
+       __raw_readl((u32)reg_clk_base + (reg))
+#define pmc_writel(value, reg) \
+       __raw_writel(value, (u32)reg_pmc_base + (reg))
+#define pmc_readl(reg) \
+       __raw_readl((u32)reg_pmc_base + (reg))
+#define chipid_readl() \
+       __raw_readl((u32)misc_gp_hidrev_base + MISC_GP_HIDREV)
+
+#define clk_writel_delay(value, reg)                                   \
+       do {                                                            \
+               __raw_writel((value), (u32)reg_clk_base + (reg));       \
+               udelay(2);                                              \
+       } while (0)
+
+
+static inline int clk_set_div(struct clk *c, u32 n)
+{
+       return clk_set_rate(c, (clk_get_rate(c->parent) + n-1) / n);
+}
+
+static inline u32 periph_clk_to_reg(
+       struct clk *c, u32 reg_L, u32 reg_V, int offs)
+{
+       u32 reg = c->u.periph.clk_num / 32;
+       BUG_ON(reg >= RST_DEVICES_NUM);
+       if (reg < 3) {
+               reg = reg_L + (reg * offs);
+       } else {
+               reg = reg_V + ((reg - 3) * offs);
+       }
+       return reg;
+}
+
+static int clk_div_x1_get_divider(unsigned long parent_rate, unsigned long rate,
+                       u32 max_x, u32 flags, u32 round_mode)
+{
+       s64 divider_ux1 = parent_rate;
+       if (!rate)
+               return -EINVAL;
+
+       if (!(flags & DIV_U71_INT))
+               divider_ux1 *= 2;
+
+       if (round_mode == ROUND_DIVIDER_UP)
+               divider_ux1 += rate - 1;
+       do_div(divider_ux1, rate);
+
+       if (flags & DIV_U71_INT)
+               divider_ux1 *= 2;
+
+       if (divider_ux1 - 2 < 0)
+               return 0;
+
+       if (divider_ux1 - 2 > max_x)
+               return -EINVAL;
+
+       return divider_ux1 - 2;
+}
+
+static int clk_div71_get_divider(unsigned long parent_rate, unsigned long rate,
+                                u32 flags, u32 round_mode)
+{
+       return clk_div_x1_get_divider(parent_rate, rate, 0xFF,
+                       flags, round_mode);
+}
+
+static int clk_div151_get_divider(unsigned long parent_rate, unsigned long rate,
+                                u32 flags, u32 round_mode)
+{
+       return clk_div_x1_get_divider(parent_rate, rate, 0xFFFF,
+                       flags, round_mode);
+}
+
+static int clk_div16_get_divider(unsigned long parent_rate, unsigned long rate)
+{
+       s64 divider_u16;
+
+       divider_u16 = parent_rate;
+       if (!rate)
+               return -EINVAL;
+       divider_u16 += rate - 1;
+       do_div(divider_u16, rate);
+
+       if (divider_u16 - 1 < 0)
+               return 0;
+
+       if (divider_u16 - 1 > 0xFFFF)
+               return -EINVAL;
+
+       return divider_u16 - 1;
+}
+
+/* clk_m functions */
+static unsigned long tegra3_clk_m_autodetect_rate(struct clk *c)
+{
+       u32 osc_ctrl = clk_readl(OSC_CTRL);
+       u32 auto_clock_control = osc_ctrl & ~OSC_CTRL_OSC_FREQ_MASK;
+       u32 pll_ref_div = osc_ctrl & OSC_CTRL_PLL_REF_DIV_MASK;
+
+       c->rate = tegra_clk_measure_input_freq();
+       switch (c->rate) {
+       case 12000000:
+               auto_clock_control |= OSC_CTRL_OSC_FREQ_12MHZ;
+               BUG_ON(pll_ref_div != OSC_CTRL_PLL_REF_DIV_1);
+               break;
+       case 13000000:
+               auto_clock_control |= OSC_CTRL_OSC_FREQ_13MHZ;
+               BUG_ON(pll_ref_div != OSC_CTRL_PLL_REF_DIV_1);
+               break;
+       case 19200000:
+               auto_clock_control |= OSC_CTRL_OSC_FREQ_19_2MHZ;
+               BUG_ON(pll_ref_div != OSC_CTRL_PLL_REF_DIV_1);
+               break;
+       case 26000000:
+               auto_clock_control |= OSC_CTRL_OSC_FREQ_26MHZ;
+               BUG_ON(pll_ref_div != OSC_CTRL_PLL_REF_DIV_1);
+               break;
+       case 16800000:
+               auto_clock_control |= OSC_CTRL_OSC_FREQ_16_8MHZ;
+               BUG_ON(pll_ref_div != OSC_CTRL_PLL_REF_DIV_1);
+               break;
+       case 38400000:
+               auto_clock_control |= OSC_CTRL_OSC_FREQ_38_4MHZ;
+               BUG_ON(pll_ref_div != OSC_CTRL_PLL_REF_DIV_2);
+               break;
+       case 48000000:
+               auto_clock_control |= OSC_CTRL_OSC_FREQ_48MHZ;
+               BUG_ON(pll_ref_div != OSC_CTRL_PLL_REF_DIV_4);
+               break;
+       default:
+               pr_err("%s: Unexpected clock rate %ld", __func__, c->rate);
+               BUG();
+       }
+       clk_writel(auto_clock_control, OSC_CTRL);
+       return c->rate;
+}
+
+static void tegra3_clk_m_init(struct clk *c)
+{
+       pr_debug("%s on clock %s\n", __func__, c->name);
+       tegra3_clk_m_autodetect_rate(c);
+}
+
+static int tegra3_clk_m_enable(struct clk *c)
+{
+       pr_debug("%s on clock %s\n", __func__, c->name);
+       return 0;
+}
+
+static void tegra3_clk_m_disable(struct clk *c)
+{
+       pr_debug("%s on clock %s\n", __func__, c->name);
+       WARN(1, "Attempting to disable main SoC clock\n");
+}
+
+static struct clk_ops tegra_clk_m_ops = {
+       .init           = tegra3_clk_m_init,
+       .enable         = tegra3_clk_m_enable,
+       .disable        = tegra3_clk_m_disable,
+};
+
+static struct clk_ops tegra_clk_m_div_ops = {
+       .enable         = tegra3_clk_m_enable,
+};
+
+/* PLL reference divider functions */
+static void tegra3_pll_ref_init(struct clk *c)
+{
+       u32 pll_ref_div = clk_readl(OSC_CTRL) & OSC_CTRL_PLL_REF_DIV_MASK;
+       pr_debug("%s on clock %s\n", __func__, c->name);
+
+       switch (pll_ref_div) {
+       case OSC_CTRL_PLL_REF_DIV_1:
+               c->div = 1;
+               break;
+       case OSC_CTRL_PLL_REF_DIV_2:
+               c->div = 2;
+               break;
+       case OSC_CTRL_PLL_REF_DIV_4:
+               c->div = 4;
+               break;
+       default:
+               pr_err("%s: Invalid pll ref divider %d", __func__, pll_ref_div);
+               BUG();
+       }
+       c->mul = 1;
+       c->state = ON;
+}
+
+static struct clk_ops tegra_pll_ref_ops = {
+       .init           = tegra3_pll_ref_init,
+       .enable         = tegra3_clk_m_enable,
+       .disable        = tegra3_clk_m_disable,
+};
+
+/* super clock functions */
+/* "super clocks" on tegra3 have two-stage muxes, fractional 7.1 divider and
+ * clock skipping super divider.  We will ignore the clock skipping divider,
+ * since we can't lower the voltage when using the clock skip, but we can if
+ * we lower the PLL frequency. We will use 7.1 divider for CPU super-clock
+ * only when its parent is a fixed rate PLL, since we can't change PLL rate
+ * in this case.
+ */
+static void tegra3_super_clk_init(struct clk *c)
+{
+       u32 val;
+       int source;
+       int shift;
+       const struct clk_mux_sel *sel;
+
+       val = clk_readl(c->reg + SUPER_CLK_MUX);
+       c->state = ON;
+       BUG_ON(((val & SUPER_STATE_MASK) != SUPER_STATE_RUN) &&
+               ((val & SUPER_STATE_MASK) != SUPER_STATE_IDLE));
+       shift = ((val & SUPER_STATE_MASK) == SUPER_STATE_IDLE) ?
+               SUPER_IDLE_SOURCE_SHIFT : SUPER_RUN_SOURCE_SHIFT;
+       source = (val >> shift) & SUPER_SOURCE_MASK;
+       if (c->flags & DIV_2)
+               source |= val & SUPER_LP_DIV2_BYPASS;
+       for (sel = c->inputs; sel->input != NULL; sel++) {
+               if (sel->value == source)
+                       break;
+       }
+       BUG_ON(sel->input == NULL);
+       c->parent = sel->input;
+
+       if (c->flags & DIV_U71) {
+               /* Init safe 7.1 divider value (does not affect PLLX path).
+                  Super skipper is enabled to be ready for emergency throttle,
+                  but set 1:1 */
+               c->mul = 2;
+               c->div = 2;
+               if (!(c->parent->flags & PLLX)) {
+                       val = clk_readl(c->reg + SUPER_CLK_DIVIDER);
+                       val &= SUPER_CLOCK_DIV_U71_MASK;
+                       val >>= SUPER_CLOCK_DIV_U71_SHIFT;
+                       val = max(val, c->u.cclk.div71);
+                       c->u.cclk.div71 = val;
+                       c->div += val;
+               }
+               val = SUPER_CLOCK_SKIP_ENABLE +
+                       (c->u.cclk.div71 << SUPER_CLOCK_DIV_U71_SHIFT);
+               clk_writel(val, c->reg + SUPER_CLK_DIVIDER);
+       }
+       else
+               clk_writel(0, c->reg + SUPER_CLK_DIVIDER);
+}
+
+static int tegra3_super_clk_enable(struct clk *c)
+{
+       return 0;
+}
+
+static void tegra3_super_clk_disable(struct clk *c)
+{
+       /* since tegra 3 has 2 CPU super clocks - low power lp-mode clock and
+          geared up g-mode super clock - mode switch may request to disable
+          either of them; accept request with no affect on h/w */
+}
+
+static int tegra3_super_clk_set_parent(struct clk *c, struct clk *p)
+{
+       u32 val;
+       const struct clk_mux_sel *sel;
+       int shift;
+
+       val = clk_readl(c->reg + SUPER_CLK_MUX);;
+       BUG_ON(((val & SUPER_STATE_MASK) != SUPER_STATE_RUN) &&
+               ((val & SUPER_STATE_MASK) != SUPER_STATE_IDLE));
+       shift = ((val & SUPER_STATE_MASK) == SUPER_STATE_IDLE) ?
+               SUPER_IDLE_SOURCE_SHIFT : SUPER_RUN_SOURCE_SHIFT;
+       for (sel = c->inputs; sel->input != NULL; sel++) {
+               if (sel->input == p) {
+                       /* For LP mode super-clock switch between PLLX direct
+                          and divided-by-2 outputs is allowed only when other
+                          than PLLX clock source is current parent */
+                       if ((c->flags & DIV_2) && (p->flags & PLLX) &&
+                           ((sel->value ^ val) & SUPER_LP_DIV2_BYPASS)) {
+                               if (c->parent->flags & PLLX)
+                                       return -EINVAL;
+                               val ^= SUPER_LP_DIV2_BYPASS;
+                               clk_writel_delay(val, c->reg);
+                       }
+                       val &= ~(SUPER_SOURCE_MASK << shift);
+                       val |= (sel->value & SUPER_SOURCE_MASK) << shift;
+
+                       /* 7.1 divider for CPU super-clock does not affect
+                          PLLX path */
+                       if (c->flags & DIV_U71) {
+                               u32 div = 0;
+                               if (!(p->flags & PLLX)) {
+                                       div = clk_readl(c->reg +
+                                                       SUPER_CLK_DIVIDER);
+                                       div &= SUPER_CLOCK_DIV_U71_MASK;
+                                       div >>= SUPER_CLOCK_DIV_U71_SHIFT;
+                               }
+                               c->div = div + 2;
+                               c->mul = 2;
+                       }
+
+                       if (c->refcnt)
+                               clk_enable(p);
+
+                       clk_writel_delay(val, c->reg);
+
+                       if (c->refcnt && c->parent)
+                               clk_disable(c->parent);
+
+                       clk_reparent(c, p);
+                       return 0;
+               }
+       }
+       return -EINVAL;
+}
+
+static DEFINE_SPINLOCK(super_divider_lock);
+
+static void tegra3_super_clk_divider_update(struct clk *c, u8 div)
+{
+       u32 val;
+       unsigned long flags;
+
+       spin_lock_irqsave(&super_divider_lock, flags);
+       val = clk_readl(c->reg + SUPER_CLK_DIVIDER);
+       val &= ~SUPER_CLOCK_DIV_U71_MASK;
+       val |= div << SUPER_CLOCK_DIV_U71_SHIFT;
+       clk_writel(val, c->reg + SUPER_CLK_DIVIDER);
+       spin_unlock_irqrestore(&super_divider_lock, flags);
+       udelay(2);
+}
+
+static void tegra3_super_clk_skipper_update(struct clk *c, u8 mul, u8 div)
+{
+       u32 val;
+       unsigned long flags;
+
+       spin_lock_irqsave(&super_divider_lock, flags);
+       val = clk_readl(c->reg + SUPER_CLK_DIVIDER);
+
+       /* multiplier or divider value = the respective field + 1 */
+       if (mul && div) {
+               u32 old_mul = ((val & SUPER_CLOCK_SKIP_MUL_MASK) >>
+                              SUPER_CLOCK_SKIP_MUL_SHIFT) + 1;
+               u32 old_div = ((val & SUPER_CLOCK_SKIP_DIV_MASK) >>
+                              SUPER_CLOCK_SKIP_DIV_SHIFT) + 1;
+
+               if (mul >= div) {
+                       /* improper fraction is only used to reciprocate the
+                          previous proper one - the division below is exact */
+                       old_mul /= div;
+                       old_div /= mul;
+               } else {
+                       old_mul *= mul;
+                       old_div *= div;
+               }
+               mul = (old_mul <= SUPER_CLOCK_SKIP_TERM_MAX) ?
+                       old_mul : SUPER_CLOCK_SKIP_TERM_MAX;
+               div = (old_div <= SUPER_CLOCK_SKIP_TERM_MAX) ?
+                       old_div : SUPER_CLOCK_SKIP_TERM_MAX;
+       }
+
+       if (!mul || (mul >= div)) {
+               mul = 1;
+               div = 1;
+       }
+       val &= ~SUPER_CLOCK_SKIP_MASK;
+       val |= SUPER_CLOCK_SKIP_ENABLE |
+               ((mul - 1) << SUPER_CLOCK_SKIP_MUL_SHIFT) |
+               ((div - 1) << SUPER_CLOCK_SKIP_DIV_SHIFT);
+
+       clk_writel(val, c->reg + SUPER_CLK_DIVIDER);
+       spin_unlock_irqrestore(&super_divider_lock, flags);
+}
+
+/*
+ * Do not use super clocks "skippers", since dividing using a clock skipper
+ * does not allow the voltage to be scaled down. Instead adjust the rate of
+ * the parent clock. This requires that the parent of a super clock have no
+ * other children, otherwise the rate will change underneath the other
+ * children. Special case: if fixed rate PLL is CPU super clock parent the
+ * rate of this PLL can't be changed, and it has many other children. In
+ * this case use 7.1 fractional divider to adjust the super clock rate.
+ */
+static int tegra3_super_clk_set_rate(struct clk *c, unsigned long rate)
+{
+       if ((c->flags & DIV_U71) && (c->parent->flags & PLL_FIXED)) {
+               int div = clk_div71_get_divider(c->parent->u.pll.fixed_rate,
+                                       rate, c->flags, ROUND_DIVIDER_DOWN);
+               if (div < 0)
+                       return div;
+
+               tegra3_super_clk_divider_update(c, div);
+               c->u.cclk.div71 = div;
+               c->div = div + 2;
+               c->mul = 2;
+               return 0;
+       }
+       return clk_set_rate(c->parent, rate);
+}
+
+static struct clk_ops tegra_super_ops = {
+       .init                   = tegra3_super_clk_init,
+       .enable                 = tegra3_super_clk_enable,
+       .disable                = tegra3_super_clk_disable,
+       .set_parent             = tegra3_super_clk_set_parent,
+       .set_rate               = tegra3_super_clk_set_rate,
+};
+
+static int tegra3_twd_clk_set_rate(struct clk *c, unsigned long rate)
+{
+       /* The input value 'rate' is the clock rate of the CPU complex. */
+       c->rate = (rate * c->mul) / c->div;
+       return 0;
+}
+
+static struct clk_ops tegra3_twd_ops = {
+       .set_rate       = tegra3_twd_clk_set_rate,
+};
+
+static struct clk tegra3_clk_twd = {
+       /* NOTE: The twd clock must have *NO* parent. It's rate is directly
+                updated by tegra3_cpu_cmplx_clk_set_rate() because the
+                frequency change notifer for the twd is called in an
+                atomic context which cannot take a mutex. */
+       .name     = "twd",
+       .ops      = &tegra3_twd_ops,
+       .max_rate = 1400000000, /* Same as tegra_clk_cpu_cmplx.max_rate */
+       .mul      = 1,
+       .div      = 2,
+};
+
+/* virtual cpu clock functions */
+/* some clocks can not be stopped (cpu, memory bus) while the SoC is running.
+   To change the frequency of these clocks, the parent pll may need to be
+   reprogrammed, so the clock must be moved off the pll, the pll reprogrammed,
+   and then the clock moved back to the pll. Clock skipper maybe temporarily
+   engaged during the switch to limit frequency jumps. To hide this sequence,
+   a virtual clock handles it.
+ */
+static void tegra3_cpu_clk_init(struct clk *c)
+{
+       c->state = (!is_lp_cluster() == (c->u.cpu.mode == MODE_G))? ON : OFF;
+}
+
+static int tegra3_cpu_clk_enable(struct clk *c)
+{
+       return 0;
+}
+
+static void tegra3_cpu_clk_disable(struct clk *c)
+{
+       /* since tegra 3 has 2 virtual CPU clocks - low power lp-mode clock
+          and geared up g-mode clock - mode switch may request to disable
+          either of them; accept request with no affect on h/w */
+}
+
+static int tegra3_cpu_clk_set_rate(struct clk *c, unsigned long rate)
+{
+       int ret = 0;
+       bool skipped = false;
+       bool skip = (c->u.cpu.mode == MODE_G) && skipper_delay;
+       bool skip_from_backup = skip && (rate >= SKIPPER_ENGAGE_RATE);
+       bool skip_to_backup =
+               skip && (clk_get_rate_all_locked(c) >= SKIPPER_ENGAGE_RATE);
+
+       if (c->dvfs) {
+               if (!c->dvfs->dvfs_rail)
+                       return -ENOSYS;
+               else if ((!c->dvfs->dvfs_rail->reg) &&
+                         (clk_get_rate_locked(c) < rate)) {
+                       WARN(1, "Increasing CPU rate while regulator is not"
+                               " ready may overclock CPU\n");
+                       return -ENOSYS;
+               }
+       }
+
+       /*
+        * Take an extra reference to the main pll so it doesn't turn
+        * off when we move the cpu off of it
+        */
+       clk_enable(c->u.cpu.main);
+
+       if (c->parent->parent != c->u.cpu.backup) {
+               if (skip_to_backup) {
+                       /* on G CPU use 1/2 skipper step for main <=> backup */
+                       skipped = true;
+                       tegra3_super_clk_skipper_update(c->parent, 1, 2);
+                       udelay(skipper_delay);
+               }
+
+               ret = clk_set_parent(c->parent, c->u.cpu.backup);
+               if (ret) {
+                       pr_err("Failed to switch cpu to clock %s\n",
+                              c->u.cpu.backup->name);
+                       goto out;
+               }
+
+               if (skipped && !skip_from_backup) {
+                       skipped = false;
+                       tegra3_super_clk_skipper_update(c->parent, 2, 1);
+               }
+       }
+
+       if (rate <= cpu_stay_on_backup_max) {
+               ret = clk_set_rate(c->parent, rate);
+               if (ret)
+                       pr_err("Failed to set cpu rate %lu on backup source\n",
+                              rate);
+               goto out;
+       } else {
+               ret = clk_set_rate(c->parent, c->u.cpu.backup_rate);
+               if (ret) {
+                       pr_err("Failed to set cpu rate %lu on backup source\n",
+                              c->u.cpu.backup_rate);
+                       goto out;
+               }
+       }
+
+       if (rate != clk_get_rate(c->u.cpu.main)) {
+               ret = clk_set_rate(c->u.cpu.main, rate);
+               if (ret) {
+                       pr_err("Failed to change cpu pll to %lu\n", rate);
+                       goto out;
+               }
+       }
+
+       if (!skipped && skip_from_backup) {
+               skipped = true;
+               tegra3_super_clk_skipper_update(c->parent, 1, 2);
+       }
+
+       ret = clk_set_parent(c->parent, c->u.cpu.main);
+       if (ret) {
+               pr_err("Failed to switch cpu to clock %s\n", c->u.cpu.main->name);
+               goto out;
+       }
+
+out:
+       if (skipped) {
+               udelay(skipper_delay);
+               tegra3_super_clk_skipper_update(c->parent, 2, 1);
+       }
+       clk_disable(c->u.cpu.main);
+       return ret;
+}
+
+static struct clk_ops tegra_cpu_ops = {
+       .init     = tegra3_cpu_clk_init,
+       .enable   = tegra3_cpu_clk_enable,
+       .disable  = tegra3_cpu_clk_disable,
+       .set_rate = tegra3_cpu_clk_set_rate,
+};
+
+
+static void tegra3_cpu_cmplx_clk_init(struct clk *c)
+{
+       int i = !!is_lp_cluster();
+
+       BUG_ON(c->inputs[0].input->u.cpu.mode != MODE_G);
+       BUG_ON(c->inputs[1].input->u.cpu.mode != MODE_LP);
+       c->parent = c->inputs[i].input;
+}
+
+/* cpu complex clock provides second level vitualization (on top of
+   cpu virtual cpu rate control) in order to hide the CPU mode switch
+   sequence */
+#if PARAMETERIZE_CLUSTER_SWITCH
+static unsigned int switch_delay;
+static unsigned int switch_flags;
+static DEFINE_SPINLOCK(parameters_lock);
+
+void tegra_cluster_switch_set_parameters(unsigned int us, unsigned int flags)
+{
+       spin_lock(&parameters_lock);
+       switch_delay = us;
+       switch_flags = flags;
+       spin_unlock(&parameters_lock);
+}
+#endif
+
+static int tegra3_cpu_cmplx_clk_enable(struct clk *c)
+{
+       return 0;
+}
+
+static void tegra3_cpu_cmplx_clk_disable(struct clk *c)
+{
+       pr_debug("%s on clock %s\n", __func__, c->name);
+
+       /* oops - don't disable the CPU complex clock! */
+       BUG();
+}
+
+static int tegra3_cpu_cmplx_clk_set_rate(struct clk *c, unsigned long rate)
+{
+       unsigned long flags;
+       int ret;
+       struct clk *parent = c->parent;
+
+       if (!parent->ops || !parent->ops->set_rate)
+               return -ENOSYS;
+
+       clk_lock_save(parent, &flags);
+
+       ret = clk_set_rate_locked(parent, rate);
+
+       /* We can't parent the twd to directly to the CPU complex because
+          the TWD frequency update notifier is called in an atomic context
+          and the CPU frequency update requires a mutex. Update the twd
+          clock rate with the new CPU complex rate. */
+       clk_set_rate(&tegra3_clk_twd, clk_get_rate_locked(parent));
+
+       clk_unlock_restore(parent, &flags);
+
+       return ret;
+}
+
+static int tegra3_cpu_cmplx_clk_set_parent(struct clk *c, struct clk *p)
+{
+       int ret;
+       unsigned int flags, delay;
+       const struct clk_mux_sel *sel;
+       unsigned long rate = clk_get_rate(c->parent);
+
+       pr_debug("%s: %s %s\n", __func__, c->name, p->name);
+       BUG_ON(c->parent->u.cpu.mode != (is_lp_cluster() ? MODE_LP : MODE_G));
+
+       for (sel = c->inputs; sel->input != NULL; sel++) {
+               if (sel->input == p)
+                       break;
+       }
+       if (!sel->input)
+               return -EINVAL;
+
+#if PARAMETERIZE_CLUSTER_SWITCH
+       spin_lock(&parameters_lock);
+       flags = switch_flags;
+       delay = switch_delay;
+       switch_flags = 0;
+       spin_unlock(&parameters_lock);
+
+       if (flags) {
+               /* over/under-clocking after switch - allow, but update rate */
+               if ((rate > p->max_rate) || (rate < p->min_rate)) {
+                       unsigned long fl;
+
+                       rate = rate > p->max_rate ? p->max_rate : p->min_rate;
+                       ret = clk_set_rate(c->parent, rate);
+                       if (ret) {
+                               pr_err("%s: Failed to set rate %lu for %s\n",
+                                       __func__, rate, p->name);
+                               return ret;
+                       }
+                       clk_lock_save(c->parent, &fl);
+                       clk_set_rate(&tegra3_clk_twd,
+                                       clk_get_rate_locked(c->parent));
+                       clk_unlock_restore(c->parent, &fl);
+               }
+       } else
+#endif
+       {
+               if (p == c->parent)             /* already switched - exit*/
+                       return 0;
+
+               if (rate > p->max_rate) {       /* over-clocking - no switch */
+                       pr_warn("%s: No %s mode switch to %s at rate %lu\n",
+                                __func__, c->name, p->name, rate);
+                       return -ECANCELED;
+               }
+               flags = TEGRA_POWER_CLUSTER_IMMEDIATE;
+               delay = 0;
+       }
+       flags |= (p->u.cpu.mode == MODE_LP) ? TEGRA_POWER_CLUSTER_LP :
+               TEGRA_POWER_CLUSTER_G;
+
+       clk_enable(cpu_mode_sclk);      /* set SCLK floor for cluster switch */
+
+       /* Since in both LP and G mode CPU main and backup sources are the
+          same, set rate on the new parent just synchronizes super-clock
+          muxes before mode switch with no PLL re-locking */
+       ret = clk_set_rate(p, rate);
+       if (ret) {
+               pr_err("%s: Failed to set rate %lu for %s\n",
+                      __func__, rate, p->name);
+               clk_disable(cpu_mode_sclk);
+               return ret;
+       }
+
+       /* Enabling new parent scales new mode voltage rail in advanvce
+          before the switch happens*/
+       if (c->refcnt)
+               clk_enable(p);
+
+       /* switch CPU mode */
+       ret = tegra_cluster_control(delay, flags);
+       if (ret) {
+               if (c->refcnt)
+                       clk_disable(p);
+               pr_err("%s: Failed to switch %s mode to %s\n",
+                      __func__, c->name, p->name);
+               clk_disable(cpu_mode_sclk);
+               return ret;
+       }
+
+       /* Disabling old parent scales old mode voltage rail */
+       if (c->refcnt && c->parent)
+               clk_disable(c->parent);
+
+       clk_reparent(c, p);
+       clk_disable(cpu_mode_sclk);
+       return 0;
+}
+
+static long tegra3_cpu_cmplx_round_rate(struct clk *c,
+       unsigned long rate)
+{
+       if (rate > c->parent->max_rate)
+               rate = c->parent->max_rate;
+       else if (rate < c->parent->min_rate)
+               rate = c->parent->min_rate;
+       return rate;
+}
+
+static struct clk_ops tegra_cpu_cmplx_ops = {
+       .init     = tegra3_cpu_cmplx_clk_init,
+       .enable   = tegra3_cpu_cmplx_clk_enable,
+       .disable  = tegra3_cpu_cmplx_clk_disable,
+       .set_rate = tegra3_cpu_cmplx_clk_set_rate,
+       .set_parent = tegra3_cpu_cmplx_clk_set_parent,
+       .round_rate = tegra3_cpu_cmplx_round_rate,
+};
+
+/* virtual cop clock functions. Used to acquire the fake 'cop' clock to
+ * reset the COP block (i.e. AVP) */
+static void tegra3_cop_clk_reset(struct clk *c, bool assert)
+{
+       unsigned long reg = assert ? RST_DEVICES_SET_L : RST_DEVICES_CLR_L;
+
+       pr_debug("%s %s\n", __func__, assert ? "assert" : "deassert");
+       clk_writel(1 << 1, reg);
+}
+
+static struct clk_ops tegra_cop_ops = {
+       .reset    = tegra3_cop_clk_reset,
+};
+
+/* bus clock functions */
+static void tegra3_bus_clk_init(struct clk *c)
+{
+       u32 val = clk_readl(c->reg);
+       c->state = ((val >> c->reg_shift) & BUS_CLK_DISABLE) ? OFF : ON;
+       c->div = ((val >> c->reg_shift) & BUS_CLK_DIV_MASK) + 1;
+       c->mul = 1;
+}
+
+static int tegra3_bus_clk_enable(struct clk *c)
+{
+       u32 val = clk_readl(c->reg);
+       val &= ~(BUS_CLK_DISABLE << c->reg_shift);
+       clk_writel(val, c->reg);
+       return 0;
+}
+
+static void tegra3_bus_clk_disable(struct clk *c)
+{
+       u32 val = clk_readl(c->reg);
+       val |= BUS_CLK_DISABLE << c->reg_shift;
+       clk_writel(val, c->reg);
+}
+
+static int tegra3_bus_clk_set_rate(struct clk *c, unsigned long rate)
+{
+       u32 val = clk_readl(c->reg);
+       unsigned long parent_rate = clk_get_rate(c->parent);
+       int i;
+       for (i = 1; i <= 4; i++) {
+               if (rate >= parent_rate / i) {
+                       val &= ~(BUS_CLK_DIV_MASK << c->reg_shift);
+                       val |= (i - 1) << c->reg_shift;
+                       clk_writel(val, c->reg);
+                       c->div = i;
+                       c->mul = 1;
+                       return 0;
+               }
+       }
+       return -EINVAL;
+}
+
+static struct clk_ops tegra_bus_ops = {
+       .init                   = tegra3_bus_clk_init,
+       .enable                 = tegra3_bus_clk_enable,
+       .disable                = tegra3_bus_clk_disable,
+       .set_rate               = tegra3_bus_clk_set_rate,
+};
+
+/* Virtual system bus complex clock is used to hide the sequence of
+   changing sclk/hclk/pclk parents and dividers to configure requested
+   sclk target rate. */
+static void tegra3_sbus_cmplx_init(struct clk *c)
+{
+       unsigned long rate;
+
+       c->max_rate = c->parent->max_rate;
+       c->min_rate = c->parent->min_rate;
+
+       /* Threshold must be an exact proper factor of low range parent,
+          and both low/high range parents have 7.1 fractional dividers */
+       rate = clk_get_rate(c->u.system.sclk_low->parent);
+       if (c->u.system.threshold) {
+               BUG_ON(c->u.system.threshold > rate) ;
+               BUG_ON((rate % c->u.system.threshold) != 0);
+       }
+       BUG_ON(!(c->u.system.sclk_low->flags & DIV_U71));
+       BUG_ON(!(c->u.system.sclk_high->flags & DIV_U71));
+}
+
+/* This special sbus round function is implemented because:
+ *
+ * (a) fractional dividers can not be used to derive system bus clock with one
+ * exception: 1 : 2.5 divider is allowed at 1.2V and above (and we do need this
+ * divider to reach top sbus frequencies from high frequency source).
+ *
+ * (b) since sbus is a shared bus, and its frequency is set to the highest
+ * enabled shared_bus_user clock, the target rate should be rounded up divider
+ * ladder (if max limit allows it) - for pll_div and peripheral_div common is
+ * rounding down - special case again.
+ *
+ * Note that final rate is trimmed (not rounded up) to avoid spiraling up in
+ * recursive calls. Lost 1Hz is added in tegra3_sbus_cmplx_set_rate before
+ * actually setting divider rate.
+ */
+static unsigned long sclk_high_2_5_rate;
+static bool sclk_high_2_5_valid;
+
+static long tegra3_sbus_cmplx_round_rate(struct clk *c, unsigned long rate)
+{
+       int i, divider;
+       unsigned long source_rate, round_rate;
+       struct clk *new_parent;
+
+       rate = max(rate, c->min_rate);
+
+       if (!sclk_high_2_5_rate) {
+               source_rate = clk_get_rate(c->u.system.sclk_high->parent);
+               sclk_high_2_5_rate = 2 * source_rate / 5;
+               i = tegra_dvfs_predict_millivolts(c, sclk_high_2_5_rate);
+               if (!IS_ERR_VALUE(i) && (i >= 1200) &&
+                   (sclk_high_2_5_rate <= c->max_rate))
+                       sclk_high_2_5_valid = true;
+       }
+
+       new_parent = (rate <= c->u.system.threshold) ?
+               c->u.system.sclk_low : c->u.system.sclk_high;
+       source_rate = clk_get_rate(new_parent->parent);
+
+       divider = clk_div71_get_divider(source_rate, rate,
+               new_parent->flags | DIV_U71_INT, ROUND_DIVIDER_DOWN);
+       if (divider < 0)
+               return divider;
+
+       round_rate = source_rate * 2 / (divider + 2);
+       if (round_rate > c->max_rate) {
+               divider += 2;
+               round_rate = source_rate * 2 / (divider + 2);
+       }
+
+       if (new_parent == c->u.system.sclk_high) {
+               /* Check if 1 : 2.5 ratio provides better approximation */
+               if (sclk_high_2_5_valid) {
+                       if (((sclk_high_2_5_rate < round_rate) &&
+                           (sclk_high_2_5_rate >= rate)) ||
+                           ((round_rate < sclk_high_2_5_rate) &&
+                            (round_rate < rate)))
+                               round_rate = sclk_high_2_5_rate;
+               }
+
+               if (round_rate <= c->u.system.threshold)
+                       round_rate = c->u.system.threshold;
+       }
+       return round_rate;
+}
+
+static int tegra3_sbus_cmplx_set_rate(struct clk *c, unsigned long rate)
+{
+       int ret;
+       struct clk *new_parent;
+
+       /* - select the appropriate sclk parent
+          - keep hclk at the same rate as sclk
+          - set pclk at 1:2 rate of hclk unless pclk minimum is violated,
+            in the latter case switch to 1:1 ratio */
+
+       if (rate >= c->u.system.pclk->min_rate * 2) {
+               ret = clk_set_div(c->u.system.pclk, 2);
+               if (ret) {
+                       pr_err("Failed to set 1 : 2 pclk divider\n");
+                       return ret;
+               }
+       }
+
+       new_parent = (rate <= c->u.system.threshold) ?
+               c->u.system.sclk_low : c->u.system.sclk_high;
+
+       ret = clk_set_rate(new_parent, rate + 1);
+       if (ret) {
+               pr_err("Failed to set sclk source %s to %lu\n",
+                      new_parent->name, rate);
+               return ret;
+       }
+
+       if (new_parent != clk_get_parent(c->parent)) {
+               ret = clk_set_parent(c->parent, new_parent);
+               if (ret) {
+                       pr_err("Failed to switch sclk source to %s\n",
+                              new_parent->name);
+                       return ret;
+               }
+       }
+
+       if (rate < c->u.system.pclk->min_rate * 2) {
+               ret = clk_set_div(c->u.system.pclk, 1);
+               if (ret) {
+                       pr_err("Failed to set 1 : 1 pclk divider\n");
+                       return ret;
+               }
+       }
+
+       return 0;
+}
+
+static struct clk_ops tegra_sbus_cmplx_ops = {
+       .init = tegra3_sbus_cmplx_init,
+       .set_rate = tegra3_sbus_cmplx_set_rate,
+       .round_rate = tegra3_sbus_cmplx_round_rate,
+       .shared_bus_update = tegra3_clk_shared_bus_update,
+};
+
+/* Blink output functions */
+
+static void tegra3_blink_clk_init(struct clk *c)
+{
+       u32 val;
+
+       val = pmc_readl(PMC_CTRL);
+       c->state = (val & PMC_CTRL_BLINK_ENB) ? ON : OFF;
+       c->mul = 1;
+       val = pmc_readl(c->reg);
+
+       if (val & PMC_BLINK_TIMER_ENB) {
+               unsigned int on_off;
+
+               on_off = (val >> PMC_BLINK_TIMER_DATA_ON_SHIFT) &
+                       PMC_BLINK_TIMER_DATA_ON_MASK;
+               val >>= PMC_BLINK_TIMER_DATA_OFF_SHIFT;
+               val &= PMC_BLINK_TIMER_DATA_OFF_MASK;
+               on_off += val;
+               /* each tick in the blink timer is 4 32KHz clocks */
+               c->div = on_off * 4;
+       } else {
+               c->div = 1;
+       }
+}
+
+static int tegra3_blink_clk_enable(struct clk *c)
+{
+       u32 val;
+
+       val = pmc_readl(PMC_DPD_PADS_ORIDE);
+       pmc_writel(val | PMC_DPD_PADS_ORIDE_BLINK_ENB, PMC_DPD_PADS_ORIDE);
+
+       val = pmc_readl(PMC_CTRL);
+       pmc_writel(val | PMC_CTRL_BLINK_ENB, PMC_CTRL);
+
+       return 0;
+}
+
+static void tegra3_blink_clk_disable(struct clk *c)
+{
+       u32 val;
+
+       val = pmc_readl(PMC_CTRL);
+       pmc_writel(val & ~PMC_CTRL_BLINK_ENB, PMC_CTRL);
+
+       val = pmc_readl(PMC_DPD_PADS_ORIDE);
+       pmc_writel(val & ~PMC_DPD_PADS_ORIDE_BLINK_ENB, PMC_DPD_PADS_ORIDE);
+}
+
+static int tegra3_blink_clk_set_rate(struct clk *c, unsigned long rate)
+{
+       unsigned long parent_rate = clk_get_rate(c->parent);
+       if (rate >= parent_rate) {
+               c->div = 1;
+               pmc_writel(0, c->reg);
+       } else {
+               unsigned int on_off;
+               u32 val;
+
+               on_off = DIV_ROUND_UP(parent_rate / 8, rate);
+               c->div = on_off * 8;
+
+               val = (on_off & PMC_BLINK_TIMER_DATA_ON_MASK) <<
+                       PMC_BLINK_TIMER_DATA_ON_SHIFT;
+               on_off &= PMC_BLINK_TIMER_DATA_OFF_MASK;
+               on_off <<= PMC_BLINK_TIMER_DATA_OFF_SHIFT;
+               val |= on_off;
+               val |= PMC_BLINK_TIMER_ENB;
+               pmc_writel(val, c->reg);
+       }
+
+       return 0;
+}
+
+static struct clk_ops tegra_blink_clk_ops = {
+       .init                   = &tegra3_blink_clk_init,
+       .enable                 = &tegra3_blink_clk_enable,
+       .disable                = &tegra3_blink_clk_disable,
+       .set_rate               = &tegra3_blink_clk_set_rate,
+};
+
+/* PLL Functions */
+static int tegra3_pll_clk_wait_for_lock(struct clk *c, u32 lock_reg, u32 lock_bit)
+{
+#if USE_PLL_LOCK_BITS
+       int i;
+       for (i = 0; i < c->u.pll.lock_delay; i++) {
+               udelay(2);              /* timeout = 2 * lock time */
+               if (clk_readl(lock_reg) & lock_bit) {
+                       udelay(PLL_POST_LOCK_DELAY);
+                       return 0;
+               }
+       }
+       pr_err("Timed out waiting for lock bit on pll %s", c->name);
+       return -1;
+#endif
+       udelay(c->u.pll.lock_delay);
+
+       return 0;
+}
+
+
+static void tegra3_utmi_param_configure(struct clk *c)
+{
+       u32 reg;
+       int i;
+       unsigned long main_rate =
+               clk_get_rate(c->parent->parent);
+
+       for (i = 0; i < ARRAY_SIZE(utmi_parameters); i++) {
+               if (main_rate == utmi_parameters[i].osc_frequency) {
+                       break;
+               }
+       }
+
+       if (i >= ARRAY_SIZE(utmi_parameters)) {
+               pr_err("%s: Unexpected main rate %lu\n", __func__, main_rate);
+               return;
+       }
+
+       reg = clk_readl(UTMIP_PLL_CFG2);
+
+       /* Program UTMIP PLL stable and active counts */
+       /* [FIXME] arclk_rst.h says WRONG! This should be 1ms -> 0x50 Check! */
+       reg &= ~UTMIP_PLL_CFG2_STABLE_COUNT(~0);
+       reg |= UTMIP_PLL_CFG2_STABLE_COUNT(
+                       utmi_parameters[i].stable_count);
+
+       reg &= ~UTMIP_PLL_CFG2_ACTIVE_DLY_COUNT(~0);
+
+       reg |= UTMIP_PLL_CFG2_ACTIVE_DLY_COUNT(
+                       utmi_parameters[i].active_delay_count);
+
+       /* Remove power downs from UTMIP PLL control bits */
+       reg &= ~UTMIP_PLL_CFG2_FORCE_PD_SAMP_A_POWERDOWN;
+       reg &= ~UTMIP_PLL_CFG2_FORCE_PD_SAMP_B_POWERDOWN;
+       reg &= ~UTMIP_PLL_CFG2_FORCE_PD_SAMP_C_POWERDOWN;
+
+       clk_writel(reg, UTMIP_PLL_CFG2);
+
+       /* Program UTMIP PLL delay and oscillator frequency counts */
+       reg = clk_readl(UTMIP_PLL_CFG1);
+       reg &= ~UTMIP_PLL_CFG1_ENABLE_DLY_COUNT(~0);
+
+       reg |= UTMIP_PLL_CFG1_ENABLE_DLY_COUNT(
+               utmi_parameters[i].enable_delay_count);
+
+       reg &= ~UTMIP_PLL_CFG1_XTAL_FREQ_COUNT(~0);
+       reg |= UTMIP_PLL_CFG1_XTAL_FREQ_COUNT(
+               utmi_parameters[i].xtal_freq_count);
+
+       /* Remove power downs from UTMIP PLL control bits */
+       reg &= ~UTMIP_PLL_CFG1_FORCE_PLL_ENABLE_POWERDOWN;
+       reg &= ~UTMIP_PLL_CFG1_FORCE_PLL_ACTIVE_POWERDOWN;
+       reg &= ~UTMIP_PLL_CFG1_FORCE_PLLU_POWERDOWN;
+
+       clk_writel(reg, UTMIP_PLL_CFG1);
+}
+
+static void tegra3_pll_m_override_update(struct clk *c, bool init)
+{
+       u32 val = pmc_readl(PMC_PLLP_WB0_OVERRIDE);
+
+       if (!(val & PMC_PLLP_WB0_OVERRIDE_PLLM_OVERRIDE))
+               return;
+
+       /* override PLLM state with PMC settings */
+       c->state = (val & PMC_PLLP_WB0_OVERRIDE_PLLM_ENABLE) ? ON : OFF;
+
+       val = pmc_readl(PMC_PLLM_WB0_OVERRIDE);
+       c->mul = (val & PMC_PLLM_WB0_OVERRIDE_DIVN_MASK) >>
+               PMC_PLLM_WB0_OVERRIDE_DIVN_SHIFT;
+       c->div = (val & PMC_PLLM_WB0_OVERRIDE_DIVM_MASK) >>
+               PMC_PLLM_WB0_OVERRIDE_DIVM_SHIFT;
+       c->div *= (0x1 << ((val & PMC_PLLM_WB0_OVERRIDE_DIVP_MASK) >>
+                          PMC_PLLM_WB0_OVERRIDE_DIVP_SHIFT));
+
+       /* Save initial override settings in Scratch2 register; will be used by
+          LP0 entry code to restore PLLM boot configuration */
+       if (init)
+               pmc_writel(val, PMC_SCRATCH2);
+}
+
+static void tegra3_pll_clk_init(struct clk *c)
+{
+       u32 val = clk_readl(c->reg + PLL_BASE);
+
+       c->state = (val & PLL_BASE_ENABLE) ? ON : OFF;
+
+       if (c->flags & PLL_FIXED && !(val & PLL_BASE_OVERRIDE)) {
+               const struct clk_pll_freq_table *sel;
+               unsigned long input_rate = clk_get_rate(c->parent);
+               c->u.pll.fixed_rate = PLLP_DEFAULT_FIXED_RATE;
+
+               for (sel = c->u.pll.freq_table; sel->input_rate != 0; sel++) {
+                       if (sel->input_rate == input_rate &&
+                               sel->output_rate == c->u.pll.fixed_rate) {
+                               c->mul = sel->n;
+                               c->div = sel->m * sel->p;
+                               return;
+                       }
+               }
+               pr_err("Clock %s has unknown fixed frequency\n", c->name);
+               BUG();
+       } else if (val & PLL_BASE_BYPASS) {
+               c->mul = 1;
+               c->div = 1;
+       } else {
+               c->mul = (val & PLL_BASE_DIVN_MASK) >> PLL_BASE_DIVN_SHIFT;
+               c->div = (val & PLL_BASE_DIVM_MASK) >> PLL_BASE_DIVM_SHIFT;
+               if (c->flags & PLLU)
+                       c->div *= (val & PLLU_BASE_POST_DIV) ? 1 : 2;
+               else
+                       c->div *= (0x1 << ((val & PLL_BASE_DIVP_MASK) >>
+                                       PLL_BASE_DIVP_SHIFT));
+       }
+
+       if (c->flags & PLL_FIXED) {
+               c->u.pll.fixed_rate = clk_get_rate_locked(c);
+       }
+
+       if (c->flags & PLLU) {
+               tegra3_utmi_param_configure(c);
+       }
+
+       if (c->flags & PLLM)
+               tegra3_pll_m_override_update(c, true);
+}
+
+static int tegra3_pll_clk_enable(struct clk *c)
+{
+       u32 val;
+       pr_debug("%s on clock %s\n", __func__, c->name);
+
+#if USE_PLL_LOCK_BITS
+       val = clk_readl(c->reg + PLL_MISC(c));
+       val |= PLL_MISC_LOCK_ENABLE(c);
+       clk_writel(val, c->reg + PLL_MISC(c));
+#endif
+       val = clk_readl(c->reg + PLL_BASE);
+       val &= ~PLL_BASE_BYPASS;
+       val |= PLL_BASE_ENABLE;
+       clk_writel(val, c->reg + PLL_BASE);
+
+       if (c->flags & PLLM) {
+               val = pmc_readl(PMC_PLLP_WB0_OVERRIDE);
+               val |= PMC_PLLP_WB0_OVERRIDE_PLLM_ENABLE;
+               pmc_writel(val, PMC_PLLP_WB0_OVERRIDE);
+               pmc_readl(PMC_PLLP_WB0_OVERRIDE);
+       }
+
+       tegra3_pll_clk_wait_for_lock(c, c->reg + PLL_BASE, PLL_BASE_LOCK);
+
+       return 0;
+}
+
+static void tegra3_pll_clk_disable(struct clk *c)
+{
+       u32 val;
+       pr_debug("%s on clock %s\n", __func__, c->name);
+
+       val = clk_readl(c->reg);
+       val &= ~(PLL_BASE_BYPASS | PLL_BASE_ENABLE);
+       clk_writel(val, c->reg);
+
+       if (c->flags & PLLM) {
+               val = pmc_readl(PMC_PLLP_WB0_OVERRIDE);
+               val &= ~PMC_PLLP_WB0_OVERRIDE_PLLM_ENABLE;
+               pmc_writel(val, PMC_PLLP_WB0_OVERRIDE);
+       }
+}
+
+static int tegra3_pllm_override_rate(
+       struct clk *c, const struct clk_pll_freq_table *sel, u32 p_div)
+{
+       u32 val, old_base;
+
+       old_base = val = pmc_readl(PMC_PLLM_WB0_OVERRIDE);
+
+       /* Keep default CPCON and DCCON in override configuration */
+       val &= ~(PMC_PLLM_WB0_OVERRIDE_DIVM_MASK |
+                PMC_PLLM_WB0_OVERRIDE_DIVN_MASK |
+                PMC_PLLM_WB0_OVERRIDE_DIVP_MASK);
+       val |= (sel->m << PMC_PLLM_WB0_OVERRIDE_DIVM_SHIFT) |
+               (sel->n << PMC_PLLM_WB0_OVERRIDE_DIVN_SHIFT) |
+               (p_div << PMC_PLLM_WB0_OVERRIDE_DIVP_SHIFT);
+
+       if (val != old_base)
+               pmc_writel(val, PMC_PLLM_WB0_OVERRIDE);
+
+       return 0;
+}
+
+static int tegra3_pll_clk_set_rate(struct clk *c, unsigned long rate)
+{
+       u32 val, p_div, old_base;
+       unsigned long input_rate;
+       const struct clk_pll_freq_table *sel;
+       struct clk_pll_freq_table cfg;
+
+       pr_debug("%s: %s %lu\n", __func__, c->name, rate);
+
+       if (c->flags & PLL_FIXED) {
+               int ret = 0;
+               if (rate != c->u.pll.fixed_rate) {
+                       pr_err("%s: Can not change %s fixed rate %lu to %lu\n",
+                              __func__, c->name, c->u.pll.fixed_rate, rate);
+                       ret = -EINVAL;
+               }
+               return ret;
+       }
+
+       if ((c->flags & PLLM) && (c->state == ON)) {
+               if (rate != clk_get_rate_locked(c)) {
+                       pr_err("%s: Can not change memory %s rate in flight\n",
+                              __func__, c->name);
+                       return -EINVAL;
+               }
+               return 0;
+       }
+
+       p_div = 0;
+       input_rate = clk_get_rate(c->parent);
+
+       /* Check if the target rate is tabulated */
+       for (sel = c->u.pll.freq_table; sel->input_rate != 0; sel++) {
+               if (sel->input_rate == input_rate && sel->output_rate == rate) {
+                       if (c->flags & PLLU) {
+                               BUG_ON(sel->p < 1 || sel->p > 2);
+                               if (sel->p == 1)
+                                       p_div = PLLU_BASE_POST_DIV;
+                       } else {
+                               BUG_ON(sel->p < 1);
+                               for (val = sel->p; val > 1; val >>= 1, p_div++);
+                               p_div <<= PLL_BASE_DIVP_SHIFT;
+                       }
+                       break;
+               }
+       }
+
+       /* Configure out-of-table rate */
+       if (sel->input_rate == 0) {
+               unsigned long cfreq;
+               BUG_ON(c->flags & PLLU);
+               sel = &cfg;
+
+               switch (input_rate) {
+               case 12000000:
+               case 26000000:
+                       cfreq = (rate <= 1000000 * 1000) ? 1000000 : 2000000;
+                       break;
+               case 13000000:
+                       cfreq = (rate <= 1000000 * 1000) ? 1000000 : 2600000;
+                       break;
+               case 16800000:
+               case 19200000:
+                       cfreq = (rate <= 1200000 * 1000) ? 1200000 : 2400000;
+                       break;
+               default:
+                       if (c->parent->flags & DIV_U71_FIXED) {
+                               /* PLLP_OUT1 rate is not in PLLA table */
+                               pr_warn("%s: failed %s ref/out rates %lu/%lu\n",
+                                       __func__, c->name, input_rate, rate);
+                               cfreq = input_rate/(input_rate/1000000);
+                               break;
+                       }
+                       pr_err("%s: Unexpected reference rate %lu\n",
+                              __func__, input_rate);
+                       BUG();
+               }
+
+               /* Raise VCO to guarantee 0.5% accuracy */
+               for (cfg.output_rate = rate; cfg.output_rate < 200 * cfreq;
+                     cfg.output_rate <<= 1, p_div++);
+
+               cfg.p = 0x1 << p_div;
+               cfg.m = input_rate / cfreq;
+               cfg.n = cfg.output_rate / cfreq;
+               cfg.cpcon = OUT_OF_TABLE_CPCON;
+
+               if ((cfg.m > (PLL_BASE_DIVM_MASK >> PLL_BASE_DIVM_SHIFT)) ||
+                   (cfg.n > (PLL_BASE_DIVN_MASK >> PLL_BASE_DIVN_SHIFT)) ||
+                   (p_div > (PLL_BASE_DIVP_MASK >> PLL_BASE_DIVP_SHIFT)) ||
+                   (cfg.output_rate > c->u.pll.vco_max)) {
+                       pr_err("%s: Failed to set %s out-of-table rate %lu\n",
+                              __func__, c->name, rate);
+                       return -EINVAL;
+               }
+               p_div <<= PLL_BASE_DIVP_SHIFT;
+       }
+
+       c->mul = sel->n;
+       c->div = sel->m * sel->p;
+
+       if (c->flags & PLLM) {
+               val = pmc_readl(PMC_PLLP_WB0_OVERRIDE);
+               if (val & PMC_PLLP_WB0_OVERRIDE_PLLM_OVERRIDE)
+                       return tegra3_pllm_override_rate(
+                               c, sel, p_div >> PLL_BASE_DIVP_SHIFT);
+       }
+
+       old_base = val = clk_readl(c->reg + PLL_BASE);
+       val &= ~(PLL_BASE_DIVM_MASK | PLL_BASE_DIVN_MASK |
+                ((c->flags & PLLU) ? PLLU_BASE_POST_DIV : PLL_BASE_DIVP_MASK));
+       val |= (sel->m << PLL_BASE_DIVM_SHIFT) |
+               (sel->n << PLL_BASE_DIVN_SHIFT) | p_div;
+       if (val == old_base)
+               return 0;
+
+       if (c->state == ON) {
+               tegra3_pll_clk_disable(c);
+               val &= ~(PLL_BASE_BYPASS | PLL_BASE_ENABLE);
+       }
+       clk_writel(val, c->reg + PLL_BASE);
+
+       if (c->flags & PLL_HAS_CPCON) {
+               val = clk_readl(c->reg + PLL_MISC(c));
+               val &= ~PLL_MISC_CPCON_MASK;
+               val |= sel->cpcon << PLL_MISC_CPCON_SHIFT;
+               if (c->flags & (PLLU | PLLD)) {
+                       val &= ~PLL_MISC_LFCON_MASK;
+                       if (sel->n >= PLLDU_LFCON_SET_DIVN)
+                               val |= 0x1 << PLL_MISC_LFCON_SHIFT;
+               } else if (c->flags & (PLLX | PLLM)) {
+                       val &= ~(0x1 << PLL_MISC_DCCON_SHIFT);
+                       if (rate >= (c->u.pll.vco_max >> 1))
+                               val |= 0x1 << PLL_MISC_DCCON_SHIFT;
+               }
+               clk_writel(val, c->reg + PLL_MISC(c));
+       }
+
+       if (c->state == ON)
+               tegra3_pll_clk_enable(c);
+
+       return 0;
+}
+
+static struct clk_ops tegra_pll_ops = {
+       .init                   = tegra3_pll_clk_init,
+       .enable                 = tegra3_pll_clk_enable,
+       .disable                = tegra3_pll_clk_disable,
+       .set_rate               = tegra3_pll_clk_set_rate,
+};
+
+static void tegra3_pllp_clk_init(struct clk *c)
+{
+       tegra3_pll_clk_init(c);
+       tegra3_pllp_init_dependencies(c->u.pll.fixed_rate);
+}
+
+#if defined(CONFIG_PM_SLEEP)
+static void tegra3_pllp_clk_resume(struct clk *c)
+{
+       unsigned long rate = c->u.pll.fixed_rate;
+       tegra3_pll_clk_init(c);
+       BUG_ON(rate != c->u.pll.fixed_rate);
+}
+#endif
+
+static struct clk_ops tegra_pllp_ops = {
+       .init                   = tegra3_pllp_clk_init,
+       .enable                 = tegra3_pll_clk_enable,
+       .disable                = tegra3_pll_clk_disable,
+       .set_rate               = tegra3_pll_clk_set_rate,
+};
+
+static int
+tegra3_plld_clk_cfg_ex(struct clk *c, enum tegra_clk_ex_param p, u32 setting)
+{
+       u32 val, mask, reg;
+
+       switch (p) {
+       case TEGRA_CLK_PLLD_CSI_OUT_ENB:
+               mask = PLLD_BASE_CSI_CLKENABLE;
+               reg = c->reg + PLL_BASE;
+               break;
+       case TEGRA_CLK_PLLD_DSI_OUT_ENB:
+               mask = PLLD_MISC_DSI_CLKENABLE;
+               reg = c->reg + PLL_MISC(c);
+               break;
+       case TEGRA_CLK_PLLD_MIPI_MUX_SEL:
+               if (!(c->flags & PLL_ALT_MISC_REG)) {
+                       mask = PLLD_BASE_DSIB_MUX_MASK;
+                       reg = c->reg + PLL_BASE;
+                       break;
+               }
+       /* fall through - error since PLLD2 does not have MUX_SEL control */
+       default:
+               return -EINVAL;
+       }
+
+       val = clk_readl(reg);
+       if (setting)
+               val |= mask;
+       else
+               val &= ~mask;
+       clk_writel(val, reg);
+       return 0;
+}
+
+static struct clk_ops tegra_plld_ops = {
+       .init                   = tegra3_pll_clk_init,
+       .enable                 = tegra3_pll_clk_enable,
+       .disable                = tegra3_pll_clk_disable,
+       .set_rate               = tegra3_pll_clk_set_rate,
+       .clk_cfg_ex             = tegra3_plld_clk_cfg_ex,
+};
+
+static void tegra3_plle_clk_init(struct clk *c)
+{
+       u32 val;
+
+       val = clk_readl(PLLE_AUX);
+       c->parent = (val & PLLE_AUX_PLLP_SEL) ?
+               tegra_get_clock_by_name("pll_p") :
+               tegra_get_clock_by_name("pll_ref");
+
+       val = clk_readl(c->reg + PLL_BASE);
+       c->state = (val & PLLE_BASE_ENABLE) ? ON : OFF;
+       c->mul = (val & PLLE_BASE_DIVN_MASK) >> PLLE_BASE_DIVN_SHIFT;
+       c->div = (val & PLLE_BASE_DIVM_MASK) >> PLLE_BASE_DIVM_SHIFT;
+       c->div *= (val & PLLE_BASE_DIVP_MASK) >> PLLE_BASE_DIVP_SHIFT;
+}
+
+static void tegra3_plle_clk_disable(struct clk *c)
+{
+       u32 val;
+       pr_debug("%s on clock %s\n", __func__, c->name);
+
+       val = clk_readl(c->reg + PLL_BASE);
+       val &= ~(PLLE_BASE_CML_ENABLE | PLLE_BASE_ENABLE);
+       clk_writel(val, c->reg + PLL_BASE);
+}
+
+static void tegra3_plle_training(struct clk *c)
+{
+       u32 val;
+
+       /* PLLE is already disabled, and setup cleared;
+        * create falling edge on PLLE IDDQ input */
+       val = pmc_readl(PMC_SATA_PWRGT);
+       val |= PMC_SATA_PWRGT_PLLE_IDDQ_VALUE;
+       pmc_writel(val, PMC_SATA_PWRGT);
+
+       val = pmc_readl(PMC_SATA_PWRGT);
+       val |= PMC_SATA_PWRGT_PLLE_IDDQ_SWCTL;
+       pmc_writel(val, PMC_SATA_PWRGT);
+
+       val = pmc_readl(PMC_SATA_PWRGT);
+       val &= ~PMC_SATA_PWRGT_PLLE_IDDQ_VALUE;
+       pmc_writel(val, PMC_SATA_PWRGT);
+
+       do {
+               val = clk_readl(c->reg + PLL_MISC(c));
+       } while (!(val & PLLE_MISC_READY));
+}
+
+static int tegra3_plle_configure(struct clk *c, bool force_training)
+{
+       u32 val;
+       const struct clk_pll_freq_table *sel;
+       unsigned long rate = c->u.pll.fixed_rate;
+       unsigned long input_rate = clk_get_rate(c->parent);
+
+       for (sel = c->u.pll.freq_table; sel->input_rate != 0; sel++) {
+               if (sel->input_rate == input_rate && sel->output_rate == rate)
+                       break;
+       }
+
+       if (sel->input_rate == 0)
+               return -ENOSYS;
+
+       /* disable PLLE, clear setup fiels */
+       tegra3_plle_clk_disable(c);
+
+       val = clk_readl(c->reg + PLL_MISC(c));
+       val &= ~(PLLE_MISC_LOCK_ENABLE | PLLE_MISC_SETUP_MASK);
+       clk_writel(val, c->reg + PLL_MISC(c));
+
+       /* training */
+       val = clk_readl(c->reg + PLL_MISC(c));
+       if (force_training || (!(val & PLLE_MISC_READY)))
+               tegra3_plle_training(c);
+
+       /* configure dividers, setup, disable SS */
+       val = clk_readl(c->reg + PLL_BASE);
+       val &= ~PLLE_BASE_DIV_MASK;
+       val |= PLLE_BASE_DIV(sel->m, sel->n, sel->p, sel->cpcon);
+       clk_writel(val, c->reg + PLL_BASE);
+       c->mul = sel->n;
+       c->div = sel->m * sel->p;
+
+       val = clk_readl(c->reg + PLL_MISC(c));
+       val |= PLLE_MISC_SETUP_VALUE;
+       val |= PLLE_MISC_LOCK_ENABLE;
+       clk_writel(val, c->reg + PLL_MISC(c));
+
+       val = clk_readl(PLLE_SS_CTRL);
+       val |= PLLE_SS_DISABLE;
+       clk_writel(val, PLLE_SS_CTRL);
+
+       /* enable and lock PLLE*/
+       val = clk_readl(c->reg + PLL_BASE);
+       val |= (PLLE_BASE_CML_ENABLE | PLLE_BASE_ENABLE);
+       clk_writel(val, c->reg + PLL_BASE);
+
+       tegra3_pll_clk_wait_for_lock(c, c->reg + PLL_MISC(c), PLLE_MISC_LOCK);
+
+#if USE_PLLE_SS
+       /* configure spread spectrum coefficients */
+       /* FIXME: coefficients for 216MHZ input? */
+#ifdef CONFIG_TEGRA_SILICON_PLATFORM
+       if (input_rate == 12000000)
+#endif
+       {
+               val = clk_readl(PLLE_SS_CTRL);
+               val &= ~(PLLE_SS_COEFFICIENTS_MASK | PLLE_SS_DISABLE);
+               val |= PLLE_SS_COEFFICIENTS_12MHZ;
+               clk_writel(val, PLLE_SS_CTRL);
+       }
+#endif
+       return 0;
+}
+
+static int tegra3_plle_clk_enable(struct clk *c)
+{
+       pr_debug("%s on clock %s\n", __func__, c->name);
+       return tegra3_plle_configure(c, !c->set);
+}
+
+static struct clk_ops tegra_plle_ops = {
+       .init                   = tegra3_plle_clk_init,
+       .enable                 = tegra3_plle_clk_enable,
+       .disable                = tegra3_plle_clk_disable,
+};
+
+/* Clock divider ops (non-atomic shared register access) */
+static DEFINE_SPINLOCK(pll_div_lock);
+
+static int tegra3_pll_div_clk_set_rate(struct clk *c, unsigned long rate);
+static void tegra3_pll_div_clk_init(struct clk *c)
+{
+       if (c->flags & DIV_U71) {
+               u32 divu71;
+               u32 val = clk_readl(c->reg);
+               val >>= c->reg_shift;
+               c->state = (val & PLL_OUT_CLKEN) ? ON : OFF;
+               if (!(val & PLL_OUT_RESET_DISABLE))
+                       c->state = OFF;
+
+               if (c->u.pll_div.default_rate) {
+                       int ret = tegra3_pll_div_clk_set_rate(
+                                       c, c->u.pll_div.default_rate);
+                       if (!ret)
+                               return;
+               }
+               divu71 = (val & PLL_OUT_RATIO_MASK) >> PLL_OUT_RATIO_SHIFT;
+               c->div = (divu71 + 2);
+               c->mul = 2;
+       } else if (c->flags & DIV_2) {
+               c->state = ON;
+               if (c->flags & (PLLD | PLLX)) {
+                       c->div = 2;
+                       c->mul = 1;
+               }
+               else
+                       BUG();
+       } else {
+               c->state = ON;
+               c->div = 1;
+               c->mul = 1;
+       }
+}
+
+static int tegra3_pll_div_clk_enable(struct clk *c)
+{
+       u32 val;
+       u32 new_val;
+       unsigned long flags;
+
+       pr_debug("%s: %s\n", __func__, c->name);
+       if (c->flags & DIV_U71) {
+               spin_lock_irqsave(&pll_div_lock, flags);
+               val = clk_readl(c->reg);
+               new_val = val >> c->reg_shift;
+               new_val &= 0xFFFF;
+
+               new_val |= PLL_OUT_CLKEN | PLL_OUT_RESET_DISABLE;
+
+               val &= ~(0xFFFF << c->reg_shift);
+               val |= new_val << c->reg_shift;
+               clk_writel_delay(val, c->reg);
+               spin_unlock_irqrestore(&pll_div_lock, flags);
+               return 0;
+       } else if (c->flags & DIV_2) {
+               return 0;
+       }
+       return -EINVAL;
+}
+
+static void tegra3_pll_div_clk_disable(struct clk *c)
+{
+       u32 val;
+       u32 new_val;
+       unsigned long flags;
+
+       pr_debug("%s: %s\n", __func__, c->name);
+       if (c->flags & DIV_U71) {
+               spin_lock_irqsave(&pll_div_lock, flags);
+               val = clk_readl(c->reg);
+               new_val = val >> c->reg_shift;
+               new_val &= 0xFFFF;
+
+               new_val &= ~(PLL_OUT_CLKEN | PLL_OUT_RESET_DISABLE);
+
+               val &= ~(0xFFFF << c->reg_shift);
+               val |= new_val << c->reg_shift;
+               clk_writel_delay(val, c->reg);
+               spin_unlock_irqrestore(&pll_div_lock, flags);
+       }
+}
+
+static int tegra3_pll_div_clk_set_rate(struct clk *c, unsigned long rate)
+{
+       u32 val;
+       u32 new_val;
+       int divider_u71;
+       unsigned long parent_rate = clk_get_rate(c->parent);
+       unsigned long flags;
+
+       pr_debug("%s: %s %lu\n", __func__, c->name, rate);
+       if (c->flags & DIV_U71) {
+               divider_u71 = clk_div71_get_divider(
+                       parent_rate, rate, c->flags, ROUND_DIVIDER_UP);
+               if (divider_u71 >= 0) {
+                       spin_lock_irqsave(&pll_div_lock, flags);
+                       val = clk_readl(c->reg);
+                       new_val = val >> c->reg_shift;
+                       new_val &= 0xFFFF;
+                       if (c->flags & DIV_U71_FIXED)
+                               new_val |= PLL_OUT_OVERRIDE;
+                       new_val &= ~PLL_OUT_RATIO_MASK;
+                       new_val |= divider_u71 << PLL_OUT_RATIO_SHIFT;
+
+                       val &= ~(0xFFFF << c->reg_shift);
+                       val |= new_val << c->reg_shift;
+                       clk_writel_delay(val, c->reg);
+                       c->div = divider_u71 + 2;
+                       c->mul = 2;
+                       spin_unlock_irqrestore(&pll_div_lock, flags);
+                       return 0;
+               }
+       } else if (c->flags & DIV_2)
+               return clk_set_rate(c->parent, rate * 2);
+
+       return -EINVAL;
+}
+
+static long tegra3_pll_div_clk_round_rate(struct clk *c, unsigned long rate)
+{
+       int divider;
+       unsigned long parent_rate = clk_get_rate(c->parent);
+       pr_debug("%s: %s %lu\n", __func__, c->name, rate);
+
+       if (c->flags & DIV_U71) {
+               divider = clk_div71_get_divider(
+                       parent_rate, rate, c->flags, ROUND_DIVIDER_UP);
+               if (divider < 0)
+                       return divider;
+               return DIV_ROUND_UP(parent_rate * 2, divider + 2);
+       } else if (c->flags & DIV_2)
+               /* no rounding - fixed DIV_2 dividers pass rate to parent PLL */
+               return rate;
+
+       return -EINVAL;
+}
+
+static struct clk_ops tegra_pll_div_ops = {
+       .init                   = tegra3_pll_div_clk_init,
+       .enable                 = tegra3_pll_div_clk_enable,
+       .disable                = tegra3_pll_div_clk_disable,
+       .set_rate               = tegra3_pll_div_clk_set_rate,
+       .round_rate             = tegra3_pll_div_clk_round_rate,
+};
+
+/* Periph clk ops */
+static inline u32 periph_clk_source_mask(struct clk *c)
+{
+       if (c->flags & MUX8)
+                return 7 << 29;
+       else if (c->flags & MUX_PWM)
+               return 3 << 28;
+       else if (c->flags & MUX_CLK_OUT)
+               return 3 << (c->u.periph.clk_num + 4);
+       else if (c->flags & PLLD)
+               return PLLD_BASE_DSIB_MUX_MASK;
+       else
+               return 3 << 30;
+}
+
+static inline u32 periph_clk_source_shift(struct clk *c)
+{
+       if (c->flags & MUX8)
+                return 29;
+       else if (c->flags & MUX_PWM)
+               return 28;
+       else if (c->flags & MUX_CLK_OUT)
+               return c->u.periph.clk_num + 4;
+       else if (c->flags & PLLD)
+               return PLLD_BASE_DSIB_MUX_SHIFT;
+       else
+               return 30;
+}
+
+static void tegra3_periph_clk_init(struct clk *c)
+{
+       u32 val = clk_readl(c->reg);
+       const struct clk_mux_sel *mux = 0;
+       const struct clk_mux_sel *sel;
+       if (c->flags & MUX) {
+               for (sel = c->inputs; sel->input != NULL; sel++) {
+                       if (((val & periph_clk_source_mask(c)) >>
+                           periph_clk_source_shift(c)) == sel->value)
+                               mux = sel;
+               }
+               BUG_ON(!mux);
+
+               c->parent = mux->input;
+       } else {
+               c->parent = c->inputs[0].input;
+       }
+
+       if (c->flags & DIV_U71) {
+               u32 divu71 = val & PERIPH_CLK_SOURCE_DIVU71_MASK;
+               if (c->flags & DIV_U71_IDLE) {
+                       val &= ~(PERIPH_CLK_SOURCE_DIVU71_MASK <<
+                               PERIPH_CLK_SOURCE_DIVIDLE_SHIFT);
+                       val |= (PERIPH_CLK_SOURCE_DIVIDLE_VAL <<
+                               PERIPH_CLK_SOURCE_DIVIDLE_SHIFT);
+                       clk_writel(val, c->reg);
+               }
+               c->div = divu71 + 2;
+               c->mul = 2;
+       } else if (c->flags & DIV_U151) {
+               u32 divu151 = val & PERIPH_CLK_SOURCE_DIVU16_MASK;
+               if ((c->flags & DIV_U151_UART) &&
+                   (!(val & PERIPH_CLK_UART_DIV_ENB))) {
+                       divu151 = 0;
+               }
+               c->div = divu151 + 2;
+               c->mul = 2;
+       } else if (c->flags & DIV_U16) {
+               u32 divu16 = val & PERIPH_CLK_SOURCE_DIVU16_MASK;
+               c->div = divu16 + 1;
+               c->mul = 1;
+       } else {
+               c->div = 1;
+               c->mul = 1;
+       }
+
+       c->state = ON;
+
+       if (c->flags & PERIPH_NO_ENB)
+               return;
+
+       if (!(clk_readl(PERIPH_CLK_TO_ENB_REG(c)) & PERIPH_CLK_TO_BIT(c)))
+               c->state = OFF;
+       if (!(c->flags & PERIPH_NO_RESET))
+               if (clk_readl(PERIPH_CLK_TO_RST_REG(c)) & PERIPH_CLK_TO_BIT(c))
+                       c->state = OFF;
+}
+
+static int tegra3_periph_clk_enable(struct clk *c)
+{
+       unsigned long flags;
+       pr_debug("%s on clock %s\n", __func__, c->name);
+
+       if (c->flags & PERIPH_NO_ENB)
+               return 0;
+
+       spin_lock_irqsave(&periph_refcount_lock, flags);
+
+       tegra_periph_clk_enable_refcount[c->u.periph.clk_num]++;
+       if (tegra_periph_clk_enable_refcount[c->u.periph.clk_num] > 1) {
+               spin_unlock_irqrestore(&periph_refcount_lock, flags);
+               return 0;
+       }
+
+       clk_writel_delay(PERIPH_CLK_TO_BIT(c), PERIPH_CLK_TO_ENB_SET_REG(c));
+       if (!(c->flags & PERIPH_NO_RESET) && !(c->flags & PERIPH_MANUAL_RESET)) {
+               if (clk_readl(PERIPH_CLK_TO_RST_REG(c)) & PERIPH_CLK_TO_BIT(c)) {
+                       udelay(5);      /* reset propagation delay */
+                       clk_writel(PERIPH_CLK_TO_BIT(c), PERIPH_CLK_TO_RST_CLR_REG(c));
+               }
+       }
+       spin_unlock_irqrestore(&periph_refcount_lock, flags);
+       return 0;
+}
+
+static void tegra3_periph_clk_disable(struct clk *c)
+{
+       unsigned long val, flags;
+       pr_debug("%s on clock %s\n", __func__, c->name);
+
+       if (c->flags & PERIPH_NO_ENB)
+               return;
+
+       spin_lock_irqsave(&periph_refcount_lock, flags);
+
+       if (c->refcnt)
+               tegra_periph_clk_enable_refcount[c->u.periph.clk_num]--;
+
+       if (tegra_periph_clk_enable_refcount[c->u.periph.clk_num] == 0) {
+               /* If peripheral is in the APB bus then read the APB bus to
+                * flush the write operation in apb bus. This will avoid the
+                * peripheral access after disabling clock*/
+               if (c->flags & PERIPH_ON_APB)
+                       val = chipid_readl();
+
+               clk_writel_delay(
+                       PERIPH_CLK_TO_BIT(c), PERIPH_CLK_TO_ENB_CLR_REG(c));
+       }
+       spin_unlock_irqrestore(&periph_refcount_lock, flags);
+}
+
+static void tegra3_periph_clk_reset(struct clk *c, bool assert)
+{
+       unsigned long val;
+       pr_debug("%s %s on clock %s\n", __func__,
+                assert ? "assert" : "deassert", c->name);
+
+       if (c->flags & PERIPH_NO_ENB)
+               return;
+
+       if (!(c->flags & PERIPH_NO_RESET)) {
+               if (assert) {
+                       /* If peripheral is in the APB bus then read the APB
+                        * bus to flush the write operation in apb bus. This
+                        * will avoid the peripheral access after disabling
+                        * clock */
+                       if (c->flags & PERIPH_ON_APB)
+                               val = chipid_readl();
+
+                       clk_writel(PERIPH_CLK_TO_BIT(c),
+                                  PERIPH_CLK_TO_RST_SET_REG(c));
+               } else
+                       clk_writel(PERIPH_CLK_TO_BIT(c),
+                                  PERIPH_CLK_TO_RST_CLR_REG(c));
+       }
+}
+
+static int tegra3_periph_clk_set_parent(struct clk *c, struct clk *p)
+{
+       u32 val;
+       const struct clk_mux_sel *sel;
+       pr_debug("%s: %s %s\n", __func__, c->name, p->name);
+
+       if (!(c->flags & MUX))
+               return (p == c->parent) ? 0 : (-EINVAL);
+
+       for (sel = c->inputs; sel->input != NULL; sel++) {
+               if (sel->input == p) {
+                       val = clk_readl(c->reg);
+                       val &= ~periph_clk_source_mask(c);
+                       val |= (sel->value << periph_clk_source_shift(c));
+
+                       if (c->refcnt)
+                               clk_enable(p);
+
+                       clk_writel_delay(val, c->reg);
+
+                       if (c->refcnt && c->parent)
+                               clk_disable(c->parent);
+
+                       clk_reparent(c, p);
+                       return 0;
+               }
+       }
+
+       return -EINVAL;
+}
+
+static int tegra3_periph_clk_set_rate(struct clk *c, unsigned long rate)
+{
+       u32 val;
+       int divider;
+       unsigned long parent_rate = clk_get_rate(c->parent);
+
+       if (c->flags & DIV_U71) {
+               divider = clk_div71_get_divider(
+                       parent_rate, rate, c->flags, ROUND_DIVIDER_UP);
+               if (divider >= 0) {
+                       val = clk_readl(c->reg);
+                       val &= ~PERIPH_CLK_SOURCE_DIVU71_MASK;
+                       val |= divider;
+                       clk_writel_delay(val, c->reg);
+                       c->div = divider + 2;
+                       c->mul = 2;
+                       return 0;
+               }
+       } else if (c->flags & DIV_U151) {
+               divider = clk_div151_get_divider(
+                       parent_rate, rate, c->flags, ROUND_DIVIDER_UP);
+               if (divider >= 0) {
+                       val = clk_readl(c->reg);
+                       val &= ~PERIPH_CLK_SOURCE_DIVU16_MASK;
+                       val |= divider;
+                       if (c->flags & DIV_U151_UART) {
+                               if (divider)
+                                       val |= PERIPH_CLK_UART_DIV_ENB;
+                               else
+                                       val &= ~PERIPH_CLK_UART_DIV_ENB;
+                       }
+                       clk_writel_delay(val, c->reg);
+                       c->div = divider + 2;
+                       c->mul = 2;
+                       return 0;
+               }
+       } else if (c->flags & DIV_U16) {
+               divider = clk_div16_get_divider(parent_rate, rate);
+               if (divider >= 0) {
+                       val = clk_readl(c->reg);
+                       val &= ~PERIPH_CLK_SOURCE_DIVU16_MASK;
+                       val |= divider;
+                       clk_writel_delay(val, c->reg);
+                       c->div = divider + 1;
+                       c->mul = 1;
+                       return 0;
+               }
+       } else if (parent_rate <= rate) {
+               c->div = 1;
+               c->mul = 1;
+               return 0;
+       }
+       return -EINVAL;
+}
+
+static long tegra3_periph_clk_round_rate(struct clk *c,
+       unsigned long rate)
+{
+       int divider;
+       unsigned long parent_rate = clk_get_rate(c->parent);
+       pr_debug("%s: %s %lu\n", __func__, c->name, rate);
+
+       if (c->flags & DIV_U71) {
+               divider = clk_div71_get_divider(
+                       parent_rate, rate, c->flags, ROUND_DIVIDER_UP);
+               if (divider < 0)
+                       return divider;
+
+               return DIV_ROUND_UP(parent_rate * 2, divider + 2);
+       } else if (c->flags & DIV_U151) {
+               divider = clk_div151_get_divider(
+                       parent_rate, rate, c->flags, ROUND_DIVIDER_UP);
+               if (divider < 0)
+                       return divider;
+
+               return DIV_ROUND_UP(parent_rate * 2, divider + 2);
+       } else if (c->flags & DIV_U16) {
+               divider = clk_div16_get_divider(parent_rate, rate);
+               if (divider < 0)
+                       return divider;
+               return DIV_ROUND_UP(parent_rate, divider + 1);
+       }
+       return -EINVAL;
+}
+
+static struct clk_ops tegra_periph_clk_ops = {
+       .init                   = &tegra3_periph_clk_init,
+       .enable                 = &tegra3_periph_clk_enable,
+       .disable                = &tegra3_periph_clk_disable,
+       .set_parent             = &tegra3_periph_clk_set_parent,
+       .set_rate               = &tegra3_periph_clk_set_rate,
+       .round_rate             = &tegra3_periph_clk_round_rate,
+       .reset                  = &tegra3_periph_clk_reset,
+};
+
+
+/* Periph extended clock configuration ops */
+static int
+tegra3_vi_clk_cfg_ex(struct clk *c, enum tegra_clk_ex_param p, u32 setting)
+{
+       if (p == TEGRA_CLK_VI_INP_SEL) {
+               u32 val = clk_readl(c->reg);
+               val &= ~PERIPH_CLK_VI_SEL_EX_MASK;
+               val |= (setting << PERIPH_CLK_VI_SEL_EX_SHIFT) &
+                       PERIPH_CLK_VI_SEL_EX_MASK;
+               clk_writel(val, c->reg);
+               return 0;
+       }
+       return -EINVAL;
+}
+
+static struct clk_ops tegra_vi_clk_ops = {
+       .init                   = &tegra3_periph_clk_init,
+       .enable                 = &tegra3_periph_clk_enable,
+       .disable                = &tegra3_periph_clk_disable,
+       .set_parent             = &tegra3_periph_clk_set_parent,
+       .set_rate               = &tegra3_periph_clk_set_rate,
+       .round_rate             = &tegra3_periph_clk_round_rate,
+       .clk_cfg_ex             = &tegra3_vi_clk_cfg_ex,
+       .reset                  = &tegra3_periph_clk_reset,
+};
+
+static int
+tegra3_nand_clk_cfg_ex(struct clk *c, enum tegra_clk_ex_param p, u32 setting)
+{
+       if (p == TEGRA_CLK_NAND_PAD_DIV2_ENB) {
+               u32 val = clk_readl(c->reg);
+               if (setting)
+                       val |= PERIPH_CLK_NAND_DIV_EX_ENB;
+               else
+                       val &= ~PERIPH_CLK_NAND_DIV_EX_ENB;
+               clk_writel(val, c->reg);
+               return 0;
+       }
+       return -EINVAL;
+}
+
+static struct clk_ops tegra_nand_clk_ops = {
+       .init                   = &tegra3_periph_clk_init,
+       .enable                 = &tegra3_periph_clk_enable,
+       .disable                = &tegra3_periph_clk_disable,
+       .set_parent             = &tegra3_periph_clk_set_parent,
+       .set_rate               = &tegra3_periph_clk_set_rate,
+       .round_rate             = &tegra3_periph_clk_round_rate,
+       .clk_cfg_ex             = &tegra3_nand_clk_cfg_ex,
+       .reset                  = &tegra3_periph_clk_reset,
+};
+
+
+static int
+tegra3_dtv_clk_cfg_ex(struct clk *c, enum tegra_clk_ex_param p, u32 setting)
+{
+       if (p == TEGRA_CLK_DTV_INVERT) {
+               u32 val = clk_readl(c->reg);
+               if (setting)
+                       val |= PERIPH_CLK_DTV_POLARITY_INV;
+               else
+                       val &= ~PERIPH_CLK_DTV_POLARITY_INV;
+               clk_writel(val, c->reg);
+               return 0;
+       }
+       return -EINVAL;
+}
+
+static struct clk_ops tegra_dtv_clk_ops = {
+       .init                   = &tegra3_periph_clk_init,
+       .enable                 = &tegra3_periph_clk_enable,
+       .disable                = &tegra3_periph_clk_disable,
+       .set_parent             = &tegra3_periph_clk_set_parent,
+       .set_rate               = &tegra3_periph_clk_set_rate,
+       .round_rate             = &tegra3_periph_clk_round_rate,
+       .clk_cfg_ex             = &tegra3_dtv_clk_cfg_ex,
+       .reset                  = &tegra3_periph_clk_reset,
+};
+
+static int tegra3_dsib_clk_set_parent(struct clk *c, struct clk *p)
+{
+       const struct clk_mux_sel *sel;
+       struct clk *d = tegra_get_clock_by_name("pll_d");
+
+       pr_debug("%s: %s %s\n", __func__, c->name, p->name);
+
+       for (sel = c->inputs; sel->input != NULL; sel++) {
+               if (sel->input == p) {
+                       if (c->refcnt)
+                               clk_enable(p);
+
+                       /* The DSIB parent selection bit is in PLLD base
+                          register - can not do direct r-m-w, must be
+                          protected by PLLD lock */
+                       tegra_clk_cfg_ex(
+                               d, TEGRA_CLK_PLLD_MIPI_MUX_SEL, sel->value);
+
+                       if (c->refcnt && c->parent)
+                               clk_disable(c->parent);
+
+                       clk_reparent(c, p);
+                       return 0;
+               }
+       }
+
+       return -EINVAL;
+}
+
+static struct clk_ops tegra_dsib_clk_ops = {
+       .init                   = &tegra3_periph_clk_init,
+       .enable                 = &tegra3_periph_clk_enable,
+       .disable                = &tegra3_periph_clk_disable,
+       .set_parent             = &tegra3_dsib_clk_set_parent,
+       .set_rate               = &tegra3_periph_clk_set_rate,
+       .round_rate             = &tegra3_periph_clk_round_rate,
+       .reset                  = &tegra3_periph_clk_reset,
+};
+
+/* pciex clock support only reset function */
+static struct clk_ops tegra_pciex_clk_ops = {
+       .reset    = tegra3_periph_clk_reset,
+};
+
+/* Output clock ops (non-atomic shared register access) */
+
+static DEFINE_SPINLOCK(clk_out_lock);
+
+static void tegra3_clk_out_init(struct clk *c)
+{
+       const struct clk_mux_sel *mux = 0;
+       const struct clk_mux_sel *sel;
+       u32 val = pmc_readl(c->reg);
+
+       c->state = (val & (0x1 << c->u.periph.clk_num)) ? ON : OFF;
+       c->mul = 1;
+       c->div = 1;
+
+       for (sel = c->inputs; sel->input != NULL; sel++) {
+               if (((val & periph_clk_source_mask(c)) >>
+                    periph_clk_source_shift(c)) == sel->value)
+                       mux = sel;
+       }
+       BUG_ON(!mux);
+       c->parent = mux->input;
+}
+
+static int tegra3_clk_out_enable(struct clk *c)
+{
+       u32 val;
+       unsigned long flags;
+
+       pr_debug("%s on clock %s\n", __func__, c->name);
+
+       spin_lock_irqsave(&clk_out_lock, flags);
+       val = pmc_readl(c->reg);
+       val |= (0x1 << c->u.periph.clk_num);
+       pmc_writel(val, c->reg);
+       spin_unlock_irqrestore(&clk_out_lock, flags);
+
+       return 0;
+}
+
+static void tegra3_clk_out_disable(struct clk *c)
+{
+       u32 val;
+       unsigned long flags;
+
+       pr_debug("%s on clock %s\n", __func__, c->name);
+
+       spin_lock_irqsave(&clk_out_lock, flags);
+       val = pmc_readl(c->reg);
+       val &= ~(0x1 << c->u.periph.clk_num);
+       pmc_writel(val, c->reg);
+       spin_unlock_irqrestore(&clk_out_lock, flags);
+}
+
+static int tegra3_clk_out_set_parent(struct clk *c, struct clk *p)
+{
+       u32 val;
+       unsigned long flags;
+       const struct clk_mux_sel *sel;
+
+       pr_debug("%s: %s %s\n", __func__, c->name, p->name);
+
+       for (sel = c->inputs; sel->input != NULL; sel++) {
+               if (sel->input == p) {
+                       if (c->refcnt)
+                               clk_enable(p);
+
+                       spin_lock_irqsave(&clk_out_lock, flags);
+                       val = pmc_readl(c->reg);
+                       val &= ~periph_clk_source_mask(c);
+                       val |= (sel->value << periph_clk_source_shift(c));
+                       pmc_writel(val, c->reg);
+                       spin_unlock_irqrestore(&clk_out_lock, flags);
+
+                       if (c->refcnt && c->parent)
+                               clk_disable(c->parent);
+
+                       clk_reparent(c, p);
+                       return 0;
+               }
+       }
+       return -EINVAL;
+}
+
+static struct clk_ops tegra_clk_out_ops = {
+       .init                   = &tegra3_clk_out_init,
+       .enable                 = &tegra3_clk_out_enable,
+       .disable                = &tegra3_clk_out_disable,
+       .set_parent             = &tegra3_clk_out_set_parent,
+};
+
+
+/* External memory controller clock ops */
+static void tegra3_emc_clk_init(struct clk *c)
+{
+       tegra3_periph_clk_init(c);
+       tegra_emc_dram_type_init(c);
+
+       /* On A01 limit EMC maximum rate to boot frequency;
+          starting with A02 full PLLM range should be supported */
+       if (tegra_get_revision() == TEGRA_REVISION_A01)
+               c->max_rate = clk_get_rate_locked(c);
+       else
+               c->max_rate = clk_get_rate(c->parent);
+}
+
+static long tegra3_emc_clk_round_rate(struct clk *c, unsigned long rate)
+{
+       long new_rate = max(rate, c->min_rate);
+
+       new_rate = tegra_emc_round_rate(new_rate);
+       if (new_rate < 0)
+               new_rate = c->max_rate;
+
+       return new_rate;
+}
+
+static int tegra3_emc_clk_set_rate(struct clk *c, unsigned long rate)
+{
+       int ret;
+       u32 div_value;
+       struct clk *p;
+
+       /* The tegra3 memory controller has an interlock with the clock
+        * block that allows memory shadowed registers to be updated,
+        * and then transfer them to the main registers at the same
+        * time as the clock update without glitches. During clock change
+        * operation both clock parent and divider may change simultaneously
+        * to achieve requested rate. */
+       p = tegra_emc_predict_parent(rate, &div_value);
+       div_value += 2;         /* emc has fractional DIV_U71 divider */
+
+       /* No matching rate in emc dfs table */
+       if (IS_ERR(p))
+               return PTR_ERR(p);
+
+       /* Table rate found, but need to relock source pll */
+       if (!p)
+               return tegra3_emc_relock_set_rate(c, clk_get_rate_locked(c),
+                                                 rate, rate * (div_value / 2));
+
+       if (p == c->parent) {
+               if (div_value == c->div)
+                       return 0;
+       } else if (c->refcnt)
+               clk_enable(p);
+
+       ret = tegra_emc_set_rate(rate);
+       if (ret < 0)
+               return ret;
+
+       if (p != c->parent) {
+               if(c->refcnt && c->parent)
+                       clk_disable(c->parent);
+               clk_reparent(c, p);
+       }
+       c->div = div_value;
+       c->mul = 2;
+       return 0;
+}
+
+static struct clk_ops tegra_emc_clk_ops = {
+       .init                   = &tegra3_emc_clk_init,
+       .enable                 = &tegra3_periph_clk_enable,
+       .disable                = &tegra3_periph_clk_disable,
+       .set_rate               = &tegra3_emc_clk_set_rate,
+       .round_rate             = &tegra3_emc_clk_round_rate,
+       .reset                  = &tegra3_periph_clk_reset,
+       .shared_bus_update      = &tegra3_clk_shared_bus_update,
+};
+
+/* Clock doubler ops (non-atomic shared register access) */
+static DEFINE_SPINLOCK(doubler_lock);
+
+static void tegra3_clk_double_init(struct clk *c)
+{
+       u32 val = clk_readl(c->reg);
+       c->mul = val & (0x1 << c->reg_shift) ? 1 : 2;
+       c->div = 1;
+       c->state = ON;
+       if (!(clk_readl(PERIPH_CLK_TO_ENB_REG(c)) & PERIPH_CLK_TO_BIT(c)))
+               c->state = OFF;
+};
+
+static int tegra3_clk_double_set_rate(struct clk *c, unsigned long rate)
+{
+       u32 val;
+       unsigned long parent_rate = clk_get_rate(c->parent);
+       unsigned long flags;
+
+       if (rate == parent_rate) {
+               spin_lock_irqsave(&doubler_lock, flags);
+               val = clk_readl(c->reg) | (0x1 << c->reg_shift);
+               clk_writel(val, c->reg);
+               c->mul = 1;
+               c->div = 1;
+               spin_unlock_irqrestore(&doubler_lock, flags);
+               return 0;
+       } else if (rate == 2 * parent_rate) {
+               spin_lock_irqsave(&doubler_lock, flags);
+               val = clk_readl(c->reg) & (~(0x1 << c->reg_shift));
+               clk_writel(val, c->reg);
+               c->mul = 2;
+               c->div = 1;
+               spin_unlock_irqrestore(&doubler_lock, flags);
+               return 0;
+       }
+       return -EINVAL;
+}
+
+static struct clk_ops tegra_clk_double_ops = {
+       .init                   = &tegra3_clk_double_init,
+       .enable                 = &tegra3_periph_clk_enable,
+       .disable                = &tegra3_periph_clk_disable,
+       .set_rate               = &tegra3_clk_double_set_rate,
+};
+
+/* Audio sync clock ops */
+static int tegra3_sync_source_set_rate(struct clk *c, unsigned long rate)
+{
+       c->rate = rate;
+       return 0;
+}
+
+static struct clk_ops tegra_sync_source_ops = {
+       .set_rate               = &tegra3_sync_source_set_rate,
+};
+
+static void tegra3_audio_sync_clk_init(struct clk *c)
+{
+       int source;
+       const struct clk_mux_sel *sel;
+       u32 val = clk_readl(c->reg);
+       c->state = (val & AUDIO_SYNC_DISABLE_BIT) ? OFF : ON;
+       source = val & AUDIO_SYNC_SOURCE_MASK;
+       for (sel = c->inputs; sel->input != NULL; sel++)
+               if (sel->value == source)
+                       break;
+       BUG_ON(sel->input == NULL);
+       c->parent = sel->input;
+}
+
+static int tegra3_audio_sync_clk_enable(struct clk *c)
+{
+       u32 val = clk_readl(c->reg);
+       clk_writel((val & (~AUDIO_SYNC_DISABLE_BIT)), c->reg);
+       return 0;
+}
+
+static void tegra3_audio_sync_clk_disable(struct clk *c)
+{
+       u32 val = clk_readl(c->reg);
+       clk_writel((val | AUDIO_SYNC_DISABLE_BIT), c->reg);
+}
+
+static int tegra3_audio_sync_clk_set_parent(struct clk *c, struct clk *p)
+{
+       u32 val;
+       const struct clk_mux_sel *sel;
+       for (sel = c->inputs; sel->input != NULL; sel++) {
+               if (sel->input == p) {
+                       val = clk_readl(c->reg);
+                       val &= ~AUDIO_SYNC_SOURCE_MASK;
+                       val |= sel->value;
+
+                       if (c->refcnt)
+                               clk_enable(p);
+
+                       clk_writel(val, c->reg);
+
+                       if (c->refcnt && c->parent)
+                               clk_disable(c->parent);
+
+                       clk_reparent(c, p);
+                       return 0;
+               }
+       }
+
+       return -EINVAL;
+}
+
+static struct clk_ops tegra_audio_sync_clk_ops = {
+       .init       = tegra3_audio_sync_clk_init,
+       .enable     = tegra3_audio_sync_clk_enable,
+       .disable    = tegra3_audio_sync_clk_disable,
+       .set_parent = tegra3_audio_sync_clk_set_parent,
+};
+
+/* cml0 (pcie), and cml1 (sata) clock ops (non-atomic shared register access) */
+static DEFINE_SPINLOCK(cml_lock);
+
+static void tegra3_cml_clk_init(struct clk *c)
+{
+       u32 val = clk_readl(c->reg);
+       c->state = val & (0x1 << c->u.periph.clk_num) ? ON : OFF;
+}
+
+static int tegra3_cml_clk_enable(struct clk *c)
+{
+       u32 val;
+       unsigned long flags;
+
+       spin_lock_irqsave(&cml_lock, flags);
+       val = clk_readl(c->reg);
+       val |= (0x1 << c->u.periph.clk_num);
+       clk_writel(val, c->reg);
+       spin_unlock_irqrestore(&cml_lock, flags);
+       return 0;
+}
+
+static void tegra3_cml_clk_disable(struct clk *c)
+{
+       u32 val;
+       unsigned long flags;
+
+       spin_lock_irqsave(&cml_lock, flags);
+       val = clk_readl(c->reg);
+       val &= ~(0x1 << c->u.periph.clk_num);
+       clk_writel(val, c->reg);
+       spin_unlock_irqrestore(&cml_lock, flags);
+}
+
+static struct clk_ops tegra_cml_clk_ops = {
+       .init                   = &tegra3_cml_clk_init,
+       .enable                 = &tegra3_cml_clk_enable,
+       .disable                = &tegra3_cml_clk_disable,
+};
+
+
+/* cbus ops */
+/*
+ * Some clocks require dynamic re-locking of source PLL in order to
+ * achieve frequency scaling granularity that matches characterized
+ * core voltage steps. The cbus clock creates a shared bus that
+ * provides a virtual root for such clocks to hide and synchronize
+ * parent PLL re-locking as well as backup operations.
+*/
+
+static void tegra3_clk_cbus_init(struct clk *c)
+{
+       c->state = OFF;
+       c->set = true;
+       c->shared_bus_backup.bus_rate =
+               clk_get_rate(c->shared_bus_backup.input) /
+               c->shared_bus_backup.value;
+}
+
+static int tegra3_clk_cbus_enable(struct clk *c)
+{
+       return 0;
+}
+
+static long tegra3_clk_cbus_round_rate(struct clk *c, unsigned long rate)
+{
+       int i;
+
+       if (!c->dvfs)
+               return rate;
+
+       /* update min now, since no dvfs table was available during init
+          (skip placeholder entries set to 1 kHz) */
+       if (!c->min_rate) {
+               for (i = 0; i < (c->dvfs->num_freqs - 1); i++) {
+                       if (c->dvfs->freqs[i] > 1 * c->dvfs->freqs_mult) {
+                               c->min_rate = c->dvfs->freqs[i];
+                               break;
+                       }
+               }
+               BUG_ON(!c->min_rate);
+       }
+       rate = max(rate, c->min_rate);
+
+       for (i = 0; i < (c->dvfs->num_freqs - 1); i++) {
+               unsigned long f = c->dvfs->freqs[i];
+               if (f >= rate)
+                       break;
+       }
+       return c->dvfs->freqs[i];
+}
+
+static int cbus_switch_one(struct clk *c, struct clk *p, u32 div, bool abort)
+{
+       int ret = 0;
+
+       /* set new divider if it is bigger than the current one */
+       if (c->div < c->mul * div) {
+               ret = clk_set_div(c, div);
+               if (ret) {
+                       pr_err("%s: failed to set %s clock divider %u: %d\n",
+                              __func__, c->name, div, ret);
+                       if (abort)
+                               return ret;
+               }
+       }
+
+       ret = clk_set_parent(c, p);
+       if (ret) {
+               pr_err("%s: failed to set %s clock parent %s: %d\n",
+                      __func__, c->name, p->name, ret);
+               if (abort)
+                       return ret;
+       }
+
+       /* set new divider if it is smaller than the current one */
+       if (c->div > c->mul * div) {
+               ret = clk_set_div(c, div);
+               if (ret)
+                       pr_err("%s: failed to set %s clock divider %u: %d\n",
+                              __func__, c->name, div, ret);
+       }
+
+       return ret;
+}
+
+static int cbus_backup(struct clk *c)
+{
+       int ret;
+       struct clk *user;
+
+       list_for_each_entry(user, &c->shared_bus_list,
+                       u.shared_bus_user.node) {
+               bool enabled = user->u.shared_bus_user.client &&
+                       (user->u.shared_bus_user.enabled ||
+                       user->u.shared_bus_user.client->refcnt);
+               if (enabled) {
+                       ret = cbus_switch_one(user->u.shared_bus_user.client,
+                                             c->shared_bus_backup.input,
+                                             c->shared_bus_backup.value *
+                                             user->div, true);
+                       if (ret)
+                               return ret;
+               }
+       }
+       return 0;
+}
+
+static void cbus_restore(struct clk *c)
+{
+       struct clk *user;
+
+       list_for_each_entry(user, &c->shared_bus_list,
+                       u.shared_bus_user.node) {
+               bool back = user->u.shared_bus_user.client && (c->parent !=
+                       user->u.shared_bus_user.client->parent);
+               if (back)
+                       cbus_switch_one(user->u.shared_bus_user.client,
+                                       c->parent, c->div * user->div, false);
+       }
+}
+
+static int tegra3_clk_cbus_set_rate(struct clk *c, unsigned long rate)
+{
+       int ret;
+
+       if (rate == 0)
+               return 0;
+
+       ret = clk_enable(c->parent);
+       if (ret) {
+               pr_err("%s: failed to enable %s clock: %d\n",
+                      __func__, c->name, ret);
+               return ret;
+       }
+
+       ret = cbus_backup(c);
+       if (ret)
+               goto out;
+
+       ret = clk_set_rate(c->parent, rate * c->div);
+       if (ret) {
+               pr_err("%s: failed to set %s clock rate %lu: %d\n",
+                      __func__, c->name, rate, ret);
+               goto out;
+       }
+
+       cbus_restore(c);
+
+out:
+       clk_disable(c->parent);
+       return ret;
+}
+
+static struct clk_ops tegra_clk_cbus_ops = {
+       .init = tegra3_clk_cbus_init,
+       .enable = tegra3_clk_cbus_enable,
+       .set_rate = tegra3_clk_cbus_set_rate,
+       .round_rate = tegra3_clk_cbus_round_rate,
+       .shared_bus_update = tegra3_clk_shared_bus_update,
+};
+
+/* shared bus ops */
+/*
+ * Some clocks may have multiple downstream users that need to request a
+ * higher clock rate.  Shared bus clocks provide a unique shared_bus_user
+ * clock to each user.  The frequency of the bus is set to the highest
+ * enabled shared_bus_user clock, with a minimum value set by the
+ * shared bus.
+ */
+
+static noinline int shared_bus_set_rate(struct clk *bus, unsigned long rate,
+                                       unsigned long old_rate)
+{
+       int ret, mv, old_mv;
+       unsigned long bridge_rate = emc_bridge->u.shared_bus_user.rate;
+
+       /* If bridge is not needed (LPDDR2) just set bus rate */
+       if (tegra_emc_get_dram_type() == DRAM_TYPE_LPDDR2)
+               return clk_set_rate_locked(bus, rate);
+
+       mv = tegra_dvfs_predict_millivolts(bus, rate);
+       old_mv = tegra_dvfs_predict_millivolts(bus, old_rate);
+       if (IS_ERR_VALUE(mv) || IS_ERR_VALUE(old_mv)) {
+               pr_err("%s: Failed to predict %s voltage for %lu => %lu\n",
+                      __func__, bus->name, old_rate, rate);
+               return -EINVAL;
+       }
+
+       /* emc bus: set bridge rate as intermediate step when crossing
+        * bridge threshold in any direction
+        */
+       if (bus->flags & PERIPH_EMC_ENB) {
+               if (((mv > TEGRA_EMC_BRIDGE_MVOLTS_MIN) &&
+                    (old_rate < bridge_rate)) ||
+                   ((old_mv > TEGRA_EMC_BRIDGE_MVOLTS_MIN) &&
+                    (rate < bridge_rate))) {
+                       ret = clk_set_rate_locked(bus, bridge_rate);
+                       if (ret) {
+                               pr_err("%s: Failed to set emc bridge rate %lu\n",
+                                       __func__, bridge_rate);
+                               return ret;
+                       }
+               }
+               return clk_set_rate_locked(bus, rate);
+       }
+
+       /* sbus and cbus: enable/disable emc bridge user when crossing voltage
+        * threshold up/down respectively; hence, emc rate is kept above the
+        * bridge rate as long as any sbus or cbus user requires high voltage
+        */
+       if ((mv > TEGRA_EMC_BRIDGE_MVOLTS_MIN) &&
+           (old_mv <= TEGRA_EMC_BRIDGE_MVOLTS_MIN)) {
+               ret = clk_enable(emc_bridge);
+               if (ret) {
+                       pr_err("%s: Failed to enable emc bridge\n", __func__);
+                       return ret;
+               }
+       }
+
+       ret = clk_set_rate_locked(bus, rate);
+       if (ret)
+               return ret;
+
+       if ((mv <= TEGRA_EMC_BRIDGE_MVOLTS_MIN) &&
+           (old_mv > TEGRA_EMC_BRIDGE_MVOLTS_MIN))
+               clk_disable(emc_bridge);
+
+       return 0;
+}
+
+static int tegra3_clk_shared_bus_update(struct clk *bus)
+{
+       struct clk *c;
+       unsigned long old_rate;
+       unsigned long rate = bus->min_rate;
+       unsigned long bw = 0;
+       unsigned long ceiling = bus->max_rate;
+       u8 emc_bw_efficiency = tegra_emc_bw_efficiency_boost;
+
+       if (detach_shared_bus)
+               return 0;
+
+       list_for_each_entry(c, &bus->shared_bus_list,
+                       u.shared_bus_user.node) {
+               /* Ignore requests from disabled floor and bw users, and from
+                * auto-users riding the bus. Always honor ceiling users, even
+                * if they are disabled - we do not want to keep enabled parent
+                * bus just because ceiling is set.
+                */
+               if (c->u.shared_bus_user.enabled ||
+                   (c->u.shared_bus_user.mode == SHARED_CEILING)) {
+                       if (!strcmp(c->name, "3d.emc"))
+                               emc_bw_efficiency = tegra_emc_bw_efficiency;
+
+                       switch (c->u.shared_bus_user.mode) {
+                       case SHARED_BW:
+                               if (bw < bus->max_rate)
+                                       bw += c->u.shared_bus_user.rate;
+                               break;
+                       case SHARED_CEILING:
+                               ceiling = min(c->u.shared_bus_user.rate,
+                                              ceiling);
+                               break;
+                       case SHARED_AUTO:
+                       case SHARED_FLOOR:
+                       default:
+                               rate = max(c->u.shared_bus_user.rate, rate);
+                       }
+               }
+       }
+
+       if (bw) {
+               if (bus->flags & PERIPH_EMC_ENB) {
+                       bw = emc_bw_efficiency ?
+                               (bw / emc_bw_efficiency) : bus->max_rate;
+                       bw = (bw < bus->max_rate / 100) ?
+                               (bw * 100) : bus->max_rate;
+               }
+               bw = clk_round_rate_locked(bus, bw);
+       }
+       rate = min(max(rate, bw), ceiling);
+
+       old_rate = clk_get_rate_locked(bus);
+       if (rate == old_rate)
+               return 0;
+
+       return shared_bus_set_rate(bus, rate, old_rate);
+};
+
+static void tegra_clk_shared_bus_init(struct clk *c)
+{
+       c->max_rate = c->parent->max_rate;
+       c->u.shared_bus_user.rate = c->parent->max_rate;
+       c->state = OFF;
+       c->set = true;
+
+       if (c->u.shared_bus_user.client_id) {
+               c->u.shared_bus_user.client =
+                       tegra_get_clock_by_name(c->u.shared_bus_user.client_id);
+               if (!c->u.shared_bus_user.client) {
+                       pr_err("%s: could not find clk %s\n", __func__,
+                              c->u.shared_bus_user.client_id);
+                       return;
+               }
+               c->u.shared_bus_user.client->flags |=
+                       c->parent->flags & PERIPH_ON_CBUS;
+               c->flags |= c->parent->flags & PERIPH_ON_CBUS;
+               c->div = c->u.shared_bus_user.client_div ? : 1;
+               c->mul = 1;
+       }
+
+       list_add_tail(&c->u.shared_bus_user.node,
+               &c->parent->shared_bus_list);
+}
+
+static int tegra_clk_shared_bus_set_rate(struct clk *c, unsigned long rate)
+{
+       c->u.shared_bus_user.rate = rate;
+       tegra_clk_shared_bus_update(c->parent);
+       return 0;
+}
+
+static long tegra_clk_shared_bus_round_rate(struct clk *c, unsigned long rate)
+{
+       /* auto user follow others, by itself it run at minimum bus rate */
+       if (c->u.shared_bus_user.mode == SHARED_AUTO)
+               rate = 0;
+
+       /* BW users should not be rounded until aggregated */
+       if (c->u.shared_bus_user.mode == SHARED_BW)
+               return rate;
+
+       return clk_round_rate(c->parent, rate);
+}
+
+static int tegra_clk_shared_bus_enable(struct clk *c)
+{
+       c->u.shared_bus_user.enabled = true;
+       tegra_clk_shared_bus_update(c->parent);
+       if (c->u.shared_bus_user.client) {
+               return clk_enable(c->u.shared_bus_user.client);
+       }
+       return 0;
+}
+
+static void tegra_clk_shared_bus_disable(struct clk *c)
+{