aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--arch/arm64/configs/lineageos_bullhead_defconfig677
-rw-r--r--drivers/leds/leds-qpnp.c14
-rw-r--r--drivers/mmc/core/core.c2
-rw-r--r--drivers/video/msm/mdss/Makefile2
-rw-r--r--drivers/video/msm/mdss/mdss_dsi_panel.c9
-rw-r--r--drivers/video/msm/mdss/mdss_fb.c5
-rw-r--r--drivers/video/msm/mdss/mdss_livedisplay.c678
-rw-r--r--drivers/video/msm/mdss/mdss_livedisplay.h108
-rw-r--r--drivers/video/msm/mdss/mdss_mdp.h1
-rw-r--r--drivers/video/msm/mdss/mdss_mdp_pp.c102
-rw-r--r--drivers/video/msm/mdss/mdss_panel.h4
-rw-r--r--fs/exec.c9
-rw-r--r--fs/namei.c10
-rw-r--r--fs/proc/cmdline.c28
-rw-r--r--fs/readdir.c15
-rw-r--r--include/linux/dcache.h7
-rw-r--r--include/linux/fs.h1
-rw-r--r--include/linux/sched.h8
-rw-r--r--include/linux/uidgid.h3
-rw-r--r--kernel/exit.c4
-rw-r--r--kernel/fork.c2
-rw-r--r--kernel/sched/core.c32
22 files changed, 1714 insertions, 7 deletions
diff --git a/arch/arm64/configs/lineageos_bullhead_defconfig b/arch/arm64/configs/lineageos_bullhead_defconfig
new file mode 100644
index 00000000000..983c23fbfb4
--- /dev/null
+++ b/arch/arm64/configs/lineageos_bullhead_defconfig
@@ -0,0 +1,677 @@
+CONFIG_AUDIT=y
+CONFIG_NO_HZ=y
+CONFIG_HIGH_RES_TIMERS=y
+CONFIG_IRQ_TIME_ACCOUNTING=y
+CONFIG_RCU_FAST_NO_HZ=y
+CONFIG_RCU_BOOST=y
+CONFIG_LOG_BUF_SHIFT=20
+CONFIG_CGROUPS=y
+CONFIG_CGROUP_DEBUG=y
+CONFIG_CGROUP_FREEZER=y
+CONFIG_CPUSETS=y
+CONFIG_CGROUP_CPUACCT=y
+CONFIG_RESOURCE_COUNTERS=y
+CONFIG_CGROUP_SCHED=y
+CONFIG_CFS_BANDWIDTH=y
+CONFIG_RT_GROUP_SCHED=y
+CONFIG_SCHED_HMP=y
+CONFIG_NAMESPACES=y
+# CONFIG_UTS_NS is not set
+# CONFIG_PID_NS is not set
+CONFIG_BLK_DEV_INITRD=y
+CONFIG_RD_BZIP2=y
+CONFIG_RD_LZMA=y
+CONFIG_CC_OPTIMIZE_FOR_SIZE=y
+CONFIG_PANIC_TIMEOUT=5
+CONFIG_KALLSYMS_ALL=y
+CONFIG_EMBEDDED=y
+# CONFIG_SLUB_DEBUG is not set
+CONFIG_PROFILING=y
+CONFIG_CC_STACKPROTECTOR_STRONG=y
+CONFIG_ARCH_MMAP_RND_BITS=24
+CONFIG_ARCH_MMAP_RND_COMPAT_BITS=16
+CONFIG_PARTITION_ADVANCED=y
+CONFIG_ARCH_MSM=y
+CONFIG_ARCH_MSM8994=y
+CONFIG_ARCH_MSM8994_V1_TLBI_WA=y
+CONFIG_ARCH_MSM8992=y
+CONFIG_PCI_MSM=y
+CONFIG_ARM64_A57_ERRATA_832075=y
+CONFIG_SMP=y
+CONFIG_SCHED_MC=y
+CONFIG_ARCH_WANTS_CTXSW_LOGGING=y
+CONFIG_NR_CPUS=6
+CONFIG_PREEMPT=y
+CONFIG_HZ_300=y
+CONFIG_ARMV7_COMPAT=y
+CONFIG_BALANCE_ANON_FILE_RECLAIM=y
+CONFIG_ZSMALLOC=y
+CONFIG_SECCOMP=y
+CONFIG_BUILD_ARM64_APPENDED_DTB_IMAGE=y
+# CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set
+CONFIG_COMPAT=y
+CONFIG_PM_AUTOSLEEP=y
+CONFIG_PM_WAKELOCKS=y
+CONFIG_PM_WAKELOCKS_LIMIT=0
+CONFIG_PM_RUNTIME=y
+CONFIG_SUSPEND_TIME=y
+CONFIG_CPU_FREQ=y
+CONFIG_CPU_FREQ_GOV_POWERSAVE=y
+CONFIG_CPU_FREQ_GOV_USERSPACE=y
+CONFIG_CPU_FREQ_GOV_ONDEMAND=y
+CONFIG_CPU_FREQ_GOV_INTERACTIVE=y
+CONFIG_CPU_BOOST=y
+CONFIG_CPU_IDLE=y
+CONFIG_CPU_IDLE_MULTIPLE_DRIVERS=y
+# CONFIG_CPU_IDLE_GOV_LADDER is not set
+# CONFIG_CPU_IDLE_GOV_MENU is not set
+CONFIG_NET=y
+CONFIG_PACKET=y
+CONFIG_UNIX=y
+CONFIG_XFRM_USER=y
+CONFIG_XFRM_STATISTICS=y
+CONFIG_NET_KEY=y
+CONFIG_INET=y
+CONFIG_IP_MULTICAST=y
+CONFIG_IP_ADVANCED_ROUTER=y
+CONFIG_IP_MULTIPLE_TABLES=y
+CONFIG_IP_ROUTE_VERBOSE=y
+CONFIG_IP_PNP=y
+CONFIG_IP_PNP_DHCP=y
+CONFIG_INET_AH=y
+CONFIG_INET_ESP=y
+CONFIG_INET_IPCOMP=y
+# CONFIG_INET_XFRM_MODE_BEET is not set
+# CONFIG_INET_LRO is not set
+CONFIG_INET_DIAG_DESTROY=y
+CONFIG_IPV6_PRIVACY=y
+CONFIG_IPV6_ROUTER_PREF=y
+CONFIG_IPV6_ROUTE_INFO=y
+CONFIG_IPV6_OPTIMISTIC_DAD=y
+CONFIG_INET6_AH=y
+CONFIG_INET6_ESP=y
+CONFIG_INET6_IPCOMP=y
+CONFIG_IPV6_MIP6=y
+CONFIG_IPV6_MULTIPLE_TABLES=y
+CONFIG_IPV6_SUBTREES=y
+CONFIG_NETFILTER=y
+CONFIG_NF_CONNTRACK=y
+CONFIG_NF_CONNTRACK_EVENTS=y
+CONFIG_NF_CT_PROTO_DCCP=y
+CONFIG_NF_CT_PROTO_SCTP=y
+CONFIG_NF_CT_PROTO_UDPLITE=y
+CONFIG_NF_CONNTRACK_AMANDA=y
+CONFIG_NF_CONNTRACK_FTP=y
+CONFIG_NF_CONNTRACK_H323=y
+CONFIG_NF_CONNTRACK_IRC=y
+CONFIG_NF_CONNTRACK_NETBIOS_NS=y
+CONFIG_NF_CONNTRACK_PPTP=y
+CONFIG_NF_CONNTRACK_SANE=y
+CONFIG_NF_CONNTRACK_TFTP=y
+CONFIG_NF_CT_NETLINK=y
+CONFIG_NETFILTER_TPROXY=y
+CONFIG_NETFILTER_XT_TARGET_CLASSIFY=y
+CONFIG_NETFILTER_XT_TARGET_CONNMARK=y
+CONFIG_NETFILTER_XT_TARGET_IDLETIMER=y
+CONFIG_NETFILTER_XT_TARGET_HARDIDLETIMER=y
+CONFIG_NETFILTER_XT_TARGET_LOG=y
+CONFIG_NETFILTER_XT_TARGET_MARK=y
+CONFIG_NETFILTER_XT_TARGET_NFLOG=y
+CONFIG_NETFILTER_XT_TARGET_NFQUEUE=y
+CONFIG_NETFILTER_XT_TARGET_NOTRACK=y
+CONFIG_NETFILTER_XT_TARGET_TEE=y
+CONFIG_NETFILTER_XT_TARGET_TPROXY=y
+CONFIG_NETFILTER_XT_TARGET_TRACE=y
+CONFIG_NETFILTER_XT_TARGET_TCPMSS=y
+CONFIG_NETFILTER_XT_MATCH_COMMENT=y
+CONFIG_NETFILTER_XT_MATCH_CONNLIMIT=y
+CONFIG_NETFILTER_XT_MATCH_CONNMARK=y
+CONFIG_NETFILTER_XT_MATCH_CONNTRACK=y
+CONFIG_NETFILTER_XT_MATCH_ESP=y
+CONFIG_NETFILTER_XT_MATCH_HASHLIMIT=y
+CONFIG_NETFILTER_XT_MATCH_HELPER=y
+CONFIG_NETFILTER_XT_MATCH_IPRANGE=y
+CONFIG_NETFILTER_XT_MATCH_LENGTH=y
+CONFIG_NETFILTER_XT_MATCH_LIMIT=y
+CONFIG_NETFILTER_XT_MATCH_MAC=y
+CONFIG_NETFILTER_XT_MATCH_MARK=y
+CONFIG_NETFILTER_XT_MATCH_MULTIPORT=y
+CONFIG_NETFILTER_XT_MATCH_POLICY=y
+CONFIG_NETFILTER_XT_MATCH_PKTTYPE=y
+CONFIG_NETFILTER_XT_MATCH_QTAGUID=y
+CONFIG_NETFILTER_XT_MATCH_QUOTA=y
+CONFIG_NETFILTER_XT_MATCH_QUOTA2=y
+CONFIG_NETFILTER_XT_MATCH_QUOTA2_LOG=y
+CONFIG_NETFILTER_XT_MATCH_SOCKET=y
+CONFIG_NETFILTER_XT_MATCH_STATE=y
+CONFIG_NETFILTER_XT_MATCH_STATISTIC=y
+CONFIG_NETFILTER_XT_MATCH_STRING=y
+CONFIG_NETFILTER_XT_MATCH_TIME=y
+CONFIG_NETFILTER_XT_MATCH_U32=y
+CONFIG_NF_CONNTRACK_IPV4=y
+CONFIG_IP_NF_IPTABLES=y
+CONFIG_IP_NF_MATCH_AH=y
+CONFIG_IP_NF_MATCH_ECN=y
+CONFIG_IP_NF_MATCH_TTL=y
+CONFIG_IP_NF_FILTER=y
+CONFIG_IP_NF_TARGET_REJECT=y
+CONFIG_NF_NAT_IPV4=y
+CONFIG_IP_NF_TARGET_MASQUERADE=y
+CONFIG_IP_NF_TARGET_NETMAP=y
+CONFIG_IP_NF_TARGET_REDIRECT=y
+CONFIG_IP_NF_MANGLE=y
+CONFIG_IP_NF_RAW=y
+CONFIG_IP_NF_ARPTABLES=y
+CONFIG_IP_NF_ARPFILTER=y
+CONFIG_IP_NF_ARP_MANGLE=y
+CONFIG_NF_CONNTRACK_IPV6=y
+CONFIG_IP6_NF_IPTABLES=y
+CONFIG_IP6_NF_MATCH_RPFILTER=y
+CONFIG_IP6_NF_FILTER=y
+CONFIG_IP6_NF_TARGET_REJECT=y
+CONFIG_IP6_NF_MANGLE=y
+CONFIG_IP6_NF_RAW=y
+CONFIG_BRIDGE_NF_EBTABLES=y
+CONFIG_BRIDGE_EBT_BROUTE=y
+CONFIG_L2TP=y
+CONFIG_L2TP_DEBUGFS=y
+CONFIG_L2TP_V3=y
+CONFIG_L2TP_IP=y
+CONFIG_L2TP_ETH=y
+CONFIG_BRIDGE=y
+CONFIG_NET_SCHED=y
+CONFIG_NET_SCH_HTB=y
+CONFIG_NET_SCH_PRIO=y
+CONFIG_NET_CLS_FW=y
+CONFIG_NET_CLS_U32=y
+CONFIG_CLS_U32_MARK=y
+CONFIG_NET_CLS_FLOW=y
+CONFIG_NET_EMATCH=y
+CONFIG_NET_EMATCH_U32=y
+CONFIG_NET_CLS_ACT=y
+CONFIG_RMNET_DATA=y
+CONFIG_RMNET_DATA_FC=y
+CONFIG_SOCKEV_NLMCAST=y
+CONFIG_BT=y
+CONFIG_CFG80211=y
+CONFIG_CFG80211_INTERNAL_REGDB=y
+CONFIG_RFKILL=y
+CONFIG_NFC=y
+CONFIG_NFC_PN548=y
+CONFIG_IPC_ROUTER=y
+CONFIG_IPC_ROUTER_SECURITY=y
+CONFIG_CMA=y
+CONFIG_ARM_CCI=y
+CONFIG_PROC_DEVICETREE=y
+CONFIG_ZRAM=y
+CONFIG_ZRAM_LZ4_COMPRESS=y
+CONFIG_BLK_DEV_LOOP=y
+CONFIG_BLK_DEV_RAM=y
+CONFIG_UID_STAT=y
+CONFIG_QSEECOM=y
+CONFIG_TI_DRV2667=y
+CONFIG_EARJACK_DEBUGGER=y
+CONFIG_UID_CPUTIME=y
+CONFIG_EEPROM_93CX6=y
+CONFIG_SCSI=y
+CONFIG_BLK_DEV_SD=y
+CONFIG_SCSI_MULTI_LUN=y
+# CONFIG_SCSI_LOWLEVEL is not set
+CONFIG_MD=y
+CONFIG_BLK_DEV_DM=y
+CONFIG_DM_CRYPT=y
+CONFIG_DM_REQ_CRYPT=y
+CONFIG_DM_VERITY=y
+CONFIG_DM_VERITY_FEC=y
+CONFIG_NETDEVICES=y
+CONFIG_DUMMY=y
+CONFIG_TUN=y
+CONFIG_RNDIS_IPA=y
+CONFIG_PPP=y
+CONFIG_PPP_BSDCOMP=y
+CONFIG_PPP_DEFLATE=y
+CONFIG_PPP_FILTER=y
+CONFIG_PPP_MPPE=y
+CONFIG_PPP_MULTILINK=y
+CONFIG_PPPOE=y
+CONFIG_PPPOL2TP=y
+CONFIG_PPPOLAC=y
+CONFIG_PPPOPNS=y
+CONFIG_PPP_ASYNC=y
+CONFIG_PPP_SYNC_TTY=y
+CONFIG_USB_CATC=y
+CONFIG_USB_KAWETH=y
+CONFIG_USB_PEGASUS=y
+CONFIG_USB_RTL8150=y
+CONFIG_USB_RTL8152=y
+CONFIG_USB_USBNET=y
+CONFIG_USB_NET_CDC_EEM=y
+CONFIG_USB_NET_CDC_MBIM=y
+CONFIG_USB_NET_DM9601=y
+CONFIG_USB_NET_SMSC75XX=y
+CONFIG_USB_NET_SMSC95XX=y
+CONFIG_USB_NET_GL620A=y
+CONFIG_USB_NET_PLUSB=y
+CONFIG_USB_NET_MCS7830=y
+CONFIG_USB_NET_RNDIS_HOST=y
+CONFIG_USB_ALI_M5632=y
+CONFIG_USB_AN2720=y
+CONFIG_USB_EPSON2888=y
+CONFIG_USB_KC2190=y
+CONFIG_USB_NET_CX82310_ETH=y
+CONFIG_USB_NET_KALMIA=y
+CONFIG_USB_NET_QMI_WWAN=y
+CONFIG_USB_HSO=y
+CONFIG_USB_NET_INT51X1=y
+CONFIG_USB_IPHETH=y
+CONFIG_USB_SIERRA_NET=y
+CONFIG_USB_VL600=y
+CONFIG_WCNSS_MEM_PRE_ALLOC=y
+CONFIG_ATH_CARDS=y
+CONFIG_CNSS_PCI=y
+CONFIG_CNSS_MAC_BUG=y
+CONFIG_CLD_LL_CORE=y
+CONFIG_BUS_AUTO_SUSPEND=y
+CONFIG_CNSS_GENL=y
+# CONFIG_INPUT_MOUSEDEV is not set
+CONFIG_INPUT_EVDEV=y
+# CONFIG_KEYBOARD_ATKBD is not set
+CONFIG_KEYBOARD_GPIO=y
+# CONFIG_MOUSE_PS2 is not set
+CONFIG_MOUSE_APPLETOUCH=y
+CONFIG_MOUSE_BCM5974=y
+CONFIG_MOUSE_SYNAPTICS_USB=y
+CONFIG_INPUT_JOYSTICK=y
+CONFIG_JOYSTICK_IFORCE=y
+CONFIG_JOYSTICK_IFORCE_USB=y
+CONFIG_JOYSTICK_IFORCE_232=y
+CONFIG_JOYSTICK_XPAD=y
+CONFIG_JOYSTICK_XPAD_FF=y
+CONFIG_JOYSTICK_XPAD_LEDS=y
+CONFIG_INPUT_TABLET=y
+CONFIG_TABLET_USB_ACECAD=y
+CONFIG_TABLET_USB_AIPTEK=y
+CONFIG_TABLET_USB_GTCO=y
+CONFIG_TABLET_USB_HANWANG=y
+CONFIG_TABLET_USB_KBTAB=y
+CONFIG_TABLET_USB_WACOM=y
+CONFIG_INPUT_TOUCHSCREEN=y
+# CONFIG_TOUCHSCREEN_SYNAPTICS_DSX_v21 is not set
+CONFIG_TOUCHSCREEN_GEN_VKEYS=y
+CONFIG_TOUCHSCREEN_SYNAPTICS_I2C_RMI4=y
+CONFIG_TOUCHSCREEN_SYNAPTICS_DSX_RMI4_DEV=y
+CONFIG_TOUCHSCREEN_SYNAPTICS_DSX_FW_UPDATE=y
+CONFIG_INPUT_MISC=y
+CONFIG_INPUT_KEYCHORD=y
+CONFIG_INPUT_UINPUT=y
+CONFIG_INPUT_GPIO=y
+CONFIG_INPUT_FPC1020=y
+# CONFIG_SERIO_I8042 is not set
+# CONFIG_VT is not set
+# CONFIG_LEGACY_PTYS is not set
+# CONFIG_DEVMEM is not set
+# CONFIG_DEVKMEM is not set
+CONFIG_SERIAL_MSM_HS=y
+CONFIG_SERIAL_MSM_HSL=y
+CONFIG_SERIAL_MSM_HSL_CONSOLE=y
+CONFIG_SERIAL_MSM_SMD=y
+CONFIG_HW_RANDOM_MSM=y
+# CONFIG_DEVPORT is not set
+CONFIG_MSM_SMD_PKT=y
+CONFIG_MSM_ADSPRPC=y
+CONFIG_I2C=y
+CONFIG_I2C_CHARDEV=y
+CONFIG_I2C_MSM_V2=y
+CONFIG_SLIMBUS_MSM_NGD=y
+CONFIG_SPI=y
+CONFIG_SPI_QUP=y
+CONFIG_SPMI=y
+CONFIG_SPMI_MSM_PMIC_ARB=y
+CONFIG_MSM_QPNP_INT=y
+CONFIG_USE_PINCTRL_IRQ=y
+CONFIG_PINCTRL_MSM_TLMM=y
+CONFIG_GPIO_SYSFS=y
+CONFIG_GPIO_QPNP_PIN=y
+CONFIG_SMB135X_CHARGER=y
+CONFIG_QPNP_SMBCHARGER=y
+CONFIG_QPNP_FG=y
+CONFIG_BATTERY_BCL=y
+CONFIG_MSM_BCL_CTL=y
+CONFIG_MSM_BCL_PERIPHERAL_CTL=y
+CONFIG_POWER_RESET_MSM=y
+CONFIG_MSM_DLOAD_MODE=y
+CONFIG_MSM_PM=y
+CONFIG_APSS_CORE_EA=y
+CONFIG_SENSORS_EPM_ADC=y
+CONFIG_SENSORS_QPNP_ADC_VOLTAGE=y
+CONFIG_THERMAL=y
+CONFIG_THERMAL_TSENS8974=y
+CONFIG_LIMITS_MONITOR=y
+CONFIG_LIMITS_LITE_HW=y
+CONFIG_THERMAL_MONITOR=y
+CONFIG_THERMAL_QPNP=y
+CONFIG_THERMAL_QPNP_ADC_TM=y
+CONFIG_WCD9330_CODEC=y
+CONFIG_REGULATOR=y
+CONFIG_REGULATOR_FIXED_VOLTAGE=y
+CONFIG_REGULATOR_PROXY_CONSUMER=y
+CONFIG_REGULATOR_MEM_ACC=y
+CONFIG_REGULATOR_TPS65132=y
+CONFIG_REGULATOR_STUB=y
+CONFIG_REGULATOR_RPM_SMD=y
+CONFIG_REGULATOR_QPNP=y
+CONFIG_REGULATOR_QPNP_LABIBB=y
+CONFIG_REGULATOR_SPM=y
+CONFIG_REGULATOR_CPR=y
+CONFIG_REGULATOR_DW8768=y
+CONFIG_MEDIA_SUPPORT=y
+CONFIG_MEDIA_CAMERA_SUPPORT=y
+CONFIG_MEDIA_CONTROLLER=y
+CONFIG_VIDEO_V4L2_SUBDEV_API=y
+CONFIG_VIDEOBUF2_MSM_MEM=y
+CONFIG_MEDIA_USB_SUPPORT=y
+CONFIG_USB_VIDEO_CLASS=y
+# CONFIG_USB_GSPCA is not set
+CONFIG_V4L_PLATFORM_DRIVERS=y
+CONFIG_MSMB_CAMERA=y
+CONFIG_MSM_CAMERA_SENSOR=y
+CONFIG_MSM_CPP=y
+CONFIG_MSM_CCI=y
+CONFIG_MSM_CSI30_HEADER=y
+CONFIG_MSM_CSIPHY=y
+CONFIG_MSM_CSID=y
+CONFIG_MSM_EEPROM=y
+CONFIG_MSM_ISPIF=y
+CONFIG_MSM_V4L2_VIDEO_OVERLAY_DEVICE=y
+CONFIG_MSMB_JPEG=y
+CONFIG_MSM_FD=y
+CONFIG_MSM_VIDC_V4L2=y
+# CONFIG_VGA_ARB is not set
+CONFIG_MSM_KGSL=y
+CONFIG_KGSL_PER_PROCESS_PAGE_TABLE=y
+CONFIG_FB=y
+CONFIG_FB_MSM=y
+CONFIG_FB_MSM_MDSS=y
+CONFIG_FB_MSM_MDSS_WRITEBACK=y
+CONFIG_SOUND=y
+CONFIG_SND=y
+# CONFIG_SND_PCI is not set
+# CONFIG_SND_SPI is not set
+CONFIG_SND_USB_AUDIO=y
+CONFIG_SND_USB_UA101=y
+CONFIG_SND_USB_CAIAQ=y
+CONFIG_SND_USB_CAIAQ_INPUT=y
+CONFIG_SND_USB_6FIRE=y
+CONFIG_SND_SOC=y
+CONFIG_SND_SOC_MSM8994=y
+CONFIG_UHID=y
+CONFIG_HID_A4TECH=y
+CONFIG_HID_APPLE=y
+CONFIG_HID_BELKIN=y
+CONFIG_HID_CHERRY=y
+CONFIG_HID_CHICONY=y
+CONFIG_HID_PRODIKEYS=y
+CONFIG_HID_CYPRESS=y
+CONFIG_HID_ELECOM=y
+CONFIG_HID_EZKEY=y
+CONFIG_HID_HOLTEK=y
+CONFIG_HID_KYE=y
+CONFIG_HID_UCLOGIC=y
+CONFIG_HID_WALTOP=y
+CONFIG_HID_GYRATION=y
+CONFIG_HID_ICADE=y
+CONFIG_HID_KENSINGTON=y
+CONFIG_HID_LCPOWER=y
+CONFIG_HID_LOGITECH=y
+CONFIG_HID_LOGITECH_DJ=y
+CONFIG_LOGITECH_FF=y
+CONFIG_LOGIRUMBLEPAD2_FF=y
+CONFIG_LOGIG940_FF=y
+CONFIG_HID_MAGICMOUSE=y
+CONFIG_HID_MICROSOFT=y
+CONFIG_HID_MONTEREY=y
+CONFIG_HID_MULTITOUCH=y
+CONFIG_HID_NTRIG=y
+CONFIG_HID_ORTEK=y
+CONFIG_HID_PANTHERLORD=y
+CONFIG_PANTHERLORD_FF=y
+CONFIG_HID_PRIMAX=y
+CONFIG_HID_PS3REMOTE=y
+CONFIG_HID_ROCCAT=y
+CONFIG_HID_SAITEK=y
+CONFIG_HID_SAMSUNG=y
+CONFIG_HID_SONY=y
+CONFIG_HID_SPEEDLINK=y
+CONFIG_HID_STEELSERIES=y
+CONFIG_HID_SUNPLUS=y
+CONFIG_HID_SMARTJOYPLUS=y
+CONFIG_HID_TOPSEED=y
+CONFIG_HID_THINGM=y
+CONFIG_HID_THRUSTMASTER=y
+CONFIG_HID_WACOM=y
+CONFIG_HID_WIIMOTE=y
+CONFIG_HID_ZEROPLUS=y
+CONFIG_USB_HIDDEV=y
+CONFIG_USB_ANNOUNCE_NEW_DEVICES=y
+CONFIG_USB_XHCI_HCD=y
+CONFIG_USB_EHCI_HCD=y
+CONFIG_USB_EHCI_EHSET=y
+CONFIG_USB_EHCI_MSM=y
+CONFIG_USB_CCID_BRIDGE=y
+CONFIG_USB_STORAGE=y
+CONFIG_USB_STORAGE_REALTEK=y
+CONFIG_USB_STORAGE_DATAFAB=y
+CONFIG_USB_STORAGE_FREECOM=y
+CONFIG_USB_STORAGE_ISD200=y
+CONFIG_USB_STORAGE_USBAT=y
+CONFIG_USB_STORAGE_SDDR09=y
+CONFIG_USB_STORAGE_SDDR55=y
+CONFIG_USB_STORAGE_JUMPSHOT=y
+CONFIG_USB_STORAGE_ALAUDA=y
+CONFIG_USB_STORAGE_ONETOUCH=y
+CONFIG_USB_STORAGE_KARMA=y
+CONFIG_USB_STORAGE_CYPRESS_ATACB=y
+CONFIG_USB_STORAGE_ENE_UB6250=y
+CONFIG_USB_SERIAL=y
+CONFIG_USB_SERIAL_GENERIC=y
+CONFIG_USB_SERIAL_FTDI_SIO=y
+CONFIG_USB_SERIAL_PL2303=y
+CONFIG_USB_EMI62=y
+CONFIG_USB_EMI26=y
+CONFIG_USB_EHSET_TEST_FIXTURE=y
+CONFIG_USB_CC_TUSB320=y
+CONFIG_USB_CC_FUSB301=y
+CONFIG_USB_PHY=y
+CONFIG_USB_MSM_SSPHY_QMP=y
+CONFIG_MSM_QUSB_PHY=y
+CONFIG_DUAL_ROLE_USB_INTF=y
+CONFIG_USB_GADGET=y
+CONFIG_USB_GADGET_DEBUG_FILES=y
+CONFIG_USB_GADGET_DEBUG_FS=y
+CONFIG_USB_CI13XXX_MSM=y
+CONFIG_USB_DWC3_MSM=y
+CONFIG_USB_G_ANDROID=y
+CONFIG_MMC=y
+CONFIG_MMC_PERF_PROFILING=y
+CONFIG_MMC_UNSAFE_RESUME=y
+CONFIG_MMC_CLKGATE=y
+CONFIG_MMC_PARANOID_SD_INIT=y
+CONFIG_MMC_BLOCK_MINORS=32
+CONFIG_MMC_TEST=y
+CONFIG_MMC_BLOCK_TEST=y
+CONFIG_MMC_SDHCI=y
+CONFIG_MMC_SDHCI_PLTFM=y
+CONFIG_MMC_SDHCI_MSM=y
+CONFIG_LEDS_QPNP=y
+CONFIG_LEDS_QPNP_FLASH=y
+CONFIG_LEDS_QPNP_WLED=y
+CONFIG_LEDS_TRIGGERS=y
+CONFIG_LEDS_TRIGGER_TIMER=y
+CONFIG_SWITCH=y
+CONFIG_EDAC=y
+CONFIG_EDAC_MM_EDAC=y
+CONFIG_EDAC_CORTEX_ARM64=y
+CONFIG_EDAC_CORTEX_ARM64_PANIC_ON_CE=y
+CONFIG_EDAC_CORTEX_ARM64_PANIC_ON_UE=y
+CONFIG_RTC_CLASS=y
+CONFIG_RTC_DRV_QPNP=y
+CONFIG_UIO=y
+CONFIG_UIO_MSM_SHAREDMEM=y
+CONFIG_STAGING=y
+CONFIG_ANDROID=y
+CONFIG_ANDROID_BINDER_IPC=y
+CONFIG_ANDROID_BINDER_DEVICES="binder,hwbinder"
+CONFIG_ASHMEM=y
+CONFIG_ANDROID_LOW_MEMORY_KILLER=y
+CONFIG_ANDROID_INTF_ALARM_DEV=y
+CONFIG_ONESHOT_SYNC=y
+CONFIG_ION=y
+CONFIG_ION_MSM=y
+# CONFIG_NET_VENDOR_SILICOM is not set
+CONFIG_QCA_CLD_WLAN=y
+CONFIG_QCACLD_WLAN_LFR3=y
+CONFIG_PRIMA_WLAN_OKC=y
+CONFIG_PRIMA_WLAN_11AC_HIGH_TP=y
+CONFIG_WLAN_FEATURE_11W=y
+CONFIG_WLAN_FEATURE_LPSS=y
+CONFIG_QCOM_VOWIFI_11R=y
+CONFIG_WLAN_FEATURE_NAN=y
+CONFIG_QCOM_TDLS=y
+CONFIG_QCOM_LTE_COEX=y
+CONFIG_WLAN_OFFLOAD_PACKETS=y
+CONFIG_NANOHUB=y
+CONFIG_NANOHUB_SPI=y
+CONFIG_SPS=y
+CONFIG_USB_BAM=y
+CONFIG_SPS_SUPPORT_NDP_BAM=y
+CONFIG_QPNP_POWER_ON=y
+CONFIG_QPNP_REVID=y
+CONFIG_QPNP_COINCELL=y
+CONFIG_QPNP_USB_DETECT=y
+CONFIG_IPA=y
+CONFIG_RMNET_IPA=y
+CONFIG_MSM_AVTIMER=y
+CONFIG_MSM_BUS_SCALING=y
+CONFIG_BUS_TOPOLOGY_ADHOC=y
+CONFIG_DEBUG_BUS_VOTER=y
+CONFIG_QPNP_HAPTIC=y
+CONFIG_MSM_MDSS_PLL=y
+CONFIG_REMOTE_SPINLOCK_MSM=y
+CONFIG_MSM_IOMMU_V1=y
+CONFIG_MSM_IOMMU_VBIF_CHECK=y
+CONFIG_IOMMU_FORCE_4K_MAPPINGS=y
+CONFIG_DEVFREQ_SPDM=y
+CONFIG_IIO=y
+CONFIG_IIO_BUFFER=y
+CONFIG_IIO_KFIFO_BUF=y
+CONFIG_PWM=y
+CONFIG_PWM_QPNP=y
+CONFIG_SENSORS_SSC=y
+CONFIG_GENERIC_PHY=y
+CONFIG_MSM_EVENT_TIMER=y
+CONFIG_MSM_IPC_ROUTER_SMD_XPRT=y
+CONFIG_MSM_QMI_INTERFACE=y
+CONFIG_MSM_SMD=y
+CONFIG_MSM_SMD_DEBUG=y
+CONFIG_MSM_RPM_SMD=y
+CONFIG_MSM_RPM_RBCPR_STATS_V2_LOG=y
+CONFIG_MSM_RPM_LOG=y
+CONFIG_MSM_RPM_STATS_LOG=y
+CONFIG_MSM_RUN_QUEUE_STATS=y
+CONFIG_MSM_SMEM=y
+CONFIG_MSM_SMEM_LOGGING=y
+CONFIG_MSM_SMP2P=y
+CONFIG_MSM_SMP2P_TEST=y
+CONFIG_MSM_SPM=y
+CONFIG_MSM_L2_SPM=y
+CONFIG_MSM_ADSP_LOADER=y
+CONFIG_MSM_MEMORY_DUMP_V2=y
+CONFIG_MSM_DEBUG_LAR_UNLOCK=y
+CONFIG_MSM_DDR_HEALTH=y
+CONFIG_MSM_COMMON_LOG=y
+CONFIG_MSM_WATCHDOG_V2=y
+CONFIG_MSM_FORCE_WDOG_BITE_ON_PANIC=y
+CONFIG_MSM_HVC=y
+CONFIG_MSM_SUBSYSTEM_RESTART=y
+CONFIG_MSM_SYSMON_COMM=y
+CONFIG_MSM_PIL=y
+CONFIG_MSM_PIL_SSR_GENERIC=y
+CONFIG_MSM_PIL_MSS_QDSP6V5=y
+CONFIG_MSM_OCMEM=y
+CONFIG_MSM_OCMEM_LOCAL_POWER_CTRL=y
+CONFIG_MSM_OCMEM_DEBUG=y
+CONFIG_MSM_BOOT_STATS=y
+CONFIG_MSM_SCM=y
+CONFIG_MSM_XPU_ERR_FATAL=y
+CONFIG_MSM_CPUSS_DUMP=y
+CONFIG_MSM_SHARED_HEAP_ACCESS=y
+CONFIG_MSM_SYSTEM_HEALTH_MONITOR=y
+CONFIG_QCOM_EARLY_RANDOM=y
+CONFIG_MSM_PERFORMANCE=y
+CONFIG_QCOM_NPA_DUMP=y
+CONFIG_MACH_MSM8992_BULLHEAD=y
+CONFIG_LGE_HANDLE_PANIC=y
+CONFIG_MSM_TZ_LOG=y
+CONFIG_EXT4_FS=y
+CONFIG_EXT4_FS_SECURITY=y
+CONFIG_EXT4_FS_ENCRYPTION=y
+CONFIG_QUOTA=y
+# CONFIG_PRINT_QUOTA_WARNING is not set
+CONFIG_FUSE_FS=y
+CONFIG_VFAT_FS=y
+CONFIG_TMPFS=y
+CONFIG_TMPFS_POSIX_ACL=y
+CONFIG_SDCARD_FS=y
+CONFIG_PSTORE=y
+CONFIG_PSTORE_CONSOLE=y
+CONFIG_PSTORE_PMSG=y
+CONFIG_PSTORE_RAM=y
+CONFIG_NLS_CODEPAGE_437=y
+CONFIG_NLS_ASCII=y
+CONFIG_NLS_ISO8859_1=y
+CONFIG_NLS_UTF8=y
+CONFIG_PRINTK_TIME=y
+CONFIG_MAGIC_SYSRQ=y
+# CONFIG_SYSRQ_SCHED_DEBUG is not set
+CONFIG_SCHEDSTATS=y
+CONFIG_TIMER_STATS=y
+CONFIG_DEBUG_INFO=y
+CONFIG_MSM_RTB=y
+CONFIG_MSM_RTB_SEPARATE_CPUS=y
+CONFIG_IPC_LOGGING=y
+CONFIG_BLK_DEV_IO_TRACE=y
+CONFIG_DYNAMIC_DEBUG=y
+CONFIG_OOPS_LOG_BUFFER=y
+CONFIG_LOG_BUF_MAGIC=y
+CONFIG_OOPS_LOG_BUF_SHIFT=17
+CONFIG_PANIC_ON_DATA_CORRUPTION=y
+CONFIG_ARM64_PTDUMP=y
+# CONFIG_EARLY_PRINTK is not set
+CONFIG_PID_IN_CONTEXTIDR=y
+CONFIG_SECURITY_PERF_EVENTS_RESTRICT=y
+CONFIG_SECURITY=y
+CONFIG_SECURITY_NETWORK=y
+CONFIG_LSM_MMAP_MIN_ADDR=4096
+CONFIG_SECURITY_SELINUX=y
+CONFIG_CRYPTO_NULL=y
+CONFIG_CRYPTO_XCBC=y
+CONFIG_CRYPTO_MD4=y
+CONFIG_CRYPTO_SHA512=y
+CONFIG_CRYPTO_TWOFISH=y
+CONFIG_CRYPTO_DEV_QCRYPTO=y
+CONFIG_CRYPTO_DEV_QCE=y
+CONFIG_CRYPTO_DEV_QCEDEV=y
+CONFIG_CRYPTO_DEV_QCOM_ICE=y
+CONFIG_ASYMMETRIC_KEY_TYPE=y
+CONFIG_ASYMMETRIC_PUBLIC_KEY_SUBTYPE=y
+CONFIG_PUBLIC_KEY_ALGO_RSA=y
+CONFIG_X509_CERTIFICATE_PARSER=y
+CONFIG_ARM64_CRYPTO=y
+CONFIG_CRYPTO_SHA1_ARM64_CE=y
+CONFIG_CRYPTO_SHA2_ARM64_CE=y
+CONFIG_CRYPTO_GHASH_ARM64_CE=y
+CONFIG_CRYPTO_AES_ARM64_CE_CCM=y
+CONFIG_CRYPTO_AES_ARM64_CE_BLK=y
+CONFIG_CRYPTO_AES_ARM64_NEON_BLK=y
+CONFIG_QMI_ENCDEC=y
+CONFIG_STRICT_MEMORY_RWX=y
diff --git a/drivers/leds/leds-qpnp.c b/drivers/leds/leds-qpnp.c
index c44153e57b5..2e2b67c0837 100644
--- a/drivers/leds/leds-qpnp.c
+++ b/drivers/leds/leds-qpnp.c
@@ -1750,6 +1750,18 @@ static int rgb_duration_config(struct qpnp_led_data *led)
if (!on_ms) {
return -EINVAL;
+ } else if (!off_ms) {
+ /* implement always on
+ * note:
+ * rgb_on_off_ms_store() bumps on_ms=0 up to RGB_LED_MIN_MS
+ * so setting ms on/off to 0/0 in /sys results in seeing
+ * 50/0 by the time we get here
+ */
+ ramp_step_ms = 1000;
+ num_duty_pcts = 1;
+ pwm_cfg->duty_cycles->duty_pcts[0] =
+ (led->cdev.brightness *
+ 100) / RGB_MAX_LEVEL;
} else {
ramp_step_ms = on_ms / 20;
ramp_step_ms = (ramp_step_ms < 5)? 5 : ramp_step_ms;
@@ -2856,7 +2868,7 @@ static ssize_t rgb_start_store(struct device *dev,
dev_err(led_array[i].cdev.dev,
"RGB set rgb start failed (%d)\n", ret);
if (!(led_array[i].rgb_cfg->pwm_cfg->lut_params.flags &
- PM_PWM_LUT_LOOP))
+ PM_PWM_LUT_RAMP_UP))
led_array[i].rgb_cfg->start = 0;
break;
default:
diff --git a/drivers/mmc/core/core.c b/drivers/mmc/core/core.c
index 3f24e80e54a..0f005912dbd 100644
--- a/drivers/mmc/core/core.c
+++ b/drivers/mmc/core/core.c
@@ -69,7 +69,7 @@ static const unsigned freqs[] = { 400000, 300000, 200000, 100000 };
* performance cost, and for other reasons may not always be desired.
* So we allow it it to be disabled.
*/
-bool use_spi_crc = 1;
+bool use_spi_crc = 0;
module_param(use_spi_crc, bool, 0);
/*
diff --git a/drivers/video/msm/mdss/Makefile b/drivers/video/msm/mdss/Makefile
index 718e4618b89..05acf92c25e 100644
--- a/drivers/video/msm/mdss/Makefile
+++ b/drivers/video/msm/mdss/Makefile
@@ -51,3 +51,5 @@ obj-$(CONFIG_FB_MSM_QPIC_ILI_QVGA_PANEL) += qpic_panel_ili_qvga.o
obj-$(CONFIG_FB_MSM_MDSS) += mdss_fb.o mdss_util.o
obj-$(CONFIG_COMPAT) += mdss_compat_utils.o
+
+obj-$(CONFIG_FB_MSM_MDSS) += mdss_livedisplay.o
diff --git a/drivers/video/msm/mdss/mdss_dsi_panel.c b/drivers/video/msm/mdss/mdss_dsi_panel.c
index e4637223de1..263976ca162 100644
--- a/drivers/video/msm/mdss/mdss_dsi_panel.c
+++ b/drivers/video/msm/mdss/mdss_dsi_panel.c
@@ -23,6 +23,7 @@
#include <linux/err.h>
#include "mdss_dsi.h"
+#include "mdss_livedisplay.h"
#define DT_CMD_HDR 6
#define MIN_REFRESH_RATE 30
@@ -152,7 +153,7 @@ u32 mdss_dsi_panel_cmd_read(struct mdss_dsi_ctrl_pdata *ctrl, char cmd0,
return 0;
}
-static void mdss_dsi_panel_cmds_send(struct mdss_dsi_ctrl_pdata *ctrl,
+void mdss_dsi_panel_cmds_send(struct mdss_dsi_ctrl_pdata *ctrl,
struct dsi_panel_cmds *pcmds)
{
struct dcs_cmd_req cmdreq;
@@ -679,6 +680,8 @@ static int mdss_dsi_panel_on(struct mdss_panel_data *pdata)
if (mdss_bl_ctrl_by_panel())
mdss_dsi_panel_bl_ctrl(pdata, bl_default_lvl);
+ mdss_livedisplay_update(ctrl, MODE_UPDATE_ALL);
+
end:
pinfo->blank_state = MDSS_PANEL_BLANK_UNBLANK;
pr_debug("%s:-\n", __func__);
@@ -790,7 +793,7 @@ static void mdss_dsi_parse_trigger(struct device_node *np, char *trigger,
}
-static int mdss_dsi_parse_dcs_cmds(struct device_node *np,
+int mdss_dsi_parse_dcs_cmds(struct device_node *np,
struct dsi_panel_cmds *pcmds, char *cmd_key, char *link_key)
{
const char *data;
@@ -1879,6 +1882,8 @@ static int mdss_panel_parse_dt(struct device_node *np,
of_property_read_u32(np, "qcom,bl-default-lvl",
&bl_default_lvl);
+ mdss_livedisplay_parse_dt(np, pinfo);
+
return 0;
error:
diff --git a/drivers/video/msm/mdss/mdss_fb.c b/drivers/video/msm/mdss/mdss_fb.c
index 35756ef1a7c..a80925d6ac0 100644
--- a/drivers/video/msm/mdss/mdss_fb.c
+++ b/drivers/video/msm/mdss/mdss_fb.c
@@ -55,6 +55,8 @@
#define CREATE_TRACE_POINTS
#include "mdss_debug.h"
+#include "mdss_livedisplay.h"
+
#ifdef CONFIG_FB_MSM_TRIPLE_BUFFER
#define MDSS_FB_NUM 3
#else
@@ -790,7 +792,8 @@ static int mdss_fb_create_sysfs(struct msm_fb_data_type *mfd)
rc = sysfs_create_group(&mfd->fbi->dev->kobj, &mdss_fb_attr_group);
if (rc)
pr_err("sysfs group creation failed, rc=%d\n", rc);
- return rc;
+
+ return mdss_livedisplay_create_sysfs(mfd);
}
static void mdss_fb_remove_sysfs(struct msm_fb_data_type *mfd)
diff --git a/drivers/video/msm/mdss/mdss_livedisplay.c b/drivers/video/msm/mdss/mdss_livedisplay.c
new file mode 100644
index 00000000000..afcfdc24c8d
--- /dev/null
+++ b/drivers/video/msm/mdss/mdss_livedisplay.c
@@ -0,0 +1,678 @@
+/*
+ * Copyright (c) 2015 The CyanogenMod Project
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+#include <linux/err.h>
+#include <linux/module.h>
+#include <linux/of.h>
+#include <linux/slab.h>
+#include <linux/sysfs.h>
+
+#include "mdss_dsi.h"
+#include "mdss_fb.h"
+#include "mdss_mdp.h"
+#include "mdss_livedisplay.h"
+
+/*
+ * LiveDisplay is the display management service in CyanogenMod. It uses
+ * various capabilities of the hardware and software in order to
+ * optimize the experience for ambient conditions and time of day.
+ *
+ * This module is initialized by mdss_fb for each panel, and creates
+ * several new controls in /sys/class/graphics/fbX based on the
+ * configuration in the devicetree.
+ *
+ * rgb: Always available with MDSS. Used for color temperature and
+ * user-level calibration. Takes a string of "r g b".
+ *
+ * cabc: Content Adaptive Backlight Control. Must be configured
+ * in the panel devicetree. Up to three levels.
+ * sre: Sunlight Readability Enhancement. Must be configured in
+ * the panel devicetree. Up to three levels.
+ * aco: Automatic Contrast Optimization. Must be configured in
+ * the panel devicetree. Boolean.
+ *
+ * preset: Arbitrary DSI commands, up to 10 may be configured.
+ * Useful for gamma calibration.
+ *
+ * color_enhance: Hardware color enhancement. Must be configured
+ * in the panel devicetree. Boolean.
+ */
+
+extern void mdss_dsi_panel_cmds_send(struct mdss_dsi_ctrl_pdata *ctrl,
+ struct dsi_panel_cmds *pcmds);
+
+static int parse_dsi_cmds(struct dsi_panel_cmds *pcmds, const uint8_t *cmd, int blen)
+{
+ int len;
+ char *buf, *bp;
+ struct dsi_ctrl_hdr *dchdr;
+ int i, cnt;
+
+ buf = kzalloc(blen, GFP_KERNEL);
+ if (!buf)
+ return -ENOMEM;
+
+ memcpy(buf, cmd, blen);
+
+ /* scan dcs commands */
+ bp = buf;
+ len = blen;
+ cnt = 0;
+ while (len >= sizeof(*dchdr)) {
+ dchdr = (struct dsi_ctrl_hdr *)bp;
+ dchdr->dlen = ntohs(dchdr->dlen);
+ if (dchdr->dlen > len) {
+ pr_err("%s: dtsi cmd=%x error, len=%d\n",
+ __func__, dchdr->dtype, dchdr->dlen);
+ goto exit_free;
+ }
+ bp += sizeof(*dchdr);
+ len -= sizeof(*dchdr);
+ bp += dchdr->dlen;
+ len -= dchdr->dlen;
+ cnt++;
+ }
+
+ if (len != 0) {
+ pr_err("%s: dcs_cmd=%x len=%d error!\n",
+ __func__, buf[0], blen);
+ goto exit_free;
+ }
+
+ pcmds->cmds = kzalloc(cnt * sizeof(struct dsi_cmd_desc),
+ GFP_KERNEL);
+ if (!pcmds->cmds)
+ goto exit_free;
+
+ pcmds->cmd_cnt = cnt;
+ pcmds->buf = buf;
+ pcmds->blen = blen;
+
+ bp = buf;
+ len = blen;
+ for (i = 0; i < cnt; i++) {
+ dchdr = (struct dsi_ctrl_hdr *)bp;
+ len -= sizeof(*dchdr);
+ bp += sizeof(*dchdr);
+ pcmds->cmds[i].dchdr = *dchdr;
+ pcmds->cmds[i].payload = bp;
+ bp += dchdr->dlen;
+ len -= dchdr->dlen;
+ }
+
+ /*Set default link state to HS Mode*/
+ pcmds->link_state = DSI_HS_MODE;
+
+ pr_debug("%s: dcs_cmd=%x len=%d, cmd_cnt=%d link_state=%d\n", __func__,
+ pcmds->buf[0], pcmds->blen, pcmds->cmd_cnt, pcmds->link_state);
+
+ return 0;
+
+exit_free:
+ kfree(buf);
+ return -ENOMEM;
+}
+
+/**
+ * simple color temperature interface using polynomial color correction
+ *
+ * input values are r/g/b adjustments from 0-32768 representing 0 -> 1
+ *
+ * example adjustment @ 3500K:
+ * 1.0000 / 0.5515 / 0.2520 = 32768 / 25828 / 17347
+ *
+ * reference chart:
+ * http://www.vendian.org/mncharity/dir3/blackbody/UnstableURLs/bbr_color.html
+ */
+static int mdss_livedisplay_set_rgb_locked(struct msm_fb_data_type *mfd)
+{
+ static struct mdp_pcc_cfg_data pcc_cfg;
+ struct mdss_livedisplay_ctx *mlc;
+
+ mlc = get_ctx(mfd);
+
+ if (mlc == NULL)
+ return -ENODEV;
+
+ pr_info("%s: r=%d g=%d b=%d\n", __func__, mlc->r, mlc->g, mlc->b);
+
+ memset(&pcc_cfg, 0, sizeof(struct mdp_pcc_cfg_data));
+
+ pcc_cfg.block = mfd->index + MDP_LOGICAL_BLOCK_DISP_0;
+ if (mlc->r == 32768 && mlc->g == 32768 && mlc->b == 32768)
+ pcc_cfg.ops = MDP_PP_OPS_DISABLE;
+ else
+ pcc_cfg.ops = MDP_PP_OPS_ENABLE;
+ pcc_cfg.ops |= MDP_PP_OPS_WRITE;
+ pcc_cfg.r.r = mlc->r;
+ pcc_cfg.g.g = mlc->g;
+ pcc_cfg.b.b = mlc->b;
+
+ return mdss_mdp_user_pcc_config(&pcc_cfg);
+}
+
+/*
+ * Update all or a subset of parameters
+ */
+static int mdss_livedisplay_update_locked(struct mdss_dsi_ctrl_pdata *ctrl_pdata,
+ int types)
+{
+ int ret = 0;
+ struct mdss_panel_info *pinfo = NULL;
+ struct mdss_livedisplay_ctx *mlc = NULL;
+ unsigned int len = 0, dlen = 0;
+ struct dsi_panel_cmds dsi_cmds;
+ uint8_t cabc_value = 0;
+ uint8_t *cmd_buf;
+
+ if (ctrl_pdata == NULL)
+ return -ENODEV;
+
+ pinfo = &(ctrl_pdata->panel_data.panel_info);
+ if (pinfo == NULL)
+ return -ENODEV;
+
+ mlc = pinfo->livedisplay;
+ if (mlc == NULL)
+ return -ENODEV;
+
+ if (!mlc->caps || !mdss_panel_is_power_on_interactive(pinfo->panel_power_state))
+ return 0;
+
+ // First find the length of the command array
+ if ((mlc->caps & MODE_PRESET) && (types & MODE_PRESET))
+ len += mlc->presets_len[mlc->preset];
+
+ if ((mlc->caps & MODE_COLOR_ENHANCE) && (types & MODE_COLOR_ENHANCE))
+ len += mlc->ce_enabled ? mlc->ce_on_cmds_len : mlc->ce_off_cmds_len;
+
+ if (is_cabc_cmd(types) && is_cabc_cmd(mlc->caps)) {
+
+ // The CABC command on most modern panels is also responsible for
+ // other features such as SRE and ACO. The register fields are bits
+ // and are OR'd together and sent in a single DSI command.
+ if (mlc->cabc_level == CABC_UI)
+ cabc_value |= mlc->cabc_ui_value;
+ else if (mlc->cabc_level == CABC_IMAGE)
+ cabc_value |= mlc->cabc_image_value;
+ else if (mlc->cabc_level == CABC_VIDEO)
+ cabc_value |= mlc->cabc_video_value;
+
+ if (mlc->sre_level == SRE_WEAK)
+ cabc_value |= mlc->sre_weak_value;
+ else if (mlc->sre_level == SRE_MEDIUM)
+ cabc_value |= mlc->sre_medium_value;
+ else if (mlc->sre_level == SRE_STRONG)
+ cabc_value |= mlc->sre_strong_value;
+
+ if (mlc->aco_enabled)
+ cabc_value |= mlc->aco_value;
+
+ len += mlc->cabc_cmds_len;
+
+ pr_info("%s cabc=%d sre=%d aco=%d cmd=%d\n", __func__,
+ mlc->cabc_level, mlc->sre_level, mlc->aco_enabled,
+ cabc_value);
+ }
+
+ len += mlc->post_cmds_len;
+
+ if (len == 0)
+ return 0;
+
+ memset(&dsi_cmds, 0, sizeof(struct dsi_panel_cmds));
+ cmd_buf = kzalloc(len + 1, GFP_KERNEL);
+ if (!cmd_buf)
+ return -ENOMEM;
+
+ // Build the command as a single chain, preset first
+ if ((mlc->caps & MODE_PRESET) && (types & MODE_PRESET)) {
+ memcpy(cmd_buf, mlc->presets[mlc->preset], mlc->presets_len[mlc->preset]);
+ dlen += mlc->presets_len[mlc->preset];
+ }
+
+ // Color enhancement
+ if ((mlc->caps & MODE_COLOR_ENHANCE) && (types & MODE_COLOR_ENHANCE)) {
+ if (mlc->ce_enabled) {
+ memcpy(cmd_buf + dlen, mlc->ce_on_cmds, mlc->ce_on_cmds_len);
+ dlen += mlc->ce_on_cmds_len;
+ } else {
+ memcpy(cmd_buf + dlen, mlc->ce_off_cmds, mlc->ce_off_cmds_len);
+ dlen += mlc->ce_off_cmds_len;
+ }
+ }
+
+ // CABC/SRE/ACO features
+ if (is_cabc_cmd(types) && mlc->cabc_cmds_len) {
+ memcpy(cmd_buf + dlen, mlc->cabc_cmds, mlc->cabc_cmds_len);
+ dlen += mlc->cabc_cmds_len;
+ // The CABC command parameter is the last value in the sequence
+ cmd_buf[dlen - 1] = cabc_value;
+ }
+
+ // And the post_cmd, can be used to turn on the panel
+ if (mlc->post_cmds_len) {
+ memcpy(cmd_buf + dlen, mlc->post_cmds, mlc->post_cmds_len);
+ dlen += mlc->post_cmds_len;
+ }
+
+ // Parse the command and send it
+ ret = parse_dsi_cmds(&dsi_cmds, (const uint8_t *)cmd_buf, len);
+ if (ret == 0) {
+ mdss_dsi_panel_cmds_send(ctrl_pdata, &dsi_cmds);
+ } else {
+ pr_err("%s: error parsing DSI command! ret=%d", __func__, ret);
+ }
+
+ kfree(cmd_buf);
+
+ // Restore saved RGB settings
+ mdss_livedisplay_set_rgb_locked(mlc->mfd);
+
+ return ret;
+}
+
+int mdss_livedisplay_update(struct mdss_dsi_ctrl_pdata *ctrl_pdata,
+ int types)
+{
+ struct mdss_panel_info *pinfo;
+ struct mdss_livedisplay_ctx *mlc;
+ int ret = 0;
+
+ pinfo = &(ctrl_pdata->panel_data.panel_info);
+ if (pinfo == NULL)
+ return -ENODEV;
+
+ mlc = pinfo->livedisplay;
+ if (mlc == NULL)
+ return -ENODEV;
+
+ if (mlc->mfd == NULL)
+ return -ENODEV;
+
+ mutex_lock(&mlc->lock);
+ ret = mdss_livedisplay_update_locked(ctrl_pdata, types);
+ mutex_unlock(&mlc->lock);
+
+ return ret;
+}
+
+static ssize_t mdss_livedisplay_get_cabc(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ struct fb_info *fbi = dev_get_drvdata(dev);
+ struct msm_fb_data_type *mfd = (struct msm_fb_data_type *)fbi->par;
+ struct mdss_livedisplay_ctx *mlc = get_ctx(mfd);
+
+ return sprintf(buf, "%d\n", mlc->cabc_level);
+}
+
+static ssize_t mdss_livedisplay_set_cabc(struct device *dev,
+ struct device_attribute *attr,
+ const char *buf, size_t count)
+{
+ int level = 0;
+ struct fb_info *fbi = dev_get_drvdata(dev);
+ struct msm_fb_data_type *mfd = (struct msm_fb_data_type *)fbi->par;
+ struct mdss_livedisplay_ctx *mlc = get_ctx(mfd);
+
+ mutex_lock(&mlc->lock);
+
+ sscanf(buf, "%du", &level);
+ if (level >= CABC_OFF && level < CABC_MAX &&
+ level != mlc->cabc_level) {
+ mlc->cabc_level = level;
+ mdss_livedisplay_update_locked(get_ctrl(mfd), MODE_CABC);
+ }
+
+ mutex_unlock(&mlc->lock);
+
+ return count;
+}
+
+static ssize_t mdss_livedisplay_get_sre(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ struct fb_info *fbi = dev_get_drvdata(dev);
+ struct msm_fb_data_type *mfd = (struct msm_fb_data_type *)fbi->par;
+ struct mdss_livedisplay_ctx *mlc = get_ctx(mfd);
+
+ return sprintf(buf, "%d\n", mlc->sre_level);
+}
+
+static ssize_t mdss_livedisplay_set_sre(struct device *dev,
+ struct device_attribute *attr,
+ const char *buf, size_t count)
+{
+ int level = 0;
+ struct fb_info *fbi = dev_get_drvdata(dev);
+ struct msm_fb_data_type *mfd = (struct msm_fb_data_type *)fbi->par;
+ struct mdss_livedisplay_ctx *mlc = get_ctx(mfd);
+
+ mutex_lock(&mlc->lock);
+
+ sscanf(buf, "%du", &level);
+ if (level >= SRE_OFF && level < SRE_MAX &&
+ level != mlc->sre_level) {
+ mlc->sre_level = level;
+ mdss_livedisplay_update_locked(get_ctrl(mfd), MODE_SRE);
+ }
+
+ mutex_unlock(&mlc->lock);
+
+ return count;
+}
+
+static ssize_t mdss_livedisplay_get_color_enhance(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ struct fb_info *fbi = dev_get_drvdata(dev);
+ struct msm_fb_data_type *mfd = (struct msm_fb_data_type *)fbi->par;
+ struct mdss_livedisplay_ctx *mlc = get_ctx(mfd);
+
+ return sprintf(buf, "%d\n", mlc->ce_enabled);
+}
+
+static ssize_t mdss_livedisplay_set_color_enhance(struct device *dev,
+ struct device_attribute *attr,
+ const char *buf, size_t count)
+{
+ int value = 0;
+ struct fb_info *fbi = dev_get_drvdata(dev);
+ struct msm_fb_data_type *mfd = (struct msm_fb_data_type *)fbi->par;
+ struct mdss_livedisplay_ctx *mlc = get_ctx(mfd);
+
+ mutex_lock(&mlc->lock);
+
+ sscanf(buf, "%du", &value);
+ if ((value == 0 || value == 1)
+ && value != mlc->ce_enabled) {
+ mlc->ce_enabled = value;
+ mdss_livedisplay_update_locked(get_ctrl(mfd), MODE_COLOR_ENHANCE);
+ }
+
+ mutex_unlock(&mlc->lock);
+
+ return count;
+}
+
+static ssize_t mdss_livedisplay_get_aco(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ struct fb_info *fbi = dev_get_drvdata(dev);
+ struct msm_fb_data_type *mfd = (struct msm_fb_data_type *)fbi->par;
+ struct mdss_livedisplay_ctx *mlc = get_ctx(mfd);
+
+ return sprintf(buf, "%d\n", mlc->aco_enabled);
+}
+
+static ssize_t mdss_livedisplay_set_aco(struct device *dev,
+ struct device_attribute *attr,
+ const char *buf, size_t count)
+{
+ int value = 0;
+ struct fb_info *fbi = dev_get_drvdata(dev);
+ struct msm_fb_data_type *mfd = (struct msm_fb_data_type *)fbi->par;
+ struct mdss_livedisplay_ctx *mlc = get_ctx(mfd);
+
+ mutex_lock(&mlc->lock);
+
+ sscanf(buf, "%du", &value);
+ if ((value == 0 || value == 1)
+ && value != mlc->aco_enabled) {
+ mlc->aco_enabled = value;
+ mdss_livedisplay_update_locked(get_ctrl(mfd), MODE_AUTO_CONTRAST);
+ }
+
+ mutex_unlock(&mlc->lock);
+
+ return count;
+}
+
+static ssize_t mdss_livedisplay_get_preset(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ struct fb_info *fbi = dev_get_drvdata(dev);
+ struct msm_fb_data_type *mfd = (struct msm_fb_data_type *)fbi->par;
+ struct mdss_livedisplay_ctx *mlc = get_ctx(mfd);
+
+ return sprintf(buf, "%d\n", mlc->preset);
+}
+
+static ssize_t mdss_livedisplay_set_preset(struct device *dev,
+ struct device_attribute *attr,
+ const char *buf, size_t count)
+{
+ int value = 0;
+ struct fb_info *fbi = dev_get_drvdata(dev);
+ struct msm_fb_data_type *mfd = (struct msm_fb_data_type *)fbi->par;
+ struct mdss_livedisplay_ctx *mlc = get_ctx(mfd);
+
+ mutex_lock(&mlc->lock);
+
+ sscanf(buf, "%du", &value);
+ if (value < 0 || value >= mlc->num_presets)
+ return -EINVAL;
+
+ mlc->preset = value;
+ mdss_livedisplay_update_locked(get_ctrl(mfd), MODE_PRESET);
+
+ mutex_unlock(&mlc->lock);
+
+ return count;
+}
+
+static ssize_t mdss_livedisplay_get_num_presets(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ struct fb_info *fbi = dev_get_drvdata(dev);
+ struct msm_fb_data_type *mfd = (struct msm_fb_data_type *)fbi->par;
+ struct mdss_livedisplay_ctx *mlc = get_ctx(mfd);
+
+ return sprintf(buf, "%d\n", mlc->num_presets);
+}
+
+static ssize_t mdss_livedisplay_get_rgb(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ struct fb_info *fbi = dev_get_drvdata(dev);
+ struct msm_fb_data_type *mfd = (struct msm_fb_data_type *)fbi->par;
+ struct mdss_livedisplay_ctx *mlc;
+
+ if (mfd == NULL)
+ return -ENODEV;
+
+ mlc = get_ctx(mfd);
+
+ return scnprintf(buf, PAGE_SIZE, "%d %d %d\n",
+ mlc->r, mlc->g, mlc->b);
+}
+
+static ssize_t mdss_livedisplay_set_rgb(struct device *dev,
+ struct device_attribute *attr,
+ const char *buf, size_t count)
+{
+ uint32_t r = 0, g = 0, b = 0;
+ struct fb_info *fbi = dev_get_drvdata(dev);
+ struct msm_fb_data_type *mfd = (struct msm_fb_data_type *)fbi->par;
+ struct mdss_panel_data *pdata;
+ struct mdss_livedisplay_ctx *mlc;
+ int ret = -EINVAL;
+
+ if (mfd == NULL)
+ return -ENODEV;
+
+ if (count > 19)
+ return -EINVAL;
+
+ mlc = get_ctx(mfd);
+ pdata = dev_get_platdata(&mfd->pdev->dev);
+
+ sscanf(buf, "%d %d %d", &r, &g, &b);
+
+ if (r < 0 || r > 32768)
+ return -EINVAL;
+ if (g < 0 || g > 32768)
+ return -EINVAL;
+ if (b < 0 || b > 32768)
+ return -EINVAL;
+
+ mutex_lock(&mlc->lock);
+
+ mlc->r = r;
+ mlc->g = g;
+ mlc->b = b;
+
+ if (!mdss_panel_is_power_on_interactive(mfd->panel_power_state) ||
+ (mdss_livedisplay_set_rgb_locked(mfd) == 0))
+ ret = count;
+
+ mutex_unlock(&mlc->lock);
+
+ return ret;
+}
+
+static DEVICE_ATTR(cabc, S_IRUGO | S_IWUSR | S_IWGRP, mdss_livedisplay_get_cabc, mdss_livedisplay_set_cabc);
+static DEVICE_ATTR(sre, S_IRUGO | S_IWUSR | S_IWGRP, mdss_livedisplay_get_sre, mdss_livedisplay_set_sre);
+static DEVICE_ATTR(color_enhance, S_IRUGO | S_IWUSR | S_IWGRP, mdss_livedisplay_get_color_enhance, mdss_livedisplay_set_color_enhance);
+static DEVICE_ATTR(aco, S_IRUGO | S_IWUSR | S_IWGRP, mdss_livedisplay_get_aco, mdss_livedisplay_set_aco);
+static DEVICE_ATTR(preset, S_IRUGO | S_IWUSR | S_IWGRP, mdss_livedisplay_get_preset, mdss_livedisplay_set_preset);
+static DEVICE_ATTR(num_presets, S_IRUGO, mdss_livedisplay_get_num_presets, NULL);
+static DEVICE_ATTR(rgb, S_IRUGO | S_IWUSR | S_IWGRP, mdss_livedisplay_get_rgb, mdss_livedisplay_set_rgb);
+
+int mdss_livedisplay_parse_dt(struct device_node *np, struct mdss_panel_info *pinfo)
+{
+ int rc = 0, i = 0;
+ struct mdss_livedisplay_ctx *mlc;
+ char preset_name[64];
+ uint32_t tmp = 0;
+
+ if (pinfo == NULL)
+ return -ENODEV;
+
+ mlc = kzalloc(sizeof(struct mdss_livedisplay_ctx), GFP_KERNEL);
+ mutex_init(&mlc->lock);
+
+ mlc->cabc_cmds = of_get_property(np,
+ "cm,mdss-livedisplay-cabc-cmd", &mlc->cabc_cmds_len);
+
+ if (mlc->cabc_cmds_len > 0) {
+ rc = of_property_read_u32(np, "cm,mdss-livedisplay-cabc-ui-value", &tmp);
+ if (rc == 0) {
+ mlc->caps |= MODE_CABC;
+ mlc->cabc_ui_value = (uint8_t)(tmp & 0xFF);
+ of_property_read_u32(np, "cm,mdss-livedisplay-cabc-image-value", &tmp);
+ mlc->cabc_image_value = (uint8_t)(tmp & 0xFF);
+ of_property_read_u32(np, "cm,mdss-livedisplay-cabc-video-value", &tmp);
+ mlc->cabc_video_value = (uint8_t)(tmp & 0xFF);
+ }
+ rc = of_property_read_u32(np, "cm,mdss-livedisplay-sre-medium-value", &tmp);
+ if (rc == 0) {
+ mlc->caps |= MODE_SRE;
+ mlc->sre_medium_value = (uint8_t)(tmp & 0xFF);
+ of_property_read_u32(np, "cm,mdss-livedisplay-sre-weak-value", &tmp);
+ mlc->sre_weak_value = (uint8_t)(tmp & 0xFF);
+ of_property_read_u32(np, "cm,mdss-livedisplay-sre-strong-value", &tmp);
+ mlc->sre_strong_value = (uint8_t)(tmp & 0xFF);
+ }
+ rc = of_property_read_u32(np, "cm,mdss-livedisplay-aco-value", &tmp);
+ if (rc == 0) {
+ mlc->caps |= MODE_AUTO_CONTRAST;
+ mlc->aco_value = (uint8_t)(tmp & 0xFF);
+ }
+ }
+
+ mlc->ce_on_cmds = of_get_property(np,
+ "cm,mdss-livedisplay-color-enhance-on", &mlc->ce_on_cmds_len);
+ if (mlc->ce_on_cmds_len) {
+ mlc->ce_off_cmds = of_get_property(np,
+ "cm,mdss-livedisplay-color-enhance-off", &mlc->ce_off_cmds_len);
+ if (mlc->ce_off_cmds_len)
+ mlc->caps |= MODE_COLOR_ENHANCE;
+ }
+
+ for (i = 0; i < MAX_PRESETS; i++) {
+ memset(preset_name, 0, sizeof(preset_name));
+ snprintf(preset_name, 64, "%s-%d", "cm,mdss-livedisplay-preset", i);
+ mlc->presets[mlc->num_presets] = of_get_property(np, preset_name,
+ &mlc->presets_len[mlc->num_presets]);
+ if (mlc->presets_len[mlc->num_presets] > 0)
+ mlc->num_presets++;
+ }
+
+ if (mlc->num_presets)
+ mlc->caps |= MODE_PRESET;
+
+ mlc->post_cmds = of_get_property(np,
+ "cm,mdss-livedisplay-post-cmd", &mlc->post_cmds_len);
+
+ mlc->r = mlc->g = mlc->b = 32768;
+
+ pinfo->livedisplay = mlc;
+ return 0;
+}
+
+int mdss_livedisplay_create_sysfs(struct msm_fb_data_type *mfd)
+{
+ int rc = 0;
+ struct mdss_livedisplay_ctx *mlc = get_ctx(mfd);
+
+ if (mlc == NULL)
+ return 0;
+
+ rc = sysfs_create_file(&mfd->fbi->dev->kobj, &dev_attr_rgb.attr);
+ if (rc)
+ goto sysfs_err;
+
+ if (mlc->caps & MODE_CABC) {
+ rc = sysfs_create_file(&mfd->fbi->dev->kobj, &dev_attr_cabc.attr);
+ if (rc)
+ goto sysfs_err;
+ }
+
+ if (mlc->caps & MODE_SRE) {
+ rc = sysfs_create_file(&mfd->fbi->dev->kobj, &dev_attr_sre.attr);
+ if (rc)
+ goto sysfs_err;
+ }
+
+ if (mlc->caps & MODE_AUTO_CONTRAST) {
+ rc = sysfs_create_file(&mfd->fbi->dev->kobj, &dev_attr_aco.attr);
+ if (rc)
+ goto sysfs_err;
+ }
+
+ if (mlc->caps & MODE_COLOR_ENHANCE) {
+ rc = sysfs_create_file(&mfd->fbi->dev->kobj, &dev_attr_color_enhance.attr);
+ if (rc)
+ goto sysfs_err;
+ }
+
+ if (mlc->caps & MODE_PRESET) {
+ rc = sysfs_create_file(&mfd->fbi->dev->kobj, &dev_attr_preset.attr);
+ if (rc)
+ goto sysfs_err;
+ rc = sysfs_create_file(&mfd->fbi->dev->kobj, &dev_attr_num_presets.attr);
+ if (rc)
+ goto sysfs_err;
+ }
+
+ mlc->mfd = mfd;
+
+ return rc;
+
+sysfs_err:
+ pr_err("%s: sysfs creation failed, rc=%d", __func__, rc);
+ return rc;
+}
+
diff --git a/drivers/video/msm/mdss/mdss_livedisplay.h b/drivers/video/msm/mdss/mdss_livedisplay.h
new file mode 100644
index 00000000000..7cf61028d93
--- /dev/null
+++ b/drivers/video/msm/mdss/mdss_livedisplay.h
@@ -0,0 +1,108 @@
+/*
+ * Copyright (c) 2015 The CyanogenMod Project
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+#ifndef MDSS_LIVEDISPLAY_H
+#define MDSS_LIVEDISPLAY_H
+
+#include <linux/of.h>
+#include <linux/sysfs.h>
+
+#include "mdss_dsi.h"
+#include "mdss_fb.h"
+
+#define MAX_PRESETS 10
+
+struct mdss_livedisplay_ctx {
+ uint8_t cabc_ui_value;
+ uint8_t cabc_image_value;
+ uint8_t cabc_video_value;
+ uint8_t sre_weak_value;
+ uint8_t sre_medium_value;
+ uint8_t sre_strong_value;
+ uint8_t aco_value;
+
+ const uint8_t *ce_off_cmds;
+ const uint8_t *ce_on_cmds;
+ unsigned int ce_off_cmds_len;
+ unsigned int ce_on_cmds_len;
+
+ const uint8_t *presets[MAX_PRESETS];
+ unsigned int presets_len[MAX_PRESETS];
+
+ const uint8_t *cabc_cmds;
+ unsigned int cabc_cmds_len;
+
+ const uint8_t *post_cmds;
+ unsigned int post_cmds_len;
+
+ unsigned int preset;
+ unsigned int cabc_level;
+ unsigned int sre_level;
+ bool aco_enabled;
+ bool ce_enabled;
+
+ unsigned int num_presets;
+ unsigned int caps;
+
+ uint32_t r, g, b;
+ struct msm_fb_data_type *mfd;
+
+ struct mutex lock;
+};
+
+enum {
+ CABC_OFF,
+ CABC_UI,
+ CABC_IMAGE,
+ CABC_VIDEO,
+ CABC_MAX
+};
+
+enum {
+ SRE_OFF,
+ SRE_WEAK,
+ SRE_MEDIUM,
+ SRE_STRONG,
+ SRE_MAX
+};
+
+enum {
+ MODE_CABC = 0x01,
+ MODE_SRE = 0x02,
+ MODE_AUTO_CONTRAST = 0x04,
+ MODE_COLOR_ENHANCE = 0x08,
+ MODE_PRESET = 0x10,
+ MODE_UPDATE_ALL = 0xFF,
+};
+
+int mdss_livedisplay_update(struct mdss_dsi_ctrl_pdata *ctrl_pdata, int types);
+int mdss_livedisplay_parse_dt(struct device_node *np, struct mdss_panel_info *pinfo);
+int mdss_livedisplay_create_sysfs(struct msm_fb_data_type *mfd);
+
+static inline bool is_cabc_cmd(unsigned int value)
+{
+ return (value & MODE_CABC) || (value & MODE_SRE) || (value & MODE_AUTO_CONTRAST);
+}
+
+static inline struct mdss_livedisplay_ctx* get_ctx(struct msm_fb_data_type *mfd)
+{
+ return mfd->panel_info->livedisplay;
+}
+
+static inline struct mdss_dsi_ctrl_pdata* get_ctrl(struct msm_fb_data_type *mfd)
+{
+ struct mdss_panel_data *pdata = dev_get_platdata(&mfd->pdev->dev);
+ return container_of(pdata, struct mdss_dsi_ctrl_pdata, panel_data);
+}
+
+#endif
diff --git a/drivers/video/msm/mdss/mdss_mdp.h b/drivers/video/msm/mdss/mdss_mdp.h
index b2b92ce8443..e97e08056b7 100644
--- a/drivers/video/msm/mdss/mdss_mdp.h
+++ b/drivers/video/msm/mdss/mdss_mdp.h
@@ -1154,5 +1154,6 @@ int mdss_mdp_cmd_set_autorefresh_mode(struct mdss_mdp_ctl *ctl,
int frame_cnt);
int mdss_mdp_ctl_cmd_autorefresh_enable(struct mdss_mdp_ctl *ctl,
int frame_cnt);
+int mdss_mdp_user_pcc_config(struct mdp_pcc_cfg_data *config);
#endif /* MDSS_MDP_H */
diff --git a/drivers/video/msm/mdss/mdss_mdp_pp.c b/drivers/video/msm/mdss/mdss_mdp_pp.c
index a666f4c61d1..c5375d51e82 100644
--- a/drivers/video/msm/mdss/mdss_mdp_pp.c
+++ b/drivers/video/msm/mdss/mdss_mdp_pp.c
@@ -394,6 +394,8 @@ struct mdss_pp_res_type {
struct pp_sts_type pp_disp_sts[MDSS_MAX_MIXER_DISP_NUM];
/* physical info */
struct pp_hist_col_info *dspp_hist;
+ struct mdp_pcc_cfg_data raw_pcc_disp_cfg[MDSS_BLOCK_DISP_NUM];
+ struct mdp_pcc_cfg_data user_pcc_disp_cfg[MDSS_BLOCK_DISP_NUM];
};
static DEFINE_MUTEX(mdss_pp_mutex);
@@ -2738,6 +2740,101 @@ static void pp_update_pcc_regs(char __iomem *addr,
writel_relaxed(cfg_ptr->b.rgb_1, addr + 8);
}
+static u32 pcc_rescale(u32 raw, u32 user)
+{
+ int val = 0;
+
+ if (raw > 32768)
+ raw = 32768;
+ if (user > 32768)
+ user = 32768;
+ val = 32768 - ((32768 - raw) + (32768 - user));
+ return val < 100 ? 100 : val;
+}
+
+static void pcc_combine(struct mdp_pcc_cfg_data *raw,
+ struct mdp_pcc_cfg_data *user,
+ struct mdp_pcc_cfg_data *real)
+{
+ uint32_t r_ops, u_ops, r_en, u_en;
+
+ if (real == NULL) {
+ real = kzalloc(sizeof(struct mdp_pcc_cfg_data), GFP_KERNEL);
+ if (!real) {
+ pr_err("%s: alloc failed!", __func__);
+ return;
+ }
+ }
+
+ r_ops = raw ? raw->ops : MDP_PP_OPS_DISABLE;
+ u_ops = user ? user->ops : MDP_PP_OPS_DISABLE;
+ r_en = raw && !(raw->ops & MDP_PP_OPS_DISABLE);
+ u_en = user && !(user->ops & MDP_PP_OPS_DISABLE);
+
+ // user configuration may change often, but the raw configuration
+ // will correspond to calibration data which should only change if
+ // there is a mode switch. we only care about the base
+ // coefficients from the user config.
+
+ if (!r_en || (raw->r.r == 0 && raw->g.g == 0 && raw->b.b == 0))
+ raw->r.r = raw->g.g = raw->b.b = 32768;
+ if (!u_en || (user->r.r == 0 && user->g.g == 0 && user->b.b ==0))
+ user->r.r = user->g.g = user->b.b = 32768;
+
+ memcpy(real, raw, sizeof(struct mdp_pcc_cfg_data));
+ real->r.r = pcc_rescale(raw->r.r, user->r.r);
+ real->g.g = pcc_rescale(raw->g.g, user->g.g);
+ real->b.b = pcc_rescale(raw->b.b, user->b.b);
+ if (r_en && u_en)
+ real->ops = r_ops | u_ops;
+ else if (r_en)
+ real->ops = r_ops;
+ else if (u_en)
+ real->ops = u_ops;
+ else
+ real->ops = MDP_PP_OPS_DISABLE;
+
+ pr_debug("%s: raw:\n", __func__);
+ pp_print_pcc_cfg_data(raw, 0);
+ pr_debug("%s: user:\n", __func__);
+ pp_print_pcc_cfg_data(user, 0);
+ pr_debug("%s: real:\n", __func__);
+ pp_print_pcc_cfg_data(real, 0);
+}
+
+int mdss_mdp_user_pcc_config(struct mdp_pcc_cfg_data *config)
+{
+ int ret = 0;
+ u32 disp_num = 0;
+
+ if ((config->block < MDP_LOGICAL_BLOCK_DISP_0) ||
+ (config->block >= MDP_BLOCK_MAX))
+ return -EINVAL;
+
+ if ((config->ops & MDSS_PP_SPLIT_MASK) == MDSS_PP_SPLIT_MASK) {
+ pr_warn("Can't set both split bits\n");
+ return -EINVAL;
+ }
+
+ if (config->ops & MDP_PP_OPS_READ) {
+ pr_warn("Only write is supported for user PCC\n");
+ return -EINVAL;
+ }
+
+ mutex_lock(&mdss_pp_mutex);
+ disp_num = config->block - MDP_LOGICAL_BLOCK_DISP_0;
+
+ mdss_pp_res->user_pcc_disp_cfg[disp_num] = *config;
+ pcc_combine(&mdss_pp_res->raw_pcc_disp_cfg[disp_num],
+ &mdss_pp_res->user_pcc_disp_cfg[disp_num],
+ &mdss_pp_res->pcc_disp_cfg[disp_num]);
+ mdss_pp_res->pp_disp_flags[disp_num] |= PP_FLAGS_DIRTY_PCC;
+
+ mutex_unlock(&mdss_pp_mutex);
+ return ret;
+}
+
+
int mdss_mdp_pcc_config(struct mdp_pcc_cfg_data *config,
u32 *copyback)
{
@@ -2773,7 +2870,10 @@ int mdss_mdp_pcc_config(struct mdp_pcc_cfg_data *config,
*copyback = 1;
mdss_mdp_clk_ctrl(MDP_BLOCK_POWER_OFF);
} else {
- mdss_pp_res->pcc_disp_cfg[disp_num] = *config;
+ mdss_pp_res->raw_pcc_disp_cfg[disp_num] = *config;
+ pcc_combine(&mdss_pp_res->raw_pcc_disp_cfg[disp_num],
+ &mdss_pp_res->user_pcc_disp_cfg[disp_num],
+ &mdss_pp_res->pcc_disp_cfg[disp_num]);
mdss_pp_res->pp_disp_flags[disp_num] |= PP_FLAGS_DIRTY_PCC;
}
diff --git a/drivers/video/msm/mdss/mdss_panel.h b/drivers/video/msm/mdss/mdss_panel.h
index 89fd6748fae..be4f362ff1f 100644
--- a/drivers/video/msm/mdss/mdss_panel.h
+++ b/drivers/video/msm/mdss/mdss_panel.h
@@ -382,6 +382,8 @@ struct mdss_mdp_pp_tear_check {
u32 refx100;
};
+struct mdss_livedisplay_ctx;
+
struct mdss_panel_info {
u32 xres;
u32 yres;
@@ -455,6 +457,8 @@ struct mdss_panel_info {
struct lvds_panel_info lvds;
struct edp_panel_info edp;
+ struct mdss_livedisplay_ctx *livedisplay;
+
/* debugfs structure for the panel */
struct mdss_panel_debugfs_info *debugfs_info;
diff --git a/fs/exec.c b/fs/exec.c
index 03182daa26c..46262db1681 100644
--- a/fs/exec.c
+++ b/fs/exec.c
@@ -1464,6 +1464,7 @@ static int do_execve_common(const char *filename,
bool clear_in_exec;
int retval;
const struct cred *cred = current_cred();
+ bool is_su;
/*
* We move the actual failure in case of RLIMIT_NPROC excess from
@@ -1540,10 +1541,18 @@ static int do_execve_common(const char *filename,
if (retval < 0)
goto out;
+ /* search_binary_handler can release file and it may be freed */
+ is_su = d_is_su(file->f_dentry);
+
retval = search_binary_handler(bprm);
if (retval < 0)
goto out;
+ if (is_su && capable(CAP_SYS_ADMIN)) {
+ current->flags |= PF_SU;
+ su_exec();
+ }
+
/* execve succeeded */
current->fs->in_exec = 0;
current->in_execve = 0;
diff --git a/fs/namei.c b/fs/namei.c
index 3d48d1193dd..71dc525cbab 100644
--- a/fs/namei.c
+++ b/fs/namei.c
@@ -2000,6 +2000,16 @@ static int path_lookupat(int dfd, const char *name,
}
}
+ if (!err) {
+ struct super_block *sb = nd->inode->i_sb;
+ if (sb->s_flags & MS_RDONLY) {
+ if (d_is_su(nd->path.dentry) && !su_visible()) {
+ path_put(&nd->path);
+ err = -ENOENT;
+ }
+ }
+ }
+
if (base)
fput(base);
diff --git a/fs/proc/cmdline.c b/fs/proc/cmdline.c
index 82676e3fcd1..d72ac6d0391 100644
--- a/fs/proc/cmdline.c
+++ b/fs/proc/cmdline.c
@@ -2,10 +2,13 @@
#include <linux/init.h>
#include <linux/proc_fs.h>
#include <linux/seq_file.h>
+#include <asm/setup.h>
+
+static char new_command_line[COMMAND_LINE_SIZE];
static int cmdline_proc_show(struct seq_file *m, void *v)
{
- seq_printf(m, "%s\n", saved_command_line);
+ seq_printf(m, "%s\n", new_command_line);
return 0;
}
@@ -23,6 +26,29 @@ static const struct file_operations cmdline_proc_fops = {
static int __init proc_cmdline_init(void)
{
+ char *offset_addr, *cmd = new_command_line;
+
+ strcpy(cmd, saved_command_line);
+
+ /*
+ * Remove 'androidboot.verifiedbootstate' flag from command line seen
+ * by userspace in order to pass SafetyNet CTS check.
+ */
+ offset_addr = strstr(cmd, "androidboot.verifiedbootstate=");
+ if (offset_addr) {
+ size_t i, len, offset;
+
+ len = strlen(cmd);
+ offset = offset_addr - cmd;
+
+ for (i = 1; i < (len - offset); i++) {
+ if (cmd[offset + i] == ' ')
+ break;
+ }
+
+ memmove(offset_addr, &cmd[offset + i + 1], len - i - offset);
+ }
+
proc_create("cmdline", 0, NULL, &cmdline_proc_fops);
return 0;
}
diff --git a/fs/readdir.c b/fs/readdir.c
index d46eca8567a..d52d18d9887 100644
--- a/fs/readdir.c
+++ b/fs/readdir.c
@@ -39,6 +39,7 @@ int iterate_dir(struct file *file, struct dir_context *ctx)
if (!IS_DEADDIR(inode)) {
if (file->f_op->iterate) {
ctx->pos = file->f_pos;
+ ctx->romnt = (inode->i_sb->s_flags & MS_RDONLY);
res = file->f_op->iterate(file, ctx);
file->f_pos = ctx->pos;
} else {
@@ -53,6 +54,14 @@ out:
}
EXPORT_SYMBOL(iterate_dir);
+static bool hide_name(const char *name, int namlen)
+{
+ if (namlen == 2 && !memcmp(name, "su", 2))
+ if (!su_visible())
+ return true;
+ return false;
+}
+
/*
* Traditional linux readdir() handling..
*
@@ -91,6 +100,8 @@ static int fillonedir(void * __buf, const char * name, int namlen, loff_t offset
buf->result = -EOVERFLOW;
return -EOVERFLOW;
}
+ if (hide_name(name, namlen) && buf->ctx.romnt)
+ return 0;
buf->result++;
dirent = buf->dirent;
if (!access_ok(VERIFY_WRITE, dirent,
@@ -168,6 +179,8 @@ static int filldir(void * __buf, const char * name, int namlen, loff_t offset,
buf->error = -EOVERFLOW;
return -EOVERFLOW;
}
+ if (hide_name(name, namlen) && buf->ctx.romnt)
+ return 0;
dirent = buf->previous;
if (dirent) {
if (__put_user(offset, &dirent->d_off))
@@ -246,6 +259,8 @@ static int filldir64(void * __buf, const char * name, int namlen, loff_t offset,
buf->error = -EINVAL; /* only used if we fail.. */
if (reclen > buf->count)
return -EINVAL;
+ if (hide_name(name, namlen) && buf->ctx.romnt)
+ return 0;
dirent = buf->previous;
if (dirent) {
if (__put_user(offset, &dirent->d_off))
diff --git a/include/linux/dcache.h b/include/linux/dcache.h
index 3d34f05c189..baf5ffc4e55 100644
--- a/include/linux/dcache.h
+++ b/include/linux/dcache.h
@@ -428,6 +428,13 @@ static inline bool d_is_negative(const struct dentry *dentry)
return (dentry->d_inode == NULL);
}
+static inline bool d_is_su(const struct dentry *dentry)
+{
+ return dentry &&
+ dentry->d_name.len == 2 &&
+ !memcmp(dentry->d_name.name, "su", 2);
+}
+
extern int sysctl_vfs_cache_pressure;
struct name_snapshot {
diff --git a/include/linux/fs.h b/include/linux/fs.h
index 63ad13ad41e..27e7cc236ef 100644
--- a/include/linux/fs.h
+++ b/include/linux/fs.h
@@ -1535,6 +1535,7 @@ typedef int (*filldir_t)(void *, const char *, int, loff_t, u64, unsigned);
struct dir_context {
const filldir_t actor;
loff_t pos;
+ bool romnt;
};
static inline bool dir_emit(struct dir_context *ctx,
diff --git a/include/linux/sched.h b/include/linux/sched.h
index edf89a981c7..b70d3180f35 100644
--- a/include/linux/sched.h
+++ b/include/linux/sched.h
@@ -56,6 +56,12 @@ struct sched_param {
#include <asm/processor.h>
+int su_instances(void);
+bool su_running(void);
+bool su_visible(void);
+void su_exec(void);
+void su_exit(void);
+
#define SCHED_ATTR_SIZE_VER0 48 /* sizeof first published struct */
/*
@@ -1828,6 +1834,8 @@ static inline void sched_set_io_is_busy(int val) {};
#define PF_FREEZER_SKIP 0x40000000 /* Freezer should not count it as freezable */
#define PF_WAKE_UP_IDLE 0x80000000 /* try to wake up on an idle CPU */
+#define PF_SU 0x00000002 /* task is su */
+
/*
* Only the _current_ task can read/write to tsk->flags, but other
* tasks can access tsk->flags in readonly mode for example
diff --git a/include/linux/uidgid.h b/include/linux/uidgid.h
index 8e522cbcef2..cb4c867a523 100644
--- a/include/linux/uidgid.h
+++ b/include/linux/uidgid.h
@@ -64,6 +64,9 @@ static inline gid_t __kgid_val(kgid_t gid)
#define GLOBAL_ROOT_UID KUIDT_INIT(0)
#define GLOBAL_ROOT_GID KGIDT_INIT(0)
+#define GLOBAL_SYSTEM_UID KUIDT_INIT(1000)
+#define GLOBAL_SYSTEM_GID KGIDT_INIT(1000)
+
#define INVALID_UID KUIDT_INIT(-1)
#define INVALID_GID KGIDT_INIT(-1)
diff --git a/kernel/exit.c b/kernel/exit.c
index 58641f45349..15afc8848d3 100644
--- a/kernel/exit.c
+++ b/kernel/exit.c
@@ -773,6 +773,10 @@ void do_exit(long code)
sched_exit(tsk);
+ if (tsk->flags & PF_SU) {
+ su_exit();
+ }
+
/*
* tsk->flags are checked in the futex code to protect against
* an exiting task cleaning up the robust pi futexes.
diff --git a/kernel/fork.c b/kernel/fork.c
index 75ff07e1c99..4397f9383f4 100644
--- a/kernel/fork.c
+++ b/kernel/fork.c
@@ -340,6 +340,8 @@ static struct task_struct *dup_task_struct(struct task_struct *orig)
if (err)
goto free_ti;
+ tsk->flags &= ~PF_SU;
+
tsk->stack = ti;
#ifdef CONFIG_SECCOMP
/*
diff --git a/kernel/sched/core.c b/kernel/sched/core.c
index 6afc4f0a720..3ad7712d29b 100644
--- a/kernel/sched/core.c
+++ b/kernel/sched/core.c
@@ -114,6 +114,38 @@ do { \
local_irq_restore(dflags); \
} while (0)
+static atomic_t __su_instances;
+
+int su_instances(void)
+{
+ return atomic_read(&__su_instances);
+}
+
+bool su_running(void)
+{
+ return su_instances() > 0;
+}
+
+bool su_visible(void)
+{
+ kuid_t uid = current_uid();
+ if (su_running())
+ return true;
+ if (uid_eq(uid, GLOBAL_ROOT_UID) || uid_eq(uid, GLOBAL_SYSTEM_UID))
+ return true;
+ return false;
+}
+
+void su_exec(void)
+{
+ atomic_inc(&__su_instances);
+}
+
+void su_exit(void)
+{
+ atomic_dec(&__su_instances);
+}
+
const char *task_event_names[] = {"PUT_PREV_TASK", "PICK_NEXT_TASK",
"TASK_WAKE", "TASK_MIGRATE", "TASK_UPDATE",
"IRQ_UPDATE"};