Commit 379c7265 authored by Linus Torvalds's avatar Linus Torvalds
Browse files
Pull sound fixes from Takashi Iwai:
 "This became slightly larger as I've been off in the last weeks.

  The majority of changes here is about ASoC, fixes for dmaengine
  and for addressing issues reported by CI, as well as other
  device-specific small fixes.

  Also, fixes for FireWire core stack and the usual HD-audio quirks
  are included"

* tag 'sound-5.18-rc6' of git://git.kernel.org/pub/scm/linux/kernel/git/tiwai/sound: (23 commits)
  ASoC: SOF: Fix NULL pointer exception in sof_pci_probe callback
  ASoC: ops: Validate input values in snd_soc_put_volsw_range()
  ASoC: dmaengine: Restore NULL prepare_slave_config() callback
  ASoC: atmel: mchp-pdmc: set prepare_slave_config
  ASoC: max98090: Generate notifications on changes for custom control
  ASoC: max98090: Reject invalid values in custom control put()
  ALSA: fireworks: fix wrong return count shorter than expected by 4 bytes
  ALSA: hda/realtek: Add quirk for Yoga Duet 7 13ITL6 speakers
  firewire: core: extend card->lock in fw_core_handle_bus_reset
  firewire: remove check of list iterator against head past the loop body
  firewire: fix potential uaf in outbound_phy_packet_callback()
  ASoC: rt9120: Correct the reg 0x09 size to one byte
  ALSA: hda/realtek: Enable mute/micmute LEDs support for HP Laptops
  ALSA: hda/realtek: Fix mute led issue on thinkpad with cs35l41 s-codec
  ASoC: meson: axg-card: Fix nonatomic links
  ASoC: meson: axg-tdm-interface: Fix formatters in trigger"
  ASoC: soc-ops: fix error handling
  ASoC: meson: Fix event generation for G12A tohdmi mux
  ASoC: meson: Fix event generation for AUI CODEC mux
  ASoC: meson: Fix event generation for AUI ACODEC mux
  ...
