summaryrefslogtreecommitdiff
path: root/include/linux
diff options
context:
space:
mode:
authorMark Brown <broonie@kernel.org>2026-07-21 19:18:39 +0100
committerMark Brown <broonie@kernel.org>2026-07-21 19:18:39 +0100
commit18a44e70450a22d479c5ccce33dffa8a65bf30d9 (patch)
treedc719c67eee6bc6e2500cdd21ae22e8b1200d45c /include/linux
parent38a44861771ed1aa2eac9535fbc98bd7815b672f (diff)
parent15c9fdb3c39d5073463ffa746cc64ad9682c875f (diff)
ALSA: hda: Add AW88399 HDA side codec driver for Lenovo Legion
Marco Giunta <marco_giunta@outlook.it> says: Several Lenovo Legion laptops (Pro 7i 16IAX10H, Y9000P IAX10, Pro 7 16AFR10H, R9000P ADR10) use AWINIC AW88399 smart amplifiers to drive their bass woofers, connected via I2C as side codecs to a Realtek ALC287 HDA codec. Without a driver for these amplifiers, only the tweeters produce sound, resulting in quiet and tinny audio. An ASoC driver for the AW88399 already exists in-tree (sound/soc/codecs/aw88399.c), contributed by AWINIC, but it targets ASoC topologies and cannot drive the chip when it sits behind an HDA controller. This series adds a proper HDA side codec driver, following the established pattern used by the CS35L41, CS35L56, and TAS2781 drivers. Patch 1 extracts the device-level functions from the existing ASoC driver into a shared library module (SND_SOC_AW88399_LIB) with a shared header at include/sound/aw88399.h, following the CS35L41 precedent (SND_SOC_CS35L41_LIB / include/sound/cs35l41.h). This avoids a build-time dependency on the full ASoC codec module and ensures clean separation between the ASoC and HDA drivers. Patches 2 through 5 prepare the shared library for use on ACPI-based HDA systems: patch 2 extends channel assignment to work without Device Tree properties, patch 3 adds a per-instance flag to bypass an unreliable hardware status bit on certain boards, patch 4 adds a firmware reload flag so that the HDA driver can signal that DSP firmware needs to be re-uploaded after system sleep, and patch 5 adds a channel setter so that the HDA driver can configure the amplifier without depending on ASoC-internal device headers. NOTE ON FIRMWARE: This driver requires the firmware file aw88399_acf.bin, which uses the same format and request path as the existing ASoC driver. This firmware is not yet available in the linux-firmware repository. We intend to coordinate with the AWINIC maintainers (CC'd) to arrange its inclusion. In the meantime, users can extract the firmware from the Windows driver and place it in /lib/firmware/. This work builds on the initial driver development by Yakov Till ("Lyapsus") and the bounty effort organized by Nadim Kobeissi: https://github.com/nadimkobeissi/16iax10h-linux-sound-saga Link: https://patch.msgid.link/DS7PR19MB77247D9AD698CF0FF37DB58BFCC62@DS7PR19MB7724.namprd19.prod.outlook.com
Diffstat (limited to 'include/linux')
-rw-r--r--include/linux/arm_ffa.h9
-rw-r--r--include/linux/btf.h1
-rw-r--r--include/linux/can/dev/peak_canfd.h2
-rw-r--r--include/linux/ieee80211-eht.h12
-rw-r--r--include/linux/skmsg.h14
5 files changed, 14 insertions, 24 deletions
diff --git a/include/linux/arm_ffa.h b/include/linux/arm_ffa.h
index 17eca3dfc59e..e71d83ee0aef 100644
--- a/include/linux/arm_ffa.h
+++ b/include/linux/arm_ffa.h
@@ -421,6 +421,13 @@ struct ffa_mem_region {
#define FFA_EMAD_HAS_IMPDEF_FIELD(version) ((version) >= FFA_VERSION_1_2)
#define FFA_MEM_REGION_HAS_EP_MEM_OFFSET(version) ((version) > FFA_VERSION_1_0)
+/* The layout changed from FFA_VERSION_1_0 and the region includes an
+ * ep_mem_offset.
+ */
+#define FFA_MEM_REGION_SZ(version) (!FFA_MEM_REGION_HAS_EP_MEM_OFFSET((version)) ?\
+ offsetof(struct ffa_mem_region, ep_mem_offset) :\
+ sizeof(struct ffa_mem_region))
+
static inline u32 ffa_emad_size_get(u32 ffa_version)
{
u32 sz;
@@ -445,7 +452,7 @@ ffa_mem_desc_offset(struct ffa_mem_region *buf, int count, u32 ffa_version)
if (!FFA_MEM_REGION_HAS_EP_MEM_OFFSET(ffa_version))
offset += offsetof(struct ffa_mem_region, ep_mem_offset);
else
- offset += sizeof(struct ffa_mem_region);
+ offset += buf->ep_mem_offset;
return offset;
}
diff --git a/include/linux/btf.h b/include/linux/btf.h
index 240401d9b25b..c09b7994de4e 100644
--- a/include/linux/btf.h
+++ b/include/linux/btf.h
@@ -578,6 +578,7 @@ const char *btf_str_by_offset(const struct btf *btf, u32 offset);
struct btf *btf_parse_vmlinux(void);
struct btf *bpf_prog_get_target_btf(const struct bpf_prog *prog);
u32 *btf_kfunc_flags(const struct btf *btf, u32 kfunc_btf_id, const struct bpf_prog *prog);
+int btf_kfunc_check_flag(const struct btf *btf, u32 kfunc_btf_id, u32 flag);
bool btf_kfunc_is_allowed(const struct btf *btf, u32 kfunc_btf_id, const struct bpf_prog *prog);
u32 *btf_kfunc_is_modify_return(const struct btf *btf, u32 kfunc_btf_id,
const struct bpf_prog *prog);
diff --git a/include/linux/can/dev/peak_canfd.h b/include/linux/can/dev/peak_canfd.h
index d3788a3d0942..056e0efa649f 100644
--- a/include/linux/can/dev/peak_canfd.h
+++ b/include/linux/can/dev/peak_canfd.h
@@ -3,7 +3,7 @@
* CAN driver for PEAK System micro-CAN based adapters
*
* Copyright (C) 2003-2025 PEAK System-Technik GmbH
- * Author: Stéphane Grosjean <stephane.grosjean@hms-networks.com>
+ * Author: Stéphane Grosjean <s.grosjean@peak-system.fr>
*/
#ifndef PUCAN_H
#define PUCAN_H
diff --git a/include/linux/ieee80211-eht.h b/include/linux/ieee80211-eht.h
index 18f9c662cf4c..c109722b1969 100644
--- a/include/linux/ieee80211-eht.h
+++ b/include/linux/ieee80211-eht.h
@@ -857,7 +857,7 @@ static inline bool ieee80211_mle_size_ok(const u8 *data, size_t len)
const struct ieee80211_multi_link_elem *mle = (const void *)data;
u8 fixed = sizeof(*mle);
u8 common = 0;
- bool check_common_len = false;
+ u8 common_len;
u16 control;
if (!data || len < fixed)
@@ -868,7 +868,6 @@ static inline bool ieee80211_mle_size_ok(const u8 *data, size_t len)
switch (u16_get_bits(control, IEEE80211_ML_CONTROL_TYPE)) {
case IEEE80211_ML_CONTROL_TYPE_BASIC:
common += sizeof(struct ieee80211_mle_basic_common_info);
- check_common_len = true;
if (control & IEEE80211_MLC_BASIC_PRES_LINK_ID)
common += 1;
if (control & IEEE80211_MLC_BASIC_PRES_BSS_PARAM_CH_CNT)
@@ -888,9 +887,9 @@ static inline bool ieee80211_mle_size_ok(const u8 *data, size_t len)
common += sizeof(struct ieee80211_mle_preq_common_info);
if (control & IEEE80211_MLC_PREQ_PRES_MLD_ID)
common += 1;
- check_common_len = true;
break;
case IEEE80211_ML_CONTROL_TYPE_RECONF:
+ common += 1;
if (control & IEEE80211_MLC_RECONF_PRES_MLD_MAC_ADDR)
common += ETH_ALEN;
if (control & IEEE80211_MLC_RECONF_PRES_EML_CAPA)
@@ -902,7 +901,6 @@ static inline bool ieee80211_mle_size_ok(const u8 *data, size_t len)
break;
case IEEE80211_ML_CONTROL_TYPE_TDLS:
common += sizeof(struct ieee80211_mle_tdls_common_info);
- check_common_len = true;
break;
case IEEE80211_ML_CONTROL_TYPE_PRIO_ACCESS:
common = ETH_ALEN + 1;
@@ -915,11 +913,9 @@ static inline bool ieee80211_mle_size_ok(const u8 *data, size_t len)
if (len < fixed + common)
return false;
- if (!check_common_len)
- return true;
+ common_len = mle->variable[0];
- /* if present, common length is the first octet there */
- return mle->variable[0] >= common;
+ return common_len >= common && common_len <= len - fixed;
}
/**
diff --git a/include/linux/skmsg.h b/include/linux/skmsg.h
index a8553401b1c9..d5e35f24738d 100644
--- a/include/linux/skmsg.h
+++ b/include/linux/skmsg.h
@@ -551,20 +551,6 @@ static inline void psock_progs_drop(struct sk_psock_progs *progs)
psock_set_prog(&progs->skb_verdict, NULL);
}
-/* for tcp only, sk is locked */
-static inline ssize_t sk_psock_msg_inq(struct sock *sk)
-{
- struct sk_psock *psock;
- ssize_t inq = 0;
-
- psock = sk_psock_get(sk);
- if (likely(psock)) {
- inq = sk_psock_get_msg_len_nolock(psock);
- sk_psock_put(sk, psock);
- }
- return inq;
-}
-
/* for udp only, sk is not locked */
static inline ssize_t sk_msg_first_len(struct sock *sk)
{