* [PATCH v1 09/15] ASoC: fsl_ssi: Use snd_soc_init_dma_data instead
From: Nicolin Chen @ 2017-12-19 17:00 UTC (permalink / raw)
To: timur, broonie
Cc: linux-kernel, linuxppc-dev, alsa-devel, lgirdwood, fabio.estevam,
mail, caleb, arnaud.mouiche, lukma, kernel
In-Reply-To: <1513702819-42310-1-git-send-email-nicoleotsuka@gmail.com>
Since there is a helper function, use it to help readability.
Signed-off-by: Nicolin Chen <nicoleotsuka@gmail.com>
---
sound/soc/fsl/fsl_ssi.c | 7 +++----
1 file changed, 3 insertions(+), 4 deletions(-)
diff --git a/sound/soc/fsl/fsl_ssi.c b/sound/soc/fsl/fsl_ssi.c
index b51591e..fd756dd 100644
--- a/sound/soc/fsl/fsl_ssi.c
+++ b/sound/soc/fsl/fsl_ssi.c
@@ -1100,10 +1100,9 @@ static int fsl_ssi_dai_probe(struct snd_soc_dai *dai)
{
struct fsl_ssi *ssi = snd_soc_dai_get_drvdata(dai);
- if (ssi->soc->imx && ssi->use_dma) {
- dai->playback_dma_data = &ssi->dma_params_tx;
- dai->capture_dma_data = &ssi->dma_params_rx;
- }
+ if (ssi->soc->imx && ssi->use_dma)
+ snd_soc_dai_init_dma_data(dai, &ssi->dma_params_tx,
+ &ssi->dma_params_rx);
return 0;
}
--
2.7.4
^ permalink raw reply related
* [PATCH v1 08/15] ASoC: fsl_ssi: Set xFEN0 and xFEN1 together
From: Nicolin Chen @ 2017-12-19 17:00 UTC (permalink / raw)
To: timur, broonie
Cc: linux-kernel, linuxppc-dev, alsa-devel, lgirdwood, fabio.estevam,
mail, caleb, arnaud.mouiche, lukma, kernel
In-Reply-To: <1513702819-42310-1-git-send-email-nicoleotsuka@gmail.com>
It'd be safer to enable both FIFOs for TX or RX at the same time.
Signed-off-by: Nicolin Chen <nicoleotsuka@gmail.com>
---
sound/soc/fsl/fsl_ssi.c | 12 ++++++------
1 file changed, 6 insertions(+), 6 deletions(-)
diff --git a/sound/soc/fsl/fsl_ssi.c b/sound/soc/fsl/fsl_ssi.c
index 64a0d33..b51591e 100644
--- a/sound/soc/fsl/fsl_ssi.c
+++ b/sound/soc/fsl/fsl_ssi.c
@@ -581,6 +581,11 @@ static void fsl_ssi_setup_regvals(struct fsl_ssi *ssi)
if (fsl_ssi_is_ac97(ssi))
vals[RX].scr = vals[TX].scr = 0;
+ if (ssi->use_dual_fifo) {
+ vals[RX].srcr |= SSI_SRCR_RFEN1;
+ vals[TX].stcr |= SSI_STCR_TFEN1;
+ }
+
if (ssi->use_dma) {
vals[RX].sier |= SSI_SIER_RDMAE;
vals[TX].sier |= SSI_SIER_TDMAE;
@@ -981,14 +986,9 @@ static int _fsl_ssi_set_dai_fmt(struct device *dev,
SSI_SFCSR_TFWM0(wm) | SSI_SFCSR_RFWM0(wm) |
SSI_SFCSR_TFWM1(wm) | SSI_SFCSR_RFWM1(wm));
- if (ssi->use_dual_fifo) {
- regmap_update_bits(regs, REG_SSI_SRCR,
- SSI_SRCR_RFEN1, SSI_SRCR_RFEN1);
- regmap_update_bits(regs, REG_SSI_STCR,
- SSI_STCR_TFEN1, SSI_STCR_TFEN1);
+ if (ssi->use_dual_fifo)
regmap_update_bits(regs, REG_SSI_SCR,
SSI_SCR_TCH_EN, SSI_SCR_TCH_EN);
- }
if ((fmt & SND_SOC_DAIFMT_FORMAT_MASK) == SND_SOC_DAIFMT_AC97)
fsl_ssi_setup_ac97(ssi);
--
2.7.4
^ permalink raw reply related
* [PATCH v1 07/15] ASoC: fsl_ssi: Clean up fsl_ssi_setup_regvals()
From: Nicolin Chen @ 2017-12-19 17:00 UTC (permalink / raw)
To: timur, broonie
Cc: linux-kernel, linuxppc-dev, alsa-devel, lgirdwood, fabio.estevam,
mail, caleb, arnaud.mouiche, lukma, kernel
In-Reply-To: <1513702819-42310-1-git-send-email-nicoleotsuka@gmail.com>
This patch cleans fsl_ssi_setup_regvals() by following changes:
1) Moving DBG bits to the first lines.
2) Setting SSIE, RE/TE as default and cleaning it for AC97
Signed-off-by: Nicolin Chen <nicoleotsuka@gmail.com>
---
sound/soc/fsl/fsl_ssi.c | 17 ++++++-----------
1 file changed, 6 insertions(+), 11 deletions(-)
diff --git a/sound/soc/fsl/fsl_ssi.c b/sound/soc/fsl/fsl_ssi.c
index 2d9d81d..64a0d33 100644
--- a/sound/soc/fsl/fsl_ssi.c
+++ b/sound/soc/fsl/fsl_ssi.c
@@ -570,18 +570,16 @@ static void fsl_ssi_setup_regvals(struct fsl_ssi *ssi)
{
struct fsl_ssi_regvals *vals = ssi->regvals;
- vals[RX].sier = SSI_SIER_RFF0_EN;
+ vals[RX].sier = SSI_SIER_RFF0_EN | FSLSSI_SIER_DBG_RX_FLAGS;
vals[RX].srcr = SSI_SRCR_RFEN0;
- vals[RX].scr = 0;
- vals[TX].sier = SSI_SIER_TFE0_EN;
+ vals[RX].scr = SSI_SCR_SSIEN | SSI_SCR_RE;
+ vals[TX].sier = SSI_SIER_TFE0_EN | FSLSSI_SIER_DBG_TX_FLAGS;
vals[TX].stcr = SSI_STCR_TFEN0;
- vals[TX].scr = 0;
+ vals[TX].scr = SSI_SCR_SSIEN | SSI_SCR_TE;
/* AC97 has already enabled SSIEN, RE and TE, so ignore them */
- if (!fsl_ssi_is_ac97(ssi)) {
- vals[RX].scr = SSI_SCR_SSIEN | SSI_SCR_RE;
- vals[TX].scr = SSI_SCR_SSIEN | SSI_SCR_TE;
- }
+ if (fsl_ssi_is_ac97(ssi))
+ vals[RX].scr = vals[TX].scr = 0;
if (ssi->use_dma) {
vals[RX].sier |= SSI_SIER_RDMAE;
@@ -590,9 +588,6 @@ static void fsl_ssi_setup_regvals(struct fsl_ssi *ssi)
vals[RX].sier |= SSI_SIER_RIE;
vals[TX].sier |= SSI_SIER_TIE;
}
-
- vals[RX].sier |= FSLSSI_SIER_DBG_RX_FLAGS;
- vals[TX].sier |= FSLSSI_SIER_DBG_TX_FLAGS;
}
static void fsl_ssi_setup_ac97(struct fsl_ssi *ssi)
--
2.7.4
^ permalink raw reply related
* [PATCH v1 06/15] ASoC: fsl_ssi: Add DAIFMT define for AC97
From: Nicolin Chen @ 2017-12-19 17:00 UTC (permalink / raw)
To: timur, broonie
Cc: linux-kernel, linuxppc-dev, alsa-devel, lgirdwood, fabio.estevam,
mail, caleb, arnaud.mouiche, lukma, kernel
In-Reply-To: <1513702819-42310-1-git-send-email-nicoleotsuka@gmail.com>
The _fsl_ssi_set_dai_fmt() bypasses an undefined format for AC97
mode. However, it's not really necessary if AC97 has its complete
format defined.
So this patch adds a DAIFMT macro of complete format including a
clock direction and polarity.
Signed-off-by: Nicolin Chen <nicoleotsuka@gmail.com>
---
sound/soc/fsl/fsl_ssi.c | 15 ++++++++++++---
1 file changed, 12 insertions(+), 3 deletions(-)
diff --git a/sound/soc/fsl/fsl_ssi.c b/sound/soc/fsl/fsl_ssi.c
index d8c8656..2d9d81d 100644
--- a/sound/soc/fsl/fsl_ssi.c
+++ b/sound/soc/fsl/fsl_ssi.c
@@ -86,6 +86,16 @@
SNDRV_PCM_FMTBIT_S24_LE)
#endif
+/*
+ * In AC97 mode, TXDIR bit is forced to 0 and TFDIR bit is forced to 1:
+ * - SSI inputs external bit clock and outputs frame sync clock -- CBM_CFS
+ * - Also have NB_NF to mark these two clocks will not be inverted
+ */
+#define FSLSSI_AC97_DAIFMT \
+ (SND_SOC_DAIFMT_AC97 | \
+ SND_SOC_DAIFMT_CBM_CFS | \
+ SND_SOC_DAIFMT_NB_NF)
+
#define FSLSSI_SIER_DBG_RX_FLAGS \
(SSI_SIER_RFF0_EN | \
SSI_SIER_RLS_EN | \
@@ -954,8 +964,7 @@ static int _fsl_ssi_set_dai_fmt(struct device *dev,
scr &= ~SSI_SCR_SYS_CLK_EN;
break;
default:
- if (!fsl_ssi_is_ac97(ssi))
- return -EINVAL;
+ return -EINVAL;
}
stcr |= strcr;
@@ -1362,7 +1371,7 @@ static int fsl_ssi_probe(struct platform_device *pdev)
sprop = of_get_property(np, "fsl,mode", NULL);
if (sprop) {
if (!strcmp(sprop, "ac97-slave"))
- ssi->dai_fmt = SND_SOC_DAIFMT_AC97;
+ ssi->dai_fmt = FSLSSI_AC97_DAIFMT;
}
/* Select DMA or FIQ */
--
2.7.4
^ permalink raw reply related
* [PATCH v1 05/15] ASoC: fsl_ssi: Clean up helper functions of trigger()
From: Nicolin Chen @ 2017-12-19 17:00 UTC (permalink / raw)
To: timur, broonie
Cc: linux-kernel, linuxppc-dev, alsa-devel, lgirdwood, fabio.estevam,
mail, caleb, arnaud.mouiche, lukma, kernel
In-Reply-To: <1513702819-42310-1-git-send-email-nicoleotsuka@gmail.com>
The trigger() calls fsl_ssi_tx_config() and fsl_ssi_rx_config(),
and both of them jump to fsl_ssi_config(). And fsl_ssi_config()
later calls another fsl_ssi_rxtx_config().
However, the whole routine, especially fsl_ssi_config() function,
is too complicated because of the folowing reasons:
1) It has to handle the concern of the opposite stream.
2) It has to handle cases of offline configurations support.
3) It has to handle enable and disable operations while they're
mostly different.
Since the enable and disable routines have more differences than
TX and RX rountines, this patch simplifies these helper functions
with the following changes:
- Changing to two helper functions of enable and disable instead
of TX and RX.
- Removing fsl_ssi_rxtx_config() by separately integrating it to
two newly introduced enable & disable functions.
Signed-off-by: Nicolin Chen <nicoleotsuka@gmail.com>
---
sound/soc/fsl/fsl_ssi.c | 254 +++++++++++++++++++++++-------------------------
1 file changed, 119 insertions(+), 135 deletions(-)
diff --git a/sound/soc/fsl/fsl_ssi.c b/sound/soc/fsl/fsl_ssi.c
index 0f09caf..d8c8656 100644
--- a/sound/soc/fsl/fsl_ssi.c
+++ b/sound/soc/fsl/fsl_ssi.c
@@ -378,31 +378,81 @@ static irqreturn_t fsl_ssi_isr(int irq, void *dev_id)
}
/**
- * Enable or disable all rx/tx config flags at once
+ * Set SCR, SIER, STCR and SRCR registers with cached values in regvals
+ *
+ * Notes:
+ * 1) For offline_config SoCs, enable all necessary bits of both streams
+ * when 1st stream starts, even if the opposite stream will not start
+ * 2) It also clears FIFO before setting regvals; SOR is safe to set online
*/
-static void fsl_ssi_rxtx_config(struct fsl_ssi *ssi, bool enable)
+static void fsl_ssi_config_enable(struct fsl_ssi *ssi, bool tx)
{
- struct regmap *regs = ssi->regs;
struct fsl_ssi_regvals *vals = ssi->regvals;
+ u32 sier, srcr, stcr;
- if (enable) {
- regmap_update_bits(regs, REG_SSI_SIER,
- vals[RX].sier | vals[TX].sier,
- vals[RX].sier | vals[TX].sier);
- regmap_update_bits(regs, REG_SSI_SRCR,
- vals[RX].srcr | vals[TX].srcr,
- vals[RX].srcr | vals[TX].srcr);
- regmap_update_bits(regs, REG_SSI_STCR,
- vals[RX].stcr | vals[TX].stcr,
- vals[RX].stcr | vals[TX].stcr);
+ /* Clear dirty data in the FIFO; It also prevents channel slipping */
+ regmap_update_bits(ssi->regs, REG_SSI_SOR,
+ SSI_SOR_xX_CLR(tx), SSI_SOR_xX_CLR(tx));
+
+ /*
+ * On offline_config SoCs, SxCR and SIER are already configured when
+ * the previous stream started. So skip all SxCR and SIER settings
+ * to prevent online reconfigurations, then jump to set SCR directly
+ */
+ if (ssi->soc->offline_config && ssi->streams)
+ goto enable_scr;
+
+ if (ssi->soc->offline_config) {
+ /*
+ * Online reconfiguration not supported, so enable all bits for
+ * both streams at once to avoid necessity of reconfigurations
+ */
+ srcr = vals[RX].srcr | vals[TX].srcr;
+ stcr = vals[RX].stcr | vals[TX].stcr;
+ sier = vals[RX].sier | vals[TX].sier;
} else {
- regmap_update_bits(regs, REG_SSI_SRCR,
- vals[RX].srcr | vals[TX].srcr, 0);
- regmap_update_bits(regs, REG_SSI_STCR,
- vals[RX].stcr | vals[TX].stcr, 0);
- regmap_update_bits(regs, REG_SSI_SIER,
- vals[RX].sier | vals[TX].sier, 0);
+ /* Otherwise, only set bits for the current stream */
+ srcr = vals[tx].srcr;
+ stcr = vals[tx].stcr;
+ sier = vals[tx].sier;
}
+
+ /* Configure SRCR, STCR and SIER at once */
+ regmap_update_bits(ssi->regs, REG_SSI_SRCR, srcr, srcr);
+ regmap_update_bits(ssi->regs, REG_SSI_STCR, stcr, stcr);
+ regmap_update_bits(ssi->regs, REG_SSI_SIER, sier, sier);
+
+enable_scr:
+ /*
+ * Start DMA before setting TE to avoid FIFO underrun
+ * which may cause a channel slip or a channel swap
+ *
+ * TODO: FIQ cases might also need this upon testing
+ */
+ if (ssi->use_dma && tx) {
+ int try = 100;
+ u32 sfcsr;
+
+ /* Enable SSI first to send TX DMA request */
+ regmap_update_bits(ssi->regs, REG_SSI_SCR,
+ SSI_SCR_SSIEN, SSI_SCR_SSIEN);
+
+ /* Busy wait until TX FIFO not empty -- DMA working */
+ do {
+ regmap_read(ssi->regs, REG_SSI_SFCSR, &sfcsr);
+ if (SSI_SFCSR_TFCNT0(sfcsr))
+ break;
+ } while (--try);
+
+ /* FIFO still empty -- something might be wrong */
+ if (!SSI_SFCSR_TFCNT0(sfcsr))
+ dev_warn(ssi->dev, "Timeout waiting TX FIFO filling\n");
+ }
+ /* Enable all remaining bits in SCR */
+ regmap_update_bits(ssi->regs, REG_SSI_SCR, vals[tx].scr, vals[tx].scr);
+
+ /* Log the enabled stream to the mask */
+ ssi->streams |= BIT(tx);
}
/**
@@ -426,65 +476,50 @@ static void fsl_ssi_rxtx_config(struct fsl_ssi *ssi, bool enable)
((vals) & _ssi_xor_shared_bits(vals, avals, aactive))
/**
- * Enable or disable SSI configuration.
+ * Unset SCR, SIER, STCR and SRCR registers with cached values in regvals
+ *
+ * Notes:
+ * 1) For offline_config SoCs, to avoid online reconfigurations, disable all
+ * bits of both streams at once when the last stream is abort to end
+ * 2) It also clears FIFO after unsetting regvals; SOR is safe to set online
*/
-static void fsl_ssi_config(struct fsl_ssi *ssi, bool enable,
- struct fsl_ssi_regvals *vals)
+static void fsl_ssi_config_disable(struct fsl_ssi *ssi, bool tx)
{
- bool tx = &ssi->regvals[TX] == vals;
- struct regmap *regs = ssi->regs;
- struct fsl_ssi_regvals *avals;
+ struct fsl_ssi_regvals *avals, *vals = &ssi->regvals[tx];
+ u32 sier, srcr, stcr, scr;
bool aactive;
/* Check if the opposite stream is active */
aactive = ssi->streams & BIT(!tx);
- /* Get the opposite direction to keep its values untouched */
- if (&ssi->regvals[RX] == vals)
- avals = &ssi->regvals[TX];
- else
- avals = &ssi->regvals[RX];
-
- if (!enable) {
- /*
- * To keep the other stream safe, exclude shared bits between
- * both streams, and get safe bits to disable current stream
- */
- u32 scr = ssi_excl_shared_bits(vals->scr, avals->scr, aactive);
- /* Safely disable SCR register for the stream */
- regmap_update_bits(regs, REG_SSI_SCR, scr, 0);
-
- /* Log the disabled stream to the mask */
- ssi->streams &= ~BIT(tx);
- }
+ /* Get regvals of the opposite stream to keep opposite stream safe */
+ avals = &ssi->regvals[!tx];
/*
- * For cases where online configuration is not supported,
- * 1) Enable all necessary bits of both streams when 1st stream starts
- * even if the opposite stream will not start
- * 2) Disable all remaining bits of both streams when last stream ends
+ * To keep the other stream safe, exclude shared bits between
+ * both streams, and get safe bits to disable current stream
*/
- if (ssi->soc->offline_config) {
- if ((enable && !ssi->streams) || (!enable && !aactive))
- fsl_ssi_rxtx_config(ssi, enable);
+ scr = ssi_excl_shared_bits(vals->scr, avals->scr, aactive);
- goto config_done;
- }
+ /* Disable safe bits of SCR register for the current stream */
+ regmap_update_bits(ssi->regs, REG_SSI_SCR, scr, 0);
- /* Online configure single direction while SSI is running */
- if (enable) {
- /* Clear FIFO to prevent dirty data or channel slipping */
- regmap_update_bits(ssi->regs, REG_SSI_SOR,
- SSI_SOR_xX_CLR(tx), SSI_SOR_xX_CLR(tx));
+ /* Log the disabled stream to the mask */
+ ssi->streams &= ~BIT(tx);
- regmap_update_bits(regs, REG_SSI_SRCR, vals->srcr, vals->srcr);
- regmap_update_bits(regs, REG_SSI_STCR, vals->stcr, vals->stcr);
- regmap_update_bits(regs, REG_SSI_SIER, vals->sier, vals->sier);
- } else {
- u32 sier;
- u32 srcr;
- u32 stcr;
+ /*
+ * On offline_config SoCs, if the other stream is active, skip
+ * SxCR and SIER settings to prevent online reconfigurations
+ */
+ if (ssi->soc->offline_config && aactive)
+ goto fifo_clear;
+ if (ssi->soc->offline_config) {
+ /* Now there is only current stream active, disable all bits */
+ srcr = vals->srcr | avals->srcr;
+ stcr = vals->stcr | avals->stcr;
+ sier = vals->sier | avals->sier;
+ } else {
/*
* To keep the other stream safe, exclude shared bits between
* both streams, and get safe bits to disable current stream
@@ -492,57 +527,17 @@ static void fsl_ssi_config(struct fsl_ssi *ssi, bool enable,
sier = ssi_excl_shared_bits(vals->sier, avals->sier, aactive);
srcr = ssi_excl_shared_bits(vals->srcr, avals->srcr, aactive);
stcr = ssi_excl_shared_bits(vals->stcr, avals->stcr, aactive);
-
- /* Safely disable other control registers for the stream */
- regmap_update_bits(regs, REG_SSI_SRCR, srcr, 0);
- regmap_update_bits(regs, REG_SSI_STCR, stcr, 0);
- regmap_update_bits(regs, REG_SSI_SIER, sier, 0);
-
- /* Clear FIFO to prevent dirty data or channel slipping */
- regmap_update_bits(ssi->regs, REG_SSI_SOR,
- SSI_SOR_xX_CLR(tx), SSI_SOR_xX_CLR(tx));
}
-config_done:
- /* Enabling of subunits is done after configuration */
- if (enable) {
- /*
- * Start DMA before setting TE to avoid FIFO underrun
- * which may cause a channel slip or a channel swap
- *
- * TODO: FIQ cases might also need this upon testing
- */
- if (ssi->use_dma && (vals->scr & SSI_SCR_TE)) {
- int i;
- int max_loop = 100;
-
- /* Enable SSI first to send TX DMA request */
- regmap_update_bits(regs, REG_SSI_SCR,
- SSI_SCR_SSIEN, SSI_SCR_SSIEN);
-
- /* Busy wait until TX FIFO not empty -- DMA working */
- for (i = 0; i < max_loop; i++) {
- u32 sfcsr;
- regmap_read(regs, REG_SSI_SFCSR, &sfcsr);
- if (SSI_SFCSR_TFCNT0(sfcsr))
- break;
- }
- if (i == max_loop) {
- dev_err(ssi->dev,
- "Timeout waiting TX FIFO filling\n");
- }
- }
- /* Enable all remaining bits */
- regmap_update_bits(regs, REG_SSI_SCR, vals->scr, vals->scr);
-
- /* Log the enabled stream to the mask */
- ssi->streams |= BIT(tx);
- }
-}
+ /* Clear configurations of SRCR, STCR and SIER at once */
+ regmap_update_bits(ssi->regs, REG_SSI_SRCR, srcr, 0);
+ regmap_update_bits(ssi->regs, REG_SSI_STCR, stcr, 0);
+ regmap_update_bits(ssi->regs, REG_SSI_SIER, sier, 0);
-static void fsl_ssi_rx_config(struct fsl_ssi *ssi, bool enable)
-{
- fsl_ssi_config(ssi, enable, &ssi->regvals[RX]);
+fifo_clear:
+ /* Clear remaining data in the FIFO */
+ regmap_update_bits(ssi->regs, REG_SSI_SOR,
+ SSI_SOR_xX_CLR(tx), SSI_SOR_xX_CLR(tx));
}
static void fsl_ssi_tx_ac97_saccst_setup(struct fsl_ssi *ssi)
@@ -558,21 +553,6 @@ static void fsl_ssi_tx_ac97_saccst_setup(struct fsl_ssi *ssi)
}
}
-static void fsl_ssi_tx_config(struct fsl_ssi *ssi, bool enable)
-{
- /*
- * SACCST might be modified via AC Link by a CODEC if it sends
- * extra bits in their SLOTREQ requests, which'll accidentally
- * send valid data to slots other than normal playback slots.
- *
- * To be safe, configure SACCST right before TX starts.
- */
- if (enable && fsl_ssi_is_ac97(ssi))
- fsl_ssi_tx_ac97_saccst_setup(ssi);
-
- fsl_ssi_config(ssi, enable, &ssi->regvals[TX]);
-}
-
/**
* Cache critical bits of SIER, SRCR, STCR and SCR to later set them safely
*/
@@ -1079,6 +1059,7 @@ static int fsl_ssi_set_dai_tdm_slot(struct snd_soc_dai *dai, u32 tx_mask,
static int fsl_ssi_trigger(struct snd_pcm_substream *substream, int cmd,
struct snd_soc_dai *dai)
{
+ bool tx = substream->stream == SNDRV_PCM_STREAM_PLAYBACK;
struct snd_soc_pcm_runtime *rtd = substream->private_data;
struct fsl_ssi *ssi = snd_soc_dai_get_drvdata(rtd->cpu_dai);
@@ -1086,19 +1067,22 @@ static int fsl_ssi_trigger(struct snd_pcm_substream *substream, int cmd,
case SNDRV_PCM_TRIGGER_START:
case SNDRV_PCM_TRIGGER_RESUME:
case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
- if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
- fsl_ssi_tx_config(ssi, true);
- else
- fsl_ssi_rx_config(ssi, true);
+ /*
+ * SACCST might be modified via AC Link by a CODEC if it sends
+ * extra bits in their SLOTREQ requests, which'll accidentally
+ * send valid data to slots other than normal playback slots.
+ *
+ * To be safe, configure SACCST right before TX starts.
+ */
+ if (tx && fsl_ssi_is_ac97(ssi))
+ fsl_ssi_tx_ac97_saccst_setup(ssi);
+ fsl_ssi_config_enable(ssi, tx);
break;
case SNDRV_PCM_TRIGGER_STOP:
case SNDRV_PCM_TRIGGER_SUSPEND:
case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
- if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
- fsl_ssi_tx_config(ssi, false);
- else
- fsl_ssi_rx_config(ssi, false);
+ fsl_ssi_config_disable(ssi, tx);
break;
default:
--
2.7.4
^ permalink raw reply related
* [PATCH v1 04/15] ASoC: fsl_ssi: Clear FIFO directly in fsl_ssi_config()
From: Nicolin Chen @ 2017-12-19 17:00 UTC (permalink / raw)
To: timur, broonie
Cc: linux-kernel, linuxppc-dev, alsa-devel, lgirdwood, fabio.estevam,
mail, caleb, arnaud.mouiche, lukma, kernel
In-Reply-To: <1513702819-42310-1-git-send-email-nicoleotsuka@gmail.com>
The FIFO clear helper function is just one line of code now.
So it could be cleaned up by removing it and calling regmap
directly.
Meanwhile, FIFO clear could be applied to all use cases, not
confined to AC97. So this patch also moves FIFO clear in the
trigger() to fsl_ssi_config() and removes the AC97 check.
Note that SOR register is safe from offline_config HW limit.
Signed-off-by: Nicolin Chen <nicoleotsuka@gmail.com>
---
sound/soc/fsl/fsl_ssi.c | 28 +++++++---------------------
1 file changed, 7 insertions(+), 21 deletions(-)
diff --git a/sound/soc/fsl/fsl_ssi.c b/sound/soc/fsl/fsl_ssi.c
index 6dda2e0..0f09caf 100644
--- a/sound/soc/fsl/fsl_ssi.c
+++ b/sound/soc/fsl/fsl_ssi.c
@@ -406,17 +406,6 @@ static void fsl_ssi_rxtx_config(struct fsl_ssi *ssi, bool enable)
}
/**
- * Clear remaining data in the FIFO to avoid dirty data or channel slipping
- */
-static void fsl_ssi_fifo_clear(struct fsl_ssi *ssi, bool is_rx)
-{
- bool tx = !is_rx;
-
- regmap_update_bits(ssi->regs, REG_SSI_SOR,
- SSI_SOR_xX_CLR(tx), SSI_SOR_xX_CLR(tx));
-}
-
-/**
* Exclude bits that are used by the opposite stream
*
* When both streams are active, disabling some bits for the current stream
@@ -484,7 +473,9 @@ static void fsl_ssi_config(struct fsl_ssi *ssi, bool enable,
/* Online configure single direction while SSI is running */
if (enable) {
- fsl_ssi_fifo_clear(ssi, vals->scr & SSI_SCR_RE);
+ /* Clear FIFO to prevent dirty data or channel slipping */
+ regmap_update_bits(ssi->regs, REG_SSI_SOR,
+ SSI_SOR_xX_CLR(tx), SSI_SOR_xX_CLR(tx));
regmap_update_bits(regs, REG_SSI_SRCR, vals->srcr, vals->srcr);
regmap_update_bits(regs, REG_SSI_STCR, vals->stcr, vals->stcr);
@@ -506,6 +497,10 @@ static void fsl_ssi_config(struct fsl_ssi *ssi, bool enable,
regmap_update_bits(regs, REG_SSI_SRCR, srcr, 0);
regmap_update_bits(regs, REG_SSI_STCR, stcr, 0);
regmap_update_bits(regs, REG_SSI_SIER, sier, 0);
+
+ /* Clear FIFO to prevent dirty data or channel slipping */
+ regmap_update_bits(ssi->regs, REG_SSI_SOR,
+ SSI_SOR_xX_CLR(tx), SSI_SOR_xX_CLR(tx));
}
config_done:
@@ -1086,7 +1081,6 @@ static int fsl_ssi_trigger(struct snd_pcm_substream *substream, int cmd,
{
struct snd_soc_pcm_runtime *rtd = substream->private_data;
struct fsl_ssi *ssi = snd_soc_dai_get_drvdata(rtd->cpu_dai);
- struct regmap *regs = ssi->regs;
switch (cmd) {
case SNDRV_PCM_TRIGGER_START:
@@ -1111,14 +1105,6 @@ static int fsl_ssi_trigger(struct snd_pcm_substream *substream, int cmd,
return -EINVAL;
}
- /* Clear corresponding FIFO */
- if (fsl_ssi_is_ac97(ssi)) {
- if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
- regmap_write(regs, REG_SSI_SOR, SSI_SOR_TX_CLR);
- else
- regmap_write(regs, REG_SSI_SOR, SSI_SOR_RX_CLR);
- }
-
return 0;
}
--
2.7.4
^ permalink raw reply related
* [PATCH v1 03/15] ASoC: fsl_ssi: Rename fsl_ssi_disable_val macro
From: Nicolin Chen @ 2017-12-19 17:00 UTC (permalink / raw)
To: timur, broonie
Cc: linux-kernel, linuxppc-dev, alsa-devel, lgirdwood, fabio.estevam,
mail, caleb, arnaud.mouiche, lukma, kernel
In-Reply-To: <1513702819-42310-1-git-send-email-nicoleotsuka@gmail.com>
The define of fsl_ssi_disable_val is not so clear as it mixes two
steps of calculations together. And those parameter names are also
a bit long to read.
Since it just tries to exclude the shared bits from the regvals of
current stream while the opposite stream is active, it's better to
use something like ssi_excl_shared_bits.
This patch also bisects fsl_ssi_disable_val into two macros of two
corresponding steps and then shortens its parameter names. It also
updates callers in the fsl_ssi_config() accordingly.
Signed-off-by: Nicolin Chen <nicoleotsuka@gmail.com>
---
sound/soc/fsl/fsl_ssi.c | 54 ++++++++++++++++++++-----------------------------
1 file changed, 22 insertions(+), 32 deletions(-)
diff --git a/sound/soc/fsl/fsl_ssi.c b/sound/soc/fsl/fsl_ssi.c
index f05f78d..6dda2e0 100644
--- a/sound/soc/fsl/fsl_ssi.c
+++ b/sound/soc/fsl/fsl_ssi.c
@@ -417,24 +417,24 @@ static void fsl_ssi_fifo_clear(struct fsl_ssi *ssi, bool is_rx)
}
/**
- * Calculate the bits that have to be disabled for the current stream that is
- * getting disabled. This keeps the bits enabled that are necessary for the
- * second stream to work if 'stream_active' is true.
+ * Exclude bits that are used by the opposite stream
*
- * Detailed calculation:
- * These are the values that need to be active after disabling. For non-active
- * second stream, this is 0:
- * vals_stream * !!stream_active
+ * When both streams are active, disabling some bits for the current stream
+ * might break the other stream if these bits are used by it.
*
- * The following computes the overall differences between the setup for the
- * to-disable stream and the active stream, a simple XOR:
- * vals_disable ^ (vals_stream * !!(stream_active))
+ * @vals : regvals of the current stream
+ * @avals: regvals of the opposite stream
+ * @aactive: active state of the opposite stream
*
- * The full expression adds a mask on all values we care about
+ * 1) XOR vals and avals to get the differences if the other stream is active;
+ * Otherwise, return current vals if the other stream is not active
+ * 2) AND the result of 1) with the current vals
*/
-#define fsl_ssi_disable_val(vals_disable, vals_stream, stream_active) \
- ((vals_disable) & \
- ((vals_disable) ^ ((vals_stream) * (u32)!!(stream_active))))
+#define _ssi_xor_shared_bits(vals, avals, aactive) \
+ ((vals) ^ ((avals) * (aactive)))
+
+#define ssi_excl_shared_bits(vals, avals, aactive) \
+ ((vals) & _ssi_xor_shared_bits(vals, avals, aactive))
/**
* Enable or disable SSI configuration.
@@ -445,16 +445,10 @@ static void fsl_ssi_config(struct fsl_ssi *ssi, bool enable,
bool tx = &ssi->regvals[TX] == vals;
struct regmap *regs = ssi->regs;
struct fsl_ssi_regvals *avals;
- int nr_active_streams;
- int keep_active;
-
- nr_active_streams = !!(ssi->streams & BIT(TX)) +
- !!(ssi->streams & BIT(RX));
+ bool aactive;
- if (nr_active_streams - 1 > 0)
- keep_active = 1;
- else
- keep_active = 0;
+ /* Check if the opposite stream is active */
+ aactive = ssi->streams & BIT(!tx);
/* Get the opposite direction to keep its values untouched */
if (&ssi->regvals[RX] == vals)
@@ -467,8 +461,7 @@ static void fsl_ssi_config(struct fsl_ssi *ssi, bool enable,
* To keep the other stream safe, exclude shared bits between
* both streams, and get safe bits to disable current stream
*/
- u32 scr = fsl_ssi_disable_val(vals->scr, avals->scr,
- keep_active);
+ u32 scr = ssi_excl_shared_bits(vals->scr, avals->scr, aactive);
/* Safely disable SCR register for the stream */
regmap_update_bits(regs, REG_SSI_SCR, scr, 0);
@@ -483,7 +476,7 @@ static void fsl_ssi_config(struct fsl_ssi *ssi, bool enable,
* 2) Disable all remaining bits of both streams when last stream ends
*/
if (ssi->soc->offline_config) {
- if ((enable && !nr_active_streams) || (!enable && !keep_active))
+ if ((enable && !ssi->streams) || (!enable && !aactive))
fsl_ssi_rxtx_config(ssi, enable);
goto config_done;
@@ -505,12 +498,9 @@ static void fsl_ssi_config(struct fsl_ssi *ssi, bool enable,
* To keep the other stream safe, exclude shared bits between
* both streams, and get safe bits to disable current stream
*/
- sier = fsl_ssi_disable_val(vals->sier, avals->sier,
- keep_active);
- srcr = fsl_ssi_disable_val(vals->srcr, avals->srcr,
- keep_active);
- stcr = fsl_ssi_disable_val(vals->stcr, avals->stcr,
- keep_active);
+ sier = ssi_excl_shared_bits(vals->sier, avals->sier, aactive);
+ srcr = ssi_excl_shared_bits(vals->srcr, avals->srcr, aactive);
+ stcr = ssi_excl_shared_bits(vals->stcr, avals->stcr, aactive);
/* Safely disable other control registers for the stream */
regmap_update_bits(regs, REG_SSI_SRCR, srcr, 0);
--
2.7.4
^ permalink raw reply related
* [PATCH v1 02/15] ASoC: fsl_ssi: Maintain a mask of active streams
From: Nicolin Chen @ 2017-12-19 17:00 UTC (permalink / raw)
To: timur, broonie
Cc: linux-kernel, linuxppc-dev, alsa-devel, lgirdwood, fabio.estevam,
mail, caleb, arnaud.mouiche, lukma, kernel
In-Reply-To: <1513702819-42310-1-git-send-email-nicoleotsuka@gmail.com>
Checking TE and RE bits in SCR register doesn't work for AC97 mode
which enables SSIEN, TE and RE in the fsl_ssi_setup_ac97() that's
called during probe().
So when running into the trigger(), it will always get the result
of both TE and RE being enabled already, even if actually there is
no active stream.
This patch fixes this issue by adding a variable to log the active
streams manually.
Signed-off-by: Nicolin Chen <nicoleotsuka@gmail.com>
---
sound/soc/fsl/fsl_ssi.c | 15 +++++++++++----
1 file changed, 11 insertions(+), 4 deletions(-)
diff --git a/sound/soc/fsl/fsl_ssi.c b/sound/soc/fsl/fsl_ssi.c
index ed2712b..f05f78d 100644
--- a/sound/soc/fsl/fsl_ssi.c
+++ b/sound/soc/fsl/fsl_ssi.c
@@ -201,6 +201,7 @@ struct fsl_ssi_soc_data {
* @cpu_dai_drv: CPU DAI driver for this device
*
* @dai_fmt: DAI configuration this device is currently used with
+ * @streams: Mask of current active streams: BIT(TX) and BIT(RX)
* @i2s_net: I2S and Network mode configurations of SCR register
* @use_dma: DMA is used or FIQ with stream filter
* @use_dual_fifo: DMA with support for dual FIFO mode
@@ -245,6 +246,7 @@ struct fsl_ssi {
struct snd_soc_dai_driver cpu_dai_drv;
unsigned int dai_fmt;
+ u8 streams;
u8 i2s_net;
bool use_dma;
bool use_dual_fifo;
@@ -440,15 +442,14 @@ static void fsl_ssi_fifo_clear(struct fsl_ssi *ssi, bool is_rx)
static void fsl_ssi_config(struct fsl_ssi *ssi, bool enable,
struct fsl_ssi_regvals *vals)
{
+ bool tx = &ssi->regvals[TX] == vals;
struct regmap *regs = ssi->regs;
struct fsl_ssi_regvals *avals;
int nr_active_streams;
- u32 scr;
int keep_active;
- regmap_read(regs, REG_SSI_SCR, &scr);
-
- nr_active_streams = !!(scr & SSI_SCR_TE) + !!(scr & SSI_SCR_RE);
+ nr_active_streams = !!(ssi->streams & BIT(TX)) +
+ !!(ssi->streams & BIT(RX));
if (nr_active_streams - 1 > 0)
keep_active = 1;
@@ -470,6 +471,9 @@ static void fsl_ssi_config(struct fsl_ssi *ssi, bool enable,
keep_active);
/* Safely disable SCR register for the stream */
regmap_update_bits(regs, REG_SSI_SCR, scr, 0);
+
+ /* Log the disabled stream to the mask */
+ ssi->streams &= ~BIT(tx);
}
/*
@@ -545,6 +549,9 @@ static void fsl_ssi_config(struct fsl_ssi *ssi, bool enable,
}
/* Enable all remaining bits */
regmap_update_bits(regs, REG_SSI_SCR, vals->scr, vals->scr);
+
+ /* Log the enabled stream to the mask */
+ ssi->streams |= BIT(tx);
}
}
--
2.7.4
^ permalink raw reply related
* [PATCH v1 01/15] ASoC: fsl_ssi: Clean up set_dai_tdm_slot()
From: Nicolin Chen @ 2017-12-19 17:00 UTC (permalink / raw)
To: timur, broonie
Cc: linux-kernel, linuxppc-dev, alsa-devel, lgirdwood, fabio.estevam,
mail, caleb, arnaud.mouiche, lukma, kernel
In-Reply-To: <1513702819-42310-1-git-send-email-nicoleotsuka@gmail.com>
This patch replaces the register read with ssi->i2s_net for
simplification. It also removes masking SSIEN from scr value
since it's handled later by regmap_update_bits() to set this
scr value back.
Signed-off-by: Nicolin Chen <nicoleotsuka@gmail.com>
---
sound/soc/fsl/fsl_ssi.c | 7 ++-----
1 file changed, 2 insertions(+), 5 deletions(-)
diff --git a/sound/soc/fsl/fsl_ssi.c b/sound/soc/fsl/fsl_ssi.c
index aecd00f..ed2712b 100644
--- a/sound/soc/fsl/fsl_ssi.c
+++ b/sound/soc/fsl/fsl_ssi.c
@@ -1051,9 +1051,7 @@ static int fsl_ssi_set_dai_tdm_slot(struct snd_soc_dai *dai, u32 tx_mask,
}
/* The slot number should be >= 2 if using Network mode or I2S mode */
- regmap_read(regs, REG_SSI_SCR, &val);
- val &= SSI_SCR_I2S_MODE_MASK | SSI_SCR_NET;
- if (val && slots < 2) {
+ if (ssi->i2s_net && slots < 2) {
dev_err(dai->dev, "slot number should be >= 2 in I2S or NET\n");
return -EINVAL;
}
@@ -1063,9 +1061,8 @@ static int fsl_ssi_set_dai_tdm_slot(struct snd_soc_dai *dai, u32 tx_mask,
regmap_update_bits(regs, REG_SSI_SRCCR,
SSI_SxCCR_DC_MASK, SSI_SxCCR_DC(slots));
- /* Save SSIEN bit of the SCR register */
+ /* Save the SCR register value */
regmap_read(regs, REG_SSI_SCR, &val);
- val &= SSI_SCR_SSIEN;
/* Temporarily enable SSI to allow SxMSKs to be configurable */
regmap_update_bits(regs, REG_SSI_SCR, SSI_SCR_SSIEN, SSI_SCR_SSIEN);
--
2.7.4
^ permalink raw reply related
* [PATCH v1 00/15] ASoC: fsl_ssi: Clean up - program flow level
From: Nicolin Chen @ 2017-12-19 17:00 UTC (permalink / raw)
To: timur, broonie
Cc: linux-kernel, linuxppc-dev, alsa-devel, lgirdwood, fabio.estevam,
mail, caleb, arnaud.mouiche, lukma, kernel
==Background==
The fsl_ssi driver was designed for PPC originally and then it has
been updated to support different modes for i.MX Series, including
SDMA, I2S Master mode, AC97 and older i.MXs with FIQ, by different
contributors for different use cases in different coding styles.
Additionally, in order to fix/work-around hardware bugs and design
flaws, the driver made a lot of compromise so now its program flow
looks very complicated and it's getting hard to maintain or update.
So I am going to clean up the driver on both coding style level and
program flow level.
==Introduction==
This series of patches is the second set to clean up fsl_ssi driver
in the program flow level. Any patch here may impact a fundamental
test case like playback or record.
==Verification==
This series of patches require fully tested. I have done such tests
on i.MX6SoloX with WM8962 using imx_v6_v7_defconfig as:
- Playback via I2S Master and Slave mode
- Record via I2S Master and Slave mode
- Simultaneous playback and record via I2S Master and Slave mode
- Background playback with foreground record (starting at different
time) via I2S Master and Slave mode
- Background record with foreground playback (starting at different
time) via I2S Master and Slave mode
* All tests above by hacking offline_config to true in imx51.
Example of uncovered tests: TDM, AC97, PowerPC and FIQ.
Nicolin Chen (15):
ASoC: fsl_ssi: Clean up set_dai_tdm_slot()
ASoC: fsl_ssi: Maintain a mask of active streams
ASoC: fsl_ssi: Rename fsl_ssi_disable_val macro
ASoC: fsl_ssi: Clear FIFO directly in fsl_ssi_config()
ASoC: fsl_ssi: Clean up helper functions of trigger()
ASoC: fsl_ssi: Add DAIFMT define for AC97
ASoC: fsl_ssi: Clean up fsl_ssi_setup_regvals()
ASoC: fsl_ssi: Set xFEN0 and xFEN1 together
ASoC: fsl_ssi: Use snd_soc_init_dma_data instead
ASoC: fsl_ssi: Move one-time configurations to dai_probe()
ASoC: fsl_ssi: Setup AC97 in dai_probe()
ASoC: fsl_ssi: Clean up _fsl_ssi_set_dai_fmt()
ASoC: fsl_ssi: Remove cpu_dai_drv from fsl_ssi structure
ASoC: fsl_ssi: Move DT related code to a separate probe()
ASoC: fsl_ssi: Use ssi->streams instead of reading register
sound/soc/fsl/fsl_ssi.c | 710 ++++++++++++++++++++++++------------------------
1 file changed, 348 insertions(+), 362 deletions(-)
--
2.7.4
^ permalink raw reply
* Re: [net] Revert "net: core: maybe return -EEXIST in __dev_alloc_name"
From: Johannes Berg @ 2017-12-19 16:15 UTC (permalink / raw)
To: Michael Ellerman
Cc: netdev@vger.kernel.org, Jouni Malinen, Rasmus Villemoes,
linuxppc-dev@lists.ozlabs.org
In-Reply-To: <87vah29a1m.fsf@concordia.ellerman.id.au>
Hi,
> This revert seems to have broken networking on one of my powerpc
> machines, according to git bisect.
Fun!
TBH, I only looked at the immediate problem we ran into, and reverted
what was causing it. I don't think we saw the follow-up problem you're
seeing.
> The symptom is DHCP fails and I don't get a link, I didn't dig any
> further than that. I can if it's helpful.
>
> I think the problem is that 87c320e51519 ("net: core: dev_get_valid_name
> is now the same as dev_alloc_name_ns") only makes sense while
> d6f295e9def0 remains in the tree.
>
> ie. before the entire series, dev_get_valid_name() would return EEXIST,
> and that was retained when 87c320e51519 was merged, but now that
> d6f295e9def0 has been reverted dev_get_valid_name() is returning ENFILE.
>
> I can get the network up again if I also revert 87c320e51519 ("net:
> core: dev_get_valid_name is now the same as dev_alloc_name_ns"), or with
> the gross patch below.
Makes sense. I guess that should be reverted too then, or even your
"gross" patch applied.
johannes
^ permalink raw reply
* Re: [PATCH v9 29/51] mm/mprotect, powerpc/mm/pkeys, x86/mm/pkeys: Add sysfs interface
From: Ram Pai @ 2017-12-19 16:32 UTC (permalink / raw)
To: Michael Ellerman
Cc: Dave Hansen, mingo, akpm, corbet, arnd, linux-arch, ebiederm,
linux-doc, x86, linux-kernel, mhocko, linux-mm, paulus,
aneesh.kumar, linux-kselftest, bauerman, linuxppc-dev, khandual
In-Reply-To: <877etj9ekv.fsf@concordia.ellerman.id.au>
On Tue, Dec 19, 2017 at 09:50:24PM +1100, Michael Ellerman wrote:
> Dave Hansen <dave.hansen@intel.com> writes:
>
> > On 11/06/2017 12:57 AM, Ram Pai wrote:
> >> Expose useful information for programs using memory protection keys.
> >> Provide implementation for powerpc and x86.
> >>
> >> On a powerpc system with pkeys support, here is what is shown:
> >>
> >> $ head /sys/kernel/mm/protection_keys/*
> >> ==> /sys/kernel/mm/protection_keys/disable_access_supported <==
> >> true
> >
> > This is cute, but I don't think it should be part of the ABI. Put it in
> > debugfs if you want it for cute tests. The stuff that this tells you
> > can and should come from pkey_alloc() for the ABI.
>
> Yeah I agree this is not sysfs material.
>
> In particular the total/usable numbers are completely useless vs other
> threads allocating pkeys out from under you.
The usable number is the minimum number of keys available for use by the
application, not the number of keys **currently** available. Its a
static number.
I am dropping this patch. We can revisit this when a clear request for
such a feature emerges.
>
> >
> >> Any application wanting to use protection keys needs to be able to
> >> function without them. They might be unavailable because the
> >> hardware that the application runs on does not support them, the
> >> kernel code does not contain support, the kernel support has been
> >> disabled, or because the keys have all been allocated, perhaps by a
> >> library the application is using. It is recommended that
> >> applications wanting to use protection keys should simply call
> >> pkey_alloc(2) and test whether the call succeeds, instead of
> >> attempting to detect support for the feature in any other way.
> >
> > Do you really not have standard way on ppc to say whether hardware
> > features are supported by the kernel? For instance, how do you know if
> > a given set of registers are known to and are being context-switched by
> > the kernel?
>
> Yes we do, we emit feature bits in the AT_HWCAP entry of the aux vector,
> same as some other architectures.
Ah. I was not aware of this.
Thanks,
RP
^ permalink raw reply
* Re: [PATCH v9 29/51] mm/mprotect, powerpc/mm/pkeys, x86/mm/pkeys: Add sysfs interface
From: Ram Pai @ 2017-12-19 16:22 UTC (permalink / raw)
To: Gabriel Paubert
Cc: linux-arch, corbet, arnd, linux-doc, aneesh.kumar, x86,
linux-kernel, mhocko, linux-mm, Dave Hansen, mingo, paulus,
ebiederm, linux-kselftest, bauerman, akpm, linuxppc-dev, khandual
In-Reply-To: <20171219083122.q7ycxg2dfspgzw7z@lt-gp.iram.es>
On Tue, Dec 19, 2017 at 09:31:22AM +0100, Gabriel Paubert wrote:
> On Mon, Dec 18, 2017 at 03:15:51PM -0800, Ram Pai wrote:
> > On Mon, Dec 18, 2017 at 02:28:14PM -0800, Dave Hansen wrote:
> > > On 12/18/2017 02:18 PM, Ram Pai wrote:
> > >
....snip...
> > > > I think on x86 you look for some hardware registers to determine
> > > > which hardware features are enabled by the kernel.
> > >
> > > No, we use CPUID. It's a part of the ISA that's designed for
> > > enumerating CPU and (sometimes) OS support for CPU features.
> > >
> > > > We do not have generic support for something like that on ppc. The
> > > > kernel looks at the device tree to determine what hardware features
> > > > are available. But does not have mechanism to tell the hardware to
> > > > track which of its features are currently enabled/used by the
> > > > kernel; atleast not for the memory-key feature.
> > >
> > > Bummer. You're missing out.
> > >
> > > But, you could still do this with a syscall. "Hey, kernel, do you
> > > support this feature?"
> >
> > or do powerpc specific sysfs interface.
> > or a debugfs interface.
>
> getauxval(3) ?
>
> With AT_HWCAP or HWCAP2 as parameter already gives information about
> features supported by the hardware and the kernel.
>
> Taking one bit to expose the availability of protection keys to
> applications does not look impossible.
>
> Do I miss something obvious?
No. I am told this is possible aswell.
RP
^ permalink raw reply
* Re: [PATCH 16/17] memremap: change devm_memremap_pages interface to use struct dev_pagemap
From: Christoph Hellwig @ 2017-12-19 15:03 UTC (permalink / raw)
To: Dan Williams
Cc: Christoph Hellwig, Jérôme Glisse, Logan Gunthorpe,
linux-nvdimm@lists.01.org, linuxppc-dev, X86 ML, Linux MM,
linux-kernel@vger.kernel.org
In-Reply-To: <CAPcyv4ixo=A949dN4c=LVc6x+Bdk67ERSO8xR5FQwHnL9mxQAw@mail.gmail.com>
On Sun, Dec 17, 2017 at 10:51:56AM -0800, Dan Williams wrote:
> On Fri, Dec 15, 2017 at 6:09 AM, Christoph Hellwig <hch@lst.de> wrote:
> > From: Logan Gunthorpe <logang@deltatee.com>
> >
> > This new interface is similar to how struct device (and many others)
> > work. The caller initializes a 'struct dev_pagemap' as required
> > and calls 'devm_memremap_pages'. This allows the pagemap structure to
> > be embedded in another structure and thus container_of can be used. In
> > this way application specific members can be stored in a containing
> > struct.
> >
> > This will be used by the P2P infrastructure and HMM could probably
> > be cleaned up to use it as well (instead of having it's own, similar
> > 'hmm_devmem_pages_create' function).
> >
> > Signed-off-by: Logan Gunthorpe <logang@deltatee.com>
> > Signed-off-by: Christoph Hellwig <hch@lst.de>
>
> Looks good, I notice that this does not initialize pgmap->type to
> MEMORY_DEVICE_HOST, but since that value is zero and likely won't
> change we're ok.
I'll add it jut for clarity.
^ permalink raw reply
* Re: [PATCH 14/17] memremap: simplify duplicate region handling in devm_memremap_pages
From: Christoph Hellwig @ 2017-12-19 15:03 UTC (permalink / raw)
To: Dan Williams
Cc: Christoph Hellwig, Jérôme Glisse, Logan Gunthorpe,
linux-nvdimm@lists.01.org, linuxppc-dev, X86 ML, Linux MM,
linux-kernel@vger.kernel.org
In-Reply-To: <CAPcyv4i2naLJjWzm+q0ORRfyHkT0f5dFBFKutuaXE3OgPcHX5g@mail.gmail.com>
On Sun, Dec 17, 2017 at 09:34:11AM -0800, Dan Williams wrote:
> This is not racy, we'll catch the error on insert, and I think the
> extra debug information is useful for debugging a broken memory map or
> alignment math.
We can check for -ЕEXIST and print the warning, but it's a weird pattern
for sure.
^ permalink raw reply
* Re: [PATCH 06/17] mm: pass the vmem_altmap to arch_remove_memory and __remove_pages
From: Christoph Hellwig @ 2017-12-19 15:02 UTC (permalink / raw)
To: Dan Williams
Cc: Christoph Hellwig, Jérôme Glisse, Logan Gunthorpe,
linux-nvdimm@lists.01.org, linuxppc-dev, X86 ML, Linux MM,
linux-kernel@vger.kernel.org
In-Reply-To: <CAPcyv4iNDonroVQy7YFsM-uC_0GMsjQgSBj=ZfdOB-XUK5tsKw@mail.gmail.com>
On Fri, Dec 15, 2017 at 06:04:37PM -0800, Dan Williams wrote:
> On Fri, Dec 15, 2017 at 6:09 AM, Christoph Hellwig <hch@lst.de> wrote:
> > We can just pass this on instead of having to do a radix tree lookup
> > without proper locking 2 levels into the callchain.
> >
> > Signed-off-by: Christoph Hellwig <hch@lst.de>wip
>
> I assume that "wip" is a typo?
It was the description of the patch this got folded into in my
local tree. So basically equivalent to a typo :)
^ permalink raw reply
* [PATCH] KVM: PPC: Book3S HV: Remove vcpu->arch.dec usage
From: Alexander Graf @ 2017-12-19 14:56 UTC (permalink / raw)
To: kvm-ppc; +Cc: linuxppc-dev, linux-kernel, kvm, Paul Mackerras
On Book3S in HV mode, we don't use the vcpu->arch.dec field at all.
Instead, all logic is built around vcpu->arch.dec_expires.
So let's remove the one remaining piece of code that was setting it.
Signed-off-by: Alexander Graf <agraf@suse.de>
---
Looking through the DEC logic, I fail to see any code that allows
save or restore of DEC. Do we maybe miss out on that register for
(live) migration?
---
arch/powerpc/kvm/book3s_hv_rmhandlers.S | 1 -
1 file changed, 1 deletion(-)
diff --git a/arch/powerpc/kvm/book3s_hv_rmhandlers.S b/arch/powerpc/kvm/book3s_hv_rmhandlers.S
index 2659844784b8..c8ffd69adfec 100644
--- a/arch/powerpc/kvm/book3s_hv_rmhandlers.S
+++ b/arch/powerpc/kvm/book3s_hv_rmhandlers.S
@@ -957,7 +957,6 @@ ALT_FTR_SECTION_END_IFCLR(CPU_FTR_ARCH_300)
mftb r7
subf r3,r7,r8
mtspr SPRN_DEC,r3
- std r3,VCPU_DEC(r4)
ld r5, VCPU_SPRG0(r4)
ld r6, VCPU_SPRG1(r4)
--
2.12.3
^ permalink raw reply related
* Re: [PATCH 13/13] ocxl: add MAINTAINERS entry
From: Frederic Barrat @ 2017-12-19 14:39 UTC (permalink / raw)
To: Joe Perches, linuxppc-dev, linux-kernel
Cc: arnd, gregkh, mpe, andrew.donnellan, alastair
In-Reply-To: <1513613052.31581.84.camel@perches.com>
Le 18/12/2017 à 17:04, Joe Perches a écrit :
>> +OCXL (Open Coherent Accelerator Processor Interface OpenCAPI) DRIVER
>> +M: Frederic Barrat<fbarrat@linux.vnet.ibm.com>
>> +M: Andrew Donnellan<andrew.donnellan@au1.ibm.com>
>> +L: linuxppc-dev@lists.ozlabs.org
>> +S: Supported
>> +F: arch/powerpc/platforms/powernv/ocxl.c
>> +F: arch/powerpc/include/asm/pnv-ocxl.h
>> +F: drivers/misc/ocxl/
>> +F: include/misc/ocxl*
>> +F: include/uapi/misc/ocxl.h
>> +F: Documentation/accelerators/ocxl.txt
>> +
> Alphabetic ordering by section header please...
>
> Maybe CXL - OCXL ...
Sure, I'll fix it. Thanks!
Fred
^ permalink raw reply
* Re: [PATCH v2 2/2] powerpc/book3s: Fix TB corruption in guest exit path on HMI interrupt.
From: Alexander Graf @ 2017-12-19 14:35 UTC (permalink / raw)
To: Mahesh J Salgaonkar, linuxppc-dev, Paul Mackerras,
Michael Ellerman
Cc: KVM, KVM-PPC
In-Reply-To: <20160515041426.2280.92697.stgit@mars>
On 05/15/2016 06:14 AM, Mahesh J Salgaonkar wrote:
> From: Mahesh Salgaonkar <mahesh@linux.vnet.ibm.com>
>
> When a guest is assigned to a core it converts the host Timebase (TB)
> into guest TB by adding guest timebase offset before entering into
> guest. During guest exit it restores the guest TB to host TB. This means
> under certain conditions (Guest migration) host TB and guest TB can differ.
>
> When we get an HMI for TB related issues the opal HMI handler would
> try fixing errors and restore the correct host TB value. With no guest
> running, we don't have any issues. But with guest running on the core
> we run into TB corruption issues.
>
> If we get an HMI while in the guest, the current HMI handler invokes opal
> hmi handler before forcing guest to exit. The guest exit path subtracts
> the guest TB offset from the current TB value which may have already
> been restored with host value by opal hmi handler. This leads to incorrect
> host and guest TB values.
>
> With split-core, things become more complex. With split-core, TB also gets
> split and each subcore gets its own TB register. When a hmi handler fixes
> a TB error and restores the TB value, it affects all the TB values of
> sibling subcores on the same core. On TB errors all the thread in the core
> gets HMI. With existing code, the individual threads call opal hmi handle
> independently which can easily throw TB out of sync if we have guest
> running on subcores. Hence we will need to co-ordinate with all the
> threads before making opal hmi handler call followed by TB resync.
>
> This patch introduces a sibling subcore state structure (shared by all
> threads in the core) in paca which holds information about whether sibling
> subcores are in Guest mode or host mode. An array in_guest[] of size
> MAX_SUBCORE_PER_CORE=4 is used to maintain the state of each subcore.
> The subcore id is used as index into in_guest[] array. Only primary
> thread entering/exiting the guest is responsible to set/unset its
> designated array element.
>
> On TB error, we get HMI interrupt on every thread on the core. Upon HMI,
> this patch will now force guest to vacate the core/subcore. Primary
> thread from each subcore will then turn off its respective bit
> from the above bitmap during the guest exit path just after the
> guest->host partition switch is complete.
>
> All other threads that have just exited the guest OR were already in host
> will wait until all other subcores clears their respective bit.
> Once all the subcores turn off their respective bit, all threads will
> will make call to opal hmi handler.
>
> It is not necessary that opal hmi handler would resync the TB value for
> every HMI interrupts. It would do so only for the HMI caused due to
> TB errors. For rest, it would not touch TB value. Hence to make things
> simpler, primary thread would call TB resync explicitly once for each
> core immediately after opal hmi handler instead of subtracting guest
> offset from TB. TB resync call will restore the TB with host value.
> Thus we can be sure about the TB state.
>
> One of the primary threads exiting the guest will take up the
> responsibility of calling TB resync. It will use one of the top bits
> (bit 63) from subcore state flags bitmap to make the decision. The first
> primary thread (among the subcores) that is able to set the bit will
> have to call the TB resync. Rest all other threads will wait until TB
> resync is complete. Once TB resync is complete all threads will then
> proceed.
>
> Signed-off-by: Mahesh Salgaonkar <mahesh@linux.vnet.ibm.com>
> ---
> arch/powerpc/include/asm/hmi.h | 45 ++++++++
> arch/powerpc/include/asm/paca.h | 6 +
> arch/powerpc/kernel/Makefile | 2
> arch/powerpc/kernel/exceptions-64s.S | 4 +
> arch/powerpc/kernel/hmi.c | 56 ++++++++++
> arch/powerpc/kernel/idle_power7.S | 5 +
> arch/powerpc/kernel/traps.c | 5 +
> arch/powerpc/kvm/book3s_hv.c | 37 +++++++
> arch/powerpc/kvm/book3s_hv_ras.c | 176 +++++++++++++++++++++++++++++++
> arch/powerpc/kvm/book3s_hv_rmhandlers.S | 65 +++++++++++
> 10 files changed, 396 insertions(+), 5 deletions(-)
> create mode 100644 arch/powerpc/include/asm/hmi.h
> create mode 100644 arch/powerpc/kernel/hmi.c
>
[...]
> diff --git a/arch/powerpc/kvm/book3s_hv_rmhandlers.S b/arch/powerpc/kvm/book3s_hv_rmhandlers.S
> index e571ad2..0d246fc 100644
> --- a/arch/powerpc/kvm/book3s_hv_rmhandlers.S
> +++ b/arch/powerpc/kvm/book3s_hv_rmhandlers.S
> @@ -29,6 +29,7 @@
> #include <asm/kvm_book3s_asm.h>
> #include <asm/book3s/64/mmu-hash.h>
> #include <asm/tm.h>
> +#include <asm/opal.h>
>
> #define VCPU_GPRS_TM(reg) (((reg) * ULONG_SIZE) + VCPU_GPR_TM)
>
> @@ -373,6 +374,18 @@ kvm_secondary_got_guest:
> lwsync
> std r0, HSTATE_KVM_VCORE(r13)
>
> + /*
> + * All secondaries exiting guest will fall through this path.
> + * Before proceeding, just check for HMI interrupt and
> + * invoke opal hmi handler. By now we are sure that the
> + * primary thread on this core/subcore has already made partition
> + * switch/TB resync and we are good to call opal hmi handler.
> + */
> + cmpwi r12, BOOK3S_INTERRUPT_HMI
> + bne kvm_no_guest
> +
> + li r3,0 /* NULL argument */
> + bl hmi_exception_realmode
> /*
> * At this point we have finished executing in the guest.
> * We need to wait for hwthread_req to become zero, since
> @@ -428,6 +441,22 @@ kvm_no_guest:
> */
> kvm_unsplit_nap:
> /*
> + * When secondaries are napping in kvm_unsplit_nap() with
> + * hwthread_req = 1, HMI goes ignored even though subcores are
> + * already exited the guest. Hence HMI keeps waking up secondaries
> + * from nap in a loop and secondaries always go back to nap since
> + * no vcore is assigned to them. This makes impossible for primary
> + * thread to get hold of secondary threads resulting into a soft
> + * lockup in KVM path.
> + *
> + * Let us check if HMI is pending and handle it before we go to nap.
> + */
> + cmpwi r12, BOOK3S_INTERRUPT_HMI
> + bne 55f
> + li r3, 0 /* NULL argument */
> + bl hmi_exception_realmode
> +55:
> + /*
> * Ensure that secondary doesn't nap when it has
> * its vcore pointer set.
> */
> @@ -601,6 +630,11 @@ BEGIN_FTR_SECTION
> mtspr SPRN_DPDES, r8
> END_FTR_SECTION_IFSET(CPU_FTR_ARCH_207S)
>
> + /* Mark the subcore state as inside guest */
> + bl kvmppc_subcore_enter_guest
> + nop
> + ld r5, HSTATE_KVM_VCORE(r13)
> + ld r4, HSTATE_KVM_VCPU(r13)
> li r0,1
> stb r0,VCORE_IN_GUEST(r5) /* signal secondaries to continue */
>
> @@ -1683,6 +1717,23 @@ BEGIN_FTR_SECTION
> mtspr SPRN_DPDES, r8
> END_FTR_SECTION_IFSET(CPU_FTR_ARCH_207S)
>
> + /* If HMI, call kvmppc_realmode_hmi_handler() */
> + cmpwi r12, BOOK3S_INTERRUPT_HMI
> + bne 27f
> + bl kvmppc_realmode_hmi_handler
> + nop
> + li r12, BOOK3S_INTERRUPT_HMI
> + /*
> + * At this point kvmppc_realmode_hmi_handler would have resync-ed
> + * the TB. Hence it is not required to subtract guest timebase
> + * offset from timebase. So, skip it.
So when an HMI interrupt comes, we may have a broken time base. But we
still use the time base to calculate the TB value at which the host is
supposed to fire DEC on primary as well as secondary threads. Doesn't
that calculation then break, as it's using a bogus TB value?
Alex
^ permalink raw reply
* Re: powerpc64 kernel panic if you disable CONFIG_PPC_TRANSACTIONAL_MEM?
From: Michael Ellerman @ 2017-12-19 13:05 UTC (permalink / raw)
To: Rob Landley, Kernel Mailing List, linuxppc-dev,
Benjamin Herrenschmidt, Paul Mackerras
In-Reply-To: <CAOS_Y6SsUJYjrwc5GM-MpLWudWNVgkESKi4evNPs_JppEdQ8TQ@mail.gmail.com>
Rob Landley <rob@landley.net> writes:
> I just added a ppc64 target to https://github.com/landley/mkroot which
> means I built 4.14 with the attached miniconfig and ran it with the
> attached qemu command line, and it works fine as is but if you remove
> the transactional mem line from the config the kernel panics instead
> of launching a shell prompt:
>
> init[1]: unhandled signal 4 at 0000000010001a04 nip 0000000010001a04
> lr 000000001002ebe8 code 1
> Kernel panic - not syncing: Attempted to kill init! exitcode=0x00000004
>
> CPU: 0 PID: 1 Comm: init Not tainted 4.14.0 #1
> Call Trace:
> [c00000000e02fa40] [c0000000004ba730] dump_stack+0xb0/0xf0 (unreliable)
> [c00000000e02fa80] [c0000000000602a0] panic+0x138/0x2f8
> [c00000000e02fb20] [c00000000006541c] do_exit+0xa9c/0xaa0
> [c00000000e02fbe0] [c0000000000654d8] do_group_exit+0x58/0xf0
> [c00000000e02fc20] [c000000000073274] get_signal+0x1c4/0x6b0
> [c00000000e02fd10] [c0000000000142a0] do_signal+0x60/0x290
> [c00000000e02fe00] [c00000000001461c] do_notify_resume+0x8c/0xd0
> [c00000000e02fe30] [c00000000000b630] ret_from_except_lite+0x5c/0x60
> Rebooting in 1 seconds..
I built it here and got:
init[1]: unhandled signal 4 at 00000000100f3eb4 nip 00000000100f3eb4 lr 00000000100d1e38 code 1
Which looking at objdump is:
00000000100f3eb0 <_savevr_30>:
100f3eb0: e0 ff 80 39 li r12,-32
100f3eb4: ce 01 cc 7f stvx v30,r12,r0
stvx is an ALTIVEC (vmx) instruction, so you need a kernel built with
CONFIG_ALTIVEC.
When you turn on TRANSACTIONAL_MEM it selects ALTIVEC, so that's why
enabling that "fixes" it for you.
If you just add CONFIG_ALTIVEC=y it should work.
cheers
^ permalink raw reply
* Re: [trivial PATCH] treewide: Align function definition open/close braces
From: Mauro Carvalho Chehab @ 2017-12-19 13:04 UTC (permalink / raw)
To: Joe Perches
Cc: Jiri Kosina, Linus Torvalds, linux-kernel, linux-acpi, amd-gfx,
dri-devel, linux-media, MPT-FusionLinux.pdl, linux-scsi, netdev,
linux-wireless, acpi4asus-user, platform-driver-x86, linux-rtc,
linux-fsdevel, ocfs2-devel, linux-xfs, linux-audit, alsa-devel,
linuxppc-dev
In-Reply-To: <1513556924.31581.51.camel@perches.com>
Em Sun, 17 Dec 2017 16:28:44 -0800
Joe Perches <joe@perches.com> escreveu:
> Some functions definitions have either the initial open brace and/or
> the closing brace outside of column 1.
>
> Move those braces to column 1.
>
> This allows various function analyzers like gnu complexity to work
> properly for these modified functions.
>
> Miscellanea:
>
> o Remove extra trailing ; and blank line from xfs_agf_verify
>
> Signed-off-by: Joe Perches <joe@perches.com>
For the media patch:
Acked-by: Mauro Carvalho Chehab <mchehab@s-opensource.com>
> ---
> git diff -w shows no difference other than the above 'Miscellanea'
>
> (this is against -next, but it applies against Linus' tree
> with a couple offsets)
>
> arch/x86/include/asm/atomic64_32.h | 2 +-
> drivers/acpi/custom_method.c | 2 +-
> drivers/acpi/fan.c | 2 +-
> drivers/gpu/drm/amd/display/dc/core/dc.c | 2 +-
> drivers/media/i2c/msp3400-kthreads.c | 2 +-
> drivers/message/fusion/mptsas.c | 2 +-
> drivers/net/ethernet/qlogic/netxen/netxen_nic_init.c | 2 +-
> drivers/net/wireless/ath/ath9k/xmit.c | 2 +-
> drivers/platform/x86/eeepc-laptop.c | 2 +-
> drivers/rtc/rtc-ab-b5ze-s3.c | 2 +-
> drivers/scsi/dpt_i2o.c | 2 +-
> drivers/scsi/sym53c8xx_2/sym_glue.c | 2 +-
> fs/locks.c | 2 +-
> fs/ocfs2/stack_user.c | 2 +-
> fs/xfs/libxfs/xfs_alloc.c | 5 ++---
> fs/xfs/xfs_export.c | 2 +-
> kernel/audit.c | 6 +++---
> kernel/trace/trace_printk.c | 4 ++--
> lib/raid6/sse2.c | 14 +++++++-------
> sound/soc/fsl/fsl_dma.c | 2 +-
> 20 files changed, 30 insertions(+), 31 deletions(-)
>
> diff --git a/arch/x86/include/asm/atomic64_32.h b/arch/x86/include/asm/atomic64_32.h
> index 97c46b8169b7..d4d4883080fa 100644
> --- a/arch/x86/include/asm/atomic64_32.h
> +++ b/arch/x86/include/asm/atomic64_32.h
> @@ -122,7 +122,7 @@ static inline long long atomic64_read(const atomic64_t *v)
> long long r;
> alternative_atomic64(read, "=&A" (r), "c" (v) : "memory");
> return r;
> - }
> +}
>
> /**
> * atomic64_add_return - add and return
> diff --git a/drivers/acpi/custom_method.c b/drivers/acpi/custom_method.c
> index c68e72414a67..e967c1173ba3 100644
> --- a/drivers/acpi/custom_method.c
> +++ b/drivers/acpi/custom_method.c
> @@ -94,7 +94,7 @@ static void __exit acpi_custom_method_exit(void)
> {
> if (cm_dentry)
> debugfs_remove(cm_dentry);
> - }
> +}
>
> module_init(acpi_custom_method_init);
> module_exit(acpi_custom_method_exit);
> diff --git a/drivers/acpi/fan.c b/drivers/acpi/fan.c
> index 6cf4988206f2..3563103590c6 100644
> --- a/drivers/acpi/fan.c
> +++ b/drivers/acpi/fan.c
> @@ -219,7 +219,7 @@ fan_set_cur_state(struct thermal_cooling_device *cdev, unsigned long state)
> return fan_set_state_acpi4(device, state);
> else
> return fan_set_state(device, state);
> - }
> +}
>
> static const struct thermal_cooling_device_ops fan_cooling_ops = {
> .get_max_state = fan_get_max_state,
> diff --git a/drivers/gpu/drm/amd/display/dc/core/dc.c b/drivers/gpu/drm/amd/display/dc/core/dc.c
> index d1488d5ee028..1e0d1e7c5324 100644
> --- a/drivers/gpu/drm/amd/display/dc/core/dc.c
> +++ b/drivers/gpu/drm/amd/display/dc/core/dc.c
> @@ -461,7 +461,7 @@ static void disable_dangling_plane(struct dc *dc, struct dc_state *context)
> ******************************************************************************/
>
> struct dc *dc_create(const struct dc_init_data *init_params)
> - {
> +{
> struct dc *dc = kzalloc(sizeof(*dc), GFP_KERNEL);
> unsigned int full_pipe_count;
>
> diff --git a/drivers/media/i2c/msp3400-kthreads.c b/drivers/media/i2c/msp3400-kthreads.c
> index 4dd01e9f553b..dc6cb8d475b3 100644
> --- a/drivers/media/i2c/msp3400-kthreads.c
> +++ b/drivers/media/i2c/msp3400-kthreads.c
> @@ -885,7 +885,7 @@ static int msp34xxg_modus(struct i2c_client *client)
> }
>
> static void msp34xxg_set_source(struct i2c_client *client, u16 reg, int in)
> - {
> +{
> struct msp_state *state = to_state(i2c_get_clientdata(client));
> int source, matrix;
>
> diff --git a/drivers/message/fusion/mptsas.c b/drivers/message/fusion/mptsas.c
> index 345f6035599e..69a62d23514b 100644
> --- a/drivers/message/fusion/mptsas.c
> +++ b/drivers/message/fusion/mptsas.c
> @@ -2968,7 +2968,7 @@ mptsas_exp_repmanufacture_info(MPT_ADAPTER *ioc,
> mutex_unlock(&ioc->sas_mgmt.mutex);
> out:
> return ret;
> - }
> +}
>
> static void
> mptsas_parse_device_info(struct sas_identify *identify,
> diff --git a/drivers/net/ethernet/qlogic/netxen/netxen_nic_init.c b/drivers/net/ethernet/qlogic/netxen/netxen_nic_init.c
> index 3dd973475125..0ea141ece19e 100644
> --- a/drivers/net/ethernet/qlogic/netxen/netxen_nic_init.c
> +++ b/drivers/net/ethernet/qlogic/netxen/netxen_nic_init.c
> @@ -603,7 +603,7 @@ static struct uni_table_desc *nx_get_table_desc(const u8 *unirom, int section)
>
> static int
> netxen_nic_validate_header(struct netxen_adapter *adapter)
> - {
> +{
> const u8 *unirom = adapter->fw->data;
> struct uni_table_desc *directory = (struct uni_table_desc *) &unirom[0];
> u32 fw_file_size = adapter->fw->size;
> diff --git a/drivers/net/wireless/ath/ath9k/xmit.c b/drivers/net/wireless/ath/ath9k/xmit.c
> index bd438062a6db..baedc7186b10 100644
> --- a/drivers/net/wireless/ath/ath9k/xmit.c
> +++ b/drivers/net/wireless/ath/ath9k/xmit.c
> @@ -196,7 +196,7 @@ ath_tid_pull(struct ath_atx_tid *tid)
> }
>
> return skb;
> - }
> +}
>
> static struct sk_buff *ath_tid_dequeue(struct ath_atx_tid *tid)
> {
> diff --git a/drivers/platform/x86/eeepc-laptop.c b/drivers/platform/x86/eeepc-laptop.c
> index 5a681962899c..4c38904a8a32 100644
> --- a/drivers/platform/x86/eeepc-laptop.c
> +++ b/drivers/platform/x86/eeepc-laptop.c
> @@ -492,7 +492,7 @@ static void eeepc_platform_exit(struct eeepc_laptop *eeepc)
> * potentially bad time, such as a timer interrupt.
> */
> static void tpd_led_update(struct work_struct *work)
> - {
> +{
> struct eeepc_laptop *eeepc;
>
> eeepc = container_of(work, struct eeepc_laptop, tpd_led_work);
> diff --git a/drivers/rtc/rtc-ab-b5ze-s3.c b/drivers/rtc/rtc-ab-b5ze-s3.c
> index a319bf1e49de..ef5c16dfabfa 100644
> --- a/drivers/rtc/rtc-ab-b5ze-s3.c
> +++ b/drivers/rtc/rtc-ab-b5ze-s3.c
> @@ -648,7 +648,7 @@ static int abb5zes3_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alarm)
> ret);
>
> return ret;
> - }
> +}
>
> /* Enable or disable battery low irq generation */
> static inline int _abb5zes3_rtc_battery_low_irq_enable(struct regmap *regmap,
> diff --git a/drivers/scsi/dpt_i2o.c b/drivers/scsi/dpt_i2o.c
> index fd172b0890d3..a00d822e3142 100644
> --- a/drivers/scsi/dpt_i2o.c
> +++ b/drivers/scsi/dpt_i2o.c
> @@ -3524,7 +3524,7 @@ static int adpt_i2o_systab_send(adpt_hba* pHba)
> #endif
>
> return ret;
> - }
> +}
>
>
> /*============================================================================
> diff --git a/drivers/scsi/sym53c8xx_2/sym_glue.c b/drivers/scsi/sym53c8xx_2/sym_glue.c
> index 791a2182de53..7320d5fe4cbc 100644
> --- a/drivers/scsi/sym53c8xx_2/sym_glue.c
> +++ b/drivers/scsi/sym53c8xx_2/sym_glue.c
> @@ -1393,7 +1393,7 @@ static struct Scsi_Host *sym_attach(struct scsi_host_template *tpnt, int unit,
> scsi_host_put(shost);
>
> return NULL;
> - }
> +}
>
>
> /*
> diff --git a/fs/locks.c b/fs/locks.c
> index 21b4dfa289ee..d2399d001afe 100644
> --- a/fs/locks.c
> +++ b/fs/locks.c
> @@ -559,7 +559,7 @@ static const struct lock_manager_operations lease_manager_ops = {
> * Initialize a lease, use the default lock manager operations
> */
> static int lease_init(struct file *filp, long type, struct file_lock *fl)
> - {
> +{
> if (assign_type(fl, type) != 0)
> return -EINVAL;
>
> diff --git a/fs/ocfs2/stack_user.c b/fs/ocfs2/stack_user.c
> index dae9eb7c441e..d2fb97b173da 100644
> --- a/fs/ocfs2/stack_user.c
> +++ b/fs/ocfs2/stack_user.c
> @@ -398,7 +398,7 @@ static int ocfs2_control_do_setnode_msg(struct file *file,
>
> static int ocfs2_control_do_setversion_msg(struct file *file,
> struct ocfs2_control_message_setv *msg)
> - {
> +{
> long major, minor;
> char *ptr = NULL;
> struct ocfs2_control_private *p = file->private_data;
> diff --git a/fs/xfs/libxfs/xfs_alloc.c b/fs/xfs/libxfs/xfs_alloc.c
> index 0da80019a917..217108f765d5 100644
> --- a/fs/xfs/libxfs/xfs_alloc.c
> +++ b/fs/xfs/libxfs/xfs_alloc.c
> @@ -2401,7 +2401,7 @@ static bool
> xfs_agf_verify(
> struct xfs_mount *mp,
> struct xfs_buf *bp)
> - {
> +{
> struct xfs_agf *agf = XFS_BUF_TO_AGF(bp);
>
> if (xfs_sb_version_hascrc(&mp->m_sb)) {
> @@ -2449,8 +2449,7 @@ xfs_agf_verify(
> be32_to_cpu(agf->agf_refcount_level) > XFS_BTREE_MAXLEVELS))
> return false;
>
> - return true;;
> -
> + return true;
> }
>
> static void
> diff --git a/fs/xfs/xfs_export.c b/fs/xfs/xfs_export.c
> index fe1bfee35898..7d5c355d78b5 100644
> --- a/fs/xfs/xfs_export.c
> +++ b/fs/xfs/xfs_export.c
> @@ -122,7 +122,7 @@ xfs_nfs_get_inode(
> struct super_block *sb,
> u64 ino,
> u32 generation)
> - {
> +{
> xfs_mount_t *mp = XFS_M(sb);
> xfs_inode_t *ip;
> int error;
> diff --git a/kernel/audit.c b/kernel/audit.c
> index 227db99b0f19..d97e8f0f73ca 100644
> --- a/kernel/audit.c
> +++ b/kernel/audit.c
> @@ -443,15 +443,15 @@ static int audit_set_failure(u32 state)
> * Drop any references inside the auditd connection tracking struct and free
> * the memory.
> */
> - static void auditd_conn_free(struct rcu_head *rcu)
> - {
> +static void auditd_conn_free(struct rcu_head *rcu)
> +{
> struct auditd_connection *ac;
>
> ac = container_of(rcu, struct auditd_connection, rcu);
> put_pid(ac->pid);
> put_net(ac->net);
> kfree(ac);
> - }
> +}
>
> /**
> * auditd_set - Set/Reset the auditd connection state
> diff --git a/kernel/trace/trace_printk.c b/kernel/trace/trace_printk.c
> index ad1d6164e946..50f44b7b2b32 100644
> --- a/kernel/trace/trace_printk.c
> +++ b/kernel/trace/trace_printk.c
> @@ -196,7 +196,7 @@ struct notifier_block module_trace_bprintk_format_nb = {
> };
>
> int __trace_bprintk(unsigned long ip, const char *fmt, ...)
> - {
> +{
> int ret;
> va_list ap;
>
> @@ -214,7 +214,7 @@ int __trace_bprintk(unsigned long ip, const char *fmt, ...)
> EXPORT_SYMBOL_GPL(__trace_bprintk);
>
> int __ftrace_vbprintk(unsigned long ip, const char *fmt, va_list ap)
> - {
> +{
> if (unlikely(!fmt))
> return 0;
>
> diff --git a/lib/raid6/sse2.c b/lib/raid6/sse2.c
> index 1d2276b007ee..8191e1d0d2fb 100644
> --- a/lib/raid6/sse2.c
> +++ b/lib/raid6/sse2.c
> @@ -91,7 +91,7 @@ static void raid6_sse21_gen_syndrome(int disks, size_t bytes, void **ptrs)
>
> static void raid6_sse21_xor_syndrome(int disks, int start, int stop,
> size_t bytes, void **ptrs)
> - {
> +{
> u8 **dptr = (u8 **)ptrs;
> u8 *p, *q;
> int d, z, z0;
> @@ -200,9 +200,9 @@ static void raid6_sse22_gen_syndrome(int disks, size_t bytes, void **ptrs)
> kernel_fpu_end();
> }
>
> - static void raid6_sse22_xor_syndrome(int disks, int start, int stop,
> +static void raid6_sse22_xor_syndrome(int disks, int start, int stop,
> size_t bytes, void **ptrs)
> - {
> +{
> u8 **dptr = (u8 **)ptrs;
> u8 *p, *q;
> int d, z, z0;
> @@ -265,7 +265,7 @@ static void raid6_sse22_gen_syndrome(int disks, size_t bytes, void **ptrs)
>
> asm volatile("sfence" : : : "memory");
> kernel_fpu_end();
> - }
> +}
>
> const struct raid6_calls raid6_sse2x2 = {
> raid6_sse22_gen_syndrome,
> @@ -366,9 +366,9 @@ static void raid6_sse24_gen_syndrome(int disks, size_t bytes, void **ptrs)
> kernel_fpu_end();
> }
>
> - static void raid6_sse24_xor_syndrome(int disks, int start, int stop,
> +static void raid6_sse24_xor_syndrome(int disks, int start, int stop,
> size_t bytes, void **ptrs)
> - {
> +{
> u8 **dptr = (u8 **)ptrs;
> u8 *p, *q;
> int d, z, z0;
> @@ -471,7 +471,7 @@ static void raid6_sse24_gen_syndrome(int disks, size_t bytes, void **ptrs)
> }
> asm volatile("sfence" : : : "memory");
> kernel_fpu_end();
> - }
> +}
>
>
> const struct raid6_calls raid6_sse2x4 = {
> diff --git a/sound/soc/fsl/fsl_dma.c b/sound/soc/fsl/fsl_dma.c
> index 0c11f434a374..ec619f51d336 100644
> --- a/sound/soc/fsl/fsl_dma.c
> +++ b/sound/soc/fsl/fsl_dma.c
> @@ -879,7 +879,7 @@ static const struct snd_pcm_ops fsl_dma_ops = {
> };
>
> static int fsl_soc_dma_probe(struct platform_device *pdev)
> - {
> +{
> struct dma_object *dma;
> struct device_node *np = pdev->dev.of_node;
> struct device_node *ssi_np;
>
Thanks,
Mauro
^ permalink raw reply
* Re: [net] Revert "net: core: maybe return -EEXIST in __dev_alloc_name"
From: Michael Ellerman @ 2017-12-19 12:28 UTC (permalink / raw)
To: Johannes Berg
Cc: netdev@vger.kernel.org, Jouni Malinen, Rasmus Villemoes,
Johannes Berg, linuxppc-dev@lists.ozlabs.org
In-Reply-To: <20171202074155.29146-1-johannes@sipsolutions.net>
Hi Johannes,
> From: Johannes Berg <johannes.berg@intel.com>
>
> This reverts commit d6f295e9def0; some userspace (in the case
> we noticed it's wpa_supplicant), is relying on the current
> error code to determine that a fixed name interface already
> exists.
>
> Reported-by: Jouni Malinen <j@w1.fi>
> Signed-off-by: Johannes Berg <johannes.berg@intel.com>
> ---
> net/core/dev.c | 2 +-
> 1 file changed, 1 insertion(+), 1 deletion(-)
This revert seems to have broken networking on one of my powerpc
machines, according to git bisect.
The symptom is DHCP fails and I don't get a link, I didn't dig any
further than that. I can if it's helpful.
I think the problem is that 87c320e51519 ("net: core: dev_get_valid_name
is now the same as dev_alloc_name_ns") only makes sense while
d6f295e9def0 remains in the tree.
ie. before the entire series, dev_get_valid_name() would return EEXIST,
and that was retained when 87c320e51519 was merged, but now that
d6f295e9def0 has been reverted dev_get_valid_name() is returning ENFILE.
I can get the network up again if I also revert 87c320e51519 ("net:
core: dev_get_valid_name is now the same as dev_alloc_name_ns"), or with
the gross patch below.
cheers
diff --git a/net/core/dev.c b/net/core/dev.c
index f47e96b62308..d0304461ad32 100644
--- a/net/core/dev.c
+++ b/net/core/dev.c
@@ -1146,7 +1146,11 @@ EXPORT_SYMBOL(dev_alloc_name);
int dev_get_valid_name(struct net *net, struct net_device *dev,
const char *name)
{
- return dev_alloc_name_ns(net, dev, name);
+ int rc = dev_alloc_name_ns(net, dev, name);
+ if (rc == -ENFILE)
+ rc = -EEXIST;
+
+ return rc;
}
EXPORT_SYMBOL(dev_get_valid_name);
^ permalink raw reply related
* Re: [PATCH V4 02/26] powerpc/PCI: deprecate pci_get_bus_and_slot()
From: Sinan Kaya @ 2017-12-19 12:24 UTC (permalink / raw)
To: Michael Ellerman, linux-pci, timur
Cc: linux-arm-msm, linux-arm-kernel, Benjamin Herrenschmidt,
Paul Mackerras, Tyrel Datwyler, Rob Herring, Bhumika Goyal,
open list:LINUX FOR POWERPC (32-BIT AND 64-BIT), open list
In-Reply-To: <87fu879fki.fsf@concordia.ellerman.id.au>
On 12/19/2017 5:29 AM, Michael Ellerman wrote:
> Sinan Kaya <okaya@codeaurora.org> writes:
>
>> pci_get_bus_and_slot() is restrictive such that it assumes domain=0 as
>> where a PCI device is present. This restricts the device drivers to be
>> reused for other domain numbers.
>>
>> Getting ready to remove pci_get_bus_and_slot() function in favor of
>> pci_get_domain_bus_and_slot().
>>
>> Use pci_get_domain_bus_and_slot() with a domain number of 0 as the code
>> is not ready to consume multiple domains and existing code used domain
>> number 0.
>>
>> Signed-off-by: Sinan Kaya <okaya@codeaurora.org>
>> ---
>> arch/powerpc/kernel/pci_32.c | 3 ++-
>> arch/powerpc/platforms/powermac/feature.c | 2 +-
>> arch/powerpc/sysdev/mv64x60_pci.c | 4 ++--
>> 3 files changed, 5 insertions(+), 4 deletions(-)
>
> Looks to do what it says. I don't know if any of these call sites could
> be improved to provide the domain, but that's not really your problem.
>
I tried to fix the places where I can at the rest of the series. I even took
a stab at fixing powerpc. There were places where the domain information was
not available and I couldn't locate where to extract it. I decided to leave it
as it is and hope that someone someday may expand the powerpc PCI adaptation.
> Acked-by: Michael Ellerman <mpe@ellerman.id.au> (powerpc)
>
> cheers
>
--
Sinan Kaya
Qualcomm Datacenter Technologies, Inc. as an affiliate of Qualcomm Technologies, Inc.
Qualcomm Technologies, Inc. is a member of the Code Aurora Forum, a Linux Foundation Collaborative Project.
^ permalink raw reply
* Re: [PATCH] On ppc64le we HAVE_RELIABLE_STACKTRACE
From: Torsten Duwe @ 2017-12-19 11:28 UTC (permalink / raw)
To: Josh Poimboeuf
Cc: Nicholas Piggin, linux-kernel, Jiri Kosina, live-patching,
linuxppc-dev
In-Reply-To: <20171218185622.rgoyy5doyh3gyqh5@treble>
On Mon, Dec 18, 2017 at 12:56:22PM -0600, Josh Poimboeuf wrote:
> On Mon, Dec 18, 2017 at 03:33:34PM +1000, Nicholas Piggin wrote:
> > On Sun, 17 Dec 2017 20:58:54 -0600
> > Josh Poimboeuf <jpoimboe@redhat.com> wrote:
> >
> > > On Fri, Dec 15, 2017 at 07:40:09PM +1000, Nicholas Piggin wrote:
> > > > On Tue, 12 Dec 2017 08:05:01 -0600
> > > > Josh Poimboeuf <jpoimboe@redhat.com> wrote:
> > > >
> > > > > What about leaf functions? If a leaf function doesn't establish a stack
> > > > > frame, and it has inline asm which contains a blr to another function,
> > > > > this ABI is broken.
> > >
> > > Oops, I meant to say "bl" instead of "blr".
You need to save LR, one way or the other. If gcc thinks it's a leaf function and
does not do it, nor does your asm code, you'll return in an endless loop => bug.
> > > > > Also, even for non-leaf functions, is it possible for GCC to insert the
> > > > > inline asm before it sets up the stack frame? (This is an occasional
> > > > > problem on x86.)
> > > >
> > > > Inline asm must not have control transfer out of the statement unless
> > > > it is asm goto.
> > >
> > > Can inline asm have calls to other functions?
> >
> > I don't believe so.
>
> It's allowed on x86, I don't see why it wouldn't be allowed on powerpc.
> As you mentioned, GCC doesn't pay attention to what's inside asm("").
>
> > > > > Also, what about hand-coded asm?
> > > >
> > > > Should follow the same rules if it uses the stack.
> > >
> > > How is that enforced?
> >
> > It's not, AFAIK. Gcc doesn't understand what's inside asm("").
>
> Here I was talking about .S files.
asm("") or .S ... the ABI spec is clear, and it's quite easy to follow. You
need a place to save LR before you call another function, and STDU is so
convenient to create a stack frame with a single instruction.
My impression is one would have to be very determined to break the ABI
deliberately.
> > > > > In addition to fixing the above issues, the unwinder also needs to
> > > > > detect interrupts (i.e., preemption) and page faults on the stack of a
> > > > > blocked task. If a function were preempted before it created a stack
> > > > > frame, or if a leaf function blocked on a page fault, the stack trace
> > > > > will skip the function's caller, so such a trace will need to be
> > > > > reported to livepatch as unreliable.
> > > >
> > > > I don't think there is much problem there for powerpc. Stack frame
> > > > creation and function call with return pointer are each atomic.
> > >
> > > What if the function is interrupted before it creates the stack frame?
There should be a pt_regs that shows exactly this situation, see below.
> > Then there will be no stack frame, but you still get the caller address
> > because it's saved in LR register as part of the function call. Then
> > you get the caller's caller in its stack frame.
>
> Ok. So what about the interrupted function itself? Looking at the
> powerpc version of save_context_stack(), it doesn't do anything special
> for exception frames like checking regs->nip.
>
> Though it looks like that should be possible since show_stack() has a
> way to identify exception frames.
IIRC x86 errors out if a task was interrupted in kernel context. PPC
save_stack_trace_tsk_reliable() could do the same.
Would that be sufficient?
Torsten
^ permalink raw reply
* Re: [PATCH] PCI: Add #defines for Completion Timeout Disable feature
From: Michael Ellerman @ 2017-12-19 11:24 UTC (permalink / raw)
To: Bjorn Helgaas, linux-pci
Cc: Benjamin Herrenschmidt, linuxppc-dev, Paul Mackerras,
Russell Currey
In-Reply-To: <20171215225711.176712.65146.stgit@bhelgaas-glaptop.roam.corp.google.com>
Bjorn Helgaas <helgaas@kernel.org> writes:
> From: Bjorn Helgaas <bhelgaas@google.com>
>
> Add #defines for the Completion Timeout Disable feature and use them. No
> functional change intended.
>
> Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
> ---
> arch/powerpc/platforms/powernv/eeh-powernv.c | 6 +++---
> include/uapi/linux/pci_regs.h | 2 ++
> 2 files changed, 5 insertions(+), 3 deletions(-)
LGTM.
Acked-by: Michael Ellerman <mpe@ellerman.id.au>
cheers
^ permalink raw reply
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox