Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 37ca1cc8 authored by Yu Zhao's avatar Yu Zhao Committed by Greg Kroah-Hartman
Browse files

sound: don't call skl_init_chip() to reset intel skl soc



[ Upstream commit 75383f8d ]

Internally, skl_init_chip() calls snd_hdac_bus_init_chip() which
1) sets bus->chip_init to prevent multiple entrances before device
is stopped; 2) enables interrupt.

We shouldn't use it for the purpose of resetting device only because
1) when we really want to initialize device, we won't be able to do
so; 2) we are ready to handle interrupt yet, and kernel crashes when
interrupt comes in.

Rename azx_reset() to snd_hdac_bus_reset_link(), and use it to reset
device properly.

Fixes: 60767abc ("ASoC: Intel: Skylake: Reset the controller in probe")
Reviewed-by: default avatarTakashi Iwai <tiwai@suse.de>
Signed-off-by: default avatarYu Zhao <yuzhao@google.com>
Signed-off-by: default avatarMark Brown <broonie@kernel.org>
Signed-off-by: default avatarSasha Levin <alexander.levin@microsoft.com>
Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@linuxfoundation.org>
parent 2af2b70c
Loading
Loading
Loading
Loading
+1 −0
Original line number Original line Diff line number Diff line
@@ -357,6 +357,7 @@ void snd_hdac_bus_init_cmd_io(struct hdac_bus *bus);
void snd_hdac_bus_stop_cmd_io(struct hdac_bus *bus);
void snd_hdac_bus_stop_cmd_io(struct hdac_bus *bus);
void snd_hdac_bus_enter_link_reset(struct hdac_bus *bus);
void snd_hdac_bus_enter_link_reset(struct hdac_bus *bus);
void snd_hdac_bus_exit_link_reset(struct hdac_bus *bus);
void snd_hdac_bus_exit_link_reset(struct hdac_bus *bus);
int snd_hdac_bus_reset_link(struct hdac_bus *bus, bool full_reset);


void snd_hdac_bus_update_rirb(struct hdac_bus *bus);
void snd_hdac_bus_update_rirb(struct hdac_bus *bus);
int snd_hdac_bus_handle_stream_irq(struct hdac_bus *bus, unsigned int status,
int snd_hdac_bus_handle_stream_irq(struct hdac_bus *bus, unsigned int status,
+4 −3
Original line number Original line Diff line number Diff line
@@ -384,7 +384,7 @@ void snd_hdac_bus_exit_link_reset(struct hdac_bus *bus)
EXPORT_SYMBOL_GPL(snd_hdac_bus_exit_link_reset);
EXPORT_SYMBOL_GPL(snd_hdac_bus_exit_link_reset);


/* reset codec link */
/* reset codec link */
static int azx_reset(struct hdac_bus *bus, bool full_reset)
int snd_hdac_bus_reset_link(struct hdac_bus *bus, bool full_reset)
{
{
	if (!full_reset)
	if (!full_reset)
		goto skip_reset;
		goto skip_reset;
@@ -409,7 +409,7 @@ static int azx_reset(struct hdac_bus *bus, bool full_reset)
 skip_reset:
 skip_reset:
	/* check to see if controller is ready */
	/* check to see if controller is ready */
	if (!snd_hdac_chip_readb(bus, GCTL)) {
	if (!snd_hdac_chip_readb(bus, GCTL)) {
		dev_dbg(bus->dev, "azx_reset: controller not ready!\n");
		dev_dbg(bus->dev, "controller not ready!\n");
		return -EBUSY;
		return -EBUSY;
	}
	}


@@ -424,6 +424,7 @@ static int azx_reset(struct hdac_bus *bus, bool full_reset)


	return 0;
	return 0;
}
}
EXPORT_SYMBOL_GPL(snd_hdac_bus_reset_link);


/* enable interrupts */
/* enable interrupts */
static void azx_int_enable(struct hdac_bus *bus)
static void azx_int_enable(struct hdac_bus *bus)
@@ -478,7 +479,7 @@ bool snd_hdac_bus_init_chip(struct hdac_bus *bus, bool full_reset)
		return false;
		return false;


	/* reset controller */
	/* reset controller */
	azx_reset(bus, full_reset);
	snd_hdac_bus_reset_link(bus, full_reset);


	/* clear interrupts */
	/* clear interrupts */
	azx_int_clear(bus);
	azx_int_clear(bus);
+1 −1
Original line number Original line Diff line number Diff line
@@ -698,7 +698,7 @@ static int skl_first_init(struct hdac_ext_bus *ebus)
		return -ENXIO;
		return -ENXIO;
	}
	}


	skl_init_chip(bus, true);
	snd_hdac_bus_reset_link(bus, true);


	snd_hdac_bus_parse_capabilities(bus);
	snd_hdac_bus_parse_capabilities(bus);