From 67197631871c33de20ac3b42a360ed2158dc8677 Mon Sep 17 00:00:00 2001 From: Ruslan Bilovol Date: Mon, 1 Mar 2021 13:49:35 +0200 Subject: [PATCH 01/91] UPSTREAM: usb: gadget: f_uac1: disable IN/OUT ep if unused User can configure f_uac1 function via p_chmask/c_chmask whether uac1 shall support playback and/or capture, but it has only effect on the created ALSA device, but not on the USB descriptor. This patch adds playback/capture descriptors dependent on that parameter. It is similar to the same conversion done earlier for f_uac2 Signed-off-by: Ruslan Bilovol Link: https://lore.kernel.org/r/1614599375-8803-6-git-send-email-ruslan.bilovol@gmail.com Signed-off-by: Greg Kroah-Hartman Bug: 235196743 (cherry picked from commit 254cb1e0d78cfa2c189171cacb88fc85d915bc84) Change-Id: I02328b9c496645e487ad9eb4784e9a4ac80c85f9 Signed-off-by: Luiz Matheus --- drivers/usb/gadget/function/f_uac1.c | 229 +++++++++++++++++++-------- 1 file changed, 163 insertions(+), 66 deletions(-) diff --git a/drivers/usb/gadget/function/f_uac1.c b/drivers/usb/gadget/function/f_uac1.c index e65f474ad7b3..d04707580068 100644 --- a/drivers/usb/gadget/function/f_uac1.c +++ b/drivers/usb/gadget/function/f_uac1.c @@ -22,6 +22,9 @@ /* UAC1 spec: 3.7.2.3 Audio Channel Cluster Format */ #define UAC1_CHANNEL_MASK 0x0FFF +#define EPIN_EN(_opts) ((_opts)->p_chmask != 0) +#define EPOUT_EN(_opts) ((_opts)->c_chmask != 0) + struct f_uac1 { struct g_audio g_audio; u8 ac_intf, as_in_intf, as_out_intf; @@ -50,11 +53,6 @@ static inline struct f_uac1_opts *g_audio_to_uac1_opts(struct g_audio *audio) * USB-OUT -> IT_1 -> OT_2 -> ALSA_Capture * ALSA_Playback -> IT_3 -> OT_4 -> USB-IN */ -#define F_AUDIO_AC_INTERFACE 0 -#define F_AUDIO_AS_OUT_INTERFACE 1 -#define F_AUDIO_AS_IN_INTERFACE 2 -/* Number of streaming interfaces */ -#define F_AUDIO_NUM_INTERFACES 2 /* B.3.1 Standard AC Interface Descriptor */ static struct usb_interface_descriptor ac_interface_desc = { @@ -65,73 +63,47 @@ static struct usb_interface_descriptor ac_interface_desc = { .bInterfaceSubClass = USB_SUBCLASS_AUDIOCONTROL, }; -/* - * The number of AudioStreaming and MIDIStreaming interfaces - * in the Audio Interface Collection - */ -DECLARE_UAC_AC_HEADER_DESCRIPTOR(2); - -#define UAC_DT_AC_HEADER_LENGTH UAC_DT_AC_HEADER_SIZE(F_AUDIO_NUM_INTERFACES) -/* 2 input terminals and 2 output terminals */ -#define UAC_DT_TOTAL_LENGTH (UAC_DT_AC_HEADER_LENGTH \ - + 2*UAC_DT_INPUT_TERMINAL_SIZE + 2*UAC_DT_OUTPUT_TERMINAL_SIZE) /* B.3.2 Class-Specific AC Interface Descriptor */ -static struct uac1_ac_header_descriptor_2 ac_header_desc = { - .bLength = UAC_DT_AC_HEADER_LENGTH, - .bDescriptorType = USB_DT_CS_INTERFACE, - .bDescriptorSubtype = UAC_HEADER, - .bcdADC = cpu_to_le16(0x0100), - .wTotalLength = cpu_to_le16(UAC_DT_TOTAL_LENGTH), - .bInCollection = F_AUDIO_NUM_INTERFACES, - .baInterfaceNr = { - /* Interface number of the AudioStream interfaces */ - [0] = 1, - [1] = 2, - } -}; +static struct uac1_ac_header_descriptor *ac_header_desc; -#define USB_OUT_IT_ID 1 static struct uac_input_terminal_descriptor usb_out_it_desc = { .bLength = UAC_DT_INPUT_TERMINAL_SIZE, .bDescriptorType = USB_DT_CS_INTERFACE, .bDescriptorSubtype = UAC_INPUT_TERMINAL, - .bTerminalID = USB_OUT_IT_ID, + /* .bTerminalID = DYNAMIC */ .wTerminalType = cpu_to_le16(UAC_TERMINAL_STREAMING), .bAssocTerminal = 0, .wChannelConfig = cpu_to_le16(0x3), }; -#define IO_OUT_OT_ID 2 static struct uac1_output_terminal_descriptor io_out_ot_desc = { .bLength = UAC_DT_OUTPUT_TERMINAL_SIZE, .bDescriptorType = USB_DT_CS_INTERFACE, .bDescriptorSubtype = UAC_OUTPUT_TERMINAL, - .bTerminalID = IO_OUT_OT_ID, + /* .bTerminalID = DYNAMIC */ .wTerminalType = cpu_to_le16(UAC_OUTPUT_TERMINAL_SPEAKER), .bAssocTerminal = 0, - .bSourceID = USB_OUT_IT_ID, + /* .bSourceID = DYNAMIC */ }; -#define IO_IN_IT_ID 3 static struct uac_input_terminal_descriptor io_in_it_desc = { .bLength = UAC_DT_INPUT_TERMINAL_SIZE, .bDescriptorType = USB_DT_CS_INTERFACE, .bDescriptorSubtype = UAC_INPUT_TERMINAL, - .bTerminalID = IO_IN_IT_ID, + /* .bTerminalID = DYNAMIC */ .wTerminalType = cpu_to_le16(UAC_INPUT_TERMINAL_MICROPHONE), .bAssocTerminal = 0, .wChannelConfig = cpu_to_le16(0x3), }; -#define USB_IN_OT_ID 4 static struct uac1_output_terminal_descriptor usb_in_ot_desc = { .bLength = UAC_DT_OUTPUT_TERMINAL_SIZE, .bDescriptorType = USB_DT_CS_INTERFACE, .bDescriptorSubtype = UAC_OUTPUT_TERMINAL, - .bTerminalID = USB_IN_OT_ID, + /* .bTerminalID = DYNAMIC */ .wTerminalType = cpu_to_le16(UAC_TERMINAL_STREAMING), .bAssocTerminal = 0, - .bSourceID = IO_IN_IT_ID, + /* .bSourceID = DYNAMIC */ }; /* B.4.1 Standard AS Interface Descriptor */ @@ -176,7 +148,7 @@ static struct uac1_as_header_descriptor as_out_header_desc = { .bLength = UAC_DT_AS_HEADER_SIZE, .bDescriptorType = USB_DT_CS_INTERFACE, .bDescriptorSubtype = UAC_AS_GENERAL, - .bTerminalLink = USB_OUT_IT_ID, + /* .bTerminalLink = DYNAMIC */ .bDelay = 1, .wFormatTag = cpu_to_le16(UAC_FORMAT_TYPE_I_PCM), }; @@ -185,7 +157,7 @@ static struct uac1_as_header_descriptor as_in_header_desc = { .bLength = UAC_DT_AS_HEADER_SIZE, .bDescriptorType = USB_DT_CS_INTERFACE, .bDescriptorSubtype = UAC_AS_GENERAL, - .bTerminalLink = USB_IN_OT_ID, + /* .bTerminalLink = DYNAMIC */ .bDelay = 1, .wFormatTag = cpu_to_le16(UAC_FORMAT_TYPE_I_PCM), }; @@ -513,6 +485,108 @@ static void f_audio_disable(struct usb_function *f) /*-------------------------------------------------------------------------*/ +static struct +uac1_ac_header_descriptor *build_ac_header_desc(struct f_uac1_opts *opts) +{ + struct uac1_ac_header_descriptor *ac_desc; + int ac_header_desc_size; + int num_ifaces = 0; + + if (EPOUT_EN(opts)) + num_ifaces++; + if (EPIN_EN(opts)) + num_ifaces++; + + ac_header_desc_size = UAC_DT_AC_HEADER_SIZE(num_ifaces); + + ac_desc = kzalloc(ac_header_desc_size, GFP_KERNEL); + if (!ac_desc) + return NULL; + + ac_desc->bLength = ac_header_desc_size; + ac_desc->bDescriptorType = USB_DT_CS_INTERFACE; + ac_desc->bDescriptorSubtype = UAC_HEADER; + ac_desc->bcdADC = cpu_to_le16(0x0100); + ac_desc->bInCollection = num_ifaces; + + /* wTotalLength and baInterfaceNr will be defined later */ + + return ac_desc; +} + +/* Use macro to overcome line length limitation */ +#define USBDHDR(p) (struct usb_descriptor_header *)(p) + +static void setup_descriptor(struct f_uac1_opts *opts) +{ + /* patch descriptors */ + int i = 1; /* ID's start with 1 */ + + if (EPOUT_EN(opts)) + usb_out_it_desc.bTerminalID = i++; + if (EPIN_EN(opts)) + io_in_it_desc.bTerminalID = i++; + if (EPOUT_EN(opts)) + io_out_ot_desc.bTerminalID = i++; + if (EPIN_EN(opts)) + usb_in_ot_desc.bTerminalID = i++; + + usb_in_ot_desc.bSourceID = io_in_it_desc.bTerminalID; + io_out_ot_desc.bSourceID = usb_out_it_desc.bTerminalID; + + as_out_header_desc.bTerminalLink = usb_out_it_desc.bTerminalID; + as_in_header_desc.bTerminalLink = usb_in_ot_desc.bTerminalID; + + ac_header_desc->wTotalLength = cpu_to_le16(ac_header_desc->bLength); + + if (EPIN_EN(opts)) { + u16 len = le16_to_cpu(ac_header_desc->wTotalLength); + + len += sizeof(usb_in_ot_desc); + len += sizeof(io_in_it_desc); + ac_header_desc->wTotalLength = cpu_to_le16(len); + } + if (EPOUT_EN(opts)) { + u16 len = le16_to_cpu(ac_header_desc->wTotalLength); + + len += sizeof(usb_out_it_desc); + len += sizeof(io_out_ot_desc); + ac_header_desc->wTotalLength = cpu_to_le16(len); + } + + i = 0; + f_audio_desc[i++] = USBDHDR(&ac_interface_desc); + f_audio_desc[i++] = USBDHDR(ac_header_desc); + + if (EPOUT_EN(opts)) { + f_audio_desc[i++] = USBDHDR(&usb_out_it_desc); + f_audio_desc[i++] = USBDHDR(&io_out_ot_desc); + } + + if (EPIN_EN(opts)) { + f_audio_desc[i++] = USBDHDR(&io_in_it_desc); + f_audio_desc[i++] = USBDHDR(&usb_in_ot_desc); + } + + if (EPOUT_EN(opts)) { + f_audio_desc[i++] = USBDHDR(&as_out_interface_alt_0_desc); + f_audio_desc[i++] = USBDHDR(&as_out_interface_alt_1_desc); + f_audio_desc[i++] = USBDHDR(&as_out_header_desc); + f_audio_desc[i++] = USBDHDR(&as_out_type_i_desc); + f_audio_desc[i++] = USBDHDR(&as_out_ep_desc); + f_audio_desc[i++] = USBDHDR(&as_iso_out_desc); + } + if (EPIN_EN(opts)) { + f_audio_desc[i++] = USBDHDR(&as_in_interface_alt_0_desc); + f_audio_desc[i++] = USBDHDR(&as_in_interface_alt_1_desc); + f_audio_desc[i++] = USBDHDR(&as_in_header_desc); + f_audio_desc[i++] = USBDHDR(&as_in_type_i_desc); + f_audio_desc[i++] = USBDHDR(&as_in_ep_desc); + f_audio_desc[i++] = USBDHDR(&as_iso_in_desc); + } + f_audio_desc[i] = NULL; +} + static int f_audio_validate_opts(struct g_audio *audio, struct device *dev) { struct f_uac1_opts *opts = g_audio_to_uac1_opts(audio); @@ -556,6 +630,7 @@ static int f_audio_bind(struct usb_configuration *c, struct usb_function *f) struct usb_string *us; u8 *sam_freq; int rate; + int ba_iface_id; int status; status = f_audio_validate_opts(audio, dev); @@ -567,6 +642,11 @@ static int f_audio_bind(struct usb_configuration *c, struct usb_function *f) us = usb_gstrings_attach(cdev, uac1_strings, ARRAY_SIZE(strings_uac1)); if (IS_ERR(us)) return PTR_ERR(us); + + ac_header_desc = build_ac_header_desc(audio_opts); + if (!ac_header_desc) + return -ENOMEM; + ac_interface_desc.iInterface = us[STR_AC_IF].id; usb_out_it_desc.iTerminal = us[STR_USB_OUT_IT].id; usb_out_it_desc.iChannelNames = us[STR_USB_OUT_IT_CH_NAMES].id; @@ -607,40 +687,52 @@ static int f_audio_bind(struct usb_configuration *c, struct usb_function *f) uac1->ac_intf = status; uac1->ac_alt = 0; - status = usb_interface_id(c, f); - if (status < 0) - goto fail; - as_out_interface_alt_0_desc.bInterfaceNumber = status; - as_out_interface_alt_1_desc.bInterfaceNumber = status; - ac_header_desc.baInterfaceNr[0] = status; - uac1->as_out_intf = status; - uac1->as_out_alt = 0; + ba_iface_id = 0; - status = usb_interface_id(c, f); - if (status < 0) - goto fail; - as_in_interface_alt_0_desc.bInterfaceNumber = status; - as_in_interface_alt_1_desc.bInterfaceNumber = status; - ac_header_desc.baInterfaceNr[1] = status; - uac1->as_in_intf = status; - uac1->as_in_alt = 0; + if (EPOUT_EN(audio_opts)) { + status = usb_interface_id(c, f); + if (status < 0) + goto fail; + as_out_interface_alt_0_desc.bInterfaceNumber = status; + as_out_interface_alt_1_desc.bInterfaceNumber = status; + ac_header_desc->baInterfaceNr[ba_iface_id++] = status; + uac1->as_out_intf = status; + uac1->as_out_alt = 0; + } + + if (EPIN_EN(audio_opts)) { + status = usb_interface_id(c, f); + if (status < 0) + goto fail; + as_in_interface_alt_0_desc.bInterfaceNumber = status; + as_in_interface_alt_1_desc.bInterfaceNumber = status; + ac_header_desc->baInterfaceNr[ba_iface_id++] = status; + uac1->as_in_intf = status; + uac1->as_in_alt = 0; + } audio->gadget = gadget; status = -ENODEV; /* allocate instance-specific endpoints */ - ep = usb_ep_autoconfig(cdev->gadget, &as_out_ep_desc); - if (!ep) - goto fail; - audio->out_ep = ep; - audio->out_ep->desc = &as_out_ep_desc; + if (EPOUT_EN(audio_opts)) { + ep = usb_ep_autoconfig(cdev->gadget, &as_out_ep_desc); + if (!ep) + goto fail; + audio->out_ep = ep; + audio->out_ep->desc = &as_out_ep_desc; + } - ep = usb_ep_autoconfig(cdev->gadget, &as_in_ep_desc); - if (!ep) - goto fail; - audio->in_ep = ep; - audio->in_ep->desc = &as_in_ep_desc; + if (EPIN_EN(audio_opts)) { + ep = usb_ep_autoconfig(cdev->gadget, &as_in_ep_desc); + if (!ep) + goto fail; + audio->in_ep = ep; + audio->in_ep->desc = &as_in_ep_desc; + } + + setup_descriptor(audio_opts); /* copy descriptors, and track endpoint copies */ status = usb_assign_descriptors(f, f_audio_desc, f_audio_desc, NULL, @@ -667,6 +759,8 @@ static int f_audio_bind(struct usb_configuration *c, struct usb_function *f) err_card_register: usb_free_all_descriptors(f); fail: + kfree(ac_header_desc); + ac_header_desc = NULL; return status; } @@ -809,6 +903,9 @@ static void f_audio_unbind(struct usb_configuration *c, struct usb_function *f) g_audio_cleanup(audio); usb_free_all_descriptors(f); + kfree(ac_header_desc); + ac_header_desc = NULL; + audio->gadget = NULL; } From 10027474294d8d98862befed48eb7033afa590da Mon Sep 17 00:00:00 2001 From: Charan Teja Reddy Date: Thu, 7 Apr 2022 15:17:24 +0530 Subject: [PATCH 02/91] ANDROID: mm: shmem: use reclaim_pages() to recalim pages from a list Static code analysis tool reported NULL pointer access in shrink_page_list() as the commit 26aa2d199d6f2 ("mm/migrate: demote pages during reclaim") expects valid pgdat. There is already an existing api, reclaim_pages, that tries to reclaim pages from the list. use it instead of creating custom function. Bug: 201263305 Fixes: 96f80f628451 ("ANDROID: mm: add reclaim_shmem_address_space() for faster reclaims") Change-Id: Iaa11feac94c9e8338324ace0276c49d6a0adeb0c Signed-off-by: Charan Teja Reddy --- include/linux/mm.h | 1 - mm/shmem.c | 6 +----- mm/vmscan.c | 30 ------------------------------ 3 files changed, 1 insertion(+), 36 deletions(-) diff --git a/include/linux/mm.h b/include/linux/mm.h index ff79e257a861..420a7706641e 100644 --- a/include/linux/mm.h +++ b/include/linux/mm.h @@ -3362,7 +3362,6 @@ unsigned long wp_shared_mapping_range(struct address_space *mapping, extern int sysctl_nr_trim_pages; extern bool pte_map_lock_addr(struct vm_fault *vmf, unsigned long addr); extern int reclaim_shmem_address_space(struct address_space *mapping); -extern int reclaim_pages_from_list(struct list_head *page_list); /** * seal_check_future_write - Check for F_SEAL_FUTURE_WRITE flag and handle it diff --git a/mm/shmem.c b/mm/shmem.c index 8fb9d2ddec70..0ed98d632eaa 100644 --- a/mm/shmem.c +++ b/mm/shmem.c @@ -4311,7 +4311,6 @@ int reclaim_shmem_address_space(struct address_space *mapping) pgoff_t start = 0; struct page *page; LIST_HEAD(page_list); - int reclaimed; XA_STATE(xas, &mapping->i_pages, start); if (!shmem_mapping(mapping)) @@ -4329,8 +4328,6 @@ int reclaim_shmem_address_space(struct address_space *mapping) continue; list_add(&page->lru, &page_list); - inc_node_page_state(page, NR_ISOLATED_ANON + - page_is_file_lru(page)); if (need_resched()) { xas_pause(&xas); @@ -4338,9 +4335,8 @@ int reclaim_shmem_address_space(struct address_space *mapping) } } rcu_read_unlock(); - reclaimed = reclaim_pages_from_list(&page_list); - return reclaimed; + return reclaim_pages(&page_list); #else return 0; #endif diff --git a/mm/vmscan.c b/mm/vmscan.c index 24b0c38c2c5c..e9789e8e7a6a 100644 --- a/mm/vmscan.c +++ b/mm/vmscan.c @@ -1564,36 +1564,6 @@ unsigned int reclaim_clean_pages_from_list(struct zone *zone, return nr_reclaimed; } -int reclaim_pages_from_list(struct list_head *page_list) -{ - struct scan_control sc = { - .gfp_mask = GFP_KERNEL, - .priority = DEF_PRIORITY, - .may_writepage = 1, - .may_unmap = 1, - .may_swap = 1, - }; - unsigned long nr_reclaimed; - struct reclaim_stat dummy_stat; - struct page *page; - - list_for_each_entry(page, page_list, lru) - ClearPageActive(page); - - nr_reclaimed = shrink_page_list(page_list, NULL, &sc, - &dummy_stat, false); - while (!list_empty(page_list)) { - - page = lru_to_page(page_list); - list_del(&page->lru); - dec_node_page_state(page, NR_ISOLATED_ANON + - page_is_file_lru(page)); - putback_lru_page(page); - } - - return nr_reclaimed; -} - /* * Attempt to remove the specified page from its LRU. Only take this page * if it is of the appropriate PageActive status. Pages which are being From 257d21b1848a8bfe8c25bd5800103144b4eced7c Mon Sep 17 00:00:00 2001 From: Ruslan Bilovol Date: Mon, 12 Jul 2021 14:55:26 +0200 Subject: [PATCH 03/91] UPSTREAM: usb: audio-v2: add ability to define feature unit descriptor Similar to UAC1 spec, UAC2 feature unit descriptor has variable size. Current audio-v2 feature unit descriptor structure is used for parsing descriptors, but can't be used to define your own descriptor. Add a new macro similar to what audio v1 already has. Signed-off-by: Ruslan Bilovol Signed-off-by: Pavel Hofman Link: https://lore.kernel.org/r/20210712125529.76070-2-pavel.hofman@ivitera.com Signed-off-by: Greg Kroah-Hartman Bug: 235196743 (cherry picked from commit b48f8939b9ff593ebed20433bb53c51199920412) Change-Id: Ifa8f979824d81ce6c269f34e0e1118cb4701493a Signed-off-by: Luiz Matheus --- include/linux/usb/audio-v2.h | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/include/linux/usb/audio-v2.h b/include/linux/usb/audio-v2.h index ead8c9a47c6a..8fc2abd7aecb 100644 --- a/include/linux/usb/audio-v2.h +++ b/include/linux/usb/audio-v2.h @@ -156,6 +156,20 @@ struct uac2_feature_unit_descriptor { __u8 bmaControls[]; /* variable length */ } __attribute__((packed)); +#define UAC2_DT_FEATURE_UNIT_SIZE(ch) (6 + ((ch) + 1) * 4) + +/* As above, but more useful for defining your own descriptors: */ +#define DECLARE_UAC2_FEATURE_UNIT_DESCRIPTOR(ch) \ +struct uac2_feature_unit_descriptor_##ch { \ + __u8 bLength; \ + __u8 bDescriptorType; \ + __u8 bDescriptorSubtype; \ + __u8 bUnitID; \ + __u8 bSourceID; \ + __le32 bmaControls[ch + 1]; \ + __u8 iFeature; \ +} __packed + /* 4.7.2.10 Effect Unit Descriptor */ struct uac2_effect_unit_descriptor { From 8430eb02434d2e3cd2230b320ff32f43c2a8a9b1 Mon Sep 17 00:00:00 2001 From: Ruslan Bilovol Date: Mon, 12 Jul 2021 14:55:27 +0200 Subject: [PATCH 04/91] UPSTREAM: usb: gadget: u_audio: add bi-directional volume and mute support USB Audio Class 1/2 have ability to change device's volume and mute by USB Host through class-specific control requests. Device also can notify Host about volume/mute change on its side through optional interrupt endpoint. This patch adds Volume and Mute ALSA controls which can be used by user to send and receive notifications to/from the USB Host about Volume and Mute change. These params come from f_uac* so volume and mute controls will be created only if the function support and enable each explicitly Signed-off-by: Ruslan Bilovol Signed-off-by: Pavel Hofman Link: https://lore.kernel.org/r/20210712125529.76070-3-pavel.hofman@ivitera.com Signed-off-by: Greg Kroah-Hartman Bug: 235196743 (cherry picked from commit 02de698ca8123782c0c6fb8ed99080e2f032b0d2) Change-Id: I7354c4c354952224ab88acd0b8d77d9bc4ba0745 Signed-off-by: Luiz Matheus --- drivers/usb/gadget/function/u_audio.c | 369 +++++++++++++++++++++++++- drivers/usb/gadget/function/u_audio.h | 22 ++ 2 files changed, 380 insertions(+), 11 deletions(-) diff --git a/drivers/usb/gadget/function/u_audio.c b/drivers/usb/gadget/function/u_audio.c index e35a66aec941..c712a910d826 100644 --- a/drivers/usb/gadget/function/u_audio.c +++ b/drivers/usb/gadget/function/u_audio.c @@ -12,11 +12,14 @@ * Jaswinder Singh (jaswinder.singh@linaro.org) */ +#include #include #include #include #include #include +#include +#include #include "u_audio.h" @@ -24,6 +27,12 @@ #define PRD_SIZE_MAX PAGE_SIZE #define MIN_PERIODS 4 +enum { + UAC_FBACK_CTRL, + UAC_MUTE_CTRL, + UAC_VOLUME_CTRL, +}; + /* Runtime data params for one stream */ struct uac_rtd_params { struct snd_uac_chip *uac; /* parent chip */ @@ -43,6 +52,17 @@ struct uac_rtd_params { struct usb_request *req_fback; /* Feedback endpoint request */ bool fb_ep_enabled; /* if the ep is enabled */ + + /* Volume/Mute controls and their state */ + int fu_id; /* Feature Unit ID */ + struct snd_kcontrol *snd_kctl_volume; + struct snd_kcontrol *snd_kctl_mute; + s16 volume_min, volume_max, volume_res; + s16 volume; + int mute; + + spinlock_t lock; /* lock for control transfers */ + }; struct snd_uac_chip { @@ -611,6 +631,103 @@ void u_audio_stop_playback(struct g_audio *audio_dev) } EXPORT_SYMBOL_GPL(u_audio_stop_playback); +int u_audio_get_volume(struct g_audio *audio_dev, int playback, s16 *val) +{ + struct snd_uac_chip *uac = audio_dev->uac; + struct uac_rtd_params *prm; + unsigned long flags; + + if (playback) + prm = &uac->p_prm; + else + prm = &uac->c_prm; + + spin_lock_irqsave(&prm->lock, flags); + *val = prm->volume; + spin_unlock_irqrestore(&prm->lock, flags); + + return 0; +} +EXPORT_SYMBOL_GPL(u_audio_get_volume); + +int u_audio_set_volume(struct g_audio *audio_dev, int playback, s16 val) +{ + struct snd_uac_chip *uac = audio_dev->uac; + struct uac_rtd_params *prm; + unsigned long flags; + int change = 0; + + if (playback) + prm = &uac->p_prm; + else + prm = &uac->c_prm; + + spin_lock_irqsave(&prm->lock, flags); + val = clamp(val, prm->volume_min, prm->volume_max); + if (prm->volume != val) { + prm->volume = val; + change = 1; + } + spin_unlock_irqrestore(&prm->lock, flags); + + if (change) + snd_ctl_notify(uac->card, SNDRV_CTL_EVENT_MASK_VALUE, + &prm->snd_kctl_volume->id); + + return 0; +} +EXPORT_SYMBOL_GPL(u_audio_set_volume); + +int u_audio_get_mute(struct g_audio *audio_dev, int playback, int *val) +{ + struct snd_uac_chip *uac = audio_dev->uac; + struct uac_rtd_params *prm; + unsigned long flags; + + if (playback) + prm = &uac->p_prm; + else + prm = &uac->c_prm; + + spin_lock_irqsave(&prm->lock, flags); + *val = prm->mute; + spin_unlock_irqrestore(&prm->lock, flags); + + return 0; +} +EXPORT_SYMBOL_GPL(u_audio_get_mute); + +int u_audio_set_mute(struct g_audio *audio_dev, int playback, int val) +{ + struct snd_uac_chip *uac = audio_dev->uac; + struct uac_rtd_params *prm; + unsigned long flags; + int change = 0; + int mute; + + if (playback) + prm = &uac->p_prm; + else + prm = &uac->c_prm; + + mute = val ? 1 : 0; + + spin_lock_irqsave(&prm->lock, flags); + if (prm->mute != mute) { + prm->mute = mute; + change = 1; + } + spin_unlock_irqrestore(&prm->lock, flags); + + if (change) + snd_ctl_notify(uac->card, SNDRV_CTL_EVENT_MASK_VALUE, + &prm->snd_kctl_mute->id); + + return 0; +} +EXPORT_SYMBOL_GPL(u_audio_set_mute); + + static int u_audio_pitch_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo) { @@ -670,14 +787,158 @@ static int u_audio_pitch_put(struct snd_kcontrol *kcontrol, return change; } -static const struct snd_kcontrol_new u_audio_controls[] = { +static int u_audio_mute_info(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_info *uinfo) { - .iface = SNDRV_CTL_ELEM_IFACE_PCM, - .name = "Capture Pitch 1000000", - .info = u_audio_pitch_info, - .get = u_audio_pitch_get, - .put = u_audio_pitch_put, -}, + uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN; + uinfo->count = 1; + uinfo->value.integer.min = 0; + uinfo->value.integer.max = 1; + uinfo->value.integer.step = 1; + + return 0; +} + +static int u_audio_mute_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct uac_rtd_params *prm = snd_kcontrol_chip(kcontrol); + unsigned long flags; + + spin_lock_irqsave(&prm->lock, flags); + ucontrol->value.integer.value[0] = !prm->mute; + spin_unlock_irqrestore(&prm->lock, flags); + + return 0; +} + +static int u_audio_mute_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct uac_rtd_params *prm = snd_kcontrol_chip(kcontrol); + struct snd_uac_chip *uac = prm->uac; + struct g_audio *audio_dev = uac->audio_dev; + unsigned int val; + unsigned long flags; + int change = 0; + + val = !ucontrol->value.integer.value[0]; + + spin_lock_irqsave(&prm->lock, flags); + if (val != prm->mute) { + prm->mute = val; + change = 1; + } + spin_unlock_irqrestore(&prm->lock, flags); + + if (change && audio_dev->notify) + audio_dev->notify(audio_dev, prm->fu_id, UAC_FU_MUTE); + + return change; +} + +/* + * TLV callback for mixer volume controls + */ +static int u_audio_volume_tlv(struct snd_kcontrol *kcontrol, int op_flag, + unsigned int size, unsigned int __user *_tlv) +{ + struct uac_rtd_params *prm = snd_kcontrol_chip(kcontrol); + DECLARE_TLV_DB_MINMAX(scale, 0, 0); + + if (size < sizeof(scale)) + return -ENOMEM; + + /* UAC volume resolution is 1/256 dB, TLV is 1/100 dB */ + scale[2] = (prm->volume_min * 100) / 256; + scale[3] = (prm->volume_max * 100) / 256; + if (copy_to_user(_tlv, scale, sizeof(scale))) + return -EFAULT; + + return 0; +} + +static int u_audio_volume_info(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_info *uinfo) +{ + struct uac_rtd_params *prm = snd_kcontrol_chip(kcontrol); + + uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER; + uinfo->count = 1; + uinfo->value.integer.min = 0; + uinfo->value.integer.max = + (prm->volume_max - prm->volume_min + prm->volume_res - 1) + / prm->volume_res; + uinfo->value.integer.step = 1; + + return 0; +} + +static int u_audio_volume_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct uac_rtd_params *prm = snd_kcontrol_chip(kcontrol); + unsigned long flags; + + spin_lock_irqsave(&prm->lock, flags); + ucontrol->value.integer.value[0] = + (prm->volume - prm->volume_min) / prm->volume_res; + spin_unlock_irqrestore(&prm->lock, flags); + + return 0; +} + +static int u_audio_volume_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct uac_rtd_params *prm = snd_kcontrol_chip(kcontrol); + struct snd_uac_chip *uac = prm->uac; + struct g_audio *audio_dev = uac->audio_dev; + unsigned int val; + s16 volume; + unsigned long flags; + int change = 0; + + val = ucontrol->value.integer.value[0]; + + spin_lock_irqsave(&prm->lock, flags); + volume = (val * prm->volume_res) + prm->volume_min; + volume = clamp(volume, prm->volume_min, prm->volume_max); + if (volume != prm->volume) { + prm->volume = volume; + change = 1; + } + spin_unlock_irqrestore(&prm->lock, flags); + + if (change && audio_dev->notify) + audio_dev->notify(audio_dev, prm->fu_id, UAC_FU_VOLUME); + + return change; +} + + +static struct snd_kcontrol_new u_audio_controls[] = { + [UAC_FBACK_CTRL] { + .iface = SNDRV_CTL_ELEM_IFACE_PCM, + .name = "Capture Pitch 1000000", + .info = u_audio_pitch_info, + .get = u_audio_pitch_get, + .put = u_audio_pitch_put, + }, + [UAC_MUTE_CTRL] { + .iface = SNDRV_CTL_ELEM_IFACE_MIXER, + .name = "", /* will be filled later */ + .info = u_audio_mute_info, + .get = u_audio_mute_get, + .put = u_audio_mute_put, + }, + [UAC_VOLUME_CTRL] { + .iface = SNDRV_CTL_ELEM_IFACE_MIXER, + .name = "", /* will be filled later */ + .info = u_audio_volume_info, + .get = u_audio_volume_get, + .put = u_audio_volume_put, + }, }; int g_audio_setup(struct g_audio *g_audio, const char *pcm_name, @@ -689,7 +950,7 @@ int g_audio_setup(struct g_audio *g_audio, const char *pcm_name, struct snd_kcontrol *kctl; struct uac_params *params; int p_chmask, c_chmask; - int err; + int i, err; if (!g_audio) return -EINVAL; @@ -707,7 +968,8 @@ int g_audio_setup(struct g_audio *g_audio, const char *pcm_name, if (c_chmask) { struct uac_rtd_params *prm = &uac->c_prm; - uac->c_prm.uac = uac; + spin_lock_init(&prm->lock); + uac->c_prm.uac = uac; prm->max_psize = g_audio->out_ep_maxpsize; prm->reqs = kcalloc(params->req_number, @@ -730,6 +992,7 @@ int g_audio_setup(struct g_audio *g_audio, const char *pcm_name, if (p_chmask) { struct uac_rtd_params *prm = &uac->p_prm; + spin_lock_init(&prm->lock); uac->p_prm.uac = uac; prm->max_psize = g_audio->in_ep_maxpsize; @@ -774,10 +1037,18 @@ int g_audio_setup(struct g_audio *g_audio, const char *pcm_name, snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK, &uac_pcm_ops); snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE, &uac_pcm_ops); - if (c_chmask && g_audio->in_ep_fback) { + /* + * Create mixer and controls + * Create only if it's required on USB side + */ + if ((c_chmask && g_audio->in_ep_fback) + || (p_chmask && params->p_fu.id) + || (c_chmask && params->c_fu.id)) strscpy(card->mixername, card_name, sizeof(card->driver)); - kctl = snd_ctl_new1(&u_audio_controls[0], &uac->c_prm); + if (c_chmask && g_audio->in_ep_fback) { + kctl = snd_ctl_new1(&u_audio_controls[UAC_FBACK_CTRL], + &uac->c_prm); if (!kctl) { err = -ENOMEM; goto snd_fail; @@ -791,6 +1062,82 @@ int g_audio_setup(struct g_audio *g_audio, const char *pcm_name, goto snd_fail; } + for (i = 0; i <= SNDRV_PCM_STREAM_LAST; i++) { + struct uac_rtd_params *prm; + struct uac_fu_params *fu; + char ctrl_name[24]; + char *direction; + + if (!pcm->streams[i].substream_count) + continue; + + if (i == SNDRV_PCM_STREAM_PLAYBACK) { + prm = &uac->p_prm; + fu = ¶ms->p_fu; + direction = "Playback"; + } else { + prm = &uac->c_prm; + fu = ¶ms->c_fu; + direction = "Capture"; + } + + prm->fu_id = fu->id; + + if (fu->mute_present) { + snprintf(ctrl_name, sizeof(ctrl_name), + "PCM %s Switch", direction); + + u_audio_controls[UAC_MUTE_CTRL].name = ctrl_name; + + kctl = snd_ctl_new1(&u_audio_controls[UAC_MUTE_CTRL], + prm); + if (!kctl) { + err = -ENOMEM; + goto snd_fail; + } + + kctl->id.device = pcm->device; + kctl->id.subdevice = i; + + err = snd_ctl_add(card, kctl); + if (err < 0) + goto snd_fail; + prm->snd_kctl_mute = kctl; + prm->mute = 0; + } + + if (fu->volume_present) { + snprintf(ctrl_name, sizeof(ctrl_name), + "PCM %s Volume", direction); + + u_audio_controls[UAC_VOLUME_CTRL].name = ctrl_name; + + kctl = snd_ctl_new1(&u_audio_controls[UAC_VOLUME_CTRL], + prm); + if (!kctl) { + err = -ENOMEM; + goto snd_fail; + } + + kctl->id.device = pcm->device; + kctl->id.subdevice = i; + + + kctl->tlv.c = u_audio_volume_tlv; + kctl->vd[0].access |= SNDRV_CTL_ELEM_ACCESS_TLV_READ | + SNDRV_CTL_ELEM_ACCESS_TLV_CALLBACK; + + err = snd_ctl_add(card, kctl); + if (err < 0) + goto snd_fail; + prm->snd_kctl_volume = kctl; + prm->volume = fu->volume_max; + prm->volume_max = fu->volume_max; + prm->volume_min = fu->volume_min; + prm->volume_res = fu->volume_res; + } + } + strscpy(card->driver, card_name, sizeof(card->driver)); strscpy(card->shortname, card_name, sizeof(card->shortname)); sprintf(card->longname, "%s %i", card_name, card->dev->id); diff --git a/drivers/usb/gadget/function/u_audio.h b/drivers/usb/gadget/function/u_audio.h index a218cdf771fe..001a79a46022 100644 --- a/drivers/usb/gadget/function/u_audio.h +++ b/drivers/usb/gadget/function/u_audio.h @@ -19,16 +19,30 @@ */ #define FBACK_SLOW_MAX 250 +/* Feature Unit parameters */ +struct uac_fu_params { + int id; /* Feature Unit ID */ + + bool mute_present; /* mute control enable */ + + bool volume_present; /* volume control enable */ + s16 volume_min; /* min volume in 1/256 dB */ + s16 volume_max; /* max volume in 1/256 dB */ + s16 volume_res; /* volume resolution in 1/256 dB */ +}; + struct uac_params { /* playback */ int p_chmask; /* channel mask */ int p_srate; /* rate in Hz */ int p_ssize; /* sample size */ + struct uac_fu_params p_fu; /* Feature Unit parameters */ /* capture */ int c_chmask; /* channel mask */ int c_srate; /* rate in Hz */ int c_ssize; /* sample size */ + struct uac_fu_params c_fu; /* Feature Unit parameters */ int req_number; /* number of preallocated requests */ int fb_max; /* upper frequency drift feedback limit per-mil */ @@ -49,6 +63,9 @@ struct g_audio { /* Max packet size for all out_ep possible speeds */ unsigned int out_ep_maxpsize; + /* Notify UAC driver about control change */ + int (*notify)(struct g_audio *g_audio, int unit_id, int cs); + /* The ALSA Sound Card it represents on the USB-Client side */ struct snd_uac_chip *uac; @@ -94,4 +111,9 @@ void u_audio_stop_capture(struct g_audio *g_audio); int u_audio_start_playback(struct g_audio *g_audio); void u_audio_stop_playback(struct g_audio *g_audio); +int u_audio_get_volume(struct g_audio *g_audio, int playback, s16 *val); +int u_audio_set_volume(struct g_audio *g_audio, int playback, s16 val); +int u_audio_get_mute(struct g_audio *g_audio, int playback, int *val); +int u_audio_set_mute(struct g_audio *g_audio, int playback, int val); + #endif /* __U_AUDIO_H */ From e2c0816af2f2bda618e84ead373a93524d2d037f Mon Sep 17 00:00:00 2001 From: Ruslan Bilovol Date: Mon, 12 Jul 2021 14:55:28 +0200 Subject: [PATCH 05/91] BACKPORT: usb: gadget: f_uac2: add volume and mute support This adds bi-directional (host->device, device->host) volume/mute support to the f_uac2 driver by adding Feature Units and interrupt endpoint. Currently only master channel is supported. Volume and mute are configurable through configfs, by default volume has -100..0 dB range with 1 dB step. Similar to existing flexible endpoints configuration, Feature Unit won't be added to the topology if both mute and volume are not enabled, also interrupt endpoint isn't added to the device if no feature unit is present Signed-off-by: Ruslan Bilovol Signed-off-by: Pavel Hofman Link: https://lore.kernel.org/r/20210712125529.76070-4-pavel.hofman@ivitera.com Signed-off-by: Greg Kroah-Hartman Bug: 235196743 (cherry picked from commit eaf6cbe0992052a46d93047dc122fad5126aa3bd) [luizmmat: Resolved minor conflict in f_uac2.c] Change-Id: Ie8e0de9ac43d2d2030e530e8b244760f45627d7e Signed-off-by: Luiz Matheus --- .../ABI/testing/configfs-usb-gadget-uac2 | 10 + Documentation/usb/gadget-testing.rst | 12 +- drivers/usb/gadget/function/f_uac2.c | 656 ++++++++++++++++-- drivers/usb/gadget/function/u_uac2.h | 23 +- 4 files changed, 638 insertions(+), 63 deletions(-) diff --git a/Documentation/ABI/testing/configfs-usb-gadget-uac2 b/Documentation/ABI/testing/configfs-usb-gadget-uac2 index 26fb8e9b4e61..cfd160ff8b56 100644 --- a/Documentation/ABI/testing/configfs-usb-gadget-uac2 +++ b/Documentation/ABI/testing/configfs-usb-gadget-uac2 @@ -9,8 +9,18 @@ Description: c_srate capture sampling rate c_ssize capture sample size (bytes) c_sync capture synchronization type (async/adaptive) + c_mute_present capture mute control enable + c_volume_present capture volume control enable + c_volume_min capture volume control min value (in 1/256 dB) + c_volume_max capture volume control max value (in 1/256 dB) + c_volume_res capture volume control resolution (in 1/256 dB) fb_max maximum extra bandwidth in async mode p_chmask playback channel mask p_srate playback sampling rate p_ssize playback sample size (bytes) + p_mute_present playback mute control enable + p_volume_present playback volume control enable + p_volume_min playback volume control min value (in 1/256 dB) + p_volume_max playback volume control max value (in 1/256 dB) + p_volume_res playback volume control resolution (in 1/256 dB) ========= ============================ diff --git a/Documentation/usb/gadget-testing.rst b/Documentation/usb/gadget-testing.rst index be1b085a0901..f001dd7cf678 100644 --- a/Documentation/usb/gadget-testing.rst +++ b/Documentation/usb/gadget-testing.rst @@ -729,10 +729,20 @@ The uac2 function provides these attributes in its function directory: c_srate capture sampling rate c_ssize capture sample size (bytes) c_sync capture synchronization type (async/adaptive) - fb_max maximum extra bandwidth in async mode + c_mute_present capture mute control enable + c_volume_present capture volume control enable + c_volume_min capture volume control min value (in 1/256 dB) + c_volume_max capture volume control max value (in 1/256 dB) + c_volume_res capture volume control resolution (in 1/256 dB) + fb_max maximum extra bandwidth in async mode p_chmask playback channel mask p_srate playback sampling rate p_ssize playback sample size (bytes) + p_mute_present playback mute control enable + p_volume_present playback volume control enable + p_volume_min playback volume control min value (in 1/256 dB) + p_volume_max playback volume control max value (in 1/256 dB) + p_volume_res playback volume control resolution (in 1/256 dB) req_number the number of pre-allocated request for both capture and playback =============== ==================================================== diff --git a/drivers/usb/gadget/function/f_uac2.c b/drivers/usb/gadget/function/f_uac2.c index f1ba000ac3f7..1b4542715820 100644 --- a/drivers/usb/gadget/function/f_uac2.c +++ b/drivers/usb/gadget/function/f_uac2.c @@ -5,6 +5,9 @@ * Copyright (C) 2011 * Yadwinder Singh (yadi.brar01@gmail.com) * Jaswinder Singh (jaswinder.singh@linaro.org) + * + * Copyright (C) 2020 + * Ruslan Bilovol (ruslan.bilovol@gmail.com) */ #include @@ -19,14 +22,16 @@ /* * The driver implements a simple UAC_2 topology. - * USB-OUT -> IT_1 -> OT_3 -> ALSA_Capture - * ALSA_Playback -> IT_2 -> OT_4 -> USB-IN + * USB-OUT -> IT_1 -> FU -> OT_3 -> ALSA_Capture + * ALSA_Playback -> IT_2 -> FU -> OT_4 -> USB-IN * Capture and Playback sampling rates are independently * controlled by two clock sources : * CLK_5 := c_srate, and CLK_6 := p_srate */ #define USB_OUT_CLK_ID (out_clk_src_desc.bClockID) #define USB_IN_CLK_ID (in_clk_src_desc.bClockID) +#define USB_OUT_FU_ID (out_feature_unit_desc->bUnitID) +#define USB_IN_FU_ID (in_feature_unit_desc->bUnitID) #define CONTROL_ABSENT 0 #define CONTROL_RDONLY 1 @@ -34,6 +39,8 @@ #define CLK_FREQ_CTRL 0 #define CLK_VLD_CTRL 2 +#define FU_MUTE_CTRL 0 +#define FU_VOL_CTRL 2 #define COPY_CTRL 0 #define CONN_CTRL 2 @@ -44,12 +51,24 @@ #define EPIN_EN(_opts) ((_opts)->p_chmask != 0) #define EPOUT_EN(_opts) ((_opts)->c_chmask != 0) +#define FUIN_EN(_opts) (EPIN_EN(_opts) \ + && ((_opts)->p_mute_present \ + || (_opts)->p_volume_present)) +#define FUOUT_EN(_opts) (EPOUT_EN(_opts) \ + && ((_opts)->c_mute_present \ + || (_opts)->c_volume_present)) #define EPOUT_FBACK_IN_EN(_opts) ((_opts)->c_sync == USB_ENDPOINT_SYNC_ASYNC) struct f_uac2 { struct g_audio g_audio; u8 ac_intf, as_in_intf, as_out_intf; u8 ac_alt, as_in_alt, as_out_alt; /* needed for get_alt() */ + + struct usb_ctrlrequest setup_cr; /* will be used in data stage */ + + /* Interrupt IN endpoint of AC interface */ + struct usb_ep *int_ep; + atomic_t int_count; }; static inline struct f_uac2 *func_to_uac2(struct usb_function *f) @@ -63,6 +82,8 @@ struct f_uac2_opts *g_audio_to_uac2_opts(struct g_audio *agdev) return container_of(agdev->func.fi, struct f_uac2_opts, func_inst); } +static int afunc_notify(struct g_audio *agdev, int unit_id, int cs); + /* --------- USB Function Interface ------------- */ enum { @@ -74,6 +95,8 @@ enum { STR_IO_IT, STR_USB_OT, STR_IO_OT, + STR_FU_IN, + STR_FU_OUT, STR_AS_OUT_ALT0, STR_AS_OUT_ALT1, STR_AS_IN_ALT0, @@ -92,6 +115,8 @@ static struct usb_string strings_fn[] = { [STR_IO_IT].s = "USBD Out", [STR_USB_OT].s = "USBH In", [STR_IO_OT].s = "USBD In", + [STR_FU_IN].s = "Capture Volume", + [STR_FU_OUT].s = "Playback Volume", [STR_AS_OUT_ALT0].s = "Playback Inactive", [STR_AS_OUT_ALT1].s = "Playback Active", [STR_AS_IN_ALT0].s = "Capture Inactive", @@ -126,7 +151,7 @@ static struct usb_interface_descriptor std_ac_if_desc = { .bDescriptorType = USB_DT_INTERFACE, .bAlternateSetting = 0, - .bNumEndpoints = 0, + /* .bNumEndpoints = DYNAMIC */ .bInterfaceClass = USB_CLASS_AUDIO, .bInterfaceSubClass = USB_SUBCLASS_AUDIOCONTROL, .bInterfaceProtocol = UAC_VERSION_2, @@ -212,6 +237,9 @@ static struct uac2_output_terminal_descriptor io_out_ot_desc = { .bmControls = cpu_to_le16(CONTROL_RDWR << COPY_CTRL), }; +static struct uac2_feature_unit_descriptor *in_feature_unit_desc; +static struct uac2_feature_unit_descriptor *out_feature_unit_desc; + static struct uac2_ac_header_descriptor ac_hdr_desc = { .bLength = sizeof ac_hdr_desc, .bDescriptorType = USB_DT_CS_INTERFACE, @@ -223,6 +251,36 @@ static struct uac2_ac_header_descriptor ac_hdr_desc = { .bmControls = 0, }; +/* AC IN Interrupt Endpoint */ +static struct usb_endpoint_descriptor fs_ep_int_desc = { + .bLength = USB_DT_ENDPOINT_SIZE, + .bDescriptorType = USB_DT_ENDPOINT, + + .bEndpointAddress = USB_DIR_IN, + .bmAttributes = USB_ENDPOINT_XFER_INT, + .wMaxPacketSize = cpu_to_le16(6), + .bInterval = 1, +}; + +static struct usb_endpoint_descriptor hs_ep_int_desc = { + .bLength = USB_DT_ENDPOINT_SIZE, + .bDescriptorType = USB_DT_ENDPOINT, + + .bmAttributes = USB_ENDPOINT_XFER_INT, + .wMaxPacketSize = cpu_to_le16(6), + .bInterval = 4, +}; + +static struct usb_endpoint_descriptor ss_ep_int_desc = { + .bLength = USB_DT_ENDPOINT_SIZE, + .bDescriptorType = USB_DT_ENDPOINT, + + .bEndpointAddress = USB_DIR_IN, + .bmAttributes = USB_ENDPOINT_XFER_INT, + .wMaxPacketSize = cpu_to_le16(6), + .bInterval = 4, +}; + /* Audio Streaming OUT Interface - Alt0 */ static struct usb_interface_descriptor std_as_out_if0_desc = { .bLength = sizeof std_as_out_if0_desc, @@ -460,10 +518,14 @@ static struct usb_descriptor_header *fs_audio_desc[] = { (struct usb_descriptor_header *)&in_clk_src_desc, (struct usb_descriptor_header *)&out_clk_src_desc, (struct usb_descriptor_header *)&usb_out_it_desc, + (struct usb_descriptor_header *)&out_feature_unit_desc, (struct usb_descriptor_header *)&io_in_it_desc, (struct usb_descriptor_header *)&usb_in_ot_desc, + (struct usb_descriptor_header *)&in_feature_unit_desc, (struct usb_descriptor_header *)&io_out_ot_desc, + (struct usb_descriptor_header *)&fs_ep_int_desc, + (struct usb_descriptor_header *)&std_as_out_if0_desc, (struct usb_descriptor_header *)&std_as_out_if1_desc, @@ -491,10 +553,14 @@ static struct usb_descriptor_header *hs_audio_desc[] = { (struct usb_descriptor_header *)&in_clk_src_desc, (struct usb_descriptor_header *)&out_clk_src_desc, (struct usb_descriptor_header *)&usb_out_it_desc, + (struct usb_descriptor_header *)&out_feature_unit_desc, (struct usb_descriptor_header *)&io_in_it_desc, (struct usb_descriptor_header *)&usb_in_ot_desc, + (struct usb_descriptor_header *)&in_feature_unit_desc, (struct usb_descriptor_header *)&io_out_ot_desc, + (struct usb_descriptor_header *)&hs_ep_int_desc, + (struct usb_descriptor_header *)&std_as_out_if0_desc, (struct usb_descriptor_header *)&std_as_out_if1_desc, @@ -522,10 +588,14 @@ static struct usb_descriptor_header *ss_audio_desc[] = { (struct usb_descriptor_header *)&in_clk_src_desc, (struct usb_descriptor_header *)&out_clk_src_desc, (struct usb_descriptor_header *)&usb_out_it_desc, + (struct usb_descriptor_header *)&out_feature_unit_desc, (struct usb_descriptor_header *)&io_in_it_desc, (struct usb_descriptor_header *)&usb_in_ot_desc, + (struct usb_descriptor_header *)&in_feature_unit_desc, (struct usb_descriptor_header *)&io_out_ot_desc, + (struct usb_descriptor_header *)&ss_ep_int_desc, + (struct usb_descriptor_header *)&std_as_out_if0_desc, (struct usb_descriptor_header *)&std_as_out_if1_desc, @@ -548,6 +618,17 @@ static struct usb_descriptor_header *ss_audio_desc[] = { NULL, }; +struct cntrl_cur_lay2 { + __le16 wCUR; +}; + +struct cntrl_range_lay2 { + __le16 wNumSubRanges; + __le16 wMIN; + __le16 wMAX; + __le16 wRES; +} __packed; + struct cntrl_cur_lay3 { __le32 dCUR; }; @@ -610,6 +691,26 @@ static int set_ep_max_packet_size(const struct f_uac2_opts *uac2_opts, return 0; } +static struct uac2_feature_unit_descriptor *build_fu_desc(int chmask) +{ + struct uac2_feature_unit_descriptor *fu_desc; + int channels = num_channels(chmask); + int fu_desc_size = UAC2_DT_FEATURE_UNIT_SIZE(channels); + + fu_desc = kzalloc(fu_desc_size, GFP_KERNEL); + if (!fu_desc) + return NULL; + + fu_desc->bLength = fu_desc_size; + fu_desc->bDescriptorType = USB_DT_CS_INTERFACE; + + fu_desc->bDescriptorSubtype = UAC_FEATURE_UNIT; + + /* bUnitID, bSourceID and bmaControls will be defined later */ + + return fu_desc; +} + /* Use macro to overcome line length limitation */ #define USBDHDR(p) (struct usb_descriptor_header *)(p) @@ -623,6 +724,7 @@ static void setup_headers(struct f_uac2_opts *opts, struct usb_endpoint_descriptor *epout_desc; struct usb_endpoint_descriptor *epin_desc; struct usb_endpoint_descriptor *epin_fback_desc; + struct usb_endpoint_descriptor *ep_int_desc; int i; switch (speed) { @@ -630,11 +732,13 @@ static void setup_headers(struct f_uac2_opts *opts, epout_desc = &fs_epout_desc; epin_desc = &fs_epin_desc; epin_fback_desc = &fs_epin_fback_desc; + ep_int_desc = &fs_ep_int_desc; break; case USB_SPEED_HIGH: epout_desc = &hs_epout_desc; epin_desc = &hs_epin_desc; epin_fback_desc = &hs_epin_fback_desc; + ep_int_desc = &hs_ep_int_desc; break; default: epout_desc = &ss_epout_desc; @@ -643,6 +747,7 @@ static void setup_headers(struct f_uac2_opts *opts, epin_desc_comp = &ss_epin_desc_comp; epin_fback_desc = &ss_epin_fback_desc; epin_fback_desc_comp = &ss_epin_fback_desc_comp; + ep_int_desc = &ss_ep_int_desc; } i = 0; @@ -654,13 +759,27 @@ static void setup_headers(struct f_uac2_opts *opts, if (EPOUT_EN(opts)) { headers[i++] = USBDHDR(&out_clk_src_desc); headers[i++] = USBDHDR(&usb_out_it_desc); - } + + if (FUOUT_EN(opts)) + headers[i++] = USBDHDR(out_feature_unit_desc); + } + if (EPIN_EN(opts)) { headers[i++] = USBDHDR(&io_in_it_desc); + + if (FUIN_EN(opts)) + headers[i++] = USBDHDR(in_feature_unit_desc); + headers[i++] = USBDHDR(&usb_in_ot_desc); } - if (EPOUT_EN(opts)) { + + if (EPOUT_EN(opts)) headers[i++] = USBDHDR(&io_out_ot_desc); + + if (FUOUT_EN(opts) || FUIN_EN(opts)) + headers[i++] = USBDHDR(ep_int_desc); + + if (EPOUT_EN(opts)) { headers[i++] = USBDHDR(&std_as_out_if0_desc); headers[i++] = USBDHDR(&std_as_out_if1_desc); headers[i++] = USBDHDR(&as_out_hdr_desc); @@ -677,6 +796,7 @@ static void setup_headers(struct f_uac2_opts *opts, headers[i++] = USBDHDR(epin_fback_desc_comp); } } + if (EPIN_EN(opts)) { headers[i++] = USBDHDR(&std_as_in_if0_desc); headers[i++] = USBDHDR(&std_as_in_if1_desc); @@ -704,17 +824,35 @@ static void setup_descriptor(struct f_uac2_opts *opts) io_out_ot_desc.bTerminalID = i++; if (EPIN_EN(opts)) usb_in_ot_desc.bTerminalID = i++; + if (FUOUT_EN(opts)) + out_feature_unit_desc->bUnitID = i++; + if (FUIN_EN(opts)) + in_feature_unit_desc->bUnitID = i++; if (EPOUT_EN(opts)) out_clk_src_desc.bClockID = i++; if (EPIN_EN(opts)) in_clk_src_desc.bClockID = i++; usb_out_it_desc.bCSourceID = out_clk_src_desc.bClockID; - usb_in_ot_desc.bSourceID = io_in_it_desc.bTerminalID; + + if (FUIN_EN(opts)) { + usb_in_ot_desc.bSourceID = in_feature_unit_desc->bUnitID; + in_feature_unit_desc->bSourceID = io_in_it_desc.bTerminalID; + } else { + usb_in_ot_desc.bSourceID = io_in_it_desc.bTerminalID; + } + usb_in_ot_desc.bCSourceID = in_clk_src_desc.bClockID; io_in_it_desc.bCSourceID = in_clk_src_desc.bClockID; io_out_ot_desc.bCSourceID = out_clk_src_desc.bClockID; - io_out_ot_desc.bSourceID = usb_out_it_desc.bTerminalID; + + if (FUOUT_EN(opts)) { + io_out_ot_desc.bSourceID = out_feature_unit_desc->bUnitID; + out_feature_unit_desc->bSourceID = usb_out_it_desc.bTerminalID; + } else { + io_out_ot_desc.bSourceID = usb_out_it_desc.bTerminalID; + } + as_out_hdr_desc.bTerminalLink = usb_out_it_desc.bTerminalID; as_in_hdr_desc.bTerminalLink = usb_in_ot_desc.bTerminalID; @@ -726,6 +864,10 @@ static void setup_descriptor(struct f_uac2_opts *opts) len += sizeof(in_clk_src_desc); len += sizeof(usb_in_ot_desc); + + if (FUIN_EN(opts)) + len += in_feature_unit_desc->bLength; + len += sizeof(io_in_it_desc); ac_hdr_desc.wTotalLength = cpu_to_le16(len); iad_desc.bInterfaceCount++; @@ -735,6 +877,10 @@ static void setup_descriptor(struct f_uac2_opts *opts) len += sizeof(out_clk_src_desc); len += sizeof(usb_out_it_desc); + + if (FUOUT_EN(opts)) + len += out_feature_unit_desc->bLength; + len += sizeof(io_out_ot_desc); ac_hdr_desc.wTotalLength = cpu_to_le16(len); iad_desc.bInterfaceCount++; @@ -772,6 +918,28 @@ static int afunc_validate_opts(struct g_audio *agdev, struct device *dev) return -EINVAL; } + if (opts->p_volume_max <= opts->p_volume_min) { + dev_err(dev, "Error: incorrect playback volume max/min\n"); + return -EINVAL; + } else if (opts->c_volume_max <= opts->c_volume_min) { + dev_err(dev, "Error: incorrect capture volume max/min\n"); + return -EINVAL; + } else if (opts->p_volume_res <= 0) { + dev_err(dev, "Error: negative/zero playback volume resolution\n"); + return -EINVAL; + } else if (opts->c_volume_res <= 0) { + dev_err(dev, "Error: negative/zero capture volume resolution\n"); + return -EINVAL; + } + + if ((opts->p_volume_max - opts->p_volume_min) % opts->p_volume_res) { + dev_err(dev, "Error: incorrect playback volume resolution\n"); + return -EINVAL; + } else if ((opts->c_volume_max - opts->c_volume_min) % opts->c_volume_res) { + dev_err(dev, "Error: incorrect capture volume resolution\n"); + return -EINVAL; + } + return 0; } @@ -794,6 +962,20 @@ afunc_bind(struct usb_configuration *cfg, struct usb_function *fn) us = usb_gstrings_attach(cdev, fn_strings, ARRAY_SIZE(strings_fn)); if (IS_ERR(us)) return PTR_ERR(us); + + if (FUOUT_EN(uac2_opts)) { + out_feature_unit_desc = build_fu_desc(uac2_opts->c_chmask); + if (!out_feature_unit_desc) + return -ENOMEM; + } + if (FUIN_EN(uac2_opts)) { + in_feature_unit_desc = build_fu_desc(uac2_opts->p_chmask); + if (!in_feature_unit_desc) { + ret = -ENOMEM; + goto err_free_fu; + } + } + iad_desc.iFunction = us[STR_ASSOC].id; std_ac_if_desc.iInterface = us[STR_IF_CTRL].id; in_clk_src_desc.iClockSource = us[STR_CLKSRC_IN].id; @@ -807,6 +989,21 @@ afunc_bind(struct usb_configuration *cfg, struct usb_function *fn) std_as_in_if0_desc.iInterface = us[STR_AS_IN_ALT0].id; std_as_in_if1_desc.iInterface = us[STR_AS_IN_ALT1].id; + if (FUOUT_EN(uac2_opts)) { + u8 *i_feature = (u8 *)out_feature_unit_desc; + + i_feature = (u8 *)out_feature_unit_desc + + out_feature_unit_desc->bLength - 1; + *i_feature = us[STR_FU_OUT].id; + } + if (FUIN_EN(uac2_opts)) { + u8 *i_feature = (u8 *)in_feature_unit_desc; + + i_feature = (u8 *)in_feature_unit_desc + + in_feature_unit_desc->bLength - 1; + *i_feature = us[STR_FU_IN].id; + } + /* Initialize the configurable parameters */ usb_out_it_desc.bNrChannels = num_channels(uac2_opts->c_chmask); @@ -821,6 +1018,26 @@ afunc_bind(struct usb_configuration *cfg, struct usb_function *fn) as_out_fmt1_desc.bBitResolution = uac2_opts->c_ssize * 8; as_in_fmt1_desc.bSubslotSize = uac2_opts->p_ssize; as_in_fmt1_desc.bBitResolution = uac2_opts->p_ssize * 8; + if (FUOUT_EN(uac2_opts)) { + __le32 *bma = (__le32 *)&out_feature_unit_desc->bmaControls[0]; + u32 control = 0; + + if (uac2_opts->c_mute_present) + control |= CONTROL_RDWR << FU_MUTE_CTRL; + if (uac2_opts->c_volume_present) + control |= CONTROL_RDWR << FU_VOL_CTRL; + *bma = cpu_to_le32(control); + } + if (FUIN_EN(uac2_opts)) { + __le32 *bma = (__le32 *)&in_feature_unit_desc->bmaControls[0]; + u32 control = 0; + + if (uac2_opts->p_mute_present) + control |= CONTROL_RDWR << FU_MUTE_CTRL; + if (uac2_opts->p_volume_present) + control |= CONTROL_RDWR << FU_VOL_CTRL; + *bma = cpu_to_le32(control); + } snprintf(clksrc_in, sizeof(clksrc_in), "%uHz", uac2_opts->p_srate); snprintf(clksrc_out, sizeof(clksrc_out), "%uHz", uac2_opts->c_srate); @@ -828,7 +1045,7 @@ afunc_bind(struct usb_configuration *cfg, struct usb_function *fn) ret = usb_interface_id(cfg, fn); if (ret < 0) { dev_err(dev, "%s:%d Error!\n", __func__, __LINE__); - return ret; + goto err_free_fu; } iad_desc.bFirstInterface = ret; @@ -840,7 +1057,7 @@ afunc_bind(struct usb_configuration *cfg, struct usb_function *fn) ret = usb_interface_id(cfg, fn); if (ret < 0) { dev_err(dev, "%s:%d Error!\n", __func__, __LINE__); - return ret; + goto err_free_fu; } std_as_out_if0_desc.bInterfaceNumber = ret; std_as_out_if1_desc.bInterfaceNumber = ret; @@ -869,7 +1086,7 @@ afunc_bind(struct usb_configuration *cfg, struct usb_function *fn) ret = usb_interface_id(cfg, fn); if (ret < 0) { dev_err(dev, "%s:%d Error!\n", __func__, __LINE__); - return ret; + goto err_free_fu; } std_as_in_if0_desc.bInterfaceNumber = ret; std_as_in_if1_desc.bInterfaceNumber = ret; @@ -877,6 +1094,17 @@ afunc_bind(struct usb_configuration *cfg, struct usb_function *fn) uac2->as_in_alt = 0; } + if (FUOUT_EN(uac2_opts) || FUIN_EN(uac2_opts)) { + uac2->int_ep = usb_ep_autoconfig(gadget, &fs_ep_int_desc); + if (!uac2->int_ep) { + dev_err(dev, "%s:%d Error!\n", __func__, __LINE__); + ret = -ENODEV; + goto err_free_fu; + } + + std_ac_if_desc.bNumEndpoints = 1; + } + /* Calculate wMaxPacketSize according to audio bandwidth */ ret = set_ep_max_packet_size(uac2_opts, &fs_epin_desc, USB_SPEED_FULL, true); @@ -924,7 +1152,8 @@ afunc_bind(struct usb_configuration *cfg, struct usb_function *fn) agdev->out_ep = usb_ep_autoconfig(gadget, &fs_epout_desc); if (!agdev->out_ep) { dev_err(dev, "%s:%d Error!\n", __func__, __LINE__); - return -ENODEV; + ret = -ENODEV; + goto err_free_fu; } if (EPOUT_FBACK_IN_EN(uac2_opts)) { agdev->in_ep_fback = usb_ep_autoconfig(gadget, @@ -932,7 +1161,8 @@ afunc_bind(struct usb_configuration *cfg, struct usb_function *fn) if (!agdev->in_ep_fback) { dev_err(dev, "%s:%d Error!\n", __func__, __LINE__); - return -ENODEV; + ret = -ENODEV; + goto err_free_fu; } } } @@ -941,7 +1171,8 @@ afunc_bind(struct usb_configuration *cfg, struct usb_function *fn) agdev->in_ep = usb_ep_autoconfig(gadget, &fs_epin_desc); if (!agdev->in_ep) { dev_err(dev, "%s:%d Error!\n", __func__, __LINE__); - return -ENODEV; + ret = -ENODEV; + goto err_free_fu; } } @@ -960,38 +1191,137 @@ afunc_bind(struct usb_configuration *cfg, struct usb_function *fn) ss_epin_desc_comp.wBytesPerInterval = ss_epin_desc.wMaxPacketSize; ss_epout_desc_comp.wBytesPerInterval = ss_epout_desc.wMaxPacketSize; + // HS and SS endpoint addresses are copied from autoconfigured FS descriptors + hs_ep_int_desc.bEndpointAddress = fs_ep_int_desc.bEndpointAddress; hs_epout_desc.bEndpointAddress = fs_epout_desc.bEndpointAddress; hs_epin_fback_desc.bEndpointAddress = fs_epin_fback_desc.bEndpointAddress; hs_epin_desc.bEndpointAddress = fs_epin_desc.bEndpointAddress; ss_epout_desc.bEndpointAddress = fs_epout_desc.bEndpointAddress; ss_epin_fback_desc.bEndpointAddress = fs_epin_fback_desc.bEndpointAddress; ss_epin_desc.bEndpointAddress = fs_epin_desc.bEndpointAddress; + ss_ep_int_desc.bEndpointAddress = fs_ep_int_desc.bEndpointAddress; setup_descriptor(uac2_opts); ret = usb_assign_descriptors(fn, fs_audio_desc, hs_audio_desc, ss_audio_desc, ss_audio_desc); if (ret) - return ret; + goto err_free_fu; agdev->gadget = gadget; agdev->params.p_chmask = uac2_opts->p_chmask; agdev->params.p_srate = uac2_opts->p_srate; agdev->params.p_ssize = uac2_opts->p_ssize; + if (FUIN_EN(uac2_opts)) { + agdev->params.p_fu.id = USB_IN_FU_ID; + agdev->params.p_fu.mute_present = uac2_opts->p_mute_present; + agdev->params.p_fu.volume_present = uac2_opts->p_volume_present; + agdev->params.p_fu.volume_min = uac2_opts->p_volume_min; + agdev->params.p_fu.volume_max = uac2_opts->p_volume_max; + agdev->params.p_fu.volume_res = uac2_opts->p_volume_res; + } agdev->params.c_chmask = uac2_opts->c_chmask; agdev->params.c_srate = uac2_opts->c_srate; agdev->params.c_ssize = uac2_opts->c_ssize; + if (FUOUT_EN(uac2_opts)) { + agdev->params.c_fu.id = USB_OUT_FU_ID; + agdev->params.c_fu.mute_present = uac2_opts->c_mute_present; + agdev->params.c_fu.volume_present = uac2_opts->c_volume_present; + agdev->params.c_fu.volume_min = uac2_opts->c_volume_min; + agdev->params.c_fu.volume_max = uac2_opts->c_volume_max; + agdev->params.c_fu.volume_res = uac2_opts->c_volume_res; + } agdev->params.req_number = uac2_opts->req_number; agdev->params.fb_max = uac2_opts->fb_max; + + if (FUOUT_EN(uac2_opts) || FUIN_EN(uac2_opts)) + agdev->notify = afunc_notify; + ret = g_audio_setup(agdev, "UAC2 PCM", "UAC2_Gadget"); if (ret) goto err_free_descs; + return 0; err_free_descs: usb_free_all_descriptors(fn); agdev->gadget = NULL; +err_free_fu: + kfree(out_feature_unit_desc); + out_feature_unit_desc = NULL; + kfree(in_feature_unit_desc); + in_feature_unit_desc = NULL; + return ret; +} + +static void +afunc_notify_complete(struct usb_ep *_ep, struct usb_request *req) +{ + struct g_audio *agdev = req->context; + struct f_uac2 *uac2 = func_to_uac2(&agdev->func); + + atomic_dec(&uac2->int_count); + kfree(req->buf); + usb_ep_free_request(_ep, req); +} + +static int +afunc_notify(struct g_audio *agdev, int unit_id, int cs) +{ + struct f_uac2 *uac2 = func_to_uac2(&agdev->func); + struct usb_request *req; + struct uac2_interrupt_data_msg *msg; + u16 w_index, w_value; + int ret; + + if (!uac2->int_ep->enabled) + return 0; + + if (atomic_inc_return(&uac2->int_count) > UAC2_DEF_INT_REQ_NUM) { + atomic_dec(&uac2->int_count); + return 0; + } + + req = usb_ep_alloc_request(uac2->int_ep, GFP_ATOMIC); + if (req == NULL) { + ret = -ENOMEM; + goto err_dec_int_count; + } + + msg = kzalloc(sizeof(*msg), GFP_ATOMIC); + if (msg == NULL) { + ret = -ENOMEM; + goto err_free_request; + } + + w_index = unit_id << 8 | uac2->ac_intf; + w_value = cs << 8; + + msg->bInfo = 0; /* Non-vendor, interface interrupt */ + msg->bAttribute = UAC2_CS_CUR; + msg->wIndex = cpu_to_le16(w_index); + msg->wValue = cpu_to_le16(w_value); + + req->length = sizeof(*msg); + req->buf = msg; + req->context = agdev; + req->complete = afunc_notify_complete; + + ret = usb_ep_queue(uac2->int_ep, req, GFP_ATOMIC); + + if (ret) + goto err_free_msg; + + return 0; + +err_free_msg: + kfree(msg); +err_free_request: + usb_ep_free_request(uac2->int_ep, req); +err_dec_int_count: + atomic_dec(&uac2->int_count); + return ret; } @@ -1000,6 +1330,7 @@ afunc_set_alt(struct usb_function *fn, unsigned intf, unsigned alt) { struct usb_composite_dev *cdev = fn->config->cdev; struct f_uac2 *uac2 = func_to_uac2(fn); + struct g_audio *agdev = func_to_g_audio(fn); struct usb_gadget *gadget = cdev->gadget; struct device *dev = &gadget->dev; int ret = 0; @@ -1016,6 +1347,14 @@ afunc_set_alt(struct usb_function *fn, unsigned intf, unsigned alt) dev_err(dev, "%s:%d Error!\n", __func__, __LINE__); return -EINVAL; } + + /* restart interrupt endpoint */ + if (uac2->int_ep) { + usb_ep_disable(uac2->int_ep); + config_ep_by_speed(gadget, &agdev->func, uac2->int_ep); + usb_ep_enable(uac2->int_ep); + } + return 0; } @@ -1070,6 +1409,8 @@ afunc_disable(struct usb_function *fn) uac2->as_out_alt = 0; u_audio_stop_capture(&uac2->g_audio); u_audio_stop_playback(&uac2->g_audio); + if (uac2->int_ep) + usb_ep_disable(uac2->int_ep); } static int @@ -1077,7 +1418,7 @@ in_rq_cur(struct usb_function *fn, const struct usb_ctrlrequest *cr) { struct usb_request *req = fn->config->cdev->req; struct g_audio *agdev = func_to_g_audio(fn); - struct f_uac2_opts *opts; + struct f_uac2_opts *opts = g_audio_to_uac2_opts(agdev); u16 w_length = le16_to_cpu(cr->wLength); u16 w_index = le16_to_cpu(cr->wIndex); u16 w_value = le16_to_cpu(cr->wValue); @@ -1086,28 +1427,64 @@ in_rq_cur(struct usb_function *fn, const struct usb_ctrlrequest *cr) int value = -EOPNOTSUPP; int p_srate, c_srate; - opts = g_audio_to_uac2_opts(agdev); p_srate = opts->p_srate; c_srate = opts->c_srate; - if (control_selector == UAC2_CS_CONTROL_SAM_FREQ) { - struct cntrl_cur_lay3 c; - memset(&c, 0, sizeof(struct cntrl_cur_lay3)); + if ((entity_id == USB_IN_CLK_ID) || (entity_id == USB_OUT_CLK_ID)) { + if (control_selector == UAC2_CS_CONTROL_SAM_FREQ) { + struct cntrl_cur_lay3 c; - if (entity_id == USB_IN_CLK_ID) - c.dCUR = cpu_to_le32(p_srate); - else if (entity_id == USB_OUT_CLK_ID) - c.dCUR = cpu_to_le32(c_srate); + memset(&c, 0, sizeof(struct cntrl_cur_lay3)); - value = min_t(unsigned, w_length, sizeof c); - memcpy(req->buf, &c, value); - } else if (control_selector == UAC2_CS_CONTROL_CLOCK_VALID) { - *(u8 *)req->buf = 1; - value = min_t(unsigned, w_length, 1); + if (entity_id == USB_IN_CLK_ID) + c.dCUR = cpu_to_le32(p_srate); + else if (entity_id == USB_OUT_CLK_ID) + c.dCUR = cpu_to_le32(c_srate); + + value = min_t(unsigned int, w_length, sizeof(c)); + memcpy(req->buf, &c, value); + } else if (control_selector == UAC2_CS_CONTROL_CLOCK_VALID) { + *(u8 *)req->buf = 1; + value = min_t(unsigned int, w_length, 1); + } else { + dev_err(&agdev->gadget->dev, + "%s:%d control_selector=%d TODO!\n", + __func__, __LINE__, control_selector); + } + } else if ((FUIN_EN(opts) && (entity_id == USB_IN_FU_ID)) || + (FUOUT_EN(opts) && (entity_id == USB_OUT_FU_ID))) { + unsigned int is_playback = 0; + + if (FUIN_EN(opts) && (entity_id == USB_IN_FU_ID)) + is_playback = 1; + + if (control_selector == UAC_FU_MUTE) { + unsigned int mute; + + u_audio_get_mute(agdev, is_playback, &mute); + + *(u8 *)req->buf = mute; + value = min_t(unsigned int, w_length, 1); + } else if (control_selector == UAC_FU_VOLUME) { + struct cntrl_cur_lay2 c; + s16 volume; + + memset(&c, 0, sizeof(struct cntrl_cur_lay2)); + + u_audio_get_volume(agdev, is_playback, &volume); + c.wCUR = cpu_to_le16(volume); + + value = min_t(unsigned int, w_length, sizeof(c)); + memcpy(req->buf, &c, value); + } else { + dev_err(&agdev->gadget->dev, + "%s:%d control_selector=%d TODO!\n", + __func__, __LINE__, control_selector); + } } else { dev_err(&agdev->gadget->dev, - "%s:%d control_selector=%d TODO!\n", - __func__, __LINE__, control_selector); + "%s:%d entity_id=%d control_selector=%d TODO!\n", + __func__, __LINE__, entity_id, control_selector); } return value; @@ -1118,38 +1495,77 @@ in_rq_range(struct usb_function *fn, const struct usb_ctrlrequest *cr) { struct usb_request *req = fn->config->cdev->req; struct g_audio *agdev = func_to_g_audio(fn); - struct f_uac2_opts *opts; + struct f_uac2_opts *opts = g_audio_to_uac2_opts(agdev); u16 w_length = le16_to_cpu(cr->wLength); u16 w_index = le16_to_cpu(cr->wIndex); u16 w_value = le16_to_cpu(cr->wValue); u8 entity_id = (w_index >> 8) & 0xff; u8 control_selector = w_value >> 8; - struct cntrl_range_lay3 r; int value = -EOPNOTSUPP; int p_srate, c_srate; - opts = g_audio_to_uac2_opts(agdev); p_srate = opts->p_srate; c_srate = opts->c_srate; - if (control_selector == UAC2_CS_CONTROL_SAM_FREQ) { - if (entity_id == USB_IN_CLK_ID) - r.dMIN = cpu_to_le32(p_srate); - else if (entity_id == USB_OUT_CLK_ID) - r.dMIN = cpu_to_le32(c_srate); - else - return -EOPNOTSUPP; + if ((entity_id == USB_IN_CLK_ID) || (entity_id == USB_OUT_CLK_ID)) { + if (control_selector == UAC2_CS_CONTROL_SAM_FREQ) { + struct cntrl_range_lay3 r; - r.dMAX = r.dMIN; - r.dRES = 0; - r.wNumSubRanges = cpu_to_le16(1); + if (entity_id == USB_IN_CLK_ID) + r.dMIN = cpu_to_le32(p_srate); + else if (entity_id == USB_OUT_CLK_ID) + r.dMIN = cpu_to_le32(c_srate); + else + return -EOPNOTSUPP; - value = min_t(unsigned, w_length, sizeof r); - memcpy(req->buf, &r, value); + r.dMAX = r.dMIN; + r.dRES = 0; + r.wNumSubRanges = cpu_to_le16(1); + + value = min_t(unsigned int, w_length, sizeof(r)); + memcpy(req->buf, &r, value); + } else { + dev_err(&agdev->gadget->dev, + "%s:%d control_selector=%d TODO!\n", + __func__, __LINE__, control_selector); + } + } else if ((FUIN_EN(opts) && (entity_id == USB_IN_FU_ID)) || + (FUOUT_EN(opts) && (entity_id == USB_OUT_FU_ID))) { + unsigned int is_playback = 0; + + if (FUIN_EN(opts) && (entity_id == USB_IN_FU_ID)) + is_playback = 1; + + if (control_selector == UAC_FU_VOLUME) { + struct cntrl_range_lay2 r; + s16 max_db, min_db, res_db; + + if (is_playback) { + max_db = opts->p_volume_max; + min_db = opts->p_volume_min; + res_db = opts->p_volume_res; + } else { + max_db = opts->c_volume_max; + min_db = opts->c_volume_min; + res_db = opts->c_volume_res; + } + + r.wMAX = cpu_to_le16(max_db); + r.wMIN = cpu_to_le16(min_db); + r.wRES = cpu_to_le16(res_db); + r.wNumSubRanges = cpu_to_le16(1); + + value = min_t(unsigned int, w_length, sizeof(r)); + memcpy(req->buf, &r, value); + } else { + dev_err(&agdev->gadget->dev, + "%s:%d control_selector=%d TODO!\n", + __func__, __LINE__, control_selector); + } } else { dev_err(&agdev->gadget->dev, - "%s:%d control_selector=%d TODO!\n", - __func__, __LINE__, control_selector); + "%s:%d entity_id=%d control_selector=%d TODO!\n", + __func__, __LINE__, entity_id, control_selector); } return value; @@ -1166,16 +1582,82 @@ ac_rq_in(struct usb_function *fn, const struct usb_ctrlrequest *cr) return -EOPNOTSUPP; } +static void +out_rq_cur_complete(struct usb_ep *ep, struct usb_request *req) +{ + struct g_audio *agdev = req->context; + struct usb_composite_dev *cdev = agdev->func.config->cdev; + struct f_uac2_opts *opts = g_audio_to_uac2_opts(agdev); + struct f_uac2 *uac2 = func_to_uac2(&agdev->func); + struct usb_ctrlrequest *cr = &uac2->setup_cr; + u16 w_index = le16_to_cpu(cr->wIndex); + u16 w_value = le16_to_cpu(cr->wValue); + u8 entity_id = (w_index >> 8) & 0xff; + u8 control_selector = w_value >> 8; + + if (req->status != 0) { + dev_dbg(&cdev->gadget->dev, "completion err %d\n", req->status); + return; + } + + if ((FUIN_EN(opts) && (entity_id == USB_IN_FU_ID)) || + (FUOUT_EN(opts) && (entity_id == USB_OUT_FU_ID))) { + unsigned int is_playback = 0; + + if (FUIN_EN(opts) && (entity_id == USB_IN_FU_ID)) + is_playback = 1; + + if (control_selector == UAC_FU_MUTE) { + u8 mute = *(u8 *)req->buf; + + u_audio_set_mute(agdev, is_playback, mute); + + return; + } else if (control_selector == UAC_FU_VOLUME) { + struct cntrl_cur_lay2 *c = req->buf; + s16 volume; + + volume = le16_to_cpu(c->wCUR); + u_audio_set_volume(agdev, is_playback, volume); + + return; + } else { + dev_err(&agdev->gadget->dev, + "%s:%d control_selector=%d TODO!\n", + __func__, __LINE__, control_selector); + usb_ep_set_halt(ep); + } + } +} + static int out_rq_cur(struct usb_function *fn, const struct usb_ctrlrequest *cr) { + struct usb_request *req = fn->config->cdev->req; + struct g_audio *agdev = func_to_g_audio(fn); + struct f_uac2_opts *opts = g_audio_to_uac2_opts(agdev); + struct f_uac2 *uac2 = func_to_uac2(fn); u16 w_length = le16_to_cpu(cr->wLength); + u16 w_index = le16_to_cpu(cr->wIndex); u16 w_value = le16_to_cpu(cr->wValue); + u8 entity_id = (w_index >> 8) & 0xff; u8 control_selector = w_value >> 8; - if (control_selector == UAC2_CS_CONTROL_SAM_FREQ) - return w_length; + if ((entity_id == USB_IN_CLK_ID) || (entity_id == USB_OUT_CLK_ID)) { + if (control_selector == UAC2_CS_CONTROL_SAM_FREQ) + return w_length; + } else if ((FUIN_EN(opts) && (entity_id == USB_IN_FU_ID)) || + (FUOUT_EN(opts) && (entity_id == USB_OUT_FU_ID))) { + memcpy(&uac2->setup_cr, cr, sizeof(*cr)); + req->context = agdev; + req->complete = out_rq_cur_complete; + return w_length; + } else { + dev_err(&agdev->gadget->dev, + "%s:%d entity_id=%d control_selector=%d TODO!\n", + __func__, __LINE__, entity_id, control_selector); + } return -EOPNOTSUPP; } @@ -1251,7 +1733,15 @@ static struct configfs_item_operations f_uac2_item_ops = { .release = f_uac2_attr_release, }; -#define UAC2_ATTRIBUTE(name) \ +#define uac2_kstrtou32 kstrtou32 +#define uac2_kstrtos16 kstrtos16 +#define uac2_kstrtobool(s, base, res) kstrtobool((s), (res)) + +static const char *u32_fmt = "%u\n"; +static const char *s16_fmt = "%hd\n"; +static const char *bool_fmt = "%u\n"; + +#define UAC2_ATTRIBUTE(type, name) \ static ssize_t f_uac2_opts_##name##_show(struct config_item *item, \ char *page) \ { \ @@ -1259,7 +1749,7 @@ static ssize_t f_uac2_opts_##name##_show(struct config_item *item, \ int result; \ \ mutex_lock(&opts->lock); \ - result = sprintf(page, "%u\n", opts->name); \ + result = sprintf(page, type##_fmt, opts->name); \ mutex_unlock(&opts->lock); \ \ return result; \ @@ -1270,7 +1760,7 @@ static ssize_t f_uac2_opts_##name##_store(struct config_item *item, \ { \ struct f_uac2_opts *opts = to_f_uac2_opts(item); \ int ret; \ - u32 num; \ + type num; \ \ mutex_lock(&opts->lock); \ if (opts->refcnt) { \ @@ -1278,7 +1768,7 @@ static ssize_t f_uac2_opts_##name##_store(struct config_item *item, \ goto end; \ } \ \ - ret = kstrtou32(page, 0, &num); \ + ret = uac2_kstrto##type(page, 0, &num); \ if (ret) \ goto end; \ \ @@ -1348,15 +1838,27 @@ end: \ \ CONFIGFS_ATTR(f_uac2_opts_, name) -UAC2_ATTRIBUTE(p_chmask); -UAC2_ATTRIBUTE(p_srate); -UAC2_ATTRIBUTE(p_ssize); -UAC2_ATTRIBUTE(c_chmask); -UAC2_ATTRIBUTE(c_srate); +UAC2_ATTRIBUTE(u32, p_chmask); +UAC2_ATTRIBUTE(u32, p_srate); +UAC2_ATTRIBUTE(u32, p_ssize); +UAC2_ATTRIBUTE(u32, c_chmask); +UAC2_ATTRIBUTE(u32, c_srate); UAC2_ATTRIBUTE_SYNC(c_sync); -UAC2_ATTRIBUTE(c_ssize); -UAC2_ATTRIBUTE(req_number); -UAC2_ATTRIBUTE(fb_max); +UAC2_ATTRIBUTE(u32, c_ssize); +UAC2_ATTRIBUTE(u32, req_number); + +UAC2_ATTRIBUTE(bool, p_mute_present); +UAC2_ATTRIBUTE(bool, p_volume_present); +UAC2_ATTRIBUTE(s16, p_volume_min); +UAC2_ATTRIBUTE(s16, p_volume_max); +UAC2_ATTRIBUTE(s16, p_volume_res); + +UAC2_ATTRIBUTE(bool, c_mute_present); +UAC2_ATTRIBUTE(bool, c_volume_present); +UAC2_ATTRIBUTE(s16, c_volume_min); +UAC2_ATTRIBUTE(s16, c_volume_max); +UAC2_ATTRIBUTE(s16, c_volume_res); +UAC2_ATTRIBUTE(u32, fb_max); static struct configfs_attribute *f_uac2_attrs[] = { &f_uac2_opts_attr_p_chmask, @@ -1368,6 +1870,19 @@ static struct configfs_attribute *f_uac2_attrs[] = { &f_uac2_opts_attr_c_sync, &f_uac2_opts_attr_req_number, &f_uac2_opts_attr_fb_max, + + &f_uac2_opts_attr_p_mute_present, + &f_uac2_opts_attr_p_volume_present, + &f_uac2_opts_attr_p_volume_min, + &f_uac2_opts_attr_p_volume_max, + &f_uac2_opts_attr_p_volume_res, + + &f_uac2_opts_attr_c_mute_present, + &f_uac2_opts_attr_c_volume_present, + &f_uac2_opts_attr_c_volume_min, + &f_uac2_opts_attr_c_volume_max, + &f_uac2_opts_attr_c_volume_res, + NULL, }; @@ -1406,6 +1921,19 @@ static struct usb_function_instance *afunc_alloc_inst(void) opts->c_srate = UAC2_DEF_CSRATE; opts->c_ssize = UAC2_DEF_CSSIZE; opts->c_sync = UAC2_DEF_CSYNC; + + opts->p_mute_present = UAC2_DEF_MUTE_PRESENT; + opts->p_volume_present = UAC2_DEF_VOLUME_PRESENT; + opts->p_volume_min = UAC2_DEF_MIN_DB; + opts->p_volume_max = UAC2_DEF_MAX_DB; + opts->p_volume_res = UAC2_DEF_RES_DB; + + opts->c_mute_present = UAC2_DEF_MUTE_PRESENT; + opts->c_volume_present = UAC2_DEF_VOLUME_PRESENT; + opts->c_volume_min = UAC2_DEF_MIN_DB; + opts->c_volume_max = UAC2_DEF_MAX_DB; + opts->c_volume_res = UAC2_DEF_RES_DB; + opts->req_number = UAC2_DEF_REQ_NUM; opts->fb_max = UAC2_DEF_FB_MAX; return &opts->func_inst; @@ -1432,6 +1960,11 @@ static void afunc_unbind(struct usb_configuration *c, struct usb_function *f) usb_free_all_descriptors(f); agdev->gadget = NULL; + + kfree(out_feature_unit_desc); + out_feature_unit_desc = NULL; + kfree(in_feature_unit_desc); + in_feature_unit_desc = NULL; } static struct usb_function *afunc_alloc(struct usb_function_instance *fi) @@ -1464,3 +1997,4 @@ DECLARE_USB_FUNCTION_INIT(uac2, afunc_alloc_inst, afunc_alloc); MODULE_LICENSE("GPL"); MODULE_AUTHOR("Yadwinder Singh"); MODULE_AUTHOR("Jaswinder Singh"); +MODULE_AUTHOR("Ruslan Bilovol"); diff --git a/drivers/usb/gadget/function/u_uac2.h b/drivers/usb/gadget/function/u_uac2.h index 179d3ef6a195..a73b35774c44 100644 --- a/drivers/usb/gadget/function/u_uac2.h +++ b/drivers/usb/gadget/function/u_uac2.h @@ -22,8 +22,16 @@ #define UAC2_DEF_CSRATE 64000 #define UAC2_DEF_CSSIZE 2 #define UAC2_DEF_CSYNC USB_ENDPOINT_SYNC_ASYNC + +#define UAC2_DEF_MUTE_PRESENT 1 +#define UAC2_DEF_VOLUME_PRESENT 1 +#define UAC2_DEF_MIN_DB (-100*256) /* -100 dB */ +#define UAC2_DEF_MAX_DB 0 /* 0 dB */ +#define UAC2_DEF_RES_DB (1*256) /* 1 dB */ + #define UAC2_DEF_REQ_NUM 2 #define UAC2_DEF_FB_MAX 5 +#define UAC2_DEF_INT_REQ_NUM 10 struct f_uac2_opts { struct usb_function_instance func_inst; @@ -34,9 +42,22 @@ struct f_uac2_opts { int c_srate; int c_ssize; int c_sync; + + bool p_mute_present; + bool p_volume_present; + s16 p_volume_min; + s16 p_volume_max; + s16 p_volume_res; + + bool c_mute_present; + bool c_volume_present; + s16 c_volume_min; + s16 c_volume_max; + s16 c_volume_res; + int req_number; int fb_max; - bool bound; + bool bound; struct mutex lock; int refcnt; From a380b466e0c248dfce47268912e013d99986634e Mon Sep 17 00:00:00 2001 From: Ruslan Bilovol Date: Mon, 12 Jul 2021 14:55:29 +0200 Subject: [PATCH 06/91] UPSTREAM: usb: gadget: f_uac1: add volume and mute support This adds bi-directional (host->device, device->host) volume/mute support to the f_uac1 driver by adding Feature Units and interrupt endpoint. Currently only master channel is supported. Volume and mute are configurable through configfs, by default volume has -100..0 dB range with 1 dB step. Similar to existing flexible endpoints configuration, Feature Unit won't be added to the topology if both mute and volume are not enabled, also interrupt endpoint isn't added to the device if no feature unit is present Signed-off-by: Ruslan Bilovol Signed-off-by: Pavel Hofman Link: https://lore.kernel.org/r/20210712125529.76070-5-pavel.hofman@ivitera.com Signed-off-by: Greg Kroah-Hartman Bug: 235196743 (cherry picked from commit 0356e6283c7177391d144612f4b12986ed5c4f6e) Change-Id: If37a2696bd3cfd0ab9ad1022e804b5e355fdfb64 Signed-off-by: Luiz Matheus --- .../ABI/testing/configfs-usb-gadget-uac1 | 10 + Documentation/usb/gadget-testing.rst | 26 +- drivers/usb/gadget/function/f_uac1.c | 672 +++++++++++++++++- drivers/usb/gadget/function/u_uac1.h | 20 + 4 files changed, 699 insertions(+), 29 deletions(-) diff --git a/Documentation/ABI/testing/configfs-usb-gadget-uac1 b/Documentation/ABI/testing/configfs-usb-gadget-uac1 index dc23fd776943..dd647d44d975 100644 --- a/Documentation/ABI/testing/configfs-usb-gadget-uac1 +++ b/Documentation/ABI/testing/configfs-usb-gadget-uac1 @@ -8,9 +8,19 @@ Description: c_chmask capture channel mask c_srate capture sampling rate c_ssize capture sample size (bytes) + c_mute_present capture mute control enable + c_volume_present capture volume control enable + c_volume_min capture volume control min value (in 1/256 dB) + c_volume_max capture volume control max value (in 1/256 dB) + c_volume_res capture volume control resolution (in 1/256 dB) p_chmask playback channel mask p_srate playback sampling rate p_ssize playback sample size (bytes) + p_mute_present playback mute control enable + p_volume_present playback volume control enable + p_volume_min playback volume control min value (in 1/256 dB) + p_volume_max playback volume control max value (in 1/256 dB) + p_volume_res playback volume control resolution (in 1/256 dB) req_number the number of pre-allocated request for both capture and playback ========== =================================== diff --git a/Documentation/usb/gadget-testing.rst b/Documentation/usb/gadget-testing.rst index f001dd7cf678..fe1a0e3a4eee 100644 --- a/Documentation/usb/gadget-testing.rst +++ b/Documentation/usb/gadget-testing.rst @@ -916,14 +916,24 @@ The function name to use when creating the function directory is "uac1". The uac1 function provides these attributes in its function directory: ========== ==================================================== - c_chmask capture channel mask - c_srate capture sampling rate - c_ssize capture sample size (bytes) - p_chmask playback channel mask - p_srate playback sampling rate - p_ssize playback sample size (bytes) - req_number the number of pre-allocated request for both capture - and playback + c_chmask capture channel mask + c_srate capture sampling rate + c_ssize capture sample size (bytes) + c_mute_present capture mute control enable + c_volume_present capture volume control enable + c_volume_min capture volume control min value (in 1/256 dB) + c_volume_max capture volume control max value (in 1/256 dB) + c_volume_res capture volume control resolution (in 1/256 dB) + p_chmask playback channel mask + p_srate playback sampling rate + p_ssize playback sample size (bytes) + p_mute_present playback mute control enable + p_volume_present playback volume control enable + p_volume_min playback volume control min value (in 1/256 dB) + p_volume_max playback volume control max value (in 1/256 dB) + p_volume_res playback volume control resolution (in 1/256 dB) + req_number the number of pre-allocated request for both capture + and playback ========== ==================================================== The attributes have sane default values. diff --git a/drivers/usb/gadget/function/f_uac1.c b/drivers/usb/gadget/function/f_uac1.c index d04707580068..3b3db1a8df75 100644 --- a/drivers/usb/gadget/function/f_uac1.c +++ b/drivers/usb/gadget/function/f_uac1.c @@ -22,13 +22,26 @@ /* UAC1 spec: 3.7.2.3 Audio Channel Cluster Format */ #define UAC1_CHANNEL_MASK 0x0FFF +#define USB_OUT_FU_ID (out_feature_unit_desc->bUnitID) +#define USB_IN_FU_ID (in_feature_unit_desc->bUnitID) + #define EPIN_EN(_opts) ((_opts)->p_chmask != 0) #define EPOUT_EN(_opts) ((_opts)->c_chmask != 0) +#define FUIN_EN(_opts) ((_opts)->p_mute_present \ + || (_opts)->p_volume_present) +#define FUOUT_EN(_opts) ((_opts)->c_mute_present \ + || (_opts)->c_volume_present) struct f_uac1 { struct g_audio g_audio; u8 ac_intf, as_in_intf, as_out_intf; u8 ac_alt, as_in_alt, as_out_alt; /* needed for get_alt() */ + + struct usb_ctrlrequest setup_cr; /* will be used in data stage */ + + /* Interrupt IN endpoint of AC interface */ + struct usb_ep *int_ep; + atomic_t int_count; }; static inline struct f_uac1 *func_to_uac1(struct usb_function *f) @@ -58,7 +71,7 @@ static inline struct f_uac1_opts *g_audio_to_uac1_opts(struct g_audio *audio) static struct usb_interface_descriptor ac_interface_desc = { .bLength = USB_DT_INTERFACE_SIZE, .bDescriptorType = USB_DT_INTERFACE, - .bNumEndpoints = 0, + /* .bNumEndpoints = DYNAMIC */ .bInterfaceClass = USB_CLASS_AUDIO, .bInterfaceSubClass = USB_SUBCLASS_AUDIOCONTROL, }; @@ -106,6 +119,19 @@ static struct uac1_output_terminal_descriptor usb_in_ot_desc = { /* .bSourceID = DYNAMIC */ }; +static struct uac_feature_unit_descriptor *in_feature_unit_desc; +static struct uac_feature_unit_descriptor *out_feature_unit_desc; + +/* AC IN Interrupt Endpoint */ +static struct usb_endpoint_descriptor ac_int_ep_desc = { + .bLength = USB_DT_ENDPOINT_SIZE, + .bDescriptorType = USB_DT_ENDPOINT, + .bEndpointAddress = USB_DIR_IN, + .bmAttributes = USB_ENDPOINT_XFER_INT, + .wMaxPacketSize = cpu_to_le16(2), + .bInterval = 4, +}; + /* B.4.1 Standard AS Interface Descriptor */ static struct usb_interface_descriptor as_out_interface_alt_0_desc = { .bLength = USB_DT_INTERFACE_SIZE, @@ -232,8 +258,13 @@ static struct usb_descriptor_header *f_audio_desc[] = { (struct usb_descriptor_header *)&usb_out_it_desc, (struct usb_descriptor_header *)&io_out_ot_desc, + (struct usb_descriptor_header *)&out_feature_unit_desc, + (struct usb_descriptor_header *)&io_in_it_desc, (struct usb_descriptor_header *)&usb_in_ot_desc, + (struct usb_descriptor_header *)&in_feature_unit_desc, + + (struct usb_descriptor_header *)&ac_int_ep_desc, (struct usb_descriptor_header *)&as_out_interface_alt_0_desc, (struct usb_descriptor_header *)&as_out_interface_alt_1_desc, @@ -263,6 +294,8 @@ enum { STR_IO_IN_IT, STR_IO_IN_IT_CH_NAMES, STR_USB_IN_OT, + STR_FU_IN, + STR_FU_OUT, STR_AS_OUT_IF_ALT0, STR_AS_OUT_IF_ALT1, STR_AS_IN_IF_ALT0, @@ -277,6 +310,8 @@ static struct usb_string strings_uac1[] = { [STR_IO_IN_IT].s = "Capture Input terminal", [STR_IO_IN_IT_CH_NAMES].s = "Capture Channels", [STR_USB_IN_OT].s = "Capture Output terminal", + [STR_FU_IN].s = "Capture Volume", + [STR_FU_OUT].s = "Playback Volume", [STR_AS_OUT_IF_ALT0].s = "Playback Inactive", [STR_AS_OUT_IF_ALT1].s = "Playback Active", [STR_AS_IN_IF_ALT0].s = "Capture Inactive", @@ -298,6 +333,376 @@ static struct usb_gadget_strings *uac1_strings[] = { * This function is an ALSA sound card following USB Audio Class Spec 1.0. */ +static void audio_notify_complete(struct usb_ep *_ep, struct usb_request *req) +{ + struct g_audio *audio = req->context; + struct f_uac1 *uac1 = func_to_uac1(&audio->func); + + atomic_dec(&uac1->int_count); + kfree(req->buf); + usb_ep_free_request(_ep, req); +} + +static int audio_notify(struct g_audio *audio, int unit_id, int cs) +{ + struct f_uac1 *uac1 = func_to_uac1(&audio->func); + struct usb_request *req; + struct uac1_status_word *msg; + int ret; + + if (!uac1->int_ep->enabled) + return 0; + + if (atomic_inc_return(&uac1->int_count) > UAC1_DEF_INT_REQ_NUM) { + atomic_dec(&uac1->int_count); + return 0; + } + + req = usb_ep_alloc_request(uac1->int_ep, GFP_ATOMIC); + if (req == NULL) { + ret = -ENOMEM; + goto err_dec_int_count; + } + + msg = kmalloc(sizeof(*msg), GFP_ATOMIC); + if (msg == NULL) { + ret = -ENOMEM; + goto err_free_request; + } + + msg->bStatusType = UAC1_STATUS_TYPE_IRQ_PENDING + | UAC1_STATUS_TYPE_ORIG_AUDIO_CONTROL_IF; + msg->bOriginator = unit_id; + + req->length = sizeof(*msg); + req->buf = msg; + req->context = audio; + req->complete = audio_notify_complete; + + ret = usb_ep_queue(uac1->int_ep, req, GFP_ATOMIC); + + if (ret) + goto err_free_msg; + + return 0; + +err_free_msg: + kfree(msg); +err_free_request: + usb_ep_free_request(uac1->int_ep, req); +err_dec_int_count: + atomic_dec(&uac1->int_count); + + return ret; +} + +static int +in_rq_cur(struct usb_function *fn, const struct usb_ctrlrequest *cr) +{ + struct usb_request *req = fn->config->cdev->req; + struct g_audio *audio = func_to_g_audio(fn); + struct f_uac1_opts *opts = g_audio_to_uac1_opts(audio); + u16 w_length = le16_to_cpu(cr->wLength); + u16 w_index = le16_to_cpu(cr->wIndex); + u16 w_value = le16_to_cpu(cr->wValue); + u8 entity_id = (w_index >> 8) & 0xff; + u8 control_selector = w_value >> 8; + int value = -EOPNOTSUPP; + + if ((FUIN_EN(opts) && (entity_id == USB_IN_FU_ID)) || + (FUOUT_EN(opts) && (entity_id == USB_OUT_FU_ID))) { + unsigned int is_playback = 0; + + if (FUIN_EN(opts) && (entity_id == USB_IN_FU_ID)) + is_playback = 1; + + if (control_selector == UAC_FU_MUTE) { + unsigned int mute; + + u_audio_get_mute(audio, is_playback, &mute); + + *(u8 *)req->buf = mute; + value = min_t(unsigned int, w_length, 1); + } else if (control_selector == UAC_FU_VOLUME) { + __le16 c; + s16 volume; + + u_audio_get_volume(audio, is_playback, &volume); + + c = cpu_to_le16(volume); + + value = min_t(unsigned int, w_length, sizeof(c)); + memcpy(req->buf, &c, value); + } else { + dev_err(&audio->gadget->dev, + "%s:%d control_selector=%d TODO!\n", + __func__, __LINE__, control_selector); + } + } else { + dev_err(&audio->gadget->dev, + "%s:%d entity_id=%d control_selector=%d TODO!\n", + __func__, __LINE__, entity_id, control_selector); + } + + return value; +} + +static int +in_rq_min(struct usb_function *fn, const struct usb_ctrlrequest *cr) +{ + struct usb_request *req = fn->config->cdev->req; + struct g_audio *audio = func_to_g_audio(fn); + struct f_uac1_opts *opts = g_audio_to_uac1_opts(audio); + u16 w_length = le16_to_cpu(cr->wLength); + u16 w_index = le16_to_cpu(cr->wIndex); + u16 w_value = le16_to_cpu(cr->wValue); + u8 entity_id = (w_index >> 8) & 0xff; + u8 control_selector = w_value >> 8; + int value = -EOPNOTSUPP; + + if ((FUIN_EN(opts) && (entity_id == USB_IN_FU_ID)) || + (FUOUT_EN(opts) && (entity_id == USB_OUT_FU_ID))) { + unsigned int is_playback = 0; + + if (FUIN_EN(opts) && (entity_id == USB_IN_FU_ID)) + is_playback = 1; + + if (control_selector == UAC_FU_VOLUME) { + __le16 r; + s16 min_db; + + if (is_playback) + min_db = opts->p_volume_min; + else + min_db = opts->c_volume_min; + + r = cpu_to_le16(min_db); + + value = min_t(unsigned int, w_length, sizeof(r)); + memcpy(req->buf, &r, value); + } else { + dev_err(&audio->gadget->dev, + "%s:%d control_selector=%d TODO!\n", + __func__, __LINE__, control_selector); + } + } else { + dev_err(&audio->gadget->dev, + "%s:%d entity_id=%d control_selector=%d TODO!\n", + __func__, __LINE__, entity_id, control_selector); + } + + return value; +} + +static int +in_rq_max(struct usb_function *fn, const struct usb_ctrlrequest *cr) +{ + struct usb_request *req = fn->config->cdev->req; + struct g_audio *audio = func_to_g_audio(fn); + struct f_uac1_opts *opts = g_audio_to_uac1_opts(audio); + u16 w_length = le16_to_cpu(cr->wLength); + u16 w_index = le16_to_cpu(cr->wIndex); + u16 w_value = le16_to_cpu(cr->wValue); + u8 entity_id = (w_index >> 8) & 0xff; + u8 control_selector = w_value >> 8; + int value = -EOPNOTSUPP; + + if ((FUIN_EN(opts) && (entity_id == USB_IN_FU_ID)) || + (FUOUT_EN(opts) && (entity_id == USB_OUT_FU_ID))) { + unsigned int is_playback = 0; + + if (FUIN_EN(opts) && (entity_id == USB_IN_FU_ID)) + is_playback = 1; + + if (control_selector == UAC_FU_VOLUME) { + __le16 r; + s16 max_db; + + if (is_playback) + max_db = opts->p_volume_max; + else + max_db = opts->c_volume_max; + + r = cpu_to_le16(max_db); + + value = min_t(unsigned int, w_length, sizeof(r)); + memcpy(req->buf, &r, value); + } else { + dev_err(&audio->gadget->dev, + "%s:%d control_selector=%d TODO!\n", + __func__, __LINE__, control_selector); + } + } else { + dev_err(&audio->gadget->dev, + "%s:%d entity_id=%d control_selector=%d TODO!\n", + __func__, __LINE__, entity_id, control_selector); + } + + return value; +} + +static int +in_rq_res(struct usb_function *fn, const struct usb_ctrlrequest *cr) +{ + struct usb_request *req = fn->config->cdev->req; + struct g_audio *audio = func_to_g_audio(fn); + struct f_uac1_opts *opts = g_audio_to_uac1_opts(audio); + u16 w_length = le16_to_cpu(cr->wLength); + u16 w_index = le16_to_cpu(cr->wIndex); + u16 w_value = le16_to_cpu(cr->wValue); + u8 entity_id = (w_index >> 8) & 0xff; + u8 control_selector = w_value >> 8; + int value = -EOPNOTSUPP; + + if ((FUIN_EN(opts) && (entity_id == USB_IN_FU_ID)) || + (FUOUT_EN(opts) && (entity_id == USB_OUT_FU_ID))) { + unsigned int is_playback = 0; + + if (FUIN_EN(opts) && (entity_id == USB_IN_FU_ID)) + is_playback = 1; + + if (control_selector == UAC_FU_VOLUME) { + __le16 r; + s16 res_db; + + if (is_playback) + res_db = opts->p_volume_res; + else + res_db = opts->c_volume_res; + + r = cpu_to_le16(res_db); + + value = min_t(unsigned int, w_length, sizeof(r)); + memcpy(req->buf, &r, value); + } else { + dev_err(&audio->gadget->dev, + "%s:%d control_selector=%d TODO!\n", + __func__, __LINE__, control_selector); + } + } else { + dev_err(&audio->gadget->dev, + "%s:%d entity_id=%d control_selector=%d TODO!\n", + __func__, __LINE__, entity_id, control_selector); + } + + return value; +} + +static void +out_rq_cur_complete(struct usb_ep *ep, struct usb_request *req) +{ + struct g_audio *audio = req->context; + struct usb_composite_dev *cdev = audio->func.config->cdev; + struct f_uac1_opts *opts = g_audio_to_uac1_opts(audio); + struct f_uac1 *uac1 = func_to_uac1(&audio->func); + struct usb_ctrlrequest *cr = &uac1->setup_cr; + u16 w_index = le16_to_cpu(cr->wIndex); + u16 w_value = le16_to_cpu(cr->wValue); + u8 entity_id = (w_index >> 8) & 0xff; + u8 control_selector = w_value >> 8; + + if (req->status != 0) { + dev_dbg(&cdev->gadget->dev, "completion err %d\n", req->status); + return; + } + + if ((FUIN_EN(opts) && (entity_id == USB_IN_FU_ID)) || + (FUOUT_EN(opts) && (entity_id == USB_OUT_FU_ID))) { + unsigned int is_playback = 0; + + if (FUIN_EN(opts) && (entity_id == USB_IN_FU_ID)) + is_playback = 1; + + if (control_selector == UAC_FU_MUTE) { + u8 mute = *(u8 *)req->buf; + + u_audio_set_mute(audio, is_playback, mute); + + return; + } else if (control_selector == UAC_FU_VOLUME) { + __le16 *c = req->buf; + s16 volume; + + volume = le16_to_cpu(*c); + u_audio_set_volume(audio, is_playback, volume); + + return; + } else { + dev_err(&audio->gadget->dev, + "%s:%d control_selector=%d TODO!\n", + __func__, __LINE__, control_selector); + usb_ep_set_halt(ep); + } + } else { + dev_err(&audio->gadget->dev, + "%s:%d entity_id=%d control_selector=%d TODO!\n", + __func__, __LINE__, entity_id, control_selector); + usb_ep_set_halt(ep); + + } +} + +static int +out_rq_cur(struct usb_function *fn, const struct usb_ctrlrequest *cr) +{ + struct usb_request *req = fn->config->cdev->req; + struct g_audio *audio = func_to_g_audio(fn); + struct f_uac1_opts *opts = g_audio_to_uac1_opts(audio); + struct f_uac1 *uac1 = func_to_uac1(&audio->func); + u16 w_length = le16_to_cpu(cr->wLength); + u16 w_index = le16_to_cpu(cr->wIndex); + u16 w_value = le16_to_cpu(cr->wValue); + u8 entity_id = (w_index >> 8) & 0xff; + u8 control_selector = w_value >> 8; + + if ((FUIN_EN(opts) && (entity_id == USB_IN_FU_ID)) || + (FUOUT_EN(opts) && (entity_id == USB_OUT_FU_ID))) { + memcpy(&uac1->setup_cr, cr, sizeof(*cr)); + req->context = audio; + req->complete = out_rq_cur_complete; + + return w_length; + } else { + dev_err(&audio->gadget->dev, + "%s:%d entity_id=%d control_selector=%d TODO!\n", + __func__, __LINE__, entity_id, control_selector); + } + return -EOPNOTSUPP; +} + +static int ac_rq_in(struct usb_function *f, + const struct usb_ctrlrequest *ctrl) +{ + struct usb_composite_dev *cdev = f->config->cdev; + int value = -EOPNOTSUPP; + u8 ep = ((le16_to_cpu(ctrl->wIndex) >> 8) & 0xFF); + u16 len = le16_to_cpu(ctrl->wLength); + u16 w_value = le16_to_cpu(ctrl->wValue); + + DBG(cdev, "bRequest 0x%x, w_value 0x%04x, len %d, endpoint %d\n", + ctrl->bRequest, w_value, len, ep); + + switch (ctrl->bRequest) { + case UAC_GET_CUR: + return in_rq_cur(f, ctrl); + case UAC_GET_MIN: + return in_rq_min(f, ctrl); + case UAC_GET_MAX: + return in_rq_max(f, ctrl); + case UAC_GET_RES: + return in_rq_res(f, ctrl); + case UAC_GET_MEM: + break; + case UAC_GET_STAT: + value = len; + break; + default: + break; + } + + return value; +} + static int audio_set_endpoint_req(struct usb_function *f, const struct usb_ctrlrequest *ctrl) { @@ -383,7 +788,13 @@ f_audio_setup(struct usb_function *f, const struct usb_ctrlrequest *ctrl) case USB_DIR_IN | USB_TYPE_CLASS | USB_RECIP_ENDPOINT: value = audio_get_endpoint_req(f, ctrl); break; - + case USB_DIR_OUT | USB_TYPE_CLASS | USB_RECIP_INTERFACE: + if (ctrl->bRequest == UAC_SET_CUR) + value = out_rq_cur(f, ctrl); + break; + case USB_DIR_IN | USB_TYPE_CLASS | USB_RECIP_INTERFACE: + value = ac_rq_in(f, ctrl); + break; default: ERROR(cdev, "invalid control req%02x.%02x v%04x i%04x l%d\n", ctrl->bRequestType, ctrl->bRequest, @@ -411,6 +822,7 @@ static int f_audio_set_alt(struct usb_function *f, unsigned intf, unsigned alt) struct usb_composite_dev *cdev = f->config->cdev; struct usb_gadget *gadget = cdev->gadget; struct device *dev = &gadget->dev; + struct g_audio *audio = func_to_g_audio(f); struct f_uac1 *uac1 = func_to_uac1(f); int ret = 0; @@ -426,6 +838,14 @@ static int f_audio_set_alt(struct usb_function *f, unsigned intf, unsigned alt) dev_err(dev, "%s:%d Error!\n", __func__, __LINE__); return -EINVAL; } + + /* restart interrupt endpoint */ + if (uac1->int_ep) { + usb_ep_disable(uac1->int_ep); + config_ep_by_speed(gadget, &audio->func, uac1->int_ep); + usb_ep_enable(uac1->int_ep); + } + return 0; } @@ -481,10 +901,33 @@ static void f_audio_disable(struct usb_function *f) u_audio_stop_playback(&uac1->g_audio); u_audio_stop_capture(&uac1->g_audio); + if (uac1->int_ep) + usb_ep_disable(uac1->int_ep); } /*-------------------------------------------------------------------------*/ +static struct uac_feature_unit_descriptor *build_fu_desc(int chmask) +{ + struct uac_feature_unit_descriptor *fu_desc; + int channels = num_channels(chmask); + int fu_desc_size = UAC_DT_FEATURE_UNIT_SIZE(channels); + fu_desc = kzalloc(fu_desc_size, GFP_KERNEL); + if (!fu_desc) + return NULL; + + fu_desc->bLength = fu_desc_size; + fu_desc->bDescriptorType = USB_DT_CS_INTERFACE; + + fu_desc->bDescriptorSubtype = UAC_FEATURE_UNIT; + fu_desc->bControlSize = 2; + + /* bUnitID, bSourceID and bmaControls will be defined later */ + + return fu_desc; +} + +/* B.3.2 Class-Specific AC Interface Descriptor */ static struct uac1_ac_header_descriptor *build_ac_header_desc(struct f_uac1_opts *opts) { @@ -530,9 +973,23 @@ static void setup_descriptor(struct f_uac1_opts *opts) io_out_ot_desc.bTerminalID = i++; if (EPIN_EN(opts)) usb_in_ot_desc.bTerminalID = i++; + if (FUOUT_EN(opts)) + out_feature_unit_desc->bUnitID = i++; + if (FUIN_EN(opts)) + in_feature_unit_desc->bUnitID = i++; - usb_in_ot_desc.bSourceID = io_in_it_desc.bTerminalID; - io_out_ot_desc.bSourceID = usb_out_it_desc.bTerminalID; + if (FUIN_EN(opts)) { + usb_in_ot_desc.bSourceID = in_feature_unit_desc->bUnitID; + in_feature_unit_desc->bSourceID = io_in_it_desc.bTerminalID; + } else { + usb_in_ot_desc.bSourceID = io_in_it_desc.bTerminalID; + } + if (FUOUT_EN(opts)) { + io_out_ot_desc.bSourceID = out_feature_unit_desc->bUnitID; + out_feature_unit_desc->bSourceID = usb_out_it_desc.bTerminalID; + } else { + io_out_ot_desc.bSourceID = usb_out_it_desc.bTerminalID; + } as_out_header_desc.bTerminalLink = usb_out_it_desc.bTerminalID; as_in_header_desc.bTerminalLink = usb_in_ot_desc.bTerminalID; @@ -544,6 +1001,8 @@ static void setup_descriptor(struct f_uac1_opts *opts) len += sizeof(usb_in_ot_desc); len += sizeof(io_in_it_desc); + if (FUIN_EN(opts)) + len += in_feature_unit_desc->bLength; ac_header_desc->wTotalLength = cpu_to_le16(len); } if (EPOUT_EN(opts)) { @@ -551,6 +1010,8 @@ static void setup_descriptor(struct f_uac1_opts *opts) len += sizeof(usb_out_it_desc); len += sizeof(io_out_ot_desc); + if (FUOUT_EN(opts)) + len += out_feature_unit_desc->bLength; ac_header_desc->wTotalLength = cpu_to_le16(len); } @@ -561,13 +1022,20 @@ static void setup_descriptor(struct f_uac1_opts *opts) if (EPOUT_EN(opts)) { f_audio_desc[i++] = USBDHDR(&usb_out_it_desc); f_audio_desc[i++] = USBDHDR(&io_out_ot_desc); + if (FUOUT_EN(opts)) + f_audio_desc[i++] = USBDHDR(out_feature_unit_desc); } if (EPIN_EN(opts)) { f_audio_desc[i++] = USBDHDR(&io_in_it_desc); f_audio_desc[i++] = USBDHDR(&usb_in_ot_desc); + if (FUIN_EN(opts)) + f_audio_desc[i++] = USBDHDR(in_feature_unit_desc); } + if (FUOUT_EN(opts) || FUIN_EN(opts)) + f_audio_desc[i++] = USBDHDR(&ac_int_ep_desc); + if (EPOUT_EN(opts)) { f_audio_desc[i++] = USBDHDR(&as_out_interface_alt_0_desc); f_audio_desc[i++] = USBDHDR(&as_out_interface_alt_1_desc); @@ -614,6 +1082,28 @@ static int f_audio_validate_opts(struct g_audio *audio, struct device *dev) return -EINVAL; } + if (opts->p_volume_max <= opts->p_volume_min) { + dev_err(dev, "Error: incorrect playback volume max/min\n"); + return -EINVAL; + } else if (opts->c_volume_max <= opts->c_volume_min) { + dev_err(dev, "Error: incorrect capture volume max/min\n"); + return -EINVAL; + } else if (opts->p_volume_res <= 0) { + dev_err(dev, "Error: negative/zero playback volume resolution\n"); + return -EINVAL; + } else if (opts->c_volume_res <= 0) { + dev_err(dev, "Error: negative/zero capture volume resolution\n"); + return -EINVAL; + } + + if ((opts->p_volume_max - opts->p_volume_min) % opts->p_volume_res) { + dev_err(dev, "Error: incorrect playback volume resolution\n"); + return -EINVAL; + } else if ((opts->c_volume_max - opts->c_volume_min) % opts->c_volume_res) { + dev_err(dev, "Error: incorrect capture volume resolution\n"); + return -EINVAL; + } + return 0; } @@ -647,6 +1137,21 @@ static int f_audio_bind(struct usb_configuration *c, struct usb_function *f) if (!ac_header_desc) return -ENOMEM; + if (FUOUT_EN(audio_opts)) { + out_feature_unit_desc = build_fu_desc(audio_opts->c_chmask); + if (!out_feature_unit_desc) { + status = -ENOMEM; + goto fail; + } + } + if (FUIN_EN(audio_opts)) { + in_feature_unit_desc = build_fu_desc(audio_opts->p_chmask); + if (!in_feature_unit_desc) { + status = -ENOMEM; + goto err_free_fu; + } + } + ac_interface_desc.iInterface = us[STR_AC_IF].id; usb_out_it_desc.iTerminal = us[STR_USB_OUT_IT].id; usb_out_it_desc.iChannelNames = us[STR_USB_OUT_IT_CH_NAMES].id; @@ -659,6 +1164,21 @@ static int f_audio_bind(struct usb_configuration *c, struct usb_function *f) as_in_interface_alt_0_desc.iInterface = us[STR_AS_IN_IF_ALT0].id; as_in_interface_alt_1_desc.iInterface = us[STR_AS_IN_IF_ALT1].id; + if (FUOUT_EN(audio_opts)) { + u8 *i_feature; + + i_feature = (u8 *)out_feature_unit_desc + + out_feature_unit_desc->bLength - 1; + *i_feature = us[STR_FU_OUT].id; + } + if (FUIN_EN(audio_opts)) { + u8 *i_feature; + + i_feature = (u8 *)in_feature_unit_desc + + in_feature_unit_desc->bLength - 1; + *i_feature = us[STR_FU_IN].id; + } + /* Set channel numbers */ usb_out_it_desc.bNrChannels = num_channels(audio_opts->c_chmask); usb_out_it_desc.wChannelConfig = cpu_to_le16(audio_opts->c_chmask); @@ -671,6 +1191,27 @@ static int f_audio_bind(struct usb_configuration *c, struct usb_function *f) as_in_type_i_desc.bSubframeSize = audio_opts->p_ssize; as_in_type_i_desc.bBitResolution = audio_opts->p_ssize * 8; + if (FUOUT_EN(audio_opts)) { + __le16 *bma = (__le16 *)&out_feature_unit_desc->bmaControls[0]; + u32 control = 0; + + if (audio_opts->c_mute_present) + control |= UAC_FU_MUTE; + if (audio_opts->c_volume_present) + control |= UAC_FU_VOLUME; + *bma = cpu_to_le16(control); + } + if (FUIN_EN(audio_opts)) { + __le16 *bma = (__le16 *)&in_feature_unit_desc->bmaControls[0]; + u32 control = 0; + + if (audio_opts->p_mute_present) + control |= UAC_FU_MUTE; + if (audio_opts->p_volume_present) + control |= UAC_FU_VOLUME; + *bma = cpu_to_le16(control); + } + /* Set sample rates */ rate = audio_opts->c_srate; sam_freq = as_out_type_i_desc.tSamFreq[0]; @@ -682,7 +1223,7 @@ static int f_audio_bind(struct usb_configuration *c, struct usb_function *f) /* allocate instance-specific interface IDs, and patch descriptors */ status = usb_interface_id(c, f); if (status < 0) - goto fail; + goto err_free_fu; ac_interface_desc.bInterfaceNumber = status; uac1->ac_intf = status; uac1->ac_alt = 0; @@ -692,7 +1233,7 @@ static int f_audio_bind(struct usb_configuration *c, struct usb_function *f) if (EPOUT_EN(audio_opts)) { status = usb_interface_id(c, f); if (status < 0) - goto fail; + goto err_free_fu; as_out_interface_alt_0_desc.bInterfaceNumber = status; as_out_interface_alt_1_desc.bInterfaceNumber = status; ac_header_desc->baInterfaceNr[ba_iface_id++] = status; @@ -703,7 +1244,7 @@ static int f_audio_bind(struct usb_configuration *c, struct usb_function *f) if (EPIN_EN(audio_opts)) { status = usb_interface_id(c, f); if (status < 0) - goto fail; + goto err_free_fu; as_in_interface_alt_0_desc.bInterfaceNumber = status; as_in_interface_alt_1_desc.bInterfaceNumber = status; ac_header_desc->baInterfaceNr[ba_iface_id++] = status; @@ -715,11 +1256,24 @@ static int f_audio_bind(struct usb_configuration *c, struct usb_function *f) status = -ENODEV; + ac_interface_desc.bNumEndpoints = 0; + + /* allocate AC interrupt endpoint */ + if (FUOUT_EN(audio_opts) || FUIN_EN(audio_opts)) { + ep = usb_ep_autoconfig(cdev->gadget, &ac_int_ep_desc); + if (!ep) + goto err_free_fu; + uac1->int_ep = ep; + uac1->int_ep->desc = &ac_int_ep_desc; + + ac_interface_desc.bNumEndpoints = 1; + } + /* allocate instance-specific endpoints */ if (EPOUT_EN(audio_opts)) { ep = usb_ep_autoconfig(cdev->gadget, &as_out_ep_desc); if (!ep) - goto fail; + goto err_free_fu; audio->out_ep = ep; audio->out_ep->desc = &as_out_ep_desc; } @@ -727,7 +1281,7 @@ static int f_audio_bind(struct usb_configuration *c, struct usb_function *f) if (EPIN_EN(audio_opts)) { ep = usb_ep_autoconfig(cdev->gadget, &as_in_ep_desc); if (!ep) - goto fail; + goto err_free_fu; audio->in_ep = ep; audio->in_ep->desc = &as_in_ep_desc; } @@ -738,17 +1292,37 @@ static int f_audio_bind(struct usb_configuration *c, struct usb_function *f) status = usb_assign_descriptors(f, f_audio_desc, f_audio_desc, NULL, NULL); if (status) - goto fail; + goto err_free_fu; audio->out_ep_maxpsize = le16_to_cpu(as_out_ep_desc.wMaxPacketSize); audio->in_ep_maxpsize = le16_to_cpu(as_in_ep_desc.wMaxPacketSize); audio->params.c_chmask = audio_opts->c_chmask; audio->params.c_srate = audio_opts->c_srate; audio->params.c_ssize = audio_opts->c_ssize; + if (FUIN_EN(audio_opts)) { + audio->params.p_fu.id = USB_IN_FU_ID; + audio->params.p_fu.mute_present = audio_opts->p_mute_present; + audio->params.p_fu.volume_present = + audio_opts->p_volume_present; + audio->params.p_fu.volume_min = audio_opts->p_volume_min; + audio->params.p_fu.volume_max = audio_opts->p_volume_max; + audio->params.p_fu.volume_res = audio_opts->p_volume_res; + } audio->params.p_chmask = audio_opts->p_chmask; audio->params.p_srate = audio_opts->p_srate; audio->params.p_ssize = audio_opts->p_ssize; + if (FUOUT_EN(audio_opts)) { + audio->params.c_fu.id = USB_OUT_FU_ID; + audio->params.c_fu.mute_present = audio_opts->c_mute_present; + audio->params.c_fu.volume_present = + audio_opts->c_volume_present; + audio->params.c_fu.volume_min = audio_opts->c_volume_min; + audio->params.c_fu.volume_max = audio_opts->c_volume_max; + audio->params.c_fu.volume_res = audio_opts->c_volume_res; + } audio->params.req_number = audio_opts->req_number; + if (FUOUT_EN(audio_opts) || FUIN_EN(audio_opts)) + audio->notify = audio_notify; status = g_audio_setup(audio, "UAC1_PCM", "UAC1_Gadget"); if (status) @@ -758,6 +1332,11 @@ static int f_audio_bind(struct usb_configuration *c, struct usb_function *f) err_card_register: usb_free_all_descriptors(f); +err_free_fu: + kfree(out_feature_unit_desc); + out_feature_unit_desc = NULL; + kfree(in_feature_unit_desc); + in_feature_unit_desc = NULL; fail: kfree(ac_header_desc); ac_header_desc = NULL; @@ -783,7 +1362,15 @@ static struct configfs_item_operations f_uac1_item_ops = { .release = f_uac1_attr_release, }; -#define UAC1_ATTRIBUTE(name) \ +#define uac1_kstrtou32 kstrtou32 +#define uac1_kstrtos16 kstrtos16 +#define uac1_kstrtobool(s, base, res) kstrtobool((s), (res)) + +static const char *u32_fmt = "%u\n"; +static const char *s16_fmt = "%hd\n"; +static const char *bool_fmt = "%u\n"; + +#define UAC1_ATTRIBUTE(type, name) \ static ssize_t f_uac1_opts_##name##_show( \ struct config_item *item, \ char *page) \ @@ -792,7 +1379,7 @@ static ssize_t f_uac1_opts_##name##_show( \ int result; \ \ mutex_lock(&opts->lock); \ - result = sprintf(page, "%u\n", opts->name); \ + result = sprintf(page, type##_fmt, opts->name); \ mutex_unlock(&opts->lock); \ \ return result; \ @@ -804,7 +1391,7 @@ static ssize_t f_uac1_opts_##name##_store( \ { \ struct f_uac1_opts *opts = to_f_uac1_opts(item); \ int ret; \ - u32 num; \ + type num; \ \ mutex_lock(&opts->lock); \ if (opts->refcnt) { \ @@ -812,7 +1399,7 @@ static ssize_t f_uac1_opts_##name##_store( \ goto end; \ } \ \ - ret = kstrtou32(page, 0, &num); \ + ret = uac1_kstrto##type(page, 0, &num); \ if (ret) \ goto end; \ \ @@ -826,13 +1413,25 @@ end: \ \ CONFIGFS_ATTR(f_uac1_opts_, name) -UAC1_ATTRIBUTE(c_chmask); -UAC1_ATTRIBUTE(c_srate); -UAC1_ATTRIBUTE(c_ssize); -UAC1_ATTRIBUTE(p_chmask); -UAC1_ATTRIBUTE(p_srate); -UAC1_ATTRIBUTE(p_ssize); -UAC1_ATTRIBUTE(req_number); +UAC1_ATTRIBUTE(u32, c_chmask); +UAC1_ATTRIBUTE(u32, c_srate); +UAC1_ATTRIBUTE(u32, c_ssize); +UAC1_ATTRIBUTE(u32, p_chmask); +UAC1_ATTRIBUTE(u32, p_srate); +UAC1_ATTRIBUTE(u32, p_ssize); +UAC1_ATTRIBUTE(u32, req_number); + +UAC1_ATTRIBUTE(bool, p_mute_present); +UAC1_ATTRIBUTE(bool, p_volume_present); +UAC1_ATTRIBUTE(s16, p_volume_min); +UAC1_ATTRIBUTE(s16, p_volume_max); +UAC1_ATTRIBUTE(s16, p_volume_res); + +UAC1_ATTRIBUTE(bool, c_mute_present); +UAC1_ATTRIBUTE(bool, c_volume_present); +UAC1_ATTRIBUTE(s16, c_volume_min); +UAC1_ATTRIBUTE(s16, c_volume_max); +UAC1_ATTRIBUTE(s16, c_volume_res); static struct configfs_attribute *f_uac1_attrs[] = { &f_uac1_opts_attr_c_chmask, @@ -842,6 +1441,19 @@ static struct configfs_attribute *f_uac1_attrs[] = { &f_uac1_opts_attr_p_srate, &f_uac1_opts_attr_p_ssize, &f_uac1_opts_attr_req_number, + + &f_uac1_opts_attr_p_mute_present, + &f_uac1_opts_attr_p_volume_present, + &f_uac1_opts_attr_p_volume_min, + &f_uac1_opts_attr_p_volume_max, + &f_uac1_opts_attr_p_volume_res, + + &f_uac1_opts_attr_c_mute_present, + &f_uac1_opts_attr_c_volume_present, + &f_uac1_opts_attr_c_volume_min, + &f_uac1_opts_attr_c_volume_max, + &f_uac1_opts_attr_c_volume_res, + NULL, }; @@ -879,6 +1491,19 @@ static struct usb_function_instance *f_audio_alloc_inst(void) opts->p_chmask = UAC1_DEF_PCHMASK; opts->p_srate = UAC1_DEF_PSRATE; opts->p_ssize = UAC1_DEF_PSSIZE; + + opts->p_mute_present = UAC1_DEF_MUTE_PRESENT; + opts->p_volume_present = UAC1_DEF_VOLUME_PRESENT; + opts->p_volume_min = UAC1_DEF_MIN_DB; + opts->p_volume_max = UAC1_DEF_MAX_DB; + opts->p_volume_res = UAC1_DEF_RES_DB; + + opts->c_mute_present = UAC1_DEF_MUTE_PRESENT; + opts->c_volume_present = UAC1_DEF_VOLUME_PRESENT; + opts->c_volume_min = UAC1_DEF_MIN_DB; + opts->c_volume_max = UAC1_DEF_MAX_DB; + opts->c_volume_res = UAC1_DEF_RES_DB; + opts->req_number = UAC1_DEF_REQ_NUM; return &opts->func_inst; } @@ -903,6 +1528,11 @@ static void f_audio_unbind(struct usb_configuration *c, struct usb_function *f) g_audio_cleanup(audio); usb_free_all_descriptors(f); + kfree(out_feature_unit_desc); + out_feature_unit_desc = NULL; + kfree(in_feature_unit_desc); + in_feature_unit_desc = NULL; + kfree(ac_header_desc); ac_header_desc = NULL; diff --git a/drivers/usb/gadget/function/u_uac1.h b/drivers/usb/gadget/function/u_uac1.h index 39c0e29e1b46..589fae861141 100644 --- a/drivers/usb/gadget/function/u_uac1.h +++ b/drivers/usb/gadget/function/u_uac1.h @@ -18,6 +18,13 @@ #define UAC1_DEF_PSRATE 48000 #define UAC1_DEF_PSSIZE 2 #define UAC1_DEF_REQ_NUM 2 +#define UAC1_DEF_INT_REQ_NUM 10 + +#define UAC1_DEF_MUTE_PRESENT 1 +#define UAC1_DEF_VOLUME_PRESENT 1 +#define UAC1_DEF_MIN_DB (-100*256) /* -100 dB */ +#define UAC1_DEF_MAX_DB 0 /* 0 dB */ +#define UAC1_DEF_RES_DB (1*256) /* 1 dB */ struct f_uac1_opts { @@ -28,6 +35,19 @@ struct f_uac1_opts { int p_chmask; int p_srate; int p_ssize; + + bool p_mute_present; + bool p_volume_present; + s16 p_volume_min; + s16 p_volume_max; + s16 p_volume_res; + + bool c_mute_present; + bool c_volume_present; + s16 c_volume_min; + s16 c_volume_max; + s16 c_volume_res; + int req_number; unsigned bound:1; From b9c4cbbf7a4b3fb01d7938cce29075861b3b3094 Mon Sep 17 00:00:00 2001 From: Hu Haowen Date: Thu, 5 Aug 2021 12:01:46 +0800 Subject: [PATCH 07/91] UPSTREAM: docs: usb: fix malformed table The tables are separated with tabs and spaces mixed together, leading to malformation. Changed the characters all into spaces to solve this issue. Signed-off-by: Hu Haowen Link: https://lore.kernel.org/r/20210805040146.121526-1-src.res@email.cn Signed-off-by: Greg Kroah-Hartman Bug: 235196743 (cherry picked from commit 9c0edd5649a26e380ed2e687a20f7b301a66c746) Change-Id: I3a7edcb21497cd143c2e7347c4dd796eec989218 Signed-off-by: Luiz Matheus --- Documentation/usb/gadget-testing.rst | 84 ++++++++++++++-------------- 1 file changed, 42 insertions(+), 42 deletions(-) diff --git a/Documentation/usb/gadget-testing.rst b/Documentation/usb/gadget-testing.rst index fe1a0e3a4eee..58781a268890 100644 --- a/Documentation/usb/gadget-testing.rst +++ b/Documentation/usb/gadget-testing.rst @@ -724,28 +724,28 @@ Function-specific configfs interface The function name to use when creating the function directory is "uac2". The uac2 function provides these attributes in its function directory: - =============== ==================================================== - c_chmask capture channel mask - c_srate capture sampling rate - c_ssize capture sample size (bytes) - c_sync capture synchronization type (async/adaptive) - c_mute_present capture mute control enable - c_volume_present capture volume control enable - c_volume_min capture volume control min value (in 1/256 dB) - c_volume_max capture volume control max value (in 1/256 dB) - c_volume_res capture volume control resolution (in 1/256 dB) - fb_max maximum extra bandwidth in async mode - p_chmask playback channel mask - p_srate playback sampling rate - p_ssize playback sample size (bytes) - p_mute_present playback mute control enable - p_volume_present playback volume control enable - p_volume_min playback volume control min value (in 1/256 dB) - p_volume_max playback volume control max value (in 1/256 dB) - p_volume_res playback volume control resolution (in 1/256 dB) - req_number the number of pre-allocated request for both capture - and playback - =============== ==================================================== + ================ ==================================================== + c_chmask capture channel mask + c_srate capture sampling rate + c_ssize capture sample size (bytes) + c_sync capture synchronization type (async/adaptive) + c_mute_present capture mute control enable + c_volume_present capture volume control enable + c_volume_min capture volume control min value (in 1/256 dB) + c_volume_max capture volume control max value (in 1/256 dB) + c_volume_res capture volume control resolution (in 1/256 dB) + fb_max maximum extra bandwidth in async mode + p_chmask playback channel mask + p_srate playback sampling rate + p_ssize playback sample size (bytes) + p_mute_present playback mute control enable + p_volume_present playback volume control enable + p_volume_min playback volume control min value (in 1/256 dB) + p_volume_max playback volume control max value (in 1/256 dB) + p_volume_res playback volume control resolution (in 1/256 dB) + req_number the number of pre-allocated request for both capture + and playback + ================ ==================================================== The attributes have sane default values. @@ -915,26 +915,26 @@ Function-specific configfs interface The function name to use when creating the function directory is "uac1". The uac1 function provides these attributes in its function directory: - ========== ==================================================== - c_chmask capture channel mask - c_srate capture sampling rate - c_ssize capture sample size (bytes) - c_mute_present capture mute control enable - c_volume_present capture volume control enable - c_volume_min capture volume control min value (in 1/256 dB) - c_volume_max capture volume control max value (in 1/256 dB) - c_volume_res capture volume control resolution (in 1/256 dB) - p_chmask playback channel mask - p_srate playback sampling rate - p_ssize playback sample size (bytes) - p_mute_present playback mute control enable - p_volume_present playback volume control enable - p_volume_min playback volume control min value (in 1/256 dB) - p_volume_max playback volume control max value (in 1/256 dB) - p_volume_res playback volume control resolution (in 1/256 dB) - req_number the number of pre-allocated request for both capture - and playback - ========== ==================================================== + ================ ==================================================== + c_chmask capture channel mask + c_srate capture sampling rate + c_ssize capture sample size (bytes) + c_mute_present capture mute control enable + c_volume_present capture volume control enable + c_volume_min capture volume control min value (in 1/256 dB) + c_volume_max capture volume control max value (in 1/256 dB) + c_volume_res capture volume control resolution (in 1/256 dB) + p_chmask playback channel mask + p_srate playback sampling rate + p_ssize playback sample size (bytes) + p_mute_present playback mute control enable + p_volume_present playback volume control enable + p_volume_min playback volume control min value (in 1/256 dB) + p_volume_max playback volume control max value (in 1/256 dB) + p_volume_res playback volume control resolution (in 1/256 dB) + req_number the number of pre-allocated request for both capture + and playback + ================ ==================================================== The attributes have sane default values. From bf46bbe087ba87231d051e9395fe68f9f317a32a Mon Sep 17 00:00:00 2001 From: Pavel Hofman Date: Tue, 17 Aug 2021 12:05:55 +0200 Subject: [PATCH 08/91] UPSTREAM: usb: gadget: f_uac1: fixing inconsistent indenting Fixing inconsistent indenting identified by kernel test robot. Signed-off-by: Pavel Hofman Acked-By: Felipe Balbi Link: https://lore.kernel.org/r/20210817100555.4437-1-pavel.hofman@ivitera.com Signed-off-by: Greg Kroah-Hartman Bug: 235196743 (cherry picked from commit 1bc220835526ae076eecfb7ed513f80f22cf840d) Change-Id: I3a34ed86550709247818245eca45f0e50a5d099b Signed-off-by: Luiz Matheus --- drivers/usb/gadget/function/f_uac1.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/drivers/usb/gadget/function/f_uac1.c b/drivers/usb/gadget/function/f_uac1.c index 3b3db1a8df75..5b3502df4e13 100644 --- a/drivers/usb/gadget/function/f_uac1.c +++ b/drivers/usb/gadget/function/f_uac1.c @@ -1084,24 +1084,24 @@ static int f_audio_validate_opts(struct g_audio *audio, struct device *dev) if (opts->p_volume_max <= opts->p_volume_min) { dev_err(dev, "Error: incorrect playback volume max/min\n"); - return -EINVAL; + return -EINVAL; } else if (opts->c_volume_max <= opts->c_volume_min) { dev_err(dev, "Error: incorrect capture volume max/min\n"); - return -EINVAL; + return -EINVAL; } else if (opts->p_volume_res <= 0) { dev_err(dev, "Error: negative/zero playback volume resolution\n"); - return -EINVAL; + return -EINVAL; } else if (opts->c_volume_res <= 0) { dev_err(dev, "Error: negative/zero capture volume resolution\n"); - return -EINVAL; + return -EINVAL; } if ((opts->p_volume_max - opts->p_volume_min) % opts->p_volume_res) { dev_err(dev, "Error: incorrect playback volume resolution\n"); - return -EINVAL; + return -EINVAL; } else if ((opts->c_volume_max - opts->c_volume_min) % opts->c_volume_res) { dev_err(dev, "Error: incorrect capture volume resolution\n"); - return -EINVAL; + return -EINVAL; } return 0; From ec313ae88d6c99e3f2e7bdacd4397c40f5bb3a1e Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Mon, 27 Sep 2021 13:10:53 +0200 Subject: [PATCH 09/91] UPSTREAM: ABI: configfs-usb-gadget-uac1: fix a broken table Changeset 0356e6283c71 ("usb: gadget: f_uac1: add volume and mute support") added some new elements to the table but didn't care enough to actually adjust the columns, causing the output to be broken as warned by Sphinx when producing the documentation. Readjust it for it to be a valid ReST table. Fixes: 0356e6283c71 ("usb: gadget: f_uac1: add volume and mute support") Signed-off-by: Mauro Carvalho Chehab Link: https://lore.kernel.org/r/044b0c14c35922bdcca50551fe2aa870baae9b06.1632740376.git.mchehab+huawei@kernel.org Signed-off-by: Greg Kroah-Hartman Bug: 235196743 (cherry picked from commit 1b8af67cae654c3c8d719563a2eabb88371d01c9) Change-Id: I55cbfab7a954b0bd4b256dd43fe6f7e40c5201e3 Signed-off-by: Luiz Matheus --- .../ABI/testing/configfs-usb-gadget-uac1 | 42 +++++++++++-------- 1 file changed, 24 insertions(+), 18 deletions(-) diff --git a/Documentation/ABI/testing/configfs-usb-gadget-uac1 b/Documentation/ABI/testing/configfs-usb-gadget-uac1 index dd647d44d975..b576b3d6ea6d 100644 --- a/Documentation/ABI/testing/configfs-usb-gadget-uac1 +++ b/Documentation/ABI/testing/configfs-usb-gadget-uac1 @@ -4,23 +4,29 @@ KernelVersion: 4.14 Description: The attributes: - ========== =================================== - c_chmask capture channel mask - c_srate capture sampling rate - c_ssize capture sample size (bytes) - c_mute_present capture mute control enable + ===================== ======================================= + c_chmask capture channel mask + c_srate capture sampling rate + c_ssize capture sample size (bytes) + c_mute_present capture mute control enable c_volume_present capture volume control enable - c_volume_min capture volume control min value (in 1/256 dB) - c_volume_max capture volume control max value (in 1/256 dB) - c_volume_res capture volume control resolution (in 1/256 dB) - p_chmask playback channel mask - p_srate playback sampling rate - p_ssize playback sample size (bytes) - p_mute_present playback mute control enable + c_volume_min capture volume control min value + (in 1/256 dB) + c_volume_max capture volume control max value + (in 1/256 dB) + c_volume_res capture volume control resolution + (in 1/256 dB) + p_chmask playback channel mask + p_srate playback sampling rate + p_ssize playback sample size (bytes) + p_mute_present playback mute control enable p_volume_present playback volume control enable - p_volume_min playback volume control min value (in 1/256 dB) - p_volume_max playback volume control max value (in 1/256 dB) - p_volume_res playback volume control resolution (in 1/256 dB) - req_number the number of pre-allocated request - for both capture and playback - ========== =================================== + p_volume_min playback volume control min value + (in 1/256 dB) + p_volume_max playback volume control max value + (in 1/256 dB) + p_volume_res playback volume control resolution + (in 1/256 dB) + req_number the number of pre-allocated request + for both capture and playback + ===================== ======================================= From e29d2b51783e93c1d481e0c78424e2ed5369859a Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Mon, 27 Sep 2021 13:10:54 +0200 Subject: [PATCH 10/91] UPSTREAM: ABI: configfs-usb-gadget-uac2: fix a broken table Changeset af6cbe09920 ("usb: gadget: f_uac2: add volume and mute support") added some new elements to the table but didn't care enough to actually adjust the columns, causing the output to be broken as warned by Sphinx when producing the documentation. Readjust it for it to be a valid ReST table. Fixes: eaf6cbe09920 ("usb: gadget: f_uac2: add volume and mute support") Signed-off-by: Mauro Carvalho Chehab Link: https://lore.kernel.org/r/d253819a4c201b942d754682bb91dd278300fb79.1632740376.git.mchehab+huawei@kernel.org Signed-off-by: Greg Kroah-Hartman Bug: 235196743 (cherry picked from commit 5ef803538bd2f2907b0a44e24f094cf9bbf8bc13) Change-Id: I84fedd31e7534f884a5dafdbd3bfbf612e4161f3 Signed-off-by: Luiz Matheus --- .../ABI/testing/configfs-usb-gadget-uac2 | 43 +++++++++++-------- 1 file changed, 25 insertions(+), 18 deletions(-) diff --git a/Documentation/ABI/testing/configfs-usb-gadget-uac2 b/Documentation/ABI/testing/configfs-usb-gadget-uac2 index cfd160ff8b56..244d96650123 100644 --- a/Documentation/ABI/testing/configfs-usb-gadget-uac2 +++ b/Documentation/ABI/testing/configfs-usb-gadget-uac2 @@ -4,23 +4,30 @@ KernelVersion: 3.18 Description: The attributes: - ========= ============================ - c_chmask capture channel mask - c_srate capture sampling rate - c_ssize capture sample size (bytes) - c_sync capture synchronization type (async/adaptive) - c_mute_present capture mute control enable + ===================== ======================================= + c_chmask capture channel mask + c_srate capture sampling rate + c_ssize capture sample size (bytes) + c_sync capture synchronization type + (async/adaptive) + c_mute_present capture mute control enable c_volume_present capture volume control enable - c_volume_min capture volume control min value (in 1/256 dB) - c_volume_max capture volume control max value (in 1/256 dB) - c_volume_res capture volume control resolution (in 1/256 dB) - fb_max maximum extra bandwidth in async mode - p_chmask playback channel mask - p_srate playback sampling rate - p_ssize playback sample size (bytes) - p_mute_present playback mute control enable + c_volume_min capture volume control min value + (in 1/256 dB) + c_volume_max capture volume control max value + (in 1/256 dB) + c_volume_res capture volume control resolution + (in 1/256 dB) + fb_max maximum extra bandwidth in async mode + p_chmask playback channel mask + p_srate playback sampling rate + p_ssize playback sample size (bytes) + p_mute_present playback mute control enable p_volume_present playback volume control enable - p_volume_min playback volume control min value (in 1/256 dB) - p_volume_max playback volume control max value (in 1/256 dB) - p_volume_res playback volume control resolution (in 1/256 dB) - ========= ============================ + p_volume_min playback volume control min value + (in 1/256 dB) + p_volume_max playback volume control max value + (in 1/256 dB) + p_volume_res playback volume control resolution + (in 1/256 dB) + ===================== ======================================= From 4b7c8905c56d50ae9dfd1cf3d6564584d0fbf009 Mon Sep 17 00:00:00 2001 From: Pavel Hofman Date: Wed, 13 Oct 2021 09:39:34 +0200 Subject: [PATCH 11/91] UPSTREAM: usb: gadget: u_audio.c: Adding Playback Pitch ctl for sync playback EP IN is hard-coded as ASYNC both in f_uac1 and f_uac2 but u_audio sends steady number of audio frames in each USB packet, without any control. This patch adds 'Playback Pitch 1000000' ctl analogous to the existing 'Capture Pitch 1000000' ctl. The calculation of playback req->length in u_audio_iso_complete respects the Playback Pitch ctl value to 1ppm now. Max. value for Playback Pitch is configured by the existing parameter uac2_opts->fb_max, used also for the Capture Pitch. Since the EP IN packet size can be increased by uac2_opts->fb_max now, maxPacketSize for the playback direction is calculated by the same algorithm as for the async capture direction in f_uac2.c:set_ep_max_packet_size. Signed-off-by: Pavel Hofman Link: https://lore.kernel.org/r/20211013073934.36476-1-pavel.hofman@ivitera.com Signed-off-by: Greg Kroah-Hartman Bug: 235196743 (cherry picked from commit 6fec018a7e70d611412dd961e596b0415c6d365c) Change-Id: Ib4ed5921ed9bee7579b3f5f2eb3ae853ef263883 Signed-off-by: Luiz Matheus --- drivers/usb/gadget/function/f_uac2.c | 5 +- drivers/usb/gadget/function/u_audio.c | 96 ++++++++++++++++++++------- 2 files changed, 75 insertions(+), 26 deletions(-) diff --git a/drivers/usb/gadget/function/f_uac2.c b/drivers/usb/gadget/function/f_uac2.c index 1b4542715820..67cdb46cfacb 100644 --- a/drivers/usb/gadget/function/f_uac2.c +++ b/drivers/usb/gadget/function/f_uac2.c @@ -674,8 +674,9 @@ static int set_ep_max_packet_size(const struct f_uac2_opts *uac2_opts, ssize = uac2_opts->c_ssize; } - if (!is_playback && (uac2_opts->c_sync == USB_ENDPOINT_SYNC_ASYNC)) { - // Win10 requires max packet size + 1 frame + if (is_playback || (uac2_opts->c_sync == USB_ENDPOINT_SYNC_ASYNC)) { + // playback is always async, capture only when configured + // Win10 requires max packet size + 1 frame srate = srate * (1000 + uac2_opts->fb_max) / 1000; // updated srate is always bigger, therefore DIV_ROUND_UP always yields +1 max_size_bw = num_channels(chmask) * ssize * diff --git a/drivers/usb/gadget/function/u_audio.c b/drivers/usb/gadget/function/u_audio.c index c712a910d826..cb24330abbec 100644 --- a/drivers/usb/gadget/function/u_audio.c +++ b/drivers/usb/gadget/function/u_audio.c @@ -29,6 +29,7 @@ enum { UAC_FBACK_CTRL, + UAC_P_PITCH_CTRL, UAC_MUTE_CTRL, UAC_VOLUME_CTRL, }; @@ -74,13 +75,9 @@ struct snd_uac_chip { struct snd_card *card; struct snd_pcm *pcm; - /* timekeeping for the playback endpoint */ - unsigned int p_interval; - unsigned int p_residue; - /* pre-calculated values for playback iso completion */ - unsigned int p_pktsize; - unsigned int p_pktsize_residue; + unsigned long long p_interval_mil; + unsigned long long p_residue_mil; unsigned int p_framesize; }; @@ -153,6 +150,11 @@ static void u_audio_iso_complete(struct usb_ep *ep, struct usb_request *req) struct snd_pcm_runtime *runtime; struct uac_rtd_params *prm = req->context; struct snd_uac_chip *uac = prm->uac; + struct g_audio *audio_dev = uac->audio_dev; + struct uac_params *params = &audio_dev->params; + unsigned int frames, p_pktsize; + unsigned long long pitched_rate_mil, p_pktsize_residue_mil, + residue_frames_mil, div_result; /* i/f shutting down */ if (!prm->ep_enabled) { @@ -192,19 +194,42 @@ static void u_audio_iso_complete(struct usb_ep *ep, struct usb_request *req) * If there is a residue from this division, add it to the * residue accumulator. */ - req->length = uac->p_pktsize; - uac->p_residue += uac->p_pktsize_residue; + pitched_rate_mil = (unsigned long long) + params->p_srate * prm->pitch; + div_result = pitched_rate_mil; + do_div(div_result, uac->p_interval_mil); + frames = (unsigned int) div_result; + + pr_debug("p_srate %d, pitch %d, interval_mil %llu, frames %d\n", + params->p_srate, prm->pitch, uac->p_interval_mil, frames); + + p_pktsize = min_t(unsigned int, + uac->p_framesize * frames, + ep->maxpacket); + + if (p_pktsize < ep->maxpacket) { + residue_frames_mil = pitched_rate_mil - frames * uac->p_interval_mil; + p_pktsize_residue_mil = uac->p_framesize * residue_frames_mil; + } else + p_pktsize_residue_mil = 0; + + req->length = p_pktsize; + uac->p_residue_mil += p_pktsize_residue_mil; /* - * Whenever there are more bytes in the accumulator than we + * Whenever there are more bytes in the accumulator p_residue_mil than we * need to add one more sample frame, increase this packet's * size and decrease the accumulator. */ - if (uac->p_residue / uac->p_interval >= uac->p_framesize) { + div_result = uac->p_residue_mil; + do_div(div_result, uac->p_interval_mil); + if ((unsigned int) div_result >= uac->p_framesize) { req->length += uac->p_framesize; - uac->p_residue -= uac->p_framesize * - uac->p_interval; + uac->p_residue_mil -= uac->p_framesize * + uac->p_interval_mil; + pr_debug("increased req length to %d\n", req->length); } + pr_debug("remains uac->p_residue_mil %llu\n", uac->p_residue_mil); req->actual = req->length; } @@ -371,7 +396,7 @@ static int uac_pcm_open(struct snd_pcm_substream *substream) c_srate = params->c_srate; p_chmask = params->p_chmask; c_chmask = params->c_chmask; - uac->p_residue = 0; + uac->p_residue_mil = 0; runtime->hw = uac_pcm_hardware; @@ -566,12 +591,17 @@ int u_audio_start_playback(struct g_audio *audio_dev) unsigned int factor; const struct usb_endpoint_descriptor *ep_desc; int req_len, i; + unsigned int p_interval, p_pktsize; ep = audio_dev->in_ep; prm = &uac->p_prm; config_ep_by_speed(gadget, &audio_dev->func, ep); ep_desc = ep->desc; + /* + * Always start with original frequency + */ + prm->pitch = 1000000; /* pre-calculate the playback endpoint's interval */ if (gadget->speed == USB_SPEED_FULL) @@ -582,20 +612,15 @@ int u_audio_start_playback(struct g_audio *audio_dev) /* pre-compute some values for iso_complete() */ uac->p_framesize = params->p_ssize * num_channels(params->p_chmask); - uac->p_interval = factor / (1 << (ep_desc->bInterval - 1)); - uac->p_pktsize = min_t(unsigned int, + p_interval = factor / (1 << (ep_desc->bInterval - 1)); + uac->p_interval_mil = (unsigned long long) p_interval * 1000000; + p_pktsize = min_t(unsigned int, uac->p_framesize * - (params->p_srate / uac->p_interval), + (params->p_srate / p_interval), ep->maxpacket); - if (uac->p_pktsize < ep->maxpacket) - uac->p_pktsize_residue = uac->p_framesize * - (params->p_srate % uac->p_interval); - else - uac->p_pktsize_residue = 0; - - req_len = uac->p_pktsize; - uac->p_residue = 0; + req_len = p_pktsize; + uac->p_residue_mil = 0; prm->ep_enabled = true; usb_ep_enable(ep); @@ -925,6 +950,13 @@ static struct snd_kcontrol_new u_audio_controls[] = { .get = u_audio_pitch_get, .put = u_audio_pitch_put, }, + [UAC_P_PITCH_CTRL] { + .iface = SNDRV_CTL_ELEM_IFACE_PCM, + .name = "Playback Pitch 1000000", + .info = u_audio_pitch_info, + .get = u_audio_pitch_get, + .put = u_audio_pitch_put, + }, [UAC_MUTE_CTRL] { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = "", /* will be filled later */ @@ -1062,6 +1094,22 @@ int g_audio_setup(struct g_audio *g_audio, const char *pcm_name, goto snd_fail; } + if (p_chmask) { + kctl = snd_ctl_new1(&u_audio_controls[UAC_P_PITCH_CTRL], + &uac->p_prm); + if (!kctl) { + err = -ENOMEM; + goto snd_fail; + } + + kctl->id.device = pcm->device; + kctl->id.subdevice = 0; + + err = snd_ctl_add(card, kctl); + if (err < 0) + goto snd_fail; + } + for (i = 0; i <= SNDRV_PCM_STREAM_LAST; i++) { struct uac_rtd_params *prm; struct uac_fu_params *fu; From e1377ac38f4d11db7a8baf167481a95af24c7e00 Mon Sep 17 00:00:00 2001 From: Pavel Hofman Date: Fri, 22 Oct 2021 16:03:39 +0200 Subject: [PATCH 12/91] UPSTREAM: usb:gadget: f_uac1: fixed sync playback The u_audio param fb_max was not set to its default value in f_uac1.c. As a result the maximum value of Playback Pitch ctl was kept at 1000000, not allowing to set faster playback pitch for UAC1. The setting required moving the default constant UAC2_DEF_FB_MAX from u_uac2.h to FBACK_FAST_MAX in u_audio.h as that header is common for f_uac1.c and f_uac2.c. Fixes: 6fec018a7e70 ("usb: gadget: u_audio.c: Adding Playback Pitch ctl for sync playback") Signed-off-by: Pavel Hofman Link: https://lore.kernel.org/r/20211022140339.248669-1-pavel.hofman@ivitera.com Signed-off-by: Greg Kroah-Hartman Bug: 235196743 (cherry picked from commit d9f273484358285b448aff65bffeb361d0b1f917) Change-Id: I3aadc7c6d1695be7d1ab93078c4875b87e472afd Signed-off-by: Luiz Matheus --- drivers/usb/gadget/function/f_uac1.c | 1 + drivers/usb/gadget/function/f_uac2.c | 3 ++- drivers/usb/gadget/function/u_audio.h | 10 ++++++++-- drivers/usb/gadget/function/u_uac2.h | 1 - 4 files changed, 11 insertions(+), 4 deletions(-) diff --git a/drivers/usb/gadget/function/f_uac1.c b/drivers/usb/gadget/function/f_uac1.c index 5b3502df4e13..03f50643fbba 100644 --- a/drivers/usb/gadget/function/f_uac1.c +++ b/drivers/usb/gadget/function/f_uac1.c @@ -1321,6 +1321,7 @@ static int f_audio_bind(struct usb_configuration *c, struct usb_function *f) audio->params.c_fu.volume_res = audio_opts->c_volume_res; } audio->params.req_number = audio_opts->req_number; + audio->params.fb_max = FBACK_FAST_MAX; if (FUOUT_EN(audio_opts) || FUIN_EN(audio_opts)) audio->notify = audio_notify; diff --git a/drivers/usb/gadget/function/f_uac2.c b/drivers/usb/gadget/function/f_uac2.c index 67cdb46cfacb..6b4070f0d257 100644 --- a/drivers/usb/gadget/function/f_uac2.c +++ b/drivers/usb/gadget/function/f_uac2.c @@ -15,6 +15,7 @@ #include #include "u_audio.h" + #include "u_uac2.h" /* UAC2 spec: 4.1 Audio Channel Cluster Descriptor */ @@ -1936,7 +1937,7 @@ static struct usb_function_instance *afunc_alloc_inst(void) opts->c_volume_res = UAC2_DEF_RES_DB; opts->req_number = UAC2_DEF_REQ_NUM; - opts->fb_max = UAC2_DEF_FB_MAX; + opts->fb_max = FBACK_FAST_MAX; return &opts->func_inst; } diff --git a/drivers/usb/gadget/function/u_audio.h b/drivers/usb/gadget/function/u_audio.h index 001a79a46022..8dfdae1721cd 100644 --- a/drivers/usb/gadget/function/u_audio.h +++ b/drivers/usb/gadget/function/u_audio.h @@ -14,11 +14,17 @@ /* * Same maximum frequency deviation on the slower side as in * sound/usb/endpoint.c. Value is expressed in per-mil deviation. - * The maximum deviation on the faster side will be provided as - * parameter, as it impacts the endpoint required bandwidth. */ #define FBACK_SLOW_MAX 250 +/* + * Maximum frequency deviation on the faster side, default value for UAC1/2. + * Value is expressed in per-mil deviation. + * UAC2 provides the value as a parameter as it impacts the endpoint required + * bandwidth. + */ +#define FBACK_FAST_MAX 5 + /* Feature Unit parameters */ struct uac_fu_params { int id; /* Feature Unit ID */ diff --git a/drivers/usb/gadget/function/u_uac2.h b/drivers/usb/gadget/function/u_uac2.h index a73b35774c44..e0c8e3513bfd 100644 --- a/drivers/usb/gadget/function/u_uac2.h +++ b/drivers/usb/gadget/function/u_uac2.h @@ -30,7 +30,6 @@ #define UAC2_DEF_RES_DB (1*256) /* 1 dB */ #define UAC2_DEF_REQ_NUM 2 -#define UAC2_DEF_FB_MAX 5 #define UAC2_DEF_INT_REQ_NUM 10 struct f_uac2_opts { From 02949bae5c148c2cedb493086d72eede3f3148cb Mon Sep 17 00:00:00 2001 From: Pavel Hofman Date: Sat, 25 Dec 2021 14:09:28 +0100 Subject: [PATCH 13/91] UPSTREAM: docs: ABI: added missing num_requests param to UAC2 The existing configfs-usb-gadget-uac2 ABI doc for testing was missing the num_requests param. The patch adds the parameter to the document. Signed-off-by: Pavel Hofman Link: https://lore.kernel.org/r/20211225130929.205629-1-pavel.hofman@ivitera.com Signed-off-by: Greg Kroah-Hartman Bug: 235196743 (cherry picked from commit e3088ebc1b97a3e5df13f2e218ed8430ab3a4ad2) Change-Id: I9ea7ca2f41219ed5767b88722c73f8747a464f71 Signed-off-by: Luiz Matheus --- Documentation/ABI/testing/configfs-usb-gadget-uac2 | 2 ++ 1 file changed, 2 insertions(+) diff --git a/Documentation/ABI/testing/configfs-usb-gadget-uac2 b/Documentation/ABI/testing/configfs-usb-gadget-uac2 index 244d96650123..9cddadc53e0b 100644 --- a/Documentation/ABI/testing/configfs-usb-gadget-uac2 +++ b/Documentation/ABI/testing/configfs-usb-gadget-uac2 @@ -30,4 +30,6 @@ Description: (in 1/256 dB) p_volume_res playback volume control resolution (in 1/256 dB) + req_number the number of pre-allocated requests for both capture + and playback ===================== ======================================= From f74e3e2fe4fe30d09dffca466aa666d3b74fba75 Mon Sep 17 00:00:00 2001 From: Pavel Hofman Date: Sat, 25 Dec 2021 14:09:29 +0100 Subject: [PATCH 14/91] UPSTREAM: docs: ABI: fixed req_number desc in UAC1 Fixed wording of the req_number description in UAC1 docs. Signed-off-by: Pavel Hofman Link: https://lore.kernel.org/r/20211225130929.205629-2-pavel.hofman@ivitera.com Signed-off-by: Greg Kroah-Hartman Bug: 235196743 (cherry picked from commit a8cf05160336535fc352c0af66115d0ec0299404) Change-Id: I9815823f67ea086a8e9a3216e988cdd7c7b3de5a Signed-off-by: Luiz Matheus --- Documentation/ABI/testing/configfs-usb-gadget-uac1 | 2 +- Documentation/usb/gadget-testing.rst | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Documentation/ABI/testing/configfs-usb-gadget-uac1 b/Documentation/ABI/testing/configfs-usb-gadget-uac1 index b576b3d6ea6d..d4b8cf40a9e4 100644 --- a/Documentation/ABI/testing/configfs-usb-gadget-uac1 +++ b/Documentation/ABI/testing/configfs-usb-gadget-uac1 @@ -27,6 +27,6 @@ Description: (in 1/256 dB) p_volume_res playback volume control resolution (in 1/256 dB) - req_number the number of pre-allocated request + req_number the number of pre-allocated requests for both capture and playback ===================== ======================================= diff --git a/Documentation/usb/gadget-testing.rst b/Documentation/usb/gadget-testing.rst index 58781a268890..c979e0512284 100644 --- a/Documentation/usb/gadget-testing.rst +++ b/Documentation/usb/gadget-testing.rst @@ -932,7 +932,7 @@ The uac1 function provides these attributes in its function directory: p_volume_min playback volume control min value (in 1/256 dB) p_volume_max playback volume control max value (in 1/256 dB) p_volume_res playback volume control resolution (in 1/256 dB) - req_number the number of pre-allocated request for both capture + req_number the number of pre-allocated requests for both capture and playback ================ ==================================================== From c386f34bd49dac609213b4e49462867421f682b7 Mon Sep 17 00:00:00 2001 From: John Keeping Date: Tue, 4 Jan 2022 18:32:42 +0000 Subject: [PATCH 15/91] UPSTREAM: usb: gadget: u_audio: fix calculations for small bInterval If bInterval is 1, then p_interval is 8000 and p_interval_mil is 8E9, which is too big for a 32-bit value. While the storage is indeed 64-bit, this value is used as the divisor in do_div() which will truncate it into a uint32_t leading to incorrect calculated values. Switch back to keeping the base value in struct snd_uac_chip which fits easily into an int, meaning that the division can be done in two steps with the divisor fitting safely into a uint32_t on both steps. Fixes: 6fec018a7e70 ("usb: gadget: u_audio.c: Adding Playback Pitch ctl for sync playback") Tested-by: Pavel Hofman Signed-off-by: John Keeping Link: https://lore.kernel.org/r/20220104183243.718258-1-john@metanate.com Signed-off-by: Greg Kroah-Hartman Bug: 235196743 (cherry picked from commit f2f69bf65df12176843ca11eab99949ba69e128b) Change-Id: Ia1e0dcdd66d60013705f9ee6ff5f76f18bdbb17e Signed-off-by: Luiz Matheus --- drivers/usb/gadget/function/u_audio.c | 24 +++++++++++++----------- 1 file changed, 13 insertions(+), 11 deletions(-) diff --git a/drivers/usb/gadget/function/u_audio.c b/drivers/usb/gadget/function/u_audio.c index cb24330abbec..71c19341d173 100644 --- a/drivers/usb/gadget/function/u_audio.c +++ b/drivers/usb/gadget/function/u_audio.c @@ -76,8 +76,8 @@ struct snd_uac_chip { struct snd_pcm *pcm; /* pre-calculated values for playback iso completion */ - unsigned long long p_interval_mil; unsigned long long p_residue_mil; + unsigned int p_interval; unsigned int p_framesize; }; @@ -194,21 +194,24 @@ static void u_audio_iso_complete(struct usb_ep *ep, struct usb_request *req) * If there is a residue from this division, add it to the * residue accumulator. */ + unsigned long long p_interval_mil = uac->p_interval * 1000000ULL; + pitched_rate_mil = (unsigned long long) params->p_srate * prm->pitch; div_result = pitched_rate_mil; - do_div(div_result, uac->p_interval_mil); + do_div(div_result, uac->p_interval); + do_div(div_result, 1000000); frames = (unsigned int) div_result; pr_debug("p_srate %d, pitch %d, interval_mil %llu, frames %d\n", - params->p_srate, prm->pitch, uac->p_interval_mil, frames); + params->p_srate, prm->pitch, p_interval_mil, frames); p_pktsize = min_t(unsigned int, uac->p_framesize * frames, ep->maxpacket); if (p_pktsize < ep->maxpacket) { - residue_frames_mil = pitched_rate_mil - frames * uac->p_interval_mil; + residue_frames_mil = pitched_rate_mil - frames * p_interval_mil; p_pktsize_residue_mil = uac->p_framesize * residue_frames_mil; } else p_pktsize_residue_mil = 0; @@ -222,11 +225,11 @@ static void u_audio_iso_complete(struct usb_ep *ep, struct usb_request *req) * size and decrease the accumulator. */ div_result = uac->p_residue_mil; - do_div(div_result, uac->p_interval_mil); + do_div(div_result, uac->p_interval); + do_div(div_result, 1000000); if ((unsigned int) div_result >= uac->p_framesize) { req->length += uac->p_framesize; - uac->p_residue_mil -= uac->p_framesize * - uac->p_interval_mil; + uac->p_residue_mil -= uac->p_framesize * p_interval_mil; pr_debug("increased req length to %d\n", req->length); } pr_debug("remains uac->p_residue_mil %llu\n", uac->p_residue_mil); @@ -591,7 +594,7 @@ int u_audio_start_playback(struct g_audio *audio_dev) unsigned int factor; const struct usb_endpoint_descriptor *ep_desc; int req_len, i; - unsigned int p_interval, p_pktsize; + unsigned int p_pktsize; ep = audio_dev->in_ep; prm = &uac->p_prm; @@ -612,11 +615,10 @@ int u_audio_start_playback(struct g_audio *audio_dev) /* pre-compute some values for iso_complete() */ uac->p_framesize = params->p_ssize * num_channels(params->p_chmask); - p_interval = factor / (1 << (ep_desc->bInterval - 1)); - uac->p_interval_mil = (unsigned long long) p_interval * 1000000; + uac->p_interval = factor / (1 << (ep_desc->bInterval - 1)); p_pktsize = min_t(unsigned int, uac->p_framesize * - (params->p_srate / p_interval), + (params->p_srate / uac->p_interval), ep->maxpacket); req_len = p_pktsize; From 2500cb53e619e9ca5c0df4191e5d1b31d0ac2060 Mon Sep 17 00:00:00 2001 From: Pavel Hofman Date: Wed, 5 Jan 2022 11:46:43 +0100 Subject: [PATCH 16/91] UPSTREAM: usb: gadget: u_audio: Subdevice 0 for capture ctls Both capture and playback alsa devices use subdevice 0. Yet capture-side ctls are defined for subdevice 1. The patch sets subdevice 0 for them. Fixes: 02de698ca812 ("usb: gadget: u_audio: add bi-directional volume and mute support") Signed-off-by: Pavel Hofman Link: https://lore.kernel.org/r/20220105104643.90125-1-pavel.hofman@ivitera.com Signed-off-by: Greg Kroah-Hartman Bug: 235196743 (cherry picked from commit 601a5bc1aeef772ab1f47582fd322957799f5ab5) Change-Id: I732c6dd18d23d542814c6d9df2fb424fe256abda Signed-off-by: Luiz Matheus --- drivers/usb/gadget/function/u_audio.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/usb/gadget/function/u_audio.c b/drivers/usb/gadget/function/u_audio.c index 71c19341d173..0f283ffdfbb5 100644 --- a/drivers/usb/gadget/function/u_audio.c +++ b/drivers/usb/gadget/function/u_audio.c @@ -1147,7 +1147,7 @@ int g_audio_setup(struct g_audio *g_audio, const char *pcm_name, } kctl->id.device = pcm->device; - kctl->id.subdevice = i; + kctl->id.subdevice = 0; err = snd_ctl_add(card, kctl); if (err < 0) @@ -1170,7 +1170,7 @@ int g_audio_setup(struct g_audio *g_audio, const char *pcm_name, } kctl->id.device = pcm->device; - kctl->id.subdevice = i; + kctl->id.subdevice = 0; kctl->tlv.c = u_audio_volume_tlv; From 7f496d5a99b6dc661c3aaaed358cc936632b564f Mon Sep 17 00:00:00 2001 From: Pavel Hofman Date: Sat, 8 Jan 2022 11:56:08 +0100 Subject: [PATCH 17/91] UPSTREAM: docs: ABI: fixed formatting in configfs-usb-gadget-uac2 Added missing tab, line breaks. Fixes: e3088ebc1b97 ("docs: ABI: added missing num_requests param to UAC2") Reported-by: Stephen Rothwell Signed-off-by: Pavel Hofman Link: https://lore.kernel.org/r/20220108105608.10726-1-pavel.hofman@ivitera.com Signed-off-by: Greg Kroah-Hartman Bug: 235196743 (cherry picked from commit cbb4f5f435995a56ef770e35bfafb4bcff8f0ada) Change-Id: If0e58b65b60d8b412b7c3998f989e82d30a17a91 Signed-off-by: Luiz Matheus --- Documentation/ABI/testing/configfs-usb-gadget-uac2 | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Documentation/ABI/testing/configfs-usb-gadget-uac2 b/Documentation/ABI/testing/configfs-usb-gadget-uac2 index 9cddadc53e0b..7fb3dbe26857 100644 --- a/Documentation/ABI/testing/configfs-usb-gadget-uac2 +++ b/Documentation/ABI/testing/configfs-usb-gadget-uac2 @@ -30,6 +30,6 @@ Description: (in 1/256 dB) p_volume_res playback volume control resolution (in 1/256 dB) - req_number the number of pre-allocated requests for both capture - and playback + req_number the number of pre-allocated requests + for both capture and playback ===================== ======================================= From 530916be9777f6bfe47356348af789e620760a2d Mon Sep 17 00:00:00 2001 From: Julian Scheel Date: Fri, 21 Jan 2022 16:53:00 +0100 Subject: [PATCH 18/91] UPSTREAM: usb: gadget: u_audio: Support multiple sampling rates Implement support for multiple sampling rates in u_audio part of the audio gadget. The currently configured rates are exposed through read-only amixer controls 'Capture Rate' and 'Playback Rate'. Signed-off-by: Julian Scheel Signed-off-by: Pavel Hofman Link: https://lore.kernel.org/r/20220121155308.48794-3-pavel.hofman@ivitera.com Signed-off-by: Greg Kroah-Hartman Bug: 235196743 (cherry picked from commit c565ad07ef35f5c7461ba9fc08dbb3a61420b8d2) Change-Id: I389574571cec7bf7cbff5375dab6542f7c5bf5f2 Signed-off-by: Luiz Matheus --- drivers/usb/gadget/function/f_uac1.c | 2 + drivers/usb/gadget/function/f_uac2.c | 2 + drivers/usb/gadget/function/u_audio.c | 131 +++++++++++++++++++++++ drivers/usb/gadget/function/u_audio.h | 10 +- drivers/usb/gadget/function/uac_common.h | 9 ++ 5 files changed, 152 insertions(+), 2 deletions(-) create mode 100644 drivers/usb/gadget/function/uac_common.h diff --git a/drivers/usb/gadget/function/f_uac1.c b/drivers/usb/gadget/function/f_uac1.c index 03f50643fbba..ccb0e4f41e5d 100644 --- a/drivers/usb/gadget/function/f_uac1.c +++ b/drivers/usb/gadget/function/f_uac1.c @@ -1298,6 +1298,7 @@ static int f_audio_bind(struct usb_configuration *c, struct usb_function *f) audio->in_ep_maxpsize = le16_to_cpu(as_in_ep_desc.wMaxPacketSize); audio->params.c_chmask = audio_opts->c_chmask; audio->params.c_srate = audio_opts->c_srate; + audio->params.c_srates[0] = audio_opts->c_srate; audio->params.c_ssize = audio_opts->c_ssize; if (FUIN_EN(audio_opts)) { audio->params.p_fu.id = USB_IN_FU_ID; @@ -1310,6 +1311,7 @@ static int f_audio_bind(struct usb_configuration *c, struct usb_function *f) } audio->params.p_chmask = audio_opts->p_chmask; audio->params.p_srate = audio_opts->p_srate; + audio->params.p_srates[0] = audio_opts->p_srate; audio->params.p_ssize = audio_opts->p_ssize; if (FUOUT_EN(audio_opts)) { audio->params.c_fu.id = USB_OUT_FU_ID; diff --git a/drivers/usb/gadget/function/f_uac2.c b/drivers/usb/gadget/function/f_uac2.c index 6b4070f0d257..38e09e66ca18 100644 --- a/drivers/usb/gadget/function/f_uac2.c +++ b/drivers/usb/gadget/function/f_uac2.c @@ -1214,6 +1214,7 @@ afunc_bind(struct usb_configuration *cfg, struct usb_function *fn) agdev->params.p_chmask = uac2_opts->p_chmask; agdev->params.p_srate = uac2_opts->p_srate; + agdev->params.p_srates[0] = uac2_opts->p_srate; agdev->params.p_ssize = uac2_opts->p_ssize; if (FUIN_EN(uac2_opts)) { agdev->params.p_fu.id = USB_IN_FU_ID; @@ -1225,6 +1226,7 @@ afunc_bind(struct usb_configuration *cfg, struct usb_function *fn) } agdev->params.c_chmask = uac2_opts->c_chmask; agdev->params.c_srate = uac2_opts->c_srate; + agdev->params.c_srates[0] = uac2_opts->c_srate; agdev->params.c_ssize = uac2_opts->c_ssize; if (FUOUT_EN(uac2_opts)) { agdev->params.c_fu.id = USB_OUT_FU_ID; diff --git a/drivers/usb/gadget/function/u_audio.c b/drivers/usb/gadget/function/u_audio.c index 0f283ffdfbb5..3574bb304c28 100644 --- a/drivers/usb/gadget/function/u_audio.c +++ b/drivers/usb/gadget/function/u_audio.c @@ -32,6 +32,7 @@ enum { UAC_P_PITCH_CTRL, UAC_MUTE_CTRL, UAC_VOLUME_CTRL, + UAC_RATE_CTRL, }; /* Runtime data params for one stream */ @@ -62,6 +63,8 @@ struct uac_rtd_params { s16 volume; int mute; + struct snd_kcontrol *snd_kctl_rate; /* read-only current rate */ + spinlock_t lock; /* lock for control transfers */ }; @@ -493,6 +496,44 @@ static inline void free_ep_fback(struct uac_rtd_params *prm, struct usb_ep *ep) dev_err(uac->card->dev, "%s:%d Error!\n", __func__, __LINE__); } +int u_audio_set_capture_srate(struct g_audio *audio_dev, int srate) +{ + struct uac_params *params = &audio_dev->params; + int i; + + dev_dbg(&audio_dev->gadget->dev, "%s: srate %d\n", __func__, srate); + for (i = 0; i < UAC_MAX_RATES; i++) { + if (params->c_srates[i] == srate) { + params->c_srate = srate; + return 0; + } + if (params->c_srates[i] == 0) + break; + } + + return -EINVAL; +} +EXPORT_SYMBOL_GPL(u_audio_set_capture_srate); + +int u_audio_set_playback_srate(struct g_audio *audio_dev, int srate) +{ + struct uac_params *params = &audio_dev->params; + int i; + + dev_dbg(&audio_dev->gadget->dev, "%s: srate %d\n", __func__, srate); + for (i = 0; i < UAC_MAX_RATES; i++) { + if (params->p_srates[i] == srate) { + params->p_srate = srate; + return 0; + } + if (params->p_srates[i] == 0) + break; + } + + return -EINVAL; +} +EXPORT_SYMBOL_GPL(u_audio_set_playback_srate); + int u_audio_start_capture(struct g_audio *audio_dev) { struct snd_uac_chip *uac = audio_dev->uac; @@ -504,6 +545,7 @@ int u_audio_start_capture(struct g_audio *audio_dev) struct uac_params *params = &audio_dev->params; int req_len, i; + dev_dbg(dev, "start capture with rate %d\n", params->c_srate); ep = audio_dev->out_ep; prm = &uac->c_prm; config_ep_by_speed(gadget, &audio_dev->func, ep); @@ -596,6 +638,7 @@ int u_audio_start_playback(struct g_audio *audio_dev) int req_len, i; unsigned int p_pktsize; + dev_dbg(dev, "start playback with rate %d\n", params->p_srate); ep = audio_dev->in_ep; prm = &uac->p_prm; config_ep_by_speed(gadget, &audio_dev->func, ep); @@ -943,6 +986,68 @@ static int u_audio_volume_put(struct snd_kcontrol *kcontrol, return change; } +static int get_max_srate(const int *srates) +{ + int i, max_srate = 0; + + for (i = 0; i < UAC_MAX_RATES; i++) { + if (srates[i] == 0) + break; + if (srates[i] > max_srate) + max_srate = srates[i]; + } + return max_srate; +} + +static int get_min_srate(const int *srates) +{ + int i, min_srate = INT_MAX; + + for (i = 0; i < UAC_MAX_RATES; i++) { + if (srates[i] == 0) + break; + if (srates[i] < min_srate) + min_srate = srates[i]; + } + return min_srate; +} + +static int u_audio_rate_info(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_info *uinfo) +{ + const int *srates; + struct uac_rtd_params *prm = snd_kcontrol_chip(kcontrol); + struct snd_uac_chip *uac = prm->uac; + struct g_audio *audio_dev = uac->audio_dev; + struct uac_params *params = &audio_dev->params; + + uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER; + uinfo->count = 1; + + if (prm == &uac->c_prm) + srates = params->c_srates; + else + srates = params->p_srates; + uinfo->value.integer.min = get_min_srate(srates); + uinfo->value.integer.max = get_max_srate(srates); + return 0; +} + +static int u_audio_rate_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct uac_rtd_params *prm = snd_kcontrol_chip(kcontrol); + struct snd_uac_chip *uac = prm->uac; + struct g_audio *audio_dev = uac->audio_dev; + struct uac_params *params = &audio_dev->params; + + if (prm == &uac->c_prm) + ucontrol->value.integer.value[0] = params->c_srate; + else + ucontrol->value.integer.value[0] = params->p_srate; + + return 0; +} static struct snd_kcontrol_new u_audio_controls[] = { [UAC_FBACK_CTRL] { @@ -973,6 +1078,13 @@ static struct snd_kcontrol_new u_audio_controls[] = { .get = u_audio_volume_get, .put = u_audio_volume_put, }, + [UAC_RATE_CTRL] { + .iface = SNDRV_CTL_ELEM_IFACE_PCM, + .name = "", /* will be filled later */ + .access = SNDRV_CTL_ELEM_ACCESS_READ | SNDRV_CTL_ELEM_ACCESS_VOLATILE, + .info = u_audio_rate_info, + .get = u_audio_rate_get, + }, }; int g_audio_setup(struct g_audio *g_audio, const char *pcm_name, @@ -1186,6 +1298,25 @@ int g_audio_setup(struct g_audio *g_audio, const char *pcm_name, prm->volume_min = fu->volume_min; prm->volume_res = fu->volume_res; } + + /* Add rate control */ + snprintf(ctrl_name, sizeof(ctrl_name), + "%s Rate", direction); + u_audio_controls[UAC_RATE_CTRL].name = ctrl_name; + + kctl = snd_ctl_new1(&u_audio_controls[UAC_RATE_CTRL], prm); + if (!kctl) { + err = -ENOMEM; + goto snd_fail; + } + + kctl->id.device = pcm->device; + kctl->id.subdevice = 0; + + err = snd_ctl_add(card, kctl); + if (err < 0) + goto snd_fail; + prm->snd_kctl_rate = kctl; } strscpy(card->driver, card_name, sizeof(card->driver)); diff --git a/drivers/usb/gadget/function/u_audio.h b/drivers/usb/gadget/function/u_audio.h index 8dfdae1721cd..76b5b8169444 100644 --- a/drivers/usb/gadget/function/u_audio.h +++ b/drivers/usb/gadget/function/u_audio.h @@ -10,6 +10,7 @@ #define __U_AUDIO_H #include +#include "uac_common.h" /* * Same maximum frequency deviation on the slower side as in @@ -40,13 +41,15 @@ struct uac_fu_params { struct uac_params { /* playback */ int p_chmask; /* channel mask */ - int p_srate; /* rate in Hz */ + int p_srates[UAC_MAX_RATES]; /* available rates in Hz (0 terminated list) */ + int p_srate; /* selected rate in Hz */ int p_ssize; /* sample size */ struct uac_fu_params p_fu; /* Feature Unit parameters */ /* capture */ int c_chmask; /* channel mask */ - int c_srate; /* rate in Hz */ + int c_srates[UAC_MAX_RATES]; /* available rates in Hz (0 terminated list) */ + int c_srate; /* selected rate in Hz */ int c_ssize; /* sample size */ struct uac_fu_params c_fu; /* Feature Unit parameters */ @@ -117,6 +120,9 @@ void u_audio_stop_capture(struct g_audio *g_audio); int u_audio_start_playback(struct g_audio *g_audio); void u_audio_stop_playback(struct g_audio *g_audio); +int u_audio_set_capture_srate(struct g_audio *audio_dev, int srate); +int u_audio_set_playback_srate(struct g_audio *audio_dev, int srate); + int u_audio_get_volume(struct g_audio *g_audio, int playback, s16 *val); int u_audio_set_volume(struct g_audio *g_audio, int playback, s16 val); int u_audio_get_mute(struct g_audio *g_audio, int playback, int *val); diff --git a/drivers/usb/gadget/function/uac_common.h b/drivers/usb/gadget/function/uac_common.h new file mode 100644 index 000000000000..3ecf89d6e814 --- /dev/null +++ b/drivers/usb/gadget/function/uac_common.h @@ -0,0 +1,9 @@ +/* SPDX-License-Identifier: GPL-2.0+ */ +/* + */ + +#ifndef UAC_COMMON_H +#define UAC_COMMON_H + +#define UAC_MAX_RATES 10 /* maximum number of rates configurable by f_uac1/2 */ +#endif From 3251bb32508e617ffdaecc135a17e1b4735c6c33 Mon Sep 17 00:00:00 2001 From: Pavel Hofman Date: Fri, 21 Jan 2022 16:53:01 +0100 Subject: [PATCH 19/91] UPSTREAM: usb: gadget: u_audio: Move dynamic srate from params to rtd Parameters uac_params.p_srate/c_srate are dynamic now and are not part of parametric configuration anymore. Move them to the runtime struct uac_rtd_params for each stream. Suggested-by: John Keeping Signed-off-by: Pavel Hofman Link: https://lore.kernel.org/r/20220121155308.48794-4-pavel.hofman@ivitera.com Signed-off-by: Greg Kroah-Hartman Bug: 235196743 (cherry picked from commit 8722a949e62ad77b3e4acc11fc44774ebbc32356) Change-Id: I03594d6fb6d08cac1d581676e5bb8f03a3d1e3f2 Signed-off-by: Luiz Matheus --- drivers/usb/gadget/function/f_uac1.c | 2 - drivers/usb/gadget/function/f_uac2.c | 2 - drivers/usb/gadget/function/u_audio.c | 68 ++++++++++++++------------- drivers/usb/gadget/function/u_audio.h | 4 +- 4 files changed, 38 insertions(+), 38 deletions(-) diff --git a/drivers/usb/gadget/function/f_uac1.c b/drivers/usb/gadget/function/f_uac1.c index ccb0e4f41e5d..0397b27df42e 100644 --- a/drivers/usb/gadget/function/f_uac1.c +++ b/drivers/usb/gadget/function/f_uac1.c @@ -1297,7 +1297,6 @@ static int f_audio_bind(struct usb_configuration *c, struct usb_function *f) audio->out_ep_maxpsize = le16_to_cpu(as_out_ep_desc.wMaxPacketSize); audio->in_ep_maxpsize = le16_to_cpu(as_in_ep_desc.wMaxPacketSize); audio->params.c_chmask = audio_opts->c_chmask; - audio->params.c_srate = audio_opts->c_srate; audio->params.c_srates[0] = audio_opts->c_srate; audio->params.c_ssize = audio_opts->c_ssize; if (FUIN_EN(audio_opts)) { @@ -1310,7 +1309,6 @@ static int f_audio_bind(struct usb_configuration *c, struct usb_function *f) audio->params.p_fu.volume_res = audio_opts->p_volume_res; } audio->params.p_chmask = audio_opts->p_chmask; - audio->params.p_srate = audio_opts->p_srate; audio->params.p_srates[0] = audio_opts->p_srate; audio->params.p_ssize = audio_opts->p_ssize; if (FUOUT_EN(audio_opts)) { diff --git a/drivers/usb/gadget/function/f_uac2.c b/drivers/usb/gadget/function/f_uac2.c index 38e09e66ca18..e7f233916271 100644 --- a/drivers/usb/gadget/function/f_uac2.c +++ b/drivers/usb/gadget/function/f_uac2.c @@ -1213,7 +1213,6 @@ afunc_bind(struct usb_configuration *cfg, struct usb_function *fn) agdev->gadget = gadget; agdev->params.p_chmask = uac2_opts->p_chmask; - agdev->params.p_srate = uac2_opts->p_srate; agdev->params.p_srates[0] = uac2_opts->p_srate; agdev->params.p_ssize = uac2_opts->p_ssize; if (FUIN_EN(uac2_opts)) { @@ -1225,7 +1224,6 @@ afunc_bind(struct usb_configuration *cfg, struct usb_function *fn) agdev->params.p_fu.volume_res = uac2_opts->p_volume_res; } agdev->params.c_chmask = uac2_opts->c_chmask; - agdev->params.c_srate = uac2_opts->c_srate; agdev->params.c_srates[0] = uac2_opts->c_srate; agdev->params.c_ssize = uac2_opts->c_ssize; if (FUOUT_EN(uac2_opts)) { diff --git a/drivers/usb/gadget/function/u_audio.c b/drivers/usb/gadget/function/u_audio.c index 3574bb304c28..7e4561523075 100644 --- a/drivers/usb/gadget/function/u_audio.c +++ b/drivers/usb/gadget/function/u_audio.c @@ -64,6 +64,7 @@ struct uac_rtd_params { int mute; struct snd_kcontrol *snd_kctl_rate; /* read-only current rate */ + int srate; /* selected samplerate */ spinlock_t lock; /* lock for control transfers */ @@ -153,8 +154,6 @@ static void u_audio_iso_complete(struct usb_ep *ep, struct usb_request *req) struct snd_pcm_runtime *runtime; struct uac_rtd_params *prm = req->context; struct snd_uac_chip *uac = prm->uac; - struct g_audio *audio_dev = uac->audio_dev; - struct uac_params *params = &audio_dev->params; unsigned int frames, p_pktsize; unsigned long long pitched_rate_mil, p_pktsize_residue_mil, residue_frames_mil, div_result; @@ -199,15 +198,14 @@ static void u_audio_iso_complete(struct usb_ep *ep, struct usb_request *req) */ unsigned long long p_interval_mil = uac->p_interval * 1000000ULL; - pitched_rate_mil = (unsigned long long) - params->p_srate * prm->pitch; + pitched_rate_mil = (unsigned long long) prm->srate * prm->pitch; div_result = pitched_rate_mil; do_div(div_result, uac->p_interval); do_div(div_result, 1000000); frames = (unsigned int) div_result; pr_debug("p_srate %d, pitch %d, interval_mil %llu, frames %d\n", - params->p_srate, prm->pitch, p_interval_mil, frames); + prm->srate, prm->pitch, p_interval_mil, frames); p_pktsize = min_t(unsigned int, uac->p_framesize * frames, @@ -284,7 +282,6 @@ static void u_audio_iso_fback_complete(struct usb_ep *ep, struct uac_rtd_params *prm = req->context; struct snd_uac_chip *uac = prm->uac; struct g_audio *audio_dev = uac->audio_dev; - struct uac_params *params = &audio_dev->params; int status = req->status; /* i/f shutting down */ @@ -306,7 +303,7 @@ static void u_audio_iso_fback_complete(struct usb_ep *ep, __func__, status, req->actual, req->length); u_audio_set_fback_frequency(audio_dev->gadget->speed, audio_dev->out_ep, - params->c_srate, prm->pitch, + prm->srate, prm->pitch, req->buf); if (usb_ep_queue(ep, req, GFP_ATOMIC)) @@ -390,16 +387,14 @@ static int uac_pcm_open(struct snd_pcm_substream *substream) struct snd_pcm_runtime *runtime = substream->runtime; struct g_audio *audio_dev; struct uac_params *params; + struct uac_rtd_params *prm; int p_ssize, c_ssize; - int p_srate, c_srate; int p_chmask, c_chmask; audio_dev = uac->audio_dev; params = &audio_dev->params; p_ssize = params->p_ssize; c_ssize = params->c_ssize; - p_srate = params->p_srate; - c_srate = params->c_srate; p_chmask = params->p_chmask; c_chmask = params->c_chmask; uac->p_residue_mil = 0; @@ -407,19 +402,18 @@ static int uac_pcm_open(struct snd_pcm_substream *substream) runtime->hw = uac_pcm_hardware; if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { - runtime->hw.rate_min = p_srate; runtime->hw.formats = uac_ssize_to_fmt(p_ssize); runtime->hw.channels_min = num_channels(p_chmask); - runtime->hw.period_bytes_min = 2 * uac->p_prm.max_psize - / runtime->hw.periods_min; + prm = &uac->p_prm; } else { - runtime->hw.rate_min = c_srate; runtime->hw.formats = uac_ssize_to_fmt(c_ssize); runtime->hw.channels_min = num_channels(c_chmask); - runtime->hw.period_bytes_min = 2 * uac->c_prm.max_psize - / runtime->hw.periods_min; + prm = &uac->c_prm; } + runtime->hw.period_bytes_min = 2 * prm->max_psize + / runtime->hw.periods_min; + runtime->hw.rate_min = prm->srate; runtime->hw.rate_max = runtime->hw.rate_min; runtime->hw.channels_max = runtime->hw.channels_min; @@ -499,12 +493,18 @@ static inline void free_ep_fback(struct uac_rtd_params *prm, struct usb_ep *ep) int u_audio_set_capture_srate(struct g_audio *audio_dev, int srate) { struct uac_params *params = &audio_dev->params; + struct snd_uac_chip *uac = audio_dev->uac; + struct uac_rtd_params *prm; int i; + unsigned long flags; dev_dbg(&audio_dev->gadget->dev, "%s: srate %d\n", __func__, srate); + prm = &uac->c_prm; for (i = 0; i < UAC_MAX_RATES; i++) { if (params->c_srates[i] == srate) { - params->c_srate = srate; + spin_lock_irqsave(&prm->lock, flags); + prm->srate = srate; + spin_unlock_irqrestore(&prm->lock, flags); return 0; } if (params->c_srates[i] == 0) @@ -518,12 +518,18 @@ EXPORT_SYMBOL_GPL(u_audio_set_capture_srate); int u_audio_set_playback_srate(struct g_audio *audio_dev, int srate) { struct uac_params *params = &audio_dev->params; + struct snd_uac_chip *uac = audio_dev->uac; + struct uac_rtd_params *prm; int i; + unsigned long flags; dev_dbg(&audio_dev->gadget->dev, "%s: srate %d\n", __func__, srate); + prm = &uac->p_prm; for (i = 0; i < UAC_MAX_RATES; i++) { if (params->p_srates[i] == srate) { - params->p_srate = srate; + spin_lock_irqsave(&prm->lock, flags); + prm->srate = srate; + spin_unlock_irqrestore(&prm->lock, flags); return 0; } if (params->p_srates[i] == 0) @@ -545,9 +551,9 @@ int u_audio_start_capture(struct g_audio *audio_dev) struct uac_params *params = &audio_dev->params; int req_len, i; - dev_dbg(dev, "start capture with rate %d\n", params->c_srate); - ep = audio_dev->out_ep; prm = &uac->c_prm; + dev_dbg(dev, "start capture with rate %d\n", prm->srate); + ep = audio_dev->out_ep; config_ep_by_speed(gadget, &audio_dev->func, ep); req_len = ep->maxpacket; @@ -604,7 +610,7 @@ int u_audio_start_capture(struct g_audio *audio_dev) */ prm->pitch = 1000000; u_audio_set_fback_frequency(audio_dev->gadget->speed, ep, - params->c_srate, prm->pitch, + prm->srate, prm->pitch, req_fback->buf); if (usb_ep_queue(ep_fback, req_fback, GFP_ATOMIC)) @@ -638,9 +644,9 @@ int u_audio_start_playback(struct g_audio *audio_dev) int req_len, i; unsigned int p_pktsize; - dev_dbg(dev, "start playback with rate %d\n", params->p_srate); - ep = audio_dev->in_ep; prm = &uac->p_prm; + dev_dbg(dev, "start playback with rate %d\n", prm->srate); + ep = audio_dev->in_ep; config_ep_by_speed(gadget, &audio_dev->func, ep); ep_desc = ep->desc; @@ -661,7 +667,7 @@ int u_audio_start_playback(struct g_audio *audio_dev) uac->p_interval = factor / (1 << (ep_desc->bInterval - 1)); p_pktsize = min_t(unsigned int, uac->p_framesize * - (params->p_srate / uac->p_interval), + (prm->srate / uac->p_interval), ep->maxpacket); req_len = p_pktsize; @@ -1037,15 +1043,11 @@ static int u_audio_rate_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { struct uac_rtd_params *prm = snd_kcontrol_chip(kcontrol); - struct snd_uac_chip *uac = prm->uac; - struct g_audio *audio_dev = uac->audio_dev; - struct uac_params *params = &audio_dev->params; - - if (prm == &uac->c_prm) - ucontrol->value.integer.value[0] = params->c_srate; - else - ucontrol->value.integer.value[0] = params->p_srate; + unsigned long flags; + spin_lock_irqsave(&prm->lock, flags); + ucontrol->value.integer.value[0] = prm->srate; + spin_unlock_irqrestore(&prm->lock, flags); return 0; } @@ -1117,6 +1119,7 @@ int g_audio_setup(struct g_audio *g_audio, const char *pcm_name, spin_lock_init(&prm->lock); uac->c_prm.uac = uac; prm->max_psize = g_audio->out_ep_maxpsize; + prm->srate = params->c_srates[0]; prm->reqs = kcalloc(params->req_number, sizeof(struct usb_request *), @@ -1141,6 +1144,7 @@ int g_audio_setup(struct g_audio *g_audio, const char *pcm_name, spin_lock_init(&prm->lock); uac->p_prm.uac = uac; prm->max_psize = g_audio->in_ep_maxpsize; + prm->srate = params->p_srates[0]; prm->reqs = kcalloc(params->req_number, sizeof(struct usb_request *), diff --git a/drivers/usb/gadget/function/u_audio.h b/drivers/usb/gadget/function/u_audio.h index 76b5b8169444..84579fe81b92 100644 --- a/drivers/usb/gadget/function/u_audio.h +++ b/drivers/usb/gadget/function/u_audio.h @@ -42,17 +42,17 @@ struct uac_params { /* playback */ int p_chmask; /* channel mask */ int p_srates[UAC_MAX_RATES]; /* available rates in Hz (0 terminated list) */ - int p_srate; /* selected rate in Hz */ int p_ssize; /* sample size */ struct uac_fu_params p_fu; /* Feature Unit parameters */ /* capture */ int c_chmask; /* channel mask */ int c_srates[UAC_MAX_RATES]; /* available rates in Hz (0 terminated list) */ - int c_srate; /* selected rate in Hz */ int c_ssize; /* sample size */ struct uac_fu_params c_fu; /* Feature Unit parameters */ + /* rates are dynamic, in uac_rtd_params */ + int req_number; /* number of preallocated requests */ int fb_max; /* upper frequency drift feedback limit per-mil */ }; From 37e0d5eddb56e6840a3171be6fe193460f57d6c9 Mon Sep 17 00:00:00 2001 From: Pavel Hofman Date: Fri, 21 Jan 2022 16:53:02 +0100 Subject: [PATCH 20/91] UPSTREAM: usb: gadget: u_audio: Add capture/playback srate getter UAC1/UAC2 functions will need to query u_audio about the currently set srate. Add the getter functions. Signed-off-by: Pavel Hofman Link: https://lore.kernel.org/r/20220121155308.48794-5-pavel.hofman@ivitera.com Signed-off-by: Greg Kroah-Hartman Bug: 235196743 (cherry picked from commit eb3a1ce6f5ed2c047bcae4aad76b7ee711715c7d) Change-Id: Ica0243b6f65d7e568d1e7d4adfe85b7e711a5684 Signed-off-by: Luiz Matheus --- drivers/usb/gadget/function/u_audio.c | 28 +++++++++++++++++++++++++++ drivers/usb/gadget/function/u_audio.h | 2 ++ 2 files changed, 30 insertions(+) diff --git a/drivers/usb/gadget/function/u_audio.c b/drivers/usb/gadget/function/u_audio.c index 7e4561523075..7e770440c9e4 100644 --- a/drivers/usb/gadget/function/u_audio.c +++ b/drivers/usb/gadget/function/u_audio.c @@ -515,6 +515,20 @@ int u_audio_set_capture_srate(struct g_audio *audio_dev, int srate) } EXPORT_SYMBOL_GPL(u_audio_set_capture_srate); +int u_audio_get_capture_srate(struct g_audio *audio_dev, u32 *val) +{ + struct snd_uac_chip *uac = audio_dev->uac; + struct uac_rtd_params *prm; + unsigned long flags; + + prm = &uac->c_prm; + spin_lock_irqsave(&prm->lock, flags); + *val = prm->srate; + spin_unlock_irqrestore(&prm->lock, flags); + return 0; +} +EXPORT_SYMBOL_GPL(u_audio_get_capture_srate); + int u_audio_set_playback_srate(struct g_audio *audio_dev, int srate) { struct uac_params *params = &audio_dev->params; @@ -540,6 +554,20 @@ int u_audio_set_playback_srate(struct g_audio *audio_dev, int srate) } EXPORT_SYMBOL_GPL(u_audio_set_playback_srate); +int u_audio_get_playback_srate(struct g_audio *audio_dev, u32 *val) +{ + struct snd_uac_chip *uac = audio_dev->uac; + struct uac_rtd_params *prm; + unsigned long flags; + + prm = &uac->p_prm; + spin_lock_irqsave(&prm->lock, flags); + *val = prm->srate; + spin_unlock_irqrestore(&prm->lock, flags); + return 0; +} +EXPORT_SYMBOL_GPL(u_audio_get_playback_srate); + int u_audio_start_capture(struct g_audio *audio_dev) { struct snd_uac_chip *uac = audio_dev->uac; diff --git a/drivers/usb/gadget/function/u_audio.h b/drivers/usb/gadget/function/u_audio.h index 84579fe81b92..5e6ed0f31cc3 100644 --- a/drivers/usb/gadget/function/u_audio.h +++ b/drivers/usb/gadget/function/u_audio.h @@ -120,7 +120,9 @@ void u_audio_stop_capture(struct g_audio *g_audio); int u_audio_start_playback(struct g_audio *g_audio); void u_audio_stop_playback(struct g_audio *g_audio); +int u_audio_get_capture_srate(struct g_audio *audio_dev, u32 *val); int u_audio_set_capture_srate(struct g_audio *audio_dev, int srate); +int u_audio_get_playback_srate(struct g_audio *audio_dev, u32 *val); int u_audio_set_playback_srate(struct g_audio *audio_dev, int srate); int u_audio_get_volume(struct g_audio *g_audio, int playback, s16 *val); From bedc53fae42a7010f2bee164df2c0ae0147e42db Mon Sep 17 00:00:00 2001 From: Pavel Hofman Date: Fri, 21 Jan 2022 16:52:59 +0100 Subject: [PATCH 21/91] UPSTREAM: usb: gadget:audio: Replace deprecated macro S_IRUGO Use octal digits as suggested by checkpatch instead of the deprecated macro. Signed-off-by: Pavel Hofman Link: https://lore.kernel.org/r/20220121155308.48794-2-pavel.hofman@ivitera.com Signed-off-by: Greg Kroah-Hartman Bug: 235196743 (cherry picked from commit ce6a7bfbe57161edb53fb37e7191008ceff00752) Change-Id: I3f15494218cd2b11e671e4eacb98e57ebf154f12 Signed-off-by: Luiz Matheus --- drivers/usb/gadget/legacy/audio.c | 36 +++++++++++++++---------------- 1 file changed, 18 insertions(+), 18 deletions(-) diff --git a/drivers/usb/gadget/legacy/audio.c b/drivers/usb/gadget/legacy/audio.c index a748ed0842e8..5ec477ffab7f 100644 --- a/drivers/usb/gadget/legacy/audio.c +++ b/drivers/usb/gadget/legacy/audio.c @@ -22,32 +22,32 @@ USB_GADGET_COMPOSITE_OPTIONS(); /* Playback(USB-IN) Default Stereo - Fl/Fr */ static int p_chmask = UAC2_DEF_PCHMASK; -module_param(p_chmask, uint, S_IRUGO); +module_param(p_chmask, uint, 0444); MODULE_PARM_DESC(p_chmask, "Playback Channel Mask"); /* Playback Default 48 KHz */ static int p_srate = UAC2_DEF_PSRATE; -module_param(p_srate, uint, S_IRUGO); +module_param(p_srate, uint, 0444); MODULE_PARM_DESC(p_srate, "Playback Sampling Rate"); /* Playback Default 16bits/sample */ static int p_ssize = UAC2_DEF_PSSIZE; -module_param(p_ssize, uint, S_IRUGO); +module_param(p_ssize, uint, 0444); MODULE_PARM_DESC(p_ssize, "Playback Sample Size(bytes)"); /* Capture(USB-OUT) Default Stereo - Fl/Fr */ static int c_chmask = UAC2_DEF_CCHMASK; -module_param(c_chmask, uint, S_IRUGO); +module_param(c_chmask, uint, 0444); MODULE_PARM_DESC(c_chmask, "Capture Channel Mask"); /* Capture Default 64 KHz */ static int c_srate = UAC2_DEF_CSRATE; -module_param(c_srate, uint, S_IRUGO); +module_param(c_srate, uint, 0444); MODULE_PARM_DESC(c_srate, "Capture Sampling Rate"); /* Capture Default 16bits/sample */ static int c_ssize = UAC2_DEF_CSSIZE; -module_param(c_ssize, uint, S_IRUGO); +module_param(c_ssize, uint, 0444); MODULE_PARM_DESC(c_ssize, "Capture Sample Size(bytes)"); #else #ifndef CONFIG_GADGET_UAC1_LEGACY @@ -55,58 +55,58 @@ MODULE_PARM_DESC(c_ssize, "Capture Sample Size(bytes)"); /* Playback(USB-IN) Default Stereo - Fl/Fr */ static int p_chmask = UAC1_DEF_PCHMASK; -module_param(p_chmask, uint, S_IRUGO); +module_param(p_chmask, uint, 0444); MODULE_PARM_DESC(p_chmask, "Playback Channel Mask"); /* Playback Default 48 KHz */ static int p_srate = UAC1_DEF_PSRATE; -module_param(p_srate, uint, S_IRUGO); +module_param(p_srate, uint, 0444); MODULE_PARM_DESC(p_srate, "Playback Sampling Rate"); /* Playback Default 16bits/sample */ static int p_ssize = UAC1_DEF_PSSIZE; -module_param(p_ssize, uint, S_IRUGO); +module_param(p_ssize, uint, 0444); MODULE_PARM_DESC(p_ssize, "Playback Sample Size(bytes)"); /* Capture(USB-OUT) Default Stereo - Fl/Fr */ static int c_chmask = UAC1_DEF_CCHMASK; -module_param(c_chmask, uint, S_IRUGO); +module_param(c_chmask, uint, 0444); MODULE_PARM_DESC(c_chmask, "Capture Channel Mask"); /* Capture Default 48 KHz */ static int c_srate = UAC1_DEF_CSRATE; -module_param(c_srate, uint, S_IRUGO); +module_param(c_srate, uint, 0444); MODULE_PARM_DESC(c_srate, "Capture Sampling Rate"); /* Capture Default 16bits/sample */ static int c_ssize = UAC1_DEF_CSSIZE; -module_param(c_ssize, uint, S_IRUGO); +module_param(c_ssize, uint, 0444); MODULE_PARM_DESC(c_ssize, "Capture Sample Size(bytes)"); #else /* CONFIG_GADGET_UAC1_LEGACY */ #include "u_uac1_legacy.h" static char *fn_play = FILE_PCM_PLAYBACK; -module_param(fn_play, charp, S_IRUGO); +module_param(fn_play, charp, 0444); MODULE_PARM_DESC(fn_play, "Playback PCM device file name"); static char *fn_cap = FILE_PCM_CAPTURE; -module_param(fn_cap, charp, S_IRUGO); +module_param(fn_cap, charp, 0444); MODULE_PARM_DESC(fn_cap, "Capture PCM device file name"); static char *fn_cntl = FILE_CONTROL; -module_param(fn_cntl, charp, S_IRUGO); +module_param(fn_cntl, charp, 0444); MODULE_PARM_DESC(fn_cntl, "Control device file name"); static int req_buf_size = UAC1_OUT_EP_MAX_PACKET_SIZE; -module_param(req_buf_size, int, S_IRUGO); +module_param(req_buf_size, int, 0444); MODULE_PARM_DESC(req_buf_size, "ISO OUT endpoint request buffer size"); static int req_count = UAC1_REQ_COUNT; -module_param(req_count, int, S_IRUGO); +module_param(req_count, int, 0444); MODULE_PARM_DESC(req_count, "ISO OUT endpoint request count"); static int audio_buf_size = UAC1_AUDIO_BUF_SIZE; -module_param(audio_buf_size, int, S_IRUGO); +module_param(audio_buf_size, int, 0444); MODULE_PARM_DESC(audio_buf_size, "Audio buffer size"); #endif /* CONFIG_GADGET_UAC1_LEGACY */ #endif From ae03eadb425cb80c5cdc6e372806197bf9e625d3 Mon Sep 17 00:00:00 2001 From: Julian Scheel Date: Fri, 21 Jan 2022 16:53:03 +0100 Subject: [PATCH 22/91] UPSTREAM: usb: gadget: f_uac2: Support multiple sampling rates A list of sampling rates can be specified via configfs. All enabled sampling rates are sent to the USB host on request. When the host selects a sampling rate, the internal active rate (stored in struct f_uac2) is updated. The gadget no longer supports only one frequency. Therefore USB strings corresponding to the clock sources are renamed from specific Hz value to general names Input clock/Output clock. Config strings with single value stay compatible with the previous version. Multiple samplerates passed as configuration arrays to g_audio module when built for f_uac2. Signed-off-by: Julian Scheel Signed-off-by: Pavel Hofman Link: https://lore.kernel.org/r/20220121155308.48794-6-pavel.hofman@ivitera.com Signed-off-by: Greg Kroah-Hartman Bug: 235196743 (cherry picked from commit a7339e4f5788bd088bb0be1f96a6cce459676ed0) Change-Id: I3ee59833975c6d010cd3335da0746eec828f4a0e Signed-off-by: Luiz Matheus --- .../ABI/testing/configfs-usb-gadget-uac2 | 4 +- Documentation/usb/gadget-testing.rst | 4 +- drivers/usb/gadget/function/f_uac2.c | 197 ++++++++++++++---- drivers/usb/gadget/function/u_uac2.h | 5 +- drivers/usb/gadget/legacy/audio.c | 25 ++- 5 files changed, 182 insertions(+), 53 deletions(-) diff --git a/Documentation/ABI/testing/configfs-usb-gadget-uac2 b/Documentation/ABI/testing/configfs-usb-gadget-uac2 index 7fb3dbe26857..9d2f59ab9701 100644 --- a/Documentation/ABI/testing/configfs-usb-gadget-uac2 +++ b/Documentation/ABI/testing/configfs-usb-gadget-uac2 @@ -6,7 +6,7 @@ Description: ===================== ======================================= c_chmask capture channel mask - c_srate capture sampling rate + c_srate list of capture sampling rates (comma-separated) c_ssize capture sample size (bytes) c_sync capture synchronization type (async/adaptive) @@ -20,7 +20,7 @@ Description: (in 1/256 dB) fb_max maximum extra bandwidth in async mode p_chmask playback channel mask - p_srate playback sampling rate + p_srate list of playback sampling rates (comma-separated) p_ssize playback sample size (bytes) p_mute_present playback mute control enable p_volume_present playback volume control enable diff --git a/Documentation/usb/gadget-testing.rst b/Documentation/usb/gadget-testing.rst index c979e0512284..49b13a5fc2c6 100644 --- a/Documentation/usb/gadget-testing.rst +++ b/Documentation/usb/gadget-testing.rst @@ -726,7 +726,7 @@ The uac2 function provides these attributes in its function directory: ================ ==================================================== c_chmask capture channel mask - c_srate capture sampling rate + c_srate list of capture sampling rates (comma-separated) c_ssize capture sample size (bytes) c_sync capture synchronization type (async/adaptive) c_mute_present capture mute control enable @@ -736,7 +736,7 @@ The uac2 function provides these attributes in its function directory: c_volume_res capture volume control resolution (in 1/256 dB) fb_max maximum extra bandwidth in async mode p_chmask playback channel mask - p_srate playback sampling rate + p_srate list of playback sampling rates (comma-separated) p_ssize playback sample size (bytes) p_mute_present playback mute control enable p_volume_present playback volume control enable diff --git a/drivers/usb/gadget/function/f_uac2.c b/drivers/usb/gadget/function/f_uac2.c index e7f233916271..991dc28adc99 100644 --- a/drivers/usb/gadget/function/f_uac2.c +++ b/drivers/usb/gadget/function/f_uac2.c @@ -70,6 +70,8 @@ struct f_uac2 { /* Interrupt IN endpoint of AC interface */ struct usb_ep *int_ep; atomic_t int_count; + /* transient state, only valid during handling of a single control request */ + int clock_id; }; static inline struct f_uac2 *func_to_uac2(struct usb_function *f) @@ -104,14 +106,11 @@ enum { STR_AS_IN_ALT1, }; -static char clksrc_in[8]; -static char clksrc_out[8]; - static struct usb_string strings_fn[] = { [STR_ASSOC].s = "Source/Sink", [STR_IF_CTRL].s = "Topology Control", - [STR_CLKSRC_IN].s = clksrc_in, - [STR_CLKSRC_OUT].s = clksrc_out, + [STR_CLKSRC_IN].s = "Input Clock", + [STR_CLKSRC_OUT].s = "Output Clock", [STR_USB_IT].s = "USBH Out", [STR_IO_IT].s = "USBD Out", [STR_USB_OT].s = "USBH In", @@ -166,7 +165,7 @@ static struct uac_clock_source_descriptor in_clk_src_desc = { .bDescriptorSubtype = UAC2_CLOCK_SOURCE, /* .bClockID = DYNAMIC */ .bmAttributes = UAC_CLOCK_SOURCE_TYPE_INT_FIXED, - .bmControls = (CONTROL_RDONLY << CLK_FREQ_CTRL), + .bmControls = (CONTROL_RDWR << CLK_FREQ_CTRL), .bAssocTerminal = 0, }; @@ -178,7 +177,7 @@ static struct uac_clock_source_descriptor out_clk_src_desc = { .bDescriptorSubtype = UAC2_CLOCK_SOURCE, /* .bClockID = DYNAMIC */ .bmAttributes = UAC_CLOCK_SOURCE_TYPE_INT_FIXED, - .bmControls = (CONTROL_RDONLY << CLK_FREQ_CTRL), + .bmControls = (CONTROL_RDWR << CLK_FREQ_CTRL), .bAssocTerminal = 0, }; @@ -634,13 +633,37 @@ struct cntrl_cur_lay3 { __le32 dCUR; }; -struct cntrl_range_lay3 { - __le16 wNumSubRanges; +struct cntrl_subrange_lay3 { __le32 dMIN; __le32 dMAX; __le32 dRES; } __packed; +#define ranges_lay3_size(c) (sizeof(c.wNumSubRanges) \ + + le16_to_cpu(c.wNumSubRanges) \ + * sizeof(struct cntrl_subrange_lay3)) + +#define DECLARE_UAC2_CNTRL_RANGES_LAY3(k, n) \ + struct cntrl_ranges_lay3_##k { \ + __le16 wNumSubRanges; \ + struct cntrl_subrange_lay3 r[n]; \ +} __packed + +DECLARE_UAC2_CNTRL_RANGES_LAY3(srates, UAC_MAX_RATES); + +static int get_max_srate(const int *srates) +{ + int i, max_srate = 0; + + for (i = 0; i < UAC_MAX_RATES; i++) { + if (srates[i] == 0) + break; + if (srates[i] > max_srate) + max_srate = srates[i]; + } + return max_srate; +} + static int set_ep_max_packet_size(const struct f_uac2_opts *uac2_opts, struct usb_endpoint_descriptor *ep_desc, enum usb_device_speed speed, bool is_playback) @@ -667,11 +690,11 @@ static int set_ep_max_packet_size(const struct f_uac2_opts *uac2_opts, if (is_playback) { chmask = uac2_opts->p_chmask; - srate = uac2_opts->p_srate; + srate = get_max_srate(uac2_opts->p_srates); ssize = uac2_opts->p_ssize; } else { chmask = uac2_opts->c_chmask; - srate = uac2_opts->c_srate; + srate = get_max_srate(uac2_opts->c_srates); ssize = uac2_opts->c_ssize; } @@ -912,10 +935,10 @@ static int afunc_validate_opts(struct g_audio *agdev, struct device *dev) } else if ((opts->c_ssize < 1) || (opts->c_ssize > 4)) { dev_err(dev, "Error: incorrect capture sample size\n"); return -EINVAL; - } else if (!opts->p_srate) { + } else if (!opts->p_srates[0]) { dev_err(dev, "Error: incorrect playback sampling rate\n"); return -EINVAL; - } else if (!opts->c_srate) { + } else if (!opts->c_srates[0]) { dev_err(dev, "Error: incorrect capture sampling rate\n"); return -EINVAL; } @@ -1041,9 +1064,6 @@ afunc_bind(struct usb_configuration *cfg, struct usb_function *fn) *bma = cpu_to_le32(control); } - snprintf(clksrc_in, sizeof(clksrc_in), "%uHz", uac2_opts->p_srate); - snprintf(clksrc_out, sizeof(clksrc_out), "%uHz", uac2_opts->c_srate); - ret = usb_interface_id(cfg, fn); if (ret < 0) { dev_err(dev, "%s:%d Error!\n", __func__, __LINE__); @@ -1213,7 +1233,8 @@ afunc_bind(struct usb_configuration *cfg, struct usb_function *fn) agdev->gadget = gadget; agdev->params.p_chmask = uac2_opts->p_chmask; - agdev->params.p_srates[0] = uac2_opts->p_srate; + memcpy(agdev->params.p_srates, uac2_opts->p_srates, + sizeof(agdev->params.p_srates)); agdev->params.p_ssize = uac2_opts->p_ssize; if (FUIN_EN(uac2_opts)) { agdev->params.p_fu.id = USB_IN_FU_ID; @@ -1224,7 +1245,8 @@ afunc_bind(struct usb_configuration *cfg, struct usb_function *fn) agdev->params.p_fu.volume_res = uac2_opts->p_volume_res; } agdev->params.c_chmask = uac2_opts->c_chmask; - agdev->params.c_srates[0] = uac2_opts->c_srate; + memcpy(agdev->params.c_srates, uac2_opts->c_srates, + sizeof(agdev->params.c_srates)); agdev->params.c_ssize = uac2_opts->c_ssize; if (FUOUT_EN(uac2_opts)) { agdev->params.c_fu.id = USB_OUT_FU_ID; @@ -1427,10 +1449,10 @@ in_rq_cur(struct usb_function *fn, const struct usb_ctrlrequest *cr) u8 entity_id = (w_index >> 8) & 0xff; u8 control_selector = w_value >> 8; int value = -EOPNOTSUPP; - int p_srate, c_srate; + u32 p_srate, c_srate; - p_srate = opts->p_srate; - c_srate = opts->c_srate; + u_audio_get_playback_srate(agdev, &p_srate); + u_audio_get_capture_srate(agdev, &c_srate); if ((entity_id == USB_IN_CLK_ID) || (entity_id == USB_OUT_CLK_ID)) { if (control_selector == UAC2_CS_CONTROL_SAM_FREQ) { @@ -1504,28 +1526,39 @@ in_rq_range(struct usb_function *fn, const struct usb_ctrlrequest *cr) u8 entity_id = (w_index >> 8) & 0xff; u8 control_selector = w_value >> 8; int value = -EOPNOTSUPP; - int p_srate, c_srate; - - p_srate = opts->p_srate; - c_srate = opts->c_srate; if ((entity_id == USB_IN_CLK_ID) || (entity_id == USB_OUT_CLK_ID)) { if (control_selector == UAC2_CS_CONTROL_SAM_FREQ) { - struct cntrl_range_lay3 r; + struct cntrl_ranges_lay3_srates rs; + int i; + int wNumSubRanges = 0; + int srate; + int *srates; if (entity_id == USB_IN_CLK_ID) - r.dMIN = cpu_to_le32(p_srate); + srates = opts->p_srates; else if (entity_id == USB_OUT_CLK_ID) - r.dMIN = cpu_to_le32(c_srate); + srates = opts->c_srates; else return -EOPNOTSUPP; + for (i = 0; i < UAC_MAX_RATES; i++) { + srate = srates[i]; + if (srate == 0) + break; - r.dMAX = r.dMIN; - r.dRES = 0; - r.wNumSubRanges = cpu_to_le16(1); - - value = min_t(unsigned int, w_length, sizeof(r)); - memcpy(req->buf, &r, value); + rs.r[wNumSubRanges].dMIN = cpu_to_le32(srate); + rs.r[wNumSubRanges].dMAX = cpu_to_le32(srate); + rs.r[wNumSubRanges].dRES = 0; + wNumSubRanges++; + dev_dbg(&agdev->gadget->dev, + "%s(): clk %d: rate ID %d: %d\n", + __func__, entity_id, wNumSubRanges, srate); + } + rs.wNumSubRanges = cpu_to_le16(wNumSubRanges); + value = min_t(unsigned int, w_length, ranges_lay3_size(rs)); + dev_dbg(&agdev->gadget->dev, "%s(): sending %d rates, size %d\n", + __func__, rs.wNumSubRanges, value); + memcpy(req->buf, &rs, value); } else { dev_err(&agdev->gadget->dev, "%s:%d control_selector=%d TODO!\n", @@ -1584,6 +1617,25 @@ ac_rq_in(struct usb_function *fn, const struct usb_ctrlrequest *cr) return -EOPNOTSUPP; } +static void uac2_cs_control_sam_freq(struct usb_ep *ep, struct usb_request *req) +{ + struct usb_function *fn = ep->driver_data; + struct g_audio *agdev = func_to_g_audio(fn); + struct f_uac2 *uac2 = func_to_uac2(fn); + u32 val; + + if (req->actual != 4) + return; + + val = le32_to_cpu(*((__le32 *)req->buf)); + dev_dbg(&agdev->gadget->dev, "%s val: %d.\n", __func__, val); + if (uac2->clock_id == USB_IN_CLK_ID) { + u_audio_set_playback_srate(agdev, val); + } else if (uac2->clock_id == USB_OUT_CLK_ID) { + u_audio_set_capture_srate(agdev, val); + } +} + static void out_rq_cur_complete(struct usb_ep *ep, struct usb_request *req) { @@ -1635,6 +1687,7 @@ out_rq_cur_complete(struct usb_ep *ep, struct usb_request *req) static int out_rq_cur(struct usb_function *fn, const struct usb_ctrlrequest *cr) { + struct usb_composite_dev *cdev = fn->config->cdev; struct usb_request *req = fn->config->cdev->req; struct g_audio *agdev = func_to_g_audio(fn); struct f_uac2_opts *opts = g_audio_to_uac2_opts(agdev); @@ -1644,10 +1697,17 @@ out_rq_cur(struct usb_function *fn, const struct usb_ctrlrequest *cr) u16 w_value = le16_to_cpu(cr->wValue); u8 entity_id = (w_index >> 8) & 0xff; u8 control_selector = w_value >> 8; + u8 clock_id = w_index >> 8; if ((entity_id == USB_IN_CLK_ID) || (entity_id == USB_OUT_CLK_ID)) { - if (control_selector == UAC2_CS_CONTROL_SAM_FREQ) + if (control_selector == UAC2_CS_CONTROL_SAM_FREQ) { + dev_dbg(&agdev->gadget->dev, + "control_selector UAC2_CS_CONTROL_SAM_FREQ, clock: %d\n", clock_id); + cdev->gadget->ep0->driver_data = fn; + uac2->clock_id = clock_id; + req->complete = uac2_cs_control_sam_freq; return w_length; + } } else if ((FUIN_EN(opts) && (entity_id == USB_IN_FU_ID)) || (FUOUT_EN(opts) && (entity_id == USB_OUT_FU_ID))) { memcpy(&uac2->setup_cr, cr, sizeof(*cr)); @@ -1840,11 +1900,70 @@ end: \ \ CONFIGFS_ATTR(f_uac2_opts_, name) +#define UAC2_RATE_ATTRIBUTE(name) \ +static ssize_t f_uac2_opts_##name##_show(struct config_item *item, \ + char *page) \ +{ \ + struct f_uac2_opts *opts = to_f_uac2_opts(item); \ + int result = 0; \ + int i; \ + \ + mutex_lock(&opts->lock); \ + page[0] = '\0'; \ + for (i = 0; i < UAC_MAX_RATES; i++) { \ + if (opts->name##s[i] == 0) \ + break; \ + result += sprintf(page + strlen(page), "%u,", \ + opts->name##s[i]); \ + } \ + if (strlen(page) > 0) \ + page[strlen(page) - 1] = '\n'; \ + mutex_unlock(&opts->lock); \ + \ + return result; \ +} \ + \ +static ssize_t f_uac2_opts_##name##_store(struct config_item *item, \ + const char *page, size_t len) \ +{ \ + struct f_uac2_opts *opts = to_f_uac2_opts(item); \ + char *split_page = NULL; \ + int ret = -EINVAL; \ + char *token; \ + u32 num; \ + int i; \ + \ + mutex_lock(&opts->lock); \ + if (opts->refcnt) { \ + ret = -EBUSY; \ + goto end; \ + } \ + \ + i = 0; \ + memset(opts->name##s, 0x00, sizeof(opts->name##s)); \ + split_page = kstrdup(page, GFP_KERNEL); \ + while ((token = strsep(&split_page, ",")) != NULL) { \ + ret = kstrtou32(token, 0, &num); \ + if (ret) \ + goto end; \ + \ + opts->name##s[i++] = num; \ + ret = len; \ + }; \ + \ +end: \ + kfree(split_page); \ + mutex_unlock(&opts->lock); \ + return ret; \ +} \ + \ +CONFIGFS_ATTR(f_uac2_opts_, name) + UAC2_ATTRIBUTE(u32, p_chmask); -UAC2_ATTRIBUTE(u32, p_srate); +UAC2_RATE_ATTRIBUTE(p_srate); UAC2_ATTRIBUTE(u32, p_ssize); UAC2_ATTRIBUTE(u32, c_chmask); -UAC2_ATTRIBUTE(u32, c_srate); +UAC2_RATE_ATTRIBUTE(c_srate); UAC2_ATTRIBUTE_SYNC(c_sync); UAC2_ATTRIBUTE(u32, c_ssize); UAC2_ATTRIBUTE(u32, req_number); @@ -1917,10 +2036,10 @@ static struct usb_function_instance *afunc_alloc_inst(void) &f_uac2_func_type); opts->p_chmask = UAC2_DEF_PCHMASK; - opts->p_srate = UAC2_DEF_PSRATE; + opts->p_srates[0] = UAC2_DEF_PSRATE; opts->p_ssize = UAC2_DEF_PSSIZE; opts->c_chmask = UAC2_DEF_CCHMASK; - opts->c_srate = UAC2_DEF_CSRATE; + opts->c_srates[0] = UAC2_DEF_CSRATE; opts->c_ssize = UAC2_DEF_CSSIZE; opts->c_sync = UAC2_DEF_CSYNC; diff --git a/drivers/usb/gadget/function/u_uac2.h b/drivers/usb/gadget/function/u_uac2.h index e0c8e3513bfd..6bfcf6d0e863 100644 --- a/drivers/usb/gadget/function/u_uac2.h +++ b/drivers/usb/gadget/function/u_uac2.h @@ -14,6 +14,7 @@ #define U_UAC2_H #include +#include "uac_common.h" #define UAC2_DEF_PCHMASK 0x3 #define UAC2_DEF_PSRATE 48000 @@ -35,10 +36,10 @@ struct f_uac2_opts { struct usb_function_instance func_inst; int p_chmask; - int p_srate; + int p_srates[UAC_MAX_RATES]; int p_ssize; int c_chmask; - int c_srate; + int c_srates[UAC_MAX_RATES]; int c_ssize; int c_sync; diff --git a/drivers/usb/gadget/legacy/audio.c b/drivers/usb/gadget/legacy/audio.c index 5ec477ffab7f..d14b9f2d4c07 100644 --- a/drivers/usb/gadget/legacy/audio.c +++ b/drivers/usb/gadget/legacy/audio.c @@ -26,9 +26,10 @@ module_param(p_chmask, uint, 0444); MODULE_PARM_DESC(p_chmask, "Playback Channel Mask"); /* Playback Default 48 KHz */ -static int p_srate = UAC2_DEF_PSRATE; -module_param(p_srate, uint, 0444); -MODULE_PARM_DESC(p_srate, "Playback Sampling Rate"); +static int p_srates[UAC_MAX_RATES] = {UAC2_DEF_PSRATE}; +static int p_srates_cnt = 1; +module_param_array_named(p_srate, p_srates, uint, &p_srates_cnt, 0444); +MODULE_PARM_DESC(p_srate, "Playback Sampling Rates (array)"); /* Playback Default 16bits/sample */ static int p_ssize = UAC2_DEF_PSSIZE; @@ -41,9 +42,10 @@ module_param(c_chmask, uint, 0444); MODULE_PARM_DESC(c_chmask, "Capture Channel Mask"); /* Capture Default 64 KHz */ -static int c_srate = UAC2_DEF_CSRATE; -module_param(c_srate, uint, 0444); -MODULE_PARM_DESC(c_srate, "Capture Sampling Rate"); +static int c_srates[UAC_MAX_RATES] = {UAC2_DEF_CSRATE}; +static int c_srates_cnt = 1; +module_param_array_named(c_srate, c_srates, uint, &c_srates_cnt, 0444); +MODULE_PARM_DESC(c_srate, "Capture Sampling Rates (array)"); /* Capture Default 16bits/sample */ static int c_ssize = UAC2_DEF_CSSIZE; @@ -237,6 +239,7 @@ static int audio_bind(struct usb_composite_dev *cdev) { #ifndef CONFIG_GADGET_UAC1 struct f_uac2_opts *uac2_opts; + int i; #else #ifndef CONFIG_GADGET_UAC1_LEGACY struct f_uac1_opts *uac1_opts; @@ -263,10 +266,16 @@ static int audio_bind(struct usb_composite_dev *cdev) #ifndef CONFIG_GADGET_UAC1 uac2_opts = container_of(fi_uac2, struct f_uac2_opts, func_inst); uac2_opts->p_chmask = p_chmask; - uac2_opts->p_srate = p_srate; + + for (i = 0; i < p_srates_cnt; ++i) + uac2_opts->p_srates[i] = p_srates[i]; + uac2_opts->p_ssize = p_ssize; uac2_opts->c_chmask = c_chmask; - uac2_opts->c_srate = c_srate; + + for (i = 0; i < c_srates_cnt; ++i) + uac2_opts->c_srates[i] = c_srates[i]; + uac2_opts->c_ssize = c_ssize; uac2_opts->req_number = UAC2_DEF_REQ_NUM; #else From 308955e3a605fa0203219340505b35ec4b577c64 Mon Sep 17 00:00:00 2001 From: Julian Scheel Date: Fri, 21 Jan 2022 16:53:04 +0100 Subject: [PATCH 23/91] UPSTREAM: usb: gadget: f_uac1: Support multiple sampling rates A list of sampling rates can be specified via configfs. All enabled sampling rates are sent to the USB host on request. When the host selects a sampling rate the internal active rate is updated. Config strings with single value stay compatible with the previous version. Multiple samplerates passed as configuration arrays to g_audio module when built for f_uac1. Signed-off-by: Julian Scheel Signed-off-by: Pavel Hofman Link: https://lore.kernel.org/r/20220121155308.48794-7-pavel.hofman@ivitera.com Signed-off-by: Greg Kroah-Hartman Bug: 235196743 (cherry picked from commit 695d39ffc2b59b8333ff85724619514f98613205) Change-Id: I0515eb9ca5ed7e809007ee711aedf389c1b1c40d Signed-off-by: Luiz Matheus --- .../ABI/testing/configfs-usb-gadget-uac1 | 4 +- Documentation/usb/gadget-testing.rst | 4 +- drivers/usb/gadget/function/f_uac1.c | 181 +++++++++++++++--- drivers/usb/gadget/function/u_uac1.h | 5 +- drivers/usb/gadget/legacy/audio.c | 25 ++- 5 files changed, 179 insertions(+), 40 deletions(-) diff --git a/Documentation/ABI/testing/configfs-usb-gadget-uac1 b/Documentation/ABI/testing/configfs-usb-gadget-uac1 index d4b8cf40a9e4..09725e273e9b 100644 --- a/Documentation/ABI/testing/configfs-usb-gadget-uac1 +++ b/Documentation/ABI/testing/configfs-usb-gadget-uac1 @@ -6,7 +6,7 @@ Description: ===================== ======================================= c_chmask capture channel mask - c_srate capture sampling rate + c_srate list of capture sampling rates (comma-separated) c_ssize capture sample size (bytes) c_mute_present capture mute control enable c_volume_present capture volume control enable @@ -17,7 +17,7 @@ Description: c_volume_res capture volume control resolution (in 1/256 dB) p_chmask playback channel mask - p_srate playback sampling rate + p_srate list of playback sampling rates (comma-separated) p_ssize playback sample size (bytes) p_mute_present playback mute control enable p_volume_present playback volume control enable diff --git a/Documentation/usb/gadget-testing.rst b/Documentation/usb/gadget-testing.rst index 49b13a5fc2c6..0a59ec16f833 100644 --- a/Documentation/usb/gadget-testing.rst +++ b/Documentation/usb/gadget-testing.rst @@ -917,7 +917,7 @@ The uac1 function provides these attributes in its function directory: ================ ==================================================== c_chmask capture channel mask - c_srate capture sampling rate + c_srate list of capture sampling rates (comma-separated) c_ssize capture sample size (bytes) c_mute_present capture mute control enable c_volume_present capture volume control enable @@ -925,7 +925,7 @@ The uac1 function provides these attributes in its function directory: c_volume_max capture volume control max value (in 1/256 dB) c_volume_res capture volume control resolution (in 1/256 dB) p_chmask playback channel mask - p_srate playback sampling rate + p_srate list of playback sampling rates (comma-separated) p_ssize playback sample size (bytes) p_mute_present playback mute control enable p_volume_present playback volume control enable diff --git a/drivers/usb/gadget/function/f_uac1.c b/drivers/usb/gadget/function/f_uac1.c index 0397b27df42e..73df76a6fbe0 100644 --- a/drivers/usb/gadget/function/f_uac1.c +++ b/drivers/usb/gadget/function/f_uac1.c @@ -3,6 +3,7 @@ * f_uac1.c -- USB Audio Class 1.0 Function (using u_audio API) * * Copyright (C) 2016 Ruslan Bilovol + * Copyright (C) 2021 Julian Scheel * * This driver doesn't expect any real Audio codec to be present * on the device - the audio streams are simply sinked to and @@ -42,6 +43,9 @@ struct f_uac1 { /* Interrupt IN endpoint of AC interface */ struct usb_ep *int_ep; atomic_t int_count; + int ctl_id; /* EP id */ + int c_srate; /* current capture srate */ + int p_srate; /* current playback prate */ }; static inline struct f_uac1 *func_to_uac1(struct usb_function *f) @@ -188,16 +192,18 @@ static struct uac1_as_header_descriptor as_in_header_desc = { .wFormatTag = cpu_to_le16(UAC_FORMAT_TYPE_I_PCM), }; -DECLARE_UAC_FORMAT_TYPE_I_DISCRETE_DESC(1); +DECLARE_UAC_FORMAT_TYPE_I_DISCRETE_DESC(UAC_MAX_RATES); +#define uac_format_type_i_discrete_descriptor \ + uac_format_type_i_discrete_descriptor_##UAC_MAX_RATES -static struct uac_format_type_i_discrete_descriptor_1 as_out_type_i_desc = { - .bLength = UAC_FORMAT_TYPE_I_DISCRETE_DESC_SIZE(1), +static struct uac_format_type_i_discrete_descriptor as_out_type_i_desc = { + .bLength = 0, /* filled on rate setup */ .bDescriptorType = USB_DT_CS_INTERFACE, .bDescriptorSubtype = UAC_FORMAT_TYPE, .bFormatType = UAC_FORMAT_TYPE_I, .bSubframeSize = 2, .bBitResolution = 16, - .bSamFreqType = 1, + .bSamFreqType = 0, /* filled on rate setup */ }; /* Standard ISO OUT Endpoint Descriptor */ @@ -221,14 +227,14 @@ static struct uac_iso_endpoint_descriptor as_iso_out_desc = { .wLockDelay = cpu_to_le16(1), }; -static struct uac_format_type_i_discrete_descriptor_1 as_in_type_i_desc = { - .bLength = UAC_FORMAT_TYPE_I_DISCRETE_DESC_SIZE(1), +static struct uac_format_type_i_discrete_descriptor as_in_type_i_desc = { + .bLength = 0, /* filled on rate setup */ .bDescriptorType = USB_DT_CS_INTERFACE, .bDescriptorSubtype = UAC_FORMAT_TYPE, .bFormatType = UAC_FORMAT_TYPE_I, .bSubframeSize = 2, .bBitResolution = 16, - .bSamFreqType = 1, + .bSamFreqType = 0, /* filled on rate setup */ }; /* Standard ISO OUT Endpoint Descriptor */ @@ -333,6 +339,30 @@ static struct usb_gadget_strings *uac1_strings[] = { * This function is an ALSA sound card following USB Audio Class Spec 1.0. */ +static void uac_cs_attr_sample_rate(struct usb_ep *ep, struct usb_request *req) +{ + struct usb_function *fn = ep->driver_data; + struct usb_composite_dev *cdev = fn->config->cdev; + struct g_audio *agdev = func_to_g_audio(fn); + struct f_uac1 *uac1 = func_to_uac1(fn); + u8 *buf = (u8 *)req->buf; + u32 val = 0; + + if (req->actual != 3) { + WARN(cdev, "Invalid data size for UAC_EP_CS_ATTR_SAMPLE_RATE.\n"); + return; + } + + val = buf[0] | (buf[1] << 8) | (buf[2] << 16); + if (uac1->ctl_id == (USB_DIR_IN | 2)) { + uac1->p_srate = val; + u_audio_set_playback_srate(agdev, uac1->p_srate); + } else if (uac1->ctl_id == (USB_DIR_OUT | 1)) { + uac1->c_srate = val; + u_audio_set_capture_srate(agdev, uac1->c_srate); + } +} + static void audio_notify_complete(struct usb_ep *_ep, struct usb_request *req) { struct g_audio *audio = req->context; @@ -707,18 +737,27 @@ static int audio_set_endpoint_req(struct usb_function *f, const struct usb_ctrlrequest *ctrl) { struct usb_composite_dev *cdev = f->config->cdev; + struct usb_request *req = f->config->cdev->req; + struct f_uac1 *uac1 = func_to_uac1(f); int value = -EOPNOTSUPP; u16 ep = le16_to_cpu(ctrl->wIndex); u16 len = le16_to_cpu(ctrl->wLength); u16 w_value = le16_to_cpu(ctrl->wValue); + u8 cs = w_value >> 8; DBG(cdev, "bRequest 0x%x, w_value 0x%04x, len %d, endpoint %d\n", ctrl->bRequest, w_value, len, ep); switch (ctrl->bRequest) { - case UAC_SET_CUR: + case UAC_SET_CUR: { + if (cs == UAC_EP_CS_ATTR_SAMPLE_RATE) { + cdev->gadget->ep0->driver_data = f; + uac1->ctl_id = ep; + req->complete = uac_cs_attr_sample_rate; + } value = len; break; + } case UAC_SET_MIN: break; @@ -743,16 +782,33 @@ static int audio_get_endpoint_req(struct usb_function *f, const struct usb_ctrlrequest *ctrl) { struct usb_composite_dev *cdev = f->config->cdev; + struct usb_request *req = f->config->cdev->req; + struct f_uac1 *uac1 = func_to_uac1(f); + u8 *buf = (u8 *)req->buf; int value = -EOPNOTSUPP; - u8 ep = ((le16_to_cpu(ctrl->wIndex) >> 8) & 0xFF); + u8 ep = le16_to_cpu(ctrl->wIndex); u16 len = le16_to_cpu(ctrl->wLength); u16 w_value = le16_to_cpu(ctrl->wValue); + u8 cs = w_value >> 8; + u32 val = 0; DBG(cdev, "bRequest 0x%x, w_value 0x%04x, len %d, endpoint %d\n", ctrl->bRequest, w_value, len, ep); switch (ctrl->bRequest) { - case UAC_GET_CUR: + case UAC_GET_CUR: { + if (cs == UAC_EP_CS_ATTR_SAMPLE_RATE) { + if (ep == (USB_DIR_IN | 2)) + val = uac1->p_srate; + else if (ep == (USB_DIR_OUT | 1)) + val = uac1->c_srate; + buf[2] = (val >> 16) & 0xff; + buf[1] = (val >> 8) & 0xff; + buf[0] = val & 0xff; + } + value = len; + break; + } case UAC_GET_MIN: case UAC_GET_MAX: case UAC_GET_RES: @@ -1074,10 +1130,10 @@ static int f_audio_validate_opts(struct g_audio *audio, struct device *dev) } else if ((opts->c_ssize < 1) || (opts->c_ssize > 4)) { dev_err(dev, "Error: incorrect capture sample size\n"); return -EINVAL; - } else if (!opts->p_srate) { + } else if (!opts->p_srates[0]) { dev_err(dev, "Error: incorrect playback sampling rate\n"); return -EINVAL; - } else if (!opts->c_srate) { + } else if (!opts->c_srates[0]) { dev_err(dev, "Error: incorrect capture sampling rate\n"); return -EINVAL; } @@ -1118,10 +1174,9 @@ static int f_audio_bind(struct usb_configuration *c, struct usb_function *f) struct f_uac1_opts *audio_opts; struct usb_ep *ep = NULL; struct usb_string *us; - u8 *sam_freq; - int rate; int ba_iface_id; int status; + int idx, i; status = f_audio_validate_opts(audio, dev); if (status) @@ -1213,12 +1268,25 @@ static int f_audio_bind(struct usb_configuration *c, struct usb_function *f) } /* Set sample rates */ - rate = audio_opts->c_srate; - sam_freq = as_out_type_i_desc.tSamFreq[0]; - memcpy(sam_freq, &rate, 3); - rate = audio_opts->p_srate; - sam_freq = as_in_type_i_desc.tSamFreq[0]; - memcpy(sam_freq, &rate, 3); + for (i = 0, idx = 0; i < UAC_MAX_RATES; i++) { + if (audio_opts->c_srates[i] == 0) + break; + memcpy(as_out_type_i_desc.tSamFreq[idx++], + &audio_opts->c_srates[i], 3); + } + as_out_type_i_desc.bLength = UAC_FORMAT_TYPE_I_DISCRETE_DESC_SIZE(idx); + as_out_type_i_desc.bSamFreqType = idx; + + for (i = 0, idx = 0; i < UAC_MAX_RATES; i++) { + if (audio_opts->p_srates[i] == 0) + break; + memcpy(as_in_type_i_desc.tSamFreq[idx++], + &audio_opts->p_srates[i], 3); + } + as_in_type_i_desc.bLength = UAC_FORMAT_TYPE_I_DISCRETE_DESC_SIZE(idx); + as_in_type_i_desc.bSamFreqType = idx; + uac1->p_srate = audio_opts->p_srates[0]; + uac1->c_srate = audio_opts->c_srates[0]; /* allocate instance-specific interface IDs, and patch descriptors */ status = usb_interface_id(c, f); @@ -1297,7 +1365,8 @@ static int f_audio_bind(struct usb_configuration *c, struct usb_function *f) audio->out_ep_maxpsize = le16_to_cpu(as_out_ep_desc.wMaxPacketSize); audio->in_ep_maxpsize = le16_to_cpu(as_in_ep_desc.wMaxPacketSize); audio->params.c_chmask = audio_opts->c_chmask; - audio->params.c_srates[0] = audio_opts->c_srate; + memcpy(audio->params.c_srates, audio_opts->c_srates, + sizeof(audio->params.c_srates)); audio->params.c_ssize = audio_opts->c_ssize; if (FUIN_EN(audio_opts)) { audio->params.p_fu.id = USB_IN_FU_ID; @@ -1309,7 +1378,8 @@ static int f_audio_bind(struct usb_configuration *c, struct usb_function *f) audio->params.p_fu.volume_res = audio_opts->p_volume_res; } audio->params.p_chmask = audio_opts->p_chmask; - audio->params.p_srates[0] = audio_opts->p_srate; + memcpy(audio->params.p_srates, audio_opts->p_srates, + sizeof(audio->params.p_srates)); audio->params.p_ssize = audio_opts->p_ssize; if (FUOUT_EN(audio_opts)) { audio->params.c_fu.id = USB_OUT_FU_ID; @@ -1414,11 +1484,70 @@ end: \ \ CONFIGFS_ATTR(f_uac1_opts_, name) +#define UAC1_RATE_ATTRIBUTE(name) \ +static ssize_t f_uac1_opts_##name##_show(struct config_item *item, \ + char *page) \ +{ \ + struct f_uac1_opts *opts = to_f_uac1_opts(item); \ + int result = 0; \ + int i; \ + \ + mutex_lock(&opts->lock); \ + page[0] = '\0'; \ + for (i = 0; i < UAC_MAX_RATES; i++) { \ + if (opts->name##s[i] == 0) \ + break; \ + result += sprintf(page + strlen(page), "%u,", \ + opts->name##s[i]); \ + } \ + if (strlen(page) > 0) \ + page[strlen(page) - 1] = '\n'; \ + mutex_unlock(&opts->lock); \ + \ + return result; \ +} \ + \ +static ssize_t f_uac1_opts_##name##_store(struct config_item *item, \ + const char *page, size_t len) \ +{ \ + struct f_uac1_opts *opts = to_f_uac1_opts(item); \ + char *split_page = NULL; \ + int ret = -EINVAL; \ + char *token; \ + u32 num; \ + int i; \ + \ + mutex_lock(&opts->lock); \ + if (opts->refcnt) { \ + ret = -EBUSY; \ + goto end; \ + } \ + \ + i = 0; \ + memset(opts->name##s, 0x00, sizeof(opts->name##s)); \ + split_page = kstrdup(page, GFP_KERNEL); \ + while ((token = strsep(&split_page, ",")) != NULL) { \ + ret = kstrtou32(token, 0, &num); \ + if (ret) \ + goto end; \ + \ + opts->name##s[i++] = num; \ + ret = len; \ + }; \ + \ +end: \ + kfree(split_page); \ + mutex_unlock(&opts->lock); \ + return ret; \ +} \ + \ +CONFIGFS_ATTR(f_uac1_opts_, name) + UAC1_ATTRIBUTE(u32, c_chmask); -UAC1_ATTRIBUTE(u32, c_srate); +UAC1_RATE_ATTRIBUTE(c_srate); UAC1_ATTRIBUTE(u32, c_ssize); UAC1_ATTRIBUTE(u32, p_chmask); -UAC1_ATTRIBUTE(u32, p_srate); +UAC1_RATE_ATTRIBUTE(p_srate); UAC1_ATTRIBUTE(u32, p_ssize); UAC1_ATTRIBUTE(u32, req_number); @@ -1487,10 +1616,10 @@ static struct usb_function_instance *f_audio_alloc_inst(void) &f_uac1_func_type); opts->c_chmask = UAC1_DEF_CCHMASK; - opts->c_srate = UAC1_DEF_CSRATE; + opts->c_srates[0] = UAC1_DEF_CSRATE; opts->c_ssize = UAC1_DEF_CSSIZE; opts->p_chmask = UAC1_DEF_PCHMASK; - opts->p_srate = UAC1_DEF_PSRATE; + opts->p_srates[0] = UAC1_DEF_PSRATE; opts->p_ssize = UAC1_DEF_PSSIZE; opts->p_mute_present = UAC1_DEF_MUTE_PRESENT; diff --git a/drivers/usb/gadget/function/u_uac1.h b/drivers/usb/gadget/function/u_uac1.h index 589fae861141..b6cd6171d306 100644 --- a/drivers/usb/gadget/function/u_uac1.h +++ b/drivers/usb/gadget/function/u_uac1.h @@ -9,6 +9,7 @@ #define __U_UAC1_H #include +#include "uac_common.h" #define UAC1_OUT_EP_MAX_PACKET_SIZE 200 #define UAC1_DEF_CCHMASK 0x3 @@ -30,10 +31,10 @@ struct f_uac1_opts { struct usb_function_instance func_inst; int c_chmask; - int c_srate; + int c_srates[UAC_MAX_RATES]; int c_ssize; int p_chmask; - int p_srate; + int p_srates[UAC_MAX_RATES]; int p_ssize; bool p_mute_present; diff --git a/drivers/usb/gadget/legacy/audio.c b/drivers/usb/gadget/legacy/audio.c index d14b9f2d4c07..c89c777a1aa3 100644 --- a/drivers/usb/gadget/legacy/audio.c +++ b/drivers/usb/gadget/legacy/audio.c @@ -61,9 +61,10 @@ module_param(p_chmask, uint, 0444); MODULE_PARM_DESC(p_chmask, "Playback Channel Mask"); /* Playback Default 48 KHz */ -static int p_srate = UAC1_DEF_PSRATE; -module_param(p_srate, uint, 0444); -MODULE_PARM_DESC(p_srate, "Playback Sampling Rate"); +static int p_srates[UAC_MAX_RATES] = {UAC1_DEF_PSRATE}; +static int p_srates_cnt = 1; +module_param_array_named(p_srate, p_srates, uint, &p_srates_cnt, 0444); +MODULE_PARM_DESC(p_srate, "Playback Sampling Rates (array)"); /* Playback Default 16bits/sample */ static int p_ssize = UAC1_DEF_PSSIZE; @@ -76,9 +77,10 @@ module_param(c_chmask, uint, 0444); MODULE_PARM_DESC(c_chmask, "Capture Channel Mask"); /* Capture Default 48 KHz */ -static int c_srate = UAC1_DEF_CSRATE; -module_param(c_srate, uint, 0444); -MODULE_PARM_DESC(c_srate, "Capture Sampling Rate"); +static int c_srates[UAC_MAX_RATES] = {UAC1_DEF_CSRATE}; +static int c_srates_cnt = 1; +module_param_array_named(c_srate, c_srates, uint, &c_srates_cnt, 0444); +MODULE_PARM_DESC(c_srate, "Capture Sampling Rates (array)"); /* Capture Default 16bits/sample */ static int c_ssize = UAC1_DEF_CSSIZE; @@ -243,6 +245,7 @@ static int audio_bind(struct usb_composite_dev *cdev) #else #ifndef CONFIG_GADGET_UAC1_LEGACY struct f_uac1_opts *uac1_opts; + int i; #else struct f_uac1_legacy_opts *uac1_opts; #endif @@ -282,10 +285,16 @@ static int audio_bind(struct usb_composite_dev *cdev) #ifndef CONFIG_GADGET_UAC1_LEGACY uac1_opts = container_of(fi_uac1, struct f_uac1_opts, func_inst); uac1_opts->p_chmask = p_chmask; - uac1_opts->p_srate = p_srate; + + for (i = 0; i < p_srates_cnt; ++i) + uac1_opts->p_srates[i] = p_srates[i]; + uac1_opts->p_ssize = p_ssize; uac1_opts->c_chmask = c_chmask; - uac1_opts->c_srate = c_srate; + + for (i = 0; i < c_srates_cnt; ++i) + uac1_opts->c_srates[i] = c_srates[i]; + uac1_opts->c_ssize = c_ssize; uac1_opts->req_number = UAC1_DEF_REQ_NUM; #else /* CONFIG_GADGET_UAC1_LEGACY */ From 17643c1fdde09aa5b960489745d91fe5b55b8ebe Mon Sep 17 00:00:00 2001 From: Pavel Hofman Date: Fri, 21 Jan 2022 16:53:05 +0100 Subject: [PATCH 24/91] UPSTREAM: usb: gadget: u_audio: Rate ctl notifies about current srate (0=stopped) The Playback/Capture ctl currently reports rate value set by USB control selector UAC2_CS_CONTROL_SAM_FREQ (fixed for UAC1). When the stops playback/capture, the reported value does not change. The gadget side has no information whether the host has started/stopped capture/playback. This patch sets the value reported by the respective rate ctl to zero when the host side has stopped playback/capture. Also, it calls snd_ctl_notify when start/stop occurs, so that a subscribed client can act appropriately. Tests have confirmed that USB hosts change UAC2_CS_CONTROL_SAM_FREQ before switching altsetting to activate playback/capture, resulting in correct order (params->c/p_srate is set to requested rate before u_audio_start_capture/playback is called). The gadget rate notifications are used by user-space audio gadget controller gaudio_ctl https://github.com/pavhofman/gaudio_ctl. Signed-off-by: Pavel Hofman Link: https://lore.kernel.org/r/20220121155308.48794-8-pavel.hofman@ivitera.com Signed-off-by: Greg Kroah-Hartman Bug: 235196743 (cherry picked from commit 8fe9a03f43316cd93e753d06372159d23ba931d4) Change-Id: I5156f080c0a22a1c3a57e8b3113a1047b945c1ca Signed-off-by: Luiz Matheus --- drivers/usb/gadget/function/u_audio.c | 28 ++++++++++++++++++++++++++- 1 file changed, 27 insertions(+), 1 deletion(-) diff --git a/drivers/usb/gadget/function/u_audio.c b/drivers/usb/gadget/function/u_audio.c index 7e770440c9e4..e34b6b307054 100644 --- a/drivers/usb/gadget/function/u_audio.c +++ b/drivers/usb/gadget/function/u_audio.c @@ -65,6 +65,7 @@ struct uac_rtd_params { struct snd_kcontrol *snd_kctl_rate; /* read-only current rate */ int srate; /* selected samplerate */ + int active; /* playback/capture running */ spinlock_t lock; /* lock for control transfers */ @@ -490,6 +491,21 @@ static inline void free_ep_fback(struct uac_rtd_params *prm, struct usb_ep *ep) dev_err(uac->card->dev, "%s:%d Error!\n", __func__, __LINE__); } +static void set_active(struct uac_rtd_params *prm, bool active) +{ + // notifying through the Rate ctrl + struct snd_kcontrol *kctl = prm->snd_kctl_rate; + unsigned long flags; + + spin_lock_irqsave(&prm->lock, flags); + if (prm->active != active) { + prm->active = active; + snd_ctl_notify(prm->uac->card, SNDRV_CTL_EVENT_MASK_VALUE, + &kctl->id); + } + spin_unlock_irqrestore(&prm->lock, flags); +} + int u_audio_set_capture_srate(struct g_audio *audio_dev, int srate) { struct uac_params *params = &audio_dev->params; @@ -607,6 +623,8 @@ int u_audio_start_capture(struct g_audio *audio_dev) dev_err(dev, "%s:%d Error!\n", __func__, __LINE__); } + set_active(&uac->c_prm, true); + ep_fback = audio_dev->in_ep_fback; if (!ep_fback) return 0; @@ -652,6 +670,7 @@ void u_audio_stop_capture(struct g_audio *audio_dev) { struct snd_uac_chip *uac = audio_dev->uac; + set_active(&uac->c_prm, false); if (audio_dev->in_ep_fback) free_ep_fback(&uac->c_prm, audio_dev->in_ep_fback); free_ep(&uac->c_prm, audio_dev->out_ep); @@ -723,6 +742,8 @@ int u_audio_start_playback(struct g_audio *audio_dev) dev_err(dev, "%s:%d Error!\n", __func__, __LINE__); } + set_active(&uac->p_prm, true); + return 0; } EXPORT_SYMBOL_GPL(u_audio_start_playback); @@ -731,6 +752,7 @@ void u_audio_stop_playback(struct g_audio *audio_dev) { struct snd_uac_chip *uac = audio_dev->uac; + set_active(&uac->p_prm, false); free_ep(&uac->p_prm, audio_dev->in_ep); } EXPORT_SYMBOL_GPL(u_audio_stop_playback); @@ -1074,7 +1096,11 @@ static int u_audio_rate_get(struct snd_kcontrol *kcontrol, unsigned long flags; spin_lock_irqsave(&prm->lock, flags); - ucontrol->value.integer.value[0] = prm->srate; + if (prm->active) + ucontrol->value.integer.value[0] = prm->srate; + else + /* not active: reporting zero rate */ + ucontrol->value.integer.value[0] = 0; spin_unlock_irqrestore(&prm->lock, flags); return 0; } From 31e6d620c197a6979e9a088b3a6e165720c53388 Mon Sep 17 00:00:00 2001 From: Pavel Hofman Date: Fri, 21 Jan 2022 16:53:06 +0100 Subject: [PATCH 25/91] UPSTREAM: usb: gadget: u_audio: Add suspend call Add exported method u_audio_suspend which sets stream status to inactive and sends notifications. The method does not free any resources. Signed-off-by: Pavel Hofman Link: https://lore.kernel.org/r/20220121155308.48794-9-pavel.hofman@ivitera.com Signed-off-by: Greg Kroah-Hartman Bug: 235196743 (cherry picked from commit 62385cf158a7e65b5f347590521d02ee75dc8518) Change-Id: I064ae3c92aaeec52a3f484665b89ee31132e5053 Signed-off-by: Luiz Matheus --- drivers/usb/gadget/function/u_audio.c | 9 +++++++++ drivers/usb/gadget/function/u_audio.h | 2 ++ 2 files changed, 11 insertions(+) diff --git a/drivers/usb/gadget/function/u_audio.c b/drivers/usb/gadget/function/u_audio.c index e34b6b307054..b29cae056f7f 100644 --- a/drivers/usb/gadget/function/u_audio.c +++ b/drivers/usb/gadget/function/u_audio.c @@ -757,6 +757,15 @@ void u_audio_stop_playback(struct g_audio *audio_dev) } EXPORT_SYMBOL_GPL(u_audio_stop_playback); +void u_audio_suspend(struct g_audio *audio_dev) +{ + struct snd_uac_chip *uac = audio_dev->uac; + + set_active(&uac->p_prm, false); + set_active(&uac->c_prm, false); +} +EXPORT_SYMBOL_GPL(u_audio_suspend); + int u_audio_get_volume(struct g_audio *audio_dev, int playback, s16 *val) { struct snd_uac_chip *uac = audio_dev->uac; diff --git a/drivers/usb/gadget/function/u_audio.h b/drivers/usb/gadget/function/u_audio.h index 5e6ed0f31cc3..9512b8fccfaa 100644 --- a/drivers/usb/gadget/function/u_audio.h +++ b/drivers/usb/gadget/function/u_audio.h @@ -130,4 +130,6 @@ int u_audio_set_volume(struct g_audio *g_audio, int playback, s16 val); int u_audio_get_mute(struct g_audio *g_audio, int playback, int *val); int u_audio_set_mute(struct g_audio *g_audio, int playback, int val); +void u_audio_suspend(struct g_audio *g_audio); + #endif /* __U_AUDIO_H */ From ff5468c71eed8152f81817b418b8d323752c53ad Mon Sep 17 00:00:00 2001 From: Pavel Hofman Date: Fri, 21 Jan 2022 16:53:07 +0100 Subject: [PATCH 26/91] UPSTREAM: usb: gadget: f_uac2: Add suspend callback When USB cable gets disconnected, the undergoing playback/capture stalls, without any notification to u_audio about the change. Experiments with a dwc2 gadget revealed that Suspend interrupt is thrown at cable disconnection, which the gadget framework translates to calling suspend callback of a function, if it is defined. Add the suspend callback to f_uac2 function, calling corresponding method of u_audio in order to stop the respective PCM streams and to notify subscribed clients at cable disconnection. Signed-off-by: Pavel Hofman Link: https://lore.kernel.org/r/20220121155308.48794-10-pavel.hofman@ivitera.com Signed-off-by: Greg Kroah-Hartman Bug: 235196743 (cherry picked from commit 7ff4a3b5489959a0256840a361b54d979b822535) Change-Id: I43f5ccd6f84771bd63462ba9b2419a9e42f45746 Signed-off-by: Luiz Matheus --- drivers/usb/gadget/function/f_uac2.c | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/drivers/usb/gadget/function/f_uac2.c b/drivers/usb/gadget/function/f_uac2.c index 991dc28adc99..39ee7710188c 100644 --- a/drivers/usb/gadget/function/f_uac2.c +++ b/drivers/usb/gadget/function/f_uac2.c @@ -1437,6 +1437,14 @@ afunc_disable(struct usb_function *fn) usb_ep_disable(uac2->int_ep); } +static void +afunc_suspend(struct usb_function *fn) +{ + struct f_uac2 *uac2 = func_to_uac2(fn); + + u_audio_suspend(&uac2->g_audio); +} + static int in_rq_cur(struct usb_function *fn, const struct usb_ctrlrequest *cr) { @@ -2108,6 +2116,7 @@ static struct usb_function *afunc_alloc(struct usb_function_instance *fi) uac2->g_audio.func.set_alt = afunc_set_alt; uac2->g_audio.func.get_alt = afunc_get_alt; uac2->g_audio.func.disable = afunc_disable; + uac2->g_audio.func.suspend = afunc_suspend; uac2->g_audio.func.setup = afunc_setup; uac2->g_audio.func.free_func = afunc_free; From 29172165ca6146422c5f6975e4049704b17b9adb Mon Sep 17 00:00:00 2001 From: Pavel Hofman Date: Fri, 21 Jan 2022 16:53:08 +0100 Subject: [PATCH 27/91] UPSTREAM: usb: gadget: f_uac1: Add suspend callback Add suspend callback to f_uac1 function, calling corresponding method of u_audio in order to stop the respective PCM streams and to notify subscribed clients about the stop. Signed-off-by: Pavel Hofman Link: https://lore.kernel.org/r/20220121155308.48794-11-pavel.hofman@ivitera.com Signed-off-by: Greg Kroah-Hartman Bug: 235196743 (cherry picked from commit d1d11dd1306908bc18b6592bbd21ba7d19a931e5) Change-Id: I9d24b3f58aea89b167bae6af39a460adf37c1a2a Signed-off-by: Luiz Matheus --- drivers/usb/gadget/function/f_uac1.c | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/drivers/usb/gadget/function/f_uac1.c b/drivers/usb/gadget/function/f_uac1.c index 73df76a6fbe0..1484e5c231d3 100644 --- a/drivers/usb/gadget/function/f_uac1.c +++ b/drivers/usb/gadget/function/f_uac1.c @@ -961,6 +961,14 @@ static void f_audio_disable(struct usb_function *f) usb_ep_disable(uac1->int_ep); } +static void +f_audio_suspend(struct usb_function *f) +{ + struct f_uac1 *uac1 = func_to_uac1(f); + + u_audio_suspend(&uac1->g_audio); +} + /*-------------------------------------------------------------------------*/ static struct uac_feature_unit_descriptor *build_fu_desc(int chmask) { @@ -1691,6 +1699,7 @@ static struct usb_function *f_audio_alloc(struct usb_function_instance *fi) uac1->g_audio.func.get_alt = f_audio_get_alt; uac1->g_audio.func.setup = f_audio_setup; uac1->g_audio.func.disable = f_audio_disable; + uac1->g_audio.func.suspend = f_audio_suspend; uac1->g_audio.func.free_func = f_audio_free; return &uac1->g_audio.func; From 98fa7f7dfd5428da1a55f9f16efb11532ceba419 Mon Sep 17 00:00:00 2001 From: Yunhao Tian Date: Sat, 22 Jan 2022 19:24:40 +0800 Subject: [PATCH 28/91] UPSTREAM: usb: gadget: f_uac1: allow changing interface name via configfs This adds "function_name" configfs entry to change string value of the iInterface field. This field will be shown in Windows' audio settings panel, so being able to change it is useful. It will default to "AC Interface" just as before if unchanged. Signed-off-by: Yunhao Tian Link: https://lore.kernel.org/r/20220122112446.1415547-1-t123yh.xyz@gmail.com Signed-off-by: Greg Kroah-Hartman Bug: 235196743 (cherry picked from commit dfb05b5dc3afd90e564b69b88ff6be6947a0f32f) Change-Id: Ibd0e417ab82efe1fb3aa6fd5bb33fb70f113cf1a Signed-off-by: Luiz Matheus --- .../ABI/testing/configfs-usb-gadget-uac1 | 1 + Documentation/usb/gadget-testing.rst | 1 + drivers/usb/gadget/function/f_uac1.c | 46 ++++++++++++++++++- drivers/usb/gadget/function/u_uac1.h | 2 + 4 files changed, 49 insertions(+), 1 deletion(-) diff --git a/Documentation/ABI/testing/configfs-usb-gadget-uac1 b/Documentation/ABI/testing/configfs-usb-gadget-uac1 index 09725e273e9b..c4ba92f004c3 100644 --- a/Documentation/ABI/testing/configfs-usb-gadget-uac1 +++ b/Documentation/ABI/testing/configfs-usb-gadget-uac1 @@ -29,4 +29,5 @@ Description: (in 1/256 dB) req_number the number of pre-allocated requests for both capture and playback + function_name name of the interface ===================== ======================================= diff --git a/Documentation/usb/gadget-testing.rst b/Documentation/usb/gadget-testing.rst index 0a59ec16f833..83a8ff2b0e39 100644 --- a/Documentation/usb/gadget-testing.rst +++ b/Documentation/usb/gadget-testing.rst @@ -745,6 +745,7 @@ The uac2 function provides these attributes in its function directory: p_volume_res playback volume control resolution (in 1/256 dB) req_number the number of pre-allocated request for both capture and playback + function_name name of the interface ================ ==================================================== The attributes have sane default values. diff --git a/drivers/usb/gadget/function/f_uac1.c b/drivers/usb/gadget/function/f_uac1.c index 1484e5c231d3..6f0e1d803dc2 100644 --- a/drivers/usb/gadget/function/f_uac1.c +++ b/drivers/usb/gadget/function/f_uac1.c @@ -309,7 +309,7 @@ enum { }; static struct usb_string strings_uac1[] = { - [STR_AC_IF].s = "AC Interface", + /* [STR_AC_IF].s = DYNAMIC, */ [STR_USB_OUT_IT].s = "Playback Input terminal", [STR_USB_OUT_IT_CH_NAMES].s = "Playback Channels", [STR_IO_OUT_OT].s = "Playback Output terminal", @@ -1192,6 +1192,8 @@ static int f_audio_bind(struct usb_configuration *c, struct usb_function *f) audio_opts = container_of(f->fi, struct f_uac1_opts, func_inst); + strings_uac1[STR_AC_IF].s = audio_opts->function_name; + us = usb_gstrings_attach(cdev, uac1_strings, ARRAY_SIZE(strings_uac1)); if (IS_ERR(us)) return PTR_ERR(us); @@ -1551,6 +1553,42 @@ end: \ \ CONFIGFS_ATTR(f_uac1_opts_, name) +#define UAC1_ATTRIBUTE_STRING(name) \ +static ssize_t f_uac1_opts_##name##_show(struct config_item *item, \ + char *page) \ +{ \ + struct f_uac1_opts *opts = to_f_uac1_opts(item); \ + int result; \ + \ + mutex_lock(&opts->lock); \ + result = snprintf(page, sizeof(opts->name), "%s", opts->name); \ + mutex_unlock(&opts->lock); \ + \ + return result; \ +} \ + \ +static ssize_t f_uac1_opts_##name##_store(struct config_item *item, \ + const char *page, size_t len) \ +{ \ + struct f_uac1_opts *opts = to_f_uac1_opts(item); \ + int ret = 0; \ + \ + mutex_lock(&opts->lock); \ + if (opts->refcnt) { \ + ret = -EBUSY; \ + goto end; \ + } \ + \ + ret = snprintf(opts->name, min(sizeof(opts->name), len), \ + "%s", page); \ + \ +end: \ + mutex_unlock(&opts->lock); \ + return ret; \ +} \ + \ +CONFIGFS_ATTR(f_uac1_opts_, name) + UAC1_ATTRIBUTE(u32, c_chmask); UAC1_RATE_ATTRIBUTE(c_srate); UAC1_ATTRIBUTE(u32, c_ssize); @@ -1570,6 +1608,7 @@ UAC1_ATTRIBUTE(bool, c_volume_present); UAC1_ATTRIBUTE(s16, c_volume_min); UAC1_ATTRIBUTE(s16, c_volume_max); UAC1_ATTRIBUTE(s16, c_volume_res); +UAC1_ATTRIBUTE_STRING(function_name); static struct configfs_attribute *f_uac1_attrs[] = { &f_uac1_opts_attr_c_chmask, @@ -1592,6 +1631,8 @@ static struct configfs_attribute *f_uac1_attrs[] = { &f_uac1_opts_attr_c_volume_max, &f_uac1_opts_attr_c_volume_res, + &f_uac1_opts_attr_function_name, + NULL, }; @@ -1643,6 +1684,9 @@ static struct usb_function_instance *f_audio_alloc_inst(void) opts->c_volume_res = UAC1_DEF_RES_DB; opts->req_number = UAC1_DEF_REQ_NUM; + + snprintf(opts->function_name, sizeof(opts->function_name), "AC Interface"); + return &opts->func_inst; } diff --git a/drivers/usb/gadget/function/u_uac1.h b/drivers/usb/gadget/function/u_uac1.h index b6cd6171d306..f7a616760e31 100644 --- a/drivers/usb/gadget/function/u_uac1.h +++ b/drivers/usb/gadget/function/u_uac1.h @@ -52,6 +52,8 @@ struct f_uac1_opts { int req_number; unsigned bound:1; + char function_name[32]; + struct mutex lock; int refcnt; }; From f26c566455d8a8733c2760249af4f51ac40a17b9 Mon Sep 17 00:00:00 2001 From: Yunhao Tian Date: Sat, 22 Jan 2022 19:24:41 +0800 Subject: [PATCH 29/91] UPSTREAM: usb: gadget: f_uac2: allow changing interface name via configfs This adds "function_name" configfs entry to change string value of the iInterface field. This field will be shown in Windows' audio settings panel, so being able to change it is useful. It will default to "Source/Sink" just as before. Signed-off-by: Yunhao Tian Link: https://lore.kernel.org/r/20220122112446.1415547-2-t123yh.xyz@gmail.com Signed-off-by: Greg Kroah-Hartman Bug: 235196743 (cherry picked from commit 993a44fa85c1ea5989fb5c46236ca2e3cfd71b78) Change-Id: I6061d841eee5b611f18280c901849d0c4b2a17d4 Signed-off-by: Luiz Matheus --- .../ABI/testing/configfs-usb-gadget-uac2 | 1 + Documentation/usb/gadget-testing.rst | 1 + drivers/usb/gadget/function/f_uac2.c | 46 ++++++++++++++++++- drivers/usb/gadget/function/u_uac2.h | 2 + 4 files changed, 49 insertions(+), 1 deletion(-) diff --git a/Documentation/ABI/testing/configfs-usb-gadget-uac2 b/Documentation/ABI/testing/configfs-usb-gadget-uac2 index 9d2f59ab9701..4c6bf63fcb22 100644 --- a/Documentation/ABI/testing/configfs-usb-gadget-uac2 +++ b/Documentation/ABI/testing/configfs-usb-gadget-uac2 @@ -32,4 +32,5 @@ Description: (in 1/256 dB) req_number the number of pre-allocated requests for both capture and playback + function_name name of the interface ===================== ======================================= diff --git a/Documentation/usb/gadget-testing.rst b/Documentation/usb/gadget-testing.rst index 83a8ff2b0e39..353e4daa7861 100644 --- a/Documentation/usb/gadget-testing.rst +++ b/Documentation/usb/gadget-testing.rst @@ -935,6 +935,7 @@ The uac1 function provides these attributes in its function directory: p_volume_res playback volume control resolution (in 1/256 dB) req_number the number of pre-allocated requests for both capture and playback + function_name name of the interface ================ ==================================================== The attributes have sane default values. diff --git a/drivers/usb/gadget/function/f_uac2.c b/drivers/usb/gadget/function/f_uac2.c index 39ee7710188c..da5250a415d5 100644 --- a/drivers/usb/gadget/function/f_uac2.c +++ b/drivers/usb/gadget/function/f_uac2.c @@ -107,7 +107,7 @@ enum { }; static struct usb_string strings_fn[] = { - [STR_ASSOC].s = "Source/Sink", + /* [STR_ASSOC].s = DYNAMIC, */ [STR_IF_CTRL].s = "Topology Control", [STR_CLKSRC_IN].s = "Input Clock", [STR_CLKSRC_OUT].s = "Output Clock", @@ -984,6 +984,8 @@ afunc_bind(struct usb_configuration *cfg, struct usb_function *fn) if (ret) return ret; + strings_fn[STR_ASSOC].s = uac2_opts->function_name; + us = usb_gstrings_attach(cdev, fn_strings, ARRAY_SIZE(strings_fn)); if (IS_ERR(us)) return PTR_ERR(us); @@ -1967,6 +1969,42 @@ end: \ \ CONFIGFS_ATTR(f_uac2_opts_, name) +#define UAC2_ATTRIBUTE_STRING(name) \ +static ssize_t f_uac2_opts_##name##_show(struct config_item *item, \ + char *page) \ +{ \ + struct f_uac2_opts *opts = to_f_uac2_opts(item); \ + int result; \ + \ + mutex_lock(&opts->lock); \ + result = snprintf(page, sizeof(opts->name), "%s", opts->name); \ + mutex_unlock(&opts->lock); \ + \ + return result; \ +} \ + \ +static ssize_t f_uac2_opts_##name##_store(struct config_item *item, \ + const char *page, size_t len) \ +{ \ + struct f_uac2_opts *opts = to_f_uac2_opts(item); \ + int ret = 0; \ + \ + mutex_lock(&opts->lock); \ + if (opts->refcnt) { \ + ret = -EBUSY; \ + goto end; \ + } \ + \ + ret = snprintf(opts->name, min(sizeof(opts->name), len), \ + "%s", page); \ + \ +end: \ + mutex_unlock(&opts->lock); \ + return ret; \ +} \ + \ +CONFIGFS_ATTR(f_uac2_opts_, name) + UAC2_ATTRIBUTE(u32, p_chmask); UAC2_RATE_ATTRIBUTE(p_srate); UAC2_ATTRIBUTE(u32, p_ssize); @@ -1988,6 +2026,7 @@ UAC2_ATTRIBUTE(s16, c_volume_min); UAC2_ATTRIBUTE(s16, c_volume_max); UAC2_ATTRIBUTE(s16, c_volume_res); UAC2_ATTRIBUTE(u32, fb_max); +UAC2_ATTRIBUTE_STRING(function_name); static struct configfs_attribute *f_uac2_attrs[] = { &f_uac2_opts_attr_p_chmask, @@ -2012,6 +2051,8 @@ static struct configfs_attribute *f_uac2_attrs[] = { &f_uac2_opts_attr_c_volume_max, &f_uac2_opts_attr_c_volume_res, + &f_uac2_opts_attr_function_name, + NULL, }; @@ -2065,6 +2106,9 @@ static struct usb_function_instance *afunc_alloc_inst(void) opts->req_number = UAC2_DEF_REQ_NUM; opts->fb_max = FBACK_FAST_MAX; + + snprintf(opts->function_name, sizeof(opts->function_name), "Source/Sink"); + return &opts->func_inst; } diff --git a/drivers/usb/gadget/function/u_uac2.h b/drivers/usb/gadget/function/u_uac2.h index 6bfcf6d0e863..ed96c7c853e4 100644 --- a/drivers/usb/gadget/function/u_uac2.h +++ b/drivers/usb/gadget/function/u_uac2.h @@ -59,6 +59,8 @@ struct f_uac2_opts { int fb_max; bool bound; + char function_name[32]; + struct mutex lock; int refcnt; }; From e8fce594347a77af0481c18b6b56509b954fa771 Mon Sep 17 00:00:00 2001 From: Tejun Heo Date: Tue, 14 Jun 2022 10:36:35 +0530 Subject: [PATCH 30/91] BACKPORT: FROMGIT: cgroup: Use separate src/dst nodes when preloading css_sets for migration Each cset (css_set) is pinned by its tasks. When we're moving tasks around across csets for a migration, we need to hold the source and destination csets to ensure that they don't go away while we're moving tasks about. This is done by linking cset->mg_preload_node on either the mgctx->preloaded_dst_csets or mgctx->preloaded_dst_csets list. Using the same cset->mg_preload_node for both the src and dst lists was deemed okay as a cset can't be both the source and destination at the same time. Unfortunately, this overloading becomes problematic when multiple tasks are involved in a migration and some of them are identity noop migrations while others are actually moving across cgroups. For example, this can happen with the following sequence on cgroup1: #1> mkdir -p /sys/fs/cgroup/misc/a/b #2> echo $$ > /sys/fs/cgroup/misc/a/cgroup.procs #3> RUN_A_COMMAND_WHICH_CREATES_MULTIPLE_THREADS & #4> PID=$! #5> echo $PID > /sys/fs/cgroup/misc/a/b/tasks #6> echo $PID > /sys/fs/cgroup/misc/a/cgroup.procs the process including the group leader back into a. In this final migration, non-leader threads would be doing identity migration while the group leader is doing an actual one. After #3, let's say the whole process was in cset A, and that after #4, the leader moves to cset B. Then, during #6, the following happens: 1. cgroup_migrate_add_src() is called on B for the leader. 2. cgroup_migrate_add_src() is called on A for the other threads. 3. cgroup_migrate_prepare_dst() is called. It scans the src list. 3. It notices that B wants to migrate to A, so it tries to A to the dst list but realizes that its ->mg_preload_node is already busy. 4. and then it notices A wants to migrate to A as it's an identity migration, it culls it by list_del_init()'ing its ->mg_preload_node and putting references accordingly. 5. The rest of migration takes place with B on the src list but nothing on the dst list. This means that A isn't held while migration is in progress. If all tasks leave A before the migration finishes and the incoming task pins it, the cset will be destroyed leading to use-after-free. This is caused by overloading cset->mg_preload_node for both src and dst preload lists. We wanted to exclude the cset from the src list but ended up inadvertently excluding it from the dst list too. This patch fixes the issue by separating out cset->mg_preload_node into ->mg_src_preload_node and ->mg_dst_preload_node, so that the src and dst preloadings don't interfere with each other. Bug: 236582926 Change-Id: Ieaf1c0c8fc23753570897fd6e48a54335ab939ce Signed-off-by: Tejun Heo Reported-by: Mukesh Ojha Reported-by: shisiyuan Link: http://lkml.kernel.org/r/1654187688-27411-1-git-send-email-shisiyuan@xiaomi.com Link: https://lore.kernel.org/lkml/Yh+RGIJ0f3nrqIiN@slm.duckdns.org/#t Fixes: f817de98513d ("cgroup: prepare migration path for unified hierarchy") Cc: stable@vger.kernel.org # v3.16+ (cherry picked from commit 07fd5b6cdf3cc30bfde8fe0f644771688be04447 https://git.kernel.org/pub/scm/linux/kernel/git/tj/cgroup.git for-5.19-fixes) Signed-off-by: Elliot Berman Signed-off-by: Mukesh Ojha [mojha: Move the two new list heads into a wrapper ext_css_set struct to ensure ABI doesn't break and also defined a macro init_css_set which will be replaced with init_ext_css_set.cset to avoid too much code changes] --- include/linux/cgroup-defs.h | 7 +++ include/linux/cgroup.h | 3 +- kernel/cgroup/cgroup.c | 103 +++++++++++++++++++++--------------- 3 files changed, 70 insertions(+), 43 deletions(-) diff --git a/include/linux/cgroup-defs.h b/include/linux/cgroup-defs.h index 8c193033604f..3ee42f15483b 100644 --- a/include/linux/cgroup-defs.h +++ b/include/linux/cgroup-defs.h @@ -282,6 +282,13 @@ struct css_set { struct rcu_head rcu_head; }; +struct ext_css_set { + struct css_set cset; + + struct list_head mg_src_preload_node; + struct list_head mg_dst_preload_node; +}; + struct cgroup_base_stat { struct task_cputime cputime; }; diff --git a/include/linux/cgroup.h b/include/linux/cgroup.h index 67b2190b1dae..771fc8ecba49 100644 --- a/include/linux/cgroup.h +++ b/include/linux/cgroup.h @@ -72,7 +72,8 @@ struct css_task_iter { }; extern struct cgroup_root cgrp_dfl_root; -extern struct css_set init_css_set; +extern struct ext_css_set init_ext_css_set; +#define init_css_set init_ext_css_set.cset #define SUBSYS(_x) extern struct cgroup_subsys _x ## _cgrp_subsys; #include diff --git a/kernel/cgroup/cgroup.c b/kernel/cgroup/cgroup.c index c1e1a5c34e77..cbefd9eb2783 100644 --- a/kernel/cgroup/cgroup.c +++ b/kernel/cgroup/cgroup.c @@ -746,25 +746,28 @@ EXPORT_SYMBOL_GPL(of_css); * reference-counted, to improve performance when child cgroups * haven't been created. */ -struct css_set init_css_set = { - .refcount = REFCOUNT_INIT(1), - .dom_cset = &init_css_set, - .tasks = LIST_HEAD_INIT(init_css_set.tasks), - .mg_tasks = LIST_HEAD_INIT(init_css_set.mg_tasks), - .dying_tasks = LIST_HEAD_INIT(init_css_set.dying_tasks), - .task_iters = LIST_HEAD_INIT(init_css_set.task_iters), - .threaded_csets = LIST_HEAD_INIT(init_css_set.threaded_csets), - .cgrp_links = LIST_HEAD_INIT(init_css_set.cgrp_links), - .mg_preload_node = LIST_HEAD_INIT(init_css_set.mg_preload_node), - .mg_node = LIST_HEAD_INIT(init_css_set.mg_node), - - /* - * The following field is re-initialized when this cset gets linked - * in cgroup_init(). However, let's initialize the field - * statically too so that the default cgroup can be accessed safely - * early during boot. - */ - .dfl_cgrp = &cgrp_dfl_root.cgrp, +struct ext_css_set init_ext_css_set = { + .cset = { + .refcount = REFCOUNT_INIT(1), + .dom_cset = &init_css_set, + .tasks = LIST_HEAD_INIT(init_css_set.tasks), + .mg_tasks = LIST_HEAD_INIT(init_css_set.mg_tasks), + .dying_tasks = LIST_HEAD_INIT(init_css_set.dying_tasks), + .task_iters = LIST_HEAD_INIT(init_css_set.task_iters), + .threaded_csets = LIST_HEAD_INIT(init_css_set.threaded_csets), + .cgrp_links = LIST_HEAD_INIT(init_css_set.cgrp_links), + .mg_preload_node = LIST_HEAD_INIT(init_css_set.mg_preload_node), + .mg_node = LIST_HEAD_INIT(init_css_set.mg_node), + /* + * The following field is re-initialized when this cset gets linked + * in cgroup_init(). However, let's initialize the field + * statically too so that the default cgroup can be accessed safely + * early during boot. + */ + .dfl_cgrp = &cgrp_dfl_root.cgrp, + }, + .mg_src_preload_node = LIST_HEAD_INIT(init_ext_css_set.mg_src_preload_node), + .mg_dst_preload_node = LIST_HEAD_INIT(init_ext_css_set.mg_dst_preload_node), }; static int css_set_count = 1; /* 1 for init_css_set */ @@ -1191,6 +1194,7 @@ static struct css_set *find_css_set(struct css_set *old_cset, struct cgroup *cgrp) { struct cgroup_subsys_state *template[CGROUP_SUBSYS_COUNT] = { }; + struct ext_css_set *ext_cset; struct css_set *cset; struct list_head tmp_links; struct cgrp_cset_link *link; @@ -1211,9 +1215,10 @@ static struct css_set *find_css_set(struct css_set *old_cset, if (cset) return cset; - cset = kzalloc(sizeof(*cset), GFP_KERNEL); - if (!cset) + ext_cset = kzalloc(sizeof(*ext_cset), GFP_KERNEL); + if (!ext_cset) return NULL; + cset = &ext_cset->cset; /* Allocate all the cgrp_cset_link objects that we'll need */ if (allocate_cgrp_cset_links(cgroup_root_count, &tmp_links) < 0) { @@ -1231,6 +1236,8 @@ static struct css_set *find_css_set(struct css_set *old_cset, INIT_HLIST_NODE(&cset->hlist); INIT_LIST_HEAD(&cset->cgrp_links); INIT_LIST_HEAD(&cset->mg_preload_node); + INIT_LIST_HEAD(&ext_cset->mg_src_preload_node); + INIT_LIST_HEAD(&ext_cset->mg_dst_preload_node); INIT_LIST_HEAD(&cset->mg_node); /* Copy the set of subsystem state objects generated in @@ -2578,22 +2585,28 @@ int cgroup_migrate_vet_dst(struct cgroup *dst_cgrp) */ void cgroup_migrate_finish(struct cgroup_mgctx *mgctx) { - LIST_HEAD(preloaded); - struct css_set *cset, *tmp_cset; + struct ext_css_set *cset, *tmp_cset; lockdep_assert_held(&cgroup_mutex); spin_lock_irq(&css_set_lock); - list_splice_tail_init(&mgctx->preloaded_src_csets, &preloaded); - list_splice_tail_init(&mgctx->preloaded_dst_csets, &preloaded); + list_for_each_entry_safe(cset, tmp_cset, &mgctx->preloaded_src_csets, + mg_src_preload_node) { + cset->cset.mg_src_cgrp = NULL; + cset->cset.mg_dst_cgrp = NULL; + cset->cset.mg_dst_cset = NULL; + list_del_init(&cset->mg_src_preload_node); + put_css_set_locked(&cset->cset); + } - list_for_each_entry_safe(cset, tmp_cset, &preloaded, mg_preload_node) { - cset->mg_src_cgrp = NULL; - cset->mg_dst_cgrp = NULL; - cset->mg_dst_cset = NULL; - list_del_init(&cset->mg_preload_node); - put_css_set_locked(cset); + list_for_each_entry_safe(cset, tmp_cset, &mgctx->preloaded_dst_csets, + mg_dst_preload_node) { + cset->cset.mg_src_cgrp = NULL; + cset->cset.mg_dst_cgrp = NULL; + cset->cset.mg_dst_cset = NULL; + list_del_init(&cset->mg_dst_preload_node); + put_css_set_locked(&cset->cset); } spin_unlock_irq(&css_set_lock); @@ -2620,6 +2633,7 @@ void cgroup_migrate_add_src(struct css_set *src_cset, struct cgroup_mgctx *mgctx) { struct cgroup *src_cgrp; + struct ext_css_set *ext_src_cset; lockdep_assert_held(&cgroup_mutex); lockdep_assert_held(&css_set_lock); @@ -2633,8 +2647,9 @@ void cgroup_migrate_add_src(struct css_set *src_cset, return; src_cgrp = cset_cgroup_from_root(src_cset, dst_cgrp->root); + ext_src_cset = container_of(src_cset, struct ext_css_set, cset); - if (!list_empty(&src_cset->mg_preload_node)) + if (!list_empty(&ext_src_cset->mg_src_preload_node)) return; WARN_ON(src_cset->mg_src_cgrp); @@ -2645,7 +2660,7 @@ void cgroup_migrate_add_src(struct css_set *src_cset, src_cset->mg_src_cgrp = src_cgrp; src_cset->mg_dst_cgrp = dst_cgrp; get_css_set(src_cset); - list_add_tail(&src_cset->mg_preload_node, &mgctx->preloaded_src_csets); + list_add_tail(&ext_src_cset->mg_src_preload_node, &mgctx->preloaded_src_csets); } /** @@ -2664,20 +2679,23 @@ void cgroup_migrate_add_src(struct css_set *src_cset, */ int cgroup_migrate_prepare_dst(struct cgroup_mgctx *mgctx) { - struct css_set *src_cset, *tmp_cset; + struct ext_css_set *ext_src_set, *tmp_cset; lockdep_assert_held(&cgroup_mutex); /* look up the dst cset for each src cset and link it to src */ - list_for_each_entry_safe(src_cset, tmp_cset, &mgctx->preloaded_src_csets, - mg_preload_node) { + list_for_each_entry_safe(ext_src_set, tmp_cset, &mgctx->preloaded_src_csets, + mg_src_preload_node) { + struct css_set *src_cset = &ext_src_set->cset; struct css_set *dst_cset; + struct ext_css_set *ext_dst_cset; struct cgroup_subsys *ss; int ssid; dst_cset = find_css_set(src_cset, src_cset->mg_dst_cgrp); if (!dst_cset) return -ENOMEM; + ext_dst_cset = container_of(dst_cset, struct ext_css_set, cset); WARN_ON_ONCE(src_cset->mg_dst_cset || dst_cset->mg_dst_cset); @@ -2689,7 +2707,7 @@ int cgroup_migrate_prepare_dst(struct cgroup_mgctx *mgctx) if (src_cset == dst_cset) { src_cset->mg_src_cgrp = NULL; src_cset->mg_dst_cgrp = NULL; - list_del_init(&src_cset->mg_preload_node); + list_del_init(&ext_src_set->mg_src_preload_node); put_css_set(src_cset); put_css_set(dst_cset); continue; @@ -2697,8 +2715,8 @@ int cgroup_migrate_prepare_dst(struct cgroup_mgctx *mgctx) src_cset->mg_dst_cset = dst_cset; - if (list_empty(&dst_cset->mg_preload_node)) - list_add_tail(&dst_cset->mg_preload_node, + if (list_empty(&ext_dst_cset->mg_dst_preload_node)) + list_add_tail(&ext_dst_cset->mg_dst_preload_node, &mgctx->preloaded_dst_csets); else put_css_set(dst_cset); @@ -2926,7 +2944,7 @@ static int cgroup_update_dfl_csses(struct cgroup *cgrp) DEFINE_CGROUP_MGCTX(mgctx); struct cgroup_subsys_state *d_css; struct cgroup *dsct; - struct css_set *src_cset; + struct ext_css_set *ext_src_set; int ret; lockdep_assert_held(&cgroup_mutex); @@ -2949,11 +2967,12 @@ static int cgroup_update_dfl_csses(struct cgroup *cgrp) goto out_finish; spin_lock_irq(&css_set_lock); - list_for_each_entry(src_cset, &mgctx.preloaded_src_csets, mg_preload_node) { + list_for_each_entry(ext_src_set, &mgctx.preloaded_src_csets, + mg_src_preload_node) { struct task_struct *task, *ntask; /* all tasks in src_csets need to be migrated */ - list_for_each_entry_safe(task, ntask, &src_cset->tasks, cg_list) + list_for_each_entry_safe(task, ntask, &ext_src_set->cset.tasks, cg_list) cgroup_migrate_add_task(task, &mgctx); } spin_unlock_irq(&css_set_lock); From 8de633b735bfb08a9f570c9d68e0f9c6c5b9f684 Mon Sep 17 00:00:00 2001 From: Li Li Date: Thu, 26 May 2022 15:00:18 -0700 Subject: [PATCH 31/91] FROMGIT: Binder: add TF_UPDATE_TXN to replace outdated txn When the target process is busy, incoming oneway transactions are queued in the async_todo list. If the clients continue sending extra oneway transactions while the target process is frozen, this queue can become too large to accommodate new transactions. That's why binder driver introduced ONEWAY_SPAM_DETECTION to detect this situation. It's helpful to debug the async binder buffer exhausting issue, but the issue itself isn't solved directly. In real cases applications are designed to send oneway transactions repeatedly, delivering updated inforamtion to the target process. Typical examples are Wi-Fi signal strength and some real time sensor data. Even if the apps might only care about the lastet information, all outdated oneway transactions are still accumulated there until the frozen process is thawed later. For this kind of situations, there's no existing method to skip those outdated transactions and deliver the latest one only. This patch introduces a new transaction flag TF_UPDATE_TXN. To use it, use apps can set this new flag along with TF_ONE_WAY. When such an oneway transaction is to be queued into the async_todo list of a frozen process, binder driver will check if any previous pending transactions can be superseded by comparing their code, flags and target node. If such an outdated pending transaction is found, the latest transaction will supersede that outdated one. This effectively prevents the async binder buffer running out and saves unnecessary binder read workloads. Acked-by: Todd Kjos Signed-off-by: Li Li Link: https://lore.kernel.org/r/20220526220018.3334775-2-dualli@chromium.org Signed-off-by: Greg Kroah-Hartman Bug: 231624308 Test: manually check async binder buffer size of frozen apps Test: stress test with kernel 4.14/4.19/5.10/5.15 (cherry picked from commit 9864bb4801331daa48514face9d0f4861e4d485b git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/char-misc.git char-misc-next) Change-Id: I1c4bff1eda1ca15aaaad5bf696c8fc00be743176 --- drivers/android/binder.c | 78 +++++++++++++++++++++++++++++ drivers/android/binder_trace.h | 4 ++ include/uapi/linux/android/binder.h | 1 + 3 files changed, 83 insertions(+) diff --git a/drivers/android/binder.c b/drivers/android/binder.c index 052a1e590e9f..0d83bf894f77 100644 --- a/drivers/android/binder.c +++ b/drivers/android/binder.c @@ -2464,6 +2464,56 @@ static int binder_fixup_parent(struct binder_transaction *t, return 0; } +/** + * binder_can_update_transaction() - Can a txn be superseded by an updated one? + * @t1: the pending async txn in the frozen process + * @t2: the new async txn to supersede the outdated pending one + * + * Return: true if t2 can supersede t1 + * false if t2 can not supersede t1 + */ +static bool binder_can_update_transaction(struct binder_transaction *t1, + struct binder_transaction *t2) +{ + if ((t1->flags & t2->flags & (TF_ONE_WAY | TF_UPDATE_TXN)) != + (TF_ONE_WAY | TF_UPDATE_TXN) || !t1->to_proc || !t2->to_proc) + return false; + if (t1->to_proc->tsk == t2->to_proc->tsk && t1->code == t2->code && + t1->flags == t2->flags && t1->buffer->pid == t2->buffer->pid && + t1->buffer->target_node->ptr == t2->buffer->target_node->ptr && + t1->buffer->target_node->cookie == t2->buffer->target_node->cookie) + return true; + return false; +} + +/** + * binder_find_outdated_transaction_ilocked() - Find the outdated transaction + * @t: new async transaction + * @target_list: list to find outdated transaction + * + * Return: the outdated transaction if found + * NULL if no outdated transacton can be found + * + * Requires the proc->inner_lock to be held. + */ +static struct binder_transaction * +binder_find_outdated_transaction_ilocked(struct binder_transaction *t, + struct list_head *target_list) +{ + struct binder_work *w; + + list_for_each_entry(w, target_list, entry) { + struct binder_transaction *t_queued; + + if (w->type != BINDER_WORK_TRANSACTION) + continue; + t_queued = container_of(w, struct binder_transaction, work); + if (binder_can_update_transaction(t_queued, t)) + return t_queued; + } + return NULL; +} + /** * binder_proc_transaction() - sends a transaction to a process and wakes it up * @t: transaction to send @@ -2491,6 +2541,7 @@ static int binder_proc_transaction(struct binder_transaction *t, bool oneway = !!(t->flags & TF_ONE_WAY); bool pending_async = false; bool skip = false; + struct binder_transaction *t_outdated = NULL; BUG_ON(!node); binder_node_lock(node); @@ -2534,6 +2585,17 @@ static int binder_proc_transaction(struct binder_transaction *t, } else if (!pending_async) { binder_enqueue_work_ilocked(&t->work, &proc->todo); } else { + if ((t->flags & TF_UPDATE_TXN) && proc->is_frozen) { + t_outdated = binder_find_outdated_transaction_ilocked(t, + &node->async_todo); + if (t_outdated) { + binder_debug(BINDER_DEBUG_TRANSACTION, + "txn %d supersedes %d\n", + t->debug_id, t_outdated->debug_id); + list_del_init(&t_outdated->work.entry); + proc->outstanding_txns--; + } + } binder_enqueue_work_ilocked(&t->work, &node->async_todo); } @@ -2547,6 +2609,22 @@ static int binder_proc_transaction(struct binder_transaction *t, binder_inner_proc_unlock(proc); binder_node_unlock(node); + /* + * To reduce potential contention, free the outdated transaction and + * buffer after releasing the locks. + */ + if (t_outdated) { + struct binder_buffer *buffer = t_outdated->buffer; + + t_outdated->buffer = NULL; + buffer->transaction = NULL; + trace_binder_transaction_update_buffer_release(buffer); + binder_transaction_buffer_release(proc, NULL, buffer, 0, 0); + binder_alloc_free_buf(&proc->alloc, buffer); + kfree(t_outdated); + binder_stats_deleted(BINDER_STAT_TRANSACTION); + } + return 0; } diff --git a/drivers/android/binder_trace.h b/drivers/android/binder_trace.h index a70e23716ad0..8c4a6c3774a1 100644 --- a/drivers/android/binder_trace.h +++ b/drivers/android/binder_trace.h @@ -306,6 +306,10 @@ DEFINE_EVENT(binder_buffer_class, binder_transaction_failed_buffer_release, TP_PROTO(struct binder_buffer *buffer), TP_ARGS(buffer)); +DEFINE_EVENT(binder_buffer_class, binder_transaction_update_buffer_release, + TP_PROTO(struct binder_buffer *buffer), + TP_ARGS(buffer)); + TRACE_EVENT(binder_update_page_range, TP_PROTO(struct binder_alloc *alloc, bool allocate, void __user *start, void __user *end), diff --git a/include/uapi/linux/android/binder.h b/include/uapi/linux/android/binder.h index 2d3f015e2ae3..7badb670f24f 100644 --- a/include/uapi/linux/android/binder.h +++ b/include/uapi/linux/android/binder.h @@ -319,6 +319,7 @@ enum transaction_flags { TF_STATUS_CODE = 0x08, /* contents are a 32-bit status code */ TF_ACCEPT_FDS = 0x10, /* allow replies with file descriptors */ TF_CLEAR_BUF = 0x20, /* clear buffer on txn complete */ + TF_UPDATE_TXN = 0x40, /* update the outdated pending async txn */ }; struct binder_transaction_data { From c5eb0edfde992ba51d737855ba3d39f1c02d7523 Mon Sep 17 00:00:00 2001 From: Thinh Nguyen Date: Thu, 21 Apr 2022 19:22:31 -0700 Subject: [PATCH 32/91] FROMGIT: usb: dwc3: gadget: Prevent repeat pullup() Don't do soft-disconnect if it's previously done. Likewise, don't do soft-connect if the device is currently connected and running. It would break normal operation. Currently the caller of pullup() (udc's sysfs soft_connect) only checks if it had initiated disconnect to prevent repeating soft-disconnect. It doesn't check for soft-connect. To be safe, let's keep the check here regardless whether the udc core is fixed. Signed-off-by: Thinh Nguyen Link: https://lore.kernel.org/r/1c1345bd66c97a9d32f77d63aaadd04b7b037143.1650593829.git.Thinh.Nguyen@synopsys.com Signed-off-by: Greg Kroah-Hartman (cherry picked from commit 69e131d1ac4e52a59ec181ab4f8aa8c48cd8fb64 https://git.kernel.org/pub/scm/linux/kernel/git/gregkh/usb.git/ usb-next) BUG: 238836938 Change-Id: Ibcb208581948132cfe4736381a67fea33026c372 Signed-off-by: Udipto Goswami --- drivers/usb/dwc3/gadget.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/drivers/usb/dwc3/gadget.c b/drivers/usb/dwc3/gadget.c index 62a578831acc..7d23c6ad8182 100644 --- a/drivers/usb/dwc3/gadget.c +++ b/drivers/usb/dwc3/gadget.c @@ -2471,6 +2471,10 @@ static int dwc3_gadget_pullup(struct usb_gadget *g, int is_on) int ret; is_on = !!is_on; + + if (dwc->pullups_connected == is_on) + return 0; + vdwc->softconnect = is_on; /* From 321bf845e1d1a4c318b4f1740098bf4a24717fea Mon Sep 17 00:00:00 2001 From: Thinh Nguyen Date: Wed, 15 Jun 2022 17:24:32 -0700 Subject: [PATCH 33/91] FROMGIT: usb: dwc3: core: Deprecate GCTL.CORESOFTRESET Synopsys IP DWC_usb32 and DWC_usb31 version 1.90a and above deprecated GCTL.CORESOFTRESET. The DRD mode switching flow is updated to remove the GCTL soft reset. Add version checks to prevent using deprecated setting in mode switching flow. Signed-off-by: Thinh Nguyen Link: https://lore.kernel.org/r/9df529fde6e55f5508321b6bc26e92848044ef2b.1655338967.git.Thinh.Nguyen@synopsys.com Signed-off-by: Greg Kroah-Hartman (cherry picked from commit afbd04e66e5d16ca3c7ea2e3c56eca25558eacf3 https://git.kernel.org/pub/scm/linux/kernel/git/gregkh/usb.git usb-next) BUG: 238836938 Change-Id: I69ea5ee3b9cf25d1d972b261c8dff59c50437c04 Signed-off-by: Udipto Goswami --- drivers/usb/dwc3/core.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/usb/dwc3/core.c b/drivers/usb/dwc3/core.c index ca0966badf42..8fd631230552 100644 --- a/drivers/usb/dwc3/core.c +++ b/drivers/usb/dwc3/core.c @@ -157,7 +157,8 @@ static void __dwc3_set_mode(struct work_struct *work) } /* For DRD host or device mode only */ - if (dwc->desired_dr_role != DWC3_GCTL_PRTCAP_OTG) { + if ((DWC3_IP_IS(DWC3) || DWC3_VER_IS_PRIOR(DWC31, 190A)) && + dwc->desired_dr_role != DWC3_GCTL_PRTCAP_OTG) { reg = dwc3_readl(dwc->regs, DWC3_GCTL); reg |= DWC3_GCTL_CORESOFTRESET; dwc3_writel(dwc->regs, DWC3_GCTL, reg); From 8ee37d0bcd40117999fc5e226cc4e5b107ead09b Mon Sep 17 00:00:00 2001 From: Yunfei Wang Date: Thu, 23 Jun 2022 15:43:53 +0800 Subject: [PATCH 34/91] BACKPORT: iommu/dma: Fix race condition during iova_domain initialization When many devices share the same iova domain, iommu_dma_init_domain() may be called at the same time. The checking of iovad->start_pfn will all get false in iommu_dma_init_domain() and both enter init_iova_domain() to do iovad initialization. Fix this by protecting init_iova_domain() with iommu_dma_cookie->mutex. Exception backtrace: rb_insert_color(param1=0xFFFFFF80CD2BDB40, param3=1) + 64 init_iova_domain() + 180 iommu_setup_dma_ops() + 260 arch_setup_dma_ops() + 132 of_dma_configure_id() + 468 platform_dma_configure() + 32 really_probe() + 1168 driver_probe_device() + 268 __device_attach_driver() + 524 __device_attach() + 524 bus_probe_device() + 64 deferred_probe_work_func() + 260 process_one_work() + 580 worker_thread() + 1076 kthread() + 332 ret_from_fork() + 16 Signed-off-by: Ning Li Signed-off-by: Yunfei Wang Acked-by: Robin Murphy Reviewed-by: Miles Chen Link: https://lore.kernel.org/r/20220530120748.31733-1-yf.wang@mediatek.com Signed-off-by: Joerg Roedel Bug: 236922015 (cherry picked from commit ac9a5d522bb80be50ea84965699e1c8257d745ce https://git.kernel.org/pub/scm/linux/kernel/git/joro/iommu.git core) [Yunfei: Embed iommu_dma_cookie into iommu_dma_cookie_ext to avoid changing struct iommu_dma_cookie] Signed-off-by: Yunfei Wang Change-Id: I9b7931bea912837f17d2322713ba68a37122499d (cherry picked from commit 8a410d778a3c3b1f535acecff7f53c542ffb348c) --- drivers/iommu/dma-iommu.c | 36 +++++++++++++++++++++++++++--------- 1 file changed, 27 insertions(+), 9 deletions(-) diff --git a/drivers/iommu/dma-iommu.c b/drivers/iommu/dma-iommu.c index 2591b973a31b..6f0ba38aaeea 100644 --- a/drivers/iommu/dma-iommu.c +++ b/drivers/iommu/dma-iommu.c @@ -50,6 +50,11 @@ struct iommu_dma_cookie { struct iommu_domain *fq_domain; }; +struct iommu_dma_cookie_ext { + struct iommu_dma_cookie cookie; + struct mutex mutex; +}; + static inline size_t cookie_msi_granule(struct iommu_dma_cookie *cookie) { if (cookie->type == IOMMU_DMA_IOVA_COOKIE) @@ -59,14 +64,15 @@ static inline size_t cookie_msi_granule(struct iommu_dma_cookie *cookie) static struct iommu_dma_cookie *cookie_alloc(enum iommu_dma_cookie_type type) { - struct iommu_dma_cookie *cookie; + struct iommu_dma_cookie_ext *cookie; cookie = kzalloc(sizeof(*cookie), GFP_KERNEL); if (cookie) { - INIT_LIST_HEAD(&cookie->msi_page_list); - cookie->type = type; + INIT_LIST_HEAD(&cookie->cookie.msi_page_list); + cookie->cookie.type = type; + mutex_init(&cookie->mutex); } - return cookie; + return &cookie->cookie; } /** @@ -305,9 +311,11 @@ static int iommu_dma_init_domain(struct iommu_domain *domain, dma_addr_t base, u64 size, struct device *dev) { struct iommu_dma_cookie *cookie = domain->iova_cookie; + struct iommu_dma_cookie_ext *cookie_ext; unsigned long order, base_pfn; struct iova_domain *iovad; int attr; + int ret; if (!cookie || cookie->type != IOMMU_DMA_IOVA_COOKIE) return -EINVAL; @@ -331,14 +339,18 @@ static int iommu_dma_init_domain(struct iommu_domain *domain, dma_addr_t base, } /* start_pfn is always nonzero for an already-initialised domain */ + cookie_ext = container_of(cookie, struct iommu_dma_cookie_ext, cookie); + mutex_lock(&cookie_ext->mutex); if (iovad->start_pfn) { if (1UL << order != iovad->granule || base_pfn != iovad->start_pfn) { pr_warn("Incompatible range for DMA domain\n"); - return -EFAULT; + ret = -EFAULT; + goto done_unlock; } - return 0; + ret = 0; + goto done_unlock; } init_iova_domain(iovad, 1UL << order, base_pfn); @@ -352,10 +364,16 @@ static int iommu_dma_init_domain(struct iommu_domain *domain, dma_addr_t base, cookie->fq_domain = domain; } - if (!dev) - return 0; + if (!dev) { + ret = 0; + goto done_unlock; + } - return iova_reserve_iommu_regions(dev, domain); + ret = iova_reserve_iommu_regions(dev, domain); + +done_unlock: + mutex_unlock(&cookie_ext->mutex); + return ret; } static int iommu_dma_deferred_attach(struct device *dev, From 0e1cb2770027dfe01d429e0318377a997fd57dd0 Mon Sep 17 00:00:00 2001 From: Bing Han Date: Mon, 11 Jul 2022 17:12:21 +0800 Subject: [PATCH 35/91] ANDROID: vendor_hook: Add hook in shmem_writepage() Add vendor hook android_vh_set_shmem_page_flag in shmem_writepage to set a flag in page_ext, which indicates that this page is a shmem page, to be used in android_vh_get_swap_page. The shared page should not be reclaimed to the extended memory, ie, the specified swap location. Bug: 234214858 Signed-off-by: Bing Han Change-Id: I33a9007c88b4d8aab3da044c8a05eb45d7e74f3a --- drivers/android/vendor_hooks.c | 1 + include/trace/hooks/mm.h | 3 +++ mm/shmem.c | 2 ++ 3 files changed, 6 insertions(+) diff --git a/drivers/android/vendor_hooks.c b/drivers/android/vendor_hooks.c index a6c589b266da..c43d1cd06928 100644 --- a/drivers/android/vendor_hooks.c +++ b/drivers/android/vendor_hooks.c @@ -430,3 +430,4 @@ EXPORT_TRACEPOINT_SYMBOL_GPL(android_vh_init_swap_info_struct); EXPORT_TRACEPOINT_SYMBOL_GPL(android_vh_si_swapinfo); EXPORT_TRACEPOINT_SYMBOL_GPL(android_vh_alloc_si); EXPORT_TRACEPOINT_SYMBOL_GPL(android_vh_free_pages); +EXPORT_TRACEPOINT_SYMBOL_GPL(android_vh_set_shmem_page_flag); diff --git a/include/trace/hooks/mm.h b/include/trace/hooks/mm.h index 91d9172c6b4a..3f2784c6a0e5 100644 --- a/include/trace/hooks/mm.h +++ b/include/trace/hooks/mm.h @@ -215,6 +215,9 @@ DECLARE_HOOK(android_vh_alloc_si, DECLARE_HOOK(android_vh_free_pages, TP_PROTO(struct page *page, unsigned int order), TP_ARGS(page, order)); +DECLARE_HOOK(android_vh_set_shmem_page_flag, + TP_PROTO(struct page *page), + TP_ARGS(page)); /* macro versions of hooks are no longer required */ #endif /* _TRACE_HOOK_MM_H */ diff --git a/mm/shmem.c b/mm/shmem.c index 0ed98d632eaa..768c91896036 100644 --- a/mm/shmem.c +++ b/mm/shmem.c @@ -46,6 +46,7 @@ #undef CREATE_TRACE_POINTS #include +#include static struct vfsmount *shm_mnt; @@ -1430,6 +1431,7 @@ static int shmem_writepage(struct page *page, struct writeback_control *wbc) SetPageUptodate(page); } + trace_android_vh_set_shmem_page_flag(page); swap = get_swap_page(page); if (!swap.val) goto redirty; From 242b11e574603029393ca1d094c76900797b5897 Mon Sep 17 00:00:00 2001 From: xiaofeng Date: Tue, 12 Jul 2022 20:43:49 +0800 Subject: [PATCH 36/91] ANDROID: vendor_hooks:vendor hook for pidfd_open Add vendor hook when detecting process status through pidfd_open. Bug: 238725692 Change-Id: I565988cb8bf6dd44ab4dc15c410c2dcf50703def Signed-off-by: xiaofeng --- drivers/android/vendor_hooks.c | 1 + include/trace/hooks/sched.h | 4 ++++ kernel/pid.c | 4 ++++ 3 files changed, 9 insertions(+) diff --git a/drivers/android/vendor_hooks.c b/drivers/android/vendor_hooks.c index c43d1cd06928..0425524e57dd 100644 --- a/drivers/android/vendor_hooks.c +++ b/drivers/android/vendor_hooks.c @@ -431,3 +431,4 @@ EXPORT_TRACEPOINT_SYMBOL_GPL(android_vh_si_swapinfo); EXPORT_TRACEPOINT_SYMBOL_GPL(android_vh_alloc_si); EXPORT_TRACEPOINT_SYMBOL_GPL(android_vh_free_pages); EXPORT_TRACEPOINT_SYMBOL_GPL(android_vh_set_shmem_page_flag); +EXPORT_TRACEPOINT_SYMBOL_GPL(android_vh_pidfd_open); diff --git a/include/trace/hooks/sched.h b/include/trace/hooks/sched.h index 9f16fffd89e4..7d964e4d947a 100644 --- a/include/trace/hooks/sched.h +++ b/include/trace/hooks/sched.h @@ -391,6 +391,10 @@ DECLARE_HOOK(android_vh_setscheduler_uclamp, TP_PROTO(struct task_struct *tsk, int clamp_id, unsigned int value), TP_ARGS(tsk, clamp_id, value)); +DECLARE_HOOK(android_vh_pidfd_open, + TP_PROTO(struct pid *p), + TP_ARGS(p)); + /* macro versions of hooks are no longer required */ #endif /* _TRACE_HOOK_SCHED_H */ diff --git a/kernel/pid.c b/kernel/pid.c index 48babb1dd3e1..468d04810b40 100644 --- a/kernel/pid.c +++ b/kernel/pid.c @@ -45,6 +45,9 @@ #include #include +#undef CREATE_TRACE_POINTS +#include + struct pid init_struct_pid = { .count = REFCOUNT_INIT(1), .tasks = { @@ -602,6 +605,7 @@ SYSCALL_DEFINE2(pidfd_open, pid_t, pid, unsigned int, flags) else fd = -EINVAL; + trace_android_vh_pidfd_open(p); put_pid(p); return fd; } From 8b19ed264b40220326562a29f7ffc1342ba61c08 Mon Sep 17 00:00:00 2001 From: xiaofeng Date: Wed, 13 Jul 2022 10:23:51 +0800 Subject: [PATCH 37/91] ANDROID: vendor_hooks:vendor hook for mmput add vendor hook in mmput while mm_users decreased to 0. Bug: 238821038 Change-Id: I42a717cbeeb3176bac14b4b2391fdb2366c972d3 Signed-off-by: xiaofeng --- drivers/android/vendor_hooks.c | 1 + include/trace/hooks/sched.h | 3 +++ kernel/fork.c | 4 +++- 3 files changed, 7 insertions(+), 1 deletion(-) diff --git a/drivers/android/vendor_hooks.c b/drivers/android/vendor_hooks.c index 0425524e57dd..5a8e8aa2ed34 100644 --- a/drivers/android/vendor_hooks.c +++ b/drivers/android/vendor_hooks.c @@ -432,3 +432,4 @@ EXPORT_TRACEPOINT_SYMBOL_GPL(android_vh_alloc_si); EXPORT_TRACEPOINT_SYMBOL_GPL(android_vh_free_pages); EXPORT_TRACEPOINT_SYMBOL_GPL(android_vh_set_shmem_page_flag); EXPORT_TRACEPOINT_SYMBOL_GPL(android_vh_pidfd_open); +EXPORT_TRACEPOINT_SYMBOL_GPL(android_vh_mmput); diff --git a/include/trace/hooks/sched.h b/include/trace/hooks/sched.h index 7d964e4d947a..551cab4d1649 100644 --- a/include/trace/hooks/sched.h +++ b/include/trace/hooks/sched.h @@ -395,6 +395,9 @@ DECLARE_HOOK(android_vh_pidfd_open, TP_PROTO(struct pid *p), TP_ARGS(p)); +DECLARE_HOOK(android_vh_mmput, + TP_PROTO(void *unused), + TP_ARGS(unused)); /* macro versions of hooks are no longer required */ #endif /* _TRACE_HOOK_SCHED_H */ diff --git a/kernel/fork.c b/kernel/fork.c index 3b281326c0e1..58409b7178c2 100644 --- a/kernel/fork.c +++ b/kernel/fork.c @@ -1150,8 +1150,10 @@ void mmput(struct mm_struct *mm) { might_sleep(); - if (atomic_dec_and_test(&mm->mm_users)) + if (atomic_dec_and_test(&mm->mm_users)) { + trace_android_vh_mmput(NULL); __mmput(mm); + } } EXPORT_SYMBOL_GPL(mmput); From c301d142e8072f1a487bc37bb8d4bb3102ac41e9 Mon Sep 17 00:00:00 2001 From: Rohith Kollalsi Date: Fri, 15 Jul 2022 11:56:27 +0530 Subject: [PATCH 38/91] FROMGIT: usb: dwc3: core: Do not perform GCTL_CORE_SOFTRESET during bootup According to the programming guide, it is recommended to perform a GCTL_CORE_SOFTRESET only when switching the mode from device to host or host to device. However, it is found that during bootup when __dwc3_set_mode() is called for the first time, GCTL_CORESOFTRESET is done with suspendable bit(BIT 17) of DWC3_GUSB3PIPECTL set. This some times leads to issues like controller going into bad state and controller registers reading value zero. Until GCTL_CORESOFTRESET is done and run/stop bit is set core initialization is not complete. Setting suspendable bit of DWC3_GUSB3PIPECTL and then performing GCTL_CORESOFTRESET is therefore not recommended. Avoid this by only performing the reset if current_dr_role is set, that is, when doing subsequent role switching. Fixes: f88359e1588b ("usb: dwc3: core: Do core softreset when switch mode") Signed-off-by: Rohith Kollalsi Link: https://lore.kernel.org/r/20220714045625.20377-1-quic_rkollals@quicinc.com Signed-off-by: Greg Kroah-Hartman (cherry picked from commit 07903626d98853e605fe63e5ce149f1b7314bbea https://git.kernel.org/pub/scm/linux/kernel/git/gregkh/usb.git/ usb-next) BUG: 239121944 Change-Id: Ice6da5dd64896d5deeab425dd1ac5389425a1cc8 Signed-off-by: Rohith Kollalsi --- drivers/usb/dwc3/core.c | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/drivers/usb/dwc3/core.c b/drivers/usb/dwc3/core.c index 8fd631230552..1f60e50a8bb7 100644 --- a/drivers/usb/dwc3/core.c +++ b/drivers/usb/dwc3/core.c @@ -156,9 +156,13 @@ static void __dwc3_set_mode(struct work_struct *work) break; } - /* For DRD host or device mode only */ - if ((DWC3_IP_IS(DWC3) || DWC3_VER_IS_PRIOR(DWC31, 190A)) && - dwc->desired_dr_role != DWC3_GCTL_PRTCAP_OTG) { + /* + * When current_dr_role is not set, there's no role switching. + * Only perform GCTL.CoreSoftReset when there's DRD role switching. + */ + if (dwc->current_dr_role && ((DWC3_IP_IS(DWC3) || + DWC3_VER_IS_PRIOR(DWC31, 190A)) && + dwc->desired_dr_role != DWC3_GCTL_PRTCAP_OTG)) { reg = dwc3_readl(dwc->regs, DWC3_GCTL); reg |= DWC3_GCTL_CORESOFTRESET; dwc3_writel(dwc->regs, DWC3_GCTL, reg); From 41cbbe08f9fb2b99630b49d5960b55ab2547dbaf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?haibinzhang=20=28=E5=BC=A0=E6=B5=B7=E6=96=8C=29?= Date: Sat, 2 Jul 2022 05:43:19 +0000 Subject: [PATCH 39/91] FROMGIT: arm64: fix oops in concurrently setting insn_emulation sysctls emulation_proc_handler() changes table->data for proc_dointvec_minmax and can generate the following Oops if called concurrently with itself: | Unable to handle kernel NULL pointer dereference at virtual address 0000000000000010 | Internal error: Oops: 96000006 [#1] SMP | Call trace: | update_insn_emulation_mode+0xc0/0x148 | emulation_proc_handler+0x64/0xb8 | proc_sys_call_handler+0x9c/0xf8 | proc_sys_write+0x18/0x20 | __vfs_write+0x20/0x48 | vfs_write+0xe4/0x1d0 | ksys_write+0x70/0xf8 | __arm64_sys_write+0x20/0x28 | el0_svc_common.constprop.0+0x7c/0x1c0 | el0_svc_handler+0x2c/0xa0 | el0_svc+0x8/0x200 To fix this issue, keep the table->data as &insn->current_mode and use container_of() to retrieve the insn pointer. Another mutex is used to protect against the current_mode update but not for retrieving insn_emulation as table->data is no longer changing. Bug: 237540956 Co-developed-by: hewenliang Signed-off-by: hewenliang Signed-off-by: Haibin Zhang Reviewed-by: Catalin Marinas Link: https://lore.kernel.org/r/20220128090324.2727688-1-hewenliang4@huawei.com Link: https://lore.kernel.org/r/9A004C03-250B-46C5-BF39-782D7551B00E@tencent.com Signed-off-by: Will Deacon [Lee: Added Fixes: tag] (cherry picked from commit af483947d472eccb79e42059276c4deed76f99a6 git://git.kernel.org/pub/scm/linux/kernel/git/arm64/linux.git for-next/core) Fixes: 587064b610c7 ("arm64: Add framework for legacy instruction emulation") Signed-off-by: Lee Jones Change-Id: If9b96bb79c79903f9d8292e719b06fdef57ef1c5 --- arch/arm64/kernel/armv8_deprecated.c | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/arch/arm64/kernel/armv8_deprecated.c b/arch/arm64/kernel/armv8_deprecated.c index 0e86e8b9cedd..c5da9d1e954a 100644 --- a/arch/arm64/kernel/armv8_deprecated.c +++ b/arch/arm64/kernel/armv8_deprecated.c @@ -59,6 +59,7 @@ struct insn_emulation { static LIST_HEAD(insn_emulation); static int nr_insn_emulated __initdata; static DEFINE_RAW_SPINLOCK(insn_emulation_lock); +static DEFINE_MUTEX(insn_emulation_mutex); static void register_emulation_hooks(struct insn_emulation_ops *ops) { @@ -207,10 +208,10 @@ static int emulation_proc_handler(struct ctl_table *table, int write, loff_t *ppos) { int ret = 0; - struct insn_emulation *insn = (struct insn_emulation *) table->data; + struct insn_emulation *insn = container_of(table->data, struct insn_emulation, current_mode); enum insn_emulation_mode prev_mode = insn->current_mode; - table->data = &insn->current_mode; + mutex_lock(&insn_emulation_mutex); ret = proc_dointvec_minmax(table, write, buffer, lenp, ppos); if (ret || !write || prev_mode == insn->current_mode) @@ -223,7 +224,7 @@ static int emulation_proc_handler(struct ctl_table *table, int write, update_insn_emulation_mode(insn, INSN_UNDEF); } ret: - table->data = insn; + mutex_unlock(&insn_emulation_mutex); return ret; } @@ -247,7 +248,7 @@ static void __init register_insn_emulation_sysctl(void) sysctl->maxlen = sizeof(int); sysctl->procname = insn->ops->name; - sysctl->data = insn; + sysctl->data = &insn->current_mode; sysctl->extra1 = &insn->min; sysctl->extra2 = &insn->max; sysctl->proc_handler = emulation_proc_handler; From d63c961c9df4d9c4ae19e0a59a679af0f80ba69b Mon Sep 17 00:00:00 2001 From: Liujie Xie Date: Wed, 20 Jul 2022 14:10:58 +0800 Subject: [PATCH 40/91] ANDROID: GKI: Update symbols to symbol list Leaf changes summary: 12 artifacts changed Changed leaf types summary: 0 leaf type changed Removed/Changed/Added functions summary: 0 Removed, 0 Changed, 6 Added functions Removed/Changed/Added variables summary: 0 Removed, 0 Changed, 6 Added variables 6 Added functions: [A] 'function int __traceiter_android_vh_mutex_unlock_slowpath_end(void*, mutex*, task_struct*)' [A] 'function int __traceiter_android_vh_rwsem_mark_wake_readers(void*, rw_semaphore*, rwsem_waiter*)' [A] 'function int __traceiter_android_vh_rwsem_set_owner(void*, rw_semaphore*)' [A] 'function int __traceiter_android_vh_rwsem_set_reader_owned(void*, rw_semaphore*)' [A] 'function int __traceiter_android_vh_rwsem_up_read_end(void*, rw_semaphore*)' [A] 'function int __traceiter_android_vh_rwsem_up_write_end(void*, rw_semaphore*)' 6 Added variables: [A] 'tracepoint __tracepoint_android_vh_mutex_unlock_slowpath_end' [A] 'tracepoint __tracepoint_android_vh_rwsem_mark_wake_readers' [A] 'tracepoint __tracepoint_android_vh_rwsem_set_owner' [A] 'tracepoint __tracepoint_android_vh_rwsem_set_reader_owned' [A] 'tracepoint __tracepoint_android_vh_rwsem_up_read_end' [A] 'tracepoint __tracepoint_android_vh_rwsem_up_write_end' Bug: 193384408 Signed-off-by: Liujie Xie Change-Id: Ib21d33425191850fbe4231a6addc69ca40bcb670 --- android/abi_gki_aarch64.xml | 595 ++++++++++++++++++++-------------- android/abi_gki_aarch64_oplus | 16 +- 2 files changed, 357 insertions(+), 254 deletions(-) diff --git a/android/abi_gki_aarch64.xml b/android/abi_gki_aarch64.xml index fbbcdb424bf5..393e96a0357f 100644 --- a/android/abi_gki_aarch64.xml +++ b/android/abi_gki_aarch64.xml @@ -502,6 +502,7 @@ + @@ -518,6 +519,11 @@ + + + + + @@ -6292,6 +6298,7 @@ + @@ -6313,8 +6320,13 @@ + + + + + @@ -15002,24 +15014,24 @@ - + - + - + - + - + - + - + @@ -17641,102 +17653,102 @@ - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + @@ -47037,36 +47049,36 @@ - + - + - + - + - + - + - + - + - + - + - + @@ -48380,12 +48392,12 @@ - + - + - + @@ -52968,12 +52980,12 @@ - + - + - + @@ -59829,9 +59841,9 @@ - + - + @@ -65484,33 +65496,33 @@ - + - + - + - + - + - + - + - + - + - + @@ -74354,21 +74366,21 @@ - + - + - + - + - + - + @@ -76231,120 +76243,120 @@ - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + @@ -76905,18 +76917,18 @@ - + - + - + - + - + @@ -85042,12 +85054,12 @@ - + - + - + @@ -92024,7 +92036,20 @@ - + + + + + + + + + + + + + + @@ -93269,9 +93294,9 @@ - + - + @@ -99981,12 +100006,12 @@ - + - + - + @@ -103584,21 +103609,21 @@ - + - + - + - + - + - + @@ -105607,66 +105632,66 @@ - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + @@ -106757,7 +106782,35 @@ - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -116490,10 +116543,10 @@ - - - - + + + + @@ -117893,6 +117946,12 @@ + + + + + + @@ -117992,6 +118051,32 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -119018,6 +119103,7 @@ + @@ -119039,8 +119125,13 @@ + + + + + @@ -121357,26 +121448,26 @@ - - - + + + - - - - - + + + + + - - - + + + - - - + + + @@ -122765,14 +122856,14 @@ - - - + + + - - - + + + @@ -128182,10 +128273,10 @@ - - - - + + + + @@ -128668,8 +128759,8 @@ - - + + @@ -128696,9 +128787,9 @@ - - - + + + @@ -128709,8 +128800,8 @@ - - + + @@ -128722,8 +128813,8 @@ - - + + @@ -129668,9 +129759,9 @@ - - - + + + @@ -129702,17 +129793,17 @@ - - + + - - + + - - - + + + @@ -131165,7 +131256,7 @@ - + @@ -131501,19 +131592,19 @@ - - + + - - - + + + - - - - + + + + @@ -131546,17 +131637,17 @@ - - + + - - - + + + @@ -131624,8 +131715,8 @@ - - + + @@ -136767,14 +136858,14 @@ - - - + + + - - - + + + @@ -137645,8 +137736,8 @@ - - + + @@ -137977,8 +138068,8 @@ - - + + @@ -140357,27 +140448,27 @@ - - - - + + + + - - - + + + - - - - + + + + - - - - + + + + @@ -142762,8 +142853,8 @@ - - + + @@ -143299,11 +143390,11 @@ - - - - - + + + + + diff --git a/android/abi_gki_aarch64_oplus b/android/abi_gki_aarch64_oplus index 5b208407c2a5..64ede998ff64 100644 --- a/android/abi_gki_aarch64_oplus +++ b/android/abi_gki_aarch64_oplus @@ -2802,6 +2802,7 @@ __traceiter_android_vh_ipi_stop __traceiter_android_vh_ipv6_gen_linklocal_addr __traceiter_android_vh_jiffies_update + __traceiter_android_vh_killed_process __traceiter_android_vh_kmalloc_slab __traceiter_android_vh_logbuf __traceiter_android_vh_mem_cgroup_alloc @@ -2811,6 +2812,7 @@ __traceiter_android_vh_mem_cgroup_id_remove __traceiter_android_vh_meminfo_proc_show __traceiter_android_vh_mutex_unlock_slowpath + __traceiter_android_vh_mutex_unlock_slowpath_end __traceiter_android_vh_mutex_wait_finish __traceiter_android_vh_mutex_wait_start __traceiter_android_vh_override_creds @@ -2819,10 +2821,14 @@ __traceiter_android_vh_prepare_update_load_avg_se __traceiter_android_vh_printk_hotplug __traceiter_android_vh_process_killed - __traceiter_android_vh_killed_process __traceiter_android_vh_revert_creds __traceiter_android_vh_rmqueue __traceiter_android_vh_rwsem_init + __traceiter_android_vh_rwsem_mark_wake_readers + __traceiter_android_vh_rwsem_set_owner + __traceiter_android_vh_rwsem_set_reader_owned + __traceiter_android_vh_rwsem_up_read_end + __traceiter_android_vh_rwsem_up_write_end __traceiter_android_vh_rwsem_wake __traceiter_android_vh_rwsem_wake_finish __traceiter_android_vh_rwsem_write_finished @@ -3010,6 +3016,7 @@ __tracepoint_android_vh_ipi_stop __tracepoint_android_vh_ipv6_gen_linklocal_addr __tracepoint_android_vh_jiffies_update + __tracepoint_android_vh_killed_process __tracepoint_android_vh_kmalloc_slab __tracepoint_android_vh_logbuf __tracepoint_android_vh_mem_cgroup_alloc @@ -3019,6 +3026,7 @@ __tracepoint_android_vh_mem_cgroup_id_remove __tracepoint_android_vh_meminfo_proc_show __tracepoint_android_vh_mutex_unlock_slowpath + __tracepoint_android_vh_mutex_unlock_slowpath_end __tracepoint_android_vh_mutex_wait_finish __tracepoint_android_vh_mutex_wait_start __tracepoint_android_vh_override_creds @@ -3027,10 +3035,14 @@ __tracepoint_android_vh_prepare_update_load_avg_se __tracepoint_android_vh_printk_hotplug __tracepoint_android_vh_process_killed - __tracepoint_android_vh_killed_process __tracepoint_android_vh_revert_creds __tracepoint_android_vh_rmqueue __tracepoint_android_vh_rwsem_init + __tracepoint_android_vh_rwsem_mark_wake_readers + __tracepoint_android_vh_rwsem_set_owner + __tracepoint_android_vh_rwsem_set_reader_owned + __tracepoint_android_vh_rwsem_up_read_end + __tracepoint_android_vh_rwsem_up_write_end __tracepoint_android_vh_rwsem_wake __tracepoint_android_vh_rwsem_wake_finish __tracepoint_android_vh_rwsem_write_finished From 4536de1b708cd4cccf9d47ba8e368b2df67ba10c Mon Sep 17 00:00:00 2001 From: liuhailong Date: Thu, 21 Jul 2022 10:08:14 +0800 Subject: [PATCH 41/91] ANDROID: vendor_hooks: add hooks in __alloc_pages_slowpath Since android_vh_alloc_pages_slowpath is revert by commit e09000ee1915 ("Revert half of "ANDROID: vendor_hooks: Add hooks for memory when debug""). re-add hooks here to measure the duration Bug: 182443489 Signed-off-by: liuhailong Change-Id: Ie4534047105d8409623692cc3811b55d9ddbd17d --- drivers/android/vendor_hooks.c | 2 ++ include/trace/hooks/mm.h | 6 ++++++ mm/page_alloc.c | 3 +++ 3 files changed, 11 insertions(+) diff --git a/drivers/android/vendor_hooks.c b/drivers/android/vendor_hooks.c index 5a8e8aa2ed34..bb6c7f859b26 100644 --- a/drivers/android/vendor_hooks.c +++ b/drivers/android/vendor_hooks.c @@ -271,6 +271,8 @@ EXPORT_TRACEPOINT_SYMBOL_GPL(android_vh_exit_mm); EXPORT_TRACEPOINT_SYMBOL_GPL(android_vh_get_from_fragment_pool); EXPORT_TRACEPOINT_SYMBOL_GPL(android_vh_exclude_reserved_zone); EXPORT_TRACEPOINT_SYMBOL_GPL(android_vh_include_reserved_zone); +EXPORT_TRACEPOINT_SYMBOL_GPL(android_vh_alloc_pages_slowpath_begin); +EXPORT_TRACEPOINT_SYMBOL_GPL(android_vh_alloc_pages_slowpath_end); EXPORT_TRACEPOINT_SYMBOL_GPL(android_vh_show_mem); EXPORT_TRACEPOINT_SYMBOL_GPL(android_vh_typec_tcpci_override_toggling); EXPORT_TRACEPOINT_SYMBOL_GPL(android_rvh_typec_tcpci_chk_contaminant); diff --git a/include/trace/hooks/mm.h b/include/trace/hooks/mm.h index 3f2784c6a0e5..ae6e379fb487 100644 --- a/include/trace/hooks/mm.h +++ b/include/trace/hooks/mm.h @@ -87,6 +87,12 @@ DECLARE_HOOK(android_vh_include_reserved_zone, DECLARE_HOOK(android_vh_show_mem, TP_PROTO(unsigned int filter, nodemask_t *nodemask), TP_ARGS(filter, nodemask)); +DECLARE_HOOK(android_vh_alloc_pages_slowpath_begin, + TP_PROTO(gfp_t gfp_mask, unsigned int order, unsigned long *pdata), + TP_ARGS(gfp_mask, order, pdata)); +DECLARE_HOOK(android_vh_alloc_pages_slowpath_end, + TP_PROTO(gfp_t gfp_mask, unsigned int order, unsigned long data), + TP_ARGS(gfp_mask, order, data)); struct dirty_throttle_control; DECLARE_HOOK(android_vh_mm_dirty_limits, TP_PROTO(struct dirty_throttle_control *const gdtc, bool strictlimit, diff --git a/mm/page_alloc.c b/mm/page_alloc.c index 27b18887bf5f..d97590f78b9b 100644 --- a/mm/page_alloc.c +++ b/mm/page_alloc.c @@ -4790,7 +4790,9 @@ __alloc_pages_slowpath(gfp_t gfp_mask, unsigned int order, int no_progress_loops; unsigned int cpuset_mems_cookie; int reserve_flags; + unsigned long vh_record; + trace_android_vh_alloc_pages_slowpath_begin(gfp_mask, order, &vh_record); /* * We also sanity check to catch abuse of atomic reserves being used by * callers that are not in atomic context. @@ -5032,6 +5034,7 @@ fail: warn_alloc(gfp_mask, ac->nodemask, "page allocation failure: order:%u", order); got_pg: + trace_android_vh_alloc_pages_slowpath_end(gfp_mask, order, vh_record); return page; } From a8d7f6518eaedc4974d47535fc95a699c85eda9e Mon Sep 17 00:00:00 2001 From: liuhailong Date: Fri, 22 Jul 2022 19:08:49 +0800 Subject: [PATCH 42/91] ANDROID: oplus: Update the ABI xml and symbol list Leaf changes summary: 4 artifacts changed Changed leaf types summary: 0 leaf type changed Removed/Changed/Added functions summary: 0 Removed, 0 Changed, 2 Added functions Removed/Changed/Added variables summary: 0 Removed, 0 Changed, 2 Added variables 2 Added functions: [A] 'function int __traceiter_android_vh_alloc_pages_slowpath_begin(void*, gfp_t, unsigned int, unsigned long int*)' [A] 'function int __traceiter_android_vh_alloc_pages_slowpath_end(void*, gfp_t, unsigned int, unsigned long int)' 2 Added variables: [A] 'tracepoint __tracepoint_android_vh_alloc_pages_slowpath_begin' [A] 'tracepoint __tracepoint_android_vh_alloc_pages_slowpath_end' Bug: 182443489 Signed-off-by: liuhailong Change-Id: I2745cb53ae192e2ce31726d09d7e9746b77ccce3 --- android/abi_gki_aarch64.xml | 248 ++++++++++++++++++---------------- android/abi_gki_aarch64_oplus | 4 + 2 files changed, 138 insertions(+), 114 deletions(-) diff --git a/android/abi_gki_aarch64.xml b/android/abi_gki_aarch64.xml index 393e96a0357f..f04c35d93049 100644 --- a/android/abi_gki_aarch64.xml +++ b/android/abi_gki_aarch64.xml @@ -393,6 +393,8 @@ + + @@ -6186,6 +6188,8 @@ + + @@ -114914,11 +114918,11 @@ - - - - - + + + + + @@ -115543,9 +115547,9 @@ - - - + + + @@ -115598,9 +115602,9 @@ - - - + + + @@ -117238,6 +117242,20 @@ + + + + + + + + + + + + + + @@ -117510,10 +117528,10 @@ - - - - + + + + @@ -117592,14 +117610,14 @@ - - - - - - - - + + + + + + + + @@ -117832,11 +117850,11 @@ - - - - - + + + + + @@ -117868,31 +117886,31 @@ - - - + + + - - - - + + + + - + + + + + + + - - - - - - - - - + + + @@ -117900,20 +117918,20 @@ - - - - - - - - + + + + + + + + - - - - + + + + @@ -117991,10 +118009,10 @@ - - - - + + + + @@ -118092,16 +118110,16 @@ - - - - + + + + - - - - + + + + @@ -118239,10 +118257,10 @@ - - - - + + + + @@ -118314,12 +118332,12 @@ - - - - - - + + + + + + @@ -118991,6 +119009,8 @@ + + @@ -119031,7 +119051,7 @@ - + @@ -119044,7 +119064,7 @@ - + @@ -119085,19 +119105,19 @@ - + - - - - - + + + + + - - + + @@ -119107,11 +119127,11 @@ - + - + @@ -119137,8 +119157,8 @@ - - + + @@ -119164,14 +119184,14 @@ - + - + @@ -119179,7 +119199,7 @@ - + @@ -119204,7 +119224,7 @@ - + @@ -119767,9 +119787,9 @@ - - - + + + @@ -119886,9 +119906,9 @@ - - - + + + @@ -128913,14 +128933,14 @@ - - - + + + - - - + + + @@ -129865,8 +129885,8 @@ - - + + @@ -140489,11 +140509,11 @@ - + - - + + diff --git a/android/abi_gki_aarch64_oplus b/android/abi_gki_aarch64_oplus index 64ede998ff64..12bfddf46340 100644 --- a/android/abi_gki_aarch64_oplus +++ b/android/abi_gki_aarch64_oplus @@ -2811,6 +2811,8 @@ __traceiter_android_vh_mem_cgroup_free __traceiter_android_vh_mem_cgroup_id_remove __traceiter_android_vh_meminfo_proc_show + __traceiter_android_vh_alloc_pages_slowpath_begin + __traceiter_android_vh_alloc_pages_slowpath_end __traceiter_android_vh_mutex_unlock_slowpath __traceiter_android_vh_mutex_unlock_slowpath_end __traceiter_android_vh_mutex_wait_finish @@ -3025,6 +3027,8 @@ __tracepoint_android_vh_mem_cgroup_free __tracepoint_android_vh_mem_cgroup_id_remove __tracepoint_android_vh_meminfo_proc_show + __tracepoint_android_vh_alloc_pages_slowpath_begin + __tracepoint_android_vh_alloc_pages_slowpath_end __tracepoint_android_vh_mutex_unlock_slowpath __tracepoint_android_vh_mutex_unlock_slowpath_end __tracepoint_android_vh_mutex_wait_finish From 51b3e17071145718a41e55878b8a0513763cf385 Mon Sep 17 00:00:00 2001 From: Rob Herring Date: Mon, 26 Oct 2020 13:16:52 -0500 Subject: [PATCH 43/91] UPSTREAM: PCI: dwc: Support multiple ATU memory regions The current ATU setup only supports a single memory resource which isn't sufficient if there are also prefetchable memory regions. In order to support multiple memory regions, we need to move away from fixed ATU slots and rework the assignment. As there's always an ATU entry for config space, let's assign index 0 to config space. Then we assign memory resources to index 1 and up. Finally, if we have an I/O region and slots remaining, we assign the I/O region last. If there aren't remaining slots, we keep the same config and I/O space sharing. Bug: 239396464 Link: https://lore.kernel.org/r/20201026181652.418729-1-robh@kernel.org Tested-by: Vidya Sagar Signed-off-by: Rob Herring Signed-off-by: Lorenzo Pieralisi Reviewed-by: Vidya Sagar Acked-by: Jingoo Han Cc: Vidya Sagar Cc: Jingoo Han Cc: Gustavo Pimentel Cc: Lorenzo Pieralisi Cc: Bjorn Helgaas Signed-off-by: Shawn Lin Signed-off-by: Jon Lin Change-Id: Ib945de723c29a80f055227474a01806283bd1873 (cherry picked from commit 9f9e59a4809563f24e3d1377aa804a4b7386a418) Signed-off-by: Kever Yang --- .../pci/controller/dwc/pcie-designware-host.c | 52 +++++++++++-------- drivers/pci/controller/dwc/pcie-designware.h | 6 +-- 2 files changed, 33 insertions(+), 25 deletions(-) diff --git a/drivers/pci/controller/dwc/pcie-designware-host.c b/drivers/pci/controller/dwc/pcie-designware-host.c index 72a76372ff3d..c46584d366ce 100644 --- a/drivers/pci/controller/dwc/pcie-designware-host.c +++ b/drivers/pci/controller/dwc/pcie-designware-host.c @@ -465,9 +465,7 @@ static void __iomem *dw_pcie_other_conf_map_bus(struct pci_bus *bus, type = PCIE_ATU_TYPE_CFG1; - dw_pcie_prog_outbound_atu(pci, PCIE_ATU_REGION_INDEX1, - type, pp->cfg0_base, - busdev, pp->cfg0_size); + dw_pcie_prog_outbound_atu(pci, 0, type, pp->cfg0_base, busdev, pp->cfg0_size); return pp->va_cfg0_base + where; } @@ -481,9 +479,8 @@ static int dw_pcie_rd_other_conf(struct pci_bus *bus, unsigned int devfn, ret = pci_generic_config_read(bus, devfn, where, size, val); - if (!ret && pci->num_viewport <= 2) - dw_pcie_prog_outbound_atu(pci, PCIE_ATU_REGION_INDEX1, - PCIE_ATU_TYPE_IO, pp->io_base, + if (!ret && pci->io_cfg_atu_shared) + dw_pcie_prog_outbound_atu(pci, 0, PCIE_ATU_TYPE_IO, pp->io_base, pp->io_bus_addr, pp->io_size); return ret; @@ -498,9 +495,8 @@ static int dw_pcie_wr_other_conf(struct pci_bus *bus, unsigned int devfn, ret = pci_generic_config_write(bus, devfn, where, size, val); - if (!ret && pci->num_viewport <= 2) - dw_pcie_prog_outbound_atu(pci, PCIE_ATU_REGION_INDEX1, - PCIE_ATU_TYPE_IO, pp->io_base, + if (!ret && pci->io_cfg_atu_shared) + dw_pcie_prog_outbound_atu(pci, 0, PCIE_ATU_TYPE_IO, pp->io_base, pp->io_bus_addr, pp->io_size); return ret; @@ -587,21 +583,35 @@ void dw_pcie_setup_rc(struct pcie_port *pp) * ATU, so we should not program the ATU here. */ if (pp->bridge->child_ops == &dw_child_pcie_ops) { - struct resource_entry *tmp, *entry = NULL; + int atu_idx = 0; + struct resource_entry *entry; /* Get last memory resource entry */ - resource_list_for_each_entry(tmp, &pp->bridge->windows) - if (resource_type(tmp->res) == IORESOURCE_MEM) - entry = tmp; + resource_list_for_each_entry(entry, &pp->bridge->windows) { + if (resource_type(entry->res) != IORESOURCE_MEM) + continue; - dw_pcie_prog_outbound_atu(pci, PCIE_ATU_REGION_INDEX0, - PCIE_ATU_TYPE_MEM, entry->res->start, - entry->res->start - entry->offset, - resource_size(entry->res)); - if (pci->num_viewport > 2) - dw_pcie_prog_outbound_atu(pci, PCIE_ATU_REGION_INDEX2, - PCIE_ATU_TYPE_IO, pp->io_base, - pp->io_bus_addr, pp->io_size); + if (pci->num_viewport <= ++atu_idx) + break; + + dw_pcie_prog_outbound_atu(pci, atu_idx, + PCIE_ATU_TYPE_MEM, entry->res->start, + entry->res->start - entry->offset, + resource_size(entry->res)); + } + + if (pp->io_size) { + if (pci->num_viewport > ++atu_idx) + dw_pcie_prog_outbound_atu(pci, atu_idx, + PCIE_ATU_TYPE_IO, pp->io_base, + pp->io_bus_addr, pp->io_size); + else + pci->io_cfg_atu_shared = true; + } + + if (pci->num_viewport <= atu_idx) + dev_warn(pci->dev, "Resources exceed number of ATU entries (%d)", + pci->num_viewport); } dw_pcie_writel_dbi(pci, PCI_BASE_ADDRESS_0, 0); diff --git a/drivers/pci/controller/dwc/pcie-designware.h b/drivers/pci/controller/dwc/pcie-designware.h index 9d2f511f13fa..ed19c34dd0fe 100644 --- a/drivers/pci/controller/dwc/pcie-designware.h +++ b/drivers/pci/controller/dwc/pcie-designware.h @@ -80,9 +80,6 @@ #define PCIE_ATU_VIEWPORT 0x900 #define PCIE_ATU_REGION_INBOUND BIT(31) #define PCIE_ATU_REGION_OUTBOUND 0 -#define PCIE_ATU_REGION_INDEX2 0x2 -#define PCIE_ATU_REGION_INDEX1 0x1 -#define PCIE_ATU_REGION_INDEX0 0x0 #define PCIE_ATU_CR1 0x904 #define PCIE_ATU_TYPE_MEM 0x0 #define PCIE_ATU_TYPE_IO 0x2 @@ -266,7 +263,6 @@ struct dw_pcie { /* Used when iatu_unroll_enabled is true */ void __iomem *atu_base; u32 num_viewport; - u8 iatu_unroll_enabled; struct pcie_port pp; struct dw_pcie_ep ep; const struct dw_pcie_ops *ops; @@ -274,6 +270,8 @@ struct dw_pcie { int num_lanes; int link_gen; u8 n_fts[2]; + bool iatu_unroll_enabled: 1; + bool io_cfg_atu_shared: 1; }; #define to_dw_pcie_from_pp(port) container_of((port), struct dw_pcie, pp) From 5fa1e1affc12a0f23f689fbfe66084a7ea952239 Mon Sep 17 00:00:00 2001 From: Kever Yang Date: Fri, 22 Jul 2022 10:40:07 +0800 Subject: [PATCH 44/91] ANDROID: GKI: pcie: Fix the broken dw_pcie structure This patch fix the break to abi dw_pcie structure and keep other code AS IS. Bug: 239396464 Signed-off-by: Kever Yang Change-Id: I138f28812eb4254671fa353a7541e65bddfc1bda --- drivers/pci/controller/dwc/pcie-designware-host.c | 6 +++--- drivers/pci/controller/dwc/pcie-designware.c | 9 +++++---- drivers/pci/controller/dwc/pcie-designware.h | 5 +++-- 3 files changed, 11 insertions(+), 9 deletions(-) diff --git a/drivers/pci/controller/dwc/pcie-designware-host.c b/drivers/pci/controller/dwc/pcie-designware-host.c index c46584d366ce..dc0d135e81df 100644 --- a/drivers/pci/controller/dwc/pcie-designware-host.c +++ b/drivers/pci/controller/dwc/pcie-designware-host.c @@ -479,7 +479,7 @@ static int dw_pcie_rd_other_conf(struct pci_bus *bus, unsigned int devfn, ret = pci_generic_config_read(bus, devfn, where, size, val); - if (!ret && pci->io_cfg_atu_shared) + if (!ret && (pci->iatu_unroll_enabled & DWC_IATU_IOCFG_SHARED)) dw_pcie_prog_outbound_atu(pci, 0, PCIE_ATU_TYPE_IO, pp->io_base, pp->io_bus_addr, pp->io_size); @@ -495,7 +495,7 @@ static int dw_pcie_wr_other_conf(struct pci_bus *bus, unsigned int devfn, ret = pci_generic_config_write(bus, devfn, where, size, val); - if (!ret && pci->io_cfg_atu_shared) + if (!ret && (pci->iatu_unroll_enabled & DWC_IATU_IOCFG_SHARED)) dw_pcie_prog_outbound_atu(pci, 0, PCIE_ATU_TYPE_IO, pp->io_base, pp->io_bus_addr, pp->io_size); @@ -606,7 +606,7 @@ void dw_pcie_setup_rc(struct pcie_port *pp) PCIE_ATU_TYPE_IO, pp->io_base, pp->io_bus_addr, pp->io_size); else - pci->io_cfg_atu_shared = true; + pci->iatu_unroll_enabled |= DWC_IATU_IOCFG_SHARED; } if (pci->num_viewport <= atu_idx) diff --git a/drivers/pci/controller/dwc/pcie-designware.c b/drivers/pci/controller/dwc/pcie-designware.c index c85e128bc0ea..5c6c3a986600 100644 --- a/drivers/pci/controller/dwc/pcie-designware.c +++ b/drivers/pci/controller/dwc/pcie-designware.c @@ -274,7 +274,7 @@ static void __dw_pcie_prog_outbound_atu(struct dw_pcie *pci, u8 func_no, if (pci->ops->cpu_addr_fixup) cpu_addr = pci->ops->cpu_addr_fixup(pci, cpu_addr); - if (pci->iatu_unroll_enabled) { + if (pci->iatu_unroll_enabled & DWC_IATU_UNROLL_EN) { dw_pcie_prog_outbound_atu_unroll(pci, func_no, index, type, cpu_addr, pci_addr, size); return; @@ -394,7 +394,7 @@ int dw_pcie_prog_inbound_atu(struct dw_pcie *pci, u8 func_no, int index, int type; u32 retries, val; - if (pci->iatu_unroll_enabled) + if (pci->iatu_unroll_enabled & DWC_IATU_UNROLL_EN) return dw_pcie_prog_inbound_atu_unroll(pci, func_no, index, bar, cpu_addr, as_type); @@ -554,14 +554,15 @@ void dw_pcie_setup(struct dw_pcie *pci) if (pci->version >= 0x480A || (!pci->version && dw_pcie_iatu_unroll_enabled(pci))) { - pci->iatu_unroll_enabled = true; + pci->iatu_unroll_enabled |= DWC_IATU_UNROLL_EN; if (!pci->atu_base) pci->atu_base = devm_platform_ioremap_resource_byname(pdev, "atu"); if (IS_ERR(pci->atu_base)) pci->atu_base = pci->dbi_base + DEFAULT_DBI_ATU_OFFSET; } - dev_dbg(pci->dev, "iATU unroll: %s\n", pci->iatu_unroll_enabled ? + dev_dbg(pci->dev, "iATU unroll: %s\n", + pci->iatu_unroll_enabled & DWC_IATU_UNROLL_EN ? "enabled" : "disabled"); if (pci->link_gen > 0) diff --git a/drivers/pci/controller/dwc/pcie-designware.h b/drivers/pci/controller/dwc/pcie-designware.h index ed19c34dd0fe..98084e8489ec 100644 --- a/drivers/pci/controller/dwc/pcie-designware.h +++ b/drivers/pci/controller/dwc/pcie-designware.h @@ -256,6 +256,8 @@ struct dw_pcie_ops { void (*stop_link)(struct dw_pcie *pcie); }; +#define DWC_IATU_UNROLL_EN BIT(0) +#define DWC_IATU_IOCFG_SHARED BIT(1) struct dw_pcie { struct device *dev; void __iomem *dbi_base; @@ -263,6 +265,7 @@ struct dw_pcie { /* Used when iatu_unroll_enabled is true */ void __iomem *atu_base; u32 num_viewport; + u8 iatu_unroll_enabled; struct pcie_port pp; struct dw_pcie_ep ep; const struct dw_pcie_ops *ops; @@ -270,8 +273,6 @@ struct dw_pcie { int num_lanes; int link_gen; u8 n_fts[2]; - bool iatu_unroll_enabled: 1; - bool io_cfg_atu_shared: 1; }; #define to_dw_pcie_from_pp(port) container_of((port), struct dw_pcie, pp) From b2e5773ea411cfe8982d93fc38ca2a14e6ea627d Mon Sep 17 00:00:00 2001 From: Carlos Llamas Date: Fri, 1 Jul 2022 18:20:41 +0000 Subject: [PATCH 45/91] FROMGIT: binder: fix redefinition of seq_file attributes The patchset in [1] exported some definitions to binder_internal.h in order to make the debugfs entries such as 'stats' and 'transaction_log' available in a binderfs instance. However, the DEFINE_SHOW_ATTRIBUTE macro expands into a static function/variable pair, which in turn get redefined each time a source file includes this internal header. This problem was made evident after a report from the kernel test robot where several W=1 build warnings are seen in downstream kernels. See the following example: include/../drivers/android/binder_internal.h:111:23: warning: 'binder_stats_fops' defined but not used [-Wunused-const-variable=] 111 | DEFINE_SHOW_ATTRIBUTE(binder_stats); | ^~~~~~~~~~~~ include/linux/seq_file.h:174:37: note: in definition of macro 'DEFINE_SHOW_ATTRIBUTE' 174 | static const struct file_operations __name ## _fops = { \ | ^~~~~~ This patch fixes the above issues by moving back the definitions into binder.c and instead creates an array of the debugfs entries which is more convenient to share with binderfs and iterate through. [1] https://lore.kernel.org/all/20190903161655.107408-1-hridya@google.com/ Fixes: 0e13e452dafc ("binder: Add stats, state and transactions files") Fixes: 03e2e07e3814 ("binder: Make transaction_log available in binderfs") Reported-by: kernel test robot Signed-off-by: Carlos Llamas Link: https://lore.kernel.org/r/20220701182041.2134313-1-cmllamas@google.com Signed-off-by: Greg Kroah-Hartman Bug: 240404657 (cherry picked from commit b7e241bbff24f9e106bf616408fd58bcedc44bae git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/char-misc.git char-misc-next) Signed-off-by: Carlos Llamas Change-Id: I7e9ca1ab1f3a5a4a272e50f24d404c17cad55d32 --- drivers/android/binder.c | 114 +++++++++++++++++++++--------- drivers/android/binder_internal.h | 46 +++--------- drivers/android/binderfs.c | 47 +++--------- 3 files changed, 100 insertions(+), 107 deletions(-) diff --git a/drivers/android/binder.c b/drivers/android/binder.c index 0d83bf894f77..75cd8b927ad4 100644 --- a/drivers/android/binder.c +++ b/drivers/android/binder.c @@ -173,8 +173,32 @@ static inline void binder_stats_created(enum binder_stat_types type) atomic_inc(&binder_stats.obj_created[type]); } -struct binder_transaction_log binder_transaction_log; -struct binder_transaction_log binder_transaction_log_failed; +struct binder_transaction_log_entry { + int debug_id; + int debug_id_done; + int call_type; + int from_proc; + int from_thread; + int target_handle; + int to_proc; + int to_thread; + int to_node; + int data_size; + int offsets_size; + int return_error_line; + uint32_t return_error; + uint32_t return_error_param; + char context_name[BINDERFS_MAX_NAME + 1]; +}; + +struct binder_transaction_log { + atomic_t cur; + bool full; + struct binder_transaction_log_entry entry[32]; +}; + +static struct binder_transaction_log binder_transaction_log; +static struct binder_transaction_log binder_transaction_log_failed; static struct binder_transaction_log_entry *binder_transaction_log_add( struct binder_transaction_log *log) @@ -6028,8 +6052,7 @@ static void print_binder_proc_stats(struct seq_file *m, print_binder_stats(m, " ", &proc->stats); } - -int binder_state_show(struct seq_file *m, void *unused) +static int state_show(struct seq_file *m, void *unused) { struct binder_proc *proc; struct binder_node *node; @@ -6068,7 +6091,7 @@ int binder_state_show(struct seq_file *m, void *unused) return 0; } -int binder_stats_show(struct seq_file *m, void *unused) +static int stats_show(struct seq_file *m, void *unused) { struct binder_proc *proc; @@ -6084,7 +6107,7 @@ int binder_stats_show(struct seq_file *m, void *unused) return 0; } -int binder_transactions_show(struct seq_file *m, void *unused) +static int transactions_show(struct seq_file *m, void *unused) { struct binder_proc *proc; @@ -6140,7 +6163,7 @@ static void print_binder_transaction_log_entry(struct seq_file *m, "\n" : " (incomplete)\n"); } -int binder_transaction_log_show(struct seq_file *m, void *unused) +static int transaction_log_show(struct seq_file *m, void *unused) { struct binder_transaction_log *log = m->private; unsigned int log_cur = atomic_read(&log->cur); @@ -6172,6 +6195,45 @@ const struct file_operations binder_fops = { .release = binder_release, }; +DEFINE_SHOW_ATTRIBUTE(state); +DEFINE_SHOW_ATTRIBUTE(stats); +DEFINE_SHOW_ATTRIBUTE(transactions); +DEFINE_SHOW_ATTRIBUTE(transaction_log); + +const struct binder_debugfs_entry binder_debugfs_entries[] = { + { + .name = "state", + .mode = 0444, + .fops = &state_fops, + .data = NULL, + }, + { + .name = "stats", + .mode = 0444, + .fops = &stats_fops, + .data = NULL, + }, + { + .name = "transactions", + .mode = 0444, + .fops = &transactions_fops, + .data = NULL, + }, + { + .name = "transaction_log", + .mode = 0444, + .fops = &transaction_log_fops, + .data = &binder_transaction_log, + }, + { + .name = "failed_transaction_log", + .mode = 0444, + .fops = &transaction_log_fops, + .data = &binder_transaction_log_failed, + }, + {} /* terminator */ +}; + static int __init init_binder_device(const char *name) { int ret; @@ -6217,36 +6279,18 @@ static int __init binder_init(void) atomic_set(&binder_transaction_log_failed.cur, ~0U); binder_debugfs_dir_entry_root = debugfs_create_dir("binder", NULL); - if (binder_debugfs_dir_entry_root) + if (binder_debugfs_dir_entry_root) { + const struct binder_debugfs_entry *db_entry; + + binder_for_each_debugfs_entry(db_entry) + debugfs_create_file(db_entry->name, + db_entry->mode, + binder_debugfs_dir_entry_root, + db_entry->data, + db_entry->fops); + binder_debugfs_dir_entry_proc = debugfs_create_dir("proc", binder_debugfs_dir_entry_root); - - if (binder_debugfs_dir_entry_root) { - debugfs_create_file("state", - 0444, - binder_debugfs_dir_entry_root, - NULL, - &binder_state_fops); - debugfs_create_file("stats", - 0444, - binder_debugfs_dir_entry_root, - NULL, - &binder_stats_fops); - debugfs_create_file("transactions", - 0444, - binder_debugfs_dir_entry_root, - NULL, - &binder_transactions_fops); - debugfs_create_file("transaction_log", - 0444, - binder_debugfs_dir_entry_root, - &binder_transaction_log, - &binder_transaction_log_fops); - debugfs_create_file("failed_transaction_log", - 0444, - binder_debugfs_dir_entry_root, - &binder_transaction_log_failed, - &binder_transaction_log_fops); } if (!IS_ENABLED(CONFIG_ANDROID_BINDERFS) && diff --git a/drivers/android/binder_internal.h b/drivers/android/binder_internal.h index 93f02395b0d7..00010c2e3e3c 100644 --- a/drivers/android/binder_internal.h +++ b/drivers/android/binder_internal.h @@ -107,41 +107,19 @@ static inline int __init init_binderfs(void) } #endif -int binder_stats_show(struct seq_file *m, void *unused); -DEFINE_SHOW_ATTRIBUTE(binder_stats); - -int binder_state_show(struct seq_file *m, void *unused); -DEFINE_SHOW_ATTRIBUTE(binder_state); - -int binder_transactions_show(struct seq_file *m, void *unused); -DEFINE_SHOW_ATTRIBUTE(binder_transactions); - -int binder_transaction_log_show(struct seq_file *m, void *unused); -DEFINE_SHOW_ATTRIBUTE(binder_transaction_log); - -struct binder_transaction_log_entry { - int debug_id; - int debug_id_done; - int call_type; - int from_proc; - int from_thread; - int target_handle; - int to_proc; - int to_thread; - int to_node; - int data_size; - int offsets_size; - int return_error_line; - uint32_t return_error; - uint32_t return_error_param; - char context_name[BINDERFS_MAX_NAME + 1]; +struct binder_debugfs_entry { + const char *name; + umode_t mode; + const struct file_operations *fops; + void *data; }; -struct binder_transaction_log { - atomic_t cur; - bool full; - struct binder_transaction_log_entry entry[32]; -}; +extern const struct binder_debugfs_entry binder_debugfs_entries[]; + +#define binder_for_each_debugfs_entry(entry) \ + for ((entry) = binder_debugfs_entries; \ + (entry)->name; \ + (entry)++) enum binder_stat_types { BINDER_STAT_PROC, @@ -620,6 +598,4 @@ struct binder_object { }; }; -extern struct binder_transaction_log binder_transaction_log; -extern struct binder_transaction_log binder_transaction_log_failed; #endif /* _LINUX_BINDER_INTERNAL_H */ diff --git a/drivers/android/binderfs.c b/drivers/android/binderfs.c index 7b4f154f07e6..2e5fbb3adb09 100644 --- a/drivers/android/binderfs.c +++ b/drivers/android/binderfs.c @@ -584,6 +584,7 @@ out: static int init_binder_logs(struct super_block *sb) { struct dentry *binder_logs_root_dir, *dentry, *proc_log_dir; + const struct binder_debugfs_entry *db_entry; struct binderfs_info *info; int ret = 0; @@ -594,43 +595,15 @@ static int init_binder_logs(struct super_block *sb) goto out; } - dentry = binderfs_create_file(binder_logs_root_dir, "stats", - &binder_stats_fops, NULL); - if (IS_ERR(dentry)) { - ret = PTR_ERR(dentry); - goto out; - } - - dentry = binderfs_create_file(binder_logs_root_dir, "state", - &binder_state_fops, NULL); - if (IS_ERR(dentry)) { - ret = PTR_ERR(dentry); - goto out; - } - - dentry = binderfs_create_file(binder_logs_root_dir, "transactions", - &binder_transactions_fops, NULL); - if (IS_ERR(dentry)) { - ret = PTR_ERR(dentry); - goto out; - } - - dentry = binderfs_create_file(binder_logs_root_dir, - "transaction_log", - &binder_transaction_log_fops, - &binder_transaction_log); - if (IS_ERR(dentry)) { - ret = PTR_ERR(dentry); - goto out; - } - - dentry = binderfs_create_file(binder_logs_root_dir, - "failed_transaction_log", - &binder_transaction_log_fops, - &binder_transaction_log_failed); - if (IS_ERR(dentry)) { - ret = PTR_ERR(dentry); - goto out; + binder_for_each_debugfs_entry(db_entry) { + dentry = binderfs_create_file(binder_logs_root_dir, + db_entry->name, + db_entry->fops, + db_entry->data); + if (IS_ERR(dentry)) { + ret = PTR_ERR(dentry); + goto out; + } } proc_log_dir = binderfs_create_dir(binder_logs_root_dir, "proc"); From 4442801a43f36350785023f54fc37abfd36b2145 Mon Sep 17 00:00:00 2001 From: JianMin Liu Date: Wed, 29 Jun 2022 21:13:56 +0800 Subject: [PATCH 46/91] ANDROID: sched: Introducing PELT multiplier The new sysctl sched_pelt_multiplier allows a user to set a clock multiplier x2 or x4 (x1 being the default). This clock multiplier artificially speed-up PELT ramp up/down similarly to a faster half-life. Indeed, if we write PELT as a first order filter: y(t) = G * (1 - exp(t/tau)) Then we can see that multiplying the time by a constant X, is the same as dividing the time constant tau by X. y(t) = G * (1 - exp((t*X)/tau)) y(t) = G * (1 - exp(t/(tau/X))) Tau being half-life*ln(2), multiplying the PELT time is the same as dividing the half-life: - x1: 32ms half-life - x2: 16ms half-life - x4: 8ms half-life Internally, a new clock is created: rq->clock_task_mult. It sits in the clock hierarchy between rq->clock_task and rq->clock_pelt. Bug: 177593580 Bug: 237219700 Change-Id: I67e6ca7994bebea22bf75732ee11d2b10e0d6b7e Suggested-by: Morten Rasmussen Signed-off-by: Vincent Donnefort Signed-off-by: JianMin Liu --- include/linux/sched/sysctl.h | 7 ++++++ kernel/sched/fair.c | 6 +++--- kernel/sched/pelt.c | 42 ++++++++++++++++++++++++++++++++++++ kernel/sched/pelt.h | 11 ++++++++-- kernel/sched/sched.h | 10 +++++++++ kernel/sysctl.c | 9 ++++++++ 6 files changed, 80 insertions(+), 5 deletions(-) diff --git a/include/linux/sched/sysctl.h b/include/linux/sched/sysctl.h index 3c31ba88aca5..581ee79550de 100644 --- a/include/linux/sched/sysctl.h +++ b/include/linux/sched/sysctl.h @@ -92,6 +92,13 @@ int sysctl_numa_balancing(struct ctl_table *table, int write, void *buffer, int sysctl_schedstats(struct ctl_table *table, int write, void *buffer, size_t *lenp, loff_t *ppos); +#ifdef CONFIG_SMP +extern unsigned int sysctl_sched_pelt_multiplier; + +int sched_pelt_multiplier(struct ctl_table *table, int write, void *buffer, + size_t *lenp, loff_t *ppos); +#endif + #if defined(CONFIG_ENERGY_MODEL) && defined(CONFIG_CPU_FREQ_GOV_SCHEDUTIL) extern unsigned int sysctl_sched_energy_aware; int sched_energy_aware_handler(struct ctl_table *table, int write, diff --git a/kernel/sched/fair.c b/kernel/sched/fair.c index 6af244d71e6b..05682fab3872 100644 --- a/kernel/sched/fair.c +++ b/kernel/sched/fair.c @@ -4788,7 +4788,7 @@ static int tg_unthrottle_up(struct task_group *tg, void *data) cfs_rq->throttle_count--; if (!cfs_rq->throttle_count) { - cfs_rq->throttled_clock_task_time += rq_clock_task(rq) - + cfs_rq->throttled_clock_task_time += rq_clock_task_mult(rq) - cfs_rq->throttled_clock_task; /* Add cfs_rq with already running entity in the list */ @@ -4806,7 +4806,7 @@ static int tg_throttle_down(struct task_group *tg, void *data) /* group is entering throttled state, stop time */ if (!cfs_rq->throttle_count) { - cfs_rq->throttled_clock_task = rq_clock_task(rq); + cfs_rq->throttled_clock_task = rq_clock_task_mult(rq); list_del_leaf_cfs_rq(cfs_rq); } cfs_rq->throttle_count++; @@ -5224,7 +5224,7 @@ static void sync_throttle(struct task_group *tg, int cpu) pcfs_rq = tg->parent->cfs_rq[cpu]; cfs_rq->throttle_count = pcfs_rq->throttle_count; - cfs_rq->throttled_clock_task = rq_clock_task(cpu_rq(cpu)); + cfs_rq->throttled_clock_task = rq_clock_task_mult(cpu_rq(cpu)); } /* conditionally throttle active cfs_rq's from put_prev_entity() */ diff --git a/kernel/sched/pelt.c b/kernel/sched/pelt.c index bbb0de2219f9..2d2c0fa9812d 100644 --- a/kernel/sched/pelt.c +++ b/kernel/sched/pelt.c @@ -531,3 +531,45 @@ int update_irq_load_avg(struct rq *rq, u64 running) return ret; } #endif + +DEFINE_PER_CPU(u64, clock_task_mult); + +unsigned int sysctl_sched_pelt_multiplier = 1; +__read_mostly unsigned int sched_pelt_lshift; + +int sched_pelt_multiplier(struct ctl_table *table, int write, void *buffer, + size_t *lenp, loff_t *ppos) +{ + static DEFINE_MUTEX(mutex); + unsigned int old; + int ret; + + mutex_lock(&mutex); + + old = sysctl_sched_pelt_multiplier; + ret = proc_dointvec(table, write, buffer, lenp, ppos); + if (ret) + goto undo; + if (!write) + goto done; + + switch (sysctl_sched_pelt_multiplier) { + case 1: + fallthrough; + case 2: + fallthrough; + case 4: + WRITE_ONCE(sched_pelt_lshift, + sysctl_sched_pelt_multiplier >> 1); + goto done; + default: + ret = -EINVAL; + } + +undo: + sysctl_sched_pelt_multiplier = old; +done: + mutex_unlock(&mutex); + + return ret; +} diff --git a/kernel/sched/pelt.h b/kernel/sched/pelt.h index 45bf08e22207..3f00596def11 100644 --- a/kernel/sched/pelt.h +++ b/kernel/sched/pelt.h @@ -61,6 +61,8 @@ static inline void cfs_se_util_change(struct sched_avg *avg) WRITE_ONCE(avg->util_est.enqueued, enqueued); } +extern unsigned int sched_pelt_lshift; + /* * The clock_pelt scales the time to reflect the effective amount of * computation done during the running delta time but then sync back to @@ -75,9 +77,13 @@ static inline void cfs_se_util_change(struct sched_avg *avg) */ static inline void update_rq_clock_pelt(struct rq *rq, s64 delta) { + delta <<= READ_ONCE(sched_pelt_lshift); + + per_cpu(clock_task_mult, rq->cpu) += delta; + if (unlikely(is_idle_task(rq->curr))) { /* The rq is idle, we can sync to clock_task */ - rq->clock_pelt = rq_clock_task(rq); + rq->clock_pelt = rq_clock_task_mult(rq); return; } @@ -129,7 +135,8 @@ static inline void update_idle_rq_clock_pelt(struct rq *rq) * rq's clock_task. */ if (util_sum >= divider) - rq->lost_idle_time += rq_clock_task(rq) - rq->clock_pelt; + rq->lost_idle_time += rq_clock_task_mult(rq) - + rq->clock_pelt; } static inline u64 rq_clock_pelt(struct rq *rq) diff --git a/kernel/sched/sched.h b/kernel/sched/sched.h index 518da844fe2a..175d5f3ef58e 100644 --- a/kernel/sched/sched.h +++ b/kernel/sched/sched.h @@ -1193,6 +1193,16 @@ static inline u64 rq_clock_task(struct rq *rq) return rq->clock_task; } +DECLARE_PER_CPU(u64, clock_task_mult); + +static inline u64 rq_clock_task_mult(struct rq *rq) +{ + lockdep_assert_held(&rq->lock); + assert_clock_updated(rq); + + return per_cpu(clock_task_mult, rq->cpu); +} + /** * By default the decay is the default pelt decay period. * The decay shift can change the decay period in diff --git a/kernel/sysctl.c b/kernel/sysctl.c index a4006f6558d1..3632cfbc88b0 100644 --- a/kernel/sysctl.c +++ b/kernel/sysctl.c @@ -1829,6 +1829,15 @@ static struct ctl_table kern_table[] = { .mode = 0644, .proc_handler = sched_rr_handler, }, +#ifdef CONFIG_SMP + { + .procname = "sched_pelt_multiplier", + .data = &sysctl_sched_pelt_multiplier, + .maxlen = sizeof(unsigned int), + .mode = 0644, + .proc_handler = sched_pelt_multiplier, + }, +#endif #ifdef CONFIG_UCLAMP_TASK { .procname = "sched_util_clamp_min", From 14f646cca5c7c6110426ceccc5cf7b0e18b63021 Mon Sep 17 00:00:00 2001 From: Todd Kjos Date: Thu, 28 Jul 2022 14:13:33 -0700 Subject: [PATCH 47/91] ANDROID: fix kernelci issue for allnoconfig builds MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 'allnoconfig' builds failed with: kernel/sched/sched.h:1203:50: error: ‘struct rq’ has no member named ‘cpu’ rq->cpu needs to be replaced with cpu_of(rq) for !CONFIG_SMP builds Fixes: 4442801a43f3 ("ANDROID: sched: Introducing PELT multiplier") Signed-off-by: Todd Kjos Change-Id: Iceb439dc3bba27516b5ecd2c18c9835c23e5a39a --- kernel/sched/sched.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/kernel/sched/sched.h b/kernel/sched/sched.h index 175d5f3ef58e..4b9eff7c8ee9 100644 --- a/kernel/sched/sched.h +++ b/kernel/sched/sched.h @@ -1200,7 +1200,7 @@ static inline u64 rq_clock_task_mult(struct rq *rq) lockdep_assert_held(&rq->lock); assert_clock_updated(rq); - return per_cpu(clock_task_mult, rq->cpu); + return per_cpu(clock_task_mult, cpu_of(rq)); } /** From 573c7f061d100537bf32bdb47fe3ebd45e93aa55 Mon Sep 17 00:00:00 2001 From: Elliot Berman Date: Thu, 28 Jul 2022 09:38:28 -0700 Subject: [PATCH 48/91] ANDROID: Guard hooks with their CONFIG_ options ANDROID_VENDOR_HOOKS has implicit dependencies on the subsystems which it hooks into whenever it directly uses an "internal" header for that system. For instance, drivers/scsi/ufs/ufshcd.h doesn't compile unless CONFIG_SCSI_UFSHCD is enabled: In file included from drivers/android/vendor_hooks.c:41: In file included from include/trace/hooks/ufshcd.h:21: include/../drivers/scsi/ufs/ufshcd.h:675:38: error: field has incomplete type 'struct devfreq_simple_ondemand_data' struct devfreq_simple_ondemand_data ondemand_data; ^ include/../drivers/scsi/ufs/ufshcd.h:675:9: note: forward declaration of 'struct devfreq_simple_ondemand_data' struct devfreq_simple_ondemand_data ondemand_data; To avoid these implicit dependencies, guard any "internal" header includes with the respective CONFIG_ options when applicable. If the CONFIG_ option is not enabled, then the forward-declared structs are used. This is acceptable because those hooks would not have been called anyway since the underlying subsytem wasn't enabled. Fixes: commit 1590a0e8e123 ("ANDROID: GKI: include more type definitions in vendor hooks") Bug: 240404657 Change-Id: I43d19136fdb1b534e80630067f5db92c379adc67 Signed-off-by: Elliot Berman --- include/trace/hooks/binder.h | 11 ++++++++--- include/trace/hooks/block.h | 2 +- include/trace/hooks/logbuf.h | 2 +- include/trace/hooks/mmc_core.h | 10 +++++++--- include/trace/hooks/psi.h | 2 +- include/trace/hooks/typec.h | 3 ++- include/trace/hooks/ufshcd.h | 2 +- 7 files changed, 21 insertions(+), 11 deletions(-) diff --git a/include/trace/hooks/binder.h b/include/trace/hooks/binder.h index 2b9e7e09a13d..5147261de15c 100644 --- a/include/trace/hooks/binder.h +++ b/include/trace/hooks/binder.h @@ -11,19 +11,23 @@ * Following tracepoints are not exported in tracefs and provide a * mechanism for vendor modules to hook and extend functionality */ -#ifdef __GENKSYMS__ +#if defined(__GENKSYMS__) || !IS_ENABLED(CONFIG_ANDROID_BINDER_IPC) struct binder_alloc; struct binder_proc; struct binder_thread; struct binder_transaction; -struct task_struct; -struct seq_file; struct binder_transaction_data; #else /* struct binder_alloc */ #include <../drivers/android/binder_alloc.h> /* struct binder_proc, struct binder_thread, struct binder_transaction */ #include <../drivers/android/binder_internal.h> +#endif + +#ifdef __GENKSYMS__ +struct task_struct; +struct seq_file; +#else /* struct task_struct */ #include /* struct seq_file */ @@ -31,6 +35,7 @@ struct binder_transaction_data; /* struct binder_transaction_data */ #include #endif /* __GENKSYMS__ */ + DECLARE_HOOK(android_vh_binder_transaction_init, TP_PROTO(struct binder_transaction *t), TP_ARGS(t)); diff --git a/include/trace/hooks/block.h b/include/trace/hooks/block.h index 964fff355602..a5a7ac70a2ee 100644 --- a/include/trace/hooks/block.h +++ b/include/trace/hooks/block.h @@ -10,7 +10,7 @@ #include #include -#ifdef __GENKSYMS__ +#if defined(__GENKSYMS__) || !defined(CONFIG_BLOCK) struct blk_mq_tags; struct blk_mq_alloc_data; struct blk_mq_tag_set; diff --git a/include/trace/hooks/logbuf.h b/include/trace/hooks/logbuf.h index 6aeb10a4661b..3794192554cb 100644 --- a/include/trace/hooks/logbuf.h +++ b/include/trace/hooks/logbuf.h @@ -10,7 +10,7 @@ #include #include -#ifdef __GENKSYMS__ +#if defined(__GENKSYMS__) || !IS_ENABLED(CONFIG_PRINTK) struct printk_record; struct printk_ringbuffer; #else diff --git a/include/trace/hooks/mmc_core.h b/include/trace/hooks/mmc_core.h index b4b93b2f4c9e..eb012e9c8147 100644 --- a/include/trace/hooks/mmc_core.h +++ b/include/trace/hooks/mmc_core.h @@ -10,13 +10,17 @@ #include #include -#ifdef __GENKSYMS__ +#if defined(__GENKSYMS__) || !IS_ENABLED(CONFIG_MMC_SDHCI) struct sdhci_host; -struct mmc_card; -struct mmc_host; #else /* struct sdhci_host */ #include <../drivers/mmc/host/sdhci.h> +#endif + +#ifdef __GENKSYMS__ +struct mmc_card; +struct mmc_host; +#else /* struct mmc_card */ #include /* struct mmc_host */ diff --git a/include/trace/hooks/psi.h b/include/trace/hooks/psi.h index 3842118af3c3..3200b639ad3f 100644 --- a/include/trace/hooks/psi.h +++ b/include/trace/hooks/psi.h @@ -12,7 +12,7 @@ #if defined(CONFIG_TRACEPOINTS) && defined(CONFIG_ANDROID_VENDOR_HOOKS) -#ifdef __GENKSYMS__ +#if defined(__GENKSYMS__) || !defined(CONFIG_PSI) struct psi_group; struct psi_trigger; #else diff --git a/include/trace/hooks/typec.h b/include/trace/hooks/typec.h index db06fb8c30e9..825cb37bc8b2 100644 --- a/include/trace/hooks/typec.h +++ b/include/trace/hooks/typec.h @@ -6,12 +6,13 @@ #define _TRACE_HOOK_TYPEC_H #include #include +#include #include /* * Following tracepoints are not exported in tracefs and provide a * mechanism for vendor modules to hook and extend functionality */ -#ifdef __GENKSYMS__ +#if defined(__GENKSYMS__) || !IS_ENABLED(CONFIG_TYPEC_TCPCI) struct tcpci_data; #else /* struct tcpci_data */ diff --git a/include/trace/hooks/ufshcd.h b/include/trace/hooks/ufshcd.h index 8483dc966c6c..906e02740f3f 100644 --- a/include/trace/hooks/ufshcd.h +++ b/include/trace/hooks/ufshcd.h @@ -10,7 +10,7 @@ * Following tracepoints are not exported in tracefs and provide a * mechanism for vendor modules to hook and extend functionality */ -#ifdef __GENKSYMS__ +#if defined(__GENKSYMS__) || !IS_ENABLED(CONFIG_SCSI_UFSHCD) struct ufs_hba; struct ufshcd_lrb; struct uic_command; From 9e8dedef1e892ce9d54d90107faa6a568e5d39ac Mon Sep 17 00:00:00 2001 From: Jing-Ting Wu Date: Tue, 26 Jul 2022 21:04:35 +0800 Subject: [PATCH 49/91] ANDROID: sched: add vendor hook to PELT multiplier We add vendor hook at sched_pelt_multiplier for performance tuning. Bug: 240896506 Change-Id: I10e3436a986dd5dd7d375460922407666f27739d Signed-off-by: Jing-Ting Wu Signed-off-by: JianMin Liu --- drivers/android/vendor_hooks.c | 1 + include/trace/hooks/sched.h | 4 ++++ kernel/sched/pelt.c | 5 +++++ 3 files changed, 10 insertions(+) diff --git a/drivers/android/vendor_hooks.c b/drivers/android/vendor_hooks.c index bb6c7f859b26..345e6dc1b7b3 100644 --- a/drivers/android/vendor_hooks.c +++ b/drivers/android/vendor_hooks.c @@ -435,3 +435,4 @@ EXPORT_TRACEPOINT_SYMBOL_GPL(android_vh_free_pages); EXPORT_TRACEPOINT_SYMBOL_GPL(android_vh_set_shmem_page_flag); EXPORT_TRACEPOINT_SYMBOL_GPL(android_vh_pidfd_open); EXPORT_TRACEPOINT_SYMBOL_GPL(android_vh_mmput); +EXPORT_TRACEPOINT_SYMBOL_GPL(android_vh_sched_pelt_multiplier); diff --git a/include/trace/hooks/sched.h b/include/trace/hooks/sched.h index 551cab4d1649..d0fc31e2c966 100644 --- a/include/trace/hooks/sched.h +++ b/include/trace/hooks/sched.h @@ -398,6 +398,10 @@ DECLARE_HOOK(android_vh_pidfd_open, DECLARE_HOOK(android_vh_mmput, TP_PROTO(void *unused), TP_ARGS(unused)); + +DECLARE_HOOK(android_vh_sched_pelt_multiplier, + TP_PROTO(unsigned int old, unsigned int cur, int *ret), + TP_ARGS(old, cur, ret)); /* macro versions of hooks are no longer required */ #endif /* _TRACE_HOOK_SCHED_H */ diff --git a/kernel/sched/pelt.c b/kernel/sched/pelt.c index 2d2c0fa9812d..15a237ab2d0c 100644 --- a/kernel/sched/pelt.c +++ b/kernel/sched/pelt.c @@ -532,6 +532,7 @@ int update_irq_load_avg(struct rq *rq, u64 running) } #endif +#include DEFINE_PER_CPU(u64, clock_task_mult); unsigned int sysctl_sched_pelt_multiplier = 1; @@ -553,6 +554,10 @@ int sched_pelt_multiplier(struct ctl_table *table, int write, void *buffer, if (!write) goto done; + trace_android_vh_sched_pelt_multiplier(old, sysctl_sched_pelt_multiplier, &ret); + if (ret) + goto undo; + switch (sysctl_sched_pelt_multiplier) { case 1: fallthrough; From 039080d064d9a7ed1b483d0334d9abe70b25ff65 Mon Sep 17 00:00:00 2001 From: JianMin Liu Date: Mon, 1 Aug 2022 13:42:57 +0800 Subject: [PATCH 50/91] ANDROID: Update symbol list of mediatek Leaf changes summary: 3 artifacts changed Changed leaf types summary: 0 leaf type changed Removed/Changed/Added functions summary: 0 Removed, 0 Changed, 2 Added functions Removed/Changed/Added variables summary: 0 Removed, 0 Changed, 1 Added variable 2 Added functions: [A] 'function int __traceiter_android_vh_sched_pelt_multiplier(void*, unsigned int, unsigned int, int*)' [A] 'function int get_pelt_halflife()' 1 Added variable: [A] 'tracepoint __tracepoint_android_vh_sched_pelt_multiplier' Bug: 240896506 Change-Id: Ied73dce8528005b8e71d639a6ba879d4ac123449 Signed-off-by: JianMin Liu --- android/abi_gki_aarch64.xml | 391 ++++++++++++++++++++---------------- android/abi_gki_aarch64_mtk | 3 + 2 files changed, 225 insertions(+), 169 deletions(-) diff --git a/android/abi_gki_aarch64.xml b/android/abi_gki_aarch64.xml index 2b40dd55ce80..9d9c8c004b21 100644 --- a/android/abi_gki_aarch64.xml +++ b/android/abi_gki_aarch64.xml @@ -531,6 +531,7 @@ + @@ -2631,6 +2632,7 @@ + @@ -6338,6 +6340,7 @@ + @@ -8296,7 +8299,7 @@ - + @@ -9710,21 +9713,21 @@ - + - + - + - + - + - + @@ -14880,15 +14883,15 @@ - + - + - + - + @@ -30568,18 +30571,18 @@ - + - + - + - + - + @@ -43860,7 +43863,23 @@ - + + + + + + + + + + + + + + + + + @@ -48150,6 +48169,7 @@ + @@ -50424,18 +50444,18 @@ - + - + - + - + - + @@ -50838,12 +50858,12 @@ - + - + - + @@ -52665,81 +52685,81 @@ - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + @@ -53029,6 +53049,13 @@ + + + + + + + @@ -56590,18 +56617,18 @@ - + - + - + - + - + @@ -60555,12 +60582,12 @@ - + - + - + @@ -60735,7 +60762,7 @@ - + @@ -62375,24 +62402,24 @@ - + - + - + - + - + - + - + @@ -65589,6 +65616,13 @@ + + + + + + + @@ -73565,54 +73599,54 @@ - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + @@ -82433,54 +82467,54 @@ - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + @@ -82765,12 +82799,12 @@ - + - + - + @@ -90060,6 +90094,7 @@ + @@ -100054,12 +100089,12 @@ - + - + - + @@ -101691,6 +101726,12 @@ + + + + + + @@ -105709,30 +105750,30 @@ - + - + - + - + - + - + - + - + - + @@ -106555,66 +106596,66 @@ - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + @@ -109876,6 +109917,7 @@ + @@ -112413,99 +112455,99 @@ - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + @@ -118133,6 +118175,13 @@ + + + + + + + @@ -119170,6 +119219,7 @@ + @@ -129784,6 +129834,9 @@ + + + diff --git a/android/abi_gki_aarch64_mtk b/android/abi_gki_aarch64_mtk index 807be584e15b..9d74cbdb2d92 100644 --- a/android/abi_gki_aarch64_mtk +++ b/android/abi_gki_aarch64_mtk @@ -835,6 +835,7 @@ get_kernel_pages get_net_ns_by_fd get_net_ns_by_pid + get_pelt_halflife get_pid_task get_random_bytes get_random_u32 @@ -2153,6 +2154,7 @@ __traceiter_android_vh_rwsem_init __traceiter_android_vh_rwsem_wake __traceiter_android_vh_rwsem_write_finished + __traceiter_android_vh_sched_pelt_multiplier __traceiter_android_vh_scheduler_tick __traceiter_android_vh_selinux_avc_insert __traceiter_android_vh_selinux_avc_lookup @@ -2237,6 +2239,7 @@ __tracepoint_android_vh_rwsem_init __tracepoint_android_vh_rwsem_wake __tracepoint_android_vh_rwsem_write_finished + __tracepoint_android_vh_sched_pelt_multiplier __tracepoint_android_vh_scheduler_tick __tracepoint_android_vh_selinux_avc_insert __tracepoint_android_vh_selinux_avc_lookup From c9a70dd5923ea075c8401455afa7cca79118282b Mon Sep 17 00:00:00 2001 From: Suren Baghdasaryan Date: Wed, 27 Jul 2022 01:05:51 -0700 Subject: [PATCH 51/91] ANDROID: GKI: allow mm vendor hooks header inclusion from header files Introduce PROTECT_TRACE_INCLUDE_PATH to allow trace/hooks/mm.h to be included from a header file. When trace/hooks/mm.h is included from a header file PROTECT_TRACE_INCLUDE_PATH should be defined before the inclusion so that the existing TRACE_INCLUDE_PATH gets preserved. Bug: 236578020 Signed-off-by: Suren Baghdasaryan Change-Id: Ia5890ba51675de41ff3ea4ab38bcb458202df5fb --- include/trace/hooks/mm.h | 11 +++++++++ include/trace/hooks/restore_incpath.h | 32 +++++++++++++++++++++++++++ include/trace/hooks/save_incpath.h | 29 ++++++++++++++++++++++++ 3 files changed, 72 insertions(+) create mode 100644 include/trace/hooks/restore_incpath.h create mode 100644 include/trace/hooks/save_incpath.h diff --git a/include/trace/hooks/mm.h b/include/trace/hooks/mm.h index ae6e379fb487..742862fc5134 100644 --- a/include/trace/hooks/mm.h +++ b/include/trace/hooks/mm.h @@ -1,4 +1,13 @@ /* SPDX-License-Identifier: GPL-2.0 */ +#ifdef PROTECT_TRACE_INCLUDE_PATH +#undef PROTECT_TRACE_INCLUDE_PATH + +#include +#include +#include + +#else /* PROTECT_TRACE_INCLUDE_PATH */ + #undef TRACE_SYSTEM #define TRACE_SYSTEM mm @@ -230,3 +239,5 @@ DECLARE_HOOK(android_vh_set_shmem_page_flag, /* This part must be outside protection */ #include + +#endif /* PROTECT_TRACE_INCLUDE_PATH */ diff --git a/include/trace/hooks/restore_incpath.h b/include/trace/hooks/restore_incpath.h new file mode 100644 index 000000000000..3a97e4572007 --- /dev/null +++ b/include/trace/hooks/restore_incpath.h @@ -0,0 +1,32 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * Include this file from a header declaring vendor hooks to preserve and later + * restore TRACE_INCLUDE_PATH value. Typical usage: + * + * #ifdef PROTECT_TRACE_INCLUDE_PATH + * #undef PROTECT_TRACE_INCLUDE_PATH + * + * #include + * #include + * #include + * + * #else + * + * + * + * #endif + * + * The header that includes vendor hooks header file should define + * PROTECT_TRACE_INCLUDE_PATH before including the vendor hook file like this: + * + * #define PROTECT_TRACE_INCLUDE_PATH + * #include + */ +#ifdef STORED_TRACE_INCLUDE_PATH +# undef TRACE_INCLUDE_PATH +# define TRACE_INCLUDE_PATH STORED_TRACE_INCLUDE_PATH +# undef STORED_TRACE_INCLUDE_PATH +#else +# undef TRACE_INCLUDE_PATH +#endif + diff --git a/include/trace/hooks/save_incpath.h b/include/trace/hooks/save_incpath.h new file mode 100644 index 000000000000..3b4621a47275 --- /dev/null +++ b/include/trace/hooks/save_incpath.h @@ -0,0 +1,29 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * Include this file from a header declaring vendor hooks to preserve and later + * restore TRACE_INCLUDE_PATH value. Typical usage: + * + * #ifdef PROTECT_TRACE_INCLUDE_PATH + * #undef PROTECT_TRACE_INCLUDE_PATH + * + * #include + * #include + * #include + * + * #else + * + * + * + * #endif + * + * The header that includes vendor hooks header file should define + * PROTECT_TRACE_INCLUDE_PATH before including the vendor hook file like this: + * + * #define PROTECT_TRACE_INCLUDE_PATH + * #include + */ +#ifdef TRACE_INCLUDE_PATH +#define STORED_TRACE_INCLUDE_PATH TRACE_INCLUDE_PATH +#undef TRACE_INCLUDE_PATH +#endif + From 6532784c7853261bc8554997863d7f51d657c5a1 Mon Sep 17 00:00:00 2001 From: Peifeng Li Date: Mon, 1 Aug 2022 11:02:51 +0800 Subject: [PATCH 52/91] ANDROID: vendor_hooks: add hooks for remove_vm_area. Provide a vendor hook to remove additional fields when remove_vm_area for slab/vmalloc memory leak debugging. Bug: 240869642 Signed-off-by: Peifeng Li Change-Id: Iafecd7c6e75cdc2df0e77ae105283590d8852f74 --- drivers/android/vendor_hooks.c | 1 + include/trace/hooks/mm.h | 3 +++ mm/vmalloc.c | 1 + 3 files changed, 5 insertions(+) diff --git a/drivers/android/vendor_hooks.c b/drivers/android/vendor_hooks.c index 345e6dc1b7b3..8c0bbcde78ae 100644 --- a/drivers/android/vendor_hooks.c +++ b/drivers/android/vendor_hooks.c @@ -338,6 +338,7 @@ EXPORT_TRACEPOINT_SYMBOL_GPL(android_vh_mmc_attach_sd); EXPORT_TRACEPOINT_SYMBOL_GPL(android_vh_sdhci_get_cd); EXPORT_TRACEPOINT_SYMBOL_GPL(android_vh_mmc_gpio_cd_irqt); EXPORT_TRACEPOINT_SYMBOL_GPL(android_vh_save_vmalloc_stack); +EXPORT_TRACEPOINT_SYMBOL_GPL(android_vh_remove_vmalloc_stack); EXPORT_TRACEPOINT_SYMBOL_GPL(android_vh_show_stack_hash); EXPORT_TRACEPOINT_SYMBOL_GPL(android_vh_save_track_hash); EXPORT_TRACEPOINT_SYMBOL_GPL(android_vh_vmpressure); diff --git a/include/trace/hooks/mm.h b/include/trace/hooks/mm.h index 742862fc5134..6d25e458edb3 100644 --- a/include/trace/hooks/mm.h +++ b/include/trace/hooks/mm.h @@ -233,6 +233,9 @@ DECLARE_HOOK(android_vh_free_pages, DECLARE_HOOK(android_vh_set_shmem_page_flag, TP_PROTO(struct page *page), TP_ARGS(page)); +DECLARE_HOOK(android_vh_remove_vmalloc_stack, + TP_PROTO(struct vm_struct *vm), + TP_ARGS(vm)); /* macro versions of hooks are no longer required */ #endif /* _TRACE_HOOK_MM_H */ diff --git a/mm/vmalloc.c b/mm/vmalloc.c index d5615977e7f3..817a472ee30f 100644 --- a/mm/vmalloc.c +++ b/mm/vmalloc.c @@ -2170,6 +2170,7 @@ struct vm_struct *remove_vm_area(const void *addr) if (va && va->vm) { struct vm_struct *vm = va->vm; + trace_android_vh_remove_vmalloc_stack(vm); va->vm = NULL; spin_unlock(&vmap_area_lock); From 12f43224422a8df0f510f423ac6c9743c38d7a94 Mon Sep 17 00:00:00 2001 From: Elliot Berman Date: Mon, 1 Aug 2022 17:24:03 -0700 Subject: [PATCH 53/91] ANDROID: vendor_hooks: Guard cgroup struct with CONFIG_CGROUPS See commit 573c7f061d10 ("ANDROID: Guard hooks with their CONFIG_ options"). Needed to do CGROUPS as well due to cgroup_subsys definition being guarded by CONFIG_CGROUPS in include/linux/cgroup-defs.h. Bug: 240404657 Change-Id: Ie51f053a9e82ef8d7d1c149374ac02608717429d Signed-off-by: Elliot Berman --- include/trace/hooks/cgroup.h | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/include/trace/hooks/cgroup.h b/include/trace/hooks/cgroup.h index 68818ad29600..dfe79e5a3646 100644 --- a/include/trace/hooks/cgroup.h +++ b/include/trace/hooks/cgroup.h @@ -9,12 +9,16 @@ #include struct cgroup_taskset; -#ifdef __GENKSYMS__ +#if defined(__GENKSYMS__) || !IS_ENABLED(CONFIG_CGROUPS) struct cgroup_subsys; -struct task_struct; #else /* struct cgroup_subsys */ #include +#endif + +#ifdef __GENKSYMS__ +struct task_struct; +#else /* struct task_struct */ #include #endif /* __GENKSYMS__ */ From e0c9da25b2ba7dbb53c81890a851993575da97a1 Mon Sep 17 00:00:00 2001 From: Carlos Llamas Date: Mon, 1 Aug 2022 18:25:11 +0000 Subject: [PATCH 54/91] FROMLIST: binder: fix UAF of ref->proc caused by race condition A transaction of type BINDER_TYPE_WEAK_HANDLE can fail to increment the reference for a node. In this case, the target proc normally releases the failed reference upon close as expected. However, if the target is dying in parallel the call will race with binder_deferred_release(), so the target could have released all of its references by now leaving the cleanup of the new failed reference unhandled. The transaction then ends and the target proc gets released making the ref->proc now a dangling pointer. Later on, ref->node is closed and we attempt to take spin_lock(&ref->proc->inner_lock), which leads to the use-after-free bug reported below. Let's fix this by cleaning up the failed reference on the spot instead of relying on the target to do so. ================================================================== BUG: KASAN: use-after-free in _raw_spin_lock+0xa8/0x150 Write of size 4 at addr ffff5ca207094238 by task kworker/1:0/590 CPU: 1 PID: 590 Comm: kworker/1:0 Not tainted 5.19.0-rc8 #10 Hardware name: linux,dummy-virt (DT) Workqueue: events binder_deferred_func Call trace: dump_backtrace.part.0+0x1d0/0x1e0 show_stack+0x18/0x70 dump_stack_lvl+0x68/0x84 print_report+0x2e4/0x61c kasan_report+0xa4/0x110 kasan_check_range+0xfc/0x1a4 __kasan_check_write+0x3c/0x50 _raw_spin_lock+0xa8/0x150 binder_deferred_func+0x5e0/0x9b0 process_one_work+0x38c/0x5f0 worker_thread+0x9c/0x694 kthread+0x188/0x190 ret_from_fork+0x10/0x20 Signed-off-by: Carlos Llamas Acked-by: Christian Brauner (Microsoft) Bug: 239630375 Link: https://lore.kernel.org/all/20220801182511.3371447-1-cmllamas@google.com/ Signed-off-by: Carlos Llamas Change-Id: I5085dd0dc805a780a64c057e5819f82dd8f02868 (cherry picked from commit ae3fa5d16a02ba7c7b170e0e1ab56d6f0ba33964) --- drivers/android/binder.c | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/drivers/android/binder.c b/drivers/android/binder.c index 75cd8b927ad4..ba7d6a96514f 100644 --- a/drivers/android/binder.c +++ b/drivers/android/binder.c @@ -1504,6 +1504,18 @@ static int binder_inc_ref_for_node(struct binder_proc *proc, } ret = binder_inc_ref_olocked(ref, strong, target_list); *rdata = ref->data; + if (ret && ref == new_ref) { + /* + * Cleanup the failed reference here as the target + * could now be dead and have already released its + * references by now. Calling on the new reference + * with strong=0 and a tmp_refs will not decrement + * the node. The new_ref gets kfree'd below. + */ + binder_cleanup_ref_olocked(new_ref); + ref = NULL; + } + binder_proc_unlock(proc); if (new_ref && ref != new_ref) /* From 1d2287f56e988995e25e4fd40304a8664474a750 Mon Sep 17 00:00:00 2001 From: Lee Jones Date: Tue, 19 Jul 2022 12:52:51 +0100 Subject: [PATCH 55/91] FROMGIT: io_uring: Use original task for req identity in io_identity_cow() This issue is conceptually identical to the one fixed in 29f077d07051 ("io_uring: always use original task when preparing req identity"), so rather than reinvent the wheel, I'm shamelessly quoting the commit message from that patch - thanks Jens: "If the ring is setup with IORING_SETUP_IOPOLL and we have more than one task doing submissions on a ring, we can up in a situation where we assign the context from the current task rather than the request originator. Always use req->task rather than assume it's the same as current. No upstream patch exists for this issue, as only older kernels with the non-native workers have this problem." Bug: 238177383 Cc: Jens Axboe Cc: Pavel Begunkov Cc: Alexander Viro Cc: io-uring@vger.kernel.org Cc: linux-fsdevel@vger.kernel.org Fixes: 5c3462cfd123b ("io_uring: store io_identity in io_uring_task") Signed-off-by: Lee Jones Signed-off-by: Greg Kroah-Hartman (cherry picked from commit 2ee0cab11f6626071f8a64c7792406dabdd94c8d git: //git.kernel.org/pub/scm/linux/kernel/git/stable/linux-stable.git linux-5.10.y) Signed-off-by: Lee Jones Change-Id: I98adc653dbe03f8e9d214d9430fe50d351a45910 --- fs/io_uring.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/fs/io_uring.c b/fs/io_uring.c index 4330603eae35..d63d8713a197 100644 --- a/fs/io_uring.c +++ b/fs/io_uring.c @@ -1318,7 +1318,7 @@ static void io_req_clean_work(struct io_kiocb *req) */ static bool io_identity_cow(struct io_kiocb *req) { - struct io_uring_task *tctx = current->io_uring; + struct io_uring_task *tctx = req->task->io_uring; const struct cred *creds = NULL; struct io_identity *id; From 3f775b9367045cabb51247fbbcb561b24841dcb7 Mon Sep 17 00:00:00 2001 From: Peifeng Li Date: Thu, 23 Jun 2022 14:15:35 +0800 Subject: [PATCH 56/91] ANDROID: vendor_hooks: account page-mapcount Support five hooks as follows to account the amount of multi-mapped pages in kernel: - android_vh_show_mapcount_pages - android_vh_do_traversal_lruvec - android_vh_update_page_mapcount - android_vh_add_page_to_lrulist - android_vh_del_page_from_lrulist Bug: 236578020 Signed-off-by: Peifeng Li Change-Id: Ia2c7015aab442be7dbb496b8b630b9dff59ab935 --- drivers/android/vendor_hooks.c | 5 ++ include/linux/mm_inline.h | 7 +++ include/linux/rmap.h | 11 ++++- include/trace/hooks/mm.h | 16 +++++++ mm/huge_memory.c | 27 ++++++++--- mm/page_alloc.c | 1 + mm/rmap.c | 83 ++++++++++++++++++++++++++++------ mm/vmscan.c | 2 + 8 files changed, 129 insertions(+), 23 deletions(-) diff --git a/drivers/android/vendor_hooks.c b/drivers/android/vendor_hooks.c index 8c0bbcde78ae..ae0a674fe6f7 100644 --- a/drivers/android/vendor_hooks.c +++ b/drivers/android/vendor_hooks.c @@ -274,6 +274,8 @@ EXPORT_TRACEPOINT_SYMBOL_GPL(android_vh_include_reserved_zone); EXPORT_TRACEPOINT_SYMBOL_GPL(android_vh_alloc_pages_slowpath_begin); EXPORT_TRACEPOINT_SYMBOL_GPL(android_vh_alloc_pages_slowpath_end); EXPORT_TRACEPOINT_SYMBOL_GPL(android_vh_show_mem); +EXPORT_TRACEPOINT_SYMBOL_GPL(android_vh_show_mapcount_pages); +EXPORT_TRACEPOINT_SYMBOL_GPL(android_vh_do_traversal_lruvec); EXPORT_TRACEPOINT_SYMBOL_GPL(android_vh_typec_tcpci_override_toggling); EXPORT_TRACEPOINT_SYMBOL_GPL(android_rvh_typec_tcpci_chk_contaminant); EXPORT_TRACEPOINT_SYMBOL_GPL(android_rvh_typec_tcpci_get_vbus); @@ -393,6 +395,9 @@ EXPORT_TRACEPOINT_SYMBOL_GPL(android_rvh_tcp_recvmsg_stat); EXPORT_TRACEPOINT_SYMBOL_GPL(android_rvh_pci_d3_sleep); EXPORT_TRACEPOINT_SYMBOL_GPL(android_vh_kmalloc_slab); EXPORT_TRACEPOINT_SYMBOL_GPL(android_vh_mmap_region); +EXPORT_TRACEPOINT_SYMBOL_GPL(android_vh_update_page_mapcount); +EXPORT_TRACEPOINT_SYMBOL_GPL(android_vh_add_page_to_lrulist); +EXPORT_TRACEPOINT_SYMBOL_GPL(android_vh_del_page_from_lrulist); EXPORT_TRACEPOINT_SYMBOL_GPL(android_vh_try_to_unmap_one); EXPORT_TRACEPOINT_SYMBOL_GPL(android_vh_mem_cgroup_id_remove); EXPORT_TRACEPOINT_SYMBOL_GPL(android_vh_mem_cgroup_css_offline); diff --git a/include/linux/mm_inline.h b/include/linux/mm_inline.h index 8fc71e9d7bb0..835e4f83e7a4 100644 --- a/include/linux/mm_inline.h +++ b/include/linux/mm_inline.h @@ -4,6 +4,10 @@ #include #include +#ifndef __GENKSYMS__ +#define PROTECT_TRACE_INCLUDE_PATH +#include +#endif /** * page_is_file_lru - should the page be on a file LRU or anon LRU? @@ -48,6 +52,7 @@ static __always_inline void update_lru_size(struct lruvec *lruvec, static __always_inline void add_page_to_lru_list(struct page *page, struct lruvec *lruvec, enum lru_list lru) { + trace_android_vh_add_page_to_lrulist(page, false, lru); update_lru_size(lruvec, lru, page_zonenum(page), thp_nr_pages(page)); list_add(&page->lru, &lruvec->lists[lru]); } @@ -55,6 +60,7 @@ static __always_inline void add_page_to_lru_list(struct page *page, static __always_inline void add_page_to_lru_list_tail(struct page *page, struct lruvec *lruvec, enum lru_list lru) { + trace_android_vh_add_page_to_lrulist(page, false, lru); update_lru_size(lruvec, lru, page_zonenum(page), thp_nr_pages(page)); list_add_tail(&page->lru, &lruvec->lists[lru]); } @@ -62,6 +68,7 @@ static __always_inline void add_page_to_lru_list_tail(struct page *page, static __always_inline void del_page_from_lru_list(struct page *page, struct lruvec *lruvec, enum lru_list lru) { + trace_android_vh_del_page_from_lrulist(page, false, lru); list_del(&page->lru); update_lru_size(lruvec, lru, page_zonenum(page), -thp_nr_pages(page)); } diff --git a/include/linux/rmap.h b/include/linux/rmap.h index 7482da1ea67b..7dee138fbf0f 100644 --- a/include/linux/rmap.h +++ b/include/linux/rmap.h @@ -11,6 +11,10 @@ #include #include #include +#ifndef __GENKSYMS__ +#define PROTECT_TRACE_INCLUDE_PATH +#include +#endif /* * The anon_vma heads a list of private "related" vmas, to scan if @@ -194,7 +198,12 @@ void hugepage_add_new_anon_rmap(struct page *, struct vm_area_struct *, static inline void page_dup_rmap(struct page *page, bool compound) { - atomic_inc(compound ? compound_mapcount_ptr(page) : &page->_mapcount); + bool success = false; + + if (!compound) + trace_android_vh_update_page_mapcount(page, true, compound, NULL, &success); + if (!success) + atomic_inc(compound ? compound_mapcount_ptr(page) : &page->_mapcount); } /* diff --git a/include/trace/hooks/mm.h b/include/trace/hooks/mm.h index 6d25e458edb3..68d792378b50 100644 --- a/include/trace/hooks/mm.h +++ b/include/trace/hooks/mm.h @@ -153,6 +153,22 @@ DECLARE_HOOK(android_vh_drain_all_pages_bypass, int migratetype, unsigned long did_some_progress, bool *bypass), TP_ARGS(gfp_mask, order, alloc_flags, migratetype, did_some_progress, bypass)); +DECLARE_HOOK(android_vh_update_page_mapcount, + TP_PROTO(struct page *page, bool inc_size, bool compound, + bool *first_mapping, bool *success), + TP_ARGS(page, inc_size, compound, first_mapping, success)); +DECLARE_HOOK(android_vh_add_page_to_lrulist, + TP_PROTO(struct page *page, bool compound, enum lru_list lru), + TP_ARGS(page, compound, lru)); +DECLARE_HOOK(android_vh_del_page_from_lrulist, + TP_PROTO(struct page *page, bool compound, enum lru_list lru), + TP_ARGS(page, compound, lru)); +DECLARE_HOOK(android_vh_show_mapcount_pages, + TP_PROTO(void *unused), + TP_ARGS(unused)); +DECLARE_HOOK(android_vh_do_traversal_lruvec, + TP_PROTO(struct lruvec *lruvec), + TP_ARGS(lruvec)); DECLARE_HOOK(android_vh_cma_drain_all_pages_bypass, TP_PROTO(unsigned int migratetype, bool *bypass), TP_ARGS(migratetype, bypass)); diff --git a/mm/huge_memory.c b/mm/huge_memory.c index 1eea5787fd63..c24716571a93 100644 --- a/mm/huge_memory.c +++ b/mm/huge_memory.c @@ -33,7 +33,7 @@ #include #include #include - +#include #include #include #include "internal.h" @@ -2033,6 +2033,7 @@ static void __split_huge_pmd_locked(struct vm_area_struct *vma, pmd_t *pmd, bool young, write, soft_dirty, pmd_migration = false, uffd_wp = false; unsigned long addr; int i; + bool success = false; VM_BUG_ON(haddr & ~HPAGE_PMD_MASK); VM_BUG_ON_VMA(vma->vm_start > haddr, vma); @@ -2164,8 +2165,12 @@ static void __split_huge_pmd_locked(struct vm_area_struct *vma, pmd_t *pmd, pte = pte_offset_map(&_pmd, addr); BUG_ON(!pte_none(*pte)); set_pte_at(mm, addr, pte, entry); - if (!pmd_migration) - atomic_inc(&page[i]._mapcount); + if (!pmd_migration) { + trace_android_vh_update_page_mapcount(&page[i], true, + false, NULL, &success); + if (!success) + atomic_inc(&page[i]._mapcount); + } pte_unmap(pte); } @@ -2176,8 +2181,12 @@ static void __split_huge_pmd_locked(struct vm_area_struct *vma, pmd_t *pmd, */ if (compound_mapcount(page) > 1 && !TestSetPageDoubleMap(page)) { - for (i = 0; i < HPAGE_PMD_NR; i++) - atomic_inc(&page[i]._mapcount); + for (i = 0; i < HPAGE_PMD_NR; i++) { + trace_android_vh_update_page_mapcount(&page[i], true, + false, NULL, &success); + if (!success) + atomic_inc(&page[i]._mapcount); + } } lock_page_memcg(page); @@ -2186,8 +2195,12 @@ static void __split_huge_pmd_locked(struct vm_area_struct *vma, pmd_t *pmd, __dec_lruvec_page_state(page, NR_ANON_THPS); if (TestClearPageDoubleMap(page)) { /* No need in mapcount reference anymore */ - for (i = 0; i < HPAGE_PMD_NR; i++) - atomic_dec(&page[i]._mapcount); + for (i = 0; i < HPAGE_PMD_NR; i++) { + trace_android_vh_update_page_mapcount(&page[i], + false, false, NULL, &success); + if (!success) + atomic_dec(&page[i]._mapcount); + } } } unlock_page_memcg(page); diff --git a/mm/page_alloc.c b/mm/page_alloc.c index 1a5d222a7d6a..d2b7eca3a2bf 100644 --- a/mm/page_alloc.c +++ b/mm/page_alloc.c @@ -5646,6 +5646,7 @@ void show_free_areas(unsigned int filter, nodemask_t *nodemask) free_pcp, global_zone_page_state(NR_FREE_CMA_PAGES)); + trace_android_vh_show_mapcount_pages(NULL); for_each_online_pgdat(pgdat) { if (show_mem_node_skip(filter, pgdat->node_id, nodemask)) continue; diff --git a/mm/rmap.c b/mm/rmap.c index e526fbc7826e..ea1fd71b03df 100644 --- a/mm/rmap.c +++ b/mm/rmap.c @@ -1113,6 +1113,7 @@ void do_page_add_anon_rmap(struct page *page, { bool compound = flags & RMAP_COMPOUND; bool first; + bool success = false; if (unlikely(PageKsm(page))) lock_page_memcg(page); @@ -1126,7 +1127,10 @@ void do_page_add_anon_rmap(struct page *page, mapcount = compound_mapcount_ptr(page); first = atomic_inc_and_test(mapcount); } else { - first = atomic_inc_and_test(&page->_mapcount); + trace_android_vh_update_page_mapcount(page, true, compound, + &first, &success); + if (!success) + first = atomic_inc_and_test(&page->_mapcount); } if (first) { @@ -1200,13 +1204,22 @@ void __page_add_new_anon_rmap(struct page *page, void page_add_file_rmap(struct page *page, bool compound) { int i, nr = 1; + bool first_mapping; + bool success = false; VM_BUG_ON_PAGE(compound && !PageTransHuge(page), page); lock_page_memcg(page); if (compound && PageTransHuge(page)) { for (i = 0, nr = 0; i < thp_nr_pages(page); i++) { - if (atomic_inc_and_test(&page[i]._mapcount)) - nr++; + trace_android_vh_update_page_mapcount(&page[i], true, + compound, &first_mapping, &success); + if ((success)) { + if (first_mapping) + nr++; + } else { + if (atomic_inc_and_test(&page[i]._mapcount)) + nr++; + } } if (!atomic_inc_and_test(compound_mapcount_ptr(page))) goto out; @@ -1222,8 +1235,15 @@ void page_add_file_rmap(struct page *page, bool compound) if (PageMlocked(page)) clear_page_mlock(compound_head(page)); } - if (!atomic_inc_and_test(&page->_mapcount)) - goto out; + trace_android_vh_update_page_mapcount(page, true, + compound, &first_mapping, &success); + if (success) { + if (!first_mapping) + goto out; + } else { + if (!atomic_inc_and_test(&page->_mapcount)) + goto out; + } } __mod_lruvec_page_state(page, NR_FILE_MAPPED, nr); out: @@ -1233,6 +1253,8 @@ out: static void page_remove_file_rmap(struct page *page, bool compound) { int i, nr = 1; + bool first_mapping; + bool success = false; VM_BUG_ON_PAGE(compound && !PageHead(page), page); @@ -1246,8 +1268,15 @@ static void page_remove_file_rmap(struct page *page, bool compound) /* page still mapped by someone else? */ if (compound && PageTransHuge(page)) { for (i = 0, nr = 0; i < thp_nr_pages(page); i++) { - if (atomic_add_negative(-1, &page[i]._mapcount)) - nr++; + trace_android_vh_update_page_mapcount(&page[i], false, + compound, &first_mapping, &success); + if (success) { + if (first_mapping) + nr++; + } else { + if (atomic_add_negative(-1, &page[i]._mapcount)) + nr++; + } } if (!atomic_add_negative(-1, compound_mapcount_ptr(page))) return; @@ -1256,8 +1285,15 @@ static void page_remove_file_rmap(struct page *page, bool compound) else __dec_node_page_state(page, NR_FILE_PMDMAPPED); } else { - if (!atomic_add_negative(-1, &page->_mapcount)) - return; + trace_android_vh_update_page_mapcount(page, false, + compound, &first_mapping, &success); + if (success) { + if (!first_mapping) + return; + } else { + if (!atomic_add_negative(-1, &page->_mapcount)) + return; + } } /* @@ -1274,6 +1310,8 @@ static void page_remove_file_rmap(struct page *page, bool compound) static void page_remove_anon_compound_rmap(struct page *page) { int i, nr; + bool first_mapping; + bool success = false; if (!atomic_add_negative(-1, compound_mapcount_ptr(page))) return; @@ -1293,8 +1331,15 @@ static void page_remove_anon_compound_rmap(struct page *page) * them are still mapped. */ for (i = 0, nr = 0; i < thp_nr_pages(page); i++) { - if (atomic_add_negative(-1, &page[i]._mapcount)) - nr++; + trace_android_vh_update_page_mapcount(&page[i], false, + false, &first_mapping, &success); + if (success) { + if (first_mapping) + nr++; + } else { + if (atomic_add_negative(-1, &page[i]._mapcount)) + nr++; + } } /* @@ -1324,6 +1369,8 @@ static void page_remove_anon_compound_rmap(struct page *page) */ void page_remove_rmap(struct page *page, bool compound) { + bool first_mapping; + bool success = false; lock_page_memcg(page); if (!PageAnon(page)) { @@ -1336,10 +1383,16 @@ void page_remove_rmap(struct page *page, bool compound) goto out; } - /* page still mapped by someone else? */ - if (!atomic_add_negative(-1, &page->_mapcount)) - goto out; - + trace_android_vh_update_page_mapcount(page, false, + compound, &first_mapping, &success); + if (success) { + if (!first_mapping) + goto out; + } else { + /* page still mapped by someone else? */ + if (!atomic_add_negative(-1, &page->_mapcount)) + goto out; + } /* * We use the irq-unsafe __{inc|mod}_zone_page_stat because * these counters are not modified in interrupt context, and diff --git a/mm/vmscan.c b/mm/vmscan.c index e9789e8e7a6a..fef55a9ed60f 100644 --- a/mm/vmscan.c +++ b/mm/vmscan.c @@ -1727,6 +1727,7 @@ static unsigned long isolate_lru_pages(unsigned long nr_to_scan, case 0: nr_taken += nr_pages; nr_zone_taken[page_zonenum(page)] += nr_pages; + trace_android_vh_del_page_from_lrulist(page, false, lru); list_move(&page->lru, dst); break; @@ -1901,6 +1902,7 @@ static unsigned noinline_for_stack move_pages_to_lru(struct lruvec *lruvec, nr_pages = thp_nr_pages(page); update_lru_size(lruvec, lru, page_zonenum(page), nr_pages); list_move(&page->lru, &lruvec->lists[lru]); + trace_android_vh_add_page_to_lrulist(page, false, lru); if (put_page_testzero(page)) { __ClearPageLRU(page); From e56f8712cffc38406771a6a0c658ed4227559265 Mon Sep 17 00:00:00 2001 From: Peifeng Li Date: Thu, 23 Jun 2022 15:15:46 +0800 Subject: [PATCH 57/91] ANDROID: vendor_hooks: protect multi-mapcount pages in kernel Support two hooks as follows to protect multi-mapcount pages in kernel: - trace_android_vh_page_should_be_protect - trace_android_vh_mapped_page_try_sorthead Bug: 236578020 Signed-off-by: Peifeng Li Change-Id: I688aceabf17d9de2feac7c3ad7144d307de6ef29 --- drivers/android/vendor_hooks.c | 2 ++ include/trace/hooks/mm.h | 6 ++++++ mm/swap.c | 1 + mm/vmscan.c | 13 +++++++++++++ 4 files changed, 22 insertions(+) diff --git a/drivers/android/vendor_hooks.c b/drivers/android/vendor_hooks.c index ae0a674fe6f7..d7fab5cb876d 100644 --- a/drivers/android/vendor_hooks.c +++ b/drivers/android/vendor_hooks.c @@ -398,6 +398,8 @@ EXPORT_TRACEPOINT_SYMBOL_GPL(android_vh_mmap_region); EXPORT_TRACEPOINT_SYMBOL_GPL(android_vh_update_page_mapcount); EXPORT_TRACEPOINT_SYMBOL_GPL(android_vh_add_page_to_lrulist); EXPORT_TRACEPOINT_SYMBOL_GPL(android_vh_del_page_from_lrulist); +EXPORT_TRACEPOINT_SYMBOL_GPL(android_vh_page_should_be_protected); +EXPORT_TRACEPOINT_SYMBOL_GPL(android_vh_mark_page_accessed); EXPORT_TRACEPOINT_SYMBOL_GPL(android_vh_try_to_unmap_one); EXPORT_TRACEPOINT_SYMBOL_GPL(android_vh_mem_cgroup_id_remove); EXPORT_TRACEPOINT_SYMBOL_GPL(android_vh_mem_cgroup_css_offline); diff --git a/include/trace/hooks/mm.h b/include/trace/hooks/mm.h index 68d792378b50..495f66d0f926 100644 --- a/include/trace/hooks/mm.h +++ b/include/trace/hooks/mm.h @@ -169,6 +169,12 @@ DECLARE_HOOK(android_vh_show_mapcount_pages, DECLARE_HOOK(android_vh_do_traversal_lruvec, TP_PROTO(struct lruvec *lruvec), TP_ARGS(lruvec)); +DECLARE_HOOK(android_vh_page_should_be_protected, + TP_PROTO(struct page *page, bool *should_protect), + TP_ARGS(page, should_protect)); +DECLARE_HOOK(android_vh_mark_page_accessed, + TP_PROTO(struct page *page), + TP_ARGS(page)); DECLARE_HOOK(android_vh_cma_drain_all_pages_bypass, TP_PROTO(unsigned int migratetype, bool *bypass), TP_ARGS(migratetype, bypass)); diff --git a/mm/swap.c b/mm/swap.c index abf445bd7721..16b2bc48211e 100644 --- a/mm/swap.c +++ b/mm/swap.c @@ -437,6 +437,7 @@ void mark_page_accessed(struct page *page) { page = compound_head(page); + trace_android_vh_mark_page_accessed(page); if (!PageReferenced(page)) { SetPageReferenced(page); } else if (PageUnevictable(page)) { diff --git a/mm/vmscan.c b/mm/vmscan.c index fef55a9ed60f..22ab1afed87f 100644 --- a/mm/vmscan.c +++ b/mm/vmscan.c @@ -1020,6 +1020,11 @@ static enum page_references page_check_references(struct page *page, { int referenced_ptes, referenced_page; unsigned long vm_flags; + bool should_protect = false; + + trace_android_vh_page_should_be_protected(page, &should_protect); + if (unlikely(should_protect)) + return PAGEREF_ACTIVATE; referenced_ptes = page_referenced(page, 1, sc->target_mem_cgroup, &vm_flags); @@ -2057,6 +2062,7 @@ static void shrink_active_list(unsigned long nr_to_scan, int file = is_file_lru(lru); struct pglist_data *pgdat = lruvec_pgdat(lruvec); bool bypass = false; + bool should_protect = false; lru_add_drain(); @@ -2091,6 +2097,13 @@ static void shrink_active_list(unsigned long nr_to_scan, } } + trace_android_vh_page_should_be_protected(page, &should_protect); + if (unlikely(should_protect)) { + nr_rotated += thp_nr_pages(page); + list_add(&page->lru, &l_active); + continue; + } + trace_android_vh_page_referenced_check_bypass(page, nr_to_scan, lru, &bypass); if (bypass) goto skip_page_referenced; From 2b377175a35e595c0e7e1860a9b99f08ae73752f Mon Sep 17 00:00:00 2001 From: Peifeng Li Date: Fri, 15 Jul 2022 16:38:06 +0800 Subject: [PATCH 58/91] ANDROID: add two func in mm/memcontrol.c - page_to_lruvec: get lruvec from page and pgdat. - do_traversal_all_lruvec: traversal all lruvec and do hookss. Bug: 236578020 Signed-off-by: Peifeng Li Change-Id: I3d4f5159faaca1ee71ffa65f2fc1341f51da637c --- include/linux/memcontrol.h | 12 ++++++++++++ mm/memcontrol.c | 32 ++++++++++++++++++++++++++++++++ 2 files changed, 44 insertions(+) diff --git a/include/linux/memcontrol.h b/include/linux/memcontrol.h index 6ea0873708b1..2e9c8a504fab 100644 --- a/include/linux/memcontrol.h +++ b/include/linux/memcontrol.h @@ -345,6 +345,9 @@ struct mem_cgroup { extern struct mem_cgroup *root_mem_cgroup; +struct lruvec *page_to_lruvec(struct page *page, pg_data_t *pgdat); +void do_traversal_all_lruvec(void); + static __always_inline bool memcg_stat_item_in_bytes(int idx) { if (idx == MEMCG_PERCPU_B) @@ -969,6 +972,15 @@ void split_page_memcg(struct page *head, unsigned int nr); struct mem_cgroup; +static inline struct lruvec *page_to_lruvec(struct page *page, pg_data_t *pgdat) +{ + return NULL; +} + +static inline void do_traversal_all_lruvec(void) +{ +} + static inline bool mem_cgroup_is_root(struct mem_cgroup *memcg) { return true; diff --git a/mm/memcontrol.c b/mm/memcontrol.c index 008e72c2b980..f585eef0f4fe 100644 --- a/mm/memcontrol.c +++ b/mm/memcontrol.c @@ -1372,6 +1372,38 @@ out: return lruvec; } +struct lruvec *page_to_lruvec(struct page *page, pg_data_t *pgdat) +{ + struct lruvec *lruvec; + + lruvec = mem_cgroup_page_lruvec(page, pgdat); + + return lruvec; +} +EXPORT_SYMBOL_GPL(page_to_lruvec); + +void do_traversal_all_lruvec(void) +{ + pg_data_t *pgdat; + + for_each_online_pgdat(pgdat) { + struct mem_cgroup *memcg = NULL; + + spin_lock_irq(&pgdat->lru_lock); + memcg = mem_cgroup_iter(NULL, NULL, NULL); + do { + struct lruvec *lruvec = mem_cgroup_lruvec(memcg, pgdat); + + trace_android_vh_do_traversal_lruvec(lruvec); + + memcg = mem_cgroup_iter(NULL, memcg, NULL); + } while (memcg); + + spin_unlock_irq(&pgdat->lru_lock); + } +} +EXPORT_SYMBOL_GPL(do_traversal_all_lruvec); + /** * mem_cgroup_update_lru_size - account for adding or removing an lru page * @lruvec: mem_cgroup per zone lru vector From 784cc16aede4cab5c8cace943caba85b05d2d710 Mon Sep 17 00:00:00 2001 From: Luiz Augusto von Dentz Date: Thu, 21 Jul 2022 09:10:50 -0700 Subject: [PATCH 59/91] BACKPORT: Bluetooth: L2CAP: Fix use-after-free caused by l2cap_chan_put commit d0be8347c623e0ac4202a1d4e0373882821f56b0 upstream. This fixes the following trace which is caused by hci_rx_work starting up *after* the final channel reference has been put() during sock_close() but *before* the references to the channel have been destroyed, so instead the code now rely on kref_get_unless_zero/l2cap_chan_hold_unless_zero to prevent referencing a channel that is about to be destroyed. refcount_t: increment on 0; use-after-free. BUG: KASAN: use-after-free in refcount_dec_and_test+0x20/0xd0 Read of size 4 at addr ffffffc114f5bf18 by task kworker/u17:14/705 CPU: 4 PID: 705 Comm: kworker/u17:14 Tainted: G S W 4.14.234-00003-g1fb6d0bd49a4-dirty #28 Hardware name: Qualcomm Technologies, Inc. SM8150 V2 PM8150 Google Inc. MSM sm8150 Flame DVT (DT) Workqueue: hci0 hci_rx_work Call trace: dump_backtrace+0x0/0x378 show_stack+0x20/0x2c dump_stack+0x124/0x148 print_address_description+0x80/0x2e8 __kasan_report+0x168/0x188 kasan_report+0x10/0x18 __asan_load4+0x84/0x8c refcount_dec_and_test+0x20/0xd0 l2cap_chan_put+0x48/0x12c l2cap_recv_frame+0x4770/0x6550 l2cap_recv_acldata+0x44c/0x7a4 hci_acldata_packet+0x100/0x188 hci_rx_work+0x178/0x23c process_one_work+0x35c/0x95c worker_thread+0x4cc/0x960 kthread+0x1a8/0x1c4 ret_from_fork+0x10/0x18 Bug: 165329981 Cc: stable@kernel.org Reported-by: Lee Jones Signed-off-by: Luiz Augusto von Dentz Tested-by: Lee Jones Signed-off-by: Luiz Augusto von Dentz Signed-off-by: Greg Kroah-Hartman Signed-off-by: Lee Jones Change-Id: I6efae55d8014740aebc8c3534846c2d249068b29 --- include/net/bluetooth/l2cap.h | 1 + net/bluetooth/l2cap_core.c | 61 +++++++++++++++++++++++++++-------- 2 files changed, 49 insertions(+), 13 deletions(-) diff --git a/include/net/bluetooth/l2cap.h b/include/net/bluetooth/l2cap.h index 8c99677077b6..26459016f150 100644 --- a/include/net/bluetooth/l2cap.h +++ b/include/net/bluetooth/l2cap.h @@ -855,6 +855,7 @@ enum { }; void l2cap_chan_hold(struct l2cap_chan *c); +struct l2cap_chan *l2cap_chan_hold_unless_zero(struct l2cap_chan *c); void l2cap_chan_put(struct l2cap_chan *c); static inline void l2cap_chan_lock(struct l2cap_chan *chan) diff --git a/net/bluetooth/l2cap_core.c b/net/bluetooth/l2cap_core.c index 012c1a0abda8..6e8a9c4299b0 100644 --- a/net/bluetooth/l2cap_core.c +++ b/net/bluetooth/l2cap_core.c @@ -111,7 +111,8 @@ static struct l2cap_chan *__l2cap_get_chan_by_scid(struct l2cap_conn *conn, } /* Find channel with given SCID. - * Returns locked channel. */ + * Returns a reference locked channel. + */ static struct l2cap_chan *l2cap_get_chan_by_scid(struct l2cap_conn *conn, u16 cid) { @@ -119,15 +120,19 @@ static struct l2cap_chan *l2cap_get_chan_by_scid(struct l2cap_conn *conn, mutex_lock(&conn->chan_lock); c = __l2cap_get_chan_by_scid(conn, cid); - if (c) - l2cap_chan_lock(c); + if (c) { + /* Only lock if chan reference is not 0 */ + c = l2cap_chan_hold_unless_zero(c); + if (c) + l2cap_chan_lock(c); + } mutex_unlock(&conn->chan_lock); return c; } /* Find channel with given DCID. - * Returns locked channel. + * Returns a reference locked channel. */ static struct l2cap_chan *l2cap_get_chan_by_dcid(struct l2cap_conn *conn, u16 cid) @@ -136,8 +141,12 @@ static struct l2cap_chan *l2cap_get_chan_by_dcid(struct l2cap_conn *conn, mutex_lock(&conn->chan_lock); c = __l2cap_get_chan_by_dcid(conn, cid); - if (c) - l2cap_chan_lock(c); + if (c) { + /* Only lock if chan reference is not 0 */ + c = l2cap_chan_hold_unless_zero(c); + if (c) + l2cap_chan_lock(c); + } mutex_unlock(&conn->chan_lock); return c; @@ -162,8 +171,12 @@ static struct l2cap_chan *l2cap_get_chan_by_ident(struct l2cap_conn *conn, mutex_lock(&conn->chan_lock); c = __l2cap_get_chan_by_ident(conn, ident); - if (c) - l2cap_chan_lock(c); + if (c) { + /* Only lock if chan reference is not 0 */ + c = l2cap_chan_hold_unless_zero(c); + if (c) + l2cap_chan_lock(c); + } mutex_unlock(&conn->chan_lock); return c; @@ -497,6 +510,16 @@ void l2cap_chan_hold(struct l2cap_chan *c) kref_get(&c->kref); } +struct l2cap_chan *l2cap_chan_hold_unless_zero(struct l2cap_chan *c) +{ + BT_DBG("chan %p orig refcnt %u", c, kref_read(&c->kref)); + + if (!kref_get_unless_zero(&c->kref)) + return NULL; + + return c; +} + void l2cap_chan_put(struct l2cap_chan *c) { BT_DBG("chan %p orig refcnt %d", c, kref_read(&c->kref)); @@ -1965,7 +1988,10 @@ static struct l2cap_chan *l2cap_global_chan_by_psm(int state, __le16 psm, src_match = !bacmp(&c->src, src); dst_match = !bacmp(&c->dst, dst); if (src_match && dst_match) { - l2cap_chan_hold(c); + c = l2cap_chan_hold_unless_zero(c); + if (!c) + continue; + read_unlock(&chan_list_lock); return c; } @@ -1980,7 +2006,7 @@ static struct l2cap_chan *l2cap_global_chan_by_psm(int state, __le16 psm, } if (c1) - l2cap_chan_hold(c1); + c1 = l2cap_chan_hold_unless_zero(c1); read_unlock(&chan_list_lock); @@ -4460,6 +4486,7 @@ static inline int l2cap_config_req(struct l2cap_conn *conn, unlock: l2cap_chan_unlock(chan); + l2cap_chan_put(chan); return err; } @@ -4573,6 +4600,7 @@ static inline int l2cap_config_rsp(struct l2cap_conn *conn, done: l2cap_chan_unlock(chan); + l2cap_chan_put(chan); return err; } @@ -5300,6 +5328,7 @@ send_move_response: l2cap_send_move_chan_rsp(chan, result); l2cap_chan_unlock(chan); + l2cap_chan_put(chan); return 0; } @@ -5392,6 +5421,7 @@ static void l2cap_move_continue(struct l2cap_conn *conn, u16 icid, u16 result) } l2cap_chan_unlock(chan); + l2cap_chan_put(chan); } static void l2cap_move_fail(struct l2cap_conn *conn, u8 ident, u16 icid, @@ -5421,6 +5451,7 @@ static void l2cap_move_fail(struct l2cap_conn *conn, u8 ident, u16 icid, l2cap_send_move_chan_cfm(chan, L2CAP_MC_UNCONFIRMED); l2cap_chan_unlock(chan); + l2cap_chan_put(chan); } static int l2cap_move_channel_rsp(struct l2cap_conn *conn, @@ -5484,6 +5515,7 @@ static int l2cap_move_channel_confirm(struct l2cap_conn *conn, l2cap_send_move_chan_cfm_rsp(conn, cmd->ident, icid); l2cap_chan_unlock(chan); + l2cap_chan_put(chan); return 0; } @@ -5519,6 +5551,7 @@ static inline int l2cap_move_channel_confirm_rsp(struct l2cap_conn *conn, } l2cap_chan_unlock(chan); + l2cap_chan_put(chan); return 0; } @@ -5891,12 +5924,11 @@ static inline int l2cap_le_credits(struct l2cap_conn *conn, if (credits > max_credits) { BT_ERR("LE credits overflow"); l2cap_send_disconn_req(chan, ECONNRESET); - l2cap_chan_unlock(chan); /* Return 0 so that we don't trigger an unnecessary * command reject packet. */ - return 0; + goto unlock; } chan->tx_credits += credits; @@ -5907,7 +5939,9 @@ static inline int l2cap_le_credits(struct l2cap_conn *conn, if (chan->tx_credits) chan->ops->resume(chan); +unlock: l2cap_chan_unlock(chan); + l2cap_chan_put(chan); return 0; } @@ -7587,6 +7621,7 @@ drop: done: l2cap_chan_unlock(chan); + l2cap_chan_put(chan); } static void l2cap_conless_channel(struct l2cap_conn *conn, __le16 psm, @@ -8074,7 +8109,7 @@ static struct l2cap_chan *l2cap_global_fixed_chan(struct l2cap_chan *c, if (src_type != c->src_type) continue; - l2cap_chan_hold(c); + c = l2cap_chan_hold_unless_zero(c); read_unlock(&chan_list_lock); return c; } From 843d3cb41b0f9408e1f1bcbb7e4fda081b9ca5f1 Mon Sep 17 00:00:00 2001 From: Jens Axboe Date: Thu, 19 May 2022 06:05:27 -0600 Subject: [PATCH 60/91] BACKPORT: io_uring: always grab file table for deferred statx Lee reports that there's a use-after-free of the process file table. There's an assumption that we don't need the file table for some variants of statx invocation, but that turns out to be false and we end up with not grabbing a reference for the request even if the deferred execution uses it. Get rid of the REQ_F_NO_FILE_TABLE optimization for statx, and always grab that reference. This issues doesn't exist upstream since the native workers got introduced with 5.12. Bug: 220738351 Link: https://lore.kernel.org/io-uring/YoOJ%2FT4QRKC+fAZE@google.com/ Reported-by: Lee Jones Signed-off-by: Jens Axboe Signed-off-by: Greg Kroah-Hartman (cherry picked from commit 3c48558be571e01f67e65edcf03193484eeb2b79) Signed-off-by: Lee Jones Change-Id: Ife51536d95368bffdc393ad2a5e737a0e6ddf18f --- fs/io_uring.c | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/fs/io_uring.c b/fs/io_uring.c index d63d8713a197..b08d1089731c 100644 --- a/fs/io_uring.c +++ b/fs/io_uring.c @@ -4252,12 +4252,8 @@ static int io_statx(struct io_kiocb *req, bool force_nonblock) struct io_statx *ctx = &req->statx; int ret; - if (force_nonblock) { - /* only need file table for an actual valid fd */ - if (ctx->dfd == -1 || ctx->dfd == AT_FDCWD) - req->flags |= REQ_F_NO_FILE_TABLE; + if (force_nonblock) return -EAGAIN; - } ret = do_statx(ctx->dfd, ctx->filename, ctx->flags, ctx->mask, ctx->buffer); From 1c3ed9d4819b470c7cf11ac1decae85217db7686 Mon Sep 17 00:00:00 2001 From: Paolo Bonzini Date: Fri, 20 May 2022 13:48:11 -0400 Subject: [PATCH 61/91] BACKPORT: KVM: x86/mmu: fix NULL pointer dereference on guest INVPCID commit 9f46c187e2e680ecd9de7983e4d081c3391acc76 upstream. With shadow paging enabled, the INVPCID instruction results in a call to kvm_mmu_invpcid_gva. If INVPCID is executed with CR0.PG=0, the invlpg callback is not set and the result is a NULL pointer dereference. Fix it trivially by checking for mmu->invlpg before every call. There are other possibilities: - check for CR0.PG, because KVM (like all Intel processors after P5) flushes guest TLB on CR0.PG changes so that INVPCID/INVLPG are a nop with paging disabled - check for EFER.LMA, because KVM syncs and flushes when switching MMU contexts outside of 64-bit mode All of these are tricky, go for the simple solution. This is CVE-2022-1789. Bug: 235691682 Reported-by: Yongkang Jia Cc: stable@vger.kernel.org Signed-off-by: Paolo Bonzini [fix conflict due to missing b9e5603c2a3accbadfec570ac501a54431a6bdba] Signed-off-by: Vegard Nossum Signed-off-by: Greg Kroah-Hartman Signed-off-by: Lee Jones Change-Id: If558163c4ddd4606274b456324278ed3fb5b093c --- arch/x86/kvm/mmu/mmu.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/arch/x86/kvm/mmu/mmu.c b/arch/x86/kvm/mmu/mmu.c index 70ef5b542681..bcf1bd9424f2 100644 --- a/arch/x86/kvm/mmu/mmu.c +++ b/arch/x86/kvm/mmu/mmu.c @@ -5178,14 +5178,16 @@ void kvm_mmu_invpcid_gva(struct kvm_vcpu *vcpu, gva_t gva, unsigned long pcid) uint i; if (pcid == kvm_get_active_pcid(vcpu)) { - mmu->invlpg(vcpu, gva, mmu->root_hpa); + if (mmu->invlpg) + mmu->invlpg(vcpu, gva, mmu->root_hpa); tlb_flush = true; } for (i = 0; i < KVM_MMU_NUM_PREV_ROOTS; i++) { if (VALID_PAGE(mmu->prev_roots[i].hpa) && pcid == kvm_get_pcid(vcpu, mmu->prev_roots[i].pgd)) { - mmu->invlpg(vcpu, gva, mmu->prev_roots[i].hpa); + if (mmu->invlpg) + mmu->invlpg(vcpu, gva, mmu->prev_roots[i].hpa); tlb_flush = true; } } From d6207c39cb09882c91cb7f0ae2b4e097d3bf2cc9 Mon Sep 17 00:00:00 2001 From: Kever Yang Date: Mon, 18 Jul 2022 15:07:49 +0800 Subject: [PATCH 62/91] ANDROID: GKI: rockchip: Add symbols for display driver DRM display driver has update, new symbols added. Leaf changes summary: 7 artifacts changed Changed leaf types summary: 0 leaf type changed Removed/Changed/Added functions summary: 0 Removed, 0 Changed, 7 Added functions Removed/Changed/Added variables summary: 0 Removed, 0 Changed, 0 Added variable 7 Added functions: [A] 'function drm_connector_status drm_bridge_detect(drm_bridge*)' [A] 'function int drm_bridge_get_modes(drm_bridge*, drm_connector*)' [A] 'function int drm_dp_get_phy_test_pattern(drm_dp_aux*, drm_dp_phy_test_params*)' [A] 'function int drm_dp_read_dpcd_caps(drm_dp_aux*, u8*)' [A] 'function int drm_dp_set_phy_test_pattern(drm_dp_aux*, drm_dp_phy_test_params*, u8)' [A] 'function void drm_self_refresh_helper_cleanup(drm_crtc*)' [A] 'function int drm_self_refresh_helper_init(drm_crtc*)' Bug: 239396464 Signed-off-by: Kever Yang Change-Id: Ic5728516d6f7146912dc44acddb331be75e3d3f8 --- android/abi_gki_aarch64.xml | 82 +++++++++++++----- android/abi_gki_aarch64_rockchip | 142 ++++++++++++++++++++----------- 2 files changed, 152 insertions(+), 72 deletions(-) diff --git a/android/abi_gki_aarch64.xml b/android/abi_gki_aarch64.xml index 9d9c8c004b21..07d6024e1fca 100644 --- a/android/abi_gki_aarch64.xml +++ b/android/abi_gki_aarch64.xml @@ -1961,6 +1961,8 @@ + + @@ -2049,6 +2051,7 @@ + @@ -2064,7 +2067,9 @@ + + @@ -2302,6 +2307,8 @@ + + @@ -27143,6 +27150,26 @@ + + + + + + + + + + + + + + + + + + + + @@ -80093,6 +80120,7 @@ + @@ -82751,9 +82779,6 @@ - - - @@ -91644,9 +91669,6 @@ - - - @@ -104795,20 +104817,7 @@ - - - - - - - - - - - - - - + @@ -126321,6 +126330,15 @@ + + + + + + + + + @@ -126771,6 +126789,11 @@ + + + + + @@ -126850,12 +126873,23 @@ + + + + + + + + + + + @@ -128078,6 +128112,14 @@ + + + + + + + + diff --git a/android/abi_gki_aarch64_rockchip b/android/abi_gki_aarch64_rockchip index f048bf0063f0..3e324b6df2dd 100644 --- a/android/abi_gki_aarch64_rockchip +++ b/android/abi_gki_aarch64_rockchip @@ -17,7 +17,6 @@ atomic_notifier_chain_unregister bdget_disk bdput - __bitmap_set blk_cleanup_queue blk_execute_rq_nowait blk_mq_free_request @@ -36,6 +35,7 @@ blk_queue_physical_block_size blk_rq_map_user blk_rq_unmap_user + cancel_delayed_work cancel_delayed_work_sync cancel_work_sync cdev_device_add @@ -87,6 +87,8 @@ __cpuhp_setup_state cpu_hwcap_keys cpu_hwcaps + cpu_latency_qos_add_request + cpu_latency_qos_update_request cpumask_next cpu_number __cpu_online_mask @@ -124,6 +126,7 @@ device_create device_destroy device_get_child_node_count + device_get_named_child_node device_get_next_child_node device_initialize device_init_wakeup @@ -132,6 +135,7 @@ device_property_present device_property_read_string device_property_read_u32_array + device_release_driver _dev_info devm_add_action devm_clk_bulk_get @@ -168,6 +172,7 @@ __devm_of_phy_provider_register devm_phy_create devm_phy_get + devm_phy_optional_get devm_pinctrl_get devm_pinctrl_register devm_platform_get_and_ioremap_resource @@ -188,12 +193,16 @@ __devm_reset_control_get devm_snd_dmaengine_pcm_register devm_snd_soc_register_component + dev_pm_opp_disable dev_pm_opp_find_freq_ceil dev_pm_opp_get_opp_count dev_pm_opp_get_voltage dev_pm_opp_of_get_sharing_cpus dev_pm_opp_put - dev_pm_opp_remove + dev_pm_opp_put_regulators + dev_pm_opp_register_set_opp_helper + dev_pm_opp_set_rate + dev_pm_opp_set_regulators devres_add devres_alloc_node devres_free @@ -213,9 +222,11 @@ dma_free_attrs dma_get_sgtable_attrs dma_heap_add + dma_heap_get_dev dma_heap_get_name dmam_alloc_attrs dma_map_page_attrs + dma_map_resource dma_map_sg_attrs dmam_free_coherent dma_mmap_attrs @@ -228,6 +239,7 @@ dma_sync_single_for_cpu dma_sync_single_for_device dma_unmap_page_attrs + dma_unmap_resource dma_unmap_sg_attrs down_read down_write @@ -243,6 +255,8 @@ drm_atomic_helper_connector_reset drm_bridge_add drm_bridge_attach + drm_bridge_detect + drm_bridge_get_modes drm_bridge_remove drm_compat_ioctl drm_connector_attach_encoder @@ -260,9 +274,12 @@ drm_dev_register drm_dev_unregister drm_display_info_set_bus_formats + drm_display_mode_from_videomode + drm_display_mode_to_videomode drm_dp_bw_code_to_link_rate __drm_err drm_gem_dumb_map_offset + drm_gem_get_pages drm_gem_handle_create drm_gem_mmap drm_gem_mmap_obj @@ -272,6 +289,7 @@ drm_gem_object_release drm_gem_prime_fd_to_handle drm_gem_prime_handle_to_fd + drm_gem_put_pages drm_gem_vm_close drm_get_edid drm_hdmi_avi_infoframe_from_display_mode @@ -279,6 +297,7 @@ drm_helper_hpd_irq_event drm_helper_probe_single_connector_modes drm_ioctl + drm_kms_helper_hotplug_event drm_match_cea_mode drm_mode_copy drm_mode_create @@ -289,18 +308,20 @@ drm_object_attach_property drm_of_find_panel_or_bridge drm_open + drm_panel_add drm_panel_disable drm_panel_enable drm_panel_get_modes + drm_panel_init drm_panel_prepare drm_panel_unprepare drm_poll drm_prime_gem_destroy drm_prime_pages_to_sg drm_prime_sg_to_page_addr_arrays + drm_property_replace_global_blob drm_read drm_release - dummy_irq_chip enable_irq extcon_get_edev_by_phandle extcon_get_state @@ -319,6 +340,7 @@ free_irq __free_pages free_pages + fwnode_get_name fwnode_handle_put fwnode_property_present fwnode_property_read_string @@ -361,6 +383,9 @@ __hid_request hid_unregister_driver hid_validate_values + hrtimer_cancel + hrtimer_init + hrtimer_start_range_ns i2c_adapter_type i2c_add_adapter i2c_del_adapter @@ -391,7 +416,6 @@ input_set_abs_params iommu_attach_device iommu_detach_device - iommu_get_domain_for_dev __ioremap iounmap irq_create_mapping_affinity @@ -427,10 +451,12 @@ kmem_cache_destroy kmem_cache_free kmemdup + kobject_create_and_add kstrdup_const kstrtoint kstrtouint kstrtoull + kthread_create_on_node ktime_get ktime_get_mono_fast_ns ktime_get_with_offset @@ -464,6 +490,8 @@ memset memstart_addr mfd_remove_devices + mipi_dsi_create_packet + mipi_dsi_host_register mmc_of_parse mod_delayed_work_on mod_timer @@ -487,6 +515,7 @@ of_clk_del_provider of_clk_get of_clk_get_by_name + of_clk_get_parent_count of_clk_src_onecell_get of_clk_src_simple_get of_count_phandle_with_args @@ -494,10 +523,12 @@ of_device_get_match_data of_device_is_available of_device_is_compatible + of_drm_find_bridge of_find_device_by_node of_find_node_by_name of_find_property of_get_child_by_name + of_get_drm_display_mode of_get_named_gpio_flags of_get_next_available_child of_get_next_child @@ -505,6 +536,7 @@ of_get_property of_get_regulator_init_data of_graph_get_remote_node + of_graph_get_remote_port_parent of_graph_parse_endpoint of_iomap of_irq_get_byname @@ -521,6 +553,7 @@ of_property_read_string_helper of_property_read_u32_index of_property_read_variable_u32_array + of_property_read_variable_u8_array of_regulator_match of_reserved_mem_device_init_by_idx of_usb_get_dr_mode_by_phy @@ -736,6 +769,9 @@ __tracepoint_rwmmio_post_read __tracepoint_rwmmio_read __tracepoint_rwmmio_write + typec_switch_get_drvdata + typec_switch_register + typec_switch_unregister __unregister_chrdev unregister_chrdev_region unregister_reboot_notifier @@ -743,16 +779,19 @@ up_read up_write usb_debug_root + usb_hid_driver usleep_range uuid_null v4l2_async_notifier_cleanup v4l2_async_notifier_init v4l2_async_notifier_register + v4l2_async_notifier_unregister v4l2_async_register_subdev v4l2_async_subdev_notifier_register v4l2_async_unregister_subdev v4l2_ctrl_find v4l2_ctrl_g_ctrl + v4l2_ctrl_g_ctrl_int64 v4l2_ctrl_handler_free v4l2_ctrl_handler_init_class v4l2_ctrl_handler_setup @@ -816,6 +855,7 @@ wait_for_completion wait_for_completion_timeout __wake_up + wake_up_process wakeup_source_add __warn_printk @@ -853,8 +893,19 @@ drm_dp_aux_unregister drm_dp_dpcd_read drm_dp_dpcd_write + drm_dp_get_phy_test_pattern + drm_dp_link_rate_to_bw_code + drm_dp_link_train_channel_eq_delay + drm_dp_link_train_clock_recovery_delay + drm_dp_read_dpcd_caps + drm_dp_set_phy_test_pattern drm_dp_start_crc drm_dp_stop_crc + drm_modeset_acquire_fini + drm_modeset_acquire_init + drm_modeset_backoff + drm_modeset_drop_locks + drm_modeset_lock # required by ch.ko param_array_ops @@ -887,12 +938,10 @@ clk_hw_round_rate clk_mux_ops clk_mux_ro_ops - clk_register_composite clk_register_divider_table clk_register_fixed_factor clk_register_gate clk_register_mux_table - divider_get_val match_string register_restart_handler reset_controller_register @@ -908,6 +957,7 @@ cma_get_name dma_contiguous_default_area dma_heap_get_drvdata + dma_heap_put # required by cpufreq-dt.ko cpufreq_enable_boost_support @@ -925,9 +975,6 @@ dev_pm_opp_of_cpumask_add_table dev_pm_opp_of_cpumask_remove_table dev_pm_opp_of_register_em - dev_pm_opp_put_regulators - dev_pm_opp_set_rate - dev_pm_opp_set_regulators dev_pm_opp_set_sharing_cpus policy_has_boost_freq @@ -977,7 +1024,6 @@ # required by dw-hdmi.ko bcmp - cancel_delayed_work cec_fill_conn_info_from_drm cec_notifier_conn_register cec_notifier_conn_unregister @@ -991,7 +1037,6 @@ drm_hdmi_infoframe_set_hdr_metadata drm_mode_is_420_also drm_mode_is_420_only - drm_property_replace_global_blob drm_scdc_read drm_scdc_set_high_tmds_clock_ratio drm_scdc_set_scrambling @@ -1000,6 +1045,7 @@ hdmi_drm_infoframe_pack hdmi_vendor_infoframe_pack of_get_i2c_adapter_by_node + of_graph_get_endpoint_by_regs # required by dw-mipi-dsi.ko debugfs_attr_read @@ -1007,10 +1053,7 @@ drm_panel_bridge_add_typed drm_panel_bridge_connector drm_panel_bridge_remove - mipi_dsi_create_packet - mipi_dsi_host_register mipi_dsi_host_unregister - of_drm_find_bridge simple_attr_open simple_attr_release @@ -1049,12 +1092,10 @@ # required by dwc2.ko __bitmap_clear bitmap_find_next_zero_area_off + __bitmap_set device_set_wakeup_capable device_wakeup_enable devm_usb_get_phy - hrtimer_cancel - hrtimer_init - hrtimer_start_range_ns phy_reset _raw_spin_trylock usb_add_gadget_udc @@ -1090,7 +1131,6 @@ gpiod_set_raw_value # required by fusb302.ko - device_get_named_child_node disable_irq_nosync extcon_get_extcon_dev fwnode_create_software_node @@ -1258,7 +1298,6 @@ ida_free init_srcu_struct kobject_uevent_env - list_sort memchr_inv param_ops_byte param_ops_ulong @@ -1300,7 +1339,6 @@ blk_mq_update_nr_hw_queues blk_put_queue __blk_rq_map_sg - device_release_driver dma_max_mapping_size dma_pool_alloc dma_pool_create @@ -1353,7 +1391,9 @@ # required by optee.ko alloc_pages_exact __arm_smccc_hvc + bus_for_each_dev device_register + device_unregister find_vma free_pages_exact idr_get_next @@ -1374,23 +1414,24 @@ v4l2_ctrl_new_int_menu # required by panel-simple.ko + devm_backlight_device_register drm_bus_flags_from_videomode drm_connector_set_panel_orientation - drm_display_mode_from_videomode - drm_panel_add - drm_panel_init drm_panel_of_backlight drm_panel_remove mipi_dsi_attach + mipi_dsi_compression_mode + mipi_dsi_dcs_get_display_brightness + mipi_dsi_dcs_set_display_brightness mipi_dsi_dcs_write_buffer mipi_dsi_detach mipi_dsi_driver_register_full mipi_dsi_driver_unregister mipi_dsi_generic_write + mipi_dsi_picture_parameter_set of_drm_get_panel_orientation of_find_i2c_adapter_by_node of_get_display_timing - of_get_drm_display_mode videomode_from_timing # required by pcie-dw-rockchip.ko @@ -1401,14 +1442,13 @@ dw_pcie_setup_rc dw_pcie_write dw_pcie_write_dbi - kthread_create_on_node of_prop_next_string - wake_up_process # required by pcierockchiphost.ko devm_of_phy_get devm_pci_alloc_host_bridge devm_pci_remap_cfg_resource + dummy_irq_chip jiffies_to_usecs of_pci_get_max_link_speed pci_host_probe @@ -1445,6 +1485,7 @@ # required by pinctrl-rockchip.ko of_find_node_by_phandle + of_platform_depopulate of_platform_populate pinconf_generic_parse_dt_config pinctrl_force_default @@ -1459,8 +1500,6 @@ dma_async_tx_descriptor_init dmaengine_unmap_put dma_get_slave_channel - dma_map_resource - dma_unmap_resource loops_per_jiffy of_dma_controller_free of_dma_controller_register @@ -1469,7 +1508,6 @@ # required by pm_domains.ko clk_bulk_put - of_clk_get_parent_count of_genpd_add_provider_onecell panic pm_clk_add_clk @@ -1511,6 +1549,8 @@ # required by rk806-core.ko devm_regmap_add_irq_chip + kobject_put + sysfs_remove_file_ns # required by rk806-spi.ko spi_write_then_read @@ -1519,7 +1559,6 @@ gpiod_is_active_low # required by rk808.ko - kobject_create_and_add platform_device_add platform_device_alloc pm_power_off_prepare @@ -1535,9 +1574,9 @@ blocking_notifier_chain_unregister # required by rknpu.ko + dev_pm_domain_attach_by_name + dev_pm_domain_detach dma_buf_mmap - dma_fence_context_alloc - dma_fence_init dma_fence_release dma_fence_signal drm_gem_create_mmap_offset @@ -1546,16 +1585,16 @@ drm_gem_prime_export drm_gem_prime_import_dev drm_gem_vm_open - fd_install - get_unused_fd_flags - of_dma_configure_id + hrtimer_forward + iommu_get_domain_for_dev set_user_nice - sync_file_create vmf_insert_mixed + vm_insert_page # required by rockchip-cpufreq.ko + cpufreq_unregister_notifier dev_pm_opp_put_prop_name - dev_pm_opp_register_set_opp_helper + dev_pm_opp_set_supported_hw # required by rockchip-iommu.ko bus_set_iommu @@ -1592,8 +1631,6 @@ cpufreq_cpu_get cpufreq_cpu_put cpufreq_quick_get - cpu_latency_qos_add_request - cpu_latency_qos_update_request devfreq_add_governor devfreq_event_disable_edev devfreq_event_enable_edev @@ -1615,6 +1652,7 @@ input_register_handler input_unregister_handle __memset_io + system_freezable_wq # required by rockchip_dmc_common.ko down_write_trylock @@ -1636,6 +1674,7 @@ iio_trigger_notify_done # required by rockchip_thermal.ko + devm_clk_put devm_thermal_zone_of_sensor_register thermal_zone_device_disable thermal_zone_device_enable @@ -1653,7 +1692,7 @@ component_match_add_release component_unbind_all devm_of_phy_get_by_index - devm_phy_optional_get + driver_find_device drm_add_modes_noedid drm_atomic_commit drm_atomic_get_connector_state @@ -1671,13 +1710,13 @@ __drm_atomic_helper_connector_reset __drm_atomic_helper_crtc_destroy_state __drm_atomic_helper_crtc_duplicate_state - drm_atomic_helper_dirtyfb __drm_atomic_helper_disable_plane drm_atomic_helper_duplicate_state drm_atomic_helper_fake_vblank drm_atomic_helper_page_flip __drm_atomic_helper_plane_destroy_state __drm_atomic_helper_plane_duplicate_state + __drm_atomic_helper_plane_reset drm_atomic_helper_set_config drm_atomic_helper_shutdown drm_atomic_helper_swap_state @@ -1688,6 +1727,7 @@ drm_atomic_set_mode_for_crtc drm_atomic_state_alloc __drm_atomic_state_free + drm_connector_has_possible_encoder drm_connector_list_iter_begin drm_connector_list_iter_end drm_connector_list_iter_next @@ -1726,17 +1766,13 @@ drm_gem_fb_afbc_init drm_gem_fb_create_handle drm_gem_fb_init_with_funcs - drm_gem_get_pages drm_gem_map_attach drm_gem_map_detach drm_gem_map_dma_buf - drm_gem_object_put_locked - drm_gem_put_pages drm_gem_unmap_dma_buf drm_get_format_info drm_get_format_name drm_helper_mode_fill_fb_struct - drm_kms_helper_hotplug_event drm_kms_helper_poll_enable drm_kms_helper_poll_fini drm_kms_helper_poll_init @@ -1775,12 +1811,15 @@ __drm_printfn_seq_file drm_property_create drm_property_create_bitmask + drm_property_create_bool drm_property_create_enum drm_property_create_object drm_property_create_range drm_property_destroy __drm_puts_seq_file drm_rect_calc_hscale + drm_self_refresh_helper_cleanup + drm_self_refresh_helper_init drm_send_event_locked drm_simple_encoder_init drm_universal_plane_init @@ -1796,10 +1835,12 @@ iommu_set_fault_handler iommu_unmap memblock_free + of_clk_set_defaults + of_find_backlight_by_node + of_fwnode_ops of_graph_get_next_endpoint of_graph_get_port_by_id of_graph_get_remote_port - of_graph_get_remote_port_parent phy_mipi_dphy_get_default_config platform_find_device_by_driver __platform_register_drivers @@ -1878,10 +1919,8 @@ irq_stat # required by sii902x.ko - drm_display_mode_to_videomode hdmi_audio_infoframe_pack hdmi_avi_infoframe_pack - of_property_read_variable_u8_array # required by snd-soc-cx2072x.ko regmap_multi_reg_write @@ -1949,7 +1988,6 @@ dmabuf_page_pool_create dmabuf_page_pool_destroy dmabuf_page_pool_free - dma_heap_get_dev __sg_page_iter_next __sg_page_iter_start swiotlb_max_segment @@ -1961,6 +1999,7 @@ tcpci_unregister_port # required by tee.ko + anon_inode_getfd bus_register bus_unregister class_find_device @@ -1999,7 +2038,6 @@ # required by v4l2-fwnode.ko fwnode_device_is_available - fwnode_get_name fwnode_graph_get_next_endpoint fwnode_graph_get_port_parent fwnode_graph_get_remote_endpoint @@ -2009,10 +2047,11 @@ fwnode_property_read_u64_array v4l2_async_notifier_add_fwnode_subdev v4l2_async_notifier_add_subdev - v4l2_async_notifier_unregister # required by video_rkcif.ko media_entity_setup_link + __v4l2_ctrl_s_ctrl_int64 + work_busy # required by video_rkisp.ko kmalloc_order_trace @@ -2021,7 +2060,6 @@ __memcpy_toio of_property_read_u64 param_ops_ullong - v4l2_ctrl_g_ctrl_int64 v4l2_event_unsubscribe v4l2_pipeline_link_notify From 5e75deab3acc1047d8515c8786e10afd3e19e160 Mon Sep 17 00:00:00 2001 From: Cheng-Yi Chiang Date: Wed, 18 Nov 2020 12:38:52 +0800 Subject: [PATCH 63/91] UPSTREAM: ASoC: hdmi-codec: Get ELD in before reporting plugged event In plugged callback, ELD should be updated from display driver so that user space can query information from ELD immediately after receiving jack plugged event. When jack is unplugged, clear ELD buffer so that user space does not get obsolete information of unplugged HDMI. Bug: 239396464 Change-Id: I2245de6e6f7dbc64863267db864dafdd3af95747 Signed-off-by: Cheng-Yi Chiang Link: https://lore.kernel.org/r/20201118043852.1338877-1-cychiang@chromium.org Signed-off-by: Mark Brown Signed-off-by: Sugar Zhang (cherry picked from commit 25ce4f2b3593fa6bba70ddabbd2ee297b262784f) --- sound/soc/codecs/hdmi-codec.c | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/sound/soc/codecs/hdmi-codec.c b/sound/soc/codecs/hdmi-codec.c index 403d4c6a49a8..e8410b2433de 100644 --- a/sound/soc/codecs/hdmi-codec.c +++ b/sound/soc/codecs/hdmi-codec.c @@ -692,10 +692,16 @@ static void plugged_cb(struct device *dev, bool plugged) { struct hdmi_codec_priv *hcp = dev_get_drvdata(dev); - if (plugged) + if (plugged) { + if (hcp->hcd.ops->get_eld) { + hcp->hcd.ops->get_eld(dev->parent, hcp->hcd.data, + hcp->eld, sizeof(hcp->eld)); + } hdmi_codec_jack_report(hcp, SND_JACK_LINEOUT); - else + } else { hdmi_codec_jack_report(hcp, 0); + memset(hcp->eld, 0, sizeof(hcp->eld)); + } } static int hdmi_codec_set_jack(struct snd_soc_component *component, From 056409c7dc30b0e9d8ac50b91146994178a44be7 Mon Sep 17 00:00:00 2001 From: Shengjiu Wang Date: Thu, 26 Nov 2020 14:36:48 +0800 Subject: [PATCH 64/91] UPSTREAM: ASoC: hdmi-codec: Add RX support HDMI interface can also be used as receiver, this patch is to add such support. The most difference compare with TX is that RX don't need to get edid information. Bug: 239396464 Change-Id: Ib5f9f347cd50abe95fa9c8a4856bd1a91117ca67 Signed-off-by: Shengjiu Wang Link: https://lore.kernel.org/r/1606372608-2329-1-git-send-email-shengjiu.wang@nxp.com Signed-off-by: Mark Brown Signed-off-by: Sugar Zhang (cherry picked from commit 144f836646989783cb018d00fa69f3f8dab58349) --- sound/soc/codecs/hdmi-codec.c | 33 ++++++++++++++++++++++++++++----- 1 file changed, 28 insertions(+), 5 deletions(-) diff --git a/sound/soc/codecs/hdmi-codec.c b/sound/soc/codecs/hdmi-codec.c index e8410b2433de..d5fcc4db8284 100644 --- a/sound/soc/codecs/hdmi-codec.c +++ b/sound/soc/codecs/hdmi-codec.c @@ -282,6 +282,7 @@ struct hdmi_codec_priv { static const struct snd_soc_dapm_widget hdmi_widgets[] = { SND_SOC_DAPM_OUTPUT("TX"), + SND_SOC_DAPM_OUTPUT("RX"), }; enum { @@ -389,6 +390,7 @@ static int hdmi_codec_startup(struct snd_pcm_substream *substream, struct snd_soc_dai *dai) { struct hdmi_codec_priv *hcp = snd_soc_dai_get_drvdata(dai); + bool tx = substream->stream == SNDRV_PCM_STREAM_PLAYBACK; int ret = 0; mutex_lock(&hcp->lock); @@ -404,7 +406,7 @@ static int hdmi_codec_startup(struct snd_pcm_substream *substream, goto err; } - if (hcp->hcd.ops->get_eld) { + if (tx && hcp->hcd.ops->get_eld) { ret = hcp->hcd.ops->get_eld(dai->dev->parent, hcp->hcd.data, hcp->eld, sizeof(hcp->eld)); if (ret) @@ -660,14 +662,20 @@ static int hdmi_dai_probe(struct snd_soc_dai *dai) { struct snd_soc_dapm_context *dapm; struct hdmi_codec_daifmt *daifmt; - struct snd_soc_dapm_route route = { - .sink = "TX", - .source = dai->driver->playback.stream_name, + struct snd_soc_dapm_route route[] = { + { + .sink = "TX", + .source = dai->driver->playback.stream_name, + }, + { + .sink = dai->driver->capture.stream_name, + .source = "RX", + }, }; int ret; dapm = snd_soc_component_get_dapm(dai->component); - ret = snd_soc_dapm_add_routes(dapm, &route, 1); + ret = snd_soc_dapm_add_routes(dapm, route, 2); if (ret) return ret; @@ -757,6 +765,14 @@ static const struct snd_soc_dai_driver hdmi_i2s_dai = { .formats = I2S_FORMATS, .sig_bits = 24, }, + .capture = { + .stream_name = "Capture", + .channels_min = 2, + .channels_max = 8, + .rates = HDMI_RATES, + .formats = I2S_FORMATS, + .sig_bits = 24, + }, .ops = &hdmi_codec_i2s_dai_ops, .pcm_new = hdmi_codec_pcm_new, }; @@ -773,6 +789,13 @@ static const struct snd_soc_dai_driver hdmi_spdif_dai = { .rates = HDMI_RATES, .formats = SPDIF_FORMATS, }, + .capture = { + .stream_name = "Capture", + .channels_min = 2, + .channels_max = 2, + .rates = HDMI_RATES, + .formats = SPDIF_FORMATS, + }, .ops = &hdmi_codec_spdif_dai_ops, .pcm_new = hdmi_codec_pcm_new, }; From 9bf69acb92d18bf65bd85e0a25f624b14991a3ca Mon Sep 17 00:00:00 2001 From: Stephan Gerhold Date: Thu, 7 Jan 2021 17:51:31 +0100 Subject: [PATCH 65/91] UPSTREAM: ASoC: hdmi-codec: Fix return value in hdmi_codec_set_jack() Sound is broken on the DragonBoard 410c (apq8016_sbc) since 5.10: hdmi-audio-codec hdmi-audio-codec.1.auto: ASoC: error at snd_soc_component_set_jack on hdmi-audio-codec.1.auto: -95 qcom-apq8016-sbc 7702000.sound: Failed to set jack: -95 ADV7533: ASoC: error at snd_soc_link_init on ADV7533: -95 hdmi-audio-codec hdmi-audio-codec.1.auto: ASoC: error at snd_soc_component_set_jack on hdmi-audio-codec.1.auto: -95 qcom-apq8016-sbc: probe of 7702000.sound failed with error -95 This happens because apq8016_sbc calls snd_soc_component_set_jack() on all codec DAIs and attempts to ignore failures with return code -ENOTSUPP. -ENOTSUPP is also excluded from error logging in soc_component_ret(). However, hdmi_codec_set_jack() returns -E*OP*NOTSUPP if jack detection is not supported, which is not handled in apq8016_sbc and soc_component_ret(). Make it return -ENOTSUPP instead to fix sound and silence the errors. Bug: 239396464 Change-Id: Id38ce1cdfc80daaac7d77212cecd29dd6fa4e877 Cc: Cheng-Yi Chiang Cc: Srinivas Kandagatla Fixes: 55c5cc63ab32 ("ASoC: hdmi-codec: Use set_jack ops to set jack") Signed-off-by: Stephan Gerhold Acked-by: Nicolin Chen Link: https://lore.kernel.org/r/20210107165131.2535-1-stephan@gerhold.net Signed-off-by: Mark Brown (cherry picked from commit 2a0435df963f996ca870a2ef1cbf1773dc0ea25a) Signed-off-by: Sugar Zhang --- sound/soc/codecs/hdmi-codec.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sound/soc/codecs/hdmi-codec.c b/sound/soc/codecs/hdmi-codec.c index d5fcc4db8284..0f3ac22f2cf8 100644 --- a/sound/soc/codecs/hdmi-codec.c +++ b/sound/soc/codecs/hdmi-codec.c @@ -717,7 +717,7 @@ static int hdmi_codec_set_jack(struct snd_soc_component *component, void *data) { struct hdmi_codec_priv *hcp = snd_soc_component_get_drvdata(component); - int ret = -EOPNOTSUPP; + int ret = -ENOTSUPP; if (hcp->hcd.ops->hook_plugged_cb) { hcp->jack = jack; From 49e502f0c0483e3f4adad82bbedaabdb1a1df9e5 Mon Sep 17 00:00:00 2001 From: Sia Jee Heng Date: Thu, 4 Feb 2021 09:42:55 +0800 Subject: [PATCH 66/91] UPSTREAM: ASoC: codec: hdmi-codec: Support IEC958 encoded PCM format Existing hdmi-codec driver only support standard pcm format. Support of IEC958 encoded format pass from ALSA IEC958 plugin is needed so that the IEC958 encoded data can be streamed to the HDMI chip. Bug: 239396464 Change-Id: I01516e34605e380995b5312273035a0d000d36f1 Signed-off-by: Sia Jee Heng Link: https://lore.kernel.org/r/20210204014258.10197-2-jee.heng.sia@intel.com Signed-off-by: Mark Brown Signed-off-by: Sugar Zhang (cherry picked from commit 28785f548d18e6d52785a1172e5c176784ce74cd) --- include/sound/hdmi-codec.h | 5 +++++ sound/soc/codecs/hdmi-codec.c | 4 +++- 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/include/sound/hdmi-codec.h b/include/sound/hdmi-codec.h index b55970859a13..4b3a1d374b90 100644 --- a/include/sound/hdmi-codec.h +++ b/include/sound/hdmi-codec.h @@ -34,6 +34,11 @@ struct hdmi_codec_daifmt { unsigned int frame_clk_inv:1; unsigned int bit_clk_master:1; unsigned int frame_clk_master:1; + /* bit_fmt could be standard PCM format or + * IEC958 encoded format. ALSA IEC958 plugin will pass + * IEC958_SUBFRAME format to the underneath driver. + */ + snd_pcm_format_t bit_fmt; }; /* diff --git a/sound/soc/codecs/hdmi-codec.c b/sound/soc/codecs/hdmi-codec.c index 0f3ac22f2cf8..422539f933de 100644 --- a/sound/soc/codecs/hdmi-codec.c +++ b/sound/soc/codecs/hdmi-codec.c @@ -489,6 +489,7 @@ static int hdmi_codec_hw_params(struct snd_pcm_substream *substream, hp.sample_rate = params_rate(params); hp.channels = params_channels(params); + cf->bit_fmt = params_format(params); return hcp->hcd.ops->hw_params(dai->dev->parent, hcp->hcd.data, cf, &hp); } @@ -617,7 +618,8 @@ static const struct snd_soc_dai_ops hdmi_codec_spdif_dai_ops = { SNDRV_PCM_FMTBIT_S20_3LE | SNDRV_PCM_FMTBIT_S20_3BE |\ SNDRV_PCM_FMTBIT_S24_3LE | SNDRV_PCM_FMTBIT_S24_3BE |\ SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S24_BE |\ - SNDRV_PCM_FMTBIT_S32_LE | SNDRV_PCM_FMTBIT_S32_BE) + SNDRV_PCM_FMTBIT_S32_LE | SNDRV_PCM_FMTBIT_S32_BE |\ + SNDRV_PCM_FMTBIT_IEC958_SUBFRAME_LE) static int hdmi_codec_pcm_new(struct snd_soc_pcm_runtime *rtd, struct snd_soc_dai *dai) From 5a2c4a5d1e944d92469b5f594806f0b48e36b45a Mon Sep 17 00:00:00 2001 From: Pierre-Louis Bossart Date: Fri, 12 Mar 2021 12:22:33 -0600 Subject: [PATCH 67/91] UPSTREAM: ASoC: hdmi-codec: remove useless initialization Fix cppcheck warning: sound/soc/codecs/hdmi-codec.c:745:5: style: Redundant initialization for 'cf'. The initialized value is overwritten before it is read. [redundantInitialization] cf = dai->playback_dma_data; ^ sound/soc/codecs/hdmi-codec.c:738:31: note: cf is initialized struct hdmi_codec_daifmt *cf = dai->playback_dma_data; ^ sound/soc/codecs/hdmi-codec.c:745:5: note: cf is overwritten cf = dai->playback_dma_data; ^ Bug: 239396464 Change-Id: Ia903635862e043207929827afcaeb531e6344283 Signed-off-by: Pierre-Louis Bossart Link: https://lore.kernel.org/r/20210312182246.5153-11-pierre-louis.bossart@linux.intel.com Signed-off-by: Mark Brown Signed-off-by: Sugar Zhang (cherry picked from commit 3c011ef344cddd15be0a9b2256f7886f6b5eeec5) --- sound/soc/codecs/hdmi-codec.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sound/soc/codecs/hdmi-codec.c b/sound/soc/codecs/hdmi-codec.c index 422539f933de..83e74ddccf59 100644 --- a/sound/soc/codecs/hdmi-codec.c +++ b/sound/soc/codecs/hdmi-codec.c @@ -735,7 +735,7 @@ static int hdmi_codec_set_jack(struct snd_soc_component *component, static int hdmi_dai_spdif_probe(struct snd_soc_dai *dai) { - struct hdmi_codec_daifmt *cf = dai->playback_dma_data; + struct hdmi_codec_daifmt *cf; int ret; ret = hdmi_dai_probe(dai); From 8b4bb1bca07739138f1c669a42390eef6bb21af7 Mon Sep 17 00:00:00 2001 From: Pierre-Louis Bossart Date: Fri, 12 Mar 2021 12:22:34 -0600 Subject: [PATCH 68/91] UPSTREAM: ASoC: hdmi-codec: remove unused spk_mask member fix cppcheck warning: sound/soc/codecs/hdmi-codec.c:25:16: style: struct member 'hdmi_codec_channel_map_table::spk_mask' is never used. [unusedStructMember] unsigned long spk_mask; /* speaker position bit mask */ ^ Bug: 239396464 Change-Id: I235b7757db88bfbd059ad0f9795908fbfbb1cfdb Signed-off-by: Pierre-Louis Bossart Link: https://lore.kernel.org/r/20210312182246.5153-12-pierre-louis.bossart@linux.intel.com Signed-off-by: Mark Brown Signed-off-by: Sugar Zhang (cherry picked from commit 9ad869fee5c598d914fa5cf8fb26f5e106e90956) --- sound/soc/codecs/hdmi-codec.c | 1 - 1 file changed, 1 deletion(-) diff --git a/sound/soc/codecs/hdmi-codec.c b/sound/soc/codecs/hdmi-codec.c index 83e74ddccf59..1567ba196ab9 100644 --- a/sound/soc/codecs/hdmi-codec.c +++ b/sound/soc/codecs/hdmi-codec.c @@ -22,7 +22,6 @@ struct hdmi_codec_channel_map_table { unsigned char map; /* ALSA API channel map position */ - unsigned long spk_mask; /* speaker position bit mask */ }; /* From 580d2e7c78b2ff138214efed227d5c7e8c2d05ed Mon Sep 17 00:00:00 2001 From: Maxime Ripard Date: Tue, 25 May 2021 15:23:43 +0200 Subject: [PATCH 69/91] UPSTREAM: ALSA: doc: Clarify IEC958 controls iface The doc currently mentions that the IEC958 Playback Default should be exposed on the PCM iface, and the Playback Mask on the mixer iface. It's a bit confusing to advise to have two related controls on two separate ifaces, and it looks like the drivers that currently expose those controls use any combination of the mixer and PCM ifaces. Let's try to clarify the situation a bit, and encourage to at least have the controls on the same iface. Bug: 239396464 Change-Id: Ie0fb033564972f74154c378c644c581dc4d06dfa Signed-off-by: Maxime Ripard Reviewed-by: Takashi Iwai Link: https://lore.kernel.org/r/20210525132354.297468-2-maxime@cerno.tech Signed-off-by: Sugar Zhang (cherry picked from commit aa7899537a4ec63ac3d58c9ece945c2750d22168) --- .../sound/kernel-api/writing-an-alsa-driver.rst | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/Documentation/sound/kernel-api/writing-an-alsa-driver.rst b/Documentation/sound/kernel-api/writing-an-alsa-driver.rst index 73bbd59afc33..690c5238f904 100644 --- a/Documentation/sound/kernel-api/writing-an-alsa-driver.rst +++ b/Documentation/sound/kernel-api/writing-an-alsa-driver.rst @@ -3508,14 +3508,15 @@ field must be set, though). “IEC958 Playback Con Mask” is used to return the bit-mask for the IEC958 status bits of consumer mode. Similarly, “IEC958 Playback Pro Mask” -returns the bitmask for professional mode. They are read-only controls, -and are defined as MIXER controls (iface = -``SNDRV_CTL_ELEM_IFACE_MIXER``). +returns the bitmask for professional mode. They are read-only controls. Meanwhile, “IEC958 Playback Default” control is defined for getting and -setting the current default IEC958 bits. Note that this one is usually -defined as a PCM control (iface = ``SNDRV_CTL_ELEM_IFACE_PCM``), -although in some places it's defined as a MIXER control. +setting the current default IEC958 bits. + +Due to historical reasons, both variants of the Playback Mask and the +Playback Default controls can be implemented on either a +``SNDRV_CTL_ELEM_IFACE_PCM`` or a ``SNDRV_CTL_ELEM_IFACE_MIXER`` iface. +Drivers should expose the mask and default on the same iface though. In addition, you can define the control switches to enable/disable or to set the raw bit mode. The implementation will depend on the chip, but From 4c6eb3db8a8b1e55ead67df54863b8ea8eab5dd1 Mon Sep 17 00:00:00 2001 From: Maxime Ripard Date: Tue, 25 May 2021 15:23:44 +0200 Subject: [PATCH 70/91] UPSTREAM: ALSA: iec958: Split status creation and fill In some situations, like a codec probe, we need to provide an IEC status default but don't have access to the sampling rate and width yet since no stream has been configured yet. Each and every driver has its own default, whereas the core iec958 code also has some buried in the snd_pcm_create_iec958_consumer functions. Let's split these functions in two to provide a default that doesn't rely on the sampling rate and width, and another function to fill them when available. Bug: 239396464 Change-Id: I277899145367b219b337bc796f2faee8c4917082 Signed-off-by: Maxime Ripard Reviewed-by: Takashi Iwai Link: https://lore.kernel.org/r/20210525132354.297468-3-maxime@cerno.tech Signed-off-by: Sugar Zhang (cherry picked from commit 9eafc11f921b8cb7d7e28ab1fdcf6b92fcbcb0be) --- include/sound/pcm_iec958.h | 8 ++ sound/core/pcm_iec958.c | 176 ++++++++++++++++++++++++++++--------- 2 files changed, 141 insertions(+), 43 deletions(-) diff --git a/include/sound/pcm_iec958.h b/include/sound/pcm_iec958.h index 0939aa45e2fe..64e84441cde1 100644 --- a/include/sound/pcm_iec958.h +++ b/include/sound/pcm_iec958.h @@ -4,6 +4,14 @@ #include +int snd_pcm_create_iec958_consumer_default(u8 *cs, size_t len); + +int snd_pcm_fill_iec958_consumer(struct snd_pcm_runtime *runtime, u8 *cs, + size_t len); + +int snd_pcm_fill_iec958_consumer_hw_params(struct snd_pcm_hw_params *params, + u8 *cs, size_t len); + int snd_pcm_create_iec958_consumer(struct snd_pcm_runtime *runtime, u8 *cs, size_t len); diff --git a/sound/core/pcm_iec958.c b/sound/core/pcm_iec958.c index f9a211cc1f2c..7a1b816f67cc 100644 --- a/sound/core/pcm_iec958.c +++ b/sound/core/pcm_iec958.c @@ -9,41 +9,85 @@ #include #include -static int create_iec958_consumer(uint rate, uint sample_width, - u8 *cs, size_t len) +/** + * snd_pcm_create_iec958_consumer_default - create default consumer format IEC958 channel status + * @cs: channel status buffer, at least four bytes + * @len: length of channel status buffer + * + * Create the consumer format channel status data in @cs of maximum size + * @len. When relevant, the configuration-dependant bits will be set as + * unspecified. + * + * Drivers should then call einter snd_pcm_fill_iec958_consumer() or + * snd_pcm_fill_iec958_consumer_hw_params() to replace these unspecified + * bits by their actual values. + * + * Drivers may wish to tweak the contents of the buffer after creation. + * + * Returns: length of buffer, or negative error code if something failed. + */ +int snd_pcm_create_iec958_consumer_default(u8 *cs, size_t len) { - unsigned int fs, ws; - if (len < 4) return -EINVAL; - switch (rate) { - case 32000: - fs = IEC958_AES3_CON_FS_32000; - break; - case 44100: - fs = IEC958_AES3_CON_FS_44100; - break; - case 48000: - fs = IEC958_AES3_CON_FS_48000; - break; - case 88200: - fs = IEC958_AES3_CON_FS_88200; - break; - case 96000: - fs = IEC958_AES3_CON_FS_96000; - break; - case 176400: - fs = IEC958_AES3_CON_FS_176400; - break; - case 192000: - fs = IEC958_AES3_CON_FS_192000; - break; - default: + memset(cs, 0, len); + + cs[0] = IEC958_AES0_CON_NOT_COPYRIGHT | IEC958_AES0_CON_EMPHASIS_NONE; + cs[1] = IEC958_AES1_CON_GENERAL; + cs[2] = IEC958_AES2_CON_SOURCE_UNSPEC | IEC958_AES2_CON_CHANNEL_UNSPEC; + cs[3] = IEC958_AES3_CON_CLOCK_1000PPM | IEC958_AES3_CON_FS_NOTID; + + if (len > 4) + cs[4] = IEC958_AES4_CON_WORDLEN_NOTID; + + return len; +} +EXPORT_SYMBOL_GPL(snd_pcm_create_iec958_consumer_default); + +static int fill_iec958_consumer(uint rate, uint sample_width, + u8 *cs, size_t len) +{ + if (len < 4) return -EINVAL; + + if ((cs[3] & IEC958_AES3_CON_FS) == IEC958_AES3_CON_FS_NOTID) { + unsigned int fs; + + switch (rate) { + case 32000: + fs = IEC958_AES3_CON_FS_32000; + break; + case 44100: + fs = IEC958_AES3_CON_FS_44100; + break; + case 48000: + fs = IEC958_AES3_CON_FS_48000; + break; + case 88200: + fs = IEC958_AES3_CON_FS_88200; + break; + case 96000: + fs = IEC958_AES3_CON_FS_96000; + break; + case 176400: + fs = IEC958_AES3_CON_FS_176400; + break; + case 192000: + fs = IEC958_AES3_CON_FS_192000; + break; + default: + return -EINVAL; + } + + cs[3] &= ~IEC958_AES3_CON_FS; + cs[3] |= fs; } - if (len > 4) { + if (len > 4 && + (cs[4] & IEC958_AES4_CON_WORDLEN) == IEC958_AES4_CON_WORDLEN_NOTID) { + unsigned int ws; + switch (sample_width) { case 16: ws = IEC958_AES4_CON_WORDLEN_20_16; @@ -64,21 +108,58 @@ static int create_iec958_consumer(uint rate, uint sample_width, default: return -EINVAL; } + + cs[4] &= ~IEC958_AES4_CON_WORDLEN; + cs[4] |= ws; } - memset(cs, 0, len); - - cs[0] = IEC958_AES0_CON_NOT_COPYRIGHT | IEC958_AES0_CON_EMPHASIS_NONE; - cs[1] = IEC958_AES1_CON_GENERAL; - cs[2] = IEC958_AES2_CON_SOURCE_UNSPEC | IEC958_AES2_CON_CHANNEL_UNSPEC; - cs[3] = IEC958_AES3_CON_CLOCK_1000PPM | fs; - - if (len > 4) - cs[4] = ws; - return len; } +/** + * snd_pcm_fill_iec958_consumer - Fill consumer format IEC958 channel status + * @runtime: pcm runtime structure with ->rate filled in + * @cs: channel status buffer, at least four bytes + * @len: length of channel status buffer + * + * Fill the unspecified bits in an IEC958 status bits array using the + * parameters of the PCM runtime @runtime. + * + * Drivers may wish to tweak the contents of the buffer after its been + * filled. + * + * Returns: length of buffer, or negative error code if something failed. + */ +int snd_pcm_fill_iec958_consumer(struct snd_pcm_runtime *runtime, + u8 *cs, size_t len) +{ + return fill_iec958_consumer(runtime->rate, + snd_pcm_format_width(runtime->format), + cs, len); +} +EXPORT_SYMBOL_GPL(snd_pcm_fill_iec958_consumer); + +/** + * snd_pcm_fill_iec958_consumer_hw_params - Fill consumer format IEC958 channel status + * @params: the hw_params instance for extracting rate and sample format + * @cs: channel status buffer, at least four bytes + * @len: length of channel status buffer + * + * Fill the unspecified bits in an IEC958 status bits array using the + * parameters of the PCM hardware parameters @params. + * + * Drivers may wish to tweak the contents of the buffer after its been + * filled.. + * + * Returns: length of buffer, or negative error code if something failed. + */ +int snd_pcm_fill_iec958_consumer_hw_params(struct snd_pcm_hw_params *params, + u8 *cs, size_t len) +{ + return fill_iec958_consumer(params_rate(params), params_width(params), cs, len); +} +EXPORT_SYMBOL_GPL(snd_pcm_fill_iec958_consumer_hw_params); + /** * snd_pcm_create_iec958_consumer - create consumer format IEC958 channel status * @runtime: pcm runtime structure with ->rate filled in @@ -95,9 +176,13 @@ static int create_iec958_consumer(uint rate, uint sample_width, int snd_pcm_create_iec958_consumer(struct snd_pcm_runtime *runtime, u8 *cs, size_t len) { - return create_iec958_consumer(runtime->rate, - snd_pcm_format_width(runtime->format), - cs, len); + int ret; + + ret = snd_pcm_create_iec958_consumer_default(cs, len); + if (ret < 0) + return ret; + + return snd_pcm_fill_iec958_consumer(runtime, cs, len); } EXPORT_SYMBOL(snd_pcm_create_iec958_consumer); @@ -117,7 +202,12 @@ EXPORT_SYMBOL(snd_pcm_create_iec958_consumer); int snd_pcm_create_iec958_consumer_hw_params(struct snd_pcm_hw_params *params, u8 *cs, size_t len) { - return create_iec958_consumer(params_rate(params), params_width(params), - cs, len); + int ret; + + ret = snd_pcm_create_iec958_consumer_default(cs, len); + if (ret < 0) + return ret; + + return fill_iec958_consumer(params_rate(params), params_width(params), cs, len); } EXPORT_SYMBOL(snd_pcm_create_iec958_consumer_hw_params); From c0c2f6962d948f716dd506e1b91f5ab52e6362d8 Mon Sep 17 00:00:00 2001 From: Maxime Ripard Date: Tue, 25 May 2021 15:23:45 +0200 Subject: [PATCH 71/91] UPSTREAM: ASoC: hdmi-codec: Rework to support more controls We're going to add more controls to support the IEC958 output, so let's rework the control registration a bit to support more of them. Bug: 239396464 Change-Id: Ia8c0bf8c997638b5a121ae7356fa1eb27746036f Signed-off-by: Maxime Ripard Acked-by: Mark Brown Link: https://lore.kernel.org/r/20210525132354.297468-4-maxime@cerno.tech Signed-off-by: Sugar Zhang (cherry picked from commit 366b45b974481bea9603843d308aded519aab7dc) --- sound/soc/codecs/hdmi-codec.c | 41 ++++++++++++++++++++++------------- 1 file changed, 26 insertions(+), 15 deletions(-) diff --git a/sound/soc/codecs/hdmi-codec.c b/sound/soc/codecs/hdmi-codec.c index 1567ba196ab9..65bde6f0ea1c 100644 --- a/sound/soc/codecs/hdmi-codec.c +++ b/sound/soc/codecs/hdmi-codec.c @@ -620,21 +620,23 @@ static const struct snd_soc_dai_ops hdmi_codec_spdif_dai_ops = { SNDRV_PCM_FMTBIT_S32_LE | SNDRV_PCM_FMTBIT_S32_BE |\ SNDRV_PCM_FMTBIT_IEC958_SUBFRAME_LE) +struct snd_kcontrol_new hdmi_codec_controls[] = { + { + .access = (SNDRV_CTL_ELEM_ACCESS_READ | + SNDRV_CTL_ELEM_ACCESS_VOLATILE), + .iface = SNDRV_CTL_ELEM_IFACE_PCM, + .name = "ELD", + .info = hdmi_eld_ctl_info, + .get = hdmi_eld_ctl_get, + }, +}; + static int hdmi_codec_pcm_new(struct snd_soc_pcm_runtime *rtd, struct snd_soc_dai *dai) { struct snd_soc_dai_driver *drv = dai->driver; struct hdmi_codec_priv *hcp = snd_soc_dai_get_drvdata(dai); - struct snd_kcontrol *kctl; - struct snd_kcontrol_new hdmi_eld_ctl = { - .access = SNDRV_CTL_ELEM_ACCESS_READ | - SNDRV_CTL_ELEM_ACCESS_VOLATILE, - .iface = SNDRV_CTL_ELEM_IFACE_PCM, - .name = "ELD", - .info = hdmi_eld_ctl_info, - .get = hdmi_eld_ctl_get, - .device = rtd->pcm->device, - }; + unsigned int i; int ret; ret = snd_pcm_add_chmap_ctls(rtd->pcm, SNDRV_PCM_STREAM_PLAYBACK, @@ -651,12 +653,21 @@ static int hdmi_codec_pcm_new(struct snd_soc_pcm_runtime *rtd, hcp->chmap_info->chmap = hdmi_codec_stereo_chmaps; hcp->chmap_idx = HDMI_CODEC_CHMAP_IDX_UNKNOWN; - /* add ELD ctl with the device number corresponding to the PCM stream */ - kctl = snd_ctl_new1(&hdmi_eld_ctl, dai->component); - if (!kctl) - return -ENOMEM; + for (i = 0; i < ARRAY_SIZE(hdmi_codec_controls); i++) { + struct snd_kcontrol *kctl; - return snd_ctl_add(rtd->card->snd_card, kctl); + /* add ELD ctl with the device number corresponding to the PCM stream */ + kctl = snd_ctl_new1(&hdmi_codec_controls[i], dai->component); + if (!kctl) + return -ENOMEM; + + kctl->id.device = rtd->pcm->device; + ret = snd_ctl_add(rtd->card->snd_card, kctl); + if (ret < 0) + return ret; + } + + return 0; } static int hdmi_dai_probe(struct snd_soc_dai *dai) From 4ad97b395f94bc0f546f27bbe9b8a62321f49ad3 Mon Sep 17 00:00:00 2001 From: Maxime Ripard Date: Tue, 25 May 2021 15:23:46 +0200 Subject: [PATCH 72/91] UPSTREAM: ASoC: hdmi-codec: Add iec958 controls The IEC958 status bits can be exposed and modified by the userspace through dedicated ALSA controls. This patch implements those controls for the hdmi-codec driver. It relies on a default value being setup at probe time that can later be overridden by the control put. The hw_params callback is then called with a buffer filled with the proper bits for the current parameters being passed on so the underlying driver can just reuse those bits as is. Bug: 239396464 Change-Id: I99f37b7e74655687e73a75ba19fd2de8041f8646 Signed-off-by: Maxime Ripard Acked-by: Mark Brown Link: https://lore.kernel.org/r/20210525132354.297468-5-maxime@cerno.tech Signed-off-by: Sugar Zhang (cherry picked from commit 7a8e1d44211e16eb394b7b9e0b236ee1503a3ad3) --- sound/soc/codecs/hdmi-codec.c | 66 +++++++++++++++++++++++++++++++++-- 1 file changed, 64 insertions(+), 2 deletions(-) diff --git a/sound/soc/codecs/hdmi-codec.c b/sound/soc/codecs/hdmi-codec.c index 65bde6f0ea1c..a0834b784814 100644 --- a/sound/soc/codecs/hdmi-codec.c +++ b/sound/soc/codecs/hdmi-codec.c @@ -277,6 +277,7 @@ struct hdmi_codec_priv { bool busy; struct snd_soc_jack *jack; unsigned int jack_status; + u8 iec_status[5]; }; static const struct snd_soc_dapm_widget hdmi_widgets[] = { @@ -385,6 +386,47 @@ static int hdmi_codec_chmap_ctl_get(struct snd_kcontrol *kcontrol, return 0; } +static int hdmi_codec_iec958_info(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_info *uinfo) +{ + uinfo->type = SNDRV_CTL_ELEM_TYPE_IEC958; + uinfo->count = 1; + return 0; +} + +static int hdmi_codec_iec958_default_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct snd_soc_component *component = snd_kcontrol_chip(kcontrol); + struct hdmi_codec_priv *hcp = snd_soc_component_get_drvdata(component); + + memcpy(ucontrol->value.iec958.status, hcp->iec_status, + sizeof(hcp->iec_status)); + + return 0; +} + +static int hdmi_codec_iec958_default_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct snd_soc_component *component = snd_kcontrol_chip(kcontrol); + struct hdmi_codec_priv *hcp = snd_soc_component_get_drvdata(component); + + memcpy(hcp->iec_status, ucontrol->value.iec958.status, + sizeof(hcp->iec_status)); + + return 0; +} + +static int hdmi_codec_iec958_mask_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + memset(ucontrol->value.iec958.status, 0xff, + sizeof_field(struct hdmi_codec_priv, iec_status)); + + return 0; +} + static int hdmi_codec_startup(struct snd_pcm_substream *substream, struct snd_soc_dai *dai) { @@ -459,8 +501,9 @@ static int hdmi_codec_hw_params(struct snd_pcm_substream *substream, params_width(params), params_rate(params), params_channels(params)); - ret = snd_pcm_create_iec958_consumer_hw_params(params, hp.iec.status, - sizeof(hp.iec.status)); + memcpy(hp.iec.status, hcp->iec_status, sizeof(hp.iec.status)); + ret = snd_pcm_fill_iec958_consumer_hw_params(params, hp.iec.status, + sizeof(hp.iec.status)); if (ret < 0) { dev_err(dai->dev, "Creating IEC958 channel status failed %d\n", ret); @@ -621,6 +664,20 @@ static const struct snd_soc_dai_ops hdmi_codec_spdif_dai_ops = { SNDRV_PCM_FMTBIT_IEC958_SUBFRAME_LE) struct snd_kcontrol_new hdmi_codec_controls[] = { + { + .access = SNDRV_CTL_ELEM_ACCESS_READ, + .iface = SNDRV_CTL_ELEM_IFACE_PCM, + .name = SNDRV_CTL_NAME_IEC958("", PLAYBACK, MASK), + .info = hdmi_codec_iec958_info, + .get = hdmi_codec_iec958_mask_get, + }, + { + .iface = SNDRV_CTL_ELEM_IFACE_PCM, + .name = SNDRV_CTL_NAME_IEC958("", PLAYBACK, DEFAULT), + .info = hdmi_codec_iec958_info, + .get = hdmi_codec_iec958_default_get, + .put = hdmi_codec_iec958_default_put, + }, { .access = (SNDRV_CTL_ELEM_ACCESS_READ | SNDRV_CTL_ELEM_ACCESS_VOLATILE), @@ -873,6 +930,11 @@ static int hdmi_codec_probe(struct platform_device *pdev) hcp->hcd = *hcd; mutex_init(&hcp->lock); + ret = snd_pcm_create_iec958_consumer_default(hcp->iec_status, + sizeof(hcp->iec_status)); + if (ret < 0) + return ret; + daidrv = devm_kcalloc(dev, dai_count, sizeof(*daidrv), GFP_KERNEL); if (!daidrv) return -ENOMEM; From 9eda09e511f648adf90efdb805e2429bf5bc25cb Mon Sep 17 00:00:00 2001 From: Maxime Ripard Date: Tue, 25 May 2021 15:23:47 +0200 Subject: [PATCH 73/91] UPSTREAM: ASoC: hdmi-codec: Add a prepare hook The IEC958 status bit is usually set by the userspace after hw_params has been called, so in order to use whatever is set by the userspace, we need to implement the prepare hook. Let's add it to the hdmi_codec_ops, and mandate that either prepare or hw_params is implemented. Bug: 239396464 Change-Id: I06ccde5d8185955bb60783b597f0205811460968 Signed-off-by: Maxime Ripard Acked-by: Mark Brown Link: https://lore.kernel.org/r/20210525132354.297468-6-maxime@cerno.tech Signed-off-by: Sugar Zhang (cherry picked from commit 2fef64eec23a0840c97977b16dd8919afaffa876) --- include/sound/hdmi-codec.h | 12 +++- sound/soc/codecs/hdmi-codec.c | 110 +++++++++++++++++++++++++++------- 2 files changed, 98 insertions(+), 24 deletions(-) diff --git a/include/sound/hdmi-codec.h b/include/sound/hdmi-codec.h index 4b3a1d374b90..4fc733c8c570 100644 --- a/include/sound/hdmi-codec.h +++ b/include/sound/hdmi-codec.h @@ -65,12 +65,22 @@ struct hdmi_codec_ops { /* * Configures HDMI-encoder for audio stream. - * Mandatory + * Having either prepare or hw_params is mandatory. */ int (*hw_params)(struct device *dev, void *data, struct hdmi_codec_daifmt *fmt, struct hdmi_codec_params *hparms); + /* + * Configures HDMI-encoder for audio stream. Can be called + * multiple times for each setup. + * + * Having either prepare or hw_params is mandatory. + */ + int (*prepare)(struct device *dev, void *data, + struct hdmi_codec_daifmt *fmt, + struct hdmi_codec_params *hparms); + /* * Shuts down the audio stream. * Mandatory diff --git a/sound/soc/codecs/hdmi-codec.c b/sound/soc/codecs/hdmi-codec.c index a0834b784814..a67c92032e11 100644 --- a/sound/soc/codecs/hdmi-codec.c +++ b/sound/soc/codecs/hdmi-codec.c @@ -481,6 +481,42 @@ static void hdmi_codec_shutdown(struct snd_pcm_substream *substream, mutex_unlock(&hcp->lock); } +static int hdmi_codec_fill_codec_params(struct snd_soc_dai *dai, + unsigned int sample_width, + unsigned int sample_rate, + unsigned int channels, + struct hdmi_codec_params *hp) +{ + struct hdmi_codec_priv *hcp = snd_soc_dai_get_drvdata(dai); + int idx; + + /* Select a channel allocation that matches with ELD and pcm channels */ + idx = hdmi_codec_get_ch_alloc_table_idx(hcp, channels); + if (idx < 0) { + dev_err(dai->dev, "Not able to map channels to speakers (%d)\n", + idx); + hcp->chmap_idx = HDMI_CODEC_CHMAP_IDX_UNKNOWN; + return idx; + } + + memset(hp, 0, sizeof(*hp)); + + hdmi_audio_infoframe_init(&hp->cea); + hp->cea.channels = channels; + hp->cea.coding_type = HDMI_AUDIO_CODING_TYPE_STREAM; + hp->cea.sample_size = HDMI_AUDIO_SAMPLE_SIZE_STREAM; + hp->cea.sample_frequency = HDMI_AUDIO_SAMPLE_FREQUENCY_STREAM; + hp->cea.channel_allocation = hdmi_codec_channel_alloc[idx].ca_id; + + hp->sample_width = sample_width; + hp->sample_rate = sample_rate; + hp->channels = channels; + + hcp->chmap_idx = hdmi_codec_channel_alloc[idx].ca_id; + + return 0; +} + static int hdmi_codec_hw_params(struct snd_pcm_substream *substream, struct snd_pcm_hw_params *params, struct snd_soc_dai *dai) @@ -495,12 +531,23 @@ static int hdmi_codec_hw_params(struct snd_pcm_substream *substream, .dig_subframe = { 0 }, } }; - int ret, idx; + int ret; + + if (!hcp->hcd.ops->hw_params) + return 0; dev_dbg(dai->dev, "%s() width %d rate %d channels %d\n", __func__, params_width(params), params_rate(params), params_channels(params)); + ret = hdmi_codec_fill_codec_params(dai, + params_width(params), + params_rate(params), + params_channels(params), + &hp); + if (ret < 0) + return ret; + memcpy(hp.iec.status, hcp->iec_status, sizeof(hp.iec.status)); ret = snd_pcm_fill_iec958_consumer_hw_params(params, hp.iec.status, sizeof(hp.iec.status)); @@ -510,32 +557,47 @@ static int hdmi_codec_hw_params(struct snd_pcm_substream *substream, return ret; } - hdmi_audio_infoframe_init(&hp.cea); - hp.cea.channels = params_channels(params); - hp.cea.coding_type = HDMI_AUDIO_CODING_TYPE_STREAM; - hp.cea.sample_size = HDMI_AUDIO_SAMPLE_SIZE_STREAM; - hp.cea.sample_frequency = HDMI_AUDIO_SAMPLE_FREQUENCY_STREAM; - - /* Select a channel allocation that matches with ELD and pcm channels */ - idx = hdmi_codec_get_ch_alloc_table_idx(hcp, hp.cea.channels); - if (idx < 0) { - dev_err(dai->dev, "Not able to map channels to speakers (%d)\n", - idx); - hcp->chmap_idx = HDMI_CODEC_CHMAP_IDX_UNKNOWN; - return idx; - } - hp.cea.channel_allocation = hdmi_codec_channel_alloc[idx].ca_id; - hcp->chmap_idx = hdmi_codec_channel_alloc[idx].ca_id; - - hp.sample_width = params_width(params); - hp.sample_rate = params_rate(params); - hp.channels = params_channels(params); - cf->bit_fmt = params_format(params); return hcp->hcd.ops->hw_params(dai->dev->parent, hcp->hcd.data, cf, &hp); } +static int hdmi_codec_prepare(struct snd_pcm_substream *substream, + struct snd_soc_dai *dai) +{ + struct hdmi_codec_priv *hcp = snd_soc_dai_get_drvdata(dai); + struct hdmi_codec_daifmt *cf = dai->playback_dma_data; + struct snd_pcm_runtime *runtime = substream->runtime; + unsigned int channels = runtime->channels; + unsigned int width = snd_pcm_format_width(runtime->format); + unsigned int rate = runtime->rate; + struct hdmi_codec_params hp; + int ret; + + if (!hcp->hcd.ops->prepare) + return 0; + + dev_dbg(dai->dev, "%s() width %d rate %d channels %d\n", __func__, + width, rate, channels); + + ret = hdmi_codec_fill_codec_params(dai, width, rate, channels, &hp); + if (ret < 0) + return ret; + + memcpy(hp.iec.status, hcp->iec_status, sizeof(hp.iec.status)); + ret = snd_pcm_fill_iec958_consumer(runtime, hp.iec.status, + sizeof(hp.iec.status)); + if (ret < 0) { + dev_err(dai->dev, "Creating IEC958 channel status failed %d\n", + ret); + return ret; + } + + cf->bit_fmt = runtime->format; + return hcp->hcd.ops->prepare(dai->dev->parent, hcp->hcd.data, + cf, &hp); +} + static int hdmi_codec_i2s_set_fmt(struct snd_soc_dai *dai, unsigned int fmt) { @@ -627,6 +689,7 @@ static const struct snd_soc_dai_ops hdmi_codec_i2s_dai_ops = { .startup = hdmi_codec_startup, .shutdown = hdmi_codec_shutdown, .hw_params = hdmi_codec_hw_params, + .prepare = hdmi_codec_prepare, .set_fmt = hdmi_codec_i2s_set_fmt, .mute_stream = hdmi_codec_mute, }; @@ -917,7 +980,8 @@ static int hdmi_codec_probe(struct platform_device *pdev) } dai_count = hcd->i2s + hcd->spdif; - if (dai_count < 1 || !hcd->ops || !hcd->ops->hw_params || + if (dai_count < 1 || !hcd->ops || + (!hcd->ops->hw_params && !hcd->ops->prepare) || !hcd->ops->audio_shutdown) { dev_err(dev, "%s: Invalid parameters\n", __func__); return -EINVAL; From a09241c6dd68754fd47d27e4a37d685017a804c1 Mon Sep 17 00:00:00 2001 From: Jiapeng Chong Date: Wed, 16 Jun 2021 13:55:41 +0800 Subject: [PATCH 74/91] UPSTREAM: ASoC: hdmi-codec: make hdmi_codec_controls static This symbol is not used outside of hdmi-codec.c, so marks it static. Fix the following sparse warning: sound/soc/codecs/hdmi-codec.c:750:25: warning: symbol 'hdmi_codec_controls' was not declared. Should it be static? Bug: 239396464 Change-Id: I6569284ef557fee683afb9031e5cc1b5684a1c30 Reported-by: Abaci Robot Signed-off-by: Jiapeng Chong Link: https://lore.kernel.org/r/1623822941-3077-1-git-send-email-jiapeng.chong@linux.alibaba.com Signed-off-by: Mark Brown Signed-off-by: Sugar Zhang (cherry picked from commit e99d7c69fd4c18e7319f8aab8e252b12130796bf) --- sound/soc/codecs/hdmi-codec.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sound/soc/codecs/hdmi-codec.c b/sound/soc/codecs/hdmi-codec.c index a67c92032e11..d0fb04ae372c 100644 --- a/sound/soc/codecs/hdmi-codec.c +++ b/sound/soc/codecs/hdmi-codec.c @@ -726,7 +726,7 @@ static const struct snd_soc_dai_ops hdmi_codec_spdif_dai_ops = { SNDRV_PCM_FMTBIT_S32_LE | SNDRV_PCM_FMTBIT_S32_BE |\ SNDRV_PCM_FMTBIT_IEC958_SUBFRAME_LE) -struct snd_kcontrol_new hdmi_codec_controls[] = { +static struct snd_kcontrol_new hdmi_codec_controls[] = { { .access = SNDRV_CTL_ELEM_ACCESS_READ, .iface = SNDRV_CTL_ELEM_IFACE_PCM, From a3e70ff5bf641146e7064acf6b2e7f2382c8397a Mon Sep 17 00:00:00 2001 From: Peifeng Li Date: Thu, 4 Aug 2022 11:56:17 +0800 Subject: [PATCH 75/91] ANDROID: GKI: Update symbols to symbol list Leaf changes summary: 17 artifacts changed Changed leaf types summary: 0 leaf type changed Removed/Changed/Added functions summary: 0 Removed, 0 Changed, 10 Added functions Removed/Changed/Added variables summary: 0 Removed, 0 Changed, 7 Added variables 10 Added functions: [A] 'function int __page_mapcount(page*)' [A] 'function int __traceiter_android_vh_add_page_to_lrulist(void*, page*, bool, lru_list)' [A] 'function int __traceiter_android_vh_del_page_from_lrulist(void*, page*, bool, lru_list)' [A] 'function int __traceiter_android_vh_do_traversal_lruvec(void*, lruvec*)' [A] 'function int __traceiter_android_vh_mark_page_accessed(void*, page*)' [A] 'function int __traceiter_android_vh_page_should_be_protected(void*, page*, bool*)' [A] 'function int __traceiter_android_vh_show_mapcount_pages(void*, void*)' [A] 'function int __traceiter_android_vh_update_page_mapcount(void*, page*, bool, bool, bool*, bool*)' [A] 'function void do_traversal_all_lruvec()' [A] 'function lruvec* page_to_lruvec(page*, pg_data_t*)' 7 Added variables: [A] 'tracepoint __tracepoint_android_vh_add_page_to_lrulist' [A] 'tracepoint __tracepoint_android_vh_del_page_from_lrulist' [A] 'tracepoint __tracepoint_android_vh_do_traversal_lruvec' [A] 'tracepoint __tracepoint_android_vh_mark_page_accessed' [A] 'tracepoint __tracepoint_android_vh_page_should_be_protected' [A] 'tracepoint __tracepoint_android_vh_show_mapcount_pages' [A] 'tracepoint __tracepoint_android_vh_update_page_mapcount' Bug: 193384408 Signed-off-by: Peifeng Li Change-Id: I13191de69a284241056cafc0e9100e5c7c72d272 --- android/abi_gki_aarch64.xml | 1192 ++++++++++++++++----------------- android/abi_gki_aarch64_oplus | 17 + 2 files changed, 594 insertions(+), 615 deletions(-) diff --git a/android/abi_gki_aarch64.xml b/android/abi_gki_aarch64.xml index 07d6024e1fca..dabe6fed31c8 100644 --- a/android/abi_gki_aarch64.xml +++ b/android/abi_gki_aarch64.xml @@ -208,6 +208,7 @@ + @@ -390,6 +391,7 @@ + @@ -446,7 +448,9 @@ + + @@ -490,6 +494,7 @@ + @@ -510,6 +515,7 @@ + @@ -552,6 +558,7 @@ + @@ -586,6 +593,7 @@ + @@ -1820,6 +1828,7 @@ + @@ -3804,6 +3813,7 @@ + @@ -6194,6 +6204,7 @@ + @@ -6250,7 +6261,9 @@ + + @@ -6297,6 +6310,7 @@ + @@ -6318,6 +6332,7 @@ + @@ -6370,6 +6385,7 @@ + @@ -6407,6 +6423,7 @@ + @@ -6960,7 +6977,7 @@ - + @@ -7840,6 +7857,15 @@ + + + + + + + + + @@ -14399,24 +14425,24 @@ - + - + - + - + - + - + - + @@ -14920,89 +14946,6 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - @@ -43890,23 +43833,7 @@ - - - - - - - - - - - - - - - - - + @@ -48196,7 +48123,6 @@ - @@ -51245,6 +51171,7 @@ + @@ -53076,13 +53003,6 @@ - - - - - - - @@ -61206,6 +61126,7 @@ + @@ -65643,13 +65564,6 @@ - - - - - - - @@ -67583,14 +67497,7 @@ - - - - - - - - + @@ -68136,6 +68043,7 @@ + @@ -90119,7 +90027,6 @@ - @@ -92614,7 +92521,6 @@ - @@ -101748,12 +101654,6 @@ - - - - - - @@ -109926,7 +109826,6 @@ - @@ -116177,12 +116076,16 @@ + + + + - - + + @@ -116675,12 +116578,12 @@ - - - - - - + + + + + + @@ -116695,11 +116598,11 @@ - - - - - + + + + + @@ -116753,10 +116656,10 @@ - - - - + + + + @@ -117116,9 +117019,9 @@ - - - + + + @@ -117127,14 +117030,14 @@ - - - + + + - - - + + + @@ -117181,19 +117084,19 @@ - - - - - + + + + + - - - - - - + + + + + + @@ -117280,6 +117183,13 @@ + + + + + + + @@ -117304,18 +117214,18 @@ - - - - - + + + + + - - - - - + + + + + @@ -117355,148 +117265,148 @@ - - - - - + + + + + - - - - + + + + - - - + + + - - - - - + + + + + - - - - + + + + - - - - - + + + + + - - - - + + + + - - - - - - + + + + + + - - - - + + + + - - - - - - - - - - - + + - - - - - + + + + + + + + - - - - - - + + + + - - - - + + + + + + - - - - + + + + - - - - - + + + + - - - - + + + + + - - - - - - + + + + - - - + + + + + + - - - - - + + + - - - - - + + + + + + + + + + + + @@ -117519,16 +117429,16 @@ - - - - + + + + - - - - + + + + @@ -117575,25 +117485,25 @@ - - - - - - - - + + + + + + + + - - - + + + - - - - + + + + @@ -117659,6 +117569,13 @@ + + + + + + + @@ -117666,20 +117583,25 @@ + + + + + - - - - - - - - + + + + + + + + @@ -117712,10 +117634,10 @@ - - - - + + + + @@ -117724,22 +117646,22 @@ - + + + + + + + + + + + + - - - - - - - - - - - - - - + + + @@ -117818,11 +117740,11 @@ - - - - - + + + + + @@ -117836,11 +117758,11 @@ - - - - - + + + + + @@ -117912,11 +117834,11 @@ - - - - - + + + + + @@ -117941,6 +117863,11 @@ + + + + + @@ -117948,77 +117875,77 @@ - - - - - - - - - - - - + - - - - + + + + - - - - - - - - - - - - - - - - - - - - - + - - + + - - - - - + + + - - - + + + - - - - - + + + - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -118062,19 +117989,25 @@ - - - - - - - + + + + - - - - + + + + + + + + + + + + + @@ -118106,14 +118039,14 @@ - - - - - - - - + + + + + + + + @@ -118172,16 +118105,16 @@ - - - - + + + + - - - - + + + + @@ -118214,15 +118147,15 @@ - - - + + + - - - - + + + + @@ -118309,16 +118242,21 @@ + + + + + - - - - + + + + @@ -118326,10 +118264,10 @@ - - - - + + + + @@ -118371,10 +118309,10 @@ - - - - + + + + @@ -118401,12 +118339,12 @@ - - - - - - + + + + + + @@ -118425,41 +118363,41 @@ - - - - - + + + + + - - - - - + + + + + - - - - - - - - + + + + + + + + - - - - - + + + + + - - - - + + + + @@ -118528,6 +118466,15 @@ + + + + + + + + + @@ -118973,10 +118920,10 @@ - + - + @@ -118984,7 +118931,7 @@ - + @@ -119022,7 +118969,7 @@ - + @@ -119044,10 +118991,10 @@ - + - - + + @@ -119059,8 +119006,8 @@ - - + + @@ -119075,42 +119022,43 @@ + - - + + - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + - - + + @@ -119118,9 +119066,9 @@ - - - + + + @@ -119131,19 +119079,21 @@ + + - + - + - - - + + + @@ -119157,11 +119107,11 @@ - + - + @@ -119174,33 +119124,35 @@ - + + - - - - - - - - - - - - + + + + + + + + + + + + - + - - + + + @@ -119208,7 +119160,7 @@ - + @@ -119226,16 +119178,16 @@ - - + + - - + + @@ -119251,33 +119203,34 @@ + - + - + - - + + - + - - - - - + + + + + @@ -119288,13 +119241,14 @@ + - + @@ -119469,9 +119423,9 @@ - - - + + + @@ -119857,9 +119811,9 @@ - - - + + + @@ -125630,6 +125584,9 @@ + + + @@ -133301,14 +133258,14 @@ - - + + - + - + @@ -133599,8 +133556,8 @@ - - + + @@ -133631,7 +133588,7 @@ - + @@ -135797,6 +135754,11 @@ + + + + + @@ -135830,19 +135792,19 @@ - - - - - + + + + + - - - - - - + + + + + + @@ -138780,9 +138742,9 @@ - - - + + + @@ -138797,10 +138759,10 @@ - - - - + + + + @@ -143516,11 +143478,11 @@ - - - - - + + + + + @@ -146359,8 +146321,8 @@ - - + + @@ -146793,8 +146755,8 @@ - - + + @@ -146808,15 +146770,15 @@ - - + + - - - - - + + + + + @@ -146944,17 +146906,17 @@ - - + + - - + + - - - + + + diff --git a/android/abi_gki_aarch64_oplus b/android/abi_gki_aarch64_oplus index 12bfddf46340..4f25e9accef0 100644 --- a/android/abi_gki_aarch64_oplus +++ b/android/abi_gki_aarch64_oplus @@ -681,6 +681,7 @@ dma_unmap_sg_attrs do_exit do_wait_intr_irq + do_traversal_all_lruvec down down_interruptible down_read @@ -1802,10 +1803,12 @@ page_endio __page_file_index __page_file_mapping + __page_mapcount page_get_link page_mapping __page_pinner_migration_failed page_symlink + page_to_lruvec panic panic_notifier_list panic_timeout @@ -2819,6 +2822,13 @@ __traceiter_android_vh_mutex_wait_start __traceiter_android_vh_override_creds __traceiter_android_vh_page_referenced_check_bypass + __traceiter_android_vh_page_should_be_protected + __traceiter_android_vh_mark_page_accessed + __traceiter_android_vh_show_mapcount_pages + __traceiter_android_vh_do_traversal_lruvec + __traceiter_android_vh_update_page_mapcount + __traceiter_android_vh_add_page_to_lrulist + __traceiter_android_vh_del_page_from_lrulist __traceiter_android_vh_pcplist_add_cma_pages_bypass __traceiter_android_vh_prepare_update_load_avg_se __traceiter_android_vh_printk_hotplug @@ -3035,6 +3045,13 @@ __tracepoint_android_vh_mutex_wait_start __tracepoint_android_vh_override_creds __tracepoint_android_vh_page_referenced_check_bypass + __tracepoint_android_vh_page_should_be_protected + __tracepoint_android_vh_mark_page_accessed + __tracepoint_android_vh_show_mapcount_pages + __tracepoint_android_vh_do_traversal_lruvec + __tracepoint_android_vh_update_page_mapcount + __tracepoint_android_vh_add_page_to_lrulist + __tracepoint_android_vh_del_page_from_lrulist __tracepoint_android_vh_pcplist_add_cma_pages_bypass __tracepoint_android_vh_prepare_update_load_avg_se __tracepoint_android_vh_printk_hotplug From e7ed66854e89e526d16ac519775d24b307212113 Mon Sep 17 00:00:00 2001 From: Kever Yang Date: Tue, 19 Jul 2022 11:47:08 +0800 Subject: [PATCH 76/91] ANDROID: GKI: rockchip: Update symbols for drm Leaf changes summary: 8 artifacts changed Changed leaf types summary: 0 leaf type changed Removed/Changed/Added functions summary: 0 Removed, 0 Changed, 8 Added functions Removed/Changed/Added variables summary: 0 Removed, 0 Changed, 0 Added variable 8 Added functions: [A] 'function long long unsigned int drm_format_info_min_pitch(const drm_format_info*, int, unsigned int)' [A] 'function int drm_mm_reserve_node(drm_mm*, drm_mm_node*)' [A] 'function ssize_t hdmi_avi_infoframe_pack_only(const hdmi_avi_infoframe*, void*, size_t)' [A] 'function bool mipi_dsi_packet_format_is_short(u8)' [A] 'function int snd_pcm_create_iec958_consumer_default(u8*, size_t)' [A] 'function int snd_pcm_fill_iec958_consumer(snd_pcm_runtime*, u8*, size_t)' [A] 'function int snd_pcm_fill_iec958_consumer_hw_params(snd_pcm_hw_params*, u8*, size_t)' [A] 'function void tcpm_tcpc_reset(tcpm_port*)' Bug: 239396464 Signed-off-by: Kever Yang Change-Id: Ia21a2437d2e86783948d75d400c96e45651cdd65 --- android/abi_gki_aarch64.xml | 11274 +++++++++++++++-------------- android/abi_gki_aarch64_rockchip | 72 +- 2 files changed, 5750 insertions(+), 5596 deletions(-) diff --git a/android/abi_gki_aarch64.xml b/android/abi_gki_aarch64.xml index dabe6fed31c8..c9e67ad7887b 100644 --- a/android/abi_gki_aarch64.xml +++ b/android/abi_gki_aarch64.xml @@ -2104,6 +2104,7 @@ + @@ -2206,6 +2207,7 @@ + @@ -2762,6 +2764,7 @@ + @@ -3451,6 +3454,7 @@ + @@ -4884,7 +4888,10 @@ + + + @@ -5240,6 +5247,7 @@ + @@ -7350,6 +7358,7 @@ + @@ -9136,9 +9145,9 @@ - - - + + + @@ -9159,6 +9168,7 @@ + @@ -9244,6 +9254,7 @@ + @@ -11621,6 +11632,7 @@ + @@ -12155,7 +12167,6 @@ - @@ -12562,8 +12573,8 @@ - - + + @@ -13874,7 +13885,6 @@ - @@ -14644,9 +14654,9 @@ - + - + @@ -15385,6 +15395,12 @@ + + + + + + @@ -15879,9 +15895,6 @@ - - - @@ -16101,29 +16114,7 @@ - - - - - - - - - - - - - - - - - - - - - - - + @@ -19028,6 +19019,7 @@ + @@ -19418,7 +19410,11 @@ - + + + + + @@ -20373,6 +20369,7 @@ + @@ -20570,6 +20567,7 @@ + @@ -21010,6 +21008,14 @@ + + + + + + + + @@ -22093,7 +22099,6 @@ - @@ -22835,11 +22840,6 @@ - - - - - @@ -25032,7 +25032,7 @@ - + @@ -25071,6 +25071,7 @@ + @@ -25257,7 +25258,6 @@ - @@ -25563,23 +25563,7 @@ - - - - - - - - - - - - - - - - - + @@ -26242,7 +26226,7 @@ - + @@ -26399,7 +26383,7 @@ - + @@ -26620,6 +26604,7 @@ + @@ -26697,7 +26682,7 @@ - + @@ -26754,7 +26739,6 @@ - @@ -27131,7 +27115,6 @@ - @@ -27313,36 +27296,36 @@ - + - + - + - + - + - + - + - + - + - + - + @@ -27770,7 +27753,7 @@ - + @@ -28719,6 +28702,7 @@ + @@ -31583,6 +31567,9 @@ + + + @@ -31696,7 +31683,6 @@ - @@ -32591,9 +32577,9 @@ - - - + + + @@ -33494,6 +33480,7 @@ + @@ -33748,68 +33735,7 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + @@ -34324,9 +34250,10 @@ + - + @@ -34738,7 +34665,6 @@ - @@ -34937,7 +34863,7 @@ - + @@ -36574,6 +36500,10 @@ + + + + @@ -38505,6 +38435,7 @@ + @@ -39295,8 +39226,8 @@ - - + + @@ -40270,6 +40201,17 @@ + + + + + + + + + + + @@ -40550,9 +40492,9 @@ - - - + + + @@ -41085,7 +41027,6 @@ - @@ -42069,6 +42010,7 @@ + @@ -44542,6 +44484,13 @@ + + + + + + + @@ -44571,6 +44520,11 @@ + + + + + @@ -45018,12 +44972,12 @@ - - - - - - + + + + + + @@ -45154,6 +45108,7 @@ + @@ -45935,21 +45890,21 @@ - + - + - + - + - + - + @@ -48054,8 +48009,8 @@ - - + + @@ -48419,35 +48374,7 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + @@ -48629,7 +48556,6 @@ - @@ -49014,14 +48940,7 @@ - - - - - - - - + @@ -49668,6 +49587,11 @@ + + + + + @@ -50079,7 +50003,7 @@ - + @@ -50795,7 +50719,56 @@ - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -51136,7 +51109,6 @@ - @@ -52086,7 +52058,7 @@ - + @@ -52931,6 +52903,7 @@ + @@ -53373,6 +53346,7 @@ + @@ -53423,7 +53397,6 @@ - @@ -54034,23 +54007,7 @@ - - - - - - - - - - - - - - - - - + @@ -54412,6 +54369,7 @@ + @@ -55343,9 +55301,9 @@ - - - + + + @@ -56071,7 +56029,6 @@ - @@ -56656,7 +56613,7 @@ - + @@ -57124,7 +57081,7 @@ - + @@ -58238,7 +58195,6 @@ - @@ -59376,6 +59332,7 @@ + @@ -59839,6 +59796,11 @@ + + + + + @@ -61063,7 +61025,44 @@ - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -62291,7 +62290,65 @@ - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -63788,6 +63845,7 @@ + @@ -64103,17 +64161,7 @@ - - - - - - - - - - - + @@ -65193,7 +65241,7 @@ - + @@ -65715,10 +65763,10 @@ - - - - + + + + @@ -65769,11 +65817,6 @@ - - - - - @@ -66092,6 +66135,7 @@ + @@ -67013,6 +67057,11 @@ + + + + + @@ -68042,6 +68091,11 @@ + + + + + @@ -68504,7 +68558,7 @@ - + @@ -70598,7 +70652,6 @@ - @@ -71309,7 +71362,6 @@ - @@ -73048,10 +73100,9 @@ - - - + + @@ -73170,6 +73221,7 @@ + @@ -73495,6 +73547,7 @@ + @@ -73859,8 +73912,8 @@ - - + + @@ -73932,7 +73985,6 @@ - @@ -74400,7 +74452,38 @@ - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -74511,7 +74594,7 @@ - + @@ -76066,7 +76149,6 @@ - @@ -77204,6 +77286,7 @@ + @@ -78631,12 +78714,12 @@ - + - + @@ -79721,12 +79804,12 @@ - - - - - - + + + + + + @@ -81024,7 +81107,6 @@ - @@ -81264,6 +81346,7 @@ + @@ -82009,7 +82092,6 @@ - @@ -82614,7 +82696,6 @@ - @@ -82703,6 +82784,11 @@ + + + + + @@ -82725,6 +82811,7 @@ + @@ -83185,7 +83272,7 @@ - + @@ -83261,6 +83348,14 @@ + + + + + + + + @@ -86383,7 +86478,6 @@ - @@ -87002,7 +87096,7 @@ - + @@ -87684,9 +87778,9 @@ - - - + + + @@ -88155,7 +88249,26 @@ - + + + + + + + + + + + + + + + + + + + + @@ -88180,7 +88293,7 @@ - + @@ -88205,7 +88318,6 @@ - @@ -88244,7 +88356,6 @@ - @@ -89681,7 +89792,7 @@ - + @@ -90328,8 +90439,8 @@ - - + + @@ -91576,11 +91687,6 @@ - - - - - @@ -92015,20 +92121,7 @@ - - - - - - - - - - - - - - + @@ -92584,7 +92677,7 @@ - + @@ -92759,7 +92852,7 @@ - + @@ -93054,7 +93147,6 @@ - @@ -93195,12 +93287,12 @@ - + - + @@ -93292,6 +93384,7 @@ + @@ -94766,6 +94859,7 @@ + @@ -96051,7 +96145,7 @@ - + @@ -96563,7 +96657,7 @@ - + @@ -96609,7 +96703,7 @@ - + @@ -97047,7 +97141,7 @@ - + @@ -97755,6 +97849,9 @@ + + + @@ -98994,7 +99091,6 @@ - @@ -99270,8 +99366,8 @@ - - + + @@ -99491,8 +99587,8 @@ - - + + @@ -100649,7 +100745,6 @@ - @@ -101641,14 +101736,7 @@ - - - - - - - - + @@ -103133,6 +103221,9 @@ + + + @@ -103145,9 +103236,6 @@ - - - @@ -103171,7 +103259,7 @@ - + @@ -103312,8 +103400,8 @@ - - + + @@ -103914,6 +104002,7 @@ + @@ -104182,7 +104271,6 @@ - @@ -104776,9 +104864,6 @@ - - - @@ -108237,7 +108322,6 @@ - @@ -108252,6 +108336,20 @@ + + + + + + + + + + + + + + @@ -108586,7 +108684,6 @@ - @@ -112528,6 +112625,11 @@ + + + + + @@ -112855,7 +112957,6 @@ - @@ -114644,6 +114745,7 @@ + @@ -114728,6 +114830,7 @@ + @@ -114851,8 +114954,8 @@ - - + + @@ -115450,7 +115553,6 @@ - @@ -119507,9 +119609,9 @@ - - - + + + @@ -119520,33 +119622,33 @@ - - - - - + + + + + - - - - - + + + + + - - - - - + + + + + - - - + + + - - - + + + @@ -119556,27 +119658,27 @@ - - - + + + - - - + + + - - - + + + - - - + + + @@ -119586,8 +119688,8 @@ - - + + @@ -119606,8 +119708,8 @@ - - + + @@ -119623,57 +119725,57 @@ - - + + - - + + - - + + - - + + - - + + - - + + - - - + + + - - + + - - + + @@ -119684,16 +119786,16 @@ - - + + - - + + @@ -119721,12 +119823,12 @@ - - - - - - + + + + + + @@ -119743,9 +119845,9 @@ - - - + + + @@ -119761,29 +119863,29 @@ - - + + - - - - - + + + + + - - - + + + - - + + - - - + + + @@ -119800,15 +119902,15 @@ - - - + + + - - - + + + @@ -119821,22 +119923,22 @@ - - - - + + + + - - - - + + + + - - - - + + + + @@ -119915,13 +120017,13 @@ - - - - - - - + + + + + + + @@ -119930,29 +120032,29 @@ - - - + + + - - - - - - + + + + + + - - - - + + + + - - + + @@ -119994,11 +120096,11 @@ - - - - - + + + + + @@ -120018,14 +120120,14 @@ - - + + - - - - + + + + @@ -120048,15 +120150,15 @@ - - - - + + + + - - - + + + @@ -120064,11 +120166,11 @@ - - - - - + + + + + @@ -120119,21 +120221,21 @@ - - - - - + + + + + - - - - - - + + + + + + - - + + @@ -120174,18 +120276,18 @@ - - + + - - - + + + - - - + + + @@ -120218,17 +120320,17 @@ - - - - + + + + - - - - - + + + + + @@ -120239,47 +120341,47 @@ - - - - + + + + - - + + - - - + + + - - - + + + - - - + + + - - + + - - - - + + + + - - + + - - + + @@ -120289,15 +120391,15 @@ - - + + - - - - - + + + + + @@ -120310,9 +120412,9 @@ - - - + + + @@ -120321,49 +120423,49 @@ - - - - + + + + - - - - - - - + + + + + + + - - - - + + + + - - - - - + + + + + - - - - + + + + - - - - - + + + + + @@ -120373,10 +120475,10 @@ - - - - + + + + @@ -120426,17 +120528,17 @@ - - + + - - + + - - - + + + @@ -120471,10 +120573,10 @@ - - - - + + + + @@ -120506,13 +120608,13 @@ - - - + + + - - + + @@ -120543,8 +120645,8 @@ - - + + @@ -120553,8 +120655,8 @@ - - + + @@ -120576,8 +120678,8 @@ - - + + @@ -120624,8 +120726,8 @@ - - + + @@ -120647,14 +120749,14 @@ - - + + - - - - + + + + @@ -120690,9 +120792,9 @@ - - - + + + @@ -120841,16 +120943,16 @@ - - + + - - + + @@ -120899,42 +121001,42 @@ - - - - + + + + - - - - + + + + - - - - - - + + + + + + - - - + + + - - - - - - + + + + + + - - - + + + @@ -120955,31 +121057,31 @@ - - - - + + + + - - - + + + - - - + + + - - - + + + - - - - + + + + @@ -120997,9 +121099,9 @@ - - - + + + @@ -121047,67 +121149,67 @@ - - - - + + + + - - - - - + + + + + - - - - - - + + + + + + - - - - - - - + + + + + + + - - - - - - - - + + + + + + + + - - - - - - - - - + + + + + + + + + - - - - - - - - - - + + + + + + + + + + @@ -121123,16 +121225,16 @@ - - + + - - - - - - + + + + + + @@ -121153,22 +121255,22 @@ - - + + - - + + - - + + - - + + @@ -121192,23 +121294,23 @@ - - - + + + - - - - - + + + + + - - - - - + + + + + @@ -121218,8 +121320,8 @@ - - + + @@ -121232,8 +121334,8 @@ - - + + @@ -121303,9 +121405,9 @@ - - - + + + @@ -121349,11 +121451,11 @@ - - - - - + + + + + @@ -121369,19 +121471,19 @@ - - - + + + - - - + + + - - - + + + @@ -121413,9 +121515,9 @@ - - - + + + @@ -121504,14 +121606,14 @@ - - - + + + - - - + + + @@ -121523,47 +121625,47 @@ - - - + + + - - - - + + + + - - + + - - - - - + + + + + - - - - - + + + + + - - + + - - - - + + + + - - + + @@ -121576,30 +121678,30 @@ - - + + - - + + - - + + - - - + + + - - - + + + @@ -121608,48 +121710,48 @@ - - - + + + - - - + + + - - - + + + - - - + + + - - - + + + - - + + - - + + - - - + + + @@ -121660,8 +121762,8 @@ - - + + @@ -121779,8 +121881,8 @@ - - + + @@ -121888,28 +121990,28 @@ - - - + + + - - + + - - - - - + + + + + @@ -121920,13 +122022,13 @@ - - - - - - - + + + + + + + @@ -121937,11 +122039,11 @@ - - - - - + + + + + @@ -121953,11 +122055,11 @@ - - - - - + + + + + @@ -121976,8 +122078,8 @@ - - + + @@ -122014,10 +122116,10 @@ - - - - + + + + @@ -122055,22 +122157,22 @@ - - + + - - - - + + + + - - + + - - + + @@ -122081,9 +122183,9 @@ - - - + + + @@ -122102,15 +122204,15 @@ - - + + - - - - + + + + @@ -122121,9 +122223,9 @@ - - - + + + @@ -122184,8 +122286,8 @@ - - + + @@ -122216,18 +122318,18 @@ - - + + - - - + + + - - - + + + @@ -122239,8 +122341,8 @@ - - + + @@ -122256,9 +122358,9 @@ - - - + + + @@ -122291,12 +122393,12 @@ - - + + - - + + @@ -122307,23 +122409,23 @@ - - + + - - - + + + - - - - + + + + @@ -122338,9 +122440,9 @@ - - - + + + @@ -122359,8 +122461,8 @@ - - + + @@ -122380,58 +122482,58 @@ - - - + + + - - - + + + - - - - + + + + - - - - - + + + + + - - - - - + + + + + - + - + - - - + + + - - - - - + + + + + - - - - - + + + + + @@ -122480,12 +122582,12 @@ - - + + - - + + @@ -122514,10 +122616,10 @@ - - - - + + + + @@ -122572,42 +122674,42 @@ - - - - - - + + + + + + - - - - - - + + + + + + - - + + - - - + + + - - - + + + - + @@ -122650,10 +122752,10 @@ - - - - + + + + @@ -122661,9 +122763,9 @@ - - - + + + @@ -122673,7 +122775,7 @@ - + @@ -122694,8 +122796,8 @@ - - + + @@ -122716,22 +122818,22 @@ - - + + - - - + + + - - - + + + @@ -122781,11 +122883,11 @@ - - - - - + + + + + @@ -122793,44 +122895,44 @@ - - - - - + + + + + - - - - + + + + - - - - - + + + + + - - - - + + + + - - + + - - + + - - - - + + + + @@ -122851,8 +122953,8 @@ - - + + @@ -122877,18 +122979,18 @@ - - - + + + - - - + + + @@ -122905,9 +123007,9 @@ - - - + + + @@ -122918,11 +123020,11 @@ - - - - - + + + + + @@ -122932,11 +123034,11 @@ - - + + - + @@ -122958,17 +123060,17 @@ - - + + - - + + - - - + + + @@ -122976,22 +123078,22 @@ - - + + - - + + - - - - + + + + @@ -122999,9 +123101,9 @@ - - - + + + @@ -123032,12 +123134,12 @@ - - + + - - + + @@ -123046,7 +123148,7 @@ - + @@ -123077,11 +123179,11 @@ - - - - - + + + + + @@ -123091,17 +123193,17 @@ - - - + + + - - - - - - + + + + + + @@ -123113,12 +123215,12 @@ - - - - - - + + + + + + @@ -123155,11 +123257,11 @@ - - - - - + + + + + @@ -123169,11 +123271,11 @@ - - - - - + + + + + @@ -123205,9 +123307,9 @@ - - - + + + @@ -123218,8 +123320,8 @@ - - + + @@ -123229,9 +123331,9 @@ - - - + + + @@ -123240,11 +123342,11 @@ - - - - - + + + + + @@ -123257,16 +123359,16 @@ - - + + - - + + - - + + @@ -123287,8 +123389,8 @@ - - + + @@ -123330,49 +123432,49 @@ - - + + - - - - + + + + - - - + + + - - + + - - - + + + - - - + + + - - - + + + - - - + + + - - - + + + @@ -123394,9 +123496,9 @@ - - - + + + @@ -123409,9 +123511,9 @@ - - - + + + @@ -123433,10 +123535,10 @@ - - - - + + + + @@ -123467,15 +123569,15 @@ - - - - + + + + - - - + + + @@ -123495,8 +123597,8 @@ - - + + @@ -123512,8 +123614,8 @@ - - + + @@ -123521,13 +123623,13 @@ - - + + - - - + + + @@ -123538,9 +123640,9 @@ - - - + + + @@ -123557,16 +123659,16 @@ - - + + - - + + @@ -123591,9 +123693,9 @@ - - - + + + @@ -123683,9 +123785,9 @@ - - - + + + @@ -123698,17 +123800,17 @@ - - - - + + + + - - - - + + + + @@ -123716,10 +123818,10 @@ - - - - + + + + @@ -123727,9 +123829,9 @@ - - - + + + @@ -123754,11 +123856,11 @@ - - - - - + + + + + @@ -123830,20 +123932,20 @@ - - + + - - + + - - + + @@ -123856,8 +123958,8 @@ - - + + @@ -123879,12 +123981,12 @@ - - - - - - + + + + + + @@ -123893,40 +123995,40 @@ - - - + + + - - - - - - - + + + + + + + - - + + - - - + + + - - - - + + + + - - - - + + + + @@ -123961,28 +124063,28 @@ - - - + + + - - + + - - - - + + + + - - - + + + @@ -124004,10 +124106,10 @@ - - - - + + + + @@ -124029,11 +124131,11 @@ - - - - - + + + + + @@ -124056,15 +124158,15 @@ - - - + + + - - - - + + + + @@ -124081,14 +124183,14 @@ - - - + + + - - - + + + @@ -124117,22 +124219,22 @@ - - + + - - + + - - - - + + + + @@ -124155,10 +124257,10 @@ - - - - + + + + @@ -124166,15 +124268,15 @@ - - - - + + + + - - - + + + @@ -124281,11 +124383,11 @@ - - - - - + + + + + @@ -124483,29 +124585,29 @@ - - - - + + + + - - - + + + - - - - + + + + - - - - - + + + + + @@ -124515,10 +124617,10 @@ - - - - + + + + @@ -124557,14 +124659,14 @@ - - - - - - - - + + + + + + + + @@ -124577,9 +124679,9 @@ - - - + + + @@ -124612,8 +124714,8 @@ - - + + @@ -124680,14 +124782,14 @@ - - - + + + - - - + + + @@ -124695,10 +124797,10 @@ - - - - + + + + @@ -124751,15 +124853,15 @@ - - - - + + + + - - - + + + @@ -124858,16 +124960,16 @@ - - - + + + - - - - - + + + + + @@ -124923,46 +125025,46 @@ - - - + + + - - - - - + + + + + - - - - - + + + + + - - + + - - - - - + + + + + - - + + - - + + @@ -125071,9 +125173,9 @@ - - - + + + @@ -125095,17 +125197,17 @@ - - + + - - - + + + - - + + @@ -125113,15 +125215,15 @@ - - - + + + - - - - + + + + @@ -125132,34 +125234,34 @@ - - + + - - - - + + + + - - + + - - - + + + - - - - + + + + @@ -125171,9 +125273,9 @@ - - - + + + @@ -125181,8 +125283,8 @@ - - + + @@ -125193,15 +125295,15 @@ - + - - - - - - + + + + + + @@ -125213,13 +125315,13 @@ - - - - + + + + - - + + @@ -125239,10 +125341,10 @@ - - - - + + + + @@ -125400,46 +125502,46 @@ - - - + + + - - - + + + - - + + - - - - - + + + + + - - + + - - - + + + - - - - + + + + - - - - - + + + + + @@ -125572,8 +125674,8 @@ - - + + @@ -125617,8 +125719,8 @@ - - + + @@ -125630,8 +125732,8 @@ - - + + @@ -125642,8 +125744,8 @@ - - + + @@ -125813,9 +125915,9 @@ - - - + + + @@ -125825,62 +125927,62 @@ - - + + - - - + + + - - + + - - - + + + - - - - + + + + - - - + + + - - - + + + - - - + + + - - - + + + - - + + - - - + + + - - - + + + @@ -125898,14 +126000,14 @@ - - - + + + - - - + + + @@ -125940,13 +126042,13 @@ - - - - - - - + + + + + + + @@ -126170,62 +126272,62 @@ - - + + - - - + + + - - + + - - - - - + + + + + - - - + + + - - - + + + - - - + + + - - - + + + - - - + + + - - - + + + - - + + - - + + @@ -126241,15 +126343,15 @@ - - + + - - - - - + + + + + @@ -126260,10 +126362,10 @@ - - - - + + + + @@ -126301,8 +126403,8 @@ - - + + @@ -126310,9 +126412,9 @@ - - - + + + @@ -126349,9 +126451,9 @@ - - - + + + @@ -126360,8 +126462,8 @@ - - + + @@ -126369,19 +126471,19 @@ - - - - - + + + + + - - - - - - + + + + + + @@ -126389,20 +126491,20 @@ - - + + - - + + - - + + - - + + @@ -126415,17 +126517,17 @@ - - + + - - + + - - - + + + @@ -126472,19 +126574,19 @@ - - - - - - - + + + + + + + - - - + + + @@ -126492,17 +126594,17 @@ - - - + + + - - + + @@ -126520,20 +126622,20 @@ - - + + - - + + - - + + @@ -126546,11 +126648,11 @@ - - - - - + + + + + @@ -126561,33 +126663,33 @@ - - - + + + - - - - + + + + - - - - + + + + - - + + - - + + @@ -126887,23 +126989,23 @@ - - + + - - - - + + + + - - - + + + @@ -126919,12 +127021,12 @@ - - - - - - + + + + + + @@ -126976,20 +127078,26 @@ - - + + + + + + + + - - - - + + + + - - - - + + + + @@ -127144,10 +127252,10 @@ - - - - + + + + @@ -127197,9 +127305,9 @@ - - - + + + @@ -127328,19 +127436,19 @@ - - - + + + - - - + + + - - - + + + @@ -127441,8 +127549,8 @@ - - + + @@ -127464,9 +127572,9 @@ - - - + + + @@ -127494,8 +127602,13 @@ - - + + + + + + + @@ -127510,24 +127623,24 @@ - - + + - - - + + + - - - - + + + + - - - + + + @@ -127546,9 +127659,9 @@ - - - + + + @@ -127562,18 +127675,18 @@ - - + + - - - + + + - - - + + + @@ -127594,9 +127707,9 @@ - - - + + + @@ -127627,28 +127740,28 @@ - - + + - - + + - - - + + + - - - - + + + + - - - + + + @@ -127659,83 +127772,83 @@ - - - + + + - - - - + + + + - - - + + + - - + + - - - + + + - - + + - - + + - - - + + + - - + + - - - + + + - - + + - - + + - - + + - - - - + + + + - - - - + + + + @@ -127791,17 +127904,17 @@ - - + + - - + + - - - + + + @@ -127815,20 +127928,20 @@ - - + + - - + + - - + + @@ -127897,9 +128010,9 @@ - - - + + + @@ -127907,44 +128020,44 @@ - - + + - - - - - + + + + + - - - - - - - + + + + + + + - - - - + + + + - - - - + + + + - - - - - - + + + + + + @@ -127954,12 +128067,12 @@ - - - - - - + + + + + + @@ -127970,9 +128083,9 @@ - - - + + + @@ -127980,18 +128093,18 @@ - - - - + + + + - - - - - - - + + + + + + + @@ -128006,30 +128119,30 @@ - - - - - + + + + + - - - - - + + + + + - - - - - + + + + + - - - - + + + + @@ -128065,8 +128178,8 @@ - - + + @@ -128150,20 +128263,20 @@ - - + + - - - - - - - - - - + + + + + + + + + + @@ -128172,19 +128285,19 @@ - - - + + + - - - - + + + + - - - + + + @@ -128211,40 +128324,40 @@ - - - - + + + + - - + + - - + + - - - + + + - - - - + + + + - - - - + + + + @@ -128483,8 +128596,8 @@ - - + + @@ -128498,13 +128611,13 @@ - - + + - - - + + + @@ -128521,10 +128634,10 @@ - - - - + + + + @@ -128557,14 +128670,14 @@ - - - + + + - - - + + + @@ -128572,17 +128685,17 @@ - - - - + + + + - - + + @@ -128597,9 +128710,9 @@ - - - + + + @@ -128613,54 +128726,54 @@ - - - - + + + + - - + + - - + + - - + + - - - - + + + + - - - - + + + + - - + + - - + + - - - + + + - - + + @@ -128670,15 +128783,15 @@ - - - + + + - - - - + + + + @@ -128711,18 +128824,18 @@ - - - - + + + + - - - - - + + + + + @@ -128730,9 +128843,9 @@ - - - + + + @@ -128766,12 +128879,12 @@ - - + + - - + + @@ -128817,15 +128930,15 @@ - - - + + + - - - - + + + + @@ -128834,13 +128947,13 @@ - - - + + + - - + + @@ -128850,21 +128963,21 @@ - - - + + + - - - - + + + + - - - - + + + + @@ -128880,26 +128993,26 @@ - - + + - - - + + + - - + + - - - + + + @@ -128916,11 +129029,11 @@ - - + + - + @@ -128935,8 +129048,8 @@ - - + + @@ -128984,18 +129097,18 @@ - - - + + + - - + + - - - + + + @@ -129003,13 +129116,13 @@ - - + + - - - + + + @@ -129025,9 +129138,9 @@ - - - + + + @@ -129121,9 +129234,9 @@ - - - + + + @@ -129172,11 +129285,11 @@ - - - - - + + + + + @@ -129196,11 +129309,11 @@ - - - - - + + + + + @@ -129312,8 +129425,8 @@ - - + + @@ -129322,9 +129435,9 @@ - - - + + + @@ -129337,8 +129450,8 @@ - - + + @@ -129381,12 +129494,12 @@ - - + + - - + + @@ -129423,35 +129536,35 @@ - - + + - - - + + + - - - - - - - + + + + + + + - - - - - - + + + + + + - - - + + + @@ -129463,13 +129576,13 @@ - - - + + + - - + + @@ -129512,36 +129625,36 @@ - - - - - + + + + + - - - - - + + + + + - - - - + + + + - - - + + + - - - - + + + + - - + + @@ -129584,13 +129697,13 @@ - - - - - - - + + + + + + + @@ -129615,13 +129728,13 @@ - - - + + + - - + + @@ -129657,10 +129770,10 @@ - - - - + + + + @@ -129670,12 +129783,12 @@ - - + + - - + + @@ -129686,17 +129799,17 @@ - - - - - - - + + + + + + + - - + + @@ -129713,8 +129826,8 @@ - - + + @@ -129744,15 +129857,15 @@ - - + + - - - - - + + + + + @@ -129764,8 +129877,8 @@ - - + + @@ -129791,8 +129904,8 @@ - - + + @@ -129806,20 +129919,20 @@ - - + + - + - - - + + + @@ -129836,41 +129949,41 @@ - - - - + + + + - - - + + + - - - + + + - - - + + + - - + + - - + + - - - + + + @@ -129880,13 +129993,13 @@ - - + + - - - + + + @@ -129900,41 +130013,41 @@ - - - - - - + + + + + + - - + + - - - - - - + + + + + + - - - - - + + + + + - - - - - - - - + + + + + + + + @@ -129948,8 +130061,8 @@ - - + + @@ -129961,18 +130074,18 @@ - - + + - - - - + + + + @@ -129996,23 +130109,23 @@ - - - + + + - - - + + + - - - + + + - - + + @@ -130025,9 +130138,9 @@ - - - + + + @@ -130035,29 +130148,29 @@ - - - - + + + + - - + + - - - - - + + + + + - - - - - - + + + + + + @@ -130101,9 +130214,9 @@ - - - + + + @@ -130112,8 +130225,8 @@ - - + + @@ -130122,9 +130235,9 @@ - - - + + + @@ -130221,8 +130334,8 @@ - - + + @@ -130249,10 +130362,10 @@ - - - - + + + + @@ -130264,25 +130377,25 @@ - - - + + + - - + + - - + + - - + + - - + + @@ -130327,10 +130440,10 @@ - - + + - + @@ -130345,22 +130458,22 @@ - - - + + + - - - + + + - - + + - - + + @@ -130387,6 +130500,12 @@ + + + + + + @@ -130411,38 +130530,38 @@ - - - - + + + + - - - - - - - - + + + + + + + + - - + + - - + + - + - - + + @@ -130453,9 +130572,9 @@ - - - + + + @@ -130470,26 +130589,26 @@ - - + + - - - - + + + + - - - - - - + + + + + + - - + + @@ -130500,33 +130619,32 @@ - - - + + - - - + + + - - + + - - - - - + + + + + - - - - + + + + @@ -130541,28 +130659,28 @@ - - - - - + + + + + - - + + - - - - - + + + + + - - - - + + + + @@ -130584,18 +130702,18 @@ - - + + - - + + - - + + @@ -130618,12 +130736,12 @@ - - + + - - + + @@ -130660,9 +130778,9 @@ - - - + + + @@ -130697,81 +130815,81 @@ - - - + + + - - - + + + - - - - + + + + - - - - - - + + + + + + - - - - + + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + - - - - - + + + + + - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -130901,12 +131019,12 @@ - - + + - - + + @@ -130949,14 +131067,14 @@ - - + + - - - - + + + + @@ -130977,36 +131095,36 @@ - - - - - + + + + + - - + + - - - + + + - - - - - - + + + + + + - - - - - - + + + + + + @@ -131017,39 +131135,39 @@ - - + + - - - + + + - - - - + + + + - - - + + + - - + + - - - + + + - - - - + + + + @@ -131075,14 +131193,14 @@ - - + + - - - - + + + + @@ -131103,12 +131221,12 @@ - - + + - - + + @@ -131124,8 +131242,8 @@ - - + + @@ -131252,21 +131370,21 @@ - - - - - + + + + + - - - - - - - - + + + + + + + + @@ -131276,8 +131394,8 @@ - - + + @@ -131300,8 +131418,8 @@ - - + + @@ -131309,9 +131427,9 @@ - - - + + + @@ -131331,24 +131449,24 @@ - - - - + + + + - - - + + + - - - - + + + + @@ -131356,50 +131474,50 @@ - - - - - - + + + + + + - - - + + + - - + + - - + + - - - - + + + + - - - + + + - - - + + + - - - + + + @@ -131415,8 +131533,8 @@ - - + + @@ -131437,8 +131555,8 @@ - - + + @@ -131453,8 +131571,8 @@ - - + + @@ -131487,20 +131605,20 @@ - - + + - - + + - - + + @@ -131537,12 +131655,12 @@ - - + + - - + + @@ -131554,34 +131672,34 @@ - - + + - - - + + + - - - - + + + + - - - - + + + + - - - + + + - - + + @@ -131666,9 +131784,9 @@ - - - + + + @@ -131829,74 +131947,74 @@ - - - + + + - - + + - - - + + + - - + + - - - - - - + + + + + + - - - - - - + + + + + + - - - + + + - - - - - - - + + + + + + + - - - - - - + + + + + + - - - + + + - - - - + + + + - - - - + + + + @@ -131904,53 +132022,53 @@ - - - - + + + + - - - - - + + + + + - - - - + + + + - - + + - - + + - - - - - - + + + + + + - - - - - + + + + + @@ -131985,8 +132103,8 @@ - - + + @@ -132086,13 +132204,13 @@ - - - + + + - - + + @@ -132103,15 +132221,15 @@ - - - - - - - - - + + + + + + + + + @@ -132147,9 +132265,9 @@ - - - + + + @@ -132175,30 +132293,30 @@ - - - + + + - - - - + + + + - - - - + + + + - - - + + + @@ -132211,10 +132329,10 @@ - - - - + + + + @@ -132222,11 +132340,11 @@ - - - - - + + + + + @@ -132249,10 +132367,10 @@ - - - - + + + + @@ -132265,20 +132383,20 @@ - - - + + + - - - - + + + + - + - - + + @@ -132295,9 +132413,9 @@ - - - + + + @@ -132399,14 +132517,14 @@ - - - + + + - - + + @@ -132493,8 +132611,8 @@ - - + + @@ -132504,56 +132622,56 @@ - - + + - - - - - - - - - + + + + + + + + + - - + + - - - - - - - - - + + + + + + + + + - - + + - - + + - - + + - - + + - + @@ -132564,10 +132682,10 @@ - - - - + + + + @@ -132593,21 +132711,21 @@ - - - - + + + + - - - + + + - - - - + + + + @@ -132618,35 +132736,35 @@ - - - - - - - - + + + + + + + + - - + + - - - + + + - - - - + + + + - - - - + + + + @@ -132678,46 +132796,46 @@ - - - - + + + + - - - + + + - - + + - - + + - - - + + + - - - - - + + + + + - - + + - - - + + + @@ -132726,35 +132844,35 @@ - - - - + + + + - - - - + + + + - - - - + + + + - - - + + + - - + + - - + + @@ -132763,23 +132881,23 @@ - - - + + + - - - + + + - - - + + + @@ -132787,34 +132905,34 @@ - - - - + + + + - - - + + + - - - - + + + + - - - - + + + + - - - - - + + + + + @@ -132824,16 +132942,16 @@ - - - - + + + + - - - - + + + + @@ -132849,10 +132967,10 @@ - - - - + + + + @@ -132862,10 +132980,10 @@ - - - - + + + + @@ -132875,37 +132993,37 @@ - - - - + + + + - - - - - + + + + + - - - - - + + + + + - - - - + + + + - - - - - + + + + + @@ -132916,9 +133034,9 @@ - - - + + + @@ -132932,11 +133050,11 @@ - - - - - + + + + + @@ -132972,11 +133090,11 @@ - - + + - + @@ -132993,15 +133111,15 @@ - - + + - - + + - - + + @@ -133021,8 +133139,8 @@ - - + + @@ -133036,8 +133154,8 @@ - - + + @@ -133049,8 +133167,8 @@ - - + + @@ -133064,18 +133182,18 @@ - - - + + + - - - - + + + + - - + + @@ -133083,10 +133201,10 @@ - - - - + + + + @@ -133099,14 +133217,14 @@ - - - - + + + + - - + + @@ -133142,18 +133260,18 @@ - - - + + + - - - + + + @@ -133164,8 +133282,8 @@ - - + + @@ -133186,10 +133304,10 @@ - - - - + + + + @@ -133199,30 +133317,30 @@ - - - - - + + + + + - - + + - - + + - - - + + + - - + + @@ -133241,11 +133359,11 @@ - - - - - + + + + + @@ -133253,13 +133371,13 @@ - - + + - - + + @@ -133276,11 +133394,11 @@ - - - - - + + + + + @@ -133319,8 +133437,8 @@ - - + + @@ -133328,25 +133446,25 @@ - - - + + + - - + + - - - - + + + + - - - - + + + + @@ -133359,9 +133477,9 @@ - - - + + + @@ -133372,13 +133490,13 @@ - - + + - - - + + + @@ -133386,50 +133504,50 @@ - - - + + + - - + + - - + + - - - + + + - - - + + + - - - + + + - - - + + + - - + + - - + + - - - + + + @@ -133443,8 +133561,8 @@ - - + + @@ -133520,9 +133638,9 @@ - - - + + + @@ -133560,32 +133678,32 @@ - - + + - - - + + + - - - - + + + + - - - + + + - - - + + + - + @@ -133598,9 +133716,9 @@ - - - + + + @@ -133680,10 +133798,10 @@ - - - - + + + + @@ -133728,13 +133846,13 @@ - - - - - - - + + + + + + + @@ -133916,17 +134034,21 @@ + + + + - - + + - - + + @@ -133938,11 +134060,11 @@ - - - - - + + + + + @@ -133983,8 +134105,8 @@ - - + + @@ -134037,8 +134159,8 @@ - - + + @@ -134050,9 +134172,9 @@ - - - + + + @@ -134063,28 +134185,28 @@ - - - + + + - - - - - - + + + + + + - - + + - - - - - + + + + + @@ -134095,9 +134217,9 @@ - - - + + + @@ -134158,8 +134280,8 @@ - - + + @@ -134198,9 +134320,9 @@ - - - + + + @@ -134256,8 +134378,8 @@ - - + + @@ -134279,12 +134401,12 @@ - - + + - - + + @@ -134318,8 +134440,8 @@ - - + + @@ -134330,9 +134452,9 @@ - - - + + + @@ -134340,47 +134462,47 @@ - - + + - - - + + + - - + + - - + + - - + + - - + + - - + + - - - - - + + + + + @@ -134388,18 +134510,18 @@ - - - - + + + + - - + + @@ -134407,14 +134529,14 @@ - - - - + + + + - - - + + + @@ -134450,17 +134572,17 @@ - - + + - - - + + + @@ -134470,9 +134592,9 @@ - - - + + + @@ -134514,12 +134636,12 @@ - - + + - - + + @@ -134533,67 +134655,67 @@ - - - + + + - - + + - - + + - - + + - - + + - - - - - + + + + + - - + + - - + + - - + + - - + + - - + + - - - + + + - - - + + + @@ -134601,19 +134723,19 @@ - - + + - - + + - - - - - + + + + + @@ -134624,41 +134746,41 @@ - - - - + + + + - - - + + + - - + + - - - - - + + + + + - - + + - - + + @@ -134672,16 +134794,16 @@ - - - - + + + + - - - - + + + + @@ -134702,11 +134824,11 @@ - - - - - + + + + + @@ -134723,24 +134845,24 @@ - - - - + + + + - - - - - + + + + + - - - - - + + + + + @@ -134765,10 +134887,10 @@ - - - - + + + + @@ -134781,12 +134903,12 @@ - - + + - - + + @@ -134811,18 +134933,18 @@ - - - + + + - - + + - - - + + + @@ -134846,18 +134968,18 @@ - - - - - + + + + + - - - - - + + + + + @@ -134868,19 +134990,19 @@ - - - - + + + + - - + + - - - + + + @@ -134899,14 +135021,14 @@ - - - + + + - - - + + + @@ -134932,9 +135054,9 @@ - - - + + + @@ -134947,22 +135069,22 @@ - - - - + + + + - - + + - - + + @@ -134976,43 +135098,43 @@ - - + + - - - + + + - - - + + + - - - - - + + + + + - - - + + + - - - - - + + + + + @@ -135025,9 +135147,9 @@ - - - + + + @@ -135060,14 +135182,14 @@ - - - - + + + + - - + + @@ -135078,44 +135200,44 @@ - - - - + + + + - - - + + + - - + + - - - + + + - - - + + + - - - + + + - - - - + + + + @@ -135149,16 +135271,16 @@ - - - - - - + + + + + + - - - + + + @@ -135166,9 +135288,9 @@ - - - + + + @@ -135212,33 +135334,33 @@ - - - + + + - - - + + + - - + + - - + + - - - + + + - - - - + + + + @@ -135263,9 +135385,9 @@ - - - + + + @@ -135281,32 +135403,32 @@ - - - - + + + + - - + + - - + + - - - + + + - - - + + + - - - + + + @@ -135315,9 +135437,9 @@ - - - + + + @@ -135325,74 +135447,74 @@ - - - + + + - - + + - - - + + + - - - + + + - - - - + + + + - - - - + + + + - - + + - - - + + + - - - + + + - - - + + + - - - - + + + + - - + + - - + + - - - - + + + + @@ -135404,42 +135526,42 @@ - - - - + + + + - - - - - - + + + + + + - - - - - - + + + + + + - - - - - - + + + + + + - - + + @@ -135454,8 +135576,8 @@ - - + + @@ -135475,8 +135597,8 @@ - - + + @@ -135490,61 +135612,61 @@ - - - - - + + + + + - - - + + + - - - - - + + + + + - - - - + + + + - - - - + + + + - - - - + + + + - - - - - - + + + + + + - - - - - + + + + + - - - - + + + + @@ -135562,12 +135684,12 @@ - - - - - - + + + + + + @@ -135578,12 +135700,12 @@ - - - - - - + + + + + + @@ -135598,9 +135720,9 @@ - - - + + + @@ -135613,15 +135735,15 @@ - - + + - - - - - + + + + + @@ -135638,10 +135760,10 @@ - - - - + + + + @@ -135661,10 +135783,10 @@ - - - - + + + + @@ -135710,10 +135832,10 @@ - - - - + + + + @@ -135728,16 +135850,16 @@ - - - + + + - - + + - - + + @@ -135765,11 +135887,11 @@ - - - - - + + + + + @@ -135799,16 +135921,16 @@ - - - - - - + + + + + + - - + + @@ -135911,33 +136033,33 @@ - - + + - - + + - - - - - - + + + + + + - - - + + + - - + + @@ -135963,8 +136085,8 @@ - - + + @@ -135979,16 +136101,16 @@ - - + + - - + + - - + + @@ -136073,19 +136195,19 @@ - - - + + + - - - + + + - - - + + + @@ -136100,8 +136222,8 @@ - - + + @@ -136132,9 +136254,9 @@ - - - + + + @@ -136164,14 +136286,14 @@ - - - + + + - - - + + + @@ -136184,9 +136306,9 @@ - - - + + + @@ -136194,10 +136316,10 @@ - - - - + + + + @@ -136211,12 +136333,12 @@ - - + + - - + + @@ -136237,9 +136359,9 @@ - - - + + + @@ -136251,9 +136373,9 @@ - - - + + + @@ -136301,8 +136423,8 @@ - - + + @@ -136348,9 +136470,9 @@ - - - + + + @@ -136366,10 +136488,10 @@ - - - - + + + + @@ -136390,10 +136512,10 @@ - - - - + + + + @@ -136426,17 +136548,17 @@ - - + + - - - + + + @@ -136450,55 +136572,55 @@ - - - - + + + + - - + + - - - + + + - - + + - - + + - - - - - + + + + + - - - + + + - - - + + + - - + + - - + + - - + + @@ -136520,20 +136642,20 @@ - - - - - - + + + + + + - - + + - - + + @@ -136541,21 +136663,21 @@ - - - - - + + + + + - - - - - + + + + + - - + + @@ -136566,7 +136688,7 @@ - + @@ -136585,21 +136707,21 @@ - - - - + + + + - - - - - - - - - + + + + + + + + + @@ -136633,8 +136755,8 @@ - - + + @@ -136654,9 +136776,9 @@ - - - + + + @@ -136664,23 +136786,23 @@ - - - + + + - - - + + + - - - + + + @@ -136701,37 +136823,37 @@ - - + + - - - - + + + + - - - + + + - - + + - - - - + + + + @@ -136745,11 +136867,11 @@ - - - - - + + + + + @@ -136759,12 +136881,12 @@ - - - - - - + + + + + + @@ -136808,10 +136930,10 @@ - - - - + + + + @@ -136870,24 +136992,24 @@ - - + + - - + + - - + + @@ -136897,11 +137019,11 @@ - - - - - + + + + + @@ -136946,14 +137068,14 @@ - - - - + + + + - - - + + + @@ -137186,8 +137308,8 @@ - - + + @@ -137207,29 +137329,29 @@ - - - + + + - - + + - - + + - - + + - - + + - - + + @@ -137241,14 +137363,14 @@ - - - + + + - - - + + + @@ -137261,16 +137383,16 @@ - - - - + + + + - - - - + + + + @@ -137326,12 +137448,12 @@ - - + + - - + + @@ -137378,24 +137500,24 @@ - - + + - - + + - - + + - - + + @@ -137415,13 +137537,13 @@ - - + + - - - + + + @@ -137435,16 +137557,16 @@ - - - - + + + + - - - - + + + + @@ -137457,9 +137579,9 @@ - - - + + + @@ -137480,8 +137602,8 @@ - - + + @@ -137496,8 +137618,8 @@ - - + + @@ -137531,8 +137653,8 @@ - - + + @@ -137550,10 +137672,10 @@ - - - - + + + + @@ -137566,54 +137688,54 @@ - - + + - - - + + + - - + + - + - + - - - - + + + + - - - - + + + + - - - - - - - - - + + + + + + + + + - - + + - - + + @@ -137622,36 +137744,36 @@ - - - - - + + + + + - - - - - - + + + + + + - - - - - - - + + + + + + + - - - - - - + + + + + + @@ -137662,12 +137784,12 @@ - - - - - - + + + + + + @@ -137686,9 +137808,9 @@ - - - + + + @@ -137698,8 +137820,8 @@ - - + + @@ -137713,10 +137835,10 @@ - - - - + + + + @@ -137729,13 +137851,13 @@ - - - + + + - - + + @@ -137788,11 +137910,11 @@ - - - - - + + + + + @@ -137808,24 +137930,24 @@ - - + + - - + + - - + + - - + + @@ -137833,24 +137955,24 @@ - - + + - - + + - - + + @@ -137910,8 +138032,8 @@ - - + + @@ -137921,28 +138043,28 @@ - - - - - + + + + + - - - - - + + + + + - - - - + + + + @@ -137956,23 +138078,23 @@ - - - + + + - - + + - - - - + + + + - - + + @@ -137995,48 +138117,48 @@ - - - + + + - - - + + + - - - + + + - - + + - - + + - - - + + + - - + + - - + + - - + + - - + + @@ -138045,7 +138167,7 @@ - + @@ -138085,17 +138207,17 @@ - + - + - - + + @@ -138114,8 +138236,8 @@ - - + + @@ -138152,8 +138274,8 @@ - - + + @@ -138165,23 +138287,23 @@ - - - - + + + + - - - + + + - - - + + + @@ -138241,8 +138363,8 @@ - - + + @@ -138283,16 +138405,16 @@ - - + + - - + + - - + + @@ -138303,8 +138425,8 @@ - - + + @@ -138327,12 +138449,12 @@ - - + + - - + + @@ -138352,8 +138474,8 @@ - - + + @@ -138472,10 +138594,10 @@ - - - - + + + + @@ -138484,20 +138606,20 @@ - - - - - - - - + + + + + + + + - - - - + + + + @@ -138505,14 +138627,14 @@ - - - + + + - - - + + + @@ -138530,8 +138652,8 @@ - - + + @@ -138543,8 +138665,8 @@ - - + + @@ -138581,8 +138703,8 @@ - - + + @@ -138633,22 +138755,22 @@ - - - - + + + + - - - - + + + + - - - - + + + + @@ -138738,8 +138860,8 @@ - - + + @@ -138747,22 +138869,22 @@ - - + + - - - - - - + + + + + + - - - - + + + + @@ -138775,9 +138897,9 @@ - - - + + + @@ -138785,9 +138907,9 @@ - - - + + + @@ -138835,13 +138957,13 @@ - - - - - - - + + + + + + + @@ -138849,28 +138971,28 @@ - - + + - - + + - - + + - - + + - - + + @@ -138886,20 +139008,20 @@ - - - - - - + + + + + + - - - + + + - - + + @@ -138915,8 +139037,8 @@ - - + + @@ -138933,8 +139055,8 @@ - - + + @@ -138947,15 +139069,15 @@ - - - + + + - - - - + + + + @@ -138963,39 +139085,39 @@ - - - + + + - - - - + + + + - - + + - - - + + + - - - - + + + + - - - + + + - - - + + + @@ -139003,30 +139125,30 @@ - - - - + + + + - - - - + + + + - - - - + + + + - - + + - - + + @@ -139153,8 +139275,8 @@ - - + + @@ -139278,12 +139400,12 @@ - - + + - - + + @@ -139300,9 +139422,9 @@ - - - + + + @@ -139310,9 +139432,9 @@ - - - + + + @@ -139320,9 +139442,9 @@ - - - + + + @@ -139347,12 +139469,12 @@ - - + + - - + + @@ -139370,10 +139492,10 @@ - - - - + + + + @@ -139395,61 +139517,61 @@ - - - + + + - - - - + + + + - - - + + + - - + + - - - - - - + + + + + + - - - - + + + + - - - - - - - + + + + + + + - - - + + + - - - + + + - - - + + + @@ -139459,10 +139581,10 @@ - - - - + + + + @@ -139473,13 +139595,13 @@ - + - - - - + + + + @@ -139513,10 +139635,10 @@ - - - - + + + + @@ -139558,7 +139680,7 @@ - + @@ -139566,34 +139688,34 @@ - - + + - - + + - - + + - - - - - - + + + + + + - - - - + + + + - - + + @@ -139604,10 +139726,10 @@ - - - - + + + + @@ -139617,8 +139739,8 @@ - - + + @@ -139629,8 +139751,8 @@ - - + + @@ -139668,8 +139790,8 @@ - - + + @@ -139707,14 +139829,14 @@ - - - - - + + + + + - - + + @@ -139752,11 +139874,11 @@ - - - - - + + + + + @@ -139900,21 +140022,21 @@ - - + + - - - + + + - - + + - - + + @@ -139948,11 +140070,11 @@ - - - - - + + + + + @@ -139967,21 +140089,21 @@ - - + + - - + + - - + + - - - + + + @@ -139997,11 +140119,11 @@ - - - - - + + + + + @@ -140025,12 +140147,12 @@ - - - - - - + + + + + + @@ -140050,28 +140172,28 @@ - - - - + + + + - - - - + + + + - - - + + + - - - - + + + + @@ -140091,26 +140213,26 @@ - - - - + + + + - - - + + + - - - - - + + + + + - - - + + + @@ -140119,20 +140241,20 @@ - - - + + + - - - + + + - - - + + + @@ -140142,26 +140264,26 @@ - - - + + + - - - + + + - - - - + + + + - - - - + + + + @@ -140307,9 +140429,9 @@ - - - + + + @@ -140324,9 +140446,9 @@ - - - + + + @@ -140334,26 +140456,26 @@ - - + + - - - - + + + + - - + + - - + + @@ -140361,25 +140483,25 @@ - - - + + + - - - + + + - - - + + + - - - - + + + + @@ -140391,33 +140513,33 @@ - - - - - - + + + + + + - - - - - - + + + + + + - - - - + + + + - - - + + + @@ -140425,28 +140547,28 @@ - - - + + + - - - - - + + + + + - - + + - - - + + + - - + + @@ -140457,13 +140579,13 @@ - - - - - - - + + + + + + + @@ -140495,14 +140617,14 @@ - - + + - - - - + + + + @@ -140510,10 +140632,10 @@ - - - - + + + + @@ -140521,10 +140643,10 @@ - - - - + + + + @@ -140547,10 +140669,10 @@ - - - - + + + + @@ -140566,8 +140688,8 @@ - - + + @@ -140577,29 +140699,29 @@ - + - - + + - - + + - - - - + + + + - - - - - - + + + + + + @@ -140628,13 +140750,13 @@ - - - - - - - + + + + + + + @@ -140653,10 +140775,10 @@ - - - - + + + + @@ -140673,10 +140795,10 @@ - - - - + + + + @@ -140686,30 +140808,30 @@ - - - + + + - - - - - - + + + + + + - - + + - - - - - - - + + + + + + + @@ -140726,13 +140848,13 @@ - - + + - - - + + + @@ -140751,39 +140873,39 @@ - - - + + + - - - - - + + + + + - - - - - + + + + + - - - - - + + + + + - - - + + + - - + + @@ -140806,55 +140928,55 @@ - - - - - + + + + + - - - - - + + + + + - - - + + + - - - + + + - - - + + + - - - + + + - - - + + + - - + + - - - + + + - - - + + + @@ -140864,9 +140986,9 @@ - - - + + + @@ -140876,16 +140998,16 @@ - - - - - + + + + + - - - + + + @@ -140920,15 +141042,15 @@ - - - + + + - - - - + + + + @@ -140941,11 +141063,11 @@ - - - - - + + + + + @@ -140955,16 +141077,16 @@ - - - - - + + + + + - - - + + + @@ -140974,8 +141096,8 @@ - - + + @@ -140987,25 +141109,25 @@ - - + + - - + + - - - - - - - + + + + + + + - - + + @@ -141016,9 +141138,9 @@ - - - + + + @@ -141070,15 +141192,15 @@ - - - + + + - - - - + + + + @@ -141106,22 +141228,22 @@ - - - - - + + + + + - - - - - + + + + + - - + + @@ -141200,8 +141322,8 @@ - - + + @@ -141211,9 +141333,9 @@ - - - + + + @@ -141251,10 +141373,27 @@ - - - - + + + + + + + + + + + + + + + + + + + + + @@ -141265,8 +141404,8 @@ - - + + @@ -141282,9 +141421,9 @@ - - - + + + @@ -141294,17 +141433,17 @@ - - - - + + + + - - - - - + + + + + @@ -141328,17 +141467,17 @@ - - + + - - - - - - - + + + + + + + @@ -141353,23 +141492,23 @@ - - + + - - - - + + + + - - - + + + - - + + @@ -141380,12 +141519,12 @@ - - - - - - + + + + + + @@ -141404,8 +141543,8 @@ - - + + @@ -141417,18 +141556,18 @@ - - - - - - + + + + + + - - - - + + + + @@ -141436,17 +141575,17 @@ - - - + + + - - + + - - + + @@ -141484,9 +141623,9 @@ - - - + + + @@ -141498,8 +141637,8 @@ - - + + @@ -141531,45 +141670,45 @@ - - - + + + - - - - + + + + - - - - - - + + + + + + - - - - - - + + + + + + - - - - - + + + + + - - - - - + + + + + @@ -141614,9 +141753,9 @@ - - - + + + @@ -141647,10 +141786,10 @@ - - - - + + + + @@ -141742,14 +141881,14 @@ - - - - + + + + - - + + @@ -141767,8 +141906,8 @@ - - + + @@ -142019,9 +142158,9 @@ - - - + + + @@ -142110,9 +142249,9 @@ - - - + + + @@ -142133,13 +142272,13 @@ - - - - - - - + + + + + + + @@ -142151,44 +142290,44 @@ - - - + + + - - - - + + + + - - + + - - + + - - - - - - + + + + + + - - + + - - - + + + @@ -142298,9 +142437,9 @@ - - - + + + @@ -142312,17 +142451,17 @@ - - - - - - + + + + + + - - - + + + @@ -142446,9 +142585,9 @@ - - - + + + @@ -142481,34 +142620,34 @@ - - + + - - + + - - + + - - + + - - - - + + + + - - - - - - + + + + + + @@ -142531,9 +142670,9 @@ - - - + + + @@ -142551,8 +142690,8 @@ - - + + @@ -142587,10 +142726,10 @@ - - - - + + + + @@ -142599,26 +142738,26 @@ - - - - + + + + - - - + + + - - - + + + - - - - + + + + @@ -142626,21 +142765,21 @@ - - - - + + + + - - - - - + + + + + - - - + + + @@ -142659,16 +142798,16 @@ - - - + + + - - - + + + - - + + @@ -142700,33 +142839,33 @@ - - + + - - + + - - + + - - + + - - + + - - - + + + @@ -142737,10 +142876,10 @@ - + - + @@ -142752,12 +142891,12 @@ - - + + - - + + @@ -142772,23 +142911,23 @@ - - + + - - + + - - - + + + - + - + @@ -142807,15 +142946,15 @@ - - - + + + - - - - + + + + @@ -142828,27 +142967,27 @@ - - - + + + - - - - + + + + - - - + + + - - - - + + + + @@ -142870,9 +143009,9 @@ - - - + + + @@ -142881,10 +143020,10 @@ - - - - + + + + @@ -142892,9 +143031,9 @@ - - - + + + @@ -142902,9 +143041,9 @@ - - - + + + @@ -142913,17 +143052,17 @@ - - - - + + + + - + @@ -142941,8 +143080,8 @@ - - + + @@ -143022,8 +143161,8 @@ - - + + @@ -143101,6 +143240,10 @@ + + + + @@ -143116,16 +143259,16 @@ - - + + - - + + @@ -143134,8 +143277,8 @@ - - + + @@ -143167,19 +143310,19 @@ - - - - - - - - - + + + + + + + + + - - + + @@ -143191,9 +143334,9 @@ - - - + + + @@ -143218,14 +143361,14 @@ - - - - + + + + - - + + @@ -143253,9 +143396,9 @@ - - - + + + @@ -143278,11 +143421,12 @@ + - - + + @@ -143317,19 +143461,19 @@ - - + + - - - - + + + + - - - + + + @@ -143347,8 +143491,8 @@ - - + + @@ -143358,24 +143502,24 @@ - - - - - + + + + + - - - - + + + + - - - - - + + + + + @@ -143385,26 +143529,26 @@ - - - - + + + + - - - + + + - - - + + + - - - + + + @@ -143413,10 +143557,10 @@ - - - - + + + + @@ -143436,7 +143580,7 @@ - + @@ -143470,9 +143614,9 @@ - - - + + + @@ -143610,10 +143754,10 @@ - - - - + + + + @@ -143621,10 +143765,10 @@ - - - - + + + + @@ -143703,19 +143847,19 @@ - - - + + + - - - + + + - - - + + + @@ -143745,8 +143889,8 @@ - - + + @@ -143764,16 +143908,16 @@ - - + + - - + + @@ -143826,9 +143970,9 @@ - - - + + + @@ -143842,9 +143986,9 @@ - - - + + + @@ -143883,8 +144027,8 @@ - - + + @@ -143930,9 +144074,9 @@ - - - + + + @@ -144023,11 +144167,11 @@ - - - - - + + + + + @@ -144262,9 +144406,9 @@ - - - + + + @@ -144382,27 +144526,27 @@ - - + + - - + + - - + + - - - - - + + + + + @@ -144436,8 +144580,8 @@ - - + + @@ -144476,17 +144620,17 @@ - - + + - - + + - - - + + + @@ -144497,8 +144641,8 @@ - - + + @@ -144529,12 +144673,12 @@ - - + + - - + + @@ -144561,8 +144705,8 @@ - - + + @@ -144584,8 +144728,8 @@ - - + + @@ -144621,9 +144765,9 @@ - - - + + + @@ -144646,9 +144790,9 @@ - - - + + + @@ -144663,16 +144807,16 @@ - - + + - - + + - - + + @@ -144691,8 +144835,8 @@ - - + + @@ -144707,16 +144851,16 @@ - - - - - - - - - - + + + + + + + + + + @@ -144750,8 +144894,8 @@ - - + + @@ -144766,15 +144910,15 @@ - - - - + + + + - - - + + + @@ -144785,9 +144929,9 @@ - - - + + + @@ -144799,9 +144943,9 @@ - - - + + + @@ -144820,24 +144964,24 @@ - - - + + + - - - - + + + + - - - + + + @@ -144864,8 +145008,8 @@ - - + + @@ -144884,9 +145028,9 @@ - - - + + + @@ -144895,28 +145039,28 @@ - - - - + + + + - - + + - - + + - - - + + + - - - + + + @@ -144925,14 +145069,14 @@ - - - - + + + + - - + + @@ -144943,9 +145087,9 @@ - - - + + + @@ -144960,8 +145104,8 @@ - - + + @@ -144983,8 +145127,8 @@ - - + + @@ -145087,15 +145231,15 @@ - - - + + + - - - - + + + + @@ -145107,8 +145251,8 @@ - - + + @@ -145174,16 +145318,16 @@ - - + + - - + + @@ -145191,10 +145335,10 @@ - - - - + + + + @@ -145218,8 +145362,8 @@ - - + + @@ -145230,30 +145374,30 @@ - - + + - - - + + + - - - + + + - - + + - - + + @@ -145261,10 +145405,10 @@ - - - - + + + + @@ -145288,9 +145432,9 @@ - - - + + + @@ -145298,8 +145442,8 @@ - - + + @@ -145348,9 +145492,9 @@ - - - + + + @@ -145371,10 +145515,10 @@ - - - - + + + + @@ -145424,9 +145568,9 @@ - - - + + + @@ -145486,50 +145630,50 @@ - - - + + + - - - - - - + + + + + + - - - - - + + + + + - - + + - - - - + + + + - - - - - - + + + + + + - - + + @@ -145705,9 +145849,9 @@ - - - + + + @@ -145721,27 +145865,27 @@ - - + + - - - - + + + + - - - + + + @@ -145755,33 +145899,33 @@ - - - - - + + + + + - - - + + + - - + + - - + + - - + + - - - + + + @@ -146027,15 +146171,15 @@ - - - + + + - - - - + + + + @@ -146086,15 +146230,15 @@ - - - + + + - - - + + + @@ -146107,15 +146251,15 @@ - - - - + + + + - - - + + + @@ -146193,9 +146337,9 @@ - - - + + + @@ -146211,36 +146355,36 @@ - - - + + + - - - - - + + + + + - - - - + + + + - - - - + + + + - - - + + + - - + + @@ -146255,9 +146399,9 @@ - - - + + + @@ -146272,14 +146416,14 @@ - - - + + + - - - + + + @@ -146321,15 +146465,15 @@ - - + + - - - - - + + + + + @@ -146337,11 +146481,11 @@ - - - - - + + + + + @@ -146369,14 +146513,14 @@ - - - - - + + + + + - - + + @@ -146396,8 +146540,8 @@ - - + + @@ -146440,8 +146584,8 @@ - - + + @@ -146477,8 +146621,8 @@ - - + + @@ -146545,9 +146689,9 @@ - - - + + + @@ -146618,26 +146762,26 @@ - - - - - - - + + + + + + + - - + + - - - + + + @@ -146674,21 +146818,21 @@ - - - + + + - - - + + + - - - + + + @@ -146755,15 +146899,15 @@ - - + + - - + + @@ -146774,16 +146918,16 @@ - - - - - + + + + + - - - + + + @@ -146792,11 +146936,11 @@ - - - - - + + + + + @@ -146805,9 +146949,9 @@ - - - + + + @@ -146857,11 +147001,11 @@ - - - - - + + + + + @@ -146871,23 +147015,23 @@ - - - - + + + + - - - + + + - - + + - - + + @@ -146906,12 +147050,12 @@ - - + + - - + + @@ -146919,8 +147063,8 @@ - - + + @@ -146941,8 +147085,8 @@ - - + + @@ -146950,16 +147094,16 @@ - - - + + + - + - - + + @@ -146967,8 +147111,8 @@ - - + + @@ -146984,9 +147128,9 @@ - - - + + + @@ -147009,17 +147153,17 @@ - - - + + + - - + + @@ -147036,12 +147180,12 @@ - - - - - - + + + + + + @@ -147102,9 +147246,9 @@ - - - + + + @@ -147129,34 +147273,34 @@ - - - + + + - - - - - + + + + + - - - - - + + + + + - - - - - + + + + + - - - + + + @@ -147166,17 +147310,17 @@ - - + + - - - - + + + + @@ -147187,26 +147331,26 @@ - - - - + + + + - - - - + + + + - - + + - - - - + + + + @@ -147217,9 +147361,9 @@ - - - + + + @@ -147251,10 +147395,10 @@ - - - - + + + + @@ -147287,9 +147431,9 @@ - - - + + + @@ -147306,15 +147450,15 @@ - - - - + + + + - - - + + + @@ -147338,12 +147482,12 @@ - - - - - - + + + + + + @@ -147365,13 +147509,13 @@ - - + + - - - + + + @@ -147388,10 +147532,10 @@ - - - - + + + + @@ -147402,47 +147546,47 @@ - - - + + + - - + + - - - - - - - + + + + + + + - - + + - - - + + + - - - - - - - + + + + + + + - - - - - - + + + + + + diff --git a/android/abi_gki_aarch64_rockchip b/android/abi_gki_aarch64_rockchip index 3e324b6df2dd..b343c8544d8d 100644 --- a/android/abi_gki_aarch64_rockchip +++ b/android/abi_gki_aarch64_rockchip @@ -15,6 +15,7 @@ atomic_notifier_call_chain atomic_notifier_chain_register atomic_notifier_chain_unregister + bcmp bdget_disk bdput blk_cleanup_queue @@ -41,6 +42,20 @@ cdev_device_add cdev_device_del cdev_init + cec_allocate_adapter + cec_delete_adapter + cec_fill_conn_info_from_drm + cec_notifier_cec_adap_register + cec_notifier_cec_adap_unregister + cec_notifier_conn_register + cec_notifier_conn_unregister + cec_notifier_set_phys_addr + cec_notifier_set_phys_addr_from_edid + cec_queue_pin_hpd_event + cec_received_msg_ts + cec_register_adapter + cec_transmit_attempt_done_ts + cec_unregister_adapter __cfi_slowpath __check_object_size __class_create @@ -188,6 +203,7 @@ devm_regulator_get devm_regulator_get_optional devm_regulator_register + devm_remove_action devm_request_threaded_irq devm_reset_control_array_get __devm_reset_control_get @@ -257,6 +273,7 @@ drm_bridge_attach drm_bridge_detect drm_bridge_get_modes + drm_bridge_hpd_notify drm_bridge_remove drm_compat_ioctl drm_connector_attach_encoder @@ -293,6 +310,8 @@ drm_gem_vm_close drm_get_edid drm_hdmi_avi_infoframe_from_display_mode + drm_hdmi_avi_infoframe_quant_range + drm_hdmi_infoframe_set_hdr_metadata drm_hdmi_vendor_infoframe_from_display_mode drm_helper_hpd_irq_event drm_helper_probe_single_connector_modes @@ -322,10 +341,15 @@ drm_property_replace_global_blob drm_read drm_release + drm_scdc_read + drm_scdc_set_high_tmds_clock_ratio + drm_scdc_set_scrambling + drm_scdc_write enable_irq extcon_get_edev_by_phandle extcon_get_state extcon_register_notifier + extcon_set_property_capability extcon_set_state_sync extcon_unregister_notifier failure_tracking @@ -373,6 +397,8 @@ gpio_to_desc handle_nested_irq handle_simple_irq + hdmi_audio_infoframe_pack + hdmi_drm_infoframe_pack hid_debug hid_hw_close hid_hw_open @@ -529,6 +555,7 @@ of_find_property of_get_child_by_name of_get_drm_display_mode + of_get_i2c_adapter_by_node of_get_named_gpio_flags of_get_next_available_child of_get_next_child @@ -649,6 +676,7 @@ regmap_field_update_bits_base regmap_irq_get_domain regmap_irq_get_virq + regmap_raw_read regmap_raw_write regmap_read regmap_update_bits_base @@ -762,6 +790,7 @@ tasklet_init tasklet_kill __tasklet_schedule + tcpm_tcpc_reset thermal_zone_get_zone_by_name __traceiter_rwmmio_post_read __traceiter_rwmmio_read @@ -1000,18 +1029,6 @@ power_supply_am_i_supplied power_supply_get_battery_info power_supply_put_battery_info - regmap_raw_read - -# required by dw-hdmi-cec.ko - cec_allocate_adapter - cec_delete_adapter - cec_notifier_cec_adap_register - cec_notifier_cec_adap_unregister - cec_received_msg_ts - cec_register_adapter - cec_transmit_attempt_done_ts - cec_unregister_adapter - devm_remove_action # required by dw-hdmi-hdcp.ko device_create_file @@ -1022,29 +1039,16 @@ sha1_init sha1_transform +# required by dw-hdmi-qp.ko + drm_mode_equal + hdmi_avi_infoframe_pack_only + # required by dw-hdmi.ko - bcmp - cec_fill_conn_info_from_drm - cec_notifier_conn_register - cec_notifier_conn_unregister - cec_notifier_set_phys_addr - cec_notifier_set_phys_addr_from_edid - cec_queue_pin_hpd_event - drm_bridge_hpd_notify drm_connector_attach_max_bpc_property drm_default_rgb_quant_range - drm_hdmi_avi_infoframe_quant_range - drm_hdmi_infoframe_set_hdr_metadata drm_mode_is_420_also drm_mode_is_420_only - drm_scdc_read - drm_scdc_set_high_tmds_clock_ratio - drm_scdc_set_scrambling - drm_scdc_write - extcon_set_property_capability - hdmi_drm_infoframe_pack hdmi_vendor_infoframe_pack - of_get_i2c_adapter_by_node of_graph_get_endpoint_by_regs # required by dw-mipi-dsi.ko @@ -1754,6 +1758,7 @@ drm_flip_work_init drm_flip_work_queue drm_format_info + drm_format_info_min_pitch drm_framebuffer_cleanup drm_framebuffer_init drm_gem_cma_vm_ops @@ -1781,11 +1786,13 @@ drmm_mode_config_init drm_mm_print drm_mm_remove_node + drm_mm_reserve_node drm_mm_takedown drm_mode_config_cleanup drm_mode_config_helper_resume drm_mode_config_helper_suspend drm_mode_config_reset + drm_mode_create_hdmi_colorspace_property drm_mode_create_tv_properties drm_mode_crtc_set_gamma_size drm_mode_debug_printmodeline @@ -1835,6 +1842,7 @@ iommu_set_fault_handler iommu_unmap memblock_free + mipi_dsi_packet_format_is_short of_clk_set_defaults of_find_backlight_by_node of_fwnode_ops @@ -1919,7 +1927,6 @@ irq_stat # required by sii902x.ko - hdmi_audio_infoframe_pack hdmi_avi_infoframe_pack # required by snd-soc-cx2072x.ko @@ -1936,7 +1943,9 @@ snd_ctl_add snd_ctl_new1 snd_pcm_add_chmap_ctls - snd_pcm_create_iec958_consumer_hw_params + snd_pcm_create_iec958_consumer_default + snd_pcm_fill_iec958_consumer + snd_pcm_fill_iec958_consumer_hw_params snd_pcm_hw_constraint_eld snd_soc_dapm_add_routes @@ -1994,6 +2003,7 @@ # required by tcpci_husb311.ko i2c_smbus_read_word_data + tcpci_get_tcpm_port tcpci_irq tcpci_register_port tcpci_unregister_port From 09f78c3f7e40f957c6b49d3b5c225e75ec27d850 Mon Sep 17 00:00:00 2001 From: Kever Yang Date: Fri, 22 Jul 2022 19:53:21 +0800 Subject: [PATCH 77/91] ANDROID: GKI: rockchip: Update symbol for devfreq Leaf changes summary: 3 artifacts changed Changed leaf types summary: 0 leaf type changed Removed/Changed/Added functions summary: 0 Removed, 0 Changed, 3 Added functions Removed/Changed/Added variables summary: 0 Removed, 0 Changed, 0 Added variable 3 Added functions: [A] 'function void dev_pm_opp_unregister_set_opp_helper(opp_table*)' [A] 'function unsigned int regulator_get_linear_step(regulator*)' [A] 'function int regulator_suspend_enable(regulator_dev*, suspend_state_t)' Bug: 239396464 Signed-off-by: Kever Yang Change-Id: I29bbba8070312fef5877c5b7c301623c93271ac6 --- android/abi_gki_aarch64.xml | 16 ++++++ android/abi_gki_aarch64_rockchip | 98 ++++++++++++++++++++++++++------ 2 files changed, 96 insertions(+), 18 deletions(-) diff --git a/android/abi_gki_aarch64.xml b/android/abi_gki_aarch64.xml index c9e67ad7887b..1c06f636ee93 100644 --- a/android/abi_gki_aarch64.xml +++ b/android/abi_gki_aarch64.xml @@ -1481,6 +1481,7 @@ + @@ -4377,6 +4378,7 @@ + @@ -4407,6 +4409,7 @@ + @@ -123744,6 +123747,10 @@ + + + + @@ -138694,6 +138701,10 @@ + + + + @@ -138847,6 +138858,11 @@ + + + + + diff --git a/android/abi_gki_aarch64_rockchip b/android/abi_gki_aarch64_rockchip index b343c8544d8d..21e047171614 100644 --- a/android/abi_gki_aarch64_rockchip +++ b/android/abi_gki_aarch64_rockchip @@ -15,9 +15,11 @@ atomic_notifier_call_chain atomic_notifier_chain_register atomic_notifier_chain_unregister + _bcd2bin bcmp bdget_disk bdput + _bin2bcd blk_cleanup_queue blk_execute_rq_nowait blk_mq_free_request @@ -61,6 +63,7 @@ __class_create class_destroy class_for_each_device + __class_register clk_bulk_disable clk_bulk_enable clk_bulk_prepare @@ -173,6 +176,7 @@ devm_gpiod_get_index_optional devm_gpiod_get_optional devm_gpio_request + devm_gpio_request_one devm_input_allocate_device devm_ioremap devm_ioremap_resource @@ -225,6 +229,7 @@ dev_set_name _dev_warn disable_irq + disable_irq_nosync dma_alloc_attrs dma_buf_attach dma_buf_detach @@ -386,11 +391,13 @@ gpiod_cansleep gpiod_direction_input gpiod_direction_output + gpiod_direction_output_raw gpiod_get_optional gpiod_get_raw_value gpiod_get_value gpiod_get_value_cansleep gpiod_set_consumer_name + gpiod_set_raw_value gpiod_set_value gpiod_set_value_cansleep gpiod_to_irq @@ -420,6 +427,9 @@ i2c_put_adapter i2c_register_driver i2c_smbus_read_byte_data + i2c_smbus_read_i2c_block_data + i2c_smbus_write_byte_data + i2c_smbus_write_i2c_block_data __i2c_smbus_xfer i2c_smbus_xfer i2c_transfer @@ -436,8 +446,12 @@ init_timer_key init_wait_entry __init_waitqueue_head + input_allocate_device input_event input_ff_create_memless + input_free_device + input_mt_init_slots + input_mt_report_slot_state input_register_device input_set_abs_params iommu_attach_device @@ -642,6 +656,7 @@ prepare_to_wait_event print_hex_dump printk + proc_create proc_create_data put_device put_disk @@ -687,6 +702,7 @@ regulator_disable_regmap regulator_enable regulator_enable_regmap + regulator_get regulator_get_voltage regulator_get_voltage_sel_regmap regulator_is_enabled @@ -698,6 +714,7 @@ regulator_set_voltage regulator_set_voltage_sel_regmap regulator_set_voltage_time_sel + regulator_unregister remap_pfn_range remove_proc_entry request_threaded_irq @@ -825,6 +842,7 @@ v4l2_ctrl_handler_init_class v4l2_ctrl_handler_setup v4l2_ctrl_new_std + v4l2_ctrl_new_std_menu v4l2_ctrl_new_std_menu_items v4l2_device_register v4l2_device_register_subdev @@ -1131,16 +1149,9 @@ usb_speed_string usb_wakeup_enabled_descendants -# required by fan53555.ko - gpiod_set_raw_value - # required by fusb302.ko - disable_irq_nosync extcon_get_extcon_dev fwnode_create_software_node - i2c_smbus_read_i2c_block_data - i2c_smbus_write_byte_data - i2c_smbus_write_i2c_block_data tcpm_cc_change tcpm_pd_hard_reset tcpm_pd_receive @@ -1175,13 +1186,12 @@ # required by grf.ko of_find_matching_node_and_match +# required by gslx680-pad.ko + input_unregister_device + # required by hid-alps.ko down input_alloc_absinfo - input_allocate_device - input_free_device - input_mt_init_slots - input_mt_report_slot_state input_mt_sync_frame up @@ -1245,8 +1255,11 @@ __kfifo_to_user mutex_lock_interruptible -# required by leds-gpio.ko - devm_gpio_request_one +# required by leds-rgb13h.ko + led_classdev_flash_register_ext + led_classdev_flash_unregister + ns_to_kernel_old_timeval + __usecs_to_jiffies # required by ledtrig-heartbeat.ko avenrun @@ -1410,7 +1423,6 @@ # required by ov2680.ko v4l2_ctrl_auto_cluster - v4l2_ctrl_new_std_menu __v4l2_find_nearest_size # required by ov5695.ko @@ -1541,6 +1553,22 @@ devres_release kernel_kobj +# required by rfkill-rk.ko + gpio_free + gpio_request + kstrtoll + proc_mkdir + rfkill_alloc + rfkill_destroy + rfkill_init_sw_state + rfkill_register + rfkill_set_hw_state + rfkill_set_sw_state + rfkill_unregister + +# required by rk1000.ko + of_find_i2c_device_by_node + # required by rk628.ko irq_dispose_mapping irq_domain_xlate_onetwocell @@ -1569,7 +1597,6 @@ register_syscore_ops regmap_add_irq_chip regmap_del_irq_chip - system_state unregister_syscore_ops # required by rk818_battery.ko @@ -1577,6 +1604,12 @@ blocking_notifier_chain_register blocking_notifier_chain_unregister +# required by rk860x-regulator.ko + regulator_suspend_enable + +# required by rk_headset_irq_hook_adc.ko + iio_read_channel_raw + # required by rknpu.ko dev_pm_domain_attach_by_name dev_pm_domain_detach @@ -1599,6 +1632,8 @@ cpufreq_unregister_notifier dev_pm_opp_put_prop_name dev_pm_opp_set_supported_hw + freq_qos_remove_request + freq_qos_update_request # required by rockchip-iommu.ko bus_set_iommu @@ -1650,6 +1685,7 @@ devfreq_update_interval _dev_notice dev_pm_opp_add + dev_pm_opp_unregister_set_opp_helper input_close_device input_open_device input_register_handle @@ -1661,12 +1697,20 @@ # required by rockchip_dmc_common.ko down_write_trylock +# required by rockchip_headset_core.ko + iio_channel_get + +# required by rockchip_ipa.ko + bpf_trace_run7 + of_get_compatible_child + # required by rockchip_opp_select.ko dev_pm_opp_get_opp_table dev_pm_opp_of_add_table dev_pm_opp_put_opp_table dev_pm_opp_set_prop_name of_find_node_opts_by_path + regulator_get_linear_step regulator_get_optional regulator_put @@ -1677,6 +1721,19 @@ iio_push_to_buffers iio_trigger_notify_done +# required by rockchip_system_monitor.ko + add_cpu + bitmap_parselist + compat_only_sysfs_link_entry_to_kobj + dev_pm_opp_find_freq_floor + dev_pm_qos_add_request + dev_pm_qos_remove_request + dev_pm_qos_update_request + remove_cpu + strchr + strsep + thermal_zone_get_temp + # required by rockchip_thermal.ko devm_clk_put devm_thermal_zone_of_sensor_register @@ -1860,9 +1917,15 @@ __sw_hweight8 __vmalloc +# required by rohm-bu18tl82.ko + mipi_dsi_device_register_full + mipi_dsi_device_unregister + of_find_mipi_dsi_host_by_node + +# required by rtc-hym8563.ko + devm_rtc_device_register + # required by rtc-rk808.ko - _bcd2bin - _bin2bcd devm_rtc_allocate_device __rtc_register_device rtc_time64_to_tm @@ -2080,7 +2143,6 @@ __alloc_percpu bio_endio blk_alloc_queue - __class_register class_unregister __cpuhp_state_add_instance __cpuhp_state_remove_instance From d306fd9d476f00e30f2002f8da9e5ad8a7aeec9f Mon Sep 17 00:00:00 2001 From: Seiya Wang Date: Wed, 3 Feb 2021 13:53:47 +0800 Subject: [PATCH 78/91] UPSTREAM: arm64: perf: add support for Cortex-A78 Add support for Cortex-A78 using generic PMUv3 for now. Signed-off-by: Seiya Wang Acked-by: Mark Rutland Link: https://lore.kernel.org/r/20210203055348.4935-2-seiya.wang@mediatek.com Signed-off-by: Will Deacon (cherry picked from commit db2bb91f2e8e73d85876d1665608e834d91d21ee) Signed-off-by: Will Deacon Bug: 238597093 Change-Id: I8c695a7625216cb8dc08dab4e3dd8734cd12254d --- arch/arm64/kernel/perf_event.c | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/arch/arm64/kernel/perf_event.c b/arch/arm64/kernel/perf_event.c index cdb3d4549b3a..31b95caa3be5 100644 --- a/arch/arm64/kernel/perf_event.c +++ b/arch/arm64/kernel/perf_event.c @@ -1188,6 +1188,12 @@ static int armv8_a77_pmu_init(struct arm_pmu *cpu_pmu) armv8_pmuv3_map_event); } +static int armv8_a78_pmu_init(struct arm_pmu *cpu_pmu) +{ + return armv8_pmu_init_nogroups(cpu_pmu, "armv8_cortex_a78", + armv8_pmuv3_map_event); +} + static int armv8_e1_pmu_init(struct arm_pmu *cpu_pmu) { return armv8_pmu_init_nogroups(cpu_pmu, "armv8_neoverse_e1", @@ -1225,6 +1231,7 @@ static const struct of_device_id armv8_pmu_of_device_ids[] = { {.compatible = "arm,cortex-a75-pmu", .data = armv8_a75_pmu_init}, {.compatible = "arm,cortex-a76-pmu", .data = armv8_a76_pmu_init}, {.compatible = "arm,cortex-a77-pmu", .data = armv8_a77_pmu_init}, + {.compatible = "arm,cortex-a78-pmu", .data = armv8_a78_pmu_init}, {.compatible = "arm,neoverse-e1-pmu", .data = armv8_e1_pmu_init}, {.compatible = "arm,neoverse-n1-pmu", .data = armv8_n1_pmu_init}, {.compatible = "cavium,thunder-pmu", .data = armv8_thunder_pmu_init}, From bb6c018ab6f3e42fcb3e437dcc7b94584e1ba815 Mon Sep 17 00:00:00 2001 From: Thierry Reding Date: Tue, 14 Dec 2021 14:16:13 +0000 Subject: [PATCH 79/91] UPSTREAM: arm64: perf: Support Denver and Carmel PMUs Add support for the NVIDIA Denver and Carmel PMUs using the generic PMUv3 event map for now. Acked-by: Mark Rutland Signed-off-by: Thierry Reding [ rm: reorder entries alphabetically ] Signed-off-by: Robin Murphy Link: https://lore.kernel.org/r/5f0f69d47acca78a9e479501aa4d8b429e23cf11.1639490264.git.robin.murphy@arm.com Signed-off-by: Will Deacon (cherry picked from commit d4c4844a9b47dc1c7e8ccce0cdd899602f5479fd) Signed-off-by: Will Deacon Bug: 238597093 Change-Id: I078644d2bb973fb7bd6777ad0bb702c430c05967 --- arch/arm64/kernel/perf_event.c | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/arch/arm64/kernel/perf_event.c b/arch/arm64/kernel/perf_event.c index 31b95caa3be5..6a797b14c0d1 100644 --- a/arch/arm64/kernel/perf_event.c +++ b/arch/arm64/kernel/perf_event.c @@ -1218,6 +1218,18 @@ static int armv8_vulcan_pmu_init(struct arm_pmu *cpu_pmu) armv8_vulcan_map_event); } +static int armv8_carmel_pmu_init(struct arm_pmu *cpu_pmu) +{ + return armv8_pmu_init_nogroups(cpu_pmu, "armv8_nvidia_carmel", + armv8_pmuv3_map_event); +} + +static int armv8_denver_pmu_init(struct arm_pmu *cpu_pmu) +{ + return armv8_pmu_init_nogroups(cpu_pmu, "armv8_nvidia_denver", + armv8_pmuv3_map_event); +} + static const struct of_device_id armv8_pmu_of_device_ids[] = { {.compatible = "arm,armv8-pmuv3", .data = armv8_pmuv3_init}, {.compatible = "arm,cortex-a34-pmu", .data = armv8_a34_pmu_init}, @@ -1236,6 +1248,8 @@ static const struct of_device_id armv8_pmu_of_device_ids[] = { {.compatible = "arm,neoverse-n1-pmu", .data = armv8_n1_pmu_init}, {.compatible = "cavium,thunder-pmu", .data = armv8_thunder_pmu_init}, {.compatible = "brcm,vulcan-pmu", .data = armv8_vulcan_pmu_init}, + {.compatible = "nvidia,carmel-pmu", .data = armv8_carmel_pmu_init}, + {.compatible = "nvidia,denver-pmu", .data = armv8_denver_pmu_init}, {}, }; From ed931dc8ff1d144210f32728c89ee95b81c21439 Mon Sep 17 00:00:00 2001 From: Robin Murphy Date: Tue, 14 Dec 2021 14:16:14 +0000 Subject: [PATCH 80/91] UPSTREAM: arm64: perf: Simplify registration boilerplate With the trend for per-core events moving to userspace JSON, registering names for PMUv3 implementations is increasingly a pure boilerplate exercise. Let's wrap things a step further so we can generate the basic PMUv3 init function with a macro invocation, and reduce further new addition to just 2 lines each. Suggested-by: Mark Rutland Signed-off-by: Robin Murphy Link: https://lore.kernel.org/r/b79477ea3b97f685d00511d4ecd2f686184dca34.1639490264.git.robin.murphy@arm.com Signed-off-by: Will Deacon (cherry picked from commit 6ac9f30bd43baf9e05696e9a614fcd7e83c74afa) Signed-off-by: Will Deacon Bug: 238597093 Change-Id: I635d3978555c84b4234b6a791c8012ad4f5170c4 --- arch/arm64/kernel/perf_event.c | 113 +++++++++------------------------ 1 file changed, 31 insertions(+), 82 deletions(-) diff --git a/arch/arm64/kernel/perf_event.c b/arch/arm64/kernel/perf_event.c index 6a797b14c0d1..cd741485650c 100644 --- a/arch/arm64/kernel/perf_event.c +++ b/arch/arm64/kernel/perf_event.c @@ -1116,17 +1116,26 @@ static int armv8_pmu_init_nogroups(struct arm_pmu *cpu_pmu, char *name, return armv8_pmu_init(cpu_pmu, name, map_event, NULL, NULL, NULL); } -static int armv8_pmuv3_init(struct arm_pmu *cpu_pmu) -{ - return armv8_pmu_init_nogroups(cpu_pmu, "armv8_pmuv3", - armv8_pmuv3_map_event); +#define PMUV3_INIT_SIMPLE(name) \ +static int name##_pmu_init(struct arm_pmu *cpu_pmu) \ +{ \ + return armv8_pmu_init_nogroups(cpu_pmu, #name, armv8_pmuv3_map_event);\ } -static int armv8_a34_pmu_init(struct arm_pmu *cpu_pmu) -{ - return armv8_pmu_init_nogroups(cpu_pmu, "armv8_cortex_a34", - armv8_pmuv3_map_event); -} +PMUV3_INIT_SIMPLE(armv8_pmuv3) + +PMUV3_INIT_SIMPLE(armv8_cortex_a34) +PMUV3_INIT_SIMPLE(armv8_cortex_a55) +PMUV3_INIT_SIMPLE(armv8_cortex_a65) +PMUV3_INIT_SIMPLE(armv8_cortex_a75) +PMUV3_INIT_SIMPLE(armv8_cortex_a76) +PMUV3_INIT_SIMPLE(armv8_cortex_a77) +PMUV3_INIT_SIMPLE(armv8_cortex_a78) +PMUV3_INIT_SIMPLE(armv8_neoverse_e1) +PMUV3_INIT_SIMPLE(armv8_neoverse_n1) + +PMUV3_INIT_SIMPLE(armv8_nvidia_carmel) +PMUV3_INIT_SIMPLE(armv8_nvidia_denver) static int armv8_a35_pmu_init(struct arm_pmu *cpu_pmu) { @@ -1140,24 +1149,12 @@ static int armv8_a53_pmu_init(struct arm_pmu *cpu_pmu) armv8_a53_map_event); } -static int armv8_a55_pmu_init(struct arm_pmu *cpu_pmu) -{ - return armv8_pmu_init_nogroups(cpu_pmu, "armv8_cortex_a55", - armv8_pmuv3_map_event); -} - static int armv8_a57_pmu_init(struct arm_pmu *cpu_pmu) { return armv8_pmu_init_nogroups(cpu_pmu, "armv8_cortex_a57", armv8_a57_map_event); } -static int armv8_a65_pmu_init(struct arm_pmu *cpu_pmu) -{ - return armv8_pmu_init_nogroups(cpu_pmu, "armv8_cortex_a65", - armv8_pmuv3_map_event); -} - static int armv8_a72_pmu_init(struct arm_pmu *cpu_pmu) { return armv8_pmu_init_nogroups(cpu_pmu, "armv8_cortex_a72", @@ -1170,42 +1167,6 @@ static int armv8_a73_pmu_init(struct arm_pmu *cpu_pmu) armv8_a73_map_event); } -static int armv8_a75_pmu_init(struct arm_pmu *cpu_pmu) -{ - return armv8_pmu_init_nogroups(cpu_pmu, "armv8_cortex_a75", - armv8_pmuv3_map_event); -} - -static int armv8_a76_pmu_init(struct arm_pmu *cpu_pmu) -{ - return armv8_pmu_init_nogroups(cpu_pmu, "armv8_cortex_a76", - armv8_pmuv3_map_event); -} - -static int armv8_a77_pmu_init(struct arm_pmu *cpu_pmu) -{ - return armv8_pmu_init_nogroups(cpu_pmu, "armv8_cortex_a77", - armv8_pmuv3_map_event); -} - -static int armv8_a78_pmu_init(struct arm_pmu *cpu_pmu) -{ - return armv8_pmu_init_nogroups(cpu_pmu, "armv8_cortex_a78", - armv8_pmuv3_map_event); -} - -static int armv8_e1_pmu_init(struct arm_pmu *cpu_pmu) -{ - return armv8_pmu_init_nogroups(cpu_pmu, "armv8_neoverse_e1", - armv8_pmuv3_map_event); -} - -static int armv8_n1_pmu_init(struct arm_pmu *cpu_pmu) -{ - return armv8_pmu_init_nogroups(cpu_pmu, "armv8_neoverse_n1", - armv8_pmuv3_map_event); -} - static int armv8_thunder_pmu_init(struct arm_pmu *cpu_pmu) { return armv8_pmu_init_nogroups(cpu_pmu, "armv8_cavium_thunder", @@ -1218,38 +1179,26 @@ static int armv8_vulcan_pmu_init(struct arm_pmu *cpu_pmu) armv8_vulcan_map_event); } -static int armv8_carmel_pmu_init(struct arm_pmu *cpu_pmu) -{ - return armv8_pmu_init_nogroups(cpu_pmu, "armv8_nvidia_carmel", - armv8_pmuv3_map_event); -} - -static int armv8_denver_pmu_init(struct arm_pmu *cpu_pmu) -{ - return armv8_pmu_init_nogroups(cpu_pmu, "armv8_nvidia_denver", - armv8_pmuv3_map_event); -} - static const struct of_device_id armv8_pmu_of_device_ids[] = { - {.compatible = "arm,armv8-pmuv3", .data = armv8_pmuv3_init}, - {.compatible = "arm,cortex-a34-pmu", .data = armv8_a34_pmu_init}, + {.compatible = "arm,armv8-pmuv3", .data = armv8_pmuv3_pmu_init}, + {.compatible = "arm,cortex-a34-pmu", .data = armv8_cortex_a34_pmu_init}, {.compatible = "arm,cortex-a35-pmu", .data = armv8_a35_pmu_init}, {.compatible = "arm,cortex-a53-pmu", .data = armv8_a53_pmu_init}, - {.compatible = "arm,cortex-a55-pmu", .data = armv8_a55_pmu_init}, + {.compatible = "arm,cortex-a55-pmu", .data = armv8_cortex_a55_pmu_init}, {.compatible = "arm,cortex-a57-pmu", .data = armv8_a57_pmu_init}, - {.compatible = "arm,cortex-a65-pmu", .data = armv8_a65_pmu_init}, + {.compatible = "arm,cortex-a65-pmu", .data = armv8_cortex_a65_pmu_init}, {.compatible = "arm,cortex-a72-pmu", .data = armv8_a72_pmu_init}, {.compatible = "arm,cortex-a73-pmu", .data = armv8_a73_pmu_init}, - {.compatible = "arm,cortex-a75-pmu", .data = armv8_a75_pmu_init}, - {.compatible = "arm,cortex-a76-pmu", .data = armv8_a76_pmu_init}, - {.compatible = "arm,cortex-a77-pmu", .data = armv8_a77_pmu_init}, - {.compatible = "arm,cortex-a78-pmu", .data = armv8_a78_pmu_init}, - {.compatible = "arm,neoverse-e1-pmu", .data = armv8_e1_pmu_init}, - {.compatible = "arm,neoverse-n1-pmu", .data = armv8_n1_pmu_init}, + {.compatible = "arm,cortex-a75-pmu", .data = armv8_cortex_a75_pmu_init}, + {.compatible = "arm,cortex-a76-pmu", .data = armv8_cortex_a76_pmu_init}, + {.compatible = "arm,cortex-a77-pmu", .data = armv8_cortex_a77_pmu_init}, + {.compatible = "arm,cortex-a78-pmu", .data = armv8_cortex_a78_pmu_init}, + {.compatible = "arm,neoverse-e1-pmu", .data = armv8_neoverse_e1_pmu_init}, + {.compatible = "arm,neoverse-n1-pmu", .data = armv8_neoverse_n1_pmu_init}, {.compatible = "cavium,thunder-pmu", .data = armv8_thunder_pmu_init}, {.compatible = "brcm,vulcan-pmu", .data = armv8_vulcan_pmu_init}, - {.compatible = "nvidia,carmel-pmu", .data = armv8_carmel_pmu_init}, - {.compatible = "nvidia,denver-pmu", .data = armv8_denver_pmu_init}, + {.compatible = "nvidia,carmel-pmu", .data = armv8_nvidia_carmel_pmu_init}, + {.compatible = "nvidia,denver-pmu", .data = armv8_nvidia_denver_pmu_init}, {}, }; @@ -1272,7 +1221,7 @@ static int __init armv8_pmu_driver_init(void) if (acpi_disabled) return platform_driver_register(&armv8_pmu_driver); else - return arm_pmu_acpi_probe(armv8_pmuv3_init); + return arm_pmu_acpi_probe(armv8_pmuv3_pmu_init); } device_initcall(armv8_pmu_driver_init) From 936f1e35d1e508d965d81259b539f66f73d9c808 Mon Sep 17 00:00:00 2001 From: Robin Murphy Date: Tue, 14 Dec 2021 14:16:15 +0000 Subject: [PATCH 81/91] UPSTREAM: arm64: perf: Support new DT compatibles Wire up the new DT compatibles so we can present appropriate PMU names to userspace for the latest and greatest CPUs. Signed-off-by: Robin Murphy Link: https://lore.kernel.org/r/62d14ba12d847ec7f1fba7cb0b3b881b437e1cc5.1639490264.git.robin.murphy@arm.com Signed-off-by: Will Deacon (cherry picked from commit 893c34b60a59cd0bdb496084f5c096be720bd244) Signed-off-by: Will Deacon Bug: 238597093 Change-Id: I7aef375698c5192d4adbf551cae3ea9f8027f101 --- arch/arm64/kernel/perf_event.c | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/arch/arm64/kernel/perf_event.c b/arch/arm64/kernel/perf_event.c index cd741485650c..e41cee4e1bb9 100644 --- a/arch/arm64/kernel/perf_event.c +++ b/arch/arm64/kernel/perf_event.c @@ -1131,8 +1131,14 @@ PMUV3_INIT_SIMPLE(armv8_cortex_a75) PMUV3_INIT_SIMPLE(armv8_cortex_a76) PMUV3_INIT_SIMPLE(armv8_cortex_a77) PMUV3_INIT_SIMPLE(armv8_cortex_a78) +PMUV3_INIT_SIMPLE(armv9_cortex_a510) +PMUV3_INIT_SIMPLE(armv9_cortex_a710) +PMUV3_INIT_SIMPLE(armv8_cortex_x1) +PMUV3_INIT_SIMPLE(armv9_cortex_x2) PMUV3_INIT_SIMPLE(armv8_neoverse_e1) PMUV3_INIT_SIMPLE(armv8_neoverse_n1) +PMUV3_INIT_SIMPLE(armv9_neoverse_n2) +PMUV3_INIT_SIMPLE(armv8_neoverse_v1) PMUV3_INIT_SIMPLE(armv8_nvidia_carmel) PMUV3_INIT_SIMPLE(armv8_nvidia_denver) @@ -1193,8 +1199,14 @@ static const struct of_device_id armv8_pmu_of_device_ids[] = { {.compatible = "arm,cortex-a76-pmu", .data = armv8_cortex_a76_pmu_init}, {.compatible = "arm,cortex-a77-pmu", .data = armv8_cortex_a77_pmu_init}, {.compatible = "arm,cortex-a78-pmu", .data = armv8_cortex_a78_pmu_init}, + {.compatible = "arm,cortex-a510-pmu", .data = armv9_cortex_a510_pmu_init}, + {.compatible = "arm,cortex-a710-pmu", .data = armv9_cortex_a710_pmu_init}, + {.compatible = "arm,cortex-x1-pmu", .data = armv8_cortex_x1_pmu_init}, + {.compatible = "arm,cortex-x2-pmu", .data = armv9_cortex_x2_pmu_init}, {.compatible = "arm,neoverse-e1-pmu", .data = armv8_neoverse_e1_pmu_init}, {.compatible = "arm,neoverse-n1-pmu", .data = armv8_neoverse_n1_pmu_init}, + {.compatible = "arm,neoverse-n2-pmu", .data = armv9_neoverse_n2_pmu_init}, + {.compatible = "arm,neoverse-v1-pmu", .data = armv8_neoverse_v1_pmu_init}, {.compatible = "cavium,thunder-pmu", .data = armv8_thunder_pmu_init}, {.compatible = "brcm,vulcan-pmu", .data = armv8_vulcan_pmu_init}, {.compatible = "nvidia,carmel-pmu", .data = armv8_nvidia_carmel_pmu_init}, From 00d3b8c0ccacde0d2317225b6a77a830fd20f2f6 Mon Sep 17 00:00:00 2001 From: Kever Yang Date: Fri, 22 Jul 2022 20:14:50 +0800 Subject: [PATCH 82/91] ANDROID: GKI: rockchip: Add symbols for drm dp Leaf changes summary: 4 artifacts changed Changed leaf types summary: 0 leaf type changed Removed/Changed/Added functions summary: 0 Removed, 0 Changed, 4 Added functions Removed/Changed/Added variables summary: 0 Removed, 0 Changed, 0 Added variable 4 Added functions: [A] 'function edid* drm_bridge_get_edid(drm_bridge*, drm_connector*)' [A] 'function int drm_dp_read_desc(drm_dp_aux*, drm_dp_desc*, bool)' [A] 'function int drm_dp_read_sink_count(drm_dp_aux*)' [A] 'function bool drm_probe_ddc(i2c_adapter*)' Bug: 239396464 Signed-off-by: Kever Yang Change-Id: I3d07fdd9c0e03ee4b631eb3026e6d2063bf16df9 --- android/abi_gki_aarch64.xml | 49 +++++++ android/abi_gki_aarch64_rockchip | 219 ++++++++++++++++++++----------- 2 files changed, 191 insertions(+), 77 deletions(-) diff --git a/android/abi_gki_aarch64.xml b/android/abi_gki_aarch64.xml index 1c06f636ee93..e3983fd3b185 100644 --- a/android/abi_gki_aarch64.xml +++ b/android/abi_gki_aarch64.xml @@ -1972,6 +1972,7 @@ + @@ -2077,7 +2078,9 @@ + + @@ -2292,6 +2295,7 @@ + @@ -26455,6 +26459,14 @@ + + + + + + + + @@ -43023,6 +43035,23 @@ + + + + + + + + + + + + + + + + + @@ -95634,6 +95663,7 @@ + @@ -126400,6 +126430,11 @@ + + + + + @@ -126939,11 +126974,21 @@ + + + + + + + + + + @@ -128023,6 +128068,10 @@ + + + + diff --git a/android/abi_gki_aarch64_rockchip b/android/abi_gki_aarch64_rockchip index 21e047171614..7fd1c7654b34 100644 --- a/android/abi_gki_aarch64_rockchip +++ b/android/abi_gki_aarch64_rockchip @@ -38,6 +38,10 @@ blk_queue_physical_block_size blk_rq_map_user blk_rq_unmap_user + blocking_notifier_call_chain + blocking_notifier_chain_register + blocking_notifier_chain_unregister + bpf_trace_run1 cancel_delayed_work cancel_delayed_work_sync cancel_work_sync @@ -70,9 +74,9 @@ clk_bulk_unprepare clk_disable clk_enable + clk_gate_ops clk_get __clk_get_name - clk_get_parent clk_get_rate clk_hw_get_flags clk_hw_get_name @@ -142,6 +146,7 @@ dev_fwnode device_add_disk device_create + device_create_file device_destroy device_get_child_node_count device_get_named_child_node @@ -153,6 +158,7 @@ device_property_present device_property_read_string device_property_read_u32_array + device_property_read_u8_array device_release_driver _dev_info devm_add_action @@ -188,6 +194,7 @@ devm_mfd_add_devices devm_nvmem_register devm_of_clk_add_hw_provider + devm_of_phy_get __devm_of_phy_provider_register devm_phy_create devm_phy_get @@ -213,12 +220,14 @@ __devm_reset_control_get devm_snd_dmaengine_pcm_register devm_snd_soc_register_component - dev_pm_opp_disable + devm_usb_get_phy dev_pm_opp_find_freq_ceil dev_pm_opp_get_opp_count + dev_pm_opp_get_opp_table dev_pm_opp_get_voltage dev_pm_opp_of_get_sharing_cpus dev_pm_opp_put + dev_pm_opp_put_opp_table dev_pm_opp_put_regulators dev_pm_opp_register_set_opp_helper dev_pm_opp_set_rate @@ -240,6 +249,7 @@ dma_buf_unmap_attachment dma_buf_vmap dma_buf_vunmap + dma_fence_release dma_free_attrs dma_get_sgtable_attrs dma_heap_add @@ -285,6 +295,7 @@ drm_connector_cleanup drm_connector_init drm_connector_init_with_ddc + drm_connector_unregister drm_connector_update_edid_property __drm_dbg drm_detect_hdmi_monitor @@ -298,7 +309,17 @@ drm_display_info_set_bus_formats drm_display_mode_from_videomode drm_display_mode_to_videomode + drm_dp_aux_register + drm_dp_aux_unregister drm_dp_bw_code_to_link_rate + drm_dp_dpcd_read + drm_dp_dpcd_write + drm_dp_get_phy_test_pattern + drm_dp_link_rate_to_bw_code + drm_dp_link_train_channel_eq_delay + drm_dp_link_train_clock_recovery_delay + drm_dp_read_dpcd_caps + drm_dp_set_phy_test_pattern __drm_err drm_gem_dumb_map_offset drm_gem_get_pages @@ -326,8 +347,16 @@ drm_mode_copy drm_mode_create drm_mode_duplicate + drm_mode_is_420_also + drm_mode_is_420_only drm_mode_probed_add + drm_modeset_acquire_fini + drm_modeset_acquire_init + drm_modeset_backoff + drm_modeset_drop_locks + drm_modeset_lock drm_mode_set_name + drm_mode_validate_driver drm_mode_vrefresh drm_object_attach_property drm_of_find_panel_or_bridge @@ -351,6 +380,7 @@ drm_scdc_set_scrambling drm_scdc_write enable_irq + event_triggers_call extcon_get_edev_by_phandle extcon_get_state extcon_register_notifier @@ -369,6 +399,9 @@ free_irq __free_pages free_pages + freq_qos_add_request + freq_qos_remove_request + freq_qos_update_request fwnode_get_name fwnode_handle_put fwnode_property_present @@ -404,8 +437,10 @@ gpio_to_desc handle_nested_irq handle_simple_irq + hdmi_audio_infoframe_init hdmi_audio_infoframe_pack hdmi_drm_infoframe_pack + hdmi_infoframe_pack hid_debug hid_hw_close hid_hw_open @@ -454,6 +489,7 @@ input_mt_report_slot_state input_register_device input_set_abs_params + input_set_capability iommu_attach_device iommu_detach_device __ioremap @@ -462,8 +498,8 @@ __irq_domain_add irq_domain_remove irq_find_mapping - irq_get_irq_data irq_modify_status + irq_of_parse_and_map irq_set_chained_handler_and_data irq_set_chip irq_set_chip_and_handler_name @@ -492,6 +528,7 @@ kmem_cache_free kmemdup kobject_create_and_add + kstrdup kstrdup_const kstrtoint kstrtouint @@ -529,9 +566,15 @@ memdup_user memset memstart_addr + mfd_add_devices mfd_remove_devices + mipi_dsi_attach mipi_dsi_create_packet + mipi_dsi_detach mipi_dsi_host_register + mipi_dsi_host_unregister + misc_deregister + misc_register mmc_of_parse mod_delayed_work_on mod_timer @@ -547,6 +590,7 @@ noop_llseek nr_cpu_ids ns_to_timespec64 + nvmem_cell_get nvmem_cell_put nvmem_cell_read of_address_to_resource @@ -565,6 +609,7 @@ of_device_is_compatible of_drm_find_bridge of_find_device_by_node + of_find_matching_node_and_match of_find_node_by_name of_find_property of_get_child_by_name @@ -597,6 +642,7 @@ of_property_read_variable_u8_array of_regulator_match of_reserved_mem_device_init_by_idx + __of_reset_control_get of_usb_get_dr_mode_by_phy __page_pinner_migration_failed panic_notifier_list @@ -606,6 +652,8 @@ param_ops_uint PDE_DATA __per_cpu_offset + perf_trace_buf_alloc + perf_trace_run_bpf_submit pfn_valid phy_configure phy_exit @@ -633,6 +681,8 @@ platform_get_irq_byname platform_get_resource platform_get_resource_byname + pm_clk_create + pm_clk_destroy pm_power_off __pm_relax __pm_runtime_disable @@ -648,9 +698,17 @@ __pm_runtime_use_autosuspend __pm_stay_awake pm_wakeup_ws_event + power_supply_am_i_supplied power_supply_changed power_supply_class + power_supply_get_battery_info + power_supply_get_by_phandle power_supply_get_drvdata + power_supply_get_property + power_supply_put_battery_info + power_supply_register + power_supply_reg_notifier + power_supply_unregister preempt_schedule preempt_schedule_notrace prepare_to_wait_event @@ -684,6 +742,7 @@ regcache_sync __register_chrdev register_chrdev_region + register_pm_notifier register_reboot_notifier regmap_bulk_read regmap_bulk_write @@ -691,6 +750,7 @@ regmap_field_update_bits_base regmap_irq_get_domain regmap_irq_get_virq + regmap_multi_reg_write regmap_raw_read regmap_raw_write regmap_read @@ -711,6 +771,7 @@ regulator_list_voltage_linear_range regulator_map_voltage_linear regulator_map_voltage_linear_range + regulator_put regulator_set_voltage regulator_set_voltage_sel_regmap regulator_set_voltage_time_sel @@ -786,6 +847,7 @@ __stack_chk_fail __stack_chk_guard strcmp + strcpy strlcpy strlen strncmp @@ -802,6 +864,7 @@ __sysfs_match_string sysfs_remove_group sysfs_remove_link + system_freezable_wq system_unbound_wq system_wq tasklet_init @@ -809,15 +872,24 @@ __tasklet_schedule tcpm_tcpc_reset thermal_zone_get_zone_by_name + trace_event_buffer_commit + trace_event_buffer_reserve + trace_event_ignore_this_pid + trace_event_raw_init + trace_event_reg + trace_handle_return __traceiter_rwmmio_post_read __traceiter_rwmmio_read __traceiter_rwmmio_write __tracepoint_rwmmio_post_read __tracepoint_rwmmio_read __tracepoint_rwmmio_write + trace_raw_output_prep + trace_seq_printf typec_switch_get_drvdata typec_switch_register typec_switch_unregister + __udelay __unregister_chrdev unregister_chrdev_region unregister_reboot_notifier @@ -904,6 +976,7 @@ __wake_up wake_up_process wakeup_source_add + wakeup_source_remove __warn_printk # required by 8250_dw.ko @@ -936,23 +1009,15 @@ ce_aes_expandkey # required by analogix_dp.ko - drm_dp_aux_register - drm_dp_aux_unregister - drm_dp_dpcd_read - drm_dp_dpcd_write - drm_dp_get_phy_test_pattern - drm_dp_link_rate_to_bw_code - drm_dp_link_train_channel_eq_delay - drm_dp_link_train_clock_recovery_delay - drm_dp_read_dpcd_caps - drm_dp_set_phy_test_pattern drm_dp_start_crc drm_dp_stop_crc - drm_modeset_acquire_fini - drm_modeset_acquire_init - drm_modeset_backoff - drm_modeset_drop_locks - drm_modeset_lock + +# required by bq25700_charger.ko + of_find_compatible_node + power_supply_get_by_name + +# required by bq25890_charger.ko + system_power_efficient_wq # required by ch.ko param_array_ops @@ -961,6 +1026,11 @@ scsi_print_sense_hdr scsi_register_driver +# required by clk-link.ko + pm_clk_add + pm_clk_resume + pm_clk_suspend + # required by clk-pwm.ko of_clk_add_hw_provider of_clk_hw_simple_get @@ -979,8 +1049,8 @@ clk_divider_ro_ops clk_fixed_factor_ops clk_fractional_divider_ops - clk_gate_ops __clk_get_hw + clk_get_parent clk_hw_register_composite clk_hw_round_rate clk_mux_ops @@ -992,7 +1062,6 @@ match_string register_restart_handler reset_controller_register - __udelay # required by clk-scmi.ko clk_hw_set_rate_range @@ -1042,18 +1111,13 @@ devm_blk_ksm_init mmc_cqe_request_done -# required by cw2015_battery.ko - device_property_read_u8_array - power_supply_am_i_supplied - power_supply_get_battery_info - power_supply_put_battery_info +# required by display-connector.ko + drm_atomic_get_new_bridge_state + drm_probe_ddc # required by dw-hdmi-hdcp.ko - device_create_file device_remove_file kstrtobool - misc_deregister - misc_register sha1_init sha1_transform @@ -1064,8 +1128,6 @@ # required by dw-hdmi.ko drm_connector_attach_max_bpc_property drm_default_rgb_quant_range - drm_mode_is_420_also - drm_mode_is_420_only hdmi_vendor_infoframe_pack of_graph_get_endpoint_by_regs @@ -1075,7 +1137,6 @@ drm_panel_bridge_add_typed drm_panel_bridge_connector drm_panel_bridge_remove - mipi_dsi_host_unregister simple_attr_open simple_attr_release @@ -1117,7 +1178,6 @@ __bitmap_set device_set_wakeup_capable device_wakeup_enable - devm_usb_get_phy phy_reset _raw_spin_trylock usb_add_gadget_udc @@ -1180,7 +1240,6 @@ irq_gc_set_wake irq_generic_chip_ops irq_get_domain_generic_chip - irq_of_parse_and_map of_pinctrl_get # required by grf.ko @@ -1223,6 +1282,7 @@ hid_input_report hid_parse_report i2c_smbus_read_byte + irq_get_irq_data # required by i2c-mux.ko i2c_add_numbered_adapter @@ -1298,7 +1358,6 @@ blk_set_queue_dying blk_status_to_errno blk_sync_queue - bpf_trace_run1 bpf_trace_run2 bpf_trace_run3 capable @@ -1309,7 +1368,6 @@ dev_pm_qos_expose_latency_tolerance dev_pm_qos_hide_latency_tolerance dev_pm_qos_update_user_latency_tolerance - event_triggers_call ida_alloc_range ida_destroy ida_free @@ -1318,22 +1376,12 @@ memchr_inv param_ops_byte param_ops_ulong - perf_trace_buf_alloc - perf_trace_run_bpf_submit set_capacity_revalidate_and_notify set_disk_ro __srcu_read_unlock synchronize_rcu synchronize_srcu - trace_event_buffer_commit - trace_event_buffer_reserve - trace_event_ignore_this_pid - trace_event_raw_init - trace_event_reg - trace_handle_return trace_print_symbols_seq - trace_raw_output_prep - trace_seq_printf trace_seq_putc try_module_get xa_destroy @@ -1435,12 +1483,10 @@ drm_connector_set_panel_orientation drm_panel_of_backlight drm_panel_remove - mipi_dsi_attach mipi_dsi_compression_mode mipi_dsi_dcs_get_display_brightness mipi_dsi_dcs_set_display_brightness mipi_dsi_dcs_write_buffer - mipi_dsi_detach mipi_dsi_driver_register_full mipi_dsi_driver_unregister mipi_dsi_generic_write @@ -1461,7 +1507,6 @@ of_prop_next_string # required by pcierockchiphost.ko - devm_of_phy_get devm_pci_alloc_host_bridge devm_pci_remap_cfg_resource dummy_irq_chip @@ -1475,24 +1520,26 @@ # required by phy-rockchip-inno-dsidphy.ko phy_mipi_dphy_config_validate -# required by phy-rockchip-inno-hdmi-phy.ko - nvmem_cell_get - # required by phy-rockchip-inno-usb2.ko devm_extcon_register_notifier extcon_set_state extcon_sync - wakeup_source_remove # required by phy-rockchip-inno-usb3.ko strcasecmp usb_add_phy +# required by phy-rockchip-samsung-hdptx-hdmi.ko + of_platform_device_create + # required by phy-rockchip-typec.ko extcon_get_property -# required by phy-rockchip-usb.ko - __of_reset_control_get +# required by phy-rockchip-usbdp.ko + typec_mux_get_drvdata + typec_mux_register + typec_mux_unregister + usb_get_maximum_speed # required by pinctrl-rk628.ko irq_domain_xlate_twocell @@ -1527,8 +1574,6 @@ of_genpd_add_provider_onecell panic pm_clk_add_clk - pm_clk_create - pm_clk_destroy pm_genpd_add_subdomain pm_genpd_init pm_genpd_remove @@ -1573,11 +1618,14 @@ irq_dispose_mapping irq_domain_xlate_onetwocell irq_set_parent - mfd_add_devices + +# required by rk628_dsi.ko + bus_find_device + device_match_name + of_drm_find_panel # required by rk805-pwrkey.ko devm_request_any_context_irq - input_set_capability # required by rk806-core.ko devm_regmap_add_irq_chip @@ -1614,7 +1662,6 @@ dev_pm_domain_attach_by_name dev_pm_domain_detach dma_buf_mmap - dma_fence_release dma_fence_signal drm_gem_create_mmap_offset drm_gem_dumb_destroy @@ -1632,8 +1679,6 @@ cpufreq_unregister_notifier dev_pm_opp_put_prop_name dev_pm_opp_set_supported_hw - freq_qos_remove_request - freq_qos_update_request # required by rockchip-iommu.ko bus_set_iommu @@ -1684,7 +1729,6 @@ devfreq_suspend_device devfreq_update_interval _dev_notice - dev_pm_opp_add dev_pm_opp_unregister_set_opp_helper input_close_device input_open_device @@ -1692,7 +1736,6 @@ input_register_handler input_unregister_handle __memset_io - system_freezable_wq # required by rockchip_dmc_common.ko down_write_trylock @@ -1705,14 +1748,17 @@ of_get_compatible_child # required by rockchip_opp_select.ko - dev_pm_opp_get_opp_table + dev_pm_opp_disable dev_pm_opp_of_add_table - dev_pm_opp_put_opp_table dev_pm_opp_set_prop_name of_find_node_opts_by_path regulator_get_linear_step regulator_get_optional - regulator_put + +# required by rockchip_pwm_remotectl.ko + irq_set_affinity_hint + irq_to_desc + __tasklet_hi_schedule # required by rockchip_saradc.ko devm_iio_device_alloc @@ -1729,13 +1775,13 @@ dev_pm_qos_add_request dev_pm_qos_remove_request dev_pm_qos_update_request + regulator_get remove_cpu strchr strsep thermal_zone_get_temp # required by rockchip_thermal.ko - devm_clk_put devm_thermal_zone_of_sensor_register thermal_zone_device_disable thermal_zone_device_enable @@ -1743,7 +1789,6 @@ # required by rockchipdrm.ko adjust_managed_page_count - clk_is_match clk_set_parent component_add component_bind_all @@ -1758,6 +1803,7 @@ drm_atomic_commit drm_atomic_get_connector_state drm_atomic_get_plane_state + drm_atomic_helper_bridge_propagate_bus_fmt drm_atomic_helper_check drm_atomic_helper_check_plane_state drm_atomic_helper_cleanup_planes @@ -1788,12 +1834,12 @@ drm_atomic_set_mode_for_crtc drm_atomic_state_alloc __drm_atomic_state_free + drm_bridge_get_edid drm_connector_has_possible_encoder drm_connector_list_iter_begin drm_connector_list_iter_end drm_connector_list_iter_next drm_connector_list_update - drm_connector_unregister drm_crtc_cleanup drm_crtc_enable_color_mgmt drm_crtc_from_index @@ -1807,6 +1853,12 @@ drm_debugfs_create_files drm_do_get_edid drm_dp_channel_eq_ok + drm_dp_clock_recovery_ok + drm_dp_dpcd_read_link_status + drm_dp_get_adjust_request_pre_emphasis + drm_dp_get_adjust_request_voltage + drm_dp_read_desc + drm_dp_read_sink_count drm_encoder_cleanup drm_encoder_init drm_event_reserve_init_locked @@ -1861,7 +1913,6 @@ drm_modeset_lock_all drm_modeset_unlock_all drm_mode_sort - drm_mode_validate_driver drm_mode_validate_size drm_mode_validate_ycbcr420 drm_of_crtc_port_mask @@ -1891,7 +1942,6 @@ drm_writeback_connector_init drm_writeback_queue_job drm_writeback_signal_completion - hdmi_infoframe_pack iommu_domain_alloc iommu_domain_free iommu_map @@ -1984,6 +2034,9 @@ sg_scsi_ioctl __task_pid_nr_ns +# required by sgm41542_charger.ko + regulator_unregister + # required by sha1-ce.ko crypto_sha1_finup crypto_sha1_update @@ -1993,7 +2046,6 @@ hdmi_avi_infoframe_pack # required by snd-soc-cx2072x.ko - regmap_multi_reg_write snd_soc_params_to_frame_size # required by snd-soc-es8316.ko @@ -2002,7 +2054,6 @@ snd_soc_dapm_sync_unlocked # required by snd-soc-hdmi-codec.ko - hdmi_audio_infoframe_init snd_ctl_add snd_ctl_new1 snd_pcm_add_chmap_ctls @@ -2054,6 +2105,21 @@ spi_setup stream_open +# required by sw_sync.ko + dma_fence_context_alloc + dma_fence_free + dma_fence_init + dma_fence_signal_locked + fd_install + fput + __get_task_comm + get_unused_fd_flags + put_unused_fd + rb_erase + rb_insert_color + rb_next + sync_file_create + # required by system_heap.ko deferred_free dmabuf_page_pool_alloc @@ -2089,10 +2155,11 @@ # required by test_power.ko param_get_int - power_supply_register - power_supply_unregister strncasecmp +# required by timer-rockchip.ko + clockevents_config_and_register + # required by tps65132-regulator.ko regulator_set_active_discharge_regmap @@ -2163,7 +2230,6 @@ __num_online_cpus page_endio register_blkdev - strcpy sysfs_streq unregister_blkdev vzalloc @@ -2179,7 +2245,6 @@ kern_mount kern_unmount kill_anon_super - kstrdup __lock_page page_mapping _raw_read_lock From b0988144b0b0457565aaf0ce7f4465e9d8cf0642 Mon Sep 17 00:00:00 2001 From: liujinbao1 Date: Mon, 1 Aug 2022 21:19:15 +0800 Subject: [PATCH 83/91] UPSTREAM: exfat: improve performance of exfat_free_cluster when using dirsync mount There are stressful update of cluster allocation bitmap when using dirsync mount option which is doing sync buffer on every cluster bit clearing. This could result in performance degradation when deleting big size file. Fix to update only when the bitmap buffer index is changed would make less disk access, improving performance especially for truncate operation. Testing with Samsung 256GB sdcard, mounted with dirsync option (mount -t exfat /dev/block/mmcblk0p1 /temp/mount -o dirsync) Remove 4GB file, blktrace result. [Before] : 39 secs. Total (blktrace): Reads Queued: 0, 0KiB Writes Queued: 32775, 16387KiB Read Dispatches: 0, 0KiB Write Dispatches: 32775, 16387KiB Reads Requeued: 0 Writes Requeued: 0 Reads Completed: 0, 0KiB Writes Completed: 32775, 16387KiB Read Merges: 0, 0KiB Write Merges: 0, 0KiB IO unplugs: 2 Timer unplugs: 0 [After] : 1 sec. Total (blktrace): Reads Queued: 0, 0KiB Writes Queued: 13, 6KiB Read Dispatches: 0, 0KiB Write Dispatches: 13, 6KiB Reads Requeued: 0 Writes Requeued: 0 Reads Completed: 0, 0KiB Writes Completed: 13, 6KiB Read Merges: 0, 0KiB Write Merges: 0, 0KiB IO unplugs: 1 Timer unplugs: 0 Bug: 241198061 Signed-off-by: Hyeongseok Kim Acked-by: Sungjong Seo Signed-off-by: Namjae Jeon (cherry picked from commit f728760aa923f1dd3a4818368dbdbd2c7d63b370) Signed-off-by: liujinbao1 Change-Id: I3931f005491c17489f5950293783270eb888fb09 Signed-off-by: liujinbao1 --- fs/exfat/balloc.c | 4 ++-- fs/exfat/exfat_fs.h | 2 +- fs/exfat/fatent.c | 47 ++++++++++++++++++++++++++++++++++++++------- 3 files changed, 43 insertions(+), 10 deletions(-) diff --git a/fs/exfat/balloc.c b/fs/exfat/balloc.c index 75ab43905f73..6232c0958384 100644 --- a/fs/exfat/balloc.c +++ b/fs/exfat/balloc.c @@ -158,7 +158,7 @@ int exfat_set_bitmap(struct inode *inode, unsigned int clu, bool sync) return 0; } -void exfat_clear_bitmap(struct inode *inode, unsigned int clu) +void exfat_clear_bitmap(struct inode *inode, unsigned int clu, bool sync) { int i, b; unsigned int ent_idx; @@ -172,7 +172,7 @@ void exfat_clear_bitmap(struct inode *inode, unsigned int clu) b = BITMAP_OFFSET_BIT_IN_SECTOR(sb, ent_idx); clear_bit_le(b, sbi->vol_amap[i]->b_data); - exfat_update_bh(sbi->vol_amap[i], IS_DIRSYNC(inode)); + exfat_update_bh(sbi->vol_amap[i], sync); if (opts->discard) { int ret_discard; diff --git a/fs/exfat/exfat_fs.h b/fs/exfat/exfat_fs.h index c5d370990d39..d5cdc9175326 100644 --- a/fs/exfat/exfat_fs.h +++ b/fs/exfat/exfat_fs.h @@ -408,7 +408,7 @@ int exfat_count_num_clusters(struct super_block *sb, int exfat_load_bitmap(struct super_block *sb); void exfat_free_bitmap(struct exfat_sb_info *sbi); int exfat_set_bitmap(struct inode *inode, unsigned int clu, bool sync); -void exfat_clear_bitmap(struct inode *inode, unsigned int clu); +void exfat_clear_bitmap(struct inode *inode, unsigned int clu, bool sync); unsigned int exfat_find_free_bitmap(struct super_block *sb, unsigned int clu); int exfat_count_used_clusters(struct super_block *sb, unsigned int *ret_count); diff --git a/fs/exfat/fatent.c b/fs/exfat/fatent.c index 6078cbfdfe8a..dcc103b27dbe 100644 --- a/fs/exfat/fatent.c +++ b/fs/exfat/fatent.c @@ -157,6 +157,7 @@ int exfat_free_cluster(struct inode *inode, struct exfat_chain *p_chain) unsigned int clu; struct super_block *sb = inode->i_sb; struct exfat_sb_info *sbi = EXFAT_SB(sb); + int cur_cmap_i, next_cmap_i; /* invalid cluster number */ if (p_chain->dir == EXFAT_FREE_CLUSTER || @@ -176,21 +177,53 @@ int exfat_free_cluster(struct inode *inode, struct exfat_chain *p_chain) clu = p_chain->dir; - if (p_chain->flags == ALLOC_NO_FAT_CHAIN) { - do { - exfat_clear_bitmap(inode, clu); - clu++; + cur_cmap_i = next_cmap_i = + BITMAP_OFFSET_SECTOR_INDEX(sb, CLUSTER_TO_BITMAP_ENT(clu)); + if (p_chain->flags == ALLOC_NO_FAT_CHAIN) { + unsigned int last_cluster = p_chain->dir + p_chain->size - 1; + + do { + bool sync = false; + + if (clu < last_cluster) + next_cmap_i = + BITMAP_OFFSET_SECTOR_INDEX(sb, CLUSTER_TO_BITMAP_ENT(clu+1)); + + /* flush bitmap only if index would be changed or for last cluster */ + if (clu == last_cluster || cur_cmap_i != next_cmap_i) { + sync = true; + cur_cmap_i = next_cmap_i; + } + + exfat_clear_bitmap(inode, clu, (sync && IS_DIRSYNC(inode))); + clu++; num_clusters++; } while (num_clusters < p_chain->size); } else { do { - exfat_clear_bitmap(inode, clu); + bool sync = false; + unsigned int n_clu = clu; + int err = exfat_get_next_cluster(sb, &n_clu); - if (exfat_get_next_cluster(sb, &clu)) - goto dec_used_clus; + if (err || n_clu == EXFAT_EOF_CLUSTER) + sync = true; + else + next_cmap_i = + BITMAP_OFFSET_SECTOR_INDEX(sb, CLUSTER_TO_BITMAP_ENT(n_clu)); + + if (cur_cmap_i != next_cmap_i) { + sync = true; + cur_cmap_i = next_cmap_i; + } + + exfat_clear_bitmap(inode, clu, (sync && IS_DIRSYNC(inode))); + clu = n_clu; num_clusters++; + + if (err) + goto dec_used_clus; } while (clu != EXFAT_EOF_CLUSTER); } From f3a311b456ced48ceb06ede3645d8c4c66e6e1fa Mon Sep 17 00:00:00 2001 From: Jaegeuk Kim Date: Wed, 3 Aug 2022 20:33:54 -0700 Subject: [PATCH 84/91] BACKPORT: f2fs: do not set compression bit if kernel doesn't support If kernel doesn't have CONFIG_F2FS_FS_COMPRESSION, a file having FS_COMPR_FL via ioctl(FS_IOC_SETFLAGS) is unaccessible due to f2fs_is_compress_backend_ready(). Let's avoid it. Bug: 240921972 Signed-off-by: Jaegeuk Kim (cherry picked from commit 376523b97c005fa57bb2f8e70f61ab965f16e160) Change-Id: Ieb0f8945175ea5ccb0060690e882f054360fb8f0 --- fs/f2fs/f2fs.h | 7 ++++++- fs/f2fs/file.c | 4 ++-- 2 files changed, 8 insertions(+), 3 deletions(-) diff --git a/fs/f2fs/f2fs.h b/fs/f2fs/f2fs.h index 66f655595d0e..88520c7c3a13 100644 --- a/fs/f2fs/f2fs.h +++ b/fs/f2fs/f2fs.h @@ -4210,8 +4210,9 @@ static inline void f2fs_invalidate_compress_pages(struct f2fs_sb_info *sbi, #define inc_compr_inode_stat(inode) do { } while (0) #endif -static inline void set_compress_context(struct inode *inode) +static inline int set_compress_context(struct inode *inode) { +#ifdef CONFIG_F2FS_FS_COMPRESSION struct f2fs_sb_info *sbi = F2FS_I_SB(inode); F2FS_I(inode)->i_compress_algorithm = @@ -4233,6 +4234,10 @@ static inline void set_compress_context(struct inode *inode) stat_inc_compr_inode(inode); inc_compr_inode_stat(inode); f2fs_mark_inode_dirty_sync(inode, true); + return 0; +#else + return -EOPNOTSUPP; +#endif } static inline bool f2fs_disable_compressed_file(struct inode *inode) diff --git a/fs/f2fs/file.c b/fs/f2fs/file.c index 4c556509c038..016a84ae1ec5 100644 --- a/fs/f2fs/file.c +++ b/fs/f2fs/file.c @@ -1843,8 +1843,8 @@ static int f2fs_setflags_common(struct inode *inode, u32 iflags, u32 mask) return -EINVAL; if (S_ISREG(inode->i_mode) && inode->i_size) return -EINVAL; - - set_compress_context(inode); + if (set_compress_context(inode)) + return -EOPNOTSUPP; } } if ((iflags ^ masked_flags) & F2FS_NOCOMP_FL) { From a6b6bc98b7bc718f425173aa5a4dfa63542c6fd8 Mon Sep 17 00:00:00 2001 From: Kever Yang Date: Fri, 22 Jul 2022 20:52:07 +0800 Subject: [PATCH 85/91] ANDROID: GKI: rockchip: Add symbols for video Leaf changes summary: 9 artifacts changed Changed leaf types summary: 0 leaf type changed Removed/Changed/Added functions summary: 0 Removed, 0 Changed, 9 Added functions Removed/Changed/Added variables summary: 0 Removed, 0 Changed, 0 Added variable 9 Added functions: [A] 'function int __v4l2_ctrl_handler_setup(v4l2_ctrl_handler*)' [A] 'function bool disable_hardirq(unsigned int)' [A] 'function ssize_t iio_read_const_attr(device*, device_attribute*, char*)' [A] 'function platform_device* of_device_alloc(device_node*, const char*, device*)' [A] 'function int v4l2_enum_dv_timings_cap(v4l2_enum_dv_timings*, const v4l2_dv_timings_cap*, v4l2_check_dv_timings_fnc*, void*)' [A] 'function void v4l2_print_dv_timings(const char*, const char*, const v4l2_dv_timings*, bool)' [A] 'function int v4l2_src_change_event_subdev_subscribe(v4l2_subdev*, v4l2_fh*, v4l2_event_subscription*)' [A] 'function void v4l2_subdev_notify_event(v4l2_subdev*, const v4l2_event*)' [A] 'function bool v4l2_valid_dv_timings(const v4l2_dv_timings*, const v4l2_dv_timings_cap*, v4l2_check_dv_timings_fnc*, void*)' Bug: 239396464 Signed-off-by: Kever Yang Change-Id: I79d421eb9afdb774992fe0ea8c403d7d97e3afe2 --- android/abi_gki_aarch64.xml | 70 ++++++++++++++ android/abi_gki_aarch64_rockchip | 154 ++++++++++++++++++++----------- 2 files changed, 169 insertions(+), 55 deletions(-) diff --git a/android/abi_gki_aarch64.xml b/android/abi_gki_aarch64.xml index e3983fd3b185..609f35b7726d 100644 --- a/android/abi_gki_aarch64.xml +++ b/android/abi_gki_aarch64.xml @@ -676,6 +676,7 @@ + @@ -1717,6 +1718,7 @@ + @@ -2933,6 +2935,7 @@ + @@ -3674,6 +3677,7 @@ + @@ -5776,6 +5780,7 @@ + @@ -5834,14 +5839,18 @@ + + + + @@ -30961,6 +30970,11 @@ + + + + + @@ -42087,6 +42101,7 @@ + @@ -52992,6 +53007,7 @@ + @@ -86484,6 +86500,7 @@ + @@ -106560,6 +106577,7 @@ + @@ -119511,6 +119529,10 @@ + + + + @@ -125092,6 +125114,10 @@ + + + + @@ -131393,6 +131419,12 @@ + + + + + + @@ -135154,6 +135186,12 @@ + + + + + + @@ -145938,6 +145976,13 @@ + + + + + + + @@ -146236,6 +146281,13 @@ + + + + + + + @@ -146259,6 +146311,12 @@ + + + + + + @@ -146281,7 +146339,19 @@ + + + + + + + + + + + + diff --git a/android/abi_gki_aarch64_rockchip b/android/abi_gki_aarch64_rockchip index 7fd1c7654b34..44162c69625d 100644 --- a/android/abi_gki_aarch64_rockchip +++ b/android/abi_gki_aarch64_rockchip @@ -42,9 +42,15 @@ blocking_notifier_chain_register blocking_notifier_chain_unregister bpf_trace_run1 + bus_find_device + bus_register + bus_set_iommu + bus_unregister cancel_delayed_work cancel_delayed_work_sync cancel_work_sync + cdev_add + cdev_del cdev_device_add cdev_device_del cdev_init @@ -142,8 +148,10 @@ dev_driver_string _dev_err dev_err_probe + devfreq_add_governor devfreq_recommended_opp dev_fwnode + device_add device_add_disk device_create device_create_file @@ -155,11 +163,13 @@ device_init_wakeup device_link_add device_link_del + device_match_name device_property_present device_property_read_string device_property_read_u32_array device_property_read_u8_array device_release_driver + device_remove_file _dev_info devm_add_action devm_clk_bulk_get @@ -183,6 +193,8 @@ devm_gpiod_get_optional devm_gpio_request devm_gpio_request_one + devm_iio_device_alloc + __devm_iio_device_register devm_input_allocate_device devm_ioremap devm_ioremap_resource @@ -221,6 +233,7 @@ devm_snd_dmaengine_pcm_register devm_snd_soc_register_component devm_usb_get_phy + dev_pm_domain_detach dev_pm_opp_find_freq_ceil dev_pm_opp_get_opp_count dev_pm_opp_get_opp_table @@ -232,6 +245,7 @@ dev_pm_opp_register_set_opp_helper dev_pm_opp_set_rate dev_pm_opp_set_regulators + dev_printk devres_add devres_alloc_node devres_free @@ -274,6 +288,7 @@ dma_unmap_sg_attrs down_read down_write + driver_register driver_unregister drm_add_edid_modes drm_atomic_get_crtc_state @@ -395,6 +410,7 @@ flush_work flush_workqueue fpsimd_context_busy + fput frame_vector_to_pages free_irq __free_pages @@ -416,6 +432,7 @@ gen_pool_free_owner get_cpu_device get_device + get_zeroed_page gic_nonsecure_priorities gpiochip_add_pin_range gpiochip_generic_free @@ -492,12 +509,25 @@ input_set_capability iommu_attach_device iommu_detach_device + iommu_device_register + iommu_device_sysfs_add + iommu_device_sysfs_remove + iommu_get_dma_cookie + iommu_get_domain_for_dev + iommu_group_alloc + iommu_group_put + iommu_group_ref_get + iommu_map + iommu_put_dma_cookie + iommu_set_fault_handler + iommu_unmap __ioremap iounmap irq_create_mapping_affinity __irq_domain_add irq_domain_remove irq_find_mapping + irq_get_irq_data irq_modify_status irq_of_parse_and_map irq_set_chained_handler_and_data @@ -521,6 +551,7 @@ kfree_const __kmalloc kmalloc_caches + kmalloc_order_trace kmem_cache_alloc kmem_cache_alloc_trace kmem_cache_create @@ -534,6 +565,7 @@ kstrtouint kstrtoull kthread_create_on_node + kthread_stop ktime_get ktime_get_mono_fast_ns ktime_get_with_offset @@ -578,6 +610,7 @@ mmc_of_parse mod_delayed_work_on mod_timer + __module_get module_layout module_put __msecs_to_jiffies @@ -587,8 +620,10 @@ mutex_lock mutex_unlock no_llseek + nonseekable_open noop_llseek nr_cpu_ids + ns_to_kernel_old_timeval ns_to_timespec64 nvmem_cell_get nvmem_cell_put @@ -600,6 +635,7 @@ of_clk_get of_clk_get_by_name of_clk_get_parent_count + of_clk_set_defaults of_clk_src_onecell_get of_clk_src_simple_get of_count_phandle_with_args @@ -609,8 +645,10 @@ of_device_is_compatible of_drm_find_bridge of_find_device_by_node + of_find_i2c_device_by_node of_find_matching_node_and_match of_find_node_by_name + of_find_node_opts_by_path of_find_property of_get_child_by_name of_get_drm_display_mode @@ -621,6 +659,7 @@ of_get_parent of_get_property of_get_regulator_init_data + of_graph_get_next_endpoint of_graph_get_remote_node of_graph_get_remote_port_parent of_graph_parse_endpoint @@ -681,6 +720,7 @@ platform_get_irq_byname platform_get_resource platform_get_resource_byname + platform_irq_count pm_clk_create pm_clk_destroy pm_power_off @@ -716,6 +756,7 @@ printk proc_create proc_create_data + proc_mkdir put_device put_disk __put_page @@ -778,6 +819,7 @@ regulator_unregister remap_pfn_range remove_proc_entry + report_iommu_fault request_threaded_irq reset_control_assert reset_control_deassert @@ -893,6 +935,7 @@ __unregister_chrdev unregister_chrdev_region unregister_reboot_notifier + up update_devfreq up_read up_write @@ -912,27 +955,40 @@ v4l2_ctrl_g_ctrl_int64 v4l2_ctrl_handler_free v4l2_ctrl_handler_init_class + __v4l2_ctrl_handler_setup v4l2_ctrl_handler_setup + __v4l2_ctrl_modify_range + v4l2_ctrl_new_custom + v4l2_ctrl_new_int_menu v4l2_ctrl_new_std v4l2_ctrl_new_std_menu v4l2_ctrl_new_std_menu_items + __v4l2_ctrl_s_ctrl + __v4l2_ctrl_s_ctrl_int64 + v4l2_ctrl_subdev_subscribe_event v4l2_device_register v4l2_device_register_subdev __v4l2_device_register_subdev_nodes v4l2_device_unregister v4l2_device_unregister_subdev + v4l2_enum_dv_timings_cap v4l2_event_queue v4l2_event_subdev_unsubscribe v4l2_event_subscribe v4l2_fh_open v4l2_i2c_subdev_init + v4l2_match_dv_timings v4l2_pipeline_pm_get v4l2_pipeline_pm_put + v4l2_print_dv_timings v4l2_querymenu + v4l2_src_change_event_subdev_subscribe v4l2_subdev_call_wrappers v4l2_subdev_init v4l2_subdev_link_validate + v4l2_subdev_notify_event v4l2_type_names + v4l2_valid_dv_timings vabits_actual vb2_buffer_done vb2_common_vm_ops @@ -1116,7 +1172,6 @@ drm_probe_ddc # required by dw-hdmi-hdcp.ko - device_remove_file kstrtobool sha1_init sha1_transform @@ -1221,6 +1276,9 @@ tcpm_vbus_change vsnprintf +# required by gc2145.ko + v4l2_ctrl_subdev_log_status + # required by ghash-ce.ko aes_expandkey gf128mul_lle @@ -1252,7 +1310,6 @@ down input_alloc_absinfo input_mt_sync_frame - up # required by hid-holtek-kbd.ko usb_ifnum_to_if @@ -1275,14 +1332,12 @@ i2c_bit_add_numbered_bus # required by i2c-hid.ko - dev_printk hid_add_device hid_allocate_device hid_destroy_device hid_input_report hid_parse_report i2c_smbus_read_byte - irq_get_irq_data # required by i2c-mux.ko i2c_add_numbered_adapter @@ -1318,7 +1373,6 @@ # required by leds-rgb13h.ko led_classdev_flash_register_ext led_classdev_flash_unregister - ns_to_kernel_old_timeval __usecs_to_jiffies # required by ledtrig-heartbeat.ko @@ -1362,7 +1416,6 @@ bpf_trace_run3 capable cleanup_srcu_struct - device_add device_del device_remove_file_self dev_pm_qos_expose_latency_tolerance @@ -1448,8 +1501,10 @@ sysfs_remove_file_from_group wait_for_completion_io_timeout +# required by nvp6188.ko + kthread_should_stop + # required by optee-rng.ko - driver_register hwrng_register hwrng_unregister @@ -1469,14 +1524,6 @@ msleep_interruptible wait_for_completion_interruptible -# required by ov2680.ko - v4l2_ctrl_auto_cluster - __v4l2_find_nearest_size - -# required by ov5695.ko - __v4l2_ctrl_modify_range - v4l2_ctrl_new_int_menu - # required by panel-simple.ko devm_backlight_device_register drm_bus_flags_from_videomode @@ -1602,7 +1649,6 @@ gpio_free gpio_request kstrtoll - proc_mkdir rfkill_alloc rfkill_destroy rfkill_init_sw_state @@ -1611,17 +1657,12 @@ rfkill_set_sw_state rfkill_unregister -# required by rk1000.ko - of_find_i2c_device_by_node - # required by rk628.ko irq_dispose_mapping irq_domain_xlate_onetwocell irq_set_parent # required by rk628_dsi.ko - bus_find_device - device_match_name of_drm_find_panel # required by rk805-pwrkey.ko @@ -1658,9 +1699,42 @@ # required by rk_headset_irq_hook_adc.ko iio_read_channel_raw +# required by rk_vcodec.ko + devfreq_register_opp_notifier + devfreq_remove_governor + devfreq_unregister_opp_notifier + devm_iounmap + dev_pm_domain_attach + dev_pm_opp_get_freq + dev_pm_opp_of_remove_table + disable_hardirq + dma_buf_begin_cpu_access + dma_buf_end_cpu_access + dma_buf_get + __fdget + iommu_attach_group + iommu_detach_group + iommu_device_unregister + iommu_dma_reserve_iova + iommu_group_get + kstrtouint_from_user + kthread_flush_worker + __kthread_init_worker + kthread_queue_work + kthread_worker_fn + of_device_alloc + of_dma_configure_id + platform_device_del + pm_generic_runtime_resume + pm_generic_runtime_suspend + pm_relax + pm_stay_awake + proc_create_single_data + proc_remove + strncat + # required by rknpu.ko dev_pm_domain_attach_by_name - dev_pm_domain_detach dma_buf_mmap dma_fence_signal drm_gem_create_mmap_offset @@ -1670,7 +1744,6 @@ drm_gem_prime_import_dev drm_gem_vm_open hrtimer_forward - iommu_get_domain_for_dev set_user_nice vmf_insert_mixed vm_insert_page @@ -1680,20 +1753,6 @@ dev_pm_opp_put_prop_name dev_pm_opp_set_supported_hw -# required by rockchip-iommu.ko - bus_set_iommu - get_zeroed_page - iommu_device_register - iommu_device_sysfs_add - iommu_device_sysfs_remove - iommu_get_dma_cookie - iommu_group_alloc - iommu_group_put - iommu_group_ref_get - iommu_put_dma_cookie - platform_irq_count - report_iommu_fault - # required by rockchip-rng.ko devm_hwrng_register devm_of_iomap @@ -1715,7 +1774,6 @@ cpufreq_cpu_get cpufreq_cpu_put cpufreq_quick_get - devfreq_add_governor devfreq_event_disable_edev devfreq_event_enable_edev devfreq_event_get_edev_by_phandle @@ -1751,7 +1809,6 @@ dev_pm_opp_disable dev_pm_opp_of_add_table dev_pm_opp_set_prop_name - of_find_node_opts_by_path regulator_get_linear_step regulator_get_optional @@ -1761,8 +1818,6 @@ __tasklet_hi_schedule # required by rockchip_saradc.ko - devm_iio_device_alloc - __devm_iio_device_register iio_get_time_ns iio_push_to_buffers iio_trigger_notify_done @@ -1944,16 +1999,11 @@ drm_writeback_signal_completion iommu_domain_alloc iommu_domain_free - iommu_map iommu_map_sg - iommu_set_fault_handler - iommu_unmap memblock_free mipi_dsi_packet_format_is_short - of_clk_set_defaults of_find_backlight_by_node of_fwnode_ops - of_graph_get_next_endpoint of_graph_get_port_by_id of_graph_get_remote_port phy_mipi_dphy_get_default_config @@ -2007,16 +2057,12 @@ blk_put_request blk_rq_map_user_iov blk_verify_command - cdev_add cdev_alloc - cdev_del class_interface_unregister fasync_helper get_sg_io_hdr import_iovec kill_fasync - __module_get - nonseekable_open put_sg_io_hdr _raw_read_lock_irqsave _raw_read_unlock_irqrestore @@ -2111,7 +2157,6 @@ dma_fence_init dma_fence_signal_locked fd_install - fput __get_task_comm get_unused_fd_flags put_unused_fd @@ -2139,8 +2184,6 @@ # required by tee.ko anon_inode_getfd - bus_register - bus_unregister class_find_device crypto_alloc_shash crypto_shash_final @@ -2190,11 +2233,9 @@ # required by video_rkcif.ko media_entity_setup_link - __v4l2_ctrl_s_ctrl_int64 work_busy # required by video_rkisp.ko - kmalloc_order_trace media_device_cleanup __memcpy_fromio __memcpy_toio @@ -2206,6 +2247,9 @@ # required by videobuf2-dma-sg.ko split_page +# required by vl6180.ko + iio_read_const_attr + # required by zram.ko __alloc_percpu bio_endio From 504ce2d3a6177da5de109f4995666b4dca2012d6 Mon Sep 17 00:00:00 2001 From: Kever Yang Date: Fri, 22 Jul 2022 21:08:45 +0800 Subject: [PATCH 86/91] ANDROID: GKI: rockchip: Add symbols for sound Leaf changes summary: 3 artifacts changed Changed leaf types summary: 0 leaf type changed Removed/Changed/Added functions summary: 0 Removed, 0 Changed, 3 Added functions Removed/Changed/Added variables summary: 0 Removed, 0 Changed, 0 Added variable 3 Added functions: [A] 'function int snd_soc_dapm_force_bias_level(snd_soc_dapm_context*, snd_soc_bias_level)' [A] 'function int snd_soc_jack_add_zones(snd_soc_jack*, int, snd_soc_jack_zone*)' [A] 'function int snd_soc_jack_get_type(snd_soc_jack*, int)' Bug: 239396464 Signed-off-by: Kever Yang Change-Id: Ib4245f28716e4c68c3e04205421aa8bb9910576b --- android/abi_gki_aarch64.xml | 37 ++++ android/abi_gki_aarch64_rockchip | 322 +++++++++++++++++++++++++------ 2 files changed, 297 insertions(+), 62 deletions(-) diff --git a/android/abi_gki_aarch64.xml b/android/abi_gki_aarch64.xml index 609f35b7726d..df7cf5c4b51f 100644 --- a/android/abi_gki_aarch64.xml +++ b/android/abi_gki_aarch64.xml @@ -4975,6 +4975,7 @@ + @@ -5012,6 +5013,8 @@ + + @@ -11788,6 +11791,23 @@ + + + + + + + + + + + + + + + + + @@ -71756,6 +71776,7 @@ + @@ -141916,6 +141937,11 @@ + + + + + @@ -142103,6 +142129,17 @@ + + + + + + + + + + + diff --git a/android/abi_gki_aarch64_rockchip b/android/abi_gki_aarch64_rockchip index 44162c69625d..7d6aeb518bd0 100644 --- a/android/abi_gki_aarch64_rockchip +++ b/android/abi_gki_aarch64_rockchip @@ -95,6 +95,7 @@ clk_put clk_register clk_round_rate + clk_set_parent clk_set_phase clk_set_rate clk_unprepare @@ -123,6 +124,8 @@ __cpu_possible_mask cpus_read_lock cpus_read_unlock + crc16 + crc32_le crypto_destroy_tfm crypto_inc __crypto_memneq @@ -155,6 +158,7 @@ device_add_disk device_create device_create_file + device_del device_destroy device_get_child_node_count device_get_named_child_node @@ -170,7 +174,11 @@ device_property_read_u8_array device_release_driver device_remove_file + device_set_wakeup_capable + device_set_wakeup_enable + device_wakeup_enable _dev_info + __dev_kfree_skb_any devm_add_action devm_clk_bulk_get devm_clk_bulk_get_all @@ -193,6 +201,7 @@ devm_gpiod_get_optional devm_gpio_request devm_gpio_request_one + devm_iio_channel_get devm_iio_device_alloc __devm_iio_device_register devm_input_allocate_device @@ -231,6 +240,7 @@ devm_reset_control_array_get __devm_reset_control_get devm_snd_dmaengine_pcm_register + devm_snd_soc_register_card devm_snd_soc_register_component devm_usb_get_phy dev_pm_domain_detach @@ -275,6 +285,10 @@ dma_map_sg_attrs dmam_free_coherent dma_mmap_attrs + dma_pool_alloc + dma_pool_create + dma_pool_destroy + dma_pool_free dma_release_channel dma_request_chan dma_set_coherent_mask @@ -384,7 +398,6 @@ drm_panel_prepare drm_panel_unprepare drm_poll - drm_prime_gem_destroy drm_prime_pages_to_sg drm_prime_sg_to_page_addr_arrays drm_property_replace_global_blob @@ -395,6 +408,9 @@ drm_scdc_set_scrambling drm_scdc_write enable_irq + eth_mac_addr + eth_platform_get_mac_address + eth_validate_addr event_triggers_call extcon_get_edev_by_phandle extcon_get_state @@ -425,6 +441,12 @@ fwnode_property_read_u32_array gcd generic_handle_irq + generic_mii_ioctl + __genphy_config_aneg + genphy_read_status + genphy_resume + genphy_soft_reset + genphy_suspend gen_pool_add_owner gen_pool_alloc_algo_owner gen_pool_create @@ -432,6 +454,7 @@ gen_pool_free_owner get_cpu_device get_device + get_random_bytes get_zeroed_page gic_nonsecure_priorities gpiochip_add_pin_range @@ -458,6 +481,7 @@ hdmi_audio_infoframe_pack hdmi_drm_infoframe_pack hdmi_infoframe_pack + hdmi_vendor_infoframe_pack hid_debug hid_hw_close hid_hw_open @@ -493,6 +517,9 @@ idr_remove iio_buffer_init iio_buffer_put + iio_device_attach_buffer + iio_push_to_buffers + iio_read_channel_processed __init_rwsem __init_swait_queue_head init_timer_key @@ -582,6 +609,8 @@ __log_read_mmio __log_write_mmio lzo1x_decompress_safe + mdiobus_read + mdiobus_write media_create_pad_link media_device_init __media_device_register @@ -596,10 +625,14 @@ media_pipeline_stop memcpy memdup_user + memmove memset memstart_addr mfd_add_devices mfd_remove_devices + mii_check_media + mii_ethtool_gset + mii_nway_restart mipi_dsi_attach mipi_dsi_create_packet mipi_dsi_detach @@ -618,7 +651,11 @@ __mutex_init mutex_is_locked mutex_lock + mutex_lock_interruptible mutex_unlock + netdev_err + netdev_info + netdev_warn no_llseek nonseekable_open noop_llseek @@ -671,6 +708,7 @@ of_node_name_eq of_nvmem_cell_get of_parse_phandle + of_parse_phandle_with_args of_phy_simple_xlate of_property_count_elems_of_size of_property_match_string @@ -679,6 +717,7 @@ of_property_read_u32_index of_property_read_variable_u32_array of_property_read_variable_u8_array + of_prop_next_string of_regulator_match of_reserved_mem_device_init_by_idx __of_reset_control_get @@ -695,6 +734,8 @@ perf_trace_run_bpf_submit pfn_valid phy_configure + phy_drivers_register + phy_drivers_unregister phy_exit phy_init phy_power_off @@ -757,6 +798,7 @@ proc_create proc_create_data proc_mkdir + pskb_expand_head put_device put_disk __put_page @@ -861,26 +903,50 @@ simple_strtol single_open single_release + skb_clone + skb_copy_expand + skb_pull + skb_push + skb_put + skb_trim skcipher_walk_aead_decrypt skcipher_walk_aead_encrypt skcipher_walk_done snd_pcm_format_width + snd_soc_add_component_controls + snd_soc_card_jack_new snd_soc_component_read + snd_soc_component_set_jack snd_soc_component_update_bits snd_soc_component_write + snd_soc_dai_set_sysclk + snd_soc_dapm_add_routes + snd_soc_dapm_disable_pin_unlocked snd_soc_dapm_force_enable_pin_unlocked snd_soc_dapm_get_enum_double + snd_soc_dapm_get_pin_switch snd_soc_dapm_get_volsw + snd_soc_dapm_info_pin_switch + snd_soc_dapm_new_controls snd_soc_dapm_put_enum_double + snd_soc_dapm_put_pin_switch snd_soc_dapm_put_volsw + snd_soc_dapm_sync_unlocked + snd_soc_get_dai_name snd_soc_get_enum_double snd_soc_get_volsw snd_soc_info_enum_double snd_soc_info_volsw snd_soc_jack_add_gpios snd_soc_jack_report + snd_soc_of_parse_audio_routing + snd_soc_of_parse_card_name + snd_soc_of_parse_daifmt + snd_soc_params_to_frame_size + snd_soc_pm_ops snd_soc_put_enum_double snd_soc_put_volsw + snd_soc_unregister_component snprintf __spi_register_driver spi_sync @@ -907,6 +973,8 @@ sysfs_remove_group sysfs_remove_link system_freezable_wq + system_power_efficient_wq + system_state system_unbound_wq system_wq tasklet_init @@ -928,6 +996,8 @@ __tracepoint_rwmmio_write trace_raw_output_prep trace_seq_printf + try_module_get + tty_termios_baud_rate typec_switch_get_drvdata typec_switch_register typec_switch_unregister @@ -939,8 +1009,63 @@ update_devfreq up_read up_write + usb_add_hcd + usb_alloc_urb + usb_autopm_get_interface + usb_autopm_put_interface + usb_calc_bus_time + usb_control_msg + usb_create_hcd usb_debug_root + usb_deregister + usb_deregister_dev + usb_disabled + usb_free_urb + usb_get_dev + usb_get_intf + usb_hcd_check_unlink_urb + usb_hcd_giveback_urb + usb_hcd_link_urb_to_ep + usb_hcd_resume_root_hub + usb_hcd_unlink_urb_from_ep usb_hid_driver + usb_match_id + usbnet_change_mtu + usbnet_defer_kevent + usbnet_disconnect + usbnet_get_drvinfo + usbnet_get_endpoints + usbnet_get_link + usbnet_get_link_ksettings + usbnet_get_msglevel + usbnet_get_stats64 + usbnet_link_change + usbnet_nway_reset + usbnet_open + usbnet_probe + usbnet_read_cmd + usbnet_read_cmd_nopm + usbnet_resume + usbnet_set_link_ksettings + usbnet_set_msglevel + usbnet_skb_return + usbnet_start_xmit + usbnet_stop + usbnet_suspend + usbnet_tx_timeout + usbnet_write_cmd + usbnet_write_cmd_async + usbnet_write_cmd_nopm + usb_poison_urb + usb_put_dev + usb_put_hcd + usb_put_intf + usb_register_dev + usb_register_driver + usb_remove_hcd + usb_set_interface + usb_submit_urb + usb_unpoison_urb usleep_range uuid_null v4l2_async_notifier_cleanup @@ -1049,15 +1174,12 @@ serial8250_suspend_port serial8250_unregister_port serial8250_update_uartclk - tty_termios_baud_rate # required by act8865-regulator.ko regulator_set_pull_down_regmap # required by adc-keys.ko - devm_iio_channel_get iio_get_channel_type - iio_read_channel_processed input_set_poll_interval input_setup_polling @@ -1072,8 +1194,23 @@ of_find_compatible_node power_supply_get_by_name -# required by bq25890_charger.ko - system_power_efficient_wq +# required by cdc-wdm.ko + cdc_parse_cdc_header + +# required by cdc_mbim.ko + cdc_ncm_bind_common + cdc_ncm_change_mtu + cdc_ncm_fill_tx_frame + cdc_ncm_rx_verify_ndp16 + cdc_ncm_rx_verify_nth16 + cdc_ncm_select_altsetting + cdc_ncm_unbind + in6_dev_finish_destroy + __ipv6_addr_type + ipv6_stub + __netdev_alloc_skb + __rcu_read_lock + __rcu_read_unlock # required by ch.ko param_array_ops @@ -1171,6 +1308,9 @@ drm_atomic_get_new_bridge_state drm_probe_ddc +# required by dm9601.ko + mii_link_ok + # required by dw-hdmi-hdcp.ko kstrtobool sha1_init @@ -1183,7 +1323,6 @@ # required by dw-hdmi.ko drm_connector_attach_max_bpc_property drm_default_rgb_quant_range - hdmi_vendor_infoframe_pack of_graph_get_endpoint_by_regs # required by dw-mipi-dsi.ko @@ -1231,33 +1370,20 @@ __bitmap_clear bitmap_find_next_zero_area_off __bitmap_set - device_set_wakeup_capable - device_wakeup_enable phy_reset _raw_spin_trylock usb_add_gadget_udc - usb_add_hcd - usb_calc_bus_time - usb_create_hcd usb_del_gadget_udc - usb_disabled usb_ep_set_maxpacket_limit usb_gadget_giveback_request usb_gadget_map_request usb_gadget_set_state usb_gadget_unmap_request usb_get_dr_mode - usb_hcd_check_unlink_urb - usb_hcd_giveback_urb - usb_hcd_link_urb_to_ep usb_hcd_map_urb_for_dma - usb_hcd_resume_root_hub - usb_hcd_unlink_urb_from_ep usb_hcd_unmap_urb_for_dma usb_hub_clear_tt_buffer usb_phy_set_charger_current - usb_put_hcd - usb_remove_hcd usb_role_switch_get_drvdata usb_role_switch_register usb_role_switch_unregister @@ -1283,6 +1409,9 @@ aes_expandkey gf128mul_lle +# required by gl620a.ko + __alloc_skb + # required by gpio-regulator.ko gpiod_count @@ -1314,9 +1443,6 @@ # required by hid-holtek-kbd.ko usb_ifnum_to_if -# required by hid-ntrig.ko - usb_control_msg - # required by hid-primax.ko hid_report_raw_event @@ -1359,16 +1485,17 @@ # required by industrialio-triggered-buffer.ko iio_alloc_pollfunc iio_dealloc_pollfunc - iio_device_attach_buffer # required by io-domain.ko _dev_crit regulator_register_notifier regulator_unregister_notifier +# required by kalmia.ko + usb_bulk_msg + # required by kfifo_buf.ko __kfifo_to_user - mutex_lock_interruptible # required by leds-rgb13h.ko led_classdev_flash_register_ext @@ -1416,7 +1543,6 @@ bpf_trace_run3 capable cleanup_srcu_struct - device_del device_remove_file_self dev_pm_qos_expose_latency_tolerance dev_pm_qos_hide_latency_tolerance @@ -1436,7 +1562,6 @@ synchronize_srcu trace_print_symbols_seq trace_seq_putc - try_module_get xa_destroy xa_erase xa_find @@ -1458,10 +1583,6 @@ blk_put_queue __blk_rq_map_sg dma_max_mapping_size - dma_pool_alloc - dma_pool_create - dma_pool_destroy - dma_pool_free __do_once_done __do_once_start mempool_alloc @@ -1504,6 +1625,24 @@ # required by nvp6188.ko kthread_should_stop +# required by ohci-hcd.ko + default_llseek + gen_pool_dma_alloc_align + gen_pool_dma_zalloc_align + sb800_prefetch + schedule_timeout_uninterruptible + simple_read_from_buffer + usb_amd_dev_put + usb_amd_quirk_pll_disable + usb_amd_quirk_pll_enable + usb_hc_died + usb_hcd_poll_rh_status + usb_hcds_loaded + usb_root_hub_lost_power + +# required by ohci-platform.ko + usb_hcd_platform_shutdown + # required by optee-rng.ko hwrng_register hwrng_unregister @@ -1551,7 +1690,6 @@ dw_pcie_setup_rc dw_pcie_write dw_pcie_write_dbi - of_prop_next_string # required by pcierockchiphost.ko devm_pci_alloc_host_bridge @@ -1709,7 +1847,9 @@ dev_pm_opp_of_remove_table disable_hardirq dma_buf_begin_cpu_access + dma_buf_begin_cpu_access_partial dma_buf_end_cpu_access + dma_buf_end_cpu_access_partial dma_buf_get __fdget iommu_attach_group @@ -1743,6 +1883,7 @@ drm_gem_prime_export drm_gem_prime_import_dev drm_gem_vm_open + drm_prime_gem_destroy hrtimer_forward set_user_nice vmf_insert_mixed @@ -1757,16 +1898,6 @@ devm_hwrng_register devm_of_iomap -# required by rockchip.ko - __genphy_config_aneg - genphy_resume - genphy_soft_reset - genphy_suspend - mdiobus_read - mdiobus_write - phy_drivers_register - phy_drivers_unregister - # required by rockchip_bus.ko cpu_topology @@ -1819,7 +1950,6 @@ # required by rockchip_saradc.ko iio_get_time_ns - iio_push_to_buffers iio_trigger_notify_done # required by rockchip_system_monitor.ko @@ -1844,7 +1974,6 @@ # required by rockchipdrm.ko adjust_managed_page_count - clk_set_parent component_add component_bind_all component_del @@ -2091,13 +2220,30 @@ # required by sii902x.ko hdmi_avi_infoframe_pack -# required by snd-soc-cx2072x.ko - snd_soc_params_to_frame_size +# required by smsc95xx.ko + csum_partial + ethtool_op_get_ts_info + mdiobus_alloc_size + mdiobus_free + __mdiobus_register + mdiobus_unregister + phy_attached_info + phy_connect_direct + phy_disconnect + phy_ethtool_get_link_ksettings + phy_ethtool_nway_reset + phy_ethtool_set_link_ksettings + phy_find_first + phy_get_pause + phy_init_hw + phy_mii_ioctl + phy_print_status + phy_start + phy_stop + usb_autopm_get_interface_no_resume # required by snd-soc-es8316.ko snd_pcm_hw_constraint_list - snd_soc_dapm_disable_pin_unlocked - snd_soc_dapm_sync_unlocked # required by snd-soc-hdmi-codec.ko snd_ctl_add @@ -2107,38 +2253,43 @@ snd_pcm_fill_iec958_consumer snd_pcm_fill_iec958_consumer_hw_params snd_pcm_hw_constraint_eld - snd_soc_dapm_add_routes # required by snd-soc-rk817.ko - snd_soc_add_component_controls snd_soc_component_exit_regmap snd_soc_component_init_regmap - snd_soc_unregister_component + +# required by snd-soc-rockchip-hdmi.ko + snd_soc_dapm_new_widgets + +# required by snd-soc-rockchip-i2s-tdm.ko + clk_is_match + snd_soc_add_dai_controls + +# required by snd-soc-rockchip-multicodecs.ko + of_parse_phandle_with_fixed_args + round_jiffies_relative + snd_soc_jack_add_zones + snd_soc_jack_get_type + +# required by snd-soc-rt5640.ko + gpiod_set_raw_value_cansleep + regmap_register_patch + snd_soc_dapm_force_bias_level + system_long_wq # required by snd-soc-simple-card-utils.ko devm_kasprintf devm_kvasprintf - snd_soc_card_jack_new - snd_soc_dai_set_sysclk snd_soc_dai_set_tdm_slot - snd_soc_dapm_get_pin_switch - snd_soc_dapm_info_pin_switch - snd_soc_dapm_put_pin_switch - snd_soc_of_parse_audio_routing snd_soc_of_parse_audio_simple_widgets - snd_soc_of_parse_card_name - snd_soc_of_parse_daifmt snd_soc_runtime_calc_hw # required by snd-soc-simple-card.ko - devm_snd_soc_register_card - of_parse_phandle_with_args snd_soc_dai_link_set_capabilities snd_soc_of_get_dai_name snd_soc_of_parse_aux_devs snd_soc_of_parse_node_prefix snd_soc_of_parse_tdm_slot - snd_soc_pm_ops # required by spi-rockchip.ko devm_spi_register_controller @@ -2219,6 +2370,53 @@ typec_altmode_vdm typec_get_negotiated_svdm_version +# required by usblp.ko + add_wait_queue + default_wake_function + remove_wait_queue + stpcpy + usb_anchor_urb + usb_find_common_endpoints + usb_find_interface + usb_kill_anchored_urbs + usb_poison_anchored_urbs + usb_unanchor_urb + +# required by usbserial.ko + driver_attach + param_ops_ushort + put_tty_driver + schedule_timeout_interruptible + seq_putc + __tty_alloc_driver + tty_flip_buffer_push + tty_hangup + __tty_insert_flip_char + tty_insert_flip_string_fixed_flag + tty_kref_put + tty_ldisc_deref + tty_ldisc_ref + tty_port_close + tty_port_destroy + tty_port_hangup + tty_port_init + tty_port_open + tty_port_register_device + tty_port_tty_get + tty_port_tty_wakeup + tty_register_driver + tty_set_operations + tty_standard_install + tty_std_termios + tty_termios_copy_hw + tty_unregister_device + tty_unregister_driver + tty_vhangup + usb_kill_urb + usb_match_one_id + usb_show_dynids + usb_store_new_id + # required by v4l2-fwnode.ko fwnode_device_is_available fwnode_graph_get_next_endpoint From efdf581d14e334e8b8782168d93e2f943a94f0f9 Mon Sep 17 00:00:00 2001 From: Kever Yang Date: Fri, 22 Jul 2022 21:41:19 +0800 Subject: [PATCH 87/91] ANDROID: GKI: rockchip: Add symbol pci_disable_link_state Leaf changes summary: 1 artifact changed Changed leaf types summary: 0 leaf type changed Removed/Changed/Added functions summary: 0 Removed, 0 Changed, 1 Added function Removed/Changed/Added variables summary: 0 Removed, 0 Changed, 0 Added variable 1 Added function: [A] 'function int pci_disable_link_state(pci_dev*, int)' Bug: 239396464 Signed-off-by: Kever Yang Change-Id: Ie6c80e92fa1603f575595464f0ff8df04bd51f2a --- android/abi_gki_aarch64.xml | 6 + android/abi_gki_aarch64_rockchip | 405 ++++++++++++++++++++++++------- 2 files changed, 321 insertions(+), 90 deletions(-) diff --git a/android/abi_gki_aarch64.xml b/android/abi_gki_aarch64.xml index df7cf5c4b51f..f535ad8a6b61 100644 --- a/android/abi_gki_aarch64.xml +++ b/android/abi_gki_aarch64.xml @@ -3865,6 +3865,7 @@ + @@ -136216,6 +136217,11 @@ + + + + + diff --git a/android/abi_gki_aarch64_rockchip b/android/abi_gki_aarch64_rockchip index 7d6aeb518bd0..4431bfa09cb7 100644 --- a/android/abi_gki_aarch64_rockchip +++ b/android/abi_gki_aarch64_rockchip @@ -6,7 +6,9 @@ alloc_chrdev_region __alloc_disk_node __alloc_pages_nodemask + __alloc_skb alloc_workqueue + anon_inode_getfd __arch_copy_from_user __arch_copy_to_user arm64_const_caps_ready @@ -42,6 +44,12 @@ blocking_notifier_chain_register blocking_notifier_chain_unregister bpf_trace_run1 + bpf_trace_run2 + bpf_trace_run3 + bpf_trace_run4 + bpf_trace_run5 + bpf_trace_run6 + bpf_trace_run7 bus_find_device bus_register bus_set_iommu @@ -74,6 +82,7 @@ class_destroy class_for_each_device __class_register + class_unregister clk_bulk_disable clk_bulk_enable clk_bulk_prepare @@ -106,6 +115,7 @@ complete completion_done __const_udelay + consume_skb __cpufreq_driver_target cpufreq_generic_suspend cpufreq_register_governor @@ -126,6 +136,7 @@ cpus_read_unlock crc16 crc32_le + crypto_alloc_shash crypto_destroy_tfm crypto_inc __crypto_memneq @@ -133,26 +144,35 @@ crypto_register_alg crypto_register_scomp crypto_register_shash + crypto_shash_update crypto_unregister_aead crypto_unregister_alg crypto_unregister_scomp crypto_unregister_shash __crypto_xor + debugfs_attr_read + debugfs_attr_write debugfs_create_dir debugfs_create_file debugfs_create_regset32 debugfs_remove + default_llseek delayed_work_timer_fn del_gendisk del_timer del_timer_sync desc_to_gpio destroy_workqueue + dev_close dev_driver_string _dev_err dev_err_probe devfreq_add_governor devfreq_recommended_opp + devfreq_register_opp_notifier + devfreq_resume_device + devfreq_suspend_device + devfreq_unregister_opp_notifier dev_fwnode device_add device_add_disk @@ -243,18 +263,22 @@ devm_snd_soc_register_card devm_snd_soc_register_component devm_usb_get_phy + _dev_notice dev_pm_domain_detach dev_pm_opp_find_freq_ceil + dev_pm_opp_find_freq_floor dev_pm_opp_get_opp_count dev_pm_opp_get_opp_table dev_pm_opp_get_voltage dev_pm_opp_of_get_sharing_cpus + dev_pm_opp_of_remove_table dev_pm_opp_put dev_pm_opp_put_opp_table dev_pm_opp_put_regulators dev_pm_opp_register_set_opp_helper dev_pm_opp_set_rate dev_pm_opp_set_regulators + dev_pm_opp_unregister_set_opp_helper dev_printk devres_add devres_alloc_node @@ -265,15 +289,22 @@ disable_irq_nosync dma_alloc_attrs dma_buf_attach + dma_buf_begin_cpu_access dma_buf_detach + dma_buf_end_cpu_access dma_buf_export dma_buf_fd + dma_buf_get dma_buf_map_attachment + dma_buf_mmap dma_buf_put dma_buf_unmap_attachment dma_buf_vmap dma_buf_vunmap + dma_fence_context_alloc + dma_fence_init dma_fence_release + dma_fence_signal dma_free_attrs dma_get_sgtable_attrs dma_heap_add @@ -410,6 +441,7 @@ enable_irq eth_mac_addr eth_platform_get_mac_address + eth_type_trans eth_validate_addr event_triggers_call extcon_get_edev_by_phandle @@ -419,8 +451,10 @@ extcon_set_state_sync extcon_unregister_notifier failure_tracking + fd_install find_next_bit find_next_zero_bit + find_vma finish_wait flush_delayed_work flush_work @@ -431,6 +465,7 @@ free_irq __free_pages free_pages + free_percpu freq_qos_add_request freq_qos_remove_request freq_qos_update_request @@ -454,7 +489,9 @@ gen_pool_free_owner get_cpu_device get_device + __get_free_pages get_random_bytes + get_unused_fd_flags get_zeroed_page gic_nonsecure_priorities gpiochip_add_pin_range @@ -493,6 +530,7 @@ hid_unregister_driver hid_validate_values hrtimer_cancel + hrtimer_forward hrtimer_init hrtimer_start_range_ns i2c_adapter_type @@ -513,6 +551,8 @@ idr_alloc idr_destroy idr_find + idr_for_each + idr_get_next idr_preload idr_remove iio_buffer_init @@ -557,6 +597,7 @@ irq_get_irq_data irq_modify_status irq_of_parse_and_map + irq_set_affinity_hint irq_set_chained_handler_and_data irq_set_chip irq_set_chip_and_handler_name @@ -576,6 +617,9 @@ __kfifo_out kfree kfree_const + kfree_sensitive + kfree_skb + kimage_voffset __kmalloc kmalloc_caches kmalloc_order_trace @@ -586,17 +630,23 @@ kmem_cache_free kmemdup kobject_create_and_add + kobject_put + kobject_uevent_env kstrdup kstrdup_const kstrtoint kstrtouint + kstrtouint_from_user kstrtoull kthread_create_on_node + kthread_should_stop kthread_stop ktime_get ktime_get_mono_fast_ns + ktime_get_real_ts64 ktime_get_with_offset kvfree + kvfree_call_rcu kvmalloc_node led_classdev_register_ext led_classdev_unregister @@ -648,11 +698,13 @@ module_put __msecs_to_jiffies msleep + msleep_interruptible __mutex_init mutex_is_locked mutex_lock mutex_lock_interruptible mutex_unlock + __netdev_alloc_skb netdev_err netdev_info netdev_warn @@ -681,6 +733,7 @@ of_device_is_available of_device_is_compatible of_drm_find_bridge + of_find_compatible_node of_find_device_by_node of_find_i2c_device_by_node of_find_matching_node_and_match @@ -688,6 +741,7 @@ of_find_node_opts_by_path of_find_property of_get_child_by_name + of_get_compatible_child of_get_drm_display_mode of_get_i2c_adapter_by_node of_get_named_gpio_flags @@ -715,16 +769,19 @@ of_property_read_string of_property_read_string_helper of_property_read_u32_index + of_property_read_u64 of_property_read_variable_u32_array of_property_read_variable_u8_array - of_prop_next_string of_regulator_match of_reserved_mem_device_init_by_idx __of_reset_control_get of_usb_get_dr_mode_by_phy __page_pinner_migration_failed panic_notifier_list + param_array_ops param_ops_bool + param_ops_byte + param_ops_charp param_ops_int param_ops_string param_ops_uint @@ -799,6 +856,7 @@ proc_create_data proc_mkdir pskb_expand_head + __pskb_pull_tail put_device put_disk __put_page @@ -817,6 +875,11 @@ _raw_spin_unlock_bh _raw_spin_unlock_irq _raw_spin_unlock_irqrestore + rb_erase + rb_insert_color + rb_next + __rcu_read_lock + __rcu_read_unlock rdev_get_drvdata rdev_get_id refcount_warn_saturate @@ -825,8 +888,10 @@ regcache_sync __register_chrdev register_chrdev_region + register_netdevice_notifier register_pm_notifier register_reboot_notifier + register_shrinker regmap_bulk_read regmap_bulk_write regmap_field_read @@ -846,6 +911,7 @@ regulator_enable regulator_enable_regmap regulator_get + regulator_get_optional regulator_get_voltage regulator_get_voltage_sel_regmap regulator_is_enabled @@ -859,17 +925,28 @@ regulator_set_voltage_sel_regmap regulator_set_voltage_time_sel regulator_unregister + release_firmware remap_pfn_range remove_proc_entry report_iommu_fault + request_firmware request_threaded_irq reset_control_assert reset_control_deassert revalidate_disk_size + rfkill_alloc + rfkill_destroy + rfkill_register + rfkill_set_hw_state + rfkill_unregister + round_jiffies_relative rtc_class_open rtc_read_time rtc_tm_to_time64 rtc_valid_tm + rtnl_is_locked + rtnl_lock + rtnl_unlock scatterwalk_map_and_copy sched_clock schedule @@ -893,17 +970,25 @@ sdhci_suspend_host seq_lseek seq_printf + seq_putc seq_puts seq_read set_page_dirty_lock sg_alloc_table sg_alloc_table_from_pages sg_free_table + sg_init_table sg_next + __sg_page_iter_next + __sg_page_iter_start + simple_attr_open + simple_attr_release + simple_read_from_buffer simple_strtol single_open single_release skb_clone + skb_copy_bits skb_copy_expand skb_pull skb_push @@ -958,21 +1043,31 @@ strcpy strlcpy strlen + strncasecmp strncmp strncpy strnlen strscpy strstr + __sw_hweight16 + __sw_hweight32 + __sw_hweight64 + __sw_hweight8 + sync_file_create synchronize_irq + synchronize_rcu syscon_node_to_regmap syscon_regmap_lookup_by_phandle sysfs_create_file_ns sysfs_create_group sysfs_create_link __sysfs_match_string + sysfs_remove_file_ns sysfs_remove_group sysfs_remove_link + sysfs_streq system_freezable_wq + system_long_wq system_power_efficient_wq system_state system_unbound_wq @@ -994,6 +1089,8 @@ __tracepoint_rwmmio_post_read __tracepoint_rwmmio_read __tracepoint_rwmmio_write + trace_print_array_seq + trace_print_symbols_seq trace_raw_output_prep trace_seq_printf try_module_get @@ -1004,7 +1101,9 @@ __udelay __unregister_chrdev unregister_chrdev_region + unregister_netdevice_notifier unregister_reboot_notifier + unregister_shrinker up update_devfreq up_read @@ -1066,6 +1165,7 @@ usb_set_interface usb_submit_urb usb_unpoison_urb + __usecs_to_jiffies usleep_range uuid_null v4l2_async_notifier_cleanup @@ -1152,6 +1252,7 @@ vm_map_ram vm_unmap_ram vunmap + vzalloc wait_for_completion wait_for_completion_timeout __wake_up @@ -1190,8 +1291,80 @@ drm_dp_start_crc drm_dp_stop_crc +# required by bifrost_kbase.ko + __arch_clear_user + __bitmap_andnot + __bitmap_equal + __bitmap_or + __bitmap_weight + cache_line_size + clear_page + complete_all + debugfs_create_bool + devfreq_add_device + devfreq_cooling_unregister + devfreq_remove_device + dev_pm_opp_find_freq_exact + dma_fence_add_callback + dma_fence_default_wait + dma_fence_get_status + dma_fence_remove_callback + downgrade_write + down_read_trylock + dump_stack + find_get_pid + freezing_slow_path + generic_file_llseek + get_user_pages + get_user_pages_fast + hrtimer_active + iomem_resource + kobject_del + kobject_init_and_add + kstrndup + kstrtobool_from_user + ktime_get_raw + ktime_get_raw_ts64 + memchr + __mmdrop + of_dma_is_coherent + of_property_read_variable_u64_array + pid_task + pin_user_pages + pin_user_pages_remote + put_pid + rb_first + rb_prev + rb_replace_node + __refrigerator + register_oom_notifier + __release_region + remap_vmalloc_range + __request_region + seq_open + __seq_open_private + seq_release + seq_release_private + seq_write + set_freezable + shmem_file_setup + simple_open + strcspn + sync_file_get_fence + system_freezing_cnt + system_highpri_wq + _totalram_pages + __traceiter_gpu_mem_total + trace_output_call + __tracepoint_gpu_mem_total + trace_print_flags_seq + unmap_mapping_range + unpin_user_page + unregister_oom_notifier + vmalloc_user + vmf_insert_pfn_prot + # required by bq25700_charger.ko - of_find_compatible_node power_supply_get_by_name # required by cdc-wdm.ko @@ -1208,12 +1381,57 @@ in6_dev_finish_destroy __ipv6_addr_type ipv6_stub - __netdev_alloc_skb - __rcu_read_lock - __rcu_read_unlock + +# required by cfg80211.ko + bpf_trace_run10 + _ctype + debugfs_rename + dev_change_net_namespace + __dev_get_by_index + dev_get_by_index + device_rename + genlmsg_multicast_allns + genlmsg_put + genl_register_family + genl_unregister_family + get_net_ns_by_fd + get_net_ns_by_pid + inet_csk_get_port + init_net + init_uts_ns + key_create_or_update + key_put + keyring_alloc + ktime_get_coarse_with_offset + memcmp + netif_rx_ni + netlink_broadcast + netlink_register_notifier + netlink_unicast + netlink_unregister_notifier + net_ns_type_operations + nla_find + nla_memcpy + __nla_parse + nla_put_64bit + nla_put + nla_reserve + __nla_validate + of_prop_next_u32 + __put_net + register_pernet_device + request_firmware_nowait + rfkill_blocked + rfkill_pause_polling + rfkill_resume_polling + skb_add_rx_frag + __sock_create + sock_release + unregister_pernet_device + verify_pkcs7_signature + wireless_nlevent_flush # required by ch.ko - param_array_ops scsi_device_lookup __scsi_execute scsi_print_sense_hdr @@ -1326,13 +1544,9 @@ of_graph_get_endpoint_by_regs # required by dw-mipi-dsi.ko - debugfs_attr_read - debugfs_attr_write drm_panel_bridge_add_typed drm_panel_bridge_connector drm_panel_bridge_remove - simple_attr_open - simple_attr_release # required by dw_mmc-rockchip.ko clk_get_phase @@ -1409,9 +1623,6 @@ aes_expandkey gf128mul_lle -# required by gl620a.ko - __alloc_skb - # required by gpio-regulator.ko gpiod_count @@ -1475,6 +1686,9 @@ # required by i2c-rk3x.ko i2c_parse_fw_timings +# required by iep.ko + mutex_trylock + # required by industrialio-buffer-cb.ko bitmap_free bitmap_zalloc @@ -1500,7 +1714,6 @@ # required by leds-rgb13h.ko led_classdev_flash_register_ext led_classdev_flash_unregister - __usecs_to_jiffies # required by ledtrig-heartbeat.ko avenrun @@ -1511,6 +1724,83 @@ # required by lzo.ko lzo1x_1_compress +# required by mac80211.ko + alloc_netdev_mqs + __alloc_percpu_gfp + arc4_crypt + arc4_setkey + call_rcu + crc32_be + crypto_aead_decrypt + crypto_aead_encrypt + crypto_aead_setauthsize + crypto_aead_setkey + crypto_alloc_aead + crypto_alloc_skcipher + crypto_shash_digest + crypto_shash_finup + crypto_shash_setkey + crypto_skcipher_decrypt + crypto_skcipher_encrypt + crypto_skcipher_setkey + dev_alloc_name + dev_fetch_sw_netstats + dev_queue_xmit + ether_setup + ethtool_op_get_link + free_netdev + get_random_u32 + __hw_addr_init + __hw_addr_sync + __hw_addr_unsync + kernel_param_lock + kernel_param_unlock + kfree_skb_list + ktime_get_seconds + __local_bh_enable_ip + napi_gro_receive + netdev_set_default_ethtool_ops + netif_carrier_off + netif_carrier_on + netif_receive_skb + netif_receive_skb_list + netif_rx + netif_tx_stop_all_queues + netif_tx_wake_queue + net_ratelimit + prandom_bytes + prandom_u32 + ___pskb_trim + rcu_barrier + register_inet6addr_notifier + register_inetaddr_notifier + register_netdevice + rhashtable_free_and_destroy + rhashtable_insert_slow + rhltable_init + __rht_bucket_nested + rht_bucket_nested + rht_bucket_nested_insert + round_jiffies + round_jiffies_up + sg_init_one + skb_checksum_help + skb_clone_sk + skb_complete_wifi_ack + skb_copy + skb_dequeue + skb_ensure_writable + __skb_get_hash + __skb_gso_segment + skb_queue_head + skb_queue_purge + skb_queue_tail + synchronize_net + unregister_inet6addr_notifier + unregister_inetaddr_notifier + unregister_netdevice_many + unregister_netdevice_queue + # required by nvme-core.ko bd_set_nr_sectors blk_execute_rq @@ -1539,8 +1829,6 @@ blk_set_queue_dying blk_status_to_errno blk_sync_queue - bpf_trace_run2 - bpf_trace_run3 capable cleanup_srcu_struct device_remove_file_self @@ -1551,16 +1839,12 @@ ida_destroy ida_free init_srcu_struct - kobject_uevent_env memchr_inv - param_ops_byte param_ops_ulong set_capacity_revalidate_and_notify set_disk_ro __srcu_read_unlock - synchronize_rcu synchronize_srcu - trace_print_symbols_seq trace_seq_putc xa_destroy xa_erase @@ -1617,21 +1901,14 @@ pci_sriov_configure_simple pci_unregister_driver pm_suspend_global_flags - sg_init_table - __sw_hweight64 sysfs_remove_file_from_group wait_for_completion_io_timeout -# required by nvp6188.ko - kthread_should_stop - # required by ohci-hcd.ko - default_llseek gen_pool_dma_alloc_align gen_pool_dma_zalloc_align sb800_prefetch schedule_timeout_uninterruptible - simple_read_from_buffer usb_amd_dev_put usb_amd_quirk_pll_disable usb_amd_quirk_pll_enable @@ -1653,14 +1930,9 @@ bus_for_each_dev device_register device_unregister - find_vma free_pages_exact - idr_get_next - kimage_voffset - ktime_get_real_ts64 memremap memunmap - msleep_interruptible wait_for_completion_interruptible # required by panel-simple.ko @@ -1683,6 +1955,9 @@ videomode_from_timing # required by pcie-dw-rockchip.ko + cpu_bit_bitmap + cpumask_next_and + dw_pcie_find_ext_capability dw_pcie_host_init dw_pcie_link_up dw_pcie_read @@ -1690,6 +1965,11 @@ dw_pcie_setup_rc dw_pcie_write dw_pcie_write_dbi + pci_disable_link_state + pcie_capability_clear_and_set_word + pci_read_config_dword + pci_set_power_state + pci_write_config_dword # required by pcierockchiphost.ko devm_pci_alloc_host_bridge @@ -1787,13 +2067,8 @@ gpio_free gpio_request kstrtoll - rfkill_alloc - rfkill_destroy rfkill_init_sw_state - rfkill_register - rfkill_set_hw_state rfkill_set_sw_state - rfkill_unregister # required by rk628.ko irq_dispose_mapping @@ -1808,8 +2083,6 @@ # required by rk806-core.ko devm_regmap_add_irq_chip - kobject_put - sysfs_remove_file_ns # required by rk806-spi.ko spi_write_then_read @@ -1838,26 +2111,19 @@ iio_read_channel_raw # required by rk_vcodec.ko - devfreq_register_opp_notifier devfreq_remove_governor - devfreq_unregister_opp_notifier devm_iounmap dev_pm_domain_attach dev_pm_opp_get_freq - dev_pm_opp_of_remove_table disable_hardirq - dma_buf_begin_cpu_access dma_buf_begin_cpu_access_partial - dma_buf_end_cpu_access dma_buf_end_cpu_access_partial - dma_buf_get __fdget iommu_attach_group iommu_detach_group iommu_device_unregister iommu_dma_reserve_iova iommu_group_get - kstrtouint_from_user kthread_flush_worker __kthread_init_worker kthread_queue_work @@ -1875,8 +2141,6 @@ # required by rknpu.ko dev_pm_domain_attach_by_name - dma_buf_mmap - dma_fence_signal drm_gem_create_mmap_offset drm_gem_dumb_destroy drm_gem_handle_delete @@ -1884,7 +2148,6 @@ drm_gem_prime_import_dev drm_gem_vm_open drm_prime_gem_destroy - hrtimer_forward set_user_nice vmf_insert_mixed vm_insert_page @@ -1914,11 +2177,7 @@ devfreq_monitor_start devfreq_monitor_stop devfreq_monitor_suspend - devfreq_resume_device - devfreq_suspend_device devfreq_update_interval - _dev_notice - dev_pm_opp_unregister_set_opp_helper input_close_device input_open_device input_register_handle @@ -1932,19 +2191,13 @@ # required by rockchip_headset_core.ko iio_channel_get -# required by rockchip_ipa.ko - bpf_trace_run7 - of_get_compatible_child - # required by rockchip_opp_select.ko dev_pm_opp_disable dev_pm_opp_of_add_table dev_pm_opp_set_prop_name regulator_get_linear_step - regulator_get_optional # required by rockchip_pwm_remotectl.ko - irq_set_affinity_hint irq_to_desc __tasklet_hi_schedule @@ -1956,7 +2209,6 @@ add_cpu bitmap_parselist compat_only_sysfs_link_entry_to_kobj - dev_pm_opp_find_freq_floor dev_pm_qos_add_request dev_pm_qos_remove_request dev_pm_qos_update_request @@ -2139,11 +2391,7 @@ platform_find_device_by_driver __platform_register_drivers platform_unregister_drivers - release_firmware - request_firmware sort - __sw_hweight32 - __sw_hweight8 __vmalloc # required by rohm-bu18tl82.ko @@ -2265,9 +2513,11 @@ clk_is_match snd_soc_add_dai_controls +# required by snd-soc-rockchip-i2s.ko + of_prop_next_string + # required by snd-soc-rockchip-multicodecs.ko of_parse_phandle_with_fixed_args - round_jiffies_relative snd_soc_jack_add_zones snd_soc_jack_get_type @@ -2275,7 +2525,6 @@ gpiod_set_raw_value_cansleep regmap_register_patch snd_soc_dapm_force_bias_level - system_long_wq # required by snd-soc-simple-card-utils.ko devm_kasprintf @@ -2303,18 +2552,10 @@ stream_open # required by sw_sync.ko - dma_fence_context_alloc dma_fence_free - dma_fence_init dma_fence_signal_locked - fd_install __get_task_comm - get_unused_fd_flags put_unused_fd - rb_erase - rb_insert_color - rb_next - sync_file_create # required by system_heap.ko deferred_free @@ -2322,8 +2563,6 @@ dmabuf_page_pool_create dmabuf_page_pool_destroy dmabuf_page_pool_free - __sg_page_iter_next - __sg_page_iter_start swiotlb_max_segment # required by tcpci_husb311.ko @@ -2334,11 +2573,8 @@ tcpci_unregister_port # required by tee.ko - anon_inode_getfd class_find_device - crypto_alloc_shash crypto_shash_final - crypto_shash_update gen_pool_best_fit gen_pool_set_algo gen_pool_virt_to_phys @@ -2349,7 +2585,6 @@ # required by test_power.ko param_get_int - strncasecmp # required by timer-rockchip.ko clockevents_config_and_register @@ -2387,7 +2622,6 @@ param_ops_ushort put_tty_driver schedule_timeout_interruptible - seq_putc __tty_alloc_driver tty_flip_buffer_push tty_hangup @@ -2437,7 +2671,6 @@ media_device_cleanup __memcpy_fromio __memcpy_toio - of_property_read_u64 param_ops_ullong v4l2_event_unsubscribe v4l2_pipeline_link_notify @@ -2452,7 +2685,6 @@ __alloc_percpu bio_endio blk_alloc_queue - class_unregister __cpuhp_state_add_instance __cpuhp_state_remove_instance crypto_alloc_base @@ -2462,19 +2694,14 @@ disk_end_io_acct disk_start_io_acct flush_dcache_page - free_percpu fsync_bdev - __get_free_pages - idr_for_each kstrtou16 memparse memset64 __num_online_cpus page_endio register_blkdev - sysfs_streq unregister_blkdev - vzalloc # required by zsmalloc.ko alloc_anon_inode @@ -2493,7 +2720,5 @@ _raw_read_unlock _raw_write_lock _raw_write_unlock - register_shrinker __SetPageMovable unlock_page - unregister_shrinker From 02df0b2661e0ae44e59506e577254c0b155114d9 Mon Sep 17 00:00:00 2001 From: Kever Yang Date: Fri, 22 Jul 2022 21:25:10 +0800 Subject: [PATCH 88/91] ANDROID: GKI: rockchip: Add symbols for crypto Leaf changes summary: 8 artifacts changed Changed leaf types summary: 0 leaf type changed Removed/Changed/Added functions summary: 0 Removed, 0 Changed, 8 Added functions Removed/Changed/Added variables summary: 0 Removed, 0 Changed, 0 Added variable 8 Added functions: [A] 'function int crypto_ahash_final(ahash_request*)' [A] 'function crypto_akcipher* crypto_alloc_akcipher(const char*, u32, u32)' [A] 'function int crypto_register_akcipher(akcipher_alg*)' [A] 'function void crypto_unregister_akcipher(akcipher_alg*)' [A] 'function int des_expand_key(des_ctx*, const unsigned char*, unsigned int)' [A] 'function int rsa_parse_priv_key(rsa_key*, void*, unsigned int)' [A] 'function int rsa_parse_pub_key(rsa_key*, void*, unsigned int)' [A] 'function int sg_nents(scatterlist*)' Bug: 239396464 Signed-off-by: Kever Yang Change-Id: I5bc749ad2b6b99065d88a235c58efc7e44106ec6 --- android/abi_gki_aarch64.xml | 195 +++++++++++++++++++++++++++++++ android/abi_gki_aarch64_rockchip | 68 ++++++++--- 2 files changed, 249 insertions(+), 14 deletions(-) diff --git a/android/abi_gki_aarch64.xml b/android/abi_gki_aarch64.xml index f535ad8a6b61..2c501eb4c49c 100644 --- a/android/abi_gki_aarch64.xml +++ b/android/abi_gki_aarch64.xml @@ -1263,11 +1263,13 @@ + + @@ -1299,6 +1301,7 @@ + @@ -1330,6 +1333,7 @@ + @@ -1409,6 +1413,7 @@ + @@ -4523,6 +4528,8 @@ + + @@ -4755,6 +4762,7 @@ + @@ -9953,6 +9961,11 @@ + + + + + @@ -10886,6 +10899,7 @@ + @@ -19649,6 +19663,7 @@ + @@ -26297,6 +26312,7 @@ + @@ -35734,6 +35750,10 @@ + + + + @@ -39880,6 +39900,7 @@ + @@ -45695,6 +45716,7 @@ + @@ -49537,6 +49559,7 @@ + @@ -61684,6 +61707,11 @@ + + + + + @@ -72461,6 +72489,7 @@ + @@ -76919,6 +76948,7 @@ + @@ -81418,6 +81448,10 @@ + + + + @@ -82193,6 +82227,10 @@ + + + + @@ -89558,6 +89596,41 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -90185,6 +90258,7 @@ + @@ -96752,6 +96826,12 @@ + + + + + + @@ -97634,6 +97714,10 @@ + + + + @@ -102773,6 +102857,56 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -110146,6 +110280,26 @@ + + + + + + + + + + + + + + + + + + + + @@ -111138,6 +111292,7 @@ + @@ -122663,6 +122818,10 @@ + + + + @@ -122693,6 +122852,12 @@ + + + + + + @@ -122873,6 +123038,10 @@ + + + + @@ -123030,6 +123199,10 @@ + + + + @@ -123462,6 +123635,12 @@ + + + + + + @@ -139518,6 +139697,18 @@ + + + + + + + + + + + + @@ -140692,6 +140883,10 @@ + + + + diff --git a/android/abi_gki_aarch64_rockchip b/android/abi_gki_aarch64_rockchip index 4431bfa09cb7..2bee0c4c5eb8 100644 --- a/android/abi_gki_aarch64_rockchip +++ b/android/abi_gki_aarch64_rockchip @@ -136,7 +136,16 @@ cpus_read_unlock crc16 crc32_le + crypto_aead_decrypt + crypto_aead_encrypt + crypto_aead_setauthsize + crypto_aead_setkey + crypto_ahash_setkey + crypto_alloc_aead + crypto_alloc_ahash crypto_alloc_shash + crypto_alloc_skcipher + crypto_cipher_encrypt_one crypto_destroy_tfm crypto_inc __crypto_memneq @@ -144,11 +153,16 @@ crypto_register_alg crypto_register_scomp crypto_register_shash + crypto_register_template crypto_shash_update + crypto_skcipher_decrypt + crypto_skcipher_encrypt + crypto_skcipher_setkey crypto_unregister_aead crypto_unregister_alg crypto_unregister_scomp crypto_unregister_shash + crypto_unregister_template __crypto_xor debugfs_attr_read debugfs_attr_write @@ -456,6 +470,7 @@ find_next_zero_bit find_vma finish_wait + flush_dcache_page flush_delayed_work flush_work flush_workqueue @@ -703,6 +718,7 @@ mutex_is_locked mutex_lock mutex_lock_interruptible + mutex_trylock mutex_unlock __netdev_alloc_skb netdev_err @@ -977,7 +993,9 @@ sg_alloc_table sg_alloc_table_from_pages sg_free_table + sg_init_one sg_init_table + sg_nents sg_next __sg_page_iter_next __sg_page_iter_start @@ -994,9 +1012,12 @@ skb_push skb_put skb_trim + skcipher_alloc_instance_simple + skcipher_register_instance skcipher_walk_aead_decrypt skcipher_walk_aead_encrypt skcipher_walk_done + skcipher_walk_virt snd_pcm_format_width snd_soc_add_component_controls snd_soc_card_jack_new @@ -1522,6 +1543,17 @@ devm_blk_ksm_init mmc_cqe_request_done +# required by cryptodev.ko + __close_fd + crypto_ahash_final + crypto_alloc_akcipher + get_user_pages_remote + krealloc + proc_dointvec + register_sysctl_table + sg_last + unregister_sysctl_table + # required by display-connector.ko drm_atomic_get_new_bridge_state drm_probe_ddc @@ -1686,9 +1718,6 @@ # required by i2c-rk3x.ko i2c_parse_fw_timings -# required by iep.ko - mutex_trylock - # required by industrialio-buffer-cb.ko bitmap_free bitmap_zalloc @@ -1731,18 +1760,9 @@ arc4_setkey call_rcu crc32_be - crypto_aead_decrypt - crypto_aead_encrypt - crypto_aead_setauthsize - crypto_aead_setkey - crypto_alloc_aead - crypto_alloc_skcipher crypto_shash_digest crypto_shash_finup crypto_shash_setkey - crypto_skcipher_decrypt - crypto_skcipher_encrypt - crypto_skcipher_setkey dev_alloc_name dev_fetch_sw_netstats dev_queue_xmit @@ -1783,7 +1803,6 @@ rht_bucket_nested_insert round_jiffies round_jiffies_up - sg_init_one skb_checksum_help skb_clone_sk skb_complete_wifi_ack @@ -2107,6 +2126,28 @@ # required by rk860x-regulator.ko regulator_suspend_enable +# required by rk_crypto.ko + crypto_ahash_digest + crypto_dequeue_request + crypto_enqueue_request + crypto_init_queue + crypto_register_ahash + crypto_register_akcipher + crypto_register_skcipher + crypto_req_done + crypto_unregister_ahash + crypto_unregister_akcipher + crypto_unregister_skcipher + des_expand_key + rsa_parse_priv_key + rsa_parse_pub_key + scatterwalk_ffwd + sg_copy_from_buffer + sg_copy_to_buffer + sg_nents_for_len + sg_pcopy_from_buffer + sg_pcopy_to_buffer + # required by rk_headset_irq_hook_adc.ko iio_read_channel_raw @@ -2693,7 +2734,6 @@ crypto_has_alg disk_end_io_acct disk_start_io_acct - flush_dcache_page fsync_bdev kstrtou16 memparse From 91bfc78bc009e8afc8e6bbd153d3bd47118892cf Mon Sep 17 00:00:00 2001 From: Seiya Wang Date: Fri, 12 Aug 2022 13:29:29 +0800 Subject: [PATCH 89/91] ANDROID: Update symbol list for mtk Leaf changes summary: 6 artifacts changed Changed leaf types summary: 0 leaf type changed Removed/Changed/Added functions summary: 0 Removed, 0 Changed, 6 Added functions Removed/Changed/Added variables summary: 0 Removed, 0 Changed, 0 Added variable 6 Added functions: [A] 'function void __dev_kfree_skb_irq(sk_buff*, skb_free_reason)' [A] 'function net_device* devm_alloc_etherdev_mqs(device*, int, unsigned int, unsigned int)' [A] 'function mii_bus* devm_mdiobus_alloc_size(device*, int)' [A] 'function int devm_of_mdiobus_register(device*, mii_bus*, device_node*)' [A] 'function int devm_register_netdev(device*, net_device*)' [A] 'function int regmap_test_bits(regmap*, unsigned int, unsigned int)' Bug: 242251789 Signed-off-by: Seiya Wang Change-Id: I9f9a384e1135adf11cc7336beb29a40b68650f94 --- android/abi_gki_aarch64.xml | 293 ++++++++++++++++++++++++++++++++++-- android/abi_gki_aarch64_mtk | 43 ++++++ 2 files changed, 326 insertions(+), 10 deletions(-) diff --git a/android/abi_gki_aarch64.xml b/android/abi_gki_aarch64.xml index 2c501eb4c49c..16bd86e5d344 100644 --- a/android/abi_gki_aarch64.xml +++ b/android/abi_gki_aarch64.xml @@ -68,6 +68,7 @@ + @@ -1584,6 +1585,7 @@ + @@ -1654,6 +1656,7 @@ + @@ -1662,6 +1665,7 @@ + @@ -1685,6 +1689,7 @@ + @@ -4374,6 +4379,7 @@ + @@ -12218,6 +12224,7 @@ + @@ -13936,6 +13943,7 @@ + @@ -15946,6 +15954,9 @@ + + + @@ -16165,7 +16176,29 @@ - + + + + + + + + + + + + + + + + + + + + + + + @@ -22151,6 +22184,7 @@ + @@ -22892,6 +22926,11 @@ + + + + + @@ -25310,6 +25349,7 @@ + @@ -25615,7 +25655,23 @@ - + + + + + + + + + + + + + + + + + @@ -26800,6 +26856,7 @@ + @@ -27176,6 +27233,7 @@ + @@ -31749,6 +31807,7 @@ + @@ -33801,7 +33860,68 @@ - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -34731,6 +34851,7 @@ + @@ -41098,6 +41219,7 @@ + @@ -48464,7 +48586,35 @@ - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -48646,6 +48796,7 @@ + @@ -49030,7 +49181,14 @@ - + + + + + + + + @@ -51200,6 +51358,7 @@ + @@ -53489,6 +53648,7 @@ + @@ -54099,7 +54259,23 @@ - + + + + + + + + + + + + + + + + + @@ -56121,6 +56297,7 @@ + @@ -58287,6 +58464,7 @@ + @@ -64258,7 +64436,17 @@ - + + + + + + + + + + + @@ -65914,6 +66102,11 @@ + + + + + @@ -70749,6 +70942,7 @@ + @@ -71459,6 +71653,7 @@ + @@ -73199,6 +73394,7 @@ + @@ -74084,6 +74280,7 @@ + @@ -76248,6 +76445,7 @@ + @@ -81207,6 +81405,7 @@ + @@ -82196,6 +82395,7 @@ + @@ -82804,6 +83004,7 @@ + @@ -82876,6 +83077,9 @@ + + + @@ -86587,6 +86791,7 @@ + @@ -88427,6 +88632,7 @@ + @@ -88465,6 +88671,7 @@ + @@ -91832,6 +92039,14 @@ + + + + + + + + @@ -92266,7 +92481,20 @@ - + + + + + + + + + + + + + + @@ -93292,6 +93520,7 @@ + @@ -99247,6 +99476,7 @@ + @@ -100901,6 +101131,7 @@ + @@ -101892,7 +102123,14 @@ - + + + + + + + + @@ -103442,6 +103680,9 @@ + + + @@ -104477,6 +104718,7 @@ + @@ -105011,7 +105253,20 @@ - + + + + + + + + + + + + + + @@ -105070,6 +105325,9 @@ + + + @@ -108529,6 +108787,7 @@ + @@ -108891,6 +109150,7 @@ + @@ -113185,6 +113445,7 @@ + @@ -115577,6 +115838,11 @@ + + + + + @@ -115781,6 +116047,7 @@ + @@ -138906,6 +139173,12 @@ + + + + + + diff --git a/android/abi_gki_aarch64_mtk b/android/abi_gki_aarch64_mtk index 9d74cbdb2d92..ee8da67b460e 100644 --- a/android/abi_gki_aarch64_mtk +++ b/android/abi_gki_aarch64_mtk @@ -371,7 +371,10 @@ device_unregister _dev_info __dev_kfree_skb_any + __dev_kfree_skb_irq + devm_add_action __devm_alloc_percpu + devm_alloc_etherdev_mqs devm_blk_ksm_init devm_clk_bulk_get devm_clk_bulk_get_optional @@ -412,11 +415,13 @@ devm_led_classdev_register_ext devm_led_classdev_unregister devm_mbox_controller_register + devm_mdiobus_alloc_size devm_memremap devm_mfd_add_devices devm_nvmem_cell_get devm_nvmem_device_get devm_nvmem_register + devm_of_mdiobus_register devm_of_phy_get_by_index __devm_of_phy_provider_register devm_of_platform_populate @@ -433,6 +438,7 @@ devm_power_supply_register devm_rc_allocate_device devm_rc_register_device + devm_register_netdev devm_regmap_add_irq_chip devm_regmap_field_alloc devm_regmap_field_bulk_alloc @@ -584,6 +590,7 @@ down_write d_path dput + dql_completed drain_workqueue driver_create_file driver_remove_file @@ -809,7 +816,13 @@ genlmsg_put genl_register_family genl_unregister_family + __genphy_config_aneg + genphy_read_abilities + genphy_read_mmd_unsupported + genphy_read_status genphy_resume + genphy_suspend + genphy_write_mmd_unsupported gen_pool_add_owner gen_pool_alloc_algo_owner gen_pool_avail @@ -958,11 +971,13 @@ init_uts_ns init_wait_entry __init_waitqueue_head + input_alloc_absinfo input_allocate_device input_event input_free_device input_mt_init_slots input_mt_report_slot_state + input_mt_sync_frame input_register_device input_set_abs_params input_set_capability @@ -1170,8 +1185,12 @@ mbox_send_message mdiobus_alloc_size mdiobus_free + __mdiobus_read + mdiobus_read __mdiobus_register mdiobus_unregister + __mdiobus_write + mdiobus_write media_create_intf_link media_create_pad_link media_device_cleanup @@ -1271,10 +1290,12 @@ mutex_lock_killable mutex_trylock mutex_unlock + napi_complete_done napi_disable napi_gro_flush napi_gro_receive __napi_schedule + __napi_schedule_irqoff napi_schedule_prep __ndelay nd_tbl @@ -1293,6 +1314,7 @@ netif_receive_skb_list netif_rx netif_rx_ni + netif_schedule_queue netif_tx_stop_all_queues netif_tx_wake_queue netlink_broadcast @@ -1373,6 +1395,7 @@ of_get_next_child of_get_next_parent of_get_parent + of_get_phy_mode of_get_property of_get_regulator_init_data of_graph_get_next_endpoint @@ -1393,6 +1416,7 @@ of_parse_phandle_with_fixed_args of_phandle_iterator_init of_phandle_iterator_next + of_phy_connect of_phy_simple_xlate of_platform_depopulate of_platform_device_create @@ -1460,19 +1484,29 @@ phy_connect phy_disconnect phy_do_ioctl_running + phy_drivers_register + phy_drivers_unregister phy_ethtool_get_link_ksettings phy_ethtool_nway_reset phy_ethtool_set_link_ksettings phy_exit phy_get phy_init + phy_mii_ioctl + __phy_modify + phy_modify + phy_modify_paged_changed phy_power_off phy_power_on phy_print_status phy_put + phy_read_paged + phy_restore_page + phy_select_page phy_set_mode_ext phy_start phy_stop + phy_write_paged pid_task pinconf_generic_parse_dt_config pinctrl_dev_get_drvdata @@ -1661,6 +1695,7 @@ regmap_raw_read regmap_raw_write regmap_read + regmap_test_bits regmap_update_bits_base regmap_write regulator_count_voltages @@ -2092,6 +2127,8 @@ timer_unstable_counter_workaround topology_set_thermal_pressure _totalram_pages + touchscreen_parse_properties + touchscreen_report_pos __trace_bprintk __trace_bputs trace_event_buffer_commit @@ -2793,10 +2830,13 @@ fwnode_graph_parse_endpoint fwnode_property_get_reference_args fwnode_property_read_u64_array + gen_pool_avail gen_pool_dma_alloc_align gen_pool_has_addr + gen_pool_size getboottime64 get_governor_parent_kobj + get_pelt_halflife get_task_exe_file get_vaddr_frames get_zeroed_page @@ -3073,6 +3113,7 @@ __traceiter_android_vh_rwsem_init __traceiter_android_vh_rwsem_wake __traceiter_android_vh_rwsem_write_finished + __traceiter_android_vh_sched_pelt_multiplier __traceiter_android_vh_scmi_timeout_sync __traceiter_android_vh_show_resume_epoch_val __traceiter_android_vh_show_suspend_epoch_val @@ -3126,6 +3167,7 @@ __tracepoint_android_vh_rwsem_init __tracepoint_android_vh_rwsem_wake __tracepoint_android_vh_rwsem_write_finished + __tracepoint_android_vh_sched_pelt_multiplier __tracepoint_android_vh_scmi_timeout_sync __tracepoint_android_vh_show_resume_epoch_val __tracepoint_android_vh_show_suspend_epoch_val @@ -3196,6 +3238,7 @@ usb_otg_state_string usb_phy_set_charger_current usb_remove_phy + usb_role_switch_set_role v4l2_async_notifier_add_subdev v4l2_async_notifier_cleanup v4l2_async_subdev_notifier_register From 1f8f6d59a298c4fbd10603e681852c1670ab1b1c Mon Sep 17 00:00:00 2001 From: Peifeng Li Date: Sun, 24 Jul 2022 13:47:14 +0800 Subject: [PATCH 90/91] ANDROID: vendor_hook: Add hook to not be stuck ro rmap lock in kswapd or direct_reclaim Add hooks to support trylock in rmaplock when reclaiming in kswapd or direct_reclaim, in order to avoid wait lock for a long time. - android_vh_handle_failed_page_trylock - android_vh_page_trylock_set - android_vh_page_trylock_clear - android_vh_page_trylock_get_result - android_vh_do_page_trylock Bug: 240003372 Signed-off-by: Peifeng Li Change-Id: I0f605b35ae41f15b3ca7bc72cd5f003175c318a5 --- drivers/android/vendor_hooks.c | 5 +++++ include/trace/hooks/mm.h | 5 +++++ include/trace/hooks/vmscan.h | 12 ++++++++++++ mm/rmap.c | 20 +++++++++++++++++--- mm/vmscan.c | 18 ++++++++++++++---- 5 files changed, 53 insertions(+), 7 deletions(-) diff --git a/drivers/android/vendor_hooks.c b/drivers/android/vendor_hooks.c index d7fab5cb876d..128f63a76938 100644 --- a/drivers/android/vendor_hooks.c +++ b/drivers/android/vendor_hooks.c @@ -304,6 +304,11 @@ EXPORT_TRACEPOINT_SYMBOL_GPL(android_vh_logbuf_pr_cont); EXPORT_TRACEPOINT_SYMBOL_GPL(android_vh_tune_scan_type); EXPORT_TRACEPOINT_SYMBOL_GPL(android_vh_tune_swappiness); EXPORT_TRACEPOINT_SYMBOL_GPL(android_vh_shrink_slab_bypass); +EXPORT_TRACEPOINT_SYMBOL_GPL(android_vh_handle_failed_page_trylock); +EXPORT_TRACEPOINT_SYMBOL_GPL(android_vh_page_trylock_set); +EXPORT_TRACEPOINT_SYMBOL_GPL(android_vh_page_trylock_clear); +EXPORT_TRACEPOINT_SYMBOL_GPL(android_vh_page_trylock_get_result); +EXPORT_TRACEPOINT_SYMBOL_GPL(android_vh_do_page_trylock); EXPORT_TRACEPOINT_SYMBOL_GPL(android_vh_page_referenced_check_bypass); EXPORT_TRACEPOINT_SYMBOL_GPL(android_vh_drain_all_pages_bypass); EXPORT_TRACEPOINT_SYMBOL_GPL(android_vh_cma_drain_all_pages_bypass); diff --git a/include/trace/hooks/mm.h b/include/trace/hooks/mm.h index 495f66d0f926..8b0225ce7ced 100644 --- a/include/trace/hooks/mm.h +++ b/include/trace/hooks/mm.h @@ -22,6 +22,7 @@ #include #include #include +#include #ifdef __GENKSYMS__ struct slabinfo; @@ -148,6 +149,10 @@ DECLARE_HOOK(android_vh_mmap_region, DECLARE_HOOK(android_vh_try_to_unmap_one, TP_PROTO(struct vm_area_struct *vma, struct page *page, unsigned long addr, bool ret), TP_ARGS(vma, page, addr, ret)); +DECLARE_HOOK(android_vh_do_page_trylock, + TP_PROTO(struct page *page, struct rw_semaphore *sem, + bool *got_lock, bool *success), + TP_ARGS(page, sem, got_lock, success)); DECLARE_HOOK(android_vh_drain_all_pages_bypass, TP_PROTO(gfp_t gfp_mask, unsigned int order, unsigned long alloc_flags, int migratetype, unsigned long did_some_progress, diff --git a/include/trace/hooks/vmscan.h b/include/trace/hooks/vmscan.h index 4f1d6ab9f498..a175232c89f6 100644 --- a/include/trace/hooks/vmscan.h +++ b/include/trace/hooks/vmscan.h @@ -28,6 +28,18 @@ DECLARE_RESTRICTED_HOOK(android_rvh_set_balance_anon_file_reclaim, DECLARE_HOOK(android_vh_page_referenced_check_bypass, TP_PROTO(struct page *page, unsigned long nr_to_scan, int lru, bool *bypass), TP_ARGS(page, nr_to_scan, lru, bypass)); +DECLARE_HOOK(android_vh_page_trylock_get_result, + TP_PROTO(struct page *page, bool *trylock_fail), + TP_ARGS(page, trylock_fail)); +DECLARE_HOOK(android_vh_handle_failed_page_trylock, + TP_PROTO(struct list_head *page_list), + TP_ARGS(page_list)); +DECLARE_HOOK(android_vh_page_trylock_set, + TP_PROTO(struct page *page), + TP_ARGS(page)); +DECLARE_HOOK(android_vh_page_trylock_clear, + TP_PROTO(struct page *page), + TP_ARGS(page)); DECLARE_HOOK(android_vh_shrink_node_memcgs, TP_PROTO(struct mem_cgroup *memcg, bool *skip), TP_ARGS(memcg, skip)); diff --git a/mm/rmap.c b/mm/rmap.c index ea1fd71b03df..2e62c1aa5139 100644 --- a/mm/rmap.c +++ b/mm/rmap.c @@ -525,6 +525,7 @@ struct anon_vma *page_lock_anon_vma_read(struct page *page) struct anon_vma *anon_vma = NULL; struct anon_vma *root_anon_vma; unsigned long anon_mapping; + bool success = false; rcu_read_lock(); anon_mapping = (unsigned long)READ_ONCE(page->mapping); @@ -547,7 +548,11 @@ struct anon_vma *page_lock_anon_vma_read(struct page *page) } goto out; } - + trace_android_vh_do_page_trylock(page, NULL, NULL, &success); + if (success) { + anon_vma = NULL; + goto out; + } /* trylock failed, we got to sleep */ if (!atomic_inc_not_zero(&anon_vma->refcount)) { anon_vma = NULL; @@ -1981,6 +1986,7 @@ static void rmap_walk_file(struct page *page, struct rmap_walk_control *rwc, struct address_space *mapping = page_mapping(page); pgoff_t pgoff_start, pgoff_end; struct vm_area_struct *vma; + bool got_lock = false, success = false; /* * The page lock not only makes sure that page->mapping cannot @@ -1995,8 +2001,16 @@ static void rmap_walk_file(struct page *page, struct rmap_walk_control *rwc, pgoff_start = page_to_pgoff(page); pgoff_end = pgoff_start + thp_nr_pages(page) - 1; - if (!locked) - i_mmap_lock_read(mapping); + if (!locked) { + trace_android_vh_do_page_trylock(page, + &mapping->i_mmap_rwsem, &got_lock, &success); + if (success) { + if (!got_lock) + return; + } else { + i_mmap_lock_read(mapping); + } + } vma_interval_tree_foreach(vma, &mapping->i_mmap, pgoff_start, pgoff_end) { unsigned long address = vma_address(page, vma); diff --git a/mm/vmscan.c b/mm/vmscan.c index 22ab1afed87f..7899d6905b6e 100644 --- a/mm/vmscan.c +++ b/mm/vmscan.c @@ -1021,15 +1021,19 @@ static enum page_references page_check_references(struct page *page, int referenced_ptes, referenced_page; unsigned long vm_flags; bool should_protect = false; + bool trylock_fail = false; trace_android_vh_page_should_be_protected(page, &should_protect); if (unlikely(should_protect)) return PAGEREF_ACTIVATE; + trace_android_vh_page_trylock_set(page); referenced_ptes = page_referenced(page, 1, sc->target_mem_cgroup, &vm_flags); referenced_page = TestClearPageReferenced(page); - + trace_android_vh_page_trylock_get_result(page, &trylock_fail); + if (trylock_fail) + return PAGEREF_KEEP; /* * Mlock lost the isolation race with us. Let try_to_unmap() * move the page to the unevictable list. @@ -1341,6 +1345,7 @@ static unsigned int shrink_page_list(struct list_head *page_list, if (unlikely(PageTransHuge(page))) flags |= TTU_SPLIT_HUGE_PMD; + trace_android_vh_page_trylock_set(page); if (!try_to_unmap(page, flags)) { stat->nr_unmap_fail += nr_pages; if (!was_swapbacked && PageSwapBacked(page)) @@ -1451,6 +1456,7 @@ static unsigned int shrink_page_list(struct list_head *page_list, * increment nr_reclaimed here (and * leave it off the LRU). */ + trace_android_vh_page_trylock_clear(page); nr_reclaimed++; continue; } @@ -1486,8 +1492,10 @@ free_it: */ if (unlikely(PageTransHuge(page))) destroy_compound_page(page); - else + else { + trace_android_vh_page_trylock_clear(page); list_add(&page->lru, &free_pages); + } continue; activate_locked_split: @@ -1999,6 +2007,7 @@ shrink_inactive_list(unsigned long nr_to_scan, struct lruvec *lruvec, return 0; nr_reclaimed = shrink_page_list(&page_list, pgdat, sc, &stat, false); + trace_android_vh_handle_failed_page_trylock(&page_list); spin_lock_irq(&pgdat->lru_lock); @@ -2011,7 +2020,6 @@ shrink_inactive_list(unsigned long nr_to_scan, struct lruvec *lruvec, __count_vm_events(item, nr_reclaimed); __count_memcg_events(lruvec_memcg(lruvec), item, nr_reclaimed); __count_vm_events(PGSTEAL_ANON + file, nr_reclaimed); - spin_unlock_irq(&pgdat->lru_lock); mem_cgroup_uncharge_list(&page_list); @@ -2107,7 +2115,7 @@ static void shrink_active_list(unsigned long nr_to_scan, trace_android_vh_page_referenced_check_bypass(page, nr_to_scan, lru, &bypass); if (bypass) goto skip_page_referenced; - + trace_android_vh_page_trylock_set(page); if (page_referenced(page, 0, sc->target_mem_cgroup, &vm_flags)) { /* @@ -2120,11 +2128,13 @@ static void shrink_active_list(unsigned long nr_to_scan, * so we ignore them here. */ if ((vm_flags & VM_EXEC) && page_is_file_lru(page)) { + trace_android_vh_page_trylock_clear(page); nr_rotated += thp_nr_pages(page); list_add(&page->lru, &l_active); continue; } } + trace_android_vh_page_trylock_clear(page); skip_page_referenced: ClearPageActive(page); /* we are de-activating */ SetPageWorkingset(page); From fb39cdb9eac1fc2a202cefe6a10500dcddfa37bd Mon Sep 17 00:00:00 2001 From: Peifeng Li Date: Sun, 24 Jul 2022 14:04:52 +0800 Subject: [PATCH 91/91] ANDROID: export reclaim_pages export reclaim_pages to support to reclaim pages in drivers-page-list. Bug: 240003372 Signed-off-by: Peifeng Li Change-Id: If92ed66ec9ce9dd66565497e6774d89911652429 --- mm/vmscan.c | 1 + 1 file changed, 1 insertion(+) diff --git a/mm/vmscan.c b/mm/vmscan.c index 7899d6905b6e..0f82957c4de7 100644 --- a/mm/vmscan.c +++ b/mm/vmscan.c @@ -2216,6 +2216,7 @@ unsigned long reclaim_pages(struct list_head *page_list) return nr_reclaimed; } +EXPORT_SYMBOL_GPL(reclaim_pages); static unsigned long shrink_list(enum lru_list lru, unsigned long nr_to_scan, struct lruvec *lruvec, struct scan_control *sc)