parents 2e3afb42 ac02e3cd
Loading
Loading
Loading
Loading
+3 −0
Original line number Diff line number Diff line
@@ -668,6 +668,7 @@ EXPORT_SYMBOL_GPL(fw_card_release);
void fw_core_remove_card(struct fw_card *card)
{
	struct fw_card_driver dummy_driver = dummy_driver_template;
	unsigned long flags;

	card->driver->update_phy_reg(card, 4,
				     PHY_LINK_ACTIVE | PHY_CONTENDER, 0);
@@ -682,7 +683,9 @@ void fw_core_remove_card(struct fw_card *card)
	dummy_driver.stop_iso		= card->driver->stop_iso;
	card->driver = &dummy_driver;

	spin_lock_irqsave(&card->lock, flags);
	fw_destroy_nodes(card);
	spin_unlock_irqrestore(&card->lock, flags);

	/* Wait for all users, especially device workqueue jobs, to finish. */
	fw_card_put(card);
+3 −1
Original line number Diff line number Diff line
@@ -1500,6 +1500,7 @@ static void outbound_phy_packet_callback(struct fw_packet *packet,
{
	struct outbound_phy_packet_event *e =
		container_of(packet, struct outbound_phy_packet_event, p);
	struct client *e_client;

	switch (status) {
	/* expected: */
@@ -1516,9 +1517,10 @@ static void outbound_phy_packet_callback(struct fw_packet *packet,
	}
	e->phy_packet.data[0] = packet->timestamp;

	e_client = e->client;
	queue_event(e->client, &e->event, &e->phy_packet,
		    sizeof(e->phy_packet) + e->phy_packet.length, NULL, 0);
	client_put(e->client);
	client_put(e_client);
}

static int ioctl_send_phy_packet(struct client *client, union ioctl_arg *arg)
+3 −6
Original line number Diff line number Diff line
@@ -375,16 +375,13 @@ static void report_found_node(struct fw_card *card,
	card->bm_retries = 0;
}

/* Must be called with card->lock held */
void fw_destroy_nodes(struct fw_card *card)
{
	unsigned long flags;

	spin_lock_irqsave(&card->lock, flags);
	card->color++;
	if (card->local_node != NULL)
		for_each_fw_node(card, card->local_node, report_lost_node);
	card->local_node = NULL;
	spin_unlock_irqrestore(&card->lock, flags);
}

static void move_tree(struct fw_node *node0, struct fw_node *node1, int port)
@@ -510,6 +507,8 @@ void fw_core_handle_bus_reset(struct fw_card *card, int node_id, int generation,
	struct fw_node *local_node;
	unsigned long flags;

	spin_lock_irqsave(&card->lock, flags);

	/*
	 * If the selfID buffer is not the immediate successor of the
	 * previously processed one, we cannot reliably compare the
@@ -521,8 +520,6 @@ void fw_core_handle_bus_reset(struct fw_card *card, int node_id, int generation,
		card->bm_retries = 0;
	}

	spin_lock_irqsave(&card->lock, flags);

	card->broadcast_channel_allocated = card->broadcast_channel_auto_allocated;
	card->node_id = node_id;
	/*
+16 −14
Original line number Diff line number Diff line
@@ -73,24 +73,25 @@ static int try_cancel_split_timeout(struct fw_transaction *t)
static int close_transaction(struct fw_transaction *transaction,
			     struct fw_card *card, int rcode)
{
	struct fw_transaction *t;
	struct fw_transaction *t = NULL, *iter;
	unsigned long flags;

	spin_lock_irqsave(&card->lock, flags);
	list_for_each_entry(t, &card->transaction_list, link) {
		if (t == transaction) {
			if (!try_cancel_split_timeout(t)) {
	list_for_each_entry(iter, &card->transaction_list, link) {
		if (iter == transaction) {
			if (!try_cancel_split_timeout(iter)) {
				spin_unlock_irqrestore(&card->lock, flags);
				goto timed_out;
			}
			list_del_init(&t->link);
			card->tlabel_mask &= ~(1ULL << t->tlabel);
			list_del_init(&iter->link);
			card->tlabel_mask &= ~(1ULL << iter->tlabel);
			t = iter;
			break;
		}
	}
	spin_unlock_irqrestore(&card->lock, flags);

	if (&t->link != &card->transaction_list) {
	if (t) {
		t->callback(card, rcode, NULL, 0, t->callback_data);
		return 0;
	}
@@ -935,7 +936,7 @@ EXPORT_SYMBOL(fw_core_handle_request);

void fw_core_handle_response(struct fw_card *card, struct fw_packet *p)
{
	struct fw_transaction *t;
	struct fw_transaction *t = NULL, *iter;
	unsigned long flags;
	u32 *data;
	size_t data_length;
@@ -947,20 +948,21 @@ void fw_core_handle_response(struct fw_card *card, struct fw_packet *p)
	rcode	= HEADER_GET_RCODE(p->header[1]);

	spin_lock_irqsave(&card->lock, flags);
	list_for_each_entry(t, &card->transaction_list, link) {
		if (t->node_id == source && t->tlabel == tlabel) {
			if (!try_cancel_split_timeout(t)) {
	list_for_each_entry(iter, &card->transaction_list, link) {
		if (iter->node_id == source && iter->tlabel == tlabel) {
			if (!try_cancel_split_timeout(iter)) {
				spin_unlock_irqrestore(&card->lock, flags);
				goto timed_out;
			}
			list_del_init(&t->link);
			card->tlabel_mask &= ~(1ULL << t->tlabel);
			list_del_init(&iter->link);
			card->tlabel_mask &= ~(1ULL << iter->tlabel);
			t = iter;
			break;
		}
	}
	spin_unlock_irqrestore(&card->lock, flags);

	if (&t->link == &card->transaction_list) {
	if (!t) {
 timed_out:
		fw_notice(card, "unsolicited response (source %x, tlabel %x)\n",
			  source, tlabel);
+7 −6
Original line number Diff line number Diff line
@@ -408,7 +408,7 @@ static void sbp2_status_write(struct fw_card *card, struct fw_request *request,
			      void *payload, size_t length, void *callback_data)
{
	struct sbp2_logical_unit *lu = callback_data;
	struct sbp2_orb *orb;
	struct sbp2_orb *orb = NULL, *iter;
	struct sbp2_status status;
	unsigned long flags;

@@ -433,17 +433,18 @@ static void sbp2_status_write(struct fw_card *card, struct fw_request *request,

	/* Lookup the orb corresponding to this status write. */
	spin_lock_irqsave(&lu->tgt->lock, flags);
	list_for_each_entry(orb, &lu->orb_list, link) {
	list_for_each_entry(iter, &lu->orb_list, link) {
		if (STATUS_GET_ORB_HIGH(status) == 0 &&
		    STATUS_GET_ORB_LOW(status) == orb->request_bus) {
			orb->rcode = RCODE_COMPLETE;
			list_del(&orb->link);
		    STATUS_GET_ORB_LOW(status) == iter->request_bus) {
			iter->rcode = RCODE_COMPLETE;
			list_del(&iter->link);
			orb = iter;
			break;
		}
	}
	spin_unlock_irqrestore(&lu->tgt->lock, flags);

	if (&orb->link != &lu->orb_list) {
	if (orb) {
		orb->callback(orb, &status);
		kref_put(&orb->kref, free_orb); /* orb callback reference */
	} else {
Loading