6.6.2-rc1 review
Subsystems (7)
Greg Kroah-Hartman
maintainerPATCH 117/603 virtio-net: fix mismatch of getting tx-frames
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Heng Qi <[email protected]>
[ Upstream commit 134674c1877be5e35e35802517c67a9ecce21153 ]
Since virtio-net allows switching napi_tx for per txq, we have to get the specific txq's result now.
--- drivers/net/virtio_net.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/net/virtio_net.c +1 -1
@@ -3453,7 +3453,7 @@ static int virtnet_get_per_queue_coalesce(struct net_device *dev, }else { ec->rx_max_coalesced_frames =1 ; -if (vi->sq[0 ].napi.weight) +if (vi->sq[queue].napi.weight) ec->tx_max_coalesced_frames =1 ; }
Signature · 1 line
2.42.0
Greg Kroah-Hartman
maintainerPATCH 118/603 virtio-net: consistently save parameters for per-queue
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Heng Qi <[email protected]>
[ Upstream commit e9420838ab4ffb82850095549e94dcee3f7fe0cb ]
When using .set_coalesce interface to set all queue coalescing parameters, we need to update both per-queue and global save values.
--- drivers/net/virtio_net.c | 9 +++++++++ 1 file changed, 9 insertions(+)
drivers/net/virtio_net.c +9 -0
@@ -3233,6 +3233,7 @@ static int virtnet_send_notf_coal_cmds(struct virtnet_info *vi, struct ethtool_coalesce *ec) {struct scatterlist sgs_tx, sgs_rx; +int i; vi->ctrl->coal_tx.tx_usecs =cpu_to_le32 (ec->tx_coalesce_usecs); vi->ctrl->coal_tx.tx_max_packets =cpu_to_le32 (ec->tx_max_coalesced_frames);
@@ -3246,6 +3247,10 @@ static int virtnet_send_notf_coal_cmds(struct virtnet_info *vi,/* Save parameters */ vi->intr_coal_tx.max_usecs = ec->tx_coalesce_usecs; vi->intr_coal_tx.max_packets = ec->tx_max_coalesced_frames; +for (i =0 ; i < vi->max_queue_pairs; i++) { + vi->sq[i].intr_coal.max_usecs = ec->tx_coalesce_usecs; + vi->sq[i].intr_coal.max_packets = ec->tx_max_coalesced_frames; + } vi->ctrl->coal_rx.rx_usecs =cpu_to_le32 (ec->rx_coalesce_usecs); vi->ctrl->coal_rx.rx_max_packets =cpu_to_le32 (ec->rx_max_coalesced_frames);
@@ -3259,6 +3264,10 @@ static int virtnet_send_notf_coal_cmds(struct virtnet_info *vi,/* Save parameters */ vi->intr_coal_rx.max_usecs = ec->rx_coalesce_usecs; vi->intr_coal_rx.max_packets = ec->rx_max_coalesced_frames; +for (i =0 ; i < vi->max_queue_pairs; i++) { + vi->rq[i].intr_coal.max_usecs = ec->rx_coalesce_usecs; + vi->rq[i].intr_coal.max_packets = ec->rx_max_coalesced_frames; + }return 0 ; }
Signature · 1 line
2.42.0
Greg Kroah-Hartman
maintainerPATCH 119/603 virtio-net: fix per queue coalescing parameter setting
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Heng Qi <[email protected]>
[ Upstream commit bfb2b3609162135625bf96acf5118051cd0d082e ]
When the user sets a non-zero coalescing parameter to 0 for a specific virtqueue, it does not work as expected, so let's fix this.
--- drivers/net/virtio_net.c | 36 ++++++++++++++++-------------------- 1 file changed, 16 insertions(+), 20 deletions(-)
drivers/net/virtio_net.c +16 -20
@@ -3296,27 +3296,23 @@ static int virtnet_send_notf_coal_vq_cmds(struct virtnet_info *vi, {int err; -if (ec->rx_coalesce_usecs || ec->rx_max_coalesced_frames) { - err =virtnet_send_ctrl_coal_vq_cmd (vi,rxq2vq (queue), - ec->rx_coalesce_usecs, - ec->rx_max_coalesced_frames); -if (err) -return err; -/* Save parameters */ - vi->rq[queue].intr_coal.max_usecs = ec->rx_coalesce_usecs; - vi->rq[queue].intr_coal.max_packets = ec->rx_max_coalesced_frames; - } + err =virtnet_send_ctrl_coal_vq_cmd (vi,rxq2vq (queue), + ec->rx_coalesce_usecs, + ec->rx_max_coalesced_frames); +if (err) +return err; -if (ec->tx_coalesce_usecs || ec->tx_max_coalesced_frames) { - err =virtnet_send_ctrl_coal_vq_cmd (vi,txq2vq (queue), - ec->tx_coalesce_usecs, - ec->tx_max_coalesced_frames); -if (err) -return err; -/* Save parameters */ - vi->sq[queue].intr_coal.max_usecs = ec->tx_coalesce_usecs; - vi->sq[queue].intr_coal.max_packets = ec->tx_max_coalesced_frames; - } + vi->rq[queue].intr_coal.max_usecs = ec->rx_coalesce_usecs; + vi->rq[queue].intr_coal.max_packets = ec->rx_max_coalesced_frames; + + err =virtnet_send_ctrl_coal_vq_cmd (vi,txq2vq (queue), + ec->tx_coalesce_usecs, + ec->tx_max_coalesced_frames); +if (err) +return err; + + vi->sq[queue].intr_coal.max_usecs = ec->tx_coalesce_usecs; + vi->sq[queue].intr_coal.max_packets = ec->tx_max_coalesced_frames;return 0 ; }
Signature · 1 line
2.42.0
Greg Kroah-Hartman
maintainerPATCH 120/603 virtio-net: fix the vq coalescing setting for vq resize
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Heng Qi <[email protected]>
[ Upstream commit f61fe5f081cf40de08d0a4c89659baf23c900f0c ]
According to the definition of virtqueue coalescing spec[1]:
Upon disabling and re-enabling a transmit virtqueue, the device MUST set the coalescing parameters of the virtqueue to those configured through the VIRTIO_NET_CTRL_NOTF_COAL_TX_SET command, or, if the driver did not set any TX coalescing parameters, to 0.
Upon disabling and re-enabling a receive virtqueue, the device MUST set the coalescing parameters of the virtqueue to those configured through the VIRTIO_NET_CTRL_NOTF_COAL_RX_SET command, or, if the driver did not set any RX coalescing parameters, to 0.
We need to add this setting for vq resize (ethtool -G) where vq_reset happens.
[1] https://lists.oasis-open.org/archives/virtio-dev/202303/msg00415.html
--- drivers/net/virtio_net.c | 27 +++++++++++++++++++++++++++ 1 file changed, 27 insertions(+)
drivers/net/virtio_net.c +27 -0
@@ -2855,6 +2855,9 @@ static void virtnet_get_ringparam(struct net_device *dev, ring->tx_pending =virtqueue_get_vring_size (vi->sq[0 ].vq); } +static int virtnet_send_ctrl_coal_vq_cmd (struct virtnet_info *vi, +u16 vqn,u32 max_usecs,u32 max_packets); + static int virtnet_set_ringparam(struct net_device *dev, struct ethtool_ringparam *ring, struct kernel_ethtool_ringparam *kernel_ring,
@@ -2890,12 +2893,36 @@ static int virtnet_set_ringparam(struct net_device *dev, err =virtnet_tx_resize (vi, sq, ring->tx_pending);if (err)return err; + +/* Upon disabling and re-enabling a transmit virtqueue, the device must +* set the coalescing parameters of the virtqueue to those configured +* through the VIRTIO_NET_CTRL_NOTF_COAL_TX_SET command, or, if the driver +* did not set any TX coalescing parameters, to 0. +*/ + err =virtnet_send_ctrl_coal_vq_cmd (vi,txq2vq (i), + vi->intr_coal_tx.max_usecs, + vi->intr_coal_tx.max_packets); +if (err) +return err; + + vi->sq[i].intr_coal.max_usecs = vi->intr_coal_tx.max_usecs; + vi->sq[i].intr_coal.max_packets = vi->intr_coal_tx.max_packets; }if (ring->rx_pending != rx_pending) { err =virtnet_rx_resize (vi, rq, ring->rx_pending);if (err)return err; + +/* The reason is same as the transmit virtqueue reset */ + err =virtnet_send_ctrl_coal_vq_cmd (vi,rxq2vq (i), + vi->intr_coal_rx.max_usecs, + vi->intr_coal_rx.max_packets); +if (err) +return err; + + vi->rq[i].intr_coal.max_usecs = vi->intr_coal_rx.max_usecs; + vi->rq[i].intr_coal.max_packets = vi->intr_coal_rx.max_packets; } }
Signature · 1 line
2.42.0
Greg Kroah-Hartman
maintainerPATCH 121/603 wifi: rtw88: Remove duplicate NULL check before calling usb_kill/free_urb()
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Jinjie Ruan <[email protected]>
[ Upstream commit de8dd096949820ce5656d41ce409a67603e79327 ]
Both usb_kill_urb() and usb_free_urb() do the NULL check itself, so there is no need to duplicate it prior to calling.
--- drivers/net/wireless/realtek/rtw88/usb.c | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-)
drivers/net/wireless/realtek/rtw88/usb.c +3 -6
@@ -611,8 +611,7 @@ static void rtw_usb_cancel_rx_bufs(struct rtw_usb *rtwusb)for (i =0 ; i <RTW_USB_RXCB_NUM ; i++) { rxcb = &rtwusb->rx_cb[i]; -if (rxcb->rx_urb) -usb_kill_urb (rxcb->rx_urb); +usb_kill_urb (rxcb->rx_urb); } }
@@ -623,10 +622,8 @@ static void rtw_usb_free_rx_bufs(struct rtw_usb *rtwusb)for (i =0 ; i <RTW_USB_RXCB_NUM ; i++) { rxcb = &rtwusb->rx_cb[i]; -if (rxcb->rx_urb) { -usb_kill_urb (rxcb->rx_urb); -usb_free_urb (rxcb->rx_urb); - } +usb_kill_urb (rxcb->rx_urb); +usb_free_urb (rxcb->rx_urb); } }
Signature · 1 line
2.42.0
Greg Kroah-Hartman
maintainerPATCH 122/603 thermal: core: prevent potential string overflow
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Dan Carpenter <[email protected]>
[ Upstream commit c99626092efca3061b387043d4a7399bf75fbdd5 ]
The dev->id value comes from ida_alloc() so it's a number between zero and INT_MAX. If it's too high then these sprintf()s will overflow.
--- drivers/thermal/thermal_core.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-)
drivers/thermal/thermal_core.c +4 -2
@@ -689,7 +689,8 @@ int thermal_zone_bind_cooling_device(struct thermal_zone_device *tz,if (result) goto release_ida; -sprintf (dev->attr_name,"cdev%d_trip_point" , dev->id); +snprintf (dev->attr_name,sizeof (dev->attr_name),"cdev%d_trip_point" , + dev->id);sysfs_attr_init (&dev->attr.attr); dev->attr.attr.name = dev->attr_name; dev->attr.attr.mode =0444 ;
@@ -698,7 +699,8 @@ int thermal_zone_bind_cooling_device(struct thermal_zone_device *tz,if (result) goto remove_symbol_link; -sprintf (dev->weight_attr_name,"cdev%d_weight" , dev->id); +snprintf (dev->weight_attr_name,sizeof (dev->weight_attr_name), +"cdev%d_weight" , dev->id);sysfs_attr_init (&dev->weight_attr.attr); dev->weight_attr.attr.name = dev->weight_attr_name; dev->weight_attr.attr.mode =S_IWUSR |S_IRUGO ;
Signature · 1 line
2.42.0
Greg Kroah-Hartman
maintainerPATCH 123/603 r8169: fix rare issue with broken rx after link-down on RTL8125
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Heiner Kallweit <[email protected]>
[ Upstream commit 621735f590643e3048ca2060c285b80551660601 ]
In very rare cases (I've seen two reports so far about different RTL8125 chip versions) it seems the MAC locks up when link goes down and requires a software reset to get revived.
Realtek doesn't publish hw errata information, therefore the root cause is unknown. Realtek vendor drivers do a full hw re-initialization on each link-up event, the slimmed-down variant here was reported to fix the issue for the reporting user.
It's not fully clear which parts of the NIC are reset as part of the software reset, therefore I can't rule out side effects.
--- drivers/net/ethernet/realtek/r8169_main.c | 4 ++++ 1 file changed, 4 insertions(+)
drivers/net/ethernet/realtek/r8169_main.c +4 -0
@@ -4596,7 +4596,11 @@ static void r8169_phylink_handler(struct net_device *ndev)if (netif_carrier_ok (ndev)) {rtl_link_chg_patch (tp);pm_request_resume (d); +netif_wake_queue (tp->dev); }else { +/* In few cases rx is broken after link-down otherwise */ +if (rtl_is_8125 (tp)) +rtl_reset_work (tp);pm_runtime_idle (d); }
Signature · 1 line
2.42.0
Greg Kroah-Hartman
maintainerPATCH 124/603 thermal/drivers/mediatek: Fix probe for THERMAL_V2
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Markus Schneider-Pargmann <[email protected]>
[ Upstream commit 5055fadfa7e16f2427d5b3c40b2bf563ddfdab22 ]
Fix the probe function to call mtk_thermal_release_periodic_ts for everything != MTK_THERMAL_V1. This was accidentally changed from V1 to V2 in the original patch.
--- drivers/thermal/mediatek/auxadc_thermal.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/thermal/mediatek/auxadc_thermal.c +1 -1
@@ -1267,7 +1267,7 @@ static int mtk_thermal_probe(struct platform_device *pdev)mtk_thermal_turn_on_buffer (mt, apmixed_base); -if (mt->conf->version !=MTK_THERMAL_V2 ) +if (mt->conf->version !=MTK_THERMAL_V1 )mtk_thermal_release_periodic_ts (mt, auxadc_base);if (mt->conf->version ==MTK_THERMAL_V1 )
Signature · 1 line
2.42.0
Greg Kroah-Hartman
maintainerPATCH 125/603 bpf: Fix missed rcu read lock in bpf_task_under_cgroup()
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Yafang Shao <[email protected]>
[ Upstream commit 29a7e00ffadddd8d68eff311de1bf12ae10687bb ]
When employed within a sleepable program not under RCU protection, the use of 'bpf_task_under_cgroup()' may trigger a warning in the kernel log, particularly when CONFIG_PROVE_RCU is enabled:
[ 1259.662357] WARNING: suspicious RCU usage [ 1259.662358] 6.5.0+ #33 Not tainted [ 1259.662360] ----------------------------- [ 1259.662361] include/linux/cgroup.h:423 suspicious rcu_dereference_check() usage!
Other info that might help to debug this:
[ 1259.662366] rcu_scheduler_active = 2, debug_locks = 1
[ 1259.662368] 1 lock held by trace/72954:
[ 1259.662369] #0: ffffffffb5e3eda0 (rcu_read_lock_trace){....}-{0:0}, at: __bpf_prog_enter_sleepable+0x0/0xb0Stack backtrace:
[ 1259.662385] CPU: 50 PID: 72954 Comm: trace Kdump: loaded Not tainted 6.5.0+ #33 [ 1259.662391] Call Trace: [ 1259.662393] <TASK> [ 1259.662395] dump_stack_lvl+0x6e/0x90 [ 1259.662401] dump_stack+0x10/0x20 [ 1259.662404] lockdep_rcu_suspicious+0x163/0x1b0 [ 1259.662412] task_css_set.part.0+0x23/0x30 [ 1259.662417] bpf_task_under_cgroup+0xe7/0xf0 [ 1259.662422] bpf_prog_7fffba481a3bcf88_lsm_run+0x5c/0x93 [ 1259.662431] bpf_trampoline_6442505574+0x60/0x1000 [ 1259.662439] bpf_lsm_bpf+0x5/0x20 [ 1259.662443] ? security_bpf+0x32/0x50 [ 1259.662452] __sys_bpf+0xe6/0xdd0 [ 1259.662463] __x64_sys_bpf+0x1a/0x30 [ 1259.662467] do_syscall_64+0x38/0x90 [ 1259.662472] entry_SYSCALL_64_after_hwframe+0x6e/0xd8 [ 1259.662479] RIP: 0033:0x7f487baf8e29 [...] [ 1259.662504] </TASK>
This issue can be reproduced by executing a straightforward program, as demonstrated below:
SEC("lsm.s/bpf")
int BPF_PROG(lsm_run, int cmd, union bpf_attr *attr, unsigned int size)
{
struct cgroup *cgrp = NULL;
struct task_struct *task;
int ret = 0;
if (cmd != BPF_LINK_CREATE)
return 0;
// The cgroup2 should be mounted first
cgrp = bpf_cgroup_from_id(1);
if (!cgrp)
goto out;
task = bpf_get_current_task_btf();
if (bpf_task_under_cgroup(task, cgrp))
ret = -1;
bpf_cgroup_release(cgrp);out:
return ret; }
After running the program, if you subsequently execute another BPF program, you will encounter the warning.
It's worth noting that task_under_cgroup_hierarchy() is also utilized by bpf_current_task_under_cgroup(). However, bpf_current_task_under_cgroup() doesn't exhibit this issue because it cannot be used in sleepable BPF programs.
--- kernel/bpf/helpers.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-)
kernel/bpf/helpers.c +6 -1
@@ -2197,7 +2197,12 @@ __bpf_kfunc struct cgroup *bpf_cgroup_from_id(u64 cgid)__bpf_kfunc long bpf_task_under_cgroup (struct task_struct *task,struct cgroup *ancestor) { -return task_under_cgroup_hierarchy (task, ancestor); +long ret; + +rcu_read_lock (); + ret =task_under_cgroup_hierarchy (task, ancestor); +rcu_read_unlock (); +return ret; }#endif /* CONFIG_CGROUPS */
Signature · 1 line
2.42.0
Greg Kroah-Hartman
maintainerPATCH 126/603 net: skb_find_text: Ignore patterns extending past to
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Phil Sutter <[email protected]>
[ Upstream commit c4eee56e14fe001e1cff54f0b438a5e2d0dd7454 ]
Assume that caller's 'to' offset really represents an upper boundary for the pattern search, so patterns extending past this offset are to be rejected.
The old behaviour also was kind of inconsistent when it comes to fragmentation (or otherwise non-linear skbs): If the pattern started in between 'to' and 'from' offsets but extended to the next fragment, it was not found if 'to' offset was still within the current fragment.
Test the new behaviour in a kselftest using iptables' string match.
--- net/core/skbuff.c | 3 +- tools/testing/selftests/netfilter/Makefile | 2 +- .../testing/selftests/netfilter/xt_string.sh | 128 ++++++++++++++++++ 3 files changed, 131 insertions(+), 2 deletions(-) create mode 100755 tools/testing/selftests/netfilter/xt_string.sh
net/core/skbuff.c +2 -1
@@ -4254,6 +4254,7 @@ static void skb_ts_finish(struct ts_config *conf, struct ts_state *state)unsigned int skb_find_text (struct sk_buff *skb,unsigned int from,unsigned int to,struct ts_config *config) { +unsigned int patlen = config->ops->get_pattern_len (config);struct ts_state state;unsigned int ret;
@@ -4265,7 +4266,7 @@ unsigned int skb_find_text(struct sk_buff *skb, unsigned int from,skb_prepare_seq_read (skb, from, to,TS_SKB_CB (&state)); ret =textsearch_find (config, &state); -return (ret <= to - from ? ret :UINT_MAX ); +return (ret + patlen <= to - from ? ret :UINT_MAX ); }EXPORT_SYMBOL (skb_find_text);
tools/testing/selftests/netfilter/Makefile +1 -1
@@ -7,7 +7,7 @@ TEST_PROGS := nft_trans_stress.sh nft_fib.sh nft_nat.sh bridge_brouter.sh \ nft_queue.sh nft_meta.sh nf_nat_edemux.sh \ ipip-conntrack-mtu.sh conntrack_tcp_unreplied.sh \ conntrack_vrf.sh nft_synproxy.sh rpath.sh nft_audit.sh \ - conntrack_sctp_collision.sh + conntrack_sctp_collision.sh xt_string.sh HOSTPKG_CONFIG := pkg-config
tools/testing/selftests/netfilter/xt_string.sh new file +128 -0
128 lines not on this page · raw message
Signature · 1 line
2.42.0
Greg Kroah-Hartman
maintainerPATCH 127/603 selftests/bpf: Make linked_list failure test more robust
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Kumar Kartikeya Dwivedi <[email protected]>
[ Upstream commit da1055b673f3baac2249571c9882ce767a0aa746 ]
The linked list failure test 'pop_front_off' and 'pop_back_off' currently rely on matching exact instruction and register values. The purpose of the test is to ensure the offset is correctly incremented for the returned pointers from list pop helpers, which can then be used with container_of to obtain the real object. Hence, somehow obtaining the information that the offset is 48 will work for us. Make the test more robust by relying on verifier error string of bpf_spin_lock and remove dependence on fragile instruction index or register number, which can be affected by different clang versions used to build the selftests.
--- tools/testing/selftests/bpf/prog_tests/linked_list.c | 10 ++-------- tools/testing/selftests/bpf/progs/linked_list_fail.c | 4 +++- 2 files changed, 5 insertions(+), 9 deletions(-)
tools/testing/selftests/bpf/prog_tests/linked_list.c +2 -8
@@ -94,14 +94,8 @@ static struct { { "incorrect_head_var_off2", "variable ptr_ access var_off=(0x0; 0xffffffff) disallowed" }, { "incorrect_head_off1", "bpf_list_head not found at offset=25" }, { "incorrect_head_off2", "bpf_list_head not found at offset=1" }, - { "pop_front_off", -"15: (bf) r1 = r6 ; R1_w=ptr_or_null_foo(id=4,ref_obj_id=4,off=48,imm=0) " -"R6_w=ptr_or_null_foo(id=4,ref_obj_id=4,off=48,imm=0) refs=2,4\n" - "16: (85) call bpf_this_cpu_ptr#154\nR1 type=ptr_or_null_ expected=percpu_ptr_" }, - { "pop_back_off", -"15: (bf) r1 = r6 ; R1_w=ptr_or_null_foo(id=4,ref_obj_id=4,off=48,imm=0) " -"R6_w=ptr_or_null_foo(id=4,ref_obj_id=4,off=48,imm=0) refs=2,4\n" - "16: (85) call bpf_this_cpu_ptr#154\nR1 type=ptr_or_null_ expected=percpu_ptr_" }, + { "pop_front_off", "off 48 doesn't point to 'struct bpf_spin_lock' that is at 40" }, + { "pop_back_off", "off 48 doesn't point to 'struct bpf_spin_lock' that is at 40" }, };static void test_linked_list_fail_prog (const char *prog_name,const char *err_msg)
tools/testing/selftests/bpf/progs/linked_list_fail.c +3 -1
@@ -591,7 +591,9 @@ int pop_ptr_off(void *(*op)(void *head)) n =op (&p->head);bpf_spin_unlock (&p->lock); -bpf_this_cpu_ptr (n); +if (!n) +return 0 ; +bpf_spin_lock ((void *)n);return 0 ; }
Signature · 1 line
2.42.0
Greg Kroah-Hartman
maintainerPATCH 128/603 thermal: core: Dont update trip points inside the hysteresis range
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Nícolas F. R. A. Prado <[email protected]>
[ Upstream commit cf3986f8c01d355490d0ac6024391b989a9d1e9d ]
When searching for the trip points that need to be set, the nearest higher trip point's temperature is used for the high trip, while the nearest lower trip point's temperature minus the hysteresis is used for the low trip. The issue with this logic is that when the current temperature is inside a trip point's hysteresis range, both high and low trips will come from the same trip point. As a consequence instability can still occur like this:
* the temperature rises slightly and enters the hysteresis range of a trip point
* polling happens and updates the trip points to the hysteresis range
* the temperature falls slightly, exiting the hysteresis range, crossing the trip point and triggering an IRQ, the trip points are updated
* repeat
So even though the current hysteresis implementation prevents instability from happening due to IRQs triggering on the same temperature value, both ways, it doesn't prevent it from happening due to an IRQ on one way and polling on the other.
To properly implement a hysteresis behavior, when inside the hysteresis range, don't update the trip points. This way, the previously set trip points will stay in effect, which will in a way remember the previous state (if the temperature signal came from above or below the range) and therefore have the right trip point already set.
The exception is if there was no previous trip point set, in which case a previous state doesn't exist, and so it's sensible to allow the hysteresis range as trip points.
The following logs show the current behavior when running on a real machine:
[ 202.524658] thermal thermal_zone0: new temperature boundaries: -2147483647 < x < 40000 203.562817: thermal_temperature: thermal_zone=vpu0-thermal id=0 temp_prev=36986 temp=37979 [ 203.562845] thermal thermal_zone0: new temperature boundaries: 37000 < x < 40000 204.176059: thermal_temperature: thermal_zone=vpu0-thermal id=0 temp_prev=37979 temp=40028 [ 204.176089] thermal thermal_zone0: new temperature boundaries: 37000 < x < 100000 205.226813: thermal_temperature: thermal_zone=vpu0-thermal id=0 temp_prev=40028 temp=38652 [ 205.226842] thermal thermal_zone0: new temperature boundaries: 37000 < x < 40000
And with this patch applied:
[ 184.933415] thermal thermal_zone0: new temperature boundaries: -2147483647 < x < 40000 185.981182: thermal_temperature: thermal_zone=vpu0-thermal id=0 temp_prev=36986 temp=37872 186.744685: thermal_temperature: thermal_zone=vpu0-thermal id=0 temp_prev=37872 temp=40058 [ 186.744716] thermal thermal_zone0: new temperature boundaries: 37000 < x < 100000 187.773284: thermal_temperature: thermal_zone=vpu0-thermal id=0 temp_prev=40058 temp=38698
--- drivers/thermal/thermal_trip.c | 19 +++++++++++++++++-- 1 file changed, 17 insertions(+), 2 deletions(-)
drivers/thermal/thermal_trip.c +17 -2
@@ -55,6 +55,7 @@ void __thermal_zone_set_trips(struct thermal_zone_device *tz) {struct thermal_trip trip;int low = -INT_MAX , high =INT_MAX ; +bool same_trip = false;int i, ret;lockdep_assert_held (&tz->lock);
@@ -63,6 +64,7 @@ void __thermal_zone_set_trips(struct thermal_zone_device *tz)return ;for (i =0 ; i < tz->num_trips; i++) { +bool low_set = false;int trip_low; ret =__thermal_zone_get_trip (tz, i , &trip);
@@ -71,18 +73,31 @@ void __thermal_zone_set_trips(struct thermal_zone_device *tz) trip_low = trip.temperature - trip.hysteresis; -if (trip_low < tz->temperature && trip_low > low) +if (trip_low < tz->temperature && trip_low > low) { low = trip_low; + low_set = true; + same_trip = false; + }if (trip.temperature > tz->temperature && - trip.temperature < high) + trip.temperature < high) { high = trip.temperature; + same_trip = low_set; + } }/* No need to change trip points */ if (tz->prev_low_trip == low && tz->prev_high_trip == high)return ; +/* +* If "high" and "low" are the same, skip the change unless this is the +* first time. +*/ +if (same_trip && (tz->prev_low_trip != -INT_MAX || + tz->prev_high_trip !=INT_MAX )) +return ; + tz->prev_low_trip = low; tz->prev_high_trip = high;
Signature · 1 line
2.42.0
Greg Kroah-Hartman
maintainerPATCH 129/603 chtls: fix tp->rcv_tstamp initialization
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Eric Dumazet <[email protected]>
[ Upstream commit 225d9ddbacb102621af6d28ff7bf5a0b4ce249d8 ]
tp->rcv_tstamp should be set to tcp_jiffies, not tcp_time_stamp().
--- drivers/net/ethernet/chelsio/inline_crypto/chtls/chtls_cm.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/net/ethernet/chelsio/inline_crypto/chtls/chtls_cm.c +1 -1
@@ -2259,7 +2259,7 @@ static void chtls_rx_ack(struct sock *sk, struct sk_buff *skb)if (tp->snd_una != snd_una) { tp->snd_una = snd_una; - tp->rcv_tstamp =tcp_time_stamp (tp); + tp->rcv_tstamp = tcp_jiffies32;if (tp->snd_una == tp->snd_nxt && !csk_flag_nochk (csk,CSK_TX_FAILOVER ))csk_reset_flag (csk,CSK_TX_WAIT_IDLE );
Signature · 1 line
2.42.0
Greg Kroah-Hartman
maintainerPATCH 130/603 tcp: fix cookie_init_timestamp() overflows
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Eric Dumazet <[email protected]>
[ Upstream commit 73ed8e03388d16c12fc577e5c700b58a29045a15 ]
cookie_init_timestamp() is supposed to return a 64bit timestamp suitable for both TSval determination and setting of skb->tstamp.
Unfortunately it uses 32bit fields and overflows after 2^32 * 10^6 nsec (~49 days) of uptime.
Generated TSval are still correct, but skb->tstamp might be set far away in the past, potentially confusing other layers.
tcp_ns_to_ts() is changed to return a full 64bit value, ts and ts_now variables are changed to u64 type, and TSMASK is removed in favor of shifts operations.
While we are at it, change this sequence:
ts >>= TSBITS; ts--; ts <<= TSBITS; ts |= options; to: ts -= (1UL << TSBITS);
--- include/net/tcp.h | 2 +- net/ipv4/syncookies.c | 20 +++++++------------- 2 files changed, 8 insertions(+), 14 deletions(-)
include/net/tcp.h +1 -1
@@ -801,7 +801,7 @@ static inline u32 tcp_time_stamp(const struct tcp_sock *tp) }/* Convert a nsec timestamp into TCP TSval timestamp (ms based currently) */ -static inline u32 tcp_ns_to_ts (u64 ns) +static inline u64 tcp_ns_to_ts (u64 ns) {return div_u64 (ns,NSEC_PER_SEC /TCP_TS_HZ ); }
net/ipv4/syncookies.c +7 -13
@@ -41,7 +41,6 @@ static siphash_aligned_key_t syncookie_secret[2];* requested/supported by the syn/synack exchange. */ #define TSBITS 6 -#define TSMASK (((__u32)1 << TSBITS) - 1)static u32 cookie_hash (__be32 saddr,__be32 daddr,__be16 sport,__be16 dport,u32 count,int c)
@@ -62,27 +61,22 @@ static u32 cookie_hash(__be32 saddr, __be32 daddr, __be16 sport, __be16 dport,*/ u64 cookie_init_timestamp (struct request_sock *req,u64 now) { -struct inet_request_sock *ireq; -u32 ts, ts_now =tcp_ns_to_ts (now); +const struct inet_request_sock *ireq =inet_rsk (req); +u64 ts, ts_now =tcp_ns_to_ts (now);u32 options =0 ; - ireq =inet_rsk (req); - options = ireq->wscale_ok ? ireq->snd_wscale :TS_OPT_WSCALE_MASK ;if (ireq->sack_ok) options |=TS_OPT_SACK ;if (ireq->ecn_ok) options |=TS_OPT_ECN ; - ts = ts_now & ~TSMASK ; + ts = (ts_now >>TSBITS ) <<TSBITS ; ts |= options; -if (ts > ts_now) { - ts >>=TSBITS ; - ts--; - ts <<=TSBITS ; - ts |= options; - } -return (u64 )ts * (NSEC_PER_SEC /TCP_TS_HZ ); +if (ts > ts_now) + ts -= (1UL <<TSBITS ); + +return ts * (NSEC_PER_SEC /TCP_TS_HZ ); }
Signature · 1 line
2.42.0
Greg Kroah-Hartman
maintainerPATCH 131/603 wifi: iwlwifi: mvm: update stations MFP flag after association
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Avraham Stern <[email protected]>
[ Upstream commit 5a86dcb4a908845e6b7ff39b78fb1141b895408f ]
The management frames protection flag is always set when the station is not yet authorized. However, it was not cleared after association even if the association did not use MFP. As a result, all public action frames are not parsed by fw (which will cause FTM to fail, for example). Update the station MFP flag after the station is authorized.
--- drivers/net/wireless/intel/iwlwifi/mvm/mac80211.c | 6 ++++++ 1 file changed, 6 insertions(+)
drivers/net/wireless/intel/iwlwifi/mvm/mac80211.c +6 -0
@@ -3791,6 +3791,12 @@ iwl_mvm_sta_state_assoc_to_authorized(struct iwl_mvm *mvm,iwl_mvm_rs_rate_init_all_links (mvm, vif, sta); +/* MFP is set by default before the station is authorized. +* Clear it here in case it's not used. +*/ +if (!sta->mfp) +return callbacks->update_sta (mvm, vif, sta); +return 0 ; }
Signature · 1 line
2.42.0
Greg Kroah-Hartman
maintainerPATCH 132/603 wifi: iwlwifi: mvm: fix removing pasn station for responder
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Avraham Stern <[email protected]>
[ Upstream commit ff2687612c21a87a58c76099f3d59f8db376b995 ]
In case of MLD operation the station should be removed using the mld api.
--- drivers/net/wireless/intel/iwlwifi/mvm/ftm-responder.c | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-)
drivers/net/wireless/intel/iwlwifi/mvm/ftm-responder.c +7 -2
@@ -1,7 +1,7 @@// SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause /* * Copyright (C) 2015-2017 Intel Deutschland GmbH -* Copyright (C) 2018-2022 Intel Corporation +* Copyright (C) 2018-2023 Intel Corporation */ #include <net/cfg80211.h> #include <linux/etherdevice.h>
@@ -302,7 +302,12 @@ static void iwl_mvm_resp_del_pasn_sta(struct iwl_mvm *mvm, struct iwl_mvm_pasn_sta *sta) {list_del (&sta->list); -iwl_mvm_rm_sta_id (mvm, vif, sta->int_sta.sta_id); + +if (iwl_mvm_has_mld_api (mvm->fw)) +iwl_mvm_mld_rm_sta_id (mvm, sta->int_sta.sta_id); +else +iwl_mvm_rm_sta_id (mvm, vif, sta->int_sta.sta_id); +iwl_mvm_dealloc_int_sta (mvm, &sta->int_sta);kfree (sta); }
Signature · 1 line
2.42.0
Greg Kroah-Hartman
maintainerPATCH 133/603 wifi: iwlwifi: mvm: use correct sta ID for IGTK/BIGTK
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Johannes Berg <[email protected]>
[ Upstream commit 63ef576c9facf5d92702e249ad213fa73eb434bf ]
We don't (yet) send the IGTK down to the firmware, but when we do it needs to be with the broadcast station ID, not the multicast station ID. Same for the BIGTK, which we may send already if firmware advertises it (but it doesn't yet.)
--- drivers/net/wireless/intel/iwlwifi/mvm/mld-key.c | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-)
drivers/net/wireless/intel/iwlwifi/mvm/mld-key.c +7 -2
@@ -24,10 +24,15 @@ static u32 iwl_mvm_get_sec_sta_mask(struct iwl_mvm *mvm,return 0 ; } -/* AP group keys are per link and should be on the mcast STA */ +/* AP group keys are per link and should be on the mcast/bcast STA */ if (vif->type ==NL80211_IFTYPE_AP && - !(keyconf->flags &IEEE80211_KEY_FLAG_PAIRWISE )) + !(keyconf->flags &IEEE80211_KEY_FLAG_PAIRWISE )) { +/* IGTK/BIGTK to bcast STA */ +if (keyconf->keyidx >=4 ) +return BIT (link_info->bcast_sta.sta_id); +/* GTK for data to mcast STA */ return BIT (link_info->mcast_sta.sta_id); + }/* for client mode use the AP STA also for group keys */ if (!sta && vif->type ==NL80211_IFTYPE_STATION )
Signature · 1 line
2.42.0
Greg Kroah-Hartman
maintainerPATCH 134/603 wifi: mac80211: dont recreate driver link debugfs in reconfig
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Johannes Berg <[email protected]>
[ Upstream commit 822cab1987a0e028e38b60aecd98af0289b46e7b ]
We can delete any that we want to remove, but we can't recreate the links as they already exist.
--- net/mac80211/driver-ops.c | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-)
net/mac80211/driver-ops.c +6 -3
@@ -510,10 +510,13 @@ int drv_change_vif_links(struct ieee80211_local *local,if (ret)return ret; -for_each_set_bit (link_id, &links_to_add,IEEE80211_MLD_MAX_NUM_LINKS ) { - link =rcu_access_pointer (sdata->link[link_id]); +if (!local->in_reconfig) { +for_each_set_bit (link_id, &links_to_add, +IEEE80211_MLD_MAX_NUM_LINKS ) { + link =rcu_access_pointer (sdata->link[link_id]); -ieee80211_link_debugfs_drv_add (link); +ieee80211_link_debugfs_drv_add (link); + } }return 0 ;
Signature · 1 line
2.42.0
Greg Kroah-Hartman
maintainerPATCH 135/603 wifi: mac80211: Fix setting vif links
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Ilan Peer <[email protected]>
[ Upstream commit e7182c4e6bbeafa272612e6c06fa92b42ad107ad ]
When setting the interface links, ignore the change iff both the valid links and the dormant links did not change. This is needed to support cases where the valid links didn't change but the dormant links did.
--- net/mac80211/link.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
net/mac80211/link.c +1 -1
@@ -195,7 +195,7 @@ static int ieee80211_vif_update_links(struct ieee80211_sub_if_data *sdata,memset (to_free,0 ,sizeof (links)); -if (old_links == new_links) +if (old_links == new_links && dormant_links == sdata->vif.dormant_links)return 0 ;/* if there were no old links, need to clear the pointers to deflink */
Signature · 1 line
2.42.0
Greg Kroah-Hartman
maintainerPATCH 136/603 wifi: iwlwifi: yoyo: swap cdb and jacket bits values
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Rotem Saado <[email protected]>
[ Upstream commit 65008777b9dcd2002414ddb2c2158293a6e2fd6f ]
The bits are wrong, the jacket bit should be 5 and cdb bit 4. Fix it.
--- drivers/net/wireless/intel/iwlwifi/iwl-prph.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
drivers/net/wireless/intel/iwlwifi/iwl-prph.h +2 -2
@@ -348,8 +348,8 @@#define RFIC_REG_RD 0xAD0470#define WFPM_CTRL_REG 0xA03030#define WFPM_OTP_CFG1_ADDR 0x00a03098 -#define WFPM_OTP_CFG1_IS_JACKET_BIT BIT(4) -#define WFPM_OTP_CFG1_IS_CDB_BIT BIT(5) +#define WFPM_OTP_CFG1_IS_JACKET_BIT BIT(5) +#define WFPM_OTP_CFG1_IS_CDB_BIT BIT(4)#define WFPM_OTP_BZ_BNJ_JACKET_BIT 5#define WFPM_OTP_BZ_BNJ_CDB_BIT 4#define WFPM_OTP_CFG1_IS_JACKET (_val) (((_val) & 0x00000020) >> WFPM_OTP_BZ_BNJ_JACKET_BIT)
Signature · 1 line
2.42.0
Greg Kroah-Hartman
maintainerPATCH 137/603 wifi: iwlwifi: mvm: Correctly set link configuration
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Ilan Peer <[email protected]>
[ Upstream commit 35b9281fb710ea9fa47dca56774f4a9606fe9154 ]
In case the link puncturing is changed such that the channel is no longer punctured, configure the FW correctly indicating the EHT parameters changed (with a 0 punctured map).
Allow EHT parameters configuration only when the link really supports EHT.
--- drivers/net/wireless/intel/iwlwifi/mvm/link.c | 13 ++++++++----- .../net/wireless/intel/iwlwifi/mvm/mld-mac80211.c | 2 +- 2 files changed, 9 insertions(+), 6 deletions(-)
drivers/net/wireless/intel/iwlwifi/mvm/link.c +8 -5
@@ -194,11 +194,14 @@ int iwl_mvm_link_changed(struct iwl_mvm *mvm, struct ieee80211_vif *vif, flags_mask |=LINK_FLG_MU_EDCA_CW ; } -if (link_conf->eht_puncturing && !iwlwifi_mod_params.disable_11be) - cmd.puncture_mask =cpu_to_le16 (link_conf->eht_puncturing); -else -/* This flag can be set only if the MAC has eht support */ - changes &= ~LINK_CONTEXT_MODIFY_EHT_PARAMS ; +if (changes &LINK_CONTEXT_MODIFY_EHT_PARAMS ) { +if (iwlwifi_mod_params.disable_11be || + !link_conf->eht_support) + changes &= ~LINK_CONTEXT_MODIFY_EHT_PARAMS ; +else + cmd.puncture_mask = +cpu_to_le16 (link_conf->eht_puncturing); + } cmd.bss_color = link_conf->he_bss_color.color;
drivers/net/wireless/intel/iwlwifi/mvm/mld-mac80211.c +1 -1
@@ -653,7 +653,7 @@ iwl_mvm_mld_link_info_changed_station(struct iwl_mvm *mvm, }/* Update EHT Puncturing info */ -if (changes &BSS_CHANGED_EHT_PUNCTURING && vif->cfg.assoc && has_eht) +if (changes &BSS_CHANGED_EHT_PUNCTURING && vif->cfg.assoc) link_changes |=LINK_CONTEXT_MODIFY_EHT_PARAMS ;if (link_changes) {
Signature · 1 line
2.42.0
Greg Kroah-Hartman
maintainerPATCH 138/603 wifi: iwlwifi: mvm: Fix key flags for IGTK on AP interface
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Ilan Peer <[email protected]>
[ Upstream commit 8f9a791a8edd87fa64b35037d9c3bce89a1b8d21 ]
When an IGTK is installed for an AP interface, there is no station associated with it. However, the MFP flag must be set for the installed key as otherwise the FW wouldn't use it.
Fix the security key flag to set the MFP flag also when the AP is an AP interface and the key index matches that of an IGTK.
--- drivers/net/wireless/intel/iwlwifi/mvm/mld-key.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-)
drivers/net/wireless/intel/iwlwifi/mvm/mld-key.c +6 -1
@@ -96,7 +96,12 @@ u32 iwl_mvm_get_sec_flags(struct iwl_mvm *mvm,if (!sta && vif->type ==NL80211_IFTYPE_STATION ) sta = mvmvif->ap_sta; -if (!IS_ERR_OR_NULL (sta) && sta->mfp) +/* Set the MFP flag also for an AP interface where the key is an IGTK +* key as in such a case the station would always be NULL +*/ +if ((!IS_ERR_OR_NULL (sta) && sta->mfp) || + (vif->type ==NL80211_IFTYPE_AP && + (keyconf->keyidx ==4 || keyconf->keyidx ==5 ))) flags |=IWL_SEC_KEY_FLAG_MFP ;return flags;
Signature · 1 line
2.42.0
Greg Kroah-Hartman
maintainerPATCH 139/603 wifi: iwlwifi: mvm: Dont always bind/link the P2P Device interface
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Ilan Peer <[email protected]>
[ Upstream commit 84ef7cbe90e9e54c71c1da4e645ba34e1b33da77 ]
It is not necessary to keep the P2P Device bound/linked to a PHY context when there is no active ROC.
Modify the P2P Device flows so the binding/linking would be done only while ROC is active. With this change the switch_phy_ctxt() is no longer needed so remove it.
Stable-dep-of: 43874283ce6c ("wifi: iwlwifi: mvm: fix iwl_mvm_mac_flush_sta()")
--- drivers/net/wireless/intel/iwlwifi/mvm/link.c | 9 +- .../net/wireless/intel/iwlwifi/mvm/mac-ctxt.c | 8 +- .../net/wireless/intel/iwlwifi/mvm/mac80211.c | 152 ++++++------------ .../wireless/intel/iwlwifi/mvm/mld-mac80211.c | 100 ++++-------- drivers/net/wireless/intel/iwlwifi/mvm/mvm.h | 7 +- .../wireless/intel/iwlwifi/mvm/time-event.c | 24 ++- 6 files changed, 111 insertions(+), 189 deletions(-)
drivers/net/wireless/intel/iwlwifi/mvm/link.c +2 -7
@@ -53,7 +53,6 @@ int iwl_mvm_add_link(struct iwl_mvm *mvm, struct ieee80211_vif *vif,unsigned int link_id = link_conf->link_id;struct iwl_mvm_vif_link_info *link_info = mvmvif->link[link_id];struct iwl_link_config_cmd cmd = {}; -struct iwl_mvm_phy_ctxt *phyctxt;if (WARN_ON_ONCE (!link_info))return -EINVAL ;
@@ -77,12 +76,8 @@ int iwl_mvm_add_link(struct iwl_mvm *mvm, struct ieee80211_vif *vif, cmd.link_id =cpu_to_le32 (link_info->fw_link_id); cmd.mac_id =cpu_to_le32 (mvmvif->id); cmd.spec_link_id = link_conf->link_id; -/* P2P-Device already has a valid PHY context during add */ - phyctxt = link_info->phy_ctxt; -if (phyctxt) - cmd.phy_id =cpu_to_le32 (phyctxt->id); -else - cmd.phy_id =cpu_to_le32 (FW_CTXT_INVALID ); +WARN_ON_ONCE (link_info->phy_ctxt); + cmd.phy_id =cpu_to_le32 (FW_CTXT_INVALID );memcpy (cmd.local_link_addr, link_conf->addr,ETH_ALEN );
drivers/net/wireless/intel/iwlwifi/mvm/mac-ctxt.c +4 -4
@@ -286,6 +286,10 @@ int iwl_mvm_mac_ctxt_init(struct iwl_mvm *mvm, struct ieee80211_vif *vif)INIT_LIST_HEAD (&mvmvif->time_event_data.list); mvmvif->time_event_data.id =TE_MAX ; + mvmvif->deflink.bcast_sta.sta_id =IWL_MVM_INVALID_STA ; + mvmvif->deflink.mcast_sta.sta_id =IWL_MVM_INVALID_STA ; + mvmvif->deflink.ap_sta_id =IWL_MVM_INVALID_STA ; +/* No need to allocate data queues to P2P Device MAC and NAN.*/ if (vif->type ==NL80211_IFTYPE_P2P_DEVICE )return 0 ;
@@ -300,10 +304,6 @@ int iwl_mvm_mac_ctxt_init(struct iwl_mvm *mvm, struct ieee80211_vif *vif) mvmvif->deflink.cab_queue =IWL_MVM_DQA_GCAST_QUEUE ; } - mvmvif->deflink.bcast_sta.sta_id =IWL_MVM_INVALID_STA ; - mvmvif->deflink.mcast_sta.sta_id =IWL_MVM_INVALID_STA ; - mvmvif->deflink.ap_sta_id =IWL_MVM_INVALID_STA ; -for (i =0 ; i <NUM_IWL_MVM_SMPS_REQ ; i++) mvmvif->deflink.smps_requests[i] =IEEE80211_SMPS_AUTOMATIC ;
drivers/net/wireless/intel/iwlwifi/mvm/mac80211.c +48 -104
229 lines not on this page · raw message
drivers/net/wireless/intel/iwlwifi/mvm/mld-mac80211.c +32 -68
149 lines not on this page · raw message
drivers/net/wireless/intel/iwlwifi/mvm/mvm.h +3 -4
@@ -1942,13 +1942,12 @@ void iwl_mvm_bss_info_changed_station_assoc(struct iwl_mvm *mvm,* * @add_aux_sta_for_hs20: pointer to the function that adds an aux sta * for Hot Spot 2.0 -* @switch_phy_ctxt: pointer to the function that switches a vif from one -* phy_ctx to another +* @link: For a P2P Device interface, pointer to a function that links the +* MAC/Link to the PHY context */ struct iwl_mvm_roc_ops {int (*add_aux_sta_for_hs20)(struct iwl_mvm *mvm,u32 lmac_id); -int (*switch_phy_ctxt)(struct iwl_mvm *mvm,struct ieee80211_vif *vif, -struct iwl_mvm_phy_ctxt *new_phy_ctxt); +int (*link)(struct iwl_mvm *mvm,struct ieee80211_vif *vif); }; int iwl_mvm_roc_common(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
drivers/net/wireless/intel/iwlwifi/mvm/time-event.c +22 -2
@@ -78,9 +78,29 @@ void iwl_mvm_roc_done_wk(struct work_struct *wk)*/ if (!WARN_ON (!mvm->p2p_device_vif)) { - mvmvif =iwl_mvm_vif_from_mac80211 (mvm->p2p_device_vif); +struct ieee80211_vif *vif = mvm->p2p_device_vif; + + mvmvif =iwl_mvm_vif_from_mac80211 (vif);iwl_mvm_flush_sta (mvm, &mvmvif->deflink.bcast_sta, true); + +if (mvm->mld_api_is_used) { +iwl_mvm_mld_rm_bcast_sta (mvm, vif, + &vif->bss_conf); + +iwl_mvm_link_changed (mvm, vif, &vif->bss_conf, +LINK_CONTEXT_MODIFY_ACTIVE , + false); + }else { +iwl_mvm_rm_p2p_bcast_sta (mvm, vif); +iwl_mvm_binding_remove_vif (mvm, vif); + } + +/* Do not remove the PHY context as removing and adding +* a PHY context has timing overheads. Leaving it +* configured in FW would be useful in case the next ROC +* is with the same channel. +*/ } }
@@ -880,8 +900,8 @@ void iwl_mvm_rx_session_protect_notif(struct iwl_mvm *mvm,if (!le32_to_cpu (notif->status) || !le32_to_cpu (notif->start)) {/* End TE, notify mac80211 */ mvmvif->time_event_data.id =SESSION_PROTECT_CONF_MAX_ID ; -ieee80211_remain_on_channel_expired (mvm->hw);iwl_mvm_p2p_roc_finished (mvm); +ieee80211_remain_on_channel_expired (mvm->hw); }else if (le32_to_cpu (notif->start)) {if (WARN_ON (mvmvif->time_event_data.id !=le32_to_cpu (notif->conf_id)))
Signature · 1 line
2.42.0
Greg Kroah-Hartman
maintainerPATCH 140/603 wifi: iwlwifi: mvm: change iwl_mvm_flush_sta() API
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Johannes Berg <[email protected]>
[ Upstream commit 391762969769b089c808defc8fce5544a945f9eb ]
This API is type unsafe and needs an extra parameter to know what kind of station was passed, so it has two, but really it only needs two values. Just pass the values instead of doing this type-unsafe dance, which will also make it better to use for multi-link.
Stable-dep-of: 43874283ce6c ("wifi: iwlwifi: mvm: fix iwl_mvm_mac_flush_sta()")
--- .../net/wireless/intel/iwlwifi/mvm/mac80211.c | 6 ++++-- .../net/wireless/intel/iwlwifi/mvm/mld-sta.c | 2 +- drivers/net/wireless/intel/iwlwifi/mvm/mvm.h | 2 +- drivers/net/wireless/intel/iwlwifi/mvm/sta.c | 9 ++++++--- .../wireless/intel/iwlwifi/mvm/time-event.c | 7 ++++--- drivers/net/wireless/intel/iwlwifi/mvm/tx.c | 18 ++---------------- 6 files changed, 18 insertions(+), 26 deletions(-)
drivers/net/wireless/intel/iwlwifi/mvm/mac80211.c +4 -2
@@ -5579,7 +5579,8 @@ void iwl_mvm_mac_flush(struct ieee80211_hw *hw, struct ieee80211_vif *vif, }if (drop) { -if (iwl_mvm_flush_sta (mvm, mvmsta, false)) +if (iwl_mvm_flush_sta (mvm, mvmsta->deflink.sta_id, + mvmsta->tfd_queue_msk))IWL_ERR (mvm,"flush request fail\n" ); }else {if (iwl_mvm_has_new_tx_api (mvm))
@@ -5616,7 +5617,8 @@ void iwl_mvm_mac_flush_sta(struct ieee80211_hw *hw, struct ieee80211_vif *vif, mvmsta =iwl_mvm_sta_from_mac80211 (sta); -if (iwl_mvm_flush_sta (mvm, mvmsta, false)) +if (iwl_mvm_flush_sta (mvm, mvmsta->deflink.sta_id, + mvmsta->tfd_queue_msk))IWL_ERR (mvm,"flush request fail\n" ); }mutex_unlock (&mvm->mutex);
drivers/net/wireless/intel/iwlwifi/mvm/mld-sta.c +1 -1
@@ -347,7 +347,7 @@ static int iwl_mvm_mld_rm_int_sta(struct iwl_mvm *mvm,return -EINVAL ;if (flush) -iwl_mvm_flush_sta (mvm, int_sta, true); +iwl_mvm_flush_sta (mvm, int_sta->sta_id, int_sta->tfd_queue_msk);iwl_mvm_mld_disable_txq (mvm,BIT (int_sta->sta_id), queuptr, tid);
drivers/net/wireless/intel/iwlwifi/mvm/mvm.h +1 -1
@@ -1658,7 +1658,7 @@ const char *iwl_mvm_get_tx_fail_reason(u32 status);static inline const char *iwl_mvm_get_tx_fail_reason (u32 status) {return "" ; }#endif int iwl_mvm_flush_tx_path (struct iwl_mvm *mvm,u32 tfd_msk); -int iwl_mvm_flush_sta (struct iwl_mvm *mvm,void *sta,bool internal); +int iwl_mvm_flush_sta (struct iwl_mvm *mvm,u32 sta_id,u32 tfd_queue_mask);int iwl_mvm_flush_sta_tids (struct iwl_mvm *mvm,u32 sta_id,u16 tids);/* Utils to extract sta related data */
drivers/net/wireless/intel/iwlwifi/mvm/sta.c +6 -3
@@ -2097,7 +2097,8 @@ int iwl_mvm_rm_sta(struct iwl_mvm *mvm,return ret;/* flush its queues here since we are freeing mvm_sta */ - ret =iwl_mvm_flush_sta (mvm, mvm_sta, false); + ret =iwl_mvm_flush_sta (mvm, mvm_sta->deflink.sta_id, + mvm_sta->tfd_queue_msk);if (ret)return ret;if (iwl_mvm_has_new_tx_api (mvm)) {
@@ -2408,7 +2409,8 @@ void iwl_mvm_free_bcast_sta_queues(struct iwl_mvm *mvm,lockdep_assert_held (&mvm->mutex); -iwl_mvm_flush_sta (mvm, &mvmvif->deflink.bcast_sta, true); +iwl_mvm_flush_sta (mvm, mvmvif->deflink.bcast_sta.sta_id, + mvmvif->deflink.bcast_sta.tfd_queue_msk);switch (vif->type) {case NL80211_IFTYPE_AP :
@@ -2664,7 +2666,8 @@ int iwl_mvm_rm_mcast_sta(struct iwl_mvm *mvm, struct ieee80211_vif *vif)lockdep_assert_held (&mvm->mutex); -iwl_mvm_flush_sta (mvm, &mvmvif->deflink.mcast_sta, true); +iwl_mvm_flush_sta (mvm, mvmvif->deflink.mcast_sta.sta_id, + mvmvif->deflink.mcast_sta.tfd_queue_msk);iwl_mvm_disable_txq (mvm,NULL , mvmvif->deflink.mcast_sta.sta_id, &mvmvif->deflink.cab_queue,0 );
drivers/net/wireless/intel/iwlwifi/mvm/time-event.c +4 -3
@@ -81,8 +81,8 @@ void iwl_mvm_roc_done_wk(struct work_struct *wk)struct ieee80211_vif *vif = mvm->p2p_device_vif; mvmvif =iwl_mvm_vif_from_mac80211 (vif); -iwl_mvm_flush_sta (mvm, &mvmvif->deflink.bcast_sta, - true); +iwl_mvm_flush_sta (mvm, mvmvif->deflink.bcast_sta.sta_id, + mvmvif->deflink.bcast_sta.tfd_queue_msk);if (mvm->mld_api_is_used) { iwl_mvm_mld_rm_bcast_sta(mvm, vif,
@@ -113,7 +113,8 @@ void iwl_mvm_roc_done_wk(struct work_struct *wk)*/ if (test_and_clear_bit (IWL_MVM_STATUS_ROC_AUX_RUNNING , &mvm->status)) {/* do the same in case of hot spot 2.0 */ -iwl_mvm_flush_sta (mvm, &mvm->aux_sta, true); +iwl_mvm_flush_sta (mvm, mvm->aux_sta.sta_id, + mvm->aux_sta.tfd_queue_msk);if (mvm->mld_api_is_used) {iwl_mvm_mld_rm_aux_sta (mvm);
drivers/net/wireless/intel/iwlwifi/mvm/tx.c +2 -16
@@ -2297,24 +2297,10 @@ int iwl_mvm_flush_sta_tids(struct iwl_mvm *mvm, u32 sta_id, u16 tids)return ret; } -int iwl_mvm_flush_sta (struct iwl_mvm *mvm,void *sta,bool internal) +int iwl_mvm_flush_sta (struct iwl_mvm *mvm,u32 sta_id,u32 tfd_queue_mask) { -u32 sta_id, tfd_queue_msk; - -if (internal) { -struct iwl_mvm_int_sta *int_sta = sta; - - sta_id = int_sta->sta_id; - tfd_queue_msk = int_sta->tfd_queue_msk; - }else { -struct iwl_mvm_sta *mvm_sta = sta; - - sta_id = mvm_sta->deflink.sta_id; - tfd_queue_msk = mvm_sta->tfd_queue_msk; - } -if (iwl_mvm_has_new_tx_api (mvm))return iwl_mvm_flush_sta_tids (mvm, sta_id,0xffff ); -return iwl_mvm_flush_tx_path (mvm, tfd_queue_msk); +return iwl_mvm_flush_tx_path (mvm, tfd_queue_mask); }
Signature · 1 line
2.42.0
Greg Kroah-Hartman
maintainerPATCH 141/603 wifi: iwlwifi: mvm: fix iwl_mvm_mac_flush_sta()
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Johannes Berg <[email protected]>
[ Upstream commit 43874283ce6c5bd32ac9d30878b2c96a974357cb ]
When I implemented iwl_mvm_mac_flush_sta() I completely botched it; it basically always happens after the iwl_mvm_sta_pre_rcu_remove() call, and that already clears mvm->fw_id_to_mac_id[] entries, so we cannot rely on those at iwl_mvm_mac_flush_sta() time. This means it never did anything.
Fix this by just going through the station IDs and now with the new API for iwl_mvm_flush_sta(), call those.
--- .../net/wireless/intel/iwlwifi/mvm/mac80211.c | 20 +++++++++---------- 1 file changed, 9 insertions(+), 11 deletions(-)
drivers/net/wireless/intel/iwlwifi/mvm/mac80211.c +9 -11
@@ -5602,22 +5602,20 @@ void iwl_mvm_mac_flush(struct ieee80211_hw *hw, struct ieee80211_vif *vif,void iwl_mvm_mac_flush_sta (struct ieee80211_hw *hw,struct ieee80211_vif *vif,struct ieee80211_sta *sta) { +struct iwl_mvm_sta *mvmsta =iwl_mvm_sta_from_mac80211 (sta);struct iwl_mvm *mvm =IWL_MAC80211_GET_MVM (hw); -int i; +struct iwl_mvm_link_sta *mvm_link_sta; +struct ieee80211_link_sta *link_sta; +int link_id;mutex_lock (&mvm->mutex); -for (i =0 ; i < mvm->fw->ucode_capa.num_stations; i++) { -struct iwl_mvm_sta *mvmsta; -struct ieee80211_sta *tmp; - - tmp =rcu_dereference_protected (mvm->fw_id_to_mac_id[i], -lockdep_is_held (&mvm->mutex)); -if (tmp != sta) +for_each_sta_active_link (vif, sta, link_sta, link_id) { + mvm_link_sta =rcu_dereference_protected (mvmsta->link[link_id], +lockdep_is_held (&mvm->mutex)); +if (!mvm_link_sta)continue ; - mvmsta =iwl_mvm_sta_from_mac80211 (sta); - -if (iwl_mvm_flush_sta (mvm, mvmsta->deflink.sta_id, +if (iwl_mvm_flush_sta (mvm, mvm_link_sta->sta_id, mvmsta->tfd_queue_msk))IWL_ERR (mvm,"flush request fail\n" ); }
Signature · 1 line
2.42.0
Greg Kroah-Hartman
maintainerPATCH 142/603 wifi: iwlwifi: mvm: remove TDLS stations from FW
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Johannes Berg <[email protected]>
[ Upstream commit 7b404c5cff3d4270fcd5212b6776c8484623ac74 ]
When we remove TDLS stations, we need to remove them from FW immediately, even while associated. Some previous refactoring here lost the sta ID condition, add it back.
--- drivers/net/wireless/intel/iwlwifi/mvm/sta.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)
drivers/net/wireless/intel/iwlwifi/mvm/sta.c +2 -1
@@ -2059,7 +2059,8 @@ bool iwl_mvm_sta_del(struct iwl_mvm *mvm, struct ieee80211_vif *vif, *status =IWL_MVM_QUEUE_FREE ; } -if (vif->type ==NL80211_IFTYPE_STATION ) { +if (vif->type ==NL80211_IFTYPE_STATION && + mvm_link->ap_sta_id == sta_id) {/* if associated - we can't remove the AP STA now */ if (vif->cfg.assoc)return true;
Signature · 1 line
2.42.0
Greg Kroah-Hartman
maintainerPATCH 143/603 wifi: iwlwifi: increase number of RX buffers for EHT devices
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Johannes Berg <[email protected]>
[ Upstream commit 2cf254c1e24fa8f01f42f5a8c77617e56bf50b86 ]
EHT devices can support 512 MPDUs in an A-MPDU, each of which might be an A-MSDU and thus further contain multiple MSDUs, which need their own buffer each. Increase the number of buffers to avoid running out in high-throughput scenarios.
Stable-dep-of: 08365d3b9140 ("wifi: iwlwifi: mvm: fix netif csum flags")
--- drivers/net/wireless/intel/iwlwifi/cfg/bz.c | 10 ++++------ drivers/net/wireless/intel/iwlwifi/cfg/sc.c | 8 +++----- 2 files changed, 7 insertions(+), 11 deletions(-)
drivers/net/wireless/intel/iwlwifi/cfg/bz.c +4 -6
@@ -134,12 +134,10 @@ static const struct iwl_base_params iwl_bz_base_params = { .ht_params = &iwl_gl_a_ht_params/* -* If the device doesn't support HE, no need to have that many buffers. -* These sizes were picked according to 8 MSDUs inside 256 A-MSDUs in an +* This size was picked according to 8 MSDUs inside 512 A-MSDUs in an * A-MPDU, with additional overhead to account for processing time. */ -#define IWL_NUM_RBDS_NON_HE 512 -#define IWL_NUM_RBDS_BZ_HE 4096 +#define IWL_NUM_RBDS_BZ_EHT (512 * 16)const struct iwl_cfg_trans_params iwl_bz_trans_cfg = { .device_family =IWL_DEVICE_FAMILY_BZ ,
@@ -161,7 +159,7 @@ const struct iwl_cfg iwl_cfg_bz = { .uhb_supported = true,IWL_DEVICE_BZ , .features = IWL_TX_CSUM_NETIF_FLAGS_BZ | NETIF_F_RXCSUM, - .num_rbds = IWL_NUM_RBDS_BZ_HE, + .num_rbds = IWL_NUM_RBDS_BZ_EHT, }; const struct iwl_cfg iwl_cfg_gl = {
@@ -169,7 +167,7 @@ const struct iwl_cfg iwl_cfg_gl = { .uhb_supported = true,IWL_DEVICE_BZ , .features = IWL_TX_CSUM_NETIF_FLAGS_BZ | NETIF_F_RXCSUM, - .num_rbds = IWL_NUM_RBDS_BZ_HE, + .num_rbds = IWL_NUM_RBDS_BZ_EHT, };
drivers/net/wireless/intel/iwlwifi/cfg/sc.c +3 -5
@@ -127,12 +127,10 @@ static const struct iwl_base_params iwl_sc_base_params = { .ht_params = &iwl_22000_ht_params/* -* If the device doesn't support HE, no need to have that many buffers. -* These sizes were picked according to 8 MSDUs inside 256 A-MSDUs in an +* This size was picked according to 8 MSDUs inside 512 A-MSDUs in an * A-MPDU, with additional overhead to account for processing time. */ -#define IWL_NUM_RBDS_NON_HE 512 -#define IWL_NUM_RBDS_SC_HE 4096 +#define IWL_NUM_RBDS_SC_EHT (512 * 16)const struct iwl_cfg_trans_params iwl_sc_trans_cfg = { .device_family =IWL_DEVICE_FAMILY_SC ,
@@ -154,7 +152,7 @@ const struct iwl_cfg iwl_cfg_sc = { .uhb_supported = true,IWL_DEVICE_SC , .features = IWL_TX_CSUM_NETIF_FLAGS_BZ | NETIF_F_RXCSUM, - .num_rbds = IWL_NUM_RBDS_SC_HE, + .num_rbds = IWL_NUM_RBDS_SC_EHT, };MODULE_FIRMWARE (IWL_SC_A_FM_B_FW_MODULE_FIRMWARE (IWL_SC_UCODE_API_MAX ));
Signature · 1 line
2.42.0
Greg Kroah-Hartman
maintainerPATCH 144/603 wifi: iwlwifi: mvm: fix netif csum flags
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Johannes Berg <[email protected]>
[ Upstream commit 08365d3b9140c751a84f8027ac7d2e662958f768 ]
We shouldn't advertise arbitrary checksum flags since we had to remove support for it due to broken hardware.
--- drivers/net/wireless/intel/iwlwifi/cfg/bz.c | 4 ++-- drivers/net/wireless/intel/iwlwifi/cfg/sc.c | 2 +- drivers/net/wireless/intel/iwlwifi/iwl-config.h | 5 +---- 3 files changed, 4 insertions(+), 7 deletions(-)
drivers/net/wireless/intel/iwlwifi/cfg/bz.c +2 -2
@@ -158,7 +158,7 @@ const struct iwl_cfg iwl_cfg_bz = { .fw_name_mac = "bz", .uhb_supported = true,IWL_DEVICE_BZ , - .features = IWL_TX_CSUM_NETIF_FLAGS_BZ | NETIF_F_RXCSUM, + .features = IWL_TX_CSUM_NETIF_FLAGS | NETIF_F_RXCSUM, .num_rbds = IWL_NUM_RBDS_BZ_EHT, };
@@ -166,7 +166,7 @@ const struct iwl_cfg iwl_cfg_gl = { .fw_name_mac = "gl", .uhb_supported = true,IWL_DEVICE_BZ , - .features = IWL_TX_CSUM_NETIF_FLAGS_BZ | NETIF_F_RXCSUM, + .features = IWL_TX_CSUM_NETIF_FLAGS | NETIF_F_RXCSUM, .num_rbds = IWL_NUM_RBDS_BZ_EHT, };
drivers/net/wireless/intel/iwlwifi/cfg/sc.c +1 -1
@@ -151,7 +151,7 @@ const struct iwl_cfg iwl_cfg_sc = { .fw_name_mac = "sc", .uhb_supported = true,IWL_DEVICE_SC , - .features = IWL_TX_CSUM_NETIF_FLAGS_BZ | NETIF_F_RXCSUM, + .features = IWL_TX_CSUM_NETIF_FLAGS | NETIF_F_RXCSUM, .num_rbds = IWL_NUM_RBDS_SC_EHT, };
drivers/net/wireless/intel/iwlwifi/iwl-config.h +1 -4
@@ -86,10 +86,7 @@ enum iwl_nvm_type {#define IWL_DEFAULT_MAX_TX_POWER 22#define IWL_TX_CSUM_NETIF_FLAGS (NETIF_F_IPV6_CSUM | NETIF_F_IP_CSUM |\ NETIF_F_TSO | NETIF_F_TSO6) -#define IWL_TX_CSUM_NETIF_FLAGS_BZ (NETIF_F_HW_CSUM | NETIF_F_TSO | NETIF_F_TSO6) -#define IWL_CSUM_NETIF_FLAGS_MASK (IWL_TX_CSUM_NETIF_FLAGS | \ - IWL_TX_CSUM_NETIF_FLAGS_BZ | \ - NETIF_F_RXCSUM) +#define IWL_CSUM_NETIF_FLAGS_MASK (IWL_TX_CSUM_NETIF_FLAGS | NETIF_F_RXCSUM)/* Antenna presence definitions */ #define ANT_NONE 0x0
Signature · 1 line
2.42.0
Greg Kroah-Hartman
maintainerPATCH 145/603 wifi: iwlwifi: pcie: synchronize IRQs before NAPI
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Johannes Berg <[email protected]>
[ Upstream commit 37fb29bd1f90f16d1abc95c0e9f0ff8eec9829ad ]
When we want to synchronize the NAPI, which was added in commit 5af2bb3168db ("wifi: iwlwifi: call napi_synchronize() before freeing rx/tx queues"), we also need to make sure we can't actually reschedule the NAPI. Yes, this happens while interrupts are disabled, but interrupts may still be running or pending. Also call iwl_pcie_synchronize_irqs() to ensure we won't reschedule the NAPI.
--- drivers/net/wireless/intel/iwlwifi/pcie/trans-gen2.c | 1 + drivers/net/wireless/intel/iwlwifi/pcie/trans.c | 1 + 2 files changed, 2 insertions(+)
drivers/net/wireless/intel/iwlwifi/pcie/trans-gen2.c +1 -0
@@ -161,6 +161,7 @@ void _iwl_trans_pcie_gen2_stop_device(struct iwl_trans *trans)if (test_and_clear_bit (STATUS_DEVICE_ENABLED , &trans->status)) {IWL_DEBUG_INFO (trans,"DEVICE_ENABLED bit was set and is now cleared\n" ); +iwl_pcie_synchronize_irqs (trans);iwl_pcie_rx_napi_sync (trans);iwl_txq_gen2_tx_free (trans);iwl_pcie_rx_stop (trans);
drivers/net/wireless/intel/iwlwifi/pcie/trans.c +1 -0
@@ -1263,6 +1263,7 @@ static void _iwl_trans_pcie_stop_device(struct iwl_trans *trans)if (test_and_clear_bit (STATUS_DEVICE_ENABLED , &trans->status)) {IWL_DEBUG_INFO (trans,"DEVICE_ENABLED bit was set and is now cleared\n" ); +iwl_pcie_synchronize_irqs (trans);iwl_pcie_rx_napi_sync (trans);iwl_pcie_tx_stop (trans);iwl_pcie_rx_stop (trans);
Signature · 1 line
2.42.0
Greg Kroah-Hartman
maintainerPATCH 146/603 wifi: iwlwifi: mvm: update IGTK in mvmvif upon D3 resume
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Yedidya Benshimol <[email protected]>
[ Upstream commit ac0c6fdc4c56b669abc1c4a323f1c7a3a1422dd2 ]
During the D3 resume flow, all new rekeys are passed from the FW. Because the FW supports only one IGTK at a time, every IGTK rekey update should be done by removing the last IGTK. The mvmvif holds a pointer to the last IGTK for that reason and thus should be updated when a new IGTK is passed upon resume.
--- drivers/net/wireless/intel/iwlwifi/mvm/d3.c | 10 ++++++++++ 1 file changed, 10 insertions(+)
drivers/net/wireless/intel/iwlwifi/mvm/d3.c +10 -0
@@ -2012,6 +2012,16 @@ iwl_mvm_d3_igtk_bigtk_rekey_add(struct iwl_wowlan_status_data *status,if (IS_ERR (key_config))return false;ieee80211_set_key_rx_seq (key_config,0 , &seq); + +if (key_config->keyidx ==4 || key_config->keyidx ==5 ) { +struct iwl_mvm_vif *mvmvif =iwl_mvm_vif_from_mac80211 (vif); +int link_id = vif->active_links ?__ffs (vif->active_links) :0 ; +struct iwl_mvm_vif_link_info *mvm_link = + mvmvif->link[link_id]; + + mvm_link->igtk = key_config; + } +return true; }
Signature · 1 line
2.42.0
Greg Kroah-Hartman
maintainerPATCH 147/603 wifi: iwlwifi: empty overflow queue during flush
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Miri Korenblit <[email protected]>
[ Upstream commit 658939fc68d3241f9a0019e224cd7154438c23f2 ]
If a TX queue has no space for new TX frames, the driver will keep these frames in the overflow queue, and during reclaim flow it will retry to send the frames from that queue.
But if the reclaim flow was invoked from TX queue flush, we will also TX these frames, which is wrong as we don't want to TX anything after flush.
This might also cause assert 0x125F when removing the queue, saying that the driver removes a non-empty queue
Fix this by TXing the overflow queue's frames only if we are not in flush queue flow.
--- drivers/net/wireless/intel/iwlwifi/dvm/tx.c | 5 +++-- drivers/net/wireless/intel/iwlwifi/iwl-trans.h | 7 ++++--- drivers/net/wireless/intel/iwlwifi/mvm/tx.c | 4 ++-- drivers/net/wireless/intel/iwlwifi/queue/tx.c | 9 +++++---- drivers/net/wireless/intel/iwlwifi/queue/tx.h | 2 +- 5 files changed, 15 insertions(+), 12 deletions(-)
drivers/net/wireless/intel/iwlwifi/dvm/tx.c +3 -2
@@ -3,6 +3,7 @@* * Copyright(c) 2008 - 2014 Intel Corporation. All rights reserved. * Copyright (C) 2019 Intel Corporation +* Copyright (C) 2023 Intel Corporation *****************************************************************************/ #include <linux/kernel.h>
@@ -1169,7 +1170,7 @@ void iwlagn_rx_reply_tx(struct iwl_priv *priv, struct iwl_rx_cmd_buffer *rxb)iwlagn_check_ratid_empty (priv, sta_id, tid); } -iwl_trans_reclaim (priv->trans, txq_id, ssn, &skbs); +iwl_trans_reclaim (priv->trans, txq_id, ssn, &skbs, false); freed =0 ;
@@ -1315,7 +1316,7 @@ void iwlagn_rx_reply_compressed_ba(struct iwl_priv *priv,* block-ack window (we assume that they've been successfully * transmitted ... if not, it's too late anyway). */ iwl_trans_reclaim (priv->trans, scd_flow, ba_resp_scd_ssn, - &reclaimed_skbs); + &reclaimed_skbs, false); IWL_DEBUG_TX_REPLY(priv, "REPLY_COMPRESSED_BA [%d] Received from %pM, " "sta_id = %d\n",
drivers/net/wireless/intel/iwlwifi/iwl-trans.h +4 -3
@@ -588,7 +588,7 @@ struct iwl_trans_ops {int (*tx)(struct iwl_trans *trans,struct sk_buff *skb,struct iwl_device_tx_cmd *dev_cmd,int queue);void (*reclaim)(struct iwl_trans *trans,int queue,int ssn, -struct sk_buff_head *skbs); +struct sk_buff_head *skbs,bool is_flush);void (*set_q_ptrs)(struct iwl_trans *trans,int queue,int ptr);
@@ -1273,14 +1273,15 @@ static inline int iwl_trans_tx(struct iwl_trans *trans, struct sk_buff *skb, }static inline void iwl_trans_reclaim (struct iwl_trans *trans,int queue, -int ssn,struct sk_buff_head *skbs) +int ssn,struct sk_buff_head *skbs, +bool is_flush) {if (WARN_ON_ONCE (trans->state !=IWL_TRANS_FW_ALIVE )) {IWL_ERR (trans,"%s bad state = %d\n" , __func__, trans->state);return ; } - trans->ops->reclaim (trans, queue, ssn, skbs); + trans->ops->reclaim (trans, queue, ssn, skbs, is_flush); } static inline void iwl_trans_set_q_ptrs(struct iwl_trans *trans, int queue,
drivers/net/wireless/intel/iwlwifi/mvm/tx.c +2 -2
@@ -1603,7 +1603,7 @@ static void iwl_mvm_rx_tx_cmd_single(struct iwl_mvm *mvm, seq_ctl =le16_to_cpu (tx_resp->seq_ctl);/* we can free until ssn % q.n_bd not inclusive */ -iwl_trans_reclaim (mvm->trans, txq_id, ssn, &skbs); +iwl_trans_reclaim (mvm->trans, txq_id, ssn, &skbs, false);while (!skb_queue_empty (&skbs)) {struct sk_buff *skb =__skb_dequeue (&skbs);
@@ -1955,7 +1955,7 @@ static void iwl_mvm_tx_reclaim(struct iwl_mvm *mvm, int sta_id, int tid,* block-ack window (we assume that they've been successfully * transmitted ... if not, it's too late anyway). */ -iwl_trans_reclaim (mvm->trans, txq, index, &reclaimed_skbs); +iwl_trans_reclaim (mvm->trans, txq, index, &reclaimed_skbs, is_flush); skb_queue_walk(&reclaimed_skbs, skb) {struct ieee80211_tx_info *info =IEEE80211_SKB_CB (skb);
drivers/net/wireless/intel/iwlwifi/queue/tx.c +5 -4
@@ -1575,7 +1575,7 @@ void iwl_txq_progress(struct iwl_txq *txq)/* Frees buffers until index _not_ inclusive */ void iwl_txq_reclaim (struct iwl_trans *trans,int txq_id,int ssn, -struct sk_buff_head *skbs) +struct sk_buff_head *skbs,bool is_flush) {struct iwl_txq *txq = trans->txqs.txq[txq_id];int tfd_num, read_ptr, last_to_free;
@@ -1650,9 +1650,11 @@ void iwl_txq_reclaim(struct iwl_trans *trans, int txq_id, int ssn,if (iwl_txq_space (trans, txq) > txq->low_mark &&test_bit (txq_id, trans->txqs.queue_stopped)) {struct sk_buff_head overflow_skbs; +struct sk_buff *skb;__skb_queue_head_init (&overflow_skbs); -skb_queue_splice_init (&txq->overflow_q, &overflow_skbs); +skb_queue_splice_init (&txq->overflow_q, + is_flush ? skbs : &overflow_skbs);/* * We are going to transmit from the overflow queue.
@@ -1672,8 +1674,7 @@ void iwl_txq_reclaim(struct iwl_trans *trans, int txq_id, int ssn,*/ spin_unlock_bh (&txq->lock); -while (!skb_queue_empty (&overflow_skbs)) { -struct sk_buff *skb =__skb_dequeue (&overflow_skbs); +while ((skb =__skb_dequeue (&overflow_skbs))) {struct iwl_device_tx_cmd *dev_cmd_ptr; dev_cmd_ptr = *(void **)((u8 *)skb->cb +
drivers/net/wireless/intel/iwlwifi/queue/tx.h +1 -1
@@ -179,7 +179,7 @@ void iwl_txq_gen1_update_byte_cnt_tbl(struct iwl_trans *trans, struct iwl_txq *txq, u16 byte_cnt, int num_tbs);void iwl_txq_reclaim (struct iwl_trans *trans,int txq_id,int ssn, -struct sk_buff_head *skbs); +struct sk_buff_head *skbs,bool is_flush);void iwl_txq_set_q_ptrs (struct iwl_trans *trans,int txq_id,int ptr);void iwl_trans_txq_freeze_timer (struct iwl_trans *trans,unsigned long txqs,bool freeze);
Signature · 1 line
2.42.0
Greg Kroah-Hartman
maintainerPATCH 148/603 Bluetooth: ISO: Pass BIG encryption info through QoS
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Iulia Tanasescu <[email protected]>
[ Upstream commit 1d11d70d1f6b23e7d3fc00396c17b90b876162a4 ]
This enables a broadcast sink to be informed if the PA it has synced with is associated with an encrypted BIG, by retrieving the socket QoS and checking the encryption field.
After PA sync has been successfully established and the first BIGInfo advertising report is received, a new hcon is added and notified to the ISO layer. The ISO layer sets the encryption field of the socket and hcon QoS according to the encryption parameter of the BIGInfo advertising report event.
After that, the userspace is woken up, and the QoS of the new PA sync socket can be read, to inspect the encryption field and follow up accordingly.
Stable-dep-of: 181a42edddf5 ("Bluetooth: Make handle of hci_conn be unique")
--- include/net/bluetooth/hci.h | 3 ++ include/net/bluetooth/hci_core.h | 25 ++++++++++++++- net/bluetooth/hci_conn.c | 1 + net/bluetooth/hci_event.c | 54 +++++++++++++++++++++++--------- net/bluetooth/iso.c | 19 ++++++++--- 5 files changed, 82 insertions(+), 20 deletions(-)
include/net/bluetooth/hci.h +3 -0
@@ -1,6 +1,7 @@/* BlueZ - Bluetooth protocol stack for Linux Copyright (C) 2000-2001 Qualcomm Incorporated +Copyright 2023 NXP Written 2000,2001 by Maxim Krasnyansky <[email protected]>
@@ -673,6 +674,8 @@ enum {#define HCI_TX_POWER_INVALID 127#define HCI_RSSI_INVALID 127 +#define HCI_SYNC_HANDLE_INVALID 0xffff +#define HCI_ROLE_MASTER 0x00#define HCI_ROLE_SLAVE 0x01
include/net/bluetooth/hci_core.h +24 -1
@@ -1314,7 +1314,7 @@ static inline struct hci_conn *hci_conn_hash_lookup_big_any_dst(struct hci_dev * }static inline struct hci_conn * -hci_conn_hash_lookup_pa_sync (struct hci_dev *hdev,__u8 big) +hci_conn_hash_lookup_pa_sync_big_handle (struct hci_dev *hdev,__u8 big) {struct hci_conn_hash *h = &hdev->conn_hash;struct hci_conn *c;
@@ -1336,6 +1336,29 @@ hci_conn_hash_lookup_pa_sync(struct hci_dev *hdev, __u8 big)return NULL ; } +static inline struct hci_conn * +hci_conn_hash_lookup_pa_sync_handle (struct hci_dev *hdev,__u16 sync_handle) +{ +struct hci_conn_hash *h = &hdev->conn_hash; +struct hci_conn *c; + +rcu_read_lock (); + +list_for_each_entry_rcu (c, &h->list, list) { +if (c->type !=ISO_LINK || + !test_bit (HCI_CONN_PA_SYNC , &c->flags)) +continue ; + +if (c->sync_handle == sync_handle) { +rcu_read_unlock (); +return c; + } + } +rcu_read_unlock (); + +return NULL ; +} +static inline struct hci_conn *hci_conn_hash_lookup_state (struct hci_dev *hdev,__u8 type,__u16 state) {
net/bluetooth/hci_conn.c +1 -0
@@ -973,6 +973,7 @@ struct hci_conn *hci_conn_add(struct hci_dev *hdev, int type, bdaddr_t *dst, conn->rssi =HCI_RSSI_INVALID ; conn->tx_power =HCI_TX_POWER_INVALID ; conn->max_tx_power =HCI_TX_POWER_INVALID ; + conn->sync_handle =HCI_SYNC_HANDLE_INVALID ;set_bit (HCI_CONN_POWER_SAVE , &conn->flags); conn->disc_timeout =HCI_DISCONN_TIMEOUT ;
net/bluetooth/hci_event.c +40 -14
89 lines not on this page · raw message
net/bluetooth/iso.c +14 -5
@@ -77,6 +77,7 @@ static struct bt_iso_qos default_qos;static bool check_ucast_qos (struct bt_iso_qos *qos);static bool check_bcast_qos (struct bt_iso_qos *qos);static bool iso_match_sid (struct sock *sk,void *data); +static bool iso_match_sync_handle (struct sock *sk,void *data);static void iso_sock_disconn (struct sock *sk);/* ---- ISO timers ---- */
@@ -1202,7 +1203,6 @@ static int iso_sock_recvmsg(struct socket *sock, struct msghdr *msg, test_bit(HCI_CONN_PA_SYNC, &pi->conn->hcon->flags)) { iso_conn_big_sync(sk); sk->sk_state = BT_LISTEN; - set_bit(BT_SK_PA_SYNC, &iso_pi(sk)->flags); } else {iso_conn_defer_accept (pi->conn->hcon); sk->sk_state =BT_CONFIG ;
@@ -1579,6 +1579,7 @@ static void iso_conn_ready(struct iso_conn *conn)struct sock *sk = conn->sk;struct hci_ev_le_big_sync_estabilished *ev =NULL ;struct hci_ev_le_pa_sync_established *ev2 =NULL ; +struct hci_evt_le_big_info_adv_report *ev3 =NULL ;struct hci_conn *hcon;BT_DBG ("conn %p" , conn);
@@ -1603,14 +1604,20 @@ static void iso_conn_ready(struct iso_conn *conn) parent =iso_get_sock_listen (&hcon->src, &hcon->dst, iso_match_big, ev); - }else if (test_bit (HCI_CONN_PA_SYNC , &hcon->flags) || -test_bit (HCI_CONN_PA_SYNC_FAILED , &hcon->flags)) { + }else if (test_bit (HCI_CONN_PA_SYNC_FAILED , &hcon->flags)) { ev2 =hci_recv_event_data (hcon->hdev,HCI_EV_LE_PA_SYNC_ESTABLISHED );if (ev2) parent =iso_get_sock_listen (&hcon->src, &hcon->dst, iso_match_sid, ev2); + }else if (test_bit (HCI_CONN_PA_SYNC , &hcon->flags)) { + ev3 =hci_recv_event_data (hcon->hdev, +HCI_EVT_LE_BIG_INFO_ADV_REPORT ); +if (ev3) + parent =iso_get_sock_listen (&hcon->src, + &hcon->dst, + iso_match_sync_handle, ev3); }if (!parent)
@@ -1650,11 +1657,13 @@ static void iso_conn_ready(struct iso_conn *conn) hcon->sync_handle =iso_pi (parent)->sync_handle; } -if (ev2 && !ev2->status) { -iso_pi (sk)->sync_handle =iso_pi (parent)->sync_handle; +if (ev3) {iso_pi (sk)->qos =iso_pi (parent)->qos; +iso_pi (sk)->qos.bcast.encryption = ev3->encryption; + hcon->iso_qos =iso_pi (sk)->qos;iso_pi (sk)->bc_num_bis =iso_pi (parent)->bc_num_bis;memcpy (iso_pi (sk)->bc_bis,iso_pi (parent)->bc_bis,ISO_MAX_NUM_BIS ); +set_bit (BT_SK_PA_SYNC , &iso_pi (sk)->flags); }bacpy (&iso_pi (sk)->dst, &hcon->dst);
Signature · 1 line
2.42.0
Greg Kroah-Hartman
maintainerPATCH 149/603 Bluetooth: Make handle of hci_conn be unique
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Ziyang Xuan <[email protected]>
[ Upstream commit 181a42edddf51d5d9697ecdf365d72ebeab5afb0 ]
The handle of new hci_conn is always HCI_CONN_HANDLE_MAX + 1 if the handle of the first hci_conn entry in hci_dev->conn_hash->list is not HCI_CONN_HANDLE_MAX + 1. Use ida to manage the allocation of hci_conn->handle to make it be unique.
--- include/net/bluetooth/hci_core.h | 6 +++- net/bluetooth/amp.c | 3 +- net/bluetooth/hci_conn.c | 57 ++++++++++++++++++-------------- net/bluetooth/hci_core.c | 3 ++ net/bluetooth/hci_event.c | 38 +++++++++------------ 5 files changed, 56 insertions(+), 51 deletions(-)
include/net/bluetooth/hci_core.h +5 -1
@@ -350,6 +350,8 @@ struct hci_dev {struct list_head list;struct mutex lock; +struct ida unset_handle_ida; +const char *name;unsigned long flags;__u16 id;
@@ -1449,7 +1451,9 @@ int hci_le_create_cis_pending(struct hci_dev *hdev);int hci_conn_check_create_cis (struct hci_conn *conn);struct hci_conn *hci_conn_add (struct hci_dev *hdev,int type,bdaddr_t *dst, -u8 role); +u8 role,u16 handle); +struct hci_conn *hci_conn_add_unset (struct hci_dev *hdev,int type, +bdaddr_t *dst,u8 role);void hci_conn_del (struct hci_conn *conn);void hci_conn_hash_flush (struct hci_dev *hdev);void hci_conn_check_pending (struct hci_dev *hdev);
net/bluetooth/amp.c +1 -2
@@ -109,7 +109,7 @@ struct hci_conn *phylink_add(struct hci_dev *hdev, struct amp_mgr *mgr,struct hci_conn *hcon;u8 role = out ?HCI_ROLE_MASTER :HCI_ROLE_SLAVE ; - hcon =hci_conn_add (hdev,AMP_LINK , dst, role); + hcon =hci_conn_add (hdev,AMP_LINK , dst, role,__next_handle (mgr));if (!hcon)return NULL ;
@@ -117,7 +117,6 @@ struct hci_conn *phylink_add(struct hci_dev *hdev, struct amp_mgr *mgr, hcon->state =BT_CONNECT ; hcon->attempt++; - hcon->handle =__next_handle (mgr); hcon->remote_id = remote_id; hcon->amp_mgr =amp_mgr_get (mgr);
net/bluetooth/hci_conn.c +32 -25
130 lines not on this page · raw message
net/bluetooth/hci_core.c +3 -0
@@ -2535,6 +2535,8 @@ struct hci_dev *hci_alloc_dev_priv(int sizeof_priv)mutex_init (&hdev->lock);mutex_init (&hdev->req_lock); +ida_init (&hdev->unset_handle_ida); +INIT_LIST_HEAD (&hdev->mesh_pending);INIT_LIST_HEAD (&hdev->mgmt_pending);INIT_LIST_HEAD (&hdev->reject_list);
@@ -2789,6 +2791,7 @@ void hci_release_dev(struct hci_dev *hdev)hci_codec_list_clear (&hdev->local_codecs);hci_dev_unlock (hdev); +ida_destroy (&hdev->unset_handle_ida);ida_simple_remove (&hci_index_ida, hdev->id);kfree_skb (hdev->sent_cmd);kfree_skb (hdev->recv_event);
net/bluetooth/hci_event.c +15 -23
@@ -2335,8 +2335,8 @@ static void hci_cs_create_conn(struct hci_dev *hdev, __u8 status) } }else {if (!conn) { - conn =hci_conn_add (hdev,ACL_LINK , &cp->bdaddr, -HCI_ROLE_MASTER ); + conn =hci_conn_add_unset (hdev,ACL_LINK , &cp->bdaddr, +HCI_ROLE_MASTER );if (!conn)bt_dev_err (hdev,"no memory for new connection" ); }
@@ -3151,8 +3151,8 @@ static void hci_conn_complete_evt(struct hci_dev *hdev, void *data, hci_bdaddr_list_lookup_with_flags(&hdev->accept_list, &ev->bdaddr, BDADDR_BREDR)) { - conn =hci_conn_add (hdev, ev->link_type, &ev->bdaddr, -HCI_ROLE_SLAVE ); + conn =hci_conn_add_unset (hdev, ev->link_type, + &ev->bdaddr,HCI_ROLE_SLAVE );if (!conn) {bt_dev_err (hdev,"no memory for new conn" ); goto unlock;
@@ -3317,8 +3317,8 @@ static void hci_conn_request_evt(struct hci_dev *hdev, void *data, conn =hci_conn_hash_lookup_ba (hdev, ev->link_type, &ev->bdaddr);if (!conn) { - conn =hci_conn_add (hdev, ev->link_type, &ev->bdaddr, -HCI_ROLE_SLAVE ); + conn =hci_conn_add_unset (hdev, ev->link_type, &ev->bdaddr, +HCI_ROLE_SLAVE );if (!conn) {bt_dev_err (hdev,"no memory for new connection" ); goto unlock;
@@ -5890,7 +5890,7 @@ static void le_conn_complete_evt(struct hci_dev *hdev, u8 status,if (status) goto unlock; - conn =hci_conn_add (hdev,LE_LINK , bdaddr, role); + conn =hci_conn_add_unset (hdev,LE_LINK , bdaddr, role);if (!conn) {bt_dev_err (hdev,"no memory for new connection" ); goto unlock;
@@ -5952,17 +5952,11 @@ static void le_conn_complete_evt(struct hci_dev *hdev, u8 status, conn->dst_type =ev_bdaddr_type (hdev, conn->dst_type,NULL ); -if (handle >HCI_CONN_HANDLE_MAX ) { -bt_dev_err (hdev,"Invalid handle: 0x%4.4x > 0x%4.4x" , handle, -HCI_CONN_HANDLE_MAX ); - status =HCI_ERROR_INVALID_PARAMETERS ; - } -/* All connection failure handling is taken care of by the * hci_conn_failed function which is triggered by the HCI * request completion callbacks used for connecting. */ -if (status) +if (status ||hci_conn_set_handle (conn, handle)) goto unlock;/* Drop the connection if it has been aborted */
@@ -5986,7 +5980,6 @@ static void le_conn_complete_evt(struct hci_dev *hdev, u8 status,mgmt_device_connected (hdev, conn,NULL ,0 ); conn->sec_level =BT_SECURITY_LOW ; - conn->handle = handle; conn->state =BT_CONFIG ;/* Store current advertising instance as connection advertising instance
@@ -6622,8 +6615,8 @@ static void hci_le_pa_sync_estabilished_evt(struct hci_dev *hdev, void *data,if (ev->status) {/* Add connection to indicate the failed PA sync event */ - pa_sync =hci_conn_add (hdev,ISO_LINK ,BDADDR_ANY , -HCI_ROLE_SLAVE ); + pa_sync =hci_conn_add_unset (hdev,ISO_LINK ,BDADDR_ANY , +HCI_ROLE_SLAVE );if (!pa_sync) goto unlock;
@@ -7019,12 +7012,12 @@ static void hci_le_cis_req_evt(struct hci_dev *hdev, void *data, cis =hci_conn_hash_lookup_handle (hdev, cis_handle);if (!cis) { - cis =hci_conn_add (hdev,ISO_LINK , &acl->dst,HCI_ROLE_SLAVE ); + cis =hci_conn_add (hdev,ISO_LINK , &acl->dst,HCI_ROLE_SLAVE , + cis_handle);if (!cis) {hci_le_reject_cis (hdev, ev->cis_handle); goto unlock; } - cis->handle = cis_handle; } cis->iso_qos.ucast.cig = ev->cig_id;
@@ -7139,10 +7132,9 @@ static void hci_le_big_sync_established_evt(struct hci_dev *hdev, void *data, bis =hci_conn_hash_lookup_handle (hdev, handle);if (!bis) { bis =hci_conn_add (hdev,ISO_LINK ,BDADDR_ANY , -HCI_ROLE_SLAVE ); +HCI_ROLE_SLAVE , handle);if (!bis)continue ; - bis->handle = handle; }if (ev->status !=0x42 )
@@ -7208,8 +7200,8 @@ static void hci_le_big_info_adv_report_evt(struct hci_dev *hdev, void *data, goto unlock;/* Add connection to indicate the PA sync event */ - pa_sync =hci_conn_add (hdev,ISO_LINK ,BDADDR_ANY , -HCI_ROLE_SLAVE ); + pa_sync =hci_conn_add_unset (hdev,ISO_LINK ,BDADDR_ANY , +HCI_ROLE_SLAVE );if (!pa_sync) goto unlock;
Signature · 1 line
2.42.0
Greg Kroah-Hartman
maintainerPATCH 150/603 Bluetooth: hci_sync: Fix Opcode prints in bt_dev_dbg/err
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Marcel Ziswiler <[email protected]>
[ Upstream commit 530886897c789cf77c9a0d4a7cc5549f0768b5f8 ]
Printed Opcodes may be missing leading zeros:
Bluetooth: hci0: Opcode 0x c03 failed: -110
Fix this by always printing leading zeros:
Bluetooth: hci0: Opcode 0x0c03 failed: -110
--- net/bluetooth/hci_sync.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
net/bluetooth/hci_sync.c +2 -2
@@ -152,7 +152,7 @@ struct sk_buff *__hci_cmd_sync_sk(struct hci_dev *hdev, u16 opcode, u32 plen,struct sk_buff *skb;int err =0 ; -bt_dev_dbg (hdev,"Opcode 0x%4x" , opcode); +bt_dev_dbg (hdev,"Opcode 0x%4.4x" , opcode);hci_req_init (&req, hdev);
@@ -248,7 +248,7 @@ int __hci_cmd_sync_status_sk(struct hci_dev *hdev, u16 opcode, u32 plen, skb =__hci_cmd_sync_sk (hdev, opcode, plen, param, event, timeout, sk);if (IS_ERR (skb)) {if (!event) -bt_dev_err (hdev,"Opcode 0x%4x failed: %ld" , opcode, +bt_dev_err (hdev,"Opcode 0x%4.4x failed: %ld" , opcode,PTR_ERR (skb));return PTR_ERR (skb); }
Signature · 1 line
2.42.0
Greg Kroah-Hartman
maintainerPATCH 151/603 bpf: Fix unnecessary -EBUSY from htab_lock_bucket
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Song Liu <[email protected]>
[ Upstream commit d35381aa73f7e1e8b25f3ed5283287a64d9ddff5 ]
htab_lock_bucket uses the following logic to avoid recursion:
1. preempt_disable();
2. check percpu counter htab->map_locked[hash] for recursion; 2.1. if map_lock[hash] is already taken, return -BUSY;
3. raw_spin_lock_irqsave();
However, if an IRQ hits between 2 and 3, BPF programs attached to the IRQ logic will not able to access the same hash of the hashtab and get -EBUSY.
This -EBUSY is not really necessary. Fix it by disabling IRQ before checking map_locked:
1. preempt_disable();
2. local_irq_save();
3. check percpu counter htab->map_locked[hash] for recursion; 3.1. if map_lock[hash] is already taken, return -BUSY;
4. raw_spin_lock().
Similarly, use raw_spin_unlock() and local_irq_restore() in htab_unlock_bucket().
--- kernel/bpf/hashtab.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-)
kernel/bpf/hashtab.c +5 -2
@@ -155,13 +155,15 @@ static inline int htab_lock_bucket(const struct bpf_htab *htab, hash = hash &min_t (u32,HASHTAB_MAP_LOCK_MASK , htab->n_buckets -1 );preempt_disable (); +local_irq_save (flags);if (unlikely (__this_cpu_inc_return (*(htab->map_locked[hash])) !=1 )) {__this_cpu_dec (*(htab->map_locked[hash])); +local_irq_restore (flags);preempt_enable ();return -EBUSY ; } -raw_spin_lock_irqsave (&b->raw_lock, flags); +raw_spin_lock (&b->raw_lock); *pflags = flags;return 0 ;
@@ -172,8 +174,9 @@ static inline void htab_unlock_bucket(const struct bpf_htab *htab, unsigned long flags) { hash = hash &min_t (u32,HASHTAB_MAP_LOCK_MASK , htab->n_buckets -1 ); -raw_spin_unlock_irqrestore (&b->raw_lock, flags); +raw_spin_unlock (&b->raw_lock);__this_cpu_dec (*(htab->map_locked[hash])); +local_irq_restore (flags);preempt_enable (); }
Signature · 1 line
2.42.0
Greg Kroah-Hartman
maintainerPATCH 152/603 ACPI: sysfs: Fix create_pnp_modalias() and create_of_modalias()
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Christophe JAILLET <[email protected]>
[ Upstream commit 48cf49d31994ff97b33c4044e618560ec84d35fb ]
snprintf() does not return negative values on error.
To know if the buffer was too small, the returned value needs to be compared with the length of the passed buffer. If it is greater or equal, the output has been truncated, so add checks for the truncation to create_pnp_modalias() and create_of_modalias(). Also make them return -ENOMEM in that case, as they already do that elsewhere.
Moreover, the remaining size of the buffer used by snprintf() needs to be updated after the first write to avoid out-of-bounds access as already done correctly in create_pnp_modalias(), but not in create_of_modalias(), so change the latter accordingly.
--- drivers/acpi/device_sysfs.c | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-)
drivers/acpi/device_sysfs.c +6 -4
@@ -158,8 +158,8 @@ static int create_pnp_modalias(const struct acpi_device *acpi_dev, char *modaliareturn 0 ; len =snprintf (modalias, size,"acpi:" ); -if (len <=0 ) -return len; +if (len >= size) +return -ENOMEM ; size -= len;
@@ -212,8 +212,10 @@ static int create_of_modalias(const struct acpi_device *acpi_dev, char *modalias len =snprintf (modalias, size,"of:N%sT" , (char *)buf.pointer);ACPI_FREE (buf.pointer); -if (len <=0 ) -return len; +if (len >= size) +return -ENOMEM ; + + size -= len; of_compatible = acpi_dev->data.of_compatible;if (of_compatible->type ==ACPI_TYPE_PACKAGE ) {
Signature · 1 line
2.42.0
Greg Kroah-Hartman
maintainerPATCH 153/603 mptcp: properly account fastopen data
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Paolo Abeni <[email protected]>
[ Upstream commit bf0e96108fb6707613dd055aff5e98b02b99bb14 ]
Currently the socket level counter aggregating the received data does not take in account the data received via fastopen.
Address the issue updating the counter as required.
--- net/mptcp/fastopen.c | 1 + 1 file changed, 1 insertion(+)
net/mptcp/fastopen.c +1 -0
@@ -52,6 +52,7 @@ void mptcp_fastopen_subflow_synack_set_params(struct mptcp_subflow_context *subfmptcp_set_owner_r (skb, sk);__skb_queue_tail (&sk->sk_receive_queue, skb); +mptcp_sk (sk)->bytes_received += skb->len; sk->sk_data_ready (sk);
Signature · 1 line
2.42.0
Greg Kroah-Hartman
maintainerPATCH 154/603 ipv6: avoid atomic fragment on GSO packets
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Yan Zhai <[email protected]>
[ Upstream commit 03d6c848bfb406e9ef6d9846d759e97beaeea113 ]
When the ipv6 stack output a GSO packet, if its gso_size is larger than dst MTU, then all segments would be fragmented. However, it is possible for a GSO packet to have a trailing segment with smaller actual size than both gso_size as well as the MTU, which leads to an "atomic fragment". Atomic fragments are considered harmful in RFC-8021. An Existing report from APNIC also shows that atomic fragments are more likely to be dropped even it is equivalent to a no-op [1].
Add an extra check in the GSO slow output path. For each segment from the original over-sized packet, if it fits with the path MTU, then avoid generating an atomic fragment.
--- net/ipv6/ip6_output.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-)
net/ipv6/ip6_output.c +7 -1
@@ -162,7 +162,13 @@ ip6_finish_output_gso_slowpath_drop(struct net *net, struct sock *sk,int err;skb_mark_not_on_list (segs); - err =ip6_fragment (net, sk, segs, ip6_finish_output2); +/* Last GSO segment can be smaller than gso_size (and MTU). +* Adding a fragment header would produce an "atomic fragment", +* which is considered harmful (RFC-8021). Avoid that. +*/ + err = segs->len > mtu ? +ip6_fragment (net, sk, segs, ip6_finish_output2) : +ip6_finish_output2 (net, sk, segs);if (err && ret ==0 ) ret = err; }
Signature · 1 line
2.42.0
Greg Kroah-Hartman
maintainerPATCH 155/603 virtio_net: use u64_stats_t infra to avoid data-races
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Eric Dumazet <[email protected]>
[ Upstream commit 61217d8f6360437329af1b16b8bbd9143167718d ]
syzbot reported a data-race in virtnet_poll / virtnet_stats [1]
u64_stats_t infra has very nice accessors that must be used to avoid potential load-store tearing.
[1]
BUG: KCSAN: data-race in virtnet_poll / virtnet_stats
read-write to 0xffff88810271b1a0 of 8 bytes by interrupt on cpu 0:
virtnet_receive drivers/net/virtio_net.c:2102 [inline] virtnet_poll+0x6c8/0xb40 drivers/net/virtio_net.c:2148 __napi_poll+0x60/0x3b0 net/core/dev.c:6527 napi_poll net/core/dev.c:6594 [inline] net_rx_action+0x32b/0x750 net/core/dev.c:6727 __do_softirq+0xc1/0x265 kernel/softirq.c:553 invoke_softirq kernel/softirq.c:427 [inline] __irq_exit_rcu kernel/softirq.c:632 [inline] irq_exit_rcu+0x3b/0x90 kernel/softirq.c:644 common_interrupt+0x7f/0x90 arch/x86/kernel/irq.c:247 asm_common_interrupt+0x26/0x40 arch/x86/include/asm/idtentry.h:636 __sanitizer_cov_trace_const_cmp8+0x0/0x80 kernel/kcov.c:306 jbd2_write_access_granted fs/jbd2/transaction.c:1174 [inline] jbd2_journal_get_write_access+0x94/0x1c0 fs/jbd2/transaction.c:1239 __ext4_journal_get_write_access+0x154/0x3f0 fs/ext4/ext4_jbd2.c:241 ext4_reserve_inode_write+0x14e/0x200 fs/ext4/inode.c:5745 __ext4_mark_inode_dirty+0x8e/0x440 fs/ext4/inode.c:5919 ext4_evict_inode+0xaf0/0xdc0 fs/ext4/inode.c:299 evict+0x1aa/0x410 fs/inode.c:664 iput_final fs/inode.c:1775 [inline] iput+0x42c/0x5b0 fs/inode.c:1801 do_unlinkat+0x2b9/0x4f0 fs/namei.c:4405 __do_sys_unlink fs/namei.c:4446 [inline] __se_sys_unlink fs/namei.c:4444 [inline] __x64_sys_unlink+0x30/0x40 fs/namei.c:4444 do_syscall_x64 arch/x86/entry/common.c:50 [inline] do_syscall_64+0x41/0xc0 arch/x86/entry/common.c:80 entry_SYSCALL_64_after_hwframe+0x63/0xcd
read to 0xffff88810271b1a0 of 8 bytes by task 2814 on cpu 1:
virtnet_stats+0x1b3/0x340 drivers/net/virtio_net.c:2564 dev_get_stats+0x6d/0x860 net/core/dev.c:10511 rtnl_fill_stats+0x45/0x320 net/core/rtnetlink.c:1261 rtnl_fill_ifinfo+0xd0e/0x1120 net/core/rtnetlink.c:1867 rtnl_dump_ifinfo+0x7f9/0xc20 net/core/rtnetlink.c:2240 netlink_dump+0x390/0x720 net/netlink/af_netlink.c:2266 netlink_recvmsg+0x425/0x780 net/netlink/af_netlink.c:1992 sock_recvmsg_nosec net/socket.c:1027 [inline] sock_recvmsg net/socket.c:1049 [inline] ____sys_recvmsg+0x156/0x310 net/socket.c:2760 ___sys_recvmsg net/socket.c:2802 [inline] __sys_recvmsg+0x1ea/0x270 net/socket.c:2832 __do_sys_recvmsg net/socket.c:2842 [inline] __se_sys_recvmsg net/socket.c:2839 [inline] __x64_sys_recvmsg+0x46/0x50 net/socket.c:2839 do_syscall_x64 arch/x86/entry/common.c:50 [inline] do_syscall_64+0x41/0xc0 arch/x86/entry/common.c:80 entry_SYSCALL_64_after_hwframe+0x63/0xcd
value changed: 0x000000000045c334 -> 0x000000000045c376
--- drivers/net/virtio_net.c | 124 ++++++++++++++++++++------------------- 1 file changed, 65 insertions(+), 59 deletions(-)
drivers/net/virtio_net.c +65 -59
@@ -81,24 +81,24 @@ struct virtnet_stat_desc {struct virtnet_sq_stats {struct u64_stats_sync syncp; -u64 packets; -u64 bytes; -u64 xdp_tx; -u64 xdp_tx_drops; -u64 kicks; -u64 tx_timeouts; +u64_stats_t packets; +u64_stats_t bytes; +u64_stats_t xdp_tx; +u64_stats_t xdp_tx_drops; +u64_stats_t kicks; +u64_stats_t tx_timeouts; };struct virtnet_rq_stats {struct u64_stats_sync syncp; -u64 packets; -u64 bytes; -u64 drops; -u64 xdp_packets; -u64 xdp_tx; -u64 xdp_redirects; -u64 xdp_drops; -u64 kicks; +u64_stats_t packets; +u64_stats_t bytes; +u64_stats_t drops; +u64_stats_t xdp_packets; +u64_stats_t xdp_tx; +u64_stats_t xdp_redirects; +u64_stats_t xdp_drops; +u64_stats_t kicks; };#define VIRTNET_SQ_STAT (m) offsetof(struct virtnet_sq_stats, m)
@@ -775,8 +775,8 @@ static void free_old_xmit_skbs(struct send_queue *sq, bool in_napi)return ;u64_stats_update_begin (&sq->stats.syncp); - sq->stats.bytes += bytes; - sq->stats.packets += packets; +u64_stats_add (&sq->stats.bytes, bytes); +u64_stats_add (&sq->stats.packets, packets);u64_stats_update_end (&sq->stats.syncp); }
@@ -975,11 +975,11 @@ static int virtnet_xdp_xmit(struct net_device *dev, } out:u64_stats_update_begin (&sq->stats.syncp); - sq->stats.bytes += bytes; - sq->stats.packets += packets; - sq->stats.xdp_tx += n; - sq->stats.xdp_tx_drops += n - nxmit; - sq->stats.kicks += kicks; +u64_stats_add (&sq->stats.bytes, bytes); +u64_stats_add (&sq->stats.packets, packets); +u64_stats_add (&sq->stats.xdp_tx, n); +u64_stats_add (&sq->stats.xdp_tx_drops, n - nxmit); +u64_stats_add (&sq->stats.kicks, kicks);u64_stats_update_end (&sq->stats.syncp);virtnet_xdp_put_sq (vi, sq);
@@ -1011,14 +1011,14 @@ static int virtnet_xdp_handler(struct bpf_prog *xdp_prog, struct xdp_buff *xdp,u32 act; act =bpf_prog_run_xdp (xdp_prog, xdp); - stats->xdp_packets++; +u64_stats_inc (&stats->xdp_packets);switch (act) {case XDP_PASS :return act;case XDP_TX : - stats->xdp_tx++; +u64_stats_inc (&stats->xdp_tx); xdpf =xdp_convert_buff_to_frame (xdp);if (unlikely (!xdpf)) {netdev_dbg (dev,"convert buff to frame failed for xdp\n" );
@@ -1036,7 +1036,7 @@ static int virtnet_xdp_handler(struct bpf_prog *xdp_prog, struct xdp_buff *xdp,return act;case XDP_REDIRECT : - stats->xdp_redirects++; +u64_stats_inc (&stats->xdp_redirects); err =xdp_do_redirect (dev, xdp, xdp_prog);if (err)return XDP_DROP ;
@@ -1232,9 +1232,9 @@ static struct sk_buff *receive_small_xdp(struct net_device *dev,return skb; err_xdp: - stats->xdp_drops++; +u64_stats_inc (&stats->xdp_drops); err: - stats->drops++; +u64_stats_inc (&stats->drops);put_page (page); xdp_xmit:return NULL ;
@@ -1253,7 +1253,7 @@ static struct sk_buff *receive_small(struct net_device *dev,struct sk_buff *skb; len -= vi->hdr_len; - stats->bytes += len; +u64_stats_add (&stats->bytes, len);if (unlikely (len >GOOD_PACKET_LEN )) { pr_debug("%s: rx error: len %u exceeds max size %d\n",
@@ -1282,7 +1282,7 @@ static struct sk_buff *receive_small(struct net_device *dev,return skb; err: - stats->drops++; +u64_stats_inc (&stats->drops);put_page (page);return NULL ; }
@@ -1298,14 +1298,14 @@ static struct sk_buff *receive_big(struct net_device *dev,struct sk_buff *skb =page_to_skb (vi, rq, page,0 , len,PAGE_SIZE ,0 ); - stats->bytes += len - vi->hdr_len; +u64_stats_add (&stats->bytes, len - vi->hdr_len);if (unlikely (!skb)) goto err;return skb; err: - stats->drops++; +u64_stats_inc (&stats->drops);give_pages (rq, page);return NULL ; }
@@ -1326,7 +1326,7 @@ static void mergeable_buf_free(struct receive_queue *rq, int num_buf, dev->stats.rx_length_errors++;break ; } - stats->bytes += len; +u64_stats_add (&stats->bytes, len); page =virt_to_head_page (buf);put_page (page); }
@@ -1436,7 +1436,7 @@ static int virtnet_build_xdp_buff_mrg(struct net_device *dev, goto err; } - stats->bytes += len; +u64_stats_add (&stats->bytes, len); page =virt_to_head_page (buf); offset = buf -page_address (page);
@@ -1600,8 +1600,8 @@ static struct sk_buff *receive_mergeable_xdp(struct net_device *dev,put_page (page);mergeable_buf_free (rq, num_buf, dev, stats); - stats->xdp_drops++; - stats->drops++; +u64_stats_inc (&stats->xdp_drops); +u64_stats_inc (&stats->drops);return NULL ; }
@@ -1625,7 +1625,7 @@ static struct sk_buff *receive_mergeable(struct net_device *dev,unsigned int room =SKB_DATA_ALIGN (headroom + tailroom); head_skb =NULL ; - stats->bytes += len - vi->hdr_len; +u64_stats_add (&stats->bytes, len - vi->hdr_len);if (unlikely (len > truesize - room)) { pr_debug("%s: rx error: len %u exceeds truesize %lu\n",
@@ -1666,7 +1666,7 @@ static struct sk_buff *receive_mergeable(struct net_device *dev, goto err_buf; } - stats->bytes += len; +u64_stats_add (&stats->bytes, len); page =virt_to_head_page (buf); truesize =mergeable_ctx_to_truesize (ctx);
@@ -1718,7 +1718,7 @@ static struct sk_buff *receive_mergeable(struct net_device *dev,mergeable_buf_free (rq, num_buf, dev, stats); err_buf: - stats->drops++; +u64_stats_inc (&stats->drops);dev_kfree_skb (head_skb);return NULL ; }
@@ -1985,7 +1985,7 @@ static bool try_fill_recv(struct virtnet_info *vi, struct receive_queue *rq,unsigned long flags; flags =u64_stats_update_begin_irqsave (&rq->stats.syncp); - rq->stats.kicks++; +u64_stats_inc (&rq->stats.kicks);u64_stats_update_end_irqrestore (&rq->stats.syncp, flags); }
@@ -2065,22 +2065,23 @@ static int virtnet_receive(struct receive_queue *rq, int budget,struct virtnet_info *vi = rq->vq->vdev->priv;struct virtnet_rq_stats stats = {};unsigned int len; +int packets =0 ;void *buf;int i;if (!vi->big_packets || vi->mergeable_rx_bufs) {void *ctx; -while (stats.packets < budget && +while (packets < budget && (buf =virtnet_rq_get_buf (rq, &len, &ctx))) {receive_buf (vi, rq, buf, len, ctx, xdp_xmit, &stats); - stats.packets++; + packets++; } }else { -while (stats.packets < budget && +while (packets < budget && (buf =virtnet_rq_get_buf (rq, &len,NULL )) !=NULL ) {receive_buf (vi, rq, buf, len,NULL , xdp_xmit, &stats); - stats.packets++; + packets++; } }
@@ -2093,17 +2094,19 @@ static int virtnet_receive(struct receive_queue *rq, int budget, } } +u64_stats_set (&stats.packets, packets);u64_stats_update_begin (&rq->stats.syncp);for (i =0 ; i <VIRTNET_RQ_STATS_LEN ; i++) {size_t offset = virtnet_rq_stats_desc[i].offset; -u64 *item; +u64_stats_t *item, *src; - item = (u64 *)((u8 *)&rq->stats + offset); - *item += *(u64 *)((u8 *)&stats + offset); + item = (u64_stats_t *)((u8 *)&rq->stats + offset); + src = (u64_stats_t *)((u8 *)&stats + offset); +u64_stats_add (item,u64_stats_read (src)); }u64_stats_update_end (&rq->stats.syncp); -return stats.packets; +return packets; }static void virtnet_poll_cleantx (struct receive_queue *rq)
@@ -2158,7 +2161,7 @@ static int virtnet_poll(struct napi_struct *napi, int budget) sq =virtnet_xdp_get_sq (vi);if (virtqueue_kick_prepare (sq->vq) &&virtqueue_notify (sq->vq)) {u64_stats_update_begin (&sq->stats.syncp); - sq->stats.kicks++; +u64_stats_inc (&sq->stats.kicks);u64_stats_update_end (&sq->stats.syncp); }virtnet_xdp_put_sq (vi, sq);
@@ -2370,7 +2373,7 @@ static netdev_tx_t start_xmit(struct sk_buff *skb, struct net_device *dev)if (kick ||netif_xmit_stopped (txq)) {if (virtqueue_kick_prepare (sq->vq) &&virtqueue_notify (sq->vq)) {u64_stats_update_begin (&sq->stats.syncp); - sq->stats.kicks++; +u64_stats_inc (&sq->stats.kicks);u64_stats_update_end (&sq->stats.syncp); } }
@@ -2553,16 +2556,16 @@ static void virtnet_stats(struct net_device *dev,do { start =u64_stats_fetch_begin (&sq->stats.syncp); - tpackets = sq->stats.packets; - tbytes = sq->stats.bytes; - terrors = sq->stats.tx_timeouts; + tpackets =u64_stats_read (&sq->stats.packets); + tbytes =u64_stats_read (&sq->stats.bytes); + terrors =u64_stats_read (&sq->stats.tx_timeouts); }while (u64_stats_fetch_retry (&sq->stats.syncp, start));do { start =u64_stats_fetch_begin (&rq->stats.syncp); - rpackets = rq->stats.packets; - rbytes = rq->stats.bytes; - rdrops = rq->stats.drops; + rpackets =u64_stats_read (&rq->stats.packets); + rbytes =u64_stats_read (&rq->stats.bytes); + rdrops =u64_stats_read (&rq->stats.drops); }while (u64_stats_fetch_retry (&rq->stats.syncp, start)); tot->rx_packets += rpackets;
@@ -3191,17 +3194,19 @@ static void virtnet_get_ethtool_stats(struct net_device *dev,struct virtnet_info *vi =netdev_priv (dev);unsigned int idx =0 , start, i, j;const u8 *stats_base; +const u64_stats_t *p;size_t offset;for (i =0 ; i < vi->curr_queue_pairs; i++) {struct receive_queue *rq = &vi->rq[i]; - stats_base = (u8 *)&rq->stats; + stats_base = (const u8 *)&rq->stats;do { start =u64_stats_fetch_begin (&rq->stats.syncp);for (j =0 ; j <VIRTNET_RQ_STATS_LEN ; j++) { offset = virtnet_rq_stats_desc[j].offset; - data[idx + j] = *(u64 *)(stats_base + offset); + p = (const u64_stats_t *)(stats_base + offset); + data[idx + j] =u64_stats_read (p); } }while (u64_stats_fetch_retry (&rq->stats.syncp, start)); idx +=VIRTNET_RQ_STATS_LEN ;
@@ -3210,12 +3215,13 @@ static void virtnet_get_ethtool_stats(struct net_device *dev,for (i =0 ; i < vi->curr_queue_pairs; i++) {struct send_queue *sq = &vi->sq[i]; - stats_base = (u8 *)&sq->stats; + stats_base = (const u8 *)&sq->stats;do { start =u64_stats_fetch_begin (&sq->stats.syncp);for (j =0 ; j <VIRTNET_SQ_STATS_LEN ; j++) { offset = virtnet_sq_stats_desc[j].offset; - data[idx + j] = *(u64 *)(stats_base + offset); + p = (const u64_stats_t *)(stats_base + offset); + data[idx + j] =u64_stats_read (p); } }while (u64_stats_fetch_retry (&sq->stats.syncp, start)); idx +=VIRTNET_SQ_STATS_LEN ;
@@ -3898,7 +3904,7 @@ static void virtnet_tx_timeout(struct net_device *dev, unsigned int txqueue)struct netdev_queue *txq =netdev_get_tx_queue (dev, txqueue);u64_stats_update_begin (&sq->stats.syncp); - sq->stats.tx_timeouts++; +u64_stats_inc (&sq->stats.tx_timeouts);u64_stats_update_end (&sq->stats.syncp); netdev_err(dev, "TX timeout on queue: %u, sq: %s, vq: 0x%x, name: %s, %u usecs ago\n",
Signature · 1 line
2.42.0
Greg Kroah-Hartman
maintainerPATCH 156/603 net: add DEV_STATS_READ() helper
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Eric Dumazet <[email protected]>
[ Upstream commit 0b068c714ca9479d2783cc333fff5bc2d4a6d45c ]
Companion of DEV_STATS_INC() & DEV_STATS_ADD().
This is going to be used in the series.
Use it in macsec_get_stats64().
Stable-dep-of: ff672b9ffeb3 ("ipvlan: properly track tx_errors")
--- drivers/net/macsec.c | 6 +++--- include/linux/netdevice.h | 1 + 2 files changed, 4 insertions(+), 3 deletions(-)
drivers/net/macsec.c +3 -3
@@ -3657,9 +3657,9 @@ static void macsec_get_stats64(struct net_device *dev,dev_fetch_sw_netstats (s, dev->tstats); - s->rx_dropped =atomic_long_read (&dev->stats.__rx_dropped); - s->tx_dropped =atomic_long_read (&dev->stats.__tx_dropped); - s->rx_errors =atomic_long_read (&dev->stats.__rx_errors); + s->rx_dropped =DEV_STATS_READ (dev, rx_dropped); + s->tx_dropped =DEV_STATS_READ (dev, tx_dropped); + s->rx_errors =DEV_STATS_READ (dev, rx_errors); }static int macsec_get_iflink (const struct net_device *dev)
include/linux/netdevice.h +1 -0
@@ -5214,5 +5214,6 @@ extern struct net_device *blackhole_netdev;#define DEV_STATS_INC (DEV ,FIELD ) atomic_long_inc(&(DEV)->stats.__##FIELD)#define DEV_STATS_ADD (DEV ,FIELD ,VAL ) \ atomic_long_add((VAL), &(DEV)->stats.__##FIELD) +#define DEV_STATS_READ (DEV ,FIELD ) atomic_long_read(&(DEV)->stats.__##FIELD)#endif /* _LINUX_NETDEVICE_H */
Signature · 1 line
2.42.0
Greg Kroah-Hartman
maintainerPATCH 157/603 ipvlan: properly track tx_errors
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Eric Dumazet <[email protected]>
[ Upstream commit ff672b9ffeb3f82135488ac16c5c5eb4b992999b ]
Both ipvlan_process_v4_outbound() and ipvlan_process_v6_outbound() increment dev->stats.tx_errors in case of errors.
Unfortunately there are two issues :
1) ipvlan_get_stats64() does not propagate dev->stats.tx_errors to user.
2) Increments are not atomic. KCSAN would complain eventually.
Use DEV_STATS_INC() to not miss an update, and change ipvlan_get_stats64() to copy the value back to user.
--- drivers/net/ipvlan/ipvlan_core.c | 8 ++++---- drivers/net/ipvlan/ipvlan_main.c | 1 + 2 files changed, 5 insertions(+), 4 deletions(-)
drivers/net/ipvlan/ipvlan_core.c +4 -4
@@ -441,12 +441,12 @@ static int ipvlan_process_v4_outbound(struct sk_buff *skb) err =ip_local_out (net, skb->sk, skb);if (unlikely (net_xmit_eval (err))) - dev->stats.tx_errors++; +DEV_STATS_INC (dev, tx_errors);else ret =NET_XMIT_SUCCESS ; goto out; err: - dev->stats.tx_errors++; +DEV_STATS_INC (dev, tx_errors);kfree_skb (skb); out:return ret;
@@ -482,12 +482,12 @@ static int ipvlan_process_v6_outbound(struct sk_buff *skb) err =ip6_local_out (net, skb->sk, skb);if (unlikely (net_xmit_eval (err))) - dev->stats.tx_errors++; +DEV_STATS_INC (dev, tx_errors);else ret =NET_XMIT_SUCCESS ; goto out; err: - dev->stats.tx_errors++; +DEV_STATS_INC (dev, tx_errors);kfree_skb (skb); out:return ret;
drivers/net/ipvlan/ipvlan_main.c +1 -0
@@ -324,6 +324,7 @@ static void ipvlan_get_stats64(struct net_device *dev, s->rx_dropped = rx_errs; s->tx_dropped = tx_drps; } + s->tx_errors =DEV_STATS_READ (dev, tx_errors); }static int ipvlan_vlan_rx_add_vid (struct net_device *dev,__be16 proto,u16 vid)
Signature · 1 line
2.42.0
Greg Kroah-Hartman
maintainerPATCH 158/603 regmap: debugfs: Fix a erroneous check after snprintf()
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Christophe JAILLET <[email protected]>
[ Upstream commit d3601857e14de6369f00ae19564f1d817d175d19 ]
This error handling looks really strange.
Check if the string has been truncated instead.
--- drivers/base/regmap/regmap-debugfs.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/base/regmap/regmap-debugfs.c +1 -1
@@ -48,7 +48,7 @@ static ssize_t regmap_name_read_file(struct file *file, name = map->dev->driver->name; ret =snprintf (buf,PAGE_SIZE ,"%s\n" , name); -if (ret <0 ) { +if (ret >=PAGE_SIZE ) {kfree (buf);return ret; }
Signature · 1 line
2.42.0
Greg Kroah-Hartman
maintainerPATCH 159/603 spi: tegra: Fix missing IRQ check in tegra_slink_probe()
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Zhang Shurong <[email protected]>
[ Upstream commit eb9913b511f10968a02cfa5329a896855dd152a3 ]
This func misses checking for platform_get_irq()'s call and may passes the negative error codes to request_irq(), which takes unsigned IRQ #, causing it to fail with -EINVAL, overriding an original error code.
Fix this by stop calling request_irq() with invalid IRQ #s.
--- drivers/spi/spi-tegra20-slink.c | 2 ++ 1 file changed, 2 insertions(+)
drivers/spi/spi-tegra20-slink.c +2 -0
@@ -1086,6 +1086,8 @@ static int tegra_slink_probe(struct platform_device *pdev)reset_control_deassert (tspi->rst); spi_irq =platform_get_irq (pdev,0 ); +if (spi_irq <0 ) +return spi_irq; tspi->irq = spi_irq; ret = request_threaded_irq(tspi->irq, tegra_slink_isr, tegra_slink_isr_thread, IRQF_ONESHOT,
Signature · 1 line
2.42.0
Greg Kroah-Hartman
maintainerPATCH 160/603 clk: qcom: ipq5332: Drop set rate parent from gpll0 dependent clocks
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Varadarajan Narayanan <[email protected]>
[ Upstream commit ccd8ab030643040600a663edde56b434b6f4fb6c ]
IPQ5332's GPLL0's nominal/turbo frequency is 800MHz. This must not be scaled based on the requirement of dependent clocks. Hence remove the CLK_SET_RATE_PARENT flag.
--- drivers/clk/qcom/gcc-ipq5332.c | 2 -- 1 file changed, 2 deletions(-)
drivers/clk/qcom/gcc-ipq5332.c +0 -2
@@ -71,7 +71,6 @@ static struct clk_fixed_factor gpll0_div2 = { &gpll0_main.clkr.hw }, .num_parents = 1, .ops = &clk_fixed_factor_ops, - .flags = CLK_SET_RATE_PARENT, }, };
@@ -85,7 +84,6 @@ static struct clk_alpha_pll_postdiv gpll0 = { &gpll0_main.clkr.hw }, .num_parents = 1, .ops = &clk_alpha_pll_postdiv_ro_ops, - .flags = CLK_SET_RATE_PARENT, }, };
Signature · 1 line
2.42.0
Greg Kroah-Hartman
maintainerPATCH 161/603 clk: qcom: gcc-msm8996: Remove RPM bus clocks
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Konrad Dybcio <[email protected]>
[ Upstream commit 4afda5f6bcdf673ef2556fcfa458daf3a5a648d8 ]
The GCC driver contains clocks that are owned (meaning configured and scaled) by the RPM core.
Remove them from Linux to stop interjecting the RPM's logic.
--- drivers/clk/qcom/gcc-msm8996.c | 237 +-------------------------------- 1 file changed, 5 insertions(+), 232 deletions(-)
drivers/clk/qcom/gcc-msm8996.c +5 -232
@@ -244,71 +244,6 @@ static const struct clk_parent_data gcc_xo_gpll0_gpll4_gpll0_early_div[] = { { .hw = &gpll0_early_div.hw } }; -static const struct freq_tbl ftbl_system_noc_clk_src[] = { -F (19200000 ,P_XO ,1 ,0 ,0 ), -F (50000000 ,P_GPLL0_EARLY_DIV ,6 ,0 ,0 ), -F (100000000 ,P_GPLL0 ,6 ,0 ,0 ), -F (150000000 ,P_GPLL0 ,4 ,0 ,0 ), -F (200000000 ,P_GPLL0 ,3 ,0 ,0 ), -F (240000000 ,P_GPLL0 ,2.5 ,0 ,0 ), - { } -}; - -static struct clk_rcg2 system_noc_clk_src = { - .cmd_rcgr =0x0401c , - .hid_width =5 , - .parent_map = gcc_xo_gpll0_gpll0_early_div_map, - .freq_tbl = ftbl_system_noc_clk_src, - .clkr.hw.init = &(struct clk_init_data ){ - .name ="system_noc_clk_src" , - .parent_data = gcc_xo_gpll0_gpll0_early_div, - .num_parents =ARRAY_SIZE (gcc_xo_gpll0_gpll0_early_div), - .ops = &clk_rcg2_ops, - }, -}; - -static const struct freq_tbl ftbl_config_noc_clk_src[] = { -F (19200000 ,P_XO ,1 ,0 ,0 ), -F (37500000 ,P_GPLL0 ,16 ,0 ,0 ), -F (75000000 ,P_GPLL0 ,8 ,0 ,0 ), - { } -}; - -static struct clk_rcg2 config_noc_clk_src = { - .cmd_rcgr =0x0500c , - .hid_width =5 , - .parent_map = gcc_xo_gpll0_map, - .freq_tbl = ftbl_config_noc_clk_src, - .clkr.hw.init = &(struct clk_init_data ){ - .name ="config_noc_clk_src" , - .parent_data = gcc_xo_gpll0, - .num_parents =ARRAY_SIZE (gcc_xo_gpll0), - .ops = &clk_rcg2_ops, - }, -}; - -static const struct freq_tbl ftbl_periph_noc_clk_src[] = { -F (19200000 ,P_XO ,1 ,0 ,0 ), -F (37500000 ,P_GPLL0 ,16 ,0 ,0 ), -F (50000000 ,P_GPLL0 ,12 ,0 ,0 ), -F (75000000 ,P_GPLL0 ,8 ,0 ,0 ), -F (100000000 ,P_GPLL0 ,6 ,0 ,0 ), - { } -}; - -static struct clk_rcg2 periph_noc_clk_src = { - .cmd_rcgr =0x06014 , - .hid_width =5 , - .parent_map = gcc_xo_gpll0_map, - .freq_tbl = ftbl_periph_noc_clk_src, - .clkr.hw.init = &(struct clk_init_data ){ - .name ="periph_noc_clk_src" , - .parent_data = gcc_xo_gpll0, - .num_parents =ARRAY_SIZE (gcc_xo_gpll0), - .ops = &clk_rcg2_ops, - }, -}; -static const struct freq_tbl ftbl_usb30_master_clk_src[] = {F (19200000 ,P_XO ,1 ,0 ,0 ),F (120000000 ,P_GPLL0 ,5 ,0 ,0 ),
@@ -1297,11 +1232,7 @@ static struct clk_branch gcc_mmss_noc_cfg_ahb_clk = { .enable_mask = BIT(0), .hw.init = &(struct clk_init_data ){ .name ="gcc_mmss_noc_cfg_ahb_clk" , - .parent_hws = (const struct clk_hw *[]){ - &config_noc_clk_src.clkr.hw, - }, - .num_parents =1 , - .flags =CLK_SET_RATE_PARENT |CLK_IGNORE_UNUSED , + .flags =CLK_IGNORE_UNUSED , .ops = &clk_branch2_ops, }, },
@@ -1464,11 +1395,6 @@ static struct clk_branch gcc_usb_phy_cfg_ahb2phy_clk = { .enable_mask = BIT(0), .hw.init = &(struct clk_init_data ){ .name ="gcc_usb_phy_cfg_ahb2phy_clk" , - .parent_hws = (const struct clk_hw *[]){ - &periph_noc_clk_src.clkr.hw, - }, - .num_parents =1 , - .flags =CLK_SET_RATE_PARENT , .ops = &clk_branch2_ops, }, },
@@ -1498,11 +1424,6 @@ static struct clk_branch gcc_sdcc1_ahb_clk = { .enable_mask = BIT(0), .hw.init = &(struct clk_init_data ){ .name ="gcc_sdcc1_ahb_clk" , - .parent_hws = (const struct clk_hw *[]){ - &periph_noc_clk_src.clkr.hw, - }, - .num_parents =1 , - .flags =CLK_SET_RATE_PARENT , .ops = &clk_branch2_ops, }, },
@@ -1549,11 +1470,6 @@ static struct clk_branch gcc_sdcc2_ahb_clk = { .enable_mask = BIT(0), .hw.init = &(struct clk_init_data ){ .name ="gcc_sdcc2_ahb_clk" , - .parent_hws = (const struct clk_hw *[]){ - &periph_noc_clk_src.clkr.hw, - }, - .num_parents =1 , - .flags =CLK_SET_RATE_PARENT , .ops = &clk_branch2_ops, }, },
@@ -1583,11 +1499,6 @@ static struct clk_branch gcc_sdcc3_ahb_clk = { .enable_mask = BIT(0), .hw.init = &(struct clk_init_data ){ .name ="gcc_sdcc3_ahb_clk" , - .parent_hws = (const struct clk_hw *[]){ - &periph_noc_clk_src.clkr.hw, - }, - .num_parents =1 , - .flags =CLK_SET_RATE_PARENT , .ops = &clk_branch2_ops, }, },
@@ -1617,11 +1528,6 @@ static struct clk_branch gcc_sdcc4_ahb_clk = { .enable_mask = BIT(0), .hw.init = &(struct clk_init_data ){ .name ="gcc_sdcc4_ahb_clk" , - .parent_hws = (const struct clk_hw *[]){ - &periph_noc_clk_src.clkr.hw, - }, - .num_parents =1 , - .flags =CLK_SET_RATE_PARENT , .ops = &clk_branch2_ops, }, },
@@ -1635,11 +1541,6 @@ static struct clk_branch gcc_blsp1_ahb_clk = { .enable_mask = BIT(17), .hw.init = &(struct clk_init_data ){ .name ="gcc_blsp1_ahb_clk" , - .parent_hws = (const struct clk_hw *[]){ - &periph_noc_clk_src.clkr.hw, - }, - .num_parents =1 , - .flags =CLK_SET_RATE_PARENT , .ops = &clk_branch2_ops, }, },
@@ -1977,11 +1878,6 @@ static struct clk_branch gcc_blsp2_ahb_clk = { .enable_mask = BIT(15), .hw.init = &(struct clk_init_data ){ .name ="gcc_blsp2_ahb_clk" , - .parent_hws = (const struct clk_hw *[]){ - &periph_noc_clk_src.clkr.hw, - }, - .num_parents =1 , - .flags =CLK_SET_RATE_PARENT , .ops = &clk_branch2_ops, }, },
@@ -2318,11 +2214,6 @@ static struct clk_branch gcc_pdm_ahb_clk = { .enable_mask = BIT(0), .hw.init = &(struct clk_init_data ){ .name ="gcc_pdm_ahb_clk" , - .parent_hws = (const struct clk_hw *[]){ - &periph_noc_clk_src.clkr.hw, - }, - .num_parents =1 , - .flags =CLK_SET_RATE_PARENT , .ops = &clk_branch2_ops, }, },
@@ -2353,11 +2244,6 @@ static struct clk_branch gcc_prng_ahb_clk = { .enable_mask = BIT(13), .hw.init = &(struct clk_init_data ){ .name ="gcc_prng_ahb_clk" , - .parent_hws = (const struct clk_hw *[]){ - &config_noc_clk_src.clkr.hw, - }, - .num_parents =1 , - .flags =CLK_SET_RATE_PARENT , .ops = &clk_branch2_ops, }, },
@@ -2370,11 +2256,6 @@ static struct clk_branch gcc_tsif_ahb_clk = { .enable_mask = BIT(0), .hw.init = &(struct clk_init_data ){ .name ="gcc_tsif_ahb_clk" , - .parent_hws = (const struct clk_hw *[]){ - &periph_noc_clk_src.clkr.hw, - }, - .num_parents =1 , - .flags =CLK_SET_RATE_PARENT , .ops = &clk_branch2_ops, }, },
@@ -2422,11 +2303,6 @@ static struct clk_branch gcc_boot_rom_ahb_clk = { .enable_mask = BIT(10), .hw.init = &(struct clk_init_data ){ .name ="gcc_boot_rom_ahb_clk" , - .parent_hws = (const struct clk_hw *[]){ - &config_noc_clk_src.clkr.hw, - }, - .num_parents =1 , - .flags =CLK_SET_RATE_PARENT , .ops = &clk_branch2_ops, }, },
@@ -2520,11 +2396,6 @@ static struct clk_branch gcc_pcie_0_slv_axi_clk = { .enable_mask = BIT(0), .hw.init = &(struct clk_init_data ){ .name ="gcc_pcie_0_slv_axi_clk" , - .parent_hws = (const struct clk_hw *[]){ - &system_noc_clk_src.clkr.hw, - }, - .num_parents =1 , - .flags =CLK_SET_RATE_PARENT , .ops = &clk_branch2_ops, }, },
@@ -2537,11 +2408,6 @@ static struct clk_branch gcc_pcie_0_mstr_axi_clk = { .enable_mask = BIT(0), .hw.init = &(struct clk_init_data ){ .name ="gcc_pcie_0_mstr_axi_clk" , - .parent_hws = (const struct clk_hw *[]){ - &system_noc_clk_src.clkr.hw, - }, - .num_parents =1 , - .flags =CLK_SET_RATE_PARENT , .ops = &clk_branch2_ops, }, },
@@ -2554,11 +2420,6 @@ static struct clk_branch gcc_pcie_0_cfg_ahb_clk = { .enable_mask = BIT(0), .hw.init = &(struct clk_init_data ){ .name ="gcc_pcie_0_cfg_ahb_clk" , - .parent_hws = (const struct clk_hw *[]){ - &config_noc_clk_src.clkr.hw, - }, - .num_parents =1 , - .flags =CLK_SET_RATE_PARENT , .ops = &clk_branch2_ops, }, },
@@ -2606,11 +2467,6 @@ static struct clk_branch gcc_pcie_1_slv_axi_clk = { .enable_mask = BIT(0), .hw.init = &(struct clk_init_data ){ .name ="gcc_pcie_1_slv_axi_clk" , - .parent_hws = (const struct clk_hw *[]){ - &system_noc_clk_src.clkr.hw, - }, - .num_parents =1 , - .flags =CLK_SET_RATE_PARENT , .ops = &clk_branch2_ops, }, },
@@ -2623,11 +2479,6 @@ static struct clk_branch gcc_pcie_1_mstr_axi_clk = { .enable_mask = BIT(0), .hw.init = &(struct clk_init_data ){ .name ="gcc_pcie_1_mstr_axi_clk" , - .parent_hws = (const struct clk_hw *[]){ - &system_noc_clk_src.clkr.hw, - }, - .num_parents =1 , - .flags =CLK_SET_RATE_PARENT , .ops = &clk_branch2_ops, }, },
@@ -2640,11 +2491,6 @@ static struct clk_branch gcc_pcie_1_cfg_ahb_clk = { .enable_mask = BIT(0), .hw.init = &(struct clk_init_data ){ .name ="gcc_pcie_1_cfg_ahb_clk" , - .parent_hws = (const struct clk_hw *[]){ - &config_noc_clk_src.clkr.hw, - }, - .num_parents =1 , - .flags =CLK_SET_RATE_PARENT , .ops = &clk_branch2_ops, }, },
@@ -2692,11 +2538,6 @@ static struct clk_branch gcc_pcie_2_slv_axi_clk = { .enable_mask = BIT(0), .hw.init = &(struct clk_init_data ){ .name ="gcc_pcie_2_slv_axi_clk" , - .parent_hws = (const struct clk_hw *[]){ - &system_noc_clk_src.clkr.hw, - }, - .num_parents =1 , - .flags =CLK_SET_RATE_PARENT , .ops = &clk_branch2_ops, }, },
@@ -2709,11 +2550,6 @@ static struct clk_branch gcc_pcie_2_mstr_axi_clk = { .enable_mask = BIT(0), .hw.init = &(struct clk_init_data ){ .name ="gcc_pcie_2_mstr_axi_clk" , - .parent_hws = (const struct clk_hw *[]){ - &system_noc_clk_src.clkr.hw, - }, - .num_parents =1 , - .flags =CLK_SET_RATE_PARENT , .ops = &clk_branch2_ops, }, },
@@ -2726,11 +2562,6 @@ static struct clk_branch gcc_pcie_2_cfg_ahb_clk = { .enable_mask = BIT(0), .hw.init = &(struct clk_init_data ){ .name ="gcc_pcie_2_cfg_ahb_clk" , - .parent_hws = (const struct clk_hw *[]){ - &config_noc_clk_src.clkr.hw, - }, - .num_parents =1 , - .flags =CLK_SET_RATE_PARENT , .ops = &clk_branch2_ops, }, },
@@ -2778,11 +2609,6 @@ static struct clk_branch gcc_pcie_phy_cfg_ahb_clk = { .enable_mask = BIT(0), .hw.init = &(struct clk_init_data ){ .name ="gcc_pcie_phy_cfg_ahb_clk" , - .parent_hws = (const struct clk_hw *[]){ - &config_noc_clk_src.clkr.hw, - }, - .num_parents =1 , - .flags =CLK_SET_RATE_PARENT , .ops = &clk_branch2_ops, }, },
@@ -2829,11 +2655,6 @@ static struct clk_branch gcc_ufs_ahb_clk = { .enable_mask = BIT(0), .hw.init = &(struct clk_init_data ){ .name ="gcc_ufs_ahb_clk" , - .parent_hws = (const struct clk_hw *[]){ - &config_noc_clk_src.clkr.hw, - }, - .num_parents =1 , - .flags =CLK_SET_RATE_PARENT , .ops = &clk_branch2_ops, }, },
@@ -3060,11 +2881,7 @@ static struct clk_branch gcc_aggre0_snoc_axi_clk = { .enable_mask = BIT(0), .hw.init = &(struct clk_init_data ){ .name ="gcc_aggre0_snoc_axi_clk" , - .parent_hws = (const struct clk_hw *[]){ - &system_noc_clk_src.clkr.hw, - }, - .num_parents =1 , - .flags =CLK_SET_RATE_PARENT |CLK_IS_CRITICAL , + .flags =CLK_IS_CRITICAL , .ops = &clk_branch2_ops, }, },
@@ -3077,11 +2894,7 @@ static struct clk_branch gcc_aggre0_cnoc_ahb_clk = { .enable_mask = BIT(0), .hw.init = &(struct clk_init_data ){ .name ="gcc_aggre0_cnoc_ahb_clk" , - .parent_hws = (const struct clk_hw *[]){ - &config_noc_clk_src.clkr.hw, - }, - .num_parents =1 , - .flags =CLK_SET_RATE_PARENT |CLK_IS_CRITICAL , + .flags =CLK_IS_CRITICAL , .ops = &clk_branch2_ops, }, },
@@ -3094,11 +2907,7 @@ static struct clk_branch gcc_smmu_aggre0_axi_clk = { .enable_mask = BIT(0), .hw.init = &(struct clk_init_data ){ .name ="gcc_smmu_aggre0_axi_clk" , - .parent_hws = (const struct clk_hw *[]){ - &system_noc_clk_src.clkr.hw, - }, - .num_parents =1 , - .flags =CLK_SET_RATE_PARENT |CLK_IS_CRITICAL , + .flags =CLK_IS_CRITICAL , .ops = &clk_branch2_ops, }, },
@@ -3111,11 +2920,7 @@ static struct clk_branch gcc_smmu_aggre0_ahb_clk = { .enable_mask = BIT(0), .hw.init = &(struct clk_init_data ){ .name ="gcc_smmu_aggre0_ahb_clk" , - .parent_hws = (const struct clk_hw *[]){ - &config_noc_clk_src.clkr.hw, - }, - .num_parents =1 , - .flags =CLK_SET_RATE_PARENT |CLK_IS_CRITICAL , + .flags =CLK_IS_CRITICAL , .ops = &clk_branch2_ops, }, },
@@ -3162,10 +2967,6 @@ static struct clk_branch gcc_dcc_ahb_clk = { .enable_mask = BIT(0), .hw.init = &(struct clk_init_data ){ .name ="gcc_dcc_ahb_clk" , - .parent_hws = (const struct clk_hw *[]){ - &config_noc_clk_src.clkr.hw, - }, - .num_parents =1 , .ops = &clk_branch2_ops, }, },
@@ -3178,10 +2979,6 @@ static struct clk_branch gcc_aggre0_noc_mpu_cfg_ahb_clk = { .enable_mask = BIT(0), .hw.init = &(struct clk_init_data ){ .name ="gcc_aggre0_noc_mpu_cfg_ahb_clk" , - .parent_hws = (const struct clk_hw *[]){ - &config_noc_clk_src.clkr.hw, - }, - .num_parents =1 , .ops = &clk_branch2_ops, }, },
@@ -3194,11 +2991,6 @@ static struct clk_branch gcc_qspi_ahb_clk = { .enable_mask = BIT(0), .hw.init = &(struct clk_init_data ){ .name ="gcc_qspi_ahb_clk" , - .parent_hws = (const struct clk_hw *[]){ - &periph_noc_clk_src.clkr.hw, - }, - .num_parents =1 , - .flags =CLK_SET_RATE_PARENT , .ops = &clk_branch2_ops, }, },
@@ -3347,10 +3139,6 @@ static struct clk_branch gcc_mss_cfg_ahb_clk = { .enable_mask = BIT(0), .hw.init = &(struct clk_init_data ){ .name ="gcc_mss_cfg_ahb_clk" , - .parent_hws = (const struct clk_hw *[]){ - &config_noc_clk_src.clkr.hw, - }, - .num_parents =1 , .ops = &clk_branch2_ops, }, },
@@ -3363,10 +3151,6 @@ static struct clk_branch gcc_mss_mnoc_bimc_axi_clk = { .enable_mask = BIT(0), .hw.init = &(struct clk_init_data ){ .name ="gcc_mss_mnoc_bimc_axi_clk" , - .parent_hws = (const struct clk_hw *[]){ - &system_noc_clk_src.clkr.hw, - }, - .num_parents =1 , .ops = &clk_branch2_ops, }, },
@@ -3379,10 +3163,6 @@ static struct clk_branch gcc_mss_snoc_axi_clk = { .enable_mask = BIT(0), .hw.init = &(struct clk_init_data ){ .name ="gcc_mss_snoc_axi_clk" , - .parent_hws = (const struct clk_hw *[]){ - &system_noc_clk_src.clkr.hw, - }, - .num_parents =1 , .ops = &clk_branch2_ops, }, },
@@ -3395,10 +3175,6 @@ static struct clk_branch gcc_mss_q6_bimc_axi_clk = { .enable_mask = BIT(0), .hw.init = &(struct clk_init_data ){ .name ="gcc_mss_q6_bimc_axi_clk" , - .parent_hws = (const struct clk_hw *[]){ - &system_noc_clk_src.clkr.hw, - }, - .num_parents =1 , .ops = &clk_branch2_ops, }, },
@@ -3495,9 +3271,6 @@ static struct clk_regmap *gcc_msm8996_clocks[] = { [GPLL0] = &gpll0.clkr, [GPLL4_EARLY] = &gpll4_early.clkr, [GPLL4] = &gpll4.clkr, - [SYSTEM_NOC_CLK_SRC] = &system_noc_clk_src.clkr, - [CONFIG_NOC_CLK_SRC] = &config_noc_clk_src.clkr, - [PERIPH_NOC_CLK_SRC] = &periph_noc_clk_src.clkr, [USB30_MASTER_CLK_SRC] = &usb30_master_clk_src.clkr, [USB30_MOCK_UTMI_CLK_SRC] = &usb30_mock_utmi_clk_src.clkr, [USB3_PHY_AUX_CLK_SRC] = &usb3_phy_aux_clk_src.clkr,
Signature · 1 line
2.42.0
Greg Kroah-Hartman
maintainerPATCH 162/603 clk: qcom: clk-rcg2: Fix clock rate overflow for high parent frequencies
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Devi Priya <[email protected]>
[ Upstream commit f7b7d30158cff246667273bd2a62fc93ee0725d2 ]
If the parent clock rate is greater than unsigned long max/2 then integer overflow happens when calculating the clock rate on 32-bit systems. As RCG2 uses half integer dividers, the clock rate is first being multiplied by 2 which will overflow the unsigned long max value. Hence, replace the common pattern of doing 64-bit multiplication and then a do_div() call with simpler mult_frac call.
--- drivers/clk/qcom/clk-rcg2.c | 14 ++++---------- 1 file changed, 4 insertions(+), 10 deletions(-)
drivers/clk/qcom/clk-rcg2.c +4 -10
@@ -158,17 +158,11 @@ static int clk_rcg2_set_parent(struct clk_hw *hw, u8 index)static unsigned long calc_rate (unsigned long rate,u32 m,u32 n,u32 mode,u32 hid_div) { -if (hid_div) { - rate *=2 ; - rate /= hid_div +1 ; - } +if (hid_div) + rate =mult_frac (rate,2 , hid_div +1 ); -if (mode) { -u64 tmp = rate; - tmp *= m; -do_div (tmp, n); - rate = tmp; - } +if (mode) + rate =mult_frac (rate, m, n);return rate; }
Signature · 1 line
2.42.0
Greg Kroah-Hartman
maintainerPATCH 163/603 clk: qcom: mmcc-msm8998: Dont check halt bit on some branch clks
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Konrad Dybcio <[email protected]>
[ Upstream commit 9906c4140897bbdbff7bb71c6ae67903cb9954ce ]
Some branch clocks are governed externally and we're only supposed to send a request concerning their shutdown, not actually ensure it happens.
Use the BRANCH_HALT_SKIP define to skip checking the halt bit.
--- drivers/clk/qcom/mmcc-msm8998.c | 3 +++ 1 file changed, 3 insertions(+)
drivers/clk/qcom/mmcc-msm8998.c +3 -0
@@ -2439,6 +2439,7 @@ static struct clk_branch fd_ahb_clk = {static struct clk_branch mnoc_ahb_clk = { .halt_reg =0x5024 , + .halt_check =BRANCH_HALT_SKIP , .clkr = { .enable_reg =0x5024 , .enable_mask =BIT (0 ),
@@ -2454,6 +2455,7 @@ static struct clk_branch mnoc_ahb_clk = {static struct clk_branch bimc_smmu_ahb_clk = { .halt_reg =0xe004 , + .halt_check =BRANCH_HALT_SKIP , .hwcg_reg =0xe004 , .hwcg_bit =1 , .clkr = {
@@ -2471,6 +2473,7 @@ static struct clk_branch bimc_smmu_ahb_clk = {static struct clk_branch bimc_smmu_axi_clk = { .halt_reg =0xe008 , + .halt_check =BRANCH_HALT_SKIP , .hwcg_reg =0xe008 , .hwcg_bit =1 , .clkr = {
Signature · 1 line
2.42.0
Greg Kroah-Hartman
maintainerPATCH 164/603 clk: qcom: mmcc-msm8998: Fix the SMMU GDSC
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Konrad Dybcio <[email protected]>
[ Upstream commit 1fc62c8347397faf4e18249e88ecd4470c0a5357 ]
The SMMU GDSC doesn't have to be ALWAYS-ON and shouldn't feature the HW_CTRL flag (it's separate from hw_ctrl_addr). In addition to that, it should feature a cxc entry for bimc_smmu_axi_clk and be marked as votable.
Fix all of these issues.
--- drivers/clk/qcom/mmcc-msm8998.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-)
drivers/clk/qcom/mmcc-msm8998.c +3 -1
@@ -2610,11 +2610,13 @@ static struct gdsc camss_cpp_gdsc = {static struct gdsc bimc_smmu_gdsc = { .gdscr =0xe020 , .gds_hw_ctrl =0xe024 , + .cxcs = (unsigned int []){0xe008 }, + .cxc_count =1 , .pd = { .name ="bimc_smmu" , }, .pwrsts =PWRSTS_OFF_ON , - .flags =HW_CTRL |ALWAYS_ON , + .flags =VOTABLE , };static struct clk_regmap *mmcc_msm8998_clocks[] = {
Signature · 1 line
2.42.0
Greg Kroah-Hartman
maintainerPATCH 165/603 clk: qcom: gcc-sm8150: Fix gcc_sdcc2_apps_clk_src
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Danila Tikhonov <[email protected]>
[ Upstream commit 7138c244fb293f24ce8ab782961022eff00a10c4 ]
Set .flags = CLK_OPS_PARENT_ENABLE to fix "gcc_sdcc2_apps_clk_src: rcg didn't update its configuration" error.
--- drivers/clk/qcom/gcc-sm8150.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/clk/qcom/gcc-sm8150.c +1 -1
@@ -774,7 +774,7 @@ static struct clk_rcg2 gcc_sdcc2_apps_clk_src = { .name = "gcc_sdcc2_apps_clk_src", .parent_data = gcc_parents_6, .num_parents = ARRAY_SIZE(gcc_parents_6), - .flags = CLK_SET_RATE_PARENT, + .flags = CLK_OPS_PARENT_ENABLE, .ops = &clk_rcg2_floor_ops, }, };
Signature · 1 line
2.42.0
Greg Kroah-Hartman
maintainerPATCH 166/603 gpio: sim: initialize a managed pointer when declaring it
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Bartosz Golaszewski <[email protected]>
[ Upstream commit 9f93f18305f5777820491e6ab9b34422c160371b ]
Variables managed with __free() should typically be initialized where they are declared so that the __free() callback is paired with its counterpart resource allocator. Fix the second instance of using __free() in gpio-sim to follow this pattern.
--- drivers/gpio/gpio-sim.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
drivers/gpio/gpio-sim.c +2 -2
@@ -1438,10 +1438,10 @@ static const struct config_item_type gpio_sim_device_config_group_type = {static struct config_group *gpio_sim_config_make_device_group (struct config_group *group,const char *name) { - struct gpio_sim_device *dev __free(kfree) = NULL;int id; - dev =kzalloc (sizeof (*dev),GFP_KERNEL ); + struct gpio_sim_device *dev __free(kfree) = kzalloc(sizeof(*dev), +GFP_KERNEL );if (!dev)return ERR_PTR (-ENOMEM );
Signature · 1 line
2.42.0
Greg Kroah-Hartman
maintainerPATCH 167/603 regulator: mt6358: Fail probe on unknown chip ID
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Chen-Yu Tsai <[email protected]>
[ Upstream commit 7442edec72bc657e6ce38ae01de9f10e55decfaa ]
The MT6358 and MT6366 PMICs, and likely many others from MediaTek, have a chip ID register, making the chip semi-discoverable.
The driver currently supports two PMICs and expects to be probed on one or the other. It does not account for incorrect mfd driver entries or device trees. While these should not happen, if they do, it could be catastrophic for the device. The driver should be sure the hardware is what it expects.
Make the driver fail to probe if the chip ID presented is not a known one.
--- drivers/regulator/mt6358-regulator.c | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-)
drivers/regulator/mt6358-regulator.c +10 -4
@@ -688,12 +688,18 @@ static int mt6358_regulator_probe(struct platform_device *pdev)const struct mt6358_regulator_info *mt6358_info;int i, max_regulator, ret; -if (mt6397->chip_id ==MT6366_CHIP_ID ) { - max_regulator =MT6366_MAX_REGULATOR ; - mt6358_info = mt6366_regulators; - }else { +switch (mt6397->chip_id) { +case MT6358_CHIP_ID : max_regulator =MT6358_MAX_REGULATOR ; mt6358_info = mt6358_regulators; +break ; +case MT6366_CHIP_ID : + max_regulator =MT6366_MAX_REGULATOR ; + mt6358_info = mt6366_regulators; +break ; +default : +dev_err (&pdev->dev,"unsupported chip ID: %d\n" , mt6397->chip_id); +return -EINVAL ; } ret =mt6358_sync_vcn33_setting (&pdev->dev);
Signature · 1 line
2.42.0
Greg Kroah-Hartman
maintainerPATCH 168/603 clk: imx: Select MXC_CLK for CLK_IMX8QXP
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Abel Vesa <[email protected]>
[ Upstream commit 317e69c49b4ceef8aebb47d771498ccb3571bdf9 ]
If the i.MX8QXP clock provider is built-in but the MXC_CLK is built as module, build fails:
aarch64-linux-ld: drivers/clk/imx/clk-imx8-acm.o: in function `imx8_acm_clk_probe':
clk-imx8-acm.c:(.text+0x3d0): undefined reference to `imx_check_clk_hws'
Fix that by selecting MXC_CLK in case of CLK_IMX8QXP.
--- drivers/clk/imx/Kconfig | 1 + 1 file changed, 1 insertion(+)
drivers/clk/imx/Kconfig +1 -0
@@ -96,6 +96,7 @@ config CLK_IMX8QXP depends on (ARCH_MXC && ARM64) || COMPILE_TEST depends on IMX_SCU && HAVE_ARM_SMCCC select MXC_CLK_SCU + select MXC_CLK help Build the driver for IMX8QXP SCU based clocks.
Signature · 1 line
2.42.0
Greg Kroah-Hartman
maintainerPATCH 169/603 clk: imx: imx8: Fix an error handling path in clk_imx_acm_attach_pm_domains()
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Christophe JAILLET <[email protected]>
[ Upstream commit 156624e2cf815ce98fad5a24f04370f4459ae6f4 ]
If a dev_pm_domain_attach_by_id() call fails, previously allocated resources need to be released.
--- drivers/clk/imx/clk-imx8-acm.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-)
drivers/clk/imx/clk-imx8-acm.c +4 -2
@@ -279,8 +279,10 @@ static int clk_imx_acm_attach_pm_domains(struct device *dev,for (i =0 ; i < dev_pm->num_domains; i++) { dev_pm->pd_dev[i] =dev_pm_domain_attach_by_id (dev, i); -if (IS_ERR (dev_pm->pd_dev[i])) -return PTR_ERR (dev_pm->pd_dev[i]); +if (IS_ERR (dev_pm->pd_dev[i])) { + ret =PTR_ERR (dev_pm->pd_dev[i]); + goto detach_pm; + } dev_pm->pd_dev_link[i] = device_link_add(dev, dev_pm->pd_dev[i],
Signature · 1 line
2.42.0
Greg Kroah-Hartman
maintainerPATCH 170/603 clk: imx: imx8: Fix an error handling path if devm_clk_hw_register_mux_parent_data_table() fails
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Christophe JAILLET <[email protected]>
[ Upstream commit 9a0108acdb1b6189dcc8f9318edfc6b7e0281df4 ]
If a devm_clk_hw_register_mux_parent_data_table() call fails, it is likely that the probe should fail with an error code.
Set 'ret' before leaving the function.
--- drivers/clk/imx/clk-imx8-acm.c | 1 + 1 file changed, 1 insertion(+)
drivers/clk/imx/clk-imx8-acm.c +1 -0
@@ -373,6 +373,7 @@ static int imx8_acm_clk_probe(struct platform_device *pdev) sels[i].shift, sels[i].width, 0, NULL, NULL);if (IS_ERR (hws[sels[i].clkid])) { + ret =PTR_ERR (hws[sels[i].clkid]);pm_runtime_disable (&pdev->dev); goto err_clk_register; }
Signature · 1 line
2.42.0
Greg Kroah-Hartman
maintainerPATCH 171/603 clk: imx: imx8: Fix an error handling path in imx8_acm_clk_probe()
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Christophe JAILLET <[email protected]>
[ Upstream commit e9a164e367f039629fd5466a79b9f495646e1261 ]
If an error occurs after a successful clk_imx_acm_attach_pm_domains() call, it must be undone.
Add an explicit error handling path, re-order the code and add the missing clk_imx_acm_detach_pm_domains() call.
--- drivers/clk/imx/clk-imx8-acm.c | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-)
drivers/clk/imx/clk-imx8-acm.c +6 -3
@@ -374,7 +374,6 @@ static int imx8_acm_clk_probe(struct platform_device *pdev) 0, NULL, NULL);if (IS_ERR (hws[sels[i].clkid])) { ret =PTR_ERR (hws[sels[i].clkid]); -pm_runtime_disable (&pdev->dev); goto err_clk_register; } }
@@ -384,12 +383,16 @@ static int imx8_acm_clk_probe(struct platform_device *pdev) ret =devm_of_clk_add_hw_provider (dev, of_clk_hw_onecell_get, clk_hw_data);if (ret <0 ) {dev_err (dev,"failed to register hws for ACM\n" ); -pm_runtime_disable (&pdev->dev); + goto err_clk_register; } -err_clk_register: +pm_runtime_put_sync (&pdev->dev); +return 0 ; +err_clk_register:pm_runtime_put_sync (&pdev->dev); +pm_runtime_disable (&pdev->dev); +clk_imx_acm_detach_pm_domains (&pdev->dev, &priv->dev_pm);return ret; }
Signature · 1 line
2.42.0
Greg Kroah-Hartman
maintainerPATCH 172/603 clk: imx: imx8mq: correct error handling path
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Peng Fan <[email protected]>
[ Upstream commit 577ad169966e6e75b10e004389a3f79813e84b5d ]
Avoid memory leak in error handling path. It does not make much sense for the SoC without clk driver, to make program behavior correct, let's fix it.
--- drivers/clk/imx/clk-imx8mq.c | 17 ++++++++++------- 1 file changed, 10 insertions(+), 7 deletions(-)
drivers/clk/imx/clk-imx8mq.c +10 -7
@@ -288,8 +288,7 @@ static int imx8mq_clocks_probe(struct platform_device *pdev)void __iomem *base;int err; - clk_hw_data =kzalloc (struct_size (clk_hw_data, hws, -IMX8MQ_CLK_END ),GFP_KERNEL ); + clk_hw_data =devm_kzalloc (dev,struct_size (clk_hw_data, hws,IMX8MQ_CLK_END ),GFP_KERNEL );if (WARN_ON (!clk_hw_data))return -ENOMEM ;
@@ -306,10 +305,12 @@ static int imx8mq_clocks_probe(struct platform_device *pdev) hws[IMX8MQ_CLK_EXT4 ] =imx_get_clk_hw_by_name (np,"clk_ext4" ); np =of_find_compatible_node (NULL ,NULL ,"fsl,imx8mq-anatop" ); - base =of_iomap (np,0 ); + base =devm_of_iomap (dev, np,0 ,NULL );of_node_put (np); -if (WARN_ON (!base)) -return -ENOMEM ; +if (WARN_ON (IS_ERR (base))) { + err =PTR_ERR (base); + goto unregister_hws; + } hws[IMX8MQ_ARM_PLL_REF_SEL ] =imx_clk_hw_mux ("arm_pll_ref_sel" , base +0x28 ,16 ,2 , pll_ref_sels,ARRAY_SIZE (pll_ref_sels)); hws[IMX8MQ_GPU_PLL_REF_SEL ] =imx_clk_hw_mux ("gpu_pll_ref_sel" , base +0x18 ,16 ,2 , pll_ref_sels,ARRAY_SIZE (pll_ref_sels));
@@ -395,8 +396,10 @@ static int imx8mq_clocks_probe(struct platform_device *pdev) np = dev->of_node; base =devm_platform_ioremap_resource (pdev,0 ); -if (WARN_ON (IS_ERR (base))) -return PTR_ERR (base); +if (WARN_ON (IS_ERR (base))) { + err =PTR_ERR (base); + goto unregister_hws; + }/* CORE */ hws[IMX8MQ_CLK_A53_DIV ] =imx8m_clk_hw_composite_core ("arm_a53_div" , imx8mq_a53_sels, base +0x8000 );
Signature · 1 line
2.42.0
Greg Kroah-Hartman
maintainerPATCH 173/603 clk: imx: imx8qxp: Fix elcdif_pll clock
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Robert Chiras <[email protected]>
[ Upstream commit 15cee75dacb82ade710d61bfd536011933ef9bf2 ]
Move the elcdif_pll clock initialization before the lcd_clk, since the elcdif_clk needs to be initialized ahead of lcd_clk, being its parent. This change fixes issues with the LCD clocks during suspend/resume.
--- drivers/clk/imx/clk-imx8qxp.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/clk/imx/clk-imx8qxp.c +1 -1
@@ -147,10 +147,10 @@ static int imx8qxp_clk_probe(struct platform_device *pdev)imx_clk_scu ("adc0_clk" ,IMX_SC_R_ADC_0 ,IMX_SC_PM_CLK_PER );imx_clk_scu ("adc1_clk" ,IMX_SC_R_ADC_1 ,IMX_SC_PM_CLK_PER );imx_clk_scu ("pwm_clk" ,IMX_SC_R_LCD_0_PWM_0 ,IMX_SC_PM_CLK_PER ); +imx_clk_scu ("elcdif_pll" ,IMX_SC_R_ELCDIF_PLL ,IMX_SC_PM_CLK_PLL );imx_clk_scu2 ("lcd_clk" , lcd_sels,ARRAY_SIZE (lcd_sels),IMX_SC_R_LCD_0 ,IMX_SC_PM_CLK_PER );imx_clk_scu2 ("lcd_pxl_clk" , lcd_pxl_sels,ARRAY_SIZE (lcd_pxl_sels),IMX_SC_R_LCD_0 ,IMX_SC_PM_CLK_MISC0 );imx_clk_scu ("lcd_pxl_bypass_div_clk" ,IMX_SC_R_LCD_0 ,IMX_SC_PM_CLK_BYPASS ); -imx_clk_scu ("elcdif_pll" ,IMX_SC_R_ELCDIF_PLL ,IMX_SC_PM_CLK_PLL );/* Audio SS */ imx_clk_scu ("audio_pll0_clk" ,IMX_SC_R_AUDIO_PLL_0 ,IMX_SC_PM_CLK_PLL );
Signature · 1 line
2.42.0
Greg Kroah-Hartman
maintainerPATCH 174/603 clk: renesas: rcar-gen3: Extend SDnH divider table
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Dirk Behme <[email protected]>
[ Upstream commit d5252d9697a3e7007c741e9c103073868955a304 ]
The clock dividers might be used with clock stop bit enabled or not. Current tables only support recommended values from the datasheet. This might result in warnings like below because no valid clock divider is found. Resulting in a 0 divider.
There are Renesas ARM Trusted Firmware version out there which e.g. configure 0x201 (shifted logical right by 2: 0x80) and with this match the added { STPnHCK | 0, 1 }:
------------[ cut here ]------------ sd1h: Zero divisor and CLK_DIVIDER_ALLOW_ZERO not set WARNING: CPU: 1 PID: 1 at drivers/clk/clk-divider.c:141 divider_recalc_rate+0x48/0x70 Modules linked in: CPU: 1 PID: 1 Comm: swapper/0 Not tainted 6.1.52 #1 Hardware name: Custom board based on r8a7796 (DT) pstate: 40000005 (nZcv daif -PAN -UAO -TCO -DIT -SSBS BTYPE=--) pc : divider_recalc_rate+0x48/0x70 ... ------------[ cut here ]------------
--- drivers/clk/renesas/rcar-cpg-lib.c | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-)
drivers/clk/renesas/rcar-cpg-lib.c +14 -1
@@ -70,8 +70,21 @@ void cpg_simple_notifier_register(struct raw_notifier_head *notifiers,#define STPnHCK BIT(9 - SDnSRCFC_SHIFT)static const struct clk_div_table cpg_sdh_div_table[] = { +/* +* These values are recommended by the datasheet. Because they come +* first, Linux will only use these. +*/ {0 ,1 }, {1 ,2 }, { STPnHCK |2 ,4 }, { STPnHCK |3 ,8 }, - { STPnHCK |4 ,16 }, {0 ,0 }, + { STPnHCK |4 ,16 }, +/* +* These values are not recommended because STPnHCK is wrong. But they +* have been seen because of broken firmware. So, we support reading +* them but Linux will sanitize them when initializing through +* recalc_rate. +*/ + { STPnHCK |0 ,1 }, { STPnHCK |1 ,2 }, {2 ,4 }, {3 ,8 }, {4 ,16 }, +/* Sentinel */ + {0 ,0 } }; struct clk * __init cpg_sdh_clk_register(const char *name,
Signature · 1 line
2.42.0
Greg Kroah-Hartman
maintainerPATCH 175/603 clk: renesas: rzg2l: Wait for status bit of SD mux before continuing
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Claudiu Beznea <[email protected]>
[ Upstream commit 549f4ae2601f968e2474c6031fb4799468882f64 ]
The hardware user manual for RZ/G2L (r01uh0914ej0130-rzg2l-rzg2lc.pdf, chapter 7.4.7 Procedure for Switching Clocks by the Dynamic Switching Frequency Selectors) specifies that we need to check CPG_PL2SDHI_DSEL for SD clock switching status.
--- drivers/clk/renesas/rzg2l-cpg.c | 17 ++++++++++------- 1 file changed, 10 insertions(+), 7 deletions(-)
drivers/clk/renesas/rzg2l-cpg.c +10 -7
@@ -188,7 +188,8 @@ static int rzg2l_cpg_sd_clk_mux_set_parent(struct clk_hw *hw, u8 index)u32 off =GET_REG_OFFSET (hwdata->conf);u32 shift =GET_SHIFT (hwdata->conf);const u32 clk_src_266 =2 ; -u32 bitmask; +u32 msk, val, bitmask; +int ret;/* * As per the HW manual, we should not directly switch from 533 MHz to
@@ -202,14 +203,10 @@ static int rzg2l_cpg_sd_clk_mux_set_parent(struct clk_hw *hw, u8 index)* the index to value mapping is done by adding 1 to the index. */ bitmask = (GENMASK (GET_WIDTH (hwdata->conf) -1 ,0 ) << shift) <<16 ; + msk = off ?CPG_CLKSTATUS_SELSDHI1_STS :CPG_CLKSTATUS_SELSDHI0_STS ;if (index != clk_src_266) { -u32 msk, val; -int ret; -writel (bitmask | ((clk_src_266 +1 ) << shift), priv->base + off); - msk = off ?CPG_CLKSTATUS_SELSDHI1_STS :CPG_CLKSTATUS_SELSDHI0_STS ; - ret =readl_poll_timeout (priv->base +CPG_CLKSTATUS , val, !(val & msk),100 ,CPG_SDHI_CLK_SWITCH_STATUS_TIMEOUT_US );
@@ -221,7 +218,13 @@ static int rzg2l_cpg_sd_clk_mux_set_parent(struct clk_hw *hw, u8 index)writel (bitmask | ((index +1 ) << shift), priv->base + off); -return 0 ; + ret =readl_poll_timeout (priv->base +CPG_CLKSTATUS , val, + !(val & msk),100 , +CPG_SDHI_CLK_SWITCH_STATUS_TIMEOUT_US ); +if (ret) +dev_err (priv->dev,"failed to switch clk source\n" ); + +return ret; }static u8 rzg2l_cpg_sd_clk_mux_get_parent (struct clk_hw *hw)
Signature · 1 line
2.42.0
Greg Kroah-Hartman
maintainerPATCH 176/603 clk: renesas: rzg2l: Lock around writes to mux register
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Claudiu Beznea <[email protected]>
[ Upstream commit d2692ed490e680a41401cef879adebcfafb4298f ]
The SD MUX output (SD0) is further divided by 4 in G2{L,UL}. The divided clock is SD0_DIV4. SD0_DIV4 is registered with CLK_SET_RATE_PARENT which means a rate request for it is propagated to the MUX and could reach rzg2l_cpg_sd_clk_mux_set_parent() concurrently with the users of SD0.
Add proper locking to avoid concurrent accesses on SD MUX set rate registers.
--- drivers/clk/renesas/rzg2l-cpg.c | 23 +++++++++++++---------- drivers/clk/renesas/rzg2l-cpg.h | 2 +- 2 files changed, 14 insertions(+), 11 deletions(-)
drivers/clk/renesas/rzg2l-cpg.c +13 -10
@@ -189,6 +189,7 @@ static int rzg2l_cpg_sd_clk_mux_set_parent(struct clk_hw *hw, u8 index)u32 shift =GET_SHIFT (hwdata->conf);const u32 clk_src_266 =2 ;u32 msk, val, bitmask; +unsigned long flags;int ret;/*
@@ -204,23 +205,25 @@ static int rzg2l_cpg_sd_clk_mux_set_parent(struct clk_hw *hw, u8 index)*/ bitmask = (GENMASK (GET_WIDTH (hwdata->conf) -1 ,0 ) << shift) <<16 ; msk = off ?CPG_CLKSTATUS_SELSDHI1_STS :CPG_CLKSTATUS_SELSDHI0_STS ; +spin_lock_irqsave (&priv->rmw_lock, flags);if (index != clk_src_266) {writel (bitmask | ((clk_src_266 +1 ) << shift), priv->base + off); - ret =readl_poll_timeout (priv->base +CPG_CLKSTATUS , val, - !(val & msk),100 , -CPG_SDHI_CLK_SWITCH_STATUS_TIMEOUT_US ); -if (ret) { -dev_err (priv->dev,"failed to switch clk source\n" ); -return ret; - } + ret =readl_poll_timeout_atomic (priv->base +CPG_CLKSTATUS , val, + !(val & msk),10 , +CPG_SDHI_CLK_SWITCH_STATUS_TIMEOUT_US ); +if (ret) + goto unlock; }writel (bitmask | ((index +1 ) << shift), priv->base + off); - ret =readl_poll_timeout (priv->base +CPG_CLKSTATUS , val, - !(val & msk),100 , -CPG_SDHI_CLK_SWITCH_STATUS_TIMEOUT_US ); + ret =readl_poll_timeout_atomic (priv->base +CPG_CLKSTATUS , val, + !(val & msk),10 , +CPG_SDHI_CLK_SWITCH_STATUS_TIMEOUT_US ); +unlock: +spin_unlock_irqrestore (&priv->rmw_lock, flags); +if (ret)dev_err (priv->dev,"failed to switch clk source\n" );
drivers/clk/renesas/rzg2l-cpg.h +1 -1
@@ -43,7 +43,7 @@#define CPG_CLKSTATUS_SELSDHI0_STS BIT(28)#define CPG_CLKSTATUS_SELSDHI1_STS BIT(29) -#define CPG_SDHI_CLK_SWITCH_STATUS_TIMEOUT_US 20000 +#define CPG_SDHI_CLK_SWITCH_STATUS_TIMEOUT_US 200/* n = 0/1/2 for PLL1/4/6 */ #define CPG_SAMPLL_CLK1 (n) (0x04 + (16 * n))
Signature · 1 line
2.42.0
Greg Kroah-Hartman
maintainerPATCH 177/603 clk: renesas: rzg2l: Trust value returned by hardware
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Claudiu Beznea <[email protected]>
[ Upstream commit bf51d3b2d048c312764a55d91d67a85ee5535e31 ]
The onitial value of the CPG_PL2SDHI_DSEL bits 0..1 or 4..6 is 01b. The hardware user's manual (r01uh0914ej0130-rzg2l-rzg2lc.pdf) specifies that setting 0 is prohibited. Hence rzg2l_cpg_sd_clk_mux_get_parent() should just read CPG_PL2SDHI_DSEL, trust the value, and return the proper clock parent index based on the value read.
--- drivers/clk/renesas/rzg2l-cpg.c | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-)
drivers/clk/renesas/rzg2l-cpg.c +1 -7
@@ -238,14 +238,8 @@ static u8 rzg2l_cpg_sd_clk_mux_get_parent(struct clk_hw *hw) val >>=GET_SHIFT (hwdata->conf); val &=GENMASK (GET_WIDTH (hwdata->conf) -1 ,0 ); -if (val) { - val--; - }else { -/* Prohibited clk source, change it to 533 MHz(reset value) */ -rzg2l_cpg_sd_clk_mux_set_parent (hw,0 ); - } -return val; +return val ? val -1 :0 ; }static const struct clk_ops rzg2l_cpg_sd_clk_mux_ops = {
Signature · 1 line
2.42.0
Greg Kroah-Hartman
maintainerPATCH 178/603 clk: renesas: rzg2l: Use FIELD_GET() for PLL register fields
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Claudiu Beznea <[email protected]>
[ Upstream commit 72977f07b035e488c3f1928832a1616c6cae7278 ]
Use FIELD_GET() for PLL register fields. This is its purpose.
Stable-dep-of: a2b23159499e ("clk: renesas: rzg2l: Fix computation formula")
--- drivers/clk/renesas/rzg2l-cpg.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-)
drivers/clk/renesas/rzg2l-cpg.c +5 -5
@@ -11,6 +11,7 @@* Copyright (C) 2015 Renesas Electronics Corp. */ +#include <linux/bitfield.h> #include <linux/clk.h> #include <linux/clk-provider.h> #include <linux/clk/renesas.h>
@@ -38,14 +39,13 @@#define WARN_DEBUG (x) do { } while (0)#endif -#define DIV_RSMASK (v, s, m) ((v >> s) & m)#define GET_SHIFT (val) ((val >> 12) & 0xff)#define GET_WIDTH (val) ((val >> 8) & 0xf) -#define KDIV (val) DIV_RSMASK(val, 16, 0xffff) -#define MDIV (val) DIV_RSMASK(val, 6, 0x3ff) -#define PDIV (val) DIV_RSMASK(val, 0, 0x3f) -#define SDIV (val) DIV_RSMASK(val, 0, 0x7) +#define KDIV (val) FIELD_GET(GENMASK(31, 16), val) +#define MDIV (val) FIELD_GET(GENMASK(15, 6), val) +#define PDIV (val) FIELD_GET(GENMASK(5, 0), val) +#define SDIV (val) FIELD_GET(GENMASK(2, 0), val)#define CLK_ON_R (reg) (reg)#define CLK_MON_R (reg) (0x180 + (reg))
Signature · 1 line
2.42.0
Greg Kroah-Hartman
maintainerPATCH 179/603 clk: renesas: rzg2l: Fix computation formula
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Claudiu Beznea <[email protected]>
[ Upstream commit a2b23159499efd36b2d63b3c4534075d12ddc97a ]
According to the hardware manual for RZ/G2L (r01uh0914ej0130-rzg2l-rzg2lc.pdf), the computation formula for PLL rate is as follows:
Fout = ((m + k/65536) * Fin) / (p * 2^s)
and k has values in the range [-32768, 32767]. Dividing k by 65536 with integer arithmetic gives zero all the time, causing slight differences b/w what has been set vs. what is displayed. Thus, get rid of this and decompose the formula before dividing k by 65536.
--- drivers/clk/renesas/rzg2l-cpg.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-)
drivers/clk/renesas/rzg2l-cpg.c +6 -6
@@ -42,7 +42,7 @@#define GET_SHIFT (val) ((val >> 12) & 0xff)#define GET_WIDTH (val) ((val >> 8) & 0xf) -#define KDIV (val) FIELD_GET(GENMASK(31, 16), val) +#define KDIV (val) ((s16)FIELD_GET(GENMASK(31, 16), val))#define MDIV (val) FIELD_GET(GENMASK(15, 6), val)#define PDIV (val) FIELD_GET(GENMASK(5, 0), val)#define SDIV (val) FIELD_GET(GENMASK(2, 0), val)
@@ -695,18 +695,18 @@ static unsigned long rzg2l_cpg_pll_clk_recalc_rate(struct clk_hw *hw,struct pll_clk *pll_clk =to_pll (hw);struct rzg2l_cpg_priv *priv = pll_clk->priv;unsigned int val1, val2; -unsigned int mult =1 ; -unsigned int div =1 ; +u64 rate;if (pll_clk->type !=CLK_TYPE_SAM_PLL )return parent_rate; val1 =readl (priv->base +GET_REG_SAMPLL_CLK1 (pll_clk->conf)); val2 =readl (priv->base +GET_REG_SAMPLL_CLK2 (pll_clk->conf)); - mult =MDIV (val1) +KDIV (val1) /65536 ; - div =PDIV (val1) <<SDIV (val2); -return DIV_ROUND_CLOSEST_ULL ((u64 )parent_rate * mult, div); + rate =mul_u64_u32_shr (parent_rate, (MDIV (val1) <<16 ) +KDIV (val1), +16 +SDIV (val2)); + +return DIV_ROUND_CLOSEST_ULL (rate,PDIV (val1)); }static const struct clk_ops rzg2l_cpg_pll_ops = {
Signature · 1 line
2.42.0
Greg Kroah-Hartman
maintainerPATCH 180/603 clk: linux/clk-provider.h: fix kernel-doc warnings and typos
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Randy Dunlap <[email protected]>
[ Upstream commit 84aefafe6b294041b7fa0757414c4a29c1bdeea2 ]
Fix spelling of "Structure".
Fix multiple kernel-doc warnings:
clk-provider.h:269: warning: Function parameter or member 'recalc_rate' not described in 'clk_ops'
clk-provider.h:468: warning: Function parameter or member 'parent_data' not described in 'clk_hw_register_fixed_rate_with_accuracy_parent_data' clk-provider.h:468: warning: Excess function parameter 'parent_name' description in 'clk_hw_register_fixed_rate_with_accuracy_parent_data' clk-provider.h:482: warning: Function parameter or member 'parent_data' not described in 'clk_hw_register_fixed_rate_parent_accuracy' clk-provider.h:482: warning: Excess function parameter 'parent_name' description in 'clk_hw_register_fixed_rate_parent_accuracy' clk-provider.h:687: warning: Function parameter or member 'flags' not described in 'clk_divider'
clk-provider.h:1164: warning: Function parameter or member 'flags' not described in 'clk_fractional_divider' clk-provider.h:1164: warning: Function parameter or member 'approximation' not described in 'clk_fractional_divider' clk-provider.h:1213: warning: Function parameter or member 'flags' not described in 'clk_multiplier'
--- include/linux/clk-provider.h | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-)
include/linux/clk-provider.h +8 -7
@@ -74,7 +74,7 @@ void clk_hw_forward_rate_request(const struct clk_hw *core, unsigned long parent_rate);/** -* struct clk_duty - Struture encoding the duty cycle ratio of a clock +* struct clk_duty - Structure encoding the duty cycle ratio of a clock * * @num: Numerator of the duty cycle ratio * @den: Denominator of the duty cycle ratio
@@ -129,7 +129,7 @@ struct clk_duty {* @restore_context: Restore the context of the clock after a restoration * of power. * -* @recalc_rate Recalculate the rate of this clock, by querying hardware. The +* @recalc_rate: Recalculate the rate of this clock, by querying hardware. The * parent rate is an input parameter. It is up to the caller to * ensure that the prepare_mutex is held across this call. If the * driver cannot figure out a rate for this clock, it must return
@@ -456,7 +456,7 @@ struct clk *clk_register_fixed_rate(struct device *dev, const char *name,* clock with the clock framework * @dev: device that is registering this clock * @name: name of this clock -* @parent_name: name of clock's parent +* @parent_data: name of clock's parent * @flags: framework-specific flags * @fixed_rate: non-adjustable clock rate * @fixed_accuracy: non-adjustable clock accuracy
@@ -471,7 +471,7 @@ struct clk *clk_register_fixed_rate(struct device *dev, const char *name,* the clock framework * @dev: device that is registering this clock * @name: name of this clock -* @parent_name: name of clock's parent +* @parent_data: name of clock's parent * @flags: framework-specific flags * @fixed_rate: non-adjustable clock rate */
@@ -649,7 +649,7 @@ struct clk_div_table {* Clock with an adjustable divider affecting its output frequency. Implements * .recalc_rate, .set_rate and .round_rate * -* Flags: +* @flags: * CLK_DIVIDER_ONE_BASED - by default the divisor is the value read from the * register plus one. If CLK_DIVIDER_ONE_BASED is set then the divider is * the raw value read from the register, with the value of zero considered
@@ -1130,11 +1130,12 @@ struct clk_hw *clk_hw_register_fixed_factor_parent_hw(struct device *dev,* @mwidth: width of the numerator bit field * @nshift: shift to the denominator bit field * @nwidth: width of the denominator bit field +* @approximation: clk driver's callback for calculating the divider clock * @lock: register lock * * Clock with adjustable fractional divider affecting its output frequency. * -* Flags: +* @flags: * CLK_FRAC_DIVIDER_ZERO_BASED - by default the numerator and denominator * is the value read from the register. If CLK_FRAC_DIVIDER_ZERO_BASED * is set then the numerator and denominator are both the value read
@@ -1191,7 +1192,7 @@ void clk_hw_unregister_fractional_divider(struct clk_hw *hw);* Clock with an adjustable multiplier affecting its output frequency. * Implements .recalc_rate, .set_rate and .round_rate * -* Flags: +* @flags: * CLK_MULTIPLIER_ZERO_BYPASS - By default, the multiplier is the value read * from the register, with 0 being a valid value effectively * zeroing the output clock rate. If CLK_MULTIPLIER_ZERO_BYPASS is
Signature · 1 line
2.42.0
Greg Kroah-Hartman
maintainerPATCH 181/603 spi: nxp-fspi: use the correct ioremap function
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Han Xu <[email protected]>
[ Upstream commit c3aa5cb264a38ae9bbcce32abca4c155af0456df ]
AHB memory as MMIO should be mapped with ioremap rather than ioremap_wc, which should have been used initially just to handle unaligned access as a workaround.
--- drivers/spi/spi-nxp-fspi.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/spi/spi-nxp-fspi.c +1 -1
@@ -759,7 +759,7 @@ static int nxp_fspi_read_ahb(struct nxp_fspi *f, const struct spi_mem_op *op) f->memmap_len = len >NXP_FSPI_MIN_IOMAP ? len :NXP_FSPI_MIN_IOMAP ; - f->ahb_addr =ioremap_wc (f->memmap_phy + f->memmap_start, + f->ahb_addr =ioremap (f->memmap_phy + f->memmap_start, f->memmap_len);if (!f->ahb_addr) {
Signature · 1 line
2.42.0
Greg Kroah-Hartman
maintainerPATCH 182/603 clk: ralink: mtmips: quiet unused variable warning
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Sergio Paracuellos <[email protected]>
[ Upstream commit 619102313466eaf8a6ac188e711f5df749dac6d4 ]
When CONFIG_OF is disabled then the matching table is not referenced and the following warning appears:
drivers/clk/ralink/clk-mtmips.c:821:34: warning: unused variable 'mtmips_of_match' [-Wunused-const-variable]
821 | static const struct of_device_id mtmips_of_match[] = {
| ^
There are two match tables in the driver: one for the clock driver and the other for the reset driver. The only difference between them is that the clock driver uses 'data' and does not have 'ralink,rt2880-reset' compatible. Both just can be merged into a single one just by adding the compatible 'ralink,rt2880-reset' entry to 'mtmips_of_match[]', which will allow it to be used for 'mtmips_clk_driver' (which doesn't use the data) as well as for 'mtmips_clk_init()' (which doesn't need get called for 'ralink,rt2880-reset').
Doing in this way ensures that 'CONFIG_OF' is not disabled anymore so the above warning disapears.
--- drivers/clk/ralink/clk-mtmips.c | 20 +++++--------------- 1 file changed, 5 insertions(+), 15 deletions(-)
drivers/clk/ralink/clk-mtmips.c +5 -15
@@ -821,6 +821,10 @@ static const struct mtmips_clk_data mt76x8_clk_data = { };static const struct of_device_id mtmips_of_match[] = { + { + .compatible ="ralink,rt2880-reset" , + .data =NULL , + }, { .compatible ="ralink,rt2880-sysc" , .data = &rt2880_clk_data,
@@ -1088,25 +1092,11 @@ static int mtmips_clk_probe(struct platform_device *pdev)return 0 ; } -static const struct of_device_id mtmips_clk_of_match[] = { - { .compatible ="ralink,rt2880-reset" }, - { .compatible ="ralink,rt2880-sysc" }, - { .compatible ="ralink,rt3050-sysc" }, - { .compatible ="ralink,rt3052-sysc" }, - { .compatible ="ralink,rt3352-sysc" }, - { .compatible ="ralink,rt3883-sysc" }, - { .compatible ="ralink,rt5350-sysc" }, - { .compatible ="ralink,mt7620-sysc" }, - { .compatible ="ralink,mt7628-sysc" }, - { .compatible ="ralink,mt7688-sysc" }, - {} -}; -static struct platform_driver mtmips_clk_driver = { .probe = mtmips_clk_probe, .driver = { .name ="mtmips-clk" , - .of_match_table = mtmips_clk_of_match, + .of_match_table = mtmips_of_match, }, };
Signature · 1 line
2.42.0
Greg Kroah-Hartman
maintainerPATCH 183/603 clk: keystone: pll: fix a couple NULL vs IS_ERR() checks
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Dan Carpenter <[email protected]>
[ Upstream commit a5d14f8b551eb1551c10053653ee8e27f19672fa ]
The clk_register_divider() and clk_register_mux() functions returns error pointers on error but this code checks for NULL. Fix that.
--- drivers/clk/keystone/pll.c | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-)
drivers/clk/keystone/pll.c +9 -6
@@ -281,12 +281,13 @@ static void __init of_pll_div_clk_init(struct device_node *node) clk =clk_register_divider (NULL , clk_name, parent_name,0 , reg, shift, mask,0 ,NULL ); -if (clk) { -of_clk_add_provider (node, of_clk_src_simple_get, clk); - }else { +if (IS_ERR (clk)) {pr_err ("%s: error registering divider %s\n" , __func__, clk_name);iounmap (reg); +return ; } + +of_clk_add_provider (node, of_clk_src_simple_get, clk); }CLK_OF_DECLARE (pll_divider_clock,"ti,keystone,pll-divider-clock" , of_pll_div_clk_init);
@@ -328,10 +329,12 @@ static void __init of_pll_mux_clk_init(struct device_node *node) clk =clk_register_mux (NULL , clk_name, (const char **)&parents,ARRAY_SIZE (parents) ,0 , reg, shift, mask,0 ,NULL ); -if (clk) -of_clk_add_provider (node, of_clk_src_simple_get, clk); -else +if (IS_ERR (clk)) {pr_err ("%s: error registering mux %s\n" , __func__, clk_name); +return ; + } + +of_clk_add_provider (node, of_clk_src_simple_get, clk); }CLK_OF_DECLARE (pll_mux_clock,"ti,keystone,pll-mux-clock" , of_pll_mux_clk_init);
Signature · 1 line
2.42.0
Greg Kroah-Hartman
maintainerPATCH 184/603 clk: ti: fix double free in of_ti_divider_clk_setup()
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Dan Carpenter <[email protected]>
[ Upstream commit 7af5b9eadd64c9e02a71f97c45bcdf3b64841f6b ]
The "div" pointer is freed in _register_divider() and again in of_ti_divider_clk_setup(). Delete the free in _register_divider()
--- drivers/clk/ti/divider.c | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-)
drivers/clk/ti/divider.c +1 -7
@@ -309,7 +309,6 @@ static struct clk *_register_divider(struct device_node *node,u32 flags, struct clk_omap_divider *div) { - struct clk *clk; struct clk_init_data init;const char *parent_name;const char *name;
@@ -326,12 +325,7 @@ static struct clk *_register_divider(struct device_node *node, div->hw.init = &init;/* register the clock */ - clk =of_ti_clk_register (node, &div->hw, name); - -if (IS_ERR (clk)) -kfree (div); - -return clk; +return of_ti_clk_register (node, &div->hw, name); } int ti_clk_parse_divider_data(int *div_table, int num_dividers, int max_div,
Signature · 1 line
2.42.0
Greg Kroah-Hartman
maintainerPATCH 185/603 clk: npcm7xx: Fix incorrect kfree
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Jonathan Neuschäfer <[email protected]>
[ Upstream commit bbc5080bef4a245106aa8e8d424ba8847ca7c0ca ]
The corresponding allocation is:
Quoted 2 lines
npcm7xx_clk_data= kzalloc(struct_size(npcm7xx_clk_data, hws,NPCM7XX_NUM_CLOCKS), GFP_KERNEL);
... so, kfree should be applied to npcm7xx_clk_data, not npcm7xx_clk_data->hws.
--- drivers/clk/clk-npcm7xx.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/clk/clk-npcm7xx.c +1 -1
@@ -510,7 +510,7 @@ static void __init npcm7xx_clk_init(struct device_node *clk_np)return ; npcm7xx_init_fail: -kfree (npcm7xx_clk_data->hws); +kfree (npcm7xx_clk_data); npcm7xx_init_np_err:iounmap (clk_base); npcm7xx_init_error:
Signature · 1 line
2.42.0
Greg Kroah-Hartman
maintainerPATCH 186/603 clk: mediatek: clk-mt6765: Add check for mtk_alloc_clk_data
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Jiasheng Jiang <[email protected]>
[ Upstream commit b82681042724924ae3ba0f2f2eeec217fa31e830 ]
Add the check for the return value of mtk_alloc_clk_data() in order to avoid NULL pointer dereference.
--- drivers/clk/mediatek/clk-mt6765.c | 6 ++++++ 1 file changed, 6 insertions(+)
drivers/clk/mediatek/clk-mt6765.c +6 -0
@@ -737,6 +737,8 @@ static int clk_mt6765_apmixed_probe(struct platform_device *pdev)return PTR_ERR (base); clk_data =mtk_alloc_clk_data (CLK_APMIXED_NR_CLK ); +if (!clk_data) +return -ENOMEM ;mtk_clk_register_plls (node, plls,ARRAY_SIZE (plls), clk_data);
@@ -769,6 +771,8 @@ static int clk_mt6765_top_probe(struct platform_device *pdev)return PTR_ERR (base); clk_data =mtk_alloc_clk_data (CLK_TOP_NR_CLK ); +if (!clk_data) +return -ENOMEM ;mtk_clk_register_fixed_clks (fixed_clks,ARRAY_SIZE (fixed_clks), clk_data);
@@ -807,6 +811,8 @@ static int clk_mt6765_ifr_probe(struct platform_device *pdev)return PTR_ERR (base); clk_data =mtk_alloc_clk_data (CLK_IFR_NR_CLK ); +if (!clk_data) +return -ENOMEM ;mtk_clk_register_gates (&pdev->dev, node, ifr_clks,ARRAY_SIZE (ifr_clks), clk_data);
Signature · 1 line
2.42.0
Greg Kroah-Hartman
maintainerPATCH 187/603 clk: mediatek: clk-mt6779: Add check for mtk_alloc_clk_data
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Jiasheng Jiang <[email protected]>
[ Upstream commit 1f57f78fbacf630430bf954e5a84caafdfea30c0 ]
Add the check for the return value of mtk_alloc_clk_data() in order to avoid NULL pointer dereference.
--- drivers/clk/mediatek/clk-mt6779.c | 4 ++++ 1 file changed, 4 insertions(+)
drivers/clk/mediatek/clk-mt6779.c +4 -0
@@ -1217,6 +1217,8 @@ static int clk_mt6779_apmixed_probe(struct platform_device *pdev)struct device_node *node = pdev->dev.of_node; clk_data =mtk_alloc_clk_data (CLK_APMIXED_NR_CLK ); +if (!clk_data) +return -ENOMEM ;mtk_clk_register_plls (node, plls,ARRAY_SIZE (plls), clk_data);
@@ -1237,6 +1239,8 @@ static int clk_mt6779_top_probe(struct platform_device *pdev)return PTR_ERR (base); clk_data =mtk_alloc_clk_data (CLK_TOP_NR_CLK ); +if (!clk_data) +return -ENOMEM ;mtk_clk_register_fixed_clks (top_fixed_clks,ARRAY_SIZE (top_fixed_clks), clk_data);
Signature · 1 line
2.42.0
Greg Kroah-Hartman
maintainerPATCH 188/603 clk: mediatek: clk-mt6797: Add check for mtk_alloc_clk_data
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Jiasheng Jiang <[email protected]>
[ Upstream commit 606f6366a35a3329545e38129804d65ef26ed7d2 ]
Add the check for the return value of mtk_alloc_clk_data() in order to avoid NULL pointer dereference.
--- drivers/clk/mediatek/clk-mt6797.c | 6 ++++++ 1 file changed, 6 insertions(+)
drivers/clk/mediatek/clk-mt6797.c +6 -0
@@ -390,6 +390,8 @@ static int mtk_topckgen_init(struct platform_device *pdev)return PTR_ERR (base); clk_data =mtk_alloc_clk_data (CLK_TOP_NR ); +if (!clk_data) +return -ENOMEM ;mtk_clk_register_factors (top_fixed_divs,ARRAY_SIZE (top_fixed_divs), clk_data);
@@ -545,6 +547,8 @@ static void mtk_infrasys_init_early(struct device_node *node)if (!infra_clk_data) { infra_clk_data =mtk_alloc_clk_data (CLK_INFRA_NR ); +if (!infra_clk_data) +return ;for (i =0 ; i <CLK_INFRA_NR ; i++) infra_clk_data->hws[i] =ERR_PTR (-EPROBE_DEFER );
@@ -570,6 +574,8 @@ static int mtk_infrasys_init(struct platform_device *pdev)if (!infra_clk_data) { infra_clk_data =mtk_alloc_clk_data (CLK_INFRA_NR ); +if (!infra_clk_data) +return -ENOMEM ; }else {for (i =0 ; i <CLK_INFRA_NR ; i++) {if (infra_clk_data->hws[i] ==ERR_PTR (-EPROBE_DEFER ))
Signature · 1 line
2.42.0
Greg Kroah-Hartman
maintainerPATCH 189/603 clk: mediatek: clk-mt7629-eth: Add check for mtk_alloc_clk_data
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Jiasheng Jiang <[email protected]>
[ Upstream commit 0884393c63cc9a1772f7121a6645ba7bd76feeb9 ]
Add the check for the return value of mtk_alloc_clk_data() in order to avoid NULL pointer dereference.
--- drivers/clk/mediatek/clk-mt7629-eth.c | 4 ++++ 1 file changed, 4 insertions(+)
drivers/clk/mediatek/clk-mt7629-eth.c +4 -0
@@ -77,6 +77,8 @@ static int clk_mt7629_ethsys_init(struct platform_device *pdev)int r; clk_data =mtk_alloc_clk_data (CLK_ETH_NR_CLK ); +if (!clk_data) +return -ENOMEM ;mtk_clk_register_gates (&pdev->dev, node, eth_clks,CLK_ETH_NR_CLK , clk_data);
@@ -100,6 +102,8 @@ static int clk_mt7629_sgmiisys_init(struct platform_device *pdev)int r; clk_data =mtk_alloc_clk_data (CLK_SGMII_NR_CLK ); +if (!clk_data) +return -ENOMEM ;mtk_clk_register_gates (&pdev->dev, node, sgmii_clks[id++],CLK_SGMII_NR_CLK , clk_data);
Signature · 1 line
2.42.0
Greg Kroah-Hartman
maintainerPATCH 190/603 clk: mediatek: clk-mt7629: Add check for mtk_alloc_clk_data
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Jiasheng Jiang <[email protected]>
[ Upstream commit 2befa515c1bb6cdd33c262b909d93d1973a219aa ]
Add the check for the return value of mtk_alloc_clk_data() in order to avoid NULL pointer dereference.
--- drivers/clk/mediatek/clk-mt7629.c | 6 ++++++ 1 file changed, 6 insertions(+)
drivers/clk/mediatek/clk-mt7629.c +6 -0
@@ -555,6 +555,8 @@ static int mtk_topckgen_init(struct platform_device *pdev)return PTR_ERR (base); clk_data =mtk_alloc_clk_data (CLK_TOP_NR_CLK ); +if (!clk_data) +return -ENOMEM ;mtk_clk_register_fixed_clks (top_fixed_clks,ARRAY_SIZE (top_fixed_clks), clk_data);
@@ -579,6 +581,8 @@ static int mtk_infrasys_init(struct platform_device *pdev)struct clk_hw_onecell_data *clk_data; clk_data =mtk_alloc_clk_data (CLK_INFRA_NR_CLK ); +if (!clk_data) +return -ENOMEM ;mtk_clk_register_gates (&pdev->dev, node, infra_clks,ARRAY_SIZE (infra_clks), clk_data);
@@ -602,6 +606,8 @@ static int mtk_pericfg_init(struct platform_device *pdev)return PTR_ERR (base); clk_data =mtk_alloc_clk_data (CLK_PERI_NR_CLK ); +if (!clk_data) +return -ENOMEM ;mtk_clk_register_gates (&pdev->dev, node, peri_clks,ARRAY_SIZE (peri_clks), clk_data);
Signature · 1 line
2.42.0
Greg Kroah-Hartman
maintainerPATCH 191/603 clk: mediatek: clk-mt2701: Add check for mtk_alloc_clk_data
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Jiasheng Jiang <[email protected]>
[ Upstream commit 0d6e24b422a2166a9297a8286ff2e6ab9a5e8cd3 ]
Add the check for the return value of mtk_alloc_clk_data() in order to avoid NULL pointer dereference.
--- drivers/clk/mediatek/clk-mt2701.c | 8 ++++++++ 1 file changed, 8 insertions(+)
drivers/clk/mediatek/clk-mt2701.c +8 -0
@@ -667,6 +667,8 @@ static int mtk_topckgen_init(struct platform_device *pdev)return PTR_ERR (base); clk_data =mtk_alloc_clk_data (CLK_TOP_NR ); +if (!clk_data) +return -ENOMEM ;mtk_clk_register_fixed_clks (top_fixed_clks,ARRAY_SIZE (top_fixed_clks), clk_data);
@@ -747,6 +749,8 @@ static void __init mtk_infrasys_init_early(struct device_node *node)if (!infra_clk_data) { infra_clk_data =mtk_alloc_clk_data (CLK_INFRA_NR ); +if (!infra_clk_data) +return ;for (i =0 ; i <CLK_INFRA_NR ; i++) infra_clk_data->hws[i] =ERR_PTR (-EPROBE_DEFER );
@@ -774,6 +778,8 @@ static int mtk_infrasys_init(struct platform_device *pdev)if (!infra_clk_data) { infra_clk_data =mtk_alloc_clk_data (CLK_INFRA_NR ); +if (!infra_clk_data) +return -ENOMEM ; }else {for (i =0 ; i <CLK_INFRA_NR ; i++) {if (infra_clk_data->hws[i] ==ERR_PTR (-EPROBE_DEFER ))
@@ -890,6 +896,8 @@ static int mtk_pericfg_init(struct platform_device *pdev)return PTR_ERR (base); clk_data =mtk_alloc_clk_data (CLK_PERI_NR ); +if (!clk_data) +return -ENOMEM ;mtk_clk_register_gates (&pdev->dev, node, peri_clks,ARRAY_SIZE (peri_clks), clk_data);
Signature · 1 line
2.42.0
Greg Kroah-Hartman
maintainerPATCH 192/603 clk: qcom: config IPQ_APSS_6018 should depend on QCOM_SMEM
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Varadarajan Narayanan <[email protected]>
[ Upstream commit 6a15647d0adc686226045e8046369f34d6ab03ed ]
The config IPQ_APSS_6018 should depend on QCOM_SMEM, to avoid the following error reported by 'kernel test robot'
loongarch64-linux-ld: drivers/clk/qcom/apss-ipq6018.o: in function `apss_ipq6018_probe': >> apss-ipq6018.c:(.text+0xd0): undefined reference to `qcom_smem_get_soc_id'
--- drivers/clk/qcom/Kconfig | 1 + 1 file changed, 1 insertion(+)
drivers/clk/qcom/Kconfig +1 -0
@@ -131,6 +131,7 @@ config IPQ_APSS_6018 tristate "IPQ APSS Clock Controller" select IPQ_APSS_PLL depends on QCOM_APCS_IPC || COMPILE_TEST + depends on QCOM_SMEM help Support for APSS clock controller on IPQ platforms. The APSS clock controller manages the Mux and enable block that feeds the
Signature · 1 line
2.42.0
Greg Kroah-Hartman
maintainerPATCH 193/603 clk: qcom: clk-alpha-pll: introduce stromer plus ops
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Varadarajan Narayanan <[email protected]>
[ Upstream commit 84da48921a97cee3dd1391659e93ee01d122b78b ]
Stromer plus APSS PLL does not support dynamic frequency scaling. To switch between frequencies, we have to shut down the PLL, configure the L and ALPHA values and turn on again. So introduce the separate set of ops for Stromer Plus PLL.
Stable-dep-of: 267e29198436 ("clk: qcom: apss-ipq-pll: Use stromer plus ops for stromer plus pll")
--- drivers/clk/qcom/clk-alpha-pll.c | 63 ++++++++++++++++++++++++++++++++ drivers/clk/qcom/clk-alpha-pll.h | 1 + 2 files changed, 64 insertions(+)
drivers/clk/qcom/clk-alpha-pll.c +63 -0
@@ -2479,3 +2479,66 @@ const struct clk_ops clk_alpha_pll_stromer_ops = { .set_rate = clk_alpha_pll_stromer_set_rate, };EXPORT_SYMBOL_GPL (clk_alpha_pll_stromer_ops); + +static int clk_alpha_pll_stromer_plus_set_rate (struct clk_hw *hw, +unsigned long rate, +unsigned long prate) +{ +struct clk_alpha_pll *pll =to_clk_alpha_pll (hw); +u32 l, alpha_width =pll_alpha_width (pll); +int ret, pll_mode; +u64 a; + + rate =alpha_pll_round_rate (rate, prate, &l, &a, alpha_width); + + ret =regmap_read (pll->clkr.regmap,PLL_MODE (pll), &pll_mode); +if (ret) +return ret; + +regmap_write (pll->clkr.regmap,PLL_MODE (pll),0 ); + +/* Delay of 2 output clock ticks required until output is disabled */ +udelay (1 ); + +regmap_write (pll->clkr.regmap,PLL_L_VAL (pll), l); + +if (alpha_width >ALPHA_BITWIDTH ) + a <<= alpha_width -ALPHA_BITWIDTH ; + +regmap_write (pll->clkr.regmap,PLL_ALPHA_VAL (pll), a); +regmap_write (pll->clkr.regmap,PLL_ALPHA_VAL_U (pll), + a >>ALPHA_BITWIDTH ); + +regmap_write (pll->clkr.regmap,PLL_MODE (pll),PLL_BYPASSNL ); + +/* Wait five micro seconds or more */ +udelay (5 ); +regmap_update_bits (pll->clkr.regmap,PLL_MODE (pll),PLL_RESET_N , +PLL_RESET_N ); + +/* The lock time should be less than 50 micro seconds worst case */ +usleep_range (50 ,60 ); + + ret =wait_for_pll_enable_lock (pll); +if (ret) { +pr_err ("Wait for PLL enable lock failed [%s] %d\n" , +clk_hw_get_name (hw), ret); +return ret; + } + +if (pll_mode &PLL_OUTCTRL ) +regmap_update_bits (pll->clkr.regmap,PLL_MODE (pll),PLL_OUTCTRL , +PLL_OUTCTRL ); + +return 0 ; +} + +const struct clk_ops clk_alpha_pll_stromer_plus_ops = { + .prepare = clk_alpha_pll_enable, + .unprepare = clk_alpha_pll_disable, + .is_enabled = clk_alpha_pll_is_enabled, + .recalc_rate = clk_alpha_pll_recalc_rate, + .determine_rate = clk_alpha_pll_stromer_determine_rate, + .set_rate = clk_alpha_pll_stromer_plus_set_rate, +}; +EXPORT_SYMBOL_GPL (clk_alpha_pll_stromer_plus_ops);
drivers/clk/qcom/clk-alpha-pll.h +1 -0
@@ -152,6 +152,7 @@ extern const struct clk_ops clk_alpha_pll_postdiv_ops;extern const struct clk_ops clk_alpha_pll_huayra_ops;extern const struct clk_ops clk_alpha_pll_postdiv_ro_ops;extern const struct clk_ops clk_alpha_pll_stromer_ops; +extern const struct clk_ops clk_alpha_pll_stromer_plus_ops;extern const struct clk_ops clk_alpha_pll_fabia_ops;extern const struct clk_ops clk_alpha_pll_fixed_fabia_ops;
Signature · 1 line
2.42.0
Greg Kroah-Hartman
maintainerPATCH 194/603 clk: qcom: apss-ipq-pll: Use stromer plus ops for stromer plus pll
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Varadarajan Narayanan <[email protected]>
[ Upstream commit 267e29198436a8cb6770213471f72502c895096a ]
The set rate and determine rate operations are different between Stromer and Stromer Plus PLLs. Since the programming sequence is different, the PLLs dont get configured properly and random, inexplicable crash/freeze is seen. Hence, use stromer plus ops for ipq_pll_stromer_plus.
--- drivers/clk/qcom/apss-ipq-pll.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/clk/qcom/apss-ipq-pll.c +1 -1
@@ -68,7 +68,7 @@ static struct clk_alpha_pll ipq_pll_stromer_plus = { .fw_name = "xo", }, .num_parents = 1, - .ops = &clk_alpha_pll_stromer_ops, + .ops = &clk_alpha_pll_stromer_plus_ops, }, }, };
Signature · 1 line
2.42.0
Greg Kroah-Hartman
maintainerPATCH 195/603 clk: qcom: apss-ipq-pll: Fix l value for ipq5332_pll_config
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Varadarajan Narayanan <[email protected]>
[ Upstream commit 5b7a4d3d2b33398330aef69e0ff5656273483587 ]
The earlier 'l' value of 0x3e is for 1.5GHz. Not all SKUs support this frequency. Hence set it to 0x2d to get 1.1GHz which is supported in all SKUs.
The frequency can still increase above this initial configuration made here when the cpufreq driver picks a different OPP.
--- drivers/clk/qcom/apss-ipq-pll.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/clk/qcom/apss-ipq-pll.c +1 -1
@@ -74,7 +74,7 @@ static struct clk_alpha_pll ipq_pll_stromer_plus = { };static const struct alpha_pll_config ipq5332_pll_config = { - .l =0x3e , + .l =0x2d , .config_ctl_val =0x4001075b , .config_ctl_hi_val =0x304 , .main_output_mask =BIT (0 ),
Signature · 1 line
2.42.0
Greg Kroah-Hartman
maintainerPATCH 196/603 clk: qcom: ipq5018: drop the CLK_SET_RATE_PARENT flag from GPLL clocks
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Kathiravan Thirumoorthy <[email protected]>
[ Upstream commit 01a5e4c6731ab6b4b74822661d296f8893fc1230 ]
GPLL clock rates are fixed and shouldn't be scaled based on the request from dependent clocks. Doing so will result in the unexpected behaviour. So drop the CLK_SET_RATE_PARENT flag from the GPLL clocks.
----
Changes in V2:
- New patch
--- drivers/clk/qcom/gcc-ipq5018.c | 3 --- 1 file changed, 3 deletions(-)
drivers/clk/qcom/gcc-ipq5018.c +0 -3
@@ -128,7 +128,6 @@ static struct clk_alpha_pll_postdiv gpll0 = { }, .num_parents = 1, .ops = &clk_alpha_pll_postdiv_ro_ops, - .flags = CLK_SET_RATE_PARENT, }, };
@@ -143,7 +142,6 @@ static struct clk_alpha_pll_postdiv gpll2 = { }, .num_parents = 1, .ops = &clk_alpha_pll_postdiv_ro_ops, - .flags = CLK_SET_RATE_PARENT, }, };
@@ -158,7 +156,6 @@ static struct clk_alpha_pll_postdiv gpll4 = { }, .num_parents = 1, .ops = &clk_alpha_pll_postdiv_ro_ops, - .flags = CLK_SET_RATE_PARENT, }, };
Signature · 1 line
2.42.0
Greg Kroah-Hartman
maintainerPATCH 197/603 clk: qcom: ipq9574: drop the CLK_SET_RATE_PARENT flag from GPLL clocks
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Kathiravan Thirumoorthy <[email protected]>
[ Upstream commit 99a8f8764b70158a712992640a6be46a8fd79d15 ]
GPLL clock rates are fixed and shouldn't be scaled based on the request from dependent clocks. Doing so will result in the unexpected behaviour. So drop the CLK_SET_RATE_PARENT flag from the GPLL clocks.
----
Changes in V2:
- No changes
--- drivers/clk/qcom/gcc-ipq9574.c | 4 ---- 1 file changed, 4 deletions(-)
drivers/clk/qcom/gcc-ipq9574.c +0 -4
@@ -87,7 +87,6 @@ static struct clk_fixed_factor gpll0_out_main_div2 = { &gpll0_main.clkr.hw }, .num_parents = 1, - .flags = CLK_SET_RATE_PARENT, .ops = &clk_fixed_factor_ops, }, };
@@ -102,7 +101,6 @@ static struct clk_alpha_pll_postdiv gpll0 = { &gpll0_main.clkr.hw }, .num_parents = 1, - .flags = CLK_SET_RATE_PARENT, .ops = &clk_alpha_pll_postdiv_ro_ops, }, };
@@ -132,7 +130,6 @@ static struct clk_alpha_pll_postdiv gpll4 = { &gpll4_main.clkr.hw }, .num_parents = 1, - .flags = CLK_SET_RATE_PARENT, .ops = &clk_alpha_pll_postdiv_ro_ops, }, };
@@ -162,7 +159,6 @@ static struct clk_alpha_pll_postdiv gpll2 = { &gpll2_main.clkr.hw }, .num_parents = 1, - .flags = CLK_SET_RATE_PARENT, .ops = &clk_alpha_pll_postdiv_ro_ops, }, };
Signature · 1 line
2.42.0
Greg Kroah-Hartman
maintainerPATCH 198/603 clk: qcom: ipq5332: drop the CLK_SET_RATE_PARENT flag from GPLL clocks
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Kathiravan Thirumoorthy <[email protected]>
[ Upstream commit 5635ef0bd1052420bc659a00be6fd0c60cec5cb9 ]
GPLL clock rates are fixed and shouldn't be scaled based on the request from dependent clocks. Doing so will result in the unexpected behaviour. So drop the CLK_SET_RATE_PARENT flag from the GPLL clocks.
--- drivers/clk/qcom/gcc-ipq5332.c | 2 -- 1 file changed, 2 deletions(-)
drivers/clk/qcom/gcc-ipq5332.c +0 -2
@@ -112,7 +112,6 @@ static struct clk_alpha_pll_postdiv gpll2 = { &gpll2_main.clkr.hw }, .num_parents = 1, .ops = &clk_alpha_pll_postdiv_ro_ops, - .flags = CLK_SET_RATE_PARENT, }, };
@@ -152,7 +151,6 @@ static struct clk_alpha_pll_postdiv gpll4 = { &gpll4_main.clkr.hw }, .num_parents = 1, .ops = &clk_alpha_pll_postdiv_ro_ops, - .flags = CLK_SET_RATE_PARENT, }, };
Signature · 1 line
2.42.0
Greg Kroah-Hartman
maintainerPATCH 199/603 clk: mediatek: fix double free in mtk_clk_register_pllfh()
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Dan Carpenter <[email protected]>
[ Upstream commit bd54ccc0f147019dac38e7841876a7415459b875 ]
The mtk_clk_register_pll_ops() currently frees the "pll" parameter. The function has two callers, mtk_clk_register_pll() and mtk_clk_register_pllfh(). The first one, the _pll() function relies on the free, but for the second _pllfh() function it causes a double free bug.
Really the frees should be done in the caller because that's where the allocation is.
--- drivers/clk/mediatek/clk-pll.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-)
drivers/clk/mediatek/clk-pll.c +3 -3
@@ -321,10 +321,8 @@ struct clk_hw *mtk_clk_register_pll_ops(struct mtk_clk_pll *pll, ret =clk_hw_register (NULL , &pll->hw); -if (ret) { -kfree (pll); +if (ret)return ERR_PTR (ret); - }return &pll->hw; }
@@ -340,6 +338,8 @@ struct clk_hw *mtk_clk_register_pll(const struct mtk_pll_data *data,return ERR_PTR (-ENOMEM ); hw =mtk_clk_register_pll_ops (pll, data, base, &mtk_pll_ops); +if (IS_ERR (hw)) +kfree (pll);return hw; }
Signature · 1 line
2.42.0
Greg Kroah-Hartman
maintainerPATCH 200/603 platform/x86: wmi: Fix probe failure when failing to register WMI devices
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Armin Wolf <[email protected]>
[ Upstream commit ed85891a276edaf7a867de0e9acd0837bc3008f2 ]
When a WMI device besides the first one somehow fails to register, retval is returned while still containing a negative error code. This causes the ACPI device fail to probe, leaving behind zombie WMI devices leading to various errors later.
Handle the single error path separately and return 0 unconditionally after trying to register all WMI devices to solve the issue. Also continue to register WMI devices even if some fail to allocate memory.
--- drivers/platform/x86/wmi.c | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-)
drivers/platform/x86/wmi.c +8 -8
@@ -1270,8 +1270,8 @@ static int parse_wdg(struct device *wmi_bus_dev, struct acpi_device *device)struct wmi_block *wblock, *next;union acpi_object *obj;acpi_status status; -int retval =0 ;u32 i, total; +int retval; status =acpi_evaluate_object (device->handle,"_WDG" ,NULL , &out);if (ACPI_FAILURE (status))
@@ -1282,8 +1282,8 @@ static int parse_wdg(struct device *wmi_bus_dev, struct acpi_device *device)return -ENXIO ;if (obj->type !=ACPI_TYPE_BUFFER ) { - retval = -ENXIO ; - goto out_free_pointer; +kfree (obj); +return -ENXIO ; } gblock = (const struct guid_block *)obj->buffer.pointer;
@@ -1298,8 +1298,8 @@ static int parse_wdg(struct device *wmi_bus_dev, struct acpi_device *device) wblock =kzalloc (sizeof (*wblock),GFP_KERNEL );if (!wblock) { - retval = -ENOMEM ; -break ; +dev_err (wmi_bus_dev,"Failed to allocate %pUL\n" , &gblock[i].guid); +continue ; } wblock->acpi_device = device;
@@ -1338,9 +1338,9 @@ static int parse_wdg(struct device *wmi_bus_dev, struct acpi_device *device) } } -out_free_pointer: -kfree (out.pointer); -return retval; +kfree (obj); + +return 0 ; }/*
Signature · 1 line
2.42.0
Greg Kroah-Hartman
maintainerPATCH 201/603 platform/x86: wmi: Fix opening of char device
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Armin Wolf <[email protected]>
[ Upstream commit eba9ac7abab91c8f6d351460239108bef5e7a0b6 ]
Since commit fa1f68db6ca7 ("drivers: misc: pass miscdevice pointer via file private data"), the miscdevice stores a pointer to itself inside filp->private_data, which means that private_data will not be NULL when wmi_char_open() is called. This might cause memory corruption should wmi_char_open() be unable to find its driver, something which can happen when the associated WMI device is deleted in wmi_free_devices().
Fix the problem by using the miscdevice pointer to retrieve the WMI device data associated with a char device using container_of(). This also avoids wmi_char_open() picking a wrong WMI device bound to a driver with the same name as the original driver.
--- drivers/platform/x86/wmi.c | 20 ++++++-------------- 1 file changed, 6 insertions(+), 14 deletions(-)
drivers/platform/x86/wmi.c +6 -14
@@ -911,21 +911,13 @@ static int wmi_dev_match(struct device *dev, struct device_driver *driver) }static int wmi_char_open (struct inode *inode,struct file *filp) { -const char *driver_name = filp->f_path.dentry->d_iname; -struct wmi_block *wblock; -struct wmi_block *next; - -list_for_each_entry_safe (wblock, next, &wmi_block_list, list) { -if (!wblock->dev.dev.driver) -continue ; -if (strcmp (driver_name, wblock->dev.dev.driver->name) ==0 ) { - filp->private_data = wblock; -break ; - } - } +/* +* The miscdevice already stores a pointer to itself +* inside filp->private_data +*/ + struct wmi_block *wblock = container_of(filp->private_data, struct wmi_block, char_dev); -if (!filp->private_data) -return -ENODEV ; + filp->private_data = wblock;return nonseekable_open (inode, filp); }
Signature · 1 line
2.42.0
Greg Kroah-Hartman
maintainerPATCH 202/603 regulator: qcom-rpmh: Fix smps4 regulator for pm8550ve
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Abel Vesa <[email protected]>
[ Upstream commit bc00d9f3813a40bc2d854ae0edab14c6b43a3219 ]
The type of the smps4 regulator from pm8550ve is actually FTSMPS525 medium voltage. So fix it accordingly.
--- drivers/regulator/qcom-rpmh-regulator.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/regulator/qcom-rpmh-regulator.c +1 -1
@@ -1095,7 +1095,7 @@ static const struct rpmh_vreg_init_data pm8550ve_vreg_data[] = {RPMH_VREG ("smps1" ,"smp%s1" , &pmic5_ftsmps525_lv,"vdd-s1" ),RPMH_VREG ("smps2" ,"smp%s2" , &pmic5_ftsmps525_lv,"vdd-s2" ),RPMH_VREG ("smps3" ,"smp%s3" , &pmic5_ftsmps525_lv,"vdd-s3" ), -RPMH_VREG ("smps4" ,"smp%s4" , &pmic5_ftsmps525_lv,"vdd-s4" ), +RPMH_VREG ("smps4" ,"smp%s4" , &pmic5_ftsmps525_mv,"vdd-s4" ),RPMH_VREG ("smps5" ,"smp%s5" , &pmic5_ftsmps525_lv,"vdd-s5" ),RPMH_VREG ("smps6" ,"smp%s6" , &pmic5_ftsmps525_lv,"vdd-s6" ), RPMH_VREG("smps7", "smp%s7", &pmic5_ftsmps525_lv, "vdd-s7"),
Signature · 1 line
2.42.0
Greg Kroah-Hartman
maintainerPATCH 203/603 hwmon: (axi-fan-control) Fix possible NULL pointer dereference
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Dragos Bogdan <[email protected]>
[ Upstream commit 2a5b3370a1d9750eca325292e291c8c7cb8cf2e0 ]
axi_fan_control_irq_handler(), dependent on the private axi_fan_control_data structure, might be called before the hwmon device is registered. That will cause an "Unable to handle kernel NULL pointer dereference" error.
--- drivers/hwmon/axi-fan-control.c | 29 ++++++++++++++++------------- 1 file changed, 16 insertions(+), 13 deletions(-)
drivers/hwmon/axi-fan-control.c +16 -13
@@ -496,6 +496,21 @@ static int axi_fan_control_probe(struct platform_device *pdev)return -ENODEV ; } + ret =axi_fan_control_init (ctl, pdev->dev.of_node); +if (ret) { +dev_err (&pdev->dev,"Failed to initialize device\n" ); +return ret; + } + + ctl->hdev =devm_hwmon_device_register_with_info (&pdev->dev, + name, + ctl, + &axi_chip_info, + axi_fan_control_groups); + +if (IS_ERR (ctl->hdev)) +return PTR_ERR (ctl->hdev); + ctl->irq =platform_get_irq (pdev,0 );if (ctl->irq <0 )return ctl->irq;
@@ -509,19 +524,7 @@ static int axi_fan_control_probe(struct platform_device *pdev)return ret; } - ret =axi_fan_control_init (ctl, pdev->dev.of_node); -if (ret) { -dev_err (&pdev->dev,"Failed to initialize device\n" ); -return ret; - } - - ctl->hdev =devm_hwmon_device_register_with_info (&pdev->dev, - name, - ctl, - &axi_chip_info, - axi_fan_control_groups); - -return PTR_ERR_OR_ZERO (ctl->hdev); +return 0 ; }static struct platform_driver axi_fan_control_driver = {
Signature · 1 line
2.42.0
Greg Kroah-Hartman
maintainerPATCH 204/603 hwmon: (coretemp) Fix potentially truncated sysfs attribute name
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Zhang Rui <[email protected]>
[ Upstream commit bbfff736d30e5283ad09e748caff979d75ddef7f ]
When build with W=1 and "-Werror=format-truncation", below error is observed in coretemp driver,
drivers/hwmon/coretemp.c: In function 'create_core_data':
Quoted 1 line
Quoted 1 line
drivers/hwmon/coretemp.c:393:34: error: '%s' directive output may be truncated writing likely 5 or more bytes into a region of size between 3 and 13 [-Werror=format-truncation=]
393 | "temp%d_%s", attr_no, suffixes[i]);
| ^~
drivers/hwmon/coretemp.c:393:26: note: assuming directive output of 5 bytes
393 | "temp%d_%s", attr_no, suffixes[i]);
| ^~~~~~~~~~~
drivers/hwmon/coretemp.c:392:17: note: 'snprintf' output 7 or more bytes (assuming 22) into a destination of size 19
392 | snprintf(tdata->attr_name[i], CORETEMP_NAME_LENGTH,
| ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
393 | "temp%d_%s", attr_no, suffixes[i]);
| ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~cc1: all warnings being treated as errors
Given that
1. '%d' could take 10 charactors,
2. '%s' could take 10 charactors ("crit_alarm"),
3. "temp", "_" and the NULL terminator take 6 charactors, fix the problem by increasing CORETEMP_NAME_LENGTH to 28.
--- drivers/hwmon/coretemp.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/hwmon/coretemp.c +1 -1
@@ -42,7 +42,7 @@ MODULE_PARM_DESC(tjmax, "TjMax value in degrees Celsius");#define PKG_SYSFS_ATTR_NO 1/* Sysfs attribute for package temp */ #define BASE_SYSFS_ATTR_NO 2/* Sysfs Base attr no for coretemp */ #define NUM_REAL_CORES 128/* Number of Real cores per cpu */ -#define CORETEMP_NAME_LENGTH 19/* String Length of attrs */ +#define CORETEMP_NAME_LENGTH 28/* String Length of attrs */ #define MAX_CORE_ATTRS 4/* Maximum no of basic attrs */ #define TOTAL_ATTRS (MAX_CORE_ATTRS + 1)#define MAX_CORE_DATA (NUM_REAL_CORES + BASE_SYSFS_ATTR_NO)
Signature · 1 line
2.42.0
Greg Kroah-Hartman
maintainerPATCH 205/603 Revert "hwmon: (sch56xx-common) Add DMI override table"
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Guenter Roeck <[email protected]>
[ Upstream commit 28da9dee3594423534f3ea1e1f61e6bb2d2fa651 ]
This reverts commit fd2d53c367ae9983c2100ac733a834e0c79d7537.
As reported by Ian Nartowicz, this and the preceding patch result in a failure to load the driver on Celsius W280. While the alternative would be to add the board to the DMI override table, it is quite likely that other systems are also affected. Revert the offending patches to avoid future problems.
--- drivers/hwmon/sch56xx-common.c | 44 ++++++++-------------------------- 1 file changed, 10 insertions(+), 34 deletions(-)
drivers/hwmon/sch56xx-common.c +10 -34
@@ -523,28 +523,6 @@ static int __init sch56xx_device_add(int address, const char *name)return PTR_ERR_OR_ZERO (sch56xx_pdev); } -static const struct dmi_system_id sch56xx_dmi_override_table[]__initconst = { - { - .matches = { -DMI_MATCH (DMI_SYS_VENDOR ,"FUJITSU" ), -DMI_MATCH (DMI_PRODUCT_NAME ,"CELSIUS W380" ), - }, - }, - { - .matches = { -DMI_MATCH (DMI_SYS_VENDOR ,"FUJITSU" ), -DMI_MATCH (DMI_PRODUCT_NAME ,"ESPRIMO P710" ), - }, - }, - { - .matches = { -DMI_MATCH (DMI_SYS_VENDOR ,"FUJITSU" ), -DMI_MATCH (DMI_PRODUCT_NAME ,"ESPRIMO E9900" ), - }, - }, - { } -}; -/* For autoloading only */ static const struct dmi_system_id sch56xx_dmi_table[]__initconst = { {
@@ -565,18 +543,16 @@ static int __init sch56xx_init(void)if (!dmi_check_system (sch56xx_dmi_table))return -ENODEV ; -if (!dmi_check_system (sch56xx_dmi_override_table)) { -/* -* Some machines like the Esprimo P720 and Esprimo C700 have -* onboard devices named " Antiope"/" Theseus" instead of -* "Antiope"/"Theseus", so we need to check for both. -*/ -if (!dmi_find_device (DMI_DEV_TYPE_OTHER ,"Antiope" ,NULL ) && - !dmi_find_device (DMI_DEV_TYPE_OTHER ," Antiope" ,NULL ) && - !dmi_find_device (DMI_DEV_TYPE_OTHER ,"Theseus" ,NULL ) && - !dmi_find_device (DMI_DEV_TYPE_OTHER ," Theseus" ,NULL )) -return -ENODEV ; - } +/* +* Some machines like the Esprimo P720 and Esprimo C700 have +* onboard devices named " Antiope"/" Theseus" instead of +* "Antiope"/"Theseus", so we need to check for both. +*/ +if (!dmi_find_device (DMI_DEV_TYPE_OTHER ,"Antiope" ,NULL ) && + !dmi_find_device (DMI_DEV_TYPE_OTHER ," Antiope" ,NULL ) && + !dmi_find_device (DMI_DEV_TYPE_OTHER ,"Theseus" ,NULL ) && + !dmi_find_device (DMI_DEV_TYPE_OTHER ," Theseus" ,NULL )) +return -ENODEV ; }/*
Signature · 1 line
2.42.0
Greg Kroah-Hartman
maintainerPATCH 206/603 Revert "hwmon: (sch56xx-common) Add automatic module loading on supported devices"
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Guenter Roeck <[email protected]>
[ Upstream commit d621a46d05107f4e510383d6a38f2160c62d28f7 ]
This reverts commit 393935baa45e5ccb9603cf7f9f020ed1bc0915f7.
As reported by Ian Nartowicz, this and the next patch result in a failure to load the driver on Celsius W280. While the alternative would be to add the board to the DMI override table, it is quite likely that other systems are also affected. Revert the offending patches to avoid future problems.
--- drivers/hwmon/sch56xx-common.c | 40 ++-------------------------------- 1 file changed, 2 insertions(+), 38 deletions(-)
drivers/hwmon/sch56xx-common.c +2 -38
@@ -7,10 +7,8 @@#define pr_fmt (fmt) KBUILD_MODNAME ": " fmt#include <linux/module.h> -#include <linux/mod_devicetable.h> #include <linux/init.h> #include <linux/platform_device.h> -#include <linux/dmi.h> #include <linux/err.h> #include <linux/io.h> #include <linux/acpi.h>
@@ -21,10 +19,7 @@#include <linux/slab.h> #include "sch56xx-common.h" -static bool ignore_dmi; -module_param (ignore_dmi, bool,0 ); -MODULE_PARM_DESC (ignore_dmi,"Omit DMI check for supported devices (default=0)" ); - +/* Insmod parameters */ static bool nowayout =WATCHDOG_NOWAYOUT ;module_param (nowayout, bool,0 ); MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started (default="
@@ -523,42 +518,11 @@ static int __init sch56xx_device_add(int address, const char *name)return PTR_ERR_OR_ZERO (sch56xx_pdev); } -/* For autoloading only */ -static const struct dmi_system_id sch56xx_dmi_table[]__initconst = { - { - .matches = { -DMI_MATCH (DMI_SYS_VENDOR ,"FUJITSU" ), - }, - }, - { } -}; -MODULE_DEVICE_TABLE (dmi, sch56xx_dmi_table); -static int __init sch56xx_init (void ) { -const char *name =NULL ;int address; +const char *name =NULL ; -if (!ignore_dmi) { -if (!dmi_check_system (sch56xx_dmi_table)) -return -ENODEV ; - -/* -* Some machines like the Esprimo P720 and Esprimo C700 have -* onboard devices named " Antiope"/" Theseus" instead of -* "Antiope"/"Theseus", so we need to check for both. -*/ -if (!dmi_find_device (DMI_DEV_TYPE_OTHER ,"Antiope" ,NULL ) && - !dmi_find_device (DMI_DEV_TYPE_OTHER ," Antiope" ,NULL ) && - !dmi_find_device (DMI_DEV_TYPE_OTHER ,"Theseus" ,NULL ) && - !dmi_find_device (DMI_DEV_TYPE_OTHER ," Theseus" ,NULL )) -return -ENODEV ; - } - -/* -* Some devices like the Esprimo C700 have both onboard devices, -* so we still have to check manually -*/ address =sch56xx_find (0x4e , &name);if (address <0 ) address =sch56xx_find (0x2e , &name);
Signature · 1 line
2.42.0
Greg Kroah-Hartman
maintainerPATCH 207/603 hwmon: (pmbus/mp2975) Move PGOOD fix
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Naresh Solanki <[email protected]>
[ Upstream commit 9da2901c47332b030ea4d2a2302bc7c0b83fc67c ]
The PGOOD fix was intended for MP2973 & MP2971 & not for MP2975.
--- drivers/hwmon/pmbus/mp2975.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-)
drivers/hwmon/pmbus/mp2975.c +5 -5
@@ -297,6 +297,11 @@ static int mp2973_read_word_data(struct i2c_client *client, int page,int ret;switch (reg) { +case PMBUS_STATUS_WORD : +/* MP2973 & MP2971 return PGOOD instead of PB_STATUS_POWER_GOOD_N. */ + ret =pmbus_read_word_data (client, page, phase, reg); + ret ^=PB_STATUS_POWER_GOOD_N ; +break ;case PMBUS_OT_FAULT_LIMIT : ret =mp2975_read_word_helper (client, page, phase, reg,GENMASK (7 ,0 ));
@@ -380,11 +385,6 @@ static int mp2975_read_word_data(struct i2c_client *client, int page,int ret;switch (reg) { -case PMBUS_STATUS_WORD : -/* MP2973 & MP2971 return PGOOD instead of PB_STATUS_POWER_GOOD_N. */ - ret =pmbus_read_word_data (client, page, phase, reg); - ret ^=PB_STATUS_POWER_GOOD_N ; -break ;case PMBUS_OT_FAULT_LIMIT : ret =mp2975_read_word_helper (client, page, phase, reg,GENMASK (7 ,0 ));
Signature · 1 line
2.42.0
Greg Kroah-Hartman
maintainerPATCH 208/603 hwmon: (sch5627) Use bit macros when accessing the control register
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Armin Wolf <[email protected]>
[ Upstream commit 7f0b28e0653f36b51542d25dd54ed312c397ecfc ]
Use bit macros then accessing SCH5627_REG_CTRL, so that people do not need to look at the datasheet to find out what each bit does.
Tested on a Fujitsu Esprimo P720.
Stable-dep-of: 7da8a6354360 ("hwmon: (sch5627) Disallow write access if virtual registers are locked")
--- drivers/hwmon/sch5627.c | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-)
drivers/hwmon/sch5627.c +8 -4
@@ -6,6 +6,7 @@#define pr_fmt (fmt) KBUILD_MODNAME ": " fmt +#include <linux/bits.h> #include <linux/module.h> #include <linux/mod_devicetable.h> #include <linux/init.h>
@@ -32,6 +33,9 @@#define SCH5627_REG_PRIMARY_ID 0x3f#define SCH5627_REG_CTRL 0x40 +#define SCH5627_CTRL_START BIT(0) +#define SCH5627_CTRL_VBAT BIT(4) +#define SCH5627_NO_TEMPS 8#define SCH5627_NO_FANS 4#define SCH5627_NO_IN 5
@@ -147,7 +151,8 @@ static int sch5627_update_in(struct sch5627_data *data)/* Trigger a Vbat voltage measurement every 5 minutes */ if (time_after (jiffies, data->last_battery +300 *HZ )) { -sch56xx_write_virtual_reg (data->addr,SCH5627_REG_CTRL , data->control |0x10 ); +sch56xx_write_virtual_reg (data->addr,SCH5627_REG_CTRL , + data->control |SCH5627_CTRL_VBAT ); data->last_battery = jiffies; }
@@ -483,14 +488,13 @@ static int sch5627_probe(struct platform_device *pdev)return val; data->control = val; -if (!(data->control &0x01 )) { +if (!(data->control &SCH5627_CTRL_START )) {pr_err ("hardware monitoring not enabled\n" );return -ENODEV ; }/* Trigger a Vbat voltage measurement, so that we get a valid reading the first time we read Vbat */ -sch56xx_write_virtual_reg (data->addr,SCH5627_REG_CTRL , - data->control |0x10 ); +sch56xx_write_virtual_reg (data->addr,SCH5627_REG_CTRL , data->control |SCH5627_CTRL_VBAT ); data->last_battery = jiffies;/*
Signature · 1 line
2.42.0
Greg Kroah-Hartman
maintainerPATCH 209/603 hwmon: (sch5627) Disallow write access if virtual registers are locked
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Armin Wolf <[email protected]>
[ Upstream commit 7da8a635436029957c5350da3acf51d78ed64071 ]
When the lock bit inside SCH5627_REG_CTRL is set, then the virtual registers become read-only until the next power cycle. Disallow write access to those registers in such a case.
Tested on a Fujitsu Esprimo P720.
--- drivers/hwmon/sch5627.c | 9 +++++++++ 1 file changed, 9 insertions(+)
drivers/hwmon/sch5627.c +9 -0
@@ -34,6 +34,7 @@#define SCH5627_REG_CTRL 0x40#define SCH5627_CTRL_START BIT(0) +#define SCH5627_CTRL_LOCK BIT(1)#define SCH5627_CTRL_VBAT BIT(4)#define SCH5627_NO_TEMPS 8
@@ -231,6 +232,14 @@ static int reg_to_rpm(u16 reg)static umode_t sch5627_is_visible (const void *drvdata,enum hwmon_sensor_types type,u32 attr,int channel) { +const struct sch5627_data *data = drvdata; + +/* Once the lock bit is set, the virtual registers become read-only +* until the next power cycle. +*/ +if (data->control &SCH5627_CTRL_LOCK ) +return 0444 ; +if (type == hwmon_pwm && attr == hwmon_pwm_auto_channels_temp)return 0644 ;
Signature · 1 line
2.42.0
Greg Kroah-Hartman
maintainerPATCH 210/603 hte: tegra: Fix missing error code in tegra_hte_test_probe()
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Harshit Mogalapalli <[email protected]>
[ Upstream commit b7c3ca3553d1de5e86c85636828e186d30cd0628 ]
The value of 'ret' is zero when of_hte_req_count() fails to get number of entitties to timestamp. And returning success(zero) on this failure path is incorrect.
--- drivers/hte/hte-tegra194-test.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-)
drivers/hte/hte-tegra194-test.c +3 -1
@@ -153,8 +153,10 @@ static int tegra_hte_test_probe(struct platform_device *pdev) } cnt =of_hte_req_count (hte.pdev); -if (cnt <0 ) +if (cnt <0 ) { + ret = cnt; goto free_irq; + }dev_info (&pdev->dev,"Total requested lines:%d\n" , cnt);
Signature · 1 line
2.42.0
Greg Kroah-Hartman
maintainerPATCH 211/603 platform/chrome: cros_ec_lpc: Separate host command and irq disable
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Lalith Rajendran <[email protected]>
[ Upstream commit 47ea0ddb1f5604ba3496baa19110aec6a3151f2e ]
Both cros host command and irq disable were moved to suspend prepare stage from late suspend recently. This is causing EC to report MKBP event timeouts during suspend stress testing. When the MKBP event timeouts happen during suspend, subsequent wakeup of AP by EC using MKBP doesn't happen properly. Move the irq disabling part back to late suspend stage which is a general suggestion from the suspend kernel documentaiton to do irq disable as late as possible.
--- drivers/platform/chrome/cros_ec.c | 116 +++++++++++++++++++++----- drivers/platform/chrome/cros_ec.h | 4 + drivers/platform/chrome/cros_ec_lpc.c | 22 ++++- 3 files changed, 116 insertions(+), 26 deletions(-)
drivers/platform/chrome/cros_ec.c +94 -22
@@ -321,17 +321,8 @@ void cros_ec_unregister(struct cros_ec_device *ec_dev)EXPORT_SYMBOL (cros_ec_unregister);#ifdef CONFIG_PM_SLEEP -/** -* cros_ec_suspend() - Handle a suspend operation for the ChromeOS EC device. -* @ec_dev: Device to suspend. -* -* This can be called by drivers to handle a suspend event. -* -* Return: 0 on success or negative error code. -*/ -int cros_ec_suspend (struct cros_ec_device *ec_dev) +static void cros_ec_send_suspend_event (struct cros_ec_device *ec_dev) { -struct device *dev = ec_dev->dev;int ret;u8 sleep_event;
@@ -343,7 +334,26 @@ int cros_ec_suspend(struct cros_ec_device *ec_dev)if (ret <0 )dev_dbg (ec_dev->dev,"Error %d sending suspend event to ec\n" , ret); +} +/** +* cros_ec_suspend_prepare() - Handle a suspend prepare operation for the ChromeOS EC device. +* @ec_dev: Device to suspend. +* +* This can be called by drivers to handle a suspend prepare stage of suspend. +* +* Return: 0 always. +*/ +int cros_ec_suspend_prepare (struct cros_ec_device *ec_dev) +{ +cros_ec_send_suspend_event (ec_dev); +return 0 ; +} +EXPORT_SYMBOL (cros_ec_suspend_prepare); + +static void cros_ec_disable_irq (struct cros_ec_device *ec_dev) +{ +struct device *dev = ec_dev->dev;if (device_may_wakeup (dev)) ec_dev->wake_enabled = !enable_irq_wake (ec_dev->irq);else
@@ -351,7 +361,35 @@ int cros_ec_suspend(struct cros_ec_device *ec_dev)disable_irq (ec_dev->irq); ec_dev->suspended = true; +} +/** +* cros_ec_suspend_late() - Handle a suspend late operation for the ChromeOS EC device. +* @ec_dev: Device to suspend. +* +* This can be called by drivers to handle a suspend late stage of suspend. +* +* Return: 0 always. +*/ +int cros_ec_suspend_late (struct cros_ec_device *ec_dev) +{ +cros_ec_disable_irq (ec_dev); +return 0 ; +} +EXPORT_SYMBOL (cros_ec_suspend_late); + +/** +* cros_ec_suspend() - Handle a suspend operation for the ChromeOS EC device. +* @ec_dev: Device to suspend. +* +* This can be called by drivers to handle a suspend event. +* +* Return: 0 always. +*/ +int cros_ec_suspend (struct cros_ec_device *ec_dev) +{ +cros_ec_send_suspend_event (ec_dev); +cros_ec_disable_irq (ec_dev);return 0 ; }EXPORT_SYMBOL (cros_ec_suspend);
@@ -370,22 +408,11 @@ static void cros_ec_report_events_during_suspend(struct cros_ec_device *ec_dev) } } -/** -* cros_ec_resume() - Handle a resume operation for the ChromeOS EC device. -* @ec_dev: Device to resume. -* -* This can be called by drivers to handle a resume event. -* -* Return: 0 on success or negative error code. -*/ -int cros_ec_resume (struct cros_ec_device *ec_dev) +static void cros_ec_send_resume_event (struct cros_ec_device *ec_dev) {int ret;u8 sleep_event; - ec_dev->suspended = false; -enable_irq (ec_dev->irq); - sleep_event = (!IS_ENABLED (CONFIG_ACPI ) ||pm_suspend_via_firmware ()) ?HOST_SLEEP_EVENT_S3_RESUME :HOST_SLEEP_EVENT_S0IX_RESUME ;
@@ -394,6 +421,24 @@ int cros_ec_resume(struct cros_ec_device *ec_dev)if (ret <0 )dev_dbg (ec_dev->dev,"Error %d sending resume event to ec\n" , ret); +} + +/** +* cros_ec_resume_complete() - Handle a resume complete operation for the ChromeOS EC device. +* @ec_dev: Device to resume. +* +* This can be called by drivers to handle a resume complete stage of resume. +*/ +void cros_ec_resume_complete (struct cros_ec_device *ec_dev) +{ +cros_ec_send_resume_event (ec_dev); +} +EXPORT_SYMBOL (cros_ec_resume_complete); + +static void cros_ec_enable_irq (struct cros_ec_device *ec_dev) +{ + ec_dev->suspended = false; +enable_irq (ec_dev->irq);if (ec_dev->wake_enabled)disable_irq_wake (ec_dev->irq);
@@ -403,8 +448,35 @@ int cros_ec_resume(struct cros_ec_device *ec_dev)* suspend. This way the clients know what to do with them. */ cros_ec_report_events_during_suspend (ec_dev); +} +/** +* cros_ec_resume_early() - Handle a resume early operation for the ChromeOS EC device. +* @ec_dev: Device to resume. +* +* This can be called by drivers to handle a resume early stage of resume. +* +* Return: 0 always. +*/ +int cros_ec_resume_early (struct cros_ec_device *ec_dev) +{ +cros_ec_enable_irq (ec_dev); +return 0 ; +} +EXPORT_SYMBOL (cros_ec_resume_early); +/** +* cros_ec_resume() - Handle a resume operation for the ChromeOS EC device. +* @ec_dev: Device to resume. +* +* This can be called by drivers to handle a resume event. +* +* Return: 0 always. +*/ +int cros_ec_resume (struct cros_ec_device *ec_dev) +{ +cros_ec_enable_irq (ec_dev); +cros_ec_send_resume_event (ec_dev);return 0 ; }EXPORT_SYMBOL (cros_ec_resume);
drivers/platform/chrome/cros_ec.h +4 -0
@@ -14,7 +14,11 @@ int cros_ec_register(struct cros_ec_device *ec_dev);void cros_ec_unregister (struct cros_ec_device *ec_dev);int cros_ec_suspend (struct cros_ec_device *ec_dev); +int cros_ec_suspend_late (struct cros_ec_device *ec_dev); +int cros_ec_suspend_prepare (struct cros_ec_device *ec_dev);int cros_ec_resume (struct cros_ec_device *ec_dev); +int cros_ec_resume_early (struct cros_ec_device *ec_dev); +void cros_ec_resume_complete (struct cros_ec_device *ec_dev);irqreturn_t cros_ec_irq_thread (int irq,void *data);
drivers/platform/chrome/cros_ec_lpc.c +18 -4
@@ -549,22 +549,36 @@ MODULE_DEVICE_TABLE(dmi, cros_ec_lpc_dmi_table);static int cros_ec_lpc_prepare (struct device *dev) {struct cros_ec_device *ec_dev =dev_get_drvdata (dev); - -return cros_ec_suspend (ec_dev); +return cros_ec_suspend_prepare (ec_dev); }static void cros_ec_lpc_complete (struct device *dev) {struct cros_ec_device *ec_dev =dev_get_drvdata (dev); -cros_ec_resume (ec_dev); +cros_ec_resume_complete (ec_dev); +} + +static int cros_ec_lpc_suspend_late (struct device *dev) +{ +struct cros_ec_device *ec_dev =dev_get_drvdata (dev); + +return cros_ec_suspend_late (ec_dev); +} + +static int cros_ec_lpc_resume_early (struct device *dev) +{ +struct cros_ec_device *ec_dev =dev_get_drvdata (dev); + +return cros_ec_resume_early (ec_dev); }#endif static const struct dev_pm_ops cros_ec_lpc_pm_ops = { #ifdef CONFIG_PM_SLEEP .prepare = cros_ec_lpc_prepare, - .complete = cros_ec_lpc_complete + .complete = cros_ec_lpc_complete, #endif +SET_LATE_SYSTEM_SLEEP_PM_OPS (cros_ec_lpc_suspend_late, cros_ec_lpc_resume_early) };static struct platform_driver cros_ec_lpc_driver = {
Signature · 1 line
2.42.0
Greg Kroah-Hartman
maintainerPATCH 212/603 spi: omap2-mcspi: switch to use modern name
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Yang Yingliang <[email protected]>
[ Upstream commit ee0f793cc1881225dee04216f1080201603b46bb ]
Change legacy name master/slave to modern name host/target or controller.
No functional changed.
Stable-dep-of: 2d9f4877988f ("spi: omap2-mcspi: Fix hardcoded reference clock")
--- drivers/spi/spi-omap2-mcspi.c | 236 +++++++++++++++++----------------- 1 file changed, 118 insertions(+), 118 deletions(-)
drivers/spi/spi-omap2-mcspi.c +118 -118
@@ -117,7 +117,7 @@ struct omap2_mcspi_regs {struct omap2_mcspi {struct completion txdone; -struct spi_master *master; +struct spi_controller *ctlr;/* Virtual base address of the controller */ void __iomem *base;unsigned long phys;
@@ -126,7 +126,7 @@ struct omap2_mcspi {struct device *dev;struct omap2_mcspi_regs ctx;int fifo_depth; -bool slave_aborted; +bool target_aborted; unsigned int pin_dir:1;size_t max_xfer_len; };
@@ -141,17 +141,17 @@ struct omap2_mcspi_cs {u32 chconf0, chctrl0; }; -static inline void mcspi_write_reg (struct spi_master *master, +static inline void mcspi_write_reg (struct spi_controller *ctlr,int idx,u32 val) { -struct omap2_mcspi *mcspi =spi_master_get_devdata (master); +struct omap2_mcspi *mcspi =spi_controller_get_devdata (ctlr);writel_relaxed (val, mcspi->base + idx); } -static inline u32 mcspi_read_reg (struct spi_master *master,int idx) +static inline u32 mcspi_read_reg (struct spi_controller *ctlr,int idx) { -struct omap2_mcspi *mcspi =spi_master_get_devdata (master); +struct omap2_mcspi *mcspi =spi_controller_get_devdata (ctlr);return readl_relaxed (mcspi->base + idx); }
@@ -235,7 +235,7 @@ static void omap2_mcspi_set_enable(const struct spi_device *spi, int enable)static void omap2_mcspi_set_cs (struct spi_device *spi,bool enable) { -struct omap2_mcspi *mcspi =spi_master_get_devdata (spi->master); +struct omap2_mcspi *mcspi =spi_controller_get_devdata (spi->controller);u32 l;/* The controller handles the inverted chip selects
@@ -266,24 +266,24 @@ static void omap2_mcspi_set_cs(struct spi_device *spi, bool enable) } } -static void omap2_mcspi_set_mode (struct spi_master *master) +static void omap2_mcspi_set_mode (struct spi_controller *ctlr) { -struct omap2_mcspi *mcspi =spi_master_get_devdata (master); +struct omap2_mcspi *mcspi =spi_controller_get_devdata (ctlr);struct omap2_mcspi_regs *ctx = &mcspi->ctx;u32 l;/* -* Choose master or slave mode +* Choose host or target mode */ - l =mcspi_read_reg (master,OMAP2_MCSPI_MODULCTRL ); + l =mcspi_read_reg (ctlr,OMAP2_MCSPI_MODULCTRL ); l &= ~(OMAP2_MCSPI_MODULCTRL_STEST ); -if (spi_controller_is_slave (master)) { +if (spi_controller_is_target (ctlr)) { l |= (OMAP2_MCSPI_MODULCTRL_MS ); }else { l &= ~(OMAP2_MCSPI_MODULCTRL_MS ); l |=OMAP2_MCSPI_MODULCTRL_SINGLE ; } -mcspi_write_reg (master,OMAP2_MCSPI_MODULCTRL , l); +mcspi_write_reg (ctlr,OMAP2_MCSPI_MODULCTRL , l); ctx->modulctrl = l; }
@@ -291,14 +291,14 @@ static void omap2_mcspi_set_mode(struct spi_master *master)static void omap2_mcspi_set_fifo (const struct spi_device *spi,struct spi_transfer *t,int enable) { -struct spi_master *master = spi->master; +struct spi_controller *ctlr = spi->controller;struct omap2_mcspi_cs *cs = spi->controller_state;struct omap2_mcspi *mcspi;unsigned int wcnt;int max_fifo_depth, bytes_per_word;u32 chconf, xferlevel; - mcspi =spi_master_get_devdata (master); + mcspi =spi_controller_get_devdata (ctlr); chconf =mcspi_cached_chconf0 (spi);if (enable) {
@@ -326,7 +326,7 @@ static void omap2_mcspi_set_fifo(const struct spi_device *spi, xferlevel |= bytes_per_word -1 ; } -mcspi_write_reg (master,OMAP2_MCSPI_XFERLEVEL , xferlevel); +mcspi_write_reg (ctlr,OMAP2_MCSPI_XFERLEVEL , xferlevel);mcspi_write_chconf0 (spi, chconf); mcspi->fifo_depth = max_fifo_depth;
@@ -364,9 +364,9 @@ static int mcspi_wait_for_reg_bit(void __iomem *reg, unsigned long bit)static int mcspi_wait_for_completion (struct omap2_mcspi *mcspi,struct completion *x) { -if (spi_controller_is_slave (mcspi->master)) { +if (spi_controller_is_target (mcspi->ctlr)) {if (wait_for_completion_interruptible (x) || - mcspi->slave_aborted) + mcspi->target_aborted)return -EINTR ; }else {wait_for_completion (x);
@@ -378,7 +378,7 @@ static int mcspi_wait_for_completion(struct omap2_mcspi *mcspi,static void omap2_mcspi_rx_callback (void *data) {struct spi_device *spi = data; -struct omap2_mcspi *mcspi =spi_master_get_devdata (spi->master); +struct omap2_mcspi *mcspi =spi_controller_get_devdata (spi->controller);struct omap2_mcspi_dma *mcspi_dma = &mcspi->dma_channels[spi_get_chipselect (spi,0 )];/* We must disable the DMA RX request */
@@ -390,7 +390,7 @@ static void omap2_mcspi_rx_callback(void *data)static void omap2_mcspi_tx_callback (void *data) {struct spi_device *spi = data; -struct omap2_mcspi *mcspi =spi_master_get_devdata (spi->master); +struct omap2_mcspi *mcspi =spi_controller_get_devdata (spi->controller);struct omap2_mcspi_dma *mcspi_dma = &mcspi->dma_channels[spi_get_chipselect (spi,0 )];/* We must disable the DMA TX request */
@@ -407,7 +407,7 @@ static void omap2_mcspi_tx_dma(struct spi_device *spi,struct omap2_mcspi_dma *mcspi_dma;struct dma_async_tx_descriptor *tx; - mcspi =spi_master_get_devdata (spi->master); + mcspi =spi_controller_get_devdata (spi->controller); mcspi_dma = &mcspi->dma_channels[spi_get_chipselect (spi,0 )];dmaengine_slave_config (mcspi_dma->dma_tx, &cfg);
@@ -445,13 +445,13 @@ omap2_mcspi_rx_dma(struct spi_device *spi, struct spi_transfer *xfer,void __iomem *chstat_reg = cs->base +OMAP2_MCSPI_CHSTAT0 ;struct dma_async_tx_descriptor *tx; - mcspi =spi_master_get_devdata (spi->master); + mcspi =spi_controller_get_devdata (spi->controller); mcspi_dma = &mcspi->dma_channels[spi_get_chipselect (spi,0 )]; count = xfer->len;/* * In the "End-of-Transfer Procedure" section for DMA RX in OMAP35x TRM -* it mentions reducing DMA transfer length by one element in master +* it mentions reducing DMA transfer length by one element in host * normal mode. */ if (mcspi->fifo_depth ==0 )
@@ -514,7 +514,7 @@ omap2_mcspi_rx_dma(struct spi_device *spi, struct spi_transfer *xfer,omap2_mcspi_set_dma_req (spi,1 ,1 ); ret =mcspi_wait_for_completion (mcspi, &mcspi_dma->dma_rx_completion); -if (ret || mcspi->slave_aborted) { +if (ret || mcspi->target_aborted) {dmaengine_terminate_sync (mcspi_dma->dma_rx);omap2_mcspi_set_dma_req (spi,1 ,0 );return 0 ;
@@ -590,7 +590,7 @@ omap2_mcspi_txrx_dma(struct spi_device *spi, struct spi_transfer *xfer)void __iomem *irqstat_reg;int wait_res; - mcspi =spi_master_get_devdata (spi->master); + mcspi =spi_controller_get_devdata (spi->controller); mcspi_dma = &mcspi->dma_channels[spi_get_chipselect (spi,0 )];if (cs->word_len <=8 ) {
@@ -617,14 +617,14 @@ omap2_mcspi_txrx_dma(struct spi_device *spi, struct spi_transfer *xfer) rx = xfer->rx_buf; tx = xfer->tx_buf; - mcspi->slave_aborted = false; + mcspi->target_aborted = false;reinit_completion (&mcspi_dma->dma_tx_completion);reinit_completion (&mcspi_dma->dma_rx_completion);reinit_completion (&mcspi->txdone);if (tx) { -/* Enable EOW IRQ to know end of tx in slave mode */ -if (spi_controller_is_slave (spi->master)) -mcspi_write_reg (spi->master, +/* Enable EOW IRQ to know end of tx in target mode */ +if (spi_controller_is_target (spi->controller)) +mcspi_write_reg (spi->controller,OMAP2_MCSPI_IRQENABLE ,OMAP2_MCSPI_IRQSTATUS_EOW );omap2_mcspi_tx_dma (spi, xfer, cfg);
@@ -637,15 +637,15 @@ omap2_mcspi_txrx_dma(struct spi_device *spi, struct spi_transfer *xfer)int ret; ret =mcspi_wait_for_completion (mcspi, &mcspi_dma->dma_tx_completion); -if (ret || mcspi->slave_aborted) { +if (ret || mcspi->target_aborted) {dmaengine_terminate_sync (mcspi_dma->dma_tx);omap2_mcspi_set_dma_req (spi,0 ,0 );return 0 ; } -if (spi_controller_is_slave (mcspi->master)) { +if (spi_controller_is_target (mcspi->ctlr)) { ret =mcspi_wait_for_completion (mcspi, &mcspi->txdone); -if (ret || mcspi->slave_aborted) +if (ret || mcspi->target_aborted)return 0 ; }
@@ -656,7 +656,7 @@ omap2_mcspi_txrx_dma(struct spi_device *spi, struct spi_transfer *xfer) OMAP2_MCSPI_IRQSTATUS_EOW) < 0)dev_err (&spi->dev,"EOW timed out\n" ); -mcspi_write_reg (mcspi->master,OMAP2_MCSPI_IRQSTATUS , +mcspi_write_reg (mcspi->ctlr,OMAP2_MCSPI_IRQSTATUS ,OMAP2_MCSPI_IRQSTATUS_EOW ); }
@@ -901,7 +901,7 @@ static int omap2_mcspi_setup_transfer(struct spi_device *spi,u8 word_len = spi->bits_per_word;u32 speed_hz = spi->max_speed_hz; - mcspi =spi_master_get_devdata (spi->master); + mcspi =spi_controller_get_devdata (spi->controller);if (t !=NULL && t->bits_per_word) word_len = t->bits_per_word;
@@ -926,7 +926,7 @@ static int omap2_mcspi_setup_transfer(struct spi_device *spi, l =mcspi_cached_chconf0 (spi); -/* standard 4-wire master mode: SCK, MOSI/out, MISO/in, nCS +/* standard 4-wire host mode: SCK, MOSI/out, MISO/in, nCS * REVISIT: this controller could support SPI_3WIRE mode. */ if (mcspi->pin_dir ==MCSPI_PINDIR_D0_IN_D1_OUT ) {
@@ -1017,13 +1017,13 @@ static int omap2_mcspi_request_dma(struct omap2_mcspi *mcspi,return ret; } -static void omap2_mcspi_release_dma (struct spi_master *master) +static void omap2_mcspi_release_dma (struct spi_controller *ctlr) { -struct omap2_mcspi *mcspi =spi_master_get_devdata (master); +struct omap2_mcspi *mcspi =spi_controller_get_devdata (ctlr);struct omap2_mcspi_dma *mcspi_dma;int i; -for (i =0 ; i < master->num_chipselect; i++) { +for (i =0 ; i < ctlr->num_chipselect; i++) { mcspi_dma = &mcspi->dma_channels[i];if (mcspi_dma->dma_rx) {
@@ -1054,7 +1054,7 @@ static int omap2_mcspi_setup(struct spi_device *spi) {bool initial_setup = false;int ret; -struct omap2_mcspi *mcspi =spi_master_get_devdata (spi->master); +struct omap2_mcspi *mcspi =spi_controller_get_devdata (spi->controller);struct omap2_mcspi_regs *ctx = &mcspi->ctx;struct omap2_mcspi_cs *cs = spi->controller_state;
@@ -1096,24 +1096,24 @@ static irqreturn_t omap2_mcspi_irq_handler(int irq, void *data)struct omap2_mcspi *mcspi = data;u32 irqstat; - irqstat =mcspi_read_reg (mcspi->master,OMAP2_MCSPI_IRQSTATUS ); + irqstat =mcspi_read_reg (mcspi->ctlr,OMAP2_MCSPI_IRQSTATUS );if (!irqstat)return IRQ_NONE ; -/* Disable IRQ and wakeup slave xfer task */ -mcspi_write_reg (mcspi->master,OMAP2_MCSPI_IRQENABLE ,0 ); +/* Disable IRQ and wakeup target xfer task */ +mcspi_write_reg (mcspi->ctlr,OMAP2_MCSPI_IRQENABLE ,0 );if (irqstat &OMAP2_MCSPI_IRQSTATUS_EOW )complete (&mcspi->txdone);return IRQ_HANDLED ; } -static int omap2_mcspi_slave_abort (struct spi_master *master) +static int omap2_mcspi_target_abort (struct spi_controller *ctlr) { -struct omap2_mcspi *mcspi =spi_master_get_devdata (master); +struct omap2_mcspi *mcspi =spi_controller_get_devdata (ctlr);struct omap2_mcspi_dma *mcspi_dma = mcspi->dma_channels; - mcspi->slave_aborted = true; + mcspi->target_aborted = true;complete (&mcspi_dma->dma_rx_completion);complete (&mcspi_dma->dma_tx_completion);complete (&mcspi->txdone);
@@ -1121,7 +1121,7 @@ static int omap2_mcspi_slave_abort(struct spi_master *master)return 0 ; } -static int omap2_mcspi_transfer_one (struct spi_master *master, +static int omap2_mcspi_transfer_one (struct spi_controller *ctlr,struct spi_device *spi,struct spi_transfer *t) {
@@ -1129,7 +1129,7 @@ static int omap2_mcspi_transfer_one(struct spi_master *master,/* We only enable one channel at a time -- the one whose message is * -- although this controller would gladly * arbitrate among multiple channels. This corresponds to "single -* channel" master mode. As a side effect, we need to manage the +* channel" host mode. As a side effect, we need to manage the * chipselect with the FORCE bit ... CS != channel enable. */
@@ -1141,13 +1141,13 @@ static int omap2_mcspi_transfer_one(struct spi_master *master,int status =0 ;u32 chconf; - mcspi =spi_master_get_devdata (master); + mcspi =spi_controller_get_devdata (ctlr); mcspi_dma = mcspi->dma_channels +spi_get_chipselect (spi,0 ); cs = spi->controller_state; cd = spi->controller_data;/* -* The slave driver could have changed spi->mode in which case +* The target driver could have changed spi->mode in which case * it will be different from cs->mode (the current hardware setup). * If so, set par_override (even though its not a parity issue) so * omap2_mcspi_setup_transfer will be called to configure the hardware
@@ -1175,7 +1175,7 @@ static int omap2_mcspi_transfer_one(struct spi_master *master,if (cd && cd->cs_per_word) { chconf = mcspi->ctx.modulctrl; chconf &= ~OMAP2_MCSPI_MODULCTRL_SINGLE ; -mcspi_write_reg (master,OMAP2_MCSPI_MODULCTRL , chconf); +mcspi_write_reg (ctlr,OMAP2_MCSPI_MODULCTRL , chconf); mcspi->ctx.modulctrl =mcspi_read_cs_reg (spi,OMAP2_MCSPI_MODULCTRL ); }
@@ -1201,8 +1201,8 @@ static int omap2_mcspi_transfer_one(struct spi_master *master,unsigned count;if ((mcspi_dma->dma_rx && mcspi_dma->dma_tx) && - master->cur_msg_mapped && - master->can_dma (master, spi, t)) + ctlr->cur_msg_mapped && + ctlr->can_dma (ctlr, spi, t))omap2_mcspi_set_fifo (spi, t,1 );omap2_mcspi_set_enable (spi,1 );
@@ -1213,8 +1213,8 @@ static int omap2_mcspi_transfer_one(struct spi_master *master, + OMAP2_MCSPI_TX0);if ((mcspi_dma->dma_rx && mcspi_dma->dma_tx) && - master->cur_msg_mapped && - master->can_dma (master, spi, t)) + ctlr->cur_msg_mapped && + ctlr->can_dma (ctlr, spi, t)) count =omap2_mcspi_txrx_dma (spi, t);else count =omap2_mcspi_txrx_pio (spi, t);
@@ -1240,7 +1240,7 @@ static int omap2_mcspi_transfer_one(struct spi_master *master,if (cd && cd->cs_per_word) { chconf = mcspi->ctx.modulctrl; chconf |=OMAP2_MCSPI_MODULCTRL_SINGLE ; -mcspi_write_reg (master,OMAP2_MCSPI_MODULCTRL , chconf); +mcspi_write_reg (ctlr,OMAP2_MCSPI_MODULCTRL , chconf); mcspi->ctx.modulctrl =mcspi_read_cs_reg (spi,OMAP2_MCSPI_MODULCTRL ); }
@@ -1256,10 +1256,10 @@ static int omap2_mcspi_transfer_one(struct spi_master *master,return status; } -static int omap2_mcspi_prepare_message (struct spi_master *master, +static int omap2_mcspi_prepare_message (struct spi_controller *ctlr,struct spi_message *msg) { -struct omap2_mcspi *mcspi =spi_master_get_devdata (master); +struct omap2_mcspi *mcspi =spi_controller_get_devdata (ctlr);struct omap2_mcspi_regs *ctx = &mcspi->ctx;struct omap2_mcspi_cs *cs;
@@ -1283,29 +1283,29 @@ static int omap2_mcspi_prepare_message(struct spi_master *master,return 0 ; } -static bool omap2_mcspi_can_dma (struct spi_master *master, +static bool omap2_mcspi_can_dma (struct spi_controller *ctlr,struct spi_device *spi,struct spi_transfer *xfer) { -struct omap2_mcspi *mcspi =spi_master_get_devdata (spi->master); +struct omap2_mcspi *mcspi =spi_controller_get_devdata (spi->controller);struct omap2_mcspi_dma *mcspi_dma = &mcspi->dma_channels[spi_get_chipselect (spi,0 )];if (!mcspi_dma->dma_rx || !mcspi_dma->dma_tx)return false; -if (spi_controller_is_slave (master)) +if (spi_controller_is_target (ctlr))return true; - master->dma_rx = mcspi_dma->dma_rx; - master->dma_tx = mcspi_dma->dma_tx; + ctlr->dma_rx = mcspi_dma->dma_rx; + ctlr->dma_tx = mcspi_dma->dma_tx;return (xfer->len >=DMA_MIN_BYTES ); }static size_t omap2_mcspi_max_xfer_size (struct spi_device *spi) { -struct omap2_mcspi *mcspi =spi_master_get_devdata (spi->master); +struct omap2_mcspi *mcspi =spi_controller_get_devdata (spi->controller);struct omap2_mcspi_dma *mcspi_dma = &mcspi->dma_channels[spi_get_chipselect (spi,0 )];
@@ -1317,7 +1317,7 @@ static size_t omap2_mcspi_max_xfer_size(struct spi_device *spi)static int omap2_mcspi_controller_setup (struct omap2_mcspi *mcspi) { -struct spi_master *master = mcspi->master; +struct spi_controller *ctlr = mcspi->ctlr;struct omap2_mcspi_regs *ctx = &mcspi->ctx;int ret =0 ;
@@ -1325,11 +1325,11 @@ static int omap2_mcspi_controller_setup(struct omap2_mcspi *mcspi)if (ret <0 )return ret; -mcspi_write_reg (master,OMAP2_MCSPI_WAKEUPENABLE , +mcspi_write_reg (ctlr,OMAP2_MCSPI_WAKEUPENABLE ,OMAP2_MCSPI_WAKEUPENABLE_WKEN ); ctx->wakeupenable =OMAP2_MCSPI_WAKEUPENABLE_WKEN ; -omap2_mcspi_set_mode (master); +omap2_mcspi_set_mode (ctlr);pm_runtime_mark_last_busy (mcspi->dev);pm_runtime_put_autosuspend (mcspi->dev);return 0 ;
@@ -1353,8 +1353,8 @@ static int omap_mcspi_runtime_suspend(struct device *dev)*/ static int omap_mcspi_runtime_resume (struct device *dev) { -struct spi_master *master =dev_get_drvdata (dev); -struct omap2_mcspi *mcspi =spi_master_get_devdata (master); +struct spi_controller *ctlr =dev_get_drvdata (dev); +struct omap2_mcspi *mcspi =spi_controller_get_devdata (ctlr);struct omap2_mcspi_regs *ctx = &mcspi->ctx;struct omap2_mcspi_cs *cs;int error;
@@ -1364,8 +1364,8 @@ static int omap_mcspi_runtime_resume(struct device *dev)dev_warn (dev,"%s: failed to set pins: %i\n" , __func__, error);/* McSPI: context restore */ -mcspi_write_reg (master,OMAP2_MCSPI_MODULCTRL , ctx->modulctrl); -mcspi_write_reg (master,OMAP2_MCSPI_WAKEUPENABLE , ctx->wakeupenable); +mcspi_write_reg (ctlr,OMAP2_MCSPI_MODULCTRL , ctx->modulctrl); +mcspi_write_reg (ctlr,OMAP2_MCSPI_WAKEUPENABLE , ctx->wakeupenable);list_for_each_entry (cs, &ctx->cs, node) {/*
@@ -1420,7 +1420,7 @@ MODULE_DEVICE_TABLE(of, omap_mcspi_of_match);static int omap2_mcspi_probe (struct platform_device *pdev) { -struct spi_master *master; +struct spi_controller *ctlr;const struct omap2_mcspi_platform_config *pdata;struct omap2_mcspi *mcspi;struct resource *r;
@@ -1430,32 +1430,32 @@ static int omap2_mcspi_probe(struct platform_device *pdev)const struct of_device_id *match;if (of_property_read_bool (node,"spi-slave" )) - master =spi_alloc_slave (&pdev->dev,sizeof (*mcspi)); + ctlr =spi_alloc_target (&pdev->dev,sizeof (*mcspi));else - master =spi_alloc_master (&pdev->dev,sizeof (*mcspi)); -if (!master) + ctlr =spi_alloc_host (&pdev->dev,sizeof (*mcspi)); +if (!ctlr)return -ENOMEM ;/* the spi->mode bits understood by this driver: */ - master->mode_bits =SPI_CPOL |SPI_CPHA |SPI_CS_HIGH ; - master->bits_per_word_mask =SPI_BPW_RANGE_MASK (4 ,32 ); - master->setup = omap2_mcspi_setup; - master->auto_runtime_pm = true; - master->prepare_message = omap2_mcspi_prepare_message; - master->can_dma = omap2_mcspi_can_dma; - master->transfer_one = omap2_mcspi_transfer_one; - master->set_cs = omap2_mcspi_set_cs; - master->cleanup = omap2_mcspi_cleanup; - master->slave_abort = omap2_mcspi_slave_abort; - master->dev.of_node = node; - master->max_speed_hz =OMAP2_MCSPI_MAX_FREQ ; - master->min_speed_hz =OMAP2_MCSPI_MAX_FREQ >>15 ; - master->use_gpio_descriptors = true; - -platform_set_drvdata (pdev, master); - - mcspi =spi_master_get_devdata (master); - mcspi->master = master; + ctlr->mode_bits =SPI_CPOL |SPI_CPHA |SPI_CS_HIGH ; + ctlr->bits_per_word_mask =SPI_BPW_RANGE_MASK (4 ,32 ); + ctlr->setup = omap2_mcspi_setup; + ctlr->auto_runtime_pm = true; + ctlr->prepare_message = omap2_mcspi_prepare_message; + ctlr->can_dma = omap2_mcspi_can_dma; + ctlr->transfer_one = omap2_mcspi_transfer_one; + ctlr->set_cs = omap2_mcspi_set_cs; + ctlr->cleanup = omap2_mcspi_cleanup; + ctlr->target_abort = omap2_mcspi_target_abort; + ctlr->dev.of_node = node; + ctlr->max_speed_hz =OMAP2_MCSPI_MAX_FREQ ; + ctlr->min_speed_hz =OMAP2_MCSPI_MAX_FREQ >>15 ; + ctlr->use_gpio_descriptors = true; + +platform_set_drvdata (pdev, ctlr); + + mcspi =spi_controller_get_devdata (ctlr); + mcspi->ctlr = ctlr; match =of_match_device (omap_mcspi_of_match, &pdev->dev);if (match) {
@@ -1463,24 +1463,24 @@ static int omap2_mcspi_probe(struct platform_device *pdev) pdata = match->data;of_property_read_u32 (node,"ti,spi-num-cs" , &num_cs); - master->num_chipselect = num_cs; + ctlr->num_chipselect = num_cs;if (of_property_read_bool (node,"ti,pindir-d0-out-d1-in" )) mcspi->pin_dir =MCSPI_PINDIR_D0_OUT_D1_IN ; }else { pdata =dev_get_platdata (&pdev->dev); - master->num_chipselect = pdata->num_cs; + ctlr->num_chipselect = pdata->num_cs; mcspi->pin_dir = pdata->pin_dir; } regs_offset = pdata->regs_offset;if (pdata->max_xfer_len) { mcspi->max_xfer_len = pdata->max_xfer_len; - master->max_transfer_size = omap2_mcspi_max_xfer_size; + ctlr->max_transfer_size = omap2_mcspi_max_xfer_size; } mcspi->base =devm_platform_get_and_ioremap_resource (pdev,0 , &r);if (IS_ERR (mcspi->base)) { status =PTR_ERR (mcspi->base); - goto free_master; + goto free_ctlr; } mcspi->phys = r->start + regs_offset; mcspi->base += regs_offset;
@@ -1489,34 +1489,34 @@ static int omap2_mcspi_probe(struct platform_device *pdev)INIT_LIST_HEAD (&mcspi->ctx.cs); - mcspi->dma_channels =devm_kcalloc (&pdev->dev, master->num_chipselect, + mcspi->dma_channels =devm_kcalloc (&pdev->dev, ctlr->num_chipselect,sizeof (struct omap2_mcspi_dma ),GFP_KERNEL );if (mcspi->dma_channels ==NULL ) { status = -ENOMEM ; - goto free_master; + goto free_ctlr; } -for (i =0 ; i < master->num_chipselect; i++) { +for (i =0 ; i < ctlr->num_chipselect; i++) {sprintf (mcspi->dma_channels[i].dma_rx_ch_name,"rx%d" , i);sprintf (mcspi->dma_channels[i].dma_tx_ch_name,"tx%d" , i); status =omap2_mcspi_request_dma (mcspi, &mcspi->dma_channels[i]);if (status == -EPROBE_DEFER ) - goto free_master; + goto free_ctlr; } status =platform_get_irq (pdev,0 );if (status <0 ) - goto free_master; + goto free_ctlr;init_completion (&mcspi->txdone); status =devm_request_irq (&pdev->dev, status, omap2_mcspi_irq_handler,0 , pdev->name, mcspi);if (status) {dev_err (&pdev->dev,"Cannot request IRQ" ); - goto free_master; + goto free_ctlr; }pm_runtime_use_autosuspend (&pdev->dev);
@@ -1527,7 +1527,7 @@ static int omap2_mcspi_probe(struct platform_device *pdev)if (status <0 ) goto disable_pm; - status =devm_spi_register_controller (&pdev->dev, master); + status =devm_spi_register_controller (&pdev->dev, ctlr);if (status <0 ) goto disable_pm;
@@ -1537,18 +1537,18 @@ static int omap2_mcspi_probe(struct platform_device *pdev)pm_runtime_dont_use_autosuspend (&pdev->dev);pm_runtime_put_sync (&pdev->dev);pm_runtime_disable (&pdev->dev); -free_master: -omap2_mcspi_release_dma (master); -spi_master_put (master); +free_ctlr: +omap2_mcspi_release_dma (ctlr); +spi_controller_put (ctlr);return status; }static void omap2_mcspi_remove (struct platform_device *pdev) { -struct spi_master *master =platform_get_drvdata (pdev); -struct omap2_mcspi *mcspi =spi_master_get_devdata (master); +struct spi_controller *ctlr =platform_get_drvdata (pdev); +struct omap2_mcspi *mcspi =spi_controller_get_devdata (ctlr); -omap2_mcspi_release_dma (master); +omap2_mcspi_release_dma (ctlr);pm_runtime_dont_use_autosuspend (mcspi->dev);pm_runtime_put_sync (mcspi->dev);
@@ -1560,8 +1560,8 @@ MODULE_ALIAS("platform:omap2_mcspi");static int __maybe_unused omap2_mcspi_suspend (struct device *dev) { -struct spi_master *master =dev_get_drvdata (dev); -struct omap2_mcspi *mcspi =spi_master_get_devdata (master); +struct spi_controller *ctlr =dev_get_drvdata (dev); +struct omap2_mcspi *mcspi =spi_controller_get_devdata (ctlr);int error; error =pinctrl_pm_select_sleep_state (dev);
@@ -1569,9 +1569,9 @@ static int __maybe_unused omap2_mcspi_suspend(struct device *dev)dev_warn (mcspi->dev,"%s: failed to set pins: %i\n" , __func__, error); - error =spi_master_suspend (master); + error =spi_controller_suspend (ctlr);if (error) -dev_warn (mcspi->dev,"%s: master suspend failed: %i\n" , +dev_warn (mcspi->dev,"%s: controller suspend failed: %i\n" , __func__, error);return pm_runtime_force_suspend (dev);
@@ -1579,13 +1579,13 @@ static int __maybe_unused omap2_mcspi_suspend(struct device *dev)static int __maybe_unused omap2_mcspi_resume (struct device *dev) { -struct spi_master *master =dev_get_drvdata (dev); -struct omap2_mcspi *mcspi =spi_master_get_devdata (master); +struct spi_controller *ctlr =dev_get_drvdata (dev); +struct omap2_mcspi *mcspi =spi_controller_get_devdata (ctlr);int error; - error =spi_master_resume (master); + error =spi_controller_resume (ctlr);if (error) -dev_warn (mcspi->dev,"%s: master resume failed: %i\n" , +dev_warn (mcspi->dev,"%s: controller resume failed: %i\n" , __func__, error);return pm_runtime_force_resume (dev);
Signature · 1 line
2.42.0
Greg Kroah-Hartman
maintainerPATCH 213/603 spi: omap2-mcspi: Fix hardcoded reference clock
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Vaishnav Achath <[email protected]>
[ Upstream commit 2d9f4877988f64f0f336983de65c365b6a7debfb ]
A hardcoded reference clock of 48 MHz is used to calculate the clock divisor values, but the reference clock frequency can be different across devices and can be configured which can cause a mismatch between the reported frequency and actual SPI clock frequency observed. Fix this by fetching the clock rate from the clock provider and falling back to hardcoded reference only if the clock is not supplied.
--- drivers/spi/spi-omap2-mcspi.c | 31 ++++++++++++++++++++----------- 1 file changed, 20 insertions(+), 11 deletions(-)
drivers/spi/spi-omap2-mcspi.c +20 -11
@@ -125,10 +125,12 @@ struct omap2_mcspi {struct omap2_mcspi_dma *dma_channels;struct device *dev;struct omap2_mcspi_regs ctx; +struct clk *ref_clk;int fifo_depth;bool target_aborted; unsigned int pin_dir:1;size_t max_xfer_len; +u32 ref_clk_hz; };struct omap2_mcspi_cs {
@@ -880,12 +882,12 @@ omap2_mcspi_txrx_pio(struct spi_device *spi, struct spi_transfer *xfer)return count - c; } -static u32 omap2_mcspi_calc_divisor (u32 speed_hz) +static u32 omap2_mcspi_calc_divisor (u32 speed_hz,u32 ref_clk_hz) {u32 div;for (div =0 ; div <15 ; div++) -if (speed_hz >= (OMAP2_MCSPI_MAX_FREQ >> div)) +if (speed_hz >= (ref_clk_hz >> div))return div;return 15 ;
@@ -897,7 +899,7 @@ static int omap2_mcspi_setup_transfer(struct spi_device *spi, {struct omap2_mcspi_cs *cs = spi->controller_state;struct omap2_mcspi *mcspi; -u32 l =0 , clkd =0 , div, extclk =0 , clkg =0 ; +u32 ref_clk_hz, l =0 , clkd =0 , div, extclk =0 , clkg =0 ;u8 word_len = spi->bits_per_word;u32 speed_hz = spi->max_speed_hz;
@@ -911,14 +913,15 @@ static int omap2_mcspi_setup_transfer(struct spi_device *spi,if (t && t->speed_hz) speed_hz = t->speed_hz; - speed_hz =min_t (u32, speed_hz,OMAP2_MCSPI_MAX_FREQ ); -if (speed_hz < (OMAP2_MCSPI_MAX_FREQ /OMAP2_MCSPI_MAX_DIVIDER )) { - clkd =omap2_mcspi_calc_divisor (speed_hz); - speed_hz =OMAP2_MCSPI_MAX_FREQ >> clkd; + ref_clk_hz = mcspi->ref_clk_hz; + speed_hz =min_t (u32, speed_hz, ref_clk_hz); +if (speed_hz < (ref_clk_hz /OMAP2_MCSPI_MAX_DIVIDER )) { + clkd =omap2_mcspi_calc_divisor (speed_hz, ref_clk_hz); + speed_hz = ref_clk_hz >> clkd; clkg =0 ; }else { - div = (OMAP2_MCSPI_MAX_FREQ + speed_hz -1 ) / speed_hz; - speed_hz =OMAP2_MCSPI_MAX_FREQ / div; + div = (ref_clk_hz + speed_hz -1 ) / speed_hz; + speed_hz = ref_clk_hz / div; clkd = (div -1 ) &0xf ; extclk = (div -1 ) >>4 ; clkg =OMAP2_MCSPI_CHCONF_CLKG ;
@@ -1448,8 +1451,6 @@ static int omap2_mcspi_probe(struct platform_device *pdev) ctlr->cleanup = omap2_mcspi_cleanup; ctlr->target_abort = omap2_mcspi_target_abort; ctlr->dev.of_node = node; - ctlr->max_speed_hz =OMAP2_MCSPI_MAX_FREQ ; - ctlr->min_speed_hz =OMAP2_MCSPI_MAX_FREQ >>15 ; ctlr->use_gpio_descriptors = true;platform_set_drvdata (pdev, ctlr);
@@ -1519,6 +1520,14 @@ static int omap2_mcspi_probe(struct platform_device *pdev) goto free_ctlr; } + mcspi->ref_clk =devm_clk_get_optional_enabled (&pdev->dev,NULL ); +if (mcspi->ref_clk) + mcspi->ref_clk_hz =clk_get_rate (mcspi->ref_clk); +else + mcspi->ref_clk_hz =OMAP2_MCSPI_MAX_FREQ ; + ctlr->max_speed_hz = mcspi->ref_clk_hz; + ctlr->min_speed_hz = mcspi->ref_clk_hz >>15 ; +pm_runtime_use_autosuspend (&pdev->dev);pm_runtime_set_autosuspend_delay (&pdev->dev,SPI_AUTOSUSPEND_TIMEOUT );pm_runtime_enable (&pdev->dev);
Signature · 1 line
2.42.0
Greg Kroah-Hartman
maintainerPATCH 214/603 drm: bridge: samsung-dsim: Initialize ULPS EXIT for i.MX8M DSIM
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Marek Vasut <[email protected]>
[ Upstream commit 192948f6a923bedf461b4aa09e70a25cfb8a6041 ]
The ULPS EXIT is initialized to 0xaf in downstream BSP as well as older revisions of this patchset, in newer revisions of the DSIM patchset it was left out and set to 0. Fix it.
--- drivers/gpu/drm/bridge/samsung-dsim.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/gpu/drm/bridge/samsung-dsim.c +1 -1
@@ -385,7 +385,7 @@ static const unsigned int imx8mm_dsim_reg_values[] = { [RESET_TYPE] = DSIM_SWRST, [PLL_TIMER] = 500, [STOP_STATE_CNT] = 0xf, - [PHYCTRL_ULPS_EXIT] = 0, + [PHYCTRL_ULPS_EXIT] = DSIM_PHYCTRL_ULPS_EXIT(0xaf), [PHYCTRL_VREG_LP] = 0, [PHYCTRL_SLEW_UP] = 0, [PHYTIMING_LPX] = DSIM_PHYTIMING_LPX(0x06),
Signature · 1 line
2.42.0
Greg Kroah-Hartman
maintainerPATCH 215/603 drm: bridge: for GENERIC_PHY_MIPI_DPHY also select GENERIC_PHY
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Randy Dunlap <[email protected]>
[ Upstream commit 96413b355a49fd684430a230479bd231d977894f ]
Three DRM bridge drivers select GENERIC_PHY_MIPI_DPHY when GENERIC_PHY might not be set. This causes Kconfig warnings and a build error.
WARNING: unmet direct dependencies detected for GENERIC_PHY_MIPI_DPHY
Depends on [n]: GENERIC_PHY [=n]
Selected by [y]:
- DRM_NWL_MIPI_DSI [=y] && DRM_BRIDGE [=y] && DRM [=y] && COMMON_CLK [=y] && OF [=y] && HAS_IOMEM [=y]
- DRM_SAMSUNG_DSIM [=y] && DRM [=y] && DRM_BRIDGE [=y] && COMMON_CLK [=y] && OF [=y] && HAS_IOMEM [=y]
(drm/bridge/cadence/Kconfig was found by inspection.)
aarch64-linux-ld: drivers/gpu/drm/bridge/samsung-dsim.o: in function `samsung_dsim_set_phy_ctrl':drivers/gpu/drm/bridge/samsung-dsim.c:731: undefined reference to `phy_mipi_dphy_get_default_config_for_hsclk'
Prevent these warnings and build error by also selecting GENERIC_PHY whenever selecting GENERIC_PHY_MIPI_DPHY.
--- drivers/gpu/drm/bridge/Kconfig | 2 ++ drivers/gpu/drm/bridge/cadence/Kconfig | 1 + 2 files changed, 3 insertions(+)
drivers/gpu/drm/bridge/Kconfig +2 -0
@@ -181,6 +181,7 @@ config DRM_NWL_MIPI_DSI select DRM_KMS_HELPER select DRM_MIPI_DSI select DRM_PANEL_BRIDGE + select GENERIC_PHY select GENERIC_PHY_MIPI_DPHY select MFD_SYSCON select MULTIPLEXER
@@ -227,6 +228,7 @@ config DRM_SAMSUNG_DSIM select DRM_KMS_HELPER select DRM_MIPI_DSI select DRM_PANEL_BRIDGE + select GENERIC_PHY select GENERIC_PHY_MIPI_DPHY help The Samsung MIPI DSIM bridge controller driver.
drivers/gpu/drm/bridge/cadence/Kconfig +1 -0
@@ -4,6 +4,7 @@ config DRM_CDNS_DSI select DRM_KMS_HELPER select DRM_MIPI_DSI select DRM_PANEL_BRIDGE + select GENERIC_PHY select GENERIC_PHY_MIPI_DPHY depends on OF help
Signature · 1 line
2.42.0
Greg Kroah-Hartman
maintainerPATCH 216/603 drm: bridge: samsung-dsim: Fix waiting for empty cmd transfer FIFO on older Exynos
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Marek Szyprowski <[email protected]>
[ Upstream commit 15f389da11257b806da75a070cfa41ca0cc15aae ]
Samsung DSIM used in older Exynos SoCs (like Exynos 4210, 4x12, 3250)
doesn't report empty level of packer header FIFO. In case of those SoCs,
use the old way of waiting for empty command tranfsfer FIFO, removed
recently by commit 14806c641582 ("drm: bridge: samsung-dsim: Drain command transfer FIFO before transfer").
--- drivers/gpu/drm/bridge/samsung-dsim.c | 18 ++++++++++++++++-- include/drm/bridge/samsung-dsim.h | 1 + 2 files changed, 17 insertions(+), 2 deletions(-)
drivers/gpu/drm/bridge/samsung-dsim.c +16 -2
@@ -413,6 +413,7 @@ static const struct samsung_dsim_driver_data exynos3_dsi_driver_data = { .m_min = 41, .m_max = 125, .min_freq = 500, + .has_broken_fifoctrl_emptyhdr = 1, };static const struct samsung_dsim_driver_data exynos4_dsi_driver_data = {
@@ -429,6 +430,7 @@ static const struct samsung_dsim_driver_data exynos4_dsi_driver_data = { .m_min = 41, .m_max = 125, .min_freq = 500, + .has_broken_fifoctrl_emptyhdr = 1, };static const struct samsung_dsim_driver_data exynos5_dsi_driver_data = {
@@ -1010,8 +1012,20 @@ static int samsung_dsim_wait_for_hdr_fifo(struct samsung_dsim *dsi) do { u32 reg = samsung_dsim_read(dsi, DSIM_FIFOCTRL_REG); - if (reg & DSIM_SFR_HEADER_EMPTY) - return 0; + if (!dsi->driver_data->has_broken_fifoctrl_emptyhdr) { + if (reg & DSIM_SFR_HEADER_EMPTY) + return 0; + } else { + if (!(reg & DSIM_SFR_HEADER_FULL)) { + /* + * Wait a little bit, so the pending data can + * actually leave the FIFO to avoid overflow. + */ + if (!cond_resched()) + usleep_range(950, 1050); + return 0; + } + } if (!cond_resched()) usleep_range(950, 1050);
include/drm/bridge/samsung-dsim.h +1 -0
@@ -53,6 +53,7 @@ struct samsung_dsim_driver_data {unsigned int plltmr_reg; unsigned int has_freqband:1; unsigned int has_clklane_stop:1; + unsigned int has_broken_fifoctrl_emptyhdr:1;unsigned int num_clks;unsigned int min_freq;unsigned int max_freq;
Signature · 1 line
2.42.0
Greg Kroah-Hartman
maintainerPATCH 217/603 drm/loongson: Fix error handling in lsdc_pixel_pll_setup()
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Harshit Mogalapalli <[email protected]>
[ Upstream commit 5976a28b344ecb6810882a01b76a320cac21d307 ]
There are two problems in lsdc_pixel_pll_setup()
1. If kzalloc() fails then call iounmap() to release the resources.
2. Both kzalloc and ioremap does not return error pointers on failure, so using IS_ERR_OR_NULL() checks is a bit confusing and not very right, fix this by changing those to NULL checks instead.
--- drivers/gpu/drm/loongson/lsdc_pixpll.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-)
drivers/gpu/drm/loongson/lsdc_pixpll.c +4 -2
@@ -120,12 +120,14 @@ static int lsdc_pixel_pll_setup(struct lsdc_pixpll * const this)struct lsdc_pixpll_parms *pparms; this->mmio =ioremap (this->reg_base, this->reg_size); -if (IS_ERR_OR_NULL (this->mmio)) +if (!this->mmio)return -ENOMEM ; pparms =kzalloc (sizeof (*pparms),GFP_KERNEL ); -if (IS_ERR_OR_NULL (pparms)) +if (!pparms) { +iounmap (this->mmio);return -ENOMEM ; + } pparms->ref_clock =LSDC_PLL_REF_CLK_KHZ ;
Signature · 1 line
2.42.0
Greg Kroah-Hartman
maintainerPATCH 218/603 drm/rockchip: vop: Fix reset of state in duplicate state crtc funcs
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Jonas Karlman <[email protected]>
[ Upstream commit 13fc28804bf10ca0b7bce3efbba95c534836d7ca ]
struct rockchip_crtc_state members such as output_type, output_bpc and enable_afbc is always reset to zero in the atomic_duplicate_state crtc funcs.
Fix this by using kmemdup on the subclass rockchip_crtc_state struct.
--- drivers/gpu/drm/rockchip/rockchip_drm_vop.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)
drivers/gpu/drm/rockchip/rockchip_drm_vop.c +2 -1
@@ -1614,7 +1614,8 @@ static struct drm_crtc_state *vop_crtc_duplicate_state(struct drm_crtc *crtc)if (WARN_ON (!crtc->state))return NULL ; - rockchip_state =kzalloc (sizeof (*rockchip_state),GFP_KERNEL ); + rockchip_state =kmemdup (to_rockchip_crtc_state (crtc->state), +sizeof (*rockchip_state),GFP_KERNEL );if (!rockchip_state)return NULL ;
Signature · 1 line
2.42.0
Greg Kroah-Hartman
maintainerPATCH 219/603 drm/rockchip: vop: Fix call to crtc reset helper
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Jonas Karlman <[email protected]>
[ Upstream commit 5aacd290837828c089a83ac9795c74c4c9e2c923 ]
Allocation of crtc_state may fail in vop_crtc_reset, causing an invalid pointer to be passed to __drm_atomic_helper_crtc_reset.
Fix this by adding a NULL check of crtc_state, similar to other drivers.
--- drivers/gpu/drm/rockchip/rockchip_drm_vop.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-)
drivers/gpu/drm/rockchip/rockchip_drm_vop.c +4 -1
@@ -1640,7 +1640,10 @@ static void vop_crtc_reset(struct drm_crtc *crtc)if (crtc->state)vop_crtc_destroy_state (crtc, crtc->state); -__drm_atomic_helper_crtc_reset (crtc, &crtc_state->base); +if (crtc_state) +__drm_atomic_helper_crtc_reset (crtc, &crtc_state->base); +else +__drm_atomic_helper_crtc_reset (crtc,NULL ); }#ifdef CONFIG_DRM_ANALOGIX_DP
Signature · 1 line
2.42.0
Greg Kroah-Hartman
maintainerPATCH 220/603 drm/rockchip: vop2: Dont crash for invalid duplicate_state
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Jonas Karlman <[email protected]>
[ Upstream commit 342f7e4967d02b0ec263b15916304fc54841b608 ]
It's possible for users to try to duplicate the CRTC state even when the state doesn't exist. drm_atomic_helper_crtc_duplicate_state() (and other users of __drm_atomic_helper_crtc_duplicate_state()) already guard this with a WARN_ON() instead of crashing, so let's do that here too.
--- drivers/gpu/drm/rockchip/rockchip_drm_vop2.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-)
drivers/gpu/drm/rockchip/rockchip_drm_vop2.c +5 -3
@@ -2098,11 +2098,13 @@ static void vop2_crtc_reset(struct drm_crtc *crtc)static struct drm_crtc_state *vop2_crtc_duplicate_state (struct drm_crtc *crtc) { -struct rockchip_crtc_state *vcstate, *old_vcstate; +struct rockchip_crtc_state *vcstate; - old_vcstate =to_rockchip_crtc_state (crtc->state); +if (WARN_ON (!crtc->state)) +return NULL ; - vcstate =kmemdup (old_vcstate,sizeof (*old_vcstate),GFP_KERNEL ); + vcstate =kmemdup (to_rockchip_crtc_state (crtc->state), +sizeof (*vcstate),GFP_KERNEL );if (!vcstate)return NULL ;
Signature · 1 line
2.42.0
Greg Kroah-Hartman
maintainerPATCH 221/603 drm/rockchip: vop2: Add missing call to crtc reset helper
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Jonas Karlman <[email protected]>
[ Upstream commit 4d49d87b3606369c6e29b9d051892ee1a6fc4e75 ]
Add missing call to crtc reset helper to properly vblank reset.
Also move vop2_crtc_reset and call vop2_crtc_destroy_state to simplify and remove duplicated code.
--- drivers/gpu/drm/rockchip/rockchip_drm_vop2.c | 31 +++++++++----------- 1 file changed, 14 insertions(+), 17 deletions(-)
drivers/gpu/drm/rockchip/rockchip_drm_vop2.c +14 -17
@@ -2079,23 +2079,6 @@ static const struct drm_crtc_helper_funcs vop2_crtc_helper_funcs = { .atomic_disable = vop2_crtc_atomic_disable, }; -static void vop2_crtc_reset (struct drm_crtc *crtc) -{ -struct rockchip_crtc_state *vcstate =to_rockchip_crtc_state (crtc->state); - -if (crtc->state) { -__drm_atomic_helper_crtc_destroy_state (crtc->state); -kfree (vcstate); - } - - vcstate =kzalloc (sizeof (*vcstate),GFP_KERNEL ); -if (!vcstate) -return ; - - crtc->state = &vcstate->base; - crtc->state->crtc = crtc; -} -static struct drm_crtc_state *vop2_crtc_duplicate_state (struct drm_crtc *crtc) {struct rockchip_crtc_state *vcstate;
@@ -2122,6 +2105,20 @@ static void vop2_crtc_destroy_state(struct drm_crtc *crtc,kfree (vcstate); } +static void vop2_crtc_reset (struct drm_crtc *crtc) +{ +struct rockchip_crtc_state *vcstate = +kzalloc (sizeof (*vcstate),GFP_KERNEL ); + +if (crtc->state) +vop2_crtc_destroy_state (crtc, crtc->state); + +if (vcstate) +__drm_atomic_helper_crtc_reset (crtc, &vcstate->base); +else +__drm_atomic_helper_crtc_reset (crtc,NULL ); +} +static const struct drm_crtc_funcs vop2_crtc_funcs = { .set_config = drm_atomic_helper_set_config, .page_flip = drm_atomic_helper_page_flip,
Signature · 1 line
2.42.0
Greg Kroah-Hartman
maintainerPATCH 222/603 drm/radeon: possible buffer overflow
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Konstantin Meskhidze <[email protected]>
[ Upstream commit dd05484f99d16715a88eedfca363828ef9a4c2d4 ]
Buffer 'afmt_status' of size 6 could overflow, since index 'afmt_idx' is checked after access.
--- drivers/gpu/drm/radeon/evergreen.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-)
drivers/gpu/drm/radeon/evergreen.c +4 -3
@@ -4821,14 +4821,15 @@ int evergreen_irq_process(struct radeon_device *rdev)break ;case 44 :/* hdmi */ afmt_idx = src_data; -if (!(afmt_status[afmt_idx] &AFMT_AZ_FORMAT_WTRIG )) -DRM_DEBUG ("IH: IH event w/o asserted irq bit?\n" ); -if (afmt_idx >5 ) {DRM_ERROR ("Unhandled interrupt: %d %d\n" , src_id, src_data);break ; } + +if (!(afmt_status[afmt_idx] &AFMT_AZ_FORMAT_WTRIG )) +DRM_DEBUG ("IH: IH event w/o asserted irq bit?\n" ); + afmt_status[afmt_idx] &= ~AFMT_AZ_FORMAT_WTRIG ; queue_hdmi = true;DRM_DEBUG ("IH: HDMI%d\n" , afmt_idx +1 );
Signature · 1 line
2.42.0
Greg Kroah-Hartman
maintainerPATCH 223/603 drm/radeon: Remove the references of radeon_gem_ pread & pwrite ioctls
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Srinivasan Shanmugam <[email protected]>
[ Upstream commit 52548038496fd58b762067b946f943c9bbcbd01e ]
Removing the functions of pread & pwrite & IOCTL defines, as their existence allows an authorized client to spam the system logs.
--- drivers/gpu/drm/radeon/radeon.h | 4 ---- drivers/gpu/drm/radeon/radeon_drv.c | 2 -- drivers/gpu/drm/radeon/radeon_gem.c | 16 ---------------- 3 files changed, 22 deletions(-)
drivers/gpu/drm/radeon/radeon.h +0 -4
@@ -2215,10 +2215,6 @@ int radeon_gem_pin_ioctl(struct drm_device *dev, void *data, struct drm_file *file_priv);int radeon_gem_unpin_ioctl (struct drm_device *dev,void *data,struct drm_file *file_priv); -int radeon_gem_pwrite_ioctl (struct drm_device *dev,void *data, -struct drm_file *file_priv); -int radeon_gem_pread_ioctl (struct drm_device *dev,void *data, -struct drm_file *file_priv);int radeon_gem_set_domain_ioctl (struct drm_device *dev,void *data,struct drm_file *filp); int radeon_gem_mmap_ioctl(struct drm_device *dev, void *data,
drivers/gpu/drm/radeon/radeon_drv.c +0 -2
@@ -555,8 +555,6 @@ static const struct drm_ioctl_desc radeon_ioctls_kms[] = {DRM_IOCTL_DEF_DRV (RADEON_GEM_CREATE , radeon_gem_create_ioctl,DRM_AUTH |DRM_RENDER_ALLOW ),DRM_IOCTL_DEF_DRV (RADEON_GEM_MMAP , radeon_gem_mmap_ioctl,DRM_AUTH |DRM_RENDER_ALLOW ),DRM_IOCTL_DEF_DRV (RADEON_GEM_SET_DOMAIN , radeon_gem_set_domain_ioctl,DRM_AUTH |DRM_RENDER_ALLOW ), -DRM_IOCTL_DEF_DRV (RADEON_GEM_PREAD , radeon_gem_pread_ioctl,DRM_AUTH ), -DRM_IOCTL_DEF_DRV (RADEON_GEM_PWRITE , radeon_gem_pwrite_ioctl,DRM_AUTH ),DRM_IOCTL_DEF_DRV (RADEON_GEM_WAIT_IDLE , radeon_gem_wait_idle_ioctl,DRM_AUTH |DRM_RENDER_ALLOW ),DRM_IOCTL_DEF_DRV (RADEON_CS , radeon_cs_ioctl,DRM_AUTH |DRM_RENDER_ALLOW ), DRM_IOCTL_DEF_DRV(RADEON_INFO, radeon_info_ioctl, DRM_AUTH|DRM_RENDER_ALLOW),
drivers/gpu/drm/radeon/radeon_gem.c +0 -16
@@ -311,22 +311,6 @@ int radeon_gem_info_ioctl(struct drm_device *dev, void *data,return 0 ; } -int radeon_gem_pread_ioctl (struct drm_device *dev,void *data, -struct drm_file *filp) -{ -/* TODO: implement */ -DRM_ERROR ("unimplemented %s\n" , __func__); -return -EOPNOTSUPP ; -} - -int radeon_gem_pwrite_ioctl (struct drm_device *dev,void *data, -struct drm_file *filp) -{ -/* TODO: implement */ -DRM_ERROR ("unimplemented %s\n" , __func__); -return -EOPNOTSUPP ; -} -int radeon_gem_create_ioctl (struct drm_device *dev,void *data,struct drm_file *filp) {
Signature · 1 line
2.42.0
Greg Kroah-Hartman
maintainerPATCH 224/603 drm: bridge: it66121: Fix invalid connector dereference
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Jai Luthra <[email protected]>
[ Upstream commit d0375f6858c4ff7244b62b02eb5e93428e1916cd ]
Fix the NULL pointer dereference when no monitor is connected, and the sound card is opened from userspace.
Instead return an empty buffer (of zeroes) as the EDID information to the sound framework if there is no connector attached.
--- drivers/gpu/drm/bridge/ite-it66121.c | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-)
drivers/gpu/drm/bridge/ite-it66121.c +8 -4
@@ -1447,10 +1447,14 @@ static int it66121_audio_get_eld(struct device *dev, void *data,struct it66121_ctx *ctx =dev_get_drvdata (dev);mutex_lock (&ctx->lock); - -memcpy (buf, ctx->connector->eld, -min (sizeof (ctx->connector->eld), len)); - +if (!ctx->connector) { +/* Pass en empty ELD if connector not available */ +dev_dbg (dev,"No connector present, passing empty EDID data" ); +memset (buf,0 , len); + }else { +memcpy (buf, ctx->connector->eld, +min (sizeof (ctx->connector->eld), len)); + }mutex_unlock (&ctx->lock);return 0 ;
Signature · 1 line
2.42.0
Greg Kroah-Hartman
maintainerPATCH 225/603 drm/bridge: lt8912b: Fix bridge_detach
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Tomi Valkeinen <[email protected]>
[ Upstream commit 941882a0e96d245f38116e940912b404b6a93c6f ]
The driver calls lt8912_bridge_detach() from its lt8912_remove() function. As the DRM core detaches bridges automatically, this leads to calling lt8912_bridge_detach() twice. The code probably has tried to manage the double-call with the 'is_attached' variable, but the driver never sets the variable to false, so its of no help.
Fix the issue by dropping the call to lt8912_bridge_detach() from lt8912_remove(), as the DRM core will handle the detach call for us, and also drop the useless is_attached field.
--- drivers/gpu/drm/bridge/lontium-lt8912b.c | 16 +++++----------- 1 file changed, 5 insertions(+), 11 deletions(-)
drivers/gpu/drm/bridge/lontium-lt8912b.c +5 -11
@@ -45,7 +45,6 @@ struct lt8912 {u8 data_lanes;bool is_power_on; -bool is_attached; };static int lt8912_write_init_config (struct lt8912 *lt)
@@ -575,8 +574,6 @@ static int lt8912_bridge_attach(struct drm_bridge *bridge,if (ret) goto error; - lt->is_attached = true; -return 0 ; error:
@@ -588,15 +585,13 @@ static void lt8912_bridge_detach(struct drm_bridge *bridge) {struct lt8912 *lt =bridge_to_lt8912 (bridge); -if (lt->is_attached) { -lt8912_hard_power_off (lt); +lt8912_hard_power_off (lt); -if (lt->hdmi_port->ops &DRM_BRIDGE_OP_HPD ) -drm_bridge_hpd_disable (lt->hdmi_port); +if (lt->hdmi_port->ops &DRM_BRIDGE_OP_HPD ) +drm_bridge_hpd_disable (lt->hdmi_port); -drm_connector_unregister (<->connector); -drm_connector_cleanup (<->connector); - } +drm_connector_unregister (<->connector); +drm_connector_cleanup (<->connector); } static enum drm_connector_status
@@ -750,7 +745,6 @@ static void lt8912_remove(struct i2c_client *client) {struct lt8912 *lt =i2c_get_clientdata (client); -lt8912_bridge_detach (<->bridge);drm_bridge_remove (<->bridge);lt8912_free_i2c (lt);lt8912_put_dt (lt);
Signature · 1 line
2.42.0
Greg Kroah-Hartman
maintainerPATCH 226/603 drm/bridge: lt8912b: Fix crash on bridge detach
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Tomi Valkeinen <[email protected]>
[ Upstream commit 44283993144a03af9df31934d6c32bbd42d1a347 ]
The lt8912b driver, in its bridge detach function, calls drm_connector_unregister() and drm_connector_cleanup().
drm_connector_unregister() should be called only for connectors explicitly registered with drm_connector_register(), which is not the case in lt8912b.
The driver's drm_connector_funcs.destroy hook is set to drm_connector_cleanup().
Thus the driver should not call either drm_connector_unregister() nor drm_connector_cleanup() in its lt8912_bridge_detach(), as they cause a crash on bridge detach:
Unable to handle kernel NULL pointer dereference at virtual address 0000000000000000
Mem abort info:
ESR = 0x0000000096000006
EC = 0x25: DABT (current EL), IL = 32 bits
SET = 0, FnV = 0
EA = 0, S1PTW = 0
FSC = 0x06: level 2 translation fault
Data abort info:
ISV = 0, ISS = 0x00000006, ISS2 = 0x00000000
CM = 0, WnR = 0, TnD = 0, TagAccess = 0
GCS = 0, Overlay = 0, DirtyBit = 0, Xs = 0
user pgtable: 4k pages, 48-bit VAs, pgdp=00000000858f3000
[0000000000000000] pgd=0800000085918003, p4d=0800000085918003, pud=0800000085431003, pmd=0000000000000000
Internal error: Oops: 0000000096000006 [#1] PREEMPT SMP Modules linked in: tidss(-) display_connector lontium_lt8912b tc358768 panel_lvds panel_simple drm_dma_helper drm_kms_helper drm drm_panel_orientation_quirks CPU: 3 PID: 462 Comm: rmmod Tainted: G W 6.5.0-rc2+ #2 Hardware name: Toradex Verdin AM62 on Verdin Development Board (DT) pstate: 80000005 (Nzcv daif -PAN -UAO -TCO -DIT -SSBS BTYPE=--) pc : drm_connector_cleanup+0x78/0x2d4 [drm] lr : lt8912_bridge_detach+0x54/0x6c [lontium_lt8912b]
sp : ffff800082ed3a90
x29: ffff800082ed3a90 x28: ffff0000040c1940 x27: 0000000000000000
x26: 0000000000000000 x25: dead000000000122 x24: dead000000000122
x23: dead000000000100 x22: ffff000003fb6388 x21: 0000000000000000
x20: 0000000000000000 x19: ffff000003fb6260 x18: fffffffffffe56e8
x17: 0000000000000000 x16: 0010000000000000 x15: 0000000000000038
x14: 0000000000000000 x13: ffff800081914b48 x12: 000000000000040e
x11: 000000000000015a x10: ffff80008196ebb8 x9 : ffff800081914b48 x8 : 00000000ffffefff x7 : ffff0000040c1940 x6 : ffff80007aa649d0 x5 : 0000000000000000 x4 : 0000000000000001 x3 : ffff80008159e008 x2 : 0000000000000000 x1 : 0000000000000000 x0 : 0000000000000000
Call trace: drm_connector_cleanup+0x78/0x2d4 [drm] lt8912_bridge_detach+0x54/0x6c [lontium_lt8912b] drm_bridge_detach+0x44/0x84 [drm] drm_encoder_cleanup+0x40/0xb8 [drm] drmm_encoder_alloc_release+0x1c/0x30 [drm] drm_managed_release+0xac/0x148 [drm] drm_dev_put.part.0+0x88/0xb8 [drm] devm_drm_dev_init_release+0x14/0x24 [drm] devm_action_release+0x14/0x20 release_nodes+0x5c/0x90 devres_release_all+0x8c/0xe0 device_unbind_cleanup+0x18/0x68 device_release_driver_internal+0x208/0x23c driver_detach+0x4c/0x94 bus_remove_driver+0x70/0xf4 driver_unregister+0x30/0x60 platform_driver_unregister+0x14/0x20 tidss_platform_driver_exit+0x18/0xb2c [tidss] __arm64_sys_delete_module+0x1a0/0x2b4 invoke_syscall+0x48/0x110 el0_svc_common.constprop.0+0x60/0x10c do_el0_svc_compat+0x1c/0x40 el0_svc_compat+0x40/0xac el0t_32_sync_handler+0xb0/0x138 el0t_32_sync+0x194/0x198 Code: 9104a276 f2fbd5b7 aa0203e1 91008af8 (f85c0420)
--- drivers/gpu/drm/bridge/lontium-lt8912b.c | 3 --- 1 file changed, 3 deletions(-)
drivers/gpu/drm/bridge/lontium-lt8912b.c +0 -3
@@ -589,9 +589,6 @@ static void lt8912_bridge_detach(struct drm_bridge *bridge)if (lt->hdmi_port->ops &DRM_BRIDGE_OP_HPD )drm_bridge_hpd_disable (lt->hdmi_port); - -drm_connector_unregister (<->connector); -drm_connector_cleanup (<->connector); } static enum drm_connector_status
Signature · 1 line
2.42.0
Greg Kroah-Hartman
maintainerPATCH 227/603 drm/bridge: lt8912b: Manually disable HPD only if it was enabled
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Tomi Valkeinen <[email protected]>
[ Upstream commit 6985c5efc4057bc79137807295d84ada3123d051 ]
lt8912b only calls drm_bridge_hpd_enable() if it creates a connector and the next bridge has DRM_BRIDGE_OP_HPD set. However, when calling drm_bridge_hpd_disable() it misses checking if a connector was created, calling drm_bridge_hpd_disable() even if HPD was never enabled. I don't see any issues caused by this wrong call, though.
Add the check to avoid wrongly calling drm_bridge_hpd_disable().
--- drivers/gpu/drm/bridge/lontium-lt8912b.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/gpu/drm/bridge/lontium-lt8912b.c +1 -1
@@ -587,7 +587,7 @@ static void lt8912_bridge_detach(struct drm_bridge *bridge)lt8912_hard_power_off (lt); -if (lt->hdmi_port->ops &DRM_BRIDGE_OP_HPD ) +if (lt->connector.dev && lt->hdmi_port->ops &DRM_BRIDGE_OP_HPD )drm_bridge_hpd_disable (lt->hdmi_port); }
Signature · 1 line
2.42.0
Greg Kroah-Hartman
maintainerPATCH 228/603 drm/bridge: lt8912b: Add missing drm_bridge_attach call
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Tomi Valkeinen <[email protected]>
[ Upstream commit f45acf7acf75921c0409d452f0165f51a19a74fd ]
The driver does not call drm_bridge_attach(), which causes the next bridge to not be added to the bridge chain. This causes the pipeline init to fail when DRM_BRIDGE_ATTACH_NO_CONNECTOR is used.
Add the call to drm_bridge_attach().
--- drivers/gpu/drm/bridge/lontium-lt8912b.c | 7 +++++++ 1 file changed, 7 insertions(+)
drivers/gpu/drm/bridge/lontium-lt8912b.c +7 -0
@@ -558,6 +558,13 @@ static int lt8912_bridge_attach(struct drm_bridge *bridge,struct lt8912 *lt =bridge_to_lt8912 (bridge);int ret; + ret =drm_bridge_attach (bridge->encoder, lt->hdmi_port, bridge, +DRM_BRIDGE_ATTACH_NO_CONNECTOR ); +if (ret <0 ) { +dev_err (lt->dev,"Failed to attach next bridge (%d)\n" , ret); +return ret; + } +if (!(flags &DRM_BRIDGE_ATTACH_NO_CONNECTOR )) { ret =lt8912_bridge_connector_init (bridge);if (ret) {
Signature · 1 line
2.42.0
Greg Kroah-Hartman
maintainerPATCH 229/603 drm/ssd130x: Fix screen clearing
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Geert Uytterhoeven <[email protected]>
[ Upstream commit 4dbce3d6fea59e1df1d1a35aacea0c186f72107a ]
Due to the reuse of buffers, ssd130x_clear_screen() no longers clears the screen, but merely redraws the last image that is residing in the intermediate buffer.
As there is no point in clearing the intermediate buffer and transposing an all-black image, fix this by just clearing the HW format buffer, and writing it to the panel.
--- drivers/gpu/drm/solomon/ssd130x.c | 47 +++++++++++++++++++++++++------ 1 file changed, 39 insertions(+), 8 deletions(-)
drivers/gpu/drm/solomon/ssd130x.c +39 -8
@@ -553,14 +553,45 @@ static int ssd130x_update_rect(struct ssd130x_device *ssd130x,static void ssd130x_clear_screen (struct ssd130x_device *ssd130x,struct ssd130x_plane_state *ssd130x_state) { -struct drm_rect fullscreen = { - .x1 =0 , - .x2 = ssd130x->width, - .y1 =0 , - .y2 = ssd130x->height, - }; - -ssd130x_update_rect (ssd130x, ssd130x_state, &fullscreen); +unsigned int page_height = ssd130x->device_info->page_height; +unsigned int pages =DIV_ROUND_UP (ssd130x->height, page_height); +u8 *data_array = ssd130x_state->data_array; +unsigned int width = ssd130x->width; +int ret, i; + +if (!ssd130x->page_address_mode) { +memset (data_array,0 , width * pages); + +/* Set address range for horizontal addressing mode */ + ret =ssd130x_set_col_range (ssd130x, ssd130x->col_offset, width); +if (ret <0 ) +return ; + + ret =ssd130x_set_page_range (ssd130x, ssd130x->page_offset, pages); +if (ret <0 ) +return ; + +/* Write out update in one go if we aren't using page addressing mode */ +ssd130x_write_data (ssd130x, data_array, width * pages); + }else { +/* +* In page addressing mode, the start address needs to be reset, +* and each page then needs to be written out separately. +*/ +memset (data_array,0 , width); + +for (i =0 ; i < pages; i++) { + ret =ssd130x_set_page_pos (ssd130x, + ssd130x->page_offset + i, + ssd130x->col_offset); +if (ret <0 ) +return ; + + ret =ssd130x_write_data (ssd130x, data_array, width); +if (ret <0 ) +return ; + } + } } static int ssd130x_fb_blit_rect(struct drm_plane_state *state,
Signature · 1 line
2.42.0
Greg Kroah-Hartman
maintainerPATCH 230/603 drm/mediatek: Fix coverity issue with unintentional integer overflow
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Jason-JH.Lin <[email protected]>
[ Upstream commit b0b0d811eac6b4c52cb9ad632fa6384cf48869e7 ]
1. Instead of multiplying 2 variable of different types. Change to assign a value of one variable and then multiply the other variable.
2. Add a int variable for multiplier calculation instead of calculating different types multiplier with dma_addr_t variable directly.
--- drivers/gpu/drm/mediatek/mtk_drm_gem.c | 9 +++++- drivers/gpu/drm/mediatek/mtk_drm_plane.c | 39 ++++++++++++++++++------ 2 files changed, 38 insertions(+), 10 deletions(-)
drivers/gpu/drm/mediatek/mtk_drm_gem.c +8 -1
@@ -121,7 +121,14 @@ int mtk_drm_gem_dumb_create(struct drm_file *file_priv, struct drm_device *dev,int ret; args->pitch =DIV_ROUND_UP (args->width * args->bpp,8 ); - args->size = args->pitch * args->height; + +/* +* Multiply 2 variables of different types, +* for example: args->size = args->spacing * args->height; +* may cause coverity issue with unintentional overflow. +*/ + args->size = args->pitch; + args->size *= args->height; mtk_gem =mtk_drm_gem_create (dev, args->size, false);if (IS_ERR (mtk_gem))
drivers/gpu/drm/mediatek/mtk_drm_plane.c +30 -9
@@ -141,6 +141,7 @@ static void mtk_plane_update_new_state(struct drm_plane_state *new_state,dma_addr_t addr;dma_addr_t hdr_addr =0 ;unsigned int hdr_pitch =0 ; +int offset; gem = fb->obj[0 ]; mtk_gem =to_mtk_gem_obj (gem);
@@ -150,8 +151,15 @@ static void mtk_plane_update_new_state(struct drm_plane_state *new_state, modifier = fb->modifier;if (modifier ==DRM_FORMAT_MOD_LINEAR ) { - addr += (new_state->src.x1 >>16 ) * fb->format->cpp[0 ]; - addr += (new_state->src.y1 >>16 ) * pitch; +/* +* Using dma_addr_t variable to calculate with multiplier of different types, +* for example: addr += (new_state->src.x1 >> 16) * fb->format->cpp[0]; +* may cause coverity issue with unintentional overflow. +*/ + offset = (new_state->src.x1 >>16 ) * fb->format->cpp[0 ]; + addr += offset; + offset = (new_state->src.y1 >>16 ) * pitch; + addr += offset; }else {int width_in_blocks =ALIGN (fb->width,AFBC_DATA_BLOCK_WIDTH ) /AFBC_DATA_BLOCK_WIDTH ;
@@ -159,21 +167,34 @@ static void mtk_plane_update_new_state(struct drm_plane_state *new_state, / AFBC_DATA_BLOCK_HEIGHT;int x_offset_in_blocks = (new_state->src.x1 >>16 ) /AFBC_DATA_BLOCK_WIDTH ;int y_offset_in_blocks = (new_state->src.y1 >>16 ) /AFBC_DATA_BLOCK_HEIGHT ; -int hdr_size; +int hdr_size, hdr_offset; hdr_pitch = width_in_blocks *AFBC_HEADER_BLOCK_SIZE ; pitch = width_in_blocks *AFBC_DATA_BLOCK_WIDTH *AFBC_DATA_BLOCK_HEIGHT * fb->format->cpp[0 ]; hdr_size =ALIGN (hdr_pitch * height_in_blocks,AFBC_HEADER_ALIGNMENT ); + hdr_offset = hdr_pitch * y_offset_in_blocks + +AFBC_HEADER_BLOCK_SIZE * x_offset_in_blocks; + +/* +* Using dma_addr_t variable to calculate with multiplier of different types, +* for example: addr += hdr_pitch * y_offset_in_blocks; +* may cause coverity issue with unintentional overflow. +*/ + hdr_addr = addr + hdr_offset; - hdr_addr = addr + hdr_pitch * y_offset_in_blocks + -AFBC_HEADER_BLOCK_SIZE * x_offset_in_blocks;/* The data plane is offset by 1 additional block. */ - addr = addr + hdr_size + - pitch * y_offset_in_blocks + -AFBC_DATA_BLOCK_WIDTH *AFBC_DATA_BLOCK_HEIGHT * - fb->format->cpp[0 ] * (x_offset_in_blocks +1 ); + offset = pitch * y_offset_in_blocks + +AFBC_DATA_BLOCK_WIDTH *AFBC_DATA_BLOCK_HEIGHT * + fb->format->cpp[0 ] * (x_offset_in_blocks +1 ); + +/* +* Using dma_addr_t variable to calculate with multiplier of different types, +* for example: addr += pitch * y_offset_in_blocks; +* may cause coverity issue with unintentional overflow. +*/ + addr = addr + hdr_size + offset; } mtk_plane_state->pending.enable = true;
Signature · 1 line
2.42.0
Greg Kroah-Hartman
maintainerPATCH 231/603 x86/tdx: Zero out the missing RSI in TDX_HYPERCALL macro
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Kai Huang <[email protected]>
[ Upstream commit 5d092b66119d774853cc9308522620299048a662 ]
In the TDX_HYPERCALL asm, after the TDCALL instruction returns from the untrusted VMM, the registers that the TDX guest shares to the VMM need to be cleared to avoid speculative execution of VMM-provided values.
RSI is specified in the bitmap of those registers, but it is missing when zeroing out those registers in the current TDX_HYPERCALL.
It was there when it was originally added in commit 752d13305c78 ("x86/tdx: Expand __tdx_hypercall() to handle more arguments"), but was later removed in commit 1e70c680375a ("x86/tdx: Do not corrupt frame-pointer in __tdx_hypercall()"), which was correct because %rsi is later restored in the "pop %rsi". However a later commit 7a3a401874be ("x86/tdx: Drop flags from __tdx_hypercall()") removed that "pop %rsi" but forgot to add the "xor %rsi, %rsi" back.
Fix by adding it back.
--- arch/x86/coco/tdx/tdcall.S | 1 + 1 file changed, 1 insertion(+)
arch/x86/coco/tdx/tdcall.S +1 -0
@@ -195,6 +195,7 @@ SYM_FUNC_END(__tdx_module_call) xor %r10d, %r10d xor %r11d, %r11d xor %rdi, %rdi + xor %rsi, %rsi xor %rdx, %rdx /* Restore callee-saved GPRs as mandated by the x86_64 ABI */
Signature · 1 line
2.42.0
Greg Kroah-Hartman
maintainerPATCH 232/603 drm/bridge: tc358768: Fix use of uninitialized variable
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Tomi Valkeinen <[email protected]>
[ Upstream commit a2d9036615f0adfa5b0a46bb2ce42ef1d9a04fbe ]
smatch reports:
drivers/gpu/drm/bridge/tc358768.c:223 tc358768_update_bits() error: uninitialized symbol 'orig'.
Fix this by bailing out from tc358768_update_bits() if the tc358768_read() produces an error.
--- drivers/gpu/drm/bridge/tc358768.c | 4 ++++ 1 file changed, 4 insertions(+)
drivers/gpu/drm/bridge/tc358768.c +4 -0
@@ -216,6 +216,10 @@ static void tc358768_update_bits(struct tc358768_priv *priv, u32 reg, u32 mask,u32 tmp, orig;tc358768_read (priv, reg, &orig); + +if (priv->error) +return ; + tmp = orig & ~mask; tmp |= val & mask;if (tmp != orig)
Signature · 1 line
2.42.0
Greg Kroah-Hartman
maintainerPATCH 233/603 drm/bridge: tc358768: Fix bit updates
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Tomi Valkeinen <[email protected]>
[ Upstream commit 66962d5c3c51377b9b90cae35b7e038950438e02 ]
The driver has a few places where it does:
if (thing_is_enabled_in_config)
update_thing_bit_in_hw()
This means that if the thing is _not_ enabled, the bit never gets cleared. This affects the h/vsyncs and continuous DSI clock bits.
Fix the driver to always update the bit.
--- drivers/gpu/drm/bridge/tc358768.c | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-)
drivers/gpu/drm/bridge/tc358768.c +7 -6
@@ -794,8 +794,8 @@ static void tc358768_bridge_pre_enable(struct drm_bridge *bridge) val |=BIT (i +1 );tc358768_write (priv,TC358768_HSTXVREGEN , val); -if (!(mode_flags &MIPI_DSI_CLOCK_NON_CONTINUOUS )) -tc358768_write (priv,TC358768_TXOPTIONCNTRL ,0x1 ); +tc358768_write (priv,TC358768_TXOPTIONCNTRL , + (mode_flags &MIPI_DSI_CLOCK_NON_CONTINUOUS ) ?0 :BIT (0 ));/* TXTAGOCNT[26:16] RXTASURECNT[10:0] */ val =tc358768_to_ns ((lptxcnt +1 ) * dsibclk_nsk *4 );
@@ -861,11 +861,12 @@ static void tc358768_bridge_pre_enable(struct drm_bridge *bridge)tc358768_write (priv,TC358768_DSI_HACT , hact);/* VSYNC polarity */ -if (!(mode->flags &DRM_MODE_FLAG_NVSYNC )) -tc358768_update_bits (priv,TC358768_CONFCTL ,BIT (5 ),BIT (5 )); +tc358768_update_bits (priv,TC358768_CONFCTL ,BIT (5 ), + (mode->flags &DRM_MODE_FLAG_PVSYNC ) ?BIT (5 ) :0 ); +/* HSYNC polarity */ -if (mode->flags &DRM_MODE_FLAG_PHSYNC ) -tc358768_update_bits (priv,TC358768_PP_MISC ,BIT (0 ),BIT (0 )); +tc358768_update_bits (priv,TC358768_PP_MISC ,BIT (0 ), + (mode->flags &DRM_MODE_FLAG_PHSYNC ) ?BIT (0 ) :0 );/* Start DSI Tx */ tc358768_write (priv,TC358768_DSI_START ,0x1 );
Signature · 1 line
2.42.0
Greg Kroah-Hartman
maintainerPATCH 234/603 drm/bridge: tc358768: Use struct videomode
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Tomi Valkeinen <[email protected]>
[ Upstream commit e5fb21678136a9d009d5c43821881eb4c34fae97 ]
The TC358768 documentation uses HFP, HBP, etc. values to deal with the video mode, while the driver currently uses the DRM display mode (htotal, hsync_start, etc).
Change the driver to convert the DRM display mode to struct videomode, which then allows us to use the same units the documentation uses. This makes it much easier to work on the code when using the TC358768 documentation as a reference.
Stable-dep-of: f1dabbe64506 ("drm/bridge: tc358768: Fix tc358768_ns_to_cnt()")
--- drivers/gpu/drm/bridge/tc358768.c | 45 ++++++++++++++++--------------- 1 file changed, 24 insertions(+), 21 deletions(-)
drivers/gpu/drm/bridge/tc358768.c +24 -21
@@ -650,6 +650,7 @@ static void tc358768_bridge_pre_enable(struct drm_bridge *bridge)u32 dsiclk, dsibclk, video_start;const u32 internal_delay =40 ;int ret, i; +struct videomode vm;if (mode_flags &MIPI_DSI_CLOCK_NON_CONTINUOUS ) {dev_warn_once (priv->dev,"Non-continuous mode unimplemented, falling back to continuous\n" );
@@ -673,6 +674,8 @@ static void tc358768_bridge_pre_enable(struct drm_bridge *bridge)return ; } +drm_display_mode_to_videomode (mode, &vm); + dsiclk = priv->dsiclk; dsibclk = dsiclk /4 ;
@@ -681,28 +684,28 @@ static void tc358768_bridge_pre_enable(struct drm_bridge *bridge)switch (dsi_dev->format) {case MIPI_DSI_FMT_RGB888 : val |= (0x3 <<4 ); - hact = mode->hdisplay *3 ; - video_start = (mode->htotal - mode->hsync_start) *3 ; + hact = vm.hactive *3 ; + video_start = (vm.hsync_len + vm.hback_porch) *3 ; data_type =MIPI_DSI_PACKED_PIXEL_STREAM_24 ;break ;case MIPI_DSI_FMT_RGB666 : val |= (0x4 <<4 ); - hact = mode->hdisplay *3 ; - video_start = (mode->htotal - mode->hsync_start) *3 ; + hact = vm.hactive *3 ; + video_start = (vm.hsync_len + vm.hback_porch) *3 ; data_type =MIPI_DSI_PACKED_PIXEL_STREAM_18 ;break ;case MIPI_DSI_FMT_RGB666_PACKED : val |= (0x4 <<4 ) |BIT (3 ); - hact = mode->hdisplay *18 /8 ; - video_start = (mode->htotal - mode->hsync_start) *18 /8 ; + hact = vm.hactive *18 /8 ; + video_start = (vm.hsync_len + vm.hback_porch) *18 /8 ; data_type =MIPI_DSI_PIXEL_STREAM_3BYTE_18 ;break ;case MIPI_DSI_FMT_RGB565 : val |= (0x5 <<4 ); - hact = mode->hdisplay *2 ; - video_start = (mode->htotal - mode->hsync_start) *2 ; + hact = vm.hactive *2 ; + video_start = (vm.hsync_len + vm.hback_porch) *2 ; data_type =MIPI_DSI_PACKED_PIXEL_STREAM_16 ;break ;default :
@@ -814,43 +817,43 @@ static void tc358768_bridge_pre_enable(struct drm_bridge *bridge)tc358768_write (priv,TC358768_DSI_EVENT ,0 );/* vact */ -tc358768_write (priv,TC358768_DSI_VACT , mode->vdisplay); +tc358768_write (priv,TC358768_DSI_VACT , vm.vactive);/* vsw */ -tc358768_write (priv,TC358768_DSI_VSW , - mode->vsync_end - mode->vsync_start); +tc358768_write (priv,TC358768_DSI_VSW , vm.vsync_len); +/* vbp */ -tc358768_write (priv,TC358768_DSI_VBPR , - mode->vtotal - mode->vsync_end); +tc358768_write (priv,TC358768_DSI_VBPR , vm.vback_porch);/* hsw * byteclk * ndl / pclk */ - val = (u32 )div_u64 ((mode->hsync_end - mode->hsync_start) * + val = (u32 )div_u64 (vm.hsync_len * ((u64 )priv->dsiclk /4 ) * priv->dsi_lanes, - mode->clock *1000 ); + vm.pixelclock);tc358768_write (priv,TC358768_DSI_HSW , val);/* hbp * byteclk * ndl / pclk */ - val = (u32 )div_u64 ((mode->htotal - mode->hsync_end) * + val = (u32 )div_u64 (vm.hback_porch * ((u64 )priv->dsiclk /4 ) * priv->dsi_lanes, - mode->clock *1000 ); + vm.pixelclock);tc358768_write (priv,TC358768_DSI_HBPR , val); }else {/* Set event mode */ tc358768_write (priv,TC358768_DSI_EVENT ,1 );/* vact */ -tc358768_write (priv,TC358768_DSI_VACT , mode->vdisplay); +tc358768_write (priv,TC358768_DSI_VACT , vm.vactive);/* vsw (+ vbp) */ tc358768_write (priv,TC358768_DSI_VSW , - mode->vtotal - mode->vsync_start); + vm.vsync_len + vm.vback_porch); +/* vbp (not used in event mode) */ tc358768_write (priv,TC358768_DSI_VBPR ,0 );/* (hsw + hbp) * byteclk * ndl / pclk */ - val = (u32 )div_u64 ((mode->htotal - mode->hsync_start) * + val = (u32 )div_u64 ((vm.hsync_len + vm.hback_porch) * ((u64 )priv->dsiclk /4 ) * priv->dsi_lanes, - mode->clock *1000 ); + vm.pixelclock);tc358768_write (priv,TC358768_DSI_HSW , val);/* hbp (not used in event mode) */
Signature · 1 line
2.42.0
Greg Kroah-Hartman
maintainerPATCH 235/603 drm/bridge: tc358768: Print logical values, not raw register values
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Tomi Valkeinen <[email protected]>
[ Upstream commit 013ea98cdfccef3b7c38b087c1f629488d2ef683 ]
The driver debug prints DSI related timings as raw register values in hex. It is much more useful to see the "logical" value of the timing, not the register value.
Change the prints to print the values separately, in case a single register contains multiple values, and use %u to have it in a more human consumable form.
Stable-dep-of: f1dabbe64506 ("drm/bridge: tc358768: Fix tc358768_ns_to_cnt()")
--- drivers/gpu/drm/bridge/tc358768.c | 21 ++++++++++++--------- 1 file changed, 12 insertions(+), 9 deletions(-)
drivers/gpu/drm/bridge/tc358768.c +12 -9
@@ -739,57 +739,59 @@ static void tc358768_bridge_pre_enable(struct drm_bridge *bridge)/* LP11 > 100us for D-PHY Rx Init */ val =tc358768_ns_to_cnt (100 *1000 , dsibclk_nsk) -1 ; -dev_dbg (priv->dev,"LINEINITCNT: 0x%x\n" , val); +dev_dbg (priv->dev,"LINEINITCNT: %u\n" , val);tc358768_write (priv,TC358768_LINEINITCNT , val);/* LPTimeCnt > 50ns */ val =tc358768_ns_to_cnt (50 , dsibclk_nsk) -1 ; lptxcnt = val; -dev_dbg (priv->dev,"LPTXTIMECNT: 0x%x\n" , val); +dev_dbg (priv->dev,"LPTXTIMECNT: %u\n" , val);tc358768_write (priv,TC358768_LPTXTIMECNT , val);/* 38ns < TCLK_PREPARE < 95ns */ val =tc358768_ns_to_cnt (65 , dsibclk_nsk) -1 ; +dev_dbg (priv->dev,"TCLK_PREPARECNT %u\n" , val);/* TCLK_PREPARE + TCLK_ZERO > 300ns */ val2 =tc358768_ns_to_cnt (300 -tc358768_to_ns (2 * ui_nsk), dsibclk_nsk) -2 ; +dev_dbg (priv->dev,"TCLK_ZEROCNT %u\n" , val2); val |= val2 <<8 ; -dev_dbg (priv->dev,"TCLK_HEADERCNT: 0x%x\n" , val);tc358768_write (priv,TC358768_TCLK_HEADERCNT , val);/* TCLK_TRAIL > 60ns AND TEOT <= 105 ns + 12*UI */ raw_val =tc358768_ns_to_cnt (60 +tc358768_to_ns (2 * ui_nsk), dsibclk_nsk) -5 ; val =clamp (raw_val,0 ,127 ); -dev_dbg (priv->dev,"TCLK_TRAILCNT: 0x%x\n" , val); +dev_dbg (priv->dev,"TCLK_TRAILCNT: %u\n" , val);tc358768_write (priv,TC358768_TCLK_TRAILCNT , val);/* 40ns + 4*UI < THS_PREPARE < 85ns + 6*UI */ val =50 +tc358768_to_ns (4 * ui_nsk); val =tc358768_ns_to_cnt (val, dsibclk_nsk) -1 ; +dev_dbg (priv->dev,"THS_PREPARECNT %u\n" , val);/* THS_PREPARE + THS_ZERO > 145ns + 10*UI */ raw_val =tc358768_ns_to_cnt (145 -tc358768_to_ns (3 * ui_nsk), dsibclk_nsk) -10 ; val2 =clamp (raw_val,0 ,127 ); +dev_dbg (priv->dev,"THS_ZEROCNT %u\n" , val2); val |= val2 <<8 ; -dev_dbg (priv->dev,"THS_HEADERCNT: 0x%x\n" , val);tc358768_write (priv,TC358768_THS_HEADERCNT , val);/* TWAKEUP > 1ms in lptxcnt steps */ val =tc358768_ns_to_cnt (1020000 , dsibclk_nsk); val = val / (lptxcnt +1 ) -1 ; -dev_dbg (priv->dev,"TWAKEUP: 0x%x\n" , val); +dev_dbg (priv->dev,"TWAKEUP: %u\n" , val);tc358768_write (priv,TC358768_TWAKEUP , val);/* TCLK_POSTCNT > 60ns + 52*UI */ val =tc358768_ns_to_cnt (60 +tc358768_to_ns (52 * ui_nsk), dsibclk_nsk) -3 ; -dev_dbg (priv->dev,"TCLK_POSTCNT: 0x%x\n" , val); +dev_dbg (priv->dev,"TCLK_POSTCNT: %u\n" , val);tc358768_write (priv,TC358768_TCLK_POSTCNT , val);/* max(60ns + 4*UI, 8*UI) < THS_TRAILCNT < 105ns + 12*UI */ raw_val =tc358768_ns_to_cnt (60 +tc358768_to_ns (18 * ui_nsk), dsibclk_nsk) -4 ; val =clamp (raw_val,0 ,15 ); -dev_dbg (priv->dev,"THS_TRAILCNT: 0x%x\n" , val); +dev_dbg (priv->dev,"THS_TRAILCNT: %u\n" , val);tc358768_write (priv,TC358768_THS_TRAILCNT , val); val =BIT (0 );
@@ -803,10 +805,11 @@ static void tc358768_bridge_pre_enable(struct drm_bridge *bridge)/* TXTAGOCNT[26:16] RXTASURECNT[10:0] */ val =tc358768_to_ns ((lptxcnt +1 ) * dsibclk_nsk *4 ); val =tc358768_ns_to_cnt (val, dsibclk_nsk) /4 -1 ; +dev_dbg (priv->dev,"TXTAGOCNT: %u\n" , val); val2 =tc358768_ns_to_cnt (tc358768_to_ns ((lptxcnt +1 ) * dsibclk_nsk), dsibclk_nsk) -2 ; +dev_dbg (priv->dev,"RXTASURECNT: %u\n" , val2); val = val <<16 | val2; -dev_dbg (priv->dev,"BTACNTRL1: 0x%x\n" , val);tc358768_write (priv,TC358768_BTACNTRL1 , val);/* START[0] */
Signature · 1 line
2.42.0
Greg Kroah-Hartman
maintainerPATCH 236/603 drm/bridge: tc358768: Use dev for dbg prints, not priv->dev
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Tomi Valkeinen <[email protected]>
[ Upstream commit 89cfd50e13f1bead4350998a3a77422bef1ee0a5 ]
Simplify the code by capturing the priv->dev value to dev variable, and use it.
Stable-dep-of: f1dabbe64506 ("drm/bridge: tc358768: Fix tc358768_ns_to_cnt()")
--- drivers/gpu/drm/bridge/tc358768.c | 41 ++++++++++++++++--------------- 1 file changed, 21 insertions(+), 20 deletions(-)
drivers/gpu/drm/bridge/tc358768.c +21 -20
@@ -651,9 +651,10 @@ static void tc358768_bridge_pre_enable(struct drm_bridge *bridge)const u32 internal_delay =40 ;int ret, i;struct videomode vm; +struct device *dev = priv->dev;if (mode_flags &MIPI_DSI_CLOCK_NON_CONTINUOUS ) { -dev_warn_once (priv->dev,"Non-continuous mode unimplemented, falling back to continuous\n" ); +dev_warn_once (dev,"Non-continuous mode unimplemented, falling back to continuous\n" ); mode_flags &= ~MIPI_DSI_CLOCK_NON_CONTINUOUS ; }
@@ -661,7 +662,7 @@ static void tc358768_bridge_pre_enable(struct drm_bridge *bridge) ret =tc358768_sw_reset (priv);if (ret) { -dev_err (priv->dev,"Software reset failed: %d\n" , ret); +dev_err (dev,"Software reset failed: %d\n" , ret);tc358768_hw_disable (priv);return ; }
@@ -669,7 +670,7 @@ static void tc358768_bridge_pre_enable(struct drm_bridge *bridge) mode = &bridge->encoder->crtc->state->adjusted_mode; ret =tc358768_setup_pll (priv, mode);if (ret) { -dev_err (priv->dev,"PLL setup failed: %d\n" , ret); +dev_err (dev,"PLL setup failed: %d\n" , ret);tc358768_hw_disable (priv);return ; }
@@ -709,7 +710,7 @@ static void tc358768_bridge_pre_enable(struct drm_bridge *bridge) data_type =MIPI_DSI_PACKED_PIXEL_STREAM_16 ;break ;default : -dev_err (priv->dev,"Invalid data format (%u)\n" , +dev_err (dev,"Invalid data format (%u)\n" , dsi_dev->format);tc358768_hw_disable (priv);return ;
@@ -733,65 +734,65 @@ static void tc358768_bridge_pre_enable(struct drm_bridge *bridge) dsibclk); dsiclk_nsk = (u32 )div_u64 ((u64 )1000000000 *TC358768_PRECISION , dsiclk); ui_nsk = dsiclk_nsk /2 ; -dev_dbg (priv->dev,"dsiclk_nsk: %u\n" , dsiclk_nsk); -dev_dbg (priv->dev,"ui_nsk: %u\n" , ui_nsk); -dev_dbg (priv->dev,"dsibclk_nsk: %u\n" , dsibclk_nsk); +dev_dbg (dev,"dsiclk_nsk: %u\n" , dsiclk_nsk); +dev_dbg (dev,"ui_nsk: %u\n" , ui_nsk); +dev_dbg (dev,"dsibclk_nsk: %u\n" , dsibclk_nsk);/* LP11 > 100us for D-PHY Rx Init */ val =tc358768_ns_to_cnt (100 *1000 , dsibclk_nsk) -1 ; -dev_dbg (priv->dev,"LINEINITCNT: %u\n" , val); +dev_dbg (dev,"LINEINITCNT: %u\n" , val);tc358768_write (priv,TC358768_LINEINITCNT , val);/* LPTimeCnt > 50ns */ val =tc358768_ns_to_cnt (50 , dsibclk_nsk) -1 ; lptxcnt = val; -dev_dbg (priv->dev,"LPTXTIMECNT: %u\n" , val); +dev_dbg (dev,"LPTXTIMECNT: %u\n" , val);tc358768_write (priv,TC358768_LPTXTIMECNT , val);/* 38ns < TCLK_PREPARE < 95ns */ val =tc358768_ns_to_cnt (65 , dsibclk_nsk) -1 ; -dev_dbg (priv->dev,"TCLK_PREPARECNT %u\n" , val); +dev_dbg (dev,"TCLK_PREPARECNT %u\n" , val);/* TCLK_PREPARE + TCLK_ZERO > 300ns */ val2 =tc358768_ns_to_cnt (300 -tc358768_to_ns (2 * ui_nsk), dsibclk_nsk) -2 ; -dev_dbg (priv->dev,"TCLK_ZEROCNT %u\n" , val2); +dev_dbg (dev,"TCLK_ZEROCNT %u\n" , val2); val |= val2 <<8 ;tc358768_write (priv,TC358768_TCLK_HEADERCNT , val);/* TCLK_TRAIL > 60ns AND TEOT <= 105 ns + 12*UI */ raw_val =tc358768_ns_to_cnt (60 +tc358768_to_ns (2 * ui_nsk), dsibclk_nsk) -5 ; val =clamp (raw_val,0 ,127 ); -dev_dbg (priv->dev,"TCLK_TRAILCNT: %u\n" , val); +dev_dbg (dev,"TCLK_TRAILCNT: %u\n" , val);tc358768_write (priv,TC358768_TCLK_TRAILCNT , val);/* 40ns + 4*UI < THS_PREPARE < 85ns + 6*UI */ val =50 +tc358768_to_ns (4 * ui_nsk); val =tc358768_ns_to_cnt (val, dsibclk_nsk) -1 ; -dev_dbg (priv->dev,"THS_PREPARECNT %u\n" , val); +dev_dbg (dev,"THS_PREPARECNT %u\n" , val);/* THS_PREPARE + THS_ZERO > 145ns + 10*UI */ raw_val =tc358768_ns_to_cnt (145 -tc358768_to_ns (3 * ui_nsk), dsibclk_nsk) -10 ; val2 =clamp (raw_val,0 ,127 ); -dev_dbg (priv->dev,"THS_ZEROCNT %u\n" , val2); +dev_dbg (dev,"THS_ZEROCNT %u\n" , val2); val |= val2 <<8 ;tc358768_write (priv,TC358768_THS_HEADERCNT , val);/* TWAKEUP > 1ms in lptxcnt steps */ val =tc358768_ns_to_cnt (1020000 , dsibclk_nsk); val = val / (lptxcnt +1 ) -1 ; -dev_dbg (priv->dev,"TWAKEUP: %u\n" , val); +dev_dbg (dev,"TWAKEUP: %u\n" , val);tc358768_write (priv,TC358768_TWAKEUP , val);/* TCLK_POSTCNT > 60ns + 52*UI */ val =tc358768_ns_to_cnt (60 +tc358768_to_ns (52 * ui_nsk), dsibclk_nsk) -3 ; -dev_dbg (priv->dev,"TCLK_POSTCNT: %u\n" , val); +dev_dbg (dev,"TCLK_POSTCNT: %u\n" , val);tc358768_write (priv,TC358768_TCLK_POSTCNT , val);/* max(60ns + 4*UI, 8*UI) < THS_TRAILCNT < 105ns + 12*UI */ raw_val =tc358768_ns_to_cnt (60 +tc358768_to_ns (18 * ui_nsk), dsibclk_nsk) -4 ; val =clamp (raw_val,0 ,15 ); -dev_dbg (priv->dev,"THS_TRAILCNT: %u\n" , val); +dev_dbg (dev,"THS_TRAILCNT: %u\n" , val);tc358768_write (priv,TC358768_THS_TRAILCNT , val); val =BIT (0 );
@@ -805,10 +806,10 @@ static void tc358768_bridge_pre_enable(struct drm_bridge *bridge)/* TXTAGOCNT[26:16] RXTASURECNT[10:0] */ val =tc358768_to_ns ((lptxcnt +1 ) * dsibclk_nsk *4 ); val =tc358768_ns_to_cnt (val, dsibclk_nsk) /4 -1 ; -dev_dbg (priv->dev,"TXTAGOCNT: %u\n" , val); +dev_dbg (dev,"TXTAGOCNT: %u\n" , val); val2 =tc358768_ns_to_cnt (tc358768_to_ns ((lptxcnt +1 ) * dsibclk_nsk), dsibclk_nsk) -2 ; -dev_dbg (priv->dev,"RXTASURECNT: %u\n" , val2); +dev_dbg (dev,"RXTASURECNT: %u\n" , val2); val = val <<16 | val2;tc358768_write (priv,TC358768_BTACNTRL1 , val);
@@ -902,7 +903,7 @@ static void tc358768_bridge_pre_enable(struct drm_bridge *bridge) ret =tc358768_clear_error (priv);if (ret) { -dev_err (priv->dev,"Bridge pre_enable failed: %d\n" , ret); +dev_err (dev,"Bridge pre_enable failed: %d\n" , ret);tc358768_bridge_disable (bridge);tc358768_bridge_post_disable (bridge); }
Signature · 1 line
2.42.0
Greg Kroah-Hartman
maintainerPATCH 237/603 drm/bridge: tc358768: Rename dsibclk to hsbyteclk
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Tomi Valkeinen <[email protected]>
[ Upstream commit 699cf62a7d4550759f4a50e614b1952f93de4783 ]
The Toshiba documentation talks about HSByteClk when referring to the DSI HS byte clock, whereas the driver uses 'dsibclk' name. Also, in a few places the driver calculates the byte clock from the DSI clock, even if the byte clock is already available in a variable.
To align the driver with the documentation, change the 'dsibclk' variable to 'hsbyteclk'. This also make it easier to visually separate 'dsibclk' and 'dsiclk' variables.
Stable-dep-of: f1dabbe64506 ("drm/bridge: tc358768: Fix tc358768_ns_to_cnt()")
--- drivers/gpu/drm/bridge/tc358768.c | 48 +++++++++++++++---------------- 1 file changed, 24 insertions(+), 24 deletions(-)
drivers/gpu/drm/bridge/tc358768.c +24 -24
@@ -604,7 +604,7 @@ static int tc358768_setup_pll(struct tc358768_priv *priv,dev_dbg (priv->dev,"PLL: refclk %lu, fbd %u, prd %u, frs %u\n" ,clk_get_rate (priv->refclk), fbd, prd, frs); -dev_dbg (priv->dev,"PLL: pll_clk: %u, DSIClk %u, DSIByteClk %u\n" , +dev_dbg (priv->dev,"PLL: pll_clk: %u, DSIClk %u, HSByteClk %u\n" , priv->dsiclk *2 , priv->dsiclk, priv->dsiclk /4 ); dev_dbg(priv->dev, "PLL: pclk %u (panel: %u)\n", tc358768_pll_to_pclk(priv, priv->dsiclk * 2),
@@ -646,8 +646,8 @@ static void tc358768_bridge_pre_enable(struct drm_bridge *bridge)u32 val, val2, lptxcnt, hact, data_type;s32 raw_val;const struct drm_display_mode *mode; -u32 dsibclk_nsk, dsiclk_nsk, ui_nsk; -u32 dsiclk, dsibclk, video_start; +u32 hsbyteclk_nsk, dsiclk_nsk, ui_nsk; +u32 dsiclk, hsbyteclk, video_start;const u32 internal_delay =40 ;int ret, i;struct videomode vm;
@@ -678,7 +678,7 @@ static void tc358768_bridge_pre_enable(struct drm_bridge *bridge)drm_display_mode_to_videomode (mode, &vm); dsiclk = priv->dsiclk; - dsibclk = dsiclk /4 ; + hsbyteclk = dsiclk /4 ;/* Data Format Control Register */ val =BIT (2 ) |BIT (1 ) |BIT (0 );/* rdswap_en | dsitx_en | txdt_en */
@@ -730,67 +730,67 @@ static void tc358768_bridge_pre_enable(struct drm_bridge *bridge)tc358768_write (priv,TC358768_D0W_CNTRL + i *4 ,0x0000 );/* DSI Timings */ - dsibclk_nsk = (u32 )div_u64 ((u64 )1000000000 *TC358768_PRECISION , - dsibclk); + hsbyteclk_nsk = (u32 )div_u64 ((u64 )1000000000 *TC358768_PRECISION , + hsbyteclk); dsiclk_nsk = (u32 )div_u64 ((u64 )1000000000 *TC358768_PRECISION , dsiclk); ui_nsk = dsiclk_nsk /2 ;dev_dbg (dev,"dsiclk_nsk: %u\n" , dsiclk_nsk);dev_dbg (dev,"ui_nsk: %u\n" , ui_nsk); -dev_dbg (dev,"dsibclk_nsk: %u\n" , dsibclk_nsk); +dev_dbg (dev,"hsbyteclk_nsk: %u\n" , hsbyteclk_nsk);/* LP11 > 100us for D-PHY Rx Init */ - val =tc358768_ns_to_cnt (100 *1000 , dsibclk_nsk) -1 ; + val =tc358768_ns_to_cnt (100 *1000 , hsbyteclk_nsk) -1 ;dev_dbg (dev,"LINEINITCNT: %u\n" , val);tc358768_write (priv,TC358768_LINEINITCNT , val);/* LPTimeCnt > 50ns */ - val =tc358768_ns_to_cnt (50 , dsibclk_nsk) -1 ; + val =tc358768_ns_to_cnt (50 , hsbyteclk_nsk) -1 ; lptxcnt = val;dev_dbg (dev,"LPTXTIMECNT: %u\n" , val);tc358768_write (priv,TC358768_LPTXTIMECNT , val);/* 38ns < TCLK_PREPARE < 95ns */ - val =tc358768_ns_to_cnt (65 , dsibclk_nsk) -1 ; + val =tc358768_ns_to_cnt (65 , hsbyteclk_nsk) -1 ;dev_dbg (dev,"TCLK_PREPARECNT %u\n" , val);/* TCLK_PREPARE + TCLK_ZERO > 300ns */ val2 =tc358768_ns_to_cnt (300 -tc358768_to_ns (2 * ui_nsk), - dsibclk_nsk) -2 ; + hsbyteclk_nsk) -2 ;dev_dbg (dev,"TCLK_ZEROCNT %u\n" , val2); val |= val2 <<8 ;tc358768_write (priv,TC358768_TCLK_HEADERCNT , val);/* TCLK_TRAIL > 60ns AND TEOT <= 105 ns + 12*UI */ - raw_val =tc358768_ns_to_cnt (60 +tc358768_to_ns (2 * ui_nsk), dsibclk_nsk) -5 ; + raw_val =tc358768_ns_to_cnt (60 +tc358768_to_ns (2 * ui_nsk), hsbyteclk_nsk) -5 ; val =clamp (raw_val,0 ,127 );dev_dbg (dev,"TCLK_TRAILCNT: %u\n" , val);tc358768_write (priv,TC358768_TCLK_TRAILCNT , val);/* 40ns + 4*UI < THS_PREPARE < 85ns + 6*UI */ val =50 +tc358768_to_ns (4 * ui_nsk); - val =tc358768_ns_to_cnt (val, dsibclk_nsk) -1 ; + val =tc358768_ns_to_cnt (val, hsbyteclk_nsk) -1 ;dev_dbg (dev,"THS_PREPARECNT %u\n" , val);/* THS_PREPARE + THS_ZERO > 145ns + 10*UI */ - raw_val =tc358768_ns_to_cnt (145 -tc358768_to_ns (3 * ui_nsk), dsibclk_nsk) -10 ; + raw_val =tc358768_ns_to_cnt (145 -tc358768_to_ns (3 * ui_nsk), hsbyteclk_nsk) -10 ; val2 =clamp (raw_val,0 ,127 );dev_dbg (dev,"THS_ZEROCNT %u\n" , val2); val |= val2 <<8 ;tc358768_write (priv,TC358768_THS_HEADERCNT , val);/* TWAKEUP > 1ms in lptxcnt steps */ - val =tc358768_ns_to_cnt (1020000 , dsibclk_nsk); + val =tc358768_ns_to_cnt (1020000 , hsbyteclk_nsk); val = val / (lptxcnt +1 ) -1 ;dev_dbg (dev,"TWAKEUP: %u\n" , val);tc358768_write (priv,TC358768_TWAKEUP , val);/* TCLK_POSTCNT > 60ns + 52*UI */ val =tc358768_ns_to_cnt (60 +tc358768_to_ns (52 * ui_nsk), - dsibclk_nsk) -3 ; + hsbyteclk_nsk) -3 ;dev_dbg (dev,"TCLK_POSTCNT: %u\n" , val);tc358768_write (priv,TC358768_TCLK_POSTCNT , val);/* max(60ns + 4*UI, 8*UI) < THS_TRAILCNT < 105ns + 12*UI */ raw_val =tc358768_ns_to_cnt (60 +tc358768_to_ns (18 * ui_nsk), - dsibclk_nsk) -4 ; + hsbyteclk_nsk) -4 ; val =clamp (raw_val,0 ,15 );dev_dbg (dev,"THS_TRAILCNT: %u\n" , val);tc358768_write (priv,TC358768_THS_TRAILCNT , val);
@@ -804,11 +804,11 @@ static void tc358768_bridge_pre_enable(struct drm_bridge *bridge) (mode_flags & MIPI_DSI_CLOCK_NON_CONTINUOUS) ? 0 : BIT(0));/* TXTAGOCNT[26:16] RXTASURECNT[10:0] */ - val =tc358768_to_ns ((lptxcnt +1 ) * dsibclk_nsk *4 ); - val =tc358768_ns_to_cnt (val, dsibclk_nsk) /4 -1 ; + val =tc358768_to_ns ((lptxcnt +1 ) * hsbyteclk_nsk *4 ); + val =tc358768_ns_to_cnt (val, hsbyteclk_nsk) /4 -1 ;dev_dbg (dev,"TXTAGOCNT: %u\n" , val); - val2 =tc358768_ns_to_cnt (tc358768_to_ns ((lptxcnt +1 ) * dsibclk_nsk), - dsibclk_nsk) -2 ; + val2 =tc358768_ns_to_cnt (tc358768_to_ns ((lptxcnt +1 ) * hsbyteclk_nsk), + hsbyteclk_nsk) -2 ;dev_dbg (dev,"RXTASURECNT: %u\n" , val2); val = val <<16 | val2;tc358768_write (priv,TC358768_BTACNTRL1 , val);
@@ -831,13 +831,13 @@ static void tc358768_bridge_pre_enable(struct drm_bridge *bridge)/* hsw * byteclk * ndl / pclk */ val = (u32 )div_u64 (vm.hsync_len * - ((u64 )priv->dsiclk /4 ) * priv->dsi_lanes, + (u64 )hsbyteclk * priv->dsi_lanes, vm.pixelclock);tc358768_write (priv,TC358768_DSI_HSW , val);/* hbp * byteclk * ndl / pclk */ val = (u32 )div_u64 (vm.hback_porch * - ((u64 )priv->dsiclk /4 ) * priv->dsi_lanes, + (u64 )hsbyteclk * priv->dsi_lanes, vm.pixelclock);tc358768_write (priv,TC358768_DSI_HBPR , val); }else {
@@ -856,7 +856,7 @@ static void tc358768_bridge_pre_enable(struct drm_bridge *bridge)/* (hsw + hbp) * byteclk * ndl / pclk */ val = (u32 )div_u64 ((vm.hsync_len + vm.hback_porch) * - ((u64 )priv->dsiclk /4 ) * priv->dsi_lanes, + (u64 )hsbyteclk * priv->dsi_lanes, vm.pixelclock);tc358768_write (priv,TC358768_DSI_HSW , val);
Signature · 1 line
2.42.0
Greg Kroah-Hartman
maintainerPATCH 238/603 drm/bridge: tc358768: Clean up clock period code
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Tomi Valkeinen <[email protected]>
[ Upstream commit b3aa7b34924a9ed64cf96899cac4d8ea08cd829e ]
The driver defines TC358768_PRECISION as 1000, and uses "nsk" to refer to clock periods. The original author does not remember where all this came from. Effectively the driver is using picoseconds as the unit for clock periods, yet referring to them by "nsk".
Clean this up by just saying the periods are in picoseconds.
Stable-dep-of: f1dabbe64506 ("drm/bridge: tc358768: Fix tc358768_ns_to_cnt()")
--- drivers/gpu/drm/bridge/tc358768.c | 60 +++++++++++++++---------------- 1 file changed, 29 insertions(+), 31 deletions(-)
drivers/gpu/drm/bridge/tc358768.c +29 -31
@@ -15,6 +15,7 @@#include <linux/regmap.h> #include <linux/regulator/consumer.h> #include <linux/slab.h> +#include <linux/units.h> #include <drm/drm_atomic_helper.h> #include <drm/drm_drv.h>
@@ -627,15 +628,14 @@ static int tc358768_setup_pll(struct tc358768_priv *priv,return tc358768_clear_error (priv); } -#define TC358768_PRECISION 1000 -static u32 tc358768_ns_to_cnt (u32 ns,u32 period_nsk) +static u32 tc358768_ns_to_cnt (u32 ns,u32 period_ps) { -return (ns *TC358768_PRECISION + period_nsk) / period_nsk; +return (ns *1000 + period_ps) / period_ps; } -static u32 tc358768_to_ns (u32 nsk) +static u32 tc358768_ps_to_ns (u32 ps) { -return (nsk /TC358768_PRECISION ); +return ps /1000 ; }static void tc358768_bridge_pre_enable (struct drm_bridge *bridge)
@@ -646,7 +646,7 @@ static void tc358768_bridge_pre_enable(struct drm_bridge *bridge)u32 val, val2, lptxcnt, hact, data_type;s32 raw_val;const struct drm_display_mode *mode; -u32 hsbyteclk_nsk, dsiclk_nsk, ui_nsk; +u32 hsbyteclk_ps, dsiclk_ps, ui_ps;u32 dsiclk, hsbyteclk, video_start;const u32 internal_delay =40 ;int ret, i;
@@ -730,67 +730,65 @@ static void tc358768_bridge_pre_enable(struct drm_bridge *bridge)tc358768_write (priv,TC358768_D0W_CNTRL + i *4 ,0x0000 );/* DSI Timings */ - hsbyteclk_nsk = (u32 )div_u64 ((u64 )1000000000 *TC358768_PRECISION , - hsbyteclk); - dsiclk_nsk = (u32 )div_u64 ((u64 )1000000000 *TC358768_PRECISION , dsiclk); - ui_nsk = dsiclk_nsk /2 ; -dev_dbg (dev,"dsiclk_nsk: %u\n" , dsiclk_nsk); -dev_dbg (dev,"ui_nsk: %u\n" , ui_nsk); -dev_dbg (dev,"hsbyteclk_nsk: %u\n" , hsbyteclk_nsk); + hsbyteclk_ps = (u32 )div_u64 (PICO , hsbyteclk); + dsiclk_ps = (u32 )div_u64 (PICO , dsiclk); + ui_ps = dsiclk_ps /2 ; +dev_dbg (dev,"dsiclk: %u ps, ui %u ps, hsbyteclk %u ps\n" , dsiclk_ps, + ui_ps, hsbyteclk_ps);/* LP11 > 100us for D-PHY Rx Init */ - val =tc358768_ns_to_cnt (100 *1000 , hsbyteclk_nsk) -1 ; + val =tc358768_ns_to_cnt (100 *1000 , hsbyteclk_ps) -1 ;dev_dbg (dev,"LINEINITCNT: %u\n" , val);tc358768_write (priv,TC358768_LINEINITCNT , val);/* LPTimeCnt > 50ns */ - val =tc358768_ns_to_cnt (50 , hsbyteclk_nsk) -1 ; + val =tc358768_ns_to_cnt (50 , hsbyteclk_ps) -1 ; lptxcnt = val;dev_dbg (dev,"LPTXTIMECNT: %u\n" , val);tc358768_write (priv,TC358768_LPTXTIMECNT , val);/* 38ns < TCLK_PREPARE < 95ns */ - val =tc358768_ns_to_cnt (65 , hsbyteclk_nsk) -1 ; + val =tc358768_ns_to_cnt (65 , hsbyteclk_ps) -1 ;dev_dbg (dev,"TCLK_PREPARECNT %u\n" , val);/* TCLK_PREPARE + TCLK_ZERO > 300ns */ - val2 =tc358768_ns_to_cnt (300 -tc358768_to_ns (2 * ui_nsk), - hsbyteclk_nsk) -2 ; + val2 =tc358768_ns_to_cnt (300 -tc358768_ps_to_ns (2 * ui_ps), + hsbyteclk_ps) -2 ;dev_dbg (dev,"TCLK_ZEROCNT %u\n" , val2); val |= val2 <<8 ;tc358768_write (priv,TC358768_TCLK_HEADERCNT , val);/* TCLK_TRAIL > 60ns AND TEOT <= 105 ns + 12*UI */ - raw_val =tc358768_ns_to_cnt (60 +tc358768_to_ns (2 * ui_nsk), hsbyteclk_nsk) -5 ; + raw_val =tc358768_ns_to_cnt (60 +tc358768_ps_to_ns (2 * ui_ps), hsbyteclk_ps) -5 ; val =clamp (raw_val,0 ,127 );dev_dbg (dev,"TCLK_TRAILCNT: %u\n" , val);tc358768_write (priv,TC358768_TCLK_TRAILCNT , val);/* 40ns + 4*UI < THS_PREPARE < 85ns + 6*UI */ - val =50 +tc358768_to_ns (4 * ui_nsk); - val =tc358768_ns_to_cnt (val, hsbyteclk_nsk) -1 ; + val =50 +tc358768_ps_to_ns (4 * ui_ps); + val =tc358768_ns_to_cnt (val, hsbyteclk_ps) -1 ;dev_dbg (dev,"THS_PREPARECNT %u\n" , val);/* THS_PREPARE + THS_ZERO > 145ns + 10*UI */ - raw_val =tc358768_ns_to_cnt (145 -tc358768_to_ns (3 * ui_nsk), hsbyteclk_nsk) -10 ; + raw_val =tc358768_ns_to_cnt (145 -tc358768_ps_to_ns (3 * ui_ps), hsbyteclk_ps) -10 ; val2 =clamp (raw_val,0 ,127 );dev_dbg (dev,"THS_ZEROCNT %u\n" , val2); val |= val2 <<8 ;tc358768_write (priv,TC358768_THS_HEADERCNT , val);/* TWAKEUP > 1ms in lptxcnt steps */ - val =tc358768_ns_to_cnt (1020000 , hsbyteclk_nsk); + val =tc358768_ns_to_cnt (1020000 , hsbyteclk_ps); val = val / (lptxcnt +1 ) -1 ;dev_dbg (dev,"TWAKEUP: %u\n" , val);tc358768_write (priv,TC358768_TWAKEUP , val);/* TCLK_POSTCNT > 60ns + 52*UI */ - val =tc358768_ns_to_cnt (60 +tc358768_to_ns (52 * ui_nsk), - hsbyteclk_nsk) -3 ; + val =tc358768_ns_to_cnt (60 +tc358768_ps_to_ns (52 * ui_ps), + hsbyteclk_ps) -3 ;dev_dbg (dev,"TCLK_POSTCNT: %u\n" , val);tc358768_write (priv,TC358768_TCLK_POSTCNT , val);/* max(60ns + 4*UI, 8*UI) < THS_TRAILCNT < 105ns + 12*UI */ - raw_val =tc358768_ns_to_cnt (60 +tc358768_to_ns (18 * ui_nsk), - hsbyteclk_nsk) -4 ; + raw_val =tc358768_ns_to_cnt (60 +tc358768_ps_to_ns (18 * ui_ps), + hsbyteclk_ps) -4 ; val =clamp (raw_val,0 ,15 );dev_dbg (dev,"THS_TRAILCNT: %u\n" , val);tc358768_write (priv,TC358768_THS_TRAILCNT , val);
@@ -804,11 +802,11 @@ static void tc358768_bridge_pre_enable(struct drm_bridge *bridge) (mode_flags & MIPI_DSI_CLOCK_NON_CONTINUOUS) ? 0 : BIT(0));/* TXTAGOCNT[26:16] RXTASURECNT[10:0] */ - val =tc358768_to_ns ((lptxcnt +1 ) * hsbyteclk_nsk *4 ); - val =tc358768_ns_to_cnt (val, hsbyteclk_nsk) /4 -1 ; + val =tc358768_ps_to_ns ((lptxcnt +1 ) * hsbyteclk_ps *4 ); + val =tc358768_ns_to_cnt (val, hsbyteclk_ps) /4 -1 ;dev_dbg (dev,"TXTAGOCNT: %u\n" , val); - val2 =tc358768_ns_to_cnt (tc358768_to_ns ((lptxcnt +1 ) * hsbyteclk_nsk), - hsbyteclk_nsk) -2 ; + val2 =tc358768_ns_to_cnt (tc358768_ps_to_ns ((lptxcnt +1 ) * hsbyteclk_ps), + hsbyteclk_ps) -2 ;dev_dbg (dev,"RXTASURECNT: %u\n" , val2); val = val <<16 | val2;tc358768_write (priv,TC358768_BTACNTRL1 , val);
Signature · 1 line
2.42.0
Greg Kroah-Hartman
maintainerPATCH 239/603 drm/bridge: tc358768: Fix tc358768_ns_to_cnt()
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Tomi Valkeinen <[email protected]>
[ Upstream commit f1dabbe645065d20ca863c8d446c74c59ca1ca9d ]
The tc358768_ns_to_cnt() is, most likely, supposed to do a div-round-up operation, but it misses subtracting one from the dividend.
Fix this by just using DIV_ROUND_UP().
--- drivers/gpu/drm/bridge/tc358768.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/gpu/drm/bridge/tc358768.c +1 -1
@@ -630,7 +630,7 @@ static int tc358768_setup_pll(struct tc358768_priv *priv,static u32 tc358768_ns_to_cnt (u32 ns,u32 period_ps) { -return (ns *1000 + period_ps) / period_ps; +return DIV_ROUND_UP (ns *1000 , period_ps); }static u32 tc358768_ps_to_ns (u32 ps)
Signature · 1 line
2.42.0
Greg Kroah-Hartman
maintainerPATCH 240/603 drm: Call drm_atomic_helper_shutdown() at shutdown/remove time for misc drivers
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Douglas Anderson <[email protected]>
[ Upstream commit 3c4babae3c4a1ae05f8f3f5f3d50c440ead7ca6a ]
Based on grepping through the source code these drivers appear to be missing a call to drm_atomic_helper_shutdown() at system shutdown time and at driver remove (or unbind) time. Among other things, this means that if a panel is in use that it won't be cleanly powered off at system shutdown time.
The fact that we should call drm_atomic_helper_shutdown() in the case of OS shutdown/restart and at driver remove (or unbind) time comes straight out of the kernel doc "driver instance overview" in drm_drv.c.
A few notes about these fixes:
- I confirmed that these drivers were all DRIVER_MODESET type drivers, which I believe makes this relevant.
- I confirmed that these drivers were all DRIVER_ATOMIC.
- When adding drm_atomic_helper_shutdown() to the remove/unbind path, I added it after drm_kms_helper_poll_fini() when the driver had it. This seemed to be what other drivers did. If drm_kms_helper_poll_fini() wasn't there I added it straight after drm_dev_unregister().
- This patch deals with drivers using the component model in similar ways as the patch ("drm: Call drm_atomic_helper_shutdown() at shutdown time for misc drivers")
- These fixes rely on the patch ("drm/atomic-helper:
drm_atomic_helper_shutdown(NULL) should be a noop") to simplify shutdown.
--- drivers/gpu/drm/aspeed/aspeed_gfx_drv.c | 7 +++++++ drivers/gpu/drm/mgag200/mgag200_drv.c | 8 ++++++++ drivers/gpu/drm/pl111/pl111_drv.c | 7 +++++++ drivers/gpu/drm/stm/drv.c | 7 +++++++ drivers/gpu/drm/tilcdc/tilcdc_drv.c | 11 ++++++++++- drivers/gpu/drm/tve200/tve200_drv.c | 7 +++++++ drivers/gpu/drm/vboxvideo/vbox_drv.c | 10 ++++++++++ 7 files changed, 56 insertions(+), 1 deletion(-)
drivers/gpu/drm/aspeed/aspeed_gfx_drv.c +7 -0
@@ -358,11 +358,18 @@ static void aspeed_gfx_remove(struct platform_device *pdev)sysfs_remove_group (&pdev->dev.kobj, &aspeed_sysfs_attr_group);drm_dev_unregister (drm);aspeed_gfx_unload (drm); +drm_atomic_helper_shutdown (drm); +} + +static void aspeed_gfx_shutdown (struct platform_device *pdev) +{ +drm_atomic_helper_shutdown (platform_get_drvdata (pdev)); }static struct platform_driver aspeed_gfx_platform_driver = { .probe = aspeed_gfx_probe, .remove_new = aspeed_gfx_remove, + .shutdown = aspeed_gfx_shutdown, .driver = { .name ="aspeed_gfx" , .of_match_table = aspeed_gfx_match,
drivers/gpu/drm/mgag200/mgag200_drv.c +8 -0
@@ -10,6 +10,7 @@#include <linux/pci.h> #include <drm/drm_aperture.h> +#include <drm/drm_atomic_helper.h> #include <drm/drm_drv.h> #include <drm/drm_fbdev_generic.h> #include <drm/drm_file.h>
@@ -278,6 +279,12 @@ static void mgag200_pci_remove(struct pci_dev *pdev)struct drm_device *dev =pci_get_drvdata (pdev);drm_dev_unregister (dev); +drm_atomic_helper_shutdown (dev); +} + +static void mgag200_pci_shutdown (struct pci_dev *pdev) +{ +drm_atomic_helper_shutdown (pci_get_drvdata (pdev)); }static struct pci_driver mgag200_pci_driver = {
@@ -285,6 +292,7 @@ static struct pci_driver mgag200_pci_driver = { .id_table = mgag200_pciidlist, .probe = mgag200_pci_probe, .remove = mgag200_pci_remove, + .shutdown = mgag200_pci_shutdown, };drm_module_pci_driver_if_modeset (mgag200_pci_driver, mgag200_modeset);
drivers/gpu/drm/pl111/pl111_drv.c +7 -0
@@ -323,12 +323,18 @@ static void pl111_amba_remove(struct amba_device *amba_dev)struct pl111_drm_dev_private *priv = drm->dev_private;drm_dev_unregister (drm); +drm_atomic_helper_shutdown (drm);if (priv->panel)drm_panel_bridge_remove (priv->bridge);drm_dev_put (drm);of_reserved_mem_device_release (dev); } +static void pl111_amba_shutdown (struct amba_device *amba_dev) +{ +drm_atomic_helper_shutdown (amba_get_drvdata (amba_dev)); +} +/* * This early variant lacks the 565 and 444 pixel formats. */
@@ -431,6 +437,7 @@ static struct amba_driver pl111_amba_driver __maybe_unused = { }, .probe = pl111_amba_probe, .remove = pl111_amba_remove, + .shutdown = pl111_amba_shutdown, .id_table = pl111_id_table, };
drivers/gpu/drm/stm/drv.c +7 -0
@@ -114,6 +114,7 @@ static void drv_unload(struct drm_device *ddev)DRM_DEBUG ("%s\n" , __func__);drm_kms_helper_poll_fini (ddev); +drm_atomic_helper_shutdown (ddev);ltdc_unload (ddev); }
@@ -225,6 +226,11 @@ static void stm_drm_platform_remove(struct platform_device *pdev)drm_dev_put (ddev); } +static void stm_drm_platform_shutdown (struct platform_device *pdev) +{ +drm_atomic_helper_shutdown (platform_get_drvdata (pdev)); +} +static const struct of_device_id drv_dt_ids[] = { { .compatible ="st,stm32-ltdc" }, {/* end node */ },
@@ -234,6 +240,7 @@ MODULE_DEVICE_TABLE(of, drv_dt_ids);static struct platform_driver stm_drm_platform_driver = { .probe = stm_drm_platform_probe, .remove_new = stm_drm_platform_remove, + .shutdown = stm_drm_platform_shutdown, .driver = { .name ="stm32-display" , .of_match_table = drv_dt_ids,
drivers/gpu/drm/tilcdc/tilcdc_drv.c +10 -1
@@ -175,6 +175,7 @@ static void tilcdc_fini(struct drm_device *dev)drm_dev_unregister (dev);drm_kms_helper_poll_fini (dev); +drm_atomic_helper_shutdown (dev);tilcdc_irq_uninstall (dev);drm_mode_config_cleanup (dev);
@@ -389,6 +390,7 @@ static int tilcdc_init(const struct drm_driver *ddrv, struct device *dev) init_failed:tilcdc_fini (ddev); +platform_set_drvdata (pdev,NULL );return ret; }
@@ -537,7 +539,8 @@ static void tilcdc_unbind(struct device *dev)if (!ddev->dev_private)return ; -tilcdc_fini (dev_get_drvdata (dev)); +tilcdc_fini (ddev); +dev_set_drvdata (dev,NULL ); }static const struct component_master_ops tilcdc_comp_ops = {
@@ -582,6 +585,11 @@ static int tilcdc_pdev_remove(struct platform_device *pdev)return 0 ; } +static void tilcdc_pdev_shutdown (struct platform_device *pdev) +{ +drm_atomic_helper_shutdown (platform_get_drvdata (pdev)); +} +static const struct of_device_id tilcdc_of_match[] = { { .compatible ="ti,am33xx-tilcdc" , }, { .compatible ="ti,da850-tilcdc" , },
@@ -592,6 +600,7 @@ MODULE_DEVICE_TABLE(of, tilcdc_of_match);static struct platform_driver tilcdc_platform_driver = { .probe = tilcdc_pdev_probe, .remove = tilcdc_pdev_remove, + .shutdown = tilcdc_pdev_shutdown, .driver = { .name ="tilcdc" , .pm =pm_sleep_ptr (&tilcdc_pm_ops),
drivers/gpu/drm/tve200/tve200_drv.c +7 -0
@@ -242,6 +242,7 @@ static void tve200_remove(struct platform_device *pdev)struct tve200_drm_dev_private *priv = drm->dev_private;drm_dev_unregister (drm); +drm_atomic_helper_shutdown (drm);if (priv->panel)drm_panel_bridge_remove (priv->bridge);drm_mode_config_cleanup (drm);
@@ -249,6 +250,11 @@ static void tve200_remove(struct platform_device *pdev)drm_dev_put (drm); } +static void tve200_shutdown (struct platform_device *pdev) +{ +drm_atomic_helper_shutdown (platform_get_drvdata (pdev)); +} +static const struct of_device_id tve200_of_match[] = { { .compatible ="faraday,tve200" ,
@@ -263,6 +269,7 @@ static struct platform_driver tve200_driver = { }, .probe = tve200_probe, .remove_new = tve200_remove, + .shutdown = tve200_shutdown, };drm_module_platform_driver (tve200_driver);
drivers/gpu/drm/vboxvideo/vbox_drv.c +10 -0
@@ -12,6 +12,7 @@#include <linux/vt_kern.h> #include <drm/drm_aperture.h> +#include <drm/drm_atomic_helper.h> #include <drm/drm_drv.h> #include <drm/drm_fbdev_generic.h> #include <drm/drm_file.h>
@@ -97,11 +98,19 @@ static void vbox_pci_remove(struct pci_dev *pdev)struct vbox_private *vbox =pci_get_drvdata (pdev);drm_dev_unregister (&vbox->ddev); +drm_atomic_helper_shutdown (&vbox->ddev);vbox_irq_fini (vbox);vbox_mode_fini (vbox);vbox_hw_fini (vbox); } +static void vbox_pci_shutdown (struct pci_dev *pdev) +{ +struct vbox_private *vbox =pci_get_drvdata (pdev); + +drm_atomic_helper_shutdown (&vbox->ddev); +} +static int vbox_pm_suspend (struct device *dev) {struct vbox_private *vbox =dev_get_drvdata (dev);
@@ -165,6 +174,7 @@ static struct pci_driver vbox_pci_driver = { .id_table = pciidlist, .probe = vbox_pci_probe, .remove = vbox_pci_remove, + .shutdown = vbox_pci_shutdown, .driver.pm = pm_sleep_ptr(&vbox_pm_ops), };
Signature · 1 line
2.42.0
Greg Kroah-Hartman
maintainerPATCH 241/603 drm/amdgpu: Increase IH soft ring size for GFX v9.4.3 dGPU
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Philip Yang <[email protected]>
[ Upstream commit bcfb9cee61207b80f37663ffa08c135657a27ad5 ]
On GFX v9.4.3 dGPU, applications have random timeout failure when XNACK on, dmesg log has "amdgpu: IH soft ring buffer overflow 0x900, 0x900", because dGPU mode has 272 cam entries. After increasing IH soft ring to 512 entries, no more IH soft ring overflow message and application passed.
--- drivers/gpu/drm/amd/amdgpu/amdgpu_ih.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/gpu/drm/amd/amdgpu/amdgpu_ih.h +1 -1
@@ -28,7 +28,7 @@#define AMDGPU_IH_MAX_NUM_IVS 32#define IH_RING_SIZE (256 * 1024) -#define IH_SW_RING_SIZE (8 * 1024)/* enough for 256 CAM entries */ +#define IH_SW_RING_SIZE (16 * 1024)/* enough for 512 CAM entries */ struct amdgpu_device ;struct amdgpu_iv_entry ;
Signature · 1 line
2.42.0
Greg Kroah-Hartman
maintainerPATCH 242/603 drm/amdkfd: fix some race conditions in vram buffer alloc/free of svm code
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Xiaogang Chen <[email protected]>
[ Upstream commit 7bfaa160caed8192f8262c4638f552cad94bcf5a ]
This patch fixes:
1: ref number of prange's svm_bo got decreased by an async call from hmm. When wait svm_bo of prange got released we shoul also wait prang->svm_bo become NULL, otherwise prange->svm_bo may be set to null after allocate new vram buffer.
2: During waiting svm_bo of prange got released in a while loop should reschedule current task to give other tasks oppotunity to run, specially the the workque task that handles svm_bo ref release, otherwise we may enter to softlock.
--- drivers/gpu/drm/amd/amdkfd/kfd_svm.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-)
drivers/gpu/drm/amd/amdkfd/kfd_svm.c +4 -4
@@ -495,11 +495,11 @@ svm_range_validate_svm_bo(struct kfd_node *node, struct svm_range *prange)/* We need a new svm_bo. Spin-loop to wait for concurrent * svm_range_bo_release to finish removing this range from -* its range list. After this, it is safe to reuse the -* svm_bo pointer and svm_bo_list head. +* its range list and set prange->svm_bo to null. After this, +* it is safe to reuse the svm_bo pointer and svm_bo_list head. */ -while (!list_empty_careful (&prange->svm_bo_list)) - ; +while (!list_empty_careful (&prange->svm_bo_list) || prange->svm_bo) +cond_resched ();return false; }
Signature · 1 line
2.42.0
Greg Kroah-Hartman
maintainerPATCH 243/603 drm/amdkfd: Remove svm range validated_once flag
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Philip Yang <[email protected]>
[ Upstream commit c99b16128082de519975aa147d9da3e40380de67 ]
The validated_once flag is not used after the prefault was removed, The prefault was needed to ensure validate all system memory pages at least once before mapping or migrating the range to GPU.
Stable-dep-of: eb3c357bcb28 ("drm/amdkfd: Handle errors from svm validate and map")
--- drivers/gpu/drm/amd/amdkfd/kfd_svm.c | 4 +--- drivers/gpu/drm/amd/amdkfd/kfd_svm.h | 1 - 2 files changed, 1 insertion(+), 4 deletions(-)
drivers/gpu/drm/amd/amdkfd/kfd_svm.c +1 -3
@@ -1720,10 +1720,8 @@ static int svm_range_validate_and_map(struct mm_struct *mm, addr = next; } -if (addr == end) { - prange->validated_once = true; +if (addr == end) prange->mapped_to_gpu = true; - } unreserve_out:svm_range_unreserve_bos (ctx);
drivers/gpu/drm/amd/amdkfd/kfd_svm.h +0 -1
@@ -132,7 +132,6 @@ struct svm_range {struct list_head child_list;DECLARE_BITMAP (bitmap_access,MAX_GPU_INSTANCE );DECLARE_BITMAP (bitmap_aip,MAX_GPU_INSTANCE ); -bool validated_once;bool mapped_to_gpu;bool is_error_flag; };
Signature · 1 line
2.42.0
Greg Kroah-Hartman
maintainerPATCH 244/603 drm/amdkfd: Handle errors from svm validate and map
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Philip Yang <[email protected]>
[ Upstream commit eb3c357bcb286e89386e89302061fe717fe4e562 ]
If new range is splited to multiple pranges with max_svm_range_pages alignment and added to update_list, svm validate and map should keep going after error to make sure prange->mapped_to_gpu flag is up to date for the whole range.
svm validate and map update set prange->mapped_to_gpu after mapping to GPUs successfully, otherwise clear prange->mapped_to_gpu flag (for update mapping case) instead of setting error flag, we can remove the redundant error flag to simpliy code.
Refactor to remove goto and update prange->mapped_to_gpu flag inside svm_range_lock, to guarant we always evict queues or unmap from GPUs if there are invalid ranges.
After svm validate and map return error -EAGIN, the caller retry will update the mapping for the whole range again.
--- drivers/gpu/drm/amd/amdkfd/kfd_svm.c | 82 +++++++++++++--------------- drivers/gpu/drm/amd/amdkfd/kfd_svm.h | 1 - 2 files changed, 39 insertions(+), 44 deletions(-)
drivers/gpu/drm/amd/amdkfd/kfd_svm.c +39 -43
@@ -820,7 +820,7 @@ svm_range_is_same_attrs(struct kfd_process *p, struct svm_range *prange, } } -return !prange->is_error_flag; +return true; }/**
@@ -1662,71 +1662,66 @@ static int svm_range_validate_and_map(struct mm_struct *mm, start = prange->start <<PAGE_SHIFT ; end = (prange->last +1 ) <<PAGE_SHIFT ; -for (addr = start; addr < end && !r; ) { +for (addr = start; !r && addr < end; ) {struct hmm_range *hmm_range;struct vm_area_struct *vma; -unsigned long next; +unsigned long next =0 ;unsigned long offset;unsigned long npages;bool readonly; vma =vma_lookup (mm, addr); -if (!vma) { +if (vma) { + readonly = !(vma->vm_flags &VM_WRITE ); + + next =min (vma->vm_end, end); + npages = (next - addr) >>PAGE_SHIFT ; +WRITE_ONCE (p->svms.faulting_task, current); + r =amdgpu_hmm_range_get_pages (&prange->notifier, addr, npages, + readonly, owner,NULL , + &hmm_range); +WRITE_ONCE (p->svms.faulting_task,NULL ); +if (r) { +pr_debug ("failed %d to get svm range pages\n" , r); +if (r == -EBUSY ) + r = -EAGAIN ; + } + }else { r = -EFAULT ; - goto unreserve_out; - } - readonly = !(vma->vm_flags &VM_WRITE ); - - next =min (vma->vm_end, end); - npages = (next - addr) >>PAGE_SHIFT ; -WRITE_ONCE (p->svms.faulting_task, current); - r =amdgpu_hmm_range_get_pages (&prange->notifier, addr, npages, - readonly, owner,NULL , - &hmm_range); -WRITE_ONCE (p->svms.faulting_task,NULL ); -if (r) { -pr_debug ("failed %d to get svm range pages\n" , r); -if (r == -EBUSY ) - r = -EAGAIN ; - goto unreserve_out; } - offset = (addr - start) >>PAGE_SHIFT ; - r =svm_range_dma_map (prange, ctx->bitmap, offset, npages, - hmm_range->hmm_pfns); -if (r) { -pr_debug ("failed %d to dma map range\n" , r); - goto unreserve_out; +if (!r) { + offset = (addr - start) >>PAGE_SHIFT ; + r =svm_range_dma_map (prange, ctx->bitmap, offset, npages, + hmm_range->hmm_pfns); +if (r) +pr_debug ("failed %d to dma map range\n" , r); }svm_range_lock (prange); -if (amdgpu_hmm_range_get_pages_done (hmm_range)) { +if (!r &&amdgpu_hmm_range_get_pages_done (hmm_range)) {pr_debug ("hmm update the range, need validate again\n" ); r = -EAGAIN ; - goto unlock_out; } -if (!list_empty (&prange->child_list)) { + +if (!r && !list_empty (&prange->child_list)) {pr_debug ("range split by unmap in parallel, validate again\n" ); r = -EAGAIN ; - goto unlock_out; } - r =svm_range_map_to_gpus (prange, offset, npages, readonly, - ctx->bitmap, wait, flush_tlb); +if (!r) + r =svm_range_map_to_gpus (prange, offset, npages, readonly, + ctx->bitmap, wait, flush_tlb); + +if (!r && next == end) + prange->mapped_to_gpu = true; -unlock_out:svm_range_unlock (prange); addr = next; } -if (addr == end) - prange->mapped_to_gpu = true; - -unreserve_out:svm_range_unreserve_bos (ctx); - - prange->is_error_flag = !!r;if (!r) prange->validate_timestamp =ktime_get_boottime ();
@@ -2095,7 +2090,8 @@ svm_range_add(struct kfd_process *p, uint64_t start, uint64_t size, next =interval_tree_iter_next (node, start, last); next_start =min (node->last, last) +1 ; -if (svm_range_is_same_attrs (p, prange, nattr, attrs)) { +if (svm_range_is_same_attrs (p, prange, nattr, attrs) && + prange->mapped_to_gpu) {/* nothing to do */ }else if (node->start < start || node->last > last) {/* node intersects the update range and its attributes
@@ -3505,7 +3501,7 @@ svm_range_set_attr(struct kfd_process *p, struct mm_struct *mm,struct svm_range *next;bool update_mapping = false;bool flush_tlb; -int r =0 ; +int r, ret =0 ;pr_debug ("pasid 0x%x svms 0x%p [0x%llx 0x%llx] pages 0x%llx\n" , p->pasid, &p->svms, start, start + size -1 , size);
@@ -3593,7 +3589,7 @@ svm_range_set_attr(struct kfd_process *p, struct mm_struct *mm, out_unlock_range:mutex_unlock (&prange->migrate_mutex);if (r) -break ; + ret = r; }dynamic_svm_range_dump (svms);
@@ -3606,7 +3602,7 @@ svm_range_set_attr(struct kfd_process *p, struct mm_struct *mm,pr_debug ("pasid 0x%x svms 0x%p [0x%llx 0x%llx] done, r=%d\n" , p->pasid, &p->svms, start, start + size -1 , r); -return r; +return ret ? ret : r; } static int
drivers/gpu/drm/amd/amdkfd/kfd_svm.h +0 -1
@@ -133,7 +133,6 @@ struct svm_range {DECLARE_BITMAP (bitmap_access,MAX_GPU_INSTANCE );DECLARE_BITMAP (bitmap_aip,MAX_GPU_INSTANCE );bool mapped_to_gpu; -bool is_error_flag; };static inline void svm_range_lock (struct svm_range *prange)
Signature · 1 line
2.42.0
Greg Kroah-Hartman
maintainerPATCH 245/603 drm/amd/display: Fix null pointer dereference in error message
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Cong Liu <[email protected]>
[ Upstream commit 0c3601a2fbfb265ce283651480e30c8e60459112 ]
This patch fixes a null pointer dereference in the error message that is printed when the Display Core (DC) fails to initialize. The original message includes the DC version number, which is undefined if the DC is not initialized.
--- drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-)
drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c +1 -2
@@ -1692,8 +1692,7 @@ static int amdgpu_dm_init(struct amdgpu_device *adev)DRM_INFO ("Display Core v%s initialized on %s\n" ,DC_VER ,dce_version_to_string (adev->dm.dc->ctx->dce_version)); }else { -DRM_INFO ("Display Core v%s failed to initialize on %s\n" ,DC_VER , -dce_version_to_string (adev->dm.dc->ctx->dce_version)); +DRM_INFO ("Display Core failed to initialize with v%s!\n" ,DC_VER ); goto error; }
Signature · 1 line
2.42.0