Re: [PATCH] KVM: PPC: Book3S HV: Fix pending_pri value in kvmppc_xive_get_icp()

2017-12-12 Thread Benjamin Herrenschmidt
On Tue, 2017-12-12 at 18:23 +0100, Laurent Vivier wrote:
> When we migrate a VM from a POWER8 host (XICS) to a POWER9 host
> (XICS-on-XIVE), we have an error:
> 
> qemu-kvm: Unable to restore KVM interrupt controller state \
>   (0xff00) for CPU 0: Invalid argument
> 
> This is because kvmppc_xics_set_icp() checks the new state
> is internaly consistent, and especially:
> 
> ...
>1129 if (xisr == 0) {
>1130 if (pending_pri != 0xff)
>1131 return -EINVAL;
> ...
> 
> On the other side, kvmppc_xive_get_icp() doesn't set
> neither the pending_pri value, nor the xisr value (set to 0)
> (and kvmppc_xive_set_icp() ignores the pending_pri value)
> 
> As xisr is 0, pending_pri must be set to 0xff.
> 
> Signed-off-by: Laurent Vivier 

Acked-by: Benjamin Herrenschmidt 



[PATCH] KVM: PPC: Book3S HV: Fix pending_pri value in kvmppc_xive_get_icp()

2017-12-12 Thread Laurent Vivier
When we migrate a VM from a POWER8 host (XICS) to a POWER9 host
(XICS-on-XIVE), we have an error:

qemu-kvm: Unable to restore KVM interrupt controller state \
  (0xff00) for CPU 0: Invalid argument

This is because kvmppc_xics_set_icp() checks the new state
is internaly consistent, and especially:

...
   1129 if (xisr == 0) {
   1130 if (pending_pri != 0xff)
   1131 return -EINVAL;
...

On the other side, kvmppc_xive_get_icp() doesn't set
neither the pending_pri value, nor the xisr value (set to 0)
(and kvmppc_xive_set_icp() ignores the pending_pri value)

As xisr is 0, pending_pri must be set to 0xff.

Signed-off-by: Laurent Vivier 
---
 arch/powerpc/kvm/book3s_xive.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/arch/powerpc/kvm/book3s_xive.c b/arch/powerpc/kvm/book3s_xive.c
index bf457843e032..e79062573f8c 100644
--- a/arch/powerpc/kvm/book3s_xive.c
+++ b/arch/powerpc/kvm/book3s_xive.c
@@ -725,7 +725,8 @@ u64 kvmppc_xive_get_icp(struct kvm_vcpu *vcpu)
 
/* Return the per-cpu state for state saving/migration */
return (u64)xc->cppr << KVM_REG_PPC_ICP_CPPR_SHIFT |
-  (u64)xc->mfrr << KVM_REG_PPC_ICP_MFRR_SHIFT;
+  (u64)xc->mfrr << KVM_REG_PPC_ICP_MFRR_SHIFT |
+  (u64)0xff << KVM_REG_PPC_ICP_PPRI_SHIFT;
 }
 
 int kvmppc_xive_set_icp(struct kvm_vcpu *vcpu, u64 icpval)
-- 
2.14.3



Re: Getting kernel 4.14 to run on PS3

2017-12-12 Thread Geoff Levand
Hi Nathan,

On 12/08/2017 01:25 PM, Nathan Whitehorn wrote:
> I submitted patches to libfdt that resolve this particular ABI breakage 
> yesterday. If the patch gets merged, newer kernels should become bootable 
> again.

Here's the link:

  https://github.com/dgibson/dtc/pull/12 (Add limited read-only support for 
older (V2 and V3) device tree to libfdt.)

I rebased your patch and have it in my ps3-queue
branch, but my ps3 with ps3-petitboot-09.11.30 still
would not boot with it.  I didn't spend any time yet
to look into why.

  
https://git.kernel.org/pub/scm/linux/kernel/git/geoff/ps3-linux.git/log/?h=ps3-queue

-Geoff


Re: [PATCH 00/10] ASoC: fsl_ssi: Clean up - coding style level

2017-12-12 Thread Nicolin Chen
On Mon, Dec 04, 2017 at 12:46:33PM -0800, Nicolin Chen wrote:

> Nicolin Chen (10):
>   ASoC: fsl_ssi: Remove unused struct device
>   ASoC: fsl_ssi: Rename fsl_ssi_private to fsl_ssi
>   ASoC: fsl_ssi: Cache pdev->dev pointer
>   ASoC: fsl_ssi: Refine all comments
>   ASoC: fsl_ssi: Rename registers and fields macros
>   ASoC: fsl_ssi: Refine indentations and wrappings
>   ASoC: fsl_ssi: Refine printk outputs
>   ASoC: fsl_ssi: Rename cpu_dai parameter to dai
>   ASoC: fsl_ssi: Rename scr_val to scr
>   ASoC: fsl_ssi: Replace fsl_ssi_rxtx_reg_val with fsl_ssi_regvals

Have revised some comments at one of patches and rebased the rest.
Will send v2 tonight. So let's ignore this version for now. Thanks


[PATCH v2] platform/powernv: Add debugfs interface for imc-mode and imc-command

2017-12-12 Thread Anju T Sudhakar
In memory Collection (IMC) counter pmu driver controls the ucode's execution
state. At the system boot, IMC perf driver pause the ucode. Ucode state is
changed to "running" only when any of the nest units are monitored or profiled
using perf tool.  

Nest units support only limited set of hardware counters and ucode is always
programmed in the "production mode" ("accumulation") mode. This mode is
configured to provide key performance metric data for most of the nest units.   
  

But ucode also supports other modes which would be used for "debug" to drill
down specific nest units. That is, ucode when switched to "powerbus" debug  
mode (for example), will dynamically reconfigure the nest counters to target
only "powerbus" related events in the hardware counters. This allows the IMC
nest unit to focus on powerbus related transactions in the system in more
detail. At this point, production mode events may or may not be counted.
  

IMC nest counters has both in-band (ucode access) and out of band access to it. 
Since not all nest counter configurations are supported by ucode, out of band   
tools are used to characterize other nest counter configurations.   

Patch provides an interface via "debugfs" to enable the switching of ucode
modes in the system. To switch ucode mode, one has to first pause the microcode 
(imc_cmd), and then write the target mode value to the "imc_mode" file. 
  

Proposed Approach   
=== 

In the proposed approach, the function (export_imc_mode_and_cmd) which creates  
 
the debugfs interface for imc mode and command is implemented in opal-imc.c.
Thus we can use imc_get_mem_addr() to get the homer base address for each chip. 

The interface to expose imc mode and command is required only if we have nest
pmu units registered. Employing the existing data structures to track whether
we have any nest units registered will require to extend data from perf side
to opal-imc.c. Instead an integer is introduced to hold that information by
counting successful nest unit registration. Debugfs interface is removed
based on the integer count.   

Example for the interface:  

root@:/sys/kernel/debug/imc# ls 
imc_cmd_0  imc_cmd_8  imc_mode_0  imc_mode_8   

Changes from v1 -> v2
- The latest commit by Rajarshi Das adds the control block offset in the   
  ima-catalog file. So if there is cb_offset specified in the   
  ima-catalog, that is used to export the imc mode/command, otherwise   
  IMC_CNTL_BLK_OFFSET is used. 

Signed-off-by: Anju T Sudhakar 
---
 arch/powerpc/include/asm/imc-pmu.h|  7 +++
 arch/powerpc/platforms/powernv/opal-imc.c | 77 +++
 2 files changed, 84 insertions(+)

