summaryrefslogtreecommitdiff
path: root/drivers
diff options
context:
space:
mode:
authorGreg Kroah-Hartman <gregkh@linuxfoundation.org>2026-07-04 13:44:22 +0200
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2026-07-04 13:44:22 +0200
commit1c5f3df9481bb6275aeb079a8312d037da69715b (patch)
treed13b0d25dbbc19af5884d0b780c74309c5d3fa1e /drivers
parentf657f1a475c7ab8aa116fd7bc8a6dba693d379ae (diff)
parente46dc0adfe39724bcf52cea47b8f9c9aed86a394 (diff)
downloadlinux-rolling-lts.tar.gz
linux-rolling-lts.zip
Merge v6.18.38linux-rolling-lts
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Diffstat (limited to 'drivers')
-rw-r--r--drivers/crypto/nx/nx.c6
-rw-r--r--drivers/crypto/nx/nx.h2
-rw-r--r--drivers/fpga/of-fpga-region.c3
-rw-r--r--drivers/i2c/i2c-core-base.c8
-rw-r--r--drivers/irqchip/irq-imgpdc.c6
-rw-r--r--drivers/net/wan/hdlc_ppp.c15
-rw-r--r--drivers/net/wireless/ath/ath11k/dp.c1
-rw-r--r--drivers/net/wireless/intel/iwlwifi/mld/agg.c9
-rw-r--r--drivers/net/wireless/intel/iwlwifi/mld/ptp.c2
-rw-r--r--drivers/net/wireless/intel/iwlwifi/mvm/ptp.c2
-rw-r--r--drivers/net/wireless/mediatek/mt76/mac80211.c15
-rw-r--r--drivers/net/wireless/mediatek/mt76/mt76x2/usb.c1
-rw-r--r--drivers/net/wireless/mediatek/mt76/mt7925/main.c3
-rw-r--r--drivers/net/wireless/realtek/rtlwifi/rtl8821ae/trx.h2
-rw-r--r--drivers/net/wireless/realtek/rtw88/tx.c7
-rw-r--r--drivers/net/wireless/realtek/rtw88/usb.c13
-rw-r--r--drivers/ntb/hw/epf/ntb_hw_epf.c3
-rw-r--r--drivers/pci/controller/dwc/pcie-qcom.c17
-rw-r--r--drivers/power/reset/linkstation-poweroff.c2
-rw-r--r--drivers/power/sequencing/core.c14
-rw-r--r--drivers/rpmsg/rpmsg_char.c15
-rw-r--r--drivers/tty/serial/8250/8250_dw.c4
-rw-r--r--drivers/video/fbdev/core/fbmem.c12
-rw-r--r--drivers/video/fbdev/core/fbsysfs.c10
-rw-r--r--drivers/video/fbdev/core/modedb.c5
25 files changed, 132 insertions, 45 deletions
diff --git a/drivers/crypto/nx/nx.c b/drivers/crypto/nx/nx.c
index 78135fb13f5c..1b7509e2ce44 100644
--- a/drivers/crypto/nx/nx.c
+++ b/drivers/crypto/nx/nx.c
@@ -714,15 +714,13 @@ int nx_crypto_ctx_aes_xcbc_init(struct crypto_shash *tfm)
/**
* nx_crypto_ctx_exit - destroy a crypto api context
*
- * @tfm: the crypto transform pointer for the context
+ * @nx_ctx: the crypto api context
*
* As crypto API contexts are destroyed, this exit hook is called to free the
* memory associated with it.
*/
-void nx_crypto_ctx_exit(struct crypto_tfm *tfm)
+void nx_crypto_ctx_exit(struct nx_crypto_ctx *nx_ctx)
{
- struct nx_crypto_ctx *nx_ctx = crypto_tfm_ctx(tfm);
-
kfree_sensitive(nx_ctx->kmem);
nx_ctx->csbcpb = NULL;
nx_ctx->csbcpb_aead = NULL;
diff --git a/drivers/crypto/nx/nx.h b/drivers/crypto/nx/nx.h
index 36974f08490a..6dfabfbf8192 100644
--- a/drivers/crypto/nx/nx.h
+++ b/drivers/crypto/nx/nx.h
@@ -153,7 +153,7 @@ int nx_crypto_ctx_aes_ctr_init(struct crypto_skcipher *tfm);
int nx_crypto_ctx_aes_cbc_init(struct crypto_skcipher *tfm);
int nx_crypto_ctx_aes_ecb_init(struct crypto_skcipher *tfm);
int nx_crypto_ctx_sha_init(struct crypto_shash *tfm);
-void nx_crypto_ctx_exit(struct crypto_tfm *tfm);
+void nx_crypto_ctx_exit(struct nx_crypto_ctx *nx_ctx);
void nx_crypto_ctx_skcipher_exit(struct crypto_skcipher *tfm);
void nx_crypto_ctx_aead_exit(struct crypto_aead *tfm);
void nx_crypto_ctx_shash_exit(struct crypto_shash *tfm);
diff --git a/drivers/fpga/of-fpga-region.c b/drivers/fpga/of-fpga-region.c
index caa091224dc5..9107a5b461d3 100644
--- a/drivers/fpga/of-fpga-region.c
+++ b/drivers/fpga/of-fpga-region.c
@@ -168,11 +168,10 @@ static int child_regions_with_firmware(struct device_node *overlay)
fpga_region_of_match);
}
- of_node_put(child_region);
-
if (ret)
pr_err("firmware-name not allowed in child FPGA region: %pOF",
child_region);
+ of_node_put(child_region);
return ret;
}
diff --git a/drivers/i2c/i2c-core-base.c b/drivers/i2c/i2c-core-base.c
index ae7e9c8b65a6..05b315405639 100644
--- a/drivers/i2c/i2c-core-base.c
+++ b/drivers/i2c/i2c-core-base.c
@@ -1570,6 +1570,10 @@ static int i2c_register_adapter(struct i2c_adapter *adap)
pm_suspend_ignore_children(&adap->dev, true);
pm_runtime_enable(&adap->dev);
+ mutex_lock(&core_lock);
+ idr_replace(&i2c_adapter_idr, adap, adap->nr);
+ mutex_unlock(&core_lock);
+
res = device_add(&adap->dev);
if (res) {
pr_err("adapter '%s': can't register device (%d)\n", adap->name, res);
@@ -1628,7 +1632,7 @@ static int __i2c_add_numbered_adapter(struct i2c_adapter *adap)
int id;
mutex_lock(&core_lock);
- id = idr_alloc(&i2c_adapter_idr, adap, adap->nr, adap->nr + 1, GFP_KERNEL);
+ id = idr_alloc(&i2c_adapter_idr, NULL, adap->nr, adap->nr + 1, GFP_KERNEL);
mutex_unlock(&core_lock);
if (WARN(id < 0, "couldn't get idr"))
return id == -ENOSPC ? -EBUSY : id;
@@ -1662,7 +1666,7 @@ int i2c_add_adapter(struct i2c_adapter *adapter)
}
mutex_lock(&core_lock);
- id = idr_alloc(&i2c_adapter_idr, adapter,
+ id = idr_alloc(&i2c_adapter_idr, NULL,
__i2c_first_dynamic_bus_num, 0, GFP_KERNEL);
mutex_unlock(&core_lock);
if (WARN(id < 0, "couldn't get idr"))
diff --git a/drivers/irqchip/irq-imgpdc.c b/drivers/irqchip/irq-imgpdc.c
index e9ef2f5a7207..4feef4ab5fec 100644
--- a/drivers/irqchip/irq-imgpdc.c
+++ b/drivers/irqchip/irq-imgpdc.c
@@ -378,6 +378,7 @@ static int pdc_intc_probe(struct platform_device *pdev)
dev_err(&pdev->dev, "cannot add IRQ domain\n");
return -ENOMEM;
}
+ priv->domain->flags |= IRQ_DOMAIN_FLAG_DESTROY_GC;
/*
* Set up 2 generic irq chips with 2 chip types.
@@ -465,6 +466,11 @@ static void pdc_intc_remove(struct platform_device *pdev)
{
struct pdc_intc_priv *priv = platform_get_drvdata(pdev);
+ for (unsigned int i = 0; i < priv->nr_perips; ++i)
+ irq_set_chained_handler_and_data(priv->perip_irqs[i], NULL, NULL);
+
+ irq_set_chained_handler_and_data(priv->syswake_irq, NULL, NULL);
+
irq_domain_remove(priv->domain);
}
diff --git a/drivers/net/wan/hdlc_ppp.c b/drivers/net/wan/hdlc_ppp.c
index 7496a2e9a282..22affdcb4cea 100644
--- a/drivers/net/wan/hdlc_ppp.c
+++ b/drivers/net/wan/hdlc_ppp.c
@@ -621,7 +621,6 @@ static void ppp_start(struct net_device *dev)
struct proto *proto = &ppp->protos[i];
proto->dev = dev;
- timer_setup(&proto->timer, ppp_timer, 0);
proto->state = CLOSED;
}
ppp->protos[IDX_LCP].pid = PID_LCP;
@@ -641,6 +640,15 @@ static void ppp_close(struct net_device *dev)
ppp_tx_flush();
}
+static void ppp_timer_release(struct net_device *dev)
+{
+ struct ppp *ppp = get_ppp(dev);
+ int i;
+
+ for (i = 0; i < IDX_COUNT; i++)
+ timer_shutdown_sync(&ppp->protos[i].timer);
+}
+
static struct hdlc_proto proto = {
.start = ppp_start,
.stop = ppp_stop,
@@ -649,6 +657,7 @@ static struct hdlc_proto proto = {
.ioctl = ppp_ioctl,
.netif_rx = ppp_rx,
.module = THIS_MODULE,
+ .detach = ppp_timer_release,
};
static const struct header_ops ppp_header_ops = {
@@ -659,7 +668,7 @@ static int ppp_ioctl(struct net_device *dev, struct if_settings *ifs)
{
hdlc_device *hdlc = dev_to_hdlc(dev);
struct ppp *ppp;
- int result;
+ int i, result;
switch (ifs->type) {
case IF_GET_PROTO:
@@ -687,6 +696,8 @@ static int ppp_ioctl(struct net_device *dev, struct if_settings *ifs)
return result;
ppp = get_ppp(dev);
+ for (i = 0; i < IDX_COUNT; i++)
+ timer_setup(&ppp->protos[i].timer, ppp_timer, 0);
spin_lock_init(&ppp->lock);
ppp->req_timeout = 2;
ppp->cr_retries = 10;
diff --git a/drivers/net/wireless/ath/ath11k/dp.c b/drivers/net/wireless/ath/ath11k/dp.c
index 56b1a657e0b0..68c7ef190780 100644
--- a/drivers/net/wireless/ath/ath11k/dp.c
+++ b/drivers/net/wireless/ath/ath11k/dp.c
@@ -1042,6 +1042,7 @@ void ath11k_dp_free(struct ath11k_base *ab)
idr_destroy(&dp->tx_ring[i].txbuf_idr);
spin_unlock_bh(&dp->tx_ring[i].tx_idr_lock);
kfree(dp->tx_ring[i].tx_status);
+ dp->tx_ring[i].tx_status = NULL;
}
/* Deinit any SOC level resource */
diff --git a/drivers/net/wireless/intel/iwlwifi/mld/agg.c b/drivers/net/wireless/intel/iwlwifi/mld/agg.c
index 3bf36f8f6874..e3627ad0321c 100644
--- a/drivers/net/wireless/intel/iwlwifi/mld/agg.c
+++ b/drivers/net/wireless/intel/iwlwifi/mld/agg.c
@@ -64,6 +64,9 @@ static void iwl_mld_release_frames_from_notif(struct iwl_mld *mld,
}
/* pick any STA ID to find the pointer */
+ if (WARN_ON_ONCE(!ba_data->sta_mask))
+ goto out_unlock;
+
sta_id = ffs(ba_data->sta_mask) - 1;
link_sta = rcu_dereference(mld->fw_id_to_link_sta[sta_id]);
if (WARN_ON_ONCE(IS_ERR_OR_NULL(link_sta) || !link_sta->sta))
@@ -166,6 +169,9 @@ void iwl_mld_del_ba(struct iwl_mld *mld, int queue,
goto out_unlock;
/* pick any STA ID to find the pointer */
+ if (WARN_ON_ONCE(!ba_data->sta_mask))
+ goto out_unlock;
+
sta_id = ffs(ba_data->sta_mask) - 1;
link_sta = rcu_dereference(mld->fw_id_to_link_sta[sta_id]);
if (WARN_ON_ONCE(IS_ERR_OR_NULL(link_sta) || !link_sta->sta))
@@ -347,6 +353,9 @@ static void iwl_mld_rx_agg_session_expired(struct timer_list *t)
}
/* timer expired, pick any STA ID to find the pointer */
+ if (WARN_ON_ONCE(!ba_data->sta_mask))
+ goto unlock;
+
sta_id = ffs(ba_data->sta_mask) - 1;
link_sta = rcu_dereference(ba_data->mld->fw_id_to_link_sta[sta_id]);
diff --git a/drivers/net/wireless/intel/iwlwifi/mld/ptp.c b/drivers/net/wireless/intel/iwlwifi/mld/ptp.c
index 231920425c06..b40182320801 100644
--- a/drivers/net/wireless/intel/iwlwifi/mld/ptp.c
+++ b/drivers/net/wireless/intel/iwlwifi/mld/ptp.c
@@ -319,10 +319,10 @@ void iwl_mld_ptp_remove(struct iwl_mld *mld)
mld->ptp_data.ptp_clock_info.name,
ptp_clock_index(mld->ptp_data.ptp_clock));
+ cancel_delayed_work_sync(&mld->ptp_data.dwork);
ptp_clock_unregister(mld->ptp_data.ptp_clock);
mld->ptp_data.ptp_clock = NULL;
mld->ptp_data.last_gp2 = 0;
mld->ptp_data.wrap_counter = 0;
- cancel_delayed_work_sync(&mld->ptp_data.dwork);
}
}
diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/ptp.c b/drivers/net/wireless/intel/iwlwifi/mvm/ptp.c
index ad156b82eaa9..efb291ceb0e5 100644
--- a/drivers/net/wireless/intel/iwlwifi/mvm/ptp.c
+++ b/drivers/net/wireless/intel/iwlwifi/mvm/ptp.c
@@ -323,11 +323,11 @@ void iwl_mvm_ptp_remove(struct iwl_mvm *mvm)
mvm->ptp_data.ptp_clock_info.name,
ptp_clock_index(mvm->ptp_data.ptp_clock));
+ cancel_delayed_work_sync(&mvm->ptp_data.dwork);
ptp_clock_unregister(mvm->ptp_data.ptp_clock);
mvm->ptp_data.ptp_clock = NULL;
memset(&mvm->ptp_data.ptp_clock_info, 0,
sizeof(mvm->ptp_data.ptp_clock_info));
mvm->ptp_data.last_gp2 = 0;
- cancel_delayed_work_sync(&mvm->ptp_data.dwork);
}
}
diff --git a/drivers/net/wireless/mediatek/mt76/mac80211.c b/drivers/net/wireless/mediatek/mt76/mac80211.c
index 76eb740428b8..2d24f9fa51a5 100644
--- a/drivers/net/wireless/mediatek/mt76/mac80211.c
+++ b/drivers/net/wireless/mediatek/mt76/mac80211.c
@@ -1568,6 +1568,7 @@ mt76_sta_add(struct mt76_phy *phy, struct ieee80211_vif *vif,
{
struct mt76_wcid *wcid = (struct mt76_wcid *)sta->drv_priv;
struct mt76_dev *dev = phy->dev;
+ struct mt76_wcid *published;
int ret;
int i;
@@ -1587,11 +1588,19 @@ mt76_sta_add(struct mt76_phy *phy, struct ieee80211_vif *vif,
mtxq->wcid = wcid->idx;
}
- ewma_signal_init(&wcid->rssi);
- rcu_assign_pointer(dev->wcid[wcid->idx], wcid);
+ published = rcu_dereference_protected(dev->wcid[wcid->idx],
+ lockdep_is_held(&dev->mutex));
+ if (published != wcid) {
+ WARN_ON_ONCE(published);
+ ewma_signal_init(&wcid->rssi);
+ rcu_assign_pointer(dev->wcid[wcid->idx], wcid);
+ mt76_wcid_init(wcid, phy->band_idx);
+ } else {
+ wcid->phy_idx = phy->band_idx;
+ }
+
phy->num_sta++;
- mt76_wcid_init(wcid, phy->band_idx);
out:
mutex_unlock(&dev->mutex);
diff --git a/drivers/net/wireless/mediatek/mt76/mt76x2/usb.c b/drivers/net/wireless/mediatek/mt76/mt76x2/usb.c
index 96cecc576a98..427b294423d3 100644
--- a/drivers/net/wireless/mediatek/mt76/mt76x2/usb.c
+++ b/drivers/net/wireless/mediatek/mt76/mt76x2/usb.c
@@ -16,6 +16,7 @@ static const struct usb_device_id mt76x2u_device_table[] = {
{ USB_DEVICE(0x0e8d, 0x7612) }, /* Aukey USBAC1200 - Alfa AWUS036ACM */
{ USB_DEVICE(0x057c, 0x8503) }, /* Avm FRITZ!WLAN AC860 */
{ USB_DEVICE(0x7392, 0xb711) }, /* Edimax EW 7722 UAC */
+ { USB_DEVICE(0x056e, 0x400a) }, /* ELECOM WDC-867SU3S */
{ USB_DEVICE(0x0e8d, 0x7632) }, /* HC-M7662BU1 */
{ USB_DEVICE(0x0471, 0x2126) }, /* LiteOn WN4516R module, nonstandard USB connector */
{ USB_DEVICE(0x0471, 0x7600) }, /* LiteOn WN4519R module, nonstandard USB connector */
diff --git a/drivers/net/wireless/mediatek/mt76/mt7925/main.c b/drivers/net/wireless/mediatek/mt76/mt7925/main.c
index 00126f563dfd..9a8ef3449eea 100644
--- a/drivers/net/wireless/mediatek/mt76/mt7925/main.c
+++ b/drivers/net/wireless/mediatek/mt76/mt7925/main.c
@@ -1144,6 +1144,9 @@ mt7925_mac_sta_remove_links(struct mt792x_dev *dev, struct ieee80211_vif *vif,
if (vif->type == NL80211_IFTYPE_AP)
break;
+ if (vif->type == NL80211_IFTYPE_STATION && sta->tdls)
+ continue;
+
link_sta = mt792x_sta_to_link_sta(vif, sta, link_id);
if (!link_sta)
continue;
diff --git a/drivers/net/wireless/realtek/rtlwifi/rtl8821ae/trx.h b/drivers/net/wireless/realtek/rtlwifi/rtl8821ae/trx.h
index 1155365348f3..d5de09d75f45 100644
--- a/drivers/net/wireless/realtek/rtlwifi/rtl8821ae/trx.h
+++ b/drivers/net/wireless/realtek/rtlwifi/rtl8821ae/trx.h
@@ -291,7 +291,7 @@ static inline int get_rx_desc_paggr(__le32 *__pdesc)
static inline int get_rx_status_desc_rpt_sel(__le32 *__pdesc)
{
- return le32_get_bits(*(__pdesc + 1), BIT(28));
+ return le32_get_bits(*(__pdesc + 2), BIT(28));
}
static inline int get_rx_desc_rxmcs(__le32 *__pdesc)
diff --git a/drivers/net/wireless/realtek/rtw88/tx.c b/drivers/net/wireless/realtek/rtw88/tx.c
index 2ab440cb2d67..9e24741b2cb1 100644
--- a/drivers/net/wireless/realtek/rtw88/tx.c
+++ b/drivers/net/wireless/realtek/rtw88/tx.c
@@ -196,6 +196,7 @@ void rtw_tx_report_purge_timer(struct timer_list *t)
void rtw_tx_report_enqueue(struct rtw_dev *rtwdev, struct sk_buff *skb, u8 sn)
{
struct rtw_tx_report *tx_report = &rtwdev->tx_report;
+ unsigned long timeout = RTW_TX_PROBE_TIMEOUT;
unsigned long flags;
u8 *drv_data;
@@ -207,7 +208,11 @@ void rtw_tx_report_enqueue(struct rtw_dev *rtwdev, struct sk_buff *skb, u8 sn)
__skb_queue_tail(&tx_report->queue, skb);
spin_unlock_irqrestore(&tx_report->q_lock, flags);
- mod_timer(&tx_report->purge_timer, jiffies + RTW_TX_PROBE_TIMEOUT);
+ if (rtwdev->chip->id == RTW_CHIP_TYPE_8723D &&
+ rtwdev->hci.type == RTW_HCI_TYPE_USB)
+ timeout = msecs_to_jiffies(2500);
+
+ mod_timer(&tx_report->purge_timer, jiffies + timeout);
}
EXPORT_SYMBOL(rtw_tx_report_enqueue);
diff --git a/drivers/net/wireless/realtek/rtw88/usb.c b/drivers/net/wireless/realtek/rtw88/usb.c
index 6e841a11c752..c7f723c08433 100644
--- a/drivers/net/wireless/realtek/rtw88/usb.c
+++ b/drivers/net/wireless/realtek/rtw88/usb.c
@@ -399,6 +399,7 @@ static bool rtw_usb_tx_agg_skb(struct rtw_usb *rtwusb, struct sk_buff_head *list
int agg_num = 0;
unsigned int align_next = 0;
u8 qsel;
+ int ret;
if (skb_queue_empty(list))
return false;
@@ -456,7 +457,13 @@ queue:
tx_desc = (struct rtw_tx_desc *)skb_head->data;
qsel = le32_get_bits(tx_desc->w1, RTW_TX_DESC_W1_QSEL);
- rtw_usb_write_port(rtwdev, qsel, skb_head, rtw_usb_write_port_tx_complete, txcb);
+ ret = rtw_usb_write_port(rtwdev, qsel, skb_head,
+ rtw_usb_write_port_tx_complete, txcb);
+ if (ret) {
+ ieee80211_purge_tx_queue(rtwdev->hw, &txcb->tx_ack_queue);
+ kfree(txcb);
+ return false;
+ }
return true;
}
@@ -518,8 +525,10 @@ static int rtw_usb_write_data(struct rtw_dev *rtwdev,
ret = rtw_usb_write_port(rtwdev, qsel, skb,
rtw_usb_write_port_complete, skb);
- if (unlikely(ret))
+ if (unlikely(ret)) {
rtw_err(rtwdev, "failed to do USB write, ret=%d\n", ret);
+ dev_kfree_skb_any(skb);
+ }
return ret;
}
diff --git a/drivers/ntb/hw/epf/ntb_hw_epf.c b/drivers/ntb/hw/epf/ntb_hw_epf.c
index d3ecf25a5162..9935da48a52e 100644
--- a/drivers/ntb/hw/epf/ntb_hw_epf.c
+++ b/drivers/ntb/hw/epf/ntb_hw_epf.c
@@ -646,7 +646,8 @@ static void ntb_epf_deinit_pci(struct ntb_epf_dev *ndev)
struct pci_dev *pdev = ndev->ntb.pdev;
pci_iounmap(pdev, ndev->ctrl_reg);
- pci_iounmap(pdev, ndev->peer_spad_reg);
+ if (ndev->barno_map[BAR_PEER_SPAD] != ndev->barno_map[BAR_CONFIG])
+ pci_iounmap(pdev, ndev->peer_spad_reg);
pci_iounmap(pdev, ndev->db_reg);
pci_release_regions(pdev);
diff --git a/drivers/pci/controller/dwc/pcie-qcom.c b/drivers/pci/controller/dwc/pcie-qcom.c
index 43555ad9e5dc..789cc0e3c10d 100644
--- a/drivers/pci/controller/dwc/pcie-qcom.c
+++ b/drivers/pci/controller/dwc/pcie-qcom.c
@@ -341,20 +341,15 @@ static void qcom_pcie_clear_aspm_l0s(struct dw_pcie *pci)
dw_pcie_dbi_ro_wr_dis(pci);
}
-static void qcom_pcie_set_slot_nccs(struct dw_pcie *pci)
+static void qcom_pcie_clear_hpc(struct dw_pcie *pci)
{
u16 offset = dw_pcie_find_capability(pci, PCI_CAP_ID_EXP);
u32 val;
dw_pcie_dbi_ro_wr_en(pci);
- /*
- * Qcom PCIe Root Ports do not support generating command completion
- * notifications for the Hot-Plug commands. So set the NCCS field to
- * avoid waiting for the completions.
- */
val = readl(pci->dbi_base + offset + PCI_EXP_SLTCAP);
- val |= PCI_EXP_SLTCAP_NCCS;
+ val &= ~PCI_EXP_SLTCAP_HPC;
writel(val, pci->dbi_base + offset + PCI_EXP_SLTCAP);
dw_pcie_dbi_ro_wr_dis(pci);
@@ -554,7 +549,7 @@ static int qcom_pcie_post_init_2_1_0(struct qcom_pcie *pcie)
writel(CFG_BRIDGE_SB_INIT,
pci->dbi_base + AXI_MSTR_RESP_COMP_CTRL1);
- qcom_pcie_set_slot_nccs(pcie->pci);
+ qcom_pcie_clear_hpc(pcie->pci);
return 0;
}
@@ -634,7 +629,7 @@ static int qcom_pcie_post_init_1_0_0(struct qcom_pcie *pcie)
writel(val, pcie->parf + PARF_AXI_MSTR_WR_ADDR_HALT);
}
- qcom_pcie_set_slot_nccs(pcie->pci);
+ qcom_pcie_clear_hpc(pcie->pci);
return 0;
}
@@ -727,7 +722,7 @@ static int qcom_pcie_post_init_2_3_2(struct qcom_pcie *pcie)
val |= EN;
writel(val, pcie->parf + PARF_AXI_MSTR_WR_ADDR_HALT_V2);
- qcom_pcie_set_slot_nccs(pcie->pci);
+ qcom_pcie_clear_hpc(pcie->pci);
return 0;
}
@@ -1033,7 +1028,7 @@ static int qcom_pcie_post_init_2_7_0(struct qcom_pcie *pcie)
writel(WR_NO_SNOOP_OVERRIDE_EN | RD_NO_SNOOP_OVERRIDE_EN,
pcie->parf + PARF_NO_SNOOP_OVERRIDE);
- qcom_pcie_set_slot_nccs(pcie->pci);
+ qcom_pcie_clear_hpc(pcie->pci);
return 0;
}
diff --git a/drivers/power/reset/linkstation-poweroff.c b/drivers/power/reset/linkstation-poweroff.c
index 02f5fdb8ffc4..e56d75bfcc43 100644
--- a/drivers/power/reset/linkstation-poweroff.c
+++ b/drivers/power/reset/linkstation-poweroff.c
@@ -163,10 +163,10 @@ static int __init linkstation_poweroff_init(void)
dn = of_find_matching_node(NULL, ls_poweroff_of_match);
if (!dn)
return -ENODEV;
- of_node_put(dn);
match = of_match_node(ls_poweroff_of_match, dn);
cfg = match->data;
+ of_node_put(dn);
dn = of_find_node_by_name(NULL, cfg->mdio_node_name);
if (!dn)
diff --git a/drivers/power/sequencing/core.c b/drivers/power/sequencing/core.c
index 1fcf0af7cc0b..d5da006e1ee8 100644
--- a/drivers/power/sequencing/core.c
+++ b/drivers/power/sequencing/core.c
@@ -990,8 +990,9 @@ static void *pwrseq_debugfs_seq_start(struct seq_file *seq, loff_t *pos)
ctx.index = *pos;
/*
- * We're holding the lock for the entire printout so no need to fiddle
- * with device reference count.
+ * Hold the lock for the entire printout to prevent device removal.
+ * Reference counts are managed by start()/next()/stop() as required
+ * by the seq_file contract.
*/
down_read(&pwrseq_sem);
@@ -999,7 +1000,7 @@ static void *pwrseq_debugfs_seq_start(struct seq_file *seq, loff_t *pos)
if (!ctx.index)
return NULL;
- return ctx.dev;
+ return get_device(ctx.dev);
}
static void *pwrseq_debugfs_seq_next(struct seq_file *seq, void *data,
@@ -1009,8 +1010,9 @@ static void *pwrseq_debugfs_seq_next(struct seq_file *seq, void *data,
++*pos;
- struct device *next __free(put_device) =
- bus_find_next_device(&pwrseq_bus, curr);
+ struct device *next = bus_find_next_device(&pwrseq_bus, curr);
+
+ put_device(curr);
return next;
}
@@ -1059,6 +1061,8 @@ static int pwrseq_debugfs_seq_show(struct seq_file *seq, void *data)
static void pwrseq_debugfs_seq_stop(struct seq_file *seq, void *data)
{
+ if (data)
+ put_device(data);
up_read(&pwrseq_sem);
}
diff --git a/drivers/rpmsg/rpmsg_char.c b/drivers/rpmsg/rpmsg_char.c
index 96fcdd2d7093..d918cb30db9b 100644
--- a/drivers/rpmsg/rpmsg_char.c
+++ b/drivers/rpmsg/rpmsg_char.c
@@ -104,6 +104,9 @@ static int rpmsg_ept_cb(struct rpmsg_device *rpdev, void *buf, int len,
struct rpmsg_eptdev *eptdev = priv;
struct sk_buff *skb;
+ if (!eptdev)
+ return 0;
+
skb = alloc_skb(len, GFP_ATOMIC);
if (!skb)
return -ENOMEM;
@@ -124,6 +127,9 @@ static int rpmsg_ept_flow_cb(struct rpmsg_device *rpdev, void *priv, bool enable
{
struct rpmsg_eptdev *eptdev = priv;
+ if (!eptdev)
+ return 0;
+
eptdev->remote_flow_restricted = enable;
eptdev->remote_flow_updated = true;
@@ -490,6 +496,7 @@ static int rpmsg_chrdev_probe(struct rpmsg_device *rpdev)
struct rpmsg_channel_info chinfo;
struct rpmsg_eptdev *eptdev;
struct device *dev = &rpdev->dev;
+ int ret;
memcpy(chinfo.name, rpdev->id.name, RPMSG_NAME_SIZE);
chinfo.src = rpdev->src;
@@ -502,13 +509,17 @@ static int rpmsg_chrdev_probe(struct rpmsg_device *rpdev)
/* Set the default_ept to the rpmsg device endpoint */
eptdev->default_ept = rpdev->ept;
+ ret = rpmsg_chrdev_eptdev_add(eptdev, chinfo);
+
+ if (ret)
+ return ret;
/*
* The rpmsg_ept_cb uses *priv parameter to get its rpmsg_eptdev context.
- * Storedit in default_ept *priv field.
+ * Stored it in default_ept *priv field.
*/
eptdev->default_ept->priv = eptdev;
- return rpmsg_chrdev_eptdev_add(eptdev, chinfo);
+ return 0;
}
static void rpmsg_chrdev_remove(struct rpmsg_device *rpdev)
diff --git a/drivers/tty/serial/8250/8250_dw.c b/drivers/tty/serial/8250/8250_dw.c
index 4103178725e3..7a0008363543 100644
--- a/drivers/tty/serial/8250/8250_dw.c
+++ b/drivers/tty/serial/8250/8250_dw.c
@@ -846,8 +846,10 @@ static int dw8250_probe(struct platform_device *pdev)
*/
if (data->clk) {
err = clk_notifier_register(data->clk, &data->clk_notifier);
- if (err)
+ if (err) {
+ serial8250_unregister_port(data->data.line);
return dev_err_probe(dev, err, "Failed to set the clock notifier\n");
+ }
queue_work(system_unbound_wq, &data->clk_work);
}
diff --git a/drivers/video/fbdev/core/fbmem.c b/drivers/video/fbdev/core/fbmem.c
index eff757ebbed1..30a2c0d47e5c 100644
--- a/drivers/video/fbdev/core/fbmem.c
+++ b/drivers/video/fbdev/core/fbmem.c
@@ -734,6 +734,18 @@ int fb_new_modelist(struct fb_info *info)
if (list_empty(&info->modelist))
return 1;
+ /*
+ * The new modelist may not contain the current mode (info->var), and
+ * fbcon_new_modelist() below only re-points consoles mapped to this
+ * framebuffer. Add the current mode here so info->var keeps a match
+ * even when fbcon is unbound.
+ */
+ if (!fb_match_mode(&info->var, &info->modelist)) {
+ fb_var_to_videomode(&mode, &info->var);
+ if (fb_add_videomode(&mode, &info->modelist))
+ return 1;
+ }
+
fbcon_new_modelist(info);
return 0;
diff --git a/drivers/video/fbdev/core/fbsysfs.c b/drivers/video/fbdev/core/fbsysfs.c
index baa2bae0fb5b..fe8bd33e64ab 100644
--- a/drivers/video/fbdev/core/fbsysfs.c
+++ b/drivers/video/fbdev/core/fbsysfs.c
@@ -11,6 +11,7 @@
#include <linux/major.h>
#include "fb_internal.h"
+#include "fbcon.h"
static int activate(struct fb_info *fb_info, struct fb_var_screeninfo *var)
{
@@ -111,8 +112,15 @@ static ssize_t store_modes(struct device *device,
if (fb_new_modelist(fb_info)) {
fb_destroy_modelist(&fb_info->modelist);
list_splice(&old_list, &fb_info->modelist);
- } else
+ } else {
+ /*
+ * fb_display[i].mode and fb_info->mode both point into the old
+ * list. Clear them before it is freed.
+ */
+ fbcon_delete_modelist(&old_list);
+ fb_info->mode = NULL;
fb_destroy_modelist(&old_list);
+ }
unlock_fb_info(fb_info);
console_unlock();
diff --git a/drivers/video/fbdev/core/modedb.c b/drivers/video/fbdev/core/modedb.c
index 53a610948c4a..0b1f3c5bbcdb 100644
--- a/drivers/video/fbdev/core/modedb.c
+++ b/drivers/video/fbdev/core/modedb.c
@@ -259,7 +259,7 @@ static const struct fb_videomode modedb[] = {
FB_VMODE_DOUBLE },
/* 1920x1080 @ 60 Hz, 67.3 kHz hsync */
- { NULL, 60, 1920, 1080, 6734, 148, 88, 36, 4, 44, 5, 0,
+ { NULL, 60, 1920, 1080, 6734, 148, 88, 36, 4, 44, 5,
FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT,
FB_VMODE_NONINTERLACED },
@@ -626,7 +626,7 @@ int fb_find_mode(struct fb_var_screeninfo *var,
const struct fb_videomode *default_mode,
unsigned int default_bpp)
{
- char *mode_option_buf = NULL;
+ char *mode_option_buf __free(kfree) = NULL;
int i;
/* Set up defaults */
@@ -724,7 +724,6 @@ int fb_find_mode(struct fb_var_screeninfo *var,
res_specified = 1;
}
done:
- kfree(mode_option_buf);
if (cvt) {
struct fb_videomode cvt_mode;
int ret;