diff --git a/OWNERS_core b/OWNERS_core index 1280e89f5101..1aea676a73ac 100644 --- a/OWNERS_core +++ b/OWNERS_core @@ -5,4 +5,4 @@ saravanak@google.com tkjos@google.com willmcvicker@google.com surenb@google.com -elavila@google.com \ No newline at end of file +elavila@google.com diff --git a/android/abi_gki_aarch64_generic b/android/abi_gki_aarch64_generic index 419bbb187d9b..feaf240a1f07 100644 --- a/android/abi_gki_aarch64_generic +++ b/android/abi_gki_aarch64_generic @@ -66,6 +66,7 @@ blkdev_put blk_execute_rq_nowait blk_get_request + blk_ksm_init_passthrough blk_put_request blk_queue_flag_clear blk_queue_flag_set @@ -389,6 +390,7 @@ __devm_regmap_init_spi devm_regulator_bulk_get devm_regulator_get + devm_regulator_get_exclusive devm_regulator_get_optional devm_regulator_put devm_regulator_register @@ -1179,6 +1181,7 @@ of_get_regulator_init_data of_iomap of_irq_find_parent + of_irq_get of_irq_get_byname of_irq_parse_one of_machine_is_compatible @@ -1493,6 +1496,9 @@ rtc_tm_to_time64 rtc_update_irq rtc_valid_tm + __rt_mutex_init + rt_mutex_lock + rt_mutex_unlock rtnl_is_locked rtnl_lock rtnl_unlock @@ -1821,6 +1827,8 @@ __traceiter_android_vh_ufs_send_tm_command __traceiter_android_vh_ufs_send_uic_command __traceiter_android_vh_ufs_update_sysfs + __traceiter_android_vh_usb_dev_resume + __traceiter_android_vh_usb_dev_suspend __traceiter_clock_set_rate __traceiter_cpu_frequency __traceiter_device_pm_callback_end @@ -1886,6 +1894,8 @@ __tracepoint_android_vh_ufs_send_tm_command __tracepoint_android_vh_ufs_send_uic_command __tracepoint_android_vh_ufs_update_sysfs + __tracepoint_android_vh_usb_dev_resume + __tracepoint_android_vh_usb_dev_suspend __tracepoint_clock_set_rate __tracepoint_cpu_frequency __tracepoint_device_pm_callback_end diff --git a/android/abi_gki_aarch64_virtual_device b/android/abi_gki_aarch64_virtual_device index c7028c2f267a..8650a6a8386a 100644 --- a/android/abi_gki_aarch64_virtual_device +++ b/android/abi_gki_aarch64_virtual_device @@ -27,6 +27,7 @@ blk_queue_physical_block_size blk_queue_write_cache blk_status_to_errno + bpf_trace_run1 bpf_trace_run2 bpf_trace_run3 cancel_delayed_work_sync @@ -56,6 +57,8 @@ cpu_number __cpu_online_mask __cpu_possible_mask + crc32_le + crypto_destroy_tfm crypto_register_alg crypto_register_scomp crypto_unregister_alg @@ -71,8 +74,11 @@ destroy_workqueue dev_close _dev_err + __dev_get_by_index + device_add device_add_disk device_create + device_del device_initialize device_register device_release_driver @@ -85,6 +91,7 @@ devm_kmalloc devm_request_threaded_irq _dev_notice + dev_printk dev_queue_xmit dev_set_name _dev_warn @@ -97,7 +104,9 @@ down_read down_write ether_setup + eth_mac_addr ethtool_op_get_link + eth_type_trans eth_validate_addr event_triggers_call failure_tracking @@ -110,7 +119,11 @@ free_netdev __free_pages free_pages + free_percpu fs_bio_set + genlmsg_put + genl_register_family + genl_unregister_family get_device __get_free_pages get_random_bytes @@ -122,6 +135,9 @@ ida_free idr_alloc idr_destroy + idr_find + idr_for_each + idr_get_next idr_remove __init_rwsem __init_swait_queue_head @@ -141,9 +157,11 @@ jiffies_to_msecs kasan_flag_enabled kfree + kfree_sensitive kfree_skb __kmalloc kmalloc_caches + kmalloc_order_trace kmem_cache_alloc kmem_cache_alloc_trace kmem_cache_create @@ -169,6 +187,7 @@ ktime_get_ts64 ktime_get_with_offset kvfree + kvfree_call_rcu kvmalloc_node __list_add_valid __list_del_entry_valid @@ -184,6 +203,7 @@ memstart_addr misc_deregister misc_register + mod_delayed_work_on mod_timer module_layout module_put @@ -207,7 +227,16 @@ netif_rx_ni netif_tx_stop_all_queues netif_tx_wake_queue + netlink_broadcast + netlink_register_notifier + netlink_unicast + netlink_unregister_notifier + net_ratelimit nf_conntrack_destroy + nla_memcpy + __nla_parse + nla_put_64bit + nla_put no_llseek nonseekable_open noop_llseek @@ -232,6 +261,7 @@ __per_cpu_offset perf_trace_buf_alloc perf_trace_run_bpf_submit + platform_device_register_full platform_device_unregister __platform_driver_register platform_driver_unregister @@ -252,6 +282,7 @@ prepare_to_wait prepare_to_wait_event printk + __pskb_pull_tail put_device put_disk __put_page @@ -281,7 +312,9 @@ __regmap_init regmap_read regmap_write + release_firmware remap_pfn_range + request_firmware __request_module request_threaded_irq revalidate_disk_size @@ -313,8 +346,11 @@ skb_add_rx_frag skb_clone skb_dequeue + skb_pull skb_push skb_put + skb_queue_head + skb_queue_purge skb_queue_tail snd_card_free snd_card_new @@ -334,6 +370,7 @@ snprintf sort sprintf + sscanf __stack_chk_fail strcmp strcpy @@ -345,10 +382,15 @@ submit_bio synchronize_rcu sysfs_create_group + sysfs_create_link __sysfs_match_string sysfs_remove_group sysfs_remove_link + system_freezable_wq system_wq + tasklet_init + tasklet_kill + __tasklet_schedule trace_event_buffer_commit trace_event_buffer_reserve trace_event_ignore_this_pid @@ -368,6 +410,7 @@ unlock_page unregister_blkdev unregister_netdev + unregister_netdevice_many unregister_netdevice_notifier unregister_netdevice_queue unregister_virtio_device @@ -447,6 +490,48 @@ sg_miter_start sg_miter_stop +# required by cfg80211.ko + bpf_trace_run10 + bpf_trace_run7 + debugfs_rename + dev_change_net_namespace + dev_get_by_index + device_rename + gcd + genlmsg_multicast_allns + get_net_ns_by_fd + get_net_ns_by_pid + inet_csk_get_port + init_uts_ns + key_create_or_update + key_put + keyring_alloc + ktime_get_coarse_with_offset + memcmp + net_ns_type_operations + nla_find + nla_reserve + __nla_validate + of_prop_next_u32 + __put_net + rb_erase + rb_insert_color + request_firmware_nowait + rfkill_alloc + rfkill_blocked + rfkill_destroy + rfkill_pause_polling + rfkill_register + rfkill_resume_polling + rfkill_set_hw_state + rfkill_unregister + __sock_create + sock_release + system_power_efficient_wq + trace_print_array_seq + verify_pkcs7_signature + wireless_nlevent_flush + # required by clk-vexpress-osc.ko clk_hw_set_rate_range devm_clk_hw_register @@ -461,7 +546,6 @@ # required by failover.ko netdev_master_upper_dev_link - rtnl_is_locked # required by gnss-cmdline.ko bus_find_device @@ -515,6 +599,31 @@ usb_submit_urb usb_unanchor_urb +# required by gs_usb.ko + alloc_candev_mqs + alloc_can_err_skb + alloc_can_skb + can_change_mtu + can_free_echo_skb + can_get_echo_skb + can_put_echo_skb + close_candev + free_candev + open_candev + register_candev + unregister_candev + usb_alloc_coherent + usb_alloc_urb + usb_anchor_urb + usb_control_msg + usb_deregister + usb_free_coherent + usb_free_urb + usb_kill_anchored_urbs + usb_register_driver + usb_submit_urb + usb_unanchor_urb + # required by hci_vhci.ko bt_err _copy_from_iter_full @@ -523,9 +632,6 @@ hci_recv_frame hci_register_dev hci_unregister_dev - skb_pull - skb_queue_head - skb_queue_purge # required by ledtrig-audio.ko led_set_brightness_nosleep @@ -539,6 +645,63 @@ # required by lzo.ko lzo1x_1_compress +# required by mac80211.ko + __alloc_percpu_gfp + arc4_crypt + arc4_setkey + call_rcu + crc32_be + crypto_aead_decrypt + crypto_aead_encrypt + crypto_aead_setauthsize + crypto_aead_setkey + crypto_alloc_aead + crypto_alloc_shash + crypto_alloc_skcipher + __crypto_memneq + crypto_shash_digest + crypto_shash_finup + crypto_shash_setkey + crypto_shash_update + crypto_skcipher_decrypt + crypto_skcipher_encrypt + crypto_skcipher_setkey + __crypto_xor + dev_fetch_sw_netstats + find_next_bit + flush_delayed_work + get_random_u32 + __hw_addr_init + __hw_addr_sync + __hw_addr_unsync + kernel_param_lock + kernel_param_unlock + kfree_skb_list + ktime_get_seconds + netdev_set_default_ethtool_ops + netif_receive_skb + netif_receive_skb_list + prandom_bytes + prandom_u32 + pskb_expand_head + ___pskb_trim + rcu_barrier + register_inet6addr_notifier + register_inetaddr_notifier + rhashtable_free_and_destroy + rhltable_init + round_jiffies + round_jiffies_relative + round_jiffies_up + skb_checksum_help + skb_clone_sk + skb_complete_wifi_ack + skb_ensure_writable + __skb_get_hash + __skb_gso_segment + unregister_inet6addr_notifier + unregister_inetaddr_notifier + # required by mac80211_hwsim.ko __cfg80211_alloc_event_skb __cfg80211_alloc_reply_skb @@ -546,14 +709,9 @@ cfg80211_vendor_cmd_reply debugfs_attr_read debugfs_attr_write - dev_alloc_name device_bind_driver dst_release - eth_mac_addr - genlmsg_put genl_notify - genl_register_family - genl_unregister_family hrtimer_cancel hrtimer_forward hrtimer_init @@ -586,26 +744,15 @@ netlink_unicast netlink_unregister_notifier net_namespace_list - nla_memcpy - __nla_parse - nla_put_64bit - nla_put param_ops_ushort register_pernet_device regulatory_hint rhashtable_destroy rhashtable_init - rhashtable_insert_slow - __rht_bucket_nested - rht_bucket_nested - rht_bucket_nested_insert schedule_timeout_interruptible simple_attr_open simple_attr_release - skb_copy - skb_copy_expand __skb_ext_put - skb_trim skb_unlink unregister_pernet_device wiphy_apply_custom_regulatory @@ -688,7 +835,6 @@ submit_bh submit_bio_wait sync_blockdev - sysfs_create_link unregister_reboot_notifier unregister_sysctl_table vfs_fsync @@ -790,10 +936,8 @@ snd_ctl_boolean_stereo_info strchr strlcat - __sw_hweight32 # required by snd-hda-codec.ko - bpf_trace_run4 current_work device_attach driver_register @@ -843,11 +987,9 @@ snd_dma_alloc_pages snd_dma_free_pages snd_pcm_format_width - __sw_hweight64 timecounter_init # required by snd-hda-intel.ko - bpf_trace_run1 complete_all param_array_ops param_get_int @@ -895,7 +1037,6 @@ efi efi_tpm_final_log_size hash_digest_size - idr_get_next idr_replace jiffies_to_usecs memchr_inv @@ -1072,7 +1213,6 @@ __get_task_comm iomem_resource is_vmalloc_addr - kmalloc_order_trace memdup_user seq_puts sync_file_create @@ -1145,8 +1285,6 @@ # required by virtio_mmio.ko device_for_each_child devm_platform_ioremap_resource - platform_device_register_full - sscanf # required by virtio_net.ko bpf_dispatcher_xdp_func @@ -1163,13 +1301,11 @@ eth_prepare_mac_addr_change ethtool_op_get_ts_info ethtool_virtdev_set_link_ksettings - eth_type_trans flow_keys_basic_dissector __napi_alloc_skb napi_complete_done napi_consume_skb napi_disable - napi_gro_receive __napi_schedule napi_schedule_prep netdev_notify_peers @@ -1180,8 +1316,6 @@ netif_set_real_num_rx_queues netif_set_real_num_tx_queues __netif_set_xps_queue - net_ratelimit - __pskb_pull_tail _raw_spin_trylock sched_clock skb_coalesce_rx_frag @@ -1191,7 +1325,6 @@ skb_to_sgvec skb_tstamp_tx softnet_data - synchronize_net __traceiter_xdp_exception __tracepoint_xdp_exception virtqueue_add_inbuf_ctx @@ -1288,20 +1421,14 @@ __alloc_percpu bdget_disk bdput - __class_register - class_unregister crypto_alloc_base crypto_comp_compress crypto_comp_decompress - crypto_destroy_tfm crypto_has_alg disk_end_io_acct disk_start_io_acct flush_dcache_page - free_percpu fsync_bdev - idr_find - idr_for_each kstrtou16 memset64 mutex_is_locked diff --git a/arch/arm64/boot/dts/google/gs101-common.dtsi b/arch/arm64/boot/dts/google/gs101-common.dtsi index c0ec80958c59..196a2d532ea0 100644 --- a/arch/arm64/boot/dts/google/gs101-common.dtsi +++ b/arch/arm64/boot/dts/google/gs101-common.dtsi @@ -371,4 +371,8 @@ vreg2-supply = <&m_ldo19_reg>; }; +&aoc { + sensor_1v8-supply = <&s_ldo7_reg>; + sensor_3v3-supply = <&s_ldo6_reg>; +}; diff --git a/arch/arm64/boot/dts/google/gs101-cp-s5200-sit.dtsi b/arch/arm64/boot/dts/google/gs101-cp-s5200-sit.dtsi index da97f0f82b39..ba2d54a67355 100644 --- a/arch/arm64/boot/dts/google/gs101-cp-s5200-sit.dtsi +++ b/arch/arm64/boot/dts/google/gs101-cp-s5200-sit.dtsi @@ -263,8 +263,8 @@ tpmon,measure = ; tpmon,target = ; tpmon,idx = <0>; - tpmon,threshold = <100 200>; /* Mbps */ - tpmon,values = <10000 50000 100000>; + tpmon,threshold = <200>; /* Mbps */ + tpmon,values = <100000 2000000>; }; tpmon_mif { tpmon,enable = <1>; diff --git a/arch/arm64/boot/dts/google/gs101-cpu.dtsi b/arch/arm64/boot/dts/google/gs101-cpu.dtsi index 9fc5f8155dde..826c385f3c57 100644 --- a/arch/arm64/boot/dts/google/gs101-cpu.dtsi +++ b/arch/arm64/boot/dts/google/gs101-cpu.dtsi @@ -256,6 +256,7 @@ /* max-freq is set in gs101-a0.dts and gs101-b0.dts */ min-freq = <300000>; + resume-freq = <1197000>; #cooling-cells = <2>; /* min followed by max */ ect-coeff-index = <2>; @@ -275,6 +276,7 @@ max-freq = <2253000>; min-freq = <400000>; + resume-freq = <1491000>; #cooling-cells = <2>; /* min followed by max */ ect-coeff-index = <1>; @@ -294,6 +296,7 @@ /* max-freq is set in gs101-a0.dts and gs101-b0.dts */ min-freq = <500000>; + resume-freq = <1826000>; #cooling-cells = <2>; /* min followed by max */ ect-coeff-index = <0>; diff --git a/arch/arm64/boot/dts/google/gs101-isp.dtsi b/arch/arm64/boot/dts/google/gs101-isp.dtsi index 1f1bf38a8e1a..d224f1a3f766 100644 --- a/arch/arm64/boot/dts/google/gs101-isp.dtsi +++ b/arch/arm64/boot/dts/google/gs101-isp.dtsi @@ -691,7 +691,8 @@ "itsc", "sysreg_dns", "ssmt_d0_itsc", - "ssmt_d1_itsc"; + "ssmt_d1_itsc", + "sysreg_dns"; clocks = <&clock UMUX_CLKCMU_ITP_BUS>, diff --git a/arch/arm64/boot/dts/google/gs101-oriole-battery-data.dtsi b/arch/arm64/boot/dts/google/gs101-oriole-battery-data.dtsi index dfadc4497c37..218fd929c26c 100644 --- a/arch/arm64/boot/dts/google/gs101-oriole-battery-data.dtsi +++ b/arch/arm64/boot/dts/google/gs101-oriole-battery-data.dtsi @@ -51,10 +51,10 @@ maxim,config { >; }; - /* COS: 2733, 06_p1_rc2.ini, 2021-01-27, b/178520303, rc2 model */ + /* COS: 2733, 06_p1_rc2.ini, 2021-08-23, b/197483092, rc2 model */ maxim,cos-a1-2k { maxim,batt-id-kohm = <2>; - maxim,model-version = <3>; + maxim,model-version = <5>; maxim,force-reset-model-data; maxim,fg-model = /bits/ 16 < 0x9a10 0xa600 0xb690 0xb870 0xb9b0 0xbc40 0xbd00 0xbdd0 @@ -66,7 +66,7 @@ maxim,config { >; maxim,fg-params = /bits/ 16 < /* 0x0036 */ 0xf060 /* IAvgEmpty */ - /* 0x002a */ 0x2038 /* RelaxCFG */ + /* 0x002a */ 0x0839 /* RelaxCFG */ /* 0x0028 */ 0x260e /* LearnCFG */ /* 0x001D */ 0x4217 /* Config */ /* 0x00BB */ 0x0090 /* Config2 */ @@ -77,13 +77,13 @@ maxim,config { /* 0x0045 */ 0x0094 /* dQacc */ /* 0x0023 */ 0x0940 /* FullCAPNom */ /* 0x003A */ 0xA561 /* V_empty */ - /* 0x0012 */ 0x0A80 /* QResidual00 */ - /* 0x0022 */ 0x0500 /* QResidual10 */ - /* 0x0032 */ 0x0200 /* QResidual20 */ - /* 0x0042 */ 0x0200 /* QResidual30 */ + /* 0x0012 */ 0x1500 /* QResidual00 */ + /* 0x0022 */ 0x0a00 /* QResidual10 */ + /* 0x0032 */ 0x0480 /* QResidual20 */ + /* 0x0042 */ 0x0400 /* QResidual30 */ /* 0x0038 */ 0x0700 /* RCOMP0 */ /* 0x0039 */ 0x0d00 /* TempCo */ - /* 0x001E */ 0x02d3 /* ICHGTerm */ + /* 0x001E */ 0x05a0 /* ICHGTerm */ /* 0x002C */ 0xED51 /* TGain */ /* 0x002D */ 0x1EBA /* TOff */ /* 0x00B9 */ 0x0014 /* Curve */ @@ -95,10 +95,10 @@ maxim,config { >; }; - /* LSN: 2729, 06_p1_rc2.ini, 2021-01-27, b/178520303, rc2 model */ + /* LSN: 2729, 06_p1_rc2.ini, 2021-08-23, b/197483092, rc2 model */ maxim,lsn-a1-3k { maxim,batt-id-kohm = <3>; - maxim,model-version = <3>; + maxim,model-version = <5>; maxim,force-reset-model-data; maxim,fg-model = /bits/ 16 < 0x91c0 0xa920 0xb6a0 0xb860 0xb9d0 0xbc40 0xbd20 0xbde0 @@ -110,7 +110,7 @@ maxim,config { >; maxim,fg-params = /bits/ 16 < /* 0x0036 */ 0xf060 /* IAvgEmpty */ - /* 0x002a */ 0x2038 /* RelaxCFG */ + /* 0x002a */ 0x0839 /* RelaxCFG */ /* 0x0028 */ 0x260e /* LearnCFG */ /* 0x001D */ 0x4217 /* Config */ /* 0x00BB */ 0x0090 /* Config2 */ @@ -121,13 +121,13 @@ maxim,config { /* 0x0045 */ 0x0092 /* dQacc */ /* 0x0023 */ 0x0921 /* FullCAPNom */ /* 0x003A */ 0xA561 /* V_empty */ - /* 0x0012 */ 0x0A80 /* QResidual00 */ - /* 0x0022 */ 0x0480 /* QResidual10 */ - /* 0x0032 */ 0x0200 /* QResidual20 */ - /* 0x0042 */ 0x0200 /* QResidual30 */ + /* 0x0012 */ 0x1400 /* QResidual00 */ + /* 0x0022 */ 0x0980 /* QResidual10 */ + /* 0x0032 */ 0x0480 /* QResidual20 */ + /* 0x0042 */ 0x0400 /* QResidual30 */ /* 0x0038 */ 0x0700 /* RCOMP0 */ /* 0x0039 */ 0x0d00 /* TempCo */ - /* 0x001E */ 0x02d3 /* ICHGTerm */ + /* 0x001E */ 0x05a0 /* ICHGTerm */ /* 0x002C */ 0xED51 /* TGain */ /* 0x002D */ 0x1EBA /* TOff */ /* 0x00B9 */ 0x0014 /* Curve */ diff --git a/arch/arm64/boot/dts/google/gs101-oriole-battery.dtsi b/arch/arm64/boot/dts/google/gs101-oriole-battery.dtsi index b21a0fd30a82..1b4a631a2920 100644 --- a/arch/arm64/boot/dts/google/gs101-oriole-battery.dtsi +++ b/arch/arm64/boot/dts/google/gs101-oriole-battery.dtsi @@ -23,9 +23,9 @@ google_battery: google,battery { google,ttf-temp-idx= <2>; google,ttf-adapter = <3000>; - google,ttf-soc-table = <51 60 74 85 88 91 95 100>; - google,ttf-elap-table = <41 50 65 82 99 134 204 320>; - google,ttf-tier-table = <0 62 73>; + google,ttf-soc-table = <50 58 76 83 87 91 93 100>; + google,ttf-elap-table = <38 44 58 76 89 121 165 178>; + google,ttf-tier-table = <0 59 77>; }; google_bms { diff --git a/arch/arm64/boot/dts/google/gs101-oriole-wcharger.dtsi b/arch/arm64/boot/dts/google/gs101-oriole-wcharger.dtsi index 2268b950d6f2..f25557b7a40d 100644 --- a/arch/arm64/boot/dts/google/gs101-oriole-wcharger.dtsi +++ b/arch/arm64/boot/dts/google/gs101-oriole-wcharger.dtsi @@ -11,7 +11,7 @@ p9412@3c { fod = [97 36 91 2e 97 10 9b 05 9f f3 9f ee 19 06 01 3c]; fod_epp = [8a 6d 86 56 8e 3b 8b 3e 8c 33 91 0b 20 13 01 50]; - fod_hpp = [91 9D 8D 86 8B 6B 88 5C 89 51 8E 29]; + fod_hpp = [A4 72 8F 78 8B 6B 88 5C 89 51 8E 29]; google,q_value = <67>; google,alignment_scalar_low_current = <200>; diff --git a/arch/arm64/boot/dts/google/gs101-pmic.dtsi b/arch/arm64/boot/dts/google/gs101-pmic.dtsi index 2e1b323e16ac..e5ec8753abf0 100644 --- a/arch/arm64/boot/dts/google/gs101-pmic.dtsi +++ b/arch/arm64/boot/dts/google/gs101-pmic.dtsi @@ -978,7 +978,7 @@ regulator-name = "S2MPG11_LDO6"; regulator-min-microvolt = <2500000>; regulator-max-microvolt = <3300000>; - regulator-always-on; + regulator-boot-on; regulator-initial-mode = ; channel-mux-selection = <0x26>; schematic-name = "L6S_PROX"; @@ -989,7 +989,7 @@ regulator-name = "S2MPG11_LDO7"; regulator-min-microvolt = <1600000>; regulator-max-microvolt = <1950000>; - regulator-always-on; + regulator-boot-on; regulator-initial-mode = ; channel-mux-selection = <0x27>; schematic-name = "L7S_SENSORS"; diff --git a/arch/arm64/boot/dts/google/gs101-raven-battery-data.dtsi b/arch/arm64/boot/dts/google/gs101-raven-battery-data.dtsi index c05d7386c586..6a7c913f6480 100644 --- a/arch/arm64/boot/dts/google/gs101-raven-battery-data.dtsi +++ b/arch/arm64/boot/dts/google/gs101-raven-battery-data.dtsi @@ -55,7 +55,7 @@ maxim,config { /* ATL: 1_ATL_011421_RC2, 2021-03-18, b/183051702, characterized INI */ maxim,cos-a1-1k { maxim,batt-id-kohm = <1>; - maxim,model-version = <3>; + maxim,model-version = <4>; maxim,force-reset-model-data; maxim,fg-model = /bits/ 16 < @@ -68,7 +68,7 @@ maxim,config { >; maxim,fg-params = /bits/ 16 < /* 0x0036 */ 0xf060 /* IAvgEmpty */ - /* 0x002a */ 0x2038 /* RelaxCFG */ + /* 0x002a */ 0x0839 /* RelaxCFG */ /* 0x0028 */ 0x260e /* LearnCFG */ /* 0x001D */ 0x4217 /* Config */ /* 0x00BB */ 0x0090 /* Config2 */ @@ -85,7 +85,7 @@ maxim,config { /* 0x0042 */ 0x0400 /* QResidual30 */ /* 0x0038 */ 0x08e0 /* RCOMP0 */ /* 0x0039 */ 0x0d00 /* TempCo */ - /* 0x001E */ 0x0310 /* ICHGTerm */ + /* 0x001E */ 0x0620 /* ICHGTerm */ /* 0x002C */ 0xED51 /* TGain */ /* 0x002D */ 0x1EBA /* TOff */ /* 0x00B9 */ 0x0014 /* Curve */ @@ -100,7 +100,7 @@ maxim,config { /* LSN: 3_LSN_050321_RC2_Cell, 2021-05-04, b/187115058, rc2 model */ maxim,lsn-a1-3k { maxim,batt-id-kohm = <3>; - maxim,model-version = <3>; + maxim,model-version = <4>; maxim,force-reset-model-data; maxim,fg-model = /bits/ 16 < 0x9cb0 0xb790 0xb900 0xbaf0 0xbc10 0xbd30 0xbeb0 0xc030 @@ -112,7 +112,7 @@ maxim,config { >; maxim,fg-params = /bits/ 16 < /* 0x0036 */ 0xf060 /* IAvgEmpty */ - /* 0x002a */ 0x2038 /* RelaxCFG */ + /* 0x002a */ 0x0839 /* RelaxCFG */ /* 0x0028 */ 0x260e /* LearnCFG */ /* 0x001D */ 0x4217 /* Config */ /* 0x00BB */ 0x0090 /* Config2 */ @@ -129,7 +129,7 @@ maxim,config { /* 0x0042 */ 0x0380 /* QResidual30 */ /* 0x0038 */ 0x0680 /* RCOMP0 */ /* 0x0039 */ 0x0a02 /* TempCo */ - /* 0x001E */ 0x0310 /* ICHGTerm */ + /* 0x001E */ 0x0620 /* ICHGTerm */ /* 0x002C */ 0xED51 /* TGain */ /* 0x002D */ 0x1EBA /* TOff */ /* 0x00B9 */ 0x0014 /* Curve */ diff --git a/arch/arm64/boot/dts/google/gs101-raven-battery.dtsi b/arch/arm64/boot/dts/google/gs101-raven-battery.dtsi index 3c67a62cd07b..d8ebebdd1fcb 100644 --- a/arch/arm64/boot/dts/google/gs101-raven-battery.dtsi +++ b/arch/arm64/boot/dts/google/gs101-raven-battery.dtsi @@ -23,9 +23,9 @@ google_battery: google,battery { google,ttf-temp-idx= <2>; google,ttf-adapter = <3000>; - google,ttf-soc-table = <39 48 67 74 80 85 93 100>; - google,ttf-elap-table = <39 47 56 77 95 109 198 299>; - google,ttf-tier-table = <0 53 68>; + google,ttf-soc-table = <50 57 70 73 80 84 91 100>; + google,ttf-elap-table = <39 47 55 66 78 89 138 178>; + google,ttf-tier-table = <0 57 74>; }; google_bms { diff --git a/arch/arm64/boot/dts/google/gs101-raven-charging.dtsi b/arch/arm64/boot/dts/google/gs101-raven-charging.dtsi index a01736913fd7..4109016cd7e5 100644 --- a/arch/arm64/boot/dts/google/gs101-raven-charging.dtsi +++ b/arch/arm64/boot/dts/google/gs101-raven-charging.dtsi @@ -13,5 +13,5 @@ &google_charger { google,thermal-mitigation = <5000000 4000000 2500000 1000000>; - google,wlc-fcc-thermal-mitigation = <5000000 5000000 2500000 1000000>; + google,wlc-fcc-thermal-mitigation = <5000000 5000000 4000000 2500000 1000000>; }; diff --git a/arch/arm64/boot/dts/google/gs101-raviole-thermal.dtsi b/arch/arm64/boot/dts/google/gs101-raviole-thermal.dtsi index 872938ce29f2..630df9e5c8c8 100644 --- a/arch/arm64/boot/dts/google/gs101-raviole-thermal.dtsi +++ b/arch/arm64/boot/dts/google/gs101-raviole-thermal.dtsi @@ -53,10 +53,20 @@ thermal-sensors = <&gs101_tm1 1>; trips { trip_config1: trip-config1 { - temperature = <125000>; + temperature = <56000>; hysteresis = <1000>; type = "passive"; }; + backup_shutdown_sw: backup-shutdown-sw { + temperature = <57000>; + hysteresis = <1000>; + type = "critical"; + }; + backup_shutdown_hw: backup-shutdown-hw { + temperature = <59000>; + hysteresis = <1000>; + type = "hot"; + }; }; }; qi_therm { diff --git a/arch/arm64/boot/dts/google/gs101-slider-bcl.dtsi b/arch/arm64/boot/dts/google/gs101-slider-bcl.dtsi index 032db45ee396..352637ce6eff 100644 --- a/arch/arm64/boot/dts/google/gs101-slider-bcl.dtsi +++ b/arch/arm64/boot/dts/google/gs101-slider-bcl.dtsi @@ -22,10 +22,13 @@ mpmm_settings = <0x1a>; tpu_con_heavy = <0xf041c3>; tpu_con_light = <0xf041c5>; - tpu_clkdivstep = <0x1>; + tpu_clkdivstep = <0x201>; gpu_con_heavy = <0xf04385>; gpu_con_light = <0>; - gpu_clkdivstep = <0x1>; + gpu_clkdivstep = <0x801>; + cpu2_clkdivstep = <0x801>; + cpu1_clkdivstep = <0x0>; + cpu0_clkdivstep = <0x1>; }; }; }; diff --git a/arch/arm64/boot/dts/google/gs101-tpu.dtsi b/arch/arm64/boot/dts/google/gs101-tpu.dtsi index a9ba2b50af6e..24e6e1f86f79 100644 --- a/arch/arm64/boot/dts/google/gs101-tpu.dtsi +++ b/arch/arm64/boot/dts/google/gs101-tpu.dtsi @@ -28,20 +28,21 @@ csr-phys = <0x17690000>; csr-size = <0x10000>; gsa-device = <&gsa>; - tpu_dvfs_table_size = <5 2>; /**/ + tpu_dvfs_table_size = <6 2>; /**/ /* DVFS values calculated from average power with real-world workloads * on B0 */ tpu_dvfs_table = < - /* + /* when updating tpu_dvfs_table, update tpu_dvfs_table_size as well * freq power(mW) *---------------------------------- */ - 1066000 5452 - 800000 3314 - 500000 1507 - 226000 761 - 0 0 + 1024000 4819 + 967000 4101 + 836000 3085 + 627000 1916 + 455000 1213 + 226000 0 >; samsung,tzmp; }; diff --git a/arch/arm64/boot/dts/google/gs101-whitefin1-bcl.dtsi b/arch/arm64/boot/dts/google/gs101-whitefin1-bcl.dtsi index 3d3ae2f89605..58c980a5a825 100644 --- a/arch/arm64/boot/dts/google/gs101-whitefin1-bcl.dtsi +++ b/arch/arm64/boot/dts/google/gs101-whitefin1-bcl.dtsi @@ -22,10 +22,13 @@ mpmm_settings = <0x1a>; tpu_con_heavy = <0xf041c3>; tpu_con_light = <0xf041c5>; - tpu_clkdivstep = <0x1>; + tpu_clkdivstep = <0x201>; gpu_con_heavy = <0xf04385>; gpu_con_light = <0>; - gpu_clkdivstep = <0x1>; + gpu_clkdivstep = <0x801>; + cpu2_clkdivstep = <0x801>; + cpu1_clkdivstep = <0x0>; + cpu0_clkdivstep = <0x1>; }; }; }; diff --git a/arch/arm64/boot/dts/google/gs101-whitefin2-bcl.dtsi b/arch/arm64/boot/dts/google/gs101-whitefin2-bcl.dtsi index 6676af1d7045..dc7ce22df55c 100644 --- a/arch/arm64/boot/dts/google/gs101-whitefin2-bcl.dtsi +++ b/arch/arm64/boot/dts/google/gs101-whitefin2-bcl.dtsi @@ -22,10 +22,13 @@ mpmm_settings = <0x1a>; tpu_con_heavy = <0xf041c3>; tpu_con_light = <0xf041c5>; - tpu_clkdivstep = <0x1>; + tpu_clkdivstep = <0x201>; gpu_con_heavy = <0xf04385>; gpu_con_light = <0>; - gpu_clkdivstep = <0x1>; + gpu_clkdivstep = <0x801>; + cpu2_clkdivstep = <0x801>; + cpu1_clkdivstep = <0x0>; + cpu0_clkdivstep = <0x1>; }; }; }; diff --git a/build_slider.sh b/build_slider.sh index b5cda9076c81..59ef5f0e7016 100755 --- a/build_slider.sh +++ b/build_slider.sh @@ -70,23 +70,6 @@ if [ "${BUILD_KERNEL}" = "0" ]; then fi fi -if [ "${EXPERIMENTAL_BUILD}" = "0" -a "${BUILD_KERNEL}" != "0" ]; then - MANIFEST_SHA=$(cat .repo/manifests/default.xml | grep "path=\"aosp\"" | - sed -n "s/^.*revision=\"\([0-9a-fA-F]*\)\".*/\1/p") - pushd aosp/ > /dev/null - # Booting AOSP ToT does not always work; throw a warning to prevent this. - LOCAL_MERGE_BASE=$(git merge-base HEAD aosp/android13-5.10) - if [ -n "${LOCAL_MERGE_BASE}" -a \ - "${MANIFEST_SHA}" != "${LOCAL_MERGE_BASE}" ]; then - echo "Your aosp/ directory appears to be synced to a point beyond the" - echo " latest AOSP merge point. This is not supported, currently, as" - echo " it is prone to errors. Please base any changes on the latest" - echo " merge point as specified in the manifest." - exit_if_error 1 "aosp/ is not based on latest merge point" - fi - popd > /dev/null -fi - # These are for build.sh, so they should be exported. export LTO export KMI_SYMBOL_LIST_STRICT_MODE diff --git a/drivers/android/binder.c b/drivers/android/binder.c index d565081d2f3d..2cc96a0e75ae 100644 --- a/drivers/android/binder.c +++ b/drivers/android/binder.c @@ -3196,9 +3196,8 @@ static void binder_transaction(struct binder_proc *proc, if (reply) { binder_enqueue_thread_work(thread, tcomplete); binder_inner_proc_lock(target_proc); - if (target_thread->is_dead || target_proc->is_frozen) { - return_error = target_thread->is_dead ? - BR_DEAD_REPLY : BR_FROZEN_REPLY; + if (target_thread->is_dead) { + return_error = BR_DEAD_REPLY; binder_inner_proc_unlock(target_proc); goto err_dead_proc_or_thread; } @@ -4806,6 +4805,22 @@ static int binder_ioctl_get_node_debug_info(struct binder_proc *proc, return 0; } +static bool binder_txns_pending_ilocked(struct binder_proc *proc) +{ + struct rb_node *n; + struct binder_thread *thread; + + if (proc->outstanding_txns > 0) + return true; + + for (n = rb_first(&proc->threads); n; n = rb_next(n)) { + thread = rb_entry(n, struct binder_thread, rb_node); + if (thread->transaction_stack) + return true; + } + return false; +} + static int binder_ioctl_freeze(struct binder_freeze_info *info, struct binder_proc *target_proc) { @@ -4837,8 +4852,13 @@ static int binder_ioctl_freeze(struct binder_freeze_info *info, (!target_proc->outstanding_txns), msecs_to_jiffies(info->timeout_ms)); - if (!ret && target_proc->outstanding_txns) - ret = -EAGAIN; + /* Check pending transactions that wait for reply */ + if (ret >= 0) { + binder_inner_proc_lock(target_proc); + if (binder_txns_pending_ilocked(target_proc)) + ret = -EAGAIN; + binder_inner_proc_unlock(target_proc); + } if (ret < 0) { binder_inner_proc_lock(target_proc); @@ -4854,6 +4874,7 @@ static int binder_ioctl_get_freezer_info( { struct binder_proc *target_proc; bool found = false; + __u32 txns_pending; info->sync_recv = 0; info->async_recv = 0; @@ -4863,7 +4884,9 @@ static int binder_ioctl_get_freezer_info( if (target_proc->pid == info->pid) { found = true; binder_inner_proc_lock(target_proc); - info->sync_recv |= target_proc->sync_recv; + txns_pending = binder_txns_pending_ilocked(target_proc); + info->sync_recv |= target_proc->sync_recv | + (txns_pending << 1); info->async_recv |= target_proc->async_recv; binder_inner_proc_unlock(target_proc); } diff --git a/drivers/android/binder_internal.h b/drivers/android/binder_internal.h index 2ddbec09d2f9..8508a7e45865 100644 --- a/drivers/android/binder_internal.h +++ b/drivers/android/binder_internal.h @@ -399,6 +399,8 @@ struct binder_priority { * binder transactions * (protected by @inner_lock) * @sync_recv: process received sync transactions since last frozen + * bit 0: received sync transaction after being frozen + * bit 1: new pending sync transaction during freezing * (protected by @inner_lock) * @async_recv: process received async transactions since last frozen * (protected by @inner_lock) diff --git a/drivers/android/vendor_hooks.c b/drivers/android/vendor_hooks.c index 1302b9b0f5f2..f0ca247d88df 100644 --- a/drivers/android/vendor_hooks.c +++ b/drivers/android/vendor_hooks.c @@ -380,3 +380,6 @@ EXPORT_TRACEPOINT_SYMBOL_GPL(android_rvh_udp_sendmsg); EXPORT_TRACEPOINT_SYMBOL_GPL(android_rvh_udp_recvmsg); EXPORT_TRACEPOINT_SYMBOL_GPL(android_rvh_tcp_recvmsg_stat); EXPORT_TRACEPOINT_SYMBOL_GPL(android_rvh_pci_d3_sleep); +EXPORT_TRACEPOINT_SYMBOL_GPL(android_vh_kmalloc_slab); +EXPORT_TRACEPOINT_SYMBOL_GPL(android_vh_mmap_region); +EXPORT_TRACEPOINT_SYMBOL_GPL(android_vh_try_to_unmap_one); diff --git a/drivers/firmware/arm_scmi/driver.c b/drivers/firmware/arm_scmi/driver.c index 1732fb3e332b..47ee994b3fa7 100644 --- a/drivers/firmware/arm_scmi/driver.c +++ b/drivers/firmware/arm_scmi/driver.c @@ -1395,6 +1395,21 @@ void scmi_unrequest_protocol_device(const struct scmi_device_id *id_table) mutex_unlock(&scmi_requested_devices_mtx); } +static int scmi_cleanup_txrx_channels(struct scmi_info *info) +{ + int ret; + struct idr *idr = &info->tx_idr; + + ret = idr_for_each(idr, info->desc->ops->chan_free, idr); + idr_destroy(&info->tx_idr); + + idr = &info->rx_idr; + ret = idr_for_each(idr, info->desc->ops->chan_free, idr); + idr_destroy(&info->rx_idr); + + return ret; +} + static int scmi_probe(struct platform_device *pdev) { int ret; @@ -1436,7 +1451,7 @@ static int scmi_probe(struct platform_device *pdev) ret = scmi_xfer_info_init(info); if (ret) - return ret; + goto clear_txrx_setup; if (scmi_notification_init(handle)) dev_err(dev, "SCMI Notifications NOT available.\n"); @@ -1449,7 +1464,7 @@ static int scmi_probe(struct platform_device *pdev) ret = scmi_acquire_protocol(handle, SCMI_PROTOCOL_BASE); if (ret) { dev_err(dev, "unable to communicate with SCMI\n"); - return ret; + goto notification_exit; } mutex_lock(&scmi_list_mutex); @@ -1488,6 +1503,12 @@ static int scmi_probe(struct platform_device *pdev) } return 0; + +notification_exit: + scmi_notification_exit(&info->handle); +clear_txrx_setup: + scmi_cleanup_txrx_channels(info); + return ret; } void scmi_free_channel(struct scmi_chan_info *cinfo, struct idr *idr, int id) @@ -1499,7 +1520,6 @@ static int scmi_remove(struct platform_device *pdev) { int ret = 0, id; struct scmi_info *info = platform_get_drvdata(pdev); - struct idr *idr = &info->tx_idr; struct device_node *child; mutex_lock(&scmi_list_mutex); @@ -1523,14 +1543,7 @@ static int scmi_remove(struct platform_device *pdev) idr_destroy(&info->active_protocols); /* Safe to free channels since no more users */ - ret = idr_for_each(idr, info->desc->ops->chan_free, idr); - idr_destroy(&info->tx_idr); - - idr = &info->rx_idr; - ret = idr_for_each(idr, info->desc->ops->chan_free, idr); - idr_destroy(&info->rx_idr); - - return ret; + return scmi_cleanup_txrx_channels(info); } static ssize_t protocol_version_show(struct device *dev, diff --git a/drivers/iommu/samsung-iommu-fault.c b/drivers/iommu/samsung-iommu-fault.c index 1cee5b7ea1a0..2a2a17d350e8 100644 --- a/drivers/iommu/samsung-iommu-fault.c +++ b/drivers/iommu/samsung-iommu-fault.c @@ -559,7 +559,7 @@ irqreturn_t samsung_sysmmu_irq_thread(int irq, void *dev_id) char fault_msg[128] = "Unspecified SysMMU fault"; /* Prevent power down while handling faults */ - pm_runtime_get(drvdata->dev); + pm_runtime_get_sync(drvdata->dev); sysmmu_get_interrupt_info(drvdata, &itype, &vid, &addr, is_secure); reason = sysmmu_fault_type[itype]; diff --git a/drivers/irqchip/qcom-pdc.c b/drivers/irqchip/qcom-pdc.c index afdf0d6600ba..3145e5447a00 100644 --- a/drivers/irqchip/qcom-pdc.c +++ b/drivers/irqchip/qcom-pdc.c @@ -65,26 +65,6 @@ static u32 pdc_reg_read(int reg, u32 i) return readl_relaxed(pdc_base + reg + i * sizeof(u32)); } -static int qcom_pdc_gic_get_irqchip_state(struct irq_data *d, - enum irqchip_irq_state which, - bool *state) -{ - if (d->hwirq == GPIO_NO_WAKE_IRQ) - return 0; - - return irq_chip_get_parent_state(d, which, state); -} - -static int qcom_pdc_gic_set_irqchip_state(struct irq_data *d, - enum irqchip_irq_state which, - bool value) -{ - if (d->hwirq == GPIO_NO_WAKE_IRQ) - return 0; - - return irq_chip_set_parent_state(d, which, value); -} - static void pdc_enable_intr(struct irq_data *d, bool on) { int pin_out = d->hwirq; @@ -103,38 +83,16 @@ static void pdc_enable_intr(struct irq_data *d, bool on) static void qcom_pdc_gic_disable(struct irq_data *d) { - if (d->hwirq == GPIO_NO_WAKE_IRQ) - return; - pdc_enable_intr(d, false); irq_chip_disable_parent(d); } static void qcom_pdc_gic_enable(struct irq_data *d) { - if (d->hwirq == GPIO_NO_WAKE_IRQ) - return; - pdc_enable_intr(d, true); irq_chip_enable_parent(d); } -static void qcom_pdc_gic_mask(struct irq_data *d) -{ - if (d->hwirq == GPIO_NO_WAKE_IRQ) - return; - - irq_chip_mask_parent(d); -} - -static void qcom_pdc_gic_unmask(struct irq_data *d) -{ - if (d->hwirq == GPIO_NO_WAKE_IRQ) - return; - - irq_chip_unmask_parent(d); -} - static u32 __spi_pin_read(unsigned int pin) { void __iomem *cfg_reg = spi_cfg->base + pin * 4; @@ -222,15 +180,11 @@ enum pdc_irq_config_bits { */ static int qcom_pdc_gic_set_type(struct irq_data *d, unsigned int type) { - int pin_out = d->hwirq; int parent_hwirq = d->parent_data->hwirq; enum pdc_irq_config_bits pdc_type; enum pdc_irq_config_bits old_pdc_type; int ret; - if (pin_out == GPIO_NO_WAKE_IRQ) - return 0; - switch (type) { case IRQ_TYPE_EDGE_RISING: pdc_type = PDC_EDGE_RISING; @@ -255,8 +209,8 @@ static int qcom_pdc_gic_set_type(struct irq_data *d, unsigned int type) return -EINVAL; } - old_pdc_type = pdc_reg_read(IRQ_i_CFG, pin_out); - pdc_reg_write(IRQ_i_CFG, pin_out, pdc_type); + old_pdc_type = pdc_reg_read(IRQ_i_CFG, d->hwirq); + pdc_reg_write(IRQ_i_CFG, d->hwirq, pdc_type); /* Additionally, configure (only) the GPIO in the f/w */ ret = spi_configure_type(parent_hwirq, type); @@ -285,12 +239,12 @@ static int qcom_pdc_gic_set_type(struct irq_data *d, unsigned int type) static struct irq_chip qcom_pdc_gic_chip = { .name = "PDC", .irq_eoi = irq_chip_eoi_parent, - .irq_mask = qcom_pdc_gic_mask, - .irq_unmask = qcom_pdc_gic_unmask, + .irq_mask = irq_chip_mask_parent, + .irq_unmask = irq_chip_unmask_parent, .irq_disable = qcom_pdc_gic_disable, .irq_enable = qcom_pdc_gic_enable, - .irq_get_irqchip_state = qcom_pdc_gic_get_irqchip_state, - .irq_set_irqchip_state = qcom_pdc_gic_set_irqchip_state, + .irq_get_irqchip_state = irq_chip_get_parent_state, + .irq_set_irqchip_state = irq_chip_set_parent_state, .irq_retrigger = irq_chip_retrigger_hierarchy, .irq_set_type = qcom_pdc_gic_set_type, .flags = IRQCHIP_MASK_ON_SUSPEND | @@ -351,7 +305,7 @@ static int qcom_pdc_alloc(struct irq_domain *domain, unsigned int virq, parent_hwirq = get_parent_hwirq(hwirq); if (parent_hwirq == PDC_NO_PARENT_IRQ) - return 0; + return irq_domain_disconnect_hierarchy(domain->parent, virq); if (type & IRQ_TYPE_EDGE_BOTH) type = IRQ_TYPE_EDGE_RISING; @@ -388,17 +342,17 @@ static int qcom_pdc_gpio_alloc(struct irq_domain *domain, unsigned int virq, if (ret) return ret; + if (hwirq == GPIO_NO_WAKE_IRQ) + return irq_domain_disconnect_hierarchy(domain, virq); + ret = irq_domain_set_hwirq_and_chip(domain, virq, hwirq, &qcom_pdc_gic_chip, NULL); if (ret) return ret; - if (hwirq == GPIO_NO_WAKE_IRQ) - return 0; - parent_hwirq = get_parent_hwirq(hwirq); if (parent_hwirq == PDC_NO_PARENT_IRQ) - return 0; + return irq_domain_disconnect_hierarchy(domain->parent, virq); if (type & IRQ_TYPE_EDGE_BOTH) type = IRQ_TYPE_EDGE_RISING; diff --git a/drivers/md/dm-verity-target.c b/drivers/md/dm-verity-target.c index 808a98ef624c..9d5c6dd5b756 100644 --- a/drivers/md/dm-verity-target.c +++ b/drivers/md/dm-verity-target.c @@ -475,6 +475,7 @@ static int verity_verify_io(struct dm_verity_io *io) struct bvec_iter start; unsigned b; struct crypto_wait wait; + struct bio *bio = dm_bio_from_per_bio_data(io, v->ti->per_io_data_size); for (b = 0; b < io->n_blocks; b++) { int r; @@ -529,9 +530,17 @@ static int verity_verify_io(struct dm_verity_io *io) else if (verity_fec_decode(v, io, DM_VERITY_BLOCK_TYPE_DATA, cur_block, NULL, &start) == 0) continue; - else if (verity_handle_err(v, DM_VERITY_BLOCK_TYPE_DATA, + else { + if (bio->bi_status) { + /* + * Error correction failed; Just return error + */ + return -EIO; + } + if (verity_handle_err(v, DM_VERITY_BLOCK_TYPE_DATA, cur_block)) - return -EIO; + return -EIO; + } } return 0; diff --git a/drivers/media/platform/exynos/mfc/mfc_core_hwlock.c b/drivers/media/platform/exynos/mfc/mfc_core_hwlock.c index 45bea406f24a..6435b2790a16 100644 --- a/drivers/media/platform/exynos/mfc/mfc_core_hwlock.c +++ b/drivers/media/platform/exynos/mfc/mfc_core_hwlock.c @@ -968,6 +968,7 @@ int mfc_core_just_run(struct mfc_core *core, int new_ctx_index) * as this will be newly decided in Prediction code. */ core->cache_flush_flag = 0; + core->last_cmd_has_cache_flush = 0; /* * Check again the ctx condition and clear work bits diff --git a/drivers/misc/bbdpl/bcm_gps_spi.c b/drivers/misc/bbdpl/bcm_gps_spi.c index 828a2e658269..1c76bc90ed0d 100644 --- a/drivers/misc/bbdpl/bcm_gps_spi.c +++ b/drivers/misc/bbdpl/bcm_gps_spi.c @@ -670,6 +670,7 @@ int bcm_spi_sync(struct bcm_spi_priv *priv, void *tx_buf, xfer.len = len; xfer.tx_buf = tx_buf; xfer.rx_buf = rx_buf; + xfer.bits_per_word = 8; /* bits_per_word; */ /* Sync */ pk_log("w", (unsigned char *)xfer.tx_buf, len); @@ -689,7 +690,8 @@ static int bcm_ssi_tx(struct bcm_spi_priv *priv, int length) struct bcm_ssi_tx_frame *tx = priv->tx_buf; struct bcm_ssi_rx_frame *rx = priv->rx_buf; struct bcm_spi_strm_protocol *strm = &priv->tx_strm; - int bits_per_word = (length >= 255) ? CONFIG_SPI_DMA_BITS_PER_WORD : 8; + int bits_per_word = (length + strm->ctrl_len >= MIN_DMA_SIZE) ? + CONFIG_SPI_DMA_BITS_PER_WORD : 8; int ret; unsigned short m_write; unsigned short bytes_to_write = (unsigned short)length; @@ -780,9 +782,12 @@ int bcm_ssi_rx(struct bcm_spi_priv *priv, size_t *length) { struct bcm_ssi_tx_frame *tx = priv->tx_buf; struct bcm_ssi_rx_frame *rx = priv->rx_buf; + struct circ_buf *rd_circ = &priv->read_buf; struct bcm_spi_strm_protocol *strm = &priv->rx_strm; unsigned short ctrl_len = strm->pckt_len + 1; /* +1 for rx status */ unsigned short payload_len; + int bits_per_word = 8; + size_t sz_to_recv = 0; #ifdef CONFIG_REG_IO if (likely(ssi_dbg_rng) && @@ -819,13 +824,26 @@ int bcm_ssi_rx(struct bcm_spi_priv *priv, size_t *length) return -1; } - /* TODO: limit max payload to 254 because of exynos3 bug */ - *length = min((unsigned short)(strm->frame_len-ctrl_len), - payload_len); /* MAX_SPI_FRAME_LEN */ - memset(tx->data, 0, *length + ctrl_len - 1); /* -1 for rx status */ + *length = min((unsigned short)(strm->frame_len - ctrl_len), payload_len); + + /* SWGNSSGLL-24487 : slowing down read speed if buffer is half full */ + if (CIRC_CNT(rd_circ->head, rd_circ->tail, BCM_SPI_READ_BUF_SIZE) > + BCM_SPI_READ_BUF_SIZE / 2) { + msleep(DELAY_FOR_SYSTEM_OVERLOADED_MS); + if (*length >= READ_SIZE_FOR_SYSTEM_OVERLOADED) + *length = READ_SIZE_FOR_SYSTEM_OVERLOADED; + } + sz_to_recv = *length + ctrl_len; + if (sz_to_recv >= MIN_DMA_SIZE) { + bits_per_word = CONFIG_SPI_DMA_BITS_PER_WORD; + if (sz_to_recv & (CONFIG_SPI_DMA_BYTES_PER_WORD - 1)) + *length = (sz_to_recv & ~(CONFIG_SPI_DMA_BYTES_PER_WORD - 1)) + - ctrl_len; + } + memset(tx->data, 0, *length + ctrl_len - 1); /* -1 for status byte */ - if (bcm_spi_sync(priv, tx, rx, *length+ctrl_len, 8)) + if (bcm_spi_sync(priv, tx, rx, *length+ctrl_len, bits_per_word)) return -1; payload_len = bcm_ssi_get_len(strm->ctrl_byte, rx->data); @@ -889,7 +907,6 @@ void bcm_on_packet_received(void *_priv, unsigned char *data, unsigned int size) priv->packet_received += size; mutex_unlock(&priv->rlock); - wake_up(&priv->poll_wait); bcm_check_overrun(priv, avail); } @@ -924,6 +941,7 @@ static void bcm_rxtx_work_func(struct work_struct *work) #endif struct bcm_spi_priv *priv = container_of(work, struct bcm_spi_priv, rxtx_work); + struct circ_buf *rd_circ = &priv->read_buf; struct circ_buf *wr_circ = &priv->write_buf; struct bcm_spi_strm_protocol *strm = &priv->tx_strm; unsigned short rx_pckt_len = priv->rx_strm.pckt_len; @@ -944,6 +962,7 @@ static void bcm_rxtx_work_func(struct work_struct *work) int ret = 0; size_t avail = 0; size_t written = 0; + size_t sz_to_send = 0; /* Read first */ if (!gpio_is_valid(priv->host_req)) { @@ -1052,6 +1071,13 @@ static void bcm_rxtx_work_func(struct work_struct *work) */ } + /* we should align xfer size to DMA word size. */ + sz_to_send = avail + strm->ctrl_len; + if (sz_to_send >= MIN_DMA_SIZE && + sz_to_send & (CONFIG_SPI_DMA_BYTES_PER_WORD - 1)) + avail = (sz_to_send & ~(CONFIG_SPI_DMA_BYTES_PER_WORD - 1)) + - strm->ctrl_len; + /* Copy from wr_circ the data */ while (avail > 0) { size_t cnt_to_end = CIRC_CNT_TO_END( @@ -1076,16 +1102,26 @@ static void bcm_rxtx_work_func(struct work_struct *work) if (ret) break; - wake_up(&priv->poll_wait); + /* + * SWGNSSAND-2159 While looping, + * wake up lhd only if rx ring is more than 12.5% full + */ + if (CIRC_CNT(rd_circ->head, rd_circ->tail, BCM_SPI_READ_BUF_SIZE) > + BCM_SPI_READ_BUF_SIZE / 8) { + wake_up(&priv->poll_wait); + } #ifdef DEBUG_1HZ_STAT bbd_update_stat(STAT_TX_SSI, written); #endif - } while (gpio_get_value(priv->host_req) || - CIRC_CNT(wr_circ->head, wr_circ->tail, BCM_SPI_WRITE_BUF_SIZE)); + } while (!atomic_read(&priv->suspending) && + (gpio_get_value(priv->host_req) || + CIRC_CNT(wr_circ->head, wr_circ->tail, BCM_SPI_WRITE_BUF_SIZE))); bcm477x_bye(priv); + wake_up(&priv->poll_wait); + /* Enable irq */ spin_lock_irqsave(&priv->irq_lock, flags); @@ -1205,13 +1241,12 @@ static int gps_pinctrl_select(struct bcm_spi_priv *data, bool on) /* SPI driver operations */ -static int bcm_spi_suspend(struct device *dev, pm_message_t state) +static int bcm_spi_suspend(struct device *dev) { struct spi_device *spi = to_spi_device(dev); struct bcm_spi_priv *priv = spi_get_drvdata(spi); unsigned long flags; - atomic_set(&priv->suspending, 1); /* Disable irq */ @@ -1510,6 +1545,11 @@ static const struct of_device_id match_table[] = { }; #endif +static const struct dev_pm_ops bcm_spi_pm_ops = { + .suspend = bcm_spi_suspend, + .resume = bcm_spi_resume, +}; + static struct spi_driver bcm_spi_driver = { .id_table = bcm_spi_id, .probe = bcm_spi_probe, @@ -1521,8 +1561,7 @@ static struct spi_driver bcm_spi_driver = { #ifdef CONFIG_OF .of_match_table = match_table, #endif - .suspend = bcm_spi_suspend, - .resume = bcm_spi_resume, + .pm = &bcm_spi_pm_ops, }, }; diff --git a/drivers/misc/bbdpl/bcm_gps_spi.h b/drivers/misc/bbdpl/bcm_gps_spi.h index 255c73b41d72..f40d4e7f690f 100644 --- a/drivers/misc/bbdpl/bcm_gps_spi.h +++ b/drivers/misc/bbdpl/bcm_gps_spi.h @@ -10,7 +10,10 @@ #define WORD_BURST_SIZE 4 #define CONFIG_SPI_DMA_BYTES_PER_WORD 4 -#define CONFIG_SPI_DMA_BITS_PER_WORD 32 +#define CONFIG_SPI_DMA_BITS_PER_WORD (CONFIG_SPI_DMA_BYTES_PER_WORD * 8) +#define MIN_DMA_SIZE 64 +#define DELAY_FOR_SYSTEM_OVERLOADED_MS 100 +#define READ_SIZE_FOR_SYSTEM_OVERLOADED 1024 #define SSI_MODE_STREAM 0x00 #define SSI_MODE_DEBUG 0x80 @@ -110,8 +113,8 @@ struct bcm_failsafe_data_recordlist { * *******************/ -#define BCM_SPI_READ_BUF_SIZE (8*PAGE_SIZE) -#define BCM_SPI_WRITE_BUF_SIZE (8*PAGE_SIZE) +#define BCM_SPI_READ_BUF_SIZE (16 * PAGE_SIZE) +#define BCM_SPI_WRITE_BUF_SIZE (16 * PAGE_SIZE) /* TODO: limit max payload to 254 because of exynos3 bug */ #define MAX_SPI_DREG_FRAME_LEN 254 diff --git a/drivers/mmc/core/core.c b/drivers/mmc/core/core.c index f086ce1ac9bf..1bfe0891a1bc 100644 --- a/drivers/mmc/core/core.c +++ b/drivers/mmc/core/core.c @@ -917,6 +917,7 @@ void mmc_set_clock(struct mmc_host *host, unsigned int hz) host->ios.clock = hz; mmc_set_ios(host); } +EXPORT_SYMBOL_GPL(mmc_set_clock); int mmc_execute_tuning(struct mmc_card *card) { @@ -999,6 +1000,7 @@ void mmc_set_initial_state(struct mmc_host *host) mmc_crypto_set_initial_state(host); } +EXPORT_SYMBOL_GPL(mmc_set_initial_state); /** * mmc_vdd_to_ocrbitnum - Convert a voltage to the OCR bit number @@ -1262,6 +1264,7 @@ void mmc_set_timing(struct mmc_host *host, unsigned int timing) host->ios.timing = timing; mmc_set_ios(host); } +EXPORT_SYMBOL_GPL(mmc_set_timing); /* * Select appropriate driver type for host. diff --git a/drivers/mmc/core/core.h b/drivers/mmc/core/core.h index dbe7ee457bed..5f442cf256c1 100644 --- a/drivers/mmc/core/core.h +++ b/drivers/mmc/core/core.h @@ -43,7 +43,7 @@ struct device_node *mmc_of_find_child_device(struct mmc_host *host, void mmc_init_erase(struct mmc_card *card); void mmc_set_chip_select(struct mmc_host *host, int mode); -void mmc_set_clock(struct mmc_host *host, unsigned int hz); +extern void mmc_set_clock(struct mmc_host *host, unsigned int hz); void mmc_set_bus_mode(struct mmc_host *host, unsigned int mode); void mmc_set_bus_width(struct mmc_host *host, unsigned int width); u32 mmc_select_voltage(struct mmc_host *host, u32 ocr); diff --git a/drivers/mmc/core/mmc.c b/drivers/mmc/core/mmc.c index 7494d595035e..aca62d703b21 100644 --- a/drivers/mmc/core/mmc.c +++ b/drivers/mmc/core/mmc.c @@ -972,7 +972,7 @@ static int mmc_select_powerclass(struct mmc_card *card) /* * Set the bus speed for the selected speed mode. */ -static void mmc_set_bus_speed(struct mmc_card *card) +void mmc_set_bus_speed(struct mmc_card *card) { unsigned int max_dtr = (unsigned int)-1; @@ -992,7 +992,7 @@ static void mmc_set_bus_speed(struct mmc_card *card) * If the bus width is changed successfully, return the selected width value. * Zero is returned instead of error value if the wide width is not supported. */ -static int mmc_select_bus_width(struct mmc_card *card) +int mmc_select_bus_width(struct mmc_card *card) { static unsigned ext_csd_bits[] = { EXT_CSD_BUS_WIDTH_8, @@ -1057,11 +1057,12 @@ static int mmc_select_bus_width(struct mmc_card *card) return err; } +EXPORT_SYMBOL_GPL(mmc_select_bus_width); /* * Switch to the high-speed mode */ -static int mmc_select_hs(struct mmc_card *card) +int mmc_select_hs(struct mmc_card *card) { int err; @@ -1075,11 +1076,12 @@ static int mmc_select_hs(struct mmc_card *card) return err; } +EXPORT_SYMBOL_GPL(mmc_select_hs); /* * Activate wide bus and DDR if supported. */ -static int mmc_select_hs_ddr(struct mmc_card *card) +int mmc_select_hs_ddr(struct mmc_card *card) { struct mmc_host *host = card->host; u32 bus_width, ext_csd_bits; @@ -1148,8 +1150,9 @@ static int mmc_select_hs_ddr(struct mmc_card *card) return err; } +EXPORT_SYMBOL_GPL(mmc_select_hs_ddr); -static int mmc_select_hs400(struct mmc_card *card) +int mmc_select_hs400(struct mmc_card *card) { struct mmc_host *host = card->host; unsigned int max_dtr; @@ -1235,6 +1238,7 @@ static int mmc_select_hs400(struct mmc_card *card) __func__, err); return err; } +EXPORT_SYMBOL_GPL(mmc_select_hs400); int mmc_hs200_to_hs400(struct mmc_card *card) { @@ -1505,7 +1509,7 @@ static int mmc_select_hs200(struct mmc_card *card) /* * Activate High Speed, HS200 or HS400ES mode if supported. */ -static int mmc_select_timing(struct mmc_card *card) +int mmc_select_timing(struct mmc_card *card) { int err = 0; @@ -1530,12 +1534,13 @@ static int mmc_select_timing(struct mmc_card *card) mmc_set_bus_speed(card); return 0; } +EXPORT_SYMBOL_GPL(mmc_select_timing); /* * Execute tuning sequence to seek the proper bus operating * conditions for HS200 and HS400, which sends CMD21 to the device. */ -static int mmc_hs200_tuning(struct mmc_card *card) +int mmc_hs200_tuning(struct mmc_card *card) { struct mmc_host *host = card->host; @@ -1550,6 +1555,7 @@ static int mmc_hs200_tuning(struct mmc_card *card) return mmc_execute_tuning(card); } +EXPORT_SYMBOL_GPL(mmc_hs200_tuning); /* * Handle the detection and initialisation of a card. diff --git a/drivers/mmc/core/queue.c b/drivers/mmc/core/queue.c index 33e7e65b6dde..c817f6decd6a 100644 --- a/drivers/mmc/core/queue.c +++ b/drivers/mmc/core/queue.c @@ -71,6 +71,7 @@ enum mmc_issue_type mmc_issue_type(struct mmc_queue *mq, struct request *req) return MMC_ISSUE_SYNC; } +EXPORT_SYMBOL_GPL(mmc_issue_type); static void __mmc_cqe_recovery_notifier(struct mmc_queue *mq) { diff --git a/drivers/pci/controller/dwc/pcie-exynos-gs101-rc-cal.c b/drivers/pci/controller/dwc/pcie-exynos-gs101-rc-cal.c index 9cb2812c71b6..b90b0eba87af 100644 --- a/drivers/pci/controller/dwc/pcie-exynos-gs101-rc-cal.c +++ b/drivers/pci/controller/dwc/pcie-exynos-gs101-rc-cal.c @@ -103,6 +103,7 @@ void exynos_pcie_rc_pcie_phy_config(struct exynos_pcie *exynos_pcie, int ch_num) int num_lanes = exynos_pcie->num_lanes; u32 val; u32 i; + u32 pll_lock = 0, cdr_lock = 0, oc_done = 0; /* init. input clk path */ writel(0x28, phy_base_regs + 0xD8); @@ -301,7 +302,34 @@ void exynos_pcie_rc_pcie_phy_config(struct exynos_pcie *exynos_pcie, int ch_num) val |= (0x1 << 4); val &= ~(0x1 << 3); writel(val, phy_base_regs + 0x5D0); - pr_info("XO clock configuration : 0x%x\n", readl(phy_base_regs + 0x5D0)); + pr_debug("XO clock configuration : 0x%x\n", readl(phy_base_regs + 0x5D0)); + + /* check pll & cdr lock */ + phy_base_regs = exynos_pcie->phy_base; + for (i = 0; i < 1000; i++) { + udelay(1); + pll_lock = readl(phy_base_regs + 0x3F0) & (1 << 3); + cdr_lock = readl(phy_base_regs + 0xFC0) & (1 << 4); + + if (pll_lock != 0 && cdr_lock != 0) + break; + } + + /* check offset calibration */ + for (i = 0; i < 2000; i++) { + usleep_range(10, 12); + oc_done = readl(phy_base_regs + 0xE18) & (1 << 7); + + if (oc_done != 0) + break; + } + if (oc_done == 0) { + pll_lock = readl(phy_base_regs + 0x3F0) & (1 << 3); + cdr_lock = readl(phy_base_regs + 0xFC0) & (1 << 4); + oc_done = readl(phy_base_regs + 0xE18) & (1 << 7); + pr_err("OC Fail : PLL_LOCK : 0x%x, CDR_LOCK : 0x%x, OC : 0x%x\n", + pll_lock, cdr_lock, oc_done); + } } EXPORT_SYMBOL_GPL(exynos_pcie_rc_pcie_phy_config); diff --git a/drivers/pci/controller/dwc/pcie-exynos-rc.c b/drivers/pci/controller/dwc/pcie-exynos-rc.c index 685b39d78110..0b1416c6b252 100644 --- a/drivers/pci/controller/dwc/pcie-exynos-rc.c +++ b/drivers/pci/controller/dwc/pcie-exynos-rc.c @@ -661,6 +661,11 @@ static ssize_t link_state_show(struct device *dev, struct device_attribute *attr u32 val; struct exynos_pcie *exynos_pcie = dev_get_drvdata(dev); + if (exynos_pcie->phy_control == PCIE_PHY_ISOLATION) { + val = L2; /* Not linked is equivalent to L2 */ + goto exit; + } + val = exynos_phy_pcs_read(exynos_pcie, PM_POWER_STATE); val &= PM_STATE_MASK; @@ -690,6 +695,7 @@ static ssize_t link_state_show(struct device *dev, struct device_attribute *attr val = UNKNOWN; } +exit: ret += scnprintf(buf + ret, PAGE_SIZE - ret, "%d\n", val); return ret; @@ -2344,7 +2350,6 @@ static irqreturn_t exynos_pcie_rc_irq_handler(int irq, void *arg) dev_info(dev, "check irq22 pending clear: irq2_state = 0x%x\n", val_irq2); exynos_pcie->state = STATE_LINK_DOWN_TRY; - queue_work(exynos_pcie->pcie_wq, &exynos_pcie->cpl_timeout_work.work); } #if IS_ENABLED(CONFIG_PCI_MSI) @@ -2531,6 +2536,15 @@ static int exynos_pcie_rc_establish_link(struct pcie_port *pp) val |= SOFT_PWR_RESET; exynos_elbi_write(exynos_pcie, val, PCIE_SOFT_RESET); + val = exynos_phy_read(exynos_pcie, 0x0E18) & (1 << 7); + if (!val) { + dev_err(dev, "OC Fail after soft power reset!\n"); + dev_err(dev, "PMA Info : 0x760(0x%x), 0xE0C(0x%x), 0x3F0(0x%x), 0xFC0(0x%x)\n", + exynos_phy_read(exynos_pcie, 0x760), + exynos_phy_read(exynos_pcie, 0xE0C), + exynos_phy_read(exynos_pcie, 0x3F0), + exynos_phy_read(exynos_pcie, 0xFC0)); + } /* Device Type (Sub Controller: DEVICE_TYPE offset: 0x80 */ exynos_elbi_write(exynos_pcie, 0x04, 0x80); diff --git a/drivers/scsi/ufs/ufs-pixel.c b/drivers/scsi/ufs/ufs-pixel.c index 8b393d7e5cbb..24fa51beb3f2 100644 --- a/drivers/scsi/ufs/ufs-pixel.c +++ b/drivers/scsi/ufs/ufs-pixel.c @@ -686,7 +686,8 @@ static void pixel_ufs_prepare_command(void *data, struct ufs_hba *hba, copy_from_iter(&cur_wc, 4, &iter); cur_wc = cpu_to_be32(cur_wc); if (cur_wc) - pr_info("%s RPMB write counter = %8x\n", __func__, cur_wc); + pr_info("%s RPMB write counter = %8x; start time %lu\n", + __func__, cur_wc, lrbp->cmd->jiffies_at_alloc); if (cur_wc != ufs->security_out_wc) ufs->security_out_wc = cur_wc; else if (cur_wc) { diff --git a/drivers/scsi/ufs/ufshcd.c b/drivers/scsi/ufs/ufshcd.c index 01ae180ed1fd..9f848fa73eb3 100644 --- a/drivers/scsi/ufs/ufshcd.c +++ b/drivers/scsi/ufs/ufshcd.c @@ -9323,7 +9323,7 @@ int ufshcd_alloc_host(struct device *dev, struct ufs_hba **hba_handle) } host = scsi_host_alloc(&ufshcd_driver_template, - sizeof(struct ufs_hba)); + sizeof(struct ufs_hba_with_hpb)); if (!host) { dev_err(dev, "scsi_host_alloc failed\n"); err = -ENOMEM; diff --git a/drivers/scsi/ufs/ufshcd.h b/drivers/scsi/ufs/ufshcd.h index f4d0fb6fdd97..c75c5cd7b973 100644 --- a/drivers/scsi/ufs/ufshcd.h +++ b/drivers/scsi/ufs/ufshcd.h @@ -912,7 +912,8 @@ struct ufs_hba { bool wb_enabled; struct delayed_work rpm_dev_flush_recheck_work; -#ifdef CONFIG_SCSI_UFS_HPB +#if 0 + /* This has been moved into struct ufs_hba_with_hpb. */ struct ufshpb_dev_info ufshpb_dev; #endif @@ -934,6 +935,17 @@ struct ufs_hba { ANDROID_KABI_RESERVE(4); }; +/* + * Compared to the upstream equivalent, @hpb_dev has been moved from struct + * ufs_hba into struct ufs_hba_with_hpb to satisfy the Android ABI checks. + */ +struct ufs_hba_with_hpb { + struct ufs_hba hba; +#ifdef CONFIG_SCSI_UFS_HPB + struct ufshpb_dev_info hpb_dev; +#endif +}; + /* Returns true if clocks can be gated. Otherwise false */ static inline bool ufshcd_is_clkgating_allowed(struct ufs_hba *hba) { diff --git a/drivers/scsi/ufs/ufshpb.c b/drivers/scsi/ufs/ufshpb.c index cb4a34ae5be1..9755317c3301 100644 --- a/drivers/scsi/ufs/ufshpb.c +++ b/drivers/scsi/ufs/ufshpb.c @@ -35,15 +35,20 @@ static struct workqueue_struct *ufshpb_wq; static void ufshpb_update_active_info(struct ufshpb_lu *hpb, int rgn_idx, int srgn_idx); +static inline struct ufshpb_dev_info *ufs_hba_to_hpb(struct ufs_hba *hba) +{ + return &container_of(hba, struct ufs_hba_with_hpb, hba)->hpb_dev; +} + bool ufshpb_is_allowed(struct ufs_hba *hba) { - return !(hba->ufshpb_dev.hpb_disabled); + return !(ufs_hba_to_hpb(hba)->hpb_disabled); } /* HPB version 1.0 is called as legacy version. */ bool ufshpb_is_legacy(struct ufs_hba *hba) { - return hba->ufshpb_dev.is_legacy; + return ufs_hba_to_hpb(hba)->is_legacy; } static struct ufshpb_lu *ufshpb_get_hpb_data(struct scsi_device *sdev) @@ -2743,8 +2748,7 @@ void ufshpb_init_hpb_lu(struct ufs_hba *hba, struct scsi_device *sdev) if (ret) goto out; - hpb = ufshpb_alloc_hpb_lu(hba, sdev, &hba->ufshpb_dev, - &hpb_lu_info); + hpb = ufshpb_alloc_hpb_lu(hba, sdev, ufs_hba_to_hpb(hba), &hpb_lu_info); if (!hpb) goto out; @@ -2753,7 +2757,7 @@ void ufshpb_init_hpb_lu(struct ufs_hba *hba, struct scsi_device *sdev) out: /* All LUs are initialized */ - if (atomic_dec_and_test(&hba->ufshpb_dev.slave_conf_cnt)) + if (atomic_dec_and_test(&ufs_hba_to_hpb(hba)->slave_conf_cnt)) ufshpb_hpb_lu_prepared(hba); } @@ -2810,7 +2814,7 @@ static int ufshpb_init_mem_wq(struct ufs_hba *hba) void ufshpb_get_geo_info(struct ufs_hba *hba, u8 *geo_buf) { - struct ufshpb_dev_info *hpb_info = &hba->ufshpb_dev; + struct ufshpb_dev_info *hpb_info = ufs_hba_to_hpb(hba); int max_active_rgns = 0; int hpb_num_lu; @@ -2836,7 +2840,7 @@ void ufshpb_get_geo_info(struct ufs_hba *hba, u8 *geo_buf) void ufshpb_get_dev_info(struct ufs_hba *hba, u8 *desc_buf) { - struct ufshpb_dev_info *hpb_dev_info = &hba->ufshpb_dev; + struct ufshpb_dev_info *hpb_dev_info = ufs_hba_to_hpb(hba); int version, ret; u32 max_hpb_single_cmd = HPB_MULTI_CHUNK_LOW; @@ -2873,7 +2877,7 @@ void ufshpb_get_dev_info(struct ufs_hba *hba, u8 *desc_buf) void ufshpb_init(struct ufs_hba *hba) { - struct ufshpb_dev_info *hpb_dev_info = &hba->ufshpb_dev; + struct ufshpb_dev_info *hpb_dev_info = ufs_hba_to_hpb(hba); int try; int ret; diff --git a/drivers/soc/google/cal-if/gs101/flexpmu_cal_system_gs101.h b/drivers/soc/google/cal-if/gs101/flexpmu_cal_system_gs101.h index fa2e83843656..60f7ea94b88e 100644 --- a/drivers/soc/google/cal-if/gs101/flexpmu_cal_system_gs101.h +++ b/drivers/soc/google/cal-if/gs101/flexpmu_cal_system_gs101.h @@ -22,7 +22,7 @@ struct pmucal_seq pmucal_lpm_init[] = { (0x3FC00000 << 0), 0, 0, 0xffffffff, 0), PMUCAL_SEQ_DESC(PMUCAL_WRITE, "CPUCL2_CLKDIVSTEP_SMPL_FLT", 0x20C20000, 0x083C, (0xffffffff << 0), (0x8000FFFF << 0), 0, 0, 0xffffffff, 0), PMUCAL_SEQ_DESC(PMUCAL_WRITE, "CPUCL2_CLKDIVSTEP", 0x20C20000, 0x0830, (0xffffffff << 0), - (0x3FC00001 << 0), 0, 0, 0xffffffff, 0), + (0x3FC00801 << 0), 0, 0, 0xffffffff, 0), PMUCAL_SEQ_DESC(PMUCAL_WRITE, "CMU_HCHGEN_CLKMUX", 0x1E080000, 0x0850, (0x1 << 0), (0x1 << 0), 0, 0, 0xffffffff, 0), PMUCAL_SEQ_DESC(PMUCAL_WRITE, "MIF0_HCHGEN_CLKMUX_CMUREF", 0x20800000, 0x0850, (0x1 << 0), (0x1 << 0), 0, 0, 0xffffffff, 0), PMUCAL_SEQ_DESC(PMUCAL_WRITE, "MIF1_HCHGEN_CLKMUX_CMUREF", 0x20900000, 0x0850, (0x1 << 0), (0x1 << 0), 0, 0, 0xffffffff, 0), diff --git a/drivers/soc/google/cpif/cpif_tp_monitor.c b/drivers/soc/google/cpif/cpif_tp_monitor.c index b52ee8e8fe3d..23895a788b77 100644 --- a/drivers/soc/google/cpif/cpif_tp_monitor.c +++ b/drivers/soc/google/cpif/cpif_tp_monitor.c @@ -531,6 +531,7 @@ static void tpmon_set_gro(struct tpmon_data *data) { struct mem_link_device *mld = container_of(data->tpmon->ld, struct mem_link_device, link_dev); + long timeout; #if IS_ENABLED(CONFIG_CP_PKTPROC) struct pktproc_adaptor *ppa = &mld->pktproc; int i; @@ -542,11 +543,11 @@ static void tpmon_set_gro(struct tpmon_data *data) if (!data->enable) return; - gro_flush_time = data->tpmon->use_user_value ? - data->user_value : data->values[data->curr_value_pos]; + timeout = data->tpmon->use_user_value ? + data->user_value : data->values[data->curr_value_pos]; #if !IS_ENABLED(CONFIG_CP_PKTPROC) && !IS_ENABLED(CONFIG_EXYNOS_DIT) - mld->dummy_net.gro_flush_timeout = gro_flush_time; + mld->dummy_net.gro_flush_timeout = timeout; #endif #if IS_ENABLED(CONFIG_CP_PKTPROC) @@ -554,22 +555,22 @@ static void tpmon_set_gro(struct tpmon_data *data) for (i = 0; i > ppa->num_queue; i++) { struct pktproc_queue *q = ppa->q[i]; - q->netdev.gro_flush_timeout = gro_flush_time; + q->netdev.gro_flush_timeout = timeout; } } else { - mld->dummy_net.gro_flush_timeout = gro_flush_time; + mld->dummy_net.gro_flush_timeout = timeout; } #endif #if IS_ENABLED(CONFIG_EXYNOS_DIT) netdev = dit_get_netdev(); if (netdev) { - netdev->gro_flush_timeout = gro_flush_time; + netdev->gro_flush_timeout = timeout; mld->dummy_net.gro_flush_timeout = 0; } #endif - mif_info("%s (flush time:%ld)\n", data->name, gro_flush_time); + mif_info("%s (flush timeout:%ld)\n", data->name, timeout); } /* IRQ affinity */ diff --git a/drivers/soc/google/cpif/cpif_version.h b/drivers/soc/google/cpif/cpif_version.h index 1271a8411b0a..666c55dd9c46 100644 --- a/drivers/soc/google/cpif/cpif_version.h +++ b/drivers/soc/google/cpif/cpif_version.h @@ -7,5 +7,5 @@ #ifndef __CPIF_VERSION_H__ #define __CPIF_VERSION_H__ -static const char cpif_driver_version[] = "CPIF-20210120R5"; +static const char cpif_driver_version[] = "CPIF-20210812R1"; #endif /* __CPIF_VERSION_H__ */ diff --git a/drivers/soc/google/cpif/link_device.c b/drivers/soc/google/cpif/link_device.c index 64dbeaecccb8..bb3492e89836 100644 --- a/drivers/soc/google/cpif/link_device.c +++ b/drivers/soc/google/cpif/link_device.c @@ -2556,90 +2556,6 @@ static int shmem_security_request(struct link_device *ld, struct io_device *iod, return err; } -long gro_flush_time = 10000; -module_param(gro_flush_time, long, 0644); - -#if (LINUX_VERSION_CODE >= KERNEL_VERSION(5, 4, 0)) -static void gro_flush_timer(struct link_device *ld, struct napi_struct *napi) -{ - struct mem_link_device *mld = to_mem_link_device(ld); - struct timespec64 curr, diff; - - if (!gro_flush_time) { - napi_gro_flush(napi, false); - return; - } - - if (unlikely(mld->flush_time.tv_sec == 0)) { - ktime_get_real_ts64(&mld->flush_time); - } else { - ktime_get_real_ts64(&(curr)); - diff = timespec64_sub(curr, mld->flush_time); - if ((diff.tv_sec > 0) || (diff.tv_nsec > gro_flush_time)) { - napi_gro_flush(napi, false); - ktime_get_real_ts64(&mld->flush_time); - } - } -} - -static struct timespec64 update_flush_time(struct timespec64 org_flush_time) -{ - struct timespec64 curr, diff, ret; - - ktime_get_real_ts64(&curr); - if (unlikely(org_flush_time.tv_sec == 0)) { - ktime_get_real_ts64(&ret); - return ret; - } - diff = timespec64_sub(curr, org_flush_time); - if (diff.tv_nsec > gro_flush_time) - ktime_get_real_ts64(&ret); - else - ret = org_flush_time; - - return ret; -} -#else -static void gro_flush_timer(struct link_device *ld, struct napi_struct *napi) -{ - struct mem_link_device *mld = to_mem_link_device(ld); - struct timespec curr, diff; - - if (!gro_flush_time) { - napi_gro_flush(napi, false); - return; - } - - if (unlikely(mld->flush_time.tv_sec == 0)) { - getnstimeofday(&mld->flush_time); - } else { - getnstimeofday(&(curr)); - diff = timespec_sub(curr, mld->flush_time); - if ((diff.tv_sec > 0) || (diff.tv_nsec > gro_flush_time)) { - napi_gro_flush(napi, false); - getnstimeofday(&mld->flush_time); - } - } -} -static struct timespec update_flush_time(struct timespec org_flush_time) -{ - struct timespec curr, diff, ret; - - getnstimeofday(&curr); - if (unlikely(org_flush_time.tv_sec == 0)) { - getnstimeofday(&ret); - return ret; - } - diff = timespec_sub(curr, org_flush_time); - if (diff.tv_nsec > gro_flush_time) - getnstimeofday(&ret); - else - ret = org_flush_time; - - return ret; -} -#endif - static int sbd_link_rx_func_napi(struct sbd_link_device *sl, struct link_device *ld, int budget, int *work_done) { @@ -3203,7 +3119,6 @@ static irqreturn_t shmem_irq_handler(int irq, void *data) struct link_device *ld = &mld->link_dev; ld->disable_rx_int(ld); - mld->flush_time = ld->update_flush_time(mld->flush_time); __napi_schedule(&mld->mld_napi); } @@ -3997,9 +3912,6 @@ struct link_device *create_link_device(struct platform_device *pdev, u32 link_ty ld->close_tx = shmem_close_tx; ld->get_cp_crash_reason = get_cp_crash_reason; - ld->gro_flush = gro_flush_timer; - ld->update_flush_time = update_flush_time; - ld->protocol = modem->protocol; ld->capability_check = modem->capability_check; diff --git a/drivers/soc/google/cpif/link_device_memory.h b/drivers/soc/google/cpif/link_device_memory.h index b1ab3669d6d2..7b837a25cf68 100644 --- a/drivers/soc/google/cpif/link_device_memory.h +++ b/drivers/soc/google/cpif/link_device_memory.h @@ -339,11 +339,6 @@ struct mem_link_device { unsigned int rx_int_count; unsigned int rx_poll_count; unsigned long long rx_int_disabled_time; -#if (LINUX_VERSION_CODE >= KERNEL_VERSION(5, 4, 0)) - struct timespec64 flush_time; -#else - struct timespec flush_time; -#endif /* Doorbell interrupt value to separate interrupt */ unsigned int intval_ap2cp_msg; diff --git a/drivers/soc/google/cpif/link_rx_pktproc.c b/drivers/soc/google/cpif/link_rx_pktproc.c index 708d988a3cd8..bbada938a87d 100644 --- a/drivers/soc/google/cpif/link_rx_pktproc.c +++ b/drivers/soc/google/cpif/link_rx_pktproc.c @@ -1070,7 +1070,6 @@ static irqreturn_t pktproc_irq_handler(int irq, void *arg) if (q->ppa->use_napi) { if (napi_schedule_prep(q->napi_ptr)) { q->disable_irq(q); - q->flush_time = q->mld->link_dev.update_flush_time(q->flush_time); __napi_schedule(q->napi_ptr); } } else { diff --git a/drivers/soc/google/cpif/link_rx_pktproc.h b/drivers/soc/google/cpif/link_rx_pktproc.h index 2fc2c08f4fe2..bc9cfba79813 100644 --- a/drivers/soc/google/cpif/link_rx_pktproc.h +++ b/drivers/soc/google/cpif/link_rx_pktproc.h @@ -165,11 +165,6 @@ struct pktproc_queue { struct napi_struct napi; struct napi_struct *napi_ptr; atomic_t stop_napi_poll; -#if (LINUX_VERSION_CODE >= KERNEL_VERSION(5, 4, 0)) - struct timespec64 flush_time; -#else - struct timespec flush_time; -#endif /* Statistics */ struct pktproc_statistics stat; diff --git a/drivers/soc/google/cpif/modem_io_device.c b/drivers/soc/google/cpif/modem_io_device.c index d9478b7ab3eb..d161e6cce4f4 100644 --- a/drivers/soc/google/cpif/modem_io_device.c +++ b/drivers/soc/google/cpif/modem_io_device.c @@ -447,8 +447,6 @@ static int rx_multi_pdp(struct sk_buff *skb) if (ret == GRO_DROP) mif_err_limited("%s: %s<-%s: ERR! napi_gro_receive\n", ld->name, iod->name, iod->mc->name); - - ld->gro_flush(ld, napi); } return len; } diff --git a/drivers/soc/google/cpif/modem_prj.h b/drivers/soc/google/cpif/modem_prj.h index b905c4903cdc..6629b283bb5f 100644 --- a/drivers/soc/google/cpif/modem_prj.h +++ b/drivers/soc/google/cpif/modem_prj.h @@ -556,13 +556,6 @@ struct link_device { void (*start_timers)(struct mem_link_device *mld); void (*stop_timers)(struct mem_link_device *mld); - void (*gro_flush)(struct link_device *ld, struct napi_struct *napi); -#if (LINUX_VERSION_CODE >= KERNEL_VERSION(5, 4, 0)) - struct timespec64 (*update_flush_time)(struct timespec64 org_flush_time); -#else - struct timespec (*update_flush_time)(struct timespec org_flush_time); -#endif - int (*handover_block_info)(struct link_device *ld, unsigned long arg); #if IS_ENABLED(CONFIG_LINK_DEVICE_PCIE) @@ -575,8 +568,6 @@ struct link_device { #endif }; -extern long gro_flush_time; - #define pm_to_link_device(pm) container_of(pm, struct link_device, pm) static inline struct sk_buff *rx_alloc_skb(unsigned int length, diff --git a/drivers/thermal/google/google_bcl.c b/drivers/thermal/google/google_bcl.c index 7ead11af139e..923949da5d11 100644 --- a/drivers/thermal/google/google_bcl.c +++ b/drivers/thermal/google/google_bcl.c @@ -46,6 +46,7 @@ #define SYSREG_CPUCL0_BASE (0x20c40000) #define CLUSTER0_GENERAL_CTRL_64 (0x1404) #define CLKDIVSTEP (0x830) +#define VDROOP_FLT (0x838) #define CPUCL0_CLKDIVSTEP_STAT (0x83c) #define CPUCL0_CLKDIVSTEP_CON (0x838) #define CPUCL12_CLKDIVSTEP_STAT (0x848) @@ -1314,6 +1315,21 @@ static ssize_t clk_stats_show(struct bcl_device *bcl_dev, int idx, char *buf) return sysfs_emit(buf, "0x%x\n", reg); } +static int google_bcl_init_clk_div(struct bcl_device *bcl_dev, int idx, unsigned int value) +{ + void __iomem *addr; + + addr = get_addr_by_subsystem(bcl_dev, clk_stats_source[idx]); + if (addr == NULL) + return -EINVAL; + + mutex_lock(&bcl_dev->ratio_lock); + __raw_writel(value, addr); + mutex_unlock(&bcl_dev->ratio_lock); + + return 0; +} + static ssize_t clk_div_store(struct bcl_device *bcl_dev, int idx, const char *buf, size_t size) { @@ -1325,18 +1341,23 @@ static ssize_t clk_div_store(struct bcl_device *bcl_dev, int idx, if (ret != 1) return -EINVAL; - addr = get_addr_by_subsystem(bcl_dev, clk_stats_source[idx]); - - if (addr == NULL) { - dev_err(bcl_dev->device, "Address is NULL\n"); - return -EIO; - } - if (idx == TPU) bcl_dev->tpu_clkdivstep = value; else if (idx == GPU) bcl_dev->gpu_clkdivstep = value; else { + if (idx == CPU2) + bcl_dev->cpu2_clkdivstep = value; + else if (idx == CPU1) + bcl_dev->cpu1_clkdivstep = value; + else + bcl_dev->cpu0_clkdivstep = value; + + addr = get_addr_by_subsystem(bcl_dev, clk_stats_source[idx]); + if (addr == NULL) { + dev_err(bcl_dev->device, "IDX %d: Address is NULL\n", idx); + return -EIO; + } mutex_lock(&bcl_dev->ratio_lock); __raw_writel(value, addr); mutex_unlock(&bcl_dev->ratio_lock); @@ -1454,6 +1475,137 @@ static const struct attribute_group clock_div_group = { .name = "clock_div", }; +static ssize_t vdroop_flt_show(struct bcl_device *bcl_dev, int idx, char *buf) +{ + unsigned int reg; + void __iomem *addr; + + if (idx == TPU) + return sysfs_emit(buf, "0x%x\n", bcl_dev->tpu_vdroop_flt); + else if (idx == GPU) + return sysfs_emit(buf, "0x%x\n", bcl_dev->gpu_vdroop_flt); + else if (idx >= CPU1 && idx <= CPU2) + addr = bcl_dev->base_mem[idx] + VDROOP_FLT; + else + return sysfs_emit(buf, "off\n"); + reg = __raw_readl(addr); + + return sysfs_emit(buf, "0x%x\n", reg); +} + +static ssize_t vdroop_flt_store(struct bcl_device *bcl_dev, int idx, + const char *buf, size_t size) +{ + void __iomem *addr; + unsigned int value; + + if (sscanf(buf, "0x%x", &value) != 1) + return -EINVAL; + + if (idx == TPU) + bcl_dev->tpu_vdroop_flt = value; + else if (idx == GPU) + bcl_dev->gpu_vdroop_flt = value; + else if (idx >= CPU1 && idx <= CPU2) { + addr = bcl_dev->base_mem[idx] + VDROOP_FLT; + mutex_lock(&bcl_dev->ratio_lock); + __raw_writel(value, addr); + mutex_unlock(&bcl_dev->ratio_lock); + } else + return -EINVAL; + + return size; +} + +static ssize_t cpu1_vdroop_flt_show(struct device *dev, struct device_attribute *attr, char *buf) +{ + struct platform_device *pdev = container_of(dev, struct platform_device, dev); + struct bcl_device *bcl_dev = platform_get_drvdata(pdev); + + return vdroop_flt_show(bcl_dev, CPU1, buf); +} + +static ssize_t cpu1_vdroop_flt_store(struct device *dev, struct device_attribute *attr, + const char *buf, size_t size) +{ + struct platform_device *pdev = container_of(dev, struct platform_device, dev); + struct bcl_device *bcl_dev = platform_get_drvdata(pdev); + + return vdroop_flt_store(bcl_dev, CPU1, buf, size); +} + +static DEVICE_ATTR_RW(cpu1_vdroop_flt); + +static ssize_t cpu2_vdroop_flt_show(struct device *dev, struct device_attribute *attr, char *buf) +{ + struct platform_device *pdev = container_of(dev, struct platform_device, dev); + struct bcl_device *bcl_dev = platform_get_drvdata(pdev); + + return vdroop_flt_show(bcl_dev, CPU2, buf); +} + +static ssize_t cpu2_vdroop_flt_store(struct device *dev, struct device_attribute *attr, + const char *buf, size_t size) +{ + struct platform_device *pdev = container_of(dev, struct platform_device, dev); + struct bcl_device *bcl_dev = platform_get_drvdata(pdev); + + return vdroop_flt_store(bcl_dev, CPU2, buf, size); +} + +static DEVICE_ATTR_RW(cpu2_vdroop_flt); + +static ssize_t tpu_vdroop_flt_show(struct device *dev, struct device_attribute *attr, char *buf) +{ + struct platform_device *pdev = container_of(dev, struct platform_device, dev); + struct bcl_device *bcl_dev = platform_get_drvdata(pdev); + + return vdroop_flt_show(bcl_dev, TPU, buf); +} + +static ssize_t tpu_vdroop_flt_store(struct device *dev, struct device_attribute *attr, + const char *buf, size_t size) +{ + struct platform_device *pdev = container_of(dev, struct platform_device, dev); + struct bcl_device *bcl_dev = platform_get_drvdata(pdev); + + return vdroop_flt_store(bcl_dev, TPU, buf, size); +} + +static DEVICE_ATTR_RW(tpu_vdroop_flt); + +static ssize_t gpu_vdroop_flt_show(struct device *dev, struct device_attribute *attr, char *buf) +{ + struct platform_device *pdev = container_of(dev, struct platform_device, dev); + struct bcl_device *bcl_dev = platform_get_drvdata(pdev); + + return vdroop_flt_show(bcl_dev, GPU, buf); +} + +static ssize_t gpu_vdroop_flt_store(struct device *dev, struct device_attribute *attr, + const char *buf, size_t size) +{ + struct platform_device *pdev = container_of(dev, struct platform_device, dev); + struct bcl_device *bcl_dev = platform_get_drvdata(pdev); + + return vdroop_flt_store(bcl_dev, GPU, buf, size); +} + +static DEVICE_ATTR_RW(gpu_vdroop_flt); + +static struct attribute *vdroop_flt_attrs[] = { + &dev_attr_cpu1_vdroop_flt.attr, + &dev_attr_cpu2_vdroop_flt.attr, + &dev_attr_tpu_vdroop_flt.attr, + &dev_attr_gpu_vdroop_flt.attr, + NULL, +}; + +static const struct attribute_group vdroop_flt_group = { + .attrs = vdroop_flt_attrs, + .name = "vdroop_flt", +}; + static ssize_t cpu0_clk_stats_show(struct device *dev, struct device_attribute *attr, char *buf) { struct platform_device *pdev = container_of(dev, struct platform_device, dev); @@ -1575,11 +1727,6 @@ static ssize_t clk_ratio_store(struct bcl_device *bcl_dev, int idx, if (ret != 1) return -EINVAL; - addr = get_addr_by_rail(bcl_dev, clk_ratio_source[idx]); - if (addr == NULL) { - dev_err(bcl_dev->device, "Address is NULL\n"); - return -EIO; - } if (idx == TPU_HEAVY) bcl_dev->tpu_con_heavy = value; else if (idx == GPU_HEAVY) @@ -1589,6 +1736,11 @@ static ssize_t clk_ratio_store(struct bcl_device *bcl_dev, int idx, else if (idx == GPU_LIGHT) bcl_dev->gpu_con_light = value; else { + addr = get_addr_by_rail(bcl_dev, clk_ratio_source[idx]); + if (addr == NULL) { + dev_err(bcl_dev->device, "IDX %d: Address is NULL\n", idx); + return -EIO; + } mutex_lock(&bcl_dev->ratio_lock); __raw_writel(value, addr); mutex_unlock(&bcl_dev->ratio_lock); @@ -2336,6 +2488,8 @@ int google_init_tpu_ratio(struct bcl_device *data) __raw_writel(data->tpu_con_light, addr); addr = data->base_mem[TPU] + CLKDIVSTEP; __raw_writel(data->tpu_clkdivstep, addr); + addr = data->base_mem[TPU] + VDROOP_FLT; + __raw_writel(data->tpu_vdroop_flt, addr); data->tpu_clk_stats = __raw_readl(data->base_mem[TPU] + clk_stats_offset[TPU]); mutex_unlock(&data->ratio_lock); @@ -2363,6 +2517,8 @@ int google_init_gpu_ratio(struct bcl_device *data) __raw_writel(data->gpu_con_light, addr); addr = data->base_mem[GPU] + CLKDIVSTEP; __raw_writel(data->gpu_clkdivstep, addr); + addr = data->base_mem[GPU] + VDROOP_FLT; + __raw_writel(data->gpu_vdroop_flt, addr); data->gpu_clk_stats = __raw_readl(data->base_mem[GPU] + clk_stats_offset[GPU]); mutex_unlock(&data->ratio_lock); @@ -2874,6 +3030,7 @@ const struct attribute_group *mitigation_groups[] = { &triggered_timestamp_group, &triggered_capacity_group, &triggered_voltage_group, + &vdroop_flt_group, NULL, }; @@ -3010,7 +3167,19 @@ static int google_bcl_probe(struct platform_device *pdev) bcl_dev->gpu_clkdivstep = ret ? 0 : val; ret = of_property_read_u32(np, "tpu_clkdivstep", &val); bcl_dev->tpu_clkdivstep = ret ? 0 : val; + ret = of_property_read_u32(np, "cpu2_clkdivstep", &val); + bcl_dev->cpu2_clkdivstep = ret ? 0 : val; + ret = of_property_read_u32(np, "cpu1_clkdivstep", &val); + bcl_dev->cpu1_clkdivstep = ret ? 0 : val; + ret = of_property_read_u32(np, "cpu0_clkdivstep", &val); + bcl_dev->cpu0_clkdivstep = ret ? 0 : val; bcl_dev->batt_psy_initialized = false; + if (google_bcl_init_clk_div(bcl_dev, CPU2, bcl_dev->cpu2_clkdivstep) != 0) + dev_err(bcl_dev->device, "CPU2 Address is NULL\n"); + if (google_bcl_init_clk_div(bcl_dev, CPU1, bcl_dev->cpu1_clkdivstep) != 0) + dev_err(bcl_dev->device, "CPU1 Address is NULL\n"); + if (google_bcl_init_clk_div(bcl_dev, CPU0, bcl_dev->cpu0_clkdivstep) != 0) + dev_err(bcl_dev->device, "CPU0 Address is NULL\n"); ret = google_init_fs(bcl_dev); if (ret < 0) diff --git a/drivers/thermal/google/gs101_spmic_thermal.c b/drivers/thermal/google/gs101_spmic_thermal.c index 75daafe80ec7..218c2c41be65 100644 --- a/drivers/thermal/google/gs101_spmic_thermal.c +++ b/drivers/thermal/google/gs101_spmic_thermal.c @@ -15,18 +15,19 @@ #include #include #include +#include #include #include #include "../thermal_core.h" #define GTHERM_CHAN_NUM 8 +#define SENSOR_WAIT_SLEEP_MS 50 struct gs101_spmic_thermal_sensor { struct gs101_spmic_thermal_chip *chip; struct thermal_zone_device *tzd; unsigned int adc_chan; - bool thr_triggered; int emul_temperature; int irq; }; @@ -37,6 +38,9 @@ struct gs101_spmic_thermal_chip { struct s2mpg11_dev *iodev; struct gs101_spmic_thermal_sensor sensor[GTHERM_CHAN_NUM]; u8 adc_chan_en; + struct kobject *kobjs[GTHERM_CHAN_NUM]; + struct kthread_worker *wq; + struct kthread_delayed_work wait_sensor_work; }; /** @@ -130,6 +134,25 @@ static int gs101_map_temp_volt(int input) gs101_adc_map[low - 1].temp - gs101_adc_map[low].temp); } +static int gs101_spmic_thermal_read_raw(struct gs101_spmic_thermal_sensor *s, int *raw) +{ + struct gs101_spmic_thermal_chip *gs101_spmic_thermal = s->chip; + u8 data_buf[S2MPG11_METER_NTC_BUF]; + u8 reg = S2MPG11_METER_LPF_DATA_NTC0_1 + S2MPG11_METER_NTC_BUF * s->adc_chan; + + int ret = s2mpg11_bulk_read(gs101_spmic_thermal->i2c, reg, S2MPG11_METER_NTC_BUF, data_buf); + if (ret) + return ret; + + *raw = data_buf[0] + ((data_buf[1] & 0xf) << 8); + + // All 0 usually means not ready + if (*raw == 0) + return -EBUSY; + + return ret; +} + /* * Get temperature for given tz. */ @@ -139,9 +162,6 @@ static int gs101_spmic_thermal_get_temp(void *data, int *temp) struct gs101_spmic_thermal_chip *gs101_spmic_thermal = s->chip; int emul_temp; int raw, ret = 0; - u8 data_buf[S2MPG11_METER_NTC_BUF]; - u8 reg = S2MPG11_METER_LPF_DATA_NTC0_1 + - S2MPG11_METER_NTC_BUF * s->adc_chan; u8 mask = 0x1; emul_temp = s->emul_temperature; @@ -153,13 +173,9 @@ static int gs101_spmic_thermal_get_temp(void *data, int *temp) if (!(gs101_spmic_thermal->adc_chan_en & (mask << s->adc_chan))) return -EIO; - ret = s2mpg11_bulk_read(gs101_spmic_thermal->i2c, reg, - S2MPG11_METER_NTC_BUF, data_buf); - raw = data_buf[0] + ((data_buf[1] & 0xf) << 8); - - // All 0 usually means the NTC is not ready. - if (!ret && !raw) - return -EBUSY; + ret = gs101_spmic_thermal_read_raw(s, &raw); + if (ret) + return ret; *temp = gs101_map_volt_temp(raw); @@ -202,6 +218,22 @@ static int gs101_spmic_thermal_set_trips(void *data, int low_temp, return ret; } +static int gs101_spmic_thermal_set_hot_trip(struct gs101_spmic_thermal_sensor *s, int temp) +{ + int ret = 0; + struct gs101_spmic_thermal_chip *gs101_spmic_thermal = s->chip; + u8 raw = gs101_map_temp_volt(temp) >> 4 & 0xFF; + struct device *dev = gs101_spmic_thermal->dev; + + if (temp == THERMAL_TEMP_INVALID) + return -EINVAL; + ret = s2mpg11_write_reg(gs101_spmic_thermal->i2c, S2MPG11_METER_NTC_H_WARN0 + s->adc_chan, + raw); + dev_info(dev, "Set sensor %d hot trip(mdegC):%d, ret:%d\n", s->adc_chan, temp, ret); + + return ret; +} + /* * Set temperature threshold for given tz, only critical threshold will be * programmed as shutdown threshold. @@ -209,10 +241,8 @@ static int gs101_spmic_thermal_set_trips(void *data, int low_temp, static int gs101_spmic_thermal_set_trip_temp(void *data, int trip, int temp) { struct gs101_spmic_thermal_sensor *s = data; - struct gs101_spmic_thermal_chip *gs101_spmic_thermal = s->chip; const struct thermal_trip *trip_points; int ret = 0; - u8 raw; trip_points = of_thermal_get_trip_points(s->tzd); if (!trip_points) @@ -222,9 +252,7 @@ static int gs101_spmic_thermal_set_trip_temp(void *data, int trip, int temp) return ret; /* Use THERMAL_TRIP_HOT for HW thermal shutdown */ - raw = gs101_map_temp_volt(temp) >> 4 & 0xFF; - ret = s2mpg11_write_reg(gs101_spmic_thermal->i2c, - S2MPG11_METER_NTC_H_WARN0 + s->adc_chan, raw); + ret = gs101_spmic_thermal_set_hot_trip(s, temp); return ret; } @@ -287,6 +315,59 @@ static ssize_t channel_temp_show(struct kobject *kobj, static struct kobj_attribute channel_temp_attr = __ATTR_RO(channel_temp); +static int gs101_spmic_thermal_get_hot_temp(struct thermal_zone_device *tzd) +{ + int ntrips; + const struct thermal_trip *trips; + int i; + + ntrips = of_thermal_get_ntrips(tzd); + if (ntrips <= 0) + return THERMAL_TEMP_INVALID; + + trips = of_thermal_get_trip_points(tzd); + if (!trips) + return THERMAL_TEMP_INVALID; + + for (i = 0; i < ntrips; i++) { + if (of_thermal_is_trip_valid(tzd, i) && trips[i].type == THERMAL_TRIP_HOT) + return trips[i].temperature; + } + + return THERMAL_TEMP_INVALID; +} + +/* + * Wait for sensors to be ready. + */ +static void gs101_spmic_thermal_wait_sensor(struct kthread_work *work) +{ + struct gs101_spmic_thermal_chip *gs101_spmic_thermal = + container_of(work, struct gs101_spmic_thermal_chip, wait_sensor_work.work); + struct device *dev = gs101_spmic_thermal->dev; + u8 mask = 0x1; + int raw, ret, i, j = 64000 / SENSOR_WAIT_SLEEP_MS; + + for (i = 0; i < GTHERM_CHAN_NUM; i++, mask <<= 1) { + if (!(gs101_spmic_thermal->adc_chan_en & mask)) + continue; + /* Wait for longest refresh period */ + while (j--) { + ret = gs101_spmic_thermal_read_raw(&gs101_spmic_thermal->sensor[i], &raw); + dev_info(dev, "Sensor %d raw:0x%x\n", i, raw); + if (ret != -EBUSY) + break; + dev_info(dev, "Sensor %d not ready, retry...\n", i); + msleep(SENSOR_WAIT_SLEEP_MS); + } + if (j < 0) + dev_warn(dev, "Sensor %d timeout, give up...\n", i); + + thermal_zone_device_update(gs101_spmic_thermal->sensor[i].tzd, + THERMAL_EVENT_UNSPECIFIED); + } +} + /* * Register thermal zones. */ @@ -296,7 +377,7 @@ static int gs101_spmic_thermal_register_tzd(struct gs101_spmic_thermal_chip *gs1 struct thermal_zone_device *tzd; struct device *dev = gs101_spmic_thermal->dev; u8 mask = 0x1; - struct kobject *kobj; + int temp; for (i = 0; i < GTHERM_CHAN_NUM; i++, mask <<= 1) { dev_info(dev, "Registering channel %d\n", i); @@ -315,8 +396,11 @@ static int gs101_spmic_thermal_register_tzd(struct gs101_spmic_thermal_chip *gs1 thermal_zone_device_enable(tzd); else thermal_zone_device_disable(tzd); - kobj = kobject_create_and_add("adc_channel", &tzd->device.kobj); - sysfs_create_file(kobj, &channel_temp_attr.attr); + gs101_spmic_thermal->kobjs[i] = + kobject_create_and_add("adc_channel", &tzd->device.kobj); + sysfs_create_file(gs101_spmic_thermal->kobjs[i], &channel_temp_attr.attr); + temp = gs101_spmic_thermal_get_hot_temp(tzd); + gs101_spmic_thermal_set_hot_trip(&gs101_spmic_thermal->sensor[i], temp); } return 0; } @@ -349,11 +433,13 @@ static irqreturn_t gs101_spmic_thermal_irq(int irq, void *data) static void gs101_spmic_thermal_unregister_tzd(struct gs101_spmic_thermal_chip *chip) { - unsigned int i; + int i; struct device *dev = chip->dev; for (i = 0; i < GTHERM_CHAN_NUM; i++) { dev_info(dev, "Unregistering %d sensor\n", i); + sysfs_remove_file(chip->kobjs[i], &channel_temp_attr.attr); + kobject_put(chip->kobjs[i]); devm_thermal_zone_of_sensor_unregister(chip->dev, chip->sensor[i].tzd); } @@ -407,6 +493,7 @@ gs101_spmic_set_enable(struct gs101_spmic_thermal_chip *gs101_spmic_thermal, return ret; } } + if (on) { /* WAR EVT0 disable IC power shutdown reaching NTC_H_WARN threshold */ if (gs101_spmic_thermal->iodev->pmic_rev == S2MPG11_EVT0) { @@ -421,7 +508,6 @@ gs101_spmic_set_enable(struct gs101_spmic_thermal_chip *gs101_spmic_thermal, ret = s2mpg11_write_reg(gs101_spmic_thermal->i2c, S2MPG11_METER_CTRL3, gs101_spmic_thermal->adc_chan_en); - if (ret) { dev_err(dev, "Cannot enable NTC engine\n"); } else { @@ -431,9 +517,13 @@ gs101_spmic_set_enable(struct gs101_spmic_thermal_chip *gs101_spmic_thermal, } else { ret = s2mpg11_write_reg(gs101_spmic_thermal->i2c, S2MPG11_METER_CTRL3, 0x00); - if (ret) + if (ret) { dev_err(dev, "Cannot disable NTC\n"); + } else { + dev_info(dev, "Disabled NTC channels\n"); + } } + return ret; } @@ -505,27 +595,31 @@ static int gs101_spmic_thermal_probe(struct platform_device *pdev) if (!iodev) { dev_err(dev, "Failed to get parent s2mpg11_dev\n"); - return -EINVAL; + ret = -EINVAL; + goto fail; } pdata = iodev->pdata; if (!pdata) { dev_err(dev, "Failed to get s2mpg11_platform_data\n"); - return -EINVAL; + ret = -EINVAL; + goto fail; } chip->dev = dev; chip->i2c = iodev->meter; chip->iodev = iodev; + ret = gs101_spmic_thermal_get_dt_data(pdev, chip); if (ret) { dev_err(dev, "gs101_spmic_thermal get dt data failed\n"); - return ret; + goto fail; } irq_base = pdata->irq_base; if (!irq_base) { dev_err(dev, "Failed to get irq base %d\n", irq_base); - return -ENODEV; + ret = -ENODEV; + goto fail; } gs101_spmic_thermal_init(chip); @@ -570,7 +664,19 @@ static int gs101_spmic_thermal_probe(struct platform_device *pdev) } } + chip->wq = kthread_create_worker(0, "spmic-init"); + if (IS_ERR_OR_NULL(chip->wq)) { + ret = PTR_ERR(chip->wq); + goto free_irq_tz; + } + + kthread_init_delayed_work(&chip->wait_sensor_work, gs101_spmic_thermal_wait_sensor); + platform_set_drvdata(pdev, chip); + + dev_info(dev, "probe done, now wait for sensors\n"); + kthread_mod_delayed_work(chip->wq, &chip->wait_sensor_work, 0); + return ret; free_irq_tz: @@ -581,6 +687,7 @@ static int gs101_spmic_thermal_probe(struct platform_device *pdev) disable_ntc: gs101_spmic_set_enable(chip, false); fail: + devm_kfree(&pdev->dev, chip); return ret; } @@ -589,6 +696,8 @@ static int gs101_spmic_thermal_remove(struct platform_device *pdev) int i; struct gs101_spmic_thermal_chip *chip = platform_get_drvdata(pdev); + kthread_cancel_delayed_work_sync(&chip->wait_sensor_work); + kthread_destroy_worker(chip->wq); for (i = 0; i < GTHERM_CHAN_NUM; i++) { devm_free_irq(&pdev->dev, chip->sensor[i].irq, chip); } diff --git a/drivers/thermal/thermal_of.c b/drivers/thermal/thermal_of.c index 6379f26a335f..9233f7e74454 100644 --- a/drivers/thermal/thermal_of.c +++ b/drivers/thermal/thermal_of.c @@ -89,7 +89,7 @@ static int of_thermal_get_temp(struct thermal_zone_device *tz, { struct __thermal_zone *data = tz->devdata; - if (!data->ops->get_temp) + if (!data->ops || !data->ops->get_temp) return -EINVAL; return data->ops->get_temp(data->sensor_data, temp); @@ -186,6 +186,9 @@ static int of_thermal_set_emul_temp(struct thermal_zone_device *tz, { struct __thermal_zone *data = tz->devdata; + if (!data->ops || !data->ops->set_emul_temp) + return -EINVAL; + return data->ops->set_emul_temp(data->sensor_data, temp); } @@ -194,7 +197,7 @@ static int of_thermal_get_trend(struct thermal_zone_device *tz, int trip, { struct __thermal_zone *data = tz->devdata; - if (!data->ops->get_trend) + if (!data->ops || !data->ops->get_trend) return -EINVAL; return data->ops->get_trend(data->sensor_data, trip, trend); @@ -301,7 +304,7 @@ static int of_thermal_set_trip_temp(struct thermal_zone_device *tz, int trip, if (trip >= data->ntrips || trip < 0) return -EDOM; - if (data->ops->set_trip_temp) { + if (data->ops && data->ops->set_trip_temp) { int ret; ret = data->ops->set_trip_temp(data->sensor_data, trip, temp); diff --git a/drivers/trusty/trusty-irq.c b/drivers/trusty/trusty-irq.c index 7d59950d9a57..5c6076108d0e 100644 --- a/drivers/trusty/trusty-irq.c +++ b/drivers/trusty/trusty-irq.c @@ -191,6 +191,15 @@ static int trusty_irq_cpu_up(unsigned int cpu, struct hlist_node *node) trusty_irq_enable_irqset(is, this_cpu_ptr(is->percpu_irqs)); local_irq_restore(irq_flags); + /* + * Temporary workaround blindly enqueuing work to force trusty scheduler + * to run after a cpu suspend. + * Root causing the workqueue being inappropriately empty + * (e.g. loss of an IPI) may make this workaround unnecessary + * in the future. + */ + trusty_enqueue_nop(is->trusty_dev, NULL); + return 0; } diff --git a/drivers/usb/dwc3/core.c b/drivers/usb/dwc3/core.c index be4690bcf130..f228ed9ee2e7 100644 --- a/drivers/usb/dwc3/core.c +++ b/drivers/usb/dwc3/core.c @@ -1526,15 +1526,17 @@ static int dwc3_probe(struct platform_device *pdev) { struct device *dev = &pdev->dev; struct resource *res, dwc_res; + struct dwc3_vendor *vdwc; struct dwc3 *dwc; int ret; void __iomem *regs; - dwc = devm_kzalloc(dev, sizeof(*dwc), GFP_KERNEL); - if (!dwc) + vdwc = devm_kzalloc(dev, sizeof(*vdwc), GFP_KERNEL); + if (!vdwc) return -ENOMEM; + dwc = &vdwc->dwc; dwc->dev = dev; diff --git a/drivers/usb/dwc3/core.h b/drivers/usb/dwc3/core.h index d938f85c5847..f66fefaf401a 100644 --- a/drivers/usb/dwc3/core.h +++ b/drivers/usb/dwc3/core.h @@ -1319,6 +1319,16 @@ struct dwc3 { ANDROID_KABI_RESERVE(4); }; +/** + * struct dwc3_vendor - contains parameters without modifying the format of DWC3 core + * @dwc: contains dwc3 core reference + * @softconnect: true when gadget connect is called, false when disconnect runs + */ +struct dwc3_vendor { + struct dwc3 dwc; + unsigned softconnect:1; +}; + #define INCRX_BURST_MODE 0 #define INCRX_UNDEF_LENGTH_BURST_MODE 1 diff --git a/drivers/usb/dwc3/gadget.c b/drivers/usb/dwc3/gadget.c index 0503c55d957d..a839caf82c45 100644 --- a/drivers/usb/dwc3/gadget.c +++ b/drivers/usb/dwc3/gadget.c @@ -2411,10 +2411,12 @@ static int __dwc3_gadget_start(struct dwc3 *dwc); static int dwc3_gadget_pullup(struct usb_gadget *g, int is_on) { struct dwc3 *dwc = gadget_to_dwc(g); + struct dwc3_vendor *vdwc = container_of(dwc, struct dwc3_vendor, dwc); unsigned long flags; int ret; is_on = !!is_on; + vdwc->softconnect = is_on; /* * Per databook, when we want to stop the gadget, if a control transfer @@ -4377,9 +4379,10 @@ int dwc3_gadget_suspend(struct dwc3 *dwc) int dwc3_gadget_resume(struct dwc3 *dwc) { + struct dwc3_vendor *vdwc = container_of(dwc, struct dwc3_vendor, dwc); int ret; - if (!dwc->gadget_driver) + if (!dwc->gadget_driver || !vdwc->softconnect) return 0; ret = __dwc3_gadget_start(dwc); diff --git a/drivers/usb/typec/tcpm/google/max77759_contaminant.c b/drivers/usb/typec/tcpm/google/max77759_contaminant.c index b974a5aaa225..a9880bd306d0 100644 --- a/drivers/usb/typec/tcpm/google/max77759_contaminant.c +++ b/drivers/usb/typec/tcpm/google/max77759_contaminant.c @@ -64,6 +64,7 @@ static bool contaminant_detect_maxq; struct max77759_contaminant { struct max77759_plat *chip; enum contamiant_state state; + bool auto_ultra_low_power_mode_disabled; }; static int adc_to_mv(struct max77759_contaminant *contaminant, enum fladc_select channel, @@ -328,11 +329,11 @@ static int detect_contaminant(struct max77759_contaminant *contaminant) } else { logbuffer_log(chip->log, "Contaminant: AP floating cable detected"); /* - * Consider floating cable as sink as well to allow + * Do not enable dry detection for floating cable to allow * TotalPhase analyzer to work as it presents ~600k in * one of the CC pins. */ - inferred_state = SINK; + inferred_state = FLOATING_CABLE; } } @@ -509,7 +510,8 @@ bool process_contaminant_alert(struct max77759_contaminant *contaminant, bool de return false; } - if (contaminant->state == NOT_DETECTED || contaminant->state == SINK) { + if (contaminant->state == NOT_DETECTED || contaminant->state == SINK || + contaminant->state == FLOATING_CABLE) { /* ConnectResult = 0b -> Rp */ if ((status_check(cc_status, TCPC_CC_STATUS_TERM, TCPC_CC_STATUS_TERM_RP)) && ((status_check(cc_status, TCPC_CC_STATUS_CC1_MASK << TCPC_CC_STATUS_CC1_SHIFT, @@ -523,7 +525,7 @@ bool process_contaminant_alert(struct max77759_contaminant *contaminant, bool de : detect_contaminant(contaminant); update_contaminant_state(contaminant, state); - if (state == DETECTED || state == FLOATING_CABLE) { + if (state == DETECTED) { enable_dry_detection(contaminant); return true; } @@ -565,7 +567,7 @@ bool process_contaminant_alert(struct max77759_contaminant *contaminant, bool de update_contaminant_state(contaminant, state); max77759_write8(regmap, TCPC_ROLE_CTRL, role_ctrl_backup); - if (state == DETECTED || state == FLOATING_CABLE) { + if (state == DETECTED) { enable_dry_detection(contaminant); return true; } @@ -580,8 +582,7 @@ bool process_contaminant_alert(struct max77759_contaminant *contaminant, bool de if (debounce_path) enable_contaminant_detection(contaminant->chip, contaminant_detect_maxq); return false; - } else if (contaminant->state == DETECTED || contaminant->state == - FLOATING_CABLE) { + } else if (contaminant->state == DETECTED) { if (status_check(cc_status, TCPC_CC_STATUS_TOGGLING, 0)) { logbuffer_log(chip->log, "Contaminant: Check if dry"); state = contaminant_detect_maxq ? @@ -589,12 +590,16 @@ bool process_contaminant_alert(struct max77759_contaminant *contaminant, bool de : detect_contaminant(contaminant); update_contaminant_state(contaminant, state); - if (state == DETECTED || state == FLOATING_CABLE) { + if (state == DETECTED) { enable_dry_detection(contaminant); return true; } - /* Re-enable contaminant detection, hence toggling as well. */ + /* + * Re-enable contaminant detection, hence toggling and + * auto_ultra_low_power_mode as well. + */ + disable_auto_ultra_low_power_mode(chip, false); enable_contaminant_detection(contaminant->chip, contaminant_detect_maxq); return true; } @@ -683,11 +688,13 @@ int enable_contaminant_detection(struct max77759_plat *chip, bool maxq) if (ret < 0) return ret; - /* tunable: Periodic contaminant detection */ - ret = max77759_update_bits8(regmap, TCPC_VENDOR_CC_CTRL2, CCLPMODESEL_MASK, - AUTO_ULTRA_LOW_POWER_MODE); - if (ret < 0) - return ret; + if (!contaminant->auto_ultra_low_power_mode_disabled) { + /* tunable: Periodic contaminant detection */ + ret = max77759_update_bits8(regmap, TCPC_VENDOR_CC_CTRL2, CCLPMODESEL_MASK, + AUTO_ULTRA_LOW_POWER_MODE); + if (ret < 0) + return ret; + } ret = max77759_read8(regmap, TCPC_VENDOR_CC_CTRL2, &vcc2); if (ret < 0) @@ -733,10 +740,6 @@ int enable_contaminant_detection(struct max77759_plat *chip, bool maxq) if (ret < 0) return ret; - /* Reset state before enabling detection */ - if (contaminant->state != NOT_DETECTED && contaminant->state != SINK) - contaminant->state = NOT_DETECTED; - logbuffer_log(chip->log, "Contaminant: Contaminant detection enabled"); return 0; @@ -752,6 +755,39 @@ bool is_contaminant_detected(struct max77759_plat *chip) } EXPORT_SYMBOL_GPL(is_contaminant_detected); +bool is_floating_cable_detected(struct max77759_plat *chip) +{ + if (chip) + return chip->contaminant->state == FLOATING_CABLE; + + return false; +} +EXPORT_SYMBOL_GPL(is_floating_cable_detected); + +void disable_auto_ultra_low_power_mode(struct max77759_plat *chip, bool disable) +{ + struct max77759_contaminant *contaminant = chip->contaminant; + int ret; + + if (!chip || !chip->contaminant) + return; + + if (contaminant->auto_ultra_low_power_mode_disabled == disable) { + logbuffer_log(chip->log, "Auto ultra low power mode already %s", + disable ? "disable" : "enable"); + return; + } + + ret = max77759_update_bits8(chip->data.regmap, TCPC_VENDOR_CC_CTRL2, CCLPMODESEL_MASK, + disable ? LOW_POWER_MODE_DISABLE : AUTO_ULTRA_LOW_POWER_MODE); + + logbuffer_log(chip->log, "Contaminant: Auto ultra low power mode %s ret:%d", + disable ? "disable" : "enable", ret); + if (!ret) + contaminant->auto_ultra_low_power_mode_disabled = disable; +} +EXPORT_SYMBOL_GPL(disable_auto_ultra_low_power_mode); + struct max77759_contaminant *max77759_contaminant_init(struct max77759_plat *plat, bool enable) { diff --git a/drivers/usb/typec/tcpm/google/tcpci_max77759.c b/drivers/usb/typec/tcpm/google/tcpci_max77759.c index f16d5e56acb2..532dad1cb20f 100644 --- a/drivers/usb/typec/tcpm/google/tcpci_max77759.c +++ b/drivers/usb/typec/tcpm/google/tcpci_max77759.c @@ -78,6 +78,12 @@ enum gbms_charger_modes { #define VOLTAGE_ALARM_LOW_EN_MV 1500 #define VOLTAGE_ALARM_LOW_DIS_MV 0 +#define FLOATING_CABLE_INSTANCE_THRESHOLD 5 +#define AUTO_ULTRA_LOW_POWER_MODE_REENABLE_MS 600000 + +#define REGMAP_REG_MAX_ADDR 0x95 +#define REGMAP_REG_COUNT (REGMAP_REG_MAX_ADDR + 1) + static struct logbuffer *tcpm_log; static bool modparam_conf_sbu; @@ -103,7 +109,7 @@ struct tcpci { }; static const struct regmap_range max77759_tcpci_range[] = { - regmap_reg_range(0x00, 0x95) + regmap_reg_range(0x00, REGMAP_REG_MAX_ADDR) }; const struct regmap_access_table max77759_tcpci_write_table = { @@ -114,7 +120,7 @@ const struct regmap_access_table max77759_tcpci_write_table = { static const struct regmap_config max77759_regmap_config = { .reg_bits = 8, .val_bits = 8, - .max_register = 0x95, + .max_register = REGMAP_REG_MAX_ADDR, .wr_table = &max77759_tcpci_write_table, }; @@ -142,6 +148,33 @@ static ssize_t bc12_enabled_show(struct device *dev, struct device_attribute *at }; static DEVICE_ATTR_RO(bc12_enabled); +/* Debugfs disabled in user builds. */ +static ssize_t registers_show(struct device *dev, struct device_attribute *attr, char *buf) +{ + struct max77759_plat *chip = i2c_get_clientdata(to_i2c_client(dev)); + struct regmap *regmap = chip->data.regmap; + u8 dump[REGMAP_REG_COUNT]; + int ret, offset = 0, addr; + + ret = regmap_bulk_read(regmap, 0, dump, REGMAP_REG_COUNT); + if (ret < 0) { + dev_err(chip->dev, "[%s]: Failed to dump ret:%d\n", __func__, ret); + return 0; + } + + for (addr = 0; addr < REGMAP_REG_COUNT; addr++) { + ret = sysfs_emit_at(buf, offset, "%x: %x\n", addr, dump[addr]); + if (!ret) { + dev_err(chip->dev, "[%s]: Not all registers printed. last:%x\n", addr - 1); + break; + } + offset += ret; + } + + return offset; +}; +static DEVICE_ATTR_RO(registers); + static ssize_t contaminant_detection_show(struct device *dev, struct device_attribute *attr, char *buf) { @@ -229,6 +262,7 @@ static DEVICE_ATTR_RO(contaminant_detection_status); static struct device_attribute *max77759_device_attrs[] = { &dev_attr_frs, &dev_attr_bc12_enabled, + &dev_attr_registers, &dev_attr_auto_discharge, &dev_attr_contaminant_detection, &dev_attr_contaminant_detection_status, @@ -906,10 +940,29 @@ static irqreturn_t _max77759_irq(struct max77759_plat *chip, u16 status, */ mutex_lock(&chip->rc_lock); if (!chip->contaminant_detection || !tcpm_is_toggling(tcpci->port) || - !process_contaminant_alert(chip->contaminant, false, true)) + !process_contaminant_alert(chip->contaminant, false, true)) { tcpm_cc_change(tcpci->port); - else + /* TCPM has detected valid CC terminations */ + if (!tcpm_is_toggling(tcpci->port)) { + chip->floating_cable_detected = 0; + disable_auto_ultra_low_power_mode(chip, false); + logbuffer_log(chip->log, "enable_auto_ultra_low_power_mode"); + } + } else { logbuffer_log(log, "CC update: Contaminant algorithm responded"); + if (is_floating_cable_detected(chip)) { + chip->floating_cable_detected++; + logbuffer_log(chip->log, "floating_cable_detected count: %d", + chip->floating_cable_detected); + if (chip->floating_cable_detected >= + FLOATING_CABLE_INSTANCE_THRESHOLD) { + disable_auto_ultra_low_power_mode(chip, true); + alarm_start_relative( + &chip->reenable_auto_ultra_low_power_mode_alarm, + ms_to_ktime(AUTO_ULTRA_LOW_POWER_MODE_REENABLE_MS)); + } + } + } mutex_unlock(&chip->rc_lock); } @@ -1129,9 +1182,9 @@ static int max77759_start_toggling(struct tcpci *tcpci, /* Kick debug accessory state machine when enabling toggling for the first time */ if (chip->first_toggle && chip->in_switch_gpio >= 0) { logbuffer_log(chip->log, "[%s]: Kick Debug accessory FSM", __func__); - gpio_set_value_cansleep(chip->in_switch_gpio, 0); + gpio_set_value_cansleep(chip->in_switch_gpio, !chip->in_switch_gpio_active_high); mdelay(10); - gpio_set_value_cansleep(chip->in_switch_gpio, 1); + gpio_set_value_cansleep(chip->in_switch_gpio, chip->in_switch_gpio_active_high); chip->first_toggle = false; } @@ -1513,16 +1566,26 @@ static void max77759_toggle_disable_votable_callback(struct gvotable_election *e update_contaminant_detection_locked(chip, CONTAMINANT_DETECT_DISABLE); disable_contaminant_detection(chip); max77759_enable_toggling_locked(chip, false); - gpio_set_value_cansleep(chip->in_switch_gpio, 0); - logbuffer_log(chip->log, "[%s]: Disable in-switch", __func__); + if (chip->in_switch_gpio >= 0) { + gpio_set_value_cansleep(chip->in_switch_gpio, + !chip->in_switch_gpio_active_high); + logbuffer_log(chip->log, "[%s]: Disable in-switch set %s / active %s", + __func__, !chip->in_switch_gpio_active_high ? "high" : "low", + chip->in_switch_gpio_active_high ? "high" : "low"); + } } else { if (chip->contaminant_detection_userspace) update_contaminant_detection_locked(chip, chip->contaminant_detection_userspace); else max77759_enable_toggling_locked(chip, true); - gpio_set_value_cansleep(chip->in_switch_gpio, 1); - logbuffer_log(chip->log, "[%s]: Enable in-switch", __func__); + if (chip->in_switch_gpio >= 0) { + gpio_set_value_cansleep(chip->in_switch_gpio, + chip->in_switch_gpio_active_high); + logbuffer_log(chip->log, "[%s]: Enable in-switch set %s / active %s", + __func__, chip->in_switch_gpio_active_high ? "high" : "low", + chip->in_switch_gpio_active_high ? "high" : "low"); + } } mutex_unlock(&chip->rc_lock); logbuffer_log(chip->log, "%s: reason %s value %ld\n", __func__, reason, (long)value); @@ -1754,6 +1817,34 @@ static void max77759_teardown_data_notifier(struct max77759_plat *chip) usb_role_switch_unregister(chip->usb_sw); } +static void reenable_auto_ultra_low_power_mode_work_item(struct kthread_work *work) +{ + struct max77759_plat *chip = container_of(work, struct max77759_plat, + reenable_auto_ultra_low_power_mode_work); + + chip->floating_cable_detected = 0; + disable_auto_ultra_low_power_mode(chip, false); +} + +static enum alarmtimer_restart reenable_auto_ultra_low_power_mode_alarm_handler(struct alarm *alarm, + ktime_t time) +{ + struct max77759_plat *chip = container_of(alarm, struct max77759_plat, + reenable_auto_ultra_low_power_mode_alarm); + + logbuffer_log(chip->log, "timer fired: enable_auto_ultra_low_power_mode"); + if (is_contaminant_detected(chip)) { + logbuffer_log(chip->log, + "Skipping enable_auto_ultra_low_power_mode. Dry detection in progress"); + goto exit; + } + kthread_queue_work(chip->wq, &chip->reenable_auto_ultra_low_power_mode_work); + pm_wakeup_event(chip->dev, PD_ACTIVITY_TIMEOUT_MS); + +exit: + return ALARMTIMER_NORESTART; +} + static int max77759_probe(struct i2c_client *client, const struct i2c_device_id *i2c_id) { @@ -1765,6 +1856,7 @@ static int max77759_probe(struct i2c_client *client, u16 device_id; u32 ovp_handle; const char *ovp_status; + enum of_gpio_flags flags; ret = max77759_register_vendor_hooks(client); if (ret) @@ -1789,22 +1881,36 @@ static int max77759_probe(struct i2c_client *client, return -EPROBE_DEFER; } + kthread_init_work(&chip->reenable_auto_ultra_low_power_mode_work, + reenable_auto_ultra_low_power_mode_work_item); + alarm_init(&chip->reenable_auto_ultra_low_power_mode_alarm, ALARM_BOOTTIME, + reenable_auto_ultra_low_power_mode_alarm_handler); dn = dev_of_node(&client->dev); if (!dn) { dev_err(&client->dev, "of node not found\n"); return -EINVAL; } - if (!of_property_read_u32(dn, "max20339,ovp", &ovp_handle)) { + chip->in_switch_gpio = -EINVAL; + if (of_property_read_bool(dn, "ovp-present")) { + chip->in_switch_gpio = of_get_named_gpio_flags(dn, "in-switch-gpio", 0, &flags); + if (chip->in_switch_gpio < 0) { + dev_err(&client->dev, "in-switch-gpio not found\n"); + return -EPROBE_DEFER; + } + chip->in_switch_gpio_active_high = (flags & OF_GPIO_ACTIVE_LOW) ? 0 : 1; + } else if (!of_property_read_u32(dn, "max20339,ovp", &ovp_handle)) { ovp_dn = of_find_node_by_phandle(ovp_handle); if (!IS_ERR_OR_NULL(ovp_dn) && !of_property_read_string(ovp_dn, "status", &ovp_status) && strncmp(ovp_status, "disabled", strlen("disabled"))) { - chip->in_switch_gpio = of_get_named_gpio(dn, "in-switch-gpio", 0); + chip->in_switch_gpio = of_get_named_gpio_flags(dn, "in-switch-gpio", 0, + &flags); if (chip->in_switch_gpio < 0) { dev_err(&client->dev, "in-switch-gpio not found\n"); return -EPROBE_DEFER; } + chip->in_switch_gpio_active_high = (flags & OF_GPIO_ACTIVE_LOW) ? 0 : 1; } } diff --git a/drivers/usb/typec/tcpm/google/tcpci_max77759.h b/drivers/usb/typec/tcpm/google/tcpci_max77759.h index 547718d105ee..e2dac9247861 100644 --- a/drivers/usb/typec/tcpm/google/tcpci_max77759.h +++ b/drivers/usb/typec/tcpm/google/tcpci_max77759.h @@ -7,6 +7,7 @@ #ifndef __TCPCI_MAX77759_H #define __TCPCI_MAX77759_H +#include #include #include #include @@ -65,6 +66,8 @@ struct max77759_plat { struct usb_psy_ops psy_ops; /* toggle in_switch to kick debug accessory statemachine when already connected */ int in_switch_gpio; + /* 0:active_low 1:active_high */ + bool in_switch_gpio_active_high; bool first_toggle; /* True when TCPC is in SINK DEBUG ACCESSORY CONNECTED state */ @@ -87,6 +90,12 @@ struct max77759_plat { int contaminant_detection; /* Userspace status */ bool contaminant_detection_userspace; + /* Consecutive floating cable instances */ + unsigned int floating_cable_detected; + /* Timer to re-enable auto ultra lower mode for contaminant detection */ + struct alarm reenable_auto_ultra_low_power_mode_alarm; + /* Bottom half for alarm */ + struct kthread_work reenable_auto_ultra_low_power_mode_work; /* Protects contaminant_detection variable and role_control */ struct mutex rc_lock; @@ -151,6 +160,8 @@ bool process_contaminant_alert(struct max77759_contaminant *contaminant, bool de int enable_contaminant_detection(struct max77759_plat *chip, bool maxq); void disable_contaminant_detection(struct max77759_plat *chip); bool is_contaminant_detected(struct max77759_plat *chip); +bool is_floating_cable_detected(struct max77759_plat *chip); +void disable_auto_ultra_low_power_mode(struct max77759_plat *chip, bool disable); #define VBUS_VOLTAGE_MASK 0x3ff #define VBUS_VOLTAGE_LSB_MV 25 diff --git a/drivers/usb/typec/tcpm/google/usb_psy.c b/drivers/usb/typec/tcpm/google/usb_psy.c index 9d5ef7ae1523..92f4d34be88c 100644 --- a/drivers/usb/typec/tcpm/google/usb_psy.c +++ b/drivers/usb/typec/tcpm/google/usb_psy.c @@ -106,6 +106,11 @@ struct usb_psy_data { /* Tracks attached state from Type-C */ bool attached; + /* + * Expedite UI notification. + */ + bool expedite_connect_status; + bool usb_configured; /* Alarm for forcing to DCP port on enumeration timeout */ @@ -258,6 +263,25 @@ static void set_sdp_current_limit(struct usb_psy_data *usb, int ua) disable_proto_votes(usb_icl_proto_el, log, voter_map); } +/* + * Enable 5V/500mA charging for DCP ports upon connect. + * Defer increasing to 1.5A later once PD negotiation completes. + */ +static void expedite_connect(struct usb_psy_data *usb) +{ + int ret; + struct usb_vote vote; + + init_vote(&vote, proto_voter_reason[BC12_CDP_DCP], BC12_CDP_DCP, 500000); + + ret = gvotable_cast_vote(usb->usb_icl_proto_el, vote.reason, &vote, true); + + logbuffer_log(usb->log, "%s: %s voting usb proto_el: %d by %s", __func__, + ret < 0 ? "error" : "", vote.val, vote.reason); + + usb->expedite_connect_status = true; +} + static void set_bc_current_limit(struct gvotable_election *usb_icl_proto_el, enum power_supply_usb_type usb_type, struct logbuffer *log) @@ -346,8 +370,15 @@ static int usb_psy_data_get_prop(struct power_supply *psy, val->intval = usb->sink_enabled; break; case POWER_SUPPLY_PROP_CURRENT_MAX: - /* Report the voted value to reflect TA capability */ - val->intval = usb->current_max_cache; + /* + * When expedite_connect_status is true, we have to mask + * presenting slow charging notification to UI. + * Hence report CDP_DCP_ICL_UA. + * Report the voted value to reflect TA capability when + * expedite_connect_status isn't set. + */ + val->intval = usb->expedite_connect_status ? CDP_DCP_ICL_UA : + usb->current_max_cache; break; case POWER_SUPPLY_PROP_VOLTAGE_MAX: /* Report in uv */ @@ -405,6 +436,11 @@ static int usb_psy_data_set_prop(struct power_supply *psy, usb->usb_configured = false; ops->tcpc_set_port_data_capable(client, usb->usb_type); + /* Expedite connect for UX notification */ + if (usb->usb_type == POWER_SUPPLY_USB_TYPE_DCP) + expedite_connect(usb); + + /* Defer setting actual BC current limit to later */ kthread_mod_delayed_work(usb->wq, &usb->bc_icl_work, usb->usb_type != POWER_SUPPLY_USB_TYPE_UNKNOWN ? msecs_to_jiffies(BC_VOTE_DELAY_MS) : 0); @@ -470,6 +506,11 @@ void usb_psy_set_attached_state(void *usb_psy, bool attached) } usb->attached = attached; + + /* Clear on disconnect */ + if (!attached) + usb->expedite_connect_status = false; + power_supply_changed(usb->usb_psy); } EXPORT_SYMBOL_GPL(usb_psy_set_attached_state); @@ -655,6 +696,8 @@ static void bc_icl_work_item(struct kthread_work *work) struct usb_psy_data, bc_icl_work); set_bc_current_limit(usb->usb_icl_proto_el, usb->usb_type, usb->log); + /* Clear as the actual currect limit is now set */ + usb->expedite_connect_status = false; } static void sdp_icl_work_item(struct kthread_work *work) diff --git a/drivers/usb/typec/tcpm/google/usbc_cooling_dev.c b/drivers/usb/typec/tcpm/google/usbc_cooling_dev.c index 166d25d267be..d04b758388ba 100644 --- a/drivers/usb/typec/tcpm/google/usbc_cooling_dev.c +++ b/drivers/usb/typec/tcpm/google/usbc_cooling_dev.c @@ -182,7 +182,7 @@ static int suspend_usb(struct usb_port_cooling_dev_info *usb_cdev_info) /* suspend USBIN */ ret = gvotable_cast_vote(usb_cdev_info->usb_icl_votable, USBC_COOLING_DEV_VOTER, - (void *)ENABLE_ICL_VOTE, THROTTLE_USBIN_LIMIT); + (void *)THROTTLE_USBIN_LIMIT, ENABLE_ICL_VOTE); if (ret < 0) { dev_err(usb_cdev_info->dev, "Couldn't vote for USB ICL ret=%d\n", ret); return ret; @@ -213,7 +213,7 @@ static int resume_usb(struct usb_port_cooling_dev_info *usb_cdev_info) /* enable USBIN */ ret = gvotable_cast_vote(usb_cdev_info->usb_icl_votable, USBC_COOLING_DEV_VOTER, - (void *)DISABLE_ICL_VOTE, THROTTLE_USBIN_LIMIT); + (void *)THROTTLE_USBIN_LIMIT, DISABLE_ICL_VOTE); if (ret < 0) { dev_err(usb_cdev_info->dev, "Couldn't un-vote for USB ICL ret=%d\n", ret); return ret; diff --git a/include/linux/kfence.h b/include/linux/kfence.h index a70d1ea03532..3fe6dd8a18c1 100644 --- a/include/linux/kfence.h +++ b/include/linux/kfence.h @@ -51,10 +51,11 @@ extern atomic_t kfence_allocation_gate; static __always_inline bool is_kfence_address(const void *addr) { /* - * The non-NULL check is required in case the __kfence_pool pointer was - * never initialized; keep it in the slow-path after the range-check. + * The __kfence_pool != NULL check is required to deal with the case + * where __kfence_pool == NULL && addr < KFENCE_POOL_SIZE. Keep it in + * the slow-path after the range-check! */ - return unlikely((unsigned long)((char *)addr - __kfence_pool) < KFENCE_POOL_SIZE && addr); + return unlikely((unsigned long)((char *)addr - __kfence_pool) < KFENCE_POOL_SIZE && __kfence_pool); } /** diff --git a/include/linux/mmc/mmc.h b/include/linux/mmc/mmc.h index d9a65c6a8816..2884634fdf0a 100644 --- a/include/linux/mmc/mmc.h +++ b/include/linux/mmc/mmc.h @@ -449,4 +449,13 @@ static inline bool mmc_ready_for_data(u32 status) #define mmc_driver_type_mask(n) (1 << (n)) +struct mmc_card; + +extern int mmc_select_bus_width(struct mmc_card *card); +extern int mmc_select_hs(struct mmc_card *card); +extern int mmc_select_hs_ddr(struct mmc_card *card); +extern int mmc_select_hs400(struct mmc_card *card); +extern int mmc_hs200_tuning(struct mmc_card *card); +extern int mmc_select_timing(struct mmc_card *card); + #endif /* LINUX_MMC_MMC_H */ diff --git a/include/linux/tracepoint.h b/include/linux/tracepoint.h index e4c5df71f0e7..c51a00210f88 100644 --- a/include/linux/tracepoint.h +++ b/include/linux/tracepoint.h @@ -245,7 +245,7 @@ static inline struct tracepoint *tracepoint_ptr_deref(tracepoint_ptr_t *p) extern int __traceiter_##name(data_proto); \ DECLARE_STATIC_CALL(tp_func_##name, __traceiter_##name); \ extern struct tracepoint __tracepoint_##name; \ - static inline void trace_##name(proto) \ + static inline void __nocfi trace_##name(proto) \ { \ if (static_key_false(&__tracepoint_##name.key)) \ __DO_TRACE(name, \ @@ -310,7 +310,7 @@ static inline struct tracepoint *tracepoint_ptr_deref(tracepoint_ptr_t *p) .unregfunc = _unreg, \ .funcs = NULL }; \ __TRACEPOINT_ENTRY(_name); \ - int __traceiter_##_name(void *__data, proto) \ + int __nocfi __traceiter_##_name(void *__data, proto) \ { \ struct tracepoint_func *it_func_ptr; \ void *it_func; \ diff --git a/include/soc/google/bcl.h b/include/soc/google/bcl.h index c7243b7adcaa..6b979305ef9e 100644 --- a/include/soc/google/bcl.h +++ b/include/soc/google/bcl.h @@ -91,8 +91,13 @@ struct bcl_device { unsigned int gpu_con_light; unsigned int tpu_clkdivstep; unsigned int gpu_clkdivstep; + unsigned int cpu2_clkdivstep; + unsigned int cpu1_clkdivstep; + unsigned int cpu0_clkdivstep; unsigned int gpu_clk_stats; unsigned int tpu_clk_stats; + unsigned int tpu_vdroop_flt; + unsigned int gpu_vdroop_flt; bool batt_psy_initialized; bool enabled; diff --git a/include/trace/hooks/mm.h b/include/trace/hooks/mm.h index ac6142a6e02a..4b299fd6e613 100644 --- a/include/trace/hooks/mm.h +++ b/include/trace/hooks/mm.h @@ -117,6 +117,15 @@ DECLARE_HOOK(android_vh_mem_cgroup_css_online, DECLARE_HOOK(android_vh_mem_cgroup_css_offline, TP_PROTO(struct cgroup_subsys_state *css, struct mem_cgroup *memcg), TP_ARGS(css, memcg)); +DECLARE_HOOK(android_vh_kmalloc_slab, + TP_PROTO(unsigned int index, gfp_t flags, struct kmem_cache **s), + TP_ARGS(index, flags, s)); +DECLARE_HOOK(android_vh_mmap_region, + TP_PROTO(struct vm_area_struct *vma, unsigned long addr), + TP_ARGS(vma, addr)); +DECLARE_HOOK(android_vh_try_to_unmap_one, + TP_PROTO(struct vm_area_struct *vma, struct page *page, unsigned long addr, bool ret), + TP_ARGS(vma, page, addr, ret)); /* macro versions of hooks are no longer required */ #endif /* _TRACE_HOOK_MM_H */ diff --git a/include/trace/hooks/vendor_hooks.h b/include/trace/hooks/vendor_hooks.h index f51a9ac31045..87fe9ccdc331 100644 --- a/include/trace/hooks/vendor_hooks.h +++ b/include/trace/hooks/vendor_hooks.h @@ -33,7 +33,7 @@ int android_rvh_probe_register(struct tracepoint *tp, void *probe, void *data); .unregfunc = _unreg, \ .funcs = NULL }; \ __TRACEPOINT_ENTRY(_name); \ - int __traceiter_##_name(void *__data, proto) \ + int __nocfi __traceiter_##_name(void *__data, proto) \ { \ struct tracepoint_func *it_func_ptr; \ void *it_func; \ diff --git a/include/uapi/linux/android/binder.h b/include/uapi/linux/android/binder.h index 74dcd8e92e50..2d3f015e2ae3 100644 --- a/include/uapi/linux/android/binder.h +++ b/include/uapi/linux/android/binder.h @@ -273,7 +273,14 @@ struct binder_freeze_info { struct binder_frozen_status_info { __u32 pid; + + /* process received sync transactions since last frozen + * bit 0: received sync transaction after being frozen + * bit 1: new pending sync transaction during freezing + */ __u32 sync_recv; + + /* process received async transactions since last frozen */ __u32 async_recv; }; diff --git a/kernel/irq/irqdomain.c b/kernel/irq/irqdomain.c index dffef2549d82..2c3d4943d721 100644 --- a/kernel/irq/irqdomain.c +++ b/kernel/irq/irqdomain.c @@ -1192,6 +1192,7 @@ int irq_domain_disconnect_hierarchy(struct irq_domain *domain, irqd->chip = ERR_PTR(-ENOTCONN); return 0; } +EXPORT_SYMBOL_GPL(irq_domain_disconnect_hierarchy); static int irq_domain_trim_hierarchy(unsigned int virq) { diff --git a/kernel/sched/core.c b/kernel/sched/core.c index 19f1b6ce6de6..06e2829a1ca1 100644 --- a/kernel/sched/core.c +++ b/kernel/sched/core.c @@ -4214,6 +4214,7 @@ unsigned long long task_sched_runtime(struct task_struct *p) return ns; } +EXPORT_SYMBOL_GPL(task_sched_runtime); /* * This function gets called by the timer code, with HZ frequency. @@ -5527,6 +5528,10 @@ static int __sched_setscheduler(struct task_struct *p, /* Normal users shall not reset the sched_reset_on_fork flag: */ if (p->sched_reset_on_fork && !reset_on_fork) return -EPERM; + + /* Can't change util-clamps */ + if (attr->sched_flags & SCHED_FLAG_UTIL_CLAMP) + return -EPERM; } if (user) { diff --git a/mm/filemap.c b/mm/filemap.c index d60dd67000fb..632734e9f8f1 100644 --- a/mm/filemap.c +++ b/mm/filemap.c @@ -2996,6 +2996,8 @@ vm_fault_t filemap_map_pages(struct vm_fault *vmf, addr = vma->vm_start + ((start_pgoff - vma->vm_pgoff) << PAGE_SHIFT); if (!pte_map_lock_addr(vmf, addr)) { + unlock_page(head); + put_page(head); ret = VM_FAULT_RETRY; goto out; } diff --git a/mm/kmemleak.c b/mm/kmemleak.c index fe6e3ae8e8c6..65df87f5cd34 100644 --- a/mm/kmemleak.c +++ b/mm/kmemleak.c @@ -290,7 +290,7 @@ static void hex_dump_object(struct seq_file *seq, warn_or_seq_printf(seq, " hex dump (first %zu bytes):\n", len); kasan_disable_current(); warn_or_seq_hex_dump(seq, DUMP_PREFIX_NONE, HEX_ROW_SIZE, - HEX_GROUP_SIZE, ptr, len, HEX_ASCII); + HEX_GROUP_SIZE, kasan_reset_tag((void *)ptr), len, HEX_ASCII); kasan_enable_current(); } @@ -1171,7 +1171,7 @@ static bool update_checksum(struct kmemleak_object *object) kasan_disable_current(); kcsan_disable_current(); - object->checksum = crc32(0, (void *)object->pointer, object->size); + object->checksum = crc32(0, kasan_reset_tag((void *)object->pointer), object->size); kasan_enable_current(); kcsan_enable_current(); @@ -1246,7 +1246,7 @@ static void scan_block(void *_start, void *_end, break; kasan_disable_current(); - pointer = *ptr; + pointer = *(unsigned long *)kasan_reset_tag((void *)ptr); kasan_enable_current(); untagged_ptr = (unsigned long)kasan_reset_tag((void *)pointer); diff --git a/mm/madvise.c b/mm/madvise.c index 9ec5037bf297..e865ae74a5bf 100644 --- a/mm/madvise.c +++ b/mm/madvise.c @@ -996,6 +996,7 @@ process_madvise_behavior_valid(int behavior) switch (behavior) { case MADV_COLD: case MADV_PAGEOUT: + case MADV_WILLNEED: return true; default: return false; diff --git a/mm/memory.c b/mm/memory.c index 097bf967a047..44c6a8ee197b 100644 --- a/mm/memory.c +++ b/mm/memory.c @@ -4159,8 +4159,17 @@ vm_fault_t finish_fault(struct vm_fault *vmf) return ret; } - if (unlikely(pte_alloc(vma->vm_mm, vmf->pmd))) + if (vmf->prealloc_pte) { + vmf->ptl = pmd_lock(vma->vm_mm, vmf->pmd); + if (likely(pmd_none(*vmf->pmd))) { + mm_inc_nr_ptes(vma->vm_mm); + pmd_populate(vma->vm_mm, vmf->pmd, vmf->prealloc_pte); + vmf->prealloc_pte = NULL; + } + spin_unlock(vmf->ptl); + } else if (unlikely(pte_alloc(vma->vm_mm, vmf->pmd))) { return VM_FAULT_OOM; + } } /* See comment in handle_pte_fault() */ diff --git a/mm/mmap.c b/mm/mmap.c index b1ca729a11f2..9a4f09216130 100644 --- a/mm/mmap.c +++ b/mm/mmap.c @@ -1964,6 +1964,8 @@ unsigned long mmap_region(struct file *file, unsigned long addr, vma_set_page_prot(vma); vm_write_end(vma); + trace_android_vh_mmap_region(vma, addr); + return addr; unmap_and_free_vma: diff --git a/mm/page_pinner.c b/mm/page_pinner.c index 3f5c48af3135..f4a141aafac6 100644 --- a/mm/page_pinner.c +++ b/mm/page_pinner.c @@ -59,7 +59,7 @@ static bool page_pinner_enabled; DEFINE_STATIC_KEY_FALSE(page_pinner_inited); DEFINE_STATIC_KEY_TRUE(failure_tracking); -EXPORT_SYMBOL_GPL(failure_tracking); +EXPORT_SYMBOL(failure_tracking); static depot_stack_handle_t failure_handle; @@ -350,7 +350,7 @@ void __page_pinner_migration_failed(struct page *page) acf_pinner.pinner[idx] = record; spin_unlock_irqrestore(&acf_pinner.lock, flags); } -EXPORT_SYMBOL_GPL(__page_pinner_migration_failed); +EXPORT_SYMBOL(__page_pinner_migration_failed); void __page_pinner_mark_migration_failed_pages(struct list_head *page_list) { diff --git a/mm/rmap.c b/mm/rmap.c index 4fdbda090c2c..22464daf02d6 100644 --- a/mm/rmap.c +++ b/mm/rmap.c @@ -77,6 +77,8 @@ #include +#include + #include "internal.h" static struct kmem_cache *anon_vma_cachep; @@ -1713,6 +1715,7 @@ static bool try_to_unmap_one(struct page *page, struct vm_area_struct *vma, } mmu_notifier_invalidate_range_end(&range); + trace_android_vh_try_to_unmap_one(vma, page, address, ret); return ret; } diff --git a/mm/slab_common.c b/mm/slab_common.c index 54a4be9a862a..6a04bfa91df5 100644 --- a/mm/slab_common.c +++ b/mm/slab_common.c @@ -313,6 +313,16 @@ kmem_cache_create_usercopy(const char *name, get_online_cpus(); get_online_mems(); +#ifdef CONFIG_SLUB_DEBUG + /* + * If no slub_debug was enabled globally, the static key is not yet + * enabled by setup_slub_debug(). Enable it if the cache is being + * created with any of the debugging flags passed explicitly. + */ + if (flags & SLAB_DEBUG_FLAGS) + static_branch_enable(&slub_debug_enabled); +#endif + mutex_lock(&slab_mutex); err = kmem_cache_sanity_check(name, size); @@ -640,6 +650,7 @@ static inline unsigned int size_index_elem(unsigned int bytes) struct kmem_cache *kmalloc_slab(size_t size, gfp_t flags) { unsigned int index; + struct kmem_cache *s = NULL; if (size <= 192) { if (!size) @@ -652,6 +663,10 @@ struct kmem_cache *kmalloc_slab(size_t size, gfp_t flags) index = fls(size - 1); } + trace_android_vh_kmalloc_slab(index, flags, &s); + if (s) + return s; + return kmalloc_caches[kmalloc_type(flags)][index]; } diff --git a/mm/slub.c b/mm/slub.c index e7ec933a6de7..6cdd8f0b3da7 100644 --- a/mm/slub.c +++ b/mm/slub.c @@ -535,8 +535,8 @@ static void print_section(char *level, char *text, u8 *addr, unsigned int length) { metadata_access_enable(); - print_hex_dump(level, kasan_reset_tag(text), DUMP_PREFIX_ADDRESS, - 16, 1, addr, length, 1); + print_hex_dump(level, text, DUMP_PREFIX_ADDRESS, + 16, 1, kasan_reset_tag((void *)addr), length, 1); metadata_access_disable(); } @@ -1379,12 +1379,13 @@ parse_slub_debug_flags(char *str, slab_flags_t *flags, char **slabs, bool init) static int __init setup_slub_debug(char *str) { slab_flags_t flags; + slab_flags_t global_flags; char *saved_str; char *slab_list; bool global_slub_debug_changed = false; bool slab_list_specified = false; - slub_debug = DEBUG_DEFAULT_FLAGS; + global_flags = DEBUG_DEFAULT_FLAGS; if (*str++ != '=' || !*str) /* * No options specified. Switch on full debugging. @@ -1396,7 +1397,7 @@ static int __init setup_slub_debug(char *str) str = parse_slub_debug_flags(str, &flags, &slab_list, true); if (!slab_list) { - slub_debug = flags; + global_flags = flags; global_slub_debug_changed = true; } else { slab_list_specified = true; @@ -1405,16 +1406,18 @@ static int __init setup_slub_debug(char *str) /* * For backwards compatibility, a single list of flags with list of - * slabs means debugging is only enabled for those slabs, so the global - * slub_debug should be 0. We can extended that to multiple lists as + * slabs means debugging is only changed for those slabs, so the global + * slub_debug should be unchanged (0 or DEBUG_DEFAULT_FLAGS, depending + * on CONFIG_SLUB_DEBUG_ON). We can extended that to multiple lists as * long as there is no option specifying flags without a slab list. */ if (slab_list_specified) { if (!global_slub_debug_changed) - slub_debug = 0; + global_flags = slub_debug; slub_debug_string = saved_str; } out: + slub_debug = global_flags; if (slub_debug != 0 || slub_debug_string) static_branch_enable(&slub_debug_enabled); if ((static_branch_unlikely(&init_on_alloc) ||