diff --git a/arch/powerpc/include/asm/imc-pmu.h 
b/arch/powerpc/include/asm/imc-pmu.h
index fad0e6f..e760401 100644
--- a/arch/powerpc/include/asm/imc-pmu.h
+++ b/arch/powerpc/include/asm/imc-pmu.h
@@ -35,6 +35,13 @@
 #define THREAD_IMC_ENABLE   0x8000ULL
 
 /*
+ * For debugfs interface for imc-mode and imc-command
+ */
+#define IMC_CNTL_BLK_OFFSET0x3FC00
+#define IMC_CNTL_BLK_CMD_OFFSET8
+#define IMC_CNTL_BLK_MODE_OFFSET   32
+
+/*
  * Structure to hold memory address information for imc units.
  */
 struct imc_mem_info {
diff --git a/arch/powerpc/platforms/powernv/opal-imc.c 
b/arch/powerpc/platforms/powernv/opal-imc.c
index 465ea10..dd4c9b8 100644
--- a/arch/powerpc/platforms/powernv/opal-imc.c
+++ b/arch/powerpc/platforms/powernv/opal-imc.c
@@ -21,6 +21,78 @@
 #include 
 #include 
 #include 
+#include 
+
+static struct dentry *imc_debugfs_parent;
+
+/* Helpers to export imc command and mode via debugfs */
+static int imc_mem_get(void *data, u64 *val)
+{
+   *val = cpu_to_be64(*(u64 *)data);
+   return 0;
+}
+
+static int 

[PATCH v2 00/11] ASoC: fsl_ssi: Clean up - coding style level

2017-12-12 Thread Nicolin Chen
==Changelog==
v1->v2
 * Dropped one patch to remove "struct device"
 * Revised PATCH-03 "Refine all comments"
 * Revised PATCH-05 "Refine indentations and wrappings"
 * Rebased all other patches
 * Added PATCH-10 "Rename i2smode to i2s_net"
 * Added PATCH-11 "Define ternary macros to simplify code"

 # Detialed changes are described in each updated patch.

==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 first set to clean up fsl_ssi driver
in the coding style level. Any patch here is not supposed to change
the program flow.

==Verification==
Theoretically, since these patches do not change program flow, they
only need code review, build or sanity tests. I have done build and
sanity tests on an i.MX6SoloX with WM8962 using imx_v6_v7_defconfig
and playback/record tests in I2S Master/Slave modes.

Nicolin Chen (11):
  ASoC: fsl_ssi: Rename fsl_ssi_private to fsl_ssi
  ASoC: fsl_ssi: Cache pdev->dev pointer
  ASoC: fsl_ssi: Refine all comments
  ASoC: fsl_ssi: Rename registers and fields macros
  ASoC: fsl_ssi: Refine indentations and wrappings
  ASoC: fsl_ssi: Refine printk outputs
  ASoC: fsl_ssi: Rename cpu_dai parameter to dai
  ASoC: fsl_ssi: Rename scr_val to scr
  ASoC: fsl_ssi: Replace fsl_ssi_rxtx_reg_val with fsl_ssi_regvals
  ASoC: fsl_ssi: Rename i2smode to i2s_net
  ASoC: fsl_ssi: Define ternary macros to simplify code

 sound/soc/fsl/fsl_ssi.c | 1373 +++
 sound/soc/fsl/fsl_ssi.h |  427 --
 sound/soc/fsl/fsl_ssi_dbg.c |   59 +-
 3 files changed, 876 insertions(+), 983 deletions(-)

-- 
2.7.4



[PATCH v2 01/11] ASoC: fsl_ssi: Rename fsl_ssi_private to fsl_ssi

2017-12-12 Thread Nicolin Chen
Shorten the private data structure to save some wrapped lines.

Signed-off-by: Nicolin Chen 
---
 sound/soc/fsl/fsl_ssi.c | 456 +++-
 1 file changed, 220 insertions(+), 236 deletions(-)

diff --git a/sound/soc/fsl/fsl_ssi.c b/sound/soc/fsl/fsl_ssi.c
index c350117..84d2f7e 100644
--- a/sound/soc/fsl/fsl_ssi.c
+++ b/sound/soc/fsl/fsl_ssi.c
@@ -185,7 +185,7 @@ struct fsl_ssi_soc_data {
 };
 
 /**
- * fsl_ssi_private: per-SSI private data
+ * fsl_ssi: per-SSI private data
  *
  * @reg: Pointer to the regmap registers
  * @irq: IRQ of this SSI
@@ -224,7 +224,7 @@ struct fsl_ssi_soc_data {
  * @dma_maxburst: max number of words to transfer in one go.  So far,
  * this is always the same as fifo_watermark.
  */
-struct fsl_ssi_private {
+struct fsl_ssi {
struct regmap *regs;
int irq;
struct snd_soc_dai_driver cpu_dai_drv;
@@ -325,21 +325,21 @@ static const struct of_device_id fsl_ssi_ids[] = {
 };
 MODULE_DEVICE_TABLE(of, fsl_ssi_ids);
 
-static bool fsl_ssi_is_ac97(struct fsl_ssi_private *ssi_private)
+static bool fsl_ssi_is_ac97(struct fsl_ssi *ssi)
 {
-   return (ssi_private->dai_fmt & SND_SOC_DAIFMT_FORMAT_MASK) ==
+   return (ssi->dai_fmt & SND_SOC_DAIFMT_FORMAT_MASK) ==
SND_SOC_DAIFMT_AC97;
 }
 
-static bool fsl_ssi_is_i2s_master(struct fsl_ssi_private *ssi_private)
+static bool fsl_ssi_is_i2s_master(struct fsl_ssi *ssi)
 {
-   return (ssi_private->dai_fmt & SND_SOC_DAIFMT_MASTER_MASK) ==
+   return (ssi->dai_fmt & SND_SOC_DAIFMT_MASTER_MASK) ==
SND_SOC_DAIFMT_CBS_CFS;
 }
 
-static bool fsl_ssi_is_i2s_cbm_cfs(struct fsl_ssi_private *ssi_private)
+static bool fsl_ssi_is_i2s_cbm_cfs(struct fsl_ssi *ssi)
 {
-   return (ssi_private->dai_fmt & SND_SOC_DAIFMT_MASTER_MASK) ==
+   return (ssi->dai_fmt & SND_SOC_DAIFMT_MASTER_MASK) ==
SND_SOC_DAIFMT_CBM_CFS;
 }
 /**
@@ -352,12 +352,12 @@ static bool fsl_ssi_is_i2s_cbm_cfs(struct fsl_ssi_private 
*ssi_private)
  * This interrupt handler is used only to gather statistics.
  *
  * @irq: IRQ of the SSI device
- * @dev_id: pointer to the ssi_private structure for this SSI device
+ * @dev_id: pointer to the fsl_ssi structure for this SSI device
  */
 static irqreturn_t fsl_ssi_isr(int irq, void *dev_id)
 {
-   struct fsl_ssi_private *ssi_private = dev_id;
-   struct regmap *regs = ssi_private->regs;
+   struct fsl_ssi *ssi = dev_id;
+   struct regmap *regs = ssi->regs;
__be32 sisr;
__be32 sisr2;
 
@@ -367,12 +367,12 @@ static irqreturn_t fsl_ssi_isr(int irq, void *dev_id)
 */
regmap_read(regs, CCSR_SSI_SISR, );
 
-   sisr2 = sisr & ssi_private->soc->sisr_write_mask;
+   sisr2 = sisr & ssi->soc->sisr_write_mask;
/* Clear the bits that we set */
if (sisr2)
regmap_write(regs, CCSR_SSI_SISR, sisr2);
 
-   fsl_ssi_dbg_isr(_private->dbg_stats, sisr);
+   fsl_ssi_dbg_isr(>dbg_stats, sisr);
 
return IRQ_HANDLED;
 }
@@ -380,11 +380,10 @@ static irqreturn_t fsl_ssi_isr(int irq, void *dev_id)
 /*
  * Enable/Disable all rx/tx config flags at once.
  */
-static void fsl_ssi_rxtx_config(struct fsl_ssi_private *ssi_private,
-   bool enable)
+static void fsl_ssi_rxtx_config(struct fsl_ssi *ssi, bool enable)
 {
-   struct regmap *regs = ssi_private->regs;
-   struct fsl_ssi_rxtx_reg_val *vals = _private->rxtx_reg_val;
+   struct regmap *regs = ssi->regs;
+   struct fsl_ssi_rxtx_reg_val *vals = >rxtx_reg_val;
 
if (enable) {
regmap_update_bits(regs, CCSR_SSI_SIER,
@@ -414,14 +413,13 @@ static void fsl_ssi_rxtx_config(struct fsl_ssi_private 
*ssi_private,
  * Note: The SOR is not documented in recent IMX datasheet, but
  * is described in IMX51 reference manual at section 56.3.3.15.
  */
-static void fsl_ssi_fifo_clear(struct fsl_ssi_private *ssi_private,
-   bool is_rx)
+static void fsl_ssi_fifo_clear(struct fsl_ssi *ssi, bool is_rx)
 {
if (is_rx) {
-   regmap_update_bits(ssi_private->regs, CCSR_SSI_SOR,
+   regmap_update_bits(ssi->regs, CCSR_SSI_SOR,
CCSR_SSI_SOR_RX_CLR, CCSR_SSI_SOR_RX_CLR);
} else {
-   regmap_update_bits(ssi_private->regs, CCSR_SSI_SOR,
+   regmap_update_bits(ssi->regs, CCSR_SSI_SOR,
CCSR_SSI_SOR_TX_CLR, CCSR_SSI_SOR_TX_CLR);
}
 }
@@ -448,12 +446,12 @@ static void fsl_ssi_fifo_clear(struct fsl_ssi_private 
*ssi_private,
 
 /*
  * Enable/Disable a ssi configuration. You have to pass either
- * ssi_private->rxtx_reg_val.rx or tx as vals parameter.
+ * ssi->rxtx_reg_val.rx or tx as vals parameter.
  */
-static void fsl_ssi_config(struct fsl_ssi_private *ssi_private, bool enable,
+static void fsl_ssi_config(struct fsl_ssi *ssi, bool enable,
struct fsl_ssi_reg_val *vals)
 {
-   struct regmap *regs 

[PATCH v2 02/11] ASoC: fsl_ssi: Cache pdev->dev pointer

2017-12-12 Thread Nicolin Chen
There should be no trouble to understand dev = pdev->dev.
This can save some space to have more print info or save
some wrapped lines.

Signed-off-by: Nicolin Chen 
---
 sound/soc/fsl/fsl_ssi.c | 64 -
 1 file changed, 31 insertions(+), 33 deletions(-)

diff --git a/sound/soc/fsl/fsl_ssi.c b/sound/soc/fsl/fsl_ssi.c
index 84d2f7e..e903c92 100644
--- a/sound/soc/fsl/fsl_ssi.c
+++ b/sound/soc/fsl/fsl_ssi.c
@@ -1379,23 +1379,24 @@ static int fsl_ssi_imx_probe(struct platform_device 
*pdev,
struct fsl_ssi *ssi, void __iomem *iomem)
 {
struct device_node *np = pdev->dev.of_node;
+   struct device *dev = >dev;
u32 dmas[4];
int ret;
 
if (ssi->has_ipg_clk_name)
-   ssi->clk = devm_clk_get(>dev, "ipg");
+   ssi->clk = devm_clk_get(dev, "ipg");
else
-   ssi->clk = devm_clk_get(>dev, NULL);
+   ssi->clk = devm_clk_get(dev, NULL);
if (IS_ERR(ssi->clk)) {
ret = PTR_ERR(ssi->clk);
-   dev_err(>dev, "could not get clock: %d\n", ret);
+   dev_err(dev, "could not get clock: %d\n", ret);
return ret;
}
 
if (!ssi->has_ipg_clk_name) {
ret = clk_prepare_enable(ssi->clk);
if (ret) {
-   dev_err(>dev, "clk_prepare_enable failed: %d\n", 
ret);
+   dev_err(dev, "clk_prepare_enable failed: %d\n", ret);
return ret;
}
}
@@ -1403,9 +1404,9 @@ static int fsl_ssi_imx_probe(struct platform_device *pdev,
/* For those SLAVE implementations, we ignore non-baudclk cases
 * and, instead, abandon MASTER mode that needs baud clock.
 */
-   ssi->baudclk = devm_clk_get(>dev, "baud");
+   ssi->baudclk = devm_clk_get(dev, "baud");
if (IS_ERR(ssi->baudclk))
-   dev_dbg(>dev, "could not get baud clock: %ld\n",
+   dev_dbg(dev, "could not get baud clock: %ld\n",
 PTR_ERR(ssi->baudclk));
 
ssi->dma_params_tx.maxburst = ssi->dma_maxburst;
@@ -1469,6 +1470,7 @@ static int fsl_ssi_probe(struct platform_device *pdev)
struct fsl_ssi *ssi;
int ret = 0;
struct device_node *np = pdev->dev.of_node;
+   struct device *dev = >dev;
const struct of_device_id *of_id;
const char *p, *sprop;
const uint32_t *iprop;
@@ -1477,17 +1479,16 @@ static int fsl_ssi_probe(struct platform_device *pdev)
char name[64];
struct regmap_config regconfig = fsl_ssi_regconfig;
 
-   of_id = of_match_device(fsl_ssi_ids, >dev);
+   of_id = of_match_device(fsl_ssi_ids, dev);
if (!of_id || !of_id->data)
return -EINVAL;
 
-   ssi = devm_kzalloc(>dev, sizeof(*ssi),
-   GFP_KERNEL);
+   ssi = devm_kzalloc(dev, sizeof(*ssi), GFP_KERNEL);
if (!ssi)
return -ENOMEM;
 
ssi->soc = of_id->data;
-   ssi->dev = >dev;
+   ssi->dev = dev;
 
sprop = of_get_property(np, "fsl,mode", NULL);
if (sprop) {
@@ -1507,10 +1508,10 @@ static int fsl_ssi_probe(struct platform_device *pdev)
memcpy(>cpu_dai_drv, _ssi_dai_template,
   sizeof(fsl_ssi_dai_template));
}
-   ssi->cpu_dai_drv.name = dev_name(>dev);
+   ssi->cpu_dai_drv.name = dev_name(dev);
 
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
-   iomem = devm_ioremap_resource(>dev, res);
+   iomem = devm_ioremap_resource(dev, res);
if (IS_ERR(iomem))
return PTR_ERR(iomem);
ssi->ssi_phys = res->start;
@@ -1528,21 +1529,20 @@ static int fsl_ssi_probe(struct platform_device *pdev)
ret = of_property_match_string(np, "clock-names", "ipg");
if (ret < 0) {
ssi->has_ipg_clk_name = false;
-   ssi->regs = devm_regmap_init_mmio(>dev, iomem,
-   );
+   ssi->regs = devm_regmap_init_mmio(dev, iomem, );
} else {
ssi->has_ipg_clk_name = true;
-   ssi->regs = devm_regmap_init_mmio_clk(>dev,
-   "ipg", iomem, );
+   ssi->regs = devm_regmap_init_mmio_clk(dev, "ipg", iomem,
+ );
}
if (IS_ERR(ssi->regs)) {
-   dev_err(>dev, "Failed to init register map\n");
+   dev_err(dev, "Failed to init register map\n");
return PTR_ERR(ssi->regs);
}
 
ssi->irq = platform_get_irq(pdev, 0);
if (ssi->irq < 0) {
-   dev_err(>dev, "no irq for node %s\n", pdev->name);
+   dev_err(dev, "no irq for node %s\n", pdev->name);
return ssi->irq;
}
 
@@ -1605,7 +1605,7 @@ static int fsl_ssi_probe(struct platform_device *pdev)

[PATCH v2 03/11] ASoC: fsl_ssi: Refine all comments

2017-12-12 Thread Nicolin Chen
This patch refines the comments by:
1) Removing all out-of-date comments
2) Removing all not-so-useful comments
3) Unifying the styles of all comments
4) Simplifying over-descriptive comments
5) Adding comments to improve code readablity
6) Moving all register related comments to fsl_ssi.h
7) Adding comments to all register and field defines

Signed-off-by: Nicolin Chen 
---

Changelog
v1->v2
 * Added some new comments at "SoC specific data" to be more precise.
 * Revised one comment in fsl_ssi_config().
 * Revised the comment of fsl_ssi_setup_reg_vals().
 * Added one comment for AC97 in fsl_ssi_setup_reg_vals().
 * Revised the comment of fsl_ssi_hw_params() to be more precise.
 * Added some comments in _fsl_ssi_set_dai_fmt() to help understand the formats.
 * Added one comment in fsl_ssi_set_dai_fmt() to state why AC97 needs to bypass 
it.
 * Revised comments in fsl_ssi_set_dai_tdm_slot() to be more precise.
 * Revised comments around dual FIFO code in fsl_ssi_imx_probe() to be more 
precise.

 sound/soc/fsl/fsl_ssi.c | 376 ++--
 sound/soc/fsl/fsl_ssi.h |  67 +++-
 sound/soc/fsl/fsl_ssi_dbg.c |  12 +-
 3 files changed, 188 insertions(+), 267 deletions(-)

diff --git a/sound/soc/fsl/fsl_ssi.c b/sound/soc/fsl/fsl_ssi.c
index e903c92..796a7ea 100644
--- a/sound/soc/fsl/fsl_ssi.c
+++ b/sound/soc/fsl/fsl_ssi.c
@@ -187,42 +187,48 @@ struct fsl_ssi_soc_data {
 /**
  * fsl_ssi: per-SSI private data
  *
- * @reg: Pointer to the regmap registers
+ * @regs: Pointer to the regmap registers
  * @irq: IRQ of this SSI
  * @cpu_dai_drv: CPU DAI driver for this device
  *
  * @dai_fmt: DAI configuration this device is currently used with
- * @i2s_mode: i2s and network mode configuration of the device. Is used to
- * switch between normal and i2s/network mode
- * mode depending on the number of channels
+ * @i2s_mode: I2S and Network mode configuration of SCR register
  * @use_dma: DMA is used or FIQ with stream filter
- * @use_dual_fifo: DMA with support for both FIFOs used
- * @fifo_deph: Depth of the SSI FIFOs
- * @slot_width: width of each DAI slot
- * @slots: number of slots
- * @rxtx_reg_val: Specific register settings for receive/transmit configuration
+ * @use_dual_fifo: DMA with support for dual FIFO mode
+ * @has_ipg_clk_name: If "ipg" is in the clock name list of device tree
+ * @fifo_depth: Depth of the SSI FIFOs
+ * @slot_width: Width of each DAI slot
+ * @slots: Number of slots
+ * @rxtx_reg_val: Specific RX/TX register settings
  *
- * @clk: SSI clock
- * @baudclk: SSI baud clock for master mode
+ * @clk: Clock source to access register
+ * @baudclk: Clock source to generate bit and frame-sync clocks
  * @baudclk_streams: Active streams that are using baudclk
  *
+ * @regcache_sfcsr: Cache sfcsr register value during suspend and resume
+ * @regcache_sacnt: Cache sacnt register value during suspend and resume
+ *
  * @dma_params_tx: DMA transmit parameters
  * @dma_params_rx: DMA receive parameters
  * @ssi_phys: physical address of the SSI registers
  *
  * @fiq_params: FIQ stream filtering parameters
  *
- * @pdev: Pointer to pdev used for deprecated fsl-ssi sound card
+ * @pdev: Pointer to pdev when using fsl-ssi as sound card (ppc only)
+ *TODO: Should be replaced with simple-sound-card
  *
  * @dbg_stats: Debugging statistics
  *
  * @soc: SoC specific data
+ * @dev: Pointer to >dev
+ *
+ * @fifo_watermark: The FIFO watermark setting. Notifies DMA when there are
+ *  @fifo_watermark or fewer words in TX fifo or
+ *  @fifo_watermark or more empty words in RX fifo.
+ * @dma_maxburst: Max number of words to transfer in one go. So far,
+ *this is always the same as fifo_watermark.
  *
- * @fifo_watermark: the FIFO watermark setting.  Notifies DMA when
- * there are @fifo_watermark or fewer words in TX fifo or
- * @fifo_watermark or more empty words in RX fifo.
- * @dma_maxburst: max number of words to transfer in one go.  So far,
- * this is always the same as fifo_watermark.
+ * @ac97_reg_lock: Mutex lock to serialize AC97 register access operations
  */
 struct fsl_ssi {
struct regmap *regs;
@@ -243,20 +249,15 @@ struct fsl_ssi {
struct clk *baudclk;
unsigned int baudclk_streams;
 
-   /* regcache for volatile regs */
u32 regcache_sfcsr;
u32 regcache_sacnt;
 
-   /* DMA params */
struct snd_dmaengine_dai_dma_data dma_params_tx;
struct snd_dmaengine_dai_dma_data dma_params_rx;
dma_addr_t ssi_phys;
 
-   /* params for non-dma FIQ stream filtered mode */
struct imx_pcm_fiq_params fiq_params;
 
-   /* Used when using fsl-ssi as sound-card. This is only used by ppc and
-* should be replaced with simple-sound-card. */
struct platform_device *pdev;
 
struct fsl_ssi_dbg dbg_stats;
@@ -271,19 +272,19 @@ struct fsl_ssi {
 };
 
 /*
- * imx51 

[PATCH v2 04/11] ASoC: fsl_ssi: Rename registers and fields macros

2017-12-12 Thread Nicolin Chen
This patch renames CCSR_SSI_xxx to REG_SSI_xxx and SSI_xxx_yyy style.
It also slightly reduces the length of them to save some space.

Signed-off-by: Nicolin Chen 
---
 sound/soc/fsl/fsl_ssi.c | 374 +--
 sound/soc/fsl/fsl_ssi.h | 376 ++--
 sound/soc/fsl/fsl_ssi_dbg.c |  44 +++---
 3 files changed, 397 insertions(+), 397 deletions(-)

diff --git a/sound/soc/fsl/fsl_ssi.c b/sound/soc/fsl/fsl_ssi.c
index 796a7ea..8b5407d 100644
--- a/sound/soc/fsl/fsl_ssi.c
+++ b/sound/soc/fsl/fsl_ssi.c
@@ -78,12 +78,12 @@
 SNDRV_PCM_FMTBIT_S24_3LE | SNDRV_PCM_FMTBIT_S24_LE)
 #endif
 
-#define FSLSSI_SIER_DBG_RX_FLAGS (CCSR_SSI_SIER_RFF0_EN | \
-   CCSR_SSI_SIER_RLS_EN | CCSR_SSI_SIER_RFS_EN | \
-   CCSR_SSI_SIER_ROE0_EN | CCSR_SSI_SIER_RFRC_EN)
-#define FSLSSI_SIER_DBG_TX_FLAGS (CCSR_SSI_SIER_TFE0_EN | \
-   CCSR_SSI_SIER_TLS_EN | CCSR_SSI_SIER_TFS_EN | \
-   CCSR_SSI_SIER_TUE0_EN | CCSR_SSI_SIER_TFRC_EN)
+#define FSLSSI_SIER_DBG_RX_FLAGS (SSI_SIER_RFF0_EN | \
+   SSI_SIER_RLS_EN | SSI_SIER_RFS_EN | \
+   SSI_SIER_ROE0_EN | SSI_SIER_RFRC_EN)
+#define FSLSSI_SIER_DBG_TX_FLAGS (SSI_SIER_TFE0_EN | \
+   SSI_SIER_TLS_EN | SSI_SIER_TFS_EN | \
+   SSI_SIER_TUE0_EN | SSI_SIER_TFRC_EN)
 
 enum fsl_ssi_type {
FSL_SSI_MCP8610,
@@ -107,8 +107,8 @@ struct fsl_ssi_rxtx_reg_val {
 static bool fsl_ssi_readable_reg(struct device *dev, unsigned int reg)
 {
switch (reg) {
-   case CCSR_SSI_SACCEN:
-   case CCSR_SSI_SACCDIS:
+   case REG_SSI_SACCEN:
+   case REG_SSI_SACCDIS:
return false;
default:
return true;
@@ -118,18 +118,18 @@ static bool fsl_ssi_readable_reg(struct device *dev, 
unsigned int reg)
 static bool fsl_ssi_volatile_reg(struct device *dev, unsigned int reg)
 {
switch (reg) {
-   case CCSR_SSI_STX0:
-   case CCSR_SSI_STX1:
-   case CCSR_SSI_SRX0:
-   case CCSR_SSI_SRX1:
-   case CCSR_SSI_SISR:
-   case CCSR_SSI_SFCSR:
-   case CCSR_SSI_SACNT:
-   case CCSR_SSI_SACADD:
-   case CCSR_SSI_SACDAT:
-   case CCSR_SSI_SATAG:
-   case CCSR_SSI_SACCST:
-   case CCSR_SSI_SOR:
+   case REG_SSI_STX0:
+   case REG_SSI_STX1:
+   case REG_SSI_SRX0:
+   case REG_SSI_SRX1:
+   case REG_SSI_SISR:
+   case REG_SSI_SFCSR:
+   case REG_SSI_SACNT:
+   case REG_SSI_SACADD:
+   case REG_SSI_SACDAT:
+   case REG_SSI_SATAG:
+   case REG_SSI_SACCST:
+   case REG_SSI_SOR:
return true;
default:
return false;
@@ -139,12 +139,12 @@ static bool fsl_ssi_volatile_reg(struct device *dev, 
unsigned int reg)
 static bool fsl_ssi_precious_reg(struct device *dev, unsigned int reg)
 {
switch (reg) {
-   case CCSR_SSI_SRX0:
-   case CCSR_SSI_SRX1:
-   case CCSR_SSI_SISR:
-   case CCSR_SSI_SACADD:
-   case CCSR_SSI_SACDAT:
-   case CCSR_SSI_SATAG:
+   case REG_SSI_SRX0:
+   case REG_SSI_SRX1:
+   case REG_SSI_SISR:
+   case REG_SSI_SACADD:
+   case REG_SSI_SACDAT:
+   case REG_SSI_SATAG:
return true;
default:
return false;
@@ -154,9 +154,9 @@ static bool fsl_ssi_precious_reg(struct device *dev, 
unsigned int reg)
 static bool fsl_ssi_writeable_reg(struct device *dev, unsigned int reg)
 {
switch (reg) {
-   case CCSR_SSI_SRX0:
-   case CCSR_SSI_SRX1:
-   case CCSR_SSI_SACCST:
+   case REG_SSI_SRX0:
+   case REG_SSI_SRX1:
+   case REG_SSI_SACCST:
return false;
default:
return true;
@@ -164,12 +164,12 @@ static bool fsl_ssi_writeable_reg(struct device *dev, 
unsigned int reg)
 }
 
 static const struct regmap_config fsl_ssi_regconfig = {
-   .max_register = CCSR_SSI_SACCDIS,
+   .max_register = REG_SSI_SACCDIS,
.reg_bits = 32,
.val_bits = 32,
.reg_stride = 4,
.val_format_endian = REGMAP_ENDIAN_NATIVE,
-   .num_reg_defaults_raw = CCSR_SSI_SACCDIS / sizeof(uint32_t) + 1,
+   .num_reg_defaults_raw = REG_SSI_SACCDIS / sizeof(uint32_t) + 1,
.readable_reg = fsl_ssi_readable_reg,
.volatile_reg = fsl_ssi_volatile_reg,
.precious_reg = fsl_ssi_precious_reg,
@@ -290,9 +290,9 @@ struct fsl_ssi {
 static struct fsl_ssi_soc_data fsl_ssi_mpc8610 = {
.imx = false,
.offline_config = true,
-   .sisr_write_mask = CCSR_SSI_SISR_RFRC | CCSR_SSI_SISR_TFRC |
-   CCSR_SSI_SISR_ROE0 | CCSR_SSI_SISR_ROE1 |
-   CCSR_SSI_SISR_TUE0 | CCSR_SSI_SISR_TUE1,
+   .sisr_write_mask = SSI_SISR_RFRC | SSI_SISR_TFRC |
+   SSI_SISR_ROE0 | SSI_SISR_ROE1 |
+   SSI_SISR_TUE0 | SSI_SISR_TUE1,
 };
 
 static struct fsl_ssi_soc_data fsl_ssi_imx21 = {
@@ 

[PATCH v2 05/11] ASoC: fsl_ssi: Refine indentations and wrappings

2017-12-12 Thread Nicolin Chen
This patch just simply unifies the coding style.

Signed-off-by: Nicolin Chen 
---

Changelog
v1->v2
 * Added two missing indentation changes
 * Removed two extra blank lines.

 sound/soc/fsl/fsl_ssi.c | 239 +---
 sound/soc/fsl/fsl_ssi.h |   2 +-
 sound/soc/fsl/fsl_ssi_dbg.c |   3 +-
 3 files changed, 118 insertions(+), 126 deletions(-)

diff --git a/sound/soc/fsl/fsl_ssi.c b/sound/soc/fsl/fsl_ssi.c
index 8b5407d..9a3db08 100644
--- a/sound/soc/fsl/fsl_ssi.c
+++ b/sound/soc/fsl/fsl_ssi.c
@@ -69,21 +69,35 @@
  * samples will be written to STX properly.
  */
 #ifdef __BIG_ENDIAN
-#define FSLSSI_I2S_FORMATS (SNDRV_PCM_FMTBIT_S8 | SNDRV_PCM_FMTBIT_S16_BE | \
-SNDRV_PCM_FMTBIT_S18_3BE | SNDRV_PCM_FMTBIT_S20_3BE | \
-SNDRV_PCM_FMTBIT_S24_3BE | SNDRV_PCM_FMTBIT_S24_BE)
+#define FSLSSI_I2S_FORMATS \
+   (SNDRV_PCM_FMTBIT_S8 | \
+SNDRV_PCM_FMTBIT_S16_BE | \
+SNDRV_PCM_FMTBIT_S18_3BE | \
+SNDRV_PCM_FMTBIT_S20_3BE | \
+SNDRV_PCM_FMTBIT_S24_3BE | \
+SNDRV_PCM_FMTBIT_S24_BE)
 #else
-#define FSLSSI_I2S_FORMATS (SNDRV_PCM_FMTBIT_S8 | SNDRV_PCM_FMTBIT_S16_LE | \
-SNDRV_PCM_FMTBIT_S18_3LE | SNDRV_PCM_FMTBIT_S20_3LE | \
-SNDRV_PCM_FMTBIT_S24_3LE | SNDRV_PCM_FMTBIT_S24_LE)
+#define FSLSSI_I2S_FORMATS \
+   (SNDRV_PCM_FMTBIT_S8 | \
+SNDRV_PCM_FMTBIT_S16_LE | \
+SNDRV_PCM_FMTBIT_S18_3LE | \
+SNDRV_PCM_FMTBIT_S20_3LE | \
+SNDRV_PCM_FMTBIT_S24_3LE | \
+SNDRV_PCM_FMTBIT_S24_LE)
 #endif
 
-#define FSLSSI_SIER_DBG_RX_FLAGS (SSI_SIER_RFF0_EN | \
-   SSI_SIER_RLS_EN | SSI_SIER_RFS_EN | \
-   SSI_SIER_ROE0_EN | SSI_SIER_RFRC_EN)
-#define FSLSSI_SIER_DBG_TX_FLAGS (SSI_SIER_TFE0_EN | \
-   SSI_SIER_TLS_EN | SSI_SIER_TFS_EN | \
-   SSI_SIER_TUE0_EN | SSI_SIER_TFRC_EN)
+#define FSLSSI_SIER_DBG_RX_FLAGS \
+   (SSI_SIER_RFF0_EN | \
+SSI_SIER_RLS_EN | \
+SSI_SIER_RFS_EN | \
+SSI_SIER_ROE0_EN | \
+SSI_SIER_RFRC_EN)
+#define FSLSSI_SIER_DBG_TX_FLAGS \
+   (SSI_SIER_TFE0_EN | \
+SSI_SIER_TLS_EN | \
+SSI_SIER_TFS_EN | \
+SSI_SIER_TUE0_EN | \
+SSI_SIER_TFRC_EN)
 
 enum fsl_ssi_type {
FSL_SSI_MCP8610,
@@ -291,8 +305,8 @@ static struct fsl_ssi_soc_data fsl_ssi_mpc8610 = {
.imx = false,
.offline_config = true,
.sisr_write_mask = SSI_SISR_RFRC | SSI_SISR_TFRC |
-   SSI_SISR_ROE0 | SSI_SISR_ROE1 |
-   SSI_SISR_TUE0 | SSI_SISR_TUE1,
+  SSI_SISR_ROE0 | SSI_SISR_ROE1 |
+  SSI_SISR_TUE0 | SSI_SISR_TUE1,
 };
 
 static struct fsl_ssi_soc_data fsl_ssi_imx21 = {
@@ -306,15 +320,15 @@ static struct fsl_ssi_soc_data fsl_ssi_imx35 = {
.imx = true,
.offline_config = true,
.sisr_write_mask = SSI_SISR_RFRC | SSI_SISR_TFRC |
-   SSI_SISR_ROE0 | SSI_SISR_ROE1 |
-   SSI_SISR_TUE0 | SSI_SISR_TUE1,
+  SSI_SISR_ROE0 | SSI_SISR_ROE1 |
+  SSI_SISR_TUE0 | SSI_SISR_TUE1,
 };
 
 static struct fsl_ssi_soc_data fsl_ssi_imx51 = {
.imx = true,
.offline_config = false,
.sisr_write_mask = SSI_SISR_ROE0 | SSI_SISR_ROE1 |
-   SSI_SISR_TUE0 | SSI_SISR_TUE1,
+  SSI_SISR_TUE0 | SSI_SISR_TUE1,
 };
 
 static const struct of_device_id fsl_ssi_ids[] = {
@@ -373,21 +387,21 @@ static void fsl_ssi_rxtx_config(struct fsl_ssi *ssi, bool 
enable)
 
if (enable) {
regmap_update_bits(regs, REG_SSI_SIER,
-   vals->rx.sier | vals->tx.sier,
-   vals->rx.sier | vals->tx.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);
+  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);
+  vals->rx.stcr | vals->tx.stcr,
+  vals->rx.stcr | vals->tx.stcr);
} else {
regmap_update_bits(regs, REG_SSI_SRCR,
-   vals->rx.srcr | vals->tx.srcr, 0);
+  vals->rx.srcr | vals->tx.srcr, 0);
regmap_update_bits(regs, REG_SSI_STCR,
-   vals->rx.stcr | vals->tx.stcr, 0);
+  vals->rx.stcr | vals->tx.stcr, 0);
  

[PATCH v2 06/11] ASoC: fsl_ssi: Refine printk outputs

2017-12-12 Thread Nicolin Chen
This patches unifies the error message in the "failed to " format.

It also reduces the length of one line and adds spaces to an operator.

Signed-off-by: Nicolin Chen 
---
 sound/soc/fsl/fsl_ssi.c | 16 
 1 file changed, 8 insertions(+), 8 deletions(-)

diff --git a/sound/soc/fsl/fsl_ssi.c b/sound/soc/fsl/fsl_ssi.c
index 9a3db08..d3bb662 100644
--- a/sound/soc/fsl/fsl_ssi.c
+++ b/sound/soc/fsl/fsl_ssi.c
@@ -701,7 +701,7 @@ static int fsl_ssi_set_bclk(struct snd_pcm_substream 
*substream,
 * never greater than 1/5 IPG clock rate
 */
if (freq * 5 > clk_get_rate(ssi->clk)) {
-   dev_err(cpu_dai->dev, "bitclk > ipgclk/5\n");
+   dev_err(cpu_dai->dev, "bitclk > ipgclk / 5\n");
return -EINVAL;
}
 
@@ -868,7 +868,7 @@ static int _fsl_ssi_set_dai_fmt(struct device *dev,
ssi->dai_fmt = fmt;
 
if (fsl_ssi_is_i2s_master(ssi) && IS_ERR(ssi->baudclk)) {
-   dev_err(dev, "baudclk is missing which is necessary for master 
mode\n");
+   dev_err(dev, "missing baudclk for master mode\n");
return -EINVAL;
}
 
@@ -1284,7 +1284,7 @@ static int fsl_ssi_imx_probe(struct platform_device *pdev,
ssi->clk = devm_clk_get(dev, NULL);
if (IS_ERR(ssi->clk)) {
ret = PTR_ERR(ssi->clk);
-   dev_err(dev, "could not get clock: %d\n", ret);
+   dev_err(dev, "failed to get clock: %d\n", ret);
return ret;
}
 
@@ -1300,7 +1300,7 @@ static int fsl_ssi_imx_probe(struct platform_device *pdev,
/* Do not error out for slave cases that live without a baud clock */
ssi->baudclk = devm_clk_get(dev, "baud");
if (IS_ERR(ssi->baudclk))
-   dev_dbg(dev, "could not get baud clock: %ld\n",
+   dev_dbg(dev, "failed to get baud clock: %ld\n",
 PTR_ERR(ssi->baudclk));
 
ssi->dma_params_tx.maxburst = ssi->dma_maxburst;
@@ -1421,7 +1421,7 @@ static int fsl_ssi_probe(struct platform_device *pdev)
  );
}
if (IS_ERR(ssi->regs)) {
-   dev_err(dev, "Failed to init register map\n");
+   dev_err(dev, "failed to init register map\n");
return PTR_ERR(ssi->regs);
}
 
@@ -1480,7 +1480,7 @@ static int fsl_ssi_probe(struct platform_device *pdev)
mutex_init(>ac97_reg_lock);
ret = snd_soc_set_ac97_ops_of_reset(_ssi_ac97_ops, pdev);
if (ret) {
-   dev_err(dev, "could not set AC'97 ops\n");
+   dev_err(dev, "failed to set AC'97 ops\n");
goto error_ac97_ops;
}
}
@@ -1496,7 +1496,7 @@ static int fsl_ssi_probe(struct platform_device *pdev)
ret = devm_request_irq(dev, ssi->irq, fsl_ssi_isr, 0,
   dev_name(dev), ssi);
if (ret < 0) {
-   dev_err(dev, "could not claim irq %u\n", ssi->irq);
+   dev_err(dev, "failed to claim irq %u\n", ssi->irq);
goto error_asoc_register;
}
}
@@ -1538,7 +1538,7 @@ static int fsl_ssi_probe(struct platform_device *pdev)
 
ret = of_property_read_u32(np, "cell-index", _idx);
if (ret) {
-   dev_err(dev, "cannot get SSI index property\n");
+   dev_err(dev, "failed to get SSI index property\n");
goto error_sound_card;
}
 
-- 
2.7.4



[PATCH v2 07/11] ASoC: fsl_ssi: Rename cpu_dai parameter to dai

2017-12-12 Thread Nicolin Chen
Shortens the variable name to save space, useful for dev_err outputs.

Signed-off-by: Nicolin Chen 
---
 sound/soc/fsl/fsl_ssi.c | 32 
 1 file changed, 16 insertions(+), 16 deletions(-)

diff --git a/sound/soc/fsl/fsl_ssi.c b/sound/soc/fsl/fsl_ssi.c
index d3bb662..69fa86d 100644
--- a/sound/soc/fsl/fsl_ssi.c
+++ b/sound/soc/fsl/fsl_ssi.c
@@ -668,10 +668,10 @@ static void fsl_ssi_shutdown(struct snd_pcm_substream 
*substream,
  *   (In 2-channel I2S Master mode, slot_width is fixed 32)
  */
 static int fsl_ssi_set_bclk(struct snd_pcm_substream *substream,
-   struct snd_soc_dai *cpu_dai,
+   struct snd_soc_dai *dai,
struct snd_pcm_hw_params *hw_params)
 {
-   struct fsl_ssi *ssi = snd_soc_dai_get_drvdata(cpu_dai);
+   struct fsl_ssi *ssi = snd_soc_dai_get_drvdata(dai);
struct regmap *regs = ssi->regs;
int synchronous = ssi->cpu_dai_drv.symmetric_rates, ret;
u32 pm = 999, div2, psr, stccr, mask, afreq, factor, i;
@@ -701,7 +701,7 @@ static int fsl_ssi_set_bclk(struct snd_pcm_substream 
*substream,
 * never greater than 1/5 IPG clock rate
 */
if (freq * 5 > clk_get_rate(ssi->clk)) {
-   dev_err(cpu_dai->dev, "bitclk > ipgclk / 5\n");
+   dev_err(dai->dev, "bitclk > ipgclk / 5\n");
return -EINVAL;
}
 
@@ -750,7 +750,7 @@ static int fsl_ssi_set_bclk(struct snd_pcm_substream 
*substream,
 
/* No proper pm found if it is still remaining the initial value */
if (pm == 999) {
-   dev_err(cpu_dai->dev, "failed to handle the required sysclk\n");
+   dev_err(dai->dev, "failed to handle the required sysclk\n");
return -EINVAL;
}
 
@@ -766,7 +766,7 @@ static int fsl_ssi_set_bclk(struct snd_pcm_substream 
*substream,
if (!baudclk_is_used) {
ret = clk_set_rate(ssi->baudclk, baudrate);
if (ret) {
-   dev_err(cpu_dai->dev, "failed to set baudclk rate\n");
+   dev_err(dai->dev, "failed to set baudclk rate\n");
return -EINVAL;
}
}
@@ -787,9 +787,9 @@ static int fsl_ssi_set_bclk(struct snd_pcm_substream 
*substream,
  */
 static int fsl_ssi_hw_params(struct snd_pcm_substream *substream,
 struct snd_pcm_hw_params *hw_params,
-struct snd_soc_dai *cpu_dai)
+struct snd_soc_dai *dai)
 {
-   struct fsl_ssi *ssi = snd_soc_dai_get_drvdata(cpu_dai);
+   struct fsl_ssi *ssi = snd_soc_dai_get_drvdata(dai);
struct regmap *regs = ssi->regs;
unsigned int channels = params_channels(hw_params);
unsigned int sample_size = params_width(hw_params);
@@ -806,7 +806,7 @@ static int fsl_ssi_hw_params(struct snd_pcm_substream 
*substream,
return 0;
 
if (fsl_ssi_is_i2s_master(ssi)) {
-   ret = fsl_ssi_set_bclk(substream, cpu_dai, hw_params);
+   ret = fsl_ssi_set_bclk(substream, dai, hw_params);
if (ret)
return ret;
 
@@ -844,7 +844,7 @@ static int fsl_ssi_hw_params(struct snd_pcm_substream 
*substream,
 }
 
 static int fsl_ssi_hw_free(struct snd_pcm_substream *substream,
-  struct snd_soc_dai *cpu_dai)
+  struct snd_soc_dai *dai)
 {
struct snd_soc_pcm_runtime *rtd = substream->private_data;
struct fsl_ssi *ssi = snd_soc_dai_get_drvdata(rtd->cpu_dai);
@@ -1013,30 +1013,30 @@ static int _fsl_ssi_set_dai_fmt(struct device *dev,
 /**
  * Configure Digital Audio Interface (DAI) Format
  */
-static int fsl_ssi_set_dai_fmt(struct snd_soc_dai *cpu_dai, unsigned int fmt)
+static int fsl_ssi_set_dai_fmt(struct snd_soc_dai *dai, unsigned int fmt)
 {
-   struct fsl_ssi *ssi = snd_soc_dai_get_drvdata(cpu_dai);
+   struct fsl_ssi *ssi = snd_soc_dai_get_drvdata(dai);
 
/* AC97 configured DAIFMT earlier in the probe() */
if (fsl_ssi_is_ac97(ssi))
return 0;
 
-   return _fsl_ssi_set_dai_fmt(cpu_dai->dev, ssi, fmt);
+   return _fsl_ssi_set_dai_fmt(dai->dev, ssi, fmt);
 }
 
 /**
  * Set TDM slot number and slot width
  */
-static int fsl_ssi_set_dai_tdm_slot(struct snd_soc_dai *cpu_dai, u32 tx_mask,
+static int fsl_ssi_set_dai_tdm_slot(struct snd_soc_dai *dai, u32 tx_mask,
u32 rx_mask, int slots, int slot_width)
 {
-   struct fsl_ssi *ssi = snd_soc_dai_get_drvdata(cpu_dai);
+   struct fsl_ssi *ssi = snd_soc_dai_get_drvdata(dai);
struct regmap *regs = ssi->regs;
u32 val;
 
/* The word length should be 8, 10, 12, 16, 18, 20, 22 or 24 */
if (slot_width & 1 || slot_width < 8 || slot_width > 24) {
-   dev_err(cpu_dai->dev, "invalid slot width: %d\n", 

[PATCH v2 08/11] ASoC: fsl_ssi: Rename scr_val to scr

2017-12-12 Thread Nicolin Chen
Simplify the variable name. This reduces one over-80-character line.

Signed-off-by: Nicolin Chen 
---
 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 69fa86d..7fcc6bd 100644
--- a/sound/soc/fsl/fsl_ssi.c
+++ b/sound/soc/fsl/fsl_ssi.c
@@ -448,12 +448,12 @@ static void fsl_ssi_config(struct fsl_ssi *ssi, bool 
enable,
struct regmap *regs = ssi->regs;
struct fsl_ssi_reg_val *avals;
int nr_active_streams;
-   u32 scr_val;
+   u32 scr;
int keep_active;
 
-   regmap_read(regs, REG_SSI_SCR, _val);
+   regmap_read(regs, REG_SSI_SCR, );
 
-   nr_active_streams = !!(scr_val & SSI_SCR_TE) + !!(scr_val & SSI_SCR_RE);
+   nr_active_streams = !!(scr & SSI_SCR_TE) + !!(scr & SSI_SCR_RE);
 
if (nr_active_streams - 1 > 0)
keep_active = 1;
@@ -795,11 +795,11 @@ static int fsl_ssi_hw_params(struct snd_pcm_substream 
*substream,
unsigned int sample_size = params_width(hw_params);
u32 wl = SSI_SxCCR_WL(sample_size);
int ret;
-   u32 scr_val;
+   u32 scr;
int enabled;
 
-   regmap_read(regs, REG_SSI_SCR, _val);
-   enabled = scr_val & SSI_SCR_SSIEN;
+   regmap_read(regs, REG_SSI_SCR, );
+   enabled = scr & SSI_SCR_SSIEN;
 
/* To support simultaneous TX and RX, bypass it if SSI is enabled */
if (enabled && ssi->cpu_dai_drv.symmetric_rates)
-- 
2.7.4



[PATCH v2 09/11] ASoC: fsl_ssi: Replace fsl_ssi_rxtx_reg_val with fsl_ssi_regvals

2017-12-12 Thread Nicolin Chen
The name fsl_ssi_rxtx_reg_val is too long to read comfortably.
So this patch shortens it by using an array (fsl_ssi_regvals,
renamed from fsl_ssi_reg_val). To do that, it also introduces
two macros (TX and RX) to replace the wrapper structure. This
will also help further cleanups.

Meanwhile, it unifies all local variable with the name "vals"
to get rid of the name "reg" -- could be confusing with "regs"
in the private struct for regmap.

Signed-off-by: Nicolin Chen 
---
 sound/soc/fsl/fsl_ssi.c | 79 +++--
 sound/soc/fsl/fsl_ssi.h |  3 ++
 2 files changed, 40 insertions(+), 42 deletions(-)

diff --git a/sound/soc/fsl/fsl_ssi.c b/sound/soc/fsl/fsl_ssi.c
index 7fcc6bd..7a8a768 100644
--- a/sound/soc/fsl/fsl_ssi.c
+++ b/sound/soc/fsl/fsl_ssi.c
@@ -106,18 +106,13 @@ enum fsl_ssi_type {
FSL_SSI_MX51,
 };
 
-struct fsl_ssi_reg_val {
+struct fsl_ssi_regvals {
u32 sier;
u32 srcr;
u32 stcr;
u32 scr;
 };
 
-struct fsl_ssi_rxtx_reg_val {
-   struct fsl_ssi_reg_val rx;
-   struct fsl_ssi_reg_val tx;
-};
-
 static bool fsl_ssi_readable_reg(struct device *dev, unsigned int reg)
 {
switch (reg) {
@@ -213,7 +208,7 @@ struct fsl_ssi_soc_data {
  * @fifo_depth: Depth of the SSI FIFOs
  * @slot_width: Width of each DAI slot
  * @slots: Number of slots
- * @rxtx_reg_val: Specific RX/TX register settings
+ * @regvals: Specific RX/TX register settings
  *
  * @clk: Clock source to access register
  * @baudclk: Clock source to generate bit and frame-sync clocks
@@ -257,7 +252,7 @@ struct fsl_ssi {
unsigned int fifo_depth;
unsigned int slot_width;
unsigned int slots;
-   struct fsl_ssi_rxtx_reg_val rxtx_reg_val;
+   struct fsl_ssi_regvals regvals[2];
 
struct clk *clk;
struct clk *baudclk;
@@ -383,25 +378,25 @@ static irqreturn_t fsl_ssi_isr(int irq, void *dev_id)
 static void fsl_ssi_rxtx_config(struct fsl_ssi *ssi, bool enable)
 {
struct regmap *regs = ssi->regs;
-   struct fsl_ssi_rxtx_reg_val *vals = >rxtx_reg_val;
+   struct fsl_ssi_regvals *vals = ssi->regvals;
 
if (enable) {
regmap_update_bits(regs, REG_SSI_SIER,
-  vals->rx.sier | vals->tx.sier,
-  vals->rx.sier | vals->tx.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);
+  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);
+  vals[RX].stcr | vals[TX].stcr,
+  vals[RX].stcr | vals[TX].stcr);
} else {
regmap_update_bits(regs, REG_SSI_SRCR,
-  vals->rx.srcr | vals->tx.srcr, 0);
+  vals[RX].srcr | vals[TX].srcr, 0);
regmap_update_bits(regs, REG_SSI_STCR,
-  vals->rx.stcr | vals->tx.stcr, 0);
+  vals[RX].stcr | vals[TX].stcr, 0);
regmap_update_bits(regs, REG_SSI_SIER,
-  vals->rx.sier | vals->tx.sier, 0);
+  vals[RX].sier | vals[TX].sier, 0);
}
 }
 
@@ -443,10 +438,10 @@ static void fsl_ssi_fifo_clear(struct fsl_ssi *ssi, bool 
is_rx)
  * Enable or disable SSI configuration.
  */
 static void fsl_ssi_config(struct fsl_ssi *ssi, bool enable,
-  struct fsl_ssi_reg_val *vals)
+  struct fsl_ssi_regvals *vals)
 {
struct regmap *regs = ssi->regs;
-   struct fsl_ssi_reg_val *avals;
+   struct fsl_ssi_regvals *avals;
int nr_active_streams;
u32 scr;
int keep_active;
@@ -461,10 +456,10 @@ static void fsl_ssi_config(struct fsl_ssi *ssi, bool 
enable,
keep_active = 0;
 
/* Get the opposite direction to keep its values untouched */
-   if (>rxtx_reg_val.rx == vals)
-   avals = >rxtx_reg_val.tx;
+   if (>regvals[RX] == vals)
+   avals = >regvals[TX];
else
-   avals = >rxtx_reg_val.rx;
+   avals = >regvals[RX];
 
if (!enable) {
/* Exclude necessary bits for the opposite stream */
@@ -543,7 +538,7 @@ static void fsl_ssi_config(struct fsl_ssi *ssi, bool enable,
 
 static void fsl_ssi_rx_config(struct fsl_ssi *ssi, bool enable)
 {
-   fsl_ssi_config(ssi, enable, 

[PATCH v2 10/11] ASoC: fsl_ssi: Rename i2smode to i2s_net

2017-12-12 Thread Nicolin Chen
Since this i2smode also includes the setting of Network mode, it
should have it in the name. This patch also adds its MASK define.

Signed-off-by: Nicolin Chen 
---
 sound/soc/fsl/fsl_ssi.c | 24 
 sound/soc/fsl/fsl_ssi.h |  1 +
 2 files changed, 13 insertions(+), 12 deletions(-)

diff --git a/sound/soc/fsl/fsl_ssi.c b/sound/soc/fsl/fsl_ssi.c
index 7a8a768..dd091eb 100644
--- a/sound/soc/fsl/fsl_ssi.c
+++ b/sound/soc/fsl/fsl_ssi.c
@@ -201,7 +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
- * @i2s_mode: I2S and Network mode configuration of SCR register
+ * @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
  * @has_ipg_clk_name: If "ipg" is in the clock name list of device tree
@@ -245,7 +245,7 @@ struct fsl_ssi {
struct snd_soc_dai_driver cpu_dai_drv;
 
unsigned int dai_fmt;
-   u8 i2s_mode;
+   u8 i2s_net;
bool use_dma;
bool use_dual_fifo;
bool has_ipg_clk_name;
@@ -816,16 +816,16 @@ static int fsl_ssi_hw_params(struct snd_pcm_substream 
*substream,
}
 
if (!fsl_ssi_is_ac97(ssi)) {
-   u8 i2smode;
+   u8 i2s_net;
/* Normal + Network mode to send 16-bit data in 32-bit frames */
if (fsl_ssi_is_i2s_cbm_cfs(ssi) && sample_size == 16)
-   i2smode = SSI_SCR_I2S_MODE_NORMAL | SSI_SCR_NET;
+   i2s_net = SSI_SCR_I2S_MODE_NORMAL | SSI_SCR_NET;
else
-   i2smode = ssi->i2s_mode;
+   i2s_net = ssi->i2s_net;
 
regmap_update_bits(regs, REG_SSI_SCR,
-  SSI_SCR_NET | SSI_SCR_I2S_MODE_MASK,
-  channels == 1 ? 0 : i2smode);
+  SSI_SCR_I2S_NET_MASK,
+  channels == 1 ? 0 : i2s_net);
}
 
/* In synchronous mode, the SSI uses STCCR for capture */
@@ -882,7 +882,7 @@ static int _fsl_ssi_set_dai_fmt(struct device *dev,
srcr &= ~mask;
 
/* Use Network mode as default */
-   ssi->i2s_mode = SSI_SCR_NET;
+   ssi->i2s_net = SSI_SCR_NET;
switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
case SND_SOC_DAIFMT_I2S:
regmap_update_bits(regs, REG_SSI_STCCR,
@@ -892,10 +892,10 @@ static int _fsl_ssi_set_dai_fmt(struct device *dev,
switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
case SND_SOC_DAIFMT_CBM_CFS:
case SND_SOC_DAIFMT_CBS_CFS:
-   ssi->i2s_mode |= SSI_SCR_I2S_MODE_MASTER;
+   ssi->i2s_net |= SSI_SCR_I2S_MODE_MASTER;
break;
case SND_SOC_DAIFMT_CBM_CFM:
-   ssi->i2s_mode |= SSI_SCR_I2S_MODE_SLAVE;
+   ssi->i2s_net |= SSI_SCR_I2S_MODE_SLAVE;
break;
default:
return -EINVAL;
@@ -920,12 +920,12 @@ static int _fsl_ssi_set_dai_fmt(struct device *dev,
break;
case SND_SOC_DAIFMT_AC97:
/* Data on falling edge of bclk, frame high, 1clk before data */
-   ssi->i2s_mode |= SSI_SCR_I2S_MODE_NORMAL;
+   ssi->i2s_net |= SSI_SCR_I2S_MODE_NORMAL;
break;
default:
return -EINVAL;
}
-   scr |= ssi->i2s_mode;
+   scr |= ssi->i2s_net;
 
/* DAI clock inversion */
switch (fmt & SND_SOC_DAIFMT_INV_MASK) {
diff --git a/sound/soc/fsl/fsl_ssi.h b/sound/soc/fsl/fsl_ssi.h
index 52b88f1..b610087 100644
--- a/sound/soc/fsl/fsl_ssi.h
+++ b/sound/soc/fsl/fsl_ssi.h
@@ -95,6 +95,7 @@
 #define SSI_SCR_I2S_MODE_SLAVE 0x0040
 #define SSI_SCR_SYN0x0010
 #define SSI_SCR_NET0x0008
+#define SSI_SCR_I2S_NET_MASK   (SSI_SCR_NET | SSI_SCR_I2S_MODE_MASK)
 #define SSI_SCR_RE 0x0004
 #define SSI_SCR_TE 0x0002
 #define SSI_SCR_SSIEN  0x0001
-- 
2.7.4



[PATCH v2 11/11] ASoC: fsl_ssi: Define ternary macros to simplify code

2017-12-12 Thread Nicolin Chen
Some regmap code looks redudant. So simplify it.

Signed-off-by: Nicolin Chen 
---
 sound/soc/fsl/fsl_ssi.c | 27 +++
 sound/soc/fsl/fsl_ssi.h |  4 
 2 files changed, 15 insertions(+), 16 deletions(-)

diff --git a/sound/soc/fsl/fsl_ssi.c b/sound/soc/fsl/fsl_ssi.c
index dd091eb..5b4fa43 100644
--- a/sound/soc/fsl/fsl_ssi.c
+++ b/sound/soc/fsl/fsl_ssi.c
@@ -405,13 +405,10 @@ static void fsl_ssi_rxtx_config(struct fsl_ssi *ssi, bool 
enable)
  */
 static void fsl_ssi_fifo_clear(struct fsl_ssi *ssi, bool is_rx)
 {
-   if (is_rx) {
-   regmap_update_bits(ssi->regs, REG_SSI_SOR,
-  SSI_SOR_RX_CLR, SSI_SOR_RX_CLR);
-   } else {
-   regmap_update_bits(ssi->regs, REG_SSI_SOR,
-  SSI_SOR_TX_CLR, SSI_SOR_TX_CLR);
-   }
+   bool tx = !is_rx;
+
+   regmap_update_bits(ssi->regs, REG_SSI_SOR,
+  SSI_SOR_xX_CLR(tx), SSI_SOR_xX_CLR(tx));
 }
 
 /**
@@ -666,6 +663,7 @@ static int fsl_ssi_set_bclk(struct snd_pcm_substream 
*substream,
struct snd_soc_dai *dai,
struct snd_pcm_hw_params *hw_params)
 {
+   bool tx2, tx = substream->stream == SNDRV_PCM_STREAM_PLAYBACK;
struct fsl_ssi *ssi = snd_soc_dai_get_drvdata(dai);
struct regmap *regs = ssi->regs;
int synchronous = ssi->cpu_dai_drv.symmetric_rates, ret;
@@ -753,10 +751,9 @@ static int fsl_ssi_set_bclk(struct snd_pcm_substream 
*substream,
(psr ? SSI_SxCCR_PSR : 0);
mask = SSI_SxCCR_PM_MASK | SSI_SxCCR_DIV2 | SSI_SxCCR_PSR;
 
-   if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK || synchronous)
-   regmap_update_bits(regs, REG_SSI_STCCR, mask, stccr);
-   else
-   regmap_update_bits(regs, REG_SSI_SRCCR, mask, stccr);
+   /* STCCR is used for RX in synchronous mode */
+   tx2 = tx || synchronous;
+   regmap_update_bits(regs, REG_SSI_SxCCR(tx2), mask, stccr);
 
if (!baudclk_is_used) {
ret = clk_set_rate(ssi->baudclk, baudrate);
@@ -784,6 +781,7 @@ static int fsl_ssi_hw_params(struct snd_pcm_substream 
*substream,
 struct snd_pcm_hw_params *hw_params,
 struct snd_soc_dai *dai)
 {
+   bool tx2, tx = substream->stream == SNDRV_PCM_STREAM_PLAYBACK;
struct fsl_ssi *ssi = snd_soc_dai_get_drvdata(dai);
struct regmap *regs = ssi->regs;
unsigned int channels = params_channels(hw_params);
@@ -829,11 +827,8 @@ static int fsl_ssi_hw_params(struct snd_pcm_substream 
*substream,
}
 
/* In synchronous mode, the SSI uses STCCR for capture */
-   if ((substream->stream == SNDRV_PCM_STREAM_PLAYBACK) ||
-   ssi->cpu_dai_drv.symmetric_rates)
-   regmap_update_bits(regs, REG_SSI_STCCR, SSI_SxCCR_WL_MASK, wl);
-   else
-   regmap_update_bits(regs, REG_SSI_SRCCR, SSI_SxCCR_WL_MASK, wl);
+   tx2 = tx || ssi->cpu_dai_drv.symmetric_rates;
+   regmap_update_bits(regs, REG_SSI_SxCCR(tx2), SSI_SxCCR_WL_MASK, wl);
 
return 0;
 }
diff --git a/sound/soc/fsl/fsl_ssi.h b/sound/soc/fsl/fsl_ssi.h
index b610087..de2fdc5 100644
--- a/sound/soc/fsl/fsl_ssi.h
+++ b/sound/soc/fsl/fsl_ssi.h
@@ -35,10 +35,12 @@
 #define REG_SSI_STCR   0x1c
 /* SSI Receive Configuration Register */
 #define REG_SSI_SRCR   0x20
+#define REG_SSI_SxCR(tx)   ((tx) ? REG_SSI_STCR : REG_SSI_SRCR)
 /* SSI Transmit Clock Control Register */
 #define REG_SSI_STCCR  0x24
 /* SSI Receive Clock Control Register */
 #define REG_SSI_SRCCR  0x28
+#define REG_SSI_SxCCR(tx)  ((tx) ? REG_SSI_STCCR : REG_SSI_SRCCR)
 /* SSI FIFO Control/Status Register */
 #define REG_SSI_SFCSR  0x2c
 /*
@@ -67,6 +69,7 @@
 #define REG_SSI_STMSK  0x48
 /* SSI  Receive Time Slot Mask Register */
 #define REG_SSI_SRMSK  0x4c
+#define REG_SSI_SxMSK(tx)  ((tx) ? REG_SSI_STMSK : REG_SSI_SRMSK)
 /*
  * SSI AC97 Channel Status Register
  *
@@ -249,6 +252,7 @@
 #define SSI_SOR_CLKOFF 0x0040
 #define SSI_SOR_RX_CLR 0x0020
 #define SSI_SOR_TX_CLR 0x0010
+#define SSI_SOR_xX_CLR(tx) ((tx) ? SSI_SOR_TX_CLR : SSI_SOR_RX_CLR)
 #define SSI_SOR_INIT   0x0008
 #define SSI_SOR_WAIT_SHIFT 1
 #define SSI_SOR_WAIT_MASK  0x0006
-- 
2.7.4



Re: [PATCH] powerpc/perf: Fix kfree memory allocated for nest pmus

2017-12-12 Thread Madhavan Srinivasan



On Thursday 07 December 2017 10:53 PM, Anju T Sudhakar wrote:

imc_common_cpuhp_mem_free() is the common function for all IMC (In-memory
Collection counters) domains to unregister cpuhotplug callback and free memory.
Since kfree of memory allocated for nest-imc (per_nest_pmu_arr) is in the common
code, all domains (core/nest/thread) can do the kfree in the failure case.

This could potentially create a call trace as shown below, where 
core(/thread/nest)
imc pmu initialization fails and in the failure path imc_common_cpuhp_mem_free()
free the memory(per_nest_pmu_arr), which is allocated by successfully registered
nest units.


The call trace is generated in a scenario where core-imc initialization is
made to fail and a cpuhotplug is performed in a p9 system.
During cpuhotplug ppc_nest_imc_cpu_offline() tries to access per_nest_pmu_arr,
which is already freed by core-imc.

[  136.563618] NIP [c0cb6a94] mutex_lock+0x34/0x90
[  136.563653] LR [c0cb6a88] mutex_lock+0x28/0x90
[  136.563687] Call Trace:
[  136.563707] [c016b7a93b90] [c0cb6a88] mutex_lock+0x28/0x90 
(unreliable)
[  136.563762] [c016b7a93bc0] [c02bc720] 
perf_pmu_migrate_context+0x90/0x3a0
[  136.563814] [c016b7a93c60] [c00f7a40] 
ppc_nest_imc_cpu_offline+0x190/0x1f0
[  136.563867] [c016b7a93cb0] [c0108140] 
cpuhp_invoke_callback+0x160/0x820
[  136.563918] [c016b7a93d30] [c010939c] 
cpuhp_thread_fun+0x1bc/0x270
[  136.563970] [c016b7a93d60] [c013d2b0] 
smpboot_thread_fn+0x250/0x290
[  136.564022] [c016b7a93dc0] [c0136f18] kthread+0x1a8/0x1b0
[  136.564067] [c016b7a93e30] [c000b4e8] 
ret_from_kernel_thread+0x5c/0x74

To address this scenario do the kfree(per_nest_pmu_arr) only in case of
nest-imc initialization failure, and when there is no other nest units 
registered.


My bad. Broke it when fixing the IMC_MAX_PMU. Sorry about it.

Reviewed-by: Madhavan Srinivasan 




Fixes: 73ce9aec65b1 ("powerpc/perf: Fix IMC_MAX_PMU macro")
Signed-off-by: Anju T Sudhakar 
---
  arch/powerpc/perf/imc-pmu.c | 4 +++-
  1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/arch/powerpc/perf/imc-pmu.c b/arch/powerpc/perf/imc-pmu.c
index 0ead3cd..4eb9e2b 100644
--- a/arch/powerpc/perf/imc-pmu.c
+++ b/arch/powerpc/perf/imc-pmu.c
@@ -1171,6 +1171,7 @@ static void imc_common_cpuhp_mem_free(struct imc_pmu 
*pmu_ptr)
if (nest_pmus == 1) {

cpuhp_remove_state(CPUHP_AP_PERF_POWERPC_NEST_IMC_ONLINE);
kfree(nest_imc_refc);
+   kfree(per_nest_pmu_arr);
}

if (nest_pmus > 0)
@@ -1195,7 +1196,6 @@ static void imc_common_cpuhp_mem_free(struct imc_pmu 
*pmu_ptr)
kfree(pmu_ptr->attr_groups[IMC_EVENT_ATTR]->attrs);
kfree(pmu_ptr->attr_groups[IMC_EVENT_ATTR]);
kfree(pmu_ptr);
-   kfree(per_nest_pmu_arr);
return;
  }

@@ -1309,6 +1309,8 @@ int init_imc_pmu(struct device_node *parent, struct 
imc_pmu *pmu_ptr, int pmu_id
ret = nest_pmu_cpumask_init();
if (ret) {
mutex_unlock(_init_lock);
+   kfree(nest_imc_refc);
+   kfree(per_nest_pmu_arr);
goto err_free;
}
}




Re: [PATCH 1/3] powerpc/perf: Remove thread_imc_pmu global variable from

2017-12-12 Thread Madhavan Srinivasan



On Monday 11 December 2017 11:28 AM, Anju T Sudhakar wrote:

Remove the global variable 'thread_imc_pmu', since it is not used in the code.


Reviewed-by: madhavan Srinivasan 

Maddy


Signed-off-by: Anju T Sudhakar 
---
  arch/powerpc/perf/imc-pmu.c | 2 --
  1 file changed, 2 deletions(-)

diff --git a/arch/powerpc/perf/imc-pmu.c b/arch/powerpc/perf/imc-pmu.c
index 4eb9e2b..ef7f9dd 100644
--- a/arch/powerpc/perf/imc-pmu.c
+++ b/arch/powerpc/perf/imc-pmu.c
@@ -40,7 +40,6 @@ static struct imc_pmu *core_imc_pmu;
  /* Thread IMC data structures and variables */

  static DEFINE_PER_CPU(u64 *, thread_imc_mem);
-static struct imc_pmu *thread_imc_pmu;
  static int thread_imc_mem_size;

  struct imc_pmu *imc_event_to_pmu(struct perf_event *event)
@@ -1263,7 +1262,6 @@ static int imc_mem_init(struct imc_pmu *pmu_ptr, struct 
device_node *parent,
return res;
}

-   thread_imc_pmu = pmu_ptr;
break;
default:
return -EINVAL;




Re: [PATCH 2/3] powerpc/perf: IMC code cleanup with some code refactoring

2017-12-12 Thread Madhavan Srinivasan



On Monday 11 December 2017 11:28 AM, Anju T Sudhakar wrote:

Factor out memory freeing part for attribute elements from
imc_common_cpuhp_mem_free().


Looks good to me.

Reviewed-by: Madhavan Srinivasan 


Signed-off-by: Anju T Sudhakar 
---
  arch/powerpc/perf/imc-pmu.c | 31 ---
  1 file changed, 20 insertions(+), 11 deletions(-)

diff --git a/arch/powerpc/perf/imc-pmu.c b/arch/powerpc/perf/imc-pmu.c
index ef7f9dd..71f425f 100644
--- a/arch/powerpc/perf/imc-pmu.c
+++ b/arch/powerpc/perf/imc-pmu.c
@@ -1157,6 +1157,15 @@ static void cleanup_all_thread_imc_memory(void)
}
  }

+/* Function to free the attr_groups which are dynamically allocated */
+static void imc_common_mem_free(struct imc_pmu *pmu_ptr)
+{
+   if (pmu_ptr->attr_groups[IMC_EVENT_ATTR])
+   kfree(pmu_ptr->attr_groups[IMC_EVENT_ATTR]->attrs);
+   kfree(pmu_ptr->attr_groups[IMC_EVENT_ATTR]);
+   kfree(pmu_ptr);
+}
+
  /*
   * Common function to unregister cpu hotplug callback and
   * free the memory.
@@ -1189,13 +1198,6 @@ static void imc_common_cpuhp_mem_free(struct imc_pmu 
*pmu_ptr)
cpuhp_remove_state(CPUHP_AP_PERF_POWERPC_THREAD_IMC_ONLINE);
cleanup_all_thread_imc_memory();
}
-
-   /* Only free the attr_groups which are dynamically allocated  */
-   if (pmu_ptr->attr_groups[IMC_EVENT_ATTR])
-   kfree(pmu_ptr->attr_groups[IMC_EVENT_ATTR]->attrs);
-   kfree(pmu_ptr->attr_groups[IMC_EVENT_ATTR]);
-   kfree(pmu_ptr);
-   return;
  }


@@ -1244,8 +1246,10 @@ static int imc_mem_init(struct imc_pmu *pmu_ptr, struct 
device_node *parent,
core_imc_refc = kcalloc(nr_cores, sizeof(struct imc_pmu_ref),
GFP_KERNEL);

-   if (!core_imc_refc)
+   if (!core_imc_refc) {
+   kfree(pmu_ptr->mem_info);
return -ENOMEM;
+   }

core_imc_pmu = pmu_ptr;
break;
@@ -1258,8 +1262,10 @@ static int imc_mem_init(struct imc_pmu *pmu_ptr, struct 
device_node *parent,
thread_imc_mem_size = pmu_ptr->counter_mem_size;
for_each_online_cpu(cpu) {
res = thread_imc_mem_alloc(cpu, 
pmu_ptr->counter_mem_size);
-   if (res)
+   if (res) {
+   cleanup_all_thread_imc_memory();
return res;
+   }
}

break;
@@ -1285,8 +1291,10 @@ int init_imc_pmu(struct device_node *parent, struct 
imc_pmu *pmu_ptr, int pmu_id
int ret;

ret = imc_mem_init(pmu_ptr, parent, pmu_idx);
-   if (ret)
-   goto err_free;
+   if (ret) {
+   imc_common_mem_free(pmu_ptr);
+   return ret;
+   }

switch (pmu_ptr->domain) {
case IMC_DOMAIN_NEST:
@@ -1353,6 +1361,7 @@ int init_imc_pmu(struct device_node *parent, struct 
imc_pmu *pmu_ptr, int pmu_id
return 0;

  err_free:
+   imc_common_mem_free(pmu_ptr);
imc_common_cpuhp_mem_free(pmu_ptr);
return ret;
  }




[v3 PATCH 3/3] powernv-cpufreq: Treat pstates as opaque 8-bit values

2017-12-12 Thread Gautham R. Shenoy
From: "Gautham R. Shenoy" 

On POWER8 and POWER9, the PMSR and the PMCR registers define pstates
to be 8-bit wide values. The device-tree exports pstates as 32-bit
wide values of which the lower byte is the actual pstate.

The current implementation in the kernel treats pstates as integer
type, since it used to use the sign of the pstate for performing some
boundary-checks. This is no longer required after the patch
"powernv-cpufreq: Fix pstate_to_idx() to handle non-continguous
pstates".

So, in this patch, we modify the powernv-cpufreq driver to uniformly
treat pstates as opaque 8-bit values obtained from the device-tree or
the PMCR. This simplifies the extract_pstate() helper function since
we no longer no longer require to worry about the sign-extentions.

Signed-off-by: Gautham R. Shenoy 
---
 drivers/cpufreq/powernv-cpufreq.c | 47 ---
 1 file changed, 19 insertions(+), 28 deletions(-)

diff --git a/drivers/cpufreq/powernv-cpufreq.c 
b/drivers/cpufreq/powernv-cpufreq.c
index 8e3dbca..8a4e2ce 100644
--- a/drivers/cpufreq/powernv-cpufreq.c
+++ b/drivers/cpufreq/powernv-cpufreq.c
@@ -110,12 +110,11 @@ struct global_pstate_info {
  * hashtable
  */
 struct pstate_idx_revmap_data {
-   int pstate_id;
+   u8 pstate_id;
unsigned int cpufreq_table_idx;
struct hlist_node hentry;
 };
 
-u32 pstate_sign_prefix;
 static bool rebooting, throttled, occ_reset;
 
 static const char * const throttle_reason[] = {
@@ -170,14 +169,9 @@ enum throttle_reason_type {
bool wof_enabled;
 } powernv_pstate_info;
 
-static inline int extract_pstate(u64 pmsr_val, unsigned int shift)
+static inline u8 extract_pstate(u64 pmsr_val, unsigned int shift)
 {
-   int ret = ((pmsr_val >> shift) & 0xFF);
-
-   if (!ret)
-   return ret;
-
-   return (pstate_sign_prefix | ret);
+   return ((pmsr_val >> shift) & 0xFF);
 }
 
 #define extract_local_pstate(x) extract_pstate(x, LPSTATE_SHIFT)
@@ -194,7 +188,7 @@ static inline int extract_pstate(u64 pmsr_val, unsigned int 
shift)
  *If @i is out of bound, this will return the pstate
  *corresponding to the nominal frequency.
  */
-static inline int idx_to_pstate(unsigned int i)
+static inline u8 idx_to_pstate(unsigned int i)
 {
if (unlikely(i >= powernv_pstate_info.nr_pstates)) {
pr_warn_once("idx_to_pstate: index %u is out of bound\n", i);
@@ -213,7 +207,7 @@ static inline int idx_to_pstate(unsigned int i)
  *this will return the index of the nominal
  *frequency.
  */
-static unsigned int pstate_to_idx(int pstate)
+static unsigned int pstate_to_idx(u8 pstate)
 {
unsigned int key = pstate % POWERNV_MAX_PSTATES;
struct pstate_idx_revmap_data *revmap_data;
@@ -223,7 +217,7 @@ static unsigned int pstate_to_idx(int pstate)
return revmap_data->cpufreq_table_idx;
}
 
-   pr_warn_once("pstate_to_idx: pstate %d not found\n", pstate);
+   pr_warn_once("pstate_to_idx: pstate 0x%x not found\n", pstate);
return powernv_pstate_info.nominal;
 }
 
@@ -291,7 +285,7 @@ static int init_powernv_pstates(void)
powernv_pstate_info.wof_enabled = true;
 
 next:
-   pr_info("cpufreq pstate min %d nominal %d max %d\n", pstate_min,
+   pr_info("cpufreq pstate min 0x%x nominal 0x%x max 0x%x\n", pstate_min,
pstate_nominal, pstate_max);
pr_info("Workload Optimized Frequency is %s in the platform\n",
(powernv_pstate_info.wof_enabled) ? "enabled" : "disabled");
@@ -323,8 +317,6 @@ static int init_powernv_pstates(void)
powernv_pstate_info.nr_pstates = nr_pstates;
pr_debug("NR PStates %d\n", nr_pstates);
 
-   pstate_sign_prefix = pstate_min & ~0xFF;
-
for (i = 0; i < nr_pstates; i++) {
u32 id = be32_to_cpu(pstate_ids[i]);
u32 freq = be32_to_cpu(pstate_freqs[i]);
@@ -333,14 +325,14 @@ static int init_powernv_pstates(void)
 
pr_debug("PState id %d freq %d MHz\n", id, freq);
powernv_freqs[i].frequency = freq * 1000; /* kHz */
-   powernv_freqs[i].driver_data = id;
+   powernv_freqs[i].driver_data = id & 0xFF;
 
revmap_data = (struct pstate_idx_revmap_data *)
  kmalloc(sizeof(*revmap_data), GFP_KERNEL);
 
-   revmap_data->pstate_id = id;
+   revmap_data->pstate_id = id & 0xFF;
revmap_data->cpufreq_table_idx = i;
-   key = id % POWERNV_MAX_PSTATES;
+   key = (revmap_data->pstate_id) % POWERNV_MAX_PSTATES;
hash_add(pstate_revmap, _data->hentry, key);
 
if (id == pstate_max)
@@ -364,14 +356,13 @@ static int init_powernv_pstates(void)
 }
 
 /* Returns the CPU frequency corresponding to the pstate_id. */
-static unsigned 

[v3 PATCH 0/3] powernv-cpufreq: Multiple pstate related fixes.

2017-12-12 Thread Gautham R. Shenoy
From: "Gautham R. Shenoy" 

 This is a third version of the patch to fix pstate related issues in
 the powernv-cpufreq driver.

 The previous versions can be found here:
 [v2]: https://lkml.org/lkml/2017/12/7/1562
 [v1]: https://lkml.org/lkml/2017/11/29/1338

 On POWERNV platform, Pstates are 8-bit values. On POWER8 they are
 negatively numbered while on POWER9 they are positively
 numbered. Thus, on POWER9, the maximum number of pstates could be as
 high as 256.

 In multiple places, the current code interprets pstates as a signed
 8-bit value which subsequently gets assigned to a signed integer
 variable. This causes a problem on POWER9 platforms which have more
 than 128 pstates.  On such systems, on a CPU that is in a lower
 pstate whose number is greater than 128, querying the current pstate
 via the pstate_to_idx() returns a "pstate X is out of bound" error
 message and the current pstate is reported as the nominal
 pstate. This is due to the manner in which the bounds are checked in
 pstate_to_idx which again depends on the sign of pstates and whether
 the pstates max to min are monotonically increasing or decreasing.

 Further the current code makes a couple of assumptions which is not
 guaranteed by the device-tree bindings:

  1) Pstate ids are continguous.

  2) Every Pstate should always lie between the max and the min
 pstates that are explicitly reported in the device tree.

Both these assumptions are unwarranted and can change on future
platforms.

In this patch-series, we fix the implementation via the following
changes:

PATCH 1: Define a helper function to correctly extract the pstates
 from the PMCR and take care of any sign extentions. This is
 an immediate fix to add the ability to handle more than 128
 pstates on POWER9 systems.

PATCH 2: Define a hash-map which will return the index into the
 cpufreq frequency table for a given pstate. Use this hashmap
 in the implementation of pstate_to_idx(). This does away with
 the assumptions (1) mentioned above, and will work with non
 continguous pstate ids. If no entry exists for a particular
 pstate, then such a pstate is treated as being out of
 bounds. This gets rid of assumption (2).

PATCH 3: Treat pstates as opaque 8-bit values consistent with the
 definitions in the PMSR and PMCR. We no longer need any
 sign-extentions nor do we require to interpret the sign of
 the pstates anywhere in the code.


Gautham R. Shenoy (3):
  powernv-cpufreq: Add helper to extract pstate from PMSR
  powernv-cpufreq: Fix pstate_to_idx() to handle non-continguous pstates
  powernv-cpufreq: Treat pstates as opaque 8-bit values

 drivers/cpufreq/powernv-cpufreq.c | 139 --
 1 file changed, 90 insertions(+), 49 deletions(-)

-- 
1.9.4



[v3 PATCH 2/3] powernv-cpufreq: Fix pstate_to_idx() to handle non-continguous pstates

2017-12-12 Thread Gautham R. Shenoy
From: "Gautham R. Shenoy" 

The code in powernv-cpufreq, makes the following two assumptions which
are not guaranteed by the device-tree bindings:

1) Pstate ids are continguous: This is used in pstate_to_idx() to
   obtain the reverse map from a pstate to it's corresponding
   entry into the cpufreq frequency table.

2) Every Pstate should always lie between the max and the min
   pstates that are explicitly reported in the device tree: This
   is used to determine whether a pstate reported by the PMSR is
   out of bounds.

Both these assumptions are unwarranted and can change on future
platforms.

In this patch, we maintain the reverse map from a pstate to it's index
in the cpufreq frequency table and use this in pstate_to_idx(). This
does away with the assumptions (1) mentioned above, and will work with
non continguous pstate ids. If no entry exists for a particular
pstate, then such a pstate is treated as being out of bounds. This
gets rid of assumption (2).

On all the existing platforms, where the pstates are 8-bit long
values, the new implementation of pstate_to_idx() takes constant time.

Signed-off-by: Gautham R. Shenoy 
---
 drivers/cpufreq/powernv-cpufreq.c | 85 +--
 1 file changed, 63 insertions(+), 22 deletions(-)

diff --git a/drivers/cpufreq/powernv-cpufreq.c 
b/drivers/cpufreq/powernv-cpufreq.c
index f46b60f..8e3dbca 100644
--- a/drivers/cpufreq/powernv-cpufreq.c
+++ b/drivers/cpufreq/powernv-cpufreq.c
@@ -29,6 +29,7 @@
 #include 
 #include 
 #include 
+#include 
 #include 
 
 #include 
@@ -38,7 +39,8 @@
 #include 
 #include 
 
-#define POWERNV_MAX_PSTATES256
+#define POWERNV_MAX_PSTATES_ORDER  8
+#define POWERNV_MAX_PSTATES(1UL << (POWERNV_MAX_PSTATES_ORDER))
 #define PMSR_PSAFE_ENABLE  (1UL << 30)
 #define PMSR_SPR_EM_DISABLE(1UL << 31)
 #define MAX_PSTATE_SHIFT   32
@@ -92,6 +94,27 @@ struct global_pstate_info {
 };
 
 static struct cpufreq_frequency_table powernv_freqs[POWERNV_MAX_PSTATES+1];
+
+DEFINE_HASHTABLE(pstate_revmap, POWERNV_MAX_PSTATES_ORDER);
+/**
+ * struct pstate_idx_revmap_data: Entry in the hashmap pstate_revmap
+ *   indexed by a function of pstate id.
+ *
+ * @pstate_id: pstate id for this entry.
+ *
+ * @cpufreq_table_idx: Index into the powernv_freqs
+ *cpufreq_frequency_table for frequency
+ *corresponding to pstate_id.
+ *
+ * @hentry: hlist_node that hooks this entry into the pstate_revmap
+ * hashtable
+ */
+struct pstate_idx_revmap_data {
+   int pstate_id;
+   unsigned int cpufreq_table_idx;
+   struct hlist_node hentry;
+};
+
 u32 pstate_sign_prefix;
 static bool rebooting, throttled, occ_reset;
 
@@ -161,39 +184,47 @@ static inline int extract_pstate(u64 pmsr_val, unsigned 
int shift)
 #define extract_global_pstate(x) extract_pstate(x, GPSTATE_SHIFT)
 #define extract_max_pstate(x)  extract_pstate(x, MAX_PSTATE_SHIFT)
 
-/* Use following macros for conversions between pstate_id and index */
+/* Use following functions for conversions between pstate_id and index */
+
+/**
+ * idx_to_pstate : Returns the pstate id corresponding to the
+ *frequency in the cpufreq frequency table
+ *powernv_freqs indexed by @i.
+ *
+ *If @i is out of bound, this will return the pstate
+ *corresponding to the nominal frequency.
+ */
 static inline int idx_to_pstate(unsigned int i)
 {
if (unlikely(i >= powernv_pstate_info.nr_pstates)) {
-   pr_warn_once("index %u is out of bound\n", i);
+   pr_warn_once("idx_to_pstate: index %u is out of bound\n", i);
return powernv_freqs[powernv_pstate_info.nominal].driver_data;
}
 
return powernv_freqs[i].driver_data;
 }
 
-static inline unsigned int pstate_to_idx(int pstate)
+/**
+ * pstate_to_idx : Returns the index in the cpufreq frequencytable
+ *powernv_freqs for the frequency whose corresponding
+ *pstate id is @pstate.
+ *
+ *If no frequency corresponding to @pstate is found,
+ *this will return the index of the nominal
+ *frequency.
+ */
+static unsigned int pstate_to_idx(int pstate)
 {
-   int min = powernv_freqs[powernv_pstate_info.min].driver_data;
-   int max = powernv_freqs[powernv_pstate_info.max].driver_data;
+   unsigned int key = pstate % POWERNV_MAX_PSTATES;
+   struct pstate_idx_revmap_data *revmap_data;
 
-   if (min > 0) {
-   if (unlikely((pstate < max) || (pstate > min))) {
-   pr_warn_once("pstate %d is out of bound\n", pstate);
-   return powernv_pstate_info.nominal;
-   }
-   } else {
-   if (unlikely((pstate > max) || (pstate < min))) {
-   pr_warn_once("pstate %d is out of 

[v3 PATCH 1/3] powernv-cpufreq: Add helper to extract pstate from PMSR

2017-12-12 Thread Gautham R. Shenoy
From: "Gautham R. Shenoy" 

On POWERNV platform, the fields for pstates in the Power Management
Status Register (PMSR) and the Power Management Control Register
(PMCR) are 8-bits wide. On POWER8 the pstates are negatively numbered
while on POWER9 they are positively numbered.

The device-tree exports pstates as 32-bit entries. The device-tree
implementation sign-extends the 8-bit pstate values to obtain the
corresponding 32-bit entry.

Eg: On POWER8, a pstate value 0x82 [-126] is represented in the
device-tree as 0xfff82 while on POWER9, the same value 0x82 [130]
is represented in the device-tree as 0x0082.

The powernv-cpufreq driver implementation represents pstates using the
integer type. In multiple places in the driver, the code interprets
the pstates extracted from the PMSR as a signed byte and assigns it to
a integer variable to get the sign-extention.

On POWER9 platforms which have greater than 128 pstates, this results
in the driver performing incorrect sign-extention, and thereby
treating a legitimate pstate (say 130) as an invalid pstates (since it
is interpreted as -126).

This patch fixes the issue by implementing a helper function to
extract Pstates from PMSR register, and correctly sign-extend it to be
consistent with the values provided by the device-tree.

Signed-off-by: Gautham R. Shenoy 
---
 drivers/cpufreq/powernv-cpufreq.c | 37 +++--
 1 file changed, 23 insertions(+), 14 deletions(-)

diff --git a/drivers/cpufreq/powernv-cpufreq.c 
b/drivers/cpufreq/powernv-cpufreq.c
index b6d7c4c..f46b60f 100644
--- a/drivers/cpufreq/powernv-cpufreq.c
+++ b/drivers/cpufreq/powernv-cpufreq.c
@@ -41,11 +41,9 @@
 #define POWERNV_MAX_PSTATES256
 #define PMSR_PSAFE_ENABLE  (1UL << 30)
 #define PMSR_SPR_EM_DISABLE(1UL << 31)
-#define PMSR_MAX(x)((x >> 32) & 0xFF)
+#define MAX_PSTATE_SHIFT   32
 #define LPSTATE_SHIFT  48
 #define GPSTATE_SHIFT  56
-#define GET_LPSTATE(x) (((x) >> LPSTATE_SHIFT) & 0xFF)
-#define GET_GPSTATE(x) (((x) >> GPSTATE_SHIFT) & 0xFF)
 
 #define MAX_RAMP_DOWN_TIME 5120
 /*
@@ -94,6 +92,7 @@ struct global_pstate_info {
 };
 
 static struct cpufreq_frequency_table powernv_freqs[POWERNV_MAX_PSTATES+1];
+u32 pstate_sign_prefix;
 static bool rebooting, throttled, occ_reset;
 
 static const char * const throttle_reason[] = {
@@ -148,6 +147,20 @@ enum throttle_reason_type {
bool wof_enabled;
 } powernv_pstate_info;
 
+static inline int extract_pstate(u64 pmsr_val, unsigned int shift)
+{
+   int ret = ((pmsr_val >> shift) & 0xFF);
+
+   if (!ret)
+   return ret;
+
+   return (pstate_sign_prefix | ret);
+}
+
+#define extract_local_pstate(x) extract_pstate(x, LPSTATE_SHIFT)
+#define extract_global_pstate(x) extract_pstate(x, GPSTATE_SHIFT)
+#define extract_max_pstate(x)  extract_pstate(x, MAX_PSTATE_SHIFT)
+
 /* Use following macros for conversions between pstate_id and index */
 static inline int idx_to_pstate(unsigned int i)
 {
@@ -278,6 +291,9 @@ static int init_powernv_pstates(void)
 
powernv_pstate_info.nr_pstates = nr_pstates;
pr_debug("NR PStates %d\n", nr_pstates);
+
+   pstate_sign_prefix = pstate_min & ~0xFF;
+
for (i = 0; i < nr_pstates; i++) {
u32 id = be32_to_cpu(pstate_ids[i]);
u32 freq = be32_to_cpu(pstate_freqs[i]);
@@ -438,17 +454,10 @@ struct powernv_smp_call_data {
 static void powernv_read_cpu_freq(void *arg)
 {
unsigned long pmspr_val;
-   s8 local_pstate_id;
struct powernv_smp_call_data *freq_data = arg;
 
pmspr_val = get_pmspr(SPRN_PMSR);
-
-   /*
-* The local pstate id corresponds bits 48..55 in the PMSR.
-* Note: Watch out for the sign!
-*/
-   local_pstate_id = (pmspr_val >> 48) & 0xFF;
-   freq_data->pstate_id = local_pstate_id;
+   freq_data->pstate_id = extract_local_pstate(pmspr_val);
freq_data->freq = pstate_id_to_freq(freq_data->pstate_id);
 
pr_debug("cpu %d pmsr %016lX pstate_id %d frequency %d kHz\n",
@@ -522,7 +531,7 @@ static void powernv_cpufreq_throttle_check(void *data)
chip = this_cpu_read(chip_info);
 
/* Check for Pmax Capping */
-   pmsr_pmax = (s8)PMSR_MAX(pmsr);
+   pmsr_pmax = extract_max_pstate(pmsr);
pmsr_pmax_idx = pstate_to_idx(pmsr_pmax);
if (pmsr_pmax_idx != powernv_pstate_info.max) {
if (chip->throttled)
@@ -645,8 +654,8 @@ void gpstate_timer_handler(struct timer_list *t)
 * value. Hence, read from PMCR to get correct data.
 */
val = get_pmspr(SPRN_PMCR);
-   freq_data.gpstate_id = (s8)GET_GPSTATE(val);
-   freq_data.pstate_id = (s8)GET_LPSTATE(val);
+   freq_data.gpstate_id = extract_global_pstate(val);
+   freq_data.pstate_id = extract_local_pstate(val);
if (freq_data.gpstate_id  == 

Re: [PATCH] On ppc64le we HAVE_RELIABLE_STACKTRACE

2017-12-12 Thread Torsten Duwe
On Tue, Dec 12, 2017 at 01:12:37PM +0100, Miroslav Benes wrote:
> 
> I think that this is not enough. You need to also implement 
> save_stack_trace_tsk_reliable() for powerpc defined as __weak in 
> kernel/stacktrace.c. See arch/x86/kernel/stacktrace.c for reference, but I 
> think it would be much much simpler here given the changelog description.

Is there an exhaustive, definite, non-x86-centric description of the cases
this function needs to look for? Maybe some sort of formal specification?

Torsten


Re: [1/3] powerpc/boot: Only build uartlite if XILINX_VIRTEX=y

2017-12-12 Thread Michael Ellerman
On Wed, 2017-11-08 at 11:05:27 UTC, Michael Ellerman wrote:
> The serial code in uartlite.c only matches if we find one of two
> Xilinx (xlnx) nodes in the device tree, there's no need to build or
> link the code on other platforms.
> 
> As far as I can tell CONFIG_XILINX_VIRTEX is the appropriate symbol to
> use to conditionally compile the code.
> 
> Signed-off-by: Michael Ellerman 

Series applied to powerpc next.

https://git.kernel.org/powerpc/c/3d6bf693d8bc63f2e5eca7373916c4

cheers


Re: [v5,1/3] powerpc/kernel: Separate SR-IOV Calls

2017-12-12 Thread Michael Ellerman
On Thu, 2017-11-09 at 14:00:33 UTC, "Bryant G. Ly" wrote:
> SR-IOV can now be enabled in PowerNV platforms and Pseries
> platforms. Therefore, the appropriate calls were moved to
> machine dependent code instead of definition at compile time.
> 
> Signed-off-by: Bryant G. Ly 
> Signed-off-by: Juan J. Alvarez 

Series applied to powerpc next, thanks.

https://git.kernel.org/powerpc/c/988fc3ba5653278a8c14d6ccf68737

cheers


Re: powerpc/32: Add .data.rel* sections explicitly

2017-12-12 Thread Michael Ellerman
On Mon, 2017-11-13 at 12:06:55 UTC, Nicholas Piggin wrote:
> Match powerpc/64 and include .data.rel* input sections in the .data output
> section explicitly.
> 
> This solves the warning:
> 
> powerpc-linux-gnu-ld: warning: orphan section `.data.rel.ro' from 
> `arch/powerpc/kernel/head_44x.o' being placed in section `.data.rel.ro'.
> 
> Link: https://lists.01.org/pipermail/kbuild-all/2017-November/040010.html
> Reported-by: kbuild test robot 
> Signed-off-by: Nicholas Piggin 

Applied to powerpc next, thanks.

https://git.kernel.org/powerpc/c/a10726075dec4ceb050c2f775e5436

cheers


Re: [2/4] powerpc/64: do not trace irqs-off at interrupt return to soft-disabled context

2017-12-12 Thread Michael Ellerman
On Thu, 2017-11-16 at 16:00:50 UTC, Nicholas Piggin wrote:
> When an interrupt is returning to a soft-disabled context (which can
> happen for non-maskable interrupts or synchronous interrupts), it goes
> through the motions of soft-disabling again, including calling
> TRACE_DISABLE_INTS (i.e., trace_hardirqs_off()).
> 
> This is not necessary, because we must already be soft-disabled in the
> interrupt context, it also may be causing crashes in the irq tracing
> code to re-enter as an nmi. Replace it with a warning to ensure that
> soft-interrupts are still disabled.
> 
> Signed-off-by: Nicholas Piggin 

Applied to powerpc next, thanks.

https://git.kernel.org/powerpc/c/acb1feab320e38588fccc568e37677

cheers


Re: [2/2] powerpc: Reduce log level of "OPAL detected !" message

2017-12-12 Thread Michael Ellerman
On Wed, 2017-11-22 at 06:01:06 UTC, Benjamin Herrenschmidt wrote:
> This message isn't terribly useful.
> 
> Signed-off-by: Benjamin Herrenschmidt 

Applied to powerpc next, thanks.

https://git.kernel.org/powerpc/c/5138b31422efec897461951f7ce72e

cheers


Re: [v2,1/4] 44x/fsp2: add fsp2 headers

2017-12-12 Thread Michael Ellerman
On Fri, 2017-12-01 at 15:58:24 UTC, Ivan Mikhaylov wrote:
> add cmu, plbX, l2, ddr3/4, crcs register definitions.
> add mfcmu, mtcmu functions for indirect access to cmu.
> add mtl2, mfl2 same for l2 cache core reg set.
> 
> Signed-off-by: Ivan Mikhaylov 

Series applied to powerpc next, thanks.

https://git.kernel.org/powerpc/c/494d82ceae7f3b9fdb5154b4469e5b

cheers


Re: [PATCH] On ppc64le we HAVE_RELIABLE_STACKTRACE

2017-12-12 Thread Miroslav Benes
On Tue, 12 Dec 2017, Torsten Duwe wrote:

> Hi all,
> 
> The "Power Architecture 64-Bit ELF V2 ABI" says in section 2.3.2.3:
> 
> [...] There are several rules that must be adhered to in order to ensure
> reliable and consistent call chain backtracing:
> 
> * Before a function calls any other function, it shall establish its
>   own stack frame, whose size shall be a multiple of 16 bytes.
> 
>  – In instances where a function’s prologue creates a stack frame, the
>back-chain word of the stack frame shall be updated atomically with
>the value of the stack pointer (r1) when a back chain is implemented.
>(This must be supported as default by all ELF V2 ABI-compliant
>environments.)
> [...]
>  – The function shall save the link register that contains its return
>address in the LR save doubleword of its caller’s stack frame before
>calling another function.
> 
> To me this sounds like the equivalent of HAVE_RELIABLE_STACKTRACE.
> This patch may be unneccessarily limited to ppc64le, but OTOH the only
> user of this flag so far is livepatching, which is only implemented on
> PPCs with 64-LE, a.k.a. ELF ABI v2.
> 
> Signed-off-by: Torsten Duwe 
> 
> ---
> diff --git a/arch/powerpc/Kconfig b/arch/powerpc/Kconfig
> index c51e6ce42e7a..3e3a6ab2e089 100644
> --- a/arch/powerpc/Kconfig
> +++ b/arch/powerpc/Kconfig
> @@ -218,6 +218,7 @@ config PPC
>   select HAVE_PERF_USER_STACK_DUMP
>   select HAVE_RCU_TABLE_FREE  if SMP
>   select HAVE_REGS_AND_STACK_ACCESS_API
> + select HAVE_RELIABLE_STACKTRACE if PPC64 && CPU_LITTLE_ENDIAN
>   select HAVE_SYSCALL_TRACEPOINTS
>   select HAVE_VIRT_CPU_ACCOUNTING
>   select HAVE_IRQ_TIME_ACCOUNTING

I think that this is not enough. You need to also implement 
save_stack_trace_tsk_reliable() for powerpc defined as __weak in 
kernel/stacktrace.c. See arch/x86/kernel/stacktrace.c for reference, but I 
think it would be much much simpler here given the changelog description.

Thanks,
Miroslav

[PATCH] KVM: PPC: Book3S: fix XIVE migration of pending interrupts

2017-12-12 Thread Cédric Le Goater
When restoring a pending interrupt, we are setting the Q bit to force
a retrigger in xive_finish_unmask(). But we also need to force an EOI
in this case to reach the same initial state : P=1, Q=0.

This can be done by not setting 'old_p' for pending interrupts which
will inform xive_finish_unmask() that an EOI needs to be sent.

Suggested-by: Benjamin Herrenschmidt 
Signed-off-by: Cédric Le Goater 
---

 Tested with a guest running iozone.

 arch/powerpc/kvm/book3s_xive.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/arch/powerpc/kvm/book3s_xive.c b/arch/powerpc/kvm/book3s_xive.c
index bf457843e032..b5e6d227a034 100644
--- a/arch/powerpc/kvm/book3s_xive.c
+++ b/arch/powerpc/kvm/book3s_xive.c
@@ -1558,7 +1558,7 @@ static int xive_set_source(struct kvmppc_xive *xive, long 
irq, u64 addr)
 
/*
 * Restore P and Q. If the interrupt was pending, we
-* force both P and Q, which will trigger a resend.
+* force Q and !P, which will trigger a resend.
 *
 * That means that a guest that had both an interrupt
 * pending (queued) and Q set will restore with only
@@ -1566,7 +1566,7 @@ static int xive_set_source(struct kvmppc_xive *xive, long 
irq, u64 addr)
 * is perfectly fine as coalescing interrupts that haven't
 * been presented yet is always allowed.
 */
-   if (val & KVM_XICS_PRESENTED || val & KVM_XICS_PENDING)
+   if (val & KVM_XICS_PRESENTED && !(val & KVM_XICS_PENDING))
state->old_p = true;
if (val & KVM_XICS_QUEUED || val & KVM_XICS_PENDING)
state->old_q = true;
-- 
2.13.6



Re: selftests/powerpc: fix build error in powerpc ptrace selftests.

2017-12-12 Thread Michael Ellerman
On Fri, 2017-09-01 at 02:17:14 UTC, wei.guo.si...@gmail.com wrote:
> From: Simon Guo 
> 
> GCC 7 will take "r2" in clobber list as an error will it will get following
> build errors for powerpc ptrace selftests even with -fno-pic option:
>   ptrace-tm-vsx.c: In function ‘tm_vsx’:
>   ptrace-tm-vsx.c:42:2: error: PIC register clobbered by ‘r2’ in ‘asm’
> asm __volatile__(
> ^~~
>   make[1]: *** [ptrace-tm-vsx] Error 1
>   ptrace-tm-spd-vsx.c: In function ‘tm_spd_vsx’:
>   ptrace-tm-spd-vsx.c:55:2: error: PIC register clobbered by ‘r2’ in 
> ‘asm’
> asm __volatile__(
> ^~~
>   make[1]: *** [ptrace-tm-spd-vsx] Error 1
>   ptrace-tm-spr.c: In function ‘tm_spr’:
>   ptrace-tm-spr.c:46:2: error: PIC register clobbered by ‘r2’ in ‘asm’
> asm __volatile__(
> ^~~
> 
> This patch fix the build error by removing "r2" out of clobber list.
> 
> Reported-by: Seth Forshee 
> Signed-off-by: Simon Guo 
> Tested-by: Seth Forshee 

Applied to powerpc next, thanks.

https://git.kernel.org/powerpc/c/f36dbfe1a504b85c7b3bf89fdd

cheers


Re: [v6] powerpc/vdso64: Add support for CLOCK_{REALTIME/MONOTONIC}_COARSE

2017-12-12 Thread Michael Ellerman
On Mon, 2017-10-16 at 05:49:14 UTC, Santosh Sivaraj wrote:
> Current vDSO64 implementation does not have support for coarse clocks
> (CLOCK_MONOTONIC_COARSE, CLOCK_REALTIME_COARSE), for which it falls back
> to system call, increasing the response time, vDSO implementation reduces
> the cycle time. Below is a benchmark of the difference in execution times.
> 
> (Non-coarse clocks are also included just for completion)
> 
> clock-gettime-realtime: syscall: 172 nsec/call
> clock-gettime-realtime:libc: 28 nsec/call
> clock-gettime-realtime:vdso: 22 nsec/call
> clock-gettime-monotonic: syscall: 171 nsec/call
> clock-gettime-monotonic:libc: 30 nsec/call
> clock-gettime-monotonic:vdso: 25 nsec/call
> clock-gettime-realtime-coarse: syscall: 153 nsec/call
> clock-gettime-realtime-coarse:libc: 16 nsec/call
> clock-gettime-realtime-coarse:vdso: 10 nsec/call
> clock-gettime-monotonic-coarse: syscall: 167 nsec/call
> clock-gettime-monotonic-coarse:libc: 17 nsec/call
> clock-gettime-monotonic-coarse:vdso: 11 nsec/call
> 
> CC: Benjamin Herrenschmidt 
> Reviewed-by: Naveen N. Rao 
> Signed-off-by: Santosh Sivaraj 

Applied to powerpc next, thanks.

https://git.kernel.org/powerpc/c/5c929885f1bb4b77f85b1769c49405

cheers


Re: [v4.2] powerpc/modules: Don't try to restore r2 after a sibling call

2017-12-12 Thread Michael Ellerman
On Thu, 2017-11-16 at 17:45:37 UTC, Josh Poimboeuf wrote:
> 
> From: Josh Poimboeuf 
> Subject: [PATCH v4.2] powerpc/modules: Don't try to restore r2 after a 
> sibling call
> 
> When attempting to load a livepatch module, I got the following error:
> 
>   module_64: patch_module: Expect noop after relocate, got 3c82
> 
> The error was triggered by the following code in
> unregister_netdevice_queue():
> 
>   14c:   00 00 00 48 b   14c 
>  14c: R_PPC64_REL24  net_set_todo
>   150:   00 00 82 3c addis   r4,r2,0
> 
> GCC didn't insert a nop after the branch to net_set_todo() because it's
> a sibling call, so it never returns.  The nop isn't needed after the
> branch in that case.
> 
> Signed-off-by: Josh Poimboeuf 
> Acked-by: Naveen N. Rao 

Applied to powerpc next, thanks.

https://git.kernel.org/powerpc/c/b9eab08d012fa093947b230f9a8725

cheers


Re: [v4, 1/3] kernel/modules: Add REL24 relocation support of livepatch symbols

2017-12-12 Thread Michael Ellerman
On Tue, 2017-11-14 at 09:29:08 UTC, Kamalesh Babulal wrote:
> Livepatch re-uses module loader function apply_relocate_add() to write
> relocations, instead of managing them by arch-dependent
> klp_write_module_reloc() function.
> 
> apply_relocate_add() doesn't understand livepatch symbols (marked with
> SHN_LIVEPATCH symbol section index) and assumes them to be local symbols
> by default for R_PPC64_REL24 relocation type. It fails with an error,
> when trying to calculate offset with local_entry_offset():
> 
>  module_64: kpatch_meminfo: REL24 -1152921504897399800 out of range!
> 
> Whereas livepatch symbols are essentially SHN_UNDEF, should be
> called via stub used for global calls. This issue can be fixed by
> teaching apply_relocate_add() to handle both SHN_UNDEF/SHN_LIVEPATCH
> symbols via the same stub. This patch extends SHN_UNDEF code to handle
> livepatch symbols too.
> 
> Signed-off-by: Kamalesh Babulal 
> CC: Balbir Singh 
> Cc: Naveen N. Rao 
> Cc: Josh Poimboeuf 
> Cc: Jessica Yu 
> Cc: Ananth N Mavinakayanahalli 
> Cc: Aravinda Prasad 
> Cc: Torsten Duwe 

Applied to powerpc next, thanks.

https://git.kernel.org/powerpc/c/a443bf6e8a7674b86221f4922cae82

cheers


Re: [v4,3/3] powerpc/modules: Improve restore_r2() error message

2017-12-12 Thread Michael Ellerman
On Tue, 2017-11-14 at 09:29:10 UTC, Kamalesh Babulal wrote:
> From: Josh Poimboeuf 
> 
> Print the function address associated with the restore_r2() error to
> make it easier to debug the problem.
> 
> Also clarify the wording a bit.
> 
> Before:
> 
>   module_64: patch_foo: Expect noop after relocate, got 3c82
> 
> After:
> 
>   module_64: patch_foo: Expected noop after call, got 7c630034 at 
> netdev_has_upper_dev+0x54/0xb0 [patch_foo]
> 
> Signed-off-by: Josh Poimboeuf 
> Signed-off-by: Kamalesh Babulal 

Applied to powerpc next, thanks.

https://git.kernel.org/powerpc/c/1ea61ea23985c0f15c027e4c0ac022

cheers


Re: [1/2] selftests/powerpc: Check for pthread errors in tm-unavailable

2017-12-12 Thread Michael Ellerman
On Tue, 2017-11-21 at 07:17:19 UTC, Cyril Bur wrote:
> Signed-off-by: Cyril Bur 
> Signed-off-by: Gustavo Romero 

Applied to powerpc next, thanks.

https://git.kernel.org/powerpc/c/5783ee6ec3d3323a04cc69764d57ca

cheers


Re: [1/2] powerpc: Remove DEBUG define in 64-bit early setup code

2017-12-12 Thread Michael Ellerman
On Wed, 2017-11-22 at 06:01:05 UTC, Benjamin Herrenschmidt wrote:
> This statement causes some not very useful messages to always
> be printed on the serial port at boot, even on quiet boots.
> 
> Signed-off-by: Benjamin Herrenschmidt 

Applied to powerpc next, thanks.

https://git.kernel.org/powerpc/c/10de741fd322c31f6c4f07869f4c6f

cheers


Re: [powerpc-next] Fix powerpc64 alignment of .toc section in kernel modules

2017-12-12 Thread Michael Ellerman
On Wed, 2017-12-06 at 19:12:28 UTC, Desnes Augusto Nunes do Rosario wrote:
> powerpc64 gcc can generate code that offsets an address, to access part of
> an object in memory. If the address is a -mcmodel=medium toc pointer
> relative address then code like the following is possible.
> 
>  addis r9,r2,var@toc@ha
>  ld r3,var@toc@l(r9)
>  ld r4,(var+8)@toc@l(r9)
> 
> This works fine so long as var is naturally aligned, *and* r2 is
> sufficiently aligned. If not, there is a possibility that the offset added
> to access var+8 wraps over a n*64k+32k boundary. Modules don't have any
> guarantee that r2 is sufficiently aligned. Moreover, code generated by
> older compilers generates a .toc section with 2**0 alignment, which can
> result in relocation failures at module load time even without the wrap
> problem.
> 
> Thus, this patch links modules with an aligned .toc section (Makefile and
> module.lds changes), and forces alignment for out of tree modules or those
> without a .toc section (module_64.c changes).
> 
> Signed-off-by: Alan Modra 
> [ desnesn: updated patch to apply to powerpc-next kernel v4.15 ]
> Signed-off-by: Desnes A. Nunes do Rosario 

Applied to powerpc next, thanks.

https://git.kernel.org/powerpc/c/5c45b5280196a92c4437f5648209c5

cheers


Re: powerpc: Use pr_warn instead of pr_warning

2017-12-12 Thread Joe Perches
On Tue, 2017-12-12 at 22:39 +1100, Michael Ellerman wrote:
> On Tue, 2016-10-25 at 04:00:08 UTC, Joe Perches wrote:
> > At some point, pr_warning will be removed so all logging messages use
> > a consistent _warn style.
> > 
> > Update arch/powerpc/
> > 
> > Miscellanea:
> > 
> > o Coalesce formats
> > o Realign arguments
> > o Use %s, __func__ instead of embedded function names
> > o Remove unnecessary line continuations
> > 
> > Signed-off-by: Joe Perches 
> > Acked-by: Geoff Levand 
> 
> Applied to powerpc next, thanks.
> 
> https://git.kernel.org/powerpc/c/f2c2cbcc35d47f1471a04155ac3575

OK, thanks.

But perhaps a year+ patch latency is a bit extended?


[PATCH] powerpc/perf: Dereference bhrb entries safely

2017-12-12 Thread Ravi Bangoria
It may very well happen that branch instructions recorded by
bhrb entries already get unmapped before they get processed by
the kernel. Hence, trying to dereference such memory location
will endup in a crash. Ex,

Unable to handle kernel paging request for data at address 
0xc00819c41764
Faulting instruction address: 0xc0084a14
NIP [c0084a14] branch_target+0x4/0x70
LR [c00eb828] record_and_restart+0x568/0x5c0
Call Trace:
[c00eb3b4] record_and_restart+0xf4/0x5c0 (unreliable)
[c00ec378] perf_event_interrupt+0x298/0x460
[c0027964] performance_monitor_exception+0x54/0x70
[c0009ba4] performance_monitor_common+0x114/0x120

Fix this by deferefencing them safely.

Suggested-by: Naveen N. Rao 
Signed-off-by: Ravi Bangoria 
---
 arch/powerpc/perf/core-book3s.c | 7 +--
 1 file changed, 5 insertions(+), 2 deletions(-)

diff --git a/arch/powerpc/perf/core-book3s.c b/arch/powerpc/perf/core-book3s.c
index 9e3da168d54c..5a68d2effdf9 100644
--- a/arch/powerpc/perf/core-book3s.c
+++ b/arch/powerpc/perf/core-book3s.c
@@ -410,8 +410,11 @@ static __u64 power_pmu_bhrb_to(u64 addr)
int ret;
__u64 target;
 
-   if (is_kernel_addr(addr))
-   return branch_target((unsigned int *)addr);
+   if (is_kernel_addr(addr)) {
+   if (probe_kernel_address((void *)addr, instr))
+   return 0;
+   return branch_target();
+   }
 
/* Userspace: need copy instruction here then translate it */
pagefault_disable();
-- 
2.13.6



Re: [PATCH] On ppc64le we HAVE_RELIABLE_STACKTRACE

2017-12-12 Thread Josh Poimboeuf
On Tue, Dec 12, 2017 at 12:39:12PM +0100, Torsten Duwe wrote:
> Hi all,
> 
> The "Power Architecture 64-Bit ELF V2 ABI" says in section 2.3.2.3:
> 
> [...] There are several rules that must be adhered to in order to ensure
> reliable and consistent call chain backtracing:
> 
> * Before a function calls any other function, it shall establish its
>   own stack frame, whose size shall be a multiple of 16 bytes.

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.

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.)

Also, what about hand-coded asm?

> To me this sounds like the equivalent of HAVE_RELIABLE_STACKTRACE.
> This patch may be unneccessarily limited to ppc64le, but OTOH the only
> user of this flag so far is livepatching, which is only implemented on
> PPCs with 64-LE, a.k.a. ELF ABI v2.

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.

Furthermore, the "reliable" unwinder needs to have a way to report an
error if it doesn't reach the end.  This probably just means ensuring
that it reaches the user mode registers on the stack.

And as Miroslav mentioned, once that's all done, implement
save_stack_trace_tsk_reliable().

I don't think the above is documented anywhere, it would be good to put
it in the livepatch doc.

-- 
Josh


Re: [PATCH] powerpc/perf: Dereference bhrb entries safely

2017-12-12 Thread Naveen N. Rao

Ravi Bangoria wrote:

It may very well happen that branch instructions recorded by
bhrb entries already get unmapped before they get processed by
the kernel. Hence, trying to dereference such memory location
will endup in a crash. Ex,

Unable to handle kernel paging request for data at address 
0xc00819c41764
Faulting instruction address: 0xc0084a14
NIP [c0084a14] branch_target+0x4/0x70
LR [c00eb828] record_and_restart+0x568/0x5c0
Call Trace:
[c00eb3b4] record_and_restart+0xf4/0x5c0 (unreliable)
[c00ec378] perf_event_interrupt+0x298/0x460
[c0027964] performance_monitor_exception+0x54/0x70
[c0009ba4] performance_monitor_common+0x114/0x120

Fix this by deferefencing them safely.

Suggested-by: Naveen N. Rao 
Signed-off-by: Ravi Bangoria 


Reviewed-by: Naveen N. Rao 


- Naveen




Re: [PATCH V2] cxl: Add support for ASB_Notify on POWER9

2017-12-12 Thread Philippe Bergheaud

On 01/12/2017 16:53, Christophe Lombard wrote:

The POWER9 core supports a new feature: ASB_Notify which requires the
support of the Special Purpose Register: TIDR.

The ASB_Notify command, generated by the AFU, will attempt to
wake-up the host thread identified by the particular LPID:PID:TID.

This patch assign a unique TIDR (thread id) for the current thread which
will be used in the process element entry.

A next patch will handle a new kind of "compatible" property in the
device-tree (PHB DT node) indicating which version of CAPI and which
features are supported.

Signed-off-by: Christophe Lombard 



Reviewed-by: Philippe Bergheaud 



Re: ps3: Remove deprecated create_singlethread_workqueue

2017-12-12 Thread Michael Ellerman
On Tue, 2016-08-30 at 17:14:51 UTC, Bhaktipriya Shridhar wrote:
> The workqueue "ps3av->wq" queues a single work item >work and hence
> doesn't require ordering. It is involved in waking up ps3avd to do the
> video mode setting and hence it's not being used on a memory reclaim
> path. Hence, it has been converted to use system_wq.
> 
> System workqueues have been able to handle high level of concurrency
> for a long time now and hence it's not required to have a singlethreaded
> workqueue just to gain concurrency. Unlike a dedicated per-cpu workqueue
> created with create_singlethread_workqueue(), system_wq allows multiple
> work items to overlap executions even on the same CPU; however, a
> per-cpu workqueue doesn't have any CPU locality or global ordering
> guarantee unless the target CPU is explicitly specified and thus the
> increase of local concurrency shouldn't make any difference.
> 
> The work item has been flushed in ps3av_remove to ensure that
> there are no pending tasks while disconnecting the driver.
> 
> Signed-off-by: Bhaktipriya Shridhar 
> Acked-by: Tejun Heo 

Applied to powerpc next, thanks.

https://git.kernel.org/powerpc/c/f0200c02883367f0eb6c9e2f19a8ab

cheers


Re: powerpc/powermac: fix OF node refcount leak

2017-12-12 Thread Michael Ellerman
On Tue, 2017-01-31 at 17:43:55 UTC, Dmitry Torokhov wrote:
> We need to call of_node_put() for device nodes obtained with
> of_find_node_by_name().
> 
> Signed-off-by: Dmitry Torokhov 

Applied to powerpc next, thanks.

https://git.kernel.org/powerpc/c/2aaf0a198d7af53a946ad69976d3cc

cheers


[PATCH] On ppc64le we HAVE_RELIABLE_STACKTRACE

2017-12-12 Thread Torsten Duwe
Hi all,

The "Power Architecture 64-Bit ELF V2 ABI" says in section 2.3.2.3:

[...] There are several rules that must be adhered to in order to ensure
reliable and consistent call chain backtracing:

* Before a function calls any other function, it shall establish its
  own stack frame, whose size shall be a multiple of 16 bytes.

 – In instances where a function’s prologue creates a stack frame, the
   back-chain word of the stack frame shall be updated atomically with
   the value of the stack pointer (r1) when a back chain is implemented.
   (This must be supported as default by all ELF V2 ABI-compliant
   environments.)
[...]
 – The function shall save the link register that contains its return
   address in the LR save doubleword of its caller’s stack frame before
   calling another function.

To me this sounds like the equivalent of HAVE_RELIABLE_STACKTRACE.
This patch may be unneccessarily limited to ppc64le, but OTOH the only
user of this flag so far is livepatching, which is only implemented on
PPCs with 64-LE, a.k.a. ELF ABI v2.

Signed-off-by: Torsten Duwe 

---
diff --git a/arch/powerpc/Kconfig b/arch/powerpc/Kconfig
index c51e6ce42e7a..3e3a6ab2e089 100644
--- a/arch/powerpc/Kconfig
+++ b/arch/powerpc/Kconfig
@@ -218,6 +218,7 @@ config PPC
select HAVE_PERF_USER_STACK_DUMP
select HAVE_RCU_TABLE_FREE  if SMP
select HAVE_REGS_AND_STACK_ACCESS_API
+   select HAVE_RELIABLE_STACKTRACE if PPC64 && CPU_LITTLE_ENDIAN
select HAVE_SYSCALL_TRACEPOINTS
select HAVE_VIRT_CPU_ACCOUNTING
select HAVE_IRQ_TIME_ACCOUNTING



Re: powerpc: Use pr_warn instead of pr_warning

2017-12-12 Thread Michael Ellerman
On Tue, 2016-10-25 at 04:00:08 UTC, Joe Perches wrote:
> At some point, pr_warning will be removed so all logging messages use
> a consistent _warn style.
> 
> Update arch/powerpc/
> 
> Miscellanea:
> 
> o Coalesce formats
> o Realign arguments
> o Use %s, __func__ instead of embedded function names
> o Remove unnecessary line continuations
> 
> Signed-off-by: Joe Perches 
> Acked-by: Geoff Levand 

Applied to powerpc next, thanks.

https://git.kernel.org/powerpc/c/f2c2cbcc35d47f1471a04155ac3575

cheers


Re: powerpc/powermac: drop useless call to of_find_node_by_name

2017-12-12 Thread Michael Ellerman
On Tue, 2017-01-31 at 18:01:44 UTC, Dmitry Torokhov wrote:
> We are not using result, so this simply results in a leaked refcount.
> 
> Signed-off-by: Dmitry Torokhov 

Applied to powerpc next, thanks.

https://git.kernel.org/powerpc/c/df26200299eb05fa7d059cd235847e

cheers


[mainline] rcu stalls on CPU when unbinding mpt3sas driver

2017-12-12 Thread Abdul Haleem
Hi,

Off late we are seeing cpu stalls messages while mpt3sas driver unbind
on powerpc machine for both mainline and linux-next kernels

Machine Type: Power 8 Bare-metal
Kernel version: 4.15.0-rc2
config: attached.
test: driver unbind

$ echo -n 0001:03:00.0 > /sys/bus/pci/drivers/mpt3sas/unbind
mpt3sas_cm0: removing handle(0x000a), sas_addr(0x500304801f080d00)
mpt3sas_cm0: removing : enclosure logical id(0x500304801f080d3f), slot(0)
mpt3sas_cm0: removing enclosure level(0x), connector name( )
mpt3sas_cm0: removing handle(0x000b), sas_addr(0x500304801f080d01)
mpt3sas_cm0: removing : enclosure logical id(0x500304801f080d3f), slot(1)
mpt3sas_cm0: removing enclosure level(0x), connector name( )
mpt3sas_cm0: removing handle(0x000c), sas_addr(0x500304801f080d02)
mpt3sas_cm0: removing : enclosure logical id(0x500304801f080d3f), slot(2)
mpt3sas_cm0: removing enclosure level(0x), connector name( )
mpt3sas_cm0: removing handle(0x000d), sas_addr(0x500304801f080d03)
mpt3sas_cm0: removing : enclosure logical id(0x500304801f080d3f), slot(3)
mpt3sas_cm0: removing enclosure level(0x), connector name( )
mpt3sas_cm0: removing handle(0x000e), sas_addr(0x500304801f080d04)
mpt3sas_cm0: removing : enclosure logical id(0x500304801f080d3f), slot(4)
mpt3sas_cm0: removing enclosure level(0x), connector name( )
mpt3sas_cm0: removing handle(0x000f), sas_addr(0x500304801f080d3d)
mpt3sas_cm0: removing : enclosure logical id(0x500304801f080d3f), slot(12)
mpt3sas_cm0: removing enclosure level(0x), connector name( )
sd 16:0:0:0: [sdb] Synchronizing SCSI cache
sd 16:0:0:0: [sdb] Synchronize Cache(10) failed: Result: 
hostbyte=DID_NO_CONNECT driverbyte=DRIVER_OK
sd 16:0:1:0: [sdc] tag#0 FAILED Result: hostbyte=DID_NO_CONNECT 
driverbyte=DRIVER_OK
sd 16:0:1:0: [sdc] tag#0 CDB: ATA command pass through(16) 85 06 2c 00 00 00 00 
00 00 00 00 00 00 00 e5 00
sd 16:0:2:0: [sdd] tag#0 FAILED Result: hostbyte=DID_NO_CONNECT 
driverbyte=DRIVER_OK
sd 16:0:2:0: [sdd] tag#0 CDB: ATA command pass through(16) 85 06 2c 00 00 00 00 
00 00 00 00 00 00 00 e5 00
sd 16:0:3:0: [sde] tag#0 FAILED Result: hostbyte=DID_NO_CONNECT 
driverbyte=DRIVER_OK
sd 16:0:3:0: [sde] tag#0 CDB: ATA command pass through(16) 85 06 2c 00 00 00 00 
00 00 00 00 00 00 00 e5 00
sd 16:0:4:0: [sdf] tag#0 FAILED Result: hostbyte=DID_NO_CONNECT 
driverbyte=DRIVER_OK
sd 16:0:4:0: [sdf] tag#0 CDB: ATA command pass through(16) 85 06 2c 00 00 00 00 
00 00 00 00 00 00 00 e5 00

few minutes after above command was executed, machine is flooded with rcu 
stalls messages.

INFO: rcu_sched detected expedited stalls on CPUs/tasks: { 86-... } 44191221 
jiffies s: 3445 root: 0x20/.
blocking rcu_node structures: l=1:80-95:0x40/.
Task dump for CPU 86:
sh  R  running task10384 18136  1 0x00042086
Call Trace:
[c07792d47370] [c07933667200] 0xc07933667200 (unreliable)
INFO: rcu_sched self-detected stall on CPU
86-: (50420459 ticks this GP) idle=0ae/141/0 
softirq=11962/11962 fqs=24724293 
 (t=50420460 jiffies g=80217 c=80216 q=36817447)
NMI backtrace for cpu 86
CPU: 86 PID: 18136 Comm: sh Not tainted 4.15.0-rc2-autotest #1
Call Trace:
[c07792d46f20] [c099b83c] dump_stack+0xb0/0xf4 (unreliable)
[c07792d46f60] [c09a43e4] nmi_cpu_backtrace+0x1a4/0x210
[c07792d46ff0] [c09a462c] nmi_trigger_cpumask_backtrace+0x1dc/0x220
[c07792d47090] [c002c7d0] arch_trigger_cpumask_backtrace+0x20/0x40
[c07792d470b0] [c017496c] rcu_dump_cpu_stacks+0xf4/0x158
[c07792d47100] [c0173cb0] rcu_check_callbacks+0x8f0/0xb00
[c07792d47230] [c017c25c] update_process_times+0x3c/0x90
[c07792d47260] [c01921e4] tick_sched_handle.isra.13+0x44/0x80
[c07792d47280] [c0192278] tick_sched_timer+0x58/0xb0
[c07792d472c0] [c017cd58] __hrtimer_run_queues+0xf8/0x330
[c07792d47340] [c017da74] hrtimer_interrupt+0xe4/0x280
[c07792d47400] [c0022660] __timer_interrupt+0x90/0x270
[c07792d47450] [c0022d30] timer_interrupt+0xa0/0xe0
[c07792d47480] [c0009238] decrementer_common+0x158/0x160
--- interrupt: 901 at replay_interrupt_return+0x0/0x4
LR = arch_local_irq_restore+0x74/0x90
[c07792d47770] [c03fb3185000] 0xc03fb3185000 (unreliable)
[c07792d47790] [c09bb658] _raw_spin_unlock_irqrestore+0x38/0x60
[c07792d477b0] [c066f274] scsi_remove_target+0x204/0x270
[c07792d47820] [dfc72604] sas_rphy_remove+0x94/0xa0 
[scsi_transport_sas]
[c07792d47850] [dfc745bc] sas_port_delete+0x4c/0x238 
[scsi_transport_sas]
[c07792d478b0] [d00010e82990] mpt3sas_transport_port_remove+0x2d0/0x310 
[mpt3sas]
[c07792d47950] [d00010e71ba0] _scsih_remove_device+0x100/0x2a0 [mpt3sas]
[c07792d47a10] [d00010e774d4] 
mpt3sas_device_remove_by_sas_address.part.44+0xb4/0x160 [mpt3sas]
[c07792d47a70] [d00010e77614] 

Re: [1/2] powerpc: make use of for_each_node_by_name() instead of open-coding it

2017-12-12 Thread Michael Ellerman
On Wed, 2017-02-01 at 01:54:37 UTC, Dmitry Torokhov wrote:
> Instead of manually coding the loop with of_find_node_by_name(), let's
> switch to the standard macro for iterating over nodes with given name.
> 
> Signed-off-by: Dmitry Torokhov 

Applied to powerpc next, thanks.

https://git.kernel.org/powerpc/c/0aa8ff9b76282300d16e0a1403b115

cheers


Re: [PATCH] KVM: PPC: Book3S: fix XIVE migration of pending interrupts

2017-12-12 Thread Laurent Vivier
On 12/12/2017 13:02, Cédric Le Goater wrote:
> When restoring a pending interrupt, we are setting the Q bit to force
> a retrigger in xive_finish_unmask(). But we also need to force an EOI
> in this case to reach the same initial state : P=1, Q=0.
> 
> This can be done by not setting 'old_p' for pending interrupts which
> will inform xive_finish_unmask() that an EOI needs to be sent.
> 
> Suggested-by: Benjamin Herrenschmidt 
> Signed-off-by: Cédric Le Goater 
> ---
> 
>  Tested with a guest running iozone.
> 
>  arch/powerpc/kvm/book3s_xive.c | 4 ++--
>  1 file changed, 2 insertions(+), 2 deletions(-)
> 
> diff --git a/arch/powerpc/kvm/book3s_xive.c b/arch/powerpc/kvm/book3s_xive.c
> index bf457843e032..b5e6d227a034 100644
> --- a/arch/powerpc/kvm/book3s_xive.c
> +++ b/arch/powerpc/kvm/book3s_xive.c
> @@ -1558,7 +1558,7 @@ static int xive_set_source(struct kvmppc_xive *xive, 
> long irq, u64 addr)
>  
>   /*
>* Restore P and Q. If the interrupt was pending, we
> -  * force both P and Q, which will trigger a resend.
> +  * force Q and !P, which will trigger a resend.
>*
>* That means that a guest that had both an interrupt
>* pending (queued) and Q set will restore with only
> @@ -1566,7 +1566,7 @@ static int xive_set_source(struct kvmppc_xive *xive, 
> long irq, u64 addr)
>* is perfectly fine as coalescing interrupts that haven't
>* been presented yet is always allowed.
>*/
> - if (val & KVM_XICS_PRESENTED || val & KVM_XICS_PENDING)
> + if (val & KVM_XICS_PRESENTED && !(val & KVM_XICS_PENDING))
>   state->old_p = true;
>   if (val & KVM_XICS_QUEUED || val & KVM_XICS_PENDING)
>   state->old_q = true;
> 

Reviewed-by: Laurent Vivier 
Tested-by: Laurent Vivier