diff options
| -rw-r--r-- | arch/arm64/configs/lineageos_bullhead_defconfig | 677 | ||||
| -rw-r--r-- | drivers/leds/leds-qpnp.c | 14 | ||||
| -rw-r--r-- | drivers/mmc/core/core.c | 2 | ||||
| -rw-r--r-- | drivers/video/msm/mdss/Makefile | 2 | ||||
| -rw-r--r-- | drivers/video/msm/mdss/mdss_dsi_panel.c | 9 | ||||
| -rw-r--r-- | drivers/video/msm/mdss/mdss_fb.c | 5 | ||||
| -rw-r--r-- | drivers/video/msm/mdss/mdss_livedisplay.c | 678 | ||||
| -rw-r--r-- | drivers/video/msm/mdss/mdss_livedisplay.h | 108 | ||||
| -rw-r--r-- | drivers/video/msm/mdss/mdss_mdp.h | 1 | ||||
| -rw-r--r-- | drivers/video/msm/mdss/mdss_mdp_pp.c | 102 | ||||
| -rw-r--r-- | drivers/video/msm/mdss/mdss_panel.h | 4 | ||||
| -rw-r--r-- | fs/exec.c | 9 | ||||
| -rw-r--r-- | fs/namei.c | 10 | ||||
| -rw-r--r-- | fs/proc/cmdline.c | 28 | ||||
| -rw-r--r-- | fs/readdir.c | 15 | ||||
| -rw-r--r-- | include/linux/dcache.h | 7 | ||||
| -rw-r--r-- | include/linux/fs.h | 1 | ||||
| -rw-r--r-- | include/linux/sched.h | 8 | ||||
| -rw-r--r-- | include/linux/uidgid.h | 3 | ||||
| -rw-r--r-- | kernel/exit.c | 4 | ||||
| -rw-r--r-- | kernel/fork.c | 2 | ||||
| -rw-r--r-- | kernel/sched/core.c | 32 |
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"}; |
