On 20.02.2023 12:04, Vijendar Mukunda wrote: > EXTERNAL EMAIL: Do not click links or open attachments unless you know the content is safe > > AMD ACP(v6.x) IP block has two SoundWire manager devices. > Add support for > - Manager driver probe & remove sequence > - Helper functions to enable/disable interrupts, Initialize sdw manager, > enable sdw pads > - Manager driver sdw_master_ops & port_ops callbacks > > Signed-off-by: Vijendar Mukunda <Vijendar.Mukunda@xxxxxxx> > --- > drivers/soundwire/amd_manager.c | 761 ++++++++++++++++++++++++++++++ > drivers/soundwire/amd_manager.h | 252 ++++++++++ > include/linux/soundwire/sdw_amd.h | 67 +++ > 3 files changed, 1080 insertions(+) > create mode 100644 drivers/soundwire/amd_manager.c > create mode 100644 drivers/soundwire/amd_manager.h > create mode 100644 include/linux/soundwire/sdw_amd.h > > diff --git a/drivers/soundwire/amd_manager.c b/drivers/soundwire/amd_manager.c > new file mode 100644 > index 000000000000..b820e04ca09f > --- /dev/null > +++ b/drivers/soundwire/amd_manager.c > @@ -0,0 +1,761 @@ > +// SPDX-License-Identifier: GPL-2.0+ > +/* > + * SoundWire AMD Manager driver > + * > + * Copyright 2023 Advanced Micro Devices, Inc. > + */ > + > +#include <linux/completion.h> > +#include <linux/device.h> > +#include <linux/io.h> > +#include <linux/jiffies.h> > +#include <linux/kernel.h> > +#include <linux/module.h> > +#include <linux/slab.h> > +#include <linux/soundwire/sdw.h> > +#include <linux/soundwire/sdw_registers.h> > +#include <linux/wait.h> > +#include <sound/pcm_params.h> > +#include <sound/soc.h> > +#include "bus.h" > +#include "amd_manager.h" > + > +#define DRV_NAME "amd_sdw_manager" > + > +#define to_amd_sdw(b) container_of(b, struct amd_sdw_manager, bus) > + > +static void amd_enable_sdw_pads(struct amd_sdw_manager *amd_manager) > +{ > + u32 sw_pad_pulldown_val; > + u32 val; > + > + mutex_lock(amd_manager->acp_sdw_lock); > + val = acp_reg_readl(amd_manager->acp_mmio + ACP_SW_PAD_KEEPER_EN); > + val |= amd_manager->reg_mask->sw_pad_enable_mask; > + acp_reg_writel(val, amd_manager->acp_mmio + ACP_SW_PAD_KEEPER_EN); > + usleep_range(1000, 1500); > + > + sw_pad_pulldown_val = acp_reg_readl(amd_manager->acp_mmio + ACP_PAD_PULLDOWN_CTRL); > + sw_pad_pulldown_val &= amd_manager->reg_mask->sw_pad_pulldown_mask; > + acp_reg_writel(sw_pad_pulldown_val, amd_manager->acp_mmio + ACP_PAD_PULLDOWN_CTRL); > + mutex_unlock(amd_manager->acp_sdw_lock); > +} > + > +static int amd_init_sdw_manager(struct amd_sdw_manager *amd_manager) > +{ > + u32 val; > + u32 timeout = 0; > + u32 retry_count = 0; > + > + acp_reg_writel(AMD_SDW_ENABLE, amd_manager->mmio + ACP_SW_EN); > + do { > + val = acp_reg_readl(amd_manager->mmio + ACP_SW_EN_STATUS); > + if (val) > + break; > + usleep_range(10, 50); > + } while (retry_count++ < AMD_SDW_STAT_MAX_RETRY_COUNT); Can't these timeout loops be addressed w/ read_poll_timeout()? [ ... ]