From: Charles Keepax <ckeepax@opensource.cirrus.com>
To: Pierre-Louis Bossart <pierre-louis.bossart@linux.dev>
Cc: vkoul@kernel.org, yung-chuan.liao@linux.intel.com,
peter.ujfalusi@linux.intel.com, linux-sound@vger.kernel.org,
patches@opensource.cirrus.com, linux-kernel@vger.kernel.org
Subject: Re: [PATCH 2/2] soundwire: intel_auxdevice: Don't disable IRQs before removing children
Date: Tue, 15 Sep 2026 10:13:28 +0100 [thread overview]
Message-ID: <aqkMOFfQo2YRYt2C@opensource.cirrus.com> (raw)
In-Reply-To: <8b54604a-ec75-4c84-9909-358510f6f3ba@linux.dev>
On Mon, Sep 14, 2026 at 08:27:23PM +0200, Pierre-Louis Bossart wrote:
> On 9/11/26 18:19, Charles Keepax wrote:
> > Currently the auxiliary device for the link disables IRQs before
> > it calls sdw_bus_master_delete(). This has the side effect that
> > none of the devices on the link can access their own registers
> > whilst their remove functions run, because the IRQs are required
> > for bus transactions to function.
> >
> > It would appear the reason for the disabling of the IRQs is that
> > the IRQ handler iterates through a linked list of all the links,
> > once a link is removed the memory pointed at by this linked list
> > is freed, but not removed from the linked_list.
>
> That wasn't the reason, even if you have a single link we all thought it
> made more sense to disable peripheral interrupts on the host before
> calling sdw_bus_master_delete()
What was the reason for deciding to do that, that is not in itself
a reason? A drivers remove callback should be able to access
registers on the device. The host here requires interrupts to
do so. This was the only functional reason in the code I could
find that things were done in this order.
> > --- a/drivers/soundwire/intel_auxdevice.c
> > +++ b/drivers/soundwire/intel_auxdevice.c
> > @@ -508,9 +508,12 @@ static void intel_link_remove(struct auxiliary_device *auxdev)
> > if (!bus->prop.hw_disabled) {
> > sdw_intel_debugfs_exit(sdw);
> > cancel_delayed_work_sync(&cdns->attach_dwork);
> > - sdw_cdns_enable_interrupt(cdns, false);
> > }
> > +
> > sdw_bus_master_delete(bus);
> > +
> > + if (!bus->prop.hw_disabled)
> > + sdw_cdns_enable_interrupt(cdns, false);
> > }
>
> Sorry, that sequence looks really weird to me.
>
> See the code in
>
> void sdw_bus_master_delete(struct sdw_bus *bus)
> {
> device_for_each_child(bus->dev, NULL, sdw_delete_slave);
>
> sdw_irq_delete(bus);
>
> sdw_master_device_del(bus);
>
> After doing all this, one would mask the interrupts on the host side with
>
> if (!bus->prop.hw_disabled)
> sdw_cdns_enable_interrupt(cdns, false);
>
> but that host is long gone.
>
> Does this even work?
>
> The last sdw_cdns_enable_interrupt(cdns, false) looks either very racy
> or useless, no?
I mean it definitely works and fixes the problems on driver
remove. I will check to see if the call is redundant at this
stage, or if there are any potential dangers I am missing.
> > diff --git a/include/linux/soundwire/sdw_intel.h b/include/linux/soundwire/sdw_intel.h
> > index 9710f2dc04e29..7495d35ed2fc3 100644
> > --- a/include/linux/soundwire/sdw_intel.h
> > +++ b/include/linux/soundwire/sdw_intel.h
> > @@ -307,6 +307,7 @@ struct sdw_intel_ctx {
> > acpi_handle handle;
> > struct sdw_intel_link_dev **ldev;
> > struct list_head link_list;
> > + struct mutex link_lock; /* lock protecting link_list */
> > struct mutex shim_lock; /* lock for access to shared SHIM registers */
>
> IIRC shim_lock was used to prevent access to common registers shared
> between links. How many locks do we need?
I mean we could reuse the lock but in my experience locks having
a clearly defined purpose is less error prone, than having catch
all locks. The shim lock claims to protect the SHIM registers,
this one protects the list of links. But if you feel strongly I
am happy to try reuse the shim lock for this?
Ultimately, I am not super attached to this way of solving the
problem but we do need to come up with some solution to allow
drivers to access their device in driver remove. This causes
devices to take 1-2 minutes to remove the driver and fills the log
with loads of error messages. I am more than happy to entertain
other ways of making that happen if you have ideas you prefer?
Thanks,
Charles
prev parent reply other threads:[~2026-09-15 9:15 UTC|newest]
Thread overview: 7+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-09-11 16:19 [PATCH 0/2] Allow SoundWire devices to communicate during remove Charles Keepax
2026-09-11 16:19 ` [PATCH 1/2] soundwire: bus: Don't unassign dev_num before unregistering device Charles Keepax
2026-09-14 18:21 ` Pierre-Louis Bossart
2026-09-15 9:15 ` Charles Keepax
2026-09-11 16:19 ` [PATCH 2/2] soundwire: intel_auxdevice: Don't disable IRQs before removing children Charles Keepax
2026-09-14 18:27 ` Pierre-Louis Bossart
2026-09-15 9:13 ` Charles Keepax [this message]
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=aqkMOFfQo2YRYt2C@opensource.cirrus.com \
--to=ckeepax@opensource.cirrus.com \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-sound@vger.kernel.org \
--cc=patches@opensource.cirrus.com \
--cc=peter.ujfalusi@linux.intel.com \
--cc=pierre-louis.bossart@linux.dev \
--cc=vkoul@kernel.org \
--cc=yung-chuan.liao@linux.intel.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox
all inboxes | Powered by JetHome®