diff options
80 files changed, 12612 insertions, 283 deletions
diff --git a/arch/arm/configs/cyanogenmod_d710_defconfig b/arch/arm/configs/cyanogenmod_d710_defconfig new file mode 100644 index 0000000..a2d394d --- /dev/null +++ b/arch/arm/configs/cyanogenmod_d710_defconfig @@ -0,0 +1,3151 @@ +# +# Automatically generated make config: don't edit +# Linux/arm 3.0.64 Kernel Configuration +# +CONFIG_ARM=y +CONFIG_HAVE_PWM=y +CONFIG_SYS_SUPPORTS_APM_EMULATION=y +CONFIG_GENERIC_GPIO=y +# CONFIG_ARCH_USES_GETTIMEOFFSET is not set +CONFIG_GENERIC_CLOCKEVENTS=y +CONFIG_GENERIC_CLOCKEVENTS_BROADCAST=y +CONFIG_KTIME_SCALAR=y +CONFIG_HAVE_PROC_CPU=y +CONFIG_NO_IOPORT=y +CONFIG_STACKTRACE_SUPPORT=y +CONFIG_HAVE_LATENCYTOP_SUPPORT=y +CONFIG_LOCKDEP_SUPPORT=y +CONFIG_TRACE_IRQFLAGS_SUPPORT=y +CONFIG_HARDIRQS_SW_RESEND=y +CONFIG_GENERIC_IRQ_PROBE=y +CONFIG_GENERIC_LOCKBREAK=y +CONFIG_RWSEM_GENERIC_SPINLOCK=y +CONFIG_ARCH_HAS_CPUFREQ=y +CONFIG_ARCH_HAS_CPU_IDLE_WAIT=y +CONFIG_GENERIC_HWEIGHT=y +CONFIG_GENERIC_CALIBRATE_DELAY=y +CONFIG_NEED_DMA_MAP_STATE=y +CONFIG_VECTORS_BASE=0xffff0000 +CONFIG_ARM_PATCH_PHYS_VIRT=y +CONFIG_ARCH_HIBERNATION_POSSIBLE=y +CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config" +CONFIG_HAVE_IRQ_WORK=y + +# +# General setup +# +CONFIG_EXPERIMENTAL=y +CONFIG_INIT_ENV_ARG_LIMIT=32 +CONFIG_CROSS_COMPILE="" +CONFIG_LOCALVERSION="-CM" +CONFIG_LOCALVERSION_AUTO=y +CONFIG_HAVE_KERNEL_GZIP=y +CONFIG_HAVE_KERNEL_LZMA=y +CONFIG_HAVE_KERNEL_LZO=y +# CONFIG_KERNEL_GZIP is not set +CONFIG_KERNEL_LZMA=y +# CONFIG_KERNEL_LZO is not set +CONFIG_DEFAULT_HOSTNAME="(none)" +# CONFIG_SWAP is not set +CONFIG_SYSVIPC=y +CONFIG_SYSVIPC_SYSCTL=y +# CONFIG_POSIX_MQUEUE is not set +# CONFIG_BSD_PROCESS_ACCT is not set +# CONFIG_FHANDLE is not set +# CONFIG_TASKSTATS is not set +# CONFIG_AUDIT is not set +CONFIG_HAVE_GENERIC_HARDIRQS=y + +# +# IRQ subsystem +# +CONFIG_GENERIC_HARDIRQS=y +CONFIG_HAVE_SPARSE_IRQ=y +CONFIG_GENERIC_IRQ_SHOW=y +CONFIG_GENERIC_IRQ_CHIP=y +# CONFIG_SPARSE_IRQ is not set + +# +# RCU Subsystem +# +CONFIG_TREE_PREEMPT_RCU=y +CONFIG_PREEMPT_RCU=y +# CONFIG_RCU_TRACE is not set +CONFIG_RCU_FANOUT=32 +# CONFIG_RCU_FANOUT_EXACT is not set +# CONFIG_TREE_RCU_TRACE is not set +# CONFIG_RCU_BOOST is not set +# CONFIG_IKCONFIG is not set +CONFIG_LOG_BUF_SHIFT=20 +CONFIG_CGROUPS=y +CONFIG_CGROUP_DEBUG=y +CONFIG_CGROUP_FREEZER=y +# CONFIG_CGROUP_DEVICE is not set +# CONFIG_CPUSETS is not set +CONFIG_CGROUP_CPUACCT=y +CONFIG_RESOURCE_COUNTERS=y +# CONFIG_CGROUP_MEM_RES_CTLR is not set +CONFIG_CGROUP_SCHED=y +CONFIG_FAIR_GROUP_SCHED=y +CONFIG_RT_GROUP_SCHED=y +# CONFIG_BLK_CGROUP is not set +# CONFIG_NAMESPACES is not set +# CONFIG_SCHED_AUTOGROUP is not set +# CONFIG_SYSFS_DEPRECATED is not set +# CONFIG_RELAY is not set +CONFIG_BLK_DEV_INITRD=y +CONFIG_INITRAMFS_SOURCE="source/usr/d710_initramfs.list" +CONFIG_INITRAMFS_ROOT_UID=0 +CONFIG_INITRAMFS_ROOT_GID=0 +CONFIG_RD_GZIP=y +# CONFIG_RD_BZIP2 is not set +# CONFIG_RD_LZMA is not set +# CONFIG_RD_XZ is not set +# CONFIG_RD_LZO is not set +CONFIG_INITRAMFS_COMPRESSION_NONE=y +# CONFIG_INITRAMFS_COMPRESSION_GZIP is not set +# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set +# CONFIG_CC_CHECK_WARNING_STRICTLY is not set +CONFIG_SYSCTL=y +CONFIG_ANON_INODES=y +CONFIG_PANIC_TIMEOUT=1 +CONFIG_EXPERT=y +CONFIG_UID16=y +CONFIG_SYSCTL_SYSCALL=y +CONFIG_KALLSYMS=y +CONFIG_KALLSYMS_ALL=y +CONFIG_HOTPLUG=y +CONFIG_PRINTK=y +CONFIG_BUG=y +CONFIG_ELF_CORE=y +CONFIG_BASE_FULL=y +CONFIG_FUTEX=y +CONFIG_EPOLL=y +CONFIG_SIGNALFD=y +CONFIG_TIMERFD=y +CONFIG_EVENTFD=y +CONFIG_SHMEM=y +CONFIG_ASHMEM=y +# CONFIG_AIO is not set +CONFIG_EMBEDDED=y +CONFIG_HAVE_PERF_EVENTS=y +CONFIG_PERF_USE_VMALLOC=y + +# +# Kernel Performance Events And Counters +# +# CONFIG_PERF_EVENTS is not set +# CONFIG_PERF_COUNTERS is not set +CONFIG_VM_EVENT_COUNTERS=y +# CONFIG_SLUB_DEBUG is not set +CONFIG_COMPAT_BRK=y +# CONFIG_SLAB is not set +CONFIG_SLUB=y +# CONFIG_SLOB is not set +# CONFIG_PROFILING is not set +CONFIG_HAVE_OPROFILE=y +# CONFIG_KPROBES is not set +CONFIG_HAVE_KPROBES=y +CONFIG_HAVE_KRETPROBES=y +CONFIG_USE_GENERIC_SMP_HELPERS=y +CONFIG_HAVE_DMA_CONTIGUOUS=y +CONFIG_HAVE_REGS_AND_STACK_ACCESS_API=y +CONFIG_HAVE_CLK=y +CONFIG_HAVE_DMA_API_DEBUG=y + +# +# GCOV-based kernel profiling +# +# CONFIG_GCOV_KERNEL is not set +CONFIG_HAVE_GENERIC_DMA_COHERENT=y +CONFIG_RT_MUTEXES=y +CONFIG_BASE_SMALL=0 +CONFIG_MODULES=y +CONFIG_MODULE_FORCE_LOAD=y +CONFIG_MODULE_UNLOAD=y +CONFIG_MODULE_FORCE_UNLOAD=y +# CONFIG_MODVERSIONS is not set +# CONFIG_MODULE_SRCVERSION_ALL is not set +CONFIG_STOP_MACHINE=y +CONFIG_BLOCK=y +CONFIG_LBDAF=y +# CONFIG_BLK_DEV_BSG is not set +# CONFIG_BLK_DEV_INTEGRITY is not set + +# +# IO Schedulers +# +CONFIG_IOSCHED_NOOP=y +CONFIG_IOSCHED_DEADLINE=y +CONFIG_IOSCHED_CFQ=y +CONFIG_IOSCHED_ROW=y +CONFIG_IOSCHED_SIO=y +# CONFIG_DEFAULT_DEADLINE is not set +CONFIG_DEFAULT_CFQ=y +# CONFIG_DEFAULT_ROW is not set +# CONFIG_DEFAULT_SIO is not set +# CONFIG_DEFAULT_NOOP is not set +CONFIG_DEFAULT_IOSCHED="cfq" +# CONFIG_INLINE_SPIN_TRYLOCK is not set +# CONFIG_INLINE_SPIN_TRYLOCK_BH is not set +# CONFIG_INLINE_SPIN_LOCK is not set +# CONFIG_INLINE_SPIN_LOCK_BH is not set +# CONFIG_INLINE_SPIN_LOCK_IRQ is not set +# CONFIG_INLINE_SPIN_LOCK_IRQSAVE is not set +# CONFIG_INLINE_SPIN_UNLOCK is not set +# CONFIG_INLINE_SPIN_UNLOCK_BH is not set +# CONFIG_INLINE_SPIN_UNLOCK_IRQ is not set +# CONFIG_INLINE_SPIN_UNLOCK_IRQRESTORE is not set +# CONFIG_INLINE_READ_TRYLOCK is not set +# CONFIG_INLINE_READ_LOCK is not set +# CONFIG_INLINE_READ_LOCK_BH is not set +# CONFIG_INLINE_READ_LOCK_IRQ is not set +# CONFIG_INLINE_READ_LOCK_IRQSAVE is not set +# CONFIG_INLINE_READ_UNLOCK is not set +# CONFIG_INLINE_READ_UNLOCK_BH is not set +# CONFIG_INLINE_READ_UNLOCK_IRQ is not set +# CONFIG_INLINE_READ_UNLOCK_IRQRESTORE is not set +# CONFIG_INLINE_WRITE_TRYLOCK is not set +# CONFIG_INLINE_WRITE_LOCK is not set +# CONFIG_INLINE_WRITE_LOCK_BH is not set +# CONFIG_INLINE_WRITE_LOCK_IRQ is not set +# CONFIG_INLINE_WRITE_LOCK_IRQSAVE is not set +# CONFIG_INLINE_WRITE_UNLOCK is not set +# CONFIG_INLINE_WRITE_UNLOCK_BH is not set +# CONFIG_INLINE_WRITE_UNLOCK_IRQ is not set +# CONFIG_INLINE_WRITE_UNLOCK_IRQRESTORE is not set +CONFIG_MUTEX_SPIN_ON_OWNER=y +CONFIG_FREEZER=y + +# +# System Type +# +CONFIG_MMU=y +# CONFIG_ARCH_INTEGRATOR is not set +# CONFIG_ARCH_REALVIEW is not set +# CONFIG_ARCH_VERSATILE is not set +# CONFIG_ARCH_VEXPRESS is not set +# CONFIG_ARCH_AT91 is not set +# CONFIG_ARCH_BCMRING is not set +# CONFIG_ARCH_CLPS711X is not set +# CONFIG_ARCH_CNS3XXX is not set +# CONFIG_ARCH_GEMINI is not set +# CONFIG_ARCH_EBSA110 is not set +# CONFIG_ARCH_EP93XX is not set +# CONFIG_ARCH_FOOTBRIDGE is not set +# CONFIG_ARCH_MXC is not set +# CONFIG_ARCH_MXS is not set +# CONFIG_ARCH_NETX is not set +# CONFIG_ARCH_H720X is not set +# CONFIG_ARCH_IOP13XX is not set +# CONFIG_ARCH_IOP32X is not set +# CONFIG_ARCH_IOP33X is not set +# CONFIG_ARCH_IXP23XX is not set +# CONFIG_ARCH_IXP2000 is not set +# CONFIG_ARCH_IXP4XX is not set +# CONFIG_ARCH_DOVE is not set +# CONFIG_ARCH_KIRKWOOD is not set +# CONFIG_ARCH_LOKI is not set +# CONFIG_ARCH_LPC32XX is not set +# CONFIG_ARCH_MV78XX0 is not set +# CONFIG_ARCH_ORION5X is not set +# CONFIG_ARCH_MMP is not set +# CONFIG_ARCH_KS8695 is not set +# CONFIG_ARCH_W90X900 is not set +# CONFIG_ARCH_NUC93X is not set +# CONFIG_ARCH_TEGRA is not set +# CONFIG_ARCH_PNX4008 is not set +# CONFIG_ARCH_PXA is not set +# CONFIG_ARCH_MSM is not set +# CONFIG_ARCH_SHMOBILE is not set +# CONFIG_ARCH_RPC is not set +# CONFIG_ARCH_SA1100 is not set +# CONFIG_ARCH_S3C2410 is not set +# CONFIG_ARCH_S3C64XX is not set +# CONFIG_ARCH_S5P64X0 is not set +# CONFIG_ARCH_S5PC100 is not set +# CONFIG_ARCH_S5PV210 is not set +CONFIG_ARCH_EXYNOS=y +# CONFIG_ARCH_SHARK is not set +# CONFIG_ARCH_TCC_926 is not set +# CONFIG_ARCH_U300 is not set +# CONFIG_ARCH_U8500 is not set +# CONFIG_ARCH_NOMADIK is not set +# CONFIG_ARCH_DAVINCI is not set +# CONFIG_ARCH_OMAP is not set +# CONFIG_PLAT_SPEAR is not set +# CONFIG_ARCH_VT8500 is not set +# CONFIG_GPIO_PCA953X is not set +# CONFIG_KEYBOARD_GPIO_POLLED is not set +CONFIG_PLAT_SAMSUNG=y + +# +# Base Address for SFR mapping +# +CONFIG_S3C_ADDR_BASE=0xFB000000 + +# +# Boot options +# +# CONFIG_S3C_BOOT_ERROR_RESET is not set +CONFIG_S3C_BOOT_UART_FORCE_FIFO=y +CONFIG_S3C_LOWLEVEL_UART_PORT=2 +CONFIG_SAMSUNG_CLKSRC=y +CONFIG_SAMSUNG_IRQ_VIC_TIMER=y +CONFIG_SAMSUNG_IRQ_UART=y +CONFIG_SAMSUNG_GPIOLIB_4BIT=y +CONFIG_S3C_GPIO_CFG_S3C24XX=y +CONFIG_S3C_GPIO_CFG_S3C64XX=y +CONFIG_S3C_GPIO_PULL_UPDOWN=y +CONFIG_S5P_GPIO_DRVSTR=y +CONFIG_SAMSUNG_GPIO_EXTRA=0 +CONFIG_S3C_GPIO_SPACE=0 +CONFIG_S3C_GPIO_TRACK=y +CONFIG_S3C_ADC=y +CONFIG_S3C_DEV_ADC=y +# CONFIG_S3C_DEV_ADC1 is not set +CONFIG_S3C_DEV_HSMMC2=y +CONFIG_S3C_DEV_HSMMC3=y +CONFIG_EXYNOS4_DEV_MSHC=y +CONFIG_S3C_DEV_I2C1=y +CONFIG_S3C_DEV_I2C3=y +CONFIG_S3C_DEV_I2C4=y +CONFIG_S3C_DEV_I2C5=y +CONFIG_S3C_DEV_I2C6=y +CONFIG_S3C_DEV_I2C7=y +CONFIG_S3C_DEV_I2C8_EMUL=y +CONFIG_S3C_DEV_I2C9_EMUL=y +CONFIG_S3C_DEV_I2C11_EMUL=y +# CONFIG_S3C_DEV_I2C14_EMUL is not set +CONFIG_S3C_DEV_I2C16_EMUL=y +CONFIG_S3C_DEV_I2C17_EMUL=y +CONFIG_S3C_DEV_WDT=y +CONFIG_S3C_DEV_RTC=y +CONFIG_SAMSUNG_DEV_ADC=y +CONFIG_SAMSUNG_DEV_TS=y +CONFIG_SAMSUNG_DEV_TS1=y +CONFIG_S3C24XX_PWM=y +CONFIG_S3C_PL330_DMA=y +# CONFIG_DMA_M2M_TEST is not set + +# +# Power management +# +# CONFIG_SAMSUNG_PM_DEBUG is not set +# CONFIG_SAMSUNG_PM_CHECK is not set + +# +# Power Domain +# +CONFIG_SAMSUNG_PD=y +CONFIG_PLAT_S5P=y +CONFIG_S5P_GPIO_INT=y +CONFIG_S5P_SYSTEM_MMU=y +# CONFIG_S5P_SYSTEM_MMU_REFCOUNT is not set +# CONFIG_S5P_SYSTEM_MMU_DEBUG is not set +CONFIG_IOVMM=y +CONFIG_IOMMU_EXYNOS4_API=y +CONFIG_S3C_DEV_FIMC=y +CONFIG_S5P_DEV_MFC=y +CONFIG_S5P_DEV_FIMD0=y +CONFIG_S5P_DEV_TVOUT=y +CONFIG_S5P_DEV_FIMG2D=y +CONFIG_S5P_DEV_CSIS=y +CONFIG_S5P_DEV_JPEG=y +CONFIG_S5P_DEV_USB_EHCI=y +CONFIG_S5P_DEV_FIMD_S5P=y +CONFIG_S5P_DEV_USBGADGET=y +CONFIG_S5P_MEM_CMA=y +# CONFIG_S5P_BTS is not set +# CONFIG_S3C_DEV_TSI is not set +CONFIG_ARCH_EXYNOS4=y +# CONFIG_ARCH_EXYNOS5 is not set +CONFIG_CPU_EXYNOS4210=y +# CONFIG_S5PV310_HI_ARMCLK_THAN_1_2GHZ is not set +CONFIG_EXYNOS4_PM=y +CONFIG_EXYNOS4_CPUIDLE=y +CONFIG_EXYNOS4_LOWPWR_IDLE=y +CONFIG_EXYNOS_MCT=y +CONFIG_EXYNOS4_SETUP_FIMD0=y +CONFIG_EXYNOS_DEV_PD=y +CONFIG_EXYNOS4_SETUP_I2C1=y +CONFIG_EXYNOS4_SETUP_I2C3=y +CONFIG_EXYNOS4_SETUP_I2C4=y +CONFIG_EXYNOS4_SETUP_I2C5=y +CONFIG_EXYNOS4_SETUP_I2C6=y +CONFIG_EXYNOS4_SETUP_I2C7=y +CONFIG_EXYNOS4_SETUP_MFC=y +CONFIG_EXYNOS4_SETUP_SDHCI=y +CONFIG_EXYNOS4_SETUP_SDHCI_GPIO=y +CONFIG_EXYNOS4_SETUP_MSHCI=y +CONFIG_EXYNOS4_SETUP_MSHCI_GPIO=y +CONFIG_EXYNOS4_SETUP_FIMC0=y +CONFIG_EXYNOS4_SETUP_FIMC1=y +CONFIG_EXYNOS4_SETUP_FIMC2=y +CONFIG_EXYNOS4_SETUP_FIMC3=y +CONFIG_EXYNOS4_SETUP_USB_PHY=y +CONFIG_EXYNOS4_SETUP_CSIS=y +CONFIG_EXYNOS4_SETUP_FB_S5P=y +CONFIG_EXYNOS4_SETUP_TVOUT=y +CONFIG_EXYNOS4_SETUP_THERMAL=y +# CONFIG_EXYNOS_SETUP_THERMAL is not set +# CONFIG_EXYNOS4_ENABLE_CLOCK_DOWN is not set +CONFIG_EXYNOS4_CPUFREQ=y +CONFIG_EXYNOS4210_1200MHZ_SUPPORT=y +# CONFIG_EXYNOS4210_1400MHZ_SUPPORT is not set + +# +# Support dynamic CPU Hotplug +# +CONFIG_EXYNOS_PM_HOTPLUG=y +CONFIG_STAND_ALONE_POLICY=y +# CONFIG_LEGACY_HOTPLUG_POLICY is not set +# CONFIG_WITH_DVFS_POLICY is not set +# CONFIG_DVFS_NR_RUNNING_POLICY is not set +# CONFIG_NR_RUNNING_POLICY is not set + +# +# Busfreq Model +# +CONFIG_BUSFREQ=y +# CONFIG_BUSFREQ_QOS is not set +# CONFIG_BUSFREQ_OPP is not set +# CONFIG_DISPFREQ_OPP is not set +# CONFIG_DEVFREQ_BUS is not set +# CONFIG_BUSFREQ_DEBUG is not set +# CONFIG_BUSFREQ_L2_160M is not set +CONFIG_SEC_THERMISTOR=y +# CONFIG_EXYNOS_SYSREG_PM is not set +# CONFIG_ANDROID_WIP is not set + +# +# EXYNOS4 Machines +# +# CONFIG_MACH_SMDKC210 is not set +# CONFIG_MACH_SMDKV310 is not set +# CONFIG_MACH_ARMLEX4210 is not set +# CONFIG_MACH_UNIVERSAL_C210 is not set +# CONFIG_MACH_NURI is not set +CONFIG_MACH_U1_NA_SPR=y +# CONFIG_MACH_U1_NA_USCC is not set +CONFIG_MACH_U1=y +CONFIG_MACH_U1_BD=y +# CONFIG_MACH_Q1_BD is not set +# CONFIG_TARGET_LOCALE_NAATT_TEMP is not set +# CONFIG_MACH_PX is not set +# CONFIG_PANEL_U1 is not set +CONFIG_PANEL_U1_NA_SPR=y +# CONFIG_TARGET_LOCALE_EUR is not set +# CONFIG_TARGET_LOCALE_LTN is not set +# CONFIG_TARGET_LOCALE_KOR is not set +# CONFIG_TARGET_LOCALE_P2EUR_TEMP is not set +# CONFIG_TARGET_LOCALE_P2TMO_TEMP is not set +CONFIG_TARGET_LOCALE_NA=y +# CONFIG_TARGET_LOCALE_EUR_U1_NFC is not set +# CONFIG_TARGET_LOCALE_NTT is not set +# CONFIG_TARGET_LOCALE_JPN is not set +# CONFIG_TARGET_LOCALE_CHN is not set +# CONFIG_TARGET_LOCALE_USA is not set +# CONFIG_MACH_SMDK4X12 is not set +# CONFIG_MACH_MIDAS is not set +# CONFIG_MIDAS_COMMON_BD is not set +# CONFIG_P4NOTE_00_BD is not set +# CONFIG_GC1_00_BD is not set +# CONFIG_T0_00_BD is not set +# CONFIG_T0_04_BD is not set +# CONFIG_IRON_BD is not set +# CONFIG_GRANDE_BD is not set +# CONFIG_WRITEBACK_ENABLED is not set +# CONFIG_EXYNOS_SOUND_PLATFORM_DATA is not set +# CONFIG_JACK_FET is not set +# CONFIG_JACK_GROUND_DET is not set +CONFIG_SAMSUNG_ANALOG_UART_SWITCH=1 +# CONFIG_EXYNOS5_DEV_BTS is not set + +# +# MMC/SD slot setup +# + +# +# SELECT SYNOPSYS CONTROLLER INTERFACE DRIVER +# +# CONFIG_EXYNOS4_MSHC_MPLL_40MHZ is not set +# CONFIG_EXYNOS4_MSHC_VPLL_46MHZ is not set +CONFIG_EXYNOS4_MSHC_EPLL_45MHZ=y + +# +# Use 8-bit bus width +# +CONFIG_EXYNOS4_MSHC_8BIT=y +# CONFIG_EXYNOS4_SDHCI_CH2_8BIT is not set + +# +# Use DDR +# +CONFIG_EXYNOS4_MSHC_DDR=y + +# +# Miscellaneous drivers +# +# CONFIG_WAKEUP_ASSIST is not set + +# +# Debugging Feature +# +CONFIG_SEC_DEBUG=y +CONFIG_SEC_DEBUG_SCHED_LOG=y +# CONFIG_SEC_DEBUG_SOFTIRQ_LOG is not set +CONFIG_SEC_DEBUG_SCHED_LOG_NONCACHED=y +# CONFIG_SEC_DEBUG_SEMAPHORE_LOG is not set +CONFIG_SEC_DEBUG_USER=y +# CONFIG_SEC_DEBUG_PM_TEMP is not set +# CONFIG_SEC_DEBUG_IRQ_EXIT_LOG is not set +# CONFIG_SEC_DEBUG_AUXILIARY_LOG is not set +# CONFIG_SEC_DEBUG_FUPLOAD_DUMP_MORE is not set +# CONFIG_SEC_DEBUG_UMP_ALLOC_FAIL is not set +# CONFIG_SEC_DEBUG_LIST_CORRUPTION is not set +# CONFIG_SEC_WATCHDOG_RESET is not set +CONFIG_SEC_LOG=y +CONFIG_SEC_LOG_NONCACHED=y +CONFIG_SEC_LOG_LAST_KMSG=y +CONFIG_EHCI_IRQ_DISTRIBUTION=y +# CONFIG_BT_CSR8811 is not set +CONFIG_BT_BCM4330=y +# CONFIG_BT_BCM4334 is not set +# CONFIG_BT_BCM43241 is not set +CONFIG_BT_MGMT=y + +# +# Qualcomm Modem Feature +# +# CONFIG_QC_MODEM is not set +# CONFIG_MSM_SUBSYSTEM_RESTART is not set +# CONFIG_QC_MODEM_MDM9X15 is not set +# CONFIG_MDM_HSIC_PM is not set +# CONFIG_EMI_ERROR_RECOVERY is not set +CONFIG_USB_CDFS_SUPPORT=y +CONFIG_SAMSUNG_PRODUCT_SHIP=y +# CONFIG_CORESIGHT_ETM is not set + +# +# Processor Type +# +CONFIG_CPU_V7=y +CONFIG_CPU_32v6K=y +CONFIG_CPU_32v7=y +CONFIG_CPU_ABRT_EV7=y +CONFIG_CPU_PABRT_V7=y +CONFIG_CPU_CACHE_V7=y +CONFIG_CPU_CACHE_VIPT=y +CONFIG_CPU_COPY_V6=y +CONFIG_CPU_TLB_V7=y +CONFIG_CPU_HAS_ASID=y +CONFIG_CPU_CP15=y +CONFIG_CPU_CP15_MMU=y + +# +# Processor Features +# +# CONFIG_ARM_TRUSTZONE is not set +CONFIG_ARM_THUMB=y +# CONFIG_ARM_THUMBEE is not set +CONFIG_SWP_EMULATE=y +# CONFIG_CPU_ICACHE_DISABLE is not set +# CONFIG_CPU_DCACHE_DISABLE is not set +# CONFIG_CPU_BPREDICT_DISABLE is not set +CONFIG_OUTER_CACHE=y +CONFIG_OUTER_CACHE_SYNC=y +CONFIG_CACHE_L2X0=y +CONFIG_CACHE_PL310=y +CONFIG_ARM_L1_CACHE_SHIFT=5 +CONFIG_ARM_DMA_MEM_BUFFERABLE=y +CONFIG_ARM_PLD_SIZE=32 +CONFIG_CPU_HAS_PMU=y +# CONFIG_ARM_ERRATA_430973 is not set +# CONFIG_ARM_ERRATA_458693 is not set +# CONFIG_ARM_ERRATA_460075 is not set +# CONFIG_ARM_ERRATA_742230 is not set +# CONFIG_ARM_ERRATA_742231 is not set +# CONFIG_PL310_ERRATA_588369 is not set +# CONFIG_ARM_ERRATA_720789 is not set +# CONFIG_ARM_ERRATA_720791 is not set +CONFIG_PL310_ERRATA_727915=y +CONFIG_ARM_ERRATA_743622=y +CONFIG_ARM_ERRATA_751472=y +CONFIG_ARM_ERRATA_753970=y +CONFIG_ARM_ERRATA_754322=y +# CONFIG_ARM_ERRATA_754327 is not set +# CONFIG_ARM_ERRATA_761320 is not set +# CONFIG_ARM_ERRATA_761171 is not set +# CONFIG_ARM_ERRATA_762974 is not set +# CONFIG_ARM_ERRATA_763722 is not set +CONFIG_ARM_ERRATA_764369=y +# CONFIG_PL310_ERRATA_769419 is not set +# CONFIG_ARM_ERRATA_775420 is not set +CONFIG_ARM_GIC=y +CONFIG_PL330=y +# CONFIG_FIQ_DEBUGGER is not set + +# +# Bus support +# +# CONFIG_PCI_SYSCALL is not set +# CONFIG_ARCH_SUPPORTS_MSI is not set +# CONFIG_PCCARD is not set + +# +# Kernel Features +# +CONFIG_TICK_ONESHOT=y +CONFIG_NO_HZ=y +CONFIG_HIGH_RES_TIMERS=y +CONFIG_GENERIC_CLOCKEVENTS_BUILD=y +CONFIG_SMP=y +CONFIG_SMP_ON_UP=y +CONFIG_HAVE_ARM_SCU=y +CONFIG_VMSPLIT_3G=y +# CONFIG_VMSPLIT_2G is not set +# CONFIG_VMSPLIT_1G is not set +CONFIG_PAGE_OFFSET=0xC0000000 +CONFIG_NR_CPUS=2 +CONFIG_HOTPLUG_CPU=y +CONFIG_LOCAL_TIMERS=y +# CONFIG_PREEMPT_NONE is not set +# CONFIG_PREEMPT_VOLUNTARY is not set +CONFIG_PREEMPT=y +CONFIG_HZ=200 +# CONFIG_THUMB2_KERNEL is not set +CONFIG_AEABI=y +CONFIG_OABI_COMPAT=y +# CONFIG_ARCH_SPARSEMEM_DEFAULT is not set +# CONFIG_ARCH_SELECT_MEMORY_MODEL is not set +CONFIG_HAVE_ARCH_PFN_VALID=y +CONFIG_ARCH_SKIP_SECONDARY_CALIBRATE=y +CONFIG_HIGHMEM=y +# CONFIG_HIGHPTE is not set +CONFIG_SELECT_MEMORY_MODEL=y +CONFIG_FLATMEM_MANUAL=y +CONFIG_FLATMEM=y +CONFIG_FLAT_NODE_MEM_MAP=y +CONFIG_HAVE_MEMBLOCK=y +CONFIG_PAGEFLAGS_EXTENDED=y +CONFIG_SPLIT_PTLOCK_CPUS=4 +# CONFIG_COMPACTION is not set +# CONFIG_PHYS_ADDR_T_64BIT is not set +CONFIG_ZONE_DMA_FLAG=0 +CONFIG_BOUNCE=y +CONFIG_VIRT_TO_BUS=y +# CONFIG_KSM is not set +CONFIG_DEFAULT_MMAP_MIN_ADDR=4096 +# CONFIG_CLEANCACHE is not set +CONFIG_CMA=y +# CONFIG_CMA_DEVELOPEMENT is not set +CONFIG_CMA_BEST_FIT=y +# CONFIG_DEBUG_VMALLOC is not set +CONFIG_FORCE_MAX_ZONEORDER=12 +CONFIG_ALIGNMENT_TRAP=y +# CONFIG_UACCESS_WITH_MEMCPY is not set +# CONFIG_SECCOMP is not set +# CONFIG_CC_STACKPROTECTOR is not set +# CONFIG_DEPRECATED_PARAM_STRUCT is not set +# CONFIG_ARM_FLUSH_CONSOLE_ON_RESTART is not set +# CONFIG_VMWARE_MVP is not set + +# +# Boot options +# +# CONFIG_USE_OF is not set +CONFIG_ZBOOT_ROM_TEXT=0 +CONFIG_ZBOOT_ROM_BSS=0 +CONFIG_CMDLINE="console=ttySAC2,115200 consoleblank=0" +CONFIG_CMDLINE_FROM_BOOTLOADER=y +# CONFIG_CMDLINE_EXTEND is not set +# CONFIG_CMDLINE_FORCE is not set +# CONFIG_XIP_KERNEL is not set +# CONFIG_KEXEC is not set +# CONFIG_CRASH_DUMP is not set +# CONFIG_AUTO_ZRELADDR is not set + +# +# CPU Power Management +# + +# +# CPU Frequency scaling +# +CONFIG_CPU_FREQ=y +CONFIG_CPU_FREQ_TABLE=y +CONFIG_CPU_FREQ_STAT=y +# CONFIG_CPU_FREQ_STAT_DETAILS is not set +# CONFIG_CPU_FREQ_DEFAULT_GOV_PERFORMANCE is not set +# CONFIG_CPU_FREQ_DEFAULT_GOV_POWERSAVE is not set +# CONFIG_CPU_FREQ_DEFAULT_GOV_USERSPACE is not set +CONFIG_CPU_FREQ_DEFAULT_GOV_ONDEMAND=y +# CONFIG_CPU_FREQ_DEFAULT_GOV_CONSERVATIVE is not set +# CONFIG_CPU_FREQ_DEFAULT_GOV_INTERACTIVE is not set +# CONFIG_CPU_FREQ_DEFAULT_GOV_ADAPTIVE is not set +# CONFIG_CPU_FREQ_DEFAULT_GOV_PEGASUSQ is not set +CONFIG_CPU_FREQ_GOV_PERFORMANCE=y +CONFIG_CPU_FREQ_GOV_POWERSAVE=y +CONFIG_CPU_FREQ_GOV_USERSPACE=y +CONFIG_CPU_FREQ_GOV_ONDEMAND=y +CONFIG_CPU_FREQ_GOV_ONDEMAND_FLEXRATE=y +CONFIG_CPU_FREQ_GOV_ONDEMAND_FLEXRATE_MAX_DURATION=100 +# CONFIG_CPU_FREQ_GOV_INTERACTIVE is not set +CONFIG_CPU_FREQ_GOV_CONSERVATIVE=y +# CONFIG_CPU_FREQ_GOV_ADAPTIVE is not set +CONFIG_CPU_FREQ_GOV_PEGASUSQ=y +# CONFIG_CPU_FREQ_GOV_SLP is not set +# CONFIG_CPU_FREQ_DVFS_MONITOR is not set +CONFIG_CPU_IDLE=y +CONFIG_CPU_IDLE_GOV_LADDER=y +CONFIG_CPU_IDLE_GOV_MENU=y + +# +# Floating point emulation +# + +# +# At least one emulation must be selected +# +# CONFIG_FPE_NWFPE is not set +# CONFIG_FPE_FASTFPE is not set +CONFIG_VFP=y +CONFIG_VFPv3=y +CONFIG_NEON=y + +# +# Userspace binary formats +# +CONFIG_BINFMT_ELF=y +# CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set +CONFIG_HAVE_AOUT=y +# CONFIG_BINFMT_AOUT is not set +CONFIG_BINFMT_MISC=y + +# +# Power management options +# +CONFIG_SUSPEND=y +CONFIG_SUSPEND_FREEZER=y +CONFIG_PM_WATCHDOG_TIMEOUT=y +# CONFIG_FAST_BOOT is not set +CONFIG_HAS_WAKELOCK=y +CONFIG_HAS_EARLYSUSPEND=y +CONFIG_WAKELOCK=y +CONFIG_WAKELOCK_STAT=y +CONFIG_USER_WAKELOCK=y +CONFIG_EARLYSUSPEND=y +# CONFIG_NO_USER_SPACE_SCREEN_ACCESS_CONTROL is not set +# CONFIG_CONSOLE_EARLYSUSPEND is not set +CONFIG_FB_EARLYSUSPEND=y +CONFIG_PM_SLEEP=y +CONFIG_PM_SLEEP_SMP=y +CONFIG_PM_RUNTIME=y +CONFIG_PM=y +# CONFIG_PM_DEBUG is not set +# CONFIG_APM_EMULATION is not set +CONFIG_ARCH_HAS_OPP=y +CONFIG_PM_OPP=y +CONFIG_PM_RUNTIME_CLK=y +# CONFIG_SUSPEND_TIME is not set +CONFIG_ARCH_SUSPEND_POSSIBLE=y +CONFIG_NET=y + +# +# Networking options +# +CONFIG_PACKET=y +CONFIG_UNIX=y +CONFIG_XFRM=y +# CONFIG_XFRM_USER is not set +# CONFIG_XFRM_SUB_POLICY is not set +# CONFIG_XFRM_MIGRATE is not set +# CONFIG_XFRM_STATISTICS is not set +CONFIG_XFRM_IPCOMP=y +CONFIG_NET_KEY=y +# CONFIG_NET_KEY_MIGRATE is not set +CONFIG_INET=y +CONFIG_IP_MULTICAST=y +CONFIG_IP_ADVANCED_ROUTER=y +# CONFIG_IP_FIB_TRIE_STATS is not set +CONFIG_IP_MULTIPLE_TABLES=y +# CONFIG_IP_ROUTE_MULTIPATH is not set +# CONFIG_IP_ROUTE_VERBOSE is not set +# CONFIG_IP_PNP is not set +# CONFIG_NET_IPIP is not set +# CONFIG_NET_IPGRE_DEMUX is not set +# CONFIG_IP_MROUTE is not set +# CONFIG_ARPD is not set +# CONFIG_SYN_COOKIES is not set +# CONFIG_INET_AH is not set +CONFIG_INET_ESP=y +# CONFIG_INET_IPCOMP is not set +# CONFIG_INET_XFRM_TUNNEL is not set +CONFIG_INET_TUNNEL=y +CONFIG_INET_XFRM_MODE_TRANSPORT=y +CONFIG_INET_XFRM_MODE_TUNNEL=y +# CONFIG_INET_XFRM_MODE_BEET is not set +# CONFIG_INET_LRO is not set +CONFIG_INET_DIAG=y +CONFIG_INET_TCP_DIAG=y +# CONFIG_TCP_CONG_ADVANCED is not set +CONFIG_TCP_CONG_CUBIC=y +CONFIG_DEFAULT_TCP_CONG="cubic" +# CONFIG_TCP_MD5SIG is not set +CONFIG_IPV6=y +CONFIG_IPV6_PRIVACY=y +CONFIG_IPV6_ROUTER_PREF=y +# CONFIG_IPV6_ROUTE_INFO is not set +CONFIG_IPV6_OPTIMISTIC_DAD=y +CONFIG_INET6_AH=y +CONFIG_INET6_ESP=y +CONFIG_INET6_IPCOMP=y +CONFIG_IPV6_MIP6=y +CONFIG_INET6_XFRM_TUNNEL=y +CONFIG_INET6_TUNNEL=y +CONFIG_INET6_XFRM_MODE_TRANSPORT=y +CONFIG_INET6_XFRM_MODE_TUNNEL=y +CONFIG_INET6_XFRM_MODE_BEET=y +# CONFIG_INET6_XFRM_MODE_ROUTEOPTIMIZATION is not set +CONFIG_IPV6_SIT=y +# CONFIG_IPV6_SIT_6RD is not set +CONFIG_IPV6_NDISC_NODETYPE=y +CONFIG_IPV6_TUNNEL=y +CONFIG_IPV6_MULTIPLE_TABLES=y +# CONFIG_IPV6_SUBTREES is not set +# CONFIG_IPV6_MROUTE is not set +CONFIG_ANDROID_PARANOID_NETWORK=y +CONFIG_NET_ACTIVITY_STATS=y +# CONFIG_NETWORK_SECMARK is not set +# CONFIG_NETWORK_PHY_TIMESTAMPING is not set +CONFIG_NETFILTER=y +# CONFIG_NETFILTER_DEBUG is not set +CONFIG_NETFILTER_ADVANCED=y + +# +# Core Netfilter Configuration +# +CONFIG_NETFILTER_NETLINK=y +CONFIG_NETFILTER_NETLINK_QUEUE=y +CONFIG_NETFILTER_NETLINK_LOG=y +CONFIG_NF_CONNTRACK=y +CONFIG_NF_CONNTRACK_MARK=y +CONFIG_NF_CONNTRACK_EVENTS=y +# CONFIG_NF_CONNTRACK_TIMESTAMP is not set +CONFIG_NF_CT_PROTO_DCCP=y +CONFIG_NF_CT_PROTO_GRE=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_BROADCAST=y +CONFIG_NF_CONNTRACK_NETBIOS_NS=y +# CONFIG_NF_CONNTRACK_SNMP is not set +CONFIG_NF_CONNTRACK_PPTP=y +CONFIG_NF_CONNTRACK_SANE=y +# CONFIG_NF_CONNTRACK_SIP is not set +CONFIG_NF_CONNTRACK_TFTP=y +CONFIG_NF_CT_NETLINK=y +CONFIG_NETFILTER_TPROXY=y +CONFIG_NETFILTER_XTABLES=y + +# +# Xtables combined modules +# +CONFIG_NETFILTER_XT_MARK=y +CONFIG_NETFILTER_XT_CONNMARK=y + +# +# Xtables targets +# +# CONFIG_NETFILTER_XT_TARGET_CHECKSUM is not set +CONFIG_NETFILTER_XT_TARGET_CLASSIFY=y +CONFIG_NETFILTER_XT_TARGET_CONNMARK=y +# CONFIG_NETFILTER_XT_TARGET_CT is not set +# CONFIG_NETFILTER_XT_TARGET_DSCP is not set +# CONFIG_NETFILTER_XT_TARGET_HL is not set +# CONFIG_NETFILTER_XT_TARGET_IDLETIMER is not set +# CONFIG_NETFILTER_XT_TARGET_LED is not set +CONFIG_NETFILTER_XT_TARGET_MARK=y +CONFIG_NETFILTER_XT_TARGET_NFLOG=y +CONFIG_NETFILTER_XT_TARGET_NFQUEUE=y +# CONFIG_NETFILTER_XT_TARGET_NOTRACK is not set +# CONFIG_NETFILTER_XT_TARGET_RATEEST is not set +# CONFIG_NETFILTER_XT_TARGET_TEE is not set +CONFIG_NETFILTER_XT_TARGET_TPROXY=y +CONFIG_NETFILTER_XT_TARGET_TRACE=y +CONFIG_NETFILTER_XT_TARGET_TCPMSS=y +# CONFIG_NETFILTER_XT_TARGET_TCPOPTSTRIP is not set + +# +# Xtables matches +# +# CONFIG_NETFILTER_XT_MATCH_ADDRTYPE is not set +# CONFIG_NETFILTER_XT_MATCH_CLUSTER is not set +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_CPU is not set +# CONFIG_NETFILTER_XT_MATCH_DCCP is not set +# CONFIG_NETFILTER_XT_MATCH_DEVGROUP is not set +# CONFIG_NETFILTER_XT_MATCH_DSCP is not set +# CONFIG_NETFILTER_XT_MATCH_ESP is not set +CONFIG_NETFILTER_XT_MATCH_HASHLIMIT=y +CONFIG_NETFILTER_XT_MATCH_HELPER=y +CONFIG_NETFILTER_XT_MATCH_HL=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_MULTIPORT is not set +# CONFIG_NETFILTER_XT_MATCH_OSF is not set +# CONFIG_NETFILTER_XT_MATCH_OWNER is not set +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_QUOTA2=y +CONFIG_NETFILTER_XT_MATCH_QUOTA2_LOG=y +# CONFIG_NETFILTER_XT_MATCH_RATEEST is not set +# CONFIG_NETFILTER_XT_MATCH_REALM is not set +# CONFIG_NETFILTER_XT_MATCH_RECENT is not set +# CONFIG_NETFILTER_XT_MATCH_SCTP is not set +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_TCPMSS is not set +CONFIG_NETFILTER_XT_MATCH_TIME=y +CONFIG_NETFILTER_XT_MATCH_U32=y +# CONFIG_IP_SET is not set +# CONFIG_IP_VS is not set + +# +# IP: Netfilter Configuration +# +CONFIG_NF_DEFRAG_IPV4=y +CONFIG_NF_CONNTRACK_IPV4=y +CONFIG_NF_CONNTRACK_PROC_COMPAT=y +# CONFIG_IP_NF_QUEUE is not set +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_REJECT_SKERR=y +CONFIG_IP_NF_TARGET_LOG=y +# CONFIG_IP_NF_TARGET_ULOG is not set +CONFIG_NF_NAT=y +CONFIG_NF_NAT_NEEDED=y +CONFIG_IP_NF_TARGET_MASQUERADE=y +CONFIG_IP_NF_TARGET_NETMAP=y +CONFIG_IP_NF_TARGET_REDIRECT=y +CONFIG_NF_NAT_PROTO_DCCP=y +CONFIG_NF_NAT_PROTO_GRE=y +CONFIG_NF_NAT_PROTO_UDPLITE=y +CONFIG_NF_NAT_PROTO_SCTP=y +CONFIG_NF_NAT_FTP=y +CONFIG_NF_NAT_IRC=y +CONFIG_NF_NAT_TFTP=y +CONFIG_NF_NAT_AMANDA=y +CONFIG_NF_NAT_PPTP=y +CONFIG_NF_NAT_H323=y +# CONFIG_NF_NAT_SIP is not set +CONFIG_IP_NF_MANGLE=y +# CONFIG_IP_NF_TARGET_CLUSTERIP is not set +# CONFIG_IP_NF_TARGET_ECN is not set +# CONFIG_IP_NF_TARGET_TTL is not set +CONFIG_IP_NF_RAW=y +CONFIG_IP_NF_ARPTABLES=y +CONFIG_IP_NF_ARPFILTER=y +CONFIG_IP_NF_ARP_MANGLE=y + +# +# IPv6: Netfilter Configuration +# +CONFIG_NF_DEFRAG_IPV6=y +CONFIG_NF_CONNTRACK_IPV6=y +# CONFIG_IP6_NF_QUEUE is not set +CONFIG_IP6_NF_IPTABLES=y +# CONFIG_IP6_NF_MATCH_AH is not set +# CONFIG_IP6_NF_MATCH_EUI64 is not set +# CONFIG_IP6_NF_MATCH_FRAG is not set +# CONFIG_IP6_NF_MATCH_OPTS is not set +# CONFIG_IP6_NF_MATCH_HL is not set +# CONFIG_IP6_NF_MATCH_IPV6HEADER is not set +# CONFIG_IP6_NF_MATCH_MH is not set +# CONFIG_IP6_NF_MATCH_RT is not set +# CONFIG_IP6_NF_TARGET_HL is not set +CONFIG_IP6_NF_TARGET_LOG=y +CONFIG_IP6_NF_FILTER=y +CONFIG_IP6_NF_TARGET_REJECT=y +CONFIG_IP6_NF_TARGET_REJECT_SKERR=y +CONFIG_IP6_NF_MANGLE=y +CONFIG_IP6_NF_RAW=y +# CONFIG_IP_DCCP is not set +# CONFIG_IP_SCTP is not set +# CONFIG_RDS is not set +# CONFIG_TIPC is not set +# CONFIG_ATM is not set +# CONFIG_L2TP is not set +# CONFIG_BRIDGE is not set +# CONFIG_NET_DSA is not set +# CONFIG_VLAN_8021Q is not set +# CONFIG_DECNET is not set +# CONFIG_LLC2 is not set +# CONFIG_IPX is not set +# CONFIG_ATALK is not set +# CONFIG_X25 is not set +# CONFIG_LAPB is not set +# CONFIG_ECONET is not set +# CONFIG_WAN_ROUTER is not set +CONFIG_PHONET=y +# CONFIG_IEEE802154 is not set +CONFIG_NET_SCHED=y + +# +# Queueing/Scheduling +# +# CONFIG_NET_SCH_CBQ is not set +CONFIG_NET_SCH_HTB=y +# CONFIG_NET_SCH_HFSC is not set +# CONFIG_NET_SCH_PRIO is not set +# CONFIG_NET_SCH_MULTIQ is not set +# CONFIG_NET_SCH_RED is not set +# CONFIG_NET_SCH_SFB is not set +# CONFIG_NET_SCH_SFQ is not set +# CONFIG_NET_SCH_TEQL is not set +# CONFIG_NET_SCH_TBF is not set +# CONFIG_NET_SCH_GRED is not set +# CONFIG_NET_SCH_DSMARK is not set +# CONFIG_NET_SCH_NETEM is not set +# CONFIG_NET_SCH_DRR is not set +# CONFIG_NET_SCH_MQPRIO is not set +# CONFIG_NET_SCH_CHOKE is not set +# CONFIG_NET_SCH_QFQ is not set +CONFIG_NET_SCH_INGRESS=y + +# +# Classification +# +CONFIG_NET_CLS=y +# CONFIG_NET_CLS_BASIC is not set +# CONFIG_NET_CLS_TCINDEX is not set +# CONFIG_NET_CLS_ROUTE4 is not set +# CONFIG_NET_CLS_FW is not set +CONFIG_NET_CLS_U32=y +# CONFIG_CLS_U32_PERF is not set +# CONFIG_CLS_U32_MARK is not set +# CONFIG_NET_CLS_RSVP is not set +# CONFIG_NET_CLS_RSVP6 is not set +# CONFIG_NET_CLS_FLOW is not set +# CONFIG_NET_CLS_CGROUP is not set +CONFIG_NET_EMATCH=y +CONFIG_NET_EMATCH_STACK=32 +# CONFIG_NET_EMATCH_CMP is not set +# CONFIG_NET_EMATCH_NBYTE is not set +CONFIG_NET_EMATCH_U32=y +# CONFIG_NET_EMATCH_META is not set +# CONFIG_NET_EMATCH_TEXT is not set +CONFIG_NET_CLS_ACT=y +CONFIG_NET_ACT_POLICE=y +CONFIG_NET_ACT_GACT=y +# CONFIG_GACT_PROB is not set +CONFIG_NET_ACT_MIRRED=y +# CONFIG_NET_ACT_IPT is not set +# CONFIG_NET_ACT_NAT is not set +# CONFIG_NET_ACT_PEDIT is not set +# CONFIG_NET_ACT_SIMP is not set +# CONFIG_NET_ACT_SKBEDIT is not set +# CONFIG_NET_ACT_CSUM is not set +# CONFIG_NET_CLS_IND is not set +CONFIG_NET_SCH_FIFO=y +# CONFIG_DCB is not set +CONFIG_DNS_RESOLVER=y +# CONFIG_BATMAN_ADV is not set +CONFIG_RPS=y +CONFIG_RFS_ACCEL=y +CONFIG_XPS=y + +# +# Network testing +# +# CONFIG_NET_PKTGEN is not set +# CONFIG_HAMRADIO is not set +# CONFIG_CAN is not set +# CONFIG_IRDA is not set +CONFIG_BT=y +CONFIG_BT_L2CAP=y +CONFIG_BT_SCO=y +CONFIG_BT_RFCOMM=y +CONFIG_BT_RFCOMM_TTY=y +CONFIG_BT_BNEP=y +# CONFIG_BT_BNEP_MC_FILTER is not set +# CONFIG_BT_BNEP_PROTO_FILTER is not set +CONFIG_BT_HIDP=y + +# +# Bluetooth device drivers +# +# CONFIG_BT_HCIBTUSB is not set +# CONFIG_BT_HCIBTSDIO is not set +CONFIG_BT_HCIUART=y +CONFIG_BT_HCIUART_H4=y +# CONFIG_BT_HCIUART_BCSP is not set +# CONFIG_BT_HCIUART_ATH3K is not set +# CONFIG_BT_HCIUART_LL is not set +# CONFIG_BT_HCIBCM203X is not set +# CONFIG_BT_HCIBPA10X is not set +# CONFIG_BT_HCIBFUSB is not set +# CONFIG_BT_HCIVHCI is not set +# CONFIG_BT_MRVL is not set + +# +# Bluetooth device drivers +# + +# +# Bluetooth device drivers +# +# CONFIG_AF_RXRPC is not set +CONFIG_FIB_RULES=y +CONFIG_WIRELESS=y +CONFIG_WEXT_CORE=y +CONFIG_WEXT_PROC=y +CONFIG_CFG80211=y +# CONFIG_NL80211_TESTMODE is not set +# CONFIG_CFG80211_DEVELOPER_WARNINGS is not set +# CONFIG_CFG80211_REG_DEBUG is not set +CONFIG_CFG80211_DEFAULT_PS=y +# CONFIG_CFG80211_DEBUGFS is not set +# CONFIG_CFG80211_INTERNAL_REGDB is not set +CONFIG_CFG80211_WEXT=y +CONFIG_WIRELESS_EXT_SYSFS=y +# CONFIG_LIB80211 is not set +# CONFIG_CFG80211_ALLOW_RECONNECT is not set +# CONFIG_MAC80211 is not set +# CONFIG_WIMAX is not set +CONFIG_RFKILL=y +CONFIG_RFKILL_PM=y +CONFIG_RFKILL_LEDS=y +# CONFIG_RFKILL_INPUT is not set +# CONFIG_RFKILL_REGULATOR is not set +# CONFIG_RFKILL_GPIO is not set +# CONFIG_NET_9P is not set +# CONFIG_CAIF is not set +# CONFIG_CEPH_LIB is not set + +# +# Device Drivers +# + +# +# Generic Driver Options +# +CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug" +# CONFIG_DEVTMPFS is not set +CONFIG_STANDALONE=y +CONFIG_PREVENT_FIRMWARE_BUILD=y +CONFIG_FW_LOADER=y +CONFIG_FIRMWARE_IN_KERNEL=y +CONFIG_EXTRA_FIRMWARE="" +# CONFIG_DEBUG_DRIVER is not set +# CONFIG_DEBUG_DEVRES is not set +# CONFIG_SYS_HYPERVISOR is not set +# CONFIG_DMA_SHARED_BUFFER is not set +CONFIG_SYNC=y +CONFIG_SW_SYNC=y +CONFIG_SW_SYNC_USER=y +# CONFIG_DMA_CMA is not set +# CONFIG_CONNECTOR is not set +# CONFIG_MTD is not set +# CONFIG_PARPORT is not set +CONFIG_BLK_DEV=y +# CONFIG_BLK_DEV_COW_COMMON is not set +CONFIG_BLK_DEV_LOOP=y +# CONFIG_BLK_DEV_CRYPTOLOOP is not set + +# +# DRBD disabled because PROC_FS, INET or CONNECTOR not selected +# +# CONFIG_BLK_DEV_NBD is not set +# CONFIG_BLK_DEV_UB is not set +CONFIG_BLK_DEV_RAM=y +CONFIG_BLK_DEV_RAM_COUNT=16 +CONFIG_BLK_DEV_RAM_SIZE=8192 +# CONFIG_BLK_DEV_XIP is not set +# CONFIG_CDROM_PKTCDVD is not set +# CONFIG_ATA_OVER_ETH is not set +# CONFIG_MG_DISK is not set +# CONFIG_BLK_DEV_RBD is not set +# CONFIG_SENSORS_LIS3LV02D is not set +CONFIG_MISC_DEVICES=y +# CONFIG_AD525X_DPOT is not set +# CONFIG_ANDROID_PMEM is not set +# CONFIG_INTEL_MID_PTI is not set +# CONFIG_ICS932S401 is not set +# CONFIG_ENCLOSURE_SERVICES is not set +# CONFIG_APDS9802ALS is not set +# CONFIG_ISL29003 is not set +# CONFIG_ISL29020 is not set +# CONFIG_SENSORS_TSL2550 is not set +# CONFIG_SENSORS_BH1780 is not set +# CONFIG_SENSORS_BH1770 is not set +# CONFIG_SENSORS_APDS990X is not set +# CONFIG_HMC6352 is not set +# CONFIG_SENSORS_AK8975 is not set +# CONFIG_DS1682 is not set +# CONFIG_TI_DAC7512 is not set +CONFIG_UID_STAT=y +# CONFIG_BMP085 is not set +# CONFIG_WL127X_RFKILL is not set +# CONFIG_APANIC is not set +# CONFIG_JACK_MON is not set +# CONFIG_UART_SELECT is not set +# CONFIG_SWITCH_DUAL_MODEM is not set +CONFIG_WIMAX_CMC=y +CONFIG_SEC_DEV_JACK=y +# CONFIG_MUIC_DET_JACK is not set +# CONFIG_FM34_WE395 is not set +# CONFIG_AUDIENCE_ES305 is not set +# CONFIG_2MIC_FM34_WE395 is not set +CONFIG_MUIC_MAX8997=y +# CONFIG_MUIC_MAX8997_OVPUI is not set +# CONFIG_USBHUB_USB3503 is not set +# CONFIG_USBHUB_USB3503_OTG_CONN is not set +CONFIG_USBHUB_USB3803=y +# CONFIG_PN544 is not set +# CONFIG_STMPE811_ADC is not set +# CONFIG_MPU_SENSORS_MPU3050 is not set +# CONFIG_MPU_SENSORS_MPU6050 is not set +# CONFIG_C2PORT is not set + +# +# EEPROM support +# +# CONFIG_EEPROM_AT24 is not set +# CONFIG_EEPROM_AT25 is not set +# CONFIG_EEPROM_LEGACY is not set +# CONFIG_EEPROM_MAX6875 is not set +# CONFIG_EEPROM_93CX6 is not set +# CONFIG_IWMC3200TOP is not set + +# +# Texas Instruments shared transport line discipline +# +# CONFIG_TI_ST is not set +# CONFIG_SENSORS_LIS3_SPI is not set +# CONFIG_SENSORS_LIS3_I2C is not set +# CONFIG_SEC_MODEM is not set +CONFIG_HAVE_IDE=y +# CONFIG_IDE is not set + +# +# SCSI device support +# +CONFIG_SCSI_MOD=y +# CONFIG_RAID_ATTRS is not set +CONFIG_SCSI=y +CONFIG_SCSI_DMA=y +# CONFIG_SCSI_TGT is not set +# CONFIG_SCSI_NETLINK is not set +CONFIG_SCSI_PROC_FS=y + +# +# SCSI support type (disk, tape, CD-ROM) +# +CONFIG_BLK_DEV_SD=y +# CONFIG_CHR_DEV_ST is not set +# CONFIG_CHR_DEV_OSST is not set +# CONFIG_BLK_DEV_SR is not set +CONFIG_CHR_DEV_SG=y +# CONFIG_CHR_DEV_SCH is not set +CONFIG_SCSI_MULTI_LUN=y +# CONFIG_SCSI_CONSTANTS is not set +# CONFIG_SCSI_LOGGING is not set +# CONFIG_SCSI_SCAN_ASYNC is not set +CONFIG_SCSI_WAIT_SCAN=m + +# +# SCSI Transports +# +# CONFIG_SCSI_SPI_ATTRS is not set +# CONFIG_SCSI_FC_ATTRS is not set +# CONFIG_SCSI_ISCSI_ATTRS is not set +# CONFIG_SCSI_SAS_ATTRS is not set +# CONFIG_SCSI_SAS_LIBSAS is not set +# CONFIG_SCSI_SRP_ATTRS is not set +CONFIG_SCSI_LOWLEVEL=y +# CONFIG_ISCSI_TCP is not set +# CONFIG_ISCSI_BOOT_SYSFS is not set +# CONFIG_LIBFC is not set +# CONFIG_LIBFCOE is not set +# CONFIG_SCSI_DEBUG is not set +# CONFIG_SCSI_DH is not set +# CONFIG_SCSI_OSD_INITIATOR is not set +# CONFIG_ATA is not set +CONFIG_MD=y +# CONFIG_BLK_DEV_MD is not set +CONFIG_BLK_DEV_DM=y +# CONFIG_DM_DEBUG is not set +CONFIG_DM_CRYPT=y +# CONFIG_DM_SNAPSHOT is not set +# CONFIG_DM_MIRROR is not set +# CONFIG_DM_RAID is not set +# CONFIG_DM_ZERO is not set +# CONFIG_DM_MULTIPATH is not set +# CONFIG_DM_DELAY is not set +# CONFIG_DM_UEVENT is not set +# CONFIG_DM_FLAKEY is not set +# CONFIG_TARGET_CORE is not set +CONFIG_NETDEVICES=y +# CONFIG_IFB is not set +# CONFIG_DUMMY is not set +# CONFIG_BONDING is not set +# CONFIG_MACVLAN is not set +# CONFIG_EQUALIZER is not set +CONFIG_TUN=y +# CONFIG_VETH is not set +# CONFIG_MII is not set +# CONFIG_PHYLIB is not set +# CONFIG_NET_ETHERNET is not set +# CONFIG_NETDEV_1000 is not set +# CONFIG_NETDEV_10000 is not set +CONFIG_WLAN=y +# CONFIG_USB_ZD1201 is not set +# CONFIG_USB_NET_RNDIS_WLAN is not set +CONFIG_WIFI_CONTROL_FUNC=y +# CONFIG_ATH_COMMON is not set +CONFIG_BCM4330=m +# CONFIG_BCM4334 is not set +# CONFIG_BCM4335 is not set +# CONFIG_BCM43241 is not set +CONFIG_BROADCOM_WIFI=y +CONFIG_BCMDHD_FW_PATH="/system/vendor/firmware/fw_bcmdhd.bin" +CONFIG_BCMDHD_NVRAM_PATH="/system/etc/wifi/bcmdhd.cal" +CONFIG_BROADCOM_WIFI_RESERVED_MEM=y +CONFIG_WLAN_REGION_CODE=100 +# CONFIG_HOSTAP is not set +# CONFIG_IWM is not set +# CONFIG_LIBERTAS is not set +# CONFIG_MWIFIEX is not set +CONFIG_WIMAX_CMC7XX_DEBUG=y + +# +# Enable WiMAX (Networking options) to see the WiMAX drivers +# + +# +# USB Network Adapters +# +# CONFIG_USB_CATC is not set +# CONFIG_USB_KAWETH is not set +# CONFIG_USB_PEGASUS is not set +# CONFIG_USB_RTL8150 is not set +# CONFIG_USB_USBNET is not set +# CONFIG_USB_HSO is not set +# CONFIG_USB_CDC_PHONET is not set +# CONFIG_USB_IPHETH is not set +# CONFIG_WAN is not set + +# +# CAIF transport drivers +# +CONFIG_PPP=y +# CONFIG_PPP_MULTILINK is not set +# CONFIG_PPP_FILTER is not set +CONFIG_PPP_ASYNC=y +# CONFIG_PPP_SYNC_TTY is not set +CONFIG_PPP_DEFLATE=y +CONFIG_PPP_BSDCOMP=y +CONFIG_PPP_MPPE=y +# CONFIG_PPPOE is not set +CONFIG_PPPOLAC=y +CONFIG_PPPOPNS=y +# CONFIG_SLIP is not set +CONFIG_SLHC=y +# CONFIG_NETCONSOLE is not set +# CONFIG_NETPOLL is not set +# CONFIG_NET_POLL_CONTROLLER is not set +# CONFIG_ISDN is not set +# CONFIG_PHONE is not set + +# +# Input device support +# +CONFIG_INPUT=y +# CONFIG_INPUT_FF_MEMLESS is not set +# CONFIG_INPUT_POLLDEV is not set +# CONFIG_INPUT_SPARSEKMAP is not set + +# +# Userland interfaces +# +# CONFIG_INPUT_MOUSEDEV is not set +# CONFIG_INPUT_JOYDEV is not set +CONFIG_INPUT_EVDEV=y +# CONFIG_INPUT_EVBUG is not set +# CONFIG_INPUT_SECBRIDGE is not set +# CONFIG_INPUT_KEYRESET is not set +# CONFIG_INPUT_FBSUSPEND is not set + +# +# Input Device Drivers +# +CONFIG_INPUT_KEYBOARD=y +# CONFIG_KEYBOARD_ADP5588 is not set +# CONFIG_KEYBOARD_ADP5589 is not set +CONFIG_KEYBOARD_ATKBD=y +# CONFIG_KEYBOARD_QT1070 is not set +# CONFIG_KEYBOARD_QT2160 is not set +# CONFIG_KEYBOARD_LKKBD is not set +CONFIG_KEYBOARD_GPIO=y +# CONFIG_KEYBOARD_TCA6416 is not set +# CONFIG_KEYBOARD_MATRIX is not set +# CONFIG_KEYBOARD_LM8323 is not set +# CONFIG_KEYBOARD_MAX7359 is not set +# CONFIG_KEYBOARD_MCS is not set +# CONFIG_KEYBOARD_MPR121 is not set +# CONFIG_KEYBOARD_NEWTON is not set +# CONFIG_KEYBOARD_OPENCORES is not set +# CONFIG_KEYBOARD_STOWAWAY is not set +# CONFIG_KEYBOARD_SUNKBD is not set +# CONFIG_KEYBOARD_XTKBD is not set +CONFIG_KEYBOARD_CYPRESS_TOUCH=y +# CONFIG_INPUT_MOUSE is not set +# CONFIG_INPUT_JOYSTICK is not set +# CONFIG_INPUT_TABLET is not set +CONFIG_INPUT_TOUCHSCREEN=y +# CONFIG_TOUCHSCREEN_MELFAS_GC is not set +# CONFIG_TOUCHSCREEN_MELFAS is not set +# CONFIG_TOUCHSCREEN_MELFAS_MMS is not set +# CONFIG_TOUCHSCREEN_MMS152 is not set +# CONFIG_TOUCHSCREEN_MELFAS_NOTE is not set +# CONFIG_TOUCHSCREEN_ADS7846 is not set +# CONFIG_TOUCHSCREEN_AD7877 is not set +# CONFIG_TOUCHSCREEN_AD7879 is not set +# CONFIG_TOUCHSCREEN_ATMEL_MXT is not set +CONFIG_TOUCHSCREEN_ATMEL_MXT224_U1=y +# CONFIG_TOUCHSCREEN_ATMEL_MXT224_GRANDE is not set +# CONFIG_TOUCHSCREEN_ATMEL_MXT224S_GRANDE is not set +# CONFIG_TOUCHSCREEN_ATMEL_MXT224_GC is not set +# CONFIG_TOUCHSCREEN_ATMEL_MXT1536E is not set +# CONFIG_TOUCHSCREEN_ATMEL_MXT1664S is not set +# CONFIG_TOUCHSCREEN_ATMEL_MXT540E is not set +# CONFIG_TOUCHSCREEN_ATMEL_MXT224 is not set +# CONFIG_TOUCHSCREEN_BU21013 is not set +# CONFIG_TOUCHSCREEN_CY8CTMG110 is not set +# CONFIG_TOUCHSCREEN_DYNAPRO is not set +# CONFIG_TOUCHSCREEN_HAMPSHIRE is not set +# CONFIG_TOUCHSCREEN_EETI is not set +# CONFIG_TOUCHSCREEN_FUJITSU is not set +# CONFIG_TOUCHSCREEN_S3C2410 is not set +# CONFIG_TOUCHSCREEN_EXYNOS4 is not set +# CONFIG_TOUCHSCREEN_PIXCIR is not set +# CONFIG_TOUCHSCREEN_GUNZE is not set +# CONFIG_TOUCHSCREEN_ELO is not set +# CONFIG_TOUCHSCREEN_WACOM_W8001 is not set +# CONFIG_TOUCHSCREEN_MAX11801 is not set +# CONFIG_TOUCHSCREEN_MCS5000 is not set +# CONFIG_TOUCHSCREEN_MMS114 is not set +# CONFIG_MELFAS_TOUCHKEY is not set +# CONFIG_TOUCHSCREEN_MTOUCH is not set +# CONFIG_TOUCHSCREEN_INEXIO is not set +# CONFIG_TOUCHSCREEN_MK712 is not set +# CONFIG_TOUCHSCREEN_PENMOUNT is not set +# CONFIG_TOUCHSCREEN_SYNAPTICS_I2C_RMI is not set +# CONFIG_TOUCHSCREEN_TOUCHRIGHT is not set +# CONFIG_TOUCHSCREEN_TOUCHWIN is not set +# CONFIG_TOUCHSCREEN_USB_COMPOSITE is not set +# CONFIG_TOUCHSCREEN_TOUCHIT213 is not set +# CONFIG_TOUCHSCREEN_TSC2005 is not set +# CONFIG_TOUCHSCREEN_TSC2007 is not set +# CONFIG_TOUCHSCREEN_W90X900 is not set +# CONFIG_TOUCHSCREEN_ST1232 is not set +# CONFIG_TOUCHSCREEN_TPS6507X is not set +# CONFIG_TOUCHSCREEN_ZINITIX is not set +# CONFIG_TOUCHSCREEN_MXT1386 is not set +# CONFIG_TOUCHSCREEN_MXT768E is not set +# CONFIG_TOUCHSCREEN_SYNAPTICS_S7301 is not set +# CONFIG_TOUCHSCREEN_CYTTSP4 is not set +# CONFIG_SEC_TOUCHSCREEN_DVFS_LOCK is not set +# CONFIG_KEYPAD_MELFAS_TOUCH is not set +# CONFIG_TOUCHSCREEN_ATMEL_MXT540S is not set +# CONFIG_INPUT_WACOM is not set +# CONFIG_EPEN_WACOM_G5SP is not set +# CONFIG_EPEN_WACOM_G9PM is not set +CONFIG_INPUT_MISC=y +# CONFIG_SENSORS_BH1721FVC is not set +# CONFIG_INPUT_AD714X is not set +# CONFIG_INPUT_ATI_REMOTE is not set +# CONFIG_INPUT_ATI_REMOTE2 is not set +CONFIG_INPUT_KEYCHORD=y +# CONFIG_INPUT_KEYSPAN_REMOTE is not set +# CONFIG_INPUT_POWERMATE is not set +# CONFIG_INPUT_YEALINK is not set +# CONFIG_INPUT_CM109 is not set +CONFIG_INPUT_UINPUT=y +CONFIG_INPUT_GPIO=y +# CONFIG_INPUT_PCF8574 is not set +# CONFIG_INPUT_PWM_BEEPER is not set +# CONFIG_INPUT_GPIO_ROTARY_ENCODER is not set +# CONFIG_INPUT_ADXL34X is not set +# CONFIG_OPTICAL_GP2A is not set +# CONFIG_OPTICAL_WAKE_ENABLE is not set +# CONFIG_INPUT_CMA3000 is not set +# CONFIG_INPUT_FLIP is not set +# CONFIG_INPUT_KR3DH is not set + +# +# Hardware I/O ports +# +CONFIG_SERIO=y +CONFIG_SERIO_SERPORT=y +CONFIG_SERIO_LIBPS2=y +# CONFIG_SERIO_RAW is not set +# CONFIG_SERIO_ALTERA_PS2 is not set +# CONFIG_SERIO_PS2MULT is not set +# CONFIG_GAMEPORT is not set + +# +# Character devices +# +CONFIG_VT=y +CONFIG_CONSOLE_TRANSLATIONS=y +# CONFIG_VT_CONSOLE is not set +CONFIG_HW_CONSOLE=y +# CONFIG_VT_HW_CONSOLE_BINDING is not set +CONFIG_UNIX98_PTYS=y +# CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set +# CONFIG_LEGACY_PTYS is not set +# CONFIG_SERIAL_NONSTANDARD is not set +# CONFIG_N_GSM is not set +# CONFIG_TRACE_SINK is not set +CONFIG_DEVMEM=y +CONFIG_DEVKMEM=y + +# +# Serial drivers +# +CONFIG_SERIAL_8250=y +# CONFIG_SERIAL_8250_CONSOLE is not set +CONFIG_SERIAL_8250_NR_UARTS=4 +CONFIG_SERIAL_8250_RUNTIME_UARTS=4 +# CONFIG_SERIAL_8250_EXTENDED is not set + +# +# Non-8250 serial port support +# +CONFIG_SERIAL_SAMSUNG=y +CONFIG_SERIAL_SAMSUNG_UARTS_4=y +CONFIG_SERIAL_SAMSUNG_UARTS=4 +CONFIG_SERIAL_SAMSUNG_CONSOLE=y +# CONFIG_SERIAL_SAMSUNG_CONSOLE_SWITCH is not set +CONFIG_SERIAL_S5PV210=y +# CONFIG_SERIAL_MAX3100 is not set +# CONFIG_SERIAL_MAX3107 is not set +CONFIG_SERIAL_CORE=y +CONFIG_SERIAL_CORE_CONSOLE=y +# CONFIG_SERIAL_TIMBERDALE is not set +# CONFIG_SERIAL_ALTERA_JTAGUART is not set +# CONFIG_SERIAL_ALTERA_UART is not set +# CONFIG_SERIAL_IFX6X60 is not set +# CONFIG_SERIAL_XILINX_PS_UART is not set +# CONFIG_CSR_GSD4T_CDMA is not set + +# +# Diag Support +# +# CONFIG_DIAG_CHAR is not set + +# +# DIAG traffic over USB +# + +# +# SDIO support for DIAG +# + +# +# HSIC support for DIAG +# +# CONFIG_TTY_PRINTK is not set +# CONFIG_HVC_DCC is not set +# CONFIG_IPMI_HANDLER is not set +CONFIG_HW_RANDOM=y +# CONFIG_HW_RANDOM_TIMERIOMEM is not set +# CONFIG_R3964 is not set +# CONFIG_RAW_DRIVER is not set +# CONFIG_TCG_TPM is not set +# CONFIG_DCC_TTY is not set +# CONFIG_RAMOOPS is not set +CONFIG_S3C_MEM=y +CONFIG_EXYNOS_MEM=y +CONFIG_I2C=y +CONFIG_I2C_BOARDINFO=y +CONFIG_I2C_COMPAT=y +CONFIG_I2C_CHARDEV=y +# CONFIG_I2C_MUX is not set +CONFIG_I2C_HELPER_AUTO=y +CONFIG_I2C_ALGOBIT=y + +# +# I2C Hardware Bus support +# + +# +# I2C system bus drivers (mostly embedded / system-on-chip) +# +# CONFIG_I2C_DESIGNWARE is not set +CONFIG_I2C_GPIO=y +# CONFIG_I2C_OCORES is not set +# CONFIG_I2C_PCA_PLATFORM is not set +# CONFIG_I2C_PXA_PCI is not set +CONFIG_HAVE_S3C2410_I2C=y +CONFIG_I2C_S3C2410=y +# CONFIG_I2C_SIMTEC is not set +# CONFIG_I2C_XILINX is not set + +# +# External I2C/SMBus adapter drivers +# +# CONFIG_I2C_DIOLAN_U2C is not set +# CONFIG_I2C_PARPORT_LIGHT is not set +# CONFIG_I2C_TAOS_EVM is not set +# CONFIG_I2C_TINY_USB is not set + +# +# Other I2C/SMBus bus drivers +# +# CONFIG_I2C_STUB is not set +# CONFIG_I2C_DEBUG_CORE is not set +# CONFIG_I2C_DEBUG_ALGO is not set +# CONFIG_I2C_DEBUG_BUS is not set +CONFIG_SPI=y +# CONFIG_SPI_DEBUG is not set +CONFIG_SPI_MASTER=y + +# +# SPI Master Controller Drivers +# +# CONFIG_SPI_ALTERA is not set +CONFIG_SPI_BITBANG=y +CONFIG_SPI_GPIO=y +# CONFIG_SPI_OC_TINY is not set +# CONFIG_SPI_PXA2XX_PCI is not set +# CONFIG_SPI_S3C64XX is not set +# CONFIG_SPI_XILINX is not set +# CONFIG_SPI_DESIGNWARE is not set + +# +# SPI Protocol Masters +# +# CONFIG_SPI_SPIDEV is not set +# CONFIG_SPI_TLE62X0 is not set + +# +# PPS support +# +# CONFIG_PPS is not set + +# +# PPS generators support +# + +# +# PTP clock support +# + +# +# Enable Device Drivers -> PPS to see the PTP clock options. +# +CONFIG_ARCH_REQUIRE_GPIOLIB=y +CONFIG_GPIOLIB=y +# CONFIG_DEBUG_GPIO is not set +CONFIG_GPIO_SYSFS=y + +# +# Memory mapped GPIO drivers: +# +# CONFIG_GPIO_BASIC_MMIO is not set +# CONFIG_GPIO_IT8761E is not set +CONFIG_GPIO_EXYNOS4=y +CONFIG_GPIO_PLAT_SAMSUNG=y + +# +# I2C GPIO expanders: +# +# CONFIG_GPIO_MAX7300 is not set +# CONFIG_GPIO_MAX732X is not set +# CONFIG_GPIO_PCF857X is not set +# CONFIG_GPIO_SX150X is not set +# CONFIG_GPIO_ADP5588 is not set + +# +# PCI GPIO expanders: +# + +# +# SPI GPIO expanders: +# +# CONFIG_GPIO_MAX7301 is not set +# CONFIG_GPIO_MCP23S08 is not set +# CONFIG_GPIO_MC33880 is not set +# CONFIG_GPIO_74X164 is not set + +# +# AC97 GPIO expanders: +# + +# +# MODULbus GPIO expanders: +# +# CONFIG_W1 is not set +CONFIG_POWER_SUPPLY=y +# CONFIG_MAX8997_CHARGER is not set +# CONFIG_BATTERY_MAX17043_FUELGAUGE is not set +# CONFIG_BATTERY_MAX17042_FUELGAUGE is not set +# CONFIG_BATTERY_MAX17047_FUELGAUGE is not set +# CONFIG_BATTERY_SMB136_CHARGER is not set +# CONFIG_BATTERY_SAMSUNG_P1X is not set +# CONFIG_CHARGER_MAX8903 is not set +# CONFIG_POWER_SUPPLY_DEBUG is not set +# CONFIG_PDA_POWER is not set +# CONFIG_TEST_POWER is not set +# CONFIG_BATTERY_DS2780 is not set +# CONFIG_BATTERY_DS2782 is not set +# CONFIG_BATTERY_BQ20Z75 is not set +# CONFIG_BATTERY_BQ27x00 is not set +# CONFIG_BATTERY_MAX17040 is not set +# CONFIG_BATTERY_MAX17042 is not set +# CONFIG_BATTERY_S3C_ADC is not set +# CONFIG_CHARGER_GPIO is not set +# CONFIG_BATTERY_SAMSUNG is not set +# CONFIG_CHARGER_MAX8997 is not set +CONFIG_CHARGER_MAX8997_U1=y +# CONFIG_CHARGER_MAX8997_PX is not set +CONFIG_BATTERY_SEC_U1=y +# CONFIG_BATTERY_SEC_PX is not set +CONFIG_CHARGER_MAX8922_U1=y +CONFIG_BATTERY_MAX17042_FUELGAUGE_U1=y +# CONFIG_BATTERY_MAX17042_FUELGAUGE_PX is not set +# CONFIG_SMB136_CHARGER is not set +# CONFIG_SMB136_CHARGER_Q1 is not set +# CONFIG_SMB328_CHARGER is not set +# CONFIG_SMB347_CHARGER is not set +# CONFIG_CHARGER_MANAGER is not set +# CONFIG_HWMON is not set +# CONFIG_THERMAL is not set +# CONFIG_SENSORS_EXYNOS4_TMU is not set +# CONFIG_WATCHDOG is not set +CONFIG_SSB_POSSIBLE=y + +# +# Sonics Silicon Backplane +# +# CONFIG_SSB is not set +CONFIG_BCMA_POSSIBLE=y + +# +# Broadcom specific AMBA +# +# CONFIG_BCMA is not set +CONFIG_MFD_SUPPORT=y +CONFIG_MFD_CORE=y +# CONFIG_MFD_88PM860X is not set +# CONFIG_MFD_SM501 is not set +# CONFIG_MFD_ASIC3 is not set +# CONFIG_HTC_EGPIO is not set +# CONFIG_HTC_PASIC3 is not set +# CONFIG_HTC_I2CPLD is not set +# CONFIG_TPS6105X is not set +# CONFIG_TPS65010 is not set +# CONFIG_TPS6507X is not set +# CONFIG_MFD_TPS6586X is not set +# CONFIG_TWL4030_CORE is not set +# CONFIG_MFD_STMPE is not set +# CONFIG_MFD_TC3589X is not set +# CONFIG_MFD_TMIO is not set +# CONFIG_MFD_T7L66XB is not set +# CONFIG_MFD_TC6387XB is not set +# CONFIG_MFD_TC6393XB is not set +# CONFIG_PMIC_DA903X is not set +# CONFIG_PMIC_ADP5520 is not set +# CONFIG_MFD_MAX8925 is not set +CONFIG_MFD_MAX8997=y +# CONFIG_MFD_MAX8998 is not set +# CONFIG_MFD_MAX8698 is not set +# CONFIG_MFD_MAX77686 is not set +# CONFIG_MFD_MAX77693 is not set +# CONFIG_MFD_S5M_CORE is not set +# CONFIG_MFD_WM8400 is not set +# CONFIG_MFD_WM831X_I2C is not set +# CONFIG_MFD_WM831X_SPI is not set +# CONFIG_MFD_WM8350_I2C is not set +# CONFIG_MFD_WM8994 is not set +# CONFIG_MFD_PCF50633 is not set +# CONFIG_MFD_MC13XXX is not set +# CONFIG_ABX500_CORE is not set +# CONFIG_EZX_PCAP is not set +# CONFIG_MFD_WL1273_CORE is not set +# CONFIG_MFD_TPS65910 is not set +CONFIG_REGULATOR=y +# CONFIG_REGULATOR_DEBUG is not set +# CONFIG_REGULATOR_DUMMY is not set +CONFIG_REGULATOR_FIXED_VOLTAGE=y +# CONFIG_REGULATOR_VIRTUAL_CONSUMER is not set +# CONFIG_REGULATOR_USERSPACE_CONSUMER is not set +# CONFIG_REGULATOR_BQ24022 is not set +# CONFIG_REGULATOR_MAX1586 is not set +# CONFIG_REGULATOR_MAX8649 is not set +# CONFIG_REGULATOR_MAX8660 is not set +# CONFIG_REGULATOR_MAX8952 is not set +# CONFIG_REGULATOR_MAX8952_GRANDE is not set +CONFIG_REGULATOR_MAX8997=y +# CONFIG_REGULATOR_LP3971 is not set +# CONFIG_REGULATOR_LP3972 is not set +# CONFIG_REGULATOR_LP8720 is not set +# CONFIG_REGULATOR_TPS65023 is not set +# CONFIG_REGULATOR_TPS6507X is not set +# CONFIG_REGULATOR_ISL6271A is not set +# CONFIG_REGULATOR_AD5398 is not set +# CONFIG_REGULATOR_TPS6524X is not set +CONFIG_MEDIA_SUPPORT=y + +# +# Multimedia core support +# +# CONFIG_MEDIA_CONTROLLER is not set +CONFIG_VIDEO_DEV=y +CONFIG_VIDEO_V4L2_COMMON=y +# CONFIG_DVB_CORE is not set +CONFIG_VIDEO_MEDIA=y + +# +# Multimedia drivers +# +CONFIG_RC_CORE=y +CONFIG_LIRC=y +CONFIG_RC_MAP=y +CONFIG_IR_NEC_DECODER=y +CONFIG_IR_RC5_DECODER=y +CONFIG_IR_RC6_DECODER=y +CONFIG_IR_JVC_DECODER=y +CONFIG_IR_SONY_DECODER=y +CONFIG_IR_RC5_SZ_DECODER=y +CONFIG_IR_LIRC_CODEC=y +# CONFIG_IR_IMON is not set +# CONFIG_IR_MCEUSB is not set +# CONFIG_IR_REDRAT3 is not set +# CONFIG_IR_STREAMZAP is not set +# CONFIG_RC_LOOPBACK is not set +# CONFIG_MEDIA_ATTACH is not set +CONFIG_MEDIA_TUNER=y +CONFIG_MEDIA_TUNER_CUSTOMISE=y + +# +# Customize TV tuners +# +# CONFIG_MEDIA_TUNER_SIMPLE is not set +# CONFIG_MEDIA_TUNER_TDA8290 is not set +# CONFIG_MEDIA_TUNER_TDA827X is not set +# CONFIG_MEDIA_TUNER_TDA18271 is not set +# CONFIG_MEDIA_TUNER_TDA9887 is not set +# CONFIG_MEDIA_TUNER_TEA5761 is not set +# CONFIG_MEDIA_TUNER_TEA5767 is not set +# CONFIG_MEDIA_TUNER_MT20XX is not set +# CONFIG_MEDIA_TUNER_MT2060 is not set +# CONFIG_MEDIA_TUNER_MT2266 is not set +# CONFIG_MEDIA_TUNER_MT2131 is not set +# CONFIG_MEDIA_TUNER_QT1010 is not set +# CONFIG_MEDIA_TUNER_XC2028 is not set +# CONFIG_MEDIA_TUNER_XC5000 is not set +# CONFIG_MEDIA_TUNER_MXL5005S is not set +# CONFIG_MEDIA_TUNER_MXL5007T is not set +# CONFIG_MEDIA_TUNER_MC44S803 is not set +# CONFIG_MEDIA_TUNER_MAX2165 is not set +# CONFIG_MEDIA_TUNER_TDA18218 is not set +# CONFIG_MEDIA_TUNER_TDA18212 is not set +CONFIG_VIDEO_V4L2=y +CONFIG_VIDEOBUF2_CORE=y +CONFIG_VIDEOBUF2_MEMOPS=y +CONFIG_VIDEOBUF2_CMA_PHYS=y +# CONFIG_VIDEOBUF2_ION is not set +CONFIG_VIDEO_CAPTURE_DRIVERS=y +# CONFIG_VIDEO_ADV_DEBUG is not set +CONFIG_VIDEO_FIXED_MINOR_RANGES=y +# CONFIG_VIDEO_HELPER_CHIPS_AUTO is not set +CONFIG_VIDEO_IR_I2C=y + +# +# Encoders, decoders, sensors and other helper chips +# + +# +# Audio decoders, processors and mixers +# +# CONFIG_VIDEO_TVAUDIO is not set +# CONFIG_VIDEO_TDA7432 is not set +# CONFIG_VIDEO_TDA9840 is not set +# CONFIG_VIDEO_TEA6415C is not set +# CONFIG_VIDEO_TEA6420 is not set +# CONFIG_VIDEO_MSP3400 is not set +# CONFIG_VIDEO_CS5345 is not set +# CONFIG_VIDEO_CS53L32A is not set +# CONFIG_VIDEO_TLV320AIC23B is not set +# CONFIG_VIDEO_WM8775 is not set +# CONFIG_VIDEO_WM8739 is not set +# CONFIG_VIDEO_VP27SMPX is not set + +# +# RDS decoders +# +# CONFIG_VIDEO_SAA6588 is not set + +# +# Video decoders +# +# CONFIG_VIDEO_ADV7180 is not set +# CONFIG_VIDEO_BT819 is not set +# CONFIG_VIDEO_BT856 is not set +# CONFIG_VIDEO_BT866 is not set +# CONFIG_VIDEO_KS0127 is not set +# CONFIG_VIDEO_SAA7110 is not set +# CONFIG_VIDEO_SAA711X is not set +# CONFIG_VIDEO_SAA7191 is not set +# CONFIG_VIDEO_TVP514X is not set +# CONFIG_VIDEO_TVP5150 is not set +# CONFIG_VIDEO_TVP7002 is not set +# CONFIG_VIDEO_VPX3220 is not set +CONFIG_VIDEO_M5MO=y +# CONFIG_VIDEO_M9MO is not set +# CONFIG_VIDEO_S5K5BAFX is not set +CONFIG_VIDEO_S5K5BBGX=y +# CONFIG_VIDEO_S5K5CCGX_COMMON is not set +# CONFIG_VIDEO_SR200PC20 is not set +# CONFIG_VIDEO_SR200PC20M is not set +# CONFIG_VIDEO_ISX012 is not set +# CONFIG_VIDEO_SLP_S5K4ECGX is not set +# CONFIG_VIDEO_SLP_DB8131M is not set +# CONFIG_VIDEO_S5K4EA is not set +# CONFIG_VIDEO_S5C73M3 is not set +# CONFIG_VIDEO_SLP_S5C73M3 is not set +CONFIG_VIDEO_IMPROVE_STREAMOFF=y +CONFIG_CSI_C=y +# CONFIG_CSI_D is not set + +# +# Video and audio decoders +# +# CONFIG_VIDEO_SAA717X is not set +# CONFIG_VIDEO_CX25840 is not set + +# +# MPEG video encoders +# +# CONFIG_VIDEO_CX2341X is not set + +# +# Video encoders +# +# CONFIG_VIDEO_SAA7127 is not set +# CONFIG_VIDEO_SAA7185 is not set +# CONFIG_VIDEO_ADV7170 is not set +# CONFIG_VIDEO_ADV7175 is not set +# CONFIG_VIDEO_ADV7343 is not set +# CONFIG_VIDEO_AK881X is not set + +# +# Camera sensor devices +# +# CONFIG_VIDEO_OV7670 is not set +# CONFIG_VIDEO_MT9V011 is not set +# CONFIG_VIDEO_TCM825X is not set + +# +# Video improvement chips +# +# CONFIG_VIDEO_UPD64031A is not set +# CONFIG_VIDEO_UPD64083 is not set + +# +# Miscelaneous helper chips +# +# CONFIG_VIDEO_THS7303 is not set +# CONFIG_VIDEO_M52790 is not set +# CONFIG_VIDEO_CPIA2 is not set +# CONFIG_VIDEO_SR030PC30 is not set +# CONFIG_VIDEO_NOON010PC30 is not set +# CONFIG_SOC_CAMERA is not set +# CONFIG_VIDEO_SAMSUNG_S5P_FIMC is not set +CONFIG_SAMSUNG_MFC_DRIVERS=y +CONFIG_USE_LEGACY_MFC=y +# CONFIG_USE_V4L2_MFC is not set +CONFIG_V4L_USB_DRIVERS=y +# CONFIG_USB_VIDEO_CLASS is not set +CONFIG_USB_VIDEO_CLASS_INPUT_EVDEV=y +# CONFIG_USB_GSPCA is not set +# CONFIG_VIDEO_PVRUSB2 is not set +# CONFIG_VIDEO_HDPVR is not set +# CONFIG_VIDEO_EM28XX is not set +# CONFIG_VIDEO_CX231XX is not set +# CONFIG_VIDEO_USBVISION is not set +# CONFIG_USB_ET61X251 is not set +# CONFIG_USB_SN9C102 is not set +# CONFIG_USB_PWC is not set +# CONFIG_USB_ZR364XX is not set +# CONFIG_USB_STKWEBCAM is not set +# CONFIG_USB_S2255 is not set +CONFIG_VIDEO_SAMSUNG=y +CONFIG_VIDEO_SAMSUNG_V4L2=y +CONFIG_VIDEO_FIMC=y +CONFIG_VIDEO_FIMC_RANGE_NARROW=y +# CONFIG_VIDEO_FIMC_RANGE_WIDE is not set +# CONFIG_VIDEO_FIMC_DEBUG is not set +CONFIG_VIDEO_FIMC_MIPI=y +# CONFIG_VIDEO_FIMC_MIPI_IRQ_DEBUG is not set +CONFIG_VIDEO_FIMC_DMA_AUTO=y +# CONFIG_VIDEO_FIMC_FIFO is not set +CONFIG_VIDEO_TVOUT=y +CONFIG_VIDEO_TVOUT_2CH_AUDIO=y +# CONFIG_VIDEO_TVOUT_5_1CH_AUDIO is not set +# CONFIG_HDMI_CEC is not set +CONFIG_HDMI_EARJACK_MUTE=y +CONFIG_HDMI_HPD=y +# CONFIG_HDMI_CONTROLLED_BY_EXT_IC is not set +# CONFIG_HDMI_TX_STRENGTH is not set +CONFIG_HDMI_SWITCH_HPD=y +# CONFIG_ANALOG_TVENC is not set +CONFIG_TV_FB=y +CONFIG_USER_ALLOC_TVOUT=y +# CONFIG_LSI_HDMI_AUDIO_CH_EVENT is not set +# CONFIG_TV_DEBUG is not set +CONFIG_VIDEO_MFC5X=y +CONFIG_VIDEO_MFC_MAX_INSTANCE=4 +CONFIG_VIDEO_MFC_MEM_PORT_COUNT=2 +# CONFIG_VIDEO_MFC5X_DEBUG is not set +CONFIG_VIDEO_MALI400MP=y +# CONFIG_MALI_DED_ONLY is not set +# CONFIG_MALI_DED_MMU is not set +CONFIG_MALI_OSMEM_ONLY=y +# CONFIG_MALI_DED_OSMEM is not set +# CONFIG_MALI_R3P1_LSI is not set +# CONFIG_VIDEO_MALI400MP_DEBUG is not set +CONFIG_VIDEO_MALI400MP_DVFS=y +CONFIG_VIDEO_UMP=y +# CONFIG_UMP_R3P1_LSI is not set +# CONFIG_UMP_DED_ONLY is not set +CONFIG_UMP_OSMEM_ONLY=y +# CONFIG_UMP_VCM_ONLY is not set +CONFIG_UMP_MEM_SIZE=1024 +# CONFIG_VIDEO_UMP_DEBUG is not set +CONFIG_VIDEO_FIMG2D=y +# CONFIG_VIDEO_FIMG2D_DEBUG is not set +CONFIG_VIDEO_FIMG2D3X=y +# CONFIG_VIDEO_FIMG2D3X_DEBUG is not set +CONFIG_VIDEO_JPEG=y +# CONFIG_VIDEO_JPEG_DEBUG is not set + +# +# Reserved memory configurations +# +CONFIG_VIDEO_SAMSUNG_MEMSIZE_FIMC0=5120 +CONFIG_VIDEO_SAMSUNG_MEMSIZE_FIMC1=15360 +CONFIG_VIDEO_SAMSUNG_MEMSIZE_FIMC2=25600 +CONFIG_VIDEO_SAMSUNG_MEMSIZE_FIMC3=7168 +CONFIG_VIDEO_SAMSUNG_MEMSIZE_MFC0=20480 +CONFIG_VIDEO_SAMSUNG_MEMSIZE_MFC1=34816 +CONFIG_VIDEO_SAMSUNG_MEMSIZE_JPEG=20480 +CONFIG_VIDEO_SAMSUNG_MEMSIZE_TVOUT=16384 +# CONFIG_VIDEO_EXYNOS is not set +# CONFIG_V4L_MEM2MEM_DRIVERS is not set + +# +# Mhl(sii9244) device support +# +CONFIG_SAMSUNG_MHL=y +# CONFIG_SAMSUNG_USE_11PIN_CONNECTOR is not set +# CONFIG_SAMSUNG_SMARTDOCK is not set +CONFIG_SAMSUNG_WORKAROUND_HPD_GLANCE=y +# CONFIG_SAMSUNG_MHL_UNPOWERED is not set +# CONFIG_RADIO_ADAPTERS is not set +# CONFIG_TDMB is not set +# CONFIG_ISDBT is not set + +# +# Graphics support +# +# CONFIG_DRM is not set +CONFIG_ION=y +CONFIG_ION_EXYNOS=y +CONFIG_ION_EXYNOS_CONTIGHEAP_SIZE=71680 +# CONFIG_ION_EXYNOS_CONTIGHEAP_DEBUG is not set +# CONFIG_VGASTATE is not set +# CONFIG_VIDEO_OUTPUT_CONTROL is not set +CONFIG_FB=y +# CONFIG_FIRMWARE_EDID is not set +# CONFIG_FB_DDC is not set +# CONFIG_FB_BOOT_VESA_SUPPORT is not set +CONFIG_FB_CFB_FILLRECT=y +CONFIG_FB_CFB_COPYAREA=y +CONFIG_FB_CFB_IMAGEBLIT=y +# CONFIG_FB_CFB_REV_PIXELS_IN_BYTE is not set +# CONFIG_FB_SYS_FILLRECT is not set +# CONFIG_FB_SYS_COPYAREA is not set +# CONFIG_FB_SYS_IMAGEBLIT is not set +# CONFIG_FB_FOREIGN_ENDIAN is not set +# CONFIG_FB_SYS_FOPS is not set +# CONFIG_FB_WMT_GE_ROPS is not set +# CONFIG_FB_SVGALIB is not set +# CONFIG_FB_MACMODES is not set +# CONFIG_FB_BACKLIGHT is not set +# CONFIG_FB_MODE_HELPERS is not set +# CONFIG_FB_TILEBLITTING is not set + +# +# Frame buffer hardware drivers +# +CONFIG_FB_S5P=y +# CONFIG_FB_S5P_SYSMMU is not set +CONFIG_FB_S5P_SPLASH_SCREEN=y +# CONFIG_FB_S5P_LCD_INIT is not set +# CONFIG_FB_S5P_DEBUG is not set +CONFIG_FB_S5P_VSYNC_THREAD=y +# CONFIG_FB_S5P_VSYNC_SEND_UEVENTS is not set +CONFIG_FB_S5P_VSYNC_SYSFS=y +# CONFIG_FB_S5P_TRACE_UNDERRUN is not set +CONFIG_FB_S5P_DEFAULT_WINDOW=2 +CONFIG_FB_S5P_NR_BUFFERS=2 +# CONFIG_FB_S5P_VIRTUAL is not set +CONFIG_VIDEO_SAMSUNG_MEMSIZE_FIMD=12000 +CONFIG_FB_S5P_MDNIE=y +# CONFIG_FB_MDNIE_PWM is not set +# CONFIG_FB_S5P_MIPI_DSIM is not set +CONFIG_FB_BGRA_ORDER=y +# CONFIG_FB_RGBA_ORDER is not set +CONFIG_FB_S5P_LD9040=y +# CONFIG_FB_S5P_NT35560 is not set +# CONFIG_FB_S5P_EXTDSP is not set +# CONFIG_S5P_DSIM_SWITCHABLE_DUAL_LCD is not set +# CONFIG_FB_S1D13XXX is not set +# CONFIG_FB_TMIO is not set +# CONFIG_FB_S3C is not set +# CONFIG_S5P_MIPI_DSI2 is not set +# CONFIG_FB_UDL is not set +# CONFIG_FB_VIRTUAL is not set +# CONFIG_FB_METRONOME is not set +# CONFIG_FB_BROADSHEET is not set +CONFIG_BACKLIGHT_LCD_SUPPORT=y +CONFIG_LCD_CLASS_DEVICE=y +# CONFIG_LCD_L4F00242T03 is not set +# CONFIG_LCD_LMS283GF05 is not set +# CONFIG_LCD_LTV350QV is not set +# CONFIG_LCD_TDO24M is not set +# CONFIG_LCD_VGG2432A4 is not set +# CONFIG_LCD_PLATFORM is not set +# CONFIG_LCD_S6E63M0 is not set +# CONFIG_LCD_MIPI_S6E63M0 is not set +# CONFIG_LCD_MIPI_S6E8AB0 is not set +# CONFIG_LCD_MIPI_TC358764 is not set +# CONFIG_LCD_LD9040 is not set +# CONFIG_LCD_WA101S is not set +# CONFIG_LCD_LTE480WV is not set +CONFIG_BACKLIGHT_CLASS_DEVICE=y +# CONFIG_BACKLIGHT_GENERIC is not set +# CONFIG_BACKLIGHT_PWM is not set +# CONFIG_BACKLIGHT_ADP8860 is not set +# CONFIG_BACKLIGHT_ADP8870 is not set + +# +# Display device support +# +# CONFIG_DISPLAY_SUPPORT is not set + +# +# Console display driver support +# +CONFIG_DUMMY_CONSOLE=y +# CONFIG_FRAMEBUFFER_CONSOLE is not set +# CONFIG_LOGO is not set +CONFIG_SOUND=y +# CONFIG_SOUND_OSS_CORE is not set +CONFIG_SND=y +CONFIG_SND_TIMER=y +CONFIG_SND_PCM=y +CONFIG_SND_HWDEP=y +CONFIG_SND_JACK=y +# CONFIG_SND_SEQUENCER is not set +# CONFIG_SND_MIXER_OSS is not set +# CONFIG_SND_PCM_OSS is not set +# CONFIG_SND_HRTIMER is not set +# CONFIG_SND_DYNAMIC_MINORS is not set +# CONFIG_SND_SUPPORT_OLD_API is not set +# CONFIG_SND_VERBOSE_PROCFS is not set +# CONFIG_SND_VERBOSE_PRINTK is not set +# CONFIG_SND_DEBUG is not set +# CONFIG_SND_RAWMIDI_SEQ is not set +# CONFIG_SND_OPL3_LIB_SEQ is not set +# CONFIG_SND_OPL4_LIB_SEQ is not set +# CONFIG_SND_SBAWE_SEQ is not set +# CONFIG_SND_EMU10K1_SEQ is not set +# CONFIG_SND_DRIVERS is not set +# CONFIG_SND_ARM is not set +# CONFIG_SND_SPI is not set +CONFIG_SND_USB=y +# CONFIG_SND_USB_AUDIO is not set +# CONFIG_SND_USB_UA101 is not set +# CONFIG_SND_USB_CAIAQ is not set +# CONFIG_SND_USB_6FIRE is not set +CONFIG_SND_SOC=y +# CONFIG_SND_SOC_CACHE_LZO is not set +CONFIG_SND_SOC_SAMSUNG=y +CONFIG_SND_SAMSUNG_I2S=y +CONFIG_SND_SOC_U1_MC1N2=y +# CONFIG_SND_SOC_SAMSUNG_USE_DMA_WRAPPER is not set +# CONFIG_SND_SAMSUNG_NORMAL is not set +# CONFIG_SND_SAMSUNG_LP is not set +# CONFIG_SND_SAMSUNG_ALP is not set +CONFIG_SND_SAMSUNG_RP=y +CONFIG_AUDIO_SAMSUNG_MEMSIZE_SRP=1024 +# CONFIG_SND_SAMSUNG_RP_DEBUG is not set +# CONFIG_SND_SAMSUNG_I2S_MASTER is not set +# CONFIG_SND_DUOS_MODEM_SWITCH is not set +# CONFIG_SND_USE_SUB_MIC is not set +# CONFIG_SND_USE_THIRD_MIC is not set +# CONFIG_SND_USE_STEREO_SPEAKER is not set +# CONFIG_SND_USE_LINEOUT_SWITCH is not set +# CONFIG_SND_USE_MUIC_SWITCH is not set +CONFIG_SND_SOC_I2C_AND_SPI=y +# CONFIG_SND_SOC_ALL_CODECS is not set +CONFIG_SND_SOC_MC1N2=y +CONFIG_SND_SOC_USE_EXTERNAL_MIC_BIAS=y +# CONFIG_SND_SOC_MC1N2_DEBUG is not set +# CONFIG_SOUND_PRIME is not set +CONFIG_HID_SUPPORT=y +CONFIG_HID=y +# CONFIG_HIDRAW is not set +CONFIG_UHID=y + +# +# USB Input Devices +# +CONFIG_USB_HID=y +# CONFIG_HID_PID is not set +# CONFIG_USB_HIDDEV is not set + +# +# Special HID drivers +# +# CONFIG_HID_A4TECH is not set +# CONFIG_HID_ACRUX is not set +# CONFIG_HID_APPLE is not set +# CONFIG_HID_BELKIN is not set +# CONFIG_HID_CHERRY is not set +# CONFIG_HID_CHICONY is not set +# CONFIG_HID_PRODIKEYS is not set +# CONFIG_HID_CYPRESS is not set +# CONFIG_HID_DRAGONRISE is not set +# CONFIG_HID_EMS_FF is not set +# CONFIG_HID_ELECOM is not set +# CONFIG_HID_EZKEY is not set +# CONFIG_HID_KEYTOUCH is not set +# CONFIG_HID_KYE is not set +# CONFIG_HID_UCLOGIC is not set +# CONFIG_HID_WALTOP is not set +# CONFIG_HID_GYRATION is not set +# CONFIG_HID_TWINHAN is not set +# CONFIG_HID_KENSINGTON is not set +# CONFIG_HID_LCPOWER is not set +# CONFIG_HID_LOGITECH is not set +# CONFIG_HID_MAGICMOUSE is not set +# CONFIG_HID_MICROSOFT is not set +# CONFIG_HID_MONTEREY is not set +# CONFIG_HID_MULTITOUCH is not set +# CONFIG_HID_NTRIG is not set +# CONFIG_HID_ORTEK is not set +# CONFIG_HID_PANTHERLORD is not set +# CONFIG_HID_PETALYNX is not set +# CONFIG_HID_PICOLCD is not set +# CONFIG_HID_QUANTA is not set +# CONFIG_HID_ROCCAT is not set +# CONFIG_HID_ROCCAT_ARVO is not set +# CONFIG_HID_ROCCAT_KONE is not set +# CONFIG_HID_ROCCAT_KONEPLUS is not set +# CONFIG_HID_ROCCAT_KOVAPLUS is not set +# CONFIG_HID_ROCCAT_PYRA is not set +# CONFIG_HID_SAMSUNG is not set +# CONFIG_HID_SONY is not set +# CONFIG_HID_SUNPLUS is not set +# CONFIG_HID_GREENASIA is not set +# CONFIG_HID_SMARTJOYPLUS is not set +# CONFIG_HID_TOPSEED is not set +# CONFIG_HID_THRUSTMASTER is not set +# CONFIG_HID_WACOM is not set +# CONFIG_HID_ZEROPLUS is not set +# CONFIG_HID_ZYDACRON is not set +CONFIG_USB_SUPPORT=y +CONFIG_USB_ARCH_HAS_HCD=y +CONFIG_USB_ARCH_HAS_OHCI=y +CONFIG_USB_ARCH_HAS_EHCI=y +CONFIG_USB_ARCH_HAS_XHCI=y +CONFIG_USB=y +# CONFIG_USB_DEBUG is not set +CONFIG_USB_ANNOUNCE_NEW_DEVICES=y + +# +# Miscellaneous USB options +# +CONFIG_USB_DEVICEFS=y +CONFIG_USB_DEVICE_CLASS=y +# CONFIG_USB_DYNAMIC_MINORS is not set +CONFIG_USB_SUSPEND=y +# CONFIG_USB_OTG is not set +# CONFIG_USB_OTG_WHITELIST is not set +# CONFIG_USB_OTG_BLACKLIST_HUB is not set +# CONFIG_HOST_COMPLIANT_TEST is not set +CONFIG_USB_HOST_NOTIFY=y +CONFIG_USB_MON=y +# CONFIG_USB_WUSB is not set +# CONFIG_USB_WUSB_CBAF is not set + +# +# USB Host Controller Drivers +# +# CONFIG_USB_C67X00_HCD is not set +# CONFIG_USB_XHCI_HCD is not set +CONFIG_USB_EHCI_HCD=y +# CONFIG_USB_EHCI_ROOT_HUB_TT is not set +CONFIG_USB_EHCI_TT_NEWSCHED=y +CONFIG_USB_EHCI_S5P=y +CONFIG_USB_S5P_HSIC0=y +CONFIG_USB_S5P_HSIC1=y +# CONFIG_USB_OXU210HP_HCD is not set +# CONFIG_USB_ISP116X_HCD is not set +# CONFIG_USB_ISP1760_HCD is not set +# CONFIG_USB_ISP1362_HCD is not set +# CONFIG_USB_OHCI_HCD is not set +# CONFIG_USB_SL811_HCD is not set +# CONFIG_USB_R8A66597_HCD is not set +# CONFIG_USB_HWA_HCD is not set +CONFIG_USB_S3C_OTG_HOST=y +# CONFIG_USB_MUSB_HDRC is not set + +# +# USB Device Class drivers +# +# CONFIG_USB_ACM is not set +# CONFIG_USB_PRINTER is not set +# CONFIG_USB_WDM is not set +# CONFIG_USB_TMC is not set + +# +# NOTE: USB_STORAGE depends on SCSI but BLK_DEV_SD may +# + +# +# also be needed; see USB_STORAGE Help for more info +# +CONFIG_USB_STORAGE=y +# CONFIG_USB_STORAGE_DEBUG is not set +# CONFIG_USB_STORAGE_REALTEK is not set +# CONFIG_USB_STORAGE_DATAFAB is not set +# CONFIG_USB_STORAGE_FREECOM is not set +# CONFIG_USB_STORAGE_ISD200 is not set +# CONFIG_USB_STORAGE_USBAT is not set +# CONFIG_USB_STORAGE_SDDR09 is not set +# CONFIG_USB_STORAGE_SDDR55 is not set +# CONFIG_USB_STORAGE_JUMPSHOT is not set +# CONFIG_USB_STORAGE_ALAUDA is not set +# CONFIG_USB_STORAGE_ONETOUCH is not set +# CONFIG_USB_STORAGE_KARMA is not set +# CONFIG_USB_STORAGE_CYPRESS_ATACB is not set +# CONFIG_USB_STORAGE_ENE_UB6250 is not set +# CONFIG_USB_LIBUSUAL is not set + +# +# USB Imaging devices +# +# CONFIG_USB_MDC800 is not set +# CONFIG_USB_MICROTEK is not set + +# +# USB port drivers +# +# CONFIG_USB_SERIAL is not set + +# +# USB Miscellaneous drivers +# +# CONFIG_USB_EMI62 is not set +# CONFIG_USB_EMI26 is not set +# CONFIG_USB_ADUTUX is not set +# CONFIG_USB_SEVSEG is not set +# CONFIG_USB_RIO500 is not set +# CONFIG_USB_LEGOTOWER is not set +# CONFIG_USB_LCD is not set +# CONFIG_USB_LED is not set +# CONFIG_USB_CYPRESS_CY7C63 is not set +# CONFIG_USB_CYTHERM is not set +# CONFIG_USB_IDMOUSE is not set +# CONFIG_USB_FTDI_ELAN is not set +# CONFIG_USB_APPLEDISPLAY is not set +# CONFIG_USB_SISUSBVGA is not set +# CONFIG_USB_LD is not set +# CONFIG_USB_TRANCEVIBRATOR is not set +# CONFIG_USB_IOWARRIOR is not set +# CONFIG_USB_TEST is not set +# CONFIG_USB_ISIGHTFW is not set +# CONFIG_USB_YUREX is not set +# CONFIG_USB_QCOM_DIAG_BRIDGE is not set +# CONFIG_USB_QCOM_MDM_BRIDGE is not set +CONFIG_USB_GADGET=y +# CONFIG_USB_GADGET_DEBUG is not set +# CONFIG_USB_GADGET_DEBUG_FILES is not set +# CONFIG_USB_GADGET_DEBUG_FS is not set +CONFIG_USB_GADGET_VBUS_DRAW=2 +CONFIG_USB_GADGET_SELECTED=y +# CONFIG_USB_GADGET_FUSB300 is not set +# CONFIG_USB_GADGET_R8A66597 is not set +CONFIG_USB_GADGET_S3C_OTGD=y +# CONFIG_USB_GADGET_PXA_U2O is not set +# CONFIG_USB_GADGET_M66592 is not set +# CONFIG_USB_GADGET_DUMMY_HCD is not set + +# +# NOTE: S3C OTG device role enables the controller driver below +# +CONFIG_USB_S3C_OTGD=y +CONFIG_USB_GADGET_DUALSPEED=y +# CONFIG_USB_ZERO is not set +# CONFIG_USB_AUDIO is not set +# CONFIG_USB_ETH is not set +# CONFIG_USB_G_NCM is not set +# CONFIG_USB_GADGETFS is not set +# CONFIG_USB_FUNCTIONFS is not set +# CONFIG_USB_FILE_STORAGE is not set +# CONFIG_USB_MASS_STORAGE is not set +# CONFIG_USB_G_SERIAL is not set +# CONFIG_USB_MIDI_GADGET is not set +# CONFIG_USB_G_PRINTER is not set +# CONFIG_USB_G_SLP is not set +CONFIG_USB_G_ANDROID=y +# CONFIG_USB_ANDROID_SAMSUNG_COMPOSITE is not set +# CONFIG_USB_ANDROID_SAMSUNG_MTP is not set +CONFIG_USB_DUN_SUPPORT=y +# CONFIG_USB_ANDROID is not set +# CONFIG_USB_CDC_COMPOSITE is not set +# CONFIG_USB_G_NOKIA is not set +# CONFIG_USB_G_MULTI is not set +# CONFIG_USB_G_HID is not set +# CONFIG_USB_G_DBGP is not set +# CONFIG_USB_G_WEBCAM is not set + +# +# OTG and related infrastructure +# +# CONFIG_USB_OTG_WAKELOCK is not set +# CONFIG_USB_GPIO_VBUS is not set +# CONFIG_USB_ULPI is not set +# CONFIG_NOP_USB_XCEIV is not set +CONFIG_MMC=y +# CONFIG_MMC_DEBUG is not set +CONFIG_MMC_UNSAFE_RESUME=y +CONFIG_MMC_CLKGATE=y +CONFIG_MMC_EMBEDDED_SDIO=y +# CONFIG_MMC_PARANOID_SD_INIT is not set +# CONFIG_MMC_NOT_USE_SANITIZE is not set +# CONFIG_MMC_POLLING_WAIT_CMD23 is not set + +# +# MMC/SD/SDIO Card Drivers +# +CONFIG_MMC_BLOCK=y +CONFIG_MMC_BLOCK_MINORS=8 +CONFIG_MMC_BLOCK_BOUNCE=y +# CONFIG_MMC_BLOCK_DEFERRED_RESUME is not set +# CONFIG_SDIO_UART is not set +# CONFIG_MMC_TEST is not set +# CONFIG_MMC_SELECTIVE_PACKED_CMD_POLICY is not set +# CONFIG_MMC_CPRM is not set + +# +# MMC/SD/SDIO Host Controller Drivers +# +CONFIG_MMC_MSHCI=y +# CONFIG_MMC_MSHCI_S3C_DMA_MAP is not set +# CONFIG_MMC_MSHCI_ASYNC_OPS is not set +# CONFIG_MMC_MSHCI_ENABLE_CACHE is not set +CONFIG_MMC_SDHCI=y +# CONFIG_MMC_SDHCI_PLTFM is not set +CONFIG_MMC_SDHCI_S3C=y +CONFIG_MMC_SDHCI_S3C_DMA=y +# CONFIG_MMC_DW is not set +# CONFIG_MMC_VUB300 is not set +# CONFIG_MMC_USHC is not set +# CONFIG_MEMSTICK is not set +# CONFIG_LEDS_SPFCW043 is not set +CONFIG_NEW_LEDS=y +CONFIG_LEDS_CLASS=y + +# +# LED drivers +# +# CONFIG_LEDS_LM3530 is not set +# CONFIG_LEDS_PCA9532 is not set +CONFIG_LEDS_GPIO=y +CONFIG_LEDS_GPIO_PLATFORM=y +# CONFIG_LEDS_LP3944 is not set +# CONFIG_LEDS_AN30259A is not set +# CONFIG_LEDS_LP5521 is not set +# CONFIG_LEDS_LP5523 is not set +# CONFIG_LEDS_PCA955X is not set +# CONFIG_LEDS_DAC124S085 is not set +# CONFIG_LEDS_PWM is not set +# CONFIG_LEDS_REGULATOR is not set +# CONFIG_LEDS_MAX8997 is not set +# CONFIG_LEDS_BD2802 is not set +# CONFIG_LEDS_LT3593 is not set +# CONFIG_LEDS_SWITCH is not set +# CONFIG_LEDS_AAT1290A is not set +CONFIG_LEDS_TRIGGERS=y + +# +# LED Triggers +# +CONFIG_LEDS_TRIGGER_TIMER=y +# CONFIG_LEDS_TRIGGER_HEARTBEAT is not set +# CONFIG_LEDS_TRIGGER_BACKLIGHT is not set +# CONFIG_LEDS_TRIGGER_GPIO is not set +CONFIG_LEDS_TRIGGER_DEFAULT_ON=y +# CONFIG_LEDS_TRIGGER_SLEEP is not set +CONFIG_LEDS_TRIGGER_NOTIFICATION=y + +# +# iptables trigger is under Netfilter config (LED target) +# +# CONFIG_NFC_DEVICES is not set +CONFIG_SWITCH=y +CONFIG_SWITCH_GPIO=y +# CONFIG_ACCESSIBILITY is not set +CONFIG_RTC_LIB=y +CONFIG_RTC_CLASS=y +CONFIG_RTC_HCTOSYS=y +CONFIG_RTC_HCTOSYS_DEVICE="rtc0" +# CONFIG_RTC_DEBUG is not set + +# +# RTC interfaces +# +CONFIG_RTC_INTF_SYSFS=y +CONFIG_RTC_INTF_PROC=y +CONFIG_RTC_INTF_DEV=y +# CONFIG_RTC_INTF_DEV_UIE_EMUL is not set +CONFIG_RTC_INTF_ALARM=y +CONFIG_RTC_INTF_ALARM_DEV=y +# CONFIG_RTC_ALARM_BOOT is not set +# CONFIG_RTC_POWER_OFF is not set +# CONFIG_RTC_DRV_TEST is not set + +# +# I2C RTC drivers +# +# CONFIG_RTC_DRV_DS1307 is not set +# CONFIG_RTC_DRV_DS1374 is not set +# CONFIG_RTC_DRV_DS1672 is not set +# CONFIG_RTC_DRV_DS3232 is not set +# CONFIG_RTC_DRV_MAX6900 is not set +CONFIG_RTC_DRV_MAX8997=y +# CONFIG_RTC_DRV_RS5C372 is not set +# CONFIG_RTC_DRV_ISL1208 is not set +# CONFIG_RTC_DRV_ISL12022 is not set +# CONFIG_RTC_DRV_X1205 is not set +# CONFIG_RTC_DRV_PCF8563 is not set +# CONFIG_RTC_DRV_PCF8583 is not set +# CONFIG_RTC_DRV_M41T80 is not set +# CONFIG_RTC_DRV_BQ32K is not set +# CONFIG_RTC_DRV_S35390A is not set +# CONFIG_RTC_DRV_FM3130 is not set +# CONFIG_RTC_DRV_RX8581 is not set +# CONFIG_RTC_DRV_RX8025 is not set +# CONFIG_RTC_DRV_EM3027 is not set +# CONFIG_RTC_DRV_RV3029C2 is not set + +# +# SPI RTC drivers +# +# CONFIG_RTC_DRV_M41T93 is not set +# CONFIG_RTC_DRV_M41T94 is not set +# CONFIG_RTC_DRV_DS1305 is not set +# CONFIG_RTC_DRV_DS1390 is not set +# CONFIG_RTC_DRV_MAX6902 is not set +# CONFIG_RTC_DRV_R9701 is not set +# CONFIG_RTC_DRV_RS5C348 is not set +# CONFIG_RTC_DRV_DS3234 is not set +# CONFIG_RTC_DRV_PCF2123 is not set + +# +# Platform RTC drivers +# +# CONFIG_RTC_DRV_CMOS is not set +# CONFIG_RTC_DRV_DS1286 is not set +# CONFIG_RTC_DRV_DS1511 is not set +# CONFIG_RTC_DRV_DS1553 is not set +# CONFIG_RTC_DRV_DS1742 is not set +# CONFIG_RTC_DRV_STK17TA8 is not set +# CONFIG_RTC_DRV_M48T86 is not set +# CONFIG_RTC_DRV_M48T35 is not set +# CONFIG_RTC_DRV_M48T59 is not set +# CONFIG_RTC_DRV_MSM6242 is not set +# CONFIG_RTC_DRV_BQ4802 is not set +# CONFIG_RTC_DRV_RP5C01 is not set +# CONFIG_RTC_DRV_V3020 is not set + +# +# on-CPU RTC drivers +# +CONFIG_HAVE_S3C_RTC=y +CONFIG_RTC_DRV_S3C=y +# CONFIG_DMADEVICES is not set +# CONFIG_AUXDISPLAY is not set +# CONFIG_UIO is not set +CONFIG_STAGING=y +# CONFIG_VIDEO_TM6000 is not set +# CONFIG_USBIP_CORE is not set +# CONFIG_PRISM2_USB is not set +# CONFIG_ECHO is not set +# CONFIG_BRCMUTIL is not set +# CONFIG_ASUS_OLED is not set +# CONFIG_R8712U is not set +# CONFIG_TRANZPORT is not set + +# +# Android +# +CONFIG_ANDROID=y +CONFIG_ANDROID_BINDER_IPC=y +CONFIG_ANDROID_LOGGER=y +CONFIG_ANDROID_RAM_CONSOLE=y +CONFIG_ANDROID_RAM_CONSOLE_ENABLE_VERBOSE=y +CONFIG_ANDROID_RAM_CONSOLE_ERROR_CORRECTION=y +CONFIG_ANDROID_RAM_CONSOLE_ERROR_CORRECTION_DATA_SIZE=128 +CONFIG_ANDROID_RAM_CONSOLE_ERROR_CORRECTION_ECC_SIZE=16 +CONFIG_ANDROID_RAM_CONSOLE_ERROR_CORRECTION_SYMBOL_SIZE=8 +CONFIG_ANDROID_RAM_CONSOLE_ERROR_CORRECTION_POLYNOMIAL=0x11d +# CONFIG_ANDROID_RAM_CONSOLE_EARLY_INIT is not set +CONFIG_ANDROID_TIMED_OUTPUT=y +CONFIG_ANDROID_TIMED_GPIO=y +CONFIG_ANDROID_LOW_MEMORY_KILLER=y +# CONFIG_POHMELFS is not set +# CONFIG_LINE6_USB is not set +# CONFIG_VT6656 is not set +# CONFIG_IIO is not set +# CONFIG_XVMALLOC is not set +# CONFIG_ZRAM is not set +# CONFIG_FB_SM7XX is not set +# CONFIG_LIRC_STAGING is not set +# CONFIG_EASYCAP is not set +CONFIG_WESTBRIDGE=y +CONFIG_WESTBRIDGE_ASTORIA=y +CONFIG_WESTBRIDGE_DEVICE_DRIVER=y +# CONFIG_WESTBRIDGE_BLOCK_DRIVER is not set +# CONFIG_WESTBRIDGE_GADGET_DRIVER is not set +CONFIG_WESTBRIDGE_SWITCH_DRIVER=m +CONFIG_WESTBRIDGE_HAL_SELECTED=y +CONFIG_MACH_C110_WESTBRIDGE_AST_PNAND_HAL=y +# CONFIG_MACH_NO_WESTBRIDGE is not set +CONFIG_WESTBRIDGE_DEBUG=y +# CONFIG_ATH6K_LEGACY is not set +# CONFIG_USB_ENESTORAGE is not set +# CONFIG_BCM_WIMAX is not set +# CONFIG_FT1000 is not set + +# +# Speakup console speech +# +# CONFIG_SPEAKUP is not set +# CONFIG_TOUCHSCREEN_CLEARPAD_TM1217 is not set +# CONFIG_TOUCHSCREEN_SYNAPTICS_I2C_RMI4 is not set + +# +# Altera FPGA firmware download module +# +# CONFIG_ALTERA_STAPL is not set +CONFIG_CLKDEV_LOOKUP=y +CONFIG_VIBETONZ=y +CONFIG_MOTOR_DRV_MAX8997=y +# CONFIG_MOTOR_DRV_ISA1200 is not set +# CONFIG_FM_RADIO is not set +CONFIG_SENSORS_CORE=y +CONFIG_SENSORS_AK8975C=y +# CONFIG_SENSORS_AK8963C is not set +# CONFIG_SENSORS_BMP180 is not set +CONFIG_SENSORS_CM3663=y +# CONFIG_SENSORS_PAS2M110 is not set +# CONFIG_SENSORS_BMA254 is not set +# CONFIG_SENSORS_TAOS is not set +# CONFIG_SENSORS_GP2A is not set +# CONFIG_SENSORS_GP2A_ANALOG is not set +# CONFIG_SENSORS_CM36651 is not set +# CONFIG_SENSORS_BH1721 is not set +# CONFIG_SENSORS_AL3201 is not set +CONFIG_SENSORS_K3DH=y +CONFIG_SENSORS_K3G=y +# CONFIG_SENSORS_LSM330DLC is not set +# CONFIG_SENSORS_LPS331 is not set +# CONFIG_SENSORS_SYSFS is not set +# CONFIG_SENSORS_SSP is not set +# CONFIG_SENSORS_SSP_LSM330 is not set +# CONFIG_SENSORS_SSP_AK8963C is not set +# CONFIG_SENSORS_SSP_CM36651 is not set +# CONFIG_SENSORS_SSP_BMP182 is not set +# CONFIG_SENSORS_SSP_AT32UC3L0128 is not set +# CONFIG_SENSORS_SSP_SENSORHUB is not set +# CONFIG_PM_DEVFREQ is not set +# CONFIG_SAMSUNG_PHONE_SVNET is not set +CONFIG_ACCESSORY=y +# CONFIG_30PIN_CONN is not set +# CONFIG_MHL_SII9234 is not set +# CONFIG_SEC_KEYBOARD_DOCK is not set +# CONFIG_HPD_PULL is not set +# CONFIG_SAMSUNG_MHL_9290 is not set +# CONFIG_IR_REMOCON is not set +# CONFIG_EXTCON is not set +# CONFIG_BARCODE_EMUL is not set +CONFIG_SAMSUNG_PHONE_TTY=y +CONFIG_SAMSUNG_PHONE_TTY_RAFFAELLO=y +CONFIG_SAMSUNG_PHONE_TTY_RAFFAELLO_RECOVERY=y +CONFIG_IOMMU_SUPPORT=y +# CONFIG_FELICA is not set +# CONFIG_AUTHENTEC_VPNCLIENT_INTERCEPTOR is not set + +# +# File systems +# +CONFIG_EXT2_FS=y +# CONFIG_EXT2_FS_XATTR is not set +# CONFIG_EXT2_FS_XIP is not set +# CONFIG_EXT3_FS is not set +CONFIG_EXT4_FS=y +CONFIG_EXT4_USE_FOR_EXT23=y +# CONFIG_EXT4_FS_XATTR is not set +# CONFIG_EXT4_DEBUG is not set +CONFIG_JBD2=y +# CONFIG_JBD2_DEBUG is not set +# CONFIG_REISERFS_FS is not set +# CONFIG_JFS_FS is not set +# CONFIG_XFS_FS is not set +# CONFIG_GFS2_FS is not set +# CONFIG_BTRFS_FS is not set +# CONFIG_NILFS2_FS is not set +CONFIG_FS_POSIX_ACL=y +CONFIG_FILE_LOCKING=y +CONFIG_FSNOTIFY=y +# CONFIG_DNOTIFY is not set +CONFIG_INOTIFY_USER=y +# CONFIG_FANOTIFY is not set +# CONFIG_QUOTA is not set +# CONFIG_QUOTACTL is not set +# CONFIG_AUTOFS4_FS is not set +CONFIG_FUSE_FS=y +# CONFIG_CUSE is not set +CONFIG_GENERIC_ACL=y + +# +# Caches +# +# CONFIG_FSCACHE is not set + +# +# CD-ROM/DVD Filesystems +# +# CONFIG_ISO9660_FS is not set +# CONFIG_UDF_FS is not set + +# +# DOS/FAT/NT Filesystems +# +CONFIG_FAT_FS=y +CONFIG_MSDOS_FS=y +CONFIG_VFAT_FS=y +CONFIG_FAT_DEFAULT_CODEPAGE=437 +CONFIG_FAT_DEFAULT_IOCHARSET="iso8859-1" +# CONFIG_NTFS_FS is not set + +# +# Pseudo filesystems +# +CONFIG_PROC_FS=y +CONFIG_PROC_SYSCTL=y +CONFIG_PROC_PAGE_MONITOR=y +CONFIG_SYSFS=y +CONFIG_TMPFS=y +CONFIG_TMPFS_POSIX_ACL=y +CONFIG_TMPFS_XATTR=y +# CONFIG_HUGETLB_PAGE is not set +# CONFIG_CONFIGFS_FS is not set +CONFIG_MISC_FILESYSTEMS=y +# CONFIG_ADFS_FS is not set +# CONFIG_AFFS_FS is not set +CONFIG_ECRYPT_FS=y +CONFIG_WTL_ENCRYPTION_FILTER=y +# CONFIG_HFS_FS is not set +# CONFIG_HFSPLUS_FS is not set +# CONFIG_BEFS_FS is not set +# CONFIG_BFS_FS is not set +# CONFIG_EFS_FS is not set +# CONFIG_LOGFS is not set +# CONFIG_CRAMFS is not set +# CONFIG_SQUASHFS is not set +# CONFIG_VXFS_FS is not set +# CONFIG_MINIX_FS is not set +# CONFIG_OMFS_FS is not set +# CONFIG_HPFS_FS is not set +# CONFIG_QNX4FS_FS is not set +# CONFIG_ROMFS_FS is not set +# CONFIG_PSTORE is not set +# CONFIG_SYSV_FS is not set +# CONFIG_UFS_FS is not set +CONFIG_NETWORK_FILESYSTEMS=y +CONFIG_NFS_FS=m +CONFIG_NFS_V3=y +# CONFIG_NFS_V3_ACL is not set +CONFIG_NFS_V4=y +# CONFIG_NFS_V4_1 is not set +# CONFIG_NFS_USE_LEGACY_DNS is not set +CONFIG_NFS_USE_KERNEL_DNS=y +# CONFIG_NFS_USE_NEW_IDMAPPER is not set +# CONFIG_NFSD is not set +CONFIG_LOCKD=m +CONFIG_LOCKD_V4=y +CONFIG_NFS_COMMON=y +CONFIG_SUNRPC=m +CONFIG_SUNRPC_GSS=m +# CONFIG_CEPH_FS is not set +CONFIG_CIFS=m +CONFIG_CIFS_STATS=y +CONFIG_CIFS_STATS2=y +CONFIG_CIFS_WEAK_PW_HASH=y +CONFIG_CIFS_UPCALL=y +CONFIG_CIFS_XATTR=y +CONFIG_CIFS_POSIX=y +# CONFIG_CIFS_DEBUG2 is not set +CONFIG_CIFS_DFS_UPCALL=y +CONFIG_CIFS_ACL=y +# CONFIG_NCP_FS is not set +# CONFIG_CODA_FS is not set +# CONFIG_AFS_FS is not set + +# +# Partition Types +# +CONFIG_PARTITION_ADVANCED=y +# CONFIG_ACORN_PARTITION is not set +# CONFIG_OSF_PARTITION is not set +# CONFIG_AMIGA_PARTITION is not set +# CONFIG_ATARI_PARTITION is not set +# CONFIG_MAC_PARTITION is not set +CONFIG_MSDOS_PARTITION=y +# CONFIG_BSD_DISKLABEL is not set +# CONFIG_MINIX_SUBPARTITION is not set +# CONFIG_SOLARIS_X86_PARTITION is not set +# CONFIG_UNIXWARE_DISKLABEL is not set +# CONFIG_LDM_PARTITION is not set +# CONFIG_SGI_PARTITION is not set +# CONFIG_ULTRIX_PARTITION is not set +# CONFIG_SUN_PARTITION is not set +# CONFIG_KARMA_PARTITION is not set +CONFIG_EFI_PARTITION=y +# CONFIG_SYSV68_PARTITION is not set +CONFIG_NLS=y +CONFIG_NLS_DEFAULT="iso8859-1" +CONFIG_NLS_CODEPAGE_437=y +# CONFIG_NLS_CODEPAGE_737 is not set +# CONFIG_NLS_CODEPAGE_775 is not set +# CONFIG_NLS_CODEPAGE_850 is not set +# CONFIG_NLS_CODEPAGE_852 is not set +# CONFIG_NLS_CODEPAGE_855 is not set +# CONFIG_NLS_CODEPAGE_857 is not set +# CONFIG_NLS_CODEPAGE_860 is not set +# CONFIG_NLS_CODEPAGE_861 is not set +# CONFIG_NLS_CODEPAGE_862 is not set +# CONFIG_NLS_CODEPAGE_863 is not set +# CONFIG_NLS_CODEPAGE_864 is not set +# CONFIG_NLS_CODEPAGE_865 is not set +# CONFIG_NLS_CODEPAGE_866 is not set +# CONFIG_NLS_CODEPAGE_869 is not set +# CONFIG_NLS_CODEPAGE_936 is not set +# CONFIG_NLS_CODEPAGE_950 is not set +# CONFIG_NLS_CODEPAGE_932 is not set +# CONFIG_NLS_CODEPAGE_949 is not set +# CONFIG_NLS_CODEPAGE_874 is not set +# CONFIG_NLS_ISO8859_8 is not set +# CONFIG_NLS_CODEPAGE_1250 is not set +# CONFIG_NLS_CODEPAGE_1251 is not set +CONFIG_NLS_ASCII=y +CONFIG_NLS_ISO8859_1=y +# CONFIG_NLS_ISO8859_2 is not set +# CONFIG_NLS_ISO8859_3 is not set +# CONFIG_NLS_ISO8859_4 is not set +# CONFIG_NLS_ISO8859_5 is not set +# CONFIG_NLS_ISO8859_6 is not set +# CONFIG_NLS_ISO8859_7 is not set +# CONFIG_NLS_ISO8859_9 is not set +# CONFIG_NLS_ISO8859_13 is not set +# CONFIG_NLS_ISO8859_14 is not set +# CONFIG_NLS_ISO8859_15 is not set +# CONFIG_NLS_KOI8_R is not set +# CONFIG_NLS_KOI8_U is not set +CONFIG_NLS_UTF8=y + +# +# Kernel hacking +# +CONFIG_PRINTK_TIME=y +CONFIG_PRINTK_CPU_ID=y +# CONFIG_PRINTK_PID is not set +CONFIG_DEFAULT_MESSAGE_LOGLEVEL=4 +CONFIG_ENABLE_WARN_DEPRECATED=y +CONFIG_ENABLE_MUST_CHECK=y +CONFIG_FRAME_WARN=1024 +CONFIG_MAGIC_SYSRQ=y +# CONFIG_STRIP_ASM_SYMS is not set +# CONFIG_UNUSED_SYMBOLS is not set +CONFIG_DEBUG_FS=y +# CONFIG_HEADERS_CHECK is not set +# CONFIG_DEBUG_SECTION_MISMATCH is not set +CONFIG_DEBUG_KERNEL=y +# CONFIG_DEBUG_SHIRQ is not set +CONFIG_LOCKUP_DETECTOR=y +# CONFIG_HARDLOCKUP_DETECTOR is not set +CONFIG_BOOTPARAM_HARDLOCKUP_PANIC=y +CONFIG_BOOTPARAM_HARDLOCKUP_PANIC_VALUE=1 +CONFIG_BOOTPARAM_SOFTLOCKUP_PANIC=y +CONFIG_BOOTPARAM_SOFTLOCKUP_PANIC_VALUE=1 +CONFIG_DETECT_HUNG_TASK=y +CONFIG_DEFAULT_HUNG_TASK_TIMEOUT=120 +CONFIG_BOOTPARAM_HUNG_TASK_PANIC=y +CONFIG_BOOTPARAM_HUNG_TASK_PANIC_VALUE=1 +CONFIG_SCHED_DEBUG=y +CONFIG_SCHEDSTATS=y +# CONFIG_TIMER_STATS is not set +# CONFIG_DEBUG_OBJECTS is not set +# CONFIG_SLUB_STATS is not set +# CONFIG_DEBUG_KMEMLEAK is not set +# CONFIG_DEBUG_PREEMPT is not set +# CONFIG_DEBUG_RT_MUTEXES is not set +# CONFIG_RT_MUTEX_TESTER is not set +# CONFIG_DEBUG_SPINLOCK is not set +# CONFIG_DEBUG_MUTEXES is not set +# CONFIG_DEBUG_LOCK_ALLOC is not set +# CONFIG_PROVE_LOCKING is not set +# CONFIG_SPARSE_RCU_POINTER is not set +# CONFIG_LOCK_STAT is not set +CONFIG_DEBUG_SPINLOCK_SLEEP=y +# CONFIG_DEBUG_LOCKING_API_SELFTESTS is not set +CONFIG_STACKTRACE=y +# CONFIG_DEBUG_STACK_USAGE is not set +# CONFIG_DEBUG_KOBJECT is not set +# CONFIG_DEBUG_HIGHMEM is not set +CONFIG_DEBUG_BUGVERBOSE=y +CONFIG_DEBUG_INFO=y +# CONFIG_DEBUG_INFO_REDUCED is not set +# CONFIG_DEBUG_VM is not set +# CONFIG_DEBUG_WRITECOUNT is not set +# CONFIG_DEBUG_MEMORY_INIT is not set +# CONFIG_DEBUG_LIST is not set +# CONFIG_TEST_LIST_SORT is not set +# CONFIG_DEBUG_SG is not set +# CONFIG_DEBUG_NOTIFIERS is not set +# CONFIG_DEBUG_CREDENTIALS is not set +CONFIG_FRAME_POINTER=y +# CONFIG_BOOT_PRINTK_DELAY is not set +# CONFIG_RCU_TORTURE_TEST is not set +CONFIG_RCU_CPU_STALL_TIMEOUT=60 +CONFIG_RCU_CPU_STALL_VERBOSE=y +# CONFIG_BACKTRACE_SELF_TEST is not set +# CONFIG_DEBUG_BLOCK_EXT_DEVT is not set +# CONFIG_DEBUG_FORCE_WEAK_PER_CPU is not set +# CONFIG_DEBUG_PER_CPU_MAPS is not set +# CONFIG_LKDTM is not set +# CONFIG_CPU_NOTIFIER_ERROR_INJECT is not set +# CONFIG_FAULT_INJECTION is not set +# CONFIG_LATENCYTOP is not set +CONFIG_SYSCTL_SYSCALL_CHECK=y +# CONFIG_DEBUG_PAGEALLOC is not set +CONFIG_HAVE_FUNCTION_TRACER=y +CONFIG_HAVE_FUNCTION_GRAPH_TRACER=y +CONFIG_HAVE_DYNAMIC_FTRACE=y +CONFIG_HAVE_FTRACE_MCOUNT_RECORD=y +CONFIG_HAVE_C_RECORDMCOUNT=y +CONFIG_TRACING_SUPPORT=y +# CONFIG_FTRACE is not set +# CONFIG_DYNAMIC_DEBUG is not set +# CONFIG_DMA_API_DEBUG is not set +# CONFIG_ATOMIC64_SELFTEST is not set +# CONFIG_SAMPLES is not set +CONFIG_HAVE_ARCH_KGDB=y +# CONFIG_KGDB is not set +# CONFIG_TEST_KSTRTOX is not set +# CONFIG_STRICT_DEVMEM is not set +# CONFIG_ARM_UNWIND is not set +CONFIG_DEBUG_USER=y +# CONFIG_DEBUG_LL is not set +# CONFIG_OC_ETM is not set +CONFIG_DEBUG_S3C_UART=1 +# CONFIG_CACHE_PERF is not set + +# +# Security options +# +CONFIG_KEYS=y +CONFIG_KEYS_DEBUG_PROC_KEYS=y +# CONFIG_SECURITY_DMESG_RESTRICT is not set +# CONFIG_SECURITY is not set +# CONFIG_SECURITYFS is not set +CONFIG_DEFAULT_SECURITY_DAC=y +CONFIG_DEFAULT_SECURITY="" +CONFIG_CRYPTO=y + +# +# Crypto core or helper +# +CONFIG_CRYPTO_FIPS=y +CONFIG_CRYPTO_FIPS_INTEG_OFFSET=0x2B000000 +CONFIG_CRYPTO_ALGAPI=y +CONFIG_CRYPTO_ALGAPI2=y +CONFIG_CRYPTO_AEAD=y +CONFIG_CRYPTO_AEAD2=y +CONFIG_CRYPTO_BLKCIPHER=y +CONFIG_CRYPTO_BLKCIPHER2=y +CONFIG_CRYPTO_HASH=y +CONFIG_CRYPTO_HASH2=y +CONFIG_CRYPTO_RNG=y +CONFIG_CRYPTO_RNG2=y +CONFIG_CRYPTO_PCOMP2=y +CONFIG_CRYPTO_MANAGER=y +CONFIG_CRYPTO_MANAGER2=y +CONFIG_CRYPTO_MANAGER_TESTS=y +CONFIG_CRYPTO_GF128MUL=y +CONFIG_CRYPTO_NULL=y +# CONFIG_CRYPTO_PCRYPT is not set +CONFIG_CRYPTO_WORKQUEUE=y +CONFIG_CRYPTO_CRYPTD=y +CONFIG_CRYPTO_AUTHENC=y +CONFIG_CRYPTO_TEST=y + +# +# Authenticated Encryption with Associated Data +# +# CONFIG_CRYPTO_CCM is not set +# CONFIG_CRYPTO_GCM is not set +CONFIG_CRYPTO_SEQIV=y + +# +# Block modes +# +CONFIG_CRYPTO_CBC=y +CONFIG_CRYPTO_CTR=y +CONFIG_CRYPTO_CTS=y +CONFIG_CRYPTO_ECB=y +# CONFIG_CRYPTO_LRW is not set +# CONFIG_CRYPTO_PCBC is not set +# CONFIG_CRYPTO_XTS is not set + +# +# Hash modes +# +CONFIG_CRYPTO_HMAC=y +# CONFIG_CRYPTO_XCBC is not set +# CONFIG_CRYPTO_VMAC is not set + +# +# Digest +# +CONFIG_CRYPTO_CRC32C=y +CONFIG_CRYPTO_GHASH=y +CONFIG_CRYPTO_MD4=y +CONFIG_CRYPTO_MD5=y +# CONFIG_CRYPTO_MICHAEL_MIC is not set +# CONFIG_CRYPTO_RMD128 is not set +# CONFIG_CRYPTO_RMD160 is not set +# CONFIG_CRYPTO_RMD256 is not set +# CONFIG_CRYPTO_RMD320 is not set +CONFIG_CRYPTO_SHA1=y +CONFIG_CRYPTO_SHA256=y +CONFIG_CRYPTO_SHA512=y +# CONFIG_CRYPTO_TGR192 is not set +# CONFIG_CRYPTO_WP512 is not set + +# +# Ciphers +# +CONFIG_CRYPTO_AES=y +# CONFIG_CRYPTO_ANUBIS is not set +CONFIG_CRYPTO_ARC4=y +# CONFIG_CRYPTO_BLOWFISH is not set +# CONFIG_CRYPTO_CAMELLIA is not set +# CONFIG_CRYPTO_CAST5 is not set +# CONFIG_CRYPTO_CAST6 is not set +CONFIG_CRYPTO_DES=y +# CONFIG_CRYPTO_FCRYPT is not set +# CONFIG_CRYPTO_KHAZAD is not set +# CONFIG_CRYPTO_SALSA20 is not set +# CONFIG_CRYPTO_SEED is not set +# CONFIG_CRYPTO_SERPENT is not set +# CONFIG_CRYPTO_TEA is not set +CONFIG_CRYPTO_TWOFISH=y +CONFIG_CRYPTO_TWOFISH_COMMON=y + +# +# Compression +# +CONFIG_CRYPTO_DEFLATE=y +# CONFIG_CRYPTO_ZLIB is not set +# CONFIG_CRYPTO_LZO is not set + +# +# Random Number Generation +# +CONFIG_CRYPTO_ANSI_CPRNG=y +# CONFIG_CRYPTO_USER_API_HASH is not set +# CONFIG_CRYPTO_USER_API_SKCIPHER is not set +CONFIG_CRYPTO_HW=y +# CONFIG_CRYPTO_S5P_DEV_ACE is not set +# CONFIG_BINARY_PRINTF is not set + +# +# Library routines +# +CONFIG_BITREVERSE=y +CONFIG_CRC_CCITT=y +CONFIG_CRC16=y +# CONFIG_CRC_T10DIF is not set +# CONFIG_CRC_ITU_T is not set +CONFIG_CRC32=y +# CONFIG_CRC7 is not set +CONFIG_LIBCRC32C=y +CONFIG_ZLIB_INFLATE=y +CONFIG_ZLIB_DEFLATE=y +# CONFIG_XZ_DEC is not set +# CONFIG_XZ_DEC_BCJ is not set +CONFIG_DECOMPRESS_GZIP=y +CONFIG_GENERIC_ALLOCATOR=y +CONFIG_REED_SOLOMON=y +CONFIG_REED_SOLOMON_ENC8=y +CONFIG_REED_SOLOMON_DEC8=y +CONFIG_TEXTSEARCH=y +CONFIG_TEXTSEARCH_KMP=y +CONFIG_TEXTSEARCH_BM=y +CONFIG_TEXTSEARCH_FSM=y +CONFIG_HAS_IOMEM=y +CONFIG_HAS_DMA=y +CONFIG_CPU_RMAP=y +CONFIG_NLATTR=y +# CONFIG_AVERAGE is not set diff --git a/arch/arm/mach-exynos/Makefile b/arch/arm/mach-exynos/Makefile index 65bf807..70025c6 100644 --- a/arch/arm/mach-exynos/Makefile +++ b/arch/arm/mach-exynos/Makefile @@ -84,6 +84,9 @@ endif else obj-$(CONFIG_MACH_U1_BD) += u1-gpio.o endif +ifeq ($(CONFIG_MACH_U1_NA_SPR),y) +obj-$(CONFIG_MACH_U1) += dev-c1-phone.o +endif obj-$(CONFIG_MACH_Q1_BD) += q1-gpio.o board-gps-bcm475x.o obj-$(CONFIG_MACH_U1) += u1-wlan.o obj-$(CONFIG_MACH_PX) += mach-px.o sec-common.o board-gps-bcm475x.o px-switch.o diff --git a/arch/arm/mach-exynos/cpuidle-exynos4.c b/arch/arm/mach-exynos/cpuidle-exynos4.c index 08c5b05..3bfc3fb 100644 --- a/arch/arm/mach-exynos/cpuidle-exynos4.c +++ b/arch/arm/mach-exynos/cpuidle-exynos4.c @@ -341,10 +341,12 @@ static int check_usb_op(void) #endif } -#ifdef CONFIG_SND_SAMSUNG_RP -#if defined(CONFIG_MACH_U1_NA_SPR) +#if defined (CONFIG_MACH_U1_NA_SPR) || (CONFIG_MACH_U1_NA_USCC) #include "../../../sound/soc/samsung/srp-types.h" +#include "../../../sound/soc/samsung/idma.h" #endif + +#ifdef CONFIG_SND_SAMSUNG_RP extern int srp_get_op_level(void); /* By srp driver */ #endif @@ -370,17 +372,33 @@ static inline int check_gps_uart_op(void) return gps_is_running; } -#ifdef CONFIG_INTERNAL_MODEM_IF +#if defined(CONFIG_INTERNAL_MODEM_IF) || defined(CONFIG_SAMSUNG_PHONE_TTY) static int check_idpram_op(void) { /* This pin is high when CP might be accessing dpram */ +#ifdef CONFIG_MACH_U1_NA_SPR + int cp_int = __raw_readl(S5P_VA_GPIO2 + 0xC24) & 4; +#else int cp_int = gpio_get_value(GPIO_CP_AP_DPRAM_INT); +#endif if (cp_int != 0) pr_info("%s cp_int is high.\n", __func__); return cp_int; } #endif +#if defined(CONFIG_ISDBT) +static int check_isdbt_op(void) +{ + /* This pin is high when isdbt is working */ + int isdbt_is_running = gpio_get_value(GPIO_ISDBT_EN); + + if (isdbt_is_running != 0) + printk(KERN_INFO "isdbt_is_running is high\n"); + return isdbt_is_running; +} +#endif + static atomic_t sromc_use_count; void set_sromc_access(bool access) @@ -410,21 +428,28 @@ static int exynos4_check_operation(void) #ifdef CONFIG_SND_SAMSUNG_RP if (srp_get_op_level()) return 1; -#if defined(CONFIG_MACH_U1_NA_SPR) +#endif + +#if defined (CONFIG_MACH_U1_NA_SPR) || (CONFIG_MACH_U1_NA_USCC) +#ifdef CONFIG_SND_SAMSUNG_RP if (!srp_get_status(IS_RUNNING)) return 1; +#elif defined(CONFIG_SND_SAMSUNG_ALP) + if (!idma_is_running()) + return 1; #endif #endif + if (check_usb_op()) return 1; -#if defined(CONFIG_BT) - if (check_bt_op()) +#if defined(CONFIG_ISDBT) + if (check_isdbt_op()) return 1; #endif -#ifdef CONFIG_INTERNAL_MODEM_IF - if (check_idpram_op()) +#if defined(CONFIG_BT) + if (check_bt_op()) return 1; #endif @@ -439,6 +464,10 @@ static int exynos4_check_operation(void) return 1; } +#ifdef CONFIG_INTERNAL_MODEM_IF + if (check_idpram_op()) + return 1; +#endif return 0; } @@ -634,7 +663,7 @@ static int exynos4_enter_core0_lpa(struct cpuidle_device *dev, #endif local_irq_disable(); -#ifdef CONFIG_INTERNAL_MODEM_IF +#if defined(CONFIG_INTERNAL_MODEM_IF) || defined(CONFIG_SAMSUNG_PHONE_TTY) gpio_set_value(GPIO_PDA_ACTIVE, 0); #endif @@ -730,7 +759,7 @@ early_wakeup: if (log_en) pr_info("---lpa\n"); -#ifdef CONFIG_INTERNAL_MODEM_IF +#if defined(CONFIG_INTERNAL_MODEM_IF) || defined(CONFIG_SAMSUNG_PHONE_TTY) gpio_set_value(GPIO_PDA_ACTIVE, 1); #endif diff --git a/arch/arm/mach-exynos/dev-c1-phone.c b/arch/arm/mach-exynos/dev-c1-phone.c new file mode 100644 index 0000000..94be259 --- /dev/null +++ b/arch/arm/mach-exynos/dev-c1-phone.c @@ -0,0 +1,74 @@ +/* linux/arch/arm/mach-s5pv310/dev-herring-phone.c + * Copyright (C) 2010 Samsung Electronics. 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 + * may be copied, distributed, and modified under those terms. + * + * 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. + */ + +#include <linux/kernel.h> +#include <linux/init.h> +#include <linux/platform_device.h> +#include <linux/irq.h> + +#include <linux/tty.h> +#include <linux/tty_driver.h> +#include <linux/tty_flip.h> + +#include <mach/map.h> +#include <mach/gpio.h> + +#include "../../../drivers/dpram/raffaello/dpram.h" +#include "u1.h" + + +static int c1_is_bootmode_recovery; +static int setup_bootmode(char *str) +{ + printk(KERN_INFO "%s : %s\n", __func__, str); + + c1_is_bootmode_recovery = 0; + + if (str) + if ((*str == '2') || (*str == '4')) + c1_is_bootmode_recovery = 1; + + printk(KERN_INFO "c1_is_bootmode_recovery = %d\n", c1_is_bootmode_recovery); + + return c1_is_bootmode_recovery; +} + +__setup("bootmode=", setup_bootmode); + + + +struct platform_device sec_device_dpram = { + .name = "dpram-device", + .id = -1, +}; + +struct platform_device sec_device_dpram_recovery = { + .name = "dpram-recovery", + .id = -1, +}; + + +static int __init c1_init_phone_interface(void) +{ +#if defined(CONFIG_SAMSUNG_PHONE_TTY) + if (c1_is_bootmode_recovery){ + printk(KERN_INFO "c1_init_phone_interface - RECOVERY"); + platform_device_register(&sec_device_dpram_recovery); + }else{ + printk(KERN_INFO "c1_init_phone_interface"); + platform_device_register(&sec_device_dpram); + } +#endif + return 0; +} +device_initcall(c1_init_phone_interface); diff --git a/arch/arm/mach-exynos/include/mach/gpio-u1.h b/arch/arm/mach-exynos/include/mach/gpio-u1.h index f077824..851f4f2 100644 --- a/arch/arm/mach-exynos/include/mach/gpio-u1.h +++ b/arch/arm/mach-exynos/include/mach/gpio-u1.h @@ -260,11 +260,17 @@ #define S5PV310_GPE4_6_MDM_DATA_14 EXYNOS4210_GPE4(6) #define S5PV310_GPE4_7_MDM_DATA_15 EXYNOS4210_GPE4(7) +#define S5PV310_MDM_IF_SEL 2 + #define GPIO_QSC_PHONE_ON EXYNOS4_GPC1(1) #define GPIO_QSC_PHONE_RST EXYNOS4_GPX1(4) #define GPIO_QSC_PHONE_ACTIVE EXYNOS4_GPX1(6) #define IRQ_QSC_PHONE_ACTIVE GPIO_QSC_PHONE_ACTIVE #define GPIO_C210_DPRAM_INT_N EXYNOS4_GPX1(0) + +#define GPIO_DPRAM_INT_CP_N S5PV310_GPE0_3_MDM_IRQn + +#define GPIO_PDA_ACTIVE EXYNOS4_GPY4(2) #endif /* End */ diff --git a/arch/arm/mach-exynos/mach-u1.c b/arch/arm/mach-exynos/mach-u1.c index 88dccdd..59cb0bc 100644 --- a/arch/arm/mach-exynos/mach-u1.c +++ b/arch/arm/mach-exynos/mach-u1.c @@ -395,6 +395,9 @@ static int m5mo_power_on(void) /* VT_CORE_1.5V */ ret = gpio_direction_output(GPIO_VT_CAM_15V, 1); +#ifdef CONFIG_TARGET_LOCALE_NA + s3c_gpio_setpull(GPIO_VT_CAM_15V, S3C_GPIO_PULL_NONE); +#endif /* CONFIG_TARGET_LOCALE_NA */ CAM_CHECK_ERR_RET(ret, "output VT_CAM_1.5V"); udelay(20); @@ -836,12 +839,26 @@ static int m5mo_power(int enable) printk(KERN_DEBUG "%s %s\n", __func__, enable ? "on" : "down"); if (enable) { +#if defined(CONFIG_TARGET_LOCALE_NA) + exynos_cpufreq_lock(DVFS_LOCK_ID_CAM, 1); ret = m5mo_power_on(); + exynos_cpufreq_lock_free(DVFS_LOCK_ID_CAM); +#else + + ret = m5mo_power_on(); +#endif if (unlikely(ret)) goto error_out; - } else + } else { +#if defined(CONFIG_TARGET_LOCALE_NA) + exynos_cpufreq_lock(DVFS_LOCK_ID_CAM, 1); ret = m5mo_power_down(); + exynos_cpufreq_lock_free(DVFS_LOCK_ID_CAM); +#else + ret = m5mo_power_down(); +#endif + } ret = s3c_csis_power(enable); m5mo_flash_power(enable); @@ -3943,6 +3960,10 @@ static void u1_sound_init(void) return; } gpio_direction_output(GPIO_MIC_BIAS_EN, 1); +#ifdef CONFIG_TARGET_LOCALE_NA + s3c_gpio_setpull(GPIO_MIC_BIAS_EN, S3C_GPIO_PULL_NONE); +#endif /* CONFIG_TARGET_LOCALE_NA */ + gpio_set_value(GPIO_MIC_BIAS_EN, 0); gpio_free(GPIO_MIC_BIAS_EN); @@ -3952,6 +3973,10 @@ static void u1_sound_init(void) return; } gpio_direction_output(GPIO_EAR_MIC_BIAS_EN, 1); +#ifdef CONFIG_TARGET_LOCALE_NA + s3c_gpio_setpull(GPIO_EAR_MIC_BIAS_EN, S3C_GPIO_PULL_NONE); +#endif /* CONFIG_TARGET_LOCALE_NA */ + gpio_set_value(GPIO_EAR_MIC_BIAS_EN, 0); gpio_free(GPIO_EAR_MIC_BIAS_EN); @@ -3973,6 +3998,10 @@ static void u1_sound_init(void) return; } gpio_direction_output(GPIO_SUB_MIC_BIAS_EN, 0); +#ifdef CONFIG_TARGET_LOCALE_NA + s3c_gpio_setpull(GPIO_SUB_MIC_BIAS_EN, S3C_GPIO_PULL_NONE); +#endif /* CONFIG_TARGET_LOCALE_NA */ + gpio_free(GPIO_SUB_MIC_BIAS_EN); } #endif /* #if defined(CONFIG_MACH_Q1_BD) */ @@ -4575,6 +4604,94 @@ static struct sec_bat_adc_table_data temper_table_ADC7[] = { { 1669, -60 }, { 1688, -70 }, }; +#endif +/* temperature table for ADC 7 */ +#ifdef CONFIG_TARGET_LOCALE_NA +static struct sec_bat_adc_table_data temper_table_ADC7[] = { + { 145, 670 }, + { 165, 660 }, + { 185, 650 }, + { 205, 640 }, + { 225, 630 }, + { 245, 620 }, + { 265, 610 }, + { 285, 600 }, + { 305, 590 }, + { 325, 580 }, + { 345, 570 }, + { 365, 560 }, + { 385, 550 }, + { 405, 540 }, + { 425, 530 }, + { 445, 520 }, + { 465, 510 }, + { 485, 500 }, + { 505, 490 }, + { 525, 480 }, + { 545, 470 }, + { 565, 460 }, + { 585, 450 }, + { 605, 440 }, + { 625, 430 }, + { 645, 420 }, + { 665, 410 }, + { 685, 400 }, + { 705, 390 }, + { 725, 380 }, + { 745, 370 }, + { 765, 360 }, + { 785, 350 }, + { 805, 340 }, + { 825, 330 }, + { 845, 320 }, + { 865, 310 }, + { 885, 300 }, + { 905, 290 }, + { 925, 280 }, + { 945, 270 }, + { 965, 260 }, + { 995, 250 }, + { 1015, 240 }, + { 1045, 230 }, + { 1065, 220 }, + { 1085, 210 }, + { 1105, 200 }, + { 1125, 190 }, + { 1145, 180 }, + { 1165, 170 }, + { 1185, 160 }, + { 1205, 150 }, + { 1225, 140 }, + { 1245, 130 }, + { 1265, 120 }, + { 1285, 110 }, + { 1305, 100 }, + { 1335, 90 }, + { 1365, 80 }, + { 1395, 70 }, + { 1425, 60 }, + { 1455, 50 }, + { 1475, 40 }, + { 1495, 30 }, + { 1515, 20 }, + { 1535, 10 }, + { 1545, 0 }, + { 1555, -10 }, + { 1565, -20 }, + { 1575, -30 }, + { 1585, -40 }, + { 1595, -50 }, + { 1605, -60 }, + { 1615, -70 }, + { 1625, -80 }, + { 1635, -90 }, + { 1645, -100 }, + { 1655, -110 }, + { 1665, -120 }, + { 1675, -130 }, + { 1685, -140 }, +}; + #else /* temperature table for ADC 7 */ static struct sec_bat_adc_table_data temper_table_ADC7[] = { @@ -5186,7 +5303,7 @@ static struct sec_jack_buttons_zone sec_jack_buttons_zones[] = { /* 0 <= adc <=170, stable zone */ .code = KEY_MEDIA, .adc_low = 0, -#if defined(CONFIG_TARGET_LOCALE_NTT) +#if defined(CONFIG_TARGET_LOCALE_NTT) || defined(CONFIG_TARGET_LOCALE_NA) .adc_high = 150, #else .adc_high = 170, @@ -5195,7 +5312,7 @@ static struct sec_jack_buttons_zone sec_jack_buttons_zones[] = { { /* 171 <= adc <= 370, stable zone */ .code = KEY_VOLUMEUP, -#if defined(CONFIG_TARGET_LOCALE_NTT) +#if defined(CONFIG_TARGET_LOCALE_NTT) || defined(CONFIG_TARGET_LOCALE_NA) .adc_low = 151, #else .adc_low = 171, @@ -5460,7 +5577,11 @@ static const u8 *mxt224_config[] = { #define MXT224E_THRESHOLD_BATT 40 #define MXT224E_T48_THRESHOLD_BATT 28 #define MXT224E_THRESHOLD_CHRG 37 +#if defined(CONFIG_MACH_U1_NA_SPR) +#define MXT224E_CALCFG_BATT 0x72 +#else #define MXT224E_CALCFG_BATT 0x42 +#endif #define MXT224E_CALCFG_CHRG 0x52 #if defined(CONFIG_TARGET_LOCALE_NA) #define MXT224E_ATCHFRCCALTHR_NORMAL 45 @@ -7167,8 +7288,9 @@ static struct platform_device *smdkc210_devices[] __initdata = { &exynos4_device_pd[PD_LCD1], &exynos4_device_pd[PD_CAM], &exynos4_device_pd[PD_TV], +#ifndef CONFIG_TARGET_LOCALE_NA &exynos4_device_pd[PD_GPS], - +#endif /* CONFIG_TARGET_LOCALE_NA */ #if defined(CONFIG_WIMAX_CMC) &s3c_device_cmc732, #endif diff --git a/arch/arm/mach-exynos/sec-reboot.c b/arch/arm/mach-exynos/sec-reboot.c index 593624b..b3c0b0a 100644 --- a/arch/arm/mach-exynos/sec-reboot.c +++ b/arch/arm/mach-exynos/sec-reboot.c @@ -8,6 +8,9 @@ /* charger cable state */ extern bool is_cable_attached; +#ifdef CONFIG_MACH_U1_NA_SPR +static void cdma_wimax_chk_modem_pwroff(void); +#endif static void sec_power_off(void) { int poweroff_try = 0; @@ -17,6 +20,9 @@ static void sec_power_off(void) pr_emerg("%s : cable state=%d\n", __func__, is_cable_attached); while (1) { +#ifdef CONFIG_MACH_U1_NA_SPR + cdma_wimax_chk_modem_pwroff(); +#endif /* Check reboot charging */ if (is_cable_attached || (poweroff_try >= 5)) { pr_emerg @@ -70,6 +76,34 @@ static void sec_power_off(void) #define REBOOT_SET_SWSEL 0x000e0000 #define REBOOT_SET_SUD 0x000f0000 +#ifdef CONFIG_MACH_U1_NA_SPR +static void cdma_wimax_chk_modem_pwroff(void) +{ + int phone_wait_cnt = 0; + + pr_emerg("%s\n", __func__); + + /* phone power off */ + gpio_direction_output(GPIO_QSC_PHONE_ON, GPIO_LEVEL_LOW); + + /* confirm phone off */ + while (1) { + if (gpio_get_value(GPIO_QSC_PHONE_ACTIVE)) { + printk(KERN_ALERT"Try to Turn Phone Off by CP_RST\n"); + gpio_set_value(GPIO_QSC_PHONE_RST, 0); + if (phone_wait_cnt > 10) { + pr_emerg("%s: PHONE OFF Failed\n", __func__); + break; + } + phone_wait_cnt++; + mdelay(100); + } else { + pr_emerg("%s: PHONE OFF Success\n", __func__); + break; + } + } +} +#endif static void sec_reboot(char str, const char *cmd) { local_irq_disable(); diff --git a/arch/arm/mach-exynos/sec-switch_max8997.c b/arch/arm/mach-exynos/sec-switch_max8997.c index 3d05864..f6a8526 100644 --- a/arch/arm/mach-exynos/sec-switch_max8997.c +++ b/arch/arm/mach-exynos/sec-switch_max8997.c @@ -128,6 +128,64 @@ static ssize_t u1_switch_store_vbus(struct device *dev, DEVICE_ATTR(disable_vbus, 0664, u1_switch_show_vbus, u1_switch_store_vbus); +#if defined(CONFIG_TARGET_LOCALE_NA) +#define USB_PATH_AP 0 +#define USB_PATH_CP 1 +#define USB_PATH_ALL 2 +static int hub_usb_path; + +int u1_get_usb_hub_path(void) +{ + return hub_usb_path; +} +EXPORT_SYMBOL_GPL(u1_get_usb_hub_path); + +static ssize_t u1_switch_show_usb_path(struct device *dev, + struct device_attribute *attr, char *buf) +{ + int i; + + switch (hub_usb_path) { + case USB_PATH_AP: + i = sprintf(buf, "USB_PATH: AP\n"); + break; + case USB_PATH_CP: + i = sprintf(buf, "USB_PATH: CP\n"); + break; + case USB_PATH_ALL: + i = sprintf(buf, "USB_PATH: ALL\n"); + break; + default: + i = sprintf(buf, "USB_PATH: Unknown!\n"); + break; + } + + return i; +} + +static ssize_t u1_switch_store_usb_path(struct device *dev, + struct device_attribute *attr, + const char *buf, size_t count) +{ + if (!strncmp(buf, "AP", 2)) + hub_usb_path = USB_PATH_AP; + else if (!strncmp(buf, "CP", 2)) + hub_usb_path = USB_PATH_CP; + else if (!strncmp(buf, "ALL", 3)) + hub_usb_path = USB_PATH_ALL; + else { + pr_warn("%s: Wrong command\n", __func__); + return count; + } + pr_info("%s: USB PATH = %d\n", __func__, hub_usb_path); + + return count; +} + +static DEVICE_ATTR(set_usb_path, 0664, u1_switch_show_usb_path, + u1_switch_store_usb_path); +#endif /* CONFIG_TARGET_LOCALE_NA */ + #ifdef CONFIG_TARGET_LOCALE_KOR #include "../../../drivers/usb/gadget/s3c_udc.h" /* usb access control for SEC DM */ diff --git a/arch/arm/mach-exynos/setup-fimc0.c b/arch/arm/mach-exynos/setup-fimc0.c index 975412c..84eeb90 100644 --- a/arch/arm/mach-exynos/setup-fimc0.c +++ b/arch/arm/mach-exynos/setup-fimc0.c @@ -38,7 +38,7 @@ void s3c_fimc0_cfg_gpio(struct platform_device *pdev) * FIELD */ s3c_gpio_cfgrange_nopull(EXYNOS4210_GPJ1(0), 5, S3C_GPIO_SFN(2)); -#if !defined(CONFIG_MACH_P8LTE) || !defined(CONFIG_VIDEO_S5K5BBGX) +#if !defined(CONFIG_MACH_P8LTE) && !defined(CONFIG_VIDEO_S5K5BBGX) /* CAM B port(b0011) : DATA[0-7] */ s3c_gpio_cfgrange_nopull(EXYNOS4210_GPE1(0), 8, S3C_GPIO_SFN(3)); @@ -74,7 +74,7 @@ void s3c_fimc0_cfg_gpio(struct platform_device *pdev) s3c_gpio_cfgpin(EXYNOS4210_GPJ1(3), S3C_GPIO_INPUT); s3c_gpio_setpull(EXYNOS4210_GPJ1(3), S3C_GPIO_PULL_DOWN); -#if !defined(CONFIG_MACH_P8LTE) +#if !defined(CONFIG_MACH_P8LTE) && !defined(CONFIG_MACH_U1_NA_SPR) /* CAM B port(b0011) : DATA[0-7] */ s3c_gpio_cfgrange_nopull(EXYNOS4210_GPE1(0), 8, S3C_GPIO_SFN(3)); /* CAM B port(b0011) : PCLK, VSYNC, HREF, FIELD, CLKOUT */ diff --git a/arch/arm/mach-exynos/setup-sdhci-gpio.c b/arch/arm/mach-exynos/setup-sdhci-gpio.c index 05d8ed1..00b95c2 100644 --- a/arch/arm/mach-exynos/setup-sdhci-gpio.c +++ b/arch/arm/mach-exynos/setup-sdhci-gpio.c @@ -23,6 +23,9 @@ #include <plat/regs-sdhci.h> #include <plat/sdhci.h> +extern int s3c_gpio_slp_cfgpin(unsigned int pin, unsigned int config); +extern int s3c_gpio_slp_setpull_updown(unsigned int pin, unsigned int config); + #if defined(CONFIG_ARCH_EXYNOS4) void exynos4_setup_sdhci0_cfg_gpio(struct platform_device *dev, int width) { @@ -155,6 +158,45 @@ void exynos4_setup_sdhci3_cfg_gpio(struct platform_device *dev, int width) struct s3c_sdhci_platdata *pdata = dev->dev.platform_data; unsigned int gpio; +#if defined(CONFIG_WIMAX_CMC) + if (gpio_get_value(GPIO_WIMAX_EN)) { + for (gpio = EXYNOS4_GPK3(0); gpio < EXYNOS4_GPK3(2); gpio++) { + s3c_gpio_cfgpin(gpio, S3C_GPIO_SFN(2)); + s3c_gpio_setpull(gpio, S3C_GPIO_PULL_NONE); + s5p_gpio_set_drvstr(gpio, S5P_GPIO_DRVSTR_LV2); + } + for (gpio = EXYNOS4_GPK3(3); gpio <= EXYNOS4_GPK3(6); gpio++) { + s3c_gpio_cfgpin(gpio, S3C_GPIO_SFN(2)); + s3c_gpio_setpull(gpio, S3C_GPIO_PULL_NONE); + s5p_gpio_set_drvstr(gpio, S5P_GPIO_DRVSTR_LV2); + } + for (gpio = EXYNOS4_GPK3(0); gpio < EXYNOS4_GPK3(2); gpio++) { + s3c_gpio_slp_cfgpin(gpio, S3C_GPIO_SLP_INPUT); + s3c_gpio_slp_setpull_updown(gpio, S3C_GPIO_PULL_NONE); + } + for (gpio = EXYNOS4_GPK3(3); gpio <= EXYNOS4_GPK3(6); gpio++) { + s3c_gpio_slp_cfgpin(gpio, S3C_GPIO_SLP_INPUT); + s3c_gpio_slp_setpull_updown(gpio, S3C_GPIO_PULL_NONE); + } + } else { + for (gpio = EXYNOS4_GPK3(0); gpio < EXYNOS4_GPK3(2); gpio++) { + s3c_gpio_cfgpin(gpio, S3C_GPIO_SFN(0)); + s3c_gpio_setpull(gpio, S3C_GPIO_PULL_DOWN); + } + for (gpio = EXYNOS4_GPK3(3); gpio <= EXYNOS4_GPK3(6); gpio++) { + s3c_gpio_cfgpin(gpio, S3C_GPIO_SFN(0)); + s3c_gpio_setpull(gpio, S3C_GPIO_PULL_DOWN); + } + for (gpio = EXYNOS4_GPK3(0); gpio < EXYNOS4_GPK3(2); gpio++) { + s3c_gpio_slp_cfgpin(gpio, S3C_GPIO_SLP_INPUT); + s3c_gpio_slp_setpull_updown(gpio, S3C_GPIO_PULL_DOWN); + } + for (gpio = EXYNOS4_GPK3(3); gpio <= EXYNOS4_GPK3(6); gpio++) { + s3c_gpio_slp_cfgpin(gpio, S3C_GPIO_SLP_INPUT); + s3c_gpio_slp_setpull_updown(gpio, S3C_GPIO_PULL_DOWN); + } + } +#else /* Set all the necessary GPK3[0:1] pins to special-function 2 */ for (gpio = EXYNOS4_GPK3(0); gpio < EXYNOS4_GPK3(2); gpio++) { s3c_gpio_cfgpin(gpio, S3C_GPIO_SFN(2)); @@ -208,6 +250,7 @@ void exynos4_setup_sdhci3_cfg_gpio(struct platform_device *dev, int width) s3c_gpio_setpull(EXYNOS4_GPK3(2), S3C_GPIO_PULL_NONE); s5p_gpio_set_drvstr(gpio, S5P_GPIO_DRVSTR_LV2); } +#endif } #endif /* CONFIG_ARCH_EXYNOS4 */ diff --git a/arch/arm/plat-samsung/dev-hsmmc3.c b/arch/arm/plat-samsung/dev-hsmmc3.c index 1973ef4..7e06d28 100644 --- a/arch/arm/plat-samsung/dev-hsmmc3.c +++ b/arch/arm/plat-samsung/dev-hsmmc3.c @@ -43,6 +43,9 @@ static u64 s3c_device_hsmmc3_dmamask = 0xffffffffUL; struct s3c_sdhci_platdata s3c_hsmmc3_def_platdata = { .max_width = 4, +#ifdef CONFIG_WIMAX_CMC + .enable_intr_on_resume = 1, +#endif .host_caps = (MMC_CAP_4_BIT_DATA | MMC_CAP_MMC_HIGHSPEED | MMC_CAP_SD_HIGHSPEED), .clk_type = S3C_SDHCI_CLK_DIV_INTERNAL, @@ -87,4 +90,8 @@ void s3c_sdhci3_set_platdata(struct s3c_sdhci_platdata *pd) set->host_caps |= pd->host_caps; if (pd->clk_type) set->clk_type = pd->clk_type; +#ifdef CONFIG_WIMAX_CMC + if (pd->enable_intr_on_resume) + set->enable_intr_on_resume = pd->enable_intr_on_resume; +#endif } diff --git a/arch/arm/plat-samsung/include/plat/sdhci.h b/arch/arm/plat-samsung/include/plat/sdhci.h index c0e3799..686e828 100644 --- a/arch/arm/plat-samsung/include/plat/sdhci.h +++ b/arch/arm/plat-samsung/include/plat/sdhci.h @@ -89,6 +89,9 @@ struct s3c_sdhci_platdata { void __iomem *regbase, struct mmc_ios *ios, struct mmc_card *card); +#ifdef CONFIG_WIMAX_CMC + int enable_intr_on_resume; +#endif #ifdef CONFIG_MACH_PX int (*ext_pdev)(struct platform_device *dev_id); #endif diff --git a/drivers/Kconfig b/drivers/Kconfig index 871235e..eb24286 100644 --- a/drivers/Kconfig +++ b/drivers/Kconfig @@ -152,6 +152,8 @@ source "drivers/extcon/Kconfig" source "drivers/barcode_emul/Kconfig" +source "drivers/dpram/Kconfig" + # Secure OS Mobicore source "drivers/gud/Kconfig" diff --git a/drivers/Makefile b/drivers/Makefile index 4c2d947..4b27df7 100644 --- a/drivers/Makefile +++ b/drivers/Makefile @@ -139,6 +139,7 @@ obj-$(CONFIG_ACCESSORY) += accessory/ obj-$(CONFIG_IR_REMOCON) += irda/ obj-$(CONFIG_BARCODE_EMUL) += barcode_emul/ obj-$(CONFIG_EXTCON) += extcon/ +obj-$(CONFIG_SAMSUNG_PHONE_TTY) += dpram/ # Secure OS Mobicore obj-$(CONFIG_MOBICORE_SUPPORT) += gud/ diff --git a/drivers/dpram/Kconfig b/drivers/dpram/Kconfig new file mode 100644 index 0000000..d629a43 --- /dev/null +++ b/drivers/dpram/Kconfig @@ -0,0 +1,19 @@ +# +# IDPRAM configuration +# + +menuconfig SAMSUNG_PHONE_TTY + tristate "Samsung Phone Interface - TTY" + default n + +if SAMSUNG_PHONE_TTY + +config SAMSUNG_PHONE_TTY_RAFFAELLO + tristate "Select Samsung Phone Interface - TTY for Raffaello" + depends on SAMSUNG_PHONE_TTY + +config SAMSUNG_PHONE_TTY_RAFFAELLO_RECOVERY + tristate "Select Samsung Phone Interface - TTY for Raffaello" + depends on SAMSUNG_PHONE_TTY + +endif # SAMSUNG_PHONE_TTY diff --git a/drivers/dpram/Makefile b/drivers/dpram/Makefile new file mode 100644 index 0000000..6fe6883 --- /dev/null +++ b/drivers/dpram/Makefile @@ -0,0 +1,7 @@ +# +# Makefile for kernel IDPRAM drivers. +# +override obj-dirs = $(dir $(obj)) $(obj)/raffaello/ + +obj-$(CONFIG_SAMSUNG_PHONE_TTY_RAFFAELLO) +=raffaello/dpram.o +obj-$(CONFIG_SAMSUNG_PHONE_TTY_RAFFAELLO_RECOVERY) +=raffaello/dpram_recovery.o diff --git a/drivers/dpram/raffaello/dpram.c b/drivers/dpram/raffaello/dpram.c new file mode 100755 index 0000000..77e4a03 --- /dev/null +++ b/drivers/dpram/raffaello/dpram.c @@ -0,0 +1,3747 @@ +/**************************************************************************** +** +** COPYRIGHT(C) : Samsung Electronics Co.Ltd, 2006-2010 ALL RIGHTS RESERVED +** +** IDPRAM Device Driver +** +****************************************************************************/ + +#include <linux/module.h> +#include <linux/moduleparam.h> +#include <linux/init.h> +#include <linux/interrupt.h> +#include <linux/delay.h> +#include <linux/platform_device.h> +#include <linux/uaccess.h> +#include <linux/mm.h> +#include <linux/tty.h> +#include <linux/tty_driver.h> +#include <linux/tty_flip.h> +#include <linux/irq.h> +#include <linux/poll.h> +#include <asm/io.h> +#include <asm/irq.h> +#include <mach/regs-gpio.h> +#include <plat/gpio-cfg.h> +#include <mach/hardware.h> + +#ifdef CONFIG_PROC_FS +#include <linux/proc_fs.h> +#endif /* CONFIG_PROC_FS */ + +#include <linux/workqueue.h> +#include <linux/wakelock.h> +#include <linux/miscdevice.h> +#include <linux/netdevice.h> +#ifdef CONFIG_SEC_DEBUG +#include <linux/kernel_sec_common.h> +#endif + +#include "dpram.h" +#include <mach/system.h> +#include <mach/sec_debug.h> + +/***************************************************************************/ +/* GPIO SETTING */ +/***************************************************************************/ +#include <mach/gpio.h> + +int sec_debug_dpram(void); + +/* Added to store irq num */ +int dpram_irq; +int dpram_wakeup_irq; +int phone_active_irq; +int cp_dump_irq; + +#define GPIO_QSC_INT GPIO_C210_DPRAM_INT_N +#define IRQ_QSC_INT GPIO_QSC_INT + +#define IRQ_CP_DUMP_INT GPIO_CP_DUMP_INT + +#ifdef IRQ_DPRAM_AP_INT_N +#undef IRQ_DPRAM_AP_INT_N +#endif +#define IRQ_DPRAM_AP_INT_N IRQ_MODEM_IF + +#define PRINT_DPRAM_PWR_CTRL + +/* +** Definitions for CP RAMDUMP +*/ +#if 1 +#define CMD_CP_RAMDUMP_START_REQ 0x9200 +#define CMD_CP_RAMDUMP_START_RESP 0x0300 +#define CMD_CP_RAMDUMP_SEND_REQ 0x9400 +#define CMD_CP_RAMDUMP_SEND_RESP 0x0500 +#define CMD_CP_RAMDUMP_SEND_DONE_REQ 0x9600 +#define CMD_CP_RAMDUMP_SEND_DONE_RESP 0x0700 + +#define MASK_CMD_RESULT_FAIL 0x0002 +#define MASK_CMD_RESULT_SUCCESS 0x0001 + +/* MailBox Message */ +#define QSC_UPLOAD_MODE (0x444D554C) +#define QSC_UPLOAD_MODE_COMPLETE (0xABCDEF90) + +#define CP_RAMDUMP_MAGIC_CODE_SIZE 4 +#define CP_RAMDUMP_HEADER_SIZE 12 +#define CP_RAMDUMP_BUFFER_SIZE 16364 +#define DPRAM_CP_HEADER_START_ADDRESS (DPRAM_VBASE + CP_RAMDUMP_MAGIC_CODE_SIZE) +#define DPRAM_CP_RAMDUMP_START_ADDRESS (DPRAM_CP_HEADER_START_ADDRESS + CP_RAMDUMP_HEADER_SIZE) + +#define MASK_CMD_VALID 0x8000 +#define MASK_PDA_CMD 0x1000 +#define MASK_PHONE_CMD 0x2000 + +#define RAMDUMP_WAIT_TIMEOUT 5*HZ + +typedef struct _DumpCMDHeader +{ + u32 addr; + u32 size; + u32 copyto_offset; +} DumpCMDHeader; + +typedef struct +{ + int index; + unsigned long start_addr; + unsigned long end_addr; +} s_cp_mem_region; + +typedef struct +{ + unsigned long dram_base_addr; + s_cp_mem_region cp_mem_region[16]; +} s_cp_mem_info; + +s_cp_mem_info cp_mem_info = { + 0x40000000, + { + {0, 0x00000000, 0x01FFFFFF }, + } +}; + +struct dpram { + struct class *class; + struct device *dev; + struct cdev cdev; + dev_t devid; + + wait_queue_head_t waitq; + struct fasync_struct *async_queue; + u32 mailbox; + + unsigned long base; + unsigned long size; + void __iomem *mmio; + + int irq; + + struct completion comp; + atomic_t ref_sem; + unsigned long flags; + + const struct attribute_group *group; +}; + +struct dpram *dpram_dev; + +struct completion wait_dump_data; + +static int g_irq_mask = 0; + +static u32 dump_rx_total = 0; +#endif + + +/* =========================================================================== +** +** L O C A L - V A R I A B L E S +** +** =========================================================================*/ + +/* + * GLOBALS + */ +volatile void __iomem *idpram_base = NULL; +volatile IDPRAM_SFR __iomem *idpram_sfr_base = NULL; + +static volatile u16 *dpram_mbx_BA; +static volatile u16 *dpram_mbx_AB; + +struct wake_lock dpram_wake_lock = {.name = NULL}; +static atomic_t dpram_write_lock; +static atomic_t dpram_read_lock; + +static int g_phone_sync = 0; +static int g_dump_on = 0; +static int g_dpram_wpend = IDPRAM_WPEND_UNLOCK; +struct completion g_complete_dpramdown; +static int g_cp_reset_cnt = 0; +static int g_phone_power_off_sequence = 0; + +static struct tty_driver *dpram_tty_driver; +static struct tty_struct *dpram_tty[MAX_INDEX]; +static struct ktermios *dpram_termios[MAX_INDEX]; +static struct ktermios *dpram_termios_locked[MAX_INDEX]; +static struct pdp_info *pdp_table[MAX_PDP_CONTEXT]; + +static dpram_tasklet_data_t dpram_tasklet_data[MAX_INDEX]; + +static dpram_device_t dpram_table[MAX_INDEX] = +{ + { + .in_head_addr = DPRAM_PHONE2PDA_FORMATTED_HEAD_ADDRESS, + .in_tail_addr = DPRAM_PHONE2PDA_FORMATTED_TAIL_ADDRESS, + .in_buff_addr = DPRAM_PHONE2PDA_FORMATTED_BUFFER_ADDRESS, + .in_buff_size = DPRAM_PHONE2PDA_FORMATTED_BUFFER_SIZE, + .in_head_saved = 0, + .in_tail_saved = 0, + + .out_head_addr = DPRAM_PDA2PHONE_FORMATTED_HEAD_ADDRESS, + .out_tail_addr = DPRAM_PDA2PHONE_FORMATTED_TAIL_ADDRESS, + .out_buff_addr = DPRAM_PDA2PHONE_FORMATTED_BUFFER_ADDRESS, + .out_buff_size = DPRAM_PDA2PHONE_FORMATTED_BUFFER_SIZE, + .out_head_saved = 0, + .out_tail_saved = 0, + + .mask_req_ack = INT_MASK_REQ_ACK_F, + .mask_res_ack = INT_MASK_RES_ACK_F, + .mask_send = INT_MASK_SEND_F, + }, + { + .in_head_addr = DPRAM_PHONE2PDA_RAW_HEAD_ADDRESS, + .in_tail_addr = DPRAM_PHONE2PDA_RAW_TAIL_ADDRESS, + .in_buff_addr = DPRAM_PHONE2PDA_RAW_BUFFER_ADDRESS, + .in_buff_size = DPRAM_PHONE2PDA_RAW_BUFFER_SIZE, + .in_head_saved = 0, + .in_tail_saved = 0, + + .out_head_addr = DPRAM_PDA2PHONE_RAW_HEAD_ADDRESS, + .out_tail_addr = DPRAM_PDA2PHONE_RAW_TAIL_ADDRESS, + .out_buff_addr = DPRAM_PDA2PHONE_RAW_BUFFER_ADDRESS, + .out_buff_size = DPRAM_PDA2PHONE_RAW_BUFFER_SIZE, + .out_head_saved = 0, + .out_tail_saved = 0, + + .mask_req_ack = INT_MASK_REQ_ACK_R, + .mask_res_ack = INT_MASK_RES_ACK_R, + .mask_send = INT_MASK_SEND_R, + }, +}; + +static unsigned int __log_level__ = (DL_IPC|DL_WARN|DL_NOTICE|DL_INFO|DL_DEBUG); + +#if defined(PRINT_DPRAM_WRITE) || defined(PRINT_DPRAM_READ) +static char print_buff[128]; +#endif + +static atomic_t raw_txq_req_ack_rcvd; +static atomic_t fmt_txq_req_ack_rcvd; +struct delayed_work phone_active_work; + +/* For Dual Core*/ +static DEFINE_SPINLOCK(mux_tty_lock); + + +/* +** TASKLET DECLARATIONs +*/ +static void res_ack_tasklet_handler(unsigned long data); +static void fmt_rcv_tasklet_handler(unsigned long data); +static void raw_rcv_tasklet_handler(unsigned long data); + +static DECLARE_TASKLET(fmt_send_tasklet, fmt_rcv_tasklet_handler, 0); +static DECLARE_TASKLET(raw_send_tasklet, raw_rcv_tasklet_handler, 0); +static DECLARE_TASKLET(fmt_res_ack_tasklet, res_ack_tasklet_handler, (unsigned long)&dpram_table[FORMATTED_INDEX]); +static DECLARE_TASKLET(raw_res_ack_tasklet, res_ack_tasklet_handler, (unsigned long)&dpram_table[RAW_INDEX]); +static DEFINE_MUTEX(pdp_lock); + + +/* +** FUNCTION PROTOTYPEs +*/ +static void dpram_drop_data(dpram_device_t *device); +static int kernel_sec_dump_cp_handle2(void); +static int dpram_phone_getstatus(void); +static void dpram_send_mbx_BA(u16 irq_mask); +static void dpram_send_mbx_BA_cmd(u16 irq_mask); +static void dpram_power_down(void); +static void dpram_powerup_start(void); +static int register_interrupt_handler(void); +static irqreturn_t dpram_irq_handler(int irq, void *dev_id); + + +static inline struct pdp_info * pdp_get_dev(u8 id); +static inline void check_pdp_table(const char*, int); +static void cmd_error_display_handler(void); + + +#ifdef _ENABLE_ERROR_DEVICE +static unsigned int dpram_err_len = 0; +static char dpram_err_buf[DPRAM_ERR_MSG_LEN]; +static unsigned int dpram_err_cause = 0; + +static unsigned int dpram_dump_len = 0; +static char cp_ramdump_buff[16384]; + +struct class *dpram_err_class; +struct class *dpram_dump_class; + +static DECLARE_WAIT_QUEUE_HEAD(dpram_err_wait_q); +static DECLARE_WAIT_QUEUE_HEAD(dpram_dump_wait_q); + +static struct fasync_struct *dpram_err_async_q; +static struct fasync_struct *dpram_dump_async_q; + +extern void usb_switch_mode(int); +#ifdef CONFIG_SEC_DEBUG +extern int get_sec_debug_level(void); +#endif +#endif /* _ENABLE_ERROR_DEVICE */ + + +#ifndef DISABLE_IPC_DEBUG +typedef struct { + unsigned char start_flag; + unsigned char hdlc_length[2]; + unsigned char hdlc_control; + unsigned char ipc_length[2]; + unsigned char msg_seq; + unsigned char ack_seq; + unsigned char main_cmd; + unsigned char sub_cmd; + unsigned char cmd_type; + unsigned char parameter[1024]; +} dpram_fmt_frame; +#endif + + +#if 1 +u32 dpram_write_magic_code(u32 code) +{ + u32 address = 0; + u32 value = 0; + + address = (u32)(DPRAM_VBASE + DPRAM_MAGIC_CODE_ADDRESS); + + LOGA("Code : 0x%08x, Magic code address : 0x%08x\n", code, address); + + memcpy_toio((void *)address, (void *)&code, 4); + memcpy_fromio((void *)&value, (void *)address, 4); + + LOGA("DPRAM Read Magic = 0x%08x\n", value); + + if (value != code) + LOGE("value != code\n"); + + return (value == code); +} + +static void DRV_Setting_ModemUploadMode(void) +{ + + dpram_write_magic_code(QSC_UPLOAD_MODE); +} + +static void DRV_Wait_ModemInit(void) +{ + + while (!gpio_get_value(GPIO_QSC_PHONE_ACTIVE)) { + msleep(100); + printk("."); + } + printk("\n"); +} + +static inline void dpram_clear_modem_command(void) +{ + iowrite16(0, (void*)(DPRAM_VBASE + DPRAM_PHONE2PDA_INTERRUPT_ADDRESS)); +} + +static inline u16 dpram_read_command(void) +{ + return ioread16((void*)(DPRAM_VBASE + DPRAM_PHONE2PDA_INTERRUPT_ADDRESS)); +} + +static void dpram_send_command(u16 nCmd) +{ + dpram_clear_modem_command(); + iowrite16(nCmd, (void*)(DPRAM_VBASE + DPRAM_PDA2PHONE_INTERRUPT_ADDRESS)); +} + +/* return value +// -1 : false +// 0 : continue +// 1 : true */ +#define CMD_FALSE -1 +#define CMD_RETRY 0 +#define CMD_TRUE 1 + +static u32 check_command(u16 intr, u16 mask) +{ + if (intr == 0) { + return CMD_RETRY; + } else { + if ((intr & MASK_CMD_VALID) != MASK_CMD_VALID) { + return CMD_RETRY; + } + else if ((intr & MASK_PDA_CMD) == MASK_PDA_CMD) { + return CMD_RETRY; + } + else if ((intr & MASK_PHONE_CMD) == MASK_PHONE_CMD) { + if ((intr & mask) == mask) + return CMD_TRUE; + else + return CMD_FALSE; + } + else + return CMD_RETRY; + } +} + +static u16 dpram_wait_response(u16 nCmd) +{ + u16 intr, ret; + int i; + + for (i = 0; i < 100; i++) + { + intr = dpram_read_command(); + ret = check_command(intr, nCmd); + if(ret == CMD_TRUE) + return CMD_TRUE; + else if(ret == CMD_FALSE) + return CMD_FALSE; + wait_for_completion_interruptible_timeout(&wait_dump_data, (HZ/100)); + init_completion(&wait_dump_data); + } + return CMD_RETRY; +} + +static void dpram_clear_response(void) +{ + init_completion(&wait_dump_data); + IDPRAM_INT_CLEAR(); + dpram_clear_modem_command(); +} + +static void _Request_ModemData(u32 addr, u32 size) +{ + DumpCMDHeader header; + u32 rx_required = 0; + int ret = 0; + + memset(&header, 0, sizeof(header)); + + rx_required = min(size - dump_rx_total, (u32)CP_RAMDUMP_BUFFER_SIZE); + + header.addr = addr + dump_rx_total; + header.size = rx_required; + header.copyto_offset = 0x38000010; + + memcpy_toio((void*)DPRAM_CP_HEADER_START_ADDRESS, (void*)&header, sizeof(header)); + + /* Wait for ACK */ + dpram_send_command(CMD_CP_RAMDUMP_SEND_REQ); + ret = dpram_wait_response(CMD_CP_RAMDUMP_SEND_RESP|MASK_CMD_RESULT_SUCCESS); + if (!ret) { + LOGE("Failed in dpram_wait_response()!!!\n"); + return; + } + dpram_clear_response(); + + /* Copy dump from DPRAM to local buffer */ + memcpy_fromio((void*)cp_ramdump_buff, (void*)DPRAM_CP_RAMDUMP_START_ADDRESS, CP_RAMDUMP_BUFFER_SIZE); + + /* Prepare to pass the dump data to RIL */ + dpram_dump_len = rx_required; + + dump_rx_total += rx_required; +} + +static void setup_cp_ramdump(void) +{ + DRV_Setting_ModemUploadMode(); + DRV_Wait_ModemInit(); +} + +static void start_cp_ramdump(void) +{ + int i, ret; + + for (i = 0; i < 30; i++) + { + dpram_send_command(CMD_CP_RAMDUMP_START_REQ); + ret = dpram_wait_response(CMD_CP_RAMDUMP_START_RESP|MASK_CMD_RESULT_SUCCESS); + if (ret == CMD_TRUE) { + LOGA("succeeded in dpram_wait_response()!!!\n"); + dpram_clear_response(); + return; + } else if (ret == CMD_FALSE) { + LOGE("Failed in dpram_wait_response()!!!\n"); + dpram_clear_response(); + return; + } + LOGA("RETRY is required in dpram_wait_response()!!!\n"); + } + + LOGE("Failed in dpram_wait_response()!!!\n"); + dpram_clear_response(); +} + +static void receive_cp_ramdump(void) +{ + u32 dump_start_addr, dump_end_addr, dump_size; + + dump_start_addr = cp_mem_info.cp_mem_region[0].start_addr; + dump_end_addr = cp_mem_info.cp_mem_region[0].end_addr; + dump_size = (dump_end_addr - dump_start_addr) + 1; + + /* read modem RAMDUMP data */ + _Request_ModemData(dump_start_addr, dump_size); +} + +static void close_cp_ramdump(void) +{ + int ret; + + dpram_send_command(CMD_CP_RAMDUMP_SEND_DONE_REQ); + ret = dpram_wait_response(CMD_CP_RAMDUMP_SEND_DONE_RESP|MASK_CMD_RESULT_SUCCESS); + if (!ret) { + LOGE("Failed in dpram_wait_response()!!!\n"); + return; + } + LOGA("succeeded in dpram_wait_response()!!!\n"); + dpram_clear_response(); +} +#endif + + +/* +** tty related functions. +*/ +static inline void dpram_byte_align(unsigned long dest, unsigned long src) +{ + volatile u16 *p_dest; + u16 *p_src; + + if ( (dest & 1) && (src & 1) ) + { + p_dest = (u16 *)(dest - 1); + p_src = (u16 *)(src - 1); + + *p_dest = (*p_dest & 0x00FF) | (*p_src & 0xFF00); + } + else if ( (dest & 1) && !(src & 1) ) + { + p_dest = (u16 *)(dest - 1); + p_src = (u16 *)src; + *p_dest = (*p_dest & 0x00FF) | ((*p_src << 8) & 0xFF00); + } + else if ( !(dest & 1) && (src & 1) ) + { + p_dest = (u16 *)dest; + p_src = (u16 *)(src - 1); + *p_dest = (*p_dest & 0xFF00) | ((*p_src >> 8) & 0x00FF); + } + else //if ( !(dest & 1) && !(src & 1) ) + { + p_dest = (u16 *)dest; + p_src = (u16 *)src; + *p_dest = (*p_dest & 0xFF00) | (*p_src & 0x00FF); + } +#if 0 + else + { + LOGE("oops.~\n"); + } +#endif +} + +static inline void _memcpy(void *p_dest, const void *p_src, int size) +{ + unsigned long dest = (unsigned long)p_dest; + unsigned long src = (unsigned long)p_src; + + if (size <= 0) + return; + + if (dest & 1) + { + /* If the destination address is odd, store the first byte at first.*/ + dpram_byte_align(dest, src); + dest++, src++; + size--; + } + + if (size & 1) + { + /* If the size is odd, store the last byte at first.*/ + dpram_byte_align(dest + size - 1, src + size - 1); + size--; + } + + if (src & 1) + { + volatile u16 *d = (u16 *)dest; + unsigned char *s = (u8 *)src; + + size >>= 1; + + while (size--) + { + *d++ = s[0] | (s[1] << 8); + s += 2; + } + } + else + { + volatile u16 *d = (u16 *)dest; + u16 *s = (u16 *)src; + + size >>= 1; + + while (size--) + { + *d++ = *s++; + } + } +} + +/* Note the use of non-standard return values (0=match, 1=no-match) */ +static inline int _memcmp(u8 *dest, u8 *src, int size) +{ + while( size-- ) + { + if( *dest++ != *src++ ) + return 1 ; + } + + return 0 ; +} + + +#define WRITE_TO_DPRAM(dest, src, size) \ + _memcpy((void *)(DPRAM_VBASE + dest), src, size) + +#define READ_FROM_DPRAM(dest, src, size) \ + _memcpy(dest, (void *)(DPRAM_VBASE + src), size) + + +static inline int WRITE_TO_DPRAM_VERIFY(u32 dest, void *src, int size) +{ + int cnt = 3; + + while (cnt--) + { + _memcpy((void *)(DPRAM_VBASE + dest), (void *)src, size); + + if (!_memcmp((u8 *)(DPRAM_VBASE + dest), (u8 *)src, size)) + return 0; + } + + return -1; +} + +static inline int READ_FROM_DPRAM_VERIFY(void *dest, u32 src, int size) +{ + int cnt = 3; + + while (cnt--) + { + _memcpy((void *)dest, (void *)(DPRAM_VBASE + src), size); + + if (!_memcmp((u8 *)dest, (u8 *)(DPRAM_VBASE + src), size)) + return 0; + } + + return -1; +} + +static int dpram_lock_write(const char* func) +{ + int lock_value; + + lock_value = (g_dpram_wpend == IDPRAM_WPEND_LOCK) ? -3 : atomic_inc_return(&dpram_write_lock); + if ( lock_value != 1 ) + LOGE("lock_value (%d) != 1\n", lock_value); + + return lock_value; +} + +static void dpram_unlock_write(const char* func) +{ + int lock_value; + + lock_value = atomic_dec_return(&dpram_write_lock); + + if ( lock_value != 0 ) + LOGE("lock_value (%d) != 0\n", lock_value); +} + +// TODO: +// because it is dpram device, I think read_lock don't need but I will use for holding wake_lock +static int dpram_get_lock_read(void) +{ + return atomic_read(&dpram_read_lock); +} + +static int dpram_lock_read(const char* func) +{ + int lock_value; + + lock_value = atomic_inc_return(&dpram_read_lock); + if(lock_value !=1) + LOGE("(%s, lock) lock_value: %d\n", func, lock_value); + wake_lock_timeout(&dpram_wake_lock, HZ*6); + return 0; +} + +static void dpram_unlock_read(const char* func) +{ + int lock_value; + + lock_value = atomic_dec_return(&dpram_read_lock); + + if(lock_value !=0) + LOGE("(%s, lock) lock_value: %d\n", func, lock_value); + + wake_unlock(&dpram_wake_lock); +} + + +#if defined(PRINT_DPRAM_WRITE) || defined(PRINT_DPRAM_READ) +static void dpram_print_packet(char *buf, int len) +{ + int i = 0; + LOGA("len = %d\n", len); + + print_buff[0] = '\0'; + + for (i = 0; i < len; i++) + { + sprintf((print_buff + (i%16)*3), "%02x \0", *((char *)buf + i)); + if ( (i%16) == 15 ) + { + LOGA("%s\n", print_buff); + print_buff[0] = '\0'; + } + } + + if ( strlen(print_buff) ) + { + LOGA("%s\n", print_buff); + } +} +#endif /*PRINT_DPRAM_WRITE || PRINT_DPRAM_READ*/ + +static int dpram_write(dpram_device_t *device, const unsigned char *buf, int len) +{ + int retval = 0; + int size = 0; + u16 head, tail, magic, access ; + u16 irq_mask = 0; + struct pdp_hdr *pdp_hdr_ptr = (struct pdp_hdr *)(buf + 1); + int curr_pkt_len = 0, free_space = 0; + + //PRINT_FUNC(); +#ifdef PRINT_DPRAM_WRITE + PRINT_FUNC(); + dpram_print_packet(buf, len); +#endif + + if (g_dump_on) { + LOGA("g_dump_on == 1\n"); + return 0; + } + + // If the phone is down, let's reset everything and fail the write. +#ifdef CDMA_IPC_C210_IDPRAM + magic = ioread16((void *)(DPRAM_VBASE + DPRAM_MAGIC_CODE_ADDRESS)); + access = ioread16((void *)(DPRAM_VBASE + DPRAM_ACCESS_ENABLE_ADDRESS)); +#else + READ_FROM_DPRAM_VERIFY(&magic, DPRAM_MAGIC_CODE_ADDRESS, sizeof(magic)); + READ_FROM_DPRAM_VERIFY(&access, DPRAM_ACCESS_ENABLE_ADDRESS, sizeof(access)); +#endif + + /* Gaudi : modified ril power off sequence */ + //if (g_phone_sync != 1 || !access || magic != 0xAA) + if (!access || magic != 0xAA) + { + LOGE("Phone has not booted yet!!! (phone_sync = %d)\n", g_phone_sync); + return -EFAULT; + } + + if ( dpram_lock_write(__func__) < 0 ) + { + return -EAGAIN; + } + +#ifdef CDMA_IPC_C210_IDPRAM + head = ioread16((void *)(DPRAM_VBASE + device->out_head_addr)); + tail = ioread16((void *)(DPRAM_VBASE + device->out_tail_addr)); +#else + READ_FROM_DPRAM_VERIFY(&head, device->out_head_addr, sizeof(head)); + READ_FROM_DPRAM_VERIFY(&tail, device->out_tail_addr, sizeof(tail)); +#endif + + // Make sure the queue tail pointer is valid. + if( tail >= device->out_buff_size || head >= device->out_buff_size ) + { + head = tail = 0; +#ifdef CDMA_IPC_C210_IDPRAM + iowrite16(head, (void *)(DPRAM_VBASE + device->out_head_addr)); + iowrite16(tail, (void *)(DPRAM_VBASE + device->out_tail_addr)); +#else + WRITE_TO_DPRAM_VERIFY(device->out_head_addr, &head, sizeof(head)); + WRITE_TO_DPRAM_VERIFY(device->out_tail_addr, &tail, sizeof(tail)); +#endif + dpram_unlock_write(__func__); + return 0 ; + } + +#ifdef PRINT_DPRAM_WRITE + LOGA("head: %d, tail: %d\n", head, tail); +#endif + + /* check free space */ + curr_pkt_len = pdp_hdr_ptr->len + 2; /*include SOF/EOF*/ + free_space = (head < tail) ? tail-head -1 : device->out_buff_size + tail - head - 1; + + if (curr_pkt_len > free_space) { + LOGE("WRITE: No space in Q, curr_pkt_len[%d] free_space[%d] head[%d] tail[%d]\n", + curr_pkt_len, free_space, head, tail); + dpram_unlock_write(__func__); + return -EAGAIN; + } + + // +++++++++ head ---------- tail ++++++++++ // + if (head < tail) { + size = tail - head - 1; + size = (len > size) ? size : len; + WRITE_TO_DPRAM(device->out_buff_addr + head, buf, size); + retval = size; + } + + // tail +++++++++++++++ head --------------- // + else if (tail == 0) { + size = device->out_buff_size - head - 1; + size = (len > size) ? size : len; + WRITE_TO_DPRAM(device->out_buff_addr + head, buf, size); + retval = size; + } + + // ------ tail +++++++++++ head ------------ // + else { + size = device->out_buff_size - head; + size = (len > size) ? size : len; + WRITE_TO_DPRAM(device->out_buff_addr + head, buf, size); + retval = size; + + if (len > retval) { + size = (len - retval > tail - 1) ? tail - 1 : len - retval; + WRITE_TO_DPRAM(device->out_buff_addr, buf + retval, size); + retval += size; + } + } + + /* @LDK@ calculate new head */ + head = (u16)((head + retval) % device->out_buff_size); +#ifdef CDMA_IPC_C210_IDPRAM + iowrite16(head, (void *)(DPRAM_VBASE + device->out_head_addr)); +#else + WRITE_TO_DPRAM_VERIFY(device->out_head_addr, &head, sizeof(head)); +#endif + device->out_head_saved = head; + device->out_tail_saved = tail; + + /* @LDK@ send interrupt to the phone, if.. */ + irq_mask = INT_MASK_VALID; + + if (retval > 0) + irq_mask |= device->mask_send; + + if (len > retval) + irq_mask |= device->mask_req_ack; + + dpram_unlock_write(__func__); + dpram_send_mbx_BA(irq_mask); + + return retval; +} + +static inline int dpram_tty_insert_data(dpram_device_t *device, const u8 *psrc, u16 size) +{ +#define CLUSTER_SEGMENT 1500 + + u16 copied_size = 0; + int retval = 0; + +#ifdef PRINT_DPRAM_READ + dpram_print_packet(psrc, size); +#endif + + if ( size > CLUSTER_SEGMENT && (device->serial.tty->index == 1) ) + { + while (size) + { + copied_size = (size > CLUSTER_SEGMENT) ? CLUSTER_SEGMENT : size; + tty_insert_flip_string(device->serial.tty, psrc + retval, copied_size); + + size -= copied_size; + retval += copied_size; + } + + return retval; + } + + return tty_insert_flip_string(device->serial.tty, psrc, size); +} + +static int dpram_read_fmt(dpram_device_t *device, const u16 non_cmd) +{ + int retval = 0; + int retval_add = 0; + int size = 0; + u16 head, tail; + + dpram_lock_read(__func__); + +#ifdef CDMA_IPC_C210_IDPRAM + head = ioread16((void *)(DPRAM_VBASE + device->in_head_addr)); + tail = ioread16((void *)(DPRAM_VBASE + device->in_tail_addr)); +#else + READ_FROM_DPRAM_VERIFY(&head, device->in_head_addr, sizeof(head)); + READ_FROM_DPRAM_VERIFY(&tail, device->in_tail_addr, sizeof(tail)); +#endif + +#ifdef PRINT_DPRAM_READ + LOGA("head: %d, tail: %d\n", head, tail); +#endif + + if (head != tail) + { + u16 up_tail = 0; + + // ------- tail ########## head -------- // + if (head > tail) + { + size = head - tail; + retval = dpram_tty_insert_data(device, (u8 *)(DPRAM_VBASE + (device->in_buff_addr + tail)), size); + if (size != retval) + LOGE("size: %d, retval: %d\n", size, retval); + } + // ####### head ------------ tail ###### // + else + { + int tmp_size = 0; + + // Total Size. + size = device->in_buff_size - tail + head; + + // 1. tail -> buffer end. + tmp_size = device->in_buff_size - tail; + retval = dpram_tty_insert_data(device, (u8 *)(DPRAM_VBASE + (device->in_buff_addr + tail)), tmp_size); + if (tmp_size != retval) + { + LOGE("size: %d, retval: %d\n", size, retval); + } + + // 2. buffer start -> head. + if (size > tmp_size) + { + retval_add = dpram_tty_insert_data(device, (u8 *)(DPRAM_VBASE + device->in_buff_addr), size - tmp_size); + retval += retval_add; + + if((size - tmp_size)!= retval_add) + { + LOGE("size - tmp_size: %d, retval_add: %d\n", size - tmp_size, retval_add); + } + } + } + + /* new tail */ + up_tail = (u16)((tail + retval) % device->in_buff_size); +#ifdef CDMA_IPC_C210_IDPRAM + iowrite16(up_tail, (void *)(DPRAM_VBASE + device->in_tail_addr)); +#else + WRITE_TO_DPRAM_VERIFY(device->in_tail_addr, &up_tail, sizeof(up_tail)); +#endif + } + + + device->in_head_saved = head; + device->in_tail_saved = tail; + + dpram_unlock_read(__func__); + + if ( atomic_read(&fmt_txq_req_ack_rcvd) > 0 || (non_cmd & device->mask_req_ack) ) + { + // there is a situation where the q become full after we reached the tasklet. + // so this logic will allow us to send the RES_ACK as soon as we read 1 packet and CP get a chance to + // write another buffer. +// LOGA("Sending INT_MASK_RES_ACK_F\n"); + dpram_send_mbx_BA(INT_NON_COMMAND(device->mask_res_ack)); + atomic_set(&fmt_txq_req_ack_rcvd, 0); + } + + return retval; + +} + +static int dpram_read_raw(dpram_device_t *device, const u16 non_cmd) +{ + int retval = 0; + int size = 0; + u16 head, tail; + u16 up_tail = 0; + int ret; + size_t len; + struct pdp_info *dev = NULL; + struct pdp_hdr hdr; + u16 read_offset; + u8 len_high, len_low, id, control; + u16 pre_data_size; //pre_hdr_size, + u8 ch; + + dpram_lock_read(__func__); + +#ifdef CDMA_IPC_C210_IDPRAM + head = ioread16((void *)(DPRAM_VBASE + device->in_head_addr)); + tail = ioread16((void *)(DPRAM_VBASE + device->in_tail_addr)); +#else + READ_FROM_DPRAM_VERIFY(&head, device->in_head_addr, sizeof(head)); + READ_FROM_DPRAM_VERIFY(&tail, device->in_tail_addr, sizeof(tail)); +#endif + +#ifdef PRINT_DPRAM_HEAD_TAIL + LOGA("head: %d, tail: %d\n", head, tail); +#endif + + if (head != tail) + { + up_tail = 0; + + if (head > tail) + /* ----- (tail) 7f 00 00 7e (head) ----- */ + size = head - tail; + else + /* 00 7e (head) ----------- (tail) 7f 00 */ + size = device->in_buff_size - tail + head; + + read_offset = 0; +#ifdef PRINT_DPRAM_HEAD_TAIL + LOGA("head: %d, tail: %d, size: %d\n", head, tail, size); +#endif + while (size) + { + READ_FROM_DPRAM(&ch, device->in_buff_addr +((u16)(tail + read_offset) % device->in_buff_size), sizeof(ch)); + + if (ch == 0x7F) + { + read_offset ++; + } + else + { + LOGE("First byte: 0x%02x, drop bytes: %d, buff addr: 0x%08lx, " + "read addr: 0x%08lx\n",ch, size, + (device->in_buff_addr), (device->in_buff_addr + + ((u16)(tail + read_offset) % device->in_buff_size))); + dpram_drop_data(device); + dpram_unlock_read(__func__); + return -1; + } + + len_high = len_low = id = control = 0; + READ_FROM_DPRAM(&len_low, device->in_buff_addr + ((u16)(tail + read_offset) % device->in_buff_size) ,sizeof(len_high)); + read_offset ++; + READ_FROM_DPRAM(&len_high, device->in_buff_addr + ((u16)(tail + read_offset) % device->in_buff_size) ,sizeof(len_low)); + read_offset ++; + READ_FROM_DPRAM(&id, device->in_buff_addr + ((u16)(tail + read_offset) % device->in_buff_size) ,sizeof(id)); + read_offset ++; + READ_FROM_DPRAM(&control, device->in_buff_addr + ((u16)(tail + read_offset) % device->in_buff_size) ,sizeof(control)); + read_offset ++; + + hdr.len = len_high <<8 | len_low; + hdr.id = id; + hdr.control = control; + + len = hdr.len - sizeof(struct pdp_hdr); + if (len <= 0) + { + LOGE("oops... read_offset: %d, len: %d, hdr.id: %d\n", read_offset, len, hdr.id); + dpram_drop_data(device); + dpram_unlock_read(__func__); + return -1; + } + + dev = pdp_get_dev(hdr.id); +#ifdef PRINT_DPRAM_READ + LOGA("read_offset: %d, len: %d, hdr.id: %d\n", read_offset, len, hdr.id); +#endif + if (!dev) + { + LOGE("RAW READ Failed.. NULL dev detected \n"); + check_pdp_table(__func__, __LINE__); + dpram_drop_data(device); + dpram_unlock_read(__func__); + return -1; + } + + if (dev->vs_dev.tty != NULL && dev->vs_dev.refcount) + { + if((u16)(tail + read_offset) % device->in_buff_size + len < device->in_buff_size) + { + ret = tty_insert_flip_string(dev->vs_dev.tty, (u8 *)(DPRAM_VBASE + (device->in_buff_addr + (u16)(tail + read_offset) % device->in_buff_size)), len); + dev->vs_dev.tty->low_latency = 0; + tty_flip_buffer_push(dev->vs_dev.tty); + } + else + { + pre_data_size = device->in_buff_size - (tail + read_offset); + ret = tty_insert_flip_string(dev->vs_dev.tty, (u8 *)(DPRAM_VBASE + (device->in_buff_addr + tail + read_offset)), pre_data_size); + ret += tty_insert_flip_string(dev->vs_dev.tty, (u8 *)(DPRAM_VBASE + (device->in_buff_addr)),len - pre_data_size); + dev->vs_dev.tty->low_latency = 0; + tty_flip_buffer_push(dev->vs_dev.tty); +#ifdef PRINT_DPRAM_READ + LOGE("RAW pre_data_size: %d, len-pre_data_size: %d, ret: %d\n", pre_data_size, len- pre_data_size, ret); +#endif + } + } + else + { + LOGE("tty channel(id:%d) is not opened!!!\n", dev->id); + ret = len; + } + + if (!ret) + { + LOGE("(tty_insert_flip_string) drop bytes: %d, " + "buff addr: 0x%08lx\n, read addr: 0x%08lx\n", + size, (device->in_buff_addr), + (device->in_buff_addr + ((u16)(tail + read_offset) + % device->in_buff_size))); + dpram_drop_data(device); + dpram_unlock_read(__func__); + return -1; + } + + read_offset += ret; +#ifdef PRINT_DPRAM_READ + LOGA("read_offset: %d, ret: %d\n", read_offset, ret); +#endif + READ_FROM_DPRAM(&ch, (device->in_buff_addr + ((u16)(tail + read_offset) % device->in_buff_size)), sizeof(ch)); + if (ch == 0x7e) + { + read_offset++; + } + else + { + LOGE("Last byte: 0x%02x, drop bytes: %d, buff addr: 0x%08lx, " + "read addr: 0x%08lx\n",ch, size, (device->in_buff_addr), + (device->in_buff_addr + ((u16)(tail + read_offset) % + device->in_buff_size))); + dpram_drop_data(device); + dpram_unlock_read(__func__); + return -1; + } + + size -= (ret + sizeof(struct pdp_hdr) + 2); + retval += (ret + sizeof(struct pdp_hdr) + 2); + + if (size < 0) + { + LOGE("something wrong....\n"); + break; + } + + } + + up_tail = (u16)((tail + read_offset) % device->in_buff_size); +#ifdef CDMA_IPC_C210_IDPRAM + iowrite16(up_tail, (void *)(DPRAM_VBASE + device->in_tail_addr)); +#else + WRITE_TO_DPRAM_VERIFY(device->in_tail_addr, &up_tail, sizeof(up_tail)); +#endif + } + + device->in_head_saved = head; + device->in_tail_saved = tail; + + dpram_unlock_read(__func__); + + if ( atomic_read(&raw_txq_req_ack_rcvd) > 0 || (non_cmd & device->mask_req_ack) ) + { + // there is a situation where the q become full after we reached the tasklet. + // so this logic will allow us to send the RES_ACK as soon as we read 1 packet and CP get a chance to + // write another buffer. +// LOGA("Sending INT_MASK_RES_ACK_R\n"); + dpram_send_mbx_BA(INT_NON_COMMAND(device->mask_res_ack)); + atomic_set(&raw_txq_req_ack_rcvd, 0); + } + + return retval; +} + +static int dpram_init_magic_num(void) +{ + const u16 magic_code = 0x4D4E; + u16 acc_code = 0; + u16 ret_value = 0; + + PRINT_FUNC(); + + if ( dpram_lock_write(__func__) < 0 ) + return -EAGAIN; + + /*write DPRAM disable code */ + iowrite16(acc_code, (void *)(DPRAM_VBASE + DPRAM_ACCESS_ENABLE_ADDRESS)); + + /* write DPRAM magic code : Normal boot Magic - 0x4D4E*/ + iowrite16(magic_code, (void *)(DPRAM_VBASE + DPRAM_MAGIC_CODE_ADDRESS)); + + /*write enable code */ + acc_code = 0x0001; + iowrite16(acc_code, (void *)(DPRAM_VBASE + DPRAM_ACCESS_ENABLE_ADDRESS)); + + /*send init end code to phone */ + dpram_unlock_write(__func__); + + ret_value = ioread16((void *)(DPRAM_VBASE + DPRAM_MAGIC_CODE_ADDRESS)); + + LOGA("Read_MagicNum : 0x%04x\n", ret_value); + + return 0; + +} + + +#ifdef _ENABLE_ERROR_DEVICE +void request_phone_reset(void) +{ + return; + + /* char buf[DPRAM_ERR_MSG_LEN]; + unsigned long flags; + + dpram_init_magic_num(); + + memset((void *)buf, 0, sizeof (buf)); + + LOGE("CDMA reset cnt = %d\n", g_cp_reset_cnt); + if (g_cp_reset_cnt > 5) + { + buf[0] = '1'; + buf[1] = ' '; + memcpy(buf+2, "$CDMA-DEAD", sizeof("$CDMA-DEAD")); + } + else + { + buf[0] = '8'; + buf[1] = ' '; + memcpy(buf+2, "$PHONE-OFF", sizeof("$PHONE-OFF")); + } + + LOGE("[PHONE ERROR] ->> %s\n", buf); + local_irq_save(flags); + memcpy(dpram_err_buf, buf, DPRAM_ERR_MSG_LEN); + dpram_err_len = 64; + local_irq_restore(flags); + + wake_up_interruptible(&dpram_err_wait_q); + kill_fasync(&dpram_err_async_q, SIGIO, POLL_IN);*/ +} +#endif + + +static void dpram_send_mbx_BA(u16 irq_mask) +{ + if (g_dump_on) + return; + +#ifdef CDMA_IPC_C210_IDPRAM + iowrite16(irq_mask, (void *)dpram_mbx_BA); +#else + *dpram_mbx_BA = irq_mask; +#endif + +#ifdef PRINT_DPRAM_WRITE + LOG("mbx_BA = 0x%04X\n", irq_mask); +#endif +} + + +/* + * dpram_send_mbx_BA_cmd() + * - for prevent CP interrupt command miss issue, + * below function check the CP dpram interrupt level before send interrupt + */ +#define DPRAM_CMD_SEND_RETRY_CNT 0x5 +static void dpram_send_mbx_BA_cmd(u16 irq_mask) +{ + int retry_cnt = DPRAM_CMD_SEND_RETRY_CNT; + + if (g_dump_on) + return; + + /* Set GPIO_PDA_ACTIVE as CP sometimes seems to read this pin as Low */ + gpio_set_value(GPIO_PDA_ACTIVE, GPIO_LEVEL_HIGH); + + while (gpio_get_value(GPIO_DPRAM_INT_CP_N) == 0 && retry_cnt--) + { + msleep(1); + LOGE("send cmd intr, retry cnt = %d\n", (DPRAM_CMD_SEND_RETRY_CNT-retry_cnt)); + + /* Set GPIO_PDA_ACTIVE as CP sometimes seems to read this pin as Low */ + LOGA("Current GPIO_PDA_ACTIVE = %d\n", gpio_get_value(GPIO_PDA_ACTIVE) ); + gpio_set_value(GPIO_PDA_ACTIVE, GPIO_LEVEL_HIGH); + LOGA("GPIO_PDA_ACTIVE = %d\n", gpio_get_value(GPIO_PDA_ACTIVE) ); + } + +#ifdef CDMA_IPC_C210_IDPRAM + iowrite16(irq_mask, (void *)dpram_mbx_BA); +#else + *dpram_mbx_BA = irq_mask; +#endif + +#ifdef PRINT_DPRAM_WRITE + LOGA("mbx_BA = 0x%04X\n", irq_mask); +#endif +} + + +static void dpram_clear(void) +{ + long i = 0; + long size = 0; + unsigned long flags; + + u16 value = 0; + + size = DPRAM_SIZE - (DPRAM_INTERRUPT_PORT_SIZE * 4); + + /* @LDK@ clear DPRAM except interrupt area */ + local_irq_save(flags); + + for (i = DPRAM_PDA2PHONE_FORMATTED_HEAD_ADDRESS; i < size; i += 2) + { + iowrite16(0, (void *)(DPRAM_VBASE + i)); + } + + local_irq_restore(flags); + + value = ioread16((void *)dpram_mbx_AB); +} + +static int dpram_init_and_report(void) +{ + const u16 init_start = INT_COMMAND(MBX_CMD_INIT_START); + const u16 init_end = INT_COMMAND(MBX_CMD_INIT_END | AP_PLATFORM_ANDROID); + const u16 magic_code = 0x00AA; + u16 acc_code = 0; + +//#ifdef DEBUG_DPRAM_INT_HANDLER + PRINT_FUNC(); +//#endif + + dpram_send_mbx_BA(init_start); + + if ( dpram_lock_write(__func__) < 0 ) + return -EAGAIN; + + /* @LDK@ write DPRAM disable code */ + iowrite16(acc_code, (void *)(DPRAM_VBASE + DPRAM_ACCESS_ENABLE_ADDRESS)); + + /* @LDK@ dpram clear */ + dpram_clear(); + + /* @LDK@ write DPRAM magic code & enable code */ + iowrite16(magic_code, (void *)(DPRAM_VBASE + DPRAM_MAGIC_CODE_ADDRESS)); + acc_code = 0x0001; + iowrite16(acc_code, (void *)(DPRAM_VBASE + DPRAM_ACCESS_ENABLE_ADDRESS)); + + /* @LDK@ send init end code to phone */ + dpram_unlock_write(__func__); + + dpram_send_mbx_BA(init_end); + +//#ifdef DEBUG_DPRAM_INT_HANDLER + LOGA("Sent CMD_INIT_END(0x%04X) to Phone!!!\n", init_end); +//#endif + + g_phone_sync = 1; + g_cp_reset_cnt = 0; + + return 0; +} + +static inline int dpram_get_read_available(dpram_device_t *device) +{ + u16 head = 0, tail = 0, size = 0; + +#ifdef CDMA_IPC_C210_IDPRAM + head = ioread16((void *)(DPRAM_VBASE + device->in_head_addr)); + tail = ioread16((void *)(DPRAM_VBASE + device->in_tail_addr)); +#else + READ_FROM_DPRAM_VERIFY(&head, device->in_head_addr, sizeof(head)); + READ_FROM_DPRAM_VERIFY(&tail, device->in_tail_addr, sizeof(tail)); +#endif + + if ( tail >= device->in_buff_size || head >= device->in_buff_size ) + { + return 0; + } + + size = ( head >= tail )? (head - tail) : (device->in_buff_size - tail + head); + +#ifdef PRINT_DPRAM_READ + if ( size > 0 ) + LOGA("Data size = %d\n", size); +#endif + + return size; +} + +static void dpram_drop_data(dpram_device_t *device) +{ + u16 head, tail; + +#ifdef CDMA_IPC_C210_IDPRAM + head = ioread16((void *)(DPRAM_VBASE + device->in_head_addr)); + tail = ioread16((void *)(DPRAM_VBASE + device->in_tail_addr)); +#else + READ_FROM_DPRAM_VERIFY(&head, device->in_head_addr, sizeof(head)); + READ_FROM_DPRAM_VERIFY(&tail, device->in_tail_addr, sizeof(tail)); +#endif + + if( head >= device->in_buff_size || tail >= device->in_buff_size ) + { + head = tail = 0 ; +#ifdef CDMA_IPC_C210_IDPRAM + iowrite16(head, (void *)(DPRAM_VBASE + device->in_head_addr)); +#else + WRITE_TO_DPRAM_VERIFY(device->in_head_addr, &head, sizeof(head)); +#endif + } + +#ifdef CDMA_IPC_C210_IDPRAM + iowrite16(head, (void *)(DPRAM_VBASE + device->in_tail_addr)); +#else + WRITE_TO_DPRAM_VERIFY(device->in_tail_addr, &head, sizeof(head)); +#endif + + LOGA("DROP head: %d, tail: %d\n", head, tail); +} + + +static void dpram_phone_power_on(void) +{ + u16 ret_value = 0; + + PRINT_FUNC(); + + /*Add for Gadui : Normal boot Magic - 0x54424D4E*/ + dpram_init_magic_num(); + + gpio_direction_output(GPIO_QSC_PHONE_RST, GPIO_LEVEL_HIGH); + gpio_direction_output(GPIO_QSC_PHONE_ON, GPIO_LEVEL_LOW); + msleep(100); + + gpio_direction_output(GPIO_QSC_PHONE_ON, GPIO_LEVEL_HIGH); + msleep(400); + msleep(400); + msleep(200); + gpio_direction_output(GPIO_QSC_PHONE_ON, GPIO_LEVEL_LOW); + + + ret_value = ioread16((void *)(DPRAM_VBASE + DPRAM_MAGIC_CODE_ADDRESS)); + LOGA("Read_MagicNum : 0x%04x\n", ret_value); + + +} + +static void dpram_only_qsc_phone_on_off(void) +{ + gpio_direction_output(GPIO_QSC_PHONE_ON, GPIO_LEVEL_LOW); + + LOGA("PHONE_ON level: %s\n", + gpio_get_value(GPIO_QSC_PHONE_ON) ? "HIGH" : "LOW "); +} + +static int dpram_phone_getstatus(void) +{ + return gpio_get_value(GPIO_QSC_PHONE_ACTIVE); +} + +static void dpram_phone_reset(void) +{ + PRINT_FUNC(); + + if(g_dpram_wpend == IDPRAM_WPEND_LOCK) + g_dpram_wpend = IDPRAM_WPEND_UNLOCK; // dpram write unlock + + /*Add for Gadui : Normal boot Magic - 0x54424D4E*/ + dpram_init_magic_num(); + + gpio_set_value(GPIO_QSC_PHONE_RST, GPIO_LEVEL_LOW); + msleep(100); + gpio_set_value(GPIO_QSC_PHONE_RST, GPIO_LEVEL_HIGH); + + g_cp_reset_cnt++; +} +static int dpram_extra_mem_rw(struct _param_em *param) +{ + + if(param->offset + param->size > 0xFFF800) + { + LOGE("Wrong rage of external memory access\n"); + return -1; + } + + if (param->rw) + { //write + if(dpram_lock_write(__func__) < 0) + return -EAGAIN; + WRITE_TO_DPRAM(param->offset, param->addr, param->size); + dpram_unlock_write(__func__); + } + else + { //read + dpram_lock_read(__func__); + READ_FROM_DPRAM(param->addr, param->offset, param->size); + dpram_unlock_read(__func__); + } + return 0; +} + +static int dpram_phone_ramdump_on(void) +{ + const u16 rdump_flag1 = 0xdead; + const u16 rdump_flag2 = 0xdead; + const u16 temp1, temp2; + + LOGL(DL_INFO,"Ramdump ON.\n"); + if(dpram_lock_write(__func__) < 0) + return -EAGAIN; + + WRITE_TO_DPRAM(DPRAM_MAGIC_CODE_ADDRESS, &rdump_flag1, sizeof(rdump_flag1)); + WRITE_TO_DPRAM(DPRAM_ACCESS_ENABLE_ADDRESS, &rdump_flag2, sizeof(rdump_flag2)); + + READ_FROM_DPRAM((void *)&temp1, DPRAM_MAGIC_CODE_ADDRESS, sizeof(temp1)); + READ_FROM_DPRAM((void *)&temp2, DPRAM_ACCESS_ENABLE_ADDRESS, sizeof(temp2)); + LOGL(DL_INFO,"flag1: %x flag2: %x\n", temp1, temp2); + + /* @LDK@ send init end code to phone */ + dpram_unlock_write(__func__); + + g_dump_on = 1; + // If it is configured to dump both AP and CP, reset both AP and CP here. + kernel_sec_dump_cp_handle2(); + + return 0; + +} + +static int dpram_phone_ramdump_off(void) +{ + const u16 rdump_flag1 = 0x00aa; + const u16 rdump_flag2 = 0x0001; + + LOGL(DL_INFO, "Ramdump OFF.\n"); + + g_dump_on = 0; + if(dpram_lock_write(__func__) < 0) + return -EAGAIN; + + WRITE_TO_DPRAM(DPRAM_MAGIC_CODE_ADDRESS, &rdump_flag1, sizeof(rdump_flag1)); + WRITE_TO_DPRAM(DPRAM_ACCESS_ENABLE_ADDRESS, &rdump_flag2, sizeof(rdump_flag2)); + /* @LDK@ send init end code to phone */ + dpram_unlock_write(__func__); + + //usb_switch_mode(1); #############Need to be enabled later + + g_phone_sync = 0; + + dpram_phone_reset(); + return 0; + +} + +#ifdef CONFIG_PROC_FS +static int dpram_read_proc(char *page, char **start, off_t off, + int count, int *eof, void *data) +{ + char *p = page; + int len; + + u16 magic, enable; + u16 fmt_in_head, fmt_in_tail, fmt_out_head, fmt_out_tail; + u16 raw_in_head, raw_in_tail, raw_out_head, raw_out_tail; + u16 in_interrupt = 0, out_interrupt = 0; + + int fih, fit, foh, fot; + int rih, rit, roh, rot; + +#ifdef _ENABLE_ERROR_DEVICE + char buf[DPRAM_ERR_MSG_LEN]; + unsigned long flags; +#endif /* _ENABLE_ERROR_DEVICE */ + + READ_FROM_DPRAM((void *)&magic, DPRAM_MAGIC_CODE_ADDRESS, sizeof(magic)); + READ_FROM_DPRAM((void *)&enable, DPRAM_ACCESS_ENABLE_ADDRESS, sizeof(enable)); + READ_FROM_DPRAM((void *)&fmt_in_head, DPRAM_PHONE2PDA_FORMATTED_HEAD_ADDRESS, sizeof(fmt_in_head)); + READ_FROM_DPRAM((void *)&fmt_in_tail, DPRAM_PHONE2PDA_FORMATTED_TAIL_ADDRESS, sizeof(fmt_in_tail)); + READ_FROM_DPRAM((void *)&fmt_out_head, DPRAM_PDA2PHONE_FORMATTED_HEAD_ADDRESS, sizeof(fmt_out_head)); + READ_FROM_DPRAM((void *)&fmt_out_tail, DPRAM_PDA2PHONE_FORMATTED_TAIL_ADDRESS, sizeof(fmt_out_tail)); + READ_FROM_DPRAM((void *)&raw_in_head, DPRAM_PHONE2PDA_RAW_HEAD_ADDRESS, sizeof(raw_in_head)); + READ_FROM_DPRAM((void *)&raw_in_tail, DPRAM_PHONE2PDA_RAW_TAIL_ADDRESS, sizeof(raw_in_tail)); + READ_FROM_DPRAM((void *)&raw_out_head, DPRAM_PDA2PHONE_RAW_HEAD_ADDRESS, sizeof(raw_out_head)); + READ_FROM_DPRAM((void *)&raw_out_tail, DPRAM_PDA2PHONE_RAW_TAIL_ADDRESS, sizeof(raw_out_tail)); + + fih = dpram_table[FORMATTED_INDEX].in_head_saved; + fit = dpram_table[FORMATTED_INDEX].in_tail_saved; + foh = dpram_table[FORMATTED_INDEX].out_head_saved; + fot = dpram_table[FORMATTED_INDEX].out_tail_saved; + rih = dpram_table[RAW_INDEX].in_head_saved; + rit = dpram_table[RAW_INDEX].in_tail_saved; + roh = dpram_table[RAW_INDEX].out_head_saved; + rot = dpram_table[RAW_INDEX].out_tail_saved; + out_interrupt = ioread16((void *)dpram_mbx_BA); + in_interrupt = ioread16((void *)dpram_mbx_AB); + +#ifdef _ENABLE_ERROR_DEVICE + memset((void *)buf, '\0', DPRAM_ERR_MSG_LEN); + local_irq_save(flags); + memcpy(buf, dpram_err_buf, DPRAM_ERR_MSG_LEN - 1); + local_irq_restore(flags); +#endif /* _ENABLE_ERROR_DEVICE */ + + p += sprintf(p, + "-------------------------------------\n" + "| NAME\t\t\t| VALUE\n" + "-------------------------------------\n" + "|R MAGIC CODE\t\t| 0x%04x\n" + "|R ENABLE CODE\t\t| 0x%04x\n" + "|R PHONE->PDA FMT HEAD\t| %u\n" + "|R PHONE->PDA FMT TAIL\t| %u\n" + "|R PDA->PHONE FMT HEAD\t| %u\n" + "|R PDA->PHONE FMT TAIL\t| %u\n" + "|R PHONE->PDA RAW HEAD\t| %u\n" + "|R RPHONE->PDA RAW TAIL\t| %u\n" + "|R PDA->PHONE RAW HEAD\t| %u\n" + "|R PDA->PHONE RAW TAIL\t| %u\n" + "-------------------------------------\n" + "| FMT PHONE->PDA HEAD\t| %d\n" + "| FMT PHONE->PDA TAIL\t| %d\n" + "| FMT PDA->PHONE HEAD\t| %d\n" + "| FMT PDA->PHONE TAIL\t| %d\n" + "-------------------------------------\n" + "| RAW PHONE->PDA HEAD\t| %d\n" + "| RAW PHONE->PDA TAIL\t| %d\n" + "| RAW PDA->PHONE HEAD\t| %d\n" + "| RAW PDA->PHONE TAIL\t| %d\n" + "-------------------------------------\n" + "| PHONE->PDA MAILBOX\t| 0x%04x\n" + "| PDA->PHONE MAILBOX\t| 0x%04x\n" + "-------------------------------------\n" +#ifdef _ENABLE_ERROR_DEVICE + "| LAST PHONE ERR MSG\t| %s\n" +#endif /* _ENABLE_ERROR_DEVICE */ + "| PHONE ACTIVE\t\t| %s\n" + "| DPRAM INT Level\t| %d\n" + "-------------------------------------\n", + magic, enable, + fmt_in_head, fmt_in_tail, fmt_out_head, fmt_out_tail, + raw_in_head, raw_in_tail, raw_out_head, raw_out_tail, + fih, fit, foh, fot, + rih, rit, roh, rot, + in_interrupt, out_interrupt, + +#ifdef _ENABLE_ERROR_DEVICE + (buf[0] != '\0' ? buf : "NONE"), +#endif /* _ENABLE_ERROR_DEVICE */ + (dpram_phone_getstatus() ? "ACTIVE" : "INACTIVE"), + gpio_get_value(IRQ_QSC_PHONE_ACTIVE) + ); + + len = (p - page) - off; + if (len < 0) { + len = 0; + } + + *eof = (len <= count) ? 1 : 0; + *start = page + off; + + return len; +} +#endif /* CONFIG_PROC_FS */ + +/* dpram tty file operations. */ +static int dpram_tty_open(struct tty_struct *tty, struct file *file) +{ + dpram_device_t *device = &dpram_table[tty->index]; + + PRINT_FUNC(); + device->serial.tty = tty; + device->serial.open_count++; + + if (device->serial.open_count > 1) + { + device->serial.open_count--; + return -EBUSY; + } + + tty->driver_data = (void *)device; + tty->low_latency = 1; + return 0; +} + +static void dpram_tty_close(struct tty_struct *tty, struct file *file) +{ + dpram_device_t *device = (dpram_device_t *)tty->driver_data; + + //PRINT_FUNC(); + if ( device && (device == &dpram_table[tty->index]) ) + { + down(&device->serial.sem); + device->serial.open_count--; + device->serial.tty = NULL; + up(&device->serial.sem); + } +} + +static int dpram_tty_write(struct tty_struct *tty, const unsigned char *buffer, int count) +{ + dpram_device_t *device = (dpram_device_t *)tty->driver_data; + + //PRINT_FUNC(); + if (!device) + return 0; + + return dpram_write(device, buffer, count); +} + +static int dpram_tty_write_room(struct tty_struct *tty) +{ + int avail; + u16 head, tail; + dpram_device_t *device = (dpram_device_t *)tty->driver_data; + + //PRINT_FUNC(); + + if (device != NULL) + { + head = device->out_head_saved; + tail = device->out_tail_saved; + + avail = (head < tail) ? (tail - head - 1) : (device->out_buff_size + tail - head - 1); + + return avail; + } + + return 0; +} + +static int dpram_tty_ioctl(struct tty_struct *tty, unsigned int cmd, unsigned long arg) +{ + unsigned int val; + + PRINT_FUNC(); + switch (cmd) + { + case DPRAM_PHONE_ON: + g_phone_sync = 0; + g_dump_on = 0; + g_phone_power_off_sequence = 0; + LOGA("IOCTL cmd = DPRAM_PHONE_ON\n"); + dpram_phone_power_on(); + return 0; + + case DPRAM_PHONE_GETSTATUS: + LOGA("IOCTL cmd = DPRAM_PHONE_GETSTATUS\n"); + val = dpram_phone_getstatus(); + return copy_to_user((unsigned int *)arg, &val, sizeof(val)); + + case DPRAM_PHONE_RESET: + g_phone_sync = 0; + g_dump_on = 0; + g_phone_power_off_sequence = 0; + LOGA("IOCTL cmd = DPRAM_PHONE_RESET\n"); + dpram_phone_reset(); + return 0; + + case DPRAM_PHONE_OFF: + g_phone_sync = 0; + g_phone_power_off_sequence = 1; + LOGA("IOCTL cmd = DPRAM_PHONE_OFF\n"); + dpram_only_qsc_phone_on_off(); + return 0; + + // Silent reset + case MBX_CMD_PHONE_RESET: + LOGA("IOCTL cmd = MBX_CMD_PHONE_RESET\n"); + request_phone_reset(); + return 0; + + case DPRAM_PHONE_RAMDUMP_ON: + LOGA("IOCTL cmd = DPRAM_PHONE_RAMDUMP_ON\n"); + dpram_phone_ramdump_on(); + return 0; + + case DPRAM_PHONE_RAMDUMP_OFF: + LOGA("IOCTL cmd = DPRAM_PHONE_RAMDUMP_OFF\n"); + dpram_phone_ramdump_off(); + return 0; + + case DPRAM_PHONE_UNSET_UPLOAD: + LOGA("IOCTL cmd = DPRAM_PHONE_UNSET_UPLOAD\n"); +#ifdef CONFIG_SEC_DEBUG + kernel_sec_clear_upload_magic_number(); +#endif + break; + + case DPRAM_PHONE_SET_AUTOTEST: + LOGA("IOCTL cmd = DPRAM_PHONE_SET_AUTOTEST\n"); +#ifdef CONFIG_SEC_DEBUG + kernel_sec_set_autotest(); +#endif + break; + + case DPRAM_PHONE_GET_DEBUGLEVEL: + LOGA("IOCTL cmd = DPRAM_PHONE_GET_DEBUGLEVEL\n"); +#ifdef CONFIG_SEC_DEBUG + switch(kernel_sec_get_debug_level()) { + case KERNEL_SEC_DEBUG_LEVEL_LOW: + val = 0xA0A0; + break; + case KERNEL_SEC_DEBUG_LEVEL_MID: + val = 0xB0B0; + break; + case KERNEL_SEC_DEBUG_LEVEL_HIGH: + val = 0xC0C0; + break; + default: + val = 0xFFFF; + break; + } + LOGA("DPRAM_PHONE_GET_DEBUGLEVEL = %x, %d\n", kernel_sec_get_debug_level(), val); +#endif + return copy_to_user((unsigned int *)arg, &val, sizeof(val)); + + break; + + case DPRAM_PHONE_SET_DEBUGLEVEL: + LOGA("IOCTL cmd = DPRAM_PHONE_SET_DEBUGLEVEL\n"); +#ifdef CONFIG_SEC_DEBUG + switch(kernel_sec_get_debug_level()) { + case KERNEL_SEC_DEBUG_LEVEL_LOW: + kernel_sec_set_debug_level(KERNEL_SEC_DEBUG_LEVEL_MID); + break; + case KERNEL_SEC_DEBUG_LEVEL_MID: + kernel_sec_set_debug_level(KERNEL_SEC_DEBUG_LEVEL_HIGH); + break; + case KERNEL_SEC_DEBUG_LEVEL_HIGH: + kernel_sec_set_debug_level(KERNEL_SEC_DEBUG_LEVEL_LOW); + break; + default: + break; + } +#endif + return 0; + + case DPRAM_EXTRA_MEM_RW: + { + struct _param_em param; + + LOGA("IOCTL cmd = DPRAM_EXTRA_MEM_RW\n"); + + val = copy_from_user((void *)¶m, (void *)arg, sizeof(param)); + if (dpram_extra_mem_rw(¶m) < 0) + { + LOGE("External memory access fail..\n"); + return -1; + } + + if (!param.rw) //read + { + return copy_to_user((unsigned long *)arg, ¶m, sizeof(param)); + } + + return 0; + } + + case DPRAM_PHONE_CPRAMDUMP_START: + { + LOGA("IOCTL cmd = DPRAM_PHONE_CPRAMDUMP_START\n"); +// setup_cp_ramdump(); +// LOGA("Succeeded in setup_cp_ramdump()!!!\n"); + return 0; + } + + case DPRAM_PHONE_CPRAMDUMP_DONE: + { + int ret; + + LOGA("IOCTL cmd = DPRAM_PHONE_CPRAMDUMP_DONE\n"); + + dpram_send_command(CMD_CP_RAMDUMP_SEND_DONE_REQ); + ret = dpram_wait_response(CMD_CP_RAMDUMP_SEND_DONE_RESP|MASK_CMD_RESULT_SUCCESS); + if (!ret) { + LOGE("Failed in dpram_wait_response()!!!\n"); + return 0; + } + LOGE("succeeded in dpram_wait_response()!!!\n"); + dpram_clear_response(); + + // goto Upload mode +#ifdef CONFIG_SEC_DEBUG + if (kernel_sec_get_debug_level() != KERNEL_SEC_DEBUG_LEVEL_LOW) { + LOGE("Upload Mode!!!\n"); + kernel_sec_dump_cp_handle2(); + } +#endif + + return 0; + } + + default: + LOGA("IOCTL cmd = 0x%X\n", cmd); + break; + } + + return -ENOIOCTLCMD; +} + +static int dpram_tty_chars_in_buffer(struct tty_struct *tty) +{ + int data; + u16 head, tail; + + + dpram_device_t *device = (dpram_device_t *)tty->driver_data; + + //PRINT_FUNC(); + if (device != NULL) + { + head = device->out_head_saved; + tail = device->out_tail_saved; + + data = (head > tail) ? (head - tail - 1) : (device->out_buff_size - tail + head); + + return data; + } + + return 0; +} + +#ifdef _ENABLE_ERROR_DEVICE +static int dpram_err_read(struct file *filp, char *buf, size_t count, loff_t *ppos) +{ + DECLARE_WAITQUEUE(wait, current); + + ssize_t ret; + size_t ncopy; + + //PRINT_FUNC(); + add_wait_queue(&dpram_err_wait_q, &wait); + set_current_state(TASK_INTERRUPTIBLE); + + while (1) { + if (dpram_err_len) { + ncopy = min(count, dpram_err_len); + if (copy_to_user(buf, dpram_err_buf, ncopy)) + ret = -EFAULT; + else + ret = ncopy; + + dpram_err_len = 0; + + break; + } + + if (filp->f_flags & O_NONBLOCK) { + ret = -EAGAIN; + break; + } + + if (signal_pending(current)) { + ret = -ERESTARTSYS; + break; + } + + schedule(); + } + + set_current_state(TASK_RUNNING); + remove_wait_queue(&dpram_err_wait_q, &wait); + + return ret; +} + +static int dpram_err_fasync(int fd, struct file *filp, int mode) +{ + //PRINT_FUNC(); + return fasync_helper(fd, filp, mode, &dpram_err_async_q); +} + +static unsigned int dpram_err_poll(struct file *filp, + struct poll_table_struct *wait) +{ + poll_wait(filp, &dpram_err_wait_q, wait); + return ((dpram_err_len) ? (POLLIN | POLLRDNORM) : 0); +} + +static int dpram_dump_open(struct inode *inode, struct file *filp) +{ + struct cdev *cdev = inode->i_cdev; + struct dpram *dp = container_of(cdev, struct dpram, cdev); + + //PRINT_FUNC(); + LOGA("Invoked!!!\n"); + filp->private_data = dp; + + setup_cp_ramdump(); + + return 0; +} + +static int dpram_dump_read(struct file *filp, char *buf, size_t count, loff_t *ppos) +{ + int ret; + int ncopy; + + //PRINT_FUNC(); + receive_cp_ramdump(); + + ncopy = min(count, dpram_dump_len); + if (copy_to_user(buf, cp_ramdump_buff, ncopy)) + ret = -EFAULT; + else + ret = ncopy; + + dpram_dump_len = 0; + + LOGA("RX bytes = %d\n", dump_rx_total); + + return ret; +} + +static int dpram_dump_fasync(int fd, struct file *filp, int mode) +{ + return fasync_helper(fd, filp, mode, &dpram_dump_async_q); +} + +static unsigned int dpram_dump_poll(struct file *filp, + struct poll_table_struct *wait) +{ + LOGA("%d bytes are ready.\n", dpram_dump_len); + poll_wait(filp, &dpram_dump_wait_q, wait); + return ((dpram_dump_len) ? (POLLIN | POLLRDNORM) : 0); +} + +static long dpram_dump_ioctl(struct file *filp, + unsigned int cmd, unsigned long arg) +{ + switch (cmd) + { + case DPRAM_PHONE_CPRAMDUMP_START: + { + LOGA("IOCTL cmd = DPRAM_PHONE_CPRAMDUMP_START\n"); + + start_cp_ramdump(); + return 0; + } + + case DPRAM_PHONE_CPRAMDUMP_DONE: + { + LOGA("IOCTL cmd = DPRAM_PHONE_CPRAMDUMP_DONE\n"); + + close_cp_ramdump(); + +#ifdef CONFIG_SEC_DEBUG + /* Go to Upload mode*/ + if (kernel_sec_get_debug_level() != KERNEL_SEC_DEBUG_LEVEL_LOW) + kernel_sec_dump_cp_handle2(); +#endif + + return 0; + } + + default: + LOGA("IOCTL cmd = 0x%X\n", cmd); + break; + } + + return -ENOIOCTLCMD; +} + + +#endif /* _ENABLE_ERROR_DEVICE */ + +/* handlers. */ +static void res_ack_tasklet_handler(unsigned long data) +{ + dpram_device_t *device = (dpram_device_t *)data; + + //PRINT_FUNC(); + if (device && device->serial.tty) { + struct tty_struct *tty = device->serial.tty; + + if ((tty->flags & (1 << TTY_DO_WRITE_WAKEUP)) && + tty->ldisc->ops->write_wakeup) { + (tty->ldisc->ops->write_wakeup)(tty); + } + + wake_up_interruptible(&tty->write_wait); + } +} + +static void fmt_rcv_tasklet_handler(unsigned long data) +{ + dpram_tasklet_data_t *tasklet_data = (dpram_tasklet_data_t *)data; + + dpram_device_t *device = tasklet_data->device; + u16 non_cmd = tasklet_data->non_cmd; + + int ret = 0; + int cnt = 0; + + //PRINT_FUNC(); + if (device && device->serial.tty) + { + struct tty_struct *tty = device->serial.tty; + + while (dpram_get_read_available(device)) + { + ret = dpram_read_fmt(device, non_cmd); + + if (!ret) + cnt++; + + if (cnt > 10) + { + dpram_drop_data(device); + break; + } + + if (ret < 0) + { + LOGE("FMT dpram_read_fmt failed\n"); + /* TODO: ... wrong.. */ + } + tty->low_latency = 0; + tty_flip_buffer_push(tty); + } + } + else + { + dpram_drop_data(device); + } +} + +static void raw_rcv_tasklet_handler(unsigned long data) +{ + dpram_tasklet_data_t *tasklet_data = (dpram_tasklet_data_t *)data; + + dpram_device_t *device = tasklet_data->device; + u16 non_cmd = tasklet_data->non_cmd; + + int ret = 0; + //PRINT_FUNC(); + while (dpram_get_read_available(device)) + { + ret = dpram_read_raw(device, non_cmd); + + if (ret < 0) + { + LOGE("RAW dpram_read_raw failed\n"); + /* TODO: ... wrong.. */ + } + } +} + +static void cmd_req_active_handler(void) +{ + dpram_send_mbx_BA(INT_COMMAND(MBX_CMD_RES_ACTIVE)); +} + +/* static void cmd_error_display_handler(void) + * + * this fucntion was called by dpram irq handler and phone active irq hander + * first this fucntion check the log level then jump to send error message to ril + * or CP Upload mode + */ +static void cmd_error_display_handler(void) +{ +#ifdef _ENABLE_ERROR_DEVICE + unsigned short intr; + unsigned long flags; + char buf[DPRAM_ERR_MSG_LEN]; + + memset((void *)buf, 0, sizeof (buf)); + +#ifdef CONFIG_SEC_DEBUG + if (dpram_err_cause == UPLOAD_CAUSE_CDMA_RESET) { + if(get_sec_debug_level()) + memcpy((void *)buf, "UPLOAD", sizeof("UPLOAD")); + else /*debug level is low*/ + memcpy((void *)buf, "9 $PHONE-RESET", sizeof("9 $PHONE-RESET")); + } + else { + if(get_sec_debug_level()) { + buf[0] = 'C'; + buf[1] = 'D'; + buf[2] = 'M'; + buf[3] = 'A'; + buf[4] = ' '; + READ_FROM_DPRAM((buf + 5), DPRAM_PHONE2PDA_FORMATTED_BUFFER_ADDRESS, (sizeof(buf) - 6)); + } else /*debug level is low */ + memcpy((void *)buf, "9 $PHONE-RESET", sizeof("9 $PHONE-RESET")); + } + LOGE("[PHONE ERROR] ->> %s\n", buf); + memcpy(dpram_err_buf, buf, DPRAM_ERR_MSG_LEN); + dpram_err_len = 64; + LOGE("start wake_lock_timeout: during 20sec\n"); + wake_lock_timeout(&dpram_wake_lock, HZ*20); + /* goto Upload mode : receive C9 */ + if ((get_sec_debug_level())&& \ + (dpram_err_cause != UPLOAD_CAUSE_CDMA_RESET)) + /*if (sec_debug_level())*/ + { + local_irq_save(flags); + LOGE("Upload Mode!!!\n"); + intr = ioread16((void *)dpram_mbx_AB); + if (intr == (MBX_CMD_CDMA_DEAD|INT_MASK_VALID|INT_MASK_COMMAND)) + { + LOGE("mbx_AB = 0x%04X\n", intr); + } + kernel_sec_dump_cp_handle2(); + local_irq_restore(flags); + } + dpram_err_cause = 0; + wake_up_interruptible(&dpram_err_wait_q); + kill_fasync(&dpram_err_async_q, SIGIO, POLL_IN); +#endif +#endif /* _ENABLE_ERROR_DEVICE */ +} + + +static void cmd_phone_start_handler(void) +{ + LOGA("Received CMD_PHONE_START!!! %d\n", g_phone_sync); + + PRINT_FUNC(); + if (g_phone_sync == 0) { + /* Set GPIO_PDA_ACTIVE as CP sometimes seems to read this pin as Low */ + LOGA("Current GPIO_PDA_ACTIVE = %d\n", gpio_get_value(GPIO_PDA_ACTIVE) ); + gpio_set_value(GPIO_PDA_ACTIVE, GPIO_LEVEL_HIGH); + + dpram_init_and_report(); + + LOGA("GPIO_PDA_ACTIVE = %d\n", gpio_get_value(GPIO_PDA_ACTIVE) ); + } +} + + +static void cmd_req_time_sync_handler(void) +{ + /* TODO: add your codes here.. */ +} + +static void cmd_phone_deep_sleep_handler(void) +{ + /* TODO: add your codes here.. */ +} + +static void dpram_command_handler(u16 cmd) +{ +//PRINT_FUNC(); + switch (cmd) + { + case MBX_CMD_REQ_ACTIVE: + cmd_req_active_handler(); + break; + + case MBX_CMD_CDMA_DEAD: + LOGE("received MBX_CMD_CDMA_DEAD\n"); + cmd_error_display_handler(); + break; + + case MBX_CMD_ERR_DISPLAY: + LOGE("received MBX_CMD_ERR_DISPLAY\n"); + cmd_error_display_handler(); + break; + + case MBX_CMD_PHONE_START: + cmd_phone_start_handler(); + break; + + case MBX_CMD_REQ_TIME_SYNC: + cmd_req_time_sync_handler(); + break; + + case MBX_CMD_PHONE_DEEP_SLEEP: + cmd_phone_deep_sleep_handler(); + break; + + case MBX_CMD_DPRAM_DOWN: + dpram_power_down(); + break; + + case MBX_CMD_CP_WAKEUP_START: + dpram_powerup_start(); + break; + + default: + LOGA("Unknown command (0x%04X)\n", cmd); + } +} + +static void dpram_data_handler(u16 non_cmd) +{ + u16 head, tail; + + // PRINT_FUNC(); + /* @LDK@ formatted check. */ +#ifdef CDMA_IPC_C210_IDPRAM + head = ioread16((void *)(DPRAM_VBASE + DPRAM_PHONE2PDA_FORMATTED_HEAD_ADDRESS)); + tail = ioread16((void *)(DPRAM_VBASE + DPRAM_PHONE2PDA_FORMATTED_TAIL_ADDRESS)); +#else + READ_FROM_DPRAM_VERIFY(&head, DPRAM_PHONE2PDA_FORMATTED_HEAD_ADDRESS, sizeof(head)); + READ_FROM_DPRAM_VERIFY(&tail, DPRAM_PHONE2PDA_FORMATTED_TAIL_ADDRESS, sizeof(tail)); +#endif + + if (head != tail) + { + non_cmd |= INT_MASK_SEND_F; + + if (non_cmd & INT_MASK_REQ_ACK_F) + atomic_inc(&fmt_txq_req_ack_rcvd); + } + else + { + if (non_cmd & INT_MASK_REQ_ACK_F) + { + LOGA("FMT DATA EMPTY & REQ_ACK_F (non_cmd:0x%x)\n", non_cmd); + dpram_send_mbx_BA(INT_NON_COMMAND(INT_MASK_RES_ACK_F)); + atomic_set(&fmt_txq_req_ack_rcvd, 0); + } + } + + /* @LDK@ raw check. */ +#ifdef CDMA_IPC_C210_IDPRAM + head = ioread16((void *)(DPRAM_VBASE + DPRAM_PHONE2PDA_RAW_HEAD_ADDRESS)); + tail = ioread16((void *)(DPRAM_VBASE + DPRAM_PHONE2PDA_RAW_TAIL_ADDRESS)); +#else + READ_FROM_DPRAM_VERIFY(&head, DPRAM_PHONE2PDA_RAW_HEAD_ADDRESS, sizeof(head)); + READ_FROM_DPRAM_VERIFY(&tail, DPRAM_PHONE2PDA_RAW_TAIL_ADDRESS, sizeof(tail)); +#endif + + if (head != tail) + { + non_cmd |= INT_MASK_SEND_R; + + if (non_cmd & INT_MASK_REQ_ACK_R) + atomic_inc(&raw_txq_req_ack_rcvd); + } + else + { + if (non_cmd & INT_MASK_REQ_ACK_R) + { + LOGA("RAW DATA EMPTY & REQ_ACK_R (non_cmd:0x%x)\n", non_cmd); + dpram_send_mbx_BA(INT_NON_COMMAND(INT_MASK_RES_ACK_R)); + atomic_set(&raw_txq_req_ack_rcvd, 0); + } + } + + /* @LDK@ +++ scheduling.. +++ */ + if (non_cmd & INT_MASK_SEND_F) + { + dpram_tasklet_data[FORMATTED_INDEX].device = &dpram_table[FORMATTED_INDEX]; + dpram_tasklet_data[FORMATTED_INDEX].non_cmd = non_cmd; + fmt_send_tasklet.data = (unsigned long)&dpram_tasklet_data[FORMATTED_INDEX]; + tasklet_schedule(&fmt_send_tasklet); + } + + if (non_cmd & INT_MASK_SEND_R) + { + dpram_tasklet_data[RAW_INDEX].device = &dpram_table[RAW_INDEX]; + dpram_tasklet_data[RAW_INDEX].non_cmd = non_cmd; + raw_send_tasklet.data = (unsigned long)&dpram_tasklet_data[RAW_INDEX]; + /* @LDK@ raw buffer op. -> soft irq level. */ + tasklet_hi_schedule(&raw_send_tasklet); + } + + if (non_cmd & INT_MASK_RES_ACK_F) + { + tasklet_schedule(&fmt_res_ack_tasklet); + } + + if (non_cmd & INT_MASK_RES_ACK_R) + { + tasklet_hi_schedule(&raw_res_ack_tasklet); + } +} + +static inline void check_int_pin_level(void) +{ + u16 mask = 0, cnt = 0; + + while (cnt++ < 3) + { + mask = ioread16((void *)dpram_mbx_AB); + if ( gpio_get_value(GPIO_DPRAM_INT_CP_N) ) + break; + } +} + +static void phone_active_work_func(struct work_struct *work) +{ + u32 reset_code; + + //PRINT_FUNC(); + LOGA("PHONE_ACTIVE level: %s, phone_sync: %d\n", + gpio_get_value(GPIO_QSC_PHONE_ACTIVE) ? "HIGH" : "LOW ", + g_phone_sync); + +#ifdef _ENABLE_ERROR_DEVICE + /* + ** If CDMA was reset by watchdog, phone active low time is very short. So, + ** change the IRQ type to FALLING EDGE and don't check the GPIO_QSC_PHONE_ACTIVE. + */ + if (g_phone_sync) { +#ifdef DUMP_OF_PHONE_ACTIVE_LOW_CRASH + free_irq(dpram_irq, NULL); + IDPRAM_INT_CLEAR(); + free_irq(phone_active_irq, NULL); + g_dump_on = 1; + init_completion(&wait_dump_data); +#endif + memcpy_fromio(&reset_code, (void *)DPRAM_VBASE, sizeof(reset_code)); + if (reset_code != CP_RESET_CODE) { +#ifdef CONFIG_SEC_DEBUG + dpram_err_cause = UPLOAD_CAUSE_CDMA_RESET; +#endif + if (g_phone_power_off_sequence != 1) + cmd_error_display_handler(); + } + } +#endif +} + + +/* @LDK@ interrupt handlers. */ +static irqreturn_t dpram_irq_handler(int irq, void *dev_id) +{ + unsigned long flags; + u16 irq_mask = 0; +#ifdef PRINT_DPRAM_HEAD_TAIL + u16 fih, fit, foh, fot; + u16 rih, rit, roh, rot; +#endif + + //PRINT_FUNC(); + local_irq_save(flags); + local_irq_disable(); + + irq_mask = ioread16((void *)dpram_mbx_AB); + //check_int_pin_level(); + + if (g_dump_on) { + g_irq_mask = irq_mask; + IDPRAM_INT_CLEAR(); + complete(&wait_dump_data); + LOGA("g_dump_on == 1\n"); + local_irq_restore(flags); + return IRQ_HANDLED; + } + +#ifdef DEBUG_DPRAM_INT_HANDLER + LOGA("INT2AP: 0x%04X\n", irq_mask); +#endif + + /* valid bit verification. @LDK@ */ + if ( !(irq_mask & INT_MASK_VALID) ) + { + LOGE("Invalid interrupt mask: 0x%04x\n", irq_mask); + IDPRAM_INT_CLEAR(); + local_irq_restore(flags); + return IRQ_NONE; + } + + /* command or non-command? @LDK@ */ + if ( irq_mask & INT_MASK_COMMAND ) + { + irq_mask &= ~(INT_MASK_VALID | INT_MASK_COMMAND); + dpram_command_handler(irq_mask); + } + else + { +#ifdef PRINT_DPRAM_HEAD_TAIL + fih = ioread16((void *)(DPRAM_VBASE + DPRAM_PHONE2PDA_FORMATTED_HEAD_ADDRESS)); + fit = ioread16((void *)(DPRAM_VBASE + DPRAM_PHONE2PDA_FORMATTED_TAIL_ADDRESS)); + foh = ioread16((void *)(DPRAM_VBASE + DPRAM_PDA2PHONE_FORMATTED_HEAD_ADDRESS)); + fot = ioread16((void *)(DPRAM_VBASE + DPRAM_PDA2PHONE_FORMATTED_TAIL_ADDRESS)); + rih = ioread16((void *)(DPRAM_VBASE + DPRAM_PHONE2PDA_RAW_HEAD_ADDRESS)); + rit = ioread16((void *)(DPRAM_VBASE + DPRAM_PHONE2PDA_RAW_TAIL_ADDRESS)); + roh = ioread16((void *)(DPRAM_VBASE + DPRAM_PDA2PHONE_RAW_HEAD_ADDRESS)); + rot = ioread16((void *)(DPRAM_VBASE + DPRAM_PDA2PHONE_RAW_TAIL_ADDRESS)); + LOGA(" FMT_IN (H:%4d, T:%4d, M:%4d)\n FMT_OUT (H:%4d, T:%4d, M:%4d)\n RAW_IN (H:%4d, T:%4d, M:%4d)\n RAW_OUT (H:%4d, T:%4d, M:%4d)\n", + fih, fit, DPRAM_PHONE2PDA_FORMATTED_BUFFER_SIZE, + foh, fot, DPRAM_PDA2PHONE_FORMATTED_BUFFER_SIZE, + rih, rit, DPRAM_PHONE2PDA_RAW_BUFFER_SIZE, + roh, rot, DPRAM_PDA2PHONE_RAW_BUFFER_SIZE); +#endif + irq_mask &= ~INT_MASK_VALID; + dpram_data_handler(irq_mask); + } + + IDPRAM_INT_CLEAR(); + + local_irq_restore(flags); + return IRQ_HANDLED; +} + + +static irqreturn_t dpram_wake_from_CP_irq_handler(int irq, void *dev_id) +{ +#ifdef DEBUG_DPRAM_INT_HANDLER + LOGA("wake_lock_timeout() in 5 seconds.\n", __func__); +#endif + + wake_lock_timeout(&dpram_wake_lock, 5*HZ); + + return IRQ_HANDLED; +} + +static irqreturn_t phone_active_irq_handler(int irq, void *dev_id) +{ + schedule_delayed_work(&phone_active_work, msecs_to_jiffies(1)); + return IRQ_HANDLED; +} + +static irqreturn_t cp_dump_irq_handler(int irq, void *dev_id) +{ + //only print log + //LOGA("CP_DUMP_INT - High\n", __func__); + return IRQ_HANDLED; +} + + +static int kernel_sec_dump_cp_handle2(void) +{ +#ifdef CONFIG_SEC_DEBUG + LOGA("Configure to restart AP and collect dump on restart...\n"); + /* output high */ + gpio_set_value(S5PV310_GPE0_3_MDM_IRQn, GPIO_LEVEL_HIGH); + /* GPIO output mux */ + s3c_gpio_cfgpin(S5PV310_GPE0_0_MDM_WEn, S3C_GPIO_SFN(S5PV310_MDM_IF_SEL)); + s3c_gpio_cfgpin(S5PV310_GPE0_1_MDM_CSn, S3C_GPIO_SFN(S5PV310_MDM_IF_SEL)); + s3c_gpio_cfgpin(S5PV310_GPE0_2_MDM_Rn, S3C_GPIO_SFN(S5PV310_MDM_IF_SEL)); + s3c_gpio_cfgpin(S5PV310_GPE0_3_MDM_IRQn, S3C_GPIO_SFN(S3C_GPIO_OUTPUT)); + s3c_gpio_cfgpin(S5PV310_GPE0_4_MDM_ADVN, S3C_GPIO_SFN(S5PV310_MDM_IF_SEL)); + if (dpram_err_len) + kernel_sec_set_cause_strptr(dpram_err_buf, dpram_err_len); + panic("CP Crash"); +#endif + return 0; +} + +/* basic functions. */ +#ifdef _ENABLE_ERROR_DEVICE +static struct file_operations dpram_err_ops = { + .owner = THIS_MODULE, + .read = dpram_err_read, + .fasync = dpram_err_fasync, + .poll = dpram_err_poll, + .llseek = no_llseek, + + /* TODO: add more operations */ +}; + +static struct file_operations dpram_dump_ops = { + .owner = THIS_MODULE, + .open = dpram_dump_open, + .read = dpram_dump_read, + .fasync = dpram_dump_fasync, + .poll = dpram_dump_poll, + .unlocked_ioctl = dpram_dump_ioctl, + .llseek = no_llseek, +}; +#endif /* _ENABLE_ERROR_DEVICE */ + +static struct tty_operations dpram_tty_ops = { + .open = dpram_tty_open, + .close = dpram_tty_close, + .write = dpram_tty_write, + .write_room = dpram_tty_write_room, + .ioctl = dpram_tty_ioctl, + .chars_in_buffer = dpram_tty_chars_in_buffer, + + /* TODO: add more operations */ +}; + +#ifdef _ENABLE_ERROR_DEVICE +static void unregister_dpram_err_device(void) +{ + unregister_chrdev(DRIVER_MAJOR_NUM, DPRAM_ERR_DEVICE); + class_destroy(dpram_err_class); +} + +static int register_dpram_err_device(void) +{ + struct device *dpram_err_dev_t; + int ret; + + ret = register_chrdev(DRIVER_MAJOR_NUM, DPRAM_ERR_DEVICE, &dpram_err_ops); + if (ret < 0) + return ret; + + dpram_err_class = class_create(THIS_MODULE, "err"); + if (IS_ERR(dpram_err_class)) { + unregister_dpram_err_device(); + return -EFAULT; + } + + /* @LDK@ 1 = formatted, 2 = raw, so error device is '0' */ + dpram_err_dev_t = device_create( + dpram_err_class, + NULL, + MKDEV(DRIVER_MAJOR_NUM, 0), + NULL, + DPRAM_ERR_DEVICE); + if (IS_ERR(dpram_err_dev_t)) { + unregister_dpram_err_device(); + return -EFAULT; + } + + return 0; +} + +static void unregister_dpram_dump_device(void) +{ + unregister_chrdev(DPRAM_DUMP_DEV_MAJOR, DPRAM_DUMP_DEVICE); + class_destroy(dpram_dump_class); +} + +static int register_dpram_dump_device(void) +{ + struct device *dpram_dump_dev_t; + int ret; + + ret = register_chrdev(DPRAM_DUMP_DEV_MAJOR, DPRAM_DUMP_DEVICE, &dpram_dump_ops); + if (ret < 0) + { + LOGE("Failed in register_chrdev() (%d)\n", ret); + return ret; + } + + dpram_dump_class = class_create(THIS_MODULE, "dump"); + if (IS_ERR(dpram_dump_class)) { + LOGE("Failed in class_create()\n"); + unregister_dpram_dump_device(); + return -EFAULT; + } + + dpram_dump_dev_t = device_create( + dpram_dump_class, + NULL, + MKDEV(DPRAM_DUMP_DEV_MAJOR, 0), + NULL, + DPRAM_DUMP_DEVICE); + if (IS_ERR(dpram_dump_dev_t)) { + LOGE("Failed in device_create()\n"); + unregister_dpram_dump_device(); + return -EFAULT; + } + + return 0; +} +#endif /* _ENABLE_ERROR_DEVICE */ + +static int register_dpram_driver(void) +{ + int retval = 0; + + /* @LDK@ allocate tty driver */ + dpram_tty_driver = alloc_tty_driver(MAX_INDEX); + + if (!dpram_tty_driver) { + return -ENOMEM; + } + + /* @LDK@ initialize tty driver */ + dpram_tty_driver->owner = THIS_MODULE; + dpram_tty_driver->magic = TTY_DRIVER_MAGIC; + dpram_tty_driver->driver_name = DRIVER_NAME; + dpram_tty_driver->name = "dpram"; + dpram_tty_driver->major = DRIVER_MAJOR_NUM; + dpram_tty_driver->minor_start = 1; + dpram_tty_driver->num = MAX_INDEX; + dpram_tty_driver->type = TTY_DRIVER_TYPE_SERIAL; + dpram_tty_driver->subtype = SERIAL_TYPE_NORMAL; + dpram_tty_driver->flags = TTY_DRIVER_REAL_RAW; + dpram_tty_driver->init_termios = tty_std_termios; + dpram_tty_driver->init_termios.c_cflag = (B115200 | CS8 | CREAD | CLOCAL | HUPCL); + tty_set_operations(dpram_tty_driver, &dpram_tty_ops); + + dpram_tty_driver->ttys = dpram_tty; + dpram_tty_driver->termios = dpram_termios; + dpram_tty_driver->termios_locked = dpram_termios_locked; + + /* @LDK@ register tty driver */ + retval = tty_register_driver(dpram_tty_driver); + if (retval) { + LOGE("tty_register_driver error\n"); + put_tty_driver(dpram_tty_driver); + return retval; + } + + return 0; +} + +static void unregister_dpram_driver(void) +{ + tty_unregister_driver(dpram_tty_driver); +} + +/* + * MULTI PDP FUNCTIONs + */ + +static long multipdp_ioctl(struct file *file, + unsigned int cmd, unsigned long arg) +{ + return -EINVAL; +} + +static struct file_operations multipdp_fops = { + .owner = THIS_MODULE, + .unlocked_ioctl = multipdp_ioctl, + .llseek = no_llseek, +}; + +static struct miscdevice multipdp_dev = { + .minor = 132, //MISC_DYNAMIC_MINOR, + .name = APP_DEVNAME, + .fops = &multipdp_fops, +}; + +static inline struct pdp_info * pdp_get_serdev(const char *name) +{ + int slot; + struct pdp_info *dev; + + for (slot = 0; slot < MAX_PDP_CONTEXT; slot++) { + dev = pdp_table[slot]; + if (dev && dev->type == DEV_TYPE_SERIAL && + strcmp(name, dev->vs_dev.tty_name) == 0) { + return dev; + } + } + return NULL; +} + +static inline struct pdp_info * pdp_remove_dev(u8 id) +{ + int slot; + struct pdp_info *dev; + + for (slot = 0; slot < MAX_PDP_CONTEXT; slot++) { + if (pdp_table[slot] && pdp_table[slot]->id == id) { + dev = pdp_table[slot]; + pdp_table[slot] = NULL; + return dev; + } + } + return NULL; +} + +static int vs_open(struct tty_struct *tty, struct file *filp) +{ + struct pdp_info *dev; + //PRINT_FUNC(); + dev = pdp_get_serdev(tty->driver->name); // 2.6 kernel porting + + if (dev == NULL) { + return -ENODEV; + } + + tty->driver_data = (void *)dev; + tty->low_latency = 1; + dev->vs_dev.tty = tty; + dev->vs_dev.refcount++; + + return 0; +} + +static void vs_close(struct tty_struct *tty, struct file *filp) +{ + struct pdp_info *dev; + + dev = pdp_get_serdev(tty->driver->name); + + if (!dev ) + return; + dev->vs_dev.refcount--; + + return; +} + +static int pdp_mux(struct pdp_info *dev, const void *data, size_t len ) +{ + int ret; + size_t nbytes; + u8 *tx_buf; + struct pdp_hdr *hdr; + const u8 *buf; + + int in_softirq_context = in_softirq(); + + /* check current context */ + if (in_softirq_context) + spin_lock(&mux_tty_lock); + else + spin_lock_bh(&mux_tty_lock); + + tx_buf = dev->tx_buf; + hdr = (struct pdp_hdr *)(tx_buf + 1); + buf = data; + + hdr->id = dev->id; + hdr->control = 0; + + while (len) { + if (len > MAX_PDP_DATA_LEN) { + nbytes = MAX_PDP_DATA_LEN; + } else { + nbytes = len; + } + hdr->len = nbytes + sizeof(struct pdp_hdr); + + tx_buf[0] = 0x7f; + + memcpy(tx_buf + 1 + sizeof(struct pdp_hdr), buf, nbytes); + + tx_buf[1 + hdr->len] = 0x7e; + + ret = + dpram_write(&dpram_table[RAW_INDEX], tx_buf, hdr->len + 2); + + if (ret < 0) { + LOGE("write_to_dpram() failed: %d\n", ret); + /* check curent context */ + if (in_softirq_context) + spin_unlock(&mux_tty_lock); + else + spin_unlock_bh(&mux_tty_lock); + + return ret; + } + buf += nbytes; + len -= nbytes; + } + + /* check curent context */ + if (in_softirq_context) + spin_unlock(&mux_tty_lock); + else + spin_unlock_bh(&mux_tty_lock); + + return 0; + +} + + +static int vs_write(struct tty_struct *tty, + const unsigned char *buf, int count) +{ + int ret; + struct pdp_info *dev = (struct pdp_info *)tty->driver_data; + //PRINT_FUNC(); + ret = pdp_mux(dev, buf, count); + + if (ret == 0) + { + ret = count; + } + + return ret; +} + +static int vs_write_room(struct tty_struct *tty) +{ +// return TTY_FLIPBUF_SIZE; + return 8192*2; +} + +static int vs_chars_in_buffer(struct tty_struct *tty) +{ + return 0; +} + +static int vs_ioctl(struct tty_struct *tty, + unsigned int cmd, unsigned long arg) +{ + return -ENOIOCTLCMD; +} + +static struct tty_operations multipdp_tty_ops = { + .open = vs_open, + .close = vs_close, + .write = vs_write, + .write_room = vs_write_room, + .ioctl = vs_ioctl, + .chars_in_buffer = vs_chars_in_buffer, + + /* TODO: add more operations */ +}; + +static struct tty_driver* get_tty_driver_by_id(struct pdp_info *dev) +{ + int index = 0; + + switch (dev->id) { + case 1: index = 0; break; + case 7: index = 1; break; + case 29: index = 2; break; + default: index = 0; + } + + return &dev->vs_dev.tty_driver[index]; +} + +static int get_minor_start_index(int id) +{ + int start = 0; + + switch (id) { + case 1: start = 0; break; + case 7: start = 1; break; + case 29: start = 2; break; + default: start = 0; + } + + return start; +} + +static int vs_add_dev(struct pdp_info *dev) +{ + struct tty_driver *tty_driver; + + tty_driver = get_tty_driver_by_id(dev); + + if (!tty_driver) + { + LOGE("tty driver == NULL!\n"); + return -1; + } + + kref_init(&tty_driver->kref); + + tty_driver->magic = TTY_DRIVER_MAGIC; + tty_driver->driver_name = APP_DEVNAME;//"multipdp"; + tty_driver->name = dev->vs_dev.tty_name; + tty_driver->major = CSD_MAJOR_NUM; + tty_driver->minor_start = get_minor_start_index(dev->id); + tty_driver->num = 1; + tty_driver->type = TTY_DRIVER_TYPE_SERIAL; + tty_driver->subtype = SERIAL_TYPE_NORMAL; + tty_driver->flags = TTY_DRIVER_REAL_RAW; +// kref_set(&tty_driver->kref, dev->vs_dev.refcount); + tty_driver->ttys = dev->vs_dev.tty_table; // 2.6 kernel porting + tty_driver->termios = dev->vs_dev.termios; + tty_driver->termios_locked = dev->vs_dev.termios_locked; + + tty_set_operations(tty_driver, &multipdp_tty_ops); + return tty_register_driver(tty_driver); +} + +static void vs_del_dev(struct pdp_info *dev) +{ + struct tty_driver *tty_driver = NULL; + + tty_driver = get_tty_driver_by_id(dev); + tty_unregister_driver(tty_driver); +} + +static inline void check_pdp_table(const char * func, int line) +{ + int slot; + for (slot = 0; slot < MAX_PDP_CONTEXT; slot++) + { + if (pdp_table[slot]) + LOGA("[%s,%d] addr: %x slot: %d id: %d, name: %s\n", func, line, + (u32)pdp_table[slot], slot, pdp_table[slot]->id, + pdp_table[slot]->vs_dev.tty_name); + } +} + +static inline struct pdp_info * pdp_get_dev(u8 id) +{ + int slot; + + for (slot = 0; slot < MAX_PDP_CONTEXT; slot++) + { + if (pdp_table[slot] && pdp_table[slot]->id == id) + { + return pdp_table[slot]; + } + } + return NULL; +} + +static inline int pdp_add_dev(struct pdp_info *dev) +{ + int slot; + + if (pdp_get_dev(dev->id)) { + return -EBUSY; + } + + for (slot = 0; slot < MAX_PDP_CONTEXT; slot++) { + if (pdp_table[slot] == NULL) { + pdp_table[slot] = dev; + return slot; + } + } + return -ENOSPC; +} + +static int pdp_activate(pdp_arg_t *pdp_arg, unsigned type, unsigned flags) +{ + int ret; + struct pdp_info *dev; + + LOGL(DL_INFO, "id: %d\n", pdp_arg->id); + //PRINT_FUNC(); + dev = kmalloc(sizeof(struct pdp_info) + MAX_PDP_PACKET_LEN, GFP_KERNEL); + if (dev == NULL) { + LOGE("out of memory\n"); + return -ENOMEM; + } + memset(dev, 0, sizeof(struct pdp_info)); + + dev->id = pdp_arg->id; + + dev->type = type; + dev->flags = flags; + dev->tx_buf = (u8 *)(dev + 1); + + if (type == DEV_TYPE_SERIAL) { + sema_init(&dev->vs_dev.write_lock, 1); + strcpy(dev->vs_dev.tty_name, pdp_arg->ifname); + + ret = vs_add_dev(dev); + if (ret < 0) { + kfree(dev); + return ret; + } + + mutex_lock(&pdp_lock); + ret = pdp_add_dev(dev); + if (ret < 0) { + LOGE("pdp_add_dev() failed\n"); + mutex_unlock(&pdp_lock); + vs_del_dev(dev); + kfree(dev); + return ret; + } + mutex_unlock(&pdp_lock); + + { + struct tty_driver * tty_driver = get_tty_driver_by_id(dev); +#ifndef PRODUCT_SHIP + LOGL(DL_INFO, "%s(id: %u) serial device is created.\n", + tty_driver->name, dev->id); +#endif + } + } + + return 0; +} + +static int multipdp_init(void) +{ + int i; + + pdp_arg_t pdp_args[NUM_PDP_CONTEXT] = { + { .id = 1, .ifname = "ttyCSD" }, + { .id = 7, .ifname = "ttyCDMA" }, + { .id = 29, .ifname = "ttyCPLOG" }, + // { .id = 31, .ifname = "loopback" }, + + }; + + + /* create serial device for Circuit Switched Data */ + for (i = 0; i < NUM_PDP_CONTEXT; i++) { + if (pdp_activate(&pdp_args[i], DEV_TYPE_SERIAL, DEV_FLAG_STICKY) < 0) { + LOGE("failed to create a serial device for %s\n", pdp_args[i].ifname); + } + } + + return 0; +} + +/* + * DPRAM DRIVER INITIALIZE FUNCTIONs + */ +static int dpram_init_hw(void) +{ + int rv; + + PRINT_FUNC(); + + + //1) Initialize the interrupt pins + // set_irq_type(IRQ_DPRAM_AP_INT_N, IRQ_TYPE_LEVEL_LOW); + /*irq_set_irq_type(IRQ_DPRAM_AP_INT_N, IRQ_TYPE_LEVEL_LOW);*/ + + rv = gpio_request(IRQ_QSC_INT, "gpx1_0"); + if(rv < 0) { + printk("IDPRAM: [%s] failed to get gpio GPX1_0\n",__func__); + goto err; + } + + dpram_wakeup_irq = gpio_to_irq(IRQ_QSC_INT); + + s3c_gpio_cfgpin(GPIO_C210_DPRAM_INT_N, S3C_GPIO_SFN(0xFF)); + s3c_gpio_setpull(GPIO_C210_DPRAM_INT_N, S3C_GPIO_PULL_NONE); + irq_set_irq_type(dpram_wakeup_irq, IRQ_TYPE_EDGE_RISING); + + rv = gpio_request(IRQ_QSC_PHONE_ACTIVE, "gpx1_6"); + if(rv < 0) { + printk("IDPRAM: [%s] failed to get gpio GPX1_6\n",__func__); + goto err1; + } + + phone_active_irq = gpio_to_irq(IRQ_QSC_PHONE_ACTIVE); + + s3c_gpio_setpull(GPIO_QSC_PHONE_ACTIVE, S3C_GPIO_PULL_NONE); + s3c_gpio_setpull(GPIO_QSC_PHONE_RST, S3C_GPIO_PULL_NONE); +// set_irq_type(IRQ_QSC_ACTIVE, IRQ_TYPE_EDGE_BOTH); + irq_set_irq_type(phone_active_irq, IRQ_TYPE_EDGE_FALLING); + + + rv = gpio_request(IRQ_CP_DUMP_INT, "gpx1_2"); + if(rv < 0) { + printk("IDPRAM: [%s] failed to get gpio GPX1_2\n",__func__); + goto err6; + } + + cp_dump_irq = gpio_to_irq(IRQ_CP_DUMP_INT); + + s3c_gpio_cfgpin(GPIO_CP_DUMP_INT, S3C_GPIO_SFN(0xFF)); + s3c_gpio_setpull(GPIO_CP_DUMP_INT, S3C_GPIO_PULL_DOWN); + irq_set_irq_type(cp_dump_irq, IRQ_TYPE_EDGE_RISING); + + + + // 2)EINT15 : QSC_ACTIVE (GPIO_INTERRUPT) +// #define FILTER_EINT15_EN (0x1<<31) +// #define FILTER_EINT15_SEL_DEGIT (0x1<<30) +//__raw_writel(__raw_readl(S5PV210_EINT1FLTCON1)|(FILTER_EINT15_EN & (~FILTER_EINT15_SEL_DEGIT)),S5PV210_EINT1FLTCON1); + + //3)EINT09 : QSC_INT (GPIO_INTERRUPT) +// #define FILTER_EINT9_EN (0x1<<15) +// #define FILTER_EINT9_SEL_DEGIT (0x1<<14) +//__raw_writel(__raw_readl(S5PV210_EINT1FLTCON0)|(FILTER_EINT9_EN & (~FILTER_EINT9_SEL_DEGIT)),S5PV210_EINT1FLTCON0); + + + // 4)gpio e3-e4 are for Modem if + + s3c_gpio_cfgpin(S5PV310_GPE3_0_MDM_DATA_0, S3C_GPIO_SFN(S5PV310_MDM_IF_SEL)); + s3c_gpio_cfgpin(S5PV310_GPE3_1_MDM_DATA_1, S3C_GPIO_SFN(S5PV310_MDM_IF_SEL)); + s3c_gpio_cfgpin(S5PV310_GPE3_2_MDM_DATA_2, S3C_GPIO_SFN(S5PV310_MDM_IF_SEL)); + s3c_gpio_cfgpin(S5PV310_GPE3_3_MDM_DATA_3, S3C_GPIO_SFN(S5PV310_MDM_IF_SEL)); + s3c_gpio_cfgpin(S5PV310_GPE3_4_MDM_DATA_4, S3C_GPIO_SFN(S5PV310_MDM_IF_SEL)); + s3c_gpio_cfgpin(S5PV310_GPE3_5_MDM_DATA_5, S3C_GPIO_SFN(S5PV310_MDM_IF_SEL)); + s3c_gpio_cfgpin(S5PV310_GPE3_6_MDM_DATA_6, S3C_GPIO_SFN(S5PV310_MDM_IF_SEL)); + s3c_gpio_cfgpin(S5PV310_GPE3_7_MDM_DATA_7, S3C_GPIO_SFN(S5PV310_MDM_IF_SEL)); + + s3c_gpio_cfgpin(S5PV310_GPE4_0_MDM_DATA_8, S3C_GPIO_SFN(S5PV310_MDM_IF_SEL)); + s3c_gpio_cfgpin(S5PV310_GPE4_1_MDM_DATA_9, S3C_GPIO_SFN(S5PV310_MDM_IF_SEL)); + s3c_gpio_cfgpin(S5PV310_GPE4_2_MDM_DATA_10, S3C_GPIO_SFN(S5PV310_MDM_IF_SEL)); + s3c_gpio_cfgpin(S5PV310_GPE4_3_MDM_DATA_11, S3C_GPIO_SFN(S5PV310_MDM_IF_SEL)); + s3c_gpio_cfgpin(S5PV310_GPE4_4_MDM_DATA_12, S3C_GPIO_SFN(S5PV310_MDM_IF_SEL)); + s3c_gpio_cfgpin(S5PV310_GPE4_5_MDM_DATA_13, S3C_GPIO_SFN(S5PV310_MDM_IF_SEL)); + s3c_gpio_cfgpin(S5PV310_GPE4_6_MDM_DATA_14, S3C_GPIO_SFN(S5PV310_MDM_IF_SEL)); + s3c_gpio_cfgpin(S5PV310_GPE4_7_MDM_DATA_15, S3C_GPIO_SFN(S5PV310_MDM_IF_SEL)); + + s3c_gpio_cfgpin(S5PV310_GPE0_0_MDM_WEn, S3C_GPIO_SFN(S5PV310_MDM_IF_SEL)); + s3c_gpio_cfgpin(S5PV310_GPE0_1_MDM_CSn, S3C_GPIO_SFN(S5PV310_MDM_IF_SEL)); + s3c_gpio_cfgpin(S5PV310_GPE0_2_MDM_Rn, S3C_GPIO_SFN(S5PV310_MDM_IF_SEL)); + s3c_gpio_cfgpin(S5PV310_GPE0_3_MDM_IRQn, S3C_GPIO_SFN(S5PV310_MDM_IF_SEL)); + s3c_gpio_cfgpin(S5PV310_GPE0_4_MDM_ADVN, S3C_GPIO_SFN(S5PV310_MDM_IF_SEL)); + + rv = gpio_request(GPIO_PDA_ACTIVE, "GPY4_2"); + if(rv < 0) { + printk("IDPRAM: [%s] failed to get gpio GPY4_2\n",__func__); + goto err2; + } + + rv = gpio_request(GPIO_QSC_PHONE_ON, "GPC1_1"); + if(rv < 0) { + printk("IDPRAM: [%s] failed to get gpio GPC1_1\n",__func__); + goto err3; + } + + rv = gpio_request(GPIO_QSC_PHONE_RST, "GPX1_4"); + if(rv < 0) { + printk("IDPRAM: [%s] failed to get gpio GPX1_4\n",__func__); + goto err4; + } + + s5p_gpio_set_drvstr(GPIO_QSC_PHONE_RST, S5P_GPIO_DRVSTR_LV4); //To increase driving strength of this pin + + //To config Not Connected pin GPY4_6 to I/P with no pullup + rv = gpio_request(GPIO_CP_REQ_RESET, "GPY4_6"); + if(rv < 0) { + printk("IDPRAM: [%s] failed to get gpio GPY4_6\n",__func__); + goto err5; + } + + gpio_direction_input(GPIO_CP_REQ_RESET); + s3c_gpio_setpull(GPIO_CP_REQ_RESET, S3C_GPIO_PULL_NONE); + + // 5)PDA_ACTIVE, QSC_PHONE_ON, QSC_RESET_N + gpio_direction_output(GPIO_PDA_ACTIVE, GPIO_LEVEL_HIGH); + gpio_direction_output(GPIO_QSC_PHONE_ON, GPIO_LEVEL_LOW); + s3c_gpio_setpull(GPIO_QSC_PHONE_ON, S3C_GPIO_PULL_NONE); + gpio_direction_output(GPIO_QSC_PHONE_RST, GPIO_LEVEL_LOW); + + return 0; + +err6: gpio_free(IRQ_CP_DUMP_INT); +err5: gpio_free(GPIO_QSC_PHONE_RST); +err4: gpio_free(GPIO_QSC_PHONE_ON); +err3: gpio_free(GPIO_PDA_ACTIVE); +err2: gpio_free(IRQ_QSC_PHONE_ACTIVE); +err1: gpio_free(IRQ_QSC_INT); +err: return rv; +} + + +static int dpram_shared_bank_remap(void) +{ + +//Clock Settings for Modem IF ====>FixMe + u32 val; + void __iomem *regs = ioremap(0x10030000, 0x10000); + //PRINT_FUNC(); + //Enabling Clock for ModemIF in Reg CLK_GATE_IP_PERIL:0x1003C950 + val = readl(regs + 0xC950); + val |= 0x10000000; + writel(val, regs + 0xC950); + iounmap(regs); + + //3 Get internal DPRAM / SFR Virtual address [[ + // 1) dpram base + idpram_base = (volatile void __iomem *)ioremap_nocache(IDPRAM_PHYSICAL_ADDR, IDPRAM_SIZE); + if (idpram_base == NULL) + { + LOGE("Failed!!! (idpram_base == NULL)\n"); + return -1; + } + LOGA("BUF PA = 0x%08X, VA = 0x%08X\n", (u32)IDPRAM_PHYSICAL_ADDR, + (u32)idpram_base); + + // 2) sfr base + idpram_sfr_base = (volatile IDPRAM_SFR __iomem *)ioremap_nocache(IDPRAM_SFR_PHYSICAL_ADDR, IDPRAM_SFR_SIZE); + if (idpram_sfr_base == NULL) + { + LOGE("Failed!!! (idpram_sfr_base == NULL)\n"); + iounmap(idpram_base); + return -1; + } + LOGA("SFR PA = 0x%08X, VA = 0x%08X\n", (u32)IDPRAM_SFR_PHYSICAL_ADDR, + (u32)idpram_sfr_base); + + // 3) Initialize the Modem interface block(internal DPRAM) + // TODO : Use DMA controller? ask to sys.lsi + // set Modem interface config register + idpram_sfr_base->mifcon = (IDPRAM_MIFCON_FIXBIT|IDPRAM_MIFCON_INT2APEN|IDPRAM_MIFCON_INT2MSMEN); //FIXBIT enable, interrupt enable AP,MSM(CP) + idpram_sfr_base->mifpcon = (IDPRAM_MIFPCON_ADM_MODE); //mux mode + + dpram_mbx_BA = (volatile u16*)(idpram_base + IDPRAM_AP2MSM_INT_OFFSET); + dpram_mbx_AB = (volatile u16*)(idpram_base + IDPRAM_MSM2AP_INT_OFFSET); + LOGA("VA of mbx_BA = 0x%08X, VA of mbx_AB = 0x%08X\n", (u32)dpram_mbx_BA, + (u32)dpram_mbx_AB); + + // write the normal boot magic key for CDMA boot + *((unsigned int *)idpram_base) = DPRAM_BOOT_NORMAL; + + atomic_set(&dpram_read_lock, 0); + atomic_set(&dpram_write_lock, 0); + + return 0; +} + +static void dpram_init_devices(void) +{ + int i; + + for (i = 0; i < MAX_INDEX; i++) { + //init_MUTEX(&dpram_table[i].serial.sem); + sema_init(&dpram_table[i].serial.sem, 1); + + dpram_table[i].serial.open_count = 0; + dpram_table[i].serial.tty = NULL; + } +} + +void dpram_wakeup_init(void) +{ + idpram_sfr_base->mifcon = (IDPRAM_MIFCON_FIXBIT|IDPRAM_MIFCON_INT2APEN|IDPRAM_MIFCON_INT2MSMEN); + idpram_sfr_base->mifpcon = (IDPRAM_MIFPCON_ADM_MODE); + + // mux GPIO_DPRAM_INT_CP_N to dpram interrupt + + s3c_gpio_cfgpin(S5PV310_GPE0_0_MDM_WEn, S3C_GPIO_SFN(S5PV310_MDM_IF_SEL)); + s3c_gpio_cfgpin(S5PV310_GPE0_1_MDM_CSn, S3C_GPIO_SFN(S5PV310_MDM_IF_SEL)); + s3c_gpio_cfgpin(S5PV310_GPE0_2_MDM_Rn, S3C_GPIO_SFN(S5PV310_MDM_IF_SEL)); + s3c_gpio_cfgpin(S5PV310_GPE0_3_MDM_IRQn, S3C_GPIO_SFN(S5PV310_MDM_IF_SEL)); + s3c_gpio_cfgpin(S5PV310_GPE0_4_MDM_ADVN, S3C_GPIO_SFN(S5PV310_MDM_IF_SEL)); + +} + +#define WAKESTART_TIMEOUT (HZ/10) +#define WAKESTART_TIMEOUT_RETRY 5 + +void dpram_wait_wakeup_start(void) +{ + int wakeup_retry = WAKESTART_TIMEOUT_RETRY; + int timeout_ret = 0; + + do { + init_completion(&g_complete_dpramdown); + dpram_send_mbx_BA_cmd(INT_COMMAND(MBX_CMD_PDA_WAKEUP)); + timeout_ret = wait_for_completion_timeout(&g_complete_dpramdown, WAKESTART_TIMEOUT); + } while(!timeout_ret && wakeup_retry--); + + if (!timeout_ret) + { + LOGE("T-I-M-E-O-U-T !!!\n"); + } + + g_dpram_wpend = IDPRAM_WPEND_UNLOCK; // dpram write unlock +} + +static void kill_tasklets(void) +{ + tasklet_kill(&fmt_res_ack_tasklet); + tasklet_kill(&raw_res_ack_tasklet); + + tasklet_kill(&fmt_send_tasklet); + tasklet_kill(&raw_send_tasklet); +} + +static int register_interrupt_handler(void) +{ + int retval = 0; + + dpram_irq = IRQ_DPRAM_AP_INT_N; + + dpram_clear(); + + //1)dpram interrupt + IDPRAM_INT_CLEAR(); + retval = request_irq(dpram_irq, dpram_irq_handler, IRQF_TRIGGER_NONE, "DPRAM irq", NULL); + if (retval) + { + LOGE("DPRAM interrupt handler failed.\n"); + unregister_dpram_driver(); + return -1; + } + + //2) wake up for internal dpram + + retval = request_irq(dpram_wakeup_irq, dpram_wake_from_CP_irq_handler, IRQF_DISABLED, "QSC_INT irq", NULL); + if (retval) + { + LOGE("DPRAM wakeup interrupt handler failed.\n"); + free_irq(dpram_irq, NULL); + unregister_dpram_driver(); + return -1; + } + enable_irq_wake(dpram_wakeup_irq); + + //3) phone active interrupt + retval = request_irq(phone_active_irq, phone_active_irq_handler, IRQF_DISABLED, "QSC_ACTIVE", NULL); + if (retval) + { + LOGE("Phone active interrupt handler failed.\n"); + free_irq(dpram_irq, NULL); + free_irq(dpram_wakeup_irq, NULL); + unregister_dpram_driver(); + return -1; + } + enable_irq_wake(phone_active_irq); + + + //4) cp dump int interrupt for LPA mode + retval = request_irq(cp_dump_irq, cp_dump_irq_handler, IRQF_DISABLED, "CP_DUMP_INT irq", NULL); + if (retval) + { + LOGE("CP_DUMP_INT interrupt handler failed.\n"); + free_irq(dpram_irq, NULL); + free_irq(dpram_wakeup_irq, NULL); + free_irq(phone_active_irq, NULL); + unregister_dpram_driver(); + return -1; + } + enable_irq_wake(cp_dump_irq); + + + + return 0; +} + +static void check_miss_interrupt(void) +{ + unsigned long flags; + + if (gpio_get_value(GPIO_QSC_PHONE_ACTIVE) && \ + !gpio_get_value(GPIO_DPRAM_INT_CP_N)) { + printk(KERN_INFO "[IDPRAM] %s", __func__); + local_irq_save(flags); + dpram_irq_handler(IRQ_DPRAM_AP_INT_N, NULL); + local_irq_restore(flags); + } +} + +/* + * INTERANL DPRAM POWER DOWN FUNCTION + */ + + +/* + * void dpram_power_down() + * + * This function release the wake_lock + * Phone send DRPAM POWER DOWN interrupt and handler call this function. + */ +static void dpram_power_down(void) +{ +#ifdef PRINT_DPRAM_PWR_CTRL + LOGA("Received MBX_CMD_DPRAM_DOWN (lock count = %d)!!!\n", + dpram_get_lock_read()); +#endif + complete(&g_complete_dpramdown); +} + + +static void dpram_powerup_start(void) +{ +#ifdef PRINT_DPRAM_PWR_CTRL + LOGA("Received MBX_CMD_CP_WAKEUP_START!!!\n"); +#endif + complete(&g_complete_dpramdown); +} + + +/* + * void dpram_power_up() + * + * Initialize dpram when ap wake up and send WAKEUP_INT to phone + * This function will be called by Onedram_resume() + */ +static inline void dpram_power_up(void) +{ + const u16 magic_code = 0x00AA; + u16 acc_code = 0x0001; + + dpram_clear(); + + WRITE_TO_DPRAM(DPRAM_MAGIC_CODE_ADDRESS, &magic_code, sizeof(magic_code)); + WRITE_TO_DPRAM(DPRAM_ACCESS_ENABLE_ADDRESS, &acc_code, sizeof(acc_code)); + + // Initialize the dpram controller + dpram_wakeup_init(); + +#ifdef PRINT_DPRAM_PWR_CTRL + // Check for QSC_INT for debugging + LOGA("dpram_wakeup_init() ==> QSC_INT = %s\n", + gpio_get_value(GPIO_QSC_INT) ? "HIGH" : "LOW"); +#endif +} + + +/* + * DPRAM DRIVER FUNCTIONs + */ +#define DPRAMDOWN_TIMEOUT (HZ * 3) +#define DPRAM_PDNINTR_RETRY_CNT 2 + +/* +** lock the AP write dpram and send the SLEEP INT to Phone +*/ +static int dpram_suspend(struct platform_device *dev, pm_message_t state) +{ + u16 in_intr = 0; + u16 timeout_ret = 0; + u16 suspend_retry = DPRAM_PDNINTR_RETRY_CNT; + + g_dpram_wpend = IDPRAM_WPEND_LOCK; // dpram write lock + + /* + ** if some intrrupt was received by cp, dpram hold the wake lock and pass the suspend mode. + */ + if (dpram_get_lock_read() == 0) + { + /* + ** retry sending MBX_CMD_PDA_SLEEP if CP does not send in timout + */ + do { + init_completion(&g_complete_dpramdown); + dpram_send_mbx_BA_cmd(INT_COMMAND(MBX_CMD_PDA_SLEEP)); + //timeout_ret = wait_for_completion_timeout(&g_complete_dpramdown, DPRAMDOWN_TIMEOUT); + timeout_ret = wait_for_completion_timeout(&g_complete_dpramdown, msecs_to_jiffies(500)); +#ifdef PRINT_DPRAM_PWR_CTRL + LOGA("suspend_enter cnt = %d\n", (DPRAM_PDNINTR_RETRY_CNT - suspend_retry)); +#endif + } while ( !timeout_ret && suspend_retry-- ); + + in_intr = ioread16((void *)dpram_mbx_AB); + if (in_intr != (INT_MASK_VALID|INT_MASK_COMMAND|MBX_CMD_DPRAM_DOWN)) + { + LOGE("T-I-M-E-O-U-T !!! (intr = 0x%04X)\n", in_intr); + g_dpram_wpend = IDPRAM_WPEND_UNLOCK; // dpram write unlock + + if (g_phone_sync == 0) + { + LOGE("phone_sync: [%d] retry Phone reset and on\n", g_phone_sync); + dpram_phone_reset(); + dpram_phone_power_on(); + } + return -1; + } + + /* + * Because, if dpram was powered down, cp dpram random intr was ocurred, + * So, fixed by muxing cp dpram intr pin to GPIO output high,.. + */ + gpio_set_value(S5PV310_GPE0_3_MDM_IRQn, GPIO_LEVEL_HIGH); + + s3c_gpio_cfgpin(S5PV310_GPE0_0_MDM_WEn, S3C_GPIO_SFN(S5PV310_MDM_IF_SEL)); + s3c_gpio_cfgpin(S5PV310_GPE0_1_MDM_CSn, S3C_GPIO_SFN(S5PV310_MDM_IF_SEL)); + s3c_gpio_cfgpin(S5PV310_GPE0_2_MDM_Rn, S3C_GPIO_SFN(S5PV310_MDM_IF_SEL)); + s3c_gpio_cfgpin(S5PV310_GPE0_3_MDM_IRQn, S3C_GPIO_SFN(S5PV310_MDM_IF_SEL)); + s3c_gpio_cfgpin(S5PV310_GPE0_4_MDM_ADVN, S3C_GPIO_SFN(S5PV310_MDM_IF_SEL)); + + gpio_set_value(GPIO_PDA_ACTIVE, GPIO_LEVEL_LOW); + + flush_work(&phone_active_work.work); + + //To configure AP_WAKE wakable interrupt + /* block this irq diable routine.*/ + /* When CP send the interrupt after dpram_susepnd, */ + /*int pending resister is not set until CPU sleep.*/ + /* Becuase irq is disabled.*/ + /*disable_irq(dpram_wakeup_irq); + enable_irq_wake(dpram_wakeup_irq);*/ + } + else + { + //wake_lock_timeout(&dpram_wake_lock, HZ/4); + LOGA("Skip the suspned mode - read lock \n"); + g_dpram_wpend = IDPRAM_WPEND_UNLOCK; // dpram write unlock + return -1; + } + + return 0; +} + + +static int dpram_resume(struct platform_device *dev) +{ + gpio_set_value(GPIO_PDA_ACTIVE, GPIO_LEVEL_HIGH); + + dpram_power_up(); + dpram_wait_wakeup_start(); // wait the CP ack 0xCE + + //To configure AP_WAKE normal interrupt + /*disable_irq_wake(dpram_wakeup_irq); + enable_irq(dpram_wakeup_irq);*/ + + /*check_miss_interrupt();*/ + return 0; +} + + +static int __devinit dpram_probe(struct platform_device *dev) +{ + int retval; + + PRINT_FUNC(); + + retval = register_dpram_driver(); + if (retval) { + LOGE("Failed to register dpram (tty) driver.\n"); + return -1; + } + + LOGA("register_dpram_driver() success!!!\n"); + +#ifdef _ENABLE_ERROR_DEVICE + retval = register_dpram_err_device(); + if (retval) { + LOGE("Failed to register dpram error device. (%d)\n", retval); + unregister_dpram_driver(); + return -1; + } + memset((void *)dpram_err_buf, 0, sizeof(dpram_err_buf)); + LOGA("register_dpram_err_device() success!!!\n"); + + retval = register_dpram_dump_device(); + if (retval) { + LOGE("Failed to register dpram dump device. (%d)\n", retval); + unregister_dpram_driver(); + return -1; + } + memset((void *)cp_ramdump_buff, 0, sizeof(cp_ramdump_buff)); + LOGA("register_dpram_dump_device() success!!!\n"); + + init_completion(&wait_dump_data); +#endif /* _ENABLE_ERROR_DEVICE */ + + retval = misc_register(&multipdp_dev); /* create app. interface device */ + if (retval < 0) + { + LOGE("misc_register() failed\n"); + return -1; + } + + multipdp_init(); + + retval = dpram_init_hw(); + if (retval < 0) + { + LOGE("dpram_init_hw() failed\n"); + return -1; + } + + dpram_shared_bank_remap(); + + //3 DJ07 Dr.J ADD [[ + iowrite16(0, (void *)(DPRAM_VBASE + DPRAM_MAGIC_CODE_ADDRESS)); + iowrite16(0, (void *)(DPRAM_VBASE + DPRAM_ACCESS_ENABLE_ADDRESS)); + dpram_clear(); + //3 ]] + + dpram_init_devices(); + + atomic_set(&raw_txq_req_ack_rcvd, 0); + atomic_set(&fmt_txq_req_ack_rcvd, 0); + + wake_lock_init(&dpram_wake_lock, WAKE_LOCK_SUSPEND, "DPRAM_PWDOWN"); + INIT_DELAYED_WORK(&phone_active_work, phone_active_work_func); + + retval = register_interrupt_handler(); + if ( retval < 0 ) + { + LOGE("register_interrupt_handler() failed!!!\n"); + + gpio_free(IRQ_CP_DUMP_INT); + gpio_free(GPIO_QSC_PHONE_RST); + gpio_free(GPIO_QSC_PHONE_ON); + gpio_free(GPIO_PDA_ACTIVE); + gpio_free(IRQ_QSC_PHONE_ACTIVE); + gpio_free(IRQ_QSC_INT); + + return -1; + } + +#ifdef CONFIG_PROC_FS + create_proc_read_entry(DRIVER_PROC_ENTRY, 0, 0, dpram_read_proc, NULL); +#endif /* CONFIG_PROC_FS */ +//DI20 Dr.J ... cdma_slot_switch_handler = slot_switch_handler2; + + //check_miss_interrupt(); + init_completion(&g_complete_dpramdown); + printk("IDPRAM: DPRAM driver is registered !!!\n"); + + return 0; +} + +static int __devexit dpram_remove(struct platform_device *dev) +{ + //PRINT_FUNC(); + + free_irq(IRQ_DPRAM_AP_INT_N, NULL); + free_irq(phone_active_irq, NULL); + free_irq(dpram_wakeup_irq, NULL); + free_irq(cp_dump_irq, NULL); + + /* @LDK@ unregister dpram (tty) driver */ + unregister_dpram_driver(); + + /* @LDK@ unregister dpram error device */ +#ifdef _ENABLE_ERROR_DEVICE + unregister_dpram_err_device(); + unregister_dpram_dump_device(); +#endif + + /* remove app. interface device */ + misc_deregister(&multipdp_dev); + + wake_lock_destroy(&dpram_wake_lock); + + gpio_free(IRQ_CP_DUMP_INT); + gpio_free(GPIO_QSC_PHONE_RST); + gpio_free(GPIO_QSC_PHONE_ON); + gpio_free(GPIO_PDA_ACTIVE); + gpio_free(IRQ_QSC_PHONE_ACTIVE); + gpio_free(IRQ_QSC_INT); + + flush_work(&phone_active_work.work); + kill_tasklets(); + + return 0; +} + +static void dpram_shutdown(struct platform_device *dev) +{ + dpram_remove(dev); +} + +u32 dpram_get_phone_dump_stat(void) +{ + return g_dump_on; +} + +EXPORT_SYMBOL(dpram_get_phone_dump_stat); + +static struct platform_driver platform_dpram_driver = { + .probe = dpram_probe, + .remove = __devexit_p(dpram_remove), + .suspend = dpram_suspend, + .resume = dpram_resume, + .shutdown = dpram_shutdown, + .driver = { + .name = "dpram-device", + }, +}; + +/* init & cleanup. */ +static int __init dpram_init(void) +{ + + return platform_driver_register(&platform_dpram_driver); +} + +static void __exit dpram_exit(void) +{ + platform_driver_unregister(&platform_dpram_driver); +} + +module_init(dpram_init); +module_exit(dpram_exit); + +MODULE_AUTHOR("SAMSUNG ELECTRONICS CO., LTD"); +MODULE_DESCRIPTION("Internal DPRAM Device Driver."); +MODULE_LICENSE("GPL"); diff --git a/drivers/dpram/raffaello/dpram.h b/drivers/dpram/raffaello/dpram.h new file mode 100755 index 0000000..c6ed226 --- /dev/null +++ b/drivers/dpram/raffaello/dpram.h @@ -0,0 +1,418 @@ +/**************************************************************************** + +** + +** COPYRIGHT(C) : Samsung Electronics Co.Ltd, 2006-2010 ALL RIGHTS RESERVED + +** + +** AUTHOR : Kim, Geun-Young <geunyoung.kim@samsung.com> @LDK@ + +** @LDK@ + +****************************************************************************/ + +#ifndef __IDPRAM_H__ +#define __IDPRAM_H__ + +/* +** FEATURE DEFINITIONs +*/ +#define _DEBUG + +#define CDMA_IPC_C210_IDPRAM +#define DPRAM_SIZE_16KB + +//#define DPRAM_SIZE_32KB + +#if defined(DPRAM_SIZE_16KB) +/* +** DPRAM SETTINGS - 16K S5PC210 Internal DPRAM +*/ +#define DPRAM_SIZE 0x4000 /* 16KB */ +#define DPRAM_PDA2PHONE_FORMATTED_BUFFER_SIZE 1020 +#define DPRAM_PDA2PHONE_RAW_BUFFER_SIZE 7160 +#define DPRAM_PHONE2PDA_FORMATTED_BUFFER_SIZE 1020 +#define DPRAM_PHONE2PDA_RAW_BUFFER_SIZE 7160 +#define DPRAM_INTERRUPT_PORT_SIZE 2 +#elif defined(DPRAM_SIZE_32KB) +/* +** DPRAM SETTINGS - 32K External DPRAM +*/ +#define DPRAM_SIZE 0x8000 /* 32 KB */ +#define DPRAM_PDA2PHONE_FORMATTED_BUFFER_SIZE 4092 +#define DPRAM_PDA2PHONE_RAW_BUFFER_SIZE 12272 +#define DPRAM_PHONE2PDA_FORMATTED_BUFFER_SIZE 4092 +#define DPRAM_PHONE2PDA_RAW_BUFFER_SIZE 12272 +#define DPRAM_INTERRUPT_PORT_SIZE 2 +#else +#error "Feature is neither DPRAM_SIZE_16KB nor DPRAM_SIZE_32KB" +#endif /*DPRAM_SIZE_16KB*/ + +/* +** Memory Offsets +*/ +#define DPRAM_START_ADDRESS 0x0000 + +#define DPRAM_MAGIC_CODE_ADDRESS (DPRAM_START_ADDRESS) +#define DPRAM_ACCESS_ENABLE_ADDRESS (DPRAM_START_ADDRESS + 0x0002) + +#define DPRAM_PDA2PHONE_FORMATTED_START_ADDRESS (DPRAM_START_ADDRESS + 0x0004) +#define DPRAM_PDA2PHONE_FORMATTED_HEAD_ADDRESS (DPRAM_PDA2PHONE_FORMATTED_START_ADDRESS) +#define DPRAM_PDA2PHONE_FORMATTED_TAIL_ADDRESS (DPRAM_PDA2PHONE_FORMATTED_START_ADDRESS + 0x0002) +#define DPRAM_PDA2PHONE_FORMATTED_BUFFER_ADDRESS (DPRAM_PDA2PHONE_FORMATTED_START_ADDRESS + 0x0004) + +#define DPRAM_PDA2PHONE_RAW_START_ADDRESS (DPRAM_PDA2PHONE_FORMATTED_START_ADDRESS + DPRAM_PDA2PHONE_FORMATTED_BUFFER_SIZE + 4) +#define DPRAM_PDA2PHONE_RAW_HEAD_ADDRESS (DPRAM_PDA2PHONE_RAW_START_ADDRESS) +#define DPRAM_PDA2PHONE_RAW_TAIL_ADDRESS (DPRAM_PDA2PHONE_RAW_START_ADDRESS + 0x0002) +#define DPRAM_PDA2PHONE_RAW_BUFFER_ADDRESS (DPRAM_PDA2PHONE_RAW_START_ADDRESS + 0x0004) + +#define DPRAM_PHONE2PDA_FORMATTED_START_ADDRESS (DPRAM_PDA2PHONE_RAW_START_ADDRESS + DPRAM_PDA2PHONE_RAW_BUFFER_SIZE + 4) +#define DPRAM_PHONE2PDA_FORMATTED_HEAD_ADDRESS (DPRAM_PHONE2PDA_FORMATTED_START_ADDRESS) +#define DPRAM_PHONE2PDA_FORMATTED_TAIL_ADDRESS (DPRAM_PHONE2PDA_FORMATTED_START_ADDRESS + 0x0002) +#define DPRAM_PHONE2PDA_FORMATTED_BUFFER_ADDRESS (DPRAM_PHONE2PDA_FORMATTED_START_ADDRESS + 0x0004) + +#define DPRAM_PHONE2PDA_RAW_START_ADDRESS (DPRAM_PHONE2PDA_FORMATTED_START_ADDRESS + (DPRAM_PHONE2PDA_FORMATTED_BUFFER_SIZE + 4)) +#define DPRAM_PHONE2PDA_RAW_HEAD_ADDRESS (DPRAM_PHONE2PDA_RAW_START_ADDRESS) +#define DPRAM_PHONE2PDA_RAW_TAIL_ADDRESS (DPRAM_PHONE2PDA_RAW_START_ADDRESS + 0x0002) +#define DPRAM_PHONE2PDA_RAW_BUFFER_ADDRESS (DPRAM_PHONE2PDA_RAW_START_ADDRESS + 0x0004) + +#if defined(DPRAM_SIZE_16KB) +#define DPRAM_PDA2PHONE_INTERRUPT_ADDRESS 0x3FFC +#define DPRAM_PHONE2PDA_INTERRUPT_ADDRESS 0x3FFE +#elif defined(DPRAM_SIZE_32KB) +#define DPRAM_PDA2PHONE_INTERRUPT_ADDRESS 0x7FFC +#define DPRAM_PHONE2PDA_INTERRUPT_ADDRESS 0x7FFE +#else +#error "Feature is neither DPRAM_SIZE_16KB nor DPRAM_SIZE_32KB" +#endif + + +/* +** Logic Values +*/ +#define TRUE 1 +#define FALSE 0 + + +/* +** INTERRUPT MASKs +*/ +#define INT_MASK_VALID 0x0080 +#define INT_MASK_COMMAND 0x0040 +#define INT_MASK_REQ_ACK_F 0x0020 +#define INT_MASK_REQ_ACK_R 0x0010 +#define INT_MASK_RES_ACK_F 0x0008 +#define INT_MASK_RES_ACK_R 0x0004 +#define INT_MASK_SEND_F 0x0002 +#define INT_MASK_SEND_R 0x0001 + +/* +** INTERRUPT COMMANDs +*/ +#define MBX_CMD_INIT_START 0x0001 +#define MBX_CMD_INIT_END 0x0002 +#define MBX_CMD_REQ_ACTIVE 0x0003 +#define MBX_CMD_RES_ACTIVE 0x0004 +#define MBX_CMD_REQ_TIME_SYNC 0x0005 +#define MBX_CMD_PHONE_RESET 0x0007 +#define MBX_CMD_PHONE_START 0x0008 +#define MBX_CMD_PHONE_COMMON_BOOT 0x0108 +#define MBX_CMD_ERR_DISPLAY 0x0009 +#define MBX_CMD_PHONE_DEEP_SLEEP 0x000A + +#define MBX_CMD_DPRAM_DOWN 0x000B // DPRAM_DOWN Interrupt from Modem 0xCB +#define MBX_CMD_PDA_WAKEUP 0x000C // PDA Wake up Interrupt to Modem 0xCC +#define MBX_CMD_PDA_SLEEP 0x000D // PDA Sleep Interrupt to Modem 0xCD +#define MBX_CMD_CP_WAKEUP_START 0x000E // CP Send ack CE to PDA + +#define MBX_CMD_CDMA_DEAD 0xAB09 + +#define INT_COMMAND(x) (INT_MASK_VALID | INT_MASK_COMMAND | x) +#define INT_NON_COMMAND(x) (INT_MASK_VALID | x) + +/* special interrupt cmd indicating modem boot failure. */ +#define INT_POWERSAFE_FAIL 0xDEAD + +#define FORMATTED_INDEX 0 +#define RAW_INDEX 1 +#define MAX_INDEX 2 + + +/* +** IOCTL COMMANDs +*/ +#define IOC_MZ_MAGIC ('o') +#define DPRAM_PHONE_POWON _IO(IOC_MZ_MAGIC, 0xD0) +#define DPRAM_PHONEIMG_LOAD _IO(IOC_MZ_MAGIC, 0xD1) +#define DPRAM_NVDATA_LOAD _IO(IOC_MZ_MAGIC, 0xD2) +#define DPRAM_PHONE_BOOTSTART _IO(IOC_MZ_MAGIC, 0xD3) +#define DPRAM_PHONE_BOOTTYPE _IOW(IOC_MZ_MAGIC,0xD5, unsigned int) +//#define DPRAM_PHONE_OFF _IO(IOC_MZ_MAGIC,0xD6) +#define IOCTL_ONEDRAM_WAKEUP _IOW(IOC_MZ_MAGIC,0xD7, unsigned int) +//#define DPRAM_PHONE_RESET _IO(IOC_MZ_MAGIC,0xD8) +#define DPRAM_PHONE_RAM_DUMP _IO(IOC_MZ_MAGIC,0xD9) + +#define IOCTL_SET_FATAL_OPERATION _IOW(IOC_MZ_MAGIC,0xDA, unsigned int) + +#define IOC_SEC_MAGIC (0xF0) +#define DPRAM_PHONE_ON _IO(IOC_SEC_MAGIC, 0xC0) +#define DPRAM_PHONE_OFF _IO(IOC_SEC_MAGIC, 0xC1) +#define DPRAM_PHONE_GETSTATUS _IOR(IOC_SEC_MAGIC, 0xC2, unsigned int) +//#define DPRAM_PHONE_MDUMP _IO(IOC_SEC_MAGIC, 0xC3) +//#define DPRAM_PHONE_BATTERY _IO(IOC_SEC_MAGIC, 0xC4) +#define DPRAM_PHONE_RESET _IO(IOC_SEC_MAGIC, 0xC5) +#define DPRAM_PHONE_RAMDUMP_ON _IO(IOC_SEC_MAGIC, 0xC6) +#define DPRAM_PHONE_RAMDUMP_OFF _IO(IOC_SEC_MAGIC, 0xC7) +#define DPRAM_EXTRA_MEM_RW _IOWR(IOC_SEC_MAGIC, 0xC8, unsigned long) + +#define DPRAM_PHONE_UNSET_UPLOAD _IO(IOC_SEC_MAGIC, 0xCA) +#define DPRAM_PHONE_SET_AUTOTEST _IO(IOC_SEC_MAGIC, 0xCB) +#define DPRAM_PHONE_SET_DEBUGLEVEL _IO(IOC_SEC_MAGIC, 0xCC) +#define DPRAM_PHONE_GET_DEBUGLEVEL _IO(IOC_SEC_MAGIC, 0xCD) + +#define DPRAM_PHONE_CPRAMDUMP_START _IO(IOC_SEC_MAGIC, 0xCE) +#define DPRAM_PHONE_CPRAMDUMP_DONE _IO(IOC_SEC_MAGIC, 0xCF) + +#define CP_RESET_CODE 0xCDABCDAB + +/* + * COMMON BOOT DEFINITIONs + */ +#define CP_CHIPSET_QUALCOMM 0x100 +#define CP_CHIPSET_INFINEON 0x200 +#define CP_CHIPSET_BROADCOM 0x300 +#define AP_PLATFORM_ANDROID 0x100 +#define AP_PLATFORM_LINUX 0x300 +#define CP_ONLINE_BOOT 0x0000 +#define CP_AIRPLANE_BOOT 0x1000 + +/* + * BOOT MAGIC KEY + */ +#define DPRAM_BOOT_NORMAL (('T'<<24) | ('B'<<16) | ('M'<<8) | 'N') + + +#ifdef CDMA_IPC_C210_IDPRAM +#define DPRAM_VBASE idpram_base + +/* +** S5PC11x DPRAM REGISTER MAP +*/ +#ifndef IDPRAM_PHYSICAL_ADDR +#define IDPRAM_PHYSICAL_ADDR S5P_PA_MODEMIF +#endif +#define IDPRAM_START_ADDR ((volatile void __iomem *)idpram_base) +#define IDPRAM_SIZE 0x4000 + +#define IDPRAM_AP2MSM_INT_OFFSET 0x3FFC +#define IDPRAM_MSM2AP_INT_OFFSET 0x3FFE + +#define IDPRAM_SFR_PHYSICAL_ADDR (IDPRAM_PHYSICAL_ADDR + 0x8000) +#define IDPRAM_SFR_START_ADDR ((volatile void __iomem *)idpram_sfr_base) +#define IDPRAM_SFR_INT2AP (IDPRAM_SFR_START_ADDR) +#define IDPRAM_SFR_INT2MSM (IDPRAM_SFR_START_ADDR + 0x4) +#define IDPRAM_SFR_MIFCON (IDPRAM_SFR_START_ADDR + 0x8) +#define IDPRAM_SFR_MIFPCON (IDPRAM_SFR_START_ADDR + 0xC) +#define IDPRAM_SFR_MSMINTCLR (IDPRAM_SFR_START_ADDR + 0x10) +#define IDPRAM_SFR_DMA_TX_ADR (IDPRAM_SFR_START_ADDR + 0x14) +#define IDPRAM_SFR_DMA_RX_ADR (IDPRAM_SFR_START_ADDR + 0x18) +#define IDPRAM_SFR_SIZE 0x1C + +// It is recommended that S5PC110 write data with half-word access on the interrupt port because +// S5PC100 overwrites tha data in INT2AP if there are INT2AP and INT2MSM sharing the same word +#define IDPRAM_INT2MSM_MASK 0xFF + +#define IDPRAM_MIFCON_INT2APEN (1<<2) +#define IDPRAM_MIFCON_INT2MSMEN (1<<3) +#define IDPRAM_MIFCON_DMATXREQEN_0 (1<<16) +#define IDPRAM_MIFCON_DMATXREQEN_1 (1<<17) +#define IDPRAM_MIFCON_DMARXREQEN_0 (1<<18) +#define IDPRAM_MIFCON_DMARXREQEN_1 (1<<19) +#define IDPRAM_MIFCON_FIXBIT (1<<20) + +#define IDPRAM_MIFPCON_ADM_MODE (1<<6) // mux / demux mode + +#define IDPRAM_DMA_ADR_MASK 0x3FFF +#define IDPRAM_DMA_TX_ADR_0 // shift 0 +#define IDPRAM_DMA_TX_ADR_1 // shift 16 +#define IDPRAM_DMA_RX_ADR_0 // shift 0 +#define IDPRAM_DMA_RX_ADR_1 // shift 16 + +#define IDPRAM_INT_CLEAR() idpram_sfr_base->msmintclr = 0xFF + +typedef struct { + unsigned int int2ap; + unsigned int int2msm; + unsigned int mifcon; + unsigned int mifpcon; + unsigned int msmintclr; + unsigned int dma_tx_adr; + unsigned int dma_rx_adr; +} IDPRAM_SFR; +#endif + +/* +** DEVICE DEFINITIONs +*/ +#define DRIVER_NAME "DPRAM" +#define DRIVER_PROC_ENTRY "driver/dpram" +#define DRIVER_MAJOR_NUM 249 +#define DPRAM_DUMP_DEV_MAJOR 250 + +/* +** MULTI PDP DEFINITIONs +*/ +#define APP_DEVNAME "multipdp" /* Device node name for application interface */ +#define NUM_PDP_CONTEXT 3 /* number of PDP context */ +/* Device types */ +#define DEV_TYPE_NET 0 /* network device for IP data */ +#define DEV_TYPE_SERIAL 1 /* serial device for CSD */ +#define CSD_MAJOR_NUM 248 /* Device major number */ +#define CSD_MINOR_NUM 0 /* Device minor number */ +#define MAX_PDP_CONTEXT 10 /* Maximum number of PDP context */ +#define MAX_PDP_DATA_LEN 1500 /* Maximum PDP data length */ +/* Device flags */ +#define DEV_FLAG_STICKY 0x1 /* Sticky */ +/* Maximum PDP packet length including header and start/stop bytes */ +#define MAX_PDP_PACKET_LEN (MAX_PDP_DATA_LEN + 4 + 2) + + +typedef struct pdp_arg { + unsigned char id; + char ifname[16]; +} __attribute__ ((packed)) pdp_arg_t; /* Multiple PDP */ + + +struct pdp_hdr { + u16 len; /* Data length */ + u8 id; /* Channel ID */ + u8 control; /* Control field */ +} __attribute__ ((packed)); /* PDP data packet header format */ + + +/* PDP information type */ +struct pdp_info { + u8 id; /* PDP context ID */ + unsigned type; /* Device type */ + unsigned flags; /* Device flags */ + u8 *tx_buf; /* Tx packet buffer */ + union { + struct { + struct tty_driver tty_driver[NUM_PDP_CONTEXT]; // CSD, CDMA, TRFB, CIQ + int refcount; + struct tty_struct *tty_table[1]; + struct ktermios *termios[1]; + struct ktermios *termios_locked[1]; + char tty_name[16]; + struct tty_struct *tty; + struct semaphore write_lock; + } vs_u; /* Virtual serial interface */ + } dev_u; /* App device interface */ +#define vn_dev dev_u.vnet_u +#define vs_dev dev_u.vs_u +}; + +/* +** DEBUG FEATUREs +*/ +#ifdef _DEBUG +#define _DEBUG_LOG +#define _ENABLE_ERROR_DEVICE +#endif + +#define DL_IPC 0x01<<10 +#define DL_WARN 0x01<<15 +#define DL_NOTICE 0x01<<20 +#define DL_INFO 0x01<<25 +#define DL_DEBUG 0x01<<30 + +#ifdef _DEBUG_LOG // debug printf +#define LOGE(s, args...) printk(KERN_ERR "IDPRAM/Err : <%s:%d> " s, __func__, __LINE__, ##args) // Error log +#define LOGA(s, args...) printk(KERN_INFO "IDPRAM : <%s:%d> " s, __func__, __LINE__, ##args) // Alway printed +#define LOG(s, args...) printk(KERN_INFO"IDPRAM : <%s:%d> " s, __func__, __LINE__, ##args) +#define LOGL(mask, s, args...) do{if(mask & __log_level__) printk("IDPRAM : <%s:%d> " s, __func__, __LINE__, ##args);}while(0) +#define PRINT_FUNC() printk(KERN_INFO "IDPRAM : %s() ...\n", __func__) +#else +#define LOGE(s, args...) printk("IDPRAM/Err : %s()| " s, __func__, ##args) // Error log +#define LOGA(s, args...) printk("IDPRAM : %s()| " s, __func__, ##args) // Alway printf +#define LOG(...) +#define LOGL(...) +#define PRINT_FUNC() +#endif + +#ifdef _ENABLE_ERROR_DEVICE +#define DPRAM_ERR_MSG_LEN 65 +#define DPRAM_ERR_DEVICE "dpramerr" +#define DPRAM_DUMP_DEVICE "dpram_dump" +#endif /* _ENABLE_ERROR_DEVICE */ + + +/* +** STRUCTURE DEFINITION +*/ +struct _param_em { + unsigned int offset; + unsigned char *addr; + unsigned int size; + int rw; +}; + +typedef struct dpram_serial { + struct tty_struct *tty; /* pointer to the tty for this device */ + int open_count; /* number of times this port has been opened */ + struct semaphore sem; /* locks this structure */ +} dpram_serial_t; + +typedef struct dpram_device { + /* DPRAM memory addresses */ + unsigned long in_head_addr; + unsigned long in_tail_addr; + unsigned long in_buff_addr; + unsigned long in_buff_size; + + unsigned long out_head_addr; + unsigned long out_tail_addr; + unsigned long out_buff_addr; + unsigned long out_buff_size; + + unsigned int in_head_saved; + unsigned int in_tail_saved; + unsigned int out_head_saved; + unsigned int out_tail_saved; + + u_int16_t mask_req_ack; + u_int16_t mask_res_ack; + u_int16_t mask_send; + + dpram_serial_t serial; +} dpram_device_t; + +typedef struct dpram_tasklet_data { + dpram_device_t *device; + u_int16_t non_cmd; +} dpram_tasklet_data_t; + +struct _mem_param { + unsigned short addr; + unsigned long data; + int dir; +}; + + +/* +** Add more definitions +*/ +#define GPIO_LEVEL_LOW 0 +#define GPIO_LEVEL_HIGH 1 + +#ifdef CDMA_IPC_C210_IDPRAM +#define IDPRAM_WPEND_LOCK (('l'<<24) | ('o'<<16) | ('c'<<8) | 'k') +#define IDPRAM_WPEND_UNLOCK (('u'<<24) | ('n'<<16) | ('l'<<8) | 'k') +#endif + +/* +** MACRO FUNCTIONs +*/ + +#endif /* __IDPRAM_H__ */ diff --git a/drivers/dpram/raffaello/dpram_recovery.c b/drivers/dpram/raffaello/dpram_recovery.c new file mode 100644 index 0000000..3a27bf9 --- /dev/null +++ b/drivers/dpram/raffaello/dpram_recovery.c @@ -0,0 +1,1527 @@ +#include <linux/module.h> +#include <linux/moduleparam.h> +#include <linux/init.h> +#include <linux/interrupt.h> +#include <linux/delay.h> +#include <linux/platform_device.h> +#include <linux/uaccess.h> +#include <linux/mm.h> +#include <linux/tty.h> +#include <linux/tty_driver.h> +#include <linux/tty_flip.h> +#include <linux/irq.h> +#include <linux/poll.h> +#include <asm/io.h> +#include <asm/irq.h> +#include <mach/regs-gpio.h> +#include <plat/gpio-cfg.h> +#include <mach/hardware.h> +#ifdef CONFIG_PROC_FS +#include <linux/proc_fs.h> +#endif /* CONFIG_PROC_FS */ +#include <linux/wakelock.h> +#include <linux/miscdevice.h> +#include <linux/cdev.h> +#include <linux/netdevice.h> +#include "dpram_recovery.h" +#define _DEBUG_ + +#include <mach/gpio.h> + +#ifdef _DEBUG_ +#define MSGCRIT "\x1b[1;31m" +#define MSGERR "\x1b[1;33m" +#define MSGWARN "\x1b[1;35m" +#define MSGINFO "\x1b[1;32m" +#define MSGDBG "\x1b[1;37m" + +#define MSGEND "\x1b[0m \n" +#else +#define MSGCRIT +#define MSGERR +#define MSGWARN +#define MSGINFO +#define MSGDBG +#define MSGEND +#endif + +#define DRIVER_NAME "dpram_recovery" +#define MAJOR_NUM 245 + +#ifndef min +#define min(a, b) (((a) < (b)) ? (a) : (b)) +#endif + +#define MAKEWORD(a, b) ((u16)(((u8)(a)) | ((u16)((u8)(b))) << 8)) +#define MAKELONG(a, b) ((LONG)(((u16)(a)) | ((u32)((u16)(b))) << 16)) +#define LOWORD(l) ((u16)(l)) +#define HIWORD(l) ((u16)(((u32)(l) >> 16) & 0xFFFF)) +#define LOBYTE(w) ((u8)(w)) +#define HIBYTE(w) ((u8)(((u16)(w) >> 8) & 0xFF)) + +#ifdef IRQ_DPRAM_AP_INT_N +#undef IRQ_DPRAM_AP_INT_N +#endif +#define IRQ_DPRAM_AP_INT_N IRQ_MODEM_IF /* IDPRAM's special interrupt in AP */ + + +static u16 SeqIdx; +static u16 g_TotFrame; +static u16 g_CurFrame = 1; +static u16 error_code = 0x0; + + +struct dpram_dev { + int memsize; + int dpram_vbase; + struct cdev cdev; +}; + +static struct dpram_dev *dpram; +static struct dpram_firmware fw; + +#define CRC_TAB_SIZE 256 /* 2^CRC_TAB_BITS */ +#define CRC_16_L_SEED 0xFFFF + +const u16 CRC_Table[CRC_TAB_SIZE] = { + 0x0000, 0x1189, 0x2312, 0x329b, 0x4624, 0x57ad, 0x6536, 0x74bf, + 0x8c48, 0x9dc1, 0xaf5a, 0xbed3, 0xca6c, 0xdbe5, 0xe97e, 0xf8f7, + 0x1081, 0x0108, 0x3393, 0x221a, 0x56a5, 0x472c, 0x75b7, 0x643e, + 0x9cc9, 0x8d40, 0xbfdb, 0xae52, 0xdaed, 0xcb64, 0xf9ff, 0xe876, + 0x2102, 0x308b, 0x0210, 0x1399, 0x6726, 0x76af, 0x4434, 0x55bd, + 0xad4a, 0xbcc3, 0x8e58, 0x9fd1, 0xeb6e, 0xfae7, 0xc87c, 0xd9f5, + 0x3183, 0x200a, 0x1291, 0x0318, 0x77a7, 0x662e, 0x54b5, 0x453c, + 0xbdcb, 0xac42, 0x9ed9, 0x8f50, 0xfbef, 0xea66, 0xd8fd, 0xc974, + 0x4204, 0x538d, 0x6116, 0x709f, 0x0420, 0x15a9, 0x2732, 0x36bb, + 0xce4c, 0xdfc5, 0xed5e, 0xfcd7, 0x8868, 0x99e1, 0xab7a, 0xbaf3, + 0x5285, 0x430c, 0x7197, 0x601e, 0x14a1, 0x0528, 0x37b3, 0x263a, + 0xdecd, 0xcf44, 0xfddf, 0xec56, 0x98e9, 0x8960, 0xbbfb, 0xaa72, + 0x6306, 0x728f, 0x4014, 0x519d, 0x2522, 0x34ab, 0x0630, 0x17b9, + 0xef4e, 0xfec7, 0xcc5c, 0xddd5, 0xa96a, 0xb8e3, 0x8a78, 0x9bf1, + 0x7387, 0x620e, 0x5095, 0x411c, 0x35a3, 0x242a, 0x16b1, 0x0738, + 0xffcf, 0xee46, 0xdcdd, 0xcd54, 0xb9eb, 0xa862, 0x9af9, 0x8b70, + 0x8408, 0x9581, 0xa71a, 0xb693, 0xc22c, 0xd3a5, 0xe13e, 0xf0b7, + 0x0840, 0x19c9, 0x2b52, 0x3adb, 0x4e64, 0x5fed, 0x6d76, 0x7cff, + 0x9489, 0x8500, 0xb79b, 0xa612, 0xd2ad, 0xc324, 0xf1bf, 0xe036, + 0x18c1, 0x0948, 0x3bd3, 0x2a5a, 0x5ee5, 0x4f6c, 0x7df7, 0x6c7e, + 0xa50a, 0xb483, 0x8618, 0x9791, 0xe32e, 0xf2a7, 0xc03c, 0xd1b5, + 0x2942, 0x38cb, 0x0a50, 0x1bd9, 0x6f66, 0x7eef, 0x4c74, 0x5dfd, + 0xb58b, 0xa402, 0x9699, 0x8710, 0xf3af, 0xe226, 0xd0bd, 0xc134, + 0x39c3, 0x284a, 0x1ad1, 0x0b58, 0x7fe7, 0x6e6e, 0x5cf5, 0x4d7c, + 0xc60c, 0xd785, 0xe51e, 0xf497, 0x8028, 0x91a1, 0xa33a, 0xb2b3, + 0x4a44, 0x5bcd, 0x6956, 0x78df, 0x0c60, 0x1de9, 0x2f72, 0x3efb, + 0xd68d, 0xc704, 0xf59f, 0xe416, 0x90a9, 0x8120, 0xb3bb, 0xa232, + 0x5ac5, 0x4b4c, 0x79d7, 0x685e, 0x1ce1, 0x0d68, 0x3ff3, 0x2e7a, + 0xe70e, 0xf687, 0xc41c, 0xd595, 0xa12a, 0xb0a3, 0x8238, 0x93b1, + 0x6b46, 0x7acf, 0x4854, 0x59dd, 0x2d62, 0x3ceb, 0x0e70, 0x1ff9, + 0xf78f, 0xe606, 0xd49d, 0xc514, 0xb1ab, 0xa022, 0x92b9, 0x8330, + 0x7bc7, 0x6a4e, 0x58d5, 0x495c, 0x3de3, 0x2c6a, 0x1ef1, 0x0f78 +}; + +static int dpram_recovery_ioremap(struct dpram_dev *dev); +static int dpram_recovery_modem_pwr_status(void); +static void dpram_recovery_modem_pwroff(void); +static int dpram_recovery_modem_pwron(void); +static u32 dpram_recovery_ReadMagicCode(void); +static u32 dpram_recovery_ReadMagicCode_fota(void); +static void dpram_recovery_WriteMagicCode(u32 dwCode); +static void dpram_recovery_WriteMagicCode_fota(u32 dwCode); +static int dpram_recovery_dpram_Init(void); +static int dpram_recovery_download_Init(void); +static u16 dpram_recovery_ReadCommand(void); +static void dpram_recovery_WriteCommand(u16 nCmd); +static u32 dpram_recovery_check_command(u16 intr, u16 mask); +static int dpram_recovery_wait_response(u16 cmd_mask); +static int dpram_recovery_WaitReadyPhase(void); +static int dpram_recovery_write_modem_firmware(struct dpram_dev *dev, char __user *firmware, int size); +static int dpram_recovery_write_modem_full_firmware(struct dpram_dev *dev, char __user *firmware, int size); +static u32 dpram_recovery_WriteImage(u8 * const pBuf, u32 dwWriteLen); +static u16 dpram_recovery_CalcTotFrame(u32 nDividend, u16 nDivisor); +static void dpram_recovery_WriteDoneRequest(void); +static int dpram_recovery_SendDonePhase(void); +static int dpram_recovery_UpdateRequestPhase(void); +static u32 dpram_recovery_DownloadControl(u8 *pBufIn, u32 Len); +static u32 dpram_recovery_DownloadControl_fullfirmware(u8 *pBufIn, u32 Len); +static u32 dpram_recovery_StatusNotiPhase(u32 *pPercent, u8 *UpDoneNotiFlag); +static u32 dpram_recovery_StatusNotiPhase_download(u32 *pPercent, u8 *UpDoneNotiFlag); +static int dpram_recovery_check_status(struct dpram_dev *dev, int __user *pct); +static int dpram_recovery_check_status_download(struct dpram_dev *dev, int __user *pct); +static int register_interrupt_handler(void); + +typedef struct Up_Noti { + u16 Bop; + u16 progress_status; + u16 error_code; + u16 Eop; +} Status_UpNoti, *pStatus_UpNoti; + +typedef struct Up_Notification { + u16 Bop; + u16 Region; + u16 Percent; + u16 Eop; +} Check_UpNoti; + +static int +__inline __writel_once(struct dpram_dev *dev, int addr, int data) +{ + *(int *)(dev->dpram_vbase+addr) = data; + + return 0; +} + +static int +dpram_recovery_ioremap(struct dpram_dev *dev) +{ + int i; + + /*Clock Settings for Modem IF ====>FixMe */ + u32 val; + void __iomem *regs = ioremap(0x10030000, 0x10000); + + printk(MSGDBG "%s" MSGEND, __func__); + /*Enabling Clock for ModemIF in Reg CLK_GATE_IP_PERIL:0x1003C950 */ + val = readl(regs + 0xC950); + val |= 0x10000000; + writel(val, regs + 0xC950); + iounmap(regs); + + dev->dpram_vbase = (int)ioremap_nocache(DPRAM_BASE_ADDR, DPRAM_SIZE); + + if (dev->dpram_vbase == 0) { + printk("failed ioremap\n"); + return -ENOENT; + } + + printk(KERN_DEBUG "dpram vbase=0x%8x\n", dev->dpram_vbase); + + dev->memsize = DPRAM_SIZE; + + printk(MSGDBG " dpram_vbase = 0x%08x" MSGEND, dev->dpram_vbase); + printk(MSGDBG " memsize = 0x%08x" MSGEND, dev->memsize); + + for (i = 0; i < DPRAM_SIZE; i = i+4) { + if (__writel_once(dev, i, 0xffffffff)) { + printk(KERN_DEBUG "Exit during dpram initialization.\n"); + return 0; + } + } + + return 0; +} + +static int +dpram_recovery_modem_pwr_status(void) +{ + printk(KERN_ERR "%s Modem Active: %d\n", __func__, gpio_get_value(GPIO_QSC_PHONE_ACTIVE)); + + return gpio_get_value(GPIO_QSC_PHONE_ACTIVE); +} + +static void +dpram_recovery_modem_pwroff(void) +{ + int phone_wait_cnt = 0; + + printk(KERN_ERR "%s\n", __func__); + + /* phone power off */ + gpio_direction_output(GPIO_QSC_PHONE_ON, GPIO_LEVEL_LOW); + + /* confirm phone off */ + while (1) { + if (gpio_get_value(GPIO_QSC_PHONE_ACTIVE)) { + printk(KERN_ALERT"%s: Try to Turn Phone Off by CP_RST\n", __func__); + gpio_set_value(GPIO_QSC_PHONE_RST, 0); + if (phone_wait_cnt > 1) { + printk(KERN_ALERT "%s: PHONE OFF Failed\n", __func__); + break; + } + phone_wait_cnt++; + mdelay(1000); + } else { + printk(KERN_ALERT "%s: PHONE OFF Success\n", __func__); + break; + } + } + +} + +static int +dpram_recovery_modem_pwron(void) +{ + printk(KERN_ERR "%s\n", __func__); + + gpio_direction_output(GPIO_QSC_PHONE_RST, GPIO_LEVEL_HIGH); + gpio_direction_output(GPIO_QSC_PHONE_ON, GPIO_LEVEL_LOW); + msleep(100); + + gpio_direction_output(GPIO_QSC_PHONE_ON, GPIO_LEVEL_HIGH); + msleep(400); + msleep(400); + msleep(200); + gpio_direction_output(GPIO_QSC_PHONE_ON, GPIO_LEVEL_LOW); + + + return 1; +} + +static u32 +dpram_recovery_ReadMagicCode(void) +{ + u32 dwCode; + u32 *dwMagicCodeAddress; + + dwMagicCodeAddress = (u32 *)(dpram->dpram_vbase); + memcpy((void *)&dwCode, (void *)(dwMagicCodeAddress), 4); + + return dwCode; +} + +static void +dpram_recovery_WriteMagicCode(u32 dwCode) +{ + u32 *dwMagicCodeAddress; + dwMagicCodeAddress = (u32 *)(dpram->dpram_vbase); + + SeqIdx = 1; + memcpy((void *)dwMagicCodeAddress, (void *)&dwCode, 4); +} + +static u32 +dpram_recovery_ReadMagicCode_fota(void) +{ + u32 dwCode; + u32 *dwMagicCodeAddress; + + dwMagicCodeAddress = (u32 *)(dpram->dpram_vbase); + memcpy((void *)&dwCode, (void *)(dwMagicCodeAddress + 1), 4); + + return dwCode; +} + +static void +dpram_recovery_WriteMagicCode_fota(u32 dwCode) +{ + u32 *dwMagicCodeAddress; + dwMagicCodeAddress = (u32 *)(dpram->dpram_vbase); + + SeqIdx = 1; + memcpy((void *)(dwMagicCodeAddress + 1), (void *)&dwCode, 4); +} + + +static int +dpram_recovery_dpram_Init(void) +{ + const u32 dwMagicCodeToWrite = MAGIC_FODN; + const u32 dwMagicCodeToWrite_fota = MAGIC_FOTA; + u32 dwMagicCode = 0; + u32 dwMagicCode_fota = 0; + int iRetry = 0, nCnt = 0; + + printk(KERN_DEBUG "+DPRAM_Init\n"); + + /* Write the magic code */ + for (iRetry = 1; iRetry > 0 ; iRetry--) { + dwMagicCode = dpram_recovery_ReadMagicCode(); + + if (dwMagicCode == dwMagicCodeToWrite) { + printk(KERN_DEBUG "dwMagicCode == dwMagicCodeToWrite!!\n"); + break; + } + dpram_recovery_WriteMagicCode(dwMagicCodeToWrite); + + dwMagicCode = dpram_recovery_ReadMagicCode(); + printk("\n #### magic code: %x\n", dwMagicCode); + } + + for (iRetry = 1; iRetry > 0 ; iRetry--) { + + dwMagicCode_fota = dpram_recovery_ReadMagicCode_fota(); + + if (dwMagicCode_fota == dwMagicCodeToWrite_fota) { + printk(KERN_DEBUG "dwMagicCode_fota == dwMagicCodeToWrite_fota!!\n"); + break; + } + dpram_recovery_WriteMagicCode_fota(dwMagicCodeToWrite_fota); + + dwMagicCode_fota = dpram_recovery_ReadMagicCode_fota(); + printk("\n ### magic code for FOTA: %x\n", dwMagicCode_fota); + } + + dpram_recovery_modem_pwron(); + + /* Check phone on status */ + while (!dpram_recovery_modem_pwr_status()) { + msleep(1000); + nCnt++; + if (nCnt >= 20) { + printk(KERN_DEBUG "no phone active!! \n"); + return FALSE; + } + } + /* added one second delay after phone on */ + mdelay(1000); + printk(KERN_DEBUG "Phone Active!!!\n"); + printk(KERN_DEBUG "-DPRAM_Init\n"); + return TRUE; +} + +/* download */ +static int +dpram_recovery_download_Init(void) +{ + const u32 dwMagicCodeToWrite = MAGIC_DMDL; + u32 dwMagicCode = 0; + int iRetry = 0, nCnt = 0; + + printk(KERN_DEBUG "+DPRAM_Init\n"); + + /* Write the magic code */ + for (iRetry = 1; iRetry > 0 ; iRetry--) { + dwMagicCode = dpram_recovery_ReadMagicCode(); + + if (dwMagicCode == dwMagicCodeToWrite) { + printk(KERN_DEBUG "dwMagicCode == dwMagicCodeToWrite!!\n"); + break; + } + dpram_recovery_WriteMagicCode(dwMagicCodeToWrite); + + dwMagicCode = dpram_recovery_ReadMagicCode(); + printk("\n #### magic code: %x\n", dwMagicCode); + } + + dpram_recovery_modem_pwron(); + + /* Check phone on status */ + while (!dpram_recovery_modem_pwr_status()) { + msleep(1000); + nCnt++; + if (nCnt >= 20) { + printk(KERN_DEBUG "no phone active!! \n"); + return FALSE; + } + } + mdelay(1000); + printk(KERN_DEBUG "Phone Active!!!\n"); + printk(KERN_DEBUG "-DPRAM_Init\n"); + return TRUE; +} + +/* download */ +static u16 +dpram_recovery_ReadCommand(void) +{ + u16 nCmd = 0; + + memcpy((void *)&nCmd, (void *)(dpram->dpram_vbase + DPRAM_PHONE2PDA_INTERRUPT_ADDRESS), 2); + + return nCmd; +} + +static void +dpram_recovery_clear_modem_command(void) +{ + u16 clear; + clear = 0x0000; + + printk(KERN_DEBUG "dpram_recovery_clear_modem_command\n"); + + memcpy((void *)(dpram->dpram_vbase + DPRAM_PHONE2PDA_INTERRUPT_ADDRESS), (void *)&clear, 2); +} + +static void +dpram_recovery_WriteCommand(u16 nCmd) +{ + printk(KERN_DEBUG "\n\n ###[DPRAM_WriteCommand] Start : 0x%04x \n\n", nCmd); + + dpram_recovery_clear_modem_command(); + + memcpy((void *)(dpram->dpram_vbase + DPRAM_PDA2PHONE_INTERRUPT_ADDRESS), (void *)&nCmd, 2); +} + +static u32 +dpram_recovery_check_command(u16 intr, u16 mask) +{ + /* There's no Interrupt from Phone. we have to poll again.*/ + if (intr == 0) { + return CMD_RETRY; + } + /* Some command arrived.*/ + else { + if ((intr & MASK_CMD_VALID) != MASK_CMD_VALID) + return CMD_RETRY; + + else if ((intr & MASK_PDA_CMD) == MASK_PDA_CMD) + return CMD_RETRY; + + else if ((intr & MASK_PHONE_CMD) == MASK_PHONE_CMD) { + if ((intr & mask) == mask) + return CMD_TRUE; + + else + return CMD_FALSE; + + } else + return CMD_RETRY; + + } +} + +static int +dpram_recovery_wait_response(u16 cmd_mask) +{ + u16 intr; + int nRetry = 0; + int ret = 0; + + while (1) { + if (nRetry > 100) + return FALSE; + + intr = dpram_recovery_ReadCommand(); + printk(KERN_DEBUG "intr = 0x%x\n", intr); + + ret = dpram_recovery_check_command(intr, cmd_mask); + if (ret == CMD_TRUE) { + printk(KERN_DEBUG "READY ok\n"); + return TRUE; + } else if (ret == CMD_FALSE) { + printk(KERN_DEBUG "READY failed.\n"); + return FALSE; + } + + nRetry++; + if (fw.image_type == DPRAM_MODEM_DELTA_IMAGE) + msleep(1000); + else + msleep(5); + + } + + return TRUE; +} + +static int +dpram_recovery_WaitReadyPhase(void) +{ + int retval = TRUE; + + /* Send Delta Image Receive Ready Request */ + printk("Writing command for modem \n"); + dpram_recovery_WriteCommand(CMD_FOTA_IMG_RECEIVE_READY_REQ); + + /* Wait Delta Image Receive Ready Response */ + printk("Waiting for the response from Modem \n"); + retval = dpram_recovery_wait_response(MASK_CMD_FOTA_IMG_RECEIVE_READY_RESP); + + return retval; +} + +static int +dpram_recovery_WaitReadyPhase_download(void) +{ + int retval = TRUE; + + /* Send Delta Image Receive Ready Request */ + printk("Writing command for modem \n"); + dpram_recovery_WriteCommand(CMD_FOTA_IMG_SEND_REQ); + + /* Wait Delta Image Receive Ready Response */ + printk("Waiting for the response from Modem \n"); + retval = dpram_recovery_wait_response(MASK_CMD_FOTA_SEND_DONE_RESP | MASK_CMD_RESULT_SUCCESS); + + return retval; +} + +static int +dpram_recovery_write_modem_firmware( + struct dpram_dev *dev, char __user *firmware, int size) +{ + int ret = FALSE; + + /* Start Wait Ready Phase */ + if (dpram_recovery_WaitReadyPhase() == FALSE) { + printk(" error[-2] in return %s \n", __func__); + ret = -2; + goto Exit; + } + + /* Downlaod start Req ~ Update Status Noti */ + ret = dpram_recovery_DownloadControl((u8 *)firmware, size); + if (ret < 0) { + printk(KERN_DEBUG "[DPRAM_Download]Failed in DownloadControl\n."); + goto Exit; + } + printk(KERN_DEBUG "[DPRAM_Download]FileSize : %d\n", size); + printk(KERN_DEBUG "[DPRAM_Download]Bootloader Image Download Completed!\n"); + + if (!dpram_recovery_UpdateRequestPhase()) { + printk(KERN_DEBUG "[DPRAM_DownloadControl] Wait FOTA Update Start Response Failed!!\n"); + ret = -7; /* -7 means that FOTA Update Start Response failed. */ + goto Exit; + } + + ret = TRUE; + +Exit: + return ret; +} + +static int +dpram_recovery_write_modem_full_firmware(struct dpram_dev *dev, char __user *firmware, int size) +{ + int ret = FALSE; + + /* Start Wait Ready Phase */ + if (dpram_recovery_wait_response(MASK_CMD_FOTA_IMG_RECEIVE_READY_RESP) == FALSE) { + printk(" error[-2] in return %s \n", __func__); + ret = -2; + goto Exit; + } + + /* Clear Response */ + dpram_recovery_clear_modem_command(); + + /* Downlaod start Req ~ Update Status Noti */ + ret = dpram_recovery_DownloadControl_fullfirmware((u8 *)firmware, size); + if (ret < 0) { + printk(KERN_DEBUG "[DPRAM_Download]Failed in DownloadControl\n."); + goto Exit; + } + printk(KERN_DEBUG "[DPRAM_Download]FileSize : %d\n", size); + printk(KERN_DEBUG "[DPRAM_Download]Bootloader Image Download Completed!\n"); + + ret = TRUE; + +Exit: + return ret; +} + +static u16 +dpram_recovery_MakeCRC(u16 length, u16 *data_ptr_WORD) +{ + u16 data_crc = CRC_16_L_SEED; + u16 const *table = CRC_Table; + u8 *data_ptr = (u8 *)data_ptr_WORD; + int i; + + for (i = 0; i < length; i++) { + data_crc = (((data_crc) >> 8) ^ table[((data_crc) ^ (u16)(data_ptr[i])) & 0x00ff]); + /*printk(KERN_DEBUG "%010d:0x%04x\r\n", i, data_crc ); */ + } + /*printk(KERN_DEBUG "[MakeCRC] length:%d pt:0x%08x i:%d v:0x%04x \r\n", length, data_ptr, i, data_ptr[i] ); */ + return data_crc; +} + +static u32 +dpram_recovery_WriteImage(u8 *const pBuf, u32 dwWriteLen) +{ + u8 *pDest; + u8 *pDest_Data; + u16 Len; + u16 nCrc; + + /*printk(KERN_DEBUG "Start %d 0x%04x(%d)\n", dwWriteLen, g_TotFrame, g_TotFrame);*/ + + pDest = (u8 *)(dpram->dpram_vbase + DPRAM_PDA2PHONE_FORMATTED_START_ADDRESS); + Len = (u16)min((u32)dwWriteLen, (u32)FODN_DEFAULT_WRITE_LEN); + + /*printk(KERN_DEBUG "Start : pDest(0x%08x), dwWriteLen(%d)\n",pDest, Len);*/ + + /* Start Index */ + *pDest++ = LOBYTE(START_INDEX); + *pDest++ = HIBYTE(START_INDEX); + + /*Total Frame number: */ + *pDest++ = LOBYTE(g_TotFrame); + *pDest++ = HIBYTE(g_TotFrame); + + /*Current Frame number; */ + *pDest++ = LOBYTE(g_CurFrame); + *pDest++ = HIBYTE(g_CurFrame); + g_CurFrame++; + + /* Length - Does it include the length of START_INDEX?? */ + *pDest++ = LOBYTE(Len); + *pDest++ = HIBYTE(Len); + + /* Data */ + pDest_Data = pDest; + memcpy((void *)pDest, (void *)pBuf, Len); + pDest += Len; + + /* Fill null if data length is odd */ + if (Len%2 != 0) { + *pDest++ = 0xff; + printk(KERN_DEBUG "odd 0x%08x 0x%02x\n", (unsigned int)(pDest-1), (u8)(*pDest-1)); + } + + /*printk(KERN_DEBUG "len:%d default len:%d\n", Len, FODN_DEFAULT_WRITE_LEN);*/ + /*printk(KERN_DEBUG "start data 0x%08x \n", pDest);*/ + + if (Len < FODN_DEFAULT_WRITE_LEN) { + memset((void *)pDest, 0x0 /*0xff*/, FODN_DEFAULT_WRITE_LEN - Len); + pDest += (FODN_DEFAULT_WRITE_LEN - Len) ; + } + printk(KERN_DEBUG "CRC start 0x%08x\n", (unsigned int)pDest); + + nCrc = dpram_recovery_MakeCRC(Len, (u16 *)pDest_Data); + + *pDest++ = LOBYTE(nCrc); + *pDest++ = HIBYTE(nCrc); + + printk(KERN_DEBUG "CRC value 0x%04x \n", nCrc); + + *pDest++ = LOBYTE(END_INDEX); + *pDest++ = HIBYTE(END_INDEX); + + /* Write Command*/ + dpram_recovery_WriteCommand(CMD_FOTA_IMG_SEND_REQ); + + return Len; +} + +static u32 +dpram_recovery_WriteImage_download(u8 *const pBuf, u32 dwWriteLen) +{ + u8 *pDest; + u8 *pDest_Data; + u16 Len; + u16 nCrc; + + /*printk(KERN_DEBUG "Start %d 0x%04x(%d)\n", dwWriteLen, g_TotFrame, g_TotFrame);*/ + + pDest = (u8 *)(dpram->dpram_vbase + DPRAM_PDA2PHONE_FORMATTED_START_ADDRESS); + Len = (u16)min((u32)dwWriteLen, (u32)FODN_DEFAULT_WRITE_LEN); + + /*printk(KERN_DEBUG "Start : pDest(0x%08x), dwWriteLen(%d)\n",pDest, Len);*/ + + /* Start Index */ + *pDest++ = LOBYTE(START_INDEX); + *pDest++ = HIBYTE(START_INDEX); + + /*Total Frame number: */ + *pDest++ = LOBYTE(g_TotFrame); + *pDest++ = HIBYTE(g_TotFrame); + + /*Current Frame number; */ + *pDest++ = LOBYTE(g_CurFrame); + *pDest++ = HIBYTE(g_CurFrame); + g_CurFrame++; + + /* Length - Does it include the length of START_INDEX?? */ + *pDest++ = LOBYTE(Len); + *pDest++ = HIBYTE(Len); + + /* Data */ + pDest_Data = pDest; + memcpy((void *)pDest, (void *)pBuf, Len); + pDest += Len; + + /* Fill null if data length is odd */ + if (Len%2 != 0) { + *pDest++ = 0xff; + printk(KERN_DEBUG "odd 0x%08x 0x%02x\n", (unsigned int)(pDest-1), (u8)(*pDest-1)); + } + + /*printk(KERN_DEBUG "len:%d default len:%d\n", Len, FODN_DEFAULT_WRITE_LEN);*/ + /*printk(KERN_DEBUG "start data 0x%08x \n", pDest);*/ + + if (Len < FODN_DEFAULT_WRITE_LEN) { + memset((void *)pDest, 0x0 /*0xff*/, FODN_DEFAULT_WRITE_LEN - Len); + pDest += (FODN_DEFAULT_WRITE_LEN - Len) ; + } + printk(KERN_DEBUG "CRC start 0x%08x\n", (unsigned int)pDest); + + nCrc = dpram_recovery_MakeCRC(Len, (u16 *)pDest_Data); + + *pDest++ = LOBYTE(nCrc); + *pDest++ = HIBYTE(nCrc); + + printk(KERN_DEBUG "CRC value 0x%04x \n", nCrc); + + pDest = (u8 *)(dpram->dpram_vbase + BSP_DPRAM_BASE_SIZE - 2*DPRAM_INTERRUPT_SIZE - DPRAM_INDEX_SIZE); + + *pDest++ = LOBYTE(END_INDEX); + *pDest++ = HIBYTE(END_INDEX); + + /* Write Command*/ + dpram_recovery_WriteCommand(CMD_FOTA_UPDATE_START_REQ); + + return Len; +} + + +static u16 +dpram_recovery_CalcTotFrame(u32 nDividend, u16 nDivisor) +{ + u16 nCompVal1 = 0; + u16 nCompVal2 = 0; + + printk(KERN_DEBUG "[CalcTotFrame](%d) %d %d\n", __LINE__, nDividend, nDivisor); + nCompVal1 = (u16) (nDividend / nDivisor); + nCompVal2 = (u16) (nDividend - (nCompVal1 * nDivisor)); + if (nCompVal2 > 0) { + printk(KERN_DEBUG "[CalcTotFrame](%d) val2 : %d\n", __LINE__, nCompVal2); + nCompVal1++; + } + printk(KERN_DEBUG "[CalcTotFrame](%d) result %d\n", __LINE__, nCompVal1); + return nCompVal1; +} + +static void +dpram_recovery_WriteDoneRequest(void) +{ + printk(KERN_DEBUG "[DPRAM_WriteDoneRequest] Start\n"); + + SeqIdx = 1; + + dpram_recovery_WriteCommand(CMD_FOTA_SEND_DONE_REQ); + printk(KERN_DEBUG "[DPRAM_WriteDoneRequest] End\n"); +} + +static int +dpram_recovery_SendDonePhase(void) +{ + int retval = TRUE; + + /* Send Write Done Request */ + dpram_recovery_WriteDoneRequest(); + + /* Wait Write Done Response */ + retval = dpram_recovery_wait_response(MASK_CMD_FOTA_SEND_DONE_RESP); + if (retval == FALSE) { + printk(KERN_DEBUG " Wait Write Done Response Failed!!\n"); + return retval; + } + + printk(KERN_DEBUG "Wait 0.5 secs.. .. ..\n"); + msleep(500); + + return retval; +} + +static int +dpram_recovery_UpdateRequestPhase(void) +{ + int retval = TRUE; + + /* Send FOTA Update Start Request */ + dpram_recovery_WriteCommand(CMD_FOTA_UPDATE_START_REQ); + /* Wait FOTA Update Start Response */ + /*retval = dpram_recovery_wait_response(MASK_CMD_FOTA_UPDATE_START_RESP); */ + + return retval; +} + +static u32 +dpram_recovery_DownloadControl(u8 *pBufIn, u32 Len) +{ + u32 dwWriteLen = 0, dwWrittenLen = 0, dwTotWrittenLen = 0; + u32 dwRet = 0; + u16 nTotalFrame = 0, nIntrValue = 0; + int nwRetry = 0, nrRetry = 0, retval; + + nTotalFrame = dpram_recovery_CalcTotFrame(Len, DELTA_PACKET_SIZE); + g_TotFrame = nTotalFrame; + printk(KERN_DEBUG "[DPRAM_DownloadControl] total frame:%d,%d\n", g_TotFrame, nTotalFrame); + + while (dwTotWrittenLen < Len) { + /*Write proper size of image to DPRAM*/ + printk(KERN_DEBUG "[DPRAM_DownloadControl]DPRAM_WriteImage %d/%d start\n", + g_CurFrame, g_TotFrame); + dwWriteLen = min((u32)(Len - dwTotWrittenLen), (u32)DELTA_PACKET_SIZE); + dwWrittenLen = dpram_recovery_WriteImage(pBufIn, dwWriteLen); + printk(KERN_DEBUG "[DPRAM_DownloadControl]Written data:%d\n", dwWrittenLen); + + if (dwWrittenLen > 0) { + dwTotWrittenLen += dwWrittenLen; + pBufIn += dwWrittenLen; + } else { + printk(KERN_DEBUG "[DPRAM_DownloadControl]Write Image Len is wierd.\n"); + if (nwRetry < 3) { + nwRetry++; + printk(KERN_DEBUG "[DPRAM_DownloadControl]Retry to write. nRetry = %8x\n", nwRetry); + continue; + } else { + printk(KERN_DEBUG "[DPRAM_DownloadControl]Fail to Write Image to DPRAM.\n"); + dwRet = -3; + goto Exit; + } + } + + /* Wait for the IMAGE WRITE RESPONSE */ + while (nrRetry < 10) { + retval = dpram_recovery_wait_response(MASK_CMD_FOTA_IMG_SEND_RESP); + if (retval == FALSE) { + printk(KERN_DEBUG "[DPRAM_DownloadControl] Wait Image Send Response Failed\n"); + dwRet = -4; + goto Exit; + } else { + nIntrValue = dpram_recovery_ReadCommand(); + if ((nIntrValue & MASK_CMD_RESULT_FAIL) == 0) { + printk(KERN_DEBUG "[DPRAM_DownloadControl] MASK_CMD_IMAGE_SEND_RESPONSE OK issued.\n"); + printk(KERN_DEBUG "[DPRAM_DownloadControl] %d /%d ok\n", g_CurFrame - 1, g_TotFrame); + break; + } else { + printk(KERN_DEBUG "[DPRAM_DownloadControl] MASK_CMD_IMAGE_SEND_RESPONSE Failed issued.\n"); + msleep(100); + nrRetry++; + dpram_recovery_WriteCommand(CMD_FOTA_IMG_SEND_REQ); + printk(KERN_DEBUG "[DPRAM_DownloadControl] CMD_IMG_SEND_REQ retry.(%d)\n", nrRetry); + + if (nrRetry >= 10) { + dwRet = -5; + goto Exit; + } + } + } + } + } + + g_CurFrame = 1; + + if (!dpram_recovery_SendDonePhase()) { + printk(KERN_DEBUG "[DPRAM_DownloadControl] There's something unexpeted in SendDone Phase.\n"); + dwRet = -6; /* -6 means that SendDone Phase failed. */ + goto Exit; + } + +Exit: + return dwRet; +} + +static u32 +dpram_recovery_DownloadControl_fullfirmware(u8 *pBufIn, u32 Len) +{ + u32 dwWriteLen = 0, dwWrittenLen = 0, dwTotWrittenLen = 0; + u32 dwRet = 0; + u16 nTotalFrame = 0, nIntrValue = 0; + int nwRetry = 0, nrRetry = 0, retval; + + /* Send command and wait for response */ + if (dpram_recovery_WaitReadyPhase_download() == FALSE) { + printk(" error[-2] in return %s \n", __func__); + dwRet = -2; + goto Exit; + } + + nTotalFrame = dpram_recovery_CalcTotFrame(Len, FODN_DEFAULT_WRITE_LEN); + g_TotFrame = nTotalFrame; + printk(KERN_DEBUG "[DPRAM_DownloadControl] total frame:%d\n", nTotalFrame); + + while (dwTotWrittenLen < Len) { + /*Write proper size of image to DPRAM*/ + printk(KERN_DEBUG "[DPRAM_DownloadControl]DPRAM_WriteImage %d/%d start\n", + g_CurFrame, g_TotFrame); + dwWriteLen = min((u32)(Len - dwTotWrittenLen), (u32)FODN_DEFAULT_WRITE_LEN); + dwWrittenLen = dpram_recovery_WriteImage_download(pBufIn, dwWriteLen); + printk(KERN_DEBUG "[DPRAM_DownloadControl]Written data:%d\n", dwWrittenLen); + + if (dwWrittenLen > 0) { + dwTotWrittenLen += dwWrittenLen; + pBufIn += dwWrittenLen; + } else { + printk(KERN_DEBUG "[DPRAM_DownloadControl]Write Image Len is wierd.\n"); + if (nwRetry < 3) { + nwRetry++; + printk(KERN_DEBUG "[DPRAM_DownloadControl]Retry to write. nRetry = %8x\n", nwRetry); + continue; + } else { + printk(KERN_DEBUG "[DPRAM_DownloadControl]Fail to Write Image to DPRAM.\n"); + dwRet = -3; + goto Exit; + } + } + + /* Wait for the IMAGE WRITE RESPONSE */ + while (nrRetry < 10) { + retval = dpram_recovery_wait_response(MASK_CMD_IMAGE_SEND_RESPONSE); + if (retval == FALSE) { + printk(KERN_DEBUG "[DPRAM_DownloadControl] Wait Image Send Response Failed\n"); + dwRet = -4; + goto Exit; + } else { + nIntrValue = dpram_recovery_ReadCommand(); + if ((nIntrValue & MASK_CMD_RESULT_FAIL) == 0) { + printk(KERN_DEBUG "[DPRAM_DownloadControl] MASK_CMD_IMAGE_SEND_RESPONSE OK issued.\n"); + printk(KERN_DEBUG "[DPRAM_DownloadControl] %d /%d ok\n", g_CurFrame - 1, g_TotFrame); + break; + } else { + printk(KERN_DEBUG "[DPRAM_DownloadControl] MASK_CMD_IMAGE_SEND_RESPONSE Failed issued.\n"); + msleep(100); + nrRetry++; + dpram_recovery_WriteCommand(CMD_FOTA_UPDATE_START_REQ); + printk(KERN_DEBUG "[DPRAM_DownloadControl] CMD_IMG_SEND_REQ retry.(%d)\n", nrRetry); + + if (nrRetry >= 10) { + dwRet = -5; + goto Exit; + } + } + } + } + } + + g_CurFrame = 1; + + /* SendDone Phase */ + dpram_recovery_WriteCommand(CMD_DL_SEND_DONE_REQ); + printk(KERN_DEBUG "[DPRAM_WriteDoneRequest] End\n"); + + printk(KERN_DEBUG "Wait 0.5 secs.. .. ..\n"); + msleep(500); + + +Exit: + return dwRet; +} + +static u32 +dpram_recovery_StatusNotiPhase(u32 *pPercent, u8 *UpDoneNotiFlag) +{ + Status_UpNoti UpStatus; + u16 intr = 0, ret = 0; + u32 dwRet = TRUE; + + UpStatus.progress_status = 0x00; + UpStatus.error_code = 0x00; + + *UpDoneNotiFlag = FALSE; + + /*dpram_recovery_WriteCommand(CMD_FOTA_UPDATE_STATUS_IND); */ + + /* Wait FOTA Update Status Indication */ + dwRet = dpram_recovery_wait_response(MASK_CMD_FOTA_UPDATE_STATUS_IND); + if (dwRet == FALSE) { + printk(KERN_DEBUG "Wait FOTA Update Status Indication Failed!!\n"); + intr = dpram_recovery_ReadCommand(); + ret = dpram_recovery_check_command(intr, MASK_CMD_FOTA_UPDATE_END_IND); + if (ret == CMD_TRUE) { + dwRet = TRUE; + *UpDoneNotiFlag = TRUE; + printk(KERN_DEBUG "But FOTA Update Done Indication Received!!\n"); + goto StatusRead; + } else + goto Exit; + } + +StatusRead: + memcpy((void *)&UpStatus, (void *)(dpram->dpram_vbase + DPRAM_PDA2PHONE_FORMATTED_START_ADDRESS), 8); + + printk(KERN_DEBUG "0x%x 0x%x 0x%x 0x%x \n", UpStatus.Bop, UpStatus.progress_status, UpStatus.error_code, UpStatus.Eop); + + if ((UpStatus.Bop != START_INDEX) || (UpStatus.Eop != END_INDEX)) { + printk(KERN_DEBUG "Packet format is wrong.\n"); + dwRet = 0; + } else { + printk(KERN_DEBUG "Get the Status info.\n"); + *pPercent = (u32)UpStatus.progress_status; + error_code = (u16)UpStatus.error_code; + } + + if (error_code != 0) { + printk(KERN_DEBUG "Update error is occured, error number:0x%x.\n", error_code); + dwRet = FALSE; + goto Exit; + } + +Exit: + /* Clear modem command for next IOCTL_CHK_STAT */ + dpram_recovery_clear_modem_command(); + + return dwRet; +} + +static u32 +dpram_recovery_StatusNotiPhase_download(u32 *pPercent, u8 *UpDoneNotiFlag) +{ + Check_UpNoti upstatus; + u16 ret = 0; + u32 dwRet = TRUE; + + upstatus.Region = 0x0; + upstatus.Percent = 0x0; + + *UpDoneNotiFlag = FALSE; + + dwRet = dpram_recovery_wait_response(MASK_CMD_UPDATE_DONE_NOTIFICATION|MASK_CMD_RESULT_SUCCESS); + if (dwRet == FALSE) { + dwRet = dpram_recovery_wait_response(MASK_CMD_STATUS_UPDATE_NOTIFICATION|MASK_CMD_RESULT_SUCCESS); + if (dwRet == TRUE) { + printk(KERN_DEBUG "Received UPDATE Status Notification Command in %s", __func__); + goto StatusRead; + } else { + ret = FALSE; + goto Exit; + } + } else { + printk(KERN_DEBUG " Successfully Received UPDATE DONE Command in %s", __func__); + *UpDoneNotiFlag = TRUE; + ret = TRUE; + goto StatusRead; + } + +StatusRead: + dpram_recovery_clear_modem_command(); + memcpy((void *)&upstatus, (void *)(dpram->dpram_vbase + DPRAM_PDA2PHONE_FORMATTED_START_ADDRESS), 8); + if ((upstatus.Bop != START_INDEX) || (upstatus.Eop != END_INDEX)) { + printk(KERN_DEBUG "CP Update Failed by Bad Header!! \n"); + printk(KERN_DEBUG "0x%x 0x%x \n", upstatus.Bop, upstatus.Eop); + ret = FALSE; + goto Exit; + } else { + *pPercent = upstatus.Percent; + printk(KERN_DEBUG "Region= 0x%x Percent = 0x%x \n", upstatus.Region, upstatus.Percent); + ret = TRUE; + } +Exit: + /* Clear modem command for next IOCTL_CHK_STAT */ + dpram_recovery_clear_modem_command(); + return ret; + +} + +static int +dpram_recovery_check_status(struct dpram_dev *dev, int __user *pct) +{ + u32 bUpStatusPer = 0, PrevbUpStatusPer = 0; + u8 UpDoneNotiFlag = 0; + u32 dwRet = 1; + int retval = 0; + + /* Process for UPDATE STATUS Noti. phase. */ + retval = dpram_recovery_StatusNotiPhase(&bUpStatusPer, &UpDoneNotiFlag); + if (retval == FALSE) { + printk(KERN_DEBUG "[DPRAM_DownloadControl] Wait Status Noti Phase Failed!!\n"); + dwRet = -8; + } else { + printk(KERN_DEBUG "Progress:%d\n", bUpStatusPer); + + if (bUpStatusPer > PrevbUpStatusPer) + PrevbUpStatusPer = bUpStatusPer; + + *pct = bUpStatusPer; + + if ((bUpStatusPer == 100) && (UpDoneNotiFlag == TRUE)) { + printk(KERN_DEBUG "Done!!!\n"); + dwRet = 0; + } + } + + return dwRet; +} + +static int +dpram_recovery_check_status_download(struct dpram_dev *dev, int __user *pct) +{ + u32 bUpStatusPer = 0, PrevbUpStatusPer = 0; + u8 UpDoneNotiFlag = 0; + u32 dwRet = 1; + int retval = 0; + + /* Process for UPDATE STATUS Noti. phase. */ + retval = dpram_recovery_StatusNotiPhase_download(&bUpStatusPer, &UpDoneNotiFlag); + if (retval == FALSE) { + printk(KERN_DEBUG "[DPRAM_DownloadControl] Wait Status Noti Phase Failed!!\n"); + dwRet = -8; + } else { + printk(KERN_DEBUG "Progress:%d\n", bUpStatusPer); + + if (bUpStatusPer > PrevbUpStatusPer) + PrevbUpStatusPer = bUpStatusPer; + + *pct = bUpStatusPer; + + if ((bUpStatusPer == 100) && (UpDoneNotiFlag == TRUE)) { + printk(KERN_DEBUG "Done!!!\n"); + dwRet = 0; + } + } + + return dwRet; +} + +static ssize_t +dpram_recovery_read(struct file *filp, char __user *buff, + size_t count, loff_t *fpos) +{ + return 0; +} + +static ssize_t +dpram_recovery_write(struct file *filp, const char __user *buff, + size_t size, loff_t *fpos) +{ + return 0; +} + +static long +dpram_recovery_ioctl(struct file *filp, + unsigned int cmd, unsigned long arg) + +{ + struct dpram_dev *dev; + int ret = 0, ret_check = 0; + u32 magic_code = 0x0; + + printk(MSGDBG "%s" MSGEND, __func__); + printk(KERN_ERR "%s\n", __func__); + + dev = container_of(filp->f_path.dentry->d_inode->i_cdev, struct dpram_dev, cdev); + + switch (cmd) { + case IOCTL_WRITE_MAGIC_CODE: + dpram_recovery_dpram_Init(); + break; + + case IOCTL_ST_FW_UPDATE: + printk(KERN_ERR "%s IOCTL_ST_FW_UPDATE\n", __func__); + + if (arg == 0) { + printk(MSGWARN "Firmware should be written prior to this call" MSGEND); + } else { + ret_check = copy_from_user((void *)&fw, (void *)arg, sizeof(fw)); + if (ret_check) { + printk("[IOCTL_ST_FW_UPDATE]copy from user failed!"); + return -EFAULT; + } + } + + /* Dpram Phone off */ + dpram_recovery_modem_pwroff(); + if (fw.image_type == DPRAM_MODEM_DELTA_IMAGE) { + /* Enter FOTA Update Mode */ + dpram_recovery_dpram_Init(); + ret = dpram_recovery_write_modem_firmware(dev, fw.firmware, fw.size); + if (ret < 0) { + printk("firmware write failed\n"); + } + + } else { + /* Enter Download Mode */ + dpram_recovery_download_Init(); + ret = dpram_recovery_write_modem_full_firmware(dev, fw.firmware, fw.size); + if (ret < 0) { + printk("firmware write failed\n"); + } + } + break; + case IOCTL_CHK_STAT: + { + struct stat_info *pst; + + printk(KERN_ERR "%s IOCTL_CHK_STAT\n", __func__); + pst = (struct stat_info *)arg; + if (fw.image_type == DPRAM_MODEM_DELTA_IMAGE) { + ret = dpram_recovery_check_status(dev, &(pst->pct)); + } else { + ret = dpram_recovery_check_status_download(dev, &(pst->pct)); + } + } + break; + + case IOCTL_MOD_PWROFF: + printk(KERN_ERR "%s IOCTL_MOD_PWROFF\n", __func__); + + msleep(2000); /* Delay for display */ + + /* Clear Magic Code */ + dpram_recovery_WriteMagicCode(magic_code); + + dpram_recovery_modem_pwroff(); + break; + + default: + printk(KERN_ERR "Unknown command"); + break; + } + + return ret; +} + +static int +dpram_recovery_open(struct inode *inode, struct file *filp) +{ + struct dpram_dev *dev; + + printk(KERN_ERR "%s\n", __func__); + + dev = container_of(inode->i_cdev, struct dpram_dev, cdev); + filp->private_data = (void *)dev; + + return 0; +} + +static int +dpram_recovery_release(struct inode *inode, struct file *filp) +{ + printk(KERN_DEBUG "dpram recovery device released.\n"); + return 0; +} + + +static struct file_operations dpram_recovery_fops = { + .owner = THIS_MODULE, + .read = dpram_recovery_read, + .write = dpram_recovery_write, + .unlocked_ioctl = dpram_recovery_ioctl, + .open = dpram_recovery_open, + .release = dpram_recovery_release, +}; + +static int register_dpram_rec_device(void) +{ + struct device *dpram_rec_dev_t; + struct class *dpram_rec_class; + int ret; + + ret = register_chrdev(MAJOR_NUM, DRIVER_NAME, &dpram_recovery_fops); + if (ret < 0) { + goto err; + } + + dpram_rec_class = class_create(THIS_MODULE, "rec"); + if (IS_ERR(dpram_rec_class)) { + ret = -EFAULT; + goto err1; + } + + dpram_rec_dev_t = device_create(dpram_rec_class, NULL, MKDEV(MAJOR_NUM, 0), NULL, DRIVER_NAME); + if (IS_ERR(dpram_rec_dev_t)) { + ret = -EFAULT; + goto err2; + } + + return 0; + +err2: + class_destroy(dpram_rec_class); + +err1: + unregister_chrdev(MAJOR_NUM, DRIVER_NAME); + +err: + return ret; +} + +/* Dpram Interrupt register */ +static irqreturn_t phone_active_irq_handler(int irq, void *dev_id) +{ + + printk(KERN_ERR "Received interrupt for PHONE ACTIVE \n"); + if (gpio_get_value(GPIO_QSC_PHONE_ACTIVE)) { + printk(KERN_ALERT "%s: Phone Active high and Modem is ON\n", __func__); + } else { + printk(KERN_ALERT "%s: Phone Active Low and Modem is OFF\n", __func__); + } + return IRQ_HANDLED; +} + +static int register_interrupt_handler(void) +{ + int retval = 0, phone_active_irq; + phone_active_irq = gpio_to_irq(IRQ_QSC_PHONE_ACTIVE); + + /* phone active interrupt */ + retval = request_irq(phone_active_irq, phone_active_irq_handler, IRQF_DISABLED, "QSC_ACTIVE", NULL); + if (retval) { + printk(KERN_ERR "Phone active interrupt handler failed.\n"); + } + + return 0; +} + +/* + * DPRAM DRIVER INITIALIZE FUNCTIONs + */ +int dpram_init_hw(void) +{ + int rv; + int phone_active_irq, dpram_wakeup_irq; + + /* 1) Initialize the interrupt pins */ + irq_set_irq_type(IRQ_DPRAM_AP_INT_N, IRQ_TYPE_LEVEL_LOW); + rv = gpio_request(IRQ_QSC_INT, "gpx1_0"); + if (rv < 0) { + printk("IDPRAM: [%s] failed to get gpio GPX1_0\n", __func__); + goto err; + } + dpram_wakeup_irq = gpio_to_irq(IRQ_QSC_INT); + s3c_gpio_cfgpin(GPIO_C210_DPRAM_INT_N, S3C_GPIO_SFN(0xFF)); + s3c_gpio_setpull(GPIO_C210_DPRAM_INT_N, S3C_GPIO_PULL_NONE); + irq_set_irq_type(dpram_wakeup_irq, IRQ_TYPE_EDGE_RISING); + + rv = gpio_request(IRQ_QSC_PHONE_ACTIVE, "gpx1_6"); + if (rv < 0) { + printk("IDPRAM: [%s] failed to get gpio GPX1_6\n", __func__); + goto err1; + } + + phone_active_irq = gpio_to_irq(IRQ_QSC_PHONE_ACTIVE); + + s3c_gpio_setpull(GPIO_QSC_PHONE_ACTIVE, S3C_GPIO_PULL_NONE); + s3c_gpio_setpull(GPIO_QSC_PHONE_RST, S3C_GPIO_PULL_NONE); + irq_set_irq_type(phone_active_irq, IRQ_TYPE_EDGE_FALLING); + /* 4)gpio e3-e4 are for Modem if */ + + s3c_gpio_cfgpin(S5PV310_GPE3_0_MDM_DATA_0, S3C_GPIO_SFN(S5PV310_MDM_IF_SEL)); + s3c_gpio_cfgpin(S5PV310_GPE3_1_MDM_DATA_1, S3C_GPIO_SFN(S5PV310_MDM_IF_SEL)); + s3c_gpio_cfgpin(S5PV310_GPE3_2_MDM_DATA_2, S3C_GPIO_SFN(S5PV310_MDM_IF_SEL)); + s3c_gpio_cfgpin(S5PV310_GPE3_3_MDM_DATA_3, S3C_GPIO_SFN(S5PV310_MDM_IF_SEL)); + s3c_gpio_cfgpin(S5PV310_GPE3_4_MDM_DATA_4, S3C_GPIO_SFN(S5PV310_MDM_IF_SEL)); + s3c_gpio_cfgpin(S5PV310_GPE3_5_MDM_DATA_5, S3C_GPIO_SFN(S5PV310_MDM_IF_SEL)); + s3c_gpio_cfgpin(S5PV310_GPE3_6_MDM_DATA_6, S3C_GPIO_SFN(S5PV310_MDM_IF_SEL)); + s3c_gpio_cfgpin(S5PV310_GPE3_7_MDM_DATA_7, S3C_GPIO_SFN(S5PV310_MDM_IF_SEL)); + + s3c_gpio_cfgpin(S5PV310_GPE4_0_MDM_DATA_8, S3C_GPIO_SFN(S5PV310_MDM_IF_SEL)); + s3c_gpio_cfgpin(S5PV310_GPE4_1_MDM_DATA_9, S3C_GPIO_SFN(S5PV310_MDM_IF_SEL)); + s3c_gpio_cfgpin(S5PV310_GPE4_2_MDM_DATA_10, S3C_GPIO_SFN(S5PV310_MDM_IF_SEL)); + s3c_gpio_cfgpin(S5PV310_GPE4_3_MDM_DATA_11, S3C_GPIO_SFN(S5PV310_MDM_IF_SEL)); + s3c_gpio_cfgpin(S5PV310_GPE4_4_MDM_DATA_12, S3C_GPIO_SFN(S5PV310_MDM_IF_SEL)); + s3c_gpio_cfgpin(S5PV310_GPE4_5_MDM_DATA_13, S3C_GPIO_SFN(S5PV310_MDM_IF_SEL)); + s3c_gpio_cfgpin(S5PV310_GPE4_6_MDM_DATA_14, S3C_GPIO_SFN(S5PV310_MDM_IF_SEL)); + s3c_gpio_cfgpin(S5PV310_GPE4_7_MDM_DATA_15, S3C_GPIO_SFN(S5PV310_MDM_IF_SEL)); + + s3c_gpio_cfgpin(S5PV310_GPE0_0_MDM_WEn, S3C_GPIO_SFN(S5PV310_MDM_IF_SEL)); + s3c_gpio_cfgpin(S5PV310_GPE0_1_MDM_CSn, S3C_GPIO_SFN(S5PV310_MDM_IF_SEL)); + s3c_gpio_cfgpin(S5PV310_GPE0_2_MDM_Rn, S3C_GPIO_SFN(S5PV310_MDM_IF_SEL)); + s3c_gpio_cfgpin(S5PV310_GPE0_3_MDM_IRQn, S3C_GPIO_SFN(S5PV310_MDM_IF_SEL)); + s3c_gpio_cfgpin(S5PV310_GPE0_4_MDM_ADVN, S3C_GPIO_SFN(S5PV310_MDM_IF_SEL)); + + rv = gpio_request(GPIO_PDA_ACTIVE, "GPY4_2"); + if (rv < 0) { + printk("IDPRAM: [%s] failed to get gpio GPY4_2\n", __func__); + goto err2; + } + + rv = gpio_request(GPIO_QSC_PHONE_ON, "GPC1_1"); + if (rv < 0) { + printk("IDPRAM: [%s] failed to get gpio GPC1_1\n", __func__); + goto err3; + } + + rv = gpio_request(GPIO_QSC_PHONE_RST, "GPX1_4"); + if (rv < 0) { + printk("IDPRAM: [%s] failed to get gpio GPX1_4\n", __func__); + goto err4; + } + + s5p_gpio_set_drvstr(GPIO_QSC_PHONE_RST, S5P_GPIO_DRVSTR_LV4); /*To increase driving strength of this pin */ + + /*To config Not Connected pin GPY4_6 to I/P with no pullup */ + rv = gpio_request(GPIO_CP_REQ_RESET, "GPY4_6"); + if (rv < 0) { + printk("IDPRAM: [%s] failed to get gpio GPY4_6\n", __func__); + goto err5; + } + + gpio_direction_input(GPIO_CP_REQ_RESET); + s3c_gpio_setpull(GPIO_CP_REQ_RESET, S3C_GPIO_PULL_NONE); + + /* 5)PDA_ACTIVE, QSC_PHONE_ON, QSC_RESET_N */ + gpio_direction_output(GPIO_PDA_ACTIVE, GPIO_LEVEL_HIGH); + gpio_direction_output(GPIO_QSC_PHONE_ON, GPIO_LEVEL_HIGH); + s3c_gpio_setpull(GPIO_QSC_PHONE_ON, S3C_GPIO_PULL_NONE); + gpio_direction_output(GPIO_QSC_PHONE_RST, GPIO_LEVEL_LOW); + + return 0; + +err5: gpio_free(GPIO_QSC_PHONE_RST); +err4: gpio_free(GPIO_QSC_PHONE_ON); +err3: gpio_free(GPIO_PDA_ACTIVE); +err2: gpio_free(IRQ_QSC_PHONE_ACTIVE); +err1: gpio_free(IRQ_QSC_INT); +err: return rv; +} + +static int __devinit dpram_recovery_probe(struct platform_device *pdev) +{ + int err = 0; + g_TotFrame = 0; + + printk(KERN_ERR "[DPRAM_RECOVERY] %s() ...\n", __func__); + + dpram = kmalloc(sizeof(struct dpram_dev), GFP_KERNEL); + if (dpram == NULL) { + printk(KERN_ERR "dpram recovery device allocation failed!!\n"); + err = -ENOMEM; + goto out; + } + + if (dpram_recovery_ioremap(dpram) < 0) { + printk(KERN_ERR "Dpram recovery ioremap failed!\n"); + err = -EFAULT; + goto out_err1; + } + + err = register_dpram_rec_device(); + if (err) { + printk(KERN_ERR "Failed to register dpram recovery device.\n"); + goto out_err2; + } + + err = dpram_init_hw(); + if (err < 0) { + printk("dpram_init_hw() failed\n"); + goto out_err2; + } + + err = register_interrupt_handler(); + if (err < 0) { + printk("register_interrupt_handler() failed!!!\n"); + goto out_err3; + } + + printk(KERN_ERR "%s %d\n", __func__, __LINE__); + + return 0; + +out_err3: + gpio_free(IRQ_QSC_PHONE_ACTIVE); + +out_err2: + iounmap(dpram); + +out_err1: + kfree(dpram); + +out: + return err; +} + + +static int dpram_recovery_suspend(struct device *pdev) +{ + return 0; +} + +static int dpram_recovery_resume(struct device *pdev) +{ + return 0; +} + +static const struct dev_pm_ops dpram_recovery_pm_ops = { + .suspend = dpram_recovery_suspend, + .resume = dpram_recovery_resume, +}; + +static struct platform_driver dpram_recovery_driver = { + .probe = dpram_recovery_probe, + .driver = { + .name = "dpram-recovery", + .pm = &dpram_recovery_pm_ops, + }, +}; + +static int __init dpram_recovery_init(void) +{ + return platform_driver_register(&dpram_recovery_driver); +} + +module_init(dpram_recovery_init); + +MODULE_LICENSE("GPL"); +MODULE_DESCRIPTION("DPRAM Device Driver for recovery"); diff --git a/drivers/dpram/raffaello/dpram_recovery.h b/drivers/dpram/raffaello/dpram_recovery.h new file mode 100644 index 0000000..38a76ae --- /dev/null +++ b/drivers/dpram/raffaello/dpram_recovery.h @@ -0,0 +1,132 @@ +#ifndef __DPRAM_RECOVERY_H__ +#define __DPRAM_RECOVERY_H__ + + + +/* interupt masks */ +#define MASK_CMD_FOTA_IMG_RECEIVE_READY_RESP 0x0100 +#define MASK_CMD_FOTA_IMG_SEND_RESP 0x0200 +#define MASK_CMD_FOTA_SEND_DONE_RESP 0x0300 +#define MASK_CMD_FOTA_UPDATE_START_RESP 0x0400 +#define MASK_CMD_FOTA_UPDATE_STATUS_IND 0x0500 +#define MASK_CMD_FOTA_UPDATE_END_IND 0x0C00 + +/* FORMAT */ +#define CMD_FOTA_IMG_RECEIVE_READY_REQ 0x9100 +#define CMD_FOTA_IMG_SEND_REQ 0x9200 +#define CMD_FOTA_SEND_DONE_REQ 0x9300 +#define CMD_FOTA_UPDATE_START_REQ 0x9400 +#define CMD_FOTA_UPDATE_STATUS_IND 0x9500 +#define CMD_FOTA_INIT_START_REQ 0x9A00 +#define CMD_FOTA_INIT_START_RES 0x9B00 +#define CMD_FOTA_UPDATE_END_IND 0x9C00 + +#define CMD_RETRY 0 +#define CMD_TRUE 1 +#define CMD_FALSE -1 + +#define CMD_DL_SEND_DONE_REQ 0x9600 +#define CMD_PHONE_BOOT_UPDATE 0x0001 +#define MASK_CMD_SEND_DONE_RESPONSE 0x0700 +#define MASK_CMD_STATUS_UPDATE_NOTIFICATION 0x0800 +#define MASK_CMD_UPDATE_DONE_NOTIFICATION 0x0900 +#define MASK_CMD_IMAGE_SEND_RESPONSE 0x0500 + +/* Result mask */ +#define MASK_CMD_RESULT_FAIL 0x0002 +#define MASK_CMD_RESULT_SUCCESS 0x0001 + +#define MASK_CMD_VALID 0x8000 +#define MASK_PDA_CMD 0x1000 +#define MASK_PHONE_CMD 0x2000 + +#define MAGIC_FODN 0x4E444F46 /* PDA initiate phone code */ +#define MAGIC_FOTA 0x41544C44 /* PDA initiate phone code */ +#define MAGIC_DMDL 0x444D444C +#define MAGIC_ALARMBOOT 0x00410042 + +/* DPRAM */ +#define DPRAM_BASE_ADDR S5P_PA_MODEMIF +#define DPRAM_MAGIC_CODE_SIZE 0x4 +#define DPRAM_PDA2PHONE_FORMATTED_START_ADDRESS (DPRAM_MAGIC_CODE_SIZE) +#define DPRAM_PHONE2PDA_INTERRUPT_ADDRESS (0x3FFE) +#define DPRAM_PDA2PHONE_INTERRUPT_ADDRESS (0x3FFC) +#define DPRAM_BUFFER_SIZE (DPRAM_PDA2PHONE_INTERRUPT_ADDRESS - DPRAM_PDA2PHONE_FORMATTED_START_ADDRESS) +#define BSP_DPRAM_BASE_SIZE 0x4000 /* 16KB DPRAM in Mirage */ +#define DPRAM_END_OF_ADDRESS (BSP_DPRAM_BASE_SIZE - 1) +#define DPRAM_INTERRUPT_SIZE 0x2 +#define DPRAM_INDEX_SIZE 0x2 +#define DELTA_PACKET_SIZE (0x4000 - 0x4 - 0x4) +#define WRITEIMG_HEADER_SIZE 8 +#define WRITEIMG_TAIL_SIZE 4 +#define WRITEIMG_BODY_SIZE (DPRAM_BUFFER_SIZE - WRITEIMG_HEADER_SIZE - WRITEIMG_TAIL_SIZE) +#define FODN_DEFAULT_WRITE_LEN WRITEIMG_BODY_SIZE +#define DPRAM_START_ADDRESS 0 +#define DPRAM_END_OF_ADDRESS (BSP_DPRAM_BASE_SIZE - 1) +#define DPRAM_SIZE BSP_DPRAM_BASE_SIZE + +/* ioctl commands */ +#define IOCTL_ST_FW_UPDATE _IO('D', 0x1) +#define IOCTL_CHK_STAT _IO('D', 0x2) +#define IOCTL_MOD_PWROFF _IO('D', 0x3) +#define IOCTL_WRITE_MAGIC_CODE _IO('D', 0x4) +#define IOCTL_ST_FW_DOWNLOAD _IO('D', 0x5) + +#define GPIO_QSC_INT GPIO_C210_DPRAM_INT_N +#define IRQ_QSC_INT GPIO_QSC_INT + +/* Common */ +#define TRUE 1 +#define FALSE 0 + +#define GPIO_IN 0 +#define GPIO_OUT 1 +#define GPIO_LOW 0 +#define GPIO_HIGH 1 + +#define START_INDEX 0x007F +#define END_INDEX 0x007E + +#define DPRAM_MODEM_MSG_SIZE 0x100 + +typedef struct { + unsigned int int2ap; + unsigned int int2msm; + unsigned int mifcon; + unsigned int mifpcon; + unsigned int msmintclr; + unsigned int dma_tx_adr; + unsigned int dma_rx_adr; +} IDPRAM_SFR; + +/* It is recommended that S5PC110 write data with half-word access on the interrupt port because +S5PC100 overwrites tha data in INT2AP if there are INT2AP and INT2MSM sharing the same word */ +#define IDPRAM_INT2MSM_MASK 0xFF + +#define IDPRAM_MIFCON_INT2APEN (1<<2) +#define IDPRAM_MIFCON_INT2MSMEN (1<<3) +#define IDPRAM_MIFCON_DMATXREQEN_0 (1<<16) +#define IDPRAM_MIFCON_DMATXREQEN_1 (1<<17) +#define IDPRAM_MIFCON_DMARXREQEN_0 (1<<18) +#define IDPRAM_MIFCON_DMARXREQEN_1 (1<<19) +#define IDPRAM_MIFCON_FIXBIT (1<<20) + +#define IDPRAM_MIFPCON_ADM_MODE (1<<6) /* mux / demux mode */ + +/* end */ + +struct dpram_firmware { + char *firmware; + int size; + int image_type; +}; + +struct stat_info { + int pct; + char msg[DPRAM_MODEM_MSG_SIZE]; +}; + +#define DPRAM_MODEM_DELTA_IMAGE 0 +#define DPRAM_MODEM_FULL_IMAGE 1 + +#endif /* __DPRAM_RECOVERY_H__ */ diff --git a/drivers/leds/Kconfig b/drivers/leds/Kconfig index 7cdcd46..ea556d6 100644 --- a/drivers/leds/Kconfig +++ b/drivers/leds/Kconfig @@ -528,6 +528,12 @@ config LEDS_TRIGGER_SLEEP help This turns LEDs on when the screen is off but the cpu still running. +config LEDS_TRIGGER_NOTIFICATION + tristate "Notification LED Trigger" + help + This allows LEDS to be controlled as a notification device. + If unsure, say Y. + comment "iptables trigger is under Netfilter config (LED target)" depends on LEDS_TRIGGERS diff --git a/drivers/leds/Makefile b/drivers/leds/Makefile index e538739..3e3945d 100644 --- a/drivers/leds/Makefile +++ b/drivers/leds/Makefile @@ -60,3 +60,4 @@ obj-$(CONFIG_LEDS_TRIGGER_BACKLIGHT) += ledtrig-backlight.o obj-$(CONFIG_LEDS_TRIGGER_GPIO) += ledtrig-gpio.o obj-$(CONFIG_LEDS_TRIGGER_DEFAULT_ON) += ledtrig-default-on.o obj-$(CONFIG_LEDS_TRIGGER_SLEEP) += ledtrig-sleep.o +obj-$(CONFIG_LEDS_TRIGGER_NOTIFICATION) += ledtrig-notification.o diff --git a/drivers/leds/ledtrig-notification.c b/drivers/leds/ledtrig-notification.c new file mode 100644 index 0000000..25cf3f5 --- /dev/null +++ b/drivers/leds/ledtrig-notification.c @@ -0,0 +1,364 @@ +/* + * LED notification trigger + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + */ + +#include <linux/module.h> +#include <linux/jiffies.h> +#include <linux/kernel.h> +#include <linux/init.h> +#include <linux/list.h> +#include <linux/spinlock.h> +#include <linux/device.h> +#include <linux/sysdev.h> +#include <linux/timer.h> +#include <linux/ctype.h> +#include <linux/leds.h> +#include <linux/slab.h> +#include "leds.h" +#include <linux/android_alarm.h> +#include <linux/wakelock.h> +#include <asm/mach/time.h> +#include <linux/hrtimer.h> +#include <linux/hrtimer.h> + +static struct wake_lock ledtrig_rtc_timer_wakelock; + +struct notification_trig_data { + int brightness_on; /* LED brightness during "on" period. + * (LED_OFF < brightness_on <= LED_FULL) + */ + unsigned long delay_on; /* milliseconds on */ + unsigned long delay_off; /* milliseconds off */ + unsigned long blink_cnt; /* number of blink times */ + unsigned long off_duration; /* blink stop duration */ + + unsigned long current_blink_cnt; /* current blink count */ + + struct timer_list timer; + struct alarm alarm; + struct wake_lock wakelock; +}; + +static int led_rtc_set_alarm(struct led_classdev *led_cdev, unsigned long msec) +{ + struct notification_trig_data *timer_data = led_cdev->trigger_data; + ktime_t expire; + ktime_t now; + + now = ktime_get_real(); + expire = ktime_add(now, ns_to_ktime((u64)msec*1000*1000)); + + alarm_start_range(&timer_data->alarm, expire, expire); + if(msec < 1500) { + /* If expire time is less than 1.5s keep a wake lock to prevent constant + * suspend fail. RTC alarm fails to suspend if the earliest expiration + * time is less than a second. Keep the wakelock just a jiffy more than + * the expire time to prevent wake lock timeout. */ + wake_lock_timeout(&timer_data->wakelock, (msec*HZ/1000)+1); + } + return 0; +} + +static void led_rtc_timer_function(struct alarm *alarm) +{ + struct notification_trig_data *timer_data = container_of(alarm, struct notification_trig_data, alarm); + + /* let led_timer_function do the actual work */ + mod_timer(&timer_data->timer, jiffies + 1); +} + +static void led_timer_function(unsigned long data) +{ + struct led_classdev *led_cdev = (struct led_classdev *) data; + struct notification_trig_data *timer_data = led_cdev->trigger_data; + unsigned long brightness; + unsigned long delay; + + if (!timer_data->delay_on || !timer_data->delay_off || !timer_data->blink_cnt) { + led_set_brightness(led_cdev, LED_OFF); + return; + } + + brightness = led_get_brightness(led_cdev); + if (!brightness) { + /* Time to switch the LED on. */ + brightness = timer_data->brightness_on; + delay = timer_data->delay_on; + } else { + /* Store the current brightness value to be able + * to restore it when the delay_off period is over. + */ + timer_data->brightness_on = brightness; + brightness = LED_OFF; + delay = timer_data->delay_off; + + if(timer_data->blink_cnt <= ++timer_data->current_blink_cnt) { + timer_data->current_blink_cnt = 0; + delay+=timer_data->off_duration; + } + } + + led_set_brightness(led_cdev, brightness); + + led_rtc_set_alarm(led_cdev, delay); +} + +static ssize_t led_delay_on_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ + struct led_classdev *led_cdev = dev_get_drvdata(dev); + struct notification_trig_data *timer_data = led_cdev->trigger_data; + + return sprintf(buf, "%lu\n", timer_data->delay_on); +} + +static ssize_t led_delay_on_store(struct device *dev, + struct device_attribute *attr, const char *buf, size_t size) +{ + struct led_classdev *led_cdev = dev_get_drvdata(dev); + struct notification_trig_data *timer_data = led_cdev->trigger_data; + int ret = -EINVAL; + char *after; + unsigned long state = simple_strtoul(buf, &after, 10); + size_t count = after - buf; + + if (isspace(*after)) + count++; + + if (count == size) { + if (timer_data->delay_on != state) { + /* the new value differs from the previous */ + timer_data->delay_on = state; + + /* deactivate previous settings */ + del_timer_sync(&timer_data->timer); + + mod_timer(&timer_data->timer, jiffies + 1); + } + ret = count; + } + + return ret; +} + +static ssize_t led_delay_off_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ + struct led_classdev *led_cdev = dev_get_drvdata(dev); + struct notification_trig_data *timer_data = led_cdev->trigger_data; + + return sprintf(buf, "%lu\n", timer_data->delay_off); +} + +static ssize_t led_delay_off_store(struct device *dev, + struct device_attribute *attr, const char *buf, size_t size) +{ + struct led_classdev *led_cdev = dev_get_drvdata(dev); + struct notification_trig_data *timer_data = led_cdev->trigger_data; + int ret = -EINVAL; + char *after; + unsigned long state = simple_strtoul(buf, &after, 10); + size_t count = after - buf; + + if (isspace(*after)) + count++; + + if (count == size) { + if (timer_data->delay_off != state) { + /* the new value differs from the previous */ + timer_data->delay_off = state; + + /* deactivate previous settings */ + del_timer_sync(&timer_data->timer); + + mod_timer(&timer_data->timer, jiffies + 1); + } + ret = count; + } + + return ret; +} + +static ssize_t led_blink_count_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ + struct led_classdev *led_cdev = dev_get_drvdata(dev); + struct notification_trig_data *timer_data = led_cdev->trigger_data; + + return sprintf(buf, "%lu\n", timer_data->blink_cnt); +} + +static ssize_t led_blink_count_store(struct device *dev, + struct device_attribute *attr, const char *buf, size_t size) +{ + struct led_classdev *led_cdev = dev_get_drvdata(dev); + struct notification_trig_data *timer_data = led_cdev->trigger_data; + int ret = -EINVAL; + char *after; + unsigned long state = simple_strtoul(buf, &after, 10); + size_t count = after - buf; + + if (isspace(*after)) + count++; + + if (count == size) { + if (timer_data->blink_cnt != state) { + /* the new value differs from the previous */ + timer_data->blink_cnt = state; + + /* deactivate previous settings */ + del_timer_sync(&timer_data->timer); + + mod_timer(&timer_data->timer, jiffies + 1); + } + ret = count; + } + + return ret; +} + +static ssize_t led_off_duration_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ + struct led_classdev *led_cdev = dev_get_drvdata(dev); + struct notification_trig_data *timer_data = led_cdev->trigger_data; + + return sprintf(buf, "%lu\n", timer_data->off_duration); +} + +static ssize_t led_off_duration_store(struct device *dev, + struct device_attribute *attr, const char *buf, size_t size) +{ + struct led_classdev *led_cdev = dev_get_drvdata(dev); + struct notification_trig_data *timer_data = led_cdev->trigger_data; + int ret = -EINVAL; + char *after; + unsigned long state = simple_strtoul(buf, &after, 10); + size_t count = after - buf; + + if (isspace(*after)) + count++; + + if (count == size) { + if (timer_data->off_duration != state) { + /* the new value differs from the previous */ + timer_data->off_duration = state; + + /* deactivate previous settings */ + del_timer_sync(&timer_data->timer); + + mod_timer(&timer_data->timer, jiffies + 1); + } + ret = count; + } + + return ret; +} + + +static DEVICE_ATTR(delay_on, 0777, led_delay_on_show, led_delay_on_store); +static DEVICE_ATTR(delay_off, 0777, led_delay_off_show, led_delay_off_store); +static DEVICE_ATTR(blink_count, 0777, led_blink_count_show, led_blink_count_store); +static DEVICE_ATTR(off_duration, 0777, led_off_duration_show, led_off_duration_store); + +static void notification_trig_activate(struct led_classdev *led_cdev) +{ + struct notification_trig_data *timer_data; + int rc; + + timer_data = kzalloc(sizeof(struct notification_trig_data), GFP_KERNEL); + if (!timer_data) + return; + + timer_data->brightness_on = led_get_brightness(led_cdev); + if (timer_data->brightness_on == LED_OFF) + timer_data->brightness_on = led_cdev->max_brightness; + led_cdev->trigger_data = timer_data; + + init_timer(&timer_data->timer); + timer_data->timer.function = led_timer_function; + timer_data->timer.data = (unsigned long) led_cdev; + + alarm_init(&timer_data->alarm, ANDROID_ALARM_RTC_WAKEUP, + led_rtc_timer_function); + wake_lock_init(&timer_data->wakelock, WAKE_LOCK_SUSPEND, "ledtrig_rtc_timer"); + + rc = device_create_file(led_cdev->dev, &dev_attr_delay_on); + if (rc) + goto err_out; + rc = device_create_file(led_cdev->dev, &dev_attr_delay_off); + if (rc) + goto err_out_delayon; + rc = device_create_file(led_cdev->dev, &dev_attr_blink_count); + if (rc) + goto err_attr_delay_off; + rc = device_create_file(led_cdev->dev, &dev_attr_off_duration); + if (rc) + goto err_attr_blink_count; + + /* If there is hardware support for blinking, start one + * user friendly blink rate chosen by the driver. + */ + if (led_cdev->blink_set) + led_cdev->blink_set(led_cdev, + &timer_data->delay_on, &timer_data->delay_off); + + return; +err_attr_blink_count: + device_remove_file(led_cdev->dev, &dev_attr_blink_count); +err_attr_delay_off: + device_remove_file(led_cdev->dev, &dev_attr_delay_off); +err_out_delayon: + device_remove_file(led_cdev->dev, &dev_attr_delay_on); +err_out: + led_cdev->trigger_data = NULL; + kfree(timer_data); +} + +static void notification_trig_deactivate(struct led_classdev *led_cdev) +{ + struct notification_trig_data *timer_data = led_cdev->trigger_data; + unsigned long on = 0, off = 0; + + if (timer_data) { + device_remove_file(led_cdev->dev, &dev_attr_delay_on); + device_remove_file(led_cdev->dev, &dev_attr_delay_off); + device_remove_file(led_cdev->dev, &dev_attr_blink_count); + device_remove_file(led_cdev->dev, &dev_attr_off_duration); + del_timer_sync(&timer_data->timer); + alarm_cancel(&timer_data->alarm); + wake_lock_destroy(&timer_data->wakelock); + kfree(timer_data); + } + + /* If there is hardware support for blinking, stop it */ + if (led_cdev->blink_set) + led_cdev->blink_set(led_cdev, &on, &off); +} + +static struct led_trigger notification_led_trigger = { + .name = "notification", + .activate = notification_trig_activate, + .deactivate = notification_trig_deactivate, +}; + +static int __init notification_trig_init(void) +{ + return led_trigger_register(¬ification_led_trigger); +} + +static void __exit notification_trig_exit(void) +{ + led_trigger_unregister(¬ification_led_trigger); +} + +module_init(notification_trig_init); +module_exit(notification_trig_exit); + +MODULE_DESCRIPTION("Notification LED trigger"); +MODULE_LICENSE("GPL"); diff --git a/drivers/leds/ledtrig-timer.c b/drivers/leds/ledtrig-timer.c index 328c64c..713c59c 100644 --- a/drivers/leds/ledtrig-timer.c +++ b/drivers/leds/ledtrig-timer.c @@ -11,6 +11,7 @@ * */ + #include <linux/module.h> #include <linux/kernel.h> #include <linux/init.h> @@ -19,6 +20,84 @@ #include <linux/leds.h> #include "leds.h" +#ifdef CONFIG_TARGET_LOCALE_NA +#define CONFIG_RTC_LEDTRIG_TIMER 1//chief.rtc.ledtrig +#endif /* CONFIG_TARGET_LOCALE_NA */ + + #ifdef CONFIG_TARGET_LOCALE_NA +#if defined(CONFIG_RTC_LEDTRIG_TIMER) +#include <linux/android_alarm.h> +#include <linux/wakelock.h> +#include <asm/mach/time.h> +#include <linux/hrtimer.h> +#include <linux/hrtimer.h> +#endif + +#if defined(CONFIG_RTC_LEDTRIG_TIMER) +static struct wake_lock ledtrig_rtc_timer_wakelock; +#endif +#endif /* CONFIG_TARGET_LOCALE_NA */ + +struct timer_trig_data { + int brightness_on; /* LED brightness during "on" period. + * (LED_OFF < brightness_on <= LED_FULL) + */ + unsigned long delay_on; /* milliseconds on */ + unsigned long delay_off; /* milliseconds off */ + struct timer_list timer; +#ifdef CONFIG_TARGET_LOCALE_NA +#if (CONFIG_RTC_LEDTRIG_TIMER==1) + struct alarm alarm; + struct wake_lock wakelock; +#elif (CONFIG_RTC_LEDTRIG_TIMER==2) + struct hrtimer hrtimer; +#endif +#endif /* CONFIG_TARGET_LOCALE_NA */ +}; + + +#ifdef CONFIG_TARGET_LOCALE_NA +#if (CONFIG_RTC_LEDTRIG_TIMER==1) +static int led_rtc_set_alarm(struct led_classdev *led_cdev, unsigned long msec) +{ + struct timer_trig_data *timer_data = led_cdev->trigger_data; + ktime_t expire; + ktime_t now; + + now = ktime_get_real(); + expire = ktime_add(now, ns_to_ktime((u64)msec*1000*1000)); + + alarm_start_range(&timer_data->alarm, expire, expire); + if(msec < 1500) { + /* If expire time is less than 1.5s keep a wake lock to prevent constant + * suspend fail. RTC alarm fails to suspend if the earliest expiration + * time is less than a second. Keep the wakelock just a jiffy more than + * the expire time to prevent wake lock timeout. */ + wake_lock_timeout(&timer_data->wakelock, (msec*HZ/1000)+1); + } + return 0; +} + +static void led_rtc_timer_function(struct alarm *alarm) +{ + struct timer_trig_data *timer_data = container_of(alarm, struct timer_trig_data, alarm); + + /* let led_timer_function do the actual work */ + mod_timer(&timer_data->timer, jiffies + 1); +} +#elif (CONFIG_RTC_LEDTRIG_TIMER==2) +extern int msm_pm_request_wakeup(struct hrtimer *timer); +static enum hrtimer_restart ledtrig_hrtimer_function(struct hrtimer *timer) +{ + struct timer_trig_data *timer_data = container_of(timer, struct timer_trig_data, hrtimer); + + /* let led_timer_function do the actual work */ + mod_timer(&timer_data->timer, jiffies + 1); +} +#endif +#endif /* CONFIG_TARGET_LOCALE_NA */ + + static ssize_t led_delay_on_show(struct device *dev, struct device_attribute *attr, char *buf) { diff --git a/drivers/media/video/mhl/sii9234.c b/drivers/media/video/mhl/sii9234.c index c728ea3..5408846 100644 --- a/drivers/media/video/mhl/sii9234.c +++ b/drivers/media/video/mhl/sii9234.c @@ -41,6 +41,7 @@ #include <linux/proc_fs.h> #include <linux/wakelock.h> #include <linux/earlysuspend.h> +#include <linux/hrtimer.h> #ifdef CONFIG_EXTCON #include <linux/extcon.h> #endif @@ -54,7 +55,8 @@ /* #define __CONFIG_MHL_SWING_LEVEL__ */ #define __CONFIG_SS_FACTORY__ #define __CONFIG_MHL_DEBUG__ -#if defined(CONFIG_MACH_T0) || defined(CONFIG_MACH_M3) +#if defined(CONFIG_MACH_T0) || defined(CONFIG_MACH_M3) \ + || defined(CONFIG_MACH_M0_DUOSCTC) # define __CONFIG_MHL_VER_1_2__ #else # define __CONFIG_MHL_VER_1_1__ @@ -576,54 +578,68 @@ void sii9234_tmds_offon_work(struct work_struct *work) } #endif -static int mhl_wake_toggle(struct sii9234_data *sii9234, - unsigned long high_period, unsigned long low_period) +/* pulse_timerfunc() * + * This function makes hrtimer be used for generating the wake pulse.* + * Usleep_range() cannot guarantee the exact timing. */ + +static enum hrtimer_restart pulse_timerfunc(struct hrtimer *timer) { int ret; + struct sii9234_data *sii9234 = dev_get_drvdata(sii9244_mhldev); + unsigned long width[] = { T_SRC_WAKE_PULSE_WIDTH_1, + T_SRC_WAKE_PULSE_WIDTH_1, T_SRC_WAKE_PULSE_WIDTH_2, + T_SRC_WAKE_PULSE_WIDTH_1, T_SRC_WAKE_PULSE_WIDTH_1, + T_SRC_WAKE_PULSE_WIDTH_1, T_SRC_WAKE_TO_DISCOVER }; + + if (unlikely(sii9234->wp_cnt >= 7)) { + sii9234->wp_cnt = 0; + sii9234->wake_pulse_completed = 1; + pr_info("sii9234: %s is finished!\n", __func__); + wake_up(&sii9234->wq_pulse); + return HRTIMER_NORESTART; + } - /* These bits are not documented. */ - ret = - mhl_tx_set_reg(sii9234, MHL_TX_DISC_CTRL7_REG, (1 << 7) | (1 << 6)); - if (ret < 0) - return ret; - - usleep_range(high_period * USEC_PER_MSEC, high_period * USEC_PER_MSEC); - - ret = - mhl_tx_clear_reg(sii9234, MHL_TX_DISC_CTRL7_REG, - (1 << 7) | (1 << 6)); - if (ret < 0) - return ret; - - usleep_range(low_period * USEC_PER_MSEC, low_period * USEC_PER_MSEC); - - return 0; + hrtimer_start(&sii9234->pulse_timer, + ktime_set(0, NSEC_PER_MSEC * width[sii9234->wp_cnt]), + HRTIMER_MODE_REL); + if (sii9234->wp_cnt % 2 == 0) { + ret = mhl_tx_clear_reg(sii9234, MHL_TX_DISC_CTRL7_REG, + (1 << 7) | (1 << 6)); + if (ret < 0) + return HRTIMER_NORESTART; + } else { + ret = mhl_tx_set_reg(sii9234, MHL_TX_DISC_CTRL7_REG, + (1 << 7) | (1 << 6)); + if (ret < 0) + return HRTIMER_NORESTART; + } + sii9234->wp_cnt++; + return HRTIMER_NORESTART; } - static int mhl_send_wake_pulses(struct sii9234_data *sii9234) { - int ret; - - ret = mhl_wake_toggle(sii9234, T_SRC_WAKE_PULSE_WIDTH_1, - T_SRC_WAKE_PULSE_WIDTH_1); - if (ret < 0) - return ret; - - ret = mhl_wake_toggle(sii9234, T_SRC_WAKE_PULSE_WIDTH_1, - T_SRC_WAKE_PULSE_WIDTH_2); - if (ret < 0) - return ret; - - ret = mhl_wake_toggle(sii9234, T_SRC_WAKE_PULSE_WIDTH_1, - T_SRC_WAKE_PULSE_WIDTH_1); - if (ret < 0) - return ret; - ret = mhl_wake_toggle(sii9234, T_SRC_WAKE_PULSE_WIDTH_1, - T_SRC_WAKE_TO_DISCOVER); + int ret; + sii9234->wp_cnt = 0; + sii9234->wake_pulse_completed = 0; + hrtimer_start(&sii9234->pulse_timer, + ktime_set(0, NSEC_PER_MSEC * T_SRC_WAKE_PULSE_WIDTH_1), + HRTIMER_MODE_REL); + ret = + mhl_tx_set_reg(sii9234, MHL_TX_DISC_CTRL7_REG, (1 << 7) | (1 << 6)); if (ret < 0) return ret; - + ret = wait_event_timeout(sii9234->wq_pulse, + sii9234->wake_pulse_completed == 1, + msecs_to_jiffies(T_WAIT_TIMEOUT_WAKE_PULSE)); + if (ret == 0) { + pr_err("[ERROR] %s time out!\n", __func__); + return -1; + } + if (sii9234->wake_pulse_completed != 1) { + pr_err("[ERROR] %s was not finished!\n", __func__); + return -1; + } return 0; } @@ -2483,7 +2499,7 @@ static int sii9234_30pin_reg_init_for_9290(struct sii9234_data *sii9234) ret = mhl_tx_write_reg(sii9234, 0xA1, 0xFC); if (ret < 0) return ret; -#ifdef CONFIG_MACH_P4NOTE +#ifdef CONFIG_MACH_P4NOTE ret = mhl_tx_write_reg(sii9234, 0xA3, 0xC0); /*output swing level*/ if (ret < 0) return ret; @@ -3581,6 +3597,7 @@ static ssize_t sysfs_check_mhl_command(struct class *class, struct class_attribute *attr, char *buf) { int size; + int ret; u8 sii_id = 0; struct sii9234_data *sii9234 = dev_get_drvdata(sii9244_mhldev); @@ -3590,7 +3607,11 @@ static ssize_t sysfs_check_mhl_command(struct class *class, if (sii9234->pdata->hw_reset) sii9234->pdata->hw_reset(); - mhl_tx_read_reg(sii9234, MHL_TX_IDH_REG, &sii_id); + ret = mhl_tx_read_reg(sii9234, MHL_TX_IDH_REG, &sii_id); + if (unlikely(ret < 0)) + pr_err("[ERROR] %s(): Failed to read register" + " MHL_TX_IDH_REG!\n", __func__); + pr_info("sii9234 : sel_show sii_id: %X\n", sii_id); if (sii9234->pdata->hw_onoff) @@ -4045,6 +4066,11 @@ static int __devinit sii9234_mhl_tx_i2c_probe(struct i2c_client *client, !defined(CONFIG_SAMSUNG_MHL_9290) is_mhl_power_state_on = sii9234_is_mhl_power_state_on; #endif + init_waitqueue_head(&sii9234->wq_pulse); + hrtimer_init(&sii9234->pulse_timer, CLOCK_MONOTONIC, HRTIMER_MODE_REL); + sii9234->pulse_timer.function = pulse_timerfunc; + sii9234->wp_cnt = 0; + sii9234->wake_pulse_completed = 0; return 0; diff --git a/drivers/media/video/mhl/sii9234_driver.h b/drivers/media/video/mhl/sii9234_driver.h index 437d053..25769da 100644 --- a/drivers/media/video/mhl/sii9234_driver.h +++ b/drivers/media/video/mhl/sii9234_driver.h @@ -61,6 +61,10 @@ #define T_SRC_WAKE_PULSE_WIDTH_2 60 #define T_SRC_WAKE_TO_DISCOVER 500 #define T_SRC_VBUS_CBUS_T0_STABLE 500 +#define T_WAIT_TIMEOUT_WAKE_PULSE (T_SRC_WAKE_PULSE_WIDTH_1 * 6 \ + + T_SRC_WAKE_PULSE_WIDTH_2 \ + + T_SRC_WAKE_TO_DISCOVER \ + + 150) #define T_SRC_CBUS_FLOAT 100 #define T_HPD_WIDTH 100 @@ -562,6 +566,10 @@ struct sii9234_data { #ifdef __CONFIG_TMDS_OFFON_WORKAROUND__ bool tmds_state; #endif + wait_queue_head_t wq_pulse; + bool wake_pulse_completed; + unsigned int wp_cnt; + struct hrtimer pulse_timer; }; #ifdef __MHL_NEW_CBUS_MSC_CMD__ diff --git a/drivers/mmc/card/block.c b/drivers/mmc/card/block.c index f49e92c..1c63296 100644 --- a/drivers/mmc/card/block.c +++ b/drivers/mmc/card/block.c @@ -1166,12 +1166,14 @@ static int mmc_blk_err_check(struct mmc_card *card, if ((!mmc_host_is_spi(card->host) && rq_data_dir(req) != READ) || (mq_mrq->packed_cmd == MMC_PACKED_WR_HDR)) { u32 status; +#ifndef CONFIG_WIMAX_CMC /* timeout value set 0x30000 : It works just SDcard case. * It means send CMD sequencially about 7.8sec. * If SDcard's data line stays low, timeout is about 4sec. * max timeout is up to 300ms */ u32 timeout = 0x30000; +#endif do { int err = get_card_status(card, &status, 5); if (err) { @@ -1184,6 +1186,10 @@ static int mmc_blk_err_check(struct mmc_card *card, * so make sure to check both the busy * indication and the card state. */ +#ifdef CONFIG_WIMAX_CMC + } while (!(status & R1_READY_FOR_DATA) || + (R1_CURRENT_STATE(status) == R1_STATE_PRG)); +#else /* Just SDcard case, decrease timeout */ if (mmc_card_sd(card)) timeout--; @@ -1198,6 +1204,7 @@ static int mmc_blk_err_check(struct mmc_card *card, req->rq_disk->disk_name); return MMC_BLK_DATA_ERR; } +#endif } if (brq->data.error) { @@ -1534,6 +1541,88 @@ no_packed: return 0; } +#ifdef CONFIG_WIMAX_CMC +static void mmc_blk_packed_hdr_wrq_prep(struct mmc_queue_req *mqrq, + struct mmc_card *card, + struct mmc_queue *mq, + u8 reqs) +{ + struct mmc_blk_request *brq = &mqrq->brq; + struct request *req = mqrq->req; + struct request *prq; + struct mmc_blk_data *md = mq->data; + bool do_rel_wr; + u32 *packed_cmd_hdr = mqrq->packed_cmd_hdr; + u8 i = 1; + + mqrq->packed_cmd = (rq_data_dir(req) == READ) ? + MMC_PACKED_WR_HDR : MMC_PACKED_WRITE; + mqrq->packed_blocks = 0; + mqrq->packed_fail_idx = -1; + + memset(packed_cmd_hdr, 0, sizeof(mqrq->packed_cmd_hdr)); + packed_cmd_hdr[0] = (reqs << 16) | + (((rq_data_dir(req) == READ) ? + PACKED_CMD_RD : PACKED_CMD_WR) << 8) | + PACKED_CMD_VER; + + + /* + * Argument for each entry of packed group + */ + list_for_each_entry(prq, &mqrq->packed_list, queuelist) { + do_rel_wr = mmc_req_rel_wr(prq) && (md->flags & MMC_BLK_REL_WR); + /* Argument of CMD23*/ + packed_cmd_hdr[(i * 2)] = (do_rel_wr ? MMC_CMD23_ARG_REL_WR : 0) | + blk_rq_sectors(prq); + /* Argument of CMD18 or CMD25 */ + packed_cmd_hdr[((i * 2)) + 1] = mmc_card_blockaddr(card) ? + blk_rq_pos(prq) : blk_rq_pos(prq) << 9; + mqrq->packed_blocks += blk_rq_sectors(prq); + i++; + } + + memset(brq, 0, sizeof(struct mmc_blk_request)); + brq->mrq.cmd = &brq->cmd; + brq->mrq.data = &brq->data; + brq->mrq.sbc = &brq->sbc; + brq->mrq.stop = &brq->stop; + + brq->sbc.opcode = MMC_SET_BLOCK_COUNT; + brq->sbc.arg = MMC_CMD23_ARG_PACKED | + ((rq_data_dir(req) == READ) ? 1 : mqrq->packed_blocks + 1); + brq->sbc.flags = MMC_RSP_R1 | MMC_CMD_AC; + + brq->cmd.opcode = MMC_WRITE_MULTIPLE_BLOCK; + brq->cmd.arg = blk_rq_pos(req); + if (!mmc_card_blockaddr(card)) + brq->cmd.arg <<= 9; + brq->cmd.flags = MMC_RSP_SPI_R1 | MMC_RSP_R1 | MMC_CMD_ADTC; + + brq->data.blksz = 512; + /* + * Write separately the packd command header only for packed read. + * In case of packed write, header is sent with blocks of data. + */ + brq->data.blocks = (rq_data_dir(req) == READ) ? + 1 : mqrq->packed_blocks + 1; + brq->data.flags |= MMC_DATA_WRITE; + + brq->stop.opcode = MMC_STOP_TRANSMISSION; + brq->stop.arg = 0; + brq->stop.flags = MMC_RSP_SPI_R1B | MMC_RSP_R1B | MMC_CMD_AC; + + mmc_set_data_timeout(&brq->data, card); + + brq->data.sg = mqrq->sg; + brq->data.sg_len = mmc_queue_map_sg(mq, mqrq); + + mqrq->mmc_active.mrq = &brq->mrq; + mqrq->mmc_active.err_check = mmc_blk_packed_err_check; + + mmc_queue_bounce_pre(mqrq); +} +#else static void mmc_blk_packed_hdr_wrq_prep(struct mmc_queue_req *mqrq, struct mmc_card *card, struct mmc_queue *mq) @@ -1612,7 +1701,7 @@ static void mmc_blk_packed_hdr_wrq_prep(struct mmc_queue_req *mqrq, mmc_queue_bounce_pre(mqrq); } - +#endif static void mmc_blk_packed_rrq_prep(struct mmc_queue_req *mqrq, struct mmc_card *card, struct mmc_queue *mq) @@ -1722,7 +1811,11 @@ static int mmc_blk_issue_packed_rd(struct mmc_queue *mq, ret = mmc_blk_chk_hdr_err(mq, status); if (ret) break; +#ifdef CONFIG_WIMAX_CMC + mmc_blk_packed_hdr_wrq_prep(mq_rq, card, mq, mq_rq->packed_num); +#else mmc_blk_packed_hdr_wrq_prep(mq_rq, card, mq); +#endif mmc_start_req(card->host, &mq_rq->mmc_active, NULL); } else { mmc_blk_packed_rrq_prep(mq_rq, card, mq); @@ -1762,9 +1855,14 @@ static int mmc_blk_issue_rw_rq(struct mmc_queue *mq, struct request *rqc) struct mmc_command cmd; #endif if (rqc) { +#ifdef CONFIG_WIMAX_CMC + if (reqs >= 2) + mmc_blk_packed_hdr_wrq_prep(mq->mqrq_cur, card, mq, reqs); +#else if (reqs >= packed_num) { mmc_blk_packed_hdr_wrq_prep(mq->mqrq_cur, card, mq); } +#endif else mmc_blk_rw_rq_prep(mq->mqrq_cur, card, 0, mq); areq = &mq->mqrq_cur->mmc_active; @@ -1920,22 +2018,36 @@ static int mmc_blk_issue_rw_rq(struct mmc_queue *mq, struct request *rqc) if (idx == i) { /* retry from error index */ mq_rq->packed_num -= idx; +#ifdef CONFIG_WIMAX_CMC + if (mq_rq->packed_num == 1) { + printk(KERN_ERR "SBRISSEN - I AM HERE\n"); + mq_rq->packed_cmd = MMC_PACKED_NONE; + mq_rq->packed_num = 0; + } +#endif mq_rq->req = prq; ret = 1; break; } +#ifndef CONFIG_WIMAX_CMC list_del_init(&prq->queuelist); +#endif spin_lock_irq(&md->lock); __blk_end_request(prq, 0, blk_rq_bytes(prq)); spin_unlock_irq(&md->lock); i++; } +#ifdef CONFIG_WIMAX_CMC + if (idx == -1) + mq_rq->packed_num = 0; +#else if (mq_rq->packed_num == MMC_PACKED_N_SINGLE) { prq = list_entry_rq(mq_rq->packed_list.next); list_del_init(&prq->queuelist); mq_rq->packed_cmd = MMC_PACKED_NONE; mq_rq->packed_num = MMC_PACKED_N_ZERO; } +#endif break; } else { spin_lock_irq(&md->lock); @@ -2015,7 +2127,11 @@ static int mmc_blk_issue_rw_rq(struct mmc_queue *mq, struct request *rqc) mmc_blk_rw_rq_prep(mq_rq, card, disable_multi, mq); mmc_start_req(card->host, &mq_rq->mmc_active, NULL); } else { +#ifdef CONFIG_WIMAX_CMC + mmc_blk_packed_hdr_wrq_prep(mq_rq, card, mq, mq_rq->packed_num); +#else mmc_blk_packed_hdr_wrq_prep(mq_rq, card, mq); +#endif mmc_start_req(card->host, &mq_rq->mmc_active, NULL); if (mq_rq->packed_cmd == MMC_PACKED_WR_HDR) { if (mmc_blk_issue_packed_rd(mq, mq_rq)) @@ -2478,6 +2594,10 @@ static int mmc_blk_probe(struct mmc_card *card) printk(KERN_INFO "%s: %s %s %s %s\n", md->disk->disk_name, mmc_card_id(card), mmc_card_name(card), cap_str, md->read_only ? "(ro)" : ""); +#ifdef CONFIG_WIMAX_CMC + if (mmc_blk_alloc_parts(card, md)) + goto out; +#endif mmc_set_drvdata(card, md); mmc_fixup_device(card, blk_fixups); diff --git a/drivers/mmc/core/core.c b/drivers/mmc/core/core.c index ddd6d50..8252d44 100644 --- a/drivers/mmc/core/core.c +++ b/drivers/mmc/core/core.c @@ -275,12 +275,22 @@ static void mmc_wait_for_req_done(struct mmc_host *host, /* if card is mmc type and nonremovable, and there are erros after issuing r/w command, then init eMMC and mshc */ +#ifdef CONFIG_WIMAX_CMC + if (((host->card) && mmc_card_mmc(host->card) && \ + (host->caps & MMC_CAP_NONREMOVABLE)) && \ + (mrq->cmd->error == -ENOTRECOVERABLE || \ + ((mrq->cmd->opcode == 17 || mrq->cmd->opcode == 18 || \ + mrq->cmd->opcode == 24 || mrq->cmd->opcode == 25) && \ + ((mrq->data->error) || mrq->cmd->error || \ + (mrq->sbc && mrq->sbc->error))))) { +#else if (((host->card) && mmc_card_mmc(host->card) && \ (host->caps & MMC_CAP_NONREMOVABLE)) && \ (mrq->cmd->error == -ENOTRECOVERABLE || \ ((mrq->cmd->opcode == 17 || mrq->cmd->opcode == 18) && \ ((mrq->data->error) || mrq->cmd->error || \ (mrq->sbc && mrq->sbc->error))))) { +#endif int rt_err = -1,count = 3; printk(KERN_ERR "%s: it occurs a critical error on eMMC " @@ -2440,6 +2450,7 @@ int mmc_suspend_host(struct mmc_host *host) wake_unlock(&host->detect_wake_lock); mmc_flush_scheduled_work(); if (mmc_try_claim_host(host)) { +#ifndef CONFIG_WIMAX_CMC u32 status; u32 count=300000; /* up to 300ms */ @@ -2453,7 +2464,9 @@ int mmc_suspend_host(struct mmc_host *host) "flushing emmc's cache\n", mmc_hostname(host),ret); } +#endif err = mmc_cache_ctrl(host, 0); +#ifndef CONFIG_WIMAX_CMC /* to make sure that emmc is not working. should check emmc's state */ @@ -2469,6 +2482,7 @@ int mmc_suspend_host(struct mmc_host *host) count--; } while (count && R1_CURRENT_STATE(status) == 7); } +#endif mmc_do_release_host(host); } else { err = -EBUSY; diff --git a/drivers/mmc/core/host.c b/drivers/mmc/core/host.c index 3664c49..7966957 100644 --- a/drivers/mmc/core/host.c +++ b/drivers/mmc/core/host.c @@ -53,6 +53,7 @@ static DEFINE_IDR(mmc_host_idr); static DEFINE_SPINLOCK(mmc_host_lock); #ifdef CONFIG_MMC_CLKGATE +#ifndef CONFIG_WIMAX_CMC static ssize_t clkgate_delay_show(struct device *dev, struct device_attribute *attr, char *buf) { @@ -74,6 +75,7 @@ static ssize_t clkgate_delay_store(struct device *dev, spin_unlock_irqrestore(&host->clk_lock, flags); return count; } +#endif /* * Enabling clock gating will make the core call out to the host * once up and once down when it performs a request or card operation @@ -108,10 +110,14 @@ static void mmc_host_clk_gate_delayed(struct mmc_host *host) if (!host->clk_requests) { spin_unlock_irqrestore(&host->clk_lock, flags); /* wait only when clk_gate_delay is 0 */ +#ifdef CONFIG_WIMAX_CMC if (!host->clkgate_delay) { +#endif tick_ns = DIV_ROUND_UP(1000000000, freq); ndelay(host->clk_delay * tick_ns); +#ifdef CONFIG_WIMAX_CMC } +#endif } else { /* New users appeared while waiting for this work */ spin_unlock_irqrestore(&host->clk_lock, flags); @@ -135,9 +141,13 @@ static void mmc_host_clk_gate_delayed(struct mmc_host *host) */ static void mmc_host_clk_gate_work(struct work_struct *work) { +#ifdef CONFIG_WIMAX_CMC + struct mmc_host *host = container_of(work, struct mmc_host, + clk_gate_work); +#else struct mmc_host *host = container_of(work, struct mmc_host, clk_gate_work.work); - +#endif mmc_host_clk_gate_delayed(host); } @@ -152,9 +162,10 @@ static void mmc_host_clk_gate_work(struct work_struct *work) void mmc_host_clk_hold(struct mmc_host *host) { unsigned long flags; - +#ifndef CONFIG_WIMAX_CMC /* cancel any clock gating work scheduled by mmc_host_clk_release() */ cancel_delayed_work_sync(&host->clk_gate_work); +#endif mutex_lock(&host->clk_gate_mutex); spin_lock_irqsave(&host->clk_lock, flags); if (host->clk_gated) { @@ -204,9 +215,12 @@ void mmc_host_clk_release(struct mmc_host *host) host->clk_requests--; if (mmc_host_may_gate_card(host->card) && !host->clk_requests) +#ifdef CONFIG_WIMAX_CMC + queue_work(system_nrt_wq, &host->clk_gate_work); +#else queue_delayed_work(system_nrt_wq, &host->clk_gate_work, msecs_to_jiffies(host->clkgate_delay)); - +#endif spin_unlock_irqrestore(&host->clk_lock, flags); } @@ -239,13 +253,19 @@ static inline void mmc_host_clk_init(struct mmc_host *host) host->clk_requests = 0; /* Hold MCI clock for 8 cycles by default */ host->clk_delay = 8; +#ifndef CONFIG_WIMAX_CMC /* * Default clock gating delay is 0ms to avoid wasting power. * This value can be tuned by writing into sysfs entry. */ host->clkgate_delay = 3; +#endif host->clk_gated = false; +#ifdef CONFIG_WIMAX_CMC + INIT_WORK(&host->clk_gate_work, mmc_host_clk_gate_work); +#else INIT_DELAYED_WORK(&host->clk_gate_work, mmc_host_clk_gate_work); +#endif spin_lock_init(&host->clk_lock); mutex_init(&host->clk_gate_mutex); } @@ -260,14 +280,18 @@ static inline void mmc_host_clk_exit(struct mmc_host *host) * Wait for any outstanding gate and then make sure we're * ungated before exiting. */ +#ifdef CONFIG_WIMAX_CMC + if (cancel_work_sync(&host->clk_gate_work)) +#else if (cancel_delayed_work_sync(&host->clk_gate_work)) +#endif mmc_host_clk_gate_delayed(host); if (host->clk_gated) mmc_host_clk_hold(host); /* There should be only one user now */ WARN_ON(host->clk_requests > 1); } - +#ifndef CONFIG_WIMAX_CMC static inline void mmc_host_clk_sysfs_init(struct mmc_host *host) { host->clkgate_delay_attr.show = clkgate_delay_show; @@ -279,7 +303,7 @@ static inline void mmc_host_clk_sysfs_init(struct mmc_host *host) pr_err("%s: Failed to create clkgate_delay sysfs entry\n", mmc_hostname(host)); } - +#endif #else static inline void mmc_host_clk_init(struct mmc_host *host) @@ -384,7 +408,9 @@ int mmc_add_host(struct mmc_host *host) mmc_add_host_debugfs(host); #endif +#ifndef CONFIG_WIMAX_CMC mmc_host_clk_sysfs_init(host); +#endif mmc_start_host(host); if (!(host->pm_flags & MMC_PM_IGNORE_PM_NOTIFY)) diff --git a/drivers/mmc/core/host.h b/drivers/mmc/core/host.h index 08a7852..df7d2cd 100644 --- a/drivers/mmc/core/host.h +++ b/drivers/mmc/core/host.h @@ -12,6 +12,26 @@ #define _MMC_CORE_HOST_H #include <linux/mmc/host.h> +#if defined(CONFIG_MMC_CLKGATE) +void mmc_host_clk_hold(struct mmc_host *host); +void mmc_host_clk_release(struct mmc_host *host); +unsigned int mmc_host_clk_rate(struct mmc_host *host); + +#else +static inline void mmc_host_clk_hold(struct mmc_host *host) +{ +} + +static inline void mmc_host_clk_release(struct mmc_host *host) +{ +} + +static inline unsigned int mmc_host_clk_rate(struct mmc_host *host) +{ + return host->ios.clock; +} +#endif + int mmc_register_host_class(void); void mmc_unregister_host_class(void); void mmc_host_deeper_disable(struct work_struct *work); diff --git a/drivers/mmc/core/mmc.c b/drivers/mmc/core/mmc.c index 506a4e3..1622bbb 100644 --- a/drivers/mmc/core/mmc.c +++ b/drivers/mmc/core/mmc.c @@ -30,10 +30,12 @@ #else /* For debugging about ext_csd register value */ #if 0 +#ifndef CONFIG_WIMAX_CMC #define MMC_CHECK_EXT_CSD #endif #endif #endif +#endif /* * If moviNAND VHX 4.41 device @@ -216,7 +218,7 @@ static int mmc_decode_csd(struct mmc_card *card) return 0; } -#if defined(MMC_CHECK_EXT_CSD) +#if defined(MMC_CHECK_EXT_CSD) && !defined(CONFIG_WIMAX_CMC) /* For debugging about ext_csd register value */ static u8 *ext_csd_backup; static void mmc_error_ext_csd(struct mmc_card *card, u8 *ext_csd, @@ -340,7 +342,7 @@ static int mmc_get_ext_csd(struct mmc_card *card, u8 **new_ext_csd) } else *new_ext_csd = ext_csd; -#if defined(MMC_CHECK_EXT_CSD) +#if defined(MMC_CHECK_EXT_CSD) && !defined(CONFIG_WIMAX_CMC) /* For debugging about ext_csd register value */ mmc_error_ext_csd(card, ext_csd, 1, 0); #endif @@ -369,7 +371,7 @@ static int mmc_read_ext_csd(struct mmc_card *card, u8 *ext_csd) "version %d\n", mmc_hostname(card->host), card->ext_csd.raw_ext_csd_structure); err = -EINVAL; -#if defined(MMC_CHECK_EXT_CSD) +#if defined(MMC_CHECK_EXT_CSD) && !defined(CONFIG_WIMAX_CMC) /* For debugging about ext_csd register value */ mmc_error_ext_csd(card, ext_csd, 0, EXT_CSD_STRUCTURE); #endif @@ -386,7 +388,7 @@ static int mmc_read_ext_csd(struct mmc_card *card, u8 *ext_csd) printk(KERN_ERR "%s: unrecognised EXT_CSD revision %d\n", mmc_hostname(card->host), card->ext_csd.rev); err = -EINVAL; -#if defined(MMC_CHECK_EXT_CSD) +#if defined(MMC_CHECK_EXT_CSD) && !defined(CONFIG_WIMAX_CMC) /* For debugging about ext_csd register value */ mmc_error_ext_csd(card, ext_csd, 0, EXT_CSD_REV); #endif @@ -409,6 +411,35 @@ static int mmc_read_ext_csd(struct mmc_card *card, u8 *ext_csd) mmc_card_set_blockaddr(card); } card->ext_csd.raw_card_type = ext_csd[EXT_CSD_CARD_TYPE]; +#ifdef CONFIG_WIMAX_CMC + switch (ext_csd[EXT_CSD_CARD_TYPE] & EXT_CSD_CARD_TYPE_MASK) { + case EXT_CSD_CARD_TYPE_DDR_52 | EXT_CSD_CARD_TYPE_52 | + EXT_CSD_CARD_TYPE_26: + card->ext_csd.hs_max_dtr = 52000000; + card->ext_csd.card_type = EXT_CSD_CARD_TYPE_DDR_52; + break; + case EXT_CSD_CARD_TYPE_DDR_1_2V | EXT_CSD_CARD_TYPE_52 | + EXT_CSD_CARD_TYPE_26: + card->ext_csd.hs_max_dtr = 52000000; + card->ext_csd.card_type = EXT_CSD_CARD_TYPE_DDR_1_2V; + break; + case EXT_CSD_CARD_TYPE_DDR_1_8V | EXT_CSD_CARD_TYPE_52 | + EXT_CSD_CARD_TYPE_26: + card->ext_csd.hs_max_dtr = 52000000; + card->ext_csd.card_type = EXT_CSD_CARD_TYPE_DDR_1_8V; + break; + case EXT_CSD_CARD_TYPE_52 | EXT_CSD_CARD_TYPE_26: + card->ext_csd.hs_max_dtr = 52000000; + break; + case EXT_CSD_CARD_TYPE_26: + card->ext_csd.hs_max_dtr = 26000000; + break; + default: + /* MMC v4 spec says this cannot happen */ + printk(KERN_WARNING "%s: card is mmc v4 but doesn't " + "support any high-speed modes.\n", + mmc_hostname(card->host)); +#else if (card->host->caps2 & MMC_CAP2_HS200) { switch (ext_csd[EXT_CSD_CARD_TYPE] & EXT_CSD_CARD_TYPE_MASK) { case EXT_CSD_CARD_TYPE_SDR_ALL: @@ -507,6 +538,7 @@ static int mmc_read_ext_csd(struct mmc_card *card, u8 *ext_csd) goto out; #endif } +#endif } card->ext_csd.raw_s_a_timeout = ext_csd[EXT_CSD_S_A_TIMEOUT]; @@ -608,12 +640,12 @@ static int mmc_read_ext_csd(struct mmc_card *card, u8 *ext_csd) card->host->card = card; movi_ver_check = mmc_start_movi_smart(card); } - +#ifndef CONFIG_WIMAX_CMC /* enable discard feature if emmc is 4.41+ moviNand */ if ((ext_csd[EXT_CSD_VENDOR_SPECIFIC_FIELD + 0] & 0x1) && (card->cid.manfid == 0x15)) card->ext_csd.feature_support |= MMC_DISCARD_FEATURE; - +#endif /* enable PON feature if moviNAND VHX/VMX devices */ if (CHECK_MOVI_PON_SUPPORT) { if ((movi_ver_check & MMC_MOVI_VER_VHX0) && @@ -890,6 +922,7 @@ static int mmc_select_powerclass(struct mmc_card *card, return err; } +#ifndef CONFIG_WIMAX_CMC /* * Selects the desired buswidth and switch to the HS200 mode * if bus width set without error @@ -962,7 +995,7 @@ static int mmc_select_hs200(struct mmc_card *card) err: return err; } - +#endif /* * Handle the detection and initialisation of a card. * @@ -1076,7 +1109,7 @@ static int mmc_init_card(struct mmc_host *host, u32 ocr, /* * Fetch and process extended CSD. */ -#if defined(MMC_RETRY_READ_EXT_CSD) +#if defined(MMC_RETRY_READ_EXT_CSD) && !defined(CONFIG_WIMAX_CMC) { int i = 0; for (i = 0 ; i < 3 ; i++) { @@ -1180,6 +1213,11 @@ static int mmc_init_card(struct mmc_host *host, u32 ocr, card->ext_csd.generic_cmd6_time); if (err && err != -EBADMSG) goto free_card; +#ifdef CONFIG_WIMAX_CMC + if (!err) +#else + if (!err && (host->caps2 & MMC_CAP2_POWEROFF_NOTIFY)) +#endif /* * The err can be -EBADMSG or 0, * so check for success and update the flag @@ -1192,13 +1230,20 @@ static int mmc_init_card(struct mmc_host *host, u32 ocr, * Activate high speed (if supported) */ if (card->ext_csd.hs_max_dtr != 0) { +#ifndef CONFIG_WIMAX_CMC err = 0; if (card->ext_csd.hs_max_dtr > 52000000 && host->caps2 & MMC_CAP2_HS200) err = mmc_select_hs200(card); else if (host->caps & MMC_CAP_MMC_HIGHSPEED) +#else + err = mmc_switch(card, EXT_CSD_CMD_SET_NORMAL, + EXT_CSD_HS_TIMING, 1, card->ext_csd.generic_cmd6_time); +#endif +#ifndef CONFIG_WIMAX_CMC err = mmc_switch(card, EXT_CSD_CMD_SET_NORMAL, EXT_CSD_HS_TIMING, 1, 0); +#endif if (err && err != -EBADMSG) goto free_card; diff --git a/drivers/mmc/core/mmc_ops.c b/drivers/mmc/core/mmc_ops.c index 3cec450..e0c3c88 100644 --- a/drivers/mmc/core/mmc_ops.c +++ b/drivers/mmc/core/mmc_ops.c @@ -788,7 +788,11 @@ int mmc_send_hpi_cmd(struct mmc_card *card, u32 *status) opcode = card->ext_csd.hpi_cmd; if (opcode == MMC_STOP_TRANSMISSION) +#ifdef CONFIG_WIMAX_CMC + cmd.flags = MMC_RSP_R1 | MMC_CMD_AC; +#else cmd.flags = MMC_RSP_R1B | MMC_CMD_AC; +#endif else if (opcode == MMC_SEND_STATUS) cmd.flags = MMC_RSP_R1 | MMC_CMD_AC; diff --git a/drivers/mmc/core/sdio.c b/drivers/mmc/core/sdio.c index fa2a8b4..1e9c109 100644 --- a/drivers/mmc/core/sdio.c +++ b/drivers/mmc/core/sdio.c @@ -147,10 +147,14 @@ static int sdio_read_cccr(struct mmc_card *card, u32 ocr) } if (cccr_vsn >= SDIO_CCCR_REV_1_20) { +#ifdef CONFIG_WIMAX_CMC + ret = mmc_io_rw_direct(card, 0, 0, SDIO_CCCR_SPEED, 0, &data); +#else ret = mmc_io_rw_direct(card, 0, 0, SDIO_CCCR_SPEED, 0, &speed); +#endif if (ret) goto out; - +#ifndef CONFIG_WIMAX_CMC card->scr.sda_spec3 = 0; card->sw_caps.sd3_bus_mode = 0; card->sw_caps.sd3_drv_type = 0; @@ -201,6 +205,10 @@ static int sdio_read_cccr(struct mmc_card *card, u32 ocr) card->sw_caps.hs_max_dtr = 25000000; } } +#else + if (data & SDIO_SPEED_SHS) + card->cccr.high_speed = 1; +#endif } out: @@ -382,6 +390,7 @@ static unsigned mmc_sdio_get_max_clock(struct mmc_card *card) return max_dtr; } +#ifndef CONFIG_WIMAX_CMC static unsigned char host_drive_to_sdio_drive(int host_strength) { switch (host_strength) { @@ -569,7 +578,7 @@ out: return err; } - +#endif /* * Handle the detection and initialisation of a card. * @@ -636,6 +645,7 @@ static int mmc_sdio_init_card(struct mmc_host *host, u32 ocr, if (host->ops->init_card) host->ops->init_card(host, card); +#ifndef CONFIG_WIMAX_CMC /* * If the host and card support UHS-I mode request the card * to switch to 1.8V signaling level. No 1.8v signalling if @@ -659,7 +669,7 @@ static int mmc_sdio_init_card(struct mmc_host *host, u32 ocr, ocr &= ~R4_18V_PRESENT; host->ocr &= ~R4_18V_PRESENT; } - +#endif /* * For native busses: set card RCA and quit open drain mode. */ @@ -776,7 +786,30 @@ static int mmc_sdio_init_card(struct mmc_host *host, u32 ocr, err = sdio_disable_cd(card); if (err) goto remove; +#ifdef CONFIG_WIMAX_CMC + /* + * Switch to high-speed (if supported). + */ + err = sdio_enable_hs(card); + if (err > 0) + mmc_sd_go_highspeed(card); + else if (err) + goto remove; + + /* + * Change to the card's maximum speed. + */ + mmc_set_clock(host, mmc_sdio_get_max_clock(card)); + /* + * Switch to wider bus (if supported). + */ + err = sdio_enable_4bit_bus(card); + if (err > 0) + mmc_set_bus_width(card->host, MMC_BUS_WIDTH_4); + else if (err) + goto remove; +#else /* Initialization sequence for UHS-I cards */ /* Only if card supports 1.8v and UHS signaling */ if ((ocr & R4_18V_PRESENT) && card->sw_caps.sd3_bus_mode) { @@ -810,6 +843,7 @@ static int mmc_sdio_init_card(struct mmc_host *host, u32 ocr, else if (err) goto remove; } +#endif finish: if (!oldcard) host->card = card; @@ -911,6 +945,11 @@ out: static int mmc_sdio_suspend(struct mmc_host *host) { int i, err = 0; + +#ifdef CONFIG_WIMAX_CMC + if (host->pm_flags & MMC_PM_IGNORE_SUSPEND_RESUME) + return err; +#endif for (i = 0; i < host->card->sdio_funcs; i++) { struct sdio_func *func = host->card->sdio_func[i]; @@ -933,8 +972,7 @@ static int mmc_sdio_suspend(struct mmc_host *host) } } -#ifdef CONFIG_MACH_PX -#else +#ifndef CONFIG_MACH_PX if (!err && mmc_card_keep_power(host) && mmc_card_wake_sdio_irq(host)) { mmc_claim_host(host); sdio_disable_wide(host->card); @@ -948,6 +986,11 @@ static int mmc_sdio_suspend(struct mmc_host *host) static int mmc_sdio_resume(struct mmc_host *host) { int i, err = 0; + +#ifdef CONFIG_WIMAX_CMC + if (host->pm_flags & MMC_PM_IGNORE_SUSPEND_RESUME) + return err; +#endif BUG_ON(!host); BUG_ON(!host->card); @@ -1299,3 +1342,66 @@ err: return err; } EXPORT_SYMBOL(sdio_reset_comm); + +#ifdef CONFIG_WIMAX_CMC +int cmc732_sdio_reset_comm(struct mmc_card *card) +{ + struct mmc_host *host = card->host; + u32 ocr; + int err; + printk("%s():\n",__func__); + cmc732_sdio_reset(host); + err = mmc_send_io_op_cond(host, 0, &ocr); + if (err) + goto err; +#if 1//refer to mmc_attach_sdio() + if (!host->index) + ocr |= 0x00000080; //correct cmc ocr to show support for 1.8v operation + host->ocr = mmc_select_voltage(host, ocr); + if (!host->index) + host->ocr = 0x8000;//lie to cmc card that 2.8v operation selected +#else + host->ocr = mmc_select_voltage(host, ocr); +#endif + if (!host->ocr) { + err = -EINVAL; + goto err; + } + err = mmc_send_io_op_cond(host, host->ocr, &ocr); + if (err) + goto err; + if (mmc_host_is_spi(host)) { + err = mmc_spi_set_crc(host, use_spi_crc); + if (err) + goto err; + } + if (!mmc_host_is_spi(host)) { + err = mmc_send_relative_addr(host, &card->rca); + if (err) + goto err; + mmc_set_bus_mode(host, MMC_BUSMODE_PUSHPULL); + } + if (!mmc_host_is_spi(host)) { + err = mmc_select_card(card); + if (err) + goto err; + } + err = sdio_enable_hs(card); + if (err) + goto err; + if (mmc_card_highspeed(card)) { + mmc_set_clock(host, 50000000); + } else { + mmc_set_clock(host, card->cis.max_dtr); + } + err = sdio_enable_wide(card); + if (err) + goto err; + return 0; +err: + printk("%s: Error resetting SDIO communications (%d)\n", + mmc_hostname(host), err); + return err; +} +EXPORT_SYMBOL(cmc732_sdio_reset_comm); +#endif diff --git a/drivers/mmc/core/sdio_ops.c b/drivers/mmc/core/sdio_ops.c index f087d87..42f7810 100644 --- a/drivers/mmc/core/sdio_ops.c +++ b/drivers/mmc/core/sdio_ops.c @@ -198,3 +198,27 @@ int sdio_reset(struct mmc_host *host) return ret; } +#ifdef CONFIG_WIMAX_CMC +int cmc732_sdio_reset(struct mmc_host *host) +{ + int ret; + u8 abort; + ret = mmc_io_rw_direct_host(host, 0, 0, SDIO_CCCR_ABORT, 0, &abort); + if (ret) + abort = 0x01; + else + abort |= 0x01; + ret = mmc_io_rw_direct_host(host, 1, 0, SDIO_CCCR_ABORT, abort, NULL); + ret = mmc_io_rw_direct_host(host, 0, 0, SDIO_CCCR_ABORT, 0, &abort); + abort &= 0xFE; + ret = mmc_io_rw_direct_host(host, 1, 0, SDIO_CCCR_ABORT, abort, NULL); + ret = mmc_io_rw_direct_host(host, 0, 0, SDIO_CCCR_ABORT, 0, &abort); + if (ret) + abort = 0x08; + else + abort |= 0x08; + ret = mmc_io_rw_direct_host(host, 1, 0, SDIO_CCCR_ABORT, abort, NULL); + return ret; +} +#endif + diff --git a/drivers/mmc/core/sdio_ops.h b/drivers/mmc/core/sdio_ops.h index 12a4d3a..ba07370 100644 --- a/drivers/mmc/core/sdio_ops.h +++ b/drivers/mmc/core/sdio_ops.h @@ -18,6 +18,7 @@ int mmc_io_rw_direct(struct mmc_card *card, int write, unsigned fn, int mmc_io_rw_extended(struct mmc_card *card, int write, unsigned fn, unsigned addr, int incr_addr, u8 *buf, unsigned blocks, unsigned blksz); int sdio_reset(struct mmc_host *host); +int cmc732_sdio_reset(struct mmc_host *host); #endif diff --git a/drivers/mmc/host/mshci-s3c.c b/drivers/mmc/host/mshci-s3c.c index 58670ca..2c890c9 100644 --- a/drivers/mmc/host/mshci-s3c.c +++ b/drivers/mmc/host/mshci-s3c.c @@ -488,6 +488,7 @@ static int __devinit mshci_s3c_probe(struct platform_device *pdev) if (pdata->cd_type == S3C_MSHCI_CD_PERMANENT) { host->quirks |= MSHCI_QUIRK_BROKEN_PRESENT_BIT; host->mmc->caps |= MMC_CAP_NONREMOVABLE; +#ifndef CONFIG_WIMAX_CMC if (pdata->int_power_gpio) { gpio_set_value(pdata->int_power_gpio, 1); s3c_gpio_cfgpin(pdata->int_power_gpio, @@ -495,6 +496,7 @@ static int __devinit mshci_s3c_probe(struct platform_device *pdev) s3c_gpio_setpull(pdata->int_power_gpio, S3C_GPIO_PULL_NONE); } +#endif } /* IF SD controller's WP pin donsn't connected with SD card and there @@ -511,12 +513,15 @@ static int __devinit mshci_s3c_probe(struct platform_device *pdev) if (pdata->cd_type == S3C_MSHCI_CD_GPIO && gpio_is_valid(pdata->ext_cd_gpio)) { +#ifdef CONFIG_WIMAX_CMC + gpio_request(pdata->ext_cd_gpio, "SDHCI EXT CD"); +#else ret = gpio_request(pdata->ext_cd_gpio, "MSHCI EXT CD"); if (ret) { dev_err(&pdev->dev, "cannot request gpio for card detect\n"); goto err_add_host; } - +#endif sc->ext_cd_gpio = pdata->ext_cd_gpio; sc->ext_cd_irq = gpio_to_irq(pdata->ext_cd_gpio); @@ -537,7 +542,9 @@ static int __devinit mshci_s3c_probe(struct platform_device *pdev) goto err_add_host; } +#ifndef CONFIG_WIMAX_CMC device_enable_async_suspend(dev); +#endif return 0; diff --git a/drivers/mmc/host/sdhci-s3c.c b/drivers/mmc/host/sdhci-s3c.c index 712c8c6..eba9825 100644 --- a/drivers/mmc/host/sdhci-s3c.c +++ b/drivers/mmc/host/sdhci-s3c.c @@ -608,6 +608,11 @@ static int __devinit sdhci_s3c_probe(struct platform_device *pdev) * transfers, not sure if this is a problem with this specific * SDHCI block, or a missing configuration that needs to be set. */ host->quirks |= SDHCI_QUIRK_NO_BUSY_IRQ; + +#ifdef CONFIG_WIMAX_CMC + /* This host supports the Auto CMD12 */ + host->quirks |= SDHCI_QUIRK_MULTIBLOCK_READ_ACMD12; +#endif if (pdata->cd_type == S3C_SDHCI_CD_NONE) host->quirks |= SDHCI_QUIRK_BROKEN_CARD_DETECTION; @@ -706,6 +711,10 @@ static int __devinit sdhci_s3c_probe(struct platform_device *pdev) pdata->ext_pdev(pdev); #endif } +#ifdef CONFIG_MACH_U1_NA_SPR + if (pdata->cd_type == S3C_SDHCI_CD_GPIO && pdata->ext_cd_init) + pdata->ext_cd_init(&sdhci_s3c_notify_change); +#endif if (pdata->cd_type == S3C_SDHCI_CD_GPIO && gpio_is_valid(pdata->ext_cd_gpio)) sdhci_s3c_setup_card_detect_gpio(sc); @@ -742,6 +751,10 @@ static int __devexit sdhci_s3c_remove(struct platform_device *pdev) if (pdata->cd_type == S3C_SDHCI_CD_EXTERNAL && pdata->ext_cd_cleanup) pdata->ext_cd_cleanup(&sdhci_s3c_notify_change); +#ifdef CONFIG_MACH_U1_NA_SPR + if (pdata->cd_type == S3C_SDHCI_CD_GPIO && pdata->ext_cd_cleanup) + pdata->ext_cd_cleanup(&sdhci_s3c_notify_change); +#endif if (sc->ext_cd_irq) free_irq(sc->ext_cd_irq, sc); @@ -792,9 +805,24 @@ static void sdhci_s3c_shutdown(struct platform_device *dev) static int sdhci_s3c_resume(struct platform_device *dev) { struct sdhci_host *host = platform_get_drvdata(dev); +#if defined(CONFIG_WIMAX_CMC)/* && defined(CONFIG_TARGET_LOCALE_NA)*/ + struct s3c_sdhci_platdata *pdata = dev->dev.platform_data; + u32 ier; +#endif int ret = 0; ret = sdhci_resume_host(host); + +#if defined(CONFIG_WIMAX_CMC)/* && defined(CONFIG_TARGET_LOCALE_NA)*/ + + + if (pdata->enable_intr_on_resume) { + ier = sdhci_readl(host, SDHCI_INT_ENABLE); + ier |= SDHCI_INT_CARD_INT; + sdhci_writel(host, ier, SDHCI_INT_ENABLE); + sdhci_writel(host, ier, SDHCI_SIGNAL_ENABLE); + } +#endif return ret; } diff --git a/drivers/net/wimax_cmc/Kconfig b/drivers/net/wimax_cmc/Kconfig index 16efe94..16efe94 100644..100755 --- a/drivers/net/wimax_cmc/Kconfig +++ b/drivers/net/wimax_cmc/Kconfig diff --git a/drivers/net/wimax_cmc/Makefile b/drivers/net/wimax_cmc/Makefile index e49f7fb..e49f7fb 100644..100755 --- a/drivers/net/wimax_cmc/Makefile +++ b/drivers/net/wimax_cmc/Makefile diff --git a/drivers/net/wimax_cmc/buffer.h b/drivers/net/wimax_cmc/buffer.h new file mode 100755 index 0000000..f37d902 --- /dev/null +++ b/drivers/net/wimax_cmc/buffer.h @@ -0,0 +1,75 @@ +/* + * buffer.h + * + * Used q_send for the control and data packet sending, uses the BUFFER_DESCRIPTOR + * q_received used for the control packet receive, data packet sent directly + */ +#ifndef _WIMAX_BUFFER_H +#define _WIMAX_BUFFER_H + +/* structures */ +struct buffer_descriptor { + struct list_head node; /* list node */ + void *buffer; /* allocated buffer: It is used for copying and transfer */ + u_long length; /* current data length */ + u_short type; /* buffer type (used for control buffers) */ +}; + +struct queue_info { + struct list_head head; /* list head */ + spinlock_t lock; /* protection */ +}; + +/****************************************************************************** + * queue_init_list -- Macro which will initialize a queue to NULL. + ******************************************************************************/ +#define queue_init_list(_L) ((_L).next = (_L).prev = NULL) + +/****************************************************************************** + * queue_empty -- Macro which checks to see if a queue is empty. + ******************************************************************************/ +#define queue_empty(_L) (queue_get_head((_L)) == NULL) + +/****************************************************************************** + * queue_get_head -- Macro which returns the head of the queue, but does not + * remove the head from the queue. + ******************************************************************************/ +#define queue_get_head(_L) ((struct list_head *)((_L).next)) + +/****************************************************************************** + * queue_remove_head -- Macro which removes the head of the head of queue. + ******************************************************************************/ +#define queue_remove_head(_L) \ +{ \ + struct list_head *h; \ + if ((h = (struct list_head *)(_L).next)) { /* then fix up our our list to point to next elem */ \ + if (!((_L).next = h->next)) /* rechain list pointer to next link */ \ + /* if the list pointer is null, null out the reverse link */ \ + (_L).prev = NULL; \ + } \ +} + +/****************************************************************************** + * queue_put_tail -- Macro which puts an element at the tail (end) of the queue. + ******************************************************************************/ +#define queue_put_tail(_L,_E) \ +{ \ + if ((_L).prev) { \ + ((struct list_head *)(_L).prev)->next = (struct list_head *)(&(_E)); \ + (_L).prev = (struct list_head *)(&(_E)); \ + } else \ + (_L).next = (_L).prev = (struct list_head *)(&(_E)); \ + (_E).next = NULL; \ +} + +/****************************************************************************** + * queue_pop_head -- Macro which will pop the head off of a queue (list), and + * return it (this differs only from queueremovehead only in the 1st line) + ******************************************************************************/ +#define queue_pop_head(_L) \ +{ \ + (struct list_head *) (_L).next; \ + queue_remove_head(_L); \ +} + +#endif /* _WIMAX_BUFFER_H */ diff --git a/drivers/net/wimax_cmc/control.c b/drivers/net/wimax_cmc/control.c new file mode 100755 index 0000000..b4abd60 --- /dev/null +++ b/drivers/net/wimax_cmc/control.c @@ -0,0 +1,264 @@ +/* + * control.c + * + * send and receive control packet and handle it + */ +#include "headers.h" + +u_int control_init(struct net_adapter *adapter) +{ + queue_init_list(adapter->ctl.q_received.head); + spin_lock_init(&adapter->ctl.q_received.lock); + + queue_init_list(adapter->ctl.apps.process_list); + spin_lock_init(&adapter->ctl.apps.lock); + + adapter->ctl.apps.ready = TRUE; + + return STATUS_SUCCESS; +} + +void control_remove(struct net_adapter *adapter) +{ + struct buffer_descriptor *dsc; + struct process_descriptor *process; + unsigned long flags; + /* Free the received control packets queue */ + while (!queue_empty(adapter->ctl.q_received.head)) { + /* queue is not empty */ + dump_debug("Freeing Control Receive Queue"); + dsc = (struct buffer_descriptor *) + queue_get_head(adapter->ctl.q_received.head); + if (!dsc) { + dump_debug("Fail...node is null"); + continue; + } + queue_remove_head(adapter->ctl.q_received.head); + if (dsc->buffer) + kfree(dsc->buffer); + if (dsc) + kfree(dsc); + } + + /* process list */ + if (adapter->ctl.apps.ready) { + if (!queue_empty(adapter->ctl.apps.process_list)) { + /* first time gethead needed to get the dsc nodes */ + process = (struct process_descriptor *)queue_get_head(adapter->ctl.apps.process_list); + spin_lock_irqsave(&adapter->ctl.apps.lock, flags); + while (process != NULL) { + if (process->irp) { + process->irp = FALSE; + wake_up_interruptible(&process->read_wait); + } + process = (struct process_descriptor *)process->node.next; + dump_debug("sangam dbg : waking processes"); + } + spin_unlock_irqrestore(&adapter->ctl.apps.lock, flags); + /* delay for the process release */ + msleep(100); + } + } + adapter->ctl.apps.ready = FALSE; +} + +/* add received packet to pending list */ +static void control_enqueue_buffer(struct net_adapter *adapter, + u_short type, void *buffer, u_long length) +{ + struct buffer_descriptor *dsc; + struct process_descriptor *process; + + /* Queue and wake read only if process exist. */ + process = process_by_type(adapter, type); + if (process) { + dsc = (struct buffer_descriptor *) + kmalloc(sizeof(struct buffer_descriptor), + GFP_ATOMIC); + if (dsc == NULL) { + dump_debug("dsc Memory Alloc Failure *****"); + return; + } + dsc->buffer = kmalloc(length, GFP_ATOMIC); + if (dsc->buffer == NULL) { + kfree(dsc); + dump_debug("dsc->buffer Memory Alloc Failure *****"); + return; + } + + memcpy(dsc->buffer, buffer, length); + /* fill out descriptor */ + dsc->length = length; + dsc->type = type; + /* add to pending list */ + queue_put_tail(adapter->ctl.q_received.head, dsc->node) + + if (process->irp) { + process->irp = FALSE; + wake_up_interruptible(&process->read_wait); + } + } else + dump_debug("Waiting process not found skip the packet"); +} + +/* receive control data */ +void control_recv(struct net_adapter *adapter, void *buffer, u_long length) +{ + struct eth_header *hdr; + + /* dump rx control frame */ + if (adapter->pdata->g_cfg->enable_dump_msg == 1) + dump_buffer("Control Rx", (u_char *)buffer + 12, length - 12); + + /* check halt flag */ + if (adapter->halted) + return; + + hdr = (struct eth_header *)buffer; + + /* not found, add to pending buffers list */ + spin_lock(&adapter->ctl.q_received.lock); + control_enqueue_buffer(adapter, hdr->type, buffer, length); + spin_unlock(&adapter->ctl.q_received.lock); +} + +u_int control_send(struct net_adapter *adapter, void *buffer, u_long length) +{ + if ((length + sizeof(struct hw_packet_header)) >= WIMAX_MAX_TOTAL_SIZE) + return STATUS_RESOURCES; + /* changed from SUCCESS return status */ + + return hw_send_data(adapter, buffer, length, CONTROL_PACKET); + +} + +struct process_descriptor *process_by_id(struct net_adapter *adapter, u_int id) +{ + struct process_descriptor *process; + + if (queue_empty(adapter->ctl.apps.process_list)) { + dump_debug("process_by_id: Empty process list"); + return NULL; + } + + /* first time gethead needed to get the dsc nodes */ + process = (struct process_descriptor *) + queue_get_head(adapter->ctl.apps.process_list); + while (process != NULL) { + if (process->id == id) /* process found */ + return process; + process = (struct process_descriptor *)process->node.next; + } + dump_debug("process_by_id: process not found"); + + return NULL; +} + +struct process_descriptor *process_by_type(struct net_adapter *adapter, + u_short type) +{ + struct process_descriptor *process; + + if (queue_empty(adapter->ctl.apps.process_list)) { + dump_debug("process_by_type: Empty process list"); + return NULL; + } + + /* first time gethead needed to get the dsc nodes */ + process = (struct process_descriptor *) + queue_get_head(adapter->ctl.apps.process_list); + while (process != NULL) { + if (process->type == type) /* process found */ + return process; + process = (struct process_descriptor *)process->node.next; + } + dump_debug("process_by_type: process not found"); + + return NULL; +} + +void remove_process(struct net_adapter *adapter, u_int id) +{ + struct process_descriptor *curElem; + struct process_descriptor *prevElem = NULL; + + if (queue_empty(adapter->ctl.apps.process_list)) + return; + + /* first time get head needed to get the dsc nodes */ + curElem = (struct process_descriptor *) + queue_get_head(adapter->ctl.apps.process_list); + + for ( ; curElem != NULL; prevElem = curElem, + curElem = (struct process_descriptor *) + curElem->node.next) { + if (curElem->id == id) { /* process found */ + if (prevElem == NULL) { + /* only one node present */ + (adapter->ctl.apps.process_list).next = + (((struct list_head *)curElem)->next); + if (!((adapter->ctl.apps.process_list).next)) { + /*rechain list pointer to next link*/ + dump_debug("sangam dbg first and only process delete"); + (adapter->ctl.apps.process_list).prev = NULL; + } + } else if (((struct list_head *)curElem)->next == + NULL) { + /* last node */ + dump_debug("sangam dbg only last packet"); + ((struct list_head *)prevElem)->next = NULL; + (adapter->ctl.apps.process_list).prev = + (struct list_head *)(prevElem); + } else { + /* middle node */ + dump_debug("sangam dbg middle node"); + ((struct list_head *)prevElem)->next = + ((struct list_head *)curElem)->next; + } + + kfree(curElem); + break; + } + } +} + +/* find buffer by buffer type */ +struct buffer_descriptor *buffer_by_type(struct list_head ListHead, + u_short type) +{ + struct buffer_descriptor *dsc; + + if (queue_empty(ListHead)) + return NULL; + + /* first time gethead needed to get the dsc nodes */ + dsc = (struct buffer_descriptor *)queue_get_head(ListHead); + while (dsc != NULL) { + if (dsc->type == type) /* process found */ + return dsc; + dsc = (struct buffer_descriptor *)dsc->node.next; + } + + return NULL; +} + +void dump_buffer(const char *desc, u_char *buffer, u_int len) +{ + char print_buf[256] = {0}; + char chr[8] = {0}; + int i; + + /* dump packets */ + u_char *b = buffer; + dump_debug("%s (%d) =>", desc, len); + + for (i = 0; i < len; i++) { + sprintf(chr, " %02x", b[i]); + strcat(print_buf, chr); + if (((i + 1) != len) && (i % 16 == 15)) { + dump_debug(print_buf); + memset(print_buf, 0x0, 256); + } + } + dump_debug(print_buf); +} diff --git a/drivers/net/wimax_cmc/ctl_types.h b/drivers/net/wimax_cmc/ctl_types.h new file mode 100755 index 0000000..0c3543e --- /dev/null +++ b/drivers/net/wimax_cmc/ctl_types.h @@ -0,0 +1,91 @@ +/* + * ctl_types.h + * + * Control types and definitions + */ +#ifndef _WIMAX_CTL_TYPES_H +#define _WIMAX_CTL_TYPES_H + +#ifndef FILE_DEVICE_UNKNOWN +#define FILE_DEVICE_UNKNOWN 0x89 +#endif + +/* Macro definition for defining IOCTL */ +#define CTL_CODE( DeviceType, Function, Method, Access ) \ +( \ + ((DeviceType) << 16) | ((Access) << 14) | ((Function) << 2) | (Method) \ +) +/* Define the method codes for how buffers are passed for I/O and FS controls */ +#define METHOD_BUFFERED 0 +#define METHOD_IN_DIRECT 1 +#define METHOD_OUT_DIRECT 2 +#define METHOD_NEITHER 3 + +/* + Define the access check value for any access + + The FILE_READ_ACCESS and FILE_WRITE_ACCESS constants are also defined in + ntioapi.h as FILE_READ_DATA and FILE_WRITE_DATA. The values for these + constants *MUST* always be in sync. +*/ +#define FILE_ANY_ACCESS 0 +#define FILE_READ_ACCESS (0x0001) +#define FILE_WRITE_ACCESS (0x0002) + +#define CONTROL_ETH_TYPE_WCM 0x0015 + +#define CONTROL_IOCTL_WRITE_REQUEST CTL_CODE(FILE_DEVICE_UNKNOWN, 0x820, METHOD_BUFFERED, FILE_ANY_ACCESS) +#define CONTROL_IOCTL_WIMAX_POWER_CTL CTL_CODE(FILE_DEVICE_UNKNOWN, 0x821, METHOD_BUFFERED, FILE_ANY_ACCESS) +#define CONTROL_IOCTL_WIMAX_MODE_CHANGE CTL_CODE(FILE_DEVICE_UNKNOWN, 0x838, METHOD_BUFFERED, FILE_ANY_ACCESS) +#define CONTROL_IOCTL_WIMAX_EEPROM_DOWNLOAD CTL_CODE(FILE_DEVICE_UNKNOWN, 0x839, METHOD_BUFFERED, FILE_ANY_ACCESS) +#define CONTROL_IOCTL_WIMAX_SLEEP_MODE CTL_CODE(FILE_DEVICE_UNKNOWN, 0x83A, METHOD_BUFFERED, FILE_ANY_ACCESS) +#define CONTROL_IOCTL_WIMAX_WRITE_REV CTL_CODE(FILE_DEVICE_UNKNOWN, 0x83B, METHOD_BUFFERED, FILE_ANY_ACCESS) +#define CONTROL_IOCTL_WIMAX_CHECK_CERT CTL_CODE(FILE_DEVICE_UNKNOWN, 0x83C, METHOD_BUFFERED, FILE_ANY_ACCESS) +#define CONTROL_IOCTL_WIMAX_CHECK_CAL CTL_CODE(FILE_DEVICE_UNKNOWN, 0x83D, METHOD_BUFFERED, FILE_ANY_ACCESS) + +#define MAX_APPLICATION_LEN 50 + +#define ETHERNET_ADDRESS_LENGTH 6 + +/* eth types for control message */ +enum { + ETHERTYPE_HIM = 0x1500, + ETHERTYPE_MC = 0x1501, + ETHERTYPE_DM = 0x1502, + ETHERTYPE_CT = 0x1503, + ETHERTYPE_DL = 0x1504, + ETHERTYPE_VSP = 0x1510, + ETHERTYPE_AUTH = 0x1521 +}; + +/* eth header structure */ +#pragma pack(1) +struct eth_header { + u_char dest[ETHERNET_ADDRESS_LENGTH]; + u_char src[ETHERNET_ADDRESS_LENGTH]; + u_short type; +}; +#pragma pack() + +/* process element managed by control type */ +struct process_descriptor { + struct list_head node; + wait_queue_head_t read_wait; + u_long id; + u_short type; + u_short irp; /* Used for the read thread indication */ +}; + +/* head structure for process element */ +struct ctl_app_descriptor { + struct list_head process_list; /* there could be undefined number of applications */ + spinlock_t lock; + u_char ready; +}; + +struct ctl_info { + struct ctl_app_descriptor apps; /* application device structure */ + struct queue_info q_received; /* pending queue */ +}; + +#endif /* _WIMAX_CTL_TYPES_H */ diff --git a/drivers/net/wimax_cmc/download.c b/drivers/net/wimax_cmc/download.c new file mode 100755 index 0000000..e51b210 --- /dev/null +++ b/drivers/net/wimax_cmc/download.c @@ -0,0 +1,227 @@ +/* + * download.c + * + * Firmware download (host booting) functions and definitions + */ +#include "headers.h" +#include "download.h" +#include "firmware.h" + +#include <linux/vmalloc.h> + +struct image_data g_wimax_image; + +int load_wimax_image(int mode) +{ + struct file *fp; + int read_size = 0; + + if (mode == AUTH_MODE) + fp = klib_fopen(WIMAX_LOADER_PATH, O_RDONLY, 0); /* download mode */ + else + fp = klib_fopen(WIMAX_IMAGE_PATH, O_RDONLY, 0); /* wimax mode */ + + if (fp) { + if (g_wimax_image.data == NULL) { /* check already allocated */ + g_wimax_image.data = (u_char *)vmalloc(MAX_WIMAXFW_SIZE); + + if (!g_wimax_image.data) { + dump_debug("Error: Memory alloc failure"); + klib_fclose(fp); + return STATUS_UNSUCCESSFUL; + } + } + + memset(g_wimax_image.data, 0, MAX_WIMAXFW_SIZE); + read_size = klib_flen_fcopy(g_wimax_image.data, MAX_WIMAXFW_SIZE, fp); + + g_wimax_image.size = read_size; + g_wimax_image.address = CMC732_WIMAX_ADDRESS; + g_wimax_image.offset = 0; + + klib_fclose(fp); + } else { + dump_debug("Error: WiMAX image file open failed"); + return STATUS_UNSUCCESSFUL; + } + + return STATUS_SUCCESS; +} + +void unload_wimax_image(void) +{ + if (g_wimax_image.data != NULL) { + dump_debug("Delete the Image Loaded"); + vfree(g_wimax_image.data); + g_wimax_image.data = NULL; + } +} + +u_char send_cmd_packet(struct net_adapter *adapter, u_short cmd_id) +{ + struct hw_packet_header *pkt_hdr; + struct wimax_msg_header *msg_hdr; + u_char tx_buf[CMD_MSG_TOTAL_LENGTH]; + int status = 0; + u_int offset; + u_int size; + + pkt_hdr = (struct hw_packet_header *)tx_buf; + pkt_hdr->id0 = 'W'; + pkt_hdr->id1 = 'C'; + pkt_hdr->length = be16_to_cpu(CMD_MSG_TOTAL_LENGTH); + + offset = sizeof(struct hw_packet_header); + msg_hdr = (struct wimax_msg_header *)(tx_buf + offset); + msg_hdr->type = be16_to_cpu(ETHERTYPE_DL); + msg_hdr->id = be16_to_cpu(cmd_id); + msg_hdr->length = be32_to_cpu(CMD_MSG_LENGTH); + + size = CMD_MSG_TOTAL_LENGTH; + + status = sd_send(adapter, tx_buf, size); + if (status != STATUS_SUCCESS) { + /* crc error or data error - set PCWRT '1' & send current type A packet again */ + dump_debug("hwSdioWrite : crc or data error"); + return status; + } + return status; +} + +u_char send_image_info_packet(struct net_adapter *adapter, u_short cmd_id) +{ + struct hw_packet_header *pkt_hdr; + struct wimax_msg_header *msg_hdr; + u_int image_info[4]; + u_char tx_buf[IMAGE_INFO_MSG_TOTAL_LENGTH]; + int status; + u_int offset; + u_int size; + + pkt_hdr = (struct hw_packet_header *)tx_buf; + pkt_hdr->id0 = 'W'; + pkt_hdr->id1 = 'C'; + pkt_hdr->length = be16_to_cpu(IMAGE_INFO_MSG_TOTAL_LENGTH); + + offset = sizeof(struct hw_packet_header); + msg_hdr = (struct wimax_msg_header *)(tx_buf + offset); + msg_hdr->type = be16_to_cpu(ETHERTYPE_DL); + msg_hdr->id = be16_to_cpu(cmd_id); + msg_hdr->length = be32_to_cpu(IMAGE_INFO_MSG_LENGTH); + + image_info[0] = 0; + image_info[1] = be32_to_cpu(g_wimax_image.size); + image_info[2] = be32_to_cpu(g_wimax_image.address); + image_info[3] = 0; + + offset += sizeof(struct wimax_msg_header); + memcpy(&(tx_buf[offset]), image_info, sizeof(image_info)); + + size = IMAGE_INFO_MSG_TOTAL_LENGTH; + status = sd_send(adapter, tx_buf, size); + + if (status != STATUS_SUCCESS) { + /* crc error or data error - set PCWRT '1' & send current type A packet again */ + dump_debug("hwSdioWrite : crc error"); + return status; + } + return status; +} + +u_char send_image_data_packet(struct net_adapter *adapter, u_short cmd_id) +{ + struct hw_packet_header *pkt_hdr; + struct image_data_payload *pImageDataPayload; + struct wimax_msg_header *msg_hdr; + u_char *tx_buf = NULL; + int status; + u_int len; + u_int offset; + u_int size; + + tx_buf = (u_char *)kmalloc(MAX_IMAGE_DATA_MSG_LENGTH, GFP_KERNEL); + if (tx_buf == NULL) { + dump_debug("MALLOC FAIL!!"); + return -1; + } + + pkt_hdr = (struct hw_packet_header *)tx_buf; + pkt_hdr->id0 = 'W'; + pkt_hdr->id1 = 'C'; + + offset = sizeof(struct hw_packet_header); + msg_hdr = (struct wimax_msg_header *)(tx_buf + offset); + msg_hdr->type = be16_to_cpu(ETHERTYPE_DL); + msg_hdr->id = be16_to_cpu(cmd_id); + + if (g_wimax_image.offset < (g_wimax_image.size - MAX_IMAGE_DATA_LENGTH)) + len = MAX_IMAGE_DATA_LENGTH; + else + len = g_wimax_image.size - g_wimax_image.offset; + + offset += sizeof(struct wimax_msg_header); + pImageDataPayload = (struct image_data_payload *)(tx_buf + offset); + pImageDataPayload->offset = be32_to_cpu(g_wimax_image.offset); + pImageDataPayload->size = be32_to_cpu(len); + + memcpy(pImageDataPayload->data, g_wimax_image.data + g_wimax_image.offset, len); + + size = len + 8; /* length of Payload offset + length + data */ + pkt_hdr->length = be16_to_cpu(CMD_MSG_TOTAL_LENGTH + size); + msg_hdr->length = be32_to_cpu(size); + + size = CMD_MSG_TOTAL_LENGTH + size; + + status = sd_send(adapter, tx_buf, size); + + if (status != STATUS_SUCCESS) { + /* crc error or data error - set PCWRT '1' & send current type A packet again */ + dump_debug("hwSdioWrite : crc error"); + kfree(tx_buf); + return status; + } + + g_wimax_image.offset += len; + + kfree(tx_buf); + + return status; +} + +/* used only during firmware download */ +u_int sd_send(struct net_adapter *adapter, u_char *buffer, u_int len) +{ + int nRet = 0; + + int nWriteIdx; + + len += (len & 1) ? 1 : 0; + + if (adapter->halted || adapter->removed) { + dump_debug("Halted Already"); + return STATUS_UNSUCCESSFUL; + } + + sdio_claim_host(adapter->func); + hwSdioWriteBankIndex(adapter, &nWriteIdx, &nRet); + + if(nRet || (nWriteIdx < 0) ) + return STATUS_UNSUCCESSFUL; + + sdio_writeb(adapter->func, (nWriteIdx + 1) % 15, SDIO_H2C_WP_REG, NULL); + + nRet = sdio_memcpy_toio(adapter->func, SDIO_TX_BANK_ADDR+(SDIO_BANK_SIZE * nWriteIdx)+4, buffer, len); + + if (nRet < 0) { + dump_debug("sd_send : error in sending packet!! nRet = %d",nRet); + } + + nRet = sdio_memcpy_toio(adapter->func, SDIO_TX_BANK_ADDR + (SDIO_BANK_SIZE * nWriteIdx), &len, 4); + + if (nRet < 0) { + dump_debug("sd_send : error in writing bank length!! nRet = %d",nRet); + } + sdio_release_host(adapter->func); + + return nRet; +} diff --git a/drivers/net/wimax_cmc/download.h b/drivers/net/wimax_cmc/download.h new file mode 100755 index 0000000..d46e6b6 --- /dev/null +++ b/drivers/net/wimax_cmc/download.h @@ -0,0 +1,56 @@ +/* + * download.h + * + * Firmware download (host booting) functions and definitions + */ +#ifndef _WIMAX_DOWNLOAD_H__ +#define _WIMAX_DOWNLOAD_H__ + +#define CMC732_RAM_START 0xC0000000 +#define CMC732_WIMAX_ADDRESS CMC732_RAM_START + +#define CMD_MSG_TOTAL_LENGTH 12 +#define IMAGE_INFO_MSG_TOTAL_LENGTH 28 +#define CMD_MSG_LENGTH 0 +#define IMAGE_INFO_MSG_LENGTH 16 +#define MAX_IMAGE_DATA_LENGTH 3564 +#define MAX_IMAGE_DATA_MSG_LENGTH 4096 + +#define FWDOWNLOAD_TIMEOUT 12000 +#define MAX_WIMAXFW_SIZE 2100000 + +/* used for host boot (firmware download) */ +enum { + MSG_DRIVER_OK_REQ = 0x5010, + MSG_DRIVER_OK_RESP = 0x6010, + MSG_IMAGE_INFO_REQ = 0x3021, + MSG_IMAGE_INFO_RESP = 0x4021, + MSG_IMAGE_DATA_REQ = 0x3022, + MSG_IMAGE_DATA_RESP = 0x4022, + MSG_RUN_REQ = 0x5014, + MSG_RUN_RESP = 0x6014 +}; + +struct image_data { + u_int size; + u_int address; + u_int offset; + struct mutex lock; + u_char *data; +}; + +struct image_data_payload { + u_int offset; + u_int size; + u_char data[MAX_IMAGE_DATA_LENGTH]; +}; + +int load_wimax_image(int mode); +void unload_wimax_image(void); + +u_char send_image_info_packet(struct net_adapter *adapter, u_short cmd_id); +u_char send_image_data_packet(struct net_adapter *adapter, u_short cmd_id); +u_char send_cmd_packet(struct net_adapter *adapter, u_short cmd_id); +u_int sd_send(struct net_adapter *adapter, u_char *buffer, u_int len); + +#endif /* _WIMAX_DOWNLOAD_H__ */ diff --git a/drivers/net/wimax_cmc/firmware.c b/drivers/net/wimax_cmc/firmware.c index d31eb8c..f4b6c9b 100644..100755 --- a/drivers/net/wimax_cmc/firmware.c +++ b/drivers/net/wimax_cmc/firmware.c @@ -5,7 +5,6 @@ * Firmware binary file is on the filesystem, read fild and send it through SDIO */ #include "firmware.h" -#include <linux/wimax/samsung/wimax732.h> #define SEEK_SET 0 #define SEEK_CUR 1 @@ -27,12 +26,8 @@ *************************************************************************/ struct file *klib_fopen( const char *filename, /*!< filename to open */ - /*!< O_RDONLY, O_WRONLY, O_RDWR, O_CREAT, - O_EXCL, O_TRUNC, O_APPEND, O_NONBLOCK, O_SYNC,...*/ - int flags, - /*!< file creation permisstion. S_IRxxx - S_IWxxx S_IXxxx (xxx=USR,GRP,OTH), S_IRWXx(x=U,G,O)*/ - int mode + int flags, /*!< O_RDONLY, O_WRONLY, O_RDWR, O_CREAT, O_EXCL, O_TRUNC, O_APPEND, O_NONBLOCK, O_SYNC, ... */ + int mode /*!< file creation permisstion. S_IRxxx S_IWxxx S_IXxxx (xxx=USR,GRP,OTH), S_IRWXx(x=U,G,O) */ ) { struct file *filp = filp_open(filename, flags, mode); @@ -83,8 +78,7 @@ int klib_fseek( if (pos < 0) pos = 0; - filp->f_pos = pos; - return pos; + return (filp->f_pos = pos); } else return -ENOENT; } @@ -110,17 +104,17 @@ klib_fread( mm_segment_t oldfs; if (filp == NULL) { - printk(KERN_INFO "filp == NULL\n"); + printk(" filp == NULL\n"); return -ENOENT; } if (filp->f_op->read == NULL) { - printk(KERN_INFO "filp->f_op->read == NULL\n"); + printk(" filp->f_op->read == NULL\n"); return -ENOSYS; } if (((filp->f_flags & O_ACCMODE) & O_RDONLY) != 0) { - printk(KERN_INFO "((filp->f_flags & O_ACCMODE) & O_RDONLY) != 0\n"); + printk(" ((filp->f_flags & O_ACCMODE) & O_RDONLY) != 0\n"); return -EACCES; } @@ -214,12 +208,12 @@ int klib_fwrite( mm_segment_t oldfs; if (filp == NULL) { - printk(KERN_INFO "filp == NULL\n"); + printk(" filp == NULL\n"); return -ENOENT; } if (filp->f_op->write == NULL) { - printk(KERN_INFO "filp->f_op->write == NULL\n"); + printk(" filp->f_op->write == NULL\n"); return -ENOSYS; } @@ -238,10 +232,9 @@ void s3c_bat_use_wimax(int onoff) if (!fp) pr_err("open fail"); - if (onoff) + if (onoff) klib_fwrite("1", 1, fp); else klib_fwrite("0", 1, fp); klib_fclose(fp); } -EXPORT_SYMBOL(s3c_bat_use_wimax); diff --git a/drivers/net/wimax_cmc/firmware.h b/drivers/net/wimax_cmc/firmware.h index 862d0d8..9629344 100644..100755 --- a/drivers/net/wimax_cmc/firmware.h +++ b/drivers/net/wimax_cmc/firmware.h @@ -9,7 +9,7 @@ #include <linux/fs.h> #include <linux/file.h> -#include <linux/uaccess.h> +#include <asm/uaccess.h> #define SEEK_SET 0 #define SEEK_CUR 1 @@ -18,12 +18,14 @@ /****************************************************************************** * Function Prototypes ******************************************************************************/ -struct file *klib_fopen(const char *filename, int flags, int mode); -void klib_fclose(struct file *filp); -int klib_fseek(struct file *filp, int offset, int whence); -int klib_fread(char *buf, int len, struct file *filp); -int klib_fgetc(struct file *filp); -int klib_flength(struct file *filp); -int klib_flen_fcopy(char *buf, int len, struct file *filp); -int klib_fwrite(char *buf, int len, struct file *filp); +struct file *klib_fopen (const char *filename, int flags, int mode); +void klib_fclose (struct file *filp); +int klib_fseek (struct file *filp, int offset, int whence); +int klib_fread (char *buf, int len, struct file *filp); +int klib_fgetc (struct file *filp); +int klib_flength (struct file *filp); +int klib_flen_fcopy (char *buf, int len, struct file *filp); +int klib_fwrite (char *buf, int len, struct file *filp); + +void s3c_bat_use_wimax(int onoff); #endif /* _WIMAX_FIRMWARE_H */ diff --git a/drivers/net/wimax_cmc/hardware.c b/drivers/net/wimax_cmc/hardware.c new file mode 100755 index 0000000..7540584 --- /dev/null +++ b/drivers/net/wimax_cmc/hardware.c @@ -0,0 +1,599 @@ +/* + * hardware.c + * + * gpio control functions (power on/off, init/deinit gpios) + * data tx and tx thread implemented. + */ +#include "headers.h" +#include "download.h" +#include "wimax_plat.h" + +#include <mach/gpio.h> +#include <plat/gpio-cfg.h> +#include <mach/hardware.h> +#include <plat/sdhci.h> +#include <plat/devs.h> +#include <linux/spinlock.h> + +#define WIMAX_POWER_SUCCESS 0 +#define WIMAX_ALREADY_POWER_ON -1 +#define WIMAX_PROBE_FAIL -2 +#define WIMAX_ALREADY_POWER_OFF -3 + + +static void wimax_hostwake_task(unsigned long data) +{ + struct net_adapter *adapter = (struct net_adapter *)data; + struct wimax_cfg *g_cfg = adapter->pdata->g_cfg; + + wake_lock_timeout(&g_cfg->wimax_wake_lock, 1 * HZ); + +} + +static irqreturn_t wimax_hostwake_isr(int irq, void *dev) +{ + struct net_adapter *adapter = (struct net_adapter *)dev; + tasklet_schedule(&adapter->hostwake_task); + return IRQ_HANDLED; +} +static int cmc732_setup_wake_irq(struct net_adapter *adapter) +{ + int rc = -EIO; + int irq; + + rc = gpio_request(WIMAX_INT, "gpio_wimax_int"); + if (rc < 0) { + dump_debug("%s: gpio %d request failed (%d)\n", + __func__, WIMAX_INT, rc); + return rc; + } + + rc = gpio_direction_input(WIMAX_INT); + if (rc < 0) { + dump_debug("%s: failed to set gpio %d as input (%d)\n", + __func__, WIMAX_INT, rc); + goto err_gpio_direction_input; + } + + irq = gpio_to_irq(WIMAX_INT); + + rc = request_irq(irq, wimax_hostwake_isr, IRQF_TRIGGER_FALLING, + "wimax_int", adapter); + if (rc < 0) { + dump_debug("%s: request_irq(%d) failed for gpio %d (%d)\n", + __func__, irq, + WIMAX_INT, rc); + goto err_request_irq; + } + + rc = enable_irq_wake(irq); + + if (rc < 0) { + dump_debug("%s: enable_irq_wake(%d) failed for gpio %d (%d)\n", + __func__, irq, + WIMAX_INT, rc); + goto err_enable_irq_wake; + } + + adapter->wake_irq = irq; + + tasklet_init(&adapter->hostwake_task, + wimax_hostwake_task, (unsigned long)adapter); + + goto done; +err_enable_irq_wake: + free_irq(irq, adapter); +err_request_irq: +err_gpio_direction_input: + gpio_free(WIMAX_INT); +done: + return rc; + +} +void cmc732_release_wake_irq(struct net_adapter *adapter) +{ + if (adapter->wake_irq) { + disable_irq_wake(adapter->wake_irq); + free_irq(adapter->wake_irq, adapter); + gpio_free(WIMAX_INT); + tasklet_kill(&adapter->hostwake_task); + } +} + + + +int hw_start(struct net_adapter *adapter) +{ + struct wimax_cfg *g_cfg = adapter->pdata->g_cfg; + + if (load_wimax_image(g_cfg->wimax_mode)) + return STATUS_UNSUCCESSFUL; + + adapter->download_complete = FALSE; + + if (adapter->downloading) { + sdio_claim_host(adapter->func); + send_cmd_packet(adapter, MSG_DRIVER_OK_REQ); + sdio_release_host(adapter->func); + switch (wait_event_interruptible_timeout + (adapter->download_event, + (adapter->download_complete == TRUE), + msecs_to_jiffies(FWDOWNLOAD_TIMEOUT))) { + case 0: + /* timeout */ + dump_debug("Error hw_start :" + "F/W Download timeout failed"); + adapter->halted = TRUE; + return STATUS_UNSUCCESSFUL; + case -ERESTARTSYS: + /* Interrupted by signal */ + dump_debug("Error hw_start : -ERESTARTSYS retry"); + return STATUS_UNSUCCESSFUL; + default: + /* normal condition check */ + if (adapter->removed == TRUE + || adapter->halted == TRUE) { + dump_debug("Error hw_start : " + " F/W Download surprise removed"); + return STATUS_UNSUCCESSFUL; + } + + /*Setup hostwake interrupt*/ + + if (cmc732_setup_wake_irq(adapter) < 0) + dump_debug("hw_start : " + " Error setting up wimax_int"); + + + break; + } + adapter->downloading = FALSE; + } + + return STATUS_SUCCESS; +} + +int hw_stop(struct net_adapter *adapter) +{ + adapter->halted = TRUE; + + + /* Stop Sdio Interface */ + sdio_claim_host(adapter->func); + sdio_release_irq(adapter->func); + sdio_disable_func(adapter->func); + sdio_release_host(adapter->func); + + /*Remove wakeup interrupt*/ + cmc732_release_wake_irq(adapter); + + return STATUS_SUCCESS; +} + +int hw_init(struct net_adapter *adapter) +{ + + /* set WIMAX_WAKEUP & WIMAX_IF_MODE0 */ + adapter->pdata->set_mode(); + + /* initilize hardware info structure */ + memset(&adapter->hw, 0x0, sizeof(struct hardware_info)); + + /* allocate sdio receive buffer once */ + if (adapter->hw.receive_buffer == NULL) { + dump_debug("Alloc ReceiveBuffer"); + /* the extra 8 bytes space required to copy ethernet header */ + adapter->hw.receive_buffer = kmalloc(SDIO_BUFFER_SIZE + 8, + GFP_ATOMIC | GFP_DMA); + if (adapter->hw.receive_buffer == NULL) { + dump_debug("kmalloc fail!!"); + return -ENOMEM; + } + } + + /* initialize sdio receive buffer */ + memset(adapter->hw.receive_buffer, 0x0, SDIO_BUFFER_SIZE + 8); + + /* For sending data and control packets */ + queue_init_list(adapter->hw.q_send.head); + spin_lock_init(&adapter->hw.q_send.lock); + + init_waitqueue_head(&adapter->download_event); + + return STATUS_SUCCESS; +} + +void hw_remove(struct net_adapter *adapter) +{ + struct buffer_descriptor *dsc; + + /* Free the pending data packets and control packets */ + spin_lock(&adapter->hw.q_send.lock); + while (!queue_empty(adapter->hw.q_send.head)) { + dump_debug("Freeing q_send"); + dsc = (struct buffer_descriptor *) + queue_get_head(adapter->hw.q_send.head); + if (!dsc) { + dump_debug("Fail...node is null"); + continue; + } + queue_remove_head(adapter->hw.q_send.head); + kfree(dsc->buffer); + kfree(dsc); + } + spin_unlock(&adapter->hw.q_send.lock); + +} + +int con0_poll_thread(void *data) +{ + struct net_adapter *adapter = (struct net_adapter *)data; + struct wimax_cfg *g_cfg = adapter->pdata->g_cfg; + int prev_val = 0; + int curr_val = 0; + + wake_lock(&g_cfg->wimax_tx_lock); + + while ((!adapter->halted)) { + curr_val = gpio_get_value(GPIO_WIMAX_CON0); + if ((prev_val && (!curr_val)) || (curr_val == GPIO_LEVEL_LOW)) { + adapter->pdata->restore_uart_path(); + break; + } + prev_val = curr_val; + msleep(40); + } + wake_unlock(&g_cfg->wimax_tx_lock); + do_exit(0); + return 0; +} + + + + + +/* get MAC address from device */ +void hw_get_mac_address(void *data) +{ + struct net_adapter *adapter = (struct net_adapter *)data; + struct hw_private_packet req; + int nResult = 0; + int retry = 5; + req.id0 = 'W'; + req.id1 = 'P'; + req.code = HwCodeMacRequest; + req.value = 0; + do { + if (adapter == NULL) + break; + + if (retry == 2) //odb backup takes 5.8sec + msleep(6000); + + sdio_claim_host(adapter->func); + nResult = sd_send(adapter, (u_char *)&req, + sizeof(struct hw_private_packet)); + sdio_release_host(adapter->func); + + if (nResult != STATUS_SUCCESS) + dump_debug("hw_get_mac_address: sd_send fail!!"); + msleep(300); + retry--; + /*in case we dont get MAC we need + to release power lock and probe finsh */ + if (!retry) { + adapter->download_complete = TRUE; + wake_up_interruptible(&adapter->download_event); + msleep(100); + + } + } while ((!adapter->mac_ready) && (!adapter->halted) && retry); + + adapter->pdata->g_cfg->powerup_done = true ; + dump_debug("MAC thread exit"); + return; +} + +u_int hw_send_data(struct net_adapter *adapter, + void *buffer , u_long length, bool control) +{ + struct buffer_descriptor *dsc; + struct hw_packet_header *hdr; + struct net_device *net = adapter->net; + u_char *ptr; + unsigned long flags ; + struct wimax_cfg *g_cfg = adapter->pdata->g_cfg; + + spin_lock_irqsave(&adapter->hw.q_send.lock, flags); + + dsc = (struct buffer_descriptor *)kmalloc( + sizeof(struct buffer_descriptor), GFP_ATOMIC | GFP_DMA); + if (dsc == NULL) + return STATUS_RESOURCES; + + dsc->buffer = kmalloc(BUFFER_DATA_SIZE , GFP_ATOMIC | GFP_DMA); + if (dsc->buffer == NULL) { + kfree(dsc); + return STATUS_RESOURCES; + } + + ptr = dsc->buffer; + + /* shift data pointer */ + ptr += sizeof(struct hw_packet_header); +#ifdef HARDWARE_USE_ALIGN_HEADER + ptr += 2; +#endif + hdr = (struct hw_packet_header *)dsc->buffer; + + if (control) { + memcpy(ptr, buffer + (ETHERNET_ADDRESS_LENGTH * 2), + length - (ETHERNET_ADDRESS_LENGTH * 2)); + + /* add packet header */ + hdr->id0 = 'W'; + hdr->id1 = 'C'; + hdr->length = (u_short)length - (ETHERNET_ADDRESS_LENGTH * 2); + + /* set length */ + dsc->length = (u_short)length - (ETHERNET_ADDRESS_LENGTH * 2) + + sizeof(struct hw_packet_header); + #ifdef HARDWARE_USE_ALIGN_HEADER + dsc->length += 2; + #endif + + /* dump control packet for debug */ + if (g_cfg->enable_dump_msg == 1) + dump_buffer("Control Tx", + (u_char *)dsc->buffer + 6, dsc->length - 6); + } else { + + length -= (ETHERNET_ADDRESS_LENGTH * 2); + buffer += (ETHERNET_ADDRESS_LENGTH * 2); + + memcpy(ptr, buffer, length); + + hdr->id0 = 'W'; + hdr->id1 = 'D'; + hdr->length = (u_short)length; + + dsc->length = length + sizeof(struct hw_packet_header); + #ifdef HARDWARE_USE_ALIGN_HEADER + dsc->length += 2; + #endif + adapter->netstats.tx_packets++; + adapter->netstats.tx_bytes += dsc->length; + + /* add statistics */ + if (!netif_running(net)) + dump_debug("!netif_running"); + + } + + + queue_put_tail(adapter->hw.q_send.head, dsc->node); + spin_unlock_irqrestore(&adapter->hw.q_send.lock, flags); + + queue_work(adapter->wimax_workqueue, &adapter->transmit_work); + return STATUS_SUCCESS; +} + +u_int sd_send_data(struct net_adapter *adapter, struct buffer_descriptor *dsc) +{ + int nRet = 0; + int nWriteIdx; + dsc->length += (dsc->length & 1) ? 1 : 0; + +#ifdef HARDWARE_USE_ALIGN_HEADER + if (dsc->length > SDIO_MAX_BYTE_SIZE) + dsc->length = (dsc->length + SDIO_MAX_BYTE_SIZE) + & ~(SDIO_MAX_BYTE_SIZE); +#endif + + if (adapter->halted) { + dump_debug("Halted Already"); + return STATUS_UNSUCCESSFUL; + } + hwSdioWriteBankIndex(adapter, &nWriteIdx, &nRet); + + if (nRet || (nWriteIdx < 0)) { + dump_debug("sd_send_data : " + " error fetch bank index!! nRet = %d", nRet); + return STATUS_UNSUCCESSFUL; + } + + sdio_writeb(adapter->func, (nWriteIdx + 1) % 15, + SDIO_H2C_WP_REG, NULL); + + nRet = sdio_memcpy_toio(adapter->func, + SDIO_TX_BANK_ADDR+(SDIO_BANK_SIZE * nWriteIdx)+4, + dsc->buffer, dsc->length); + + if (nRet < 0) + dump_debug("sd_send_data :" + " error writing dsc packet!! nRet = %d", nRet); + nRet = sdio_memcpy_toio(adapter->func, + SDIO_TX_BANK_ADDR + (SDIO_BANK_SIZE * nWriteIdx), + &(dsc->length), 4); + + if (nRet < 0) + dump_debug("sd_send_data :" + "error writing bank length info!! nRet = %d", nRet); + return nRet; +} + +/* Return packet for packet buffer freeing */ +void hw_return_packet(struct net_adapter *adapter, u_short type) +{ + struct buffer_descriptor *curElem; + struct buffer_descriptor *prevElem = NULL; + + if (queue_empty(adapter->ctl.q_received.head)) + return; + + /* first time get head needed to get the dsc nodes */ + curElem = (struct buffer_descriptor *) + queue_get_head(adapter->ctl.q_received.head); + + for ( ; curElem != NULL; prevElem = curElem, + curElem = (struct buffer_descriptor *)curElem->node.next) { + if (curElem->type == type) { + /* process found*/ + if (prevElem == NULL) { + /* First node or only + one node present to delete */ + adapter->ctl.q_received.head.next = + ((struct list_head *)curElem)->next; + if (!((adapter->ctl.q_received.head).next)) { + /* rechain list pointer to next link */ + /* if the list pointer is null, + null out the reverse link */ + (adapter->ctl.q_received.head).prev = + NULL; + } + } else if (((struct list_head *)curElem)->next + == NULL) { + /* last node */ + ((struct list_head *)prevElem)->next = NULL; + (adapter->ctl.q_received.head).prev = + (struct list_head *)(&prevElem); + } else { + /* middle node */ + ((struct list_head *)prevElem)->next = + ((struct list_head *)curElem)->next; + } + + kfree(curElem->buffer); + kfree(curElem); + break; + } + } +} + +int hw_device_wakeup(struct net_adapter *adapter) +{ + int rc = 0; + + adapter->pdata->wakeup_assert(1); + + while (!adapter->pdata->is_modem_awake()) { + if (rc == 0) + dump_debug("hw_device_wakeup (CON0 status):" + " waiting for modem awake"); + rc++; + if (rc > WAKEUP_MAX_TRY) { + dump_debug("hw_device_wakeup (CON0 status):" + " modem wake up time out!!"); + return -1; + } + msleep(WAKEUP_TIMEOUT/2); + adapter->pdata->wakeup_assert(0); + msleep(WAKEUP_TIMEOUT/2); + adapter->pdata->wakeup_assert(1); + s3c_bat_use_wimax(1); + } + if (rc != 0) + dump_debug("hw_device_wakeup (CON0 status): modem awake"); + adapter->pdata->wakeup_assert(0); + + return 0; +} + +/* +This Work is responsible for Transmiting Both Control And Data packet +*/ + +void hw_transmit_thread(struct work_struct *work) +{ + struct buffer_descriptor *dsc; + struct hw_private_packet hdr; + struct net_adapter *adapter; + int nRet = 0; + int modem_reset = false; + struct wimax_cfg *g_cfg; + + adapter = container_of(work, struct net_adapter, transmit_work); + g_cfg = adapter->pdata->g_cfg; + wake_lock(&g_cfg->wimax_tx_lock); + + if (!gpio_get_value(WIMAX_EN)) { + dump_debug("WiMAX Power OFF!! (TX)"); + goto exit; + } + + mutex_lock(&adapter->rx_lock); + + while (!queue_empty(adapter->hw.q_send.head)) { + if (adapter->halted) { + /* send stop message */ + hdr.id0 = 'W'; + hdr.id1 = 'P'; + hdr.code = HwCodeHaltedIndication; + hdr.value = 0; + + if (sd_send(adapter, (unsigned char *)&hdr, + sizeof(struct hw_private_packet))) + dump_debug("halted," + " send HaltIndication to FW err"); + modem_reset = true; + break; + } + + if (!g_cfg->modem_reset_flag) { + dump_debug("modem_reset_flag is not set"); + break; + } + + if(hw_device_wakeup(adapter)) { + modem_reset = true; + break; + } + + dsc = (struct buffer_descriptor *) + queue_get_head(adapter->hw.q_send.head); + + if (!dsc->buffer) { + dump_debug("dsc->buffer is NULL"); + break; + } + + if (!dsc) { + dump_debug("Fail...node is null"); + break; + } + + sdio_claim_host(adapter->func); + nRet = sd_send_data(adapter, dsc); + sdio_release_host(adapter->func); + queue_remove_head(adapter->hw.q_send.head); + kfree(dsc->buffer); + kfree(dsc); + if (nRet != STATUS_SUCCESS) { + sdio_claim_host(adapter->func); + sdio_release_irq(adapter->func); + sdio_release_host(adapter->func); + ++adapter->XmitErr; + dump_debug("SendData Fail******"); + if (nRet == -ENOMEDIUM || nRet == /*-ETIMEOUT*/-110) { + dump_debug("%s: No medium or timeout error", __func__); + // adapter->halted = TRUE; + } + modem_reset = true; + break; + } + } + + if(modem_reset) { + while (!g_cfg->modem_reset_flag) { + dump_debug("Waiting for PM_POST_SUSPEND notifier"); + msleep(100); + } + adapter->pdata->power(0); + dump_debug("Modem reset done"); + } + + mutex_unlock(&adapter->rx_lock); +exit: + wake_unlock(&g_cfg->wimax_tx_lock); + return ; +} diff --git a/drivers/net/wimax_cmc/headers.h b/drivers/net/wimax_cmc/headers.h new file mode 100755 index 0000000..f6a5b84 --- /dev/null +++ b/drivers/net/wimax_cmc/headers.h @@ -0,0 +1,116 @@ +/* + * headers.h + * + * Global definitions and fynctions + */ +#ifndef _WIMAX_HEADERS_H +#define _WIMAX_HEADERS_H + +#include <linux/kernel.h> +#include <linux/module.h> +#include <linux/sched.h> +#include <linux/slab.h> +#include <linux/init.h> +#include <linux/delay.h> +#include <linux/netdevice.h> +#include <linux/etherdevice.h> +#include <linux/ethtool.h> +#include <linux/proc_fs.h> +#include <linux/mmc/sdio_ids.h> +#include <linux/mmc/sdio_func.h> +#include <asm/byteorder.h> +#include <asm/uaccess.h> +#include <linux/wakelock.h> +#include <linux/wimax/samsung/wimax732.h> +#include "buffer.h" +#include "wimax_sdio.h" + +#define WIMAXMAC_TXT_PATH "/efs/WiMAXMAC.txt" +#define WIMAX_IMAGE_PATH "/system/etc/wimaxfw.bin" +#define WIMAX_LOADER_PATH "/system/etc/wimaxloader.bin" +#define WIMAX_BOOTIMAGE_PATH "/system/etc/wimax_boot.bin" + +#define STATUS_SUCCESS ((u_long)0x00000000L) +#define STATUS_PENDING ((u_long)0x00000103L) /* The operation that was requested is pending completion */ +#define STATUS_RESOURCES ((u_long)0x00001003L) +#define STATUS_RESET_IN_PROGRESS ((u_long)0xc001000dL) +#define STATUS_DEVICE_FAILED ((u_long)0xc0010008L) +#define STATUS_NOT_ACCEPTED ((u_long)0x00010003L) +#define STATUS_FAILURE ((u_long)0xC0000001L) +#define STATUS_UNSUCCESSFUL ((u_long)0xC0000002L) /* The requested operation was unsuccessful */ +#define STATUS_CANCELLED ((u_long)0xC0000003L) + +#ifndef TRUE_FALSE_ +#define TRUE_FALSE_ +enum BOOL { + FALSE, + TRUE +}; +#endif + +#define HARDWARE_USE_ALIGN_HEADER + +#define dump_debug(args...) \ +{ \ + printk(KERN_ALERT"\x1b[1;33m[WiMAX] "); \ + printk(args); \ + printk("\x1b[0m\n"); \ +} + + +/* external functions & variables */ +extern void set_wimax_pm(void(*suspend)(void), void(*resume)(void)); +extern void unset_wimax_pm(void); +extern int cmc732_sdio_reset_comm(struct mmc_card *card); +extern u_int system_rev; + +/* receive.c functions */ +u_int process_sdio_data(struct net_adapter *adapter, void *buffer, u_long length, long Timeout); + +/* control.c functions */ +u_int control_send(struct net_adapter *adapter, void *buffer, u_long length); +void control_recv(struct net_adapter *adapter, void *buffer, u_long length); +u_int control_init(struct net_adapter *adapter); +void control_remove(struct net_adapter *adapter); + +struct process_descriptor *process_by_id(struct net_adapter *adapter, u_int id); +struct process_descriptor *process_by_type(struct net_adapter *adapter, u_short type); +void remove_process(struct net_adapter *adapter, u_int id); + +u_long buffer_count(struct list_head ListHead); +struct buffer_descriptor *buffer_by_type(struct list_head ListHead, u_short type); +void dump_buffer(const char *desc, u_char *buffer, u_int len); + +/* hardware.c functions */ +void switch_eeprom_ap(void); +void switch_eeprom_wimax(void); +void switch_usb_ap(void); +void switch_usb_wimax(void); +void display_gpios(void); /* display GPIO status used by WiMAX module */ +void switch_uart_ap(void); +void switch_uart_wimax(void); +void hw_init_gpios(void); +void hw_deinit_gpios(void); + +u_int sd_send(struct net_adapter *adapter, u_char *buffer, u_int len); +u_int sd_send_data(struct net_adapter *adapter, struct buffer_descriptor *dsc); +u_int hw_send_data(struct net_adapter *adapter, void *buffer, u_long length,bool); +void hw_return_packet(struct net_adapter *adapter, u_short type); + +void s3c_bat_use_wimax(int onoff); + +int gpio_wimax_poweron (void); +int gpio_wimax_poweroff (void); + +int hw_start(struct net_adapter *adapter); +int hw_stop(struct net_adapter *adapter); +int hw_init(struct net_adapter *adapter); +void hw_remove(struct net_adapter *adapter); +void hw_get_mac_address(void *data); +int con0_poll_thread(void *data); +void hw_transmit_thread(struct work_struct *work); +void adapter_interrupt(struct sdio_func *func); +/* structures for global access */ +extern struct net_adapter *g_adapter; + +#endif /* _WIMAX_HEADERS_H */ diff --git a/drivers/net/wimax_cmc/hw_types.h b/drivers/net/wimax_cmc/hw_types.h new file mode 100755 index 0000000..3a1606c --- /dev/null +++ b/drivers/net/wimax_cmc/hw_types.h @@ -0,0 +1,96 @@ +/** + * hw_types.h + * + * Hardware types and definitions + */ +#ifndef _WIMAX_HW_TYPES_H +#define _WIMAX_HW_TYPES_H + +#include "ctl_types.h" + +/* private protocol defines */ +#define HW_PROT_VALUE_LINK_DOWN 0x00 +#define HW_PROT_VALUE_LINK_UP 0xff + +/* SDIO general defines */ +#define SDIO_BANK_SIZE 4096 /* size of a bank in cmc's rx and tx buffers */ +#define SDIO_MAX_BLOCK_SIZE 2048 /* maximum block size (SDIO) */ +#define SDIO_MAX_BYTE_SIZE 511 /* maximum size in byte mode */ +#define SDIO_BUFFER_SIZE SDIO_MAX_BLOCK_SIZE +/* + *We need the HEADER_MANIPULATION_OFFSET because + *we now use only one buffer while receiving data. + *since the ehternet header is larger than the hardware packet header, + *we need to keep some space at the beginning of the buffer to accomodate the + *ethernet header. 8 bytes is enough for this purpose. + */ +#define HEADER_MANIPULATION_OFFSET 8 +/* SDIO function addresses */ +#define SDIO_TX_BANK_ADDR 0x1000 +#define SDIO_RX_BANK_ADDR 0x10000 +#define SDIO_INT_STATUS_REG 0xC0 +#define SDIO_INT_STATUS_CLR_REG 0xC4 + +#define SDIO_C2H_WP_REG 0xE4 +#define SDIO_C2H_RP_REG 0xE8 +#define SDIO_H2C_WP_REG 0xEC +#define SDIO_H2C_RP_REG 0xF0 + +/* SDIO function registers */ +#define SDIO_INT_DATA_READY 0x01 +#define SDIO_INT_ERROR 0x02 + +#define WAKEUP_MAX_TRY 20 +#define WAKEUP_TIMEOUT 300 +#define CONTROL_PACKET 1 +#define DATA_PACKET 0 + +/* packet types */ +enum { + HwPktTypeNone = 0xff00, + HwPktTypePrivate, + HwPktTypeControl, + HwPktTypeData, + HwPktTypeTimeout +}; + +/* private packet opcodes */ +enum { + HwCodeMacRequest = 0x01, + HwCodeMacResponse, + HwCodeLinkIndication, + HwCodeRxReadyIndication, + HwCodeHaltedIndication, + HwCodeIdleNtfy, + HwCodeWakeUpNtfy +}; + + +#pragma pack(1) +struct hw_packet_header { + char id0; /* packet ID */ + char id1; + u_short length; /* packet length */ +}; + +struct hw_private_packet { + char id0; /* packet ID */ + char id1; + u_char code; /* command code */ + u_char value; /* command value */ +}; +#pragma pack() + +struct wimax_msg_header { + u_short type; + u_short id; + u_int length; +}; + +struct hardware_info { + void *receive_buffer; + u_char eth_header[ETHERNET_ADDRESS_LENGTH * 2]; /* ethernet header */ + struct queue_info q_send; /* send pending queue */ +}; + +#endif /* _WIMAX_HW_TYPES_H */ diff --git a/drivers/net/wimax_cmc/receive.c b/drivers/net/wimax_cmc/receive.c new file mode 100755 index 0000000..a0e43d1 --- /dev/null +++ b/drivers/net/wimax_cmc/receive.c @@ -0,0 +1,301 @@ +/* + * receive.c + * + * handle download packet, private cmd and control/data packet + */ +#include "headers.h" +#include "wimax_plat.h" +#include "firmware.h" +#include "download.h" + +#include <plat/sdhci.h> +#include <plat/devs.h> +#include <linux/mmc/host.h> +#include <linux/kthread.h> +extern struct image_data g_wimax_image; + +void process_indicate_packet(struct net_adapter *adapter, u_char *buffer) +{ + struct wimax_msg_header *packet; + char *tmp_byte; + struct wimax_cfg *g_cfg = adapter->pdata->g_cfg; + + packet = (struct wimax_msg_header *)buffer; + + if (packet->type == be16_to_cpu(ETHERTYPE_DL)) { + switch (be16_to_cpu(packet->id)) { + case MSG_DRIVER_OK_RESP: + dump_debug("process_indicate_packet: MSG_DRIVER_OK_RESP"); + send_image_info_packet(adapter, MSG_IMAGE_INFO_REQ); + break; + case MSG_IMAGE_INFO_RESP: + dump_debug("process_indicate_packet: MSG_IMAGE_INFO_RESP"); + send_image_data_packet(adapter, MSG_IMAGE_DATA_REQ); + break; + case MSG_IMAGE_DATA_RESP: + if (g_wimax_image.offset == g_wimax_image.size) { + dump_debug("process_indicate_packet: Image Download Complete"); + send_cmd_packet(adapter, MSG_RUN_REQ); /* Run Message Send */ + } else + send_image_data_packet(adapter, MSG_IMAGE_DATA_REQ); + break; + case MSG_RUN_RESP: + tmp_byte = (char *)(buffer + sizeof(struct wimax_msg_header)); + + if (*tmp_byte == 0x01) { + dump_debug("process_indicate_packet: MSG_RUN_RESP"); + + if (g_cfg->wimax_mode == SDIO_MODE || g_cfg->wimax_mode == DM_MODE + || g_cfg->wimax_mode == USB_MODE + || g_cfg->wimax_mode == USIM_RELAY_MODE) { + + dump_debug("%s: F/W Download Complete and Running ",__func__); + dump_debug("Wait for SDIO ready..."); + msleep(1200); /* IMPORTANT!! wait for cmc730 can handle mac req packet */ + + kernel_thread((int (*)(void *))hw_get_mac_address, adapter, 0); + } else if (g_cfg->wimax_mode == WTM_MODE) { + adapter->download_complete = TRUE; + wake_up_interruptible(&adapter->download_event); + adapter->pdata->g_cfg->powerup_done = true ; + adapter->wtm_task = kthread_create( + con0_poll_thread, adapter, "%s", + "wimax_con0_poll_thread"); + if (adapter->wtm_task) + wake_up_process( + adapter->wtm_task); + } else if (g_cfg->wimax_mode == AUTH_MODE) { + adapter->download_complete = TRUE; + wake_up_interruptible(&adapter->download_event); + adapter->pdata->g_cfg->powerup_done = true ; + } + } + break; + default: + dump_debug("process_indicate_packet: Unkown type"); + break; + } + } + else + dump_debug("process_indicate_packet - is not download pakcet"); +} + +u_long process_private_cmd(struct net_adapter *adapter, void *buffer) +{ + struct hw_private_packet *cmd; + u_char *bufp; + struct wimax_cfg *g_cfg = adapter->pdata->g_cfg; + cmd = (struct hw_private_packet *)buffer; + + switch (cmd->code) { + case HwCodeMacResponse: { + u_char mac_addr[ETHERNET_ADDRESS_LENGTH]; + bufp = (u_char *)buffer; + + /* processing for mac_req request */ + #ifndef PRODUCT_SHIP + dump_debug("MAC address = %02x:%02x:%02x:%02x:%02x:%02x", + bufp[3], bufp[4], bufp[5], bufp[6], bufp[7], bufp[8]); + #endif + memcpy(mac_addr, bufp + 3, ETHERNET_ADDRESS_LENGTH); + + /* create ethernet header */ + memcpy(adapter->hw.eth_header, mac_addr, ETHERNET_ADDRESS_LENGTH); + memcpy(adapter->hw.eth_header + ETHERNET_ADDRESS_LENGTH, mac_addr, ETHERNET_ADDRESS_LENGTH); + adapter->hw.eth_header[(ETHERNET_ADDRESS_LENGTH * 2) - 1] += 1; + + memcpy(adapter->net->dev_addr, bufp + 3, ETHERNET_ADDRESS_LENGTH); + adapter->mac_ready = TRUE; + + if (adapter->downloading) { + adapter->download_complete = TRUE; + wake_up_interruptible(&adapter->download_event); + } + return (sizeof(struct hw_private_packet) + ETHERNET_ADDRESS_LENGTH - sizeof(u_char)); + } + case HwCodeLinkIndication: { + if ((cmd->value == HW_PROT_VALUE_LINK_DOWN) + && (adapter->media_state != MEDIA_DISCONNECTED)) { + dump_debug("LINK_DOWN_INDICATION"); + s3c_bat_use_wimax(0); + + /* set values */ + adapter->media_state = MEDIA_DISCONNECTED; + + /* indicate link down */ + netif_stop_queue(adapter->net); + netif_carrier_off(adapter->net); + } else if ((cmd->value == HW_PROT_VALUE_LINK_UP) + && (adapter->media_state != MEDIA_CONNECTED)) { + dump_debug("LINK_UP_INDICATION"); + + s3c_bat_use_wimax(1); + /* set values */ + adapter->media_state = MEDIA_CONNECTED; + adapter->net->mtu = WIMAX_MTU_SIZE; + + /* indicate link up */ + netif_start_queue(adapter->net); + netif_carrier_on(adapter->net); + } + break; + } + case HwCodeHaltedIndication: { + dump_debug("Device is about to reset, stop driver"); + break; + } + case HwCodeRxReadyIndication: { + dump_debug("Device RxReady"); + /* to start the data packet send queue again after stopping in xmit */ + if (adapter->media_state == MEDIA_CONNECTED) + netif_wake_queue(adapter->net); + break; + } + case HwCodeIdleNtfy: { + /* set idle / vi */ + + dump_debug("process_private_cmd: HwCodeIdleNtfy"); + + s3c_bat_use_wimax(0); + break; + } + case HwCodeWakeUpNtfy: { + /* IMPORTANT!! at least 4 sec is required after modem waked up */ + wake_lock_timeout(&g_cfg->wimax_wake_lock, 4 * HZ); + dump_debug("process_private_cmd: HwCodeWakeUpNtfy"); + s3c_bat_use_wimax(1); + break; + } + default: + dump_debug("Command = %04x", cmd->code); + break; + } + + return sizeof(struct hw_private_packet); +} + +u_int process_sdio_data(struct net_adapter *adapter, + void *buffer, u_long length, long Timeout) +{ + struct hw_packet_header *hdr; + struct net_device *net = adapter->net; + u_char *ofs = (u_char *)buffer; + int res = 0; + u_int machdrlen = (ETHERNET_ADDRESS_LENGTH * 2); + u_int rlen = length; + u_long type; + u_short data_len; + struct sk_buff *skb; + while ((int)rlen > 0) { + hdr = (struct hw_packet_header *)ofs; + type = HwPktTypeNone; + + if (unlikely(hdr->id0 != 'W')) { /* "WD", "WC", "WP" or "WE" */ + if (rlen > 4) { + dump_debug("Wrong packet ID (%02x %02x)", hdr->id0, hdr->id1); + dump_buffer("Wrong packet", (u_char *)ofs, rlen); + } + /* skip rest of packets */ + return 0; + } + + /* check packet type */ + switch (hdr->id1) { + case 'P': { + u_long l = 0; + type = HwPktTypePrivate; + + /* process packet */ + l = process_private_cmd(adapter, ofs); + + /* shift */ + ofs += l; + rlen -= l; + + /* process next packet */ + continue; + } + case 'C': + type = HwPktTypeControl; + break; + case 'D': + type = HwPktTypeData; + break; + case 'E': + /* skip rest of buffer */ + return 0; + default: + dump_debug("hwParseReceivedData : Wrong packet ID [%02x %02x]", + hdr->id0, hdr->id1); + /* skip rest of buffer */ + return 0; + } + + if (likely(!adapter->downloading)) { + if (unlikely(hdr->length > WIMAX_MAX_TOTAL_SIZE + || ((hdr->length + sizeof(struct hw_packet_header)) > rlen))) { + dump_debug("Packet length is too big (%d)", hdr->length); + /* skip rest of packets */ + return 0; + } + } + + /* change offset */ + ofs += sizeof(struct hw_packet_header); + rlen -= sizeof(struct hw_packet_header); + + /* process download packet, data and control packet */ + if (likely(!adapter->downloading)) + { +#ifdef HARDWARE_USE_ALIGN_HEADER + ofs += 2; + rlen -= 2; +#endif + /* store the packet length */ + /* because we will overwrite the hardware packet header */ + data_len = hdr->length; + /* copy the MAC to ofs buffer */ + memcpy((u_char *)ofs - machdrlen, adapter->hw.eth_header, machdrlen); + + if (unlikely(type == HwPktTypeControl)) + control_recv(adapter, (u_char *)ofs -machdrlen, + data_len + machdrlen); + else { + + skb = dev_alloc_skb(data_len + machdrlen + 2); + if(!skb) + { + dump_debug("MEMORY PINCH: unable to allocate skb"); + return -ENOMEM; + } + skb_reserve(skb, 2); + memcpy(skb_put(skb, (data_len + machdrlen)), + (u_char *)ofs -machdrlen, + (data_len + machdrlen)); + skb->dev = net; + skb->protocol = eth_type_trans(skb, net); + skb->ip_summed = CHECKSUM_UNNECESSARY; + res = netif_rx(skb); + + adapter->netstats.rx_packets++; + adapter->netstats.rx_bytes += (data_len + machdrlen); + + + } + /* restore the hardware packet length information */ + hdr->length = data_len; + } else { + hdr->length -= sizeof(struct hw_packet_header); + process_indicate_packet(adapter, ofs); + } + /* + * If the packet is unreasonably long, quietly drop it rather than + * kernel panicing by calling skb_put. + */ + /* shift */ + ofs += hdr->length; + rlen-= hdr->length; + } + + return 0; +} diff --git a/drivers/net/wimax_cmc/wimax_i2c.c b/drivers/net/wimax_cmc/wimax_i2c.c index 018bfd3..474688a 100644..100755 --- a/drivers/net/wimax_cmc/wimax_i2c.c +++ b/drivers/net/wimax_cmc/wimax_i2c.c @@ -3,6 +3,7 @@ * * EEPROM access functions */ +//#include "download.h" #include "wimax_i2c.h" #include "firmware.h" #include <linux/i2c.h> @@ -28,7 +29,7 @@ struct boot_image_data g_wimax_image; -static void wimax_i2c_reset(void); +void wimax_i2c_reset(void); void dump_buffer(const char *desc, u_char *buffer, u_int len) { @@ -62,9 +63,8 @@ void eeprom_poweron(void) gpio_set_value(EEPROM_SCL, GPIO_LEVEL_HIGH); gpio_set_value(EEPROM_SDA, GPIO_LEVEL_HIGH); - /* SEL = 1 to switch i2c-eeprom path to AP */ - gpio_set_value(I2C_SEL, GPIO_LEVEL_HIGH); - usleep_range(10000, 10000); + gpio_set_value(I2C_SEL, GPIO_LEVEL_HIGH); // SEL = 1 to switch i2c-eeprom path to AP + msleep(10); /* power on */ @@ -73,7 +73,7 @@ void eeprom_poweron(void) msleep(100); wimax_i2c_reset(); - usleep_range(10000, 10000); + msleep(10); } void eeprom_poweroff(void) @@ -81,8 +81,7 @@ void eeprom_poweroff(void) /* power off */ gpio_set_value(WIMAX_EN, GPIO_LEVEL_LOW); - /* SEL = 0 to switch i2c-eeprom path to wimax */ - gpio_set_value(I2C_SEL, GPIO_LEVEL_LOW); + gpio_set_value(I2C_SEL, GPIO_LEVEL_LOW); // SEL = 0 to switch i2c-eeprom path to wimax msleep(100); @@ -145,8 +144,7 @@ void wimax_i2c_init(void) gpio_set_value(EEPROM_SDA, GPIO_LEVEL_LOW); udelay(2); - /* send 7 bits address */ - wimax_i2c_write_byte(DEVICE_ADDRESS, 7); + wimax_i2c_write_byte(DEVICE_ADDRESS, 7); /* send 7 bits address */ } void wimax_i2c_deinit(void) @@ -284,7 +282,7 @@ int wimax_i2c_eeprom_address(short addr) /* send 2 bytes address */ wimax_i2c_write_byte(buf[1], 8); - if (wimax_i2c_check_ack()) + if(wimax_i2c_check_ack()) return -1; wimax_i2c_write_byte(buf[0], 8); return wimax_i2c_check_ack(); @@ -292,8 +290,9 @@ int wimax_i2c_eeprom_address(short addr) int wimax_i2c_write_buffer(char *data, int len) { - int i; - for (i = 0; i < len; i++) { + int i; + + for(i = 0; i < len; i++) { wimax_i2c_write_byte(data[i], 8); /* 1 byte data */ if (wimax_i2c_check_ack()) return -1; @@ -352,19 +351,19 @@ int wimax_i2c_write(u_short addr, u_char *data, int length) struct i2c_msg msg; data_buffer[0] = (unsigned char)((addr >> 8) & 0xff); data_buffer[1] = (unsigned char)(addr & 0xff); - while (length) { - len = (length > MAX_BOOT_WRITE_LENGTH) ? - MAX_BOOT_WRITE_LENGTH : length ; + while(length) + { + len = (length > MAX_BOOT_WRITE_LENGTH)? MAX_BOOT_WRITE_LENGTH : length ; memcpy(data_buffer+WIMAX_EEPROM_ADDRLEN, data, len); msg.addr = pclient->addr; - msg.flags = 0; /*write*/ + msg.flags = 0; //write msg.len = (u16)length+WIMAX_EEPROM_ADDRLEN; msg.buf = data_buffer; rc = i2c_transfer(pclient->adapter, &msg, 1); if (rc < 0) return rc; - length -= len; - data += len; + length-=len; + data+=len; } return 0; } @@ -376,11 +375,11 @@ int wimax_i2c_read(u_short addr, u_char *data, int length) data_buffer[0] = (unsigned char)((addr >> 8) & 0xff); data_buffer[1] = (unsigned char)(addr & 0xff); msgs[0].addr = pclient->addr; - msgs[0].flags = 0; /*write*/ + msgs[0].flags = 0; //write msgs[0].len = WIMAX_EEPROM_ADDRLEN; msgs[0].buf = data_buffer; msgs[1].addr = pclient->addr; - msgs[1].flags = I2C_M_RD; /*read*/ + msgs[1].flags = I2C_M_RD; //read msgs[1].len = length; msgs[1].buf = data; return i2c_transfer(pclient->adapter, msgs, 2); @@ -398,9 +397,8 @@ static ssize_t eeprom_show(struct device *dev, } -static ssize_t eeprom_store(struct device *dev, - struct device_attribute *attr, - const char *buffer, size_t count) { +static ssize_t eeprom_store(struct device *dev, + struct device_attribute *attr, const char *buffer, size_t count) { if (strncmp(buffer, "wb00", 4) == 0) { pr_debug("Write EEPROM!!"); @@ -426,7 +424,7 @@ static ssize_t eeprom_store(struct device *dev, } else if (strncmp(buffer, "wrev", 4) == 0) { pr_debug("Write Rev!!"); eeprom_write_rev(); - } else + } else pr_debug("Wrong option"); return count; @@ -465,8 +463,8 @@ int wmxeeprom_remove(struct i2c_client *client) return 0; } -const struct i2c_device_id wmxeeprom_id[] = { - { "wmxeeprom", 0 }, +const struct i2c_device_id wmxeeprom_id[]={ + { "wmxeeprom",0 }, { } }; @@ -499,7 +497,7 @@ int load_wimax_boot(void) if (fp) { pr_debug("LoadWiMAXBootImage .."); - g_wimax_image.data = vmalloc(MAX_WIMAXBOOTIMAGE_SIZE); + g_wimax_image.data = (u_char *)vmalloc(MAX_WIMAXBOOTIMAGE_SIZE); if (!g_wimax_image.data) { pr_debug("Error: Memory alloc failure."); klib_fclose(fp); @@ -507,8 +505,7 @@ int load_wimax_boot(void) } memset(g_wimax_image.data, 0, MAX_WIMAXBOOTIMAGE_SIZE); - read_size = klib_flen_fcopy(g_wimax_image.data, - MAX_WIMAXBOOTIMAGE_SIZE, fp); + read_size = klib_flen_fcopy(g_wimax_image.data, MAX_WIMAXBOOTIMAGE_SIZE, fp); g_wimax_image.size = read_size; g_wimax_image.address = 0; g_wimax_image.offset = 0; @@ -534,10 +531,12 @@ int write_rev(void) /* swap */ val = be32_to_cpu(system_rev); - do { + do + { err = wimax_i2c_write(0x7080, (char *)(&val), 4); - } while (err < 0 ? ((retry--) > 0) : 0); - if (retry < 0) + } + while(err<0?((retry--)>0):0); + if(retry<0) pr_debug("eeprom error"); return err ; } @@ -549,10 +548,12 @@ void erase_cert(void) int retry = 100; int err; - do { + do + { err = wimax_i2c_write(0x5800, buf, len); - } while (err < 0 ? ((retry--) > 0) : 0); - if (retry < 0) + } + while(err<0?((retry--)>0):0); + if(retry<0) pr_debug("eeprom error"); } @@ -563,17 +564,18 @@ int check_cert(void) int retry = 100; int err; - do { + do + { err = wimax_i2c_read(0x5800, buf, len); - } while (err < 0 ? ((retry--) > 0) : 0); - if (retry < 0) + } + while(err<0?((retry--)>0):0); + if(retry<0) pr_debug("eeprom error"); dump_buffer("Certification", (u_char *)buf, (u_int)len); /* check "Cert" */ - if (buf[0] == 0x43 && buf[1] == 0x65 && - buf[2] == 0x72 && buf[3] == 0x74) + if (buf[0] == 0x43 && buf[1] == 0x65 && buf[2] == 0x72 && buf[3] == 0x74) return 0; return -1; @@ -587,10 +589,12 @@ int check_cal(void) int retry = 100; int err; - do { + do + { err = wimax_i2c_read(0x5400, buf, len); - } while (err < 0 ? ((retry--) > 0) : 0); - if (retry < 0) + } + while(err<0?((retry--)>0):0); + if(retry<0) pr_debug("eeprom error"); dump_buffer("Calibration", (u_char *)buf, (u_int)len); @@ -616,7 +620,7 @@ void eeprom_read_boot() eeprom_poweron(); - buf = kmalloc(4096, GFP_KERNEL); + buf = (char *)kmalloc(4096, GFP_KERNEL); if (buf == NULL) { pr_debug("eeprom_read_boot: MALLOC FAIL!!"); return; @@ -625,12 +629,12 @@ void eeprom_read_boot() addr = 0x0; for (j = 0; j < 1; j++) { /* read 4K */ len = 4096; - do { + do + { err = wimax_i2c_read(addr, buf, len); - } while (err < 0 ? ((retry--) > 0) : 0); - - { - /* dump boot data */ + } + while(err<0?((retry--)>0):0); + { /* dump boot data */ char print_buf[256] = {0}; char chr[8] = {0}; @@ -657,7 +661,7 @@ void eeprom_read_boot() kfree(buf); eeprom_poweroff(); - if (retry < 0) + if(retry<0) pr_debug("eeprom error"); } @@ -674,23 +678,22 @@ void eeprom_read_all() eeprom_poweron(); /* allocate 4K buffer */ - buf = kmalloc(4096, GFP_KERNEL); + buf = (char *)kmalloc(4096, GFP_KERNEL); if (buf == NULL) { pr_debug("eeprom_read_all: MALLOC FAIL!!"); return; } addr = 0x0; - - /* read 64K */ - for (j = 0; j < 16; j++) { + for (j = 0; j < 16; j++) /* read 64K */ + { len = 4096; - do { + do + { err = wimax_i2c_read(addr, buf, len); - } while (err < 0 ? ((retry--) > 0) : 0); - - { - /* dump EEPROM */ + } + while(err<0?((retry--)>0):0); + { /* dump EEPROM */ char print_buf[256] = {0}; char chr[8] = {0}; @@ -718,7 +721,7 @@ void eeprom_read_all() kfree(buf); eeprom_poweroff(); - if (retry < 0) + if(retry<0) pr_debug("eeprom error"); } @@ -734,13 +737,15 @@ void eeprom_erase_all() memset(buf, 0xff, 128); for (i = 0; i < 512; i++) { /* clear all EEPROM */ pr_debug("ERASE [0x%04x]\n", i * 128); - do { + do + { err = wimax_i2c_write(128 * i, buf, 128); - } while (err < 0 ? ((retry--) > 0) : 0); + } + while(err<0?((retry--)>0):0); } eeprom_poweroff(); - if (retry < 0) + if(retry<0) pr_debug("eeprom error"); } @@ -762,28 +767,28 @@ int eeprom_write_boot(void) g_wimax_image.offset = 0; while (g_wimax_image.size > g_wimax_image.offset) { - buffer = (u_char *)(g_wimax_image.data + g_wimax_image.offset); + buffer =(u_char *)(g_wimax_image.data + g_wimax_image.offset); ucsize = MAX_BOOT_WRITE_LENGTH; /* write buffer */ - do { - err = wimax_i2c_write( - (u_short)g_wimax_image.offset, buffer, ucsize); - } while (err < 0 ? ((retry--) > 0) : 0); + do + { + err = wimax_i2c_write((u_short)g_wimax_image.offset, buffer, ucsize); + } + while(err<0?((retry--)>0):0); g_wimax_image.offset += MAX_BOOT_WRITE_LENGTH; - if ((g_wimax_image.size - g_wimax_image.offset) - < MAX_BOOT_WRITE_LENGTH) { - buffer = (u_char *)(g_wimax_image.data + - g_wimax_image.offset); + if ((g_wimax_image.size - g_wimax_image.offset) < MAX_BOOT_WRITE_LENGTH) { + buffer = (u_char *)(g_wimax_image.data + g_wimax_image.offset); ucsize = g_wimax_image.size - g_wimax_image.offset; /* write last data */ - do { - err = wimax_i2c_write( - (u_short)g_wimax_image.offset, buffer, ucsize); - } while (err < 0 ? ((retry--) > 0) : 0); + do + { + err = wimax_i2c_write((u_short)g_wimax_image.offset, buffer, ucsize); + } + while(err<0?((retry--)>0):0); g_wimax_image.offset += MAX_BOOT_WRITE_LENGTH; } @@ -796,12 +801,12 @@ int eeprom_write_boot(void) vfree(g_wimax_image.data); g_wimax_image.data = NULL; } - - if (retry < 0) + if(retry<0) + { pr_debug("eeprom error"); - else - pr_debug("EEPROM WRITING DONE."); - + }else{ + pr_debug("EEPROM WRITING DONE."); +} return err; } diff --git a/drivers/net/wimax_cmc/wimax_i2c.h b/drivers/net/wimax_cmc/wimax_i2c.h index cadd762..dc4fd3b 100644..100755 --- a/drivers/net/wimax_cmc/wimax_i2c.h +++ b/drivers/net/wimax_cmc/wimax_i2c.h @@ -5,6 +5,7 @@ */ #ifndef __WIMAX_I2C_H__ #define __WIMAX_I2C_H__ +//#define DRIVER_BIT_BANG #include <linux/mutex.h> #define WIMAX_BOOTIMAGE_PATH "/system/etc/wimax_boot.bin" diff --git a/drivers/net/wimax_cmc/wimax_plat.h b/drivers/net/wimax_cmc/wimax_plat.h new file mode 100755 index 0000000..b71f055 --- /dev/null +++ b/drivers/net/wimax_cmc/wimax_plat.h @@ -0,0 +1,36 @@ +/** + * wimax_plat.h + * + * GPIO settings for specific HW + */ +#ifndef __WIMAX_PLAT_H__ +#define __WIMAX_PLAT_H__ + +#define WIMAX_EN GPIO_WIMAX_EN +#define WIMAX_RESET GPIO_WIMAX_RESET_N +#define WIMAX_USB_EN GPIO_WIMAX_USB_EN + +#define DEVICE_HSMMC s3c_device_hsmmc3 + +#define WIMAX_WAKEUP GPIO_WIMAX_WAKEUP +#define WIMAX_IF_MODE0 GPIO_WIMAX_IF_MODE0 +#define WIMAX_IF_MODE1 GPIO_WIMAX_IF_MODE1 +#define WIMAX_CON0 GPIO_WIMAX_CON0 +#define WIMAX_CON1 GPIO_WIMAX_CON1 +#define WIMAX_CON2 GPIO_WIMAX_CON2 +#define WIMAX_INT GPIO_WIMAX_INT + +#define I2C_SEL GPIO_WIMAX_I2C_CON +#define EEPROM_SCL GPIO_CMC_SCL_18V +#define EEPROM_SDA GPIO_CMC_SDA_18V + +#define UART_SEL1 GPIO_UART_SEL1 +#define UART_SEL GPIO_UART_SEL +#if defined(CONFIG_MACH_C1_REV02) +#define USB_SEL GPIO_USB_SW_EN_WIMAX +#endif /* CONFIG_MACH_C1_REV02 */ +#define DBGEN GPIO_WIMAX_DBGEN_28V//TBD +#define GPIO_LEVEL_LOW 0 +#define GPIO_LEVEL_HIGH 1 +#define GPIO_LEVEL_NONE 2 +#endif /* __WIMAX_PLAT_H__ */ diff --git a/drivers/net/wimax_cmc/wimax_sdio.c b/drivers/net/wimax_cmc/wimax_sdio.c index ece4b04..7e57a29 100644..100755 --- a/drivers/net/wimax_cmc/wimax_sdio.c +++ b/drivers/net/wimax_cmc/wimax_sdio.c @@ -370,58 +370,60 @@ void control_recv(struct net_adapter *adapter, void *buffer, u32 length) mutex_unlock(&adapter->control_lock); } -void prepare_skb(struct net_adapter *adapter, struct sk_buff *rx_skb) +void prepare_skb(struct net_adapter *adapter, struct sk_buff *rx_skb ) { - skb_reserve(rx_skb, - (ETHERNET_ADDRESS_LENGTH * 2) + - NET_IP_ALIGN); + skb_reserve(rx_skb, + (ETHERNET_ADDRESS_LENGTH * 2) + + NET_IP_ALIGN); - memcpy(skb_push(rx_skb, - (ETHERNET_ADDRESS_LENGTH * 2)), - adapter->eth_header, - (ETHERNET_ADDRESS_LENGTH * 2)); + memcpy(skb_push(rx_skb, + (ETHERNET_ADDRESS_LENGTH * 2)), + adapter->eth_header, + (ETHERNET_ADDRESS_LENGTH * 2)); - rx_skb->dev = adapter->net; - rx_skb->ip_summed = CHECKSUM_UNNECESSARY; + rx_skb->dev = adapter->net; + rx_skb->ip_summed = CHECKSUM_UNNECESSARY; } void flush_skb(struct net_adapter *adapter) { - if (adapter->rx_skb) { - dev_kfree_skb(adapter->rx_skb); - adapter->rx_skb = NULL; - } + if (adapter->rx_skb) { + dev_kfree_skb(adapter->rx_skb); + adapter->rx_skb = NULL; + } } struct sk_buff *fetch_skb(struct net_adapter *adapter) { - struct sk_buff *ret_skb; - if (adapter->rx_skb) { - ret_skb = adapter->rx_skb; - adapter->rx_skb = NULL; - return ret_skb; - } - ret_skb = dev_alloc_skb(WIMAX_MTU_SIZE+2+ - (ETHERNET_ADDRESS_LENGTH * 2) + - NET_IP_ALIGN); - if (!ret_skb) { - pr_debug("unable to allocate skb"); - return NULL; - } - prepare_skb(adapter, ret_skb); - return ret_skb; + struct sk_buff *ret_skb; + if (adapter->rx_skb) + { + ret_skb = adapter->rx_skb; + adapter->rx_skb = NULL; + return ret_skb; + } + ret_skb = dev_alloc_skb(WIMAX_MTU_SIZE+2+ + (ETHERNET_ADDRESS_LENGTH * 2) + + NET_IP_ALIGN); + if (!ret_skb) { + pr_debug("unable to allocate skb"); + return NULL; + } + prepare_skb(adapter, ret_skb); + return ret_skb; } void pull_skb(struct net_adapter *adapter) { - struct sk_buff *t_skb; - if (adapter->rx_skb == NULL) { - t_skb = dev_alloc_skb(WIMAX_MTU_SIZE+2+ - (ETHERNET_ADDRESS_LENGTH * 2) + - NET_IP_ALIGN); - if (!t_skb) { - pr_debug("unable to allocate skb"); - return; - } - prepare_skb(adapter, t_skb); - adapter->rx_skb = t_skb; + struct sk_buff *t_skb; + if (adapter->rx_skb == NULL) + { + t_skb = dev_alloc_skb(WIMAX_MTU_SIZE+2+ + (ETHERNET_ADDRESS_LENGTH * 2) + + NET_IP_ALIGN); + if (!t_skb) { + pr_debug("unable to allocate skb"); + return; + } + prepare_skb(adapter, t_skb); + adapter->rx_skb = t_skb; } } @@ -497,8 +499,7 @@ static void adapter_rx_packet(struct net_adapter *adapter) } } else { rx_skb = dev_alloc_skb(hdr->length + - (ETHERNET_ADDRESS_LENGTH * 2) + - NET_IP_ALIGN); + (ETHERNET_ADDRESS_LENGTH * 2) + NET_IP_ALIGN); if (!rx_skb) { pr_err("unable to allocate skb"); break; @@ -1087,7 +1088,7 @@ int con0_poll_thread(void *data) wake_lock(&g_cfg->wimax_driver_lock); - while ((g_cfg->power_state != CMC_POWERING_OFF) && + while ((g_cfg->power_state != CMC_POWERING_OFF) && (g_cfg->power_state != CMC_POWER_OFF)) { curr_val = adapter->pdata->is_modem_awake(); if ((prev_val && (!curr_val)) || (!curr_val)) { @@ -1096,9 +1097,8 @@ int con0_poll_thread(void *data) } prev_val = curr_val; wait_event_interruptible_timeout(adapter->con0_poll, - (g_cfg->power_state == CMC_POWERING_OFF) || - (g_cfg->power_state == CMC_POWER_OFF), - msecs_to_jiffies(40)); + (g_cfg->power_state == CMC_POWERING_OFF) || + (g_cfg->power_state == CMC_POWER_OFF), msecs_to_jiffies(40)); } wake_unlock(&g_cfg->wimax_driver_lock); do_exit(0); @@ -1227,9 +1227,8 @@ static int wimax_power_on(struct wimax732_platform_data *pdata) init_waitqueue_head(&adapter->modem_resp_event); count = 0; - while (!adapter->modem_resp) { - /*This command will start the - firmware download sequence through sdio*/ + while(!adapter->modem_resp) { + /*This command will start the firmware download sequence through sdio*/ send_cmd_packet(adapter, MSG_DRIVER_OK_REQ); ret = wait_event_interruptible_timeout( adapter->modem_resp_event, @@ -1282,7 +1281,7 @@ static int wimax_power_on(struct wimax732_platform_data *pdata) goto mac_request_fail; ret = wait_for_completion_interruptible_timeout( &adapter->mac, - msecs_to_jiffies((MAC_RETRY_COUNT - count) * + msecs_to_jiffies((MAC_RETRY_COUNT - count) * MAC_RETRY_INTERVAL)); if (ret == -ERESTARTSYS) { pr_err("-ERESTARTSYS MAC request fail"); @@ -1297,7 +1296,7 @@ static int wimax_power_on(struct wimax732_platform_data *pdata) adapter->wtm_task = kthread_create(con0_poll_thread, adapter, "%s", "wimax_con0_poll_thread"); if (adapter->wtm_task) - wake_up_process(adapter->wtm_task); + wake_up_process(adapter->wtm_task); } #endif adapter->uwibro_dev.minor = MISC_DYNAMIC_MINOR; @@ -1436,8 +1435,9 @@ static int wimax_power_off(struct wimax732_platform_data *pdata) adapter = (struct net_adapter *) pdata->adapter_data; g_cfg->power_state = CMC_POWERING_OFF; #ifdef WIMAX_CON0_POLL - if (g_cfg->wimax_mode == WTM_MODE) + if (g_cfg->wimax_mode == WTM_MODE) { wake_up_interruptible(&adapter->con0_poll); + } #endif cmc732_release_wake_irq(adapter); @@ -1565,14 +1565,14 @@ static long swmxdev_ioctl(struct file *file, u32 cmd, ret = eeprom_write_rev(); break; } - case CONTROL_IOCTL_WIMAX_CHECK_CERT: { + case CONTROL_IOCTL_WIMAX_CHECK_CERT: { pr_debug("CONTROL_IOCTL_WIMAX_CHECK_CERT"); wimax_power_off(gpdata); ret = eeprom_check_cert(); break; } case CONTROL_IOCTL_WIMAX_CHECK_CAL: { - pr_debug("CONTROL_IOCTL_WIMAX_CHECK_CAL"); + pr_debug("CONTROL_IOCTL_WIMAX_CHECK_CAL"); wimax_power_off(gpdata); ret = eeprom_check_cal(); break; diff --git a/drivers/net/wimax_cmc/wimax_sdio.h b/drivers/net/wimax_cmc/wimax_sdio.h index 998c695..46e81cb 100644..100755 --- a/drivers/net/wimax_cmc/wimax_sdio.h +++ b/drivers/net/wimax_cmc/wimax_sdio.h @@ -246,8 +246,8 @@ struct net_adapter { struct task_struct *wtm_task; #endif struct sk_buff *rx_skb; - u8 *receive_buffer; - u32 buff_len; + u8 *receive_buffer; + u32 buff_len; u32 image_offset; u32 msg_enable; s32 wake_irq; diff --git a/drivers/power/power_supply_sysfs.c b/drivers/power/power_supply_sysfs.c index 009e905..a647e74 100644 --- a/drivers/power/power_supply_sysfs.c +++ b/drivers/power/power_supply_sysfs.c @@ -42,14 +42,15 @@ static ssize_t power_supply_show_property(struct device *dev, struct device_attribute *attr, char *buf) { static char *type_text[] = { - "Battery", "UPS", "Mains", "USB", - "USB_DCP", "USB_CDP", "USB_ACA" + "Unknown", "Battery", "UPS", "Mains", "USB", + "USB_DCP", "USB_CDP", "USB_ACA", + "DOCK", "MISC", "WIRELESS", "OTG" }; static char *status_text[] = { "Unknown", "Charging", "Discharging", "Not charging", "Full" }; static char *charge_type[] = { - "Unknown", "N/A", "Trickle", "Fast" + "Unknown", "N/A", "Trickle", "Fast", "Slow" }; static char *health_text[] = { "Unknown", "Good", "Overheat", "Dead", "Over voltage", diff --git a/drivers/power/sec_battery_u1.c b/drivers/power/sec_battery_u1.c index 3dcd150..112a55d 100644 --- a/drivers/power/sec_battery_u1.c +++ b/drivers/power/sec_battery_u1.c @@ -214,7 +214,7 @@ #endif #ifdef CONFIG_TARGET_LOCALE_NA -#define FULL_CHARGE_COND_VOLTAGE (4000 * 1000) /* 4.00 V */ +#define FULL_CHARGE_COND_VOLTAGE (4150 * 1000) /* 4.15 V */ #else #define FULL_CHARGE_COND_VOLTAGE (4150 * 1000) /* 4.15 V */ #endif @@ -527,14 +527,6 @@ static int sec_bat_get_property(struct power_supply *ps, break; #endif case POWER_SUPPLY_PROP_CAPACITY: -#ifdef CONFIG_TARGET_LOCALE_NA - if (info->charging_status != POWER_SUPPLY_STATUS_FULL - && info->batt_soc == 100) { - val->intval = 99; - break; - } -#endif /*CONFIG_TARGET_LOCALE_NA */ - if (info->charging_status == POWER_SUPPLY_STATUS_FULL) { val->intval = 100; break; @@ -1993,6 +1985,9 @@ static bool sec_bat_check_ing_level_trigger(struct sec_bat_info *info) #endif if (info->batt_vcell >= FULL_CHARGE_COND_VOLTAGE) { +#if defined(CONFIG_TARGET_LOCALE_NA) + if (info->batt_soc > 99){ +#endif /* USB full charged */ info->charging_int_full_count++; if (info-> @@ -2010,6 +2005,9 @@ static bool sec_bat_check_ing_level_trigger(struct sec_bat_info *info) __func__, info-> charging_int_full_count); +#if defined(CONFIG_TARGET_LOCALE_NA) + } +#endif } else { info->charging_int_full_count = 0; diff --git a/drivers/sensor/k3dh.c b/drivers/sensor/k3dh.c index a44c30d..5669300 100644 --- a/drivers/sensor/k3dh.c +++ b/drivers/sensor/k3dh.c @@ -79,8 +79,45 @@ struct k3dh_data { struct k3dh_acc acc_xyz; u8 ctrl_reg1_shadow; atomic_t opened; /* opened implies enabled */ + struct accel_platform_data *acc_pdata; }; +static struct k3dh_data *g_k3dh; + + +static void k3dh_xyz_position_adjust(struct k3dh_acc *acc, + int position) +{ + const int position_map[][3][3] = { + {{ 0, -1, 0}, { 1, 0, 0}, { 0, 0, 1} }, /* 0 top/upper-left */ + {{ 1, 0, 0}, { 0, 1, 0}, { 0, 0, 1} }, /* 1 top/upper-right */ + {{ 0, 1, 0}, {-1, 0, 0}, { 0, 0, 1} }, /* 2 top/lower-right */ + {{-1, 0, 0}, { 0, -1, 0}, { 0, 0, 1} }, /* 3 top/lower-left */ + {{ 0, 1, 0}, { 1, 0, 0}, { 0, 0, -1} }, /* 4 bottom/upper-left */ + {{-1, 0, 0}, { 0, 1, 0}, { 0, 0, -1} }, /* 5 bottom/upper-right */ + {{ 0, -1, 0}, {-1, 0, 0}, { 0, 0, -1} }, /* 6 bottom/lower-right */ + {{ 1, 0, 0}, { 0, -1, 0}, { 0, 0, -1} }, /* 7 bottom/lower-left*/ + }; + + struct k3dh_acc xyz_adjusted = {0,}; + s16 raw[3] = {0,}; + int j; + raw[0] = acc->x; + raw[1] = acc->y; + raw[2] = acc->z; + for (j = 0; j < 3; j++) { + xyz_adjusted.x += + (position_map[position][0][j] * raw[j]); + xyz_adjusted.y += + (position_map[position][1][j] * raw[j]); + xyz_adjusted.z += + (position_map[position][2][j] * raw[j]); + } + acc->x = xyz_adjusted.x; + acc->y = xyz_adjusted.y; + acc->z = xyz_adjusted.z; +} + /* Read X,Y and Z-axis acceleration raw data */ static int k3dh_read_accel_raw_xyz(struct k3dh_data *data, struct k3dh_acc *acc) @@ -101,21 +138,23 @@ static int k3dh_read_accel_raw_xyz(struct k3dh_data *data, acc->y = (acc_data[3] << 8) | acc_data[2]; acc->z = (acc_data[5] << 8) | acc_data[4]; -#if defined(CONFIG_MACH_U1_NA_SPR) - acc->x = -acc->x >> 4; -#else acc->x = acc->x >> 4; -#endif acc->y = acc->y >> 4; - #if defined(CONFIG_MACH_U1_NA_SPR_REV05) \ - || defined(CONFIG_MACH_U1_NA_SPR_EPIC2_REV00) \ - || defined(CONFIG_MACH_U1_NA_USCC_REV05) \ - || defined(CONFIG_MACH_Q1_BD) +#if defined(CONFIG_MACH_U1_NA_SPR_REV05) \ + || defined(CONFIG_MACH_U1_NA_SPR_EPIC2_REV00) \ + || defined(CONFIG_MACH_U1_NA_USCC_REV05) \ + || defined(CONFIG_MACH_Q1_BD) \ + || defined(CONFIG_MACH_U1_NA_USCC) \ + || defined(CONFIG_MACH_U1_NA_SPR) acc->z = -acc->z >> 4; - #else +#else acc->z = acc->z >> 4; - #endif +#endif + if (g_k3dh->acc_pdata && + g_k3dh->acc_pdata->axis_adjust) + k3dh_xyz_position_adjust(acc, + g_k3dh->acc_pdata->accel_get_position()); return 0; } @@ -603,6 +642,7 @@ static int k3dh_probe(struct i2c_client *client, } data->client = client; + g_k3dh = data; i2c_set_clientdata(client, data); init_completion(&data->data_ready); @@ -622,6 +662,14 @@ static int k3dh_probe(struct i2c_client *client, } pdata = client->dev.platform_data; + data->acc_pdata = pdata; + /* accelerometer position set */ + if (!pdata) { + pr_err("using defualt position\n"); + } else { + pr_info("successful, position = %d\n", + pdata->accel_get_position()); + } #if defined(CONFIG_MACH_U1) || defined(CONFIG_MACH_TRATS) /* creating class/device for test */ diff --git a/drivers/sensor/k3g.c b/drivers/sensor/k3g.c index 7ca6d6f..1c4c329 100644 --- a/drivers/sensor/k3g.c +++ b/drivers/sensor/k3g.c @@ -259,8 +259,14 @@ static int k3g_report_gyro_values(struct k3g_data *k3g_data) return k3g_restart_fifo(k3g_data); } + #if defined(CONFIG_MACH_U1_NA_SPR) \ + || defined(CONFIG_MACH_U1_NA_USCC) + input_report_rel(k3g_data->input_dev, REL_RX, -data.x); + input_report_rel(k3g_data->input_dev, REL_RY, -data.y); + #else input_report_rel(k3g_data->input_dev, REL_RX, data.x); input_report_rel(k3g_data->input_dev, REL_RY, data.y); + #endif input_report_rel(k3g_data->input_dev, REL_RZ, data.z); input_sync(k3g_data->input_dev); diff --git a/drivers/staging/westbridge/astoria/device/cyasdevice_na_spr.c b/drivers/staging/westbridge/astoria/device/cyasdevice_na_spr.c index ef3970c..53663f2 100755 --- a/drivers/staging/westbridge/astoria/device/cyasdevice_na_spr.c +++ b/drivers/staging/westbridge/astoria/device/cyasdevice_na_spr.c @@ -442,10 +442,40 @@ static ssize_t store_cyas_wbcid(struct device *dev, static DEVICE_ATTR(wbcid, S_IRUGO | S_IWUSR, show_cyas_wbcid, store_cyas_wbcid); #endif + +extern struct class *sec_class; +static struct device *sd_detection_cmd_dev; +static ssize_t sd_detection_cmd_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ + unsigned int detect; + detect = cy_as_hal_detect_SD(); + pr_info("%s : detect = %d.\n", __func__, detect); + if (detect) { + pr_debug("sdhci: card inserted.\n"); + return sprintf(buf, "Insert\n"); + } else { + pr_debug("sdhci: card removed.\n"); + return sprintf(buf, "Remove\n"); + } +} + +static DEVICE_ATTR(status, 0444, sd_detection_cmd_show, NULL); static struct platform_device *westbridge_pd; static int __devinit wb_probe(struct platform_device *devptr) { + if (sd_detection_cmd_dev == NULL) { + sd_detection_cmd_dev = + device_create(sec_class, NULL, 0, + NULL, "sdcard"); + if (IS_ERR(sd_detection_cmd_dev)) + pr_err("Fail to create sysfs dev\n"); + + if (device_create_file(sd_detection_cmd_dev, + &dev_attr_status) < 0) + pr_err("Fail to create sysfs file\n"); + } cy_as_hal_print_message("%s called\n", __func__); return 0; } diff --git a/drivers/usb/core/quirks.c b/drivers/usb/core/quirks.c index df6cfa4..5da45eb 100644 --- a/drivers/usb/core/quirks.c +++ b/drivers/usb/core/quirks.c @@ -173,9 +173,11 @@ static const struct usb_device_id usb_quirk_list[] = { { USB_DEVICE(0x04cc, 0x2333), .driver_info = USB_QUIRK_HSIC_TUNE }, /* Qualcomm MDM9x15 */ - { USB_DEVICE(0x05c6, 0x9048), .driver_info = USB_QUIRK_HSIC_TUNE }, + { USB_DEVICE(0x05c6, 0x9048), + .driver_info = USB_QUIRK_HSIC_TUNE | USB_QUIRK_NO_DPM_RESUME}, - { USB_DEVICE(0x05c6, 0x904C), .driver_info = USB_QUIRK_HSIC_TUNE }, + { USB_DEVICE(0x05c6, 0x904C), + .driver_info = USB_QUIRK_HSIC_TUNE | USB_QUIRK_NO_DPM_RESUME}, { } /* terminating entry must be last */ }; diff --git a/drivers/usb/core/sec-dock.h b/drivers/usb/core/sec-dock.h index 73c4ea6..4fdf351 100644 --- a/drivers/usb/core/sec-dock.h +++ b/drivers/usb/core/sec-dock.h @@ -23,7 +23,8 @@ static struct usb_device_id battery_notify_exception_table[] = { { USB_DEVICE(0x1519, 0x0020), }, /* HSIC Device */ { USB_DEVICE(0x05c6, 0x904c), }, /* Qualcomm modem */ { USB_DEVICE(0x05c6, 0x9008), }, /* Qualcomm modem */ -{ USB_DEVICE(0x08bb, 0x27c4), }, /* TI USB Audio DAC */ +{ USB_DEVICE(0x08bb, 0x2704), }, /* TI USB Audio DAC 1 */ +{ USB_DEVICE(0x08bb, 0x27c4), }, /* TI USB Audio DAC 2 */ { } /* Terminating entry */ }; @@ -79,7 +80,9 @@ static int call_battery_notify(struct usb_device *dev, bool bOnOff) /* Smart Dock hub must be skipped */ if ((le16_to_cpu(dev->descriptor.idVendor) == 0x1a40 && - le16_to_cpu(dev->descriptor.idProduct) == 0x0101)) { + le16_to_cpu(dev->descriptor.idProduct) == 0x0101) || + (le16_to_cpu(dev->descriptor.idVendor) == 0x0424 && + le16_to_cpu(dev->descriptor.idProduct) == 0x2514)) { if (bOnOff) is_smartdock = 1; else diff --git a/drivers/usb/gadget/epautoconf.c b/drivers/usb/gadget/epautoconf.c index 212f8fc..da8482e 100644 --- a/drivers/usb/gadget/epautoconf.c +++ b/drivers/usb/gadget/epautoconf.c @@ -345,6 +345,11 @@ struct usb_ep *usb_ep_autoconfig ( #endif if (ep && ep_matches (gadget, ep, desc)) return ep; + } else if (USB_ENDPOINT_XFER_ISOC == type + && (USB_DIR_IN & desc->bEndpointAddress)) { + ep = find_ep(gadget, "ep15-iso"); + if (ep && ep_matches(gadget, ep, desc)) + return ep; } } diff --git a/drivers/usb/gadget/s3c_udc.h b/drivers/usb/gadget/s3c_udc.h index c6bf986..03ee411 100644 --- a/drivers/usb/gadget/s3c_udc.h +++ b/drivers/usb/gadget/s3c_udc.h @@ -92,7 +92,7 @@ */ typedef enum ep_type { - ep_control, ep_bulk_in, ep_bulk_out, ep_interrupt + ep_control, ep_bulk_in, ep_bulk_out, ep_interrupt, ep_iso_in } ep_type_t; struct s3c_ep { diff --git a/drivers/usb/gadget/s3c_udc_otg.c b/drivers/usb/gadget/s3c_udc_otg.c index a4f33cd..6a28e4f 100644 --- a/drivers/usb/gadget/s3c_udc_otg.c +++ b/drivers/usb/gadget/s3c_udc_otg.c @@ -672,13 +672,17 @@ static void set_max_pktsize(struct s3c_udc *dev, enum usb_device_speed speed) } else { ep0_fifo_size = 64; ep_fifo_size = 64; - ep_fifo_size2 = 64; + ep_fifo_size2 = 1023; dev->gadget.speed = USB_SPEED_FULL; } dev->ep[0].ep.maxpacket = ep0_fifo_size; - for (i = 1; i < S3C_MAX_ENDPOINTS; i++) - dev->ep[i].ep.maxpacket = ep_fifo_size; + for (i = 1; i < S3C_MAX_ENDPOINTS; i++) { + if (dev->ep[i].bmAttributes == USB_ENDPOINT_XFER_ISOC) + dev->ep[i].ep.maxpacket = ep_fifo_size2; + else + dev->ep[i].ep.maxpacket = ep_fifo_size; + } /* EP0 - Control IN (64 bytes)*/ ep_ctrl = __raw_readl(dev->regs + S3C_UDC_OTG_DIEPCTL(EP0_CON)); @@ -710,6 +714,7 @@ static int s3c_ep_enable(struct usb_ep *_ep, /* xfer types must match, except that interrupt ~= bulk */ if (ep->bmAttributes != desc->bmAttributes && ep->bmAttributes != USB_ENDPOINT_XFER_BULK + && ep->bmAttributes != USB_ENDPOINT_XFER_ISOC && desc->bmAttributes != USB_ENDPOINT_XFER_INT) { DEBUG("%s: %s type mismatch\n", __func__, _ep->name); @@ -1176,16 +1181,16 @@ static struct s3c_udc memory = { }, .ep[15] = { .ep = { - .name = "ep15-int", + .name = "ep15-iso", .ops = &s3c_ep_ops, - .maxpacket = EP_FIFO_SIZE, + .maxpacket = EP_FIFO_SIZE2, }, .dev = &memory, .bEndpointAddress = USB_DIR_IN | 15, - .bmAttributes = USB_ENDPOINT_XFER_INT, + .bmAttributes = USB_ENDPOINT_XFER_ISOC, - .ep_type = ep_interrupt, + .ep_type = ep_iso_in, .fifo = (unsigned int) S3C_UDC_OTG_EP15_FIFO, }, }; diff --git a/drivers/usb/host/ehci-s5p.c b/drivers/usb/host/ehci-s5p.c index 78399c2..3ef4856 100644 --- a/drivers/usb/host/ehci-s5p.c +++ b/drivers/usb/host/ehci-s5p.c @@ -375,6 +375,8 @@ static int s5p_ehci_runtime_resume(struct device *dev) usb_root_hub_lost_power(hcd->self.root_hub); ehci_writel(ehci, FLAG_CF, &ehci->regs->configured_flag); + ehci_writel(ehci, INTR_MASK, &ehci->regs->intr_enable); + (void)ehci_readl(ehci, &ehci->regs->intr_enable); /* here we "know" root ports should always stay powered */ ehci_port_power(ehci, 1); diff --git a/drivers/usb/host/ohci-s5p.c b/drivers/usb/host/ohci-s5p.c index 641e40c..68eecfd 100644 --- a/drivers/usb/host/ohci-s5p.c +++ b/drivers/usb/host/ohci-s5p.c @@ -173,16 +173,18 @@ static int ohci_hcd_s5p_drv_runtime_resume(struct device *dev) struct s5p_ohci_platdata *pdata = pdev->dev.platform_data; struct s5p_ohci_hcd *s5p_ohci = platform_get_drvdata(pdev); struct usb_hcd *hcd = s5p_ohci->hcd; + int ret = 0; if (dev->power.is_suspended) return 0; if (pdata->phy_resume) - pdata->phy_resume(pdev, S5P_USB_PHY_HOST); - /* Mark hardware accessible again as we are out of D3 state by now */ - set_bit(HCD_FLAG_HW_ACCESSIBLE, &hcd->flags); + ret = pdata->phy_resume(pdev, S5P_USB_PHY_HOST); - ohci_finish_controller_resume(hcd); + if (!ret) { + set_bit(HCD_FLAG_HW_ACCESSIBLE, &hcd->flags); + ohci_finish_controller_resume(hcd); + } return 0; } @@ -473,6 +475,9 @@ static void ohci_hcd_s5p_drv_shutdown(struct platform_device *pdev) if (hcd->driver->shutdown) hcd->driver->shutdown(hcd); + + clear_bit(HCD_FLAG_HW_ACCESSIBLE, &hcd->flags); + } static const struct dev_pm_ops ohci_s5p_pm_ops = { diff --git a/include/linux/mmc/host.h b/include/linux/mmc/host.h index df914ad..fcdb5f3 100644 --- a/include/linux/mmc/host.h +++ b/include/linux/mmc/host.h @@ -266,7 +266,11 @@ struct mmc_host { int clk_requests; /* internal reference counter */ unsigned int clk_delay; /* number of MCI clk hold cycles */ bool clk_gated; /* clock gated */ +#ifdef CONFIG_WIMAX_CMC + struct work_struct clk_gate_work; /* delayed clock gate */ +#else struct delayed_work clk_gate_work; /* delayed clock gate */ +#endif unsigned int clk_old; /* old clock value cache */ spinlock_t clk_lock; /* lock for clk fields */ struct mutex clk_gate_mutex; /* mutex for clock gating */ diff --git a/include/linux/power_supply.h b/include/linux/power_supply.h index c5b958b..7a1653e 100644 --- a/include/linux/power_supply.h +++ b/include/linux/power_supply.h @@ -44,6 +44,7 @@ enum { POWER_SUPPLY_CHARGE_TYPE_NONE, POWER_SUPPLY_CHARGE_TYPE_TRICKLE, POWER_SUPPLY_CHARGE_TYPE_FAST, + POWER_SUPPLY_CHARGE_TYPE_SLOW, }; enum { @@ -128,17 +129,19 @@ enum power_supply_property { }; enum power_supply_type { - POWER_SUPPLY_TYPE_BATTERY = 0, + POWER_SUPPLY_TYPE_UNKNOWN = 0, + POWER_SUPPLY_TYPE_BATTERY, POWER_SUPPLY_TYPE_UPS, POWER_SUPPLY_TYPE_MAINS, POWER_SUPPLY_TYPE_USB, /* Standard Downstream Port */ POWER_SUPPLY_TYPE_USB_DCP, /* Dedicated Charging Port */ POWER_SUPPLY_TYPE_USB_CDP, /* Charging Downstream Port */ POWER_SUPPLY_TYPE_USB_ACA, /* Accessory Charger Adapters */ - POWER_SUPPLY_TYPE_OTG, POWER_SUPPLY_TYPE_DOCK, POWER_SUPPLY_TYPE_MISC, POWER_SUPPLY_TYPE_WIRELESS, + POWER_SUPPLY_TYPE_UARTOFF, + POWER_SUPPLY_TYPE_OTG, }; enum { @@ -255,6 +258,9 @@ extern struct power_supply *power_supply_get_by_name(char *name); extern void power_supply_changed(struct power_supply *psy); extern int power_supply_am_i_supplied(struct power_supply *psy); extern int power_supply_set_battery_charged(struct power_supply *psy); +extern int power_supply_set_current_limit(struct power_supply *psy, int limit); +extern int power_supply_set_online(struct power_supply *psy, bool enable); +extern int power_supply_set_charge_type(struct power_supply *psy, int type); #if defined(CONFIG_POWER_SUPPLY) || defined(CONFIG_POWER_SUPPLY_MODULE) extern int power_supply_is_system_supplied(void); diff --git a/include/linux/usb/quirks.h b/include/linux/usb/quirks.h index ef75b0b..9ca6760 100644 --- a/include/linux/usb/quirks.h +++ b/include/linux/usb/quirks.h @@ -39,4 +39,7 @@ /* device needs hsic specific tunning */ #define USB_QUIRK_HSIC_TUNE 0x00000200 +/* resume bus driver after dpm resume */ +#define USB_QUIRK_NO_DPM_RESUME 0x00000400 + #endif /* __LINUX_USB_QUIRKS_H */ diff --git a/init/main.c b/init/main.c index 5596de7..61a880a 100644 --- a/init/main.c +++ b/init/main.c @@ -79,6 +79,12 @@ #include <asm/smp.h> #endif +#if defined (CONFIG_MACH_U1_NA_SPR) +#ifdef CONFIG_SEC_DEBUG +#include <linux/kernel_sec_common.h> +#endif +#endif + static int kernel_init(void *); extern void init_IRQ(void); @@ -621,6 +627,11 @@ asmlinkage void __init start_kernel(void) sfi_init_late(); ftrace_init(); +#if defined (CONFIG_MACH_U1_NA_SPR) +#ifdef CONFIG_SEC_DEBUG + kernel_sec_init(); +#endif +#endif /* Do the rest non-__init'ed, we're now alive */ rest_init(); diff --git a/kernel/Makefile b/kernel/Makefile index 2d64cfc..9f66566 100644 --- a/kernel/Makefile +++ b/kernel/Makefile @@ -107,6 +107,9 @@ obj-$(CONFIG_PERF_EVENTS) += events/ obj-$(CONFIG_USER_RETURN_NOTIFIER) += user-return-notifier.o obj-$(CONFIG_PADATA) += padata.o obj-$(CONFIG_CRASH_DUMP) += crash_dump.o +ifeq ($(CONFIG_MACH_U1_NA_SPR),y) +obj-$(CONFIG_SEC_DEBUG) += kernel_sec_debug.o +endif ifneq ($(CONFIG_SCHED_OMIT_FRAME_POINTER),y) # According to Alan Modra <alan@linuxcare.com.au>, the -fno-omit-frame-pointer is diff --git a/kernel/kernel_sec_debug.c b/kernel/kernel_sec_debug.c index 6ff0793..4fc4527 100644 --- a/kernel/kernel_sec_debug.c +++ b/kernel/kernel_sec_debug.c @@ -160,7 +160,7 @@ void kernel_sec_set_cp_upload(void) } mdelay(10); if (++wait_count > 500) { - printk(KERN_EMERG"- Fail to set CP uploadmode." / + printk(KERN_EMERG"- Fail to set CP uploadmode." \ "cp_irq_mask: 0x%04X\n", cp_irq_mask); break; } @@ -566,7 +566,7 @@ bool kernel_set_debug_level(int level) } else {*/ - printk(KERN_NOTICE "(kernel_set_debug_level)" / + printk(KERN_NOTICE "(kernel_set_debug_level)" \ " sec_set_param_value is not intialized !!\n"); return 0; /*}*/ diff --git a/sound/core/pcm_lib.c b/sound/core/pcm_lib.c index 3388442..397d9ad 100644 --- a/sound/core/pcm_lib.c +++ b/sound/core/pcm_lib.c @@ -1765,7 +1765,10 @@ static int wait_for_avail(struct snd_pcm_substream *substream, if (runtime->no_period_wakeup) wait_time = MAX_SCHEDULE_TIMEOUT; else { - wait_time = 10; + if (substream->pcm->card->number != 0) + wait_time = 1; + else + wait_time = 10; if (runtime->rate) { long t = runtime->period_size * 2 / runtime->rate; wait_time = max(t, wait_time); diff --git a/sound/soc/samsung/idma.c b/sound/soc/samsung/idma.c index 31fa305..8128507 100644 --- a/sound/soc/samsung/idma.c +++ b/sound/soc/samsung/idma.c @@ -523,6 +523,14 @@ void idma_init(void *regs) #endif } +#ifdef CONFIG_SND_SAMSUNG_ALP +int idma_is_running(void) +{ + return (idma.trigger_stat == LPAM_DMA_START) ? 1 : 0; +} +EXPORT_SYMBOL(idma_is_running); +#endif + #ifdef CONFIG_SND_SAMSUNG_RP int idma_irq_callback(void) { diff --git a/sound/soc/samsung/idma.h b/sound/soc/samsung/idma.h index 0480974..d132aa1 100644 --- a/sound/soc/samsung/idma.h +++ b/sound/soc/samsung/idma.h @@ -81,4 +81,6 @@ extern void idma_init(void *regs); /* These functions are used for srp driver. */ extern int idma_irq_callback(void); extern void idma_stop(void); +extern int idma_is_running(void); + #endif /* __S3C_IDMA_H_ */ diff --git a/usr/d710_initramfs.list b/usr/d710_initramfs.list new file mode 100644 index 0000000..fa40906 --- /dev/null +++ b/usr/d710_initramfs.list @@ -0,0 +1,29 @@ +dir /cache 755 0 0 +dir /dev 755 0 0 +dir /dev/block 755 0 0 +nod /dev/block/mmcblk0 600 0 0 b 179 0 +nod /dev/block/mmcblk0p1 600 0 0 b 179 1 +nod /dev/block/mmcblk0p2 600 0 0 b 179 2 +nod /dev/block/mmcblk0p3 600 0 0 b 179 3 +nod /dev/block/mmcblk0p4 600 0 0 b 179 4 +nod /dev/block/mmcblk0p5 600 0 0 b 179 5 +nod /dev/block/mmcblk0p6 600 0 0 b 179 6 +nod /dev/block/mmcblk0p7 600 0 0 b 179 7 +nod /dev/block/mmcblk0p8 600 0 0 b 179 8 +nod /dev/block/mmcblk0p9 600 0 0 b 179 9 +nod /dev/block/mmcblk0p10 600 0 0 b 179 10 +nod /dev/block/mmcblk0p11 600 0 0 b 179 11 +nod /dev/block/mmcblk0p12 600 0 0 b 179 12 +nod /dev/block/cyasblkdevblk0 600 0 0 b 253 0 +nod /dev/block/cyasblkdevblk0p1 600 0 0 b 253 1 +slink /init /stage1/init 777 0 0 +dir /proc 755 0 0 +dir /stage1 755 0 0 +file /stage1/busybox source/usr/d710_initramfs_files/busybox 755 0 0 +file /stage1/init source/usr/d710_initramfs_files/init 755 0 0 +file /stage1/read_boot_headers source/usr/d710_initramfs_files/read_boot_headers 755 0 0 +dir /sys 755 0 0 +dir /mnt 755 0 0 +dir /mnt/.lfs 755 0 0 +dir /lib 755 0 0 +dir /lib/modules 755 0 0 diff --git a/usr/d710_initramfs_files/busybox b/usr/d710_initramfs_files/busybox Binary files differnew file mode 100755 index 0000000..9496f7a --- /dev/null +++ b/usr/d710_initramfs_files/busybox diff --git a/usr/d710_initramfs_files/init b/usr/d710_initramfs_files/init new file mode 100755 index 0000000..7035361 --- /dev/null +++ b/usr/d710_initramfs_files/init @@ -0,0 +1,31 @@ +#!/stage1/busybox sh +export _PATH="$PATH" +export PATH=/stage1 +BOOT_IMAGE=/dev/block/mmcblk0p5 + +busybox cd / +busybox date >>boot.txt +exec >>boot.txt 2>&1 +busybox rm init +busybox mount -t proc proc /proc +busybox mount -t sysfs sysfs /sys + +eval $(read_boot_headers ${BOOT_IMAGE}) + +load_offset=$boot_offset +load_len=$boot_len + +if busybox grep -q bootmode=2 /proc/cmdline ; then + # recovery boot + load_offset=$recovery_offset + load_len=$recovery_len +fi + +busybox dd bs=512 if=${BOOT_IMAGE} skip=$load_offset count=$load_len | busybox zcat | busybox cpio -i + +busybox umount /sys +busybox umount /proc +busybox date >>boot.txt +busybox rm -fr /stage1 /dev/* +export PATH="${_PATH}" +exec /init diff --git a/usr/d710_initramfs_files/read_boot_headers b/usr/d710_initramfs_files/read_boot_headers Binary files differnew file mode 100755 index 0000000..3147d45 --- /dev/null +++ b/usr/d710_initramfs_files/read_boot_headers |