Re: [PATCHv3 1/1] locking/qspinlock/x86: Avoid test-and-set when PV_DEDICATED is set

2017-11-09 Thread Peter Zijlstra
On Fri, Nov 10, 2017 at 10:07:56AM +0800, Wanpeng Li wrote:

> >> Also, you should not put cpumask_t on stack, that's 'broken'.
> 
> Thanks pointing out this. I found a useful comments in arch/x86/kernel/irq.c:
> 
> /* These two declarations are only used in check_irq_vectors_for_cpu_disable()
>  * below, which is protected by stop_machine().  Putting them on the stack
>  * results in a stack frame overflow.  Dynamically allocating could result in 
> a
>  * failure so declare these two cpumasks as global.
>  */
> static struct cpumask affinity_new, online_new;

That code no longer exists.. Also not entirely sure how it would be
helpful.

What you probably want to do is have a per-cpu cpumask, since
flush_tlb_others() is called with preemption disabled. But you probably
don't want an unconditionally allocated one, since most kernels will not
in fact be PV.

So you'll want something like:

static DEFINE_PER_CPU(cpumask_var_t, __pv_tlb_mask);

And then you need something like:

for_each_possible_cpu(cpu) {
zalloc_cpumask_var_node(per_cpu_ptr(&__pb_tlb_mask, cpu),
GFP_KERNEL, cpu_to_node(cpu));
}

before you set the pv-op or so.


Re: [PATCHv3 1/1] locking/qspinlock/x86: Avoid test-and-set when PV_DEDICATED is set

2017-11-09 Thread Peter Zijlstra
On Fri, Nov 10, 2017 at 10:07:56AM +0800, Wanpeng Li wrote:

> >> Also, you should not put cpumask_t on stack, that's 'broken'.
> 
> Thanks pointing out this. I found a useful comments in arch/x86/kernel/irq.c:
> 
> /* These two declarations are only used in check_irq_vectors_for_cpu_disable()
>  * below, which is protected by stop_machine().  Putting them on the stack
>  * results in a stack frame overflow.  Dynamically allocating could result in 
> a
>  * failure so declare these two cpumasks as global.
>  */
> static struct cpumask affinity_new, online_new;

That code no longer exists.. Also not entirely sure how it would be
helpful.

What you probably want to do is have a per-cpu cpumask, since
flush_tlb_others() is called with preemption disabled. But you probably
don't want an unconditionally allocated one, since most kernels will not
in fact be PV.

So you'll want something like:

static DEFINE_PER_CPU(cpumask_var_t, __pv_tlb_mask);

And then you need something like:

for_each_possible_cpu(cpu) {
zalloc_cpumask_var_node(per_cpu_ptr(&__pb_tlb_mask, cpu),
GFP_KERNEL, cpu_to_node(cpu));
}

before you set the pv-op or so.


[PATCH 0/4] i2c: mpc: Clean up clock selection

2017-11-09 Thread Arseny Solokha
This series cleans up I2C clock selection for Freescale/NXP MPC SoCs during
the controller initialization for cases when clock settings are not to be
preserved from the bootloader.

Patch 1/4 fixes division by zero which happens during controller
initialization when (1) clock frequency is not specified in the Device
Tree, (2) preservation of clock settings from the bootloader is not
requested, and (3) the clock prescaler (which may actually depend
on the POR configuration) is not explicitly specified. It simply moves
obtaining the prescaler value before the clock computation.

Patch 2/4 unifies obtaining the prescaler value for MPC8544 with other
SoCs. It moves the relevant code to the helper function introduced
in commit 8ce795cb0c6b ("i2c: mpc: assign the correct prescaler from SVR")
and also adds handling of MPC8533 is similar to MPC8544 in this regard.

Patch 3/4 fixes checking the relevant bit in a controller's register used
for selecting the prescaler value for MPC8533 and MPC8544.

Patch 4/4 removes the facility for setting the clock prescaler value
at compile time. This facility is not used in the majority of cases. Getting
the prescaler value at run time currently covers more SoCs. Hardcoding it
is also wrong for some SoCs as it can be configured on board during POR.

Arseny Solokha (4):
  i2c: mpc: get MPC8xxx I2C clock prescaler before using it in
calculations
  i2c: mpc: unify obtaining the MPC8533/44 I2C clock prescaler w/
MPC8xxx
  i2c: mpc: fix PORDEVSR2 mask for MPC8533/44
  i2c: mpc: always determine I2C clock prescaler at runtime

 drivers/i2c/busses/i2c-mpc.c | 72 ++--
 1 file changed, 30 insertions(+), 42 deletions(-)

-- 
2.15.0



[PATCH 3/4] i2c: mpc: fix PORDEVSR2 mask for MPC8533/44

2017-11-09 Thread Arseny Solokha
According to the reference manuals for the corresponding SoCs, SEC
frequency ratio configuration is indicated by bit 26 of the POR Device
Status Register 2. Consequently, SEC_CFG bit should be tested by mask 0x20,
not 0x80. Testing the wrong bit leads to selection of wrong I2C clock
prescaler on those SoCs.

Signed-off-by: Arseny Solokha 
---
 drivers/i2c/busses/i2c-mpc.c | 8 ++--
 1 file changed, 6 insertions(+), 2 deletions(-)

diff --git a/drivers/i2c/busses/i2c-mpc.c b/drivers/i2c/busses/i2c-mpc.c
index f47916466b82..8d60db0080f6 100644
--- a/drivers/i2c/busses/i2c-mpc.c
+++ b/drivers/i2c/busses/i2c-mpc.c
@@ -332,14 +332,18 @@ static u32 mpc_i2c_get_sec_cfg_8xxx(void)
if (prop) {
/*
 * Map and check POR Device Status Register 2
-* (PORDEVSR2) at 0xE0014
+* (PORDEVSR2) at 0xE0014. Note than while MPC8533
+* and MPC8544 indicate SEC frequency ratio
+* configuration as bit 26 in PORDEVSR2, other MPC8xxx
+* parts may store it differently or may not have it
+* at all.
 */
reg = ioremap(get_immrbase() + *prop + 0x14, 0x4);
if (!reg)
printk(KERN_ERR
   "Error: couldn't map PORDEVSR2\n");
else
-   val = in_be32(reg) & 0x0080; /* sec-cfg */
+   val = in_be32(reg) & 0x0020; /* sec-cfg */
iounmap(reg);
}
}
-- 
2.15.0



[PATCH 0/4] i2c: mpc: Clean up clock selection

2017-11-09 Thread Arseny Solokha
This series cleans up I2C clock selection for Freescale/NXP MPC SoCs during
the controller initialization for cases when clock settings are not to be
preserved from the bootloader.

Patch 1/4 fixes division by zero which happens during controller
initialization when (1) clock frequency is not specified in the Device
Tree, (2) preservation of clock settings from the bootloader is not
requested, and (3) the clock prescaler (which may actually depend
on the POR configuration) is not explicitly specified. It simply moves
obtaining the prescaler value before the clock computation.

Patch 2/4 unifies obtaining the prescaler value for MPC8544 with other
SoCs. It moves the relevant code to the helper function introduced
in commit 8ce795cb0c6b ("i2c: mpc: assign the correct prescaler from SVR")
and also adds handling of MPC8533 is similar to MPC8544 in this regard.

Patch 3/4 fixes checking the relevant bit in a controller's register used
for selecting the prescaler value for MPC8533 and MPC8544.

Patch 4/4 removes the facility for setting the clock prescaler value
at compile time. This facility is not used in the majority of cases. Getting
the prescaler value at run time currently covers more SoCs. Hardcoding it
is also wrong for some SoCs as it can be configured on board during POR.

Arseny Solokha (4):
  i2c: mpc: get MPC8xxx I2C clock prescaler before using it in
calculations
  i2c: mpc: unify obtaining the MPC8533/44 I2C clock prescaler w/
MPC8xxx
  i2c: mpc: fix PORDEVSR2 mask for MPC8533/44
  i2c: mpc: always determine I2C clock prescaler at runtime

 drivers/i2c/busses/i2c-mpc.c | 72 ++--
 1 file changed, 30 insertions(+), 42 deletions(-)

-- 
2.15.0



[PATCH 3/4] i2c: mpc: fix PORDEVSR2 mask for MPC8533/44

2017-11-09 Thread Arseny Solokha
According to the reference manuals for the corresponding SoCs, SEC
frequency ratio configuration is indicated by bit 26 of the POR Device
Status Register 2. Consequently, SEC_CFG bit should be tested by mask 0x20,
not 0x80. Testing the wrong bit leads to selection of wrong I2C clock
prescaler on those SoCs.

Signed-off-by: Arseny Solokha 
---
 drivers/i2c/busses/i2c-mpc.c | 8 ++--
 1 file changed, 6 insertions(+), 2 deletions(-)

diff --git a/drivers/i2c/busses/i2c-mpc.c b/drivers/i2c/busses/i2c-mpc.c
index f47916466b82..8d60db0080f6 100644
--- a/drivers/i2c/busses/i2c-mpc.c
+++ b/drivers/i2c/busses/i2c-mpc.c
@@ -332,14 +332,18 @@ static u32 mpc_i2c_get_sec_cfg_8xxx(void)
if (prop) {
/*
 * Map and check POR Device Status Register 2
-* (PORDEVSR2) at 0xE0014
+* (PORDEVSR2) at 0xE0014. Note than while MPC8533
+* and MPC8544 indicate SEC frequency ratio
+* configuration as bit 26 in PORDEVSR2, other MPC8xxx
+* parts may store it differently or may not have it
+* at all.
 */
reg = ioremap(get_immrbase() + *prop + 0x14, 0x4);
if (!reg)
printk(KERN_ERR
   "Error: couldn't map PORDEVSR2\n");
else
-   val = in_be32(reg) & 0x0080; /* sec-cfg */
+   val = in_be32(reg) & 0x0020; /* sec-cfg */
iounmap(reg);
}
}
-- 
2.15.0



[PATCH 2/4] i2c: mpc: unify obtaining the MPC8533/44 I2C clock prescaler w/ MPC8xxx

2017-11-09 Thread Arseny Solokha
Commit 8ce795cb0c6b ("i2c: mpc: assign the correct prescaler from SVR")
introduced the common helper function for obtaining the actual clock
prescaler value for MPC85xx. However, getting the prescaler for MPC8544
which depends on the SEC frequency ratio on this platform, has been always
performed separately based on the corresponding Device Tree configuration.

Move special handling of MPC8544 into that common helper. Make it dependent
on the SoC version and not on Device Tree compatible node, as is the case
with all other SoCs. Handle MPC8533 the same way which is similar
to MPC8544 in this regard, according to AN2919 "Determining the I2C
Frequency Divider Ratio for SCL".

Signed-off-by: Arseny Solokha 
---
 drivers/i2c/busses/i2c-mpc.c | 12 +---
 1 file changed, 9 insertions(+), 3 deletions(-)

diff --git a/drivers/i2c/busses/i2c-mpc.c b/drivers/i2c/busses/i2c-mpc.c
index bf0c86d41f1a..f47916466b82 100644
--- a/drivers/i2c/busses/i2c-mpc.c
+++ b/drivers/i2c/busses/i2c-mpc.c
@@ -350,7 +350,11 @@ static u32 mpc_i2c_get_sec_cfg_8xxx(void)
 
 static u32 mpc_i2c_get_prescaler_8xxx(void)
 {
-   /* mpc83xx and mpc82xx all have prescaler 1 */
+   /*
+* According to the AN2919 all MPC824x have prescaler 1, while MPC83xx
+* may have prescaler 1, 2, or 3, depending on the power-on
+* configuration.
+*/
u32 prescaler = 1;
 
/* mpc85xx */
@@ -367,6 +371,10 @@ static u32 mpc_i2c_get_prescaler_8xxx(void)
|| (SVR_SOC_VER(svr) == SVR_8610))
/* the above 85xx SoCs have prescaler 1 */
prescaler = 1;
+   else if ((SVR_SOC_VER(svr) == SVR_8533)
+   || (SVR_SOC_VER(svr) == SVR_8544))
+   /* the above 85xx SoCs have prescaler 3 or 2 */
+   prescaler = mpc_i2c_get_sec_cfg_8xxx() ? 3 : 2;
else
/* all the other 85xx have prescaler 2 */
prescaler = 2;
@@ -383,8 +391,6 @@ static int mpc_i2c_get_fdr_8xxx(struct device_node *node, 
u32 clock,
int i;
 
/* Determine proper divider value */
-   if (of_device_is_compatible(node, "fsl,mpc8544-i2c"))
-   prescaler = mpc_i2c_get_sec_cfg_8xxx() ? 3 : 2;
if (!prescaler)
prescaler = mpc_i2c_get_prescaler_8xxx();
 
-- 
2.15.0



[PATCH 4/4] i2c: mpc: always determine I2C clock prescaler at runtime

2017-11-09 Thread Arseny Solokha
Remove the facility for setting the prescaler value at compile time
entirely. It was only used for two SoCs, duplicating the actual value
for one of them and setting sometimes bogus value for another. Make all
MPC8xxx SoCs obtain their actual I2C clock prescaler from a single place
in the code.

Signed-off-by: Arseny Solokha 
---
 drivers/i2c/busses/i2c-mpc.c | 52 +---
 1 file changed, 15 insertions(+), 37 deletions(-)

diff --git a/drivers/i2c/busses/i2c-mpc.c b/drivers/i2c/busses/i2c-mpc.c
index 8d60db0080f6..e0f059687c2d 100644
--- a/drivers/i2c/busses/i2c-mpc.c
+++ b/drivers/i2c/busses/i2c-mpc.c
@@ -78,9 +78,7 @@ struct mpc_i2c_divider {
 };
 
 struct mpc_i2c_data {
-   void (*setup)(struct device_node *node, struct mpc_i2c *i2c,
- u32 clock, u32 prescaler);
-   u32 prescaler;
+   void (*setup)(struct device_node *node, struct mpc_i2c *i2c, u32 clock);
 };
 
 static inline void writeccr(struct mpc_i2c *i2c, u32 x)
@@ -201,7 +199,7 @@ static const struct mpc_i2c_divider mpc_i2c_dividers_52xx[] 
= {
 };
 
 static int mpc_i2c_get_fdr_52xx(struct device_node *node, u32 clock,
- int prescaler, u32 *real_clk)
+ u32 *real_clk)
 {
const struct mpc_i2c_divider *div = NULL;
unsigned int pvr = mfspr(SPRN_PVR);
@@ -236,7 +234,7 @@ static int mpc_i2c_get_fdr_52xx(struct device_node *node, 
u32 clock,
 
 static void mpc_i2c_setup_52xx(struct device_node *node,
 struct mpc_i2c *i2c,
-u32 clock, u32 prescaler)
+u32 clock)
 {
int ret, fdr;
 
@@ -246,7 +244,7 @@ static void mpc_i2c_setup_52xx(struct device_node *node,
return;
}
 
-   ret = mpc_i2c_get_fdr_52xx(node, clock, prescaler, >real_clk);
+   ret = mpc_i2c_get_fdr_52xx(node, clock, >real_clk);
fdr = (ret >= 0) ? ret : 0x3f; /* backward compatibility */
 
writeb(fdr & 0xff, i2c->base + MPC_I2C_FDR);
@@ -258,7 +256,7 @@ static void mpc_i2c_setup_52xx(struct device_node *node,
 #else /* !(CONFIG_PPC_MPC52xx || CONFIG_PPC_MPC512x) */
 static void mpc_i2c_setup_52xx(struct device_node *node,
 struct mpc_i2c *i2c,
-u32 clock, u32 prescaler)
+u32 clock)
 {
 }
 #endif /* CONFIG_PPC_MPC52xx || CONFIG_PPC_MPC512x */
@@ -266,7 +264,7 @@ static void mpc_i2c_setup_52xx(struct device_node *node,
 #ifdef CONFIG_PPC_MPC512x
 static void mpc_i2c_setup_512x(struct device_node *node,
 struct mpc_i2c *i2c,
-u32 clock, u32 prescaler)
+u32 clock)
 {
struct device_node *node_ctrl;
void __iomem *ctrl;
@@ -289,12 +287,12 @@ static void mpc_i2c_setup_512x(struct device_node *node,
}
 
/* The clock setup for the 52xx works also fine for the 512x */
-   mpc_i2c_setup_52xx(node, i2c, clock, prescaler);
+   mpc_i2c_setup_52xx(node, i2c, clock);
 }
 #else /* CONFIG_PPC_MPC512x */
 static void mpc_i2c_setup_512x(struct device_node *node,
 struct mpc_i2c *i2c,
-u32 clock, u32 prescaler)
+u32 clock)
 {
 }
 #endif /* CONFIG_PPC_MPC512x */
@@ -388,16 +386,13 @@ static u32 mpc_i2c_get_prescaler_8xxx(void)
 }
 
 static int mpc_i2c_get_fdr_8xxx(struct device_node *node, u32 clock,
- u32 prescaler, u32 *real_clk)
+ u32 *real_clk)
 {
const struct mpc_i2c_divider *div = NULL;
+   u32 prescaler = mpc_i2c_get_prescaler_8xxx();
u32 divider;
int i;
 
-   /* Determine proper divider value */
-   if (!prescaler)
-   prescaler = mpc_i2c_get_prescaler_8xxx();
-
if (clock == MPC_I2C_CLOCK_LEGACY) {
/* see below - default fdr = 0x1031 -> div = 16 * 3072 */
*real_clk = fsl_get_sys_freq() / prescaler / (16 * 3072);
@@ -425,7 +420,7 @@ static int mpc_i2c_get_fdr_8xxx(struct device_node *node, 
u32 clock,
 
 static void mpc_i2c_setup_8xxx(struct device_node *node,
 struct mpc_i2c *i2c,
-u32 clock, u32 prescaler)
+u32 clock)
 {
int ret, fdr;
 
@@ -436,7 +431,7 @@ static void mpc_i2c_setup_8xxx(struct device_node *node,
return;
}
 
-   ret = mpc_i2c_get_fdr_8xxx(node, clock, prescaler, >real_clk);
+   ret = mpc_i2c_get_fdr_8xxx(node, clock, >real_clk);
fdr = (ret >= 0) ? ret : 0x1031; /* backward compatibility */
 
writeb(fdr & 

[PATCH 2/4] i2c: mpc: unify obtaining the MPC8533/44 I2C clock prescaler w/ MPC8xxx

2017-11-09 Thread Arseny Solokha
Commit 8ce795cb0c6b ("i2c: mpc: assign the correct prescaler from SVR")
introduced the common helper function for obtaining the actual clock
prescaler value for MPC85xx. However, getting the prescaler for MPC8544
which depends on the SEC frequency ratio on this platform, has been always
performed separately based on the corresponding Device Tree configuration.

Move special handling of MPC8544 into that common helper. Make it dependent
on the SoC version and not on Device Tree compatible node, as is the case
with all other SoCs. Handle MPC8533 the same way which is similar
to MPC8544 in this regard, according to AN2919 "Determining the I2C
Frequency Divider Ratio for SCL".

Signed-off-by: Arseny Solokha 
---
 drivers/i2c/busses/i2c-mpc.c | 12 +---
 1 file changed, 9 insertions(+), 3 deletions(-)

diff --git a/drivers/i2c/busses/i2c-mpc.c b/drivers/i2c/busses/i2c-mpc.c
index bf0c86d41f1a..f47916466b82 100644
--- a/drivers/i2c/busses/i2c-mpc.c
+++ b/drivers/i2c/busses/i2c-mpc.c
@@ -350,7 +350,11 @@ static u32 mpc_i2c_get_sec_cfg_8xxx(void)
 
 static u32 mpc_i2c_get_prescaler_8xxx(void)
 {
-   /* mpc83xx and mpc82xx all have prescaler 1 */
+   /*
+* According to the AN2919 all MPC824x have prescaler 1, while MPC83xx
+* may have prescaler 1, 2, or 3, depending on the power-on
+* configuration.
+*/
u32 prescaler = 1;
 
/* mpc85xx */
@@ -367,6 +371,10 @@ static u32 mpc_i2c_get_prescaler_8xxx(void)
|| (SVR_SOC_VER(svr) == SVR_8610))
/* the above 85xx SoCs have prescaler 1 */
prescaler = 1;
+   else if ((SVR_SOC_VER(svr) == SVR_8533)
+   || (SVR_SOC_VER(svr) == SVR_8544))
+   /* the above 85xx SoCs have prescaler 3 or 2 */
+   prescaler = mpc_i2c_get_sec_cfg_8xxx() ? 3 : 2;
else
/* all the other 85xx have prescaler 2 */
prescaler = 2;
@@ -383,8 +391,6 @@ static int mpc_i2c_get_fdr_8xxx(struct device_node *node, 
u32 clock,
int i;
 
/* Determine proper divider value */
-   if (of_device_is_compatible(node, "fsl,mpc8544-i2c"))
-   prescaler = mpc_i2c_get_sec_cfg_8xxx() ? 3 : 2;
if (!prescaler)
prescaler = mpc_i2c_get_prescaler_8xxx();
 
-- 
2.15.0



[PATCH 4/4] i2c: mpc: always determine I2C clock prescaler at runtime

2017-11-09 Thread Arseny Solokha
Remove the facility for setting the prescaler value at compile time
entirely. It was only used for two SoCs, duplicating the actual value
for one of them and setting sometimes bogus value for another. Make all
MPC8xxx SoCs obtain their actual I2C clock prescaler from a single place
in the code.

Signed-off-by: Arseny Solokha 
---
 drivers/i2c/busses/i2c-mpc.c | 52 +---
 1 file changed, 15 insertions(+), 37 deletions(-)

diff --git a/drivers/i2c/busses/i2c-mpc.c b/drivers/i2c/busses/i2c-mpc.c
index 8d60db0080f6..e0f059687c2d 100644
--- a/drivers/i2c/busses/i2c-mpc.c
+++ b/drivers/i2c/busses/i2c-mpc.c
@@ -78,9 +78,7 @@ struct mpc_i2c_divider {
 };
 
 struct mpc_i2c_data {
-   void (*setup)(struct device_node *node, struct mpc_i2c *i2c,
- u32 clock, u32 prescaler);
-   u32 prescaler;
+   void (*setup)(struct device_node *node, struct mpc_i2c *i2c, u32 clock);
 };
 
 static inline void writeccr(struct mpc_i2c *i2c, u32 x)
@@ -201,7 +199,7 @@ static const struct mpc_i2c_divider mpc_i2c_dividers_52xx[] 
= {
 };
 
 static int mpc_i2c_get_fdr_52xx(struct device_node *node, u32 clock,
- int prescaler, u32 *real_clk)
+ u32 *real_clk)
 {
const struct mpc_i2c_divider *div = NULL;
unsigned int pvr = mfspr(SPRN_PVR);
@@ -236,7 +234,7 @@ static int mpc_i2c_get_fdr_52xx(struct device_node *node, 
u32 clock,
 
 static void mpc_i2c_setup_52xx(struct device_node *node,
 struct mpc_i2c *i2c,
-u32 clock, u32 prescaler)
+u32 clock)
 {
int ret, fdr;
 
@@ -246,7 +244,7 @@ static void mpc_i2c_setup_52xx(struct device_node *node,
return;
}
 
-   ret = mpc_i2c_get_fdr_52xx(node, clock, prescaler, >real_clk);
+   ret = mpc_i2c_get_fdr_52xx(node, clock, >real_clk);
fdr = (ret >= 0) ? ret : 0x3f; /* backward compatibility */
 
writeb(fdr & 0xff, i2c->base + MPC_I2C_FDR);
@@ -258,7 +256,7 @@ static void mpc_i2c_setup_52xx(struct device_node *node,
 #else /* !(CONFIG_PPC_MPC52xx || CONFIG_PPC_MPC512x) */
 static void mpc_i2c_setup_52xx(struct device_node *node,
 struct mpc_i2c *i2c,
-u32 clock, u32 prescaler)
+u32 clock)
 {
 }
 #endif /* CONFIG_PPC_MPC52xx || CONFIG_PPC_MPC512x */
@@ -266,7 +264,7 @@ static void mpc_i2c_setup_52xx(struct device_node *node,
 #ifdef CONFIG_PPC_MPC512x
 static void mpc_i2c_setup_512x(struct device_node *node,
 struct mpc_i2c *i2c,
-u32 clock, u32 prescaler)
+u32 clock)
 {
struct device_node *node_ctrl;
void __iomem *ctrl;
@@ -289,12 +287,12 @@ static void mpc_i2c_setup_512x(struct device_node *node,
}
 
/* The clock setup for the 52xx works also fine for the 512x */
-   mpc_i2c_setup_52xx(node, i2c, clock, prescaler);
+   mpc_i2c_setup_52xx(node, i2c, clock);
 }
 #else /* CONFIG_PPC_MPC512x */
 static void mpc_i2c_setup_512x(struct device_node *node,
 struct mpc_i2c *i2c,
-u32 clock, u32 prescaler)
+u32 clock)
 {
 }
 #endif /* CONFIG_PPC_MPC512x */
@@ -388,16 +386,13 @@ static u32 mpc_i2c_get_prescaler_8xxx(void)
 }
 
 static int mpc_i2c_get_fdr_8xxx(struct device_node *node, u32 clock,
- u32 prescaler, u32 *real_clk)
+ u32 *real_clk)
 {
const struct mpc_i2c_divider *div = NULL;
+   u32 prescaler = mpc_i2c_get_prescaler_8xxx();
u32 divider;
int i;
 
-   /* Determine proper divider value */
-   if (!prescaler)
-   prescaler = mpc_i2c_get_prescaler_8xxx();
-
if (clock == MPC_I2C_CLOCK_LEGACY) {
/* see below - default fdr = 0x1031 -> div = 16 * 3072 */
*real_clk = fsl_get_sys_freq() / prescaler / (16 * 3072);
@@ -425,7 +420,7 @@ static int mpc_i2c_get_fdr_8xxx(struct device_node *node, 
u32 clock,
 
 static void mpc_i2c_setup_8xxx(struct device_node *node,
 struct mpc_i2c *i2c,
-u32 clock, u32 prescaler)
+u32 clock)
 {
int ret, fdr;
 
@@ -436,7 +431,7 @@ static void mpc_i2c_setup_8xxx(struct device_node *node,
return;
}
 
-   ret = mpc_i2c_get_fdr_8xxx(node, clock, prescaler, >real_clk);
+   ret = mpc_i2c_get_fdr_8xxx(node, clock, >real_clk);
fdr = (ret >= 0) ? ret : 0x1031; /* backward compatibility */
 
writeb(fdr & 0xff, i2c->base + 

Re: [PATCH] perf evsel: Fix incorrect precise_ip in default event name

2017-11-09 Thread zhangmengting

Hi Namhyung,

Yeah, you are right. I'll send a new patch later.

Thanks,

Mengting Zhang


On 2017/11/10 14:30, Namhyung Kim wrote:

Hello,

On Fri, Nov 10, 2017 at 01:49:06PM +0800, Mengting Zhang wrote:

When no event is specified with -e option, perf will specify a
"cycles" event with the highest level of precision available in
perf_event_attr.precise_ip as the default event. But the evsel name
shows an incorrect precise ip, fix it.

For example, with a highest precision perf_event_attr.precise_ip = 2,
the evsel name "cycles:ppp" shows a wrong precision available.

Before:
$./perf record sleep 1
[ perf record: Woken up 1 times to write data ]
[ perf record: Captured and wrote 0.014 MB perf.data (21 samples) ]
$./perf evlist -v
cycles:ppp: size: 112, { sample_period, sample_freq }: 4000,
sample_type: IP|TID|TIME|PERIOD, disabled: 1, inherit: 1, mmap: 1,
comm: 1, freq: 1, enable_on_exec: 1, task: 1, precise_ip: 2,
sample_id_all: 1, exclude_guest: 1, mmap2: 1, comm_exec: 1

After:
$./perf record sleep 1
[ perf record: Woken up 1 times to write data ]
[ perf record: Captured and wrote 0.014 MB perf.data (16 samples) ]
$./perf evlist -v
cycles:pp: size: 112, { sample_period, sample_freq }: 4000,
sample_type: IP|TID|TIME|PERIOD, disabled: 1, inherit: 1, mmap: 1,
comm: 1, freq: 1, enable_on_exec: 1, task: 1, precise_ip: 2,
sample_id_all: 1, exclude_guest: 1, mmap2: 1, comm_exec: 1

Signed-off-by: Mengting Zhang 
---
  tools/perf/util/evsel.c | 2 +-
  1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/tools/perf/util/evsel.c b/tools/perf/util/evsel.c
index 0dccdb8..94cf11d 100644
--- a/tools/perf/util/evsel.c
+++ b/tools/perf/util/evsel.c
@@ -312,7 +312,7 @@ struct perf_evsel *perf_evsel__new_cycles(bool precise)
if (asprintf(>name, "cycles%s%s%.*s",
 (attr.precise_ip || attr.exclude_kernel) ? ":" : "",
 attr.exclude_kernel ? "u" : "",
-attr.precise_ip ? attr.precise_ip + 1 : 0, "ppp") < 0)
+attr.precise_ip ? attr.precise_ip : 0, "ppp") < 0)

I think you don't need to check value of the precise_ip anymore.
The following should be ok:

 attr.precise_ip, "ppp") < 0)

Thanks,
Namhyung


.






Re: [PATCH] perf evsel: Fix incorrect precise_ip in default event name

2017-11-09 Thread zhangmengting

Hi Namhyung,

Yeah, you are right. I'll send a new patch later.

Thanks,

Mengting Zhang


On 2017/11/10 14:30, Namhyung Kim wrote:

Hello,

On Fri, Nov 10, 2017 at 01:49:06PM +0800, Mengting Zhang wrote:

When no event is specified with -e option, perf will specify a
"cycles" event with the highest level of precision available in
perf_event_attr.precise_ip as the default event. But the evsel name
shows an incorrect precise ip, fix it.

For example, with a highest precision perf_event_attr.precise_ip = 2,
the evsel name "cycles:ppp" shows a wrong precision available.

Before:
$./perf record sleep 1
[ perf record: Woken up 1 times to write data ]
[ perf record: Captured and wrote 0.014 MB perf.data (21 samples) ]
$./perf evlist -v
cycles:ppp: size: 112, { sample_period, sample_freq }: 4000,
sample_type: IP|TID|TIME|PERIOD, disabled: 1, inherit: 1, mmap: 1,
comm: 1, freq: 1, enable_on_exec: 1, task: 1, precise_ip: 2,
sample_id_all: 1, exclude_guest: 1, mmap2: 1, comm_exec: 1

After:
$./perf record sleep 1
[ perf record: Woken up 1 times to write data ]
[ perf record: Captured and wrote 0.014 MB perf.data (16 samples) ]
$./perf evlist -v
cycles:pp: size: 112, { sample_period, sample_freq }: 4000,
sample_type: IP|TID|TIME|PERIOD, disabled: 1, inherit: 1, mmap: 1,
comm: 1, freq: 1, enable_on_exec: 1, task: 1, precise_ip: 2,
sample_id_all: 1, exclude_guest: 1, mmap2: 1, comm_exec: 1

Signed-off-by: Mengting Zhang 
---
  tools/perf/util/evsel.c | 2 +-
  1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/tools/perf/util/evsel.c b/tools/perf/util/evsel.c
index 0dccdb8..94cf11d 100644
--- a/tools/perf/util/evsel.c
+++ b/tools/perf/util/evsel.c
@@ -312,7 +312,7 @@ struct perf_evsel *perf_evsel__new_cycles(bool precise)
if (asprintf(>name, "cycles%s%s%.*s",
 (attr.precise_ip || attr.exclude_kernel) ? ":" : "",
 attr.exclude_kernel ? "u" : "",
-attr.precise_ip ? attr.precise_ip + 1 : 0, "ppp") < 0)
+attr.precise_ip ? attr.precise_ip : 0, "ppp") < 0)

I think you don't need to check value of the precise_ip anymore.
The following should be ok:

 attr.precise_ip, "ppp") < 0)

Thanks,
Namhyung


.






[PATCH 1/4] i2c: mpc: get MPC8xxx I2C clock prescaler before using it in calculations

2017-11-09 Thread Arseny Solokha
Obtaining the actual I2C clock prescaler value in mpc_i2c_setup_8xxx() only
happens when the clock parameter is set to something other than
MPC_I2C_CLOCK_LEGACY. When the clock parameter is exactly
MPC_I2C_CLOCK_LEGACY, the prescaler parameter is used in arithmetic
division as provided by the caller, resulting in a division by zero
for the majority of processors supported by the module.

Avoid division by zero by obtaining the actual I2C clock prescaler
in mpc_i2c_setup_8xxx() unconditionally regardless of the passed clock
value.

Signed-off-by: Arseny Solokha 
---
 drivers/i2c/busses/i2c-mpc.c | 12 ++--
 1 file changed, 6 insertions(+), 6 deletions(-)

diff --git a/drivers/i2c/busses/i2c-mpc.c b/drivers/i2c/busses/i2c-mpc.c
index 96caf378b1dc..bf0c86d41f1a 100644
--- a/drivers/i2c/busses/i2c-mpc.c
+++ b/drivers/i2c/busses/i2c-mpc.c
@@ -382,18 +382,18 @@ static int mpc_i2c_get_fdr_8xxx(struct device_node *node, 
u32 clock,
u32 divider;
int i;
 
-   if (clock == MPC_I2C_CLOCK_LEGACY) {
-   /* see below - default fdr = 0x1031 -> div = 16 * 3072 */
-   *real_clk = fsl_get_sys_freq() / prescaler / (16 * 3072);
-   return -EINVAL;
-   }
-
/* Determine proper divider value */
if (of_device_is_compatible(node, "fsl,mpc8544-i2c"))
prescaler = mpc_i2c_get_sec_cfg_8xxx() ? 3 : 2;
if (!prescaler)
prescaler = mpc_i2c_get_prescaler_8xxx();
 
+   if (clock == MPC_I2C_CLOCK_LEGACY) {
+   /* see below - default fdr = 0x1031 -> div = 16 * 3072 */
+   *real_clk = fsl_get_sys_freq() / prescaler / (16 * 3072);
+   return -EINVAL;
+   }
+
divider = fsl_get_sys_freq() / clock / prescaler;
 
pr_debug("I2C: src_clock=%d clock=%d divider=%d\n",
-- 
2.15.0



[PATCH 1/4] i2c: mpc: get MPC8xxx I2C clock prescaler before using it in calculations

2017-11-09 Thread Arseny Solokha
Obtaining the actual I2C clock prescaler value in mpc_i2c_setup_8xxx() only
happens when the clock parameter is set to something other than
MPC_I2C_CLOCK_LEGACY. When the clock parameter is exactly
MPC_I2C_CLOCK_LEGACY, the prescaler parameter is used in arithmetic
division as provided by the caller, resulting in a division by zero
for the majority of processors supported by the module.

Avoid division by zero by obtaining the actual I2C clock prescaler
in mpc_i2c_setup_8xxx() unconditionally regardless of the passed clock
value.

Signed-off-by: Arseny Solokha 
---
 drivers/i2c/busses/i2c-mpc.c | 12 ++--
 1 file changed, 6 insertions(+), 6 deletions(-)

diff --git a/drivers/i2c/busses/i2c-mpc.c b/drivers/i2c/busses/i2c-mpc.c
index 96caf378b1dc..bf0c86d41f1a 100644
--- a/drivers/i2c/busses/i2c-mpc.c
+++ b/drivers/i2c/busses/i2c-mpc.c
@@ -382,18 +382,18 @@ static int mpc_i2c_get_fdr_8xxx(struct device_node *node, 
u32 clock,
u32 divider;
int i;
 
-   if (clock == MPC_I2C_CLOCK_LEGACY) {
-   /* see below - default fdr = 0x1031 -> div = 16 * 3072 */
-   *real_clk = fsl_get_sys_freq() / prescaler / (16 * 3072);
-   return -EINVAL;
-   }
-
/* Determine proper divider value */
if (of_device_is_compatible(node, "fsl,mpc8544-i2c"))
prescaler = mpc_i2c_get_sec_cfg_8xxx() ? 3 : 2;
if (!prescaler)
prescaler = mpc_i2c_get_prescaler_8xxx();
 
+   if (clock == MPC_I2C_CLOCK_LEGACY) {
+   /* see below - default fdr = 0x1031 -> div = 16 * 3072 */
+   *real_clk = fsl_get_sys_freq() / prescaler / (16 * 3072);
+   return -EINVAL;
+   }
+
divider = fsl_get_sys_freq() / clock / prescaler;
 
pr_debug("I2C: src_clock=%d clock=%d divider=%d\n",
-- 
2.15.0



Re: [PATCH v3 1/2] PM / domains: Rework governor code to be more consistent

2017-11-09 Thread Ulf Hansson
On 7 November 2017 at 02:23, Rafael J. Wysocki  wrote:
> From: Rafael J. Wysocki 
>
> The genpd governor currently uses negative PM QoS values to indicate
> the "no suspend" condition and 0 as "no restriction", but it doesn't
> use them consistently.  Moreover, it tries to refresh QoS values for
> already suspended devices in a quite questionable way.
>
> For the above reasons, rework it to be a bit more consistent.
>
> First off, note that dev_pm_qos_read_value() in
> dev_update_qos_constraint() and __default_power_down_ok() is
> evaluated for devices in suspend.  Moreover, that only happens if the
> effective_constraint_ns value for them is negative (meaning "no
> suspend").  It is not evaluated in any other cases, so effectively
> the QoS values are only updated for devices in suspend that should
> not have been suspended in the first place.  In all of the other
> cases, the QoS values taken into account are the effective ones from
> the time before the device has been suspended, so generally devices
> need to be resumed and suspended again for new QoS values to take
> effect anyway.  Thus evaluating dev_update_qos_constraint() in
> those two places doesn't make sense at all, so drop it.
>
> Second, initialize effective_constraint_ns to 0 ("no constraint")
> rather than to (-1) ("no suspend"), which makes more sense in
> general and in case effective_constraint_ns is never updated
> (the device is in suspend all the time or it is never suspended)
> it doesn't affect the device's parent and so on.
>
> Finally, rework default_suspend_ok() to explicitly handle the
> "no restriction" and "no suspend" special cases.
>
> Also add WARN_ON() around checks that should never trigger.
>
> Signed-off-by: Rafael J. Wysocki 
> Tested-by: Geert Uytterhoeven 

Acked-by: Ulf Hansson 

Kind regards
Uffe

> ---
>
> v2 -> v3: Take children that don't belong to genpd power domains into
>   account in dev_update_qos_constraint().
>
> ---
>  drivers/base/power/domain.c  |2
>  drivers/base/power/domain_governor.c |   71 
> ---
>  2 files changed, 50 insertions(+), 23 deletions(-)
>
> Index: linux-pm/drivers/base/power/domain.c
> ===
> --- linux-pm.orig/drivers/base/power/domain.c
> +++ linux-pm/drivers/base/power/domain.c
> @@ -1331,7 +1331,7 @@ static struct generic_pm_domain_data *ge
>
> gpd_data->base.dev = dev;
> gpd_data->td.constraint_changed = true;
> -   gpd_data->td.effective_constraint_ns = -1;
> +   gpd_data->td.effective_constraint_ns = 0;
> gpd_data->nb.notifier_call = genpd_dev_pm_qos_notifier;
>
> spin_lock_irq(>power.lock);
> Index: linux-pm/drivers/base/power/domain_governor.c
> ===
> --- linux-pm.orig/drivers/base/power/domain_governor.c
> +++ linux-pm/drivers/base/power/domain_governor.c
> @@ -14,22 +14,33 @@
>  static int dev_update_qos_constraint(struct device *dev, void *data)
>  {
> s64 *constraint_ns_p = data;
> -   s32 constraint_ns = -1;
> +   s64 constraint_ns;
>
> -   if (dev->power.subsys_data && dev->power.subsys_data->domain_data)
> +   if (dev->power.subsys_data && dev->power.subsys_data->domain_data) {
> +   /*
> +* Only take suspend-time QoS constraints of devices into
> +* account, because constraints updated after the device has
> +* been suspended are not guaranteed to be taken into account
> +* anyway.  In order for them to take effect, the device has 
> to
> +* be resumed and suspended again.
> +*/
> constraint_ns = dev_gpd_data(dev)->td.effective_constraint_ns;
> -
> -   if (constraint_ns < 0) {
> +   } else {
> +   /*
> +* The child is not in a domain and there's no info on its
> +* suspend/resume latencies, so assume them to be negligible 
> and
> +* take its current PM QoS constraint (that's the only thing
> +* known at this point anyway).
> +*/
> constraint_ns = dev_pm_qos_read_value(dev);
> -   constraint_ns *= NSEC_PER_USEC;
> +   if (constraint_ns > 0)
> +   constraint_ns *= NSEC_PER_USEC;
> }
> +
> +   /* 0 means "no constraint" */
> if (constraint_ns == 0)
> return 0;
>
> -   /*
> -* constraint_ns cannot be negative here, because the device has been
> -* suspended.
> -*/
> if (constraint_ns < *constraint_ns_p || *constraint_ns_p == 0)
> *constraint_ns_p = constraint_ns;
>
> @@ -76,14 +87,32 @@ static bool default_suspend_ok(struct de
> 

Re: [PATCH v3 1/2] PM / domains: Rework governor code to be more consistent

2017-11-09 Thread Ulf Hansson
On 7 November 2017 at 02:23, Rafael J. Wysocki  wrote:
> From: Rafael J. Wysocki 
>
> The genpd governor currently uses negative PM QoS values to indicate
> the "no suspend" condition and 0 as "no restriction", but it doesn't
> use them consistently.  Moreover, it tries to refresh QoS values for
> already suspended devices in a quite questionable way.
>
> For the above reasons, rework it to be a bit more consistent.
>
> First off, note that dev_pm_qos_read_value() in
> dev_update_qos_constraint() and __default_power_down_ok() is
> evaluated for devices in suspend.  Moreover, that only happens if the
> effective_constraint_ns value for them is negative (meaning "no
> suspend").  It is not evaluated in any other cases, so effectively
> the QoS values are only updated for devices in suspend that should
> not have been suspended in the first place.  In all of the other
> cases, the QoS values taken into account are the effective ones from
> the time before the device has been suspended, so generally devices
> need to be resumed and suspended again for new QoS values to take
> effect anyway.  Thus evaluating dev_update_qos_constraint() in
> those two places doesn't make sense at all, so drop it.
>
> Second, initialize effective_constraint_ns to 0 ("no constraint")
> rather than to (-1) ("no suspend"), which makes more sense in
> general and in case effective_constraint_ns is never updated
> (the device is in suspend all the time or it is never suspended)
> it doesn't affect the device's parent and so on.
>
> Finally, rework default_suspend_ok() to explicitly handle the
> "no restriction" and "no suspend" special cases.
>
> Also add WARN_ON() around checks that should never trigger.
>
> Signed-off-by: Rafael J. Wysocki 
> Tested-by: Geert Uytterhoeven 

Acked-by: Ulf Hansson 

Kind regards
Uffe

> ---
>
> v2 -> v3: Take children that don't belong to genpd power domains into
>   account in dev_update_qos_constraint().
>
> ---
>  drivers/base/power/domain.c  |2
>  drivers/base/power/domain_governor.c |   71 
> ---
>  2 files changed, 50 insertions(+), 23 deletions(-)
>
> Index: linux-pm/drivers/base/power/domain.c
> ===
> --- linux-pm.orig/drivers/base/power/domain.c
> +++ linux-pm/drivers/base/power/domain.c
> @@ -1331,7 +1331,7 @@ static struct generic_pm_domain_data *ge
>
> gpd_data->base.dev = dev;
> gpd_data->td.constraint_changed = true;
> -   gpd_data->td.effective_constraint_ns = -1;
> +   gpd_data->td.effective_constraint_ns = 0;
> gpd_data->nb.notifier_call = genpd_dev_pm_qos_notifier;
>
> spin_lock_irq(>power.lock);
> Index: linux-pm/drivers/base/power/domain_governor.c
> ===
> --- linux-pm.orig/drivers/base/power/domain_governor.c
> +++ linux-pm/drivers/base/power/domain_governor.c
> @@ -14,22 +14,33 @@
>  static int dev_update_qos_constraint(struct device *dev, void *data)
>  {
> s64 *constraint_ns_p = data;
> -   s32 constraint_ns = -1;
> +   s64 constraint_ns;
>
> -   if (dev->power.subsys_data && dev->power.subsys_data->domain_data)
> +   if (dev->power.subsys_data && dev->power.subsys_data->domain_data) {
> +   /*
> +* Only take suspend-time QoS constraints of devices into
> +* account, because constraints updated after the device has
> +* been suspended are not guaranteed to be taken into account
> +* anyway.  In order for them to take effect, the device has 
> to
> +* be resumed and suspended again.
> +*/
> constraint_ns = dev_gpd_data(dev)->td.effective_constraint_ns;
> -
> -   if (constraint_ns < 0) {
> +   } else {
> +   /*
> +* The child is not in a domain and there's no info on its
> +* suspend/resume latencies, so assume them to be negligible 
> and
> +* take its current PM QoS constraint (that's the only thing
> +* known at this point anyway).
> +*/
> constraint_ns = dev_pm_qos_read_value(dev);
> -   constraint_ns *= NSEC_PER_USEC;
> +   if (constraint_ns > 0)
> +   constraint_ns *= NSEC_PER_USEC;
> }
> +
> +   /* 0 means "no constraint" */
> if (constraint_ns == 0)
> return 0;
>
> -   /*
> -* constraint_ns cannot be negative here, because the device has been
> -* suspended.
> -*/
> if (constraint_ns < *constraint_ns_p || *constraint_ns_p == 0)
> *constraint_ns_p = constraint_ns;
>
> @@ -76,14 +87,32 @@ static bool default_suspend_ok(struct de
> device_for_each_child(dev, _ns,
>   dev_update_qos_constraint);
>
> -   if 

Re: [PATCH v4 2/2] PM / QoS: Fix device resume latency framework

2017-11-09 Thread Ulf Hansson
On 7 November 2017 at 11:33, Rafael J. Wysocki  wrote:
> From: Rafael J. Wysocki 
>
> The special value of 0 for device resume latency PM QoS means
> "no restriction", but there are two problems with that.
>
> First, device resume latency PM QoS requests with 0 as the
> value are always put in front of requests with positive
> values in the priority lists used internally by the PM QoS
> framework, causing 0 to be chosen as an effective constraint
> value.  However, that 0 is then interpreted as "no restriction"
> effectively overriding the other requests with specific
> restrictions which is incorrect.
>
> Second, the users of device resume latency PM QoS have no
> way to specify that *any* resume latency at all should be
> avoided, which is an artificial limitation in general.
>
> To address these issues, modify device resume latency PM QoS to
> use S32_MAX as the "no constraint" value and 0 as the "no
> latency at all" one and rework its users (the cpuidle menu
> governor, the genpd QoS governor and the runtime PM framework)
> to follow these changes.
>
> Also add a special "n/a" value to the corresponding user space I/F
> to allow user space to indicate that it cannot accept any resume
> latencies at all for the given device.
>
> Fixes: 85dc0b8a4019 (PM / QoS: Make it possible to expose PM QoS latency 
> constraints)
> Link: https://bugzilla.kernel.org/show_bug.cgi?id=197323
> Reported-by: Reinette Chatre 
> Signed-off-by: Rafael J. Wysocki 
> Tested-by: Reinette Chatre 
> Tested-by: Geert Uytterhoeven 

Acked-by: Ulf Hansson 

Kind regards
Uffe

> ---
>
> As noticed by Ramesh, the v3 had issues with an overlooked value
> conversion and a stale comment, so here goes a v4.
>
> ---
>  Documentation/ABI/testing/sysfs-devices-power |4 +-
>  drivers/base/cpu.c|3 +
>  drivers/base/power/domain.c   |2 -
>  drivers/base/power/domain_governor.c  |   40 
> ++
>  drivers/base/power/qos.c  |5 ++-
>  drivers/base/power/runtime.c  |2 -
>  drivers/base/power/sysfs.c|   25 +---
>  drivers/cpuidle/governors/menu.c  |4 +-
>  include/linux/pm_qos.h|   26 +++-
>  9 files changed, 68 insertions(+), 43 deletions(-)
>
> Index: linux-pm/drivers/base/power/sysfs.c
> ===
> --- linux-pm.orig/drivers/base/power/sysfs.c
> +++ linux-pm/drivers/base/power/sysfs.c
> @@ -218,7 +218,14 @@ static ssize_t pm_qos_resume_latency_sho
>   struct device_attribute *attr,
>   char *buf)
>  {
> -   return sprintf(buf, "%d\n", dev_pm_qos_requested_resume_latency(dev));
> +   s32 value = dev_pm_qos_requested_resume_latency(dev);
> +
> +   if (value == 0)
> +   return sprintf(buf, "n/a\n");
> +   else if (value == PM_QOS_RESUME_LATENCY_NO_CONSTRAINT)
> +   value = 0;
> +
> +   return sprintf(buf, "%d\n", value);
>  }
>
>  static ssize_t pm_qos_resume_latency_store(struct device *dev,
> @@ -228,11 +235,21 @@ static ssize_t pm_qos_resume_latency_sto
> s32 value;
> int ret;
>
> -   if (kstrtos32(buf, 0, ))
> -   return -EINVAL;
> +   if (!kstrtos32(buf, 0, )) {
> +   /*
> +* Prevent users from writing negative or "no constraint" 
> values
> +* directly.
> +*/
> +   if (value < 0 || value == PM_QOS_RESUME_LATENCY_NO_CONSTRAINT)
> +   return -EINVAL;
>
> -   if (value < 0)
> +   if (value == 0)
> +   value = PM_QOS_RESUME_LATENCY_NO_CONSTRAINT;
> +   } else if (!strcmp(buf, "n/a") || !strcmp(buf, "n/a\n")) {
> +   value = 0;
> +   } else {
> return -EINVAL;
> +   }
>
> ret = dev_pm_qos_update_request(dev->power.qos->resume_latency_req,
> value);
> Index: linux-pm/include/linux/pm_qos.h
> ===
> --- linux-pm.orig/include/linux/pm_qos.h
> +++ linux-pm/include/linux/pm_qos.h
> @@ -28,16 +28,19 @@ enum pm_qos_flags_status {
> PM_QOS_FLAGS_ALL,
>  };
>
> -#define PM_QOS_DEFAULT_VALUE -1
> +#define PM_QOS_DEFAULT_VALUE   (-1)
> +#define PM_QOS_LATENCY_ANY S32_MAX
> +#define PM_QOS_LATENCY_ANY_NS  ((s64)PM_QOS_LATENCY_ANY * NSEC_PER_USEC)
>
>  #define PM_QOS_CPU_DMA_LAT_DEFAULT_VALUE   (2000 * USEC_PER_SEC)
>  #define PM_QOS_NETWORK_LAT_DEFAULT_VALUE   (2000 * USEC_PER_SEC)
>  #define PM_QOS_NETWORK_THROUGHPUT_DEFAULT_VALUE0
>  #define 

Re: [PATCH v4 2/2] PM / QoS: Fix device resume latency framework

2017-11-09 Thread Ulf Hansson
On 7 November 2017 at 11:33, Rafael J. Wysocki  wrote:
> From: Rafael J. Wysocki 
>
> The special value of 0 for device resume latency PM QoS means
> "no restriction", but there are two problems with that.
>
> First, device resume latency PM QoS requests with 0 as the
> value are always put in front of requests with positive
> values in the priority lists used internally by the PM QoS
> framework, causing 0 to be chosen as an effective constraint
> value.  However, that 0 is then interpreted as "no restriction"
> effectively overriding the other requests with specific
> restrictions which is incorrect.
>
> Second, the users of device resume latency PM QoS have no
> way to specify that *any* resume latency at all should be
> avoided, which is an artificial limitation in general.
>
> To address these issues, modify device resume latency PM QoS to
> use S32_MAX as the "no constraint" value and 0 as the "no
> latency at all" one and rework its users (the cpuidle menu
> governor, the genpd QoS governor and the runtime PM framework)
> to follow these changes.
>
> Also add a special "n/a" value to the corresponding user space I/F
> to allow user space to indicate that it cannot accept any resume
> latencies at all for the given device.
>
> Fixes: 85dc0b8a4019 (PM / QoS: Make it possible to expose PM QoS latency 
> constraints)
> Link: https://bugzilla.kernel.org/show_bug.cgi?id=197323
> Reported-by: Reinette Chatre 
> Signed-off-by: Rafael J. Wysocki 
> Tested-by: Reinette Chatre 
> Tested-by: Geert Uytterhoeven 

Acked-by: Ulf Hansson 

Kind regards
Uffe

> ---
>
> As noticed by Ramesh, the v3 had issues with an overlooked value
> conversion and a stale comment, so here goes a v4.
>
> ---
>  Documentation/ABI/testing/sysfs-devices-power |4 +-
>  drivers/base/cpu.c|3 +
>  drivers/base/power/domain.c   |2 -
>  drivers/base/power/domain_governor.c  |   40 
> ++
>  drivers/base/power/qos.c  |5 ++-
>  drivers/base/power/runtime.c  |2 -
>  drivers/base/power/sysfs.c|   25 +---
>  drivers/cpuidle/governors/menu.c  |4 +-
>  include/linux/pm_qos.h|   26 +++-
>  9 files changed, 68 insertions(+), 43 deletions(-)
>
> Index: linux-pm/drivers/base/power/sysfs.c
> ===
> --- linux-pm.orig/drivers/base/power/sysfs.c
> +++ linux-pm/drivers/base/power/sysfs.c
> @@ -218,7 +218,14 @@ static ssize_t pm_qos_resume_latency_sho
>   struct device_attribute *attr,
>   char *buf)
>  {
> -   return sprintf(buf, "%d\n", dev_pm_qos_requested_resume_latency(dev));
> +   s32 value = dev_pm_qos_requested_resume_latency(dev);
> +
> +   if (value == 0)
> +   return sprintf(buf, "n/a\n");
> +   else if (value == PM_QOS_RESUME_LATENCY_NO_CONSTRAINT)
> +   value = 0;
> +
> +   return sprintf(buf, "%d\n", value);
>  }
>
>  static ssize_t pm_qos_resume_latency_store(struct device *dev,
> @@ -228,11 +235,21 @@ static ssize_t pm_qos_resume_latency_sto
> s32 value;
> int ret;
>
> -   if (kstrtos32(buf, 0, ))
> -   return -EINVAL;
> +   if (!kstrtos32(buf, 0, )) {
> +   /*
> +* Prevent users from writing negative or "no constraint" 
> values
> +* directly.
> +*/
> +   if (value < 0 || value == PM_QOS_RESUME_LATENCY_NO_CONSTRAINT)
> +   return -EINVAL;
>
> -   if (value < 0)
> +   if (value == 0)
> +   value = PM_QOS_RESUME_LATENCY_NO_CONSTRAINT;
> +   } else if (!strcmp(buf, "n/a") || !strcmp(buf, "n/a\n")) {
> +   value = 0;
> +   } else {
> return -EINVAL;
> +   }
>
> ret = dev_pm_qos_update_request(dev->power.qos->resume_latency_req,
> value);
> Index: linux-pm/include/linux/pm_qos.h
> ===
> --- linux-pm.orig/include/linux/pm_qos.h
> +++ linux-pm/include/linux/pm_qos.h
> @@ -28,16 +28,19 @@ enum pm_qos_flags_status {
> PM_QOS_FLAGS_ALL,
>  };
>
> -#define PM_QOS_DEFAULT_VALUE -1
> +#define PM_QOS_DEFAULT_VALUE   (-1)
> +#define PM_QOS_LATENCY_ANY S32_MAX
> +#define PM_QOS_LATENCY_ANY_NS  ((s64)PM_QOS_LATENCY_ANY * NSEC_PER_USEC)
>
>  #define PM_QOS_CPU_DMA_LAT_DEFAULT_VALUE   (2000 * USEC_PER_SEC)
>  #define PM_QOS_NETWORK_LAT_DEFAULT_VALUE   (2000 * USEC_PER_SEC)
>  #define PM_QOS_NETWORK_THROUGHPUT_DEFAULT_VALUE0
>  #define PM_QOS_MEMORY_BANDWIDTH_DEFAULT_VALUE  0
> -#define PM_QOS_RESUME_LATENCY_DEFAULT_VALUE0
> +#define PM_QOS_RESUME_LATENCY_DEFAULT_VALUEPM_QOS_LATENCY_ANY
> +#define 

[PATCH] fixup! kvm: arm debug: introduce helper for single-step

2017-11-09 Thread Alex Bennée
---
 arch/arm/include/asm/kvm_host.h | 5 -
 1 file changed, 4 insertions(+), 1 deletion(-)

diff --git a/arch/arm/include/asm/kvm_host.h b/arch/arm/include/asm/kvm_host.h
index a2e881d6108e..26a1ea6c6542 100644
--- a/arch/arm/include/asm/kvm_host.h
+++ b/arch/arm/include/asm/kvm_host.h
@@ -286,7 +286,10 @@ static inline void kvm_arm_setup_debug(struct kvm_vcpu 
*vcpu) {}
 static inline void kvm_arm_clear_debug(struct kvm_vcpu *vcpu) {}
 static inline void kvm_arm_reset_debug_ptr(struct kvm_vcpu *vcpu) {}
 static inline bool kvm_arm_handle_step_debug(struct kvm_vcpu *vcpu,
-struct kvm_run *run) {}
+struct kvm_run *run)
+{
+   return false;
+}
 
 int kvm_arm_vcpu_arch_set_attr(struct kvm_vcpu *vcpu,
   struct kvm_device_attr *attr);
-- 
2.14.2



[PATCH] fixup! kvm: arm debug: introduce helper for single-step

2017-11-09 Thread Alex Bennée
---
 arch/arm/include/asm/kvm_host.h | 5 -
 1 file changed, 4 insertions(+), 1 deletion(-)

diff --git a/arch/arm/include/asm/kvm_host.h b/arch/arm/include/asm/kvm_host.h
index a2e881d6108e..26a1ea6c6542 100644
--- a/arch/arm/include/asm/kvm_host.h
+++ b/arch/arm/include/asm/kvm_host.h
@@ -286,7 +286,10 @@ static inline void kvm_arm_setup_debug(struct kvm_vcpu 
*vcpu) {}
 static inline void kvm_arm_clear_debug(struct kvm_vcpu *vcpu) {}
 static inline void kvm_arm_reset_debug_ptr(struct kvm_vcpu *vcpu) {}
 static inline bool kvm_arm_handle_step_debug(struct kvm_vcpu *vcpu,
-struct kvm_run *run) {}
+struct kvm_run *run)
+{
+   return false;
+}
 
 int kvm_arm_vcpu_arch_set_attr(struct kvm_vcpu *vcpu,
   struct kvm_device_attr *attr);
-- 
2.14.2



[git pull] Input updates for v4.14-rc8

2017-11-09 Thread Dmitry Torokhov
Hi Linus,

Please pull from:

git://git.kernel.org/pub/scm/linux/kernel/git/dtor/input.git for-linus

to receive updates for the input subsystem. You will get:

- a new ACPI ID for Elan touchpad found in yet another Ideapad model;

- Synaptics RMI4 will allow binding to controllers reporting SMB version
  3 (note that we are not adding any new ACPI IDs to the Synaptics PS/2
  drover so unless user explicitly enables intertouch support there is
  no user-visible change);

- a fixup to TSC 2004/5 touchscreen driver to mark input devices as
  "direct" to help userspace identify the type of device they are
  dealing with.

Changelog:
-

Kai-Heng Feng (1):
  Input: elan_i2c - add ELAN060C to the ACPI table

Martin Kepplinger (1):
  Input: tsc200x-core - set INPUT_PROP_DIRECT

Yiannis Marangos (1):
  Input: synaptics-rmi4 - RMI4 can also use SMBUS version 3

Diffstat:


 drivers/input/mouse/elan_i2c_core.c  | 1 +
 drivers/input/rmi4/rmi_smbus.c   | 4 ++--
 drivers/input/touchscreen/tsc200x-core.c | 1 +
 3 files changed, 4 insertions(+), 2 deletions(-)

Thanks.


-- 
Dmitry


[git pull] Input updates for v4.14-rc8

2017-11-09 Thread Dmitry Torokhov
Hi Linus,

Please pull from:

git://git.kernel.org/pub/scm/linux/kernel/git/dtor/input.git for-linus

to receive updates for the input subsystem. You will get:

- a new ACPI ID for Elan touchpad found in yet another Ideapad model;

- Synaptics RMI4 will allow binding to controllers reporting SMB version
  3 (note that we are not adding any new ACPI IDs to the Synaptics PS/2
  drover so unless user explicitly enables intertouch support there is
  no user-visible change);

- a fixup to TSC 2004/5 touchscreen driver to mark input devices as
  "direct" to help userspace identify the type of device they are
  dealing with.

Changelog:
-

Kai-Heng Feng (1):
  Input: elan_i2c - add ELAN060C to the ACPI table

Martin Kepplinger (1):
  Input: tsc200x-core - set INPUT_PROP_DIRECT

Yiannis Marangos (1):
  Input: synaptics-rmi4 - RMI4 can also use SMBUS version 3

Diffstat:


 drivers/input/mouse/elan_i2c_core.c  | 1 +
 drivers/input/rmi4/rmi_smbus.c   | 4 ++--
 drivers/input/touchscreen/tsc200x-core.c | 1 +
 3 files changed, 4 insertions(+), 2 deletions(-)

Thanks.


-- 
Dmitry


[f2fs-dev] [PATCH] f2fs: validate before set/clear free nat bitmap

2017-11-09 Thread LiFan
In flush_nat_entries, all dirty nats will be flushed and if
their new address isn't NULL_ADDR, their bitmaps will be updated,
the free_nid_count of the bitmaps will be increaced regardless
of whether the nats have already been occupied before.
This could lead to wrong free_nid_count.
So this patch checks the status of the bits beforeactually
set/clear them.

Signed-off-by: Fan li 
---
 fs/f2fs/node.c | 17 ++---
 1 file changed, 10 insertions(+), 7 deletions(-)

diff --git a/fs/f2fs/node.c b/fs/f2fs/node.c
index d234c6e..b965a53 100644
--- a/fs/f2fs/node.c
+++ b/fs/f2fs/node.c
@@ -1906,15 +1906,18 @@ static void update_free_nid_bitmap(struct
f2fs_sb_info *sbi, nid_t nid,
if (!test_bit_le(nat_ofs, nm_i->nat_block_bitmap))
return;
 
-   if (set)
+   if (set) {
+   if (test_bit_le(nid_ofs, nm_i->free_nid_bitmap[nat_ofs]))
+   return;
__set_bit_le(nid_ofs, nm_i->free_nid_bitmap[nat_ofs]);
-   else
-   __clear_bit_le(nid_ofs, nm_i->free_nid_bitmap[nat_ofs]);
-
-   if (set)
nm_i->free_nid_count[nat_ofs]++;
-   else if (!build)
-   nm_i->free_nid_count[nat_ofs]--;
+   } else {
+   if (!test_bit_le(nid_ofs, nm_i->free_nid_bitmap[nat_ofs]))
+   return;
+   __clear_bit_le(nid_ofs, nm_i->free_nid_bitmap[nat_ofs]);
+   if (!build)
+   nm_i->free_nid_count[nat_ofs]--;
+   }
 }
 
 static void scan_nat_page(struct f2fs_sb_info *sbi,
-- 
2.7.4




[f2fs-dev] [PATCH] f2fs: validate before set/clear free nat bitmap

2017-11-09 Thread LiFan
In flush_nat_entries, all dirty nats will be flushed and if
their new address isn't NULL_ADDR, their bitmaps will be updated,
the free_nid_count of the bitmaps will be increaced regardless
of whether the nats have already been occupied before.
This could lead to wrong free_nid_count.
So this patch checks the status of the bits beforeactually
set/clear them.

Signed-off-by: Fan li 
---
 fs/f2fs/node.c | 17 ++---
 1 file changed, 10 insertions(+), 7 deletions(-)

diff --git a/fs/f2fs/node.c b/fs/f2fs/node.c
index d234c6e..b965a53 100644
--- a/fs/f2fs/node.c
+++ b/fs/f2fs/node.c
@@ -1906,15 +1906,18 @@ static void update_free_nid_bitmap(struct
f2fs_sb_info *sbi, nid_t nid,
if (!test_bit_le(nat_ofs, nm_i->nat_block_bitmap))
return;
 
-   if (set)
+   if (set) {
+   if (test_bit_le(nid_ofs, nm_i->free_nid_bitmap[nat_ofs]))
+   return;
__set_bit_le(nid_ofs, nm_i->free_nid_bitmap[nat_ofs]);
-   else
-   __clear_bit_le(nid_ofs, nm_i->free_nid_bitmap[nat_ofs]);
-
-   if (set)
nm_i->free_nid_count[nat_ofs]++;
-   else if (!build)
-   nm_i->free_nid_count[nat_ofs]--;
+   } else {
+   if (!test_bit_le(nid_ofs, nm_i->free_nid_bitmap[nat_ofs]))
+   return;
+   __clear_bit_le(nid_ofs, nm_i->free_nid_bitmap[nat_ofs]);
+   if (!build)
+   nm_i->free_nid_count[nat_ofs]--;
+   }
 }
 
 static void scan_nat_page(struct f2fs_sb_info *sbi,
-- 
2.7.4




Re: [PATCH v2] locking/lockdep: Revise Documentation/locking/crossrelease.txt

2017-11-09 Thread Byungchul Park

On 11/10/2017 4:30 PM, Ingo Molnar wrote:


* Byungchul Park  wrote:


 Event C depends on event A.
 Event A depends on event B.
 Event B depends on event C.
  
-   NOTE: Precisely speaking, a dependency is one between whether a

-   waiter for an event can be woken up and whether another waiter for
-   another event can be woken up. However from now on, we will describe
-   a dependency as if it's one between an event and another event for
-   simplicity.


Why was this explanation removed?


-Lockdep tries to detect a deadlock by checking dependencies created by
-lock operations, acquire and release. Waiting for a lock corresponds to
-waiting for an event, and releasing a lock corresponds to triggering an
-event in the previous section.
+Lockdep tries to detect a deadlock by checking circular dependencies
+created by lock operations, acquire and release, which are wait and
+event respectively.


What? You changed a readable paragraph into an unreadable one.

Sorry, this text needs to be acked by someone with good English skills, and I
don't have the time right now to fix it all up. Please send minimal, obvious
typo/grammar fixes only.


I will send one including minimal fixes at the next spin.

--
Thanks,
Byungchul


Re: [PATCH v2] locking/lockdep: Revise Documentation/locking/crossrelease.txt

2017-11-09 Thread Byungchul Park

On 11/10/2017 4:30 PM, Ingo Molnar wrote:


* Byungchul Park  wrote:


 Event C depends on event A.
 Event A depends on event B.
 Event B depends on event C.
  
-   NOTE: Precisely speaking, a dependency is one between whether a

-   waiter for an event can be woken up and whether another waiter for
-   another event can be woken up. However from now on, we will describe
-   a dependency as if it's one between an event and another event for
-   simplicity.


Why was this explanation removed?


-Lockdep tries to detect a deadlock by checking dependencies created by
-lock operations, acquire and release. Waiting for a lock corresponds to
-waiting for an event, and releasing a lock corresponds to triggering an
-event in the previous section.
+Lockdep tries to detect a deadlock by checking circular dependencies
+created by lock operations, acquire and release, which are wait and
+event respectively.


What? You changed a readable paragraph into an unreadable one.

Sorry, this text needs to be acked by someone with good English skills, and I
don't have the time right now to fix it all up. Please send minimal, obvious
typo/grammar fixes only.


I will send one including minimal fixes at the next spin.

--
Thanks,
Byungchul


[PATCH RFC] kbuild: fixes in Makefile.lib

2017-11-09 Thread Cao jin
commit

  cf4f21938e13e ("kbuild: Allow to specify composite modules with modname-m")

add modname-m support, but miss to update the corresponding multi-objs-m
defination.

commit 551559e13af1c ("kbuild: implement modules.order") miss to filter
the subdir listed in obj-m. Except that the subdirs are totally identical
between obj-y and obj-m, or else I think it will miss something.

But until now, no one has complaining about it, so I guess it just no
one has triggerred it.

Signed-off-by: Cao jin 
---
I found these 2 points which I think might be wrong during code
inspection, but until now, they seems didn't do anything bad, so I am not
sure this is a problem:)

 scripts/Makefile.lib | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/scripts/Makefile.lib b/scripts/Makefile.lib
index 580e605118e4..3209f303213b 100644
--- a/scripts/Makefile.lib
+++ b/scripts/Makefile.lib
@@ -22,7 +22,7 @@ lib-y := $(filter-out $(obj-y), $(sort $(lib-y) $(lib-m)))
 # Determine modorder.
 # Unfortunately, we don't have information about ordering between -y
 # and -m subdirs.  Just put -y's first.
-modorder   := $(patsubst %/,%/modules.order, $(filter %/, $(obj-y)) 
$(obj-m:.o=.ko))
+modorder   := $(patsubst %/,%/modules.order, $(filter %/, $(obj-y) 
$(obj-m) $(obj-m:.o=.ko))
 
 # Handle objects in subdirs
 # ---
@@ -49,7 +49,7 @@ single-used-m := $(sort $(filter-out 
$(multi-used-m),$(obj-m)))
 # Build list of the parts of our composite objects, our composite
 # objects depend on those (obviously)
 multi-objs-y := $(foreach m, $(multi-used-y), $($(m:.o=-objs)) $($(m:.o=-y)))
-multi-objs-m := $(foreach m, $(multi-used-m), $($(m:.o=-objs)) $($(m:.o=-y)))
+multi-objs-m := $(foreach m, $(multi-used-m), $($(m:.o=-objs)) $($(m:.o=-y)) 
$($(m:.o=-m))
 multi-objs   := $(multi-objs-y) $(multi-objs-m)
 
 # $(subdir-obj-y) is the list of objects in $(obj-y) which uses dir/ to
-- 
2.13.6





[PATCH RFC] kbuild: fixes in Makefile.lib

2017-11-09 Thread Cao jin
commit

  cf4f21938e13e ("kbuild: Allow to specify composite modules with modname-m")

add modname-m support, but miss to update the corresponding multi-objs-m
defination.

commit 551559e13af1c ("kbuild: implement modules.order") miss to filter
the subdir listed in obj-m. Except that the subdirs are totally identical
between obj-y and obj-m, or else I think it will miss something.

But until now, no one has complaining about it, so I guess it just no
one has triggerred it.

Signed-off-by: Cao jin 
---
I found these 2 points which I think might be wrong during code
inspection, but until now, they seems didn't do anything bad, so I am not
sure this is a problem:)

 scripts/Makefile.lib | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/scripts/Makefile.lib b/scripts/Makefile.lib
index 580e605118e4..3209f303213b 100644
--- a/scripts/Makefile.lib
+++ b/scripts/Makefile.lib
@@ -22,7 +22,7 @@ lib-y := $(filter-out $(obj-y), $(sort $(lib-y) $(lib-m)))
 # Determine modorder.
 # Unfortunately, we don't have information about ordering between -y
 # and -m subdirs.  Just put -y's first.
-modorder   := $(patsubst %/,%/modules.order, $(filter %/, $(obj-y)) 
$(obj-m:.o=.ko))
+modorder   := $(patsubst %/,%/modules.order, $(filter %/, $(obj-y) 
$(obj-m) $(obj-m:.o=.ko))
 
 # Handle objects in subdirs
 # ---
@@ -49,7 +49,7 @@ single-used-m := $(sort $(filter-out 
$(multi-used-m),$(obj-m)))
 # Build list of the parts of our composite objects, our composite
 # objects depend on those (obviously)
 multi-objs-y := $(foreach m, $(multi-used-y), $($(m:.o=-objs)) $($(m:.o=-y)))
-multi-objs-m := $(foreach m, $(multi-used-m), $($(m:.o=-objs)) $($(m:.o=-y)))
+multi-objs-m := $(foreach m, $(multi-used-m), $($(m:.o=-objs)) $($(m:.o=-y)) 
$($(m:.o=-m))
 multi-objs   := $(multi-objs-y) $(multi-objs-m)
 
 # $(subdir-obj-y) is the list of objects in $(obj-y) which uses dir/ to
-- 
2.13.6





Re: [PATCH v5 15/37] tracing: Add variable support to hist triggers

2017-11-09 Thread Namhyung Kim
Hi Tom,

On Thu, Nov 09, 2017 at 02:33:46PM -0600, Tom Zanussi wrote:
> Add support for saving the value of a current event's event field by
> assigning it to a variable that can be read by a subsequent event.
> 
> The basic syntax for saving a variable is to simply prefix a unique
> variable name not corresponding to any keyword along with an '=' sign
> to any event field.
> 
> Both keys and values can be saved and retrieved in this way:
> 
> # echo 'hist:keys=next_pid:vals=$ts0:ts0=$common_timestamp ...
> # echo 'hist:timer_pid=common_pid:key=$timer_pid ...'
> 
> If a variable isn't a key variable or prefixed with 'vals=', the
> associated event field will be saved in a variable but won't be summed
> as a value:
> 
> # echo 'hist:keys=next_pid:ts1=$common_timestamp:...
> 
> Multiple variables can be assigned at the same time:
> 
> # echo 'hist:keys=pid:vals=$ts0,$b,field2:ts0=$common_timestamp,b=field1 
> ...
> 
> Multiple (or single) variables can also be assigned at the same time
> using separate assignments:
> 
> # echo 'hist:keys=pid:vals=$ts0:ts0=$common_timestamp:b=field1:c=field2 
> ...
> 
> Variables set as above can be used by being referenced from another
> event, as described in a subsequent patch.
> 
> Signed-off-by: Tom Zanussi 
> Signed-off-by: Baohong Liu 
> ---

[SNIP]
> +static int parse_var_defs(struct hist_trigger_data *hist_data)
> +{
> + char *s, *str, *var_name, *field_str;
> + unsigned int i, j, n_vars = 0;
> + int ret = 0;
> +
> + for (i = 0; i < hist_data->attrs->n_assignments; i++) {
> + str = hist_data->attrs->assignment_str[i];
> + for (j = 0; j < TRACING_MAP_VARS_MAX; j++) {
> + field_str = strsep(, ",");
> + if (!field_str)
> + break;
> +
> + var_name = strsep(_str, "=");
> + if (!var_name || !field_str) {
> + ret = -EINVAL;
> + goto free;
> + }
> +
> + s = kstrdup(var_name, GFP_KERNEL);
> + if (!s) {
> + ret = -ENOMEM;
> + goto free;
> + }
> + hist_data->attrs->var_defs.name[n_vars] = s;
> +
> + s = kstrdup(field_str, GFP_KERNEL);
> + if (!s) {
> + kfree(hist_data->attrs->var_defs.name[n_vars]);
> + ret = -ENOMEM;
> + goto free;
> + }
> + hist_data->attrs->var_defs.expr[n_vars++] = s;
> +
> + hist_data->attrs->var_defs.n_vars = n_vars;
> +
> + if (n_vars == TRACING_MAP_VARS_MAX)
> + goto free;

This will silently discard all variables.  Why not returning an error?
Also I think it should be moved to the beginning of this block..

Thanks,
Namhyung


> + }
> + }
> +
> + return ret;
> + free:
> + free_var_defs(hist_data);
> +
> + return ret;
> +}


Re: [PATCH v5 15/37] tracing: Add variable support to hist triggers

2017-11-09 Thread Namhyung Kim
Hi Tom,

On Thu, Nov 09, 2017 at 02:33:46PM -0600, Tom Zanussi wrote:
> Add support for saving the value of a current event's event field by
> assigning it to a variable that can be read by a subsequent event.
> 
> The basic syntax for saving a variable is to simply prefix a unique
> variable name not corresponding to any keyword along with an '=' sign
> to any event field.
> 
> Both keys and values can be saved and retrieved in this way:
> 
> # echo 'hist:keys=next_pid:vals=$ts0:ts0=$common_timestamp ...
> # echo 'hist:timer_pid=common_pid:key=$timer_pid ...'
> 
> If a variable isn't a key variable or prefixed with 'vals=', the
> associated event field will be saved in a variable but won't be summed
> as a value:
> 
> # echo 'hist:keys=next_pid:ts1=$common_timestamp:...
> 
> Multiple variables can be assigned at the same time:
> 
> # echo 'hist:keys=pid:vals=$ts0,$b,field2:ts0=$common_timestamp,b=field1 
> ...
> 
> Multiple (or single) variables can also be assigned at the same time
> using separate assignments:
> 
> # echo 'hist:keys=pid:vals=$ts0:ts0=$common_timestamp:b=field1:c=field2 
> ...
> 
> Variables set as above can be used by being referenced from another
> event, as described in a subsequent patch.
> 
> Signed-off-by: Tom Zanussi 
> Signed-off-by: Baohong Liu 
> ---

[SNIP]
> +static int parse_var_defs(struct hist_trigger_data *hist_data)
> +{
> + char *s, *str, *var_name, *field_str;
> + unsigned int i, j, n_vars = 0;
> + int ret = 0;
> +
> + for (i = 0; i < hist_data->attrs->n_assignments; i++) {
> + str = hist_data->attrs->assignment_str[i];
> + for (j = 0; j < TRACING_MAP_VARS_MAX; j++) {
> + field_str = strsep(, ",");
> + if (!field_str)
> + break;
> +
> + var_name = strsep(_str, "=");
> + if (!var_name || !field_str) {
> + ret = -EINVAL;
> + goto free;
> + }
> +
> + s = kstrdup(var_name, GFP_KERNEL);
> + if (!s) {
> + ret = -ENOMEM;
> + goto free;
> + }
> + hist_data->attrs->var_defs.name[n_vars] = s;
> +
> + s = kstrdup(field_str, GFP_KERNEL);
> + if (!s) {
> + kfree(hist_data->attrs->var_defs.name[n_vars]);
> + ret = -ENOMEM;
> + goto free;
> + }
> + hist_data->attrs->var_defs.expr[n_vars++] = s;
> +
> + hist_data->attrs->var_defs.n_vars = n_vars;
> +
> + if (n_vars == TRACING_MAP_VARS_MAX)
> + goto free;

This will silently discard all variables.  Why not returning an error?
Also I think it should be moved to the beginning of this block..

Thanks,
Namhyung


> + }
> + }
> +
> + return ret;
> + free:
> + free_var_defs(hist_data);
> +
> + return ret;
> +}


[RFC PATCH] mm: fix device-dax pud write-faults triggered by get_user_pages()

2017-11-09 Thread Dan Williams
Currently only get_user_pages_fast() can safely handle the writable gup
case due to its use of pud_access_permitted() to check whether the pud
entry is writable. In the gup slow path pud_write() is used instead of
pud_access_permitted() and to date it has been unimplemented, just calls
BUG_ON().

kernel BUG at ./include/linux/hugetlb.h:244!
[..]
RIP: 0010:follow_devmap_pud+0x482/0x490
[..]
Call Trace:
 follow_page_mask+0x28c/0x6e0
 __get_user_pages+0xe4/0x6c0
 get_user_pages_unlocked+0x130/0x1b0
 get_user_pages_fast+0x89/0xb0
 iov_iter_get_pages_alloc+0x114/0x4a0
 nfs_direct_read_schedule_iovec+0xd2/0x350
 ? nfs_start_io_direct+0x63/0x70
 nfs_file_direct_read+0x1e0/0x250
 nfs_file_read+0x90/0xc0

Use pud_access_permitted() to implement pud_write(), a later cleanup can
remove {pte,pmd,pud}_write and replace them with
{pte,pmd,pud}_access_permitted() drectly so that we only have one set of
helpers these kinds of checks. For now, implementing pud_write()
simplifies -stable backports.

Cc: 
Cc: Dave Hansen 
Fixes: a00cc7d9dd93 ("mm, x86: add support for PUD-sized transparent hugepages")
Signed-off-by: Dan Williams 
---

Sending this as RFC for opinion on whether this should just be a
pud_flags() & _PAGE_RW check, like pmd_write, or pud_access_permitted()
that also takes protection keys into account.

 include/linux/hugetlb.h |3 +--
 1 file changed, 1 insertion(+), 2 deletions(-)

diff --git a/include/linux/hugetlb.h b/include/linux/hugetlb.h
index fbf5b31d47ee..6a142b240ef7 100644
--- a/include/linux/hugetlb.h
+++ b/include/linux/hugetlb.h
@@ -242,8 +242,7 @@ static inline int pgd_write(pgd_t pgd)
 #ifndef pud_write
 static inline int pud_write(pud_t pud)
 {
-   BUG();
-   return 0;
+   return pud_access_permitted(pud, WRITE);
 }
 #endif
 



[RFC PATCH] mm: fix device-dax pud write-faults triggered by get_user_pages()

2017-11-09 Thread Dan Williams
Currently only get_user_pages_fast() can safely handle the writable gup
case due to its use of pud_access_permitted() to check whether the pud
entry is writable. In the gup slow path pud_write() is used instead of
pud_access_permitted() and to date it has been unimplemented, just calls
BUG_ON().

kernel BUG at ./include/linux/hugetlb.h:244!
[..]
RIP: 0010:follow_devmap_pud+0x482/0x490
[..]
Call Trace:
 follow_page_mask+0x28c/0x6e0
 __get_user_pages+0xe4/0x6c0
 get_user_pages_unlocked+0x130/0x1b0
 get_user_pages_fast+0x89/0xb0
 iov_iter_get_pages_alloc+0x114/0x4a0
 nfs_direct_read_schedule_iovec+0xd2/0x350
 ? nfs_start_io_direct+0x63/0x70
 nfs_file_direct_read+0x1e0/0x250
 nfs_file_read+0x90/0xc0

Use pud_access_permitted() to implement pud_write(), a later cleanup can
remove {pte,pmd,pud}_write and replace them with
{pte,pmd,pud}_access_permitted() drectly so that we only have one set of
helpers these kinds of checks. For now, implementing pud_write()
simplifies -stable backports.

Cc: 
Cc: Dave Hansen 
Fixes: a00cc7d9dd93 ("mm, x86: add support for PUD-sized transparent hugepages")
Signed-off-by: Dan Williams 
---

Sending this as RFC for opinion on whether this should just be a
pud_flags() & _PAGE_RW check, like pmd_write, or pud_access_permitted()
that also takes protection keys into account.

 include/linux/hugetlb.h |3 +--
 1 file changed, 1 insertion(+), 2 deletions(-)

diff --git a/include/linux/hugetlb.h b/include/linux/hugetlb.h
index fbf5b31d47ee..6a142b240ef7 100644
--- a/include/linux/hugetlb.h
+++ b/include/linux/hugetlb.h
@@ -242,8 +242,7 @@ static inline int pgd_write(pgd_t pgd)
 #ifndef pud_write
 static inline int pud_write(pud_t pud)
 {
-   BUG();
-   return 0;
+   return pud_access_permitted(pud, WRITE);
 }
 #endif
 



Re: [PATCH v2] locking/lockdep: Revise Documentation/locking/crossrelease.txt

2017-11-09 Thread Ingo Molnar

* Byungchul Park  wrote:

> Event C depends on event A.
> Event A depends on event B.
> Event B depends on event C.
>  
> -   NOTE: Precisely speaking, a dependency is one between whether a
> -   waiter for an event can be woken up and whether another waiter for
> -   another event can be woken up. However from now on, we will describe
> -   a dependency as if it's one between an event and another event for
> -   simplicity.

Why was this explanation removed?

> -Lockdep tries to detect a deadlock by checking dependencies created by
> -lock operations, acquire and release. Waiting for a lock corresponds to
> -waiting for an event, and releasing a lock corresponds to triggering an
> -event in the previous section.
> +Lockdep tries to detect a deadlock by checking circular dependencies
> +created by lock operations, acquire and release, which are wait and
> +event respectively.

What? You changed a readable paragraph into an unreadable one.

Sorry, this text needs to be acked by someone with good English skills, and I 
don't have the time right now to fix it all up. Please send minimal, obvious
typo/grammar fixes only.

Thanks,

Ingo


Re: [PATCH v2] locking/lockdep: Revise Documentation/locking/crossrelease.txt

2017-11-09 Thread Ingo Molnar

* Byungchul Park  wrote:

> Event C depends on event A.
> Event A depends on event B.
> Event B depends on event C.
>  
> -   NOTE: Precisely speaking, a dependency is one between whether a
> -   waiter for an event can be woken up and whether another waiter for
> -   another event can be woken up. However from now on, we will describe
> -   a dependency as if it's one between an event and another event for
> -   simplicity.

Why was this explanation removed?

> -Lockdep tries to detect a deadlock by checking dependencies created by
> -lock operations, acquire and release. Waiting for a lock corresponds to
> -waiting for an event, and releasing a lock corresponds to triggering an
> -event in the previous section.
> +Lockdep tries to detect a deadlock by checking circular dependencies
> +created by lock operations, acquire and release, which are wait and
> +event respectively.

What? You changed a readable paragraph into an unreadable one.

Sorry, this text needs to be acked by someone with good English skills, and I 
don't have the time right now to fix it all up. Please send minimal, obvious
typo/grammar fixes only.

Thanks,

Ingo


Re: [PATCH] x86: use cpufreq_quick_get() for /proc/cpuinfo "cpu MHz" again

2017-11-09 Thread Ingo Molnar

* Rafael J. Wysocki  wrote:

> Hi Linus,
> 
> On 11/9/2017 11:38 AM, WANG Chao wrote:
> > Commit 941f5f0f6ef5 (x86: CPU: Fix up "cpu MHz" in /proc/cpuinfo) caused
> > a serious performance issue when reading from /proc/cpuinfo on system
> > with aperfmperf.
> > 
> > For each cpu, arch_freq_get_on_cpu() sleeps 20ms to get its frequency.
> > On a system with 64 cpus, it takes 1.5s to finish running `cat
> > /proc/cpuinfo`, while it previously was done in 15ms.
> 
> Honestly, I'm not sure what to do to address this ATM.
> 
> The last requested frequency is only available in the non-HWP case, so it
> cannot be used universally.

This is a serious regression that needs to be fixed ASAP, because the slowdown 
is 
utterly ridiculous on a 120 CPU system:

  fomalhaut:~> time cat /proc/cpuinfo  >/dev/null

  real0m2.689s
  user0m0.001s
  sys 0m0.007s

Thanks,

Ingo


Re: [PATCH] x86: use cpufreq_quick_get() for /proc/cpuinfo "cpu MHz" again

2017-11-09 Thread Ingo Molnar

* Rafael J. Wysocki  wrote:

> Hi Linus,
> 
> On 11/9/2017 11:38 AM, WANG Chao wrote:
> > Commit 941f5f0f6ef5 (x86: CPU: Fix up "cpu MHz" in /proc/cpuinfo) caused
> > a serious performance issue when reading from /proc/cpuinfo on system
> > with aperfmperf.
> > 
> > For each cpu, arch_freq_get_on_cpu() sleeps 20ms to get its frequency.
> > On a system with 64 cpus, it takes 1.5s to finish running `cat
> > /proc/cpuinfo`, while it previously was done in 15ms.
> 
> Honestly, I'm not sure what to do to address this ATM.
> 
> The last requested frequency is only available in the non-HWP case, so it
> cannot be used universally.

This is a serious regression that needs to be fixed ASAP, because the slowdown 
is 
utterly ridiculous on a 120 CPU system:

  fomalhaut:~> time cat /proc/cpuinfo  >/dev/null

  real0m2.689s
  user0m0.001s
  sys 0m0.007s

Thanks,

Ingo


Re: [alsa-devel] [RFC PATCH v2 7/7] sound: core: Avoid using timespec for struct snd_timer_tread

2017-11-09 Thread Takashi Iwai
On Fri, 10 Nov 2017 00:20:10 +0100,
Arnd Bergmann wrote:
> 
> On Thu, Nov 9, 2017 at 7:11 PM, Takashi Iwai  wrote:
> > On Thu, 09 Nov 2017 18:01:47 +0100,
> > Arnd Bergmann wrote:
> >>
> >> On Thu, Nov 9, 2017 at 5:52 PM, Takashi Iwai  wrote:
> >> >
> >> > IOW, is there any macro indicating the 64bit user time_t?
> >>
> >> There is a macro defined by the C library, but so far we have not
> >> started relying on it in kernel headers, because there is no guarantee
> >> that this symbol is visible before sys/time.h has been included,
> >> and there are some cases where it's possible to include a kernel
> >> header before sys/time.h.
> >>
> >> In case of sound/asound.h, that should be no problem since we rely
> >> on having seen the definition on 'struct timeval' already today, and
> >> that must come from sys/time.h. Then we just need to make sure that
> >> all C libraries define the same macro.
> >>
> >> Are you sure about the switch()/case problem? I thought that worked
> >> in C99, the only problem would be using the macro outside of a
> >> function, e.g. as initalizer for a variable
> >
> > Hmm, OK it seems working.
> >
> > But, honestly speaking, it's too scaring.  I'm OK if it were only in
> > the kernel local code.  But it's the API/ABI definition, which is
> > referred by user-space...
> >
> > A more solid condition would be really appreciated.
> 
> I understand your concern here and agree it's really ugly. It did take us
> many attempts to come up with this trick for other cases, so my initial
> reaction would be to use the same thing everywhere since I know
> it works,  but we can use #ifdef instead if you prefer that. I think we
> can use a single #ifdef variant to cover all cases, but I'd have to think
> about the x32 and x86-32 some more here. With this trick, we can
> make user space with new glibc use data structures that are compatible
> with 64-bit kernels and avoid the additional translation helpers:
> 
> enum {
>   SNDRV_PCM_MMAP_OFFSET_DATA = 0x,
>   SNDRV_PCM_MMAP_OFFSET_CONTROL = 0x8100,
> #if (__BITS_PER_LONG == 64) || !defined(__USE_TIME_BITS64)

Yeah, it's definitely better, more understandable!


thanks,

Takashi


Re: [alsa-devel] [RFC PATCH v2 7/7] sound: core: Avoid using timespec for struct snd_timer_tread

2017-11-09 Thread Takashi Iwai
On Fri, 10 Nov 2017 00:20:10 +0100,
Arnd Bergmann wrote:
> 
> On Thu, Nov 9, 2017 at 7:11 PM, Takashi Iwai  wrote:
> > On Thu, 09 Nov 2017 18:01:47 +0100,
> > Arnd Bergmann wrote:
> >>
> >> On Thu, Nov 9, 2017 at 5:52 PM, Takashi Iwai  wrote:
> >> >
> >> > IOW, is there any macro indicating the 64bit user time_t?
> >>
> >> There is a macro defined by the C library, but so far we have not
> >> started relying on it in kernel headers, because there is no guarantee
> >> that this symbol is visible before sys/time.h has been included,
> >> and there are some cases where it's possible to include a kernel
> >> header before sys/time.h.
> >>
> >> In case of sound/asound.h, that should be no problem since we rely
> >> on having seen the definition on 'struct timeval' already today, and
> >> that must come from sys/time.h. Then we just need to make sure that
> >> all C libraries define the same macro.
> >>
> >> Are you sure about the switch()/case problem? I thought that worked
> >> in C99, the only problem would be using the macro outside of a
> >> function, e.g. as initalizer for a variable
> >
> > Hmm, OK it seems working.
> >
> > But, honestly speaking, it's too scaring.  I'm OK if it were only in
> > the kernel local code.  But it's the API/ABI definition, which is
> > referred by user-space...
> >
> > A more solid condition would be really appreciated.
> 
> I understand your concern here and agree it's really ugly. It did take us
> many attempts to come up with this trick for other cases, so my initial
> reaction would be to use the same thing everywhere since I know
> it works,  but we can use #ifdef instead if you prefer that. I think we
> can use a single #ifdef variant to cover all cases, but I'd have to think
> about the x32 and x86-32 some more here. With this trick, we can
> make user space with new glibc use data structures that are compatible
> with 64-bit kernels and avoid the additional translation helpers:
> 
> enum {
>   SNDRV_PCM_MMAP_OFFSET_DATA = 0x,
>   SNDRV_PCM_MMAP_OFFSET_CONTROL = 0x8100,
> #if (__BITS_PER_LONG == 64) || !defined(__USE_TIME_BITS64)

Yeah, it's definitely better, more understandable!


thanks,

Takashi


Re: [PATCH] x86, pkeys: update documentation about availability

2017-11-09 Thread Ingo Molnar

* Dave Hansen  wrote:

> On 11/09/2017 10:12 PM, Ingo Molnar wrote:
> > 
> > * Dave Hansen  wrote:
> > 
> >>
> >> From: Dave Hansen 
> >>
> >> Now that CPUs that implement Memory Protection Keys are publicly
> >> available we can be a bit less oblique about where it is available.
> >>
> >> Signed-off-by: Dave Hansen 
> >> ---
> >>
> >>  b/Documentation/x86/protection-keys.txt |9 +++--
> >>  1 file changed, 7 insertions(+), 2 deletions(-)
> >>
> >> diff -puN Documentation/x86/protection-keys.txt~pkeys-update 
> >> Documentation/x86/protection-keys.txt
> >> --- a/Documentation/x86/protection-keys.txt~pkeys-update   2017-11-09 
> >> 10:36:53.381467202 -0800
> >> +++ b/Documentation/x86/protection-keys.txt2017-11-09 
> >> 10:43:15.527466249 -0800
> >> @@ -1,5 +1,10 @@
> >> -Memory Protection Keys for Userspace (PKU aka PKEYs) is a CPU feature
> >> -which will be found on future Intel CPUs.
> >> +Memory Protection Keys for Userspace (PKU aka PKEYs) is a feature
> >> +which is found on Intel's Skylake "Scalable Processor" Server CPUs.
> >> +It will be avalable in future non-server parts.
> >> +
> >> +For anyone wishing to test or use this feature, it is available in
> >> +Amazon's EC2 C5 instances and is known to work there using an Ubuntu
> >> +17.04 image.
> >>  
> >>  Memory Protection Keys provides a mechanism for enforcing page-based
> >>  protections, but without requiring modification of the page tables
> > 
> > Could we please first fix the pkeys self-test? One of the testcases doesn't 
> > build 
> > at all:
> > 
> >  gcc -m32 -o /home/mingo/tip/tools/testing/selftests/x86/protection_keys_32 
> > -O2 -g -std=gnu99 -pthread -Wall -no-pie  protection_keys.c -lrt -ldl -lm
> >  In file included from /usr/include/signal.h:57:0,
> >   from protection_keys.c:33:
> >  protection_keys.c: In function ‘signal_handler’:
> >  protection_keys.c:253:6: error: expected ‘=’, ‘,’, ‘;’, ‘asm’ or 
> > ‘__attribute__’ 
> >  before ‘.’ token
> >u64 si_pkey;
> 
> That's odd.  I build them all the time.  I compiled it just now with
> 4.14-rc8 and gcc 4.8.4.
> 
> I wonder if this is more fallout from the glibc headers getting updated
> to now contain pkey-related stuff.  si_pkey might be getting #defined
> over for the siginfo si_pkey.
> 
> What distro are you seeing this on?

Latest Ubuntu, 17.10:

  triton:~/tip> cat /etc/os-release 
  NAME="Ubuntu"
  VERSION="17.10 (Artful Aardvark)"

  triton:~/tip> apt-file find /usr/include/signal.h
  libc6-dev: /usr/include/signal.h

  triton:~/tip> dpkg -l libc6-dev
  Desired=Unknown/Install/Remove/Purge/Hold
  | Status=Not/Inst/Conf-files/Unpacked/halF-conf/Half-inst/trig-aWait/Trig-pend
  |/ Err?=(none)/Reinst-required (Status,Err: uppercase=bad)
  ||/ NameVersion  
Architecture Description
  
+++-===---
  ii  libc6-dev:amd64 2.26-0ubuntu2amd64
GNU C Library: Development Libraries and Header Files


> > plus, on a related note, the MPX testcase produces annoying warnings:
> > 
> >  gcc -m32 -o /home/mingo/tip/tools/testing/selftests/x86/mpx-mini-test_32 
> > -O2 -g -std=gnu99 -pthread -Wall -no-pie  mpx-mini-test.c -lrt -ldl -lm
> >  mpx-mini-test.c: In function ‘insn_test_failed’:
> >  mpx-mini-test.c:1406:3: warning: array subscript is above array bounds 
> >  [-Warray-bounds]
> > printf("bte[1]: %lx\n", bte->contents[1]);
> 
> This is kinda a weird structure:
> 
> > struct mpx_bt_entry {
> > union {
> > char x[MPX_BOUNDS_TABLE_ENTRY_SIZE_BYTES];
> > unsigned long contents[1];
> > };
> > } __attribute__((packed));
> 
> I guess it should either be contents[0] or
> contents[MPX_BOUNDS_TABLE_ENTRY_SIZE_BYTE/sizeof(long)].  But, the
> warning is harmless at least.
> 
> What gcc is this, btw?  I must be behind the times.

gcc version 7.2.0 (Ubuntu 7.2.0-8ubuntu3) 

Thanks,

Ingo


Re: [PATCH] x86, pkeys: update documentation about availability

2017-11-09 Thread Ingo Molnar

* Dave Hansen  wrote:

> On 11/09/2017 10:12 PM, Ingo Molnar wrote:
> > 
> > * Dave Hansen  wrote:
> > 
> >>
> >> From: Dave Hansen 
> >>
> >> Now that CPUs that implement Memory Protection Keys are publicly
> >> available we can be a bit less oblique about where it is available.
> >>
> >> Signed-off-by: Dave Hansen 
> >> ---
> >>
> >>  b/Documentation/x86/protection-keys.txt |9 +++--
> >>  1 file changed, 7 insertions(+), 2 deletions(-)
> >>
> >> diff -puN Documentation/x86/protection-keys.txt~pkeys-update 
> >> Documentation/x86/protection-keys.txt
> >> --- a/Documentation/x86/protection-keys.txt~pkeys-update   2017-11-09 
> >> 10:36:53.381467202 -0800
> >> +++ b/Documentation/x86/protection-keys.txt2017-11-09 
> >> 10:43:15.527466249 -0800
> >> @@ -1,5 +1,10 @@
> >> -Memory Protection Keys for Userspace (PKU aka PKEYs) is a CPU feature
> >> -which will be found on future Intel CPUs.
> >> +Memory Protection Keys for Userspace (PKU aka PKEYs) is a feature
> >> +which is found on Intel's Skylake "Scalable Processor" Server CPUs.
> >> +It will be avalable in future non-server parts.
> >> +
> >> +For anyone wishing to test or use this feature, it is available in
> >> +Amazon's EC2 C5 instances and is known to work there using an Ubuntu
> >> +17.04 image.
> >>  
> >>  Memory Protection Keys provides a mechanism for enforcing page-based
> >>  protections, but without requiring modification of the page tables
> > 
> > Could we please first fix the pkeys self-test? One of the testcases doesn't 
> > build 
> > at all:
> > 
> >  gcc -m32 -o /home/mingo/tip/tools/testing/selftests/x86/protection_keys_32 
> > -O2 -g -std=gnu99 -pthread -Wall -no-pie  protection_keys.c -lrt -ldl -lm
> >  In file included from /usr/include/signal.h:57:0,
> >   from protection_keys.c:33:
> >  protection_keys.c: In function ‘signal_handler’:
> >  protection_keys.c:253:6: error: expected ‘=’, ‘,’, ‘;’, ‘asm’ or 
> > ‘__attribute__’ 
> >  before ‘.’ token
> >u64 si_pkey;
> 
> That's odd.  I build them all the time.  I compiled it just now with
> 4.14-rc8 and gcc 4.8.4.
> 
> I wonder if this is more fallout from the glibc headers getting updated
> to now contain pkey-related stuff.  si_pkey might be getting #defined
> over for the siginfo si_pkey.
> 
> What distro are you seeing this on?

Latest Ubuntu, 17.10:

  triton:~/tip> cat /etc/os-release 
  NAME="Ubuntu"
  VERSION="17.10 (Artful Aardvark)"

  triton:~/tip> apt-file find /usr/include/signal.h
  libc6-dev: /usr/include/signal.h

  triton:~/tip> dpkg -l libc6-dev
  Desired=Unknown/Install/Remove/Purge/Hold
  | Status=Not/Inst/Conf-files/Unpacked/halF-conf/Half-inst/trig-aWait/Trig-pend
  |/ Err?=(none)/Reinst-required (Status,Err: uppercase=bad)
  ||/ NameVersion  
Architecture Description
  
+++-===---
  ii  libc6-dev:amd64 2.26-0ubuntu2amd64
GNU C Library: Development Libraries and Header Files


> > plus, on a related note, the MPX testcase produces annoying warnings:
> > 
> >  gcc -m32 -o /home/mingo/tip/tools/testing/selftests/x86/mpx-mini-test_32 
> > -O2 -g -std=gnu99 -pthread -Wall -no-pie  mpx-mini-test.c -lrt -ldl -lm
> >  mpx-mini-test.c: In function ‘insn_test_failed’:
> >  mpx-mini-test.c:1406:3: warning: array subscript is above array bounds 
> >  [-Warray-bounds]
> > printf("bte[1]: %lx\n", bte->contents[1]);
> 
> This is kinda a weird structure:
> 
> > struct mpx_bt_entry {
> > union {
> > char x[MPX_BOUNDS_TABLE_ENTRY_SIZE_BYTES];
> > unsigned long contents[1];
> > };
> > } __attribute__((packed));
> 
> I guess it should either be contents[0] or
> contents[MPX_BOUNDS_TABLE_ENTRY_SIZE_BYTE/sizeof(long)].  But, the
> warning is harmless at least.
> 
> What gcc is this, btw?  I must be behind the times.

gcc version 7.2.0 (Ubuntu 7.2.0-8ubuntu3) 

Thanks,

Ingo


Re: [PATCH 1/2] sched/swait: allow swake_up() to return

2017-11-09 Thread Peter Xu
On Thu, Nov 09, 2017 at 11:06:53AM +0100, Paolo Bonzini wrote:
> On 09/11/2017 10:18, Peter Xu wrote:
> > Let swake_up() to return whether any of the waiters is waked up. One use
> > case of it would be:
> > 
> >   if (swait_active(wq)) {
> > swake_up(wq);
> > // do something when waiter is waked up
> > waked_up++;
> >   }
> > 
> > Logically it's possible that when reaching swake_up() the wait queue is
> > not active any more, and here doing something like waked_up++ would be
> > inaccurate.  To correct it, we need an atomic version of it.
> > 
> > With this patch, we can simply re-write it into:
> > 
> >   if (swake_up(wq)) {
> > // do something when waiter is waked up
> > waked_up++;
> >   }
> > 
> > After all we are checking swait_active() inside swake_up() too.
> 
> Better subject:
> 
> sched/swait: make swake_up() return whether there were any waiters
> 
> I like this patch.

I'll see how PeterZ would like me to do next, or I can drop this patch
and send another clean up which is part of patch 2.  Thanks for the
positive feedback and commenting. :-)

-- 
Peter Xu


Re: [PATCH 1/2] sched/swait: allow swake_up() to return

2017-11-09 Thread Peter Xu
On Thu, Nov 09, 2017 at 11:06:53AM +0100, Paolo Bonzini wrote:
> On 09/11/2017 10:18, Peter Xu wrote:
> > Let swake_up() to return whether any of the waiters is waked up. One use
> > case of it would be:
> > 
> >   if (swait_active(wq)) {
> > swake_up(wq);
> > // do something when waiter is waked up
> > waked_up++;
> >   }
> > 
> > Logically it's possible that when reaching swake_up() the wait queue is
> > not active any more, and here doing something like waked_up++ would be
> > inaccurate.  To correct it, we need an atomic version of it.
> > 
> > With this patch, we can simply re-write it into:
> > 
> >   if (swake_up(wq)) {
> > // do something when waiter is waked up
> > waked_up++;
> >   }
> > 
> > After all we are checking swait_active() inside swake_up() too.
> 
> Better subject:
> 
> sched/swait: make swake_up() return whether there were any waiters
> 
> I like this patch.

I'll see how PeterZ would like me to do next, or I can drop this patch
and send another clean up which is part of patch 2.  Thanks for the
positive feedback and commenting. :-)

-- 
Peter Xu


Re: [PATCH v2 0/4] KVM: Paravirt remote TLB flush

2017-11-09 Thread Wanpeng Li
2017-11-10 15:04 GMT+08:00 Wanpeng Li :
> Remote flushing api's does a busy wait which is fine in bare-metal
> scenario. But with-in the guest, the vcpus might have been pre-empted
> or blocked. In this scenario, the initator vcpu would end up
> busy-waiting for a long amount of time.
>
> This patch set implements para-virt flush tlbs making sure that it
> does not wait for vcpus that are sleeping. And all the sleeping vcpus
> flush the tlb on guest enter. Idea was discussed here:
> https://lkml.org/lkml/2012/2/20/157
>
> The best result is achieved when we're overcommiting the host by running
> multiple vCPUs on each pCPU. In this case PV tlb flush avoids touching
> vCPUs which are not scheduled and avoid the wait on the main CPU.
>
> In addition, thanks for commit 9e52fc2b50d ("x86/mm: Enable RCU based
> page table freeing (CONFIG_HAVE_RCU_TABLE_FREE=y)")
>
> Test on a Haswell i7 desktop 4 cores (2HT), so 8 pCPUs, running ebizzy in
> one linux guest.
>
> ebizzy -M
>   vanillaoptimized boost
>  8 vCPUs   10152   10083   -0.68%
> 16 vCPUs12244866   297.5%
> 24 vCPUs11093871   249%
> 32 vCPUs10253375   229.3%

v1 -> v2:
 * a new CPUID feature bit
 * fix cmpxchg check
 * use kvm_vcpu_flush_tlb() to get the statistics right
 * just OR the KVM_VCPU_PREEMPTED in kvm_steal_time_set_preempted
 * add a new bool argument to kvm_x86_ops->tlb_flush
 * __cpumask_clear_cpu() instead of cpumask_clear_cpu()
 * not put cpumask_t on stack
 * rebase the patchset against "locking/qspinlock/x86: Avoid
test-and-set when PV_DEDICATED is set" v3

>
> Wanpeng Li (4):
>   KVM: Add vCPU running/preempted state
>   KVM: Add paravirt remote TLB flush
>   KVM: X86: introduce invalidate_gpa argument to tlb flush
>   KVM: Add flush_on_enter before guest enter
>
>  Documentation/virtual/kvm/cpuid.txt  | 10 ++
>  arch/x86/include/asm/kvm_host.h  |  2 +-
>  arch/x86/include/uapi/asm/kvm_para.h |  6 ++
>  arch/x86/kernel/kvm.c| 35 ++-
>  arch/x86/kvm/cpuid.c |  3 ++-
>  arch/x86/kvm/svm.c   | 14 +++---
>  arch/x86/kvm/vmx.c   | 21 +++--
>  arch/x86/kvm/x86.c   | 24 +++-
>  8 files changed, 86 insertions(+), 29 deletions(-)
>
> --
> 2.7.4
>


Re: [PATCH v2 0/4] KVM: Paravirt remote TLB flush

2017-11-09 Thread Wanpeng Li
2017-11-10 15:04 GMT+08:00 Wanpeng Li :
> Remote flushing api's does a busy wait which is fine in bare-metal
> scenario. But with-in the guest, the vcpus might have been pre-empted
> or blocked. In this scenario, the initator vcpu would end up
> busy-waiting for a long amount of time.
>
> This patch set implements para-virt flush tlbs making sure that it
> does not wait for vcpus that are sleeping. And all the sleeping vcpus
> flush the tlb on guest enter. Idea was discussed here:
> https://lkml.org/lkml/2012/2/20/157
>
> The best result is achieved when we're overcommiting the host by running
> multiple vCPUs on each pCPU. In this case PV tlb flush avoids touching
> vCPUs which are not scheduled and avoid the wait on the main CPU.
>
> In addition, thanks for commit 9e52fc2b50d ("x86/mm: Enable RCU based
> page table freeing (CONFIG_HAVE_RCU_TABLE_FREE=y)")
>
> Test on a Haswell i7 desktop 4 cores (2HT), so 8 pCPUs, running ebizzy in
> one linux guest.
>
> ebizzy -M
>   vanillaoptimized boost
>  8 vCPUs   10152   10083   -0.68%
> 16 vCPUs12244866   297.5%
> 24 vCPUs11093871   249%
> 32 vCPUs10253375   229.3%

v1 -> v2:
 * a new CPUID feature bit
 * fix cmpxchg check
 * use kvm_vcpu_flush_tlb() to get the statistics right
 * just OR the KVM_VCPU_PREEMPTED in kvm_steal_time_set_preempted
 * add a new bool argument to kvm_x86_ops->tlb_flush
 * __cpumask_clear_cpu() instead of cpumask_clear_cpu()
 * not put cpumask_t on stack
 * rebase the patchset against "locking/qspinlock/x86: Avoid
test-and-set when PV_DEDICATED is set" v3

>
> Wanpeng Li (4):
>   KVM: Add vCPU running/preempted state
>   KVM: Add paravirt remote TLB flush
>   KVM: X86: introduce invalidate_gpa argument to tlb flush
>   KVM: Add flush_on_enter before guest enter
>
>  Documentation/virtual/kvm/cpuid.txt  | 10 ++
>  arch/x86/include/asm/kvm_host.h  |  2 +-
>  arch/x86/include/uapi/asm/kvm_para.h |  6 ++
>  arch/x86/kernel/kvm.c| 35 ++-
>  arch/x86/kvm/cpuid.c |  3 ++-
>  arch/x86/kvm/svm.c   | 14 +++---
>  arch/x86/kvm/vmx.c   | 21 +++--
>  arch/x86/kvm/x86.c   | 24 +++-
>  8 files changed, 86 insertions(+), 29 deletions(-)
>
> --
> 2.7.4
>


Re: [PATCH 1/2] sched/swait: allow swake_up() to return

2017-11-09 Thread Peter Xu
On Thu, Nov 09, 2017 at 11:23:03AM +0100, Peter Zijlstra wrote:
> On Thu, Nov 09, 2017 at 05:18:53PM +0800, Peter Xu wrote:
> > Let swake_up() to return whether any of the waiters is waked up. One use
> > case of it would be:
> > 
> >   if (swait_active(wq)) {
> > swake_up(wq);
> > // do something when waiter is waked up
> > waked_up++;
> >   }
> 
> The word is 'woken', and no that doesn't work. All it says is that there
> was a waiter, not that you were to one to wake it. Another concurrent
> wakeup might have done so.

Yes.  Or IIUC the waiter can be calling finish_swait() somehow so it
removed itself from the list before being woken.

> 
> > 
> > Logically it's possible that when reaching swake_up() the wait queue is
> > not active any more, and here doing something like waked_up++ would be
> > inaccurate.  To correct it, we need an atomic version of it.
> > 
> > With this patch, we can simply re-write it into:
> > 
> >   if (swake_up(wq)) {
> > // do something when waiter is waked up
> > waked_up++;
> >   }
> > 
> > After all we are checking swait_active() inside swake_up() too.
> 
> We're not in fact; you've been staring at old code; see commit:
> 
>   35a2897c2a30 ("sched/wait: Remove the lockless swait_active() check in 
> swake_up*()")

I thought the tree was new enough, but obviously I was wrong...
Thanks for the pointer.

> 
> 
> Also, you're changing the interface relative to the regular wait
> interface. The two should be similar wherever possible.

Indeed.

I came to this when reading kvm_vcpu_wake_up(), so that only affects
some statistic which may not be that critical.  However I don't know
whether there would be any other real use case that we would like to
know exactly whether a call to [s]wake_up() has really done something
or just returned with a NOP.

Anyway, please let me know if you think the same change to wake_up()
would be meaningful, otherwise I can drop this patch and post another
KVM-only one to clean up the redundant callers of swait_active(),
since even if we dropped that list check in 35a2897c2a30, we'll do
that again in swake_up_locked().

And after knowing 35a2897c2a30, I do think that calling swait_active()
before swake_up() is not good since that call is without a lock as
well, just like what can happen before 35a2897c2a30.

(I am not 100% sure whether I fully understand the problem mentioned
 in 35a2897c2a30, but I think it's the memory barrier in the
 lock/unlock that matters.)

Thanks,

-- 
Peter Xu


Re: [PATCH 1/2] sched/swait: allow swake_up() to return

2017-11-09 Thread Peter Xu
On Thu, Nov 09, 2017 at 11:23:03AM +0100, Peter Zijlstra wrote:
> On Thu, Nov 09, 2017 at 05:18:53PM +0800, Peter Xu wrote:
> > Let swake_up() to return whether any of the waiters is waked up. One use
> > case of it would be:
> > 
> >   if (swait_active(wq)) {
> > swake_up(wq);
> > // do something when waiter is waked up
> > waked_up++;
> >   }
> 
> The word is 'woken', and no that doesn't work. All it says is that there
> was a waiter, not that you were to one to wake it. Another concurrent
> wakeup might have done so.

Yes.  Or IIUC the waiter can be calling finish_swait() somehow so it
removed itself from the list before being woken.

> 
> > 
> > Logically it's possible that when reaching swake_up() the wait queue is
> > not active any more, and here doing something like waked_up++ would be
> > inaccurate.  To correct it, we need an atomic version of it.
> > 
> > With this patch, we can simply re-write it into:
> > 
> >   if (swake_up(wq)) {
> > // do something when waiter is waked up
> > waked_up++;
> >   }
> > 
> > After all we are checking swait_active() inside swake_up() too.
> 
> We're not in fact; you've been staring at old code; see commit:
> 
>   35a2897c2a30 ("sched/wait: Remove the lockless swait_active() check in 
> swake_up*()")

I thought the tree was new enough, but obviously I was wrong...
Thanks for the pointer.

> 
> 
> Also, you're changing the interface relative to the regular wait
> interface. The two should be similar wherever possible.

Indeed.

I came to this when reading kvm_vcpu_wake_up(), so that only affects
some statistic which may not be that critical.  However I don't know
whether there would be any other real use case that we would like to
know exactly whether a call to [s]wake_up() has really done something
or just returned with a NOP.

Anyway, please let me know if you think the same change to wake_up()
would be meaningful, otherwise I can drop this patch and post another
KVM-only one to clean up the redundant callers of swait_active(),
since even if we dropped that list check in 35a2897c2a30, we'll do
that again in swake_up_locked().

And after knowing 35a2897c2a30, I do think that calling swait_active()
before swake_up() is not good since that call is without a lock as
well, just like what can happen before 35a2897c2a30.

(I am not 100% sure whether I fully understand the problem mentioned
 in 35a2897c2a30, but I think it's the memory barrier in the
 lock/unlock that matters.)

Thanks,

-- 
Peter Xu


[PATCH v2 3/4] KVM: X86: introduce invalidate_gpa argument to tlb flush

2017-11-09 Thread Wanpeng Li
From: Wanpeng Li 

Introduce a new bool invalidate_gpa argument to kvm_x86_ops->tlb_flush, 
it will be used by later patches to just flush guest tlb.

Cc: Paolo Bonzini 
Cc: Radim Krčmář 
Signed-off-by: Wanpeng Li 
---
 arch/x86/include/asm/kvm_host.h |  2 +-
 arch/x86/kvm/svm.c  | 14 +++---
 arch/x86/kvm/vmx.c  | 21 +++--
 arch/x86/kvm/x86.c  |  6 +++---
 4 files changed, 22 insertions(+), 21 deletions(-)

diff --git a/arch/x86/include/asm/kvm_host.h b/arch/x86/include/asm/kvm_host.h
index c73e493..b4f7bb1 100644
--- a/arch/x86/include/asm/kvm_host.h
+++ b/arch/x86/include/asm/kvm_host.h
@@ -952,7 +952,7 @@ struct kvm_x86_ops {
unsigned long (*get_rflags)(struct kvm_vcpu *vcpu);
void (*set_rflags)(struct kvm_vcpu *vcpu, unsigned long rflags);
 
-   void (*tlb_flush)(struct kvm_vcpu *vcpu);
+   void (*tlb_flush)(struct kvm_vcpu *vcpu, bool invalidate_gpa);
 
void (*run)(struct kvm_vcpu *vcpu);
int (*handle_exit)(struct kvm_vcpu *vcpu);
diff --git a/arch/x86/kvm/svm.c b/arch/x86/kvm/svm.c
index 0e68f0b..efaf95f 100644
--- a/arch/x86/kvm/svm.c
+++ b/arch/x86/kvm/svm.c
@@ -285,7 +285,7 @@ static int vgif = true;
 module_param(vgif, int, 0444);
 
 static void svm_set_cr0(struct kvm_vcpu *vcpu, unsigned long cr0);
-static void svm_flush_tlb(struct kvm_vcpu *vcpu);
+static void svm_flush_tlb(struct kvm_vcpu *vcpu, bool invalidate_gpa);
 static void svm_complete_interrupts(struct vcpu_svm *svm);
 
 static int nested_svm_exit_handled(struct vcpu_svm *svm);
@@ -2032,7 +2032,7 @@ static int svm_set_cr4(struct kvm_vcpu *vcpu, unsigned 
long cr4)
return 1;
 
if (npt_enabled && ((old_cr4 ^ cr4) & X86_CR4_PGE))
-   svm_flush_tlb(vcpu);
+   svm_flush_tlb(vcpu, true);
 
vcpu->arch.cr4 = cr4;
if (!npt_enabled)
@@ -2368,7 +2368,7 @@ static void nested_svm_set_tdp_cr3(struct kvm_vcpu *vcpu,
 
svm->vmcb->control.nested_cr3 = __sme_set(root);
mark_dirty(svm->vmcb, VMCB_NPT);
-   svm_flush_tlb(vcpu);
+   svm_flush_tlb(vcpu, true);
 }
 
 static void nested_svm_inject_npf_exit(struct kvm_vcpu *vcpu,
@@ -3033,7 +3033,7 @@ static bool nested_svm_vmrun(struct vcpu_svm *svm)
svm->nested.intercept_exceptions = 
nested_vmcb->control.intercept_exceptions;
svm->nested.intercept= nested_vmcb->control.intercept;
 
-   svm_flush_tlb(>vcpu);
+   svm_flush_tlb(>vcpu, true);
svm->vmcb->control.int_ctl = nested_vmcb->control.int_ctl | 
V_INTR_MASKING_MASK;
if (nested_vmcb->control.int_ctl & V_INTR_MASKING_MASK)
svm->vcpu.arch.hflags |= HF_VINTR_MASK;
@@ -4755,7 +4755,7 @@ static int svm_set_tss_addr(struct kvm *kvm, unsigned int 
addr)
return 0;
 }
 
-static void svm_flush_tlb(struct kvm_vcpu *vcpu)
+static void svm_flush_tlb(struct kvm_vcpu *vcpu, bool invalidate_gpa)
 {
struct vcpu_svm *svm = to_svm(vcpu);
 
@@ -5046,7 +5046,7 @@ static void svm_set_cr3(struct kvm_vcpu *vcpu, unsigned 
long root)
 
svm->vmcb->save.cr3 = __sme_set(root);
mark_dirty(svm->vmcb, VMCB_CR);
-   svm_flush_tlb(vcpu);
+   svm_flush_tlb(vcpu, true);
 }
 
 static void set_tdp_cr3(struct kvm_vcpu *vcpu, unsigned long root)
@@ -5060,7 +5060,7 @@ static void set_tdp_cr3(struct kvm_vcpu *vcpu, unsigned 
long root)
svm->vmcb->save.cr3 = kvm_read_cr3(vcpu);
mark_dirty(svm->vmcb, VMCB_CR);
 
-   svm_flush_tlb(vcpu);
+   svm_flush_tlb(vcpu, true);
 }
 
 static int is_disabled(void)
diff --git a/arch/x86/kvm/vmx.c b/arch/x86/kvm/vmx.c
index e5bea5e..17d13d2 100644
--- a/arch/x86/kvm/vmx.c
+++ b/arch/x86/kvm/vmx.c
@@ -4113,9 +4113,10 @@ static void exit_lmode(struct kvm_vcpu *vcpu)
 
 #endif
 
-static inline void __vmx_flush_tlb(struct kvm_vcpu *vcpu, int vpid)
+static inline void __vmx_flush_tlb(struct kvm_vcpu *vcpu, int vpid,
+   bool invalidate_gpa)
 {
-   if (enable_ept) {
+   if (enable_ept && (invalidate_gpa || !enable_vpid)) {
if (!VALID_PAGE(vcpu->arch.mmu.root_hpa))
return;
ept_sync_context(construct_eptp(vcpu, vcpu->arch.mmu.root_hpa));
@@ -4124,15 +4125,15 @@ static inline void __vmx_flush_tlb(struct kvm_vcpu 
*vcpu, int vpid)
}
 }
 
-static void vmx_flush_tlb(struct kvm_vcpu *vcpu)
+static void vmx_flush_tlb(struct kvm_vcpu *vcpu, bool invalidate_gpa)
 {
-   __vmx_flush_tlb(vcpu, to_vmx(vcpu)->vpid);
+   __vmx_flush_tlb(vcpu, to_vmx(vcpu)->vpid, invalidate_gpa);
 }
 
 static void vmx_flush_tlb_ept_only(struct kvm_vcpu *vcpu)
 {
if (enable_ept)
-   vmx_flush_tlb(vcpu);
+   vmx_flush_tlb(vcpu, true);
 }
 
 static void vmx_decache_cr0_guest_bits(struct kvm_vcpu *vcpu)
@@ -4330,7 +4331,7 @@ static void vmx_set_cr3(struct kvm_vcpu 

[PATCH v2 1/4] KVM: Add vCPU running/preempted state

2017-11-09 Thread Wanpeng Li
From: Wanpeng Li 

This patch reuses the preempted field in kvm_steal_time, and will export
the vcpu running/pre-empted information to the guest from host. This will
enable guest to intelligently send ipi to running vcpus and set flag for
pre-empted vcpus. This will prevent waiting for vcpus that are not running.

Cc: Paolo Bonzini 
Cc: Radim Krčmář 
Signed-off-by: Wanpeng Li 
---
 arch/x86/include/uapi/asm/kvm_para.h | 3 +++
 arch/x86/kernel/kvm.c| 2 +-
 arch/x86/kvm/x86.c   | 4 ++--
 3 files changed, 6 insertions(+), 3 deletions(-)

diff --git a/arch/x86/include/uapi/asm/kvm_para.h 
b/arch/x86/include/uapi/asm/kvm_para.h
index a965e5b0..ff23ce9 100644
--- a/arch/x86/include/uapi/asm/kvm_para.h
+++ b/arch/x86/include/uapi/asm/kvm_para.h
@@ -50,6 +50,9 @@ struct kvm_steal_time {
__u32 pad[11];
 };
 
+#define KVM_VCPU_NOT_PREEMPTED  (0 << 0)
+#define KVM_VCPU_PREEMPTED  (1 << 0)
+
 #define KVM_CLOCK_PAIRING_WALLCLOCK 0
 struct kvm_clock_pairing {
__s64 sec;
diff --git a/arch/x86/kernel/kvm.c b/arch/x86/kernel/kvm.c
index 8bb9594..1b1b641 100644
--- a/arch/x86/kernel/kvm.c
+++ b/arch/x86/kernel/kvm.c
@@ -608,7 +608,7 @@ __visible bool __kvm_vcpu_is_preempted(long cpu)
 {
struct kvm_steal_time *src = _cpu(steal_time, cpu);
 
-   return !!src->preempted;
+   return !!(src->preempted & KVM_VCPU_PREEMPTED);
 }
 PV_CALLEE_SAVE_REGS_THUNK(__kvm_vcpu_is_preempted);
 
diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c
index d61dcce3..46d4158 100644
--- a/arch/x86/kvm/x86.c
+++ b/arch/x86/kvm/x86.c
@@ -2116,7 +2116,7 @@ static void record_steal_time(struct kvm_vcpu *vcpu)
>arch.st.steal, sizeof(struct kvm_steal_time
return;
 
-   vcpu->arch.st.steal.preempted = 0;
+   vcpu->arch.st.steal.preempted = KVM_VCPU_NOT_PREEMPTED;
 
if (vcpu->arch.st.steal.version & 1)
vcpu->arch.st.steal.version += 1;  /* first time write, random 
junk */
@@ -2887,7 +2887,7 @@ static void kvm_steal_time_set_preempted(struct kvm_vcpu 
*vcpu)
if (!(vcpu->arch.st.msr_val & KVM_MSR_ENABLED))
return;
 
-   vcpu->arch.st.steal.preempted = 1;
+   vcpu->arch.st.steal.preempted = KVM_VCPU_PREEMPTED;
 
kvm_write_guest_offset_cached(vcpu->kvm, >arch.st.stime,
>arch.st.steal.preempted,
-- 
2.7.4



[PATCH v2 2/4] KVM: Add paravirt remote TLB flush

2017-11-09 Thread Wanpeng Li
From: Wanpeng Li 

Remote flushing api's does a busy wait which is fine in bare-metal
scenario. But with-in the guest, the vcpus might have been pre-empted
or blocked. In this scenario, the initator vcpu would end up
busy-waiting for a long amount of time.

This patch set implements para-virt flush tlbs making sure that it
does not wait for vcpus that are sleeping. And all the sleeping vcpus
flush the tlb on guest enter.

The best result is achieved when we're overcommiting the host by running 
multiple vCPUs on each pCPU. In this case PV tlb flush avoids touching 
vCPUs which are not scheduled and avoid the wait on the main CPU.

Test on a Haswell i7 desktop 4 cores (2HT), so 8 pCPUs, running ebizzy in 
one linux guest.

ebizzy -M 
  vanillaoptimized boost
 8 vCPUs   10152   10083   -0.68% 
16 vCPUs12244866   297.5% 
24 vCPUs11093871   249%
32 vCPUs10253375   229.3% 

Cc: Paolo Bonzini 
Cc: Radim Krčmář 
Signed-off-by: Wanpeng Li 
---
 Documentation/virtual/kvm/cpuid.txt  |  4 
 arch/x86/include/uapi/asm/kvm_para.h |  2 ++
 arch/x86/kernel/kvm.c| 31 +++
 3 files changed, 37 insertions(+)

diff --git a/Documentation/virtual/kvm/cpuid.txt 
b/Documentation/virtual/kvm/cpuid.txt
index 117066a..9693fcc 100644
--- a/Documentation/virtual/kvm/cpuid.txt
+++ b/Documentation/virtual/kvm/cpuid.txt
@@ -60,6 +60,10 @@ KVM_FEATURE_PV_DEDICATED   || 8 || guest checks 
this feature bit
||   || mizations such as usage of
||   || qspinlocks.
 --
+KVM_FEATURE_PV_TLB_FLUSH   || 9 || guest checks this feature bit
+   ||   || before enabling paravirtualized
+   ||   || tlb flush.
+--
 KVM_FEATURE_CLOCKSOURCE_STABLE_BIT ||24 || host will warn if no guest-side
||   || per-cpu warps are expected in
||   || kvmclock.
diff --git a/arch/x86/include/uapi/asm/kvm_para.h 
b/arch/x86/include/uapi/asm/kvm_para.h
index 9ead1ed..a028479 100644
--- a/arch/x86/include/uapi/asm/kvm_para.h
+++ b/arch/x86/include/uapi/asm/kvm_para.h
@@ -25,6 +25,7 @@
 #define KVM_FEATURE_PV_EOI 6
 #define KVM_FEATURE_PV_UNHALT  7
 #define KVM_FEATURE_PV_DEDICATED   8
+#define KVM_FEATURE_PV_TLB_FLUSH   9
 
 /* The last 8 bits are used to indicate how to interpret the flags field
  * in pvclock structure. If no bits are set, all flags are ignored.
@@ -53,6 +54,7 @@ struct kvm_steal_time {
 
 #define KVM_VCPU_NOT_PREEMPTED  (0 << 0)
 #define KVM_VCPU_PREEMPTED  (1 << 0)
+#define KVM_VCPU_SHOULD_FLUSH   (1 << 1)
 
 #define KVM_CLOCK_PAIRING_WALLCLOCK 0
 struct kvm_clock_pairing {
diff --git a/arch/x86/kernel/kvm.c b/arch/x86/kernel/kvm.c
index 66ed3bc..50f4b6a 100644
--- a/arch/x86/kernel/kvm.c
+++ b/arch/x86/kernel/kvm.c
@@ -465,6 +465,33 @@ static void __init kvm_apf_trap_init(void)
update_intr_gate(X86_TRAP_PF, async_page_fault);
 }
 
+static cpumask_t flushmask;
+
+static void kvm_flush_tlb_others(const struct cpumask *cpumask,
+   const struct flush_tlb_info *info)
+{
+   u8 state;
+   int cpu;
+   struct kvm_steal_time *src;
+
+   cpumask_copy(, cpumask);
+   /*
+* We have to call flush only on online vCPUs. And
+* queue flush_on_enter for pre-empted vCPUs
+*/
+   for_each_cpu(cpu, cpumask) {
+   src = _cpu(steal_time, cpu);
+   state = src->preempted;
+   if ((state & KVM_VCPU_PREEMPTED)) {
+   if (cmpxchg(>preempted, state, state |
+   KVM_VCPU_SHOULD_FLUSH) == state)
+   __cpumask_clear_cpu(cpu, );
+   }
+   }
+
+   native_flush_tlb_others(, info);
+}
+
 void __init kvm_guest_init(void)
 {
int i;
@@ -484,6 +511,10 @@ void __init kvm_guest_init(void)
pv_time_ops.steal_clock = kvm_steal_clock;
}
 
+   if (kvm_para_has_feature(KVM_FEATURE_PV_TLB_FLUSH) &&
+   !kvm_para_has_feature(KVM_FEATURE_PV_DEDICATED))
+   pv_mmu_ops.flush_tlb_others = kvm_flush_tlb_others;
+
if (kvm_para_has_feature(KVM_FEATURE_PV_EOI))
apic_set_eoi_write(kvm_guest_apic_eoi_write);
 
-- 
2.7.4



[PATCH v2 1/4] KVM: Add vCPU running/preempted state

2017-11-09 Thread Wanpeng Li
From: Wanpeng Li 

This patch reuses the preempted field in kvm_steal_time, and will export
the vcpu running/pre-empted information to the guest from host. This will
enable guest to intelligently send ipi to running vcpus and set flag for
pre-empted vcpus. This will prevent waiting for vcpus that are not running.

Cc: Paolo Bonzini 
Cc: Radim Krčmář 
Signed-off-by: Wanpeng Li 
---
 arch/x86/include/uapi/asm/kvm_para.h | 3 +++
 arch/x86/kernel/kvm.c| 2 +-
 arch/x86/kvm/x86.c   | 4 ++--
 3 files changed, 6 insertions(+), 3 deletions(-)

diff --git a/arch/x86/include/uapi/asm/kvm_para.h 
b/arch/x86/include/uapi/asm/kvm_para.h
index a965e5b0..ff23ce9 100644
--- a/arch/x86/include/uapi/asm/kvm_para.h
+++ b/arch/x86/include/uapi/asm/kvm_para.h
@@ -50,6 +50,9 @@ struct kvm_steal_time {
__u32 pad[11];
 };
 
+#define KVM_VCPU_NOT_PREEMPTED  (0 << 0)
+#define KVM_VCPU_PREEMPTED  (1 << 0)
+
 #define KVM_CLOCK_PAIRING_WALLCLOCK 0
 struct kvm_clock_pairing {
__s64 sec;
diff --git a/arch/x86/kernel/kvm.c b/arch/x86/kernel/kvm.c
index 8bb9594..1b1b641 100644
--- a/arch/x86/kernel/kvm.c
+++ b/arch/x86/kernel/kvm.c
@@ -608,7 +608,7 @@ __visible bool __kvm_vcpu_is_preempted(long cpu)
 {
struct kvm_steal_time *src = _cpu(steal_time, cpu);
 
-   return !!src->preempted;
+   return !!(src->preempted & KVM_VCPU_PREEMPTED);
 }
 PV_CALLEE_SAVE_REGS_THUNK(__kvm_vcpu_is_preempted);
 
diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c
index d61dcce3..46d4158 100644
--- a/arch/x86/kvm/x86.c
+++ b/arch/x86/kvm/x86.c
@@ -2116,7 +2116,7 @@ static void record_steal_time(struct kvm_vcpu *vcpu)
>arch.st.steal, sizeof(struct kvm_steal_time
return;
 
-   vcpu->arch.st.steal.preempted = 0;
+   vcpu->arch.st.steal.preempted = KVM_VCPU_NOT_PREEMPTED;
 
if (vcpu->arch.st.steal.version & 1)
vcpu->arch.st.steal.version += 1;  /* first time write, random 
junk */
@@ -2887,7 +2887,7 @@ static void kvm_steal_time_set_preempted(struct kvm_vcpu 
*vcpu)
if (!(vcpu->arch.st.msr_val & KVM_MSR_ENABLED))
return;
 
-   vcpu->arch.st.steal.preempted = 1;
+   vcpu->arch.st.steal.preempted = KVM_VCPU_PREEMPTED;
 
kvm_write_guest_offset_cached(vcpu->kvm, >arch.st.stime,
>arch.st.steal.preempted,
-- 
2.7.4



[PATCH v2 2/4] KVM: Add paravirt remote TLB flush

2017-11-09 Thread Wanpeng Li
From: Wanpeng Li 

Remote flushing api's does a busy wait which is fine in bare-metal
scenario. But with-in the guest, the vcpus might have been pre-empted
or blocked. In this scenario, the initator vcpu would end up
busy-waiting for a long amount of time.

This patch set implements para-virt flush tlbs making sure that it
does not wait for vcpus that are sleeping. And all the sleeping vcpus
flush the tlb on guest enter.

The best result is achieved when we're overcommiting the host by running 
multiple vCPUs on each pCPU. In this case PV tlb flush avoids touching 
vCPUs which are not scheduled and avoid the wait on the main CPU.

Test on a Haswell i7 desktop 4 cores (2HT), so 8 pCPUs, running ebizzy in 
one linux guest.

ebizzy -M 
  vanillaoptimized boost
 8 vCPUs   10152   10083   -0.68% 
16 vCPUs12244866   297.5% 
24 vCPUs11093871   249%
32 vCPUs10253375   229.3% 

Cc: Paolo Bonzini 
Cc: Radim Krčmář 
Signed-off-by: Wanpeng Li 
---
 Documentation/virtual/kvm/cpuid.txt  |  4 
 arch/x86/include/uapi/asm/kvm_para.h |  2 ++
 arch/x86/kernel/kvm.c| 31 +++
 3 files changed, 37 insertions(+)

diff --git a/Documentation/virtual/kvm/cpuid.txt 
b/Documentation/virtual/kvm/cpuid.txt
index 117066a..9693fcc 100644
--- a/Documentation/virtual/kvm/cpuid.txt
+++ b/Documentation/virtual/kvm/cpuid.txt
@@ -60,6 +60,10 @@ KVM_FEATURE_PV_DEDICATED   || 8 || guest checks 
this feature bit
||   || mizations such as usage of
||   || qspinlocks.
 --
+KVM_FEATURE_PV_TLB_FLUSH   || 9 || guest checks this feature bit
+   ||   || before enabling paravirtualized
+   ||   || tlb flush.
+--
 KVM_FEATURE_CLOCKSOURCE_STABLE_BIT ||24 || host will warn if no guest-side
||   || per-cpu warps are expected in
||   || kvmclock.
diff --git a/arch/x86/include/uapi/asm/kvm_para.h 
b/arch/x86/include/uapi/asm/kvm_para.h
index 9ead1ed..a028479 100644
--- a/arch/x86/include/uapi/asm/kvm_para.h
+++ b/arch/x86/include/uapi/asm/kvm_para.h
@@ -25,6 +25,7 @@
 #define KVM_FEATURE_PV_EOI 6
 #define KVM_FEATURE_PV_UNHALT  7
 #define KVM_FEATURE_PV_DEDICATED   8
+#define KVM_FEATURE_PV_TLB_FLUSH   9
 
 /* The last 8 bits are used to indicate how to interpret the flags field
  * in pvclock structure. If no bits are set, all flags are ignored.
@@ -53,6 +54,7 @@ struct kvm_steal_time {
 
 #define KVM_VCPU_NOT_PREEMPTED  (0 << 0)
 #define KVM_VCPU_PREEMPTED  (1 << 0)
+#define KVM_VCPU_SHOULD_FLUSH   (1 << 1)
 
 #define KVM_CLOCK_PAIRING_WALLCLOCK 0
 struct kvm_clock_pairing {
diff --git a/arch/x86/kernel/kvm.c b/arch/x86/kernel/kvm.c
index 66ed3bc..50f4b6a 100644
--- a/arch/x86/kernel/kvm.c
+++ b/arch/x86/kernel/kvm.c
@@ -465,6 +465,33 @@ static void __init kvm_apf_trap_init(void)
update_intr_gate(X86_TRAP_PF, async_page_fault);
 }
 
+static cpumask_t flushmask;
+
+static void kvm_flush_tlb_others(const struct cpumask *cpumask,
+   const struct flush_tlb_info *info)
+{
+   u8 state;
+   int cpu;
+   struct kvm_steal_time *src;
+
+   cpumask_copy(, cpumask);
+   /*
+* We have to call flush only on online vCPUs. And
+* queue flush_on_enter for pre-empted vCPUs
+*/
+   for_each_cpu(cpu, cpumask) {
+   src = _cpu(steal_time, cpu);
+   state = src->preempted;
+   if ((state & KVM_VCPU_PREEMPTED)) {
+   if (cmpxchg(>preempted, state, state |
+   KVM_VCPU_SHOULD_FLUSH) == state)
+   __cpumask_clear_cpu(cpu, );
+   }
+   }
+
+   native_flush_tlb_others(, info);
+}
+
 void __init kvm_guest_init(void)
 {
int i;
@@ -484,6 +511,10 @@ void __init kvm_guest_init(void)
pv_time_ops.steal_clock = kvm_steal_clock;
}
 
+   if (kvm_para_has_feature(KVM_FEATURE_PV_TLB_FLUSH) &&
+   !kvm_para_has_feature(KVM_FEATURE_PV_DEDICATED))
+   pv_mmu_ops.flush_tlb_others = kvm_flush_tlb_others;
+
if (kvm_para_has_feature(KVM_FEATURE_PV_EOI))
apic_set_eoi_write(kvm_guest_apic_eoi_write);
 
-- 
2.7.4



[PATCH v2 3/4] KVM: X86: introduce invalidate_gpa argument to tlb flush

2017-11-09 Thread Wanpeng Li
From: Wanpeng Li 

Introduce a new bool invalidate_gpa argument to kvm_x86_ops->tlb_flush, 
it will be used by later patches to just flush guest tlb.

Cc: Paolo Bonzini 
Cc: Radim Krčmář 
Signed-off-by: Wanpeng Li 
---
 arch/x86/include/asm/kvm_host.h |  2 +-
 arch/x86/kvm/svm.c  | 14 +++---
 arch/x86/kvm/vmx.c  | 21 +++--
 arch/x86/kvm/x86.c  |  6 +++---
 4 files changed, 22 insertions(+), 21 deletions(-)

diff --git a/arch/x86/include/asm/kvm_host.h b/arch/x86/include/asm/kvm_host.h
index c73e493..b4f7bb1 100644
--- a/arch/x86/include/asm/kvm_host.h
+++ b/arch/x86/include/asm/kvm_host.h
@@ -952,7 +952,7 @@ struct kvm_x86_ops {
unsigned long (*get_rflags)(struct kvm_vcpu *vcpu);
void (*set_rflags)(struct kvm_vcpu *vcpu, unsigned long rflags);
 
-   void (*tlb_flush)(struct kvm_vcpu *vcpu);
+   void (*tlb_flush)(struct kvm_vcpu *vcpu, bool invalidate_gpa);
 
void (*run)(struct kvm_vcpu *vcpu);
int (*handle_exit)(struct kvm_vcpu *vcpu);
diff --git a/arch/x86/kvm/svm.c b/arch/x86/kvm/svm.c
index 0e68f0b..efaf95f 100644
--- a/arch/x86/kvm/svm.c
+++ b/arch/x86/kvm/svm.c
@@ -285,7 +285,7 @@ static int vgif = true;
 module_param(vgif, int, 0444);
 
 static void svm_set_cr0(struct kvm_vcpu *vcpu, unsigned long cr0);
-static void svm_flush_tlb(struct kvm_vcpu *vcpu);
+static void svm_flush_tlb(struct kvm_vcpu *vcpu, bool invalidate_gpa);
 static void svm_complete_interrupts(struct vcpu_svm *svm);
 
 static int nested_svm_exit_handled(struct vcpu_svm *svm);
@@ -2032,7 +2032,7 @@ static int svm_set_cr4(struct kvm_vcpu *vcpu, unsigned 
long cr4)
return 1;
 
if (npt_enabled && ((old_cr4 ^ cr4) & X86_CR4_PGE))
-   svm_flush_tlb(vcpu);
+   svm_flush_tlb(vcpu, true);
 
vcpu->arch.cr4 = cr4;
if (!npt_enabled)
@@ -2368,7 +2368,7 @@ static void nested_svm_set_tdp_cr3(struct kvm_vcpu *vcpu,
 
svm->vmcb->control.nested_cr3 = __sme_set(root);
mark_dirty(svm->vmcb, VMCB_NPT);
-   svm_flush_tlb(vcpu);
+   svm_flush_tlb(vcpu, true);
 }
 
 static void nested_svm_inject_npf_exit(struct kvm_vcpu *vcpu,
@@ -3033,7 +3033,7 @@ static bool nested_svm_vmrun(struct vcpu_svm *svm)
svm->nested.intercept_exceptions = 
nested_vmcb->control.intercept_exceptions;
svm->nested.intercept= nested_vmcb->control.intercept;
 
-   svm_flush_tlb(>vcpu);
+   svm_flush_tlb(>vcpu, true);
svm->vmcb->control.int_ctl = nested_vmcb->control.int_ctl | 
V_INTR_MASKING_MASK;
if (nested_vmcb->control.int_ctl & V_INTR_MASKING_MASK)
svm->vcpu.arch.hflags |= HF_VINTR_MASK;
@@ -4755,7 +4755,7 @@ static int svm_set_tss_addr(struct kvm *kvm, unsigned int 
addr)
return 0;
 }
 
-static void svm_flush_tlb(struct kvm_vcpu *vcpu)
+static void svm_flush_tlb(struct kvm_vcpu *vcpu, bool invalidate_gpa)
 {
struct vcpu_svm *svm = to_svm(vcpu);
 
@@ -5046,7 +5046,7 @@ static void svm_set_cr3(struct kvm_vcpu *vcpu, unsigned 
long root)
 
svm->vmcb->save.cr3 = __sme_set(root);
mark_dirty(svm->vmcb, VMCB_CR);
-   svm_flush_tlb(vcpu);
+   svm_flush_tlb(vcpu, true);
 }
 
 static void set_tdp_cr3(struct kvm_vcpu *vcpu, unsigned long root)
@@ -5060,7 +5060,7 @@ static void set_tdp_cr3(struct kvm_vcpu *vcpu, unsigned 
long root)
svm->vmcb->save.cr3 = kvm_read_cr3(vcpu);
mark_dirty(svm->vmcb, VMCB_CR);
 
-   svm_flush_tlb(vcpu);
+   svm_flush_tlb(vcpu, true);
 }
 
 static int is_disabled(void)
diff --git a/arch/x86/kvm/vmx.c b/arch/x86/kvm/vmx.c
index e5bea5e..17d13d2 100644
--- a/arch/x86/kvm/vmx.c
+++ b/arch/x86/kvm/vmx.c
@@ -4113,9 +4113,10 @@ static void exit_lmode(struct kvm_vcpu *vcpu)
 
 #endif
 
-static inline void __vmx_flush_tlb(struct kvm_vcpu *vcpu, int vpid)
+static inline void __vmx_flush_tlb(struct kvm_vcpu *vcpu, int vpid,
+   bool invalidate_gpa)
 {
-   if (enable_ept) {
+   if (enable_ept && (invalidate_gpa || !enable_vpid)) {
if (!VALID_PAGE(vcpu->arch.mmu.root_hpa))
return;
ept_sync_context(construct_eptp(vcpu, vcpu->arch.mmu.root_hpa));
@@ -4124,15 +4125,15 @@ static inline void __vmx_flush_tlb(struct kvm_vcpu 
*vcpu, int vpid)
}
 }
 
-static void vmx_flush_tlb(struct kvm_vcpu *vcpu)
+static void vmx_flush_tlb(struct kvm_vcpu *vcpu, bool invalidate_gpa)
 {
-   __vmx_flush_tlb(vcpu, to_vmx(vcpu)->vpid);
+   __vmx_flush_tlb(vcpu, to_vmx(vcpu)->vpid, invalidate_gpa);
 }
 
 static void vmx_flush_tlb_ept_only(struct kvm_vcpu *vcpu)
 {
if (enable_ept)
-   vmx_flush_tlb(vcpu);
+   vmx_flush_tlb(vcpu, true);
 }
 
 static void vmx_decache_cr0_guest_bits(struct kvm_vcpu *vcpu)
@@ -4330,7 +4331,7 @@ static void vmx_set_cr3(struct kvm_vcpu *vcpu, unsigned 
long cr3)
ept_load_pdptrs(vcpu);
}
 
-   

[PATCH v2 0/4] KVM: Paravirt remote TLB flush

2017-11-09 Thread Wanpeng Li
Remote flushing api's does a busy wait which is fine in bare-metal
scenario. But with-in the guest, the vcpus might have been pre-empted
or blocked. In this scenario, the initator vcpu would end up
busy-waiting for a long amount of time.

This patch set implements para-virt flush tlbs making sure that it
does not wait for vcpus that are sleeping. And all the sleeping vcpus
flush the tlb on guest enter. Idea was discussed here:
https://lkml.org/lkml/2012/2/20/157

The best result is achieved when we're overcommiting the host by running 
multiple vCPUs on each pCPU. In this case PV tlb flush avoids touching 
vCPUs which are not scheduled and avoid the wait on the main CPU.

In addition, thanks for commit 9e52fc2b50d ("x86/mm: Enable RCU based 
page table freeing (CONFIG_HAVE_RCU_TABLE_FREE=y)")

Test on a Haswell i7 desktop 4 cores (2HT), so 8 pCPUs, running ebizzy in 
one linux guest.

ebizzy -M 
  vanillaoptimized boost
 8 vCPUs   10152   10083   -0.68% 
16 vCPUs12244866   297.5% 
24 vCPUs11093871   249%
32 vCPUs10253375   229.3% 

Wanpeng Li (4):
  KVM: Add vCPU running/preempted state
  KVM: Add paravirt remote TLB flush
  KVM: X86: introduce invalidate_gpa argument to tlb flush
  KVM: Add flush_on_enter before guest enter

 Documentation/virtual/kvm/cpuid.txt  | 10 ++
 arch/x86/include/asm/kvm_host.h  |  2 +-
 arch/x86/include/uapi/asm/kvm_para.h |  6 ++
 arch/x86/kernel/kvm.c| 35 ++-
 arch/x86/kvm/cpuid.c |  3 ++-
 arch/x86/kvm/svm.c   | 14 +++---
 arch/x86/kvm/vmx.c   | 21 +++--
 arch/x86/kvm/x86.c   | 24 +++-
 8 files changed, 86 insertions(+), 29 deletions(-)

-- 
2.7.4



[PATCH v2 0/4] KVM: Paravirt remote TLB flush

2017-11-09 Thread Wanpeng Li
Remote flushing api's does a busy wait which is fine in bare-metal
scenario. But with-in the guest, the vcpus might have been pre-empted
or blocked. In this scenario, the initator vcpu would end up
busy-waiting for a long amount of time.

This patch set implements para-virt flush tlbs making sure that it
does not wait for vcpus that are sleeping. And all the sleeping vcpus
flush the tlb on guest enter. Idea was discussed here:
https://lkml.org/lkml/2012/2/20/157

The best result is achieved when we're overcommiting the host by running 
multiple vCPUs on each pCPU. In this case PV tlb flush avoids touching 
vCPUs which are not scheduled and avoid the wait on the main CPU.

In addition, thanks for commit 9e52fc2b50d ("x86/mm: Enable RCU based 
page table freeing (CONFIG_HAVE_RCU_TABLE_FREE=y)")

Test on a Haswell i7 desktop 4 cores (2HT), so 8 pCPUs, running ebizzy in 
one linux guest.

ebizzy -M 
  vanillaoptimized boost
 8 vCPUs   10152   10083   -0.68% 
16 vCPUs12244866   297.5% 
24 vCPUs11093871   249%
32 vCPUs10253375   229.3% 

Wanpeng Li (4):
  KVM: Add vCPU running/preempted state
  KVM: Add paravirt remote TLB flush
  KVM: X86: introduce invalidate_gpa argument to tlb flush
  KVM: Add flush_on_enter before guest enter

 Documentation/virtual/kvm/cpuid.txt  | 10 ++
 arch/x86/include/asm/kvm_host.h  |  2 +-
 arch/x86/include/uapi/asm/kvm_para.h |  6 ++
 arch/x86/kernel/kvm.c| 35 ++-
 arch/x86/kvm/cpuid.c |  3 ++-
 arch/x86/kvm/svm.c   | 14 +++---
 arch/x86/kvm/vmx.c   | 21 +++--
 arch/x86/kvm/x86.c   | 24 +++-
 8 files changed, 86 insertions(+), 29 deletions(-)

-- 
2.7.4



[PATCH v2 4/4] KVM: Add flush_on_enter before guest enter

2017-11-09 Thread Wanpeng Li
PV-Flush guest would indicate to flush on enter, flush the TLB before
entering and exiting the guest.

Cc: Paolo Bonzini 
Cc: Radim Krčmář 
Signed-off-by: Wanpeng Li 
---
 arch/x86/kvm/cpuid.c |  3 ++-
 arch/x86/kvm/x86.c   | 22 ++
 2 files changed, 16 insertions(+), 9 deletions(-)

diff --git a/arch/x86/kvm/cpuid.c b/arch/x86/kvm/cpuid.c
index 0099e10..2724a5c 100644
--- a/arch/x86/kvm/cpuid.c
+++ b/arch/x86/kvm/cpuid.c
@@ -594,7 +594,8 @@ static inline int __do_cpuid_ent(struct kvm_cpuid_entry2 
*entry, u32 function,
 (1 << KVM_FEATURE_ASYNC_PF) |
 (1 << KVM_FEATURE_PV_EOI) |
 (1 << KVM_FEATURE_CLOCKSOURCE_STABLE_BIT) |
-(1 << KVM_FEATURE_PV_UNHALT);
+(1 << KVM_FEATURE_PV_UNHALT) |
+(1 << KVM_FEATURE_PV_TLB_FLUSH);
 
if (sched_info_on())
entry->eax |= (1 << KVM_FEATURE_STEAL_TIME);
diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c
index 2b2cc99..7e80be4 100644
--- a/arch/x86/kvm/x86.c
+++ b/arch/x86/kvm/x86.c
@@ -2107,6 +2107,12 @@ static void kvmclock_reset(struct kvm_vcpu *vcpu)
vcpu->arch.pv_time_enabled = false;
 }
 
+static void kvm_vcpu_flush_tlb(struct kvm_vcpu *vcpu, bool invalidate_gpa)
+{
+   ++vcpu->stat.tlb_flush;
+   kvm_x86_ops->tlb_flush(vcpu, invalidate_gpa);
+}
+
 static void record_steal_time(struct kvm_vcpu *vcpu)
 {
if (!(vcpu->arch.st.msr_val & KVM_MSR_ENABLED))
@@ -2116,7 +2122,13 @@ static void record_steal_time(struct kvm_vcpu *vcpu)
>arch.st.steal, sizeof(struct kvm_steal_time
return;
 
-   vcpu->arch.st.steal.preempted = KVM_VCPU_NOT_PREEMPTED;
+   if (xchg(>arch.st.steal.preempted, KVM_VCPU_NOT_PREEMPTED) ==
+   (KVM_VCPU_SHOULD_FLUSH | KVM_VCPU_PREEMPTED))
+   /*
+* Do TLB_FLUSH before entering the guest, its passed
+* the stage of request checking
+*/
+   kvm_vcpu_flush_tlb(vcpu, false);
 
if (vcpu->arch.st.steal.version & 1)
vcpu->arch.st.steal.version += 1;  /* first time write, random 
junk */
@@ -2887,7 +2899,7 @@ static void kvm_steal_time_set_preempted(struct kvm_vcpu 
*vcpu)
if (!(vcpu->arch.st.msr_val & KVM_MSR_ENABLED))
return;
 
-   vcpu->arch.st.steal.preempted = KVM_VCPU_PREEMPTED;
+   vcpu->arch.st.steal.preempted |= KVM_VCPU_PREEMPTED;
 
kvm_write_guest_offset_cached(vcpu->kvm, >arch.st.stime,
>arch.st.steal.preempted,
@@ -6737,12 +6749,6 @@ static void vcpu_scan_ioapic(struct kvm_vcpu *vcpu)
kvm_x86_ops->load_eoi_exitmap(vcpu, eoi_exit_bitmap);
 }
 
-static void kvm_vcpu_flush_tlb(struct kvm_vcpu *vcpu, bool invalidate_gpa)
-{
-   ++vcpu->stat.tlb_flush;
-   kvm_x86_ops->tlb_flush(vcpu, invalidate_gpa);
-}
-
 void kvm_vcpu_reload_apic_access_page(struct kvm_vcpu *vcpu)
 {
struct page *page = NULL;
-- 
2.7.4



[PATCH v2 4/4] KVM: Add flush_on_enter before guest enter

2017-11-09 Thread Wanpeng Li
PV-Flush guest would indicate to flush on enter, flush the TLB before
entering and exiting the guest.

Cc: Paolo Bonzini 
Cc: Radim Krčmář 
Signed-off-by: Wanpeng Li 
---
 arch/x86/kvm/cpuid.c |  3 ++-
 arch/x86/kvm/x86.c   | 22 ++
 2 files changed, 16 insertions(+), 9 deletions(-)

diff --git a/arch/x86/kvm/cpuid.c b/arch/x86/kvm/cpuid.c
index 0099e10..2724a5c 100644
--- a/arch/x86/kvm/cpuid.c
+++ b/arch/x86/kvm/cpuid.c
@@ -594,7 +594,8 @@ static inline int __do_cpuid_ent(struct kvm_cpuid_entry2 
*entry, u32 function,
 (1 << KVM_FEATURE_ASYNC_PF) |
 (1 << KVM_FEATURE_PV_EOI) |
 (1 << KVM_FEATURE_CLOCKSOURCE_STABLE_BIT) |
-(1 << KVM_FEATURE_PV_UNHALT);
+(1 << KVM_FEATURE_PV_UNHALT) |
+(1 << KVM_FEATURE_PV_TLB_FLUSH);
 
if (sched_info_on())
entry->eax |= (1 << KVM_FEATURE_STEAL_TIME);
diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c
index 2b2cc99..7e80be4 100644
--- a/arch/x86/kvm/x86.c
+++ b/arch/x86/kvm/x86.c
@@ -2107,6 +2107,12 @@ static void kvmclock_reset(struct kvm_vcpu *vcpu)
vcpu->arch.pv_time_enabled = false;
 }
 
+static void kvm_vcpu_flush_tlb(struct kvm_vcpu *vcpu, bool invalidate_gpa)
+{
+   ++vcpu->stat.tlb_flush;
+   kvm_x86_ops->tlb_flush(vcpu, invalidate_gpa);
+}
+
 static void record_steal_time(struct kvm_vcpu *vcpu)
 {
if (!(vcpu->arch.st.msr_val & KVM_MSR_ENABLED))
@@ -2116,7 +2122,13 @@ static void record_steal_time(struct kvm_vcpu *vcpu)
>arch.st.steal, sizeof(struct kvm_steal_time
return;
 
-   vcpu->arch.st.steal.preempted = KVM_VCPU_NOT_PREEMPTED;
+   if (xchg(>arch.st.steal.preempted, KVM_VCPU_NOT_PREEMPTED) ==
+   (KVM_VCPU_SHOULD_FLUSH | KVM_VCPU_PREEMPTED))
+   /*
+* Do TLB_FLUSH before entering the guest, its passed
+* the stage of request checking
+*/
+   kvm_vcpu_flush_tlb(vcpu, false);
 
if (vcpu->arch.st.steal.version & 1)
vcpu->arch.st.steal.version += 1;  /* first time write, random 
junk */
@@ -2887,7 +2899,7 @@ static void kvm_steal_time_set_preempted(struct kvm_vcpu 
*vcpu)
if (!(vcpu->arch.st.msr_val & KVM_MSR_ENABLED))
return;
 
-   vcpu->arch.st.steal.preempted = KVM_VCPU_PREEMPTED;
+   vcpu->arch.st.steal.preempted |= KVM_VCPU_PREEMPTED;
 
kvm_write_guest_offset_cached(vcpu->kvm, >arch.st.stime,
>arch.st.steal.preempted,
@@ -6737,12 +6749,6 @@ static void vcpu_scan_ioapic(struct kvm_vcpu *vcpu)
kvm_x86_ops->load_eoi_exitmap(vcpu, eoi_exit_bitmap);
 }
 
-static void kvm_vcpu_flush_tlb(struct kvm_vcpu *vcpu, bool invalidate_gpa)
-{
-   ++vcpu->stat.tlb_flush;
-   kvm_x86_ops->tlb_flush(vcpu, invalidate_gpa);
-}
-
 void kvm_vcpu_reload_apic_access_page(struct kvm_vcpu *vcpu)
 {
struct page *page = NULL;
-- 
2.7.4



Re: [PATCH] pstore: use ktime_get_real_fast_ns() instead of __getnstimeofday()

2017-11-09 Thread Thomas Gleixner
On Thu, 9 Nov 2017, Kees Cook wrote:
> On Thu, Nov 9, 2017 at 4:46 PM, Thomas Gleixner  wrote:
> > On Fri, 10 Nov 2017, Arnd Bergmann wrote:
> >> On Fri, Nov 10, 2017 at 12:00 AM, Thomas Gleixner  
> >> wrote:
> >> > Hmm, no. None of the regular accessor functions can be called from NMI
> >> > context safely.
> >>
> >> Right, that's what I mean: it must not get called from NMI context, but it
> >> currently is, at least for this case:
> >>
> >> NMI handler:
> >>   something bad
> >> panic()
> >>   kmsg_dump()
> >> pstore_dump()
> >>pstore_record_init()
> >>  __getnstimeofday()
> >>
> >> I should probably add that to the changelog text ;-)
> >
> > Indeed.
> 
> Er, so, is this safe to call there? I've had to fix this a few times
> now, so if using ktime_get_real_fast_ns() can be used here (and
> doesn't return 0) then this is easily an improvement over the existing
> "maybe read 0" case pstore has now.

ktime_get_real_fast_ns() is NMI safe and returns

before timekeeping_suspend():   correct time

after timekeeping_suspend():timestamp which was frozen in
timekeeping_suspend()

after timekeeping_resume(): correct time

Thanks,

tglx



Re: [PATCH] pstore: use ktime_get_real_fast_ns() instead of __getnstimeofday()

2017-11-09 Thread Thomas Gleixner
On Thu, 9 Nov 2017, Kees Cook wrote:
> On Thu, Nov 9, 2017 at 4:46 PM, Thomas Gleixner  wrote:
> > On Fri, 10 Nov 2017, Arnd Bergmann wrote:
> >> On Fri, Nov 10, 2017 at 12:00 AM, Thomas Gleixner  
> >> wrote:
> >> > Hmm, no. None of the regular accessor functions can be called from NMI
> >> > context safely.
> >>
> >> Right, that's what I mean: it must not get called from NMI context, but it
> >> currently is, at least for this case:
> >>
> >> NMI handler:
> >>   something bad
> >> panic()
> >>   kmsg_dump()
> >> pstore_dump()
> >>pstore_record_init()
> >>  __getnstimeofday()
> >>
> >> I should probably add that to the changelog text ;-)
> >
> > Indeed.
> 
> Er, so, is this safe to call there? I've had to fix this a few times
> now, so if using ktime_get_real_fast_ns() can be used here (and
> doesn't return 0) then this is easily an improvement over the existing
> "maybe read 0" case pstore has now.

ktime_get_real_fast_ns() is NMI safe and returns

before timekeeping_suspend():   correct time

after timekeeping_suspend():timestamp which was frozen in
timekeeping_suspend()

after timekeeping_resume(): correct time

Thanks,

tglx



Re: [PATCH v17 5/6] vfio: ABI for mdev display dma-buf operation

2017-11-09 Thread Gerd Hoffmann
On Thu, Nov 09, 2017 at 01:54:57PM -0700, Alex Williamson wrote:
> On Thu, 9 Nov 2017 19:35:14 +0100
> Gerd Hoffmann  wrote:
> 
> >   Hi,
> > 
> > > struct vfio_device_gfx_plane_info lacks the head field we've been
> > > discussing.  Thanks,  
> > 
> > Adding multihead support turned out to not be that easy.  There are
> > corner cases like a single framebuffer spawning both heads.  Also it
> > would be useful to somehow hint to the guest which heads it should use.
> > 
> > In short:  Proper multihead support is more complex than just adding a
> > head field for later use.  So in a short private discussion with Tina we
> > came to the conclusion that it will be better add multihead support to
> > the API when the first driver wants use it, so we can actually test the
> > interface and make sure we didn't miss anything.  Adding a incomplete
> > multihead API now doesn't help anybody.
> 
> Do you think we can enable multi-head and preserve backwards
> compatibility within this API proposed here?

Yes, I think we can.  Adding new fields is possible thanks to the argsz
field at the start of the struct, so we easily add the new fields (head,
framebuffer rectangle, whatever else is needed).  If the new fields are
not present the driver can simply assume head=0.

Does the driver set argsz too?  If so userspace can detect whenever the
driver supports the multihead API extension (before going to probe for
head=1) that way.  If not we probably need an additional probe flag for
that.  But in any case I'm confident this is solvable.

Passing hints about the display configuration to the guest needs a new
ioctl, so we don't have compatibility issues there.

cheers,
  Gerd



Re: [PATCH v17 5/6] vfio: ABI for mdev display dma-buf operation

2017-11-09 Thread Gerd Hoffmann
On Thu, Nov 09, 2017 at 01:54:57PM -0700, Alex Williamson wrote:
> On Thu, 9 Nov 2017 19:35:14 +0100
> Gerd Hoffmann  wrote:
> 
> >   Hi,
> > 
> > > struct vfio_device_gfx_plane_info lacks the head field we've been
> > > discussing.  Thanks,  
> > 
> > Adding multihead support turned out to not be that easy.  There are
> > corner cases like a single framebuffer spawning both heads.  Also it
> > would be useful to somehow hint to the guest which heads it should use.
> > 
> > In short:  Proper multihead support is more complex than just adding a
> > head field for later use.  So in a short private discussion with Tina we
> > came to the conclusion that it will be better add multihead support to
> > the API when the first driver wants use it, so we can actually test the
> > interface and make sure we didn't miss anything.  Adding a incomplete
> > multihead API now doesn't help anybody.
> 
> Do you think we can enable multi-head and preserve backwards
> compatibility within this API proposed here?

Yes, I think we can.  Adding new fields is possible thanks to the argsz
field at the start of the struct, so we easily add the new fields (head,
framebuffer rectangle, whatever else is needed).  If the new fields are
not present the driver can simply assume head=0.

Does the driver set argsz too?  If so userspace can detect whenever the
driver supports the multihead API extension (before going to probe for
head=1) that way.  If not we probably need an additional probe flag for
that.  But in any case I'm confident this is solvable.

Passing hints about the display configuration to the guest needs a new
ioctl, so we don't have compatibility issues there.

cheers,
  Gerd



[PATCH V4 06/12] clk: sprd: add divider clock support

2017-11-09 Thread Chunyan Zhang
This is a feature that can also be found in sprd composite clocks,
provide a bunch of helpers that can be reused in that.

Signed-off-by: Chunyan Zhang 
---
 drivers/clk/sprd/Makefile |   1 +
 drivers/clk/sprd/div.c| 100 ++
 drivers/clk/sprd/div.h|  79 
 3 files changed, 180 insertions(+)
 create mode 100644 drivers/clk/sprd/div.c
 create mode 100644 drivers/clk/sprd/div.h

diff --git a/drivers/clk/sprd/Makefile b/drivers/clk/sprd/Makefile
index cee36b5..80e6039 100644
--- a/drivers/clk/sprd/Makefile
+++ b/drivers/clk/sprd/Makefile
@@ -3,3 +3,4 @@ obj-$(CONFIG_SPRD_COMMON_CLK)   += clk-sprd.o
 clk-sprd-y += common.o
 clk-sprd-y += gate.o
 clk-sprd-y += mux.o
+clk-sprd-y += div.o
diff --git a/drivers/clk/sprd/div.c b/drivers/clk/sprd/div.c
new file mode 100644
index 000..3e08dcd
--- /dev/null
+++ b/drivers/clk/sprd/div.c
@@ -0,0 +1,100 @@
+/*
+ * Spreadtrum divider clock driver
+ *
+ * Copyright (C) 2017 Spreadtrum, Inc.
+ * Author: Chunyan Zhang 
+ *
+ * SPDX-License-Identifier: GPL-2.0
+ */
+
+#include 
+
+#include "div.h"
+
+DEFINE_SPINLOCK(sprd_div_lock);
+EXPORT_SYMBOL_GPL(sprd_div_lock);
+
+long sprd_div_helper_round_rate(struct sprd_clk_common *common,
+   const struct sprd_div_internal *div,
+   unsigned long rate,
+   unsigned long *parent_rate)
+{
+   return divider_round_rate(>hw, rate, parent_rate,
+ NULL, div->width, 0);
+}
+EXPORT_SYMBOL_GPL(sprd_div_helper_round_rate);
+
+static long sprd_div_round_rate(struct clk_hw *hw, unsigned long rate,
+   unsigned long *parent_rate)
+{
+   struct sprd_div *cd = hw_to_sprd_div(hw);
+
+   return sprd_div_helper_round_rate(>common, >div,
+ rate, parent_rate);
+}
+
+unsigned long sprd_div_helper_recalc_rate(struct sprd_clk_common *common,
+ const struct sprd_div_internal *div,
+ unsigned long parent_rate)
+{
+   unsigned long val;
+   unsigned int reg;
+
+   sprd_regmap_read(common->regmap, common->reg, );
+   val = reg >> div->shift;
+   val &= (1 << div->width) - 1;
+
+   return divider_recalc_rate(>hw, parent_rate, val, NULL, 0);
+}
+EXPORT_SYMBOL_GPL(sprd_div_helper_recalc_rate);
+
+static unsigned long sprd_div_recalc_rate(struct clk_hw *hw,
+ unsigned long parent_rate)
+{
+   struct sprd_div *cd = hw_to_sprd_div(hw);
+
+   return sprd_div_helper_recalc_rate(>common, >div, parent_rate);
+}
+
+int sprd_div_helper_set_rate(const struct sprd_clk_common *common,
+const struct sprd_div_internal *div,
+unsigned long rate,
+unsigned long parent_rate)
+{
+   unsigned long flags;
+   unsigned long val;
+   unsigned int reg;
+
+   val = divider_get_val(rate, parent_rate, NULL,
+ div->width, 0);
+
+   spin_lock_irqsave(common->lock, flags);
+
+   sprd_regmap_read(common->regmap, common->reg, );
+   reg &= ~GENMASK(div->width + div->shift - 1, div->shift);
+
+   sprd_regmap_write(common->regmap, common->reg,
+ reg | (val << div->shift));
+
+   spin_unlock_irqrestore(common->lock, flags);
+
+   return 0;
+
+}
+EXPORT_SYMBOL_GPL(sprd_div_helper_set_rate);
+
+static int sprd_div_set_rate(struct clk_hw *hw, unsigned long rate,
+unsigned long parent_rate)
+{
+   struct sprd_div *cd = hw_to_sprd_div(hw);
+
+   return sprd_div_helper_set_rate(>common, >div,
+   rate, parent_rate);
+}
+
+const struct clk_ops sprd_div_ops = {
+   .recalc_rate = sprd_div_recalc_rate,
+   .round_rate = sprd_div_round_rate,
+   .set_rate = sprd_div_set_rate,
+};
+EXPORT_SYMBOL_GPL(sprd_div_ops);
diff --git a/drivers/clk/sprd/div.h b/drivers/clk/sprd/div.h
new file mode 100644
index 000..fa47773
--- /dev/null
+++ b/drivers/clk/sprd/div.h
@@ -0,0 +1,79 @@
+/*
+ * Spreadtrum divider clock driver
+ *
+ * Copyright (C) 2017 Spreadtrum, Inc.
+ * Author: Chunyan Zhang 
+ *
+ * SPDX-License-Identifier: GPL-2.0
+ */
+
+#ifndef _SPRD_DIV_H_
+#define _SPRD_DIV_H_
+
+#include "common.h"
+
+/**
+ * struct sprd_div_internal - Internal divider description
+ * @shift: Bit offset of the divider in its register
+ * @width: Width of the divider field in its register
+ *
+ * That structure represents a single divider, and is meant to be
+ * embedded in other structures representing the various clock
+ * classes.
+ */
+struct sprd_div_internal {
+   u8  shift;
+   u8  width;
+};
+
+#define 

[PATCH V4 06/12] clk: sprd: add divider clock support

2017-11-09 Thread Chunyan Zhang
This is a feature that can also be found in sprd composite clocks,
provide a bunch of helpers that can be reused in that.

Signed-off-by: Chunyan Zhang 
---
 drivers/clk/sprd/Makefile |   1 +
 drivers/clk/sprd/div.c| 100 ++
 drivers/clk/sprd/div.h|  79 
 3 files changed, 180 insertions(+)
 create mode 100644 drivers/clk/sprd/div.c
 create mode 100644 drivers/clk/sprd/div.h

diff --git a/drivers/clk/sprd/Makefile b/drivers/clk/sprd/Makefile
index cee36b5..80e6039 100644
--- a/drivers/clk/sprd/Makefile
+++ b/drivers/clk/sprd/Makefile
@@ -3,3 +3,4 @@ obj-$(CONFIG_SPRD_COMMON_CLK)   += clk-sprd.o
 clk-sprd-y += common.o
 clk-sprd-y += gate.o
 clk-sprd-y += mux.o
+clk-sprd-y += div.o
diff --git a/drivers/clk/sprd/div.c b/drivers/clk/sprd/div.c
new file mode 100644
index 000..3e08dcd
--- /dev/null
+++ b/drivers/clk/sprd/div.c
@@ -0,0 +1,100 @@
+/*
+ * Spreadtrum divider clock driver
+ *
+ * Copyright (C) 2017 Spreadtrum, Inc.
+ * Author: Chunyan Zhang 
+ *
+ * SPDX-License-Identifier: GPL-2.0
+ */
+
+#include 
+
+#include "div.h"
+
+DEFINE_SPINLOCK(sprd_div_lock);
+EXPORT_SYMBOL_GPL(sprd_div_lock);
+
+long sprd_div_helper_round_rate(struct sprd_clk_common *common,
+   const struct sprd_div_internal *div,
+   unsigned long rate,
+   unsigned long *parent_rate)
+{
+   return divider_round_rate(>hw, rate, parent_rate,
+ NULL, div->width, 0);
+}
+EXPORT_SYMBOL_GPL(sprd_div_helper_round_rate);
+
+static long sprd_div_round_rate(struct clk_hw *hw, unsigned long rate,
+   unsigned long *parent_rate)
+{
+   struct sprd_div *cd = hw_to_sprd_div(hw);
+
+   return sprd_div_helper_round_rate(>common, >div,
+ rate, parent_rate);
+}
+
+unsigned long sprd_div_helper_recalc_rate(struct sprd_clk_common *common,
+ const struct sprd_div_internal *div,
+ unsigned long parent_rate)
+{
+   unsigned long val;
+   unsigned int reg;
+
+   sprd_regmap_read(common->regmap, common->reg, );
+   val = reg >> div->shift;
+   val &= (1 << div->width) - 1;
+
+   return divider_recalc_rate(>hw, parent_rate, val, NULL, 0);
+}
+EXPORT_SYMBOL_GPL(sprd_div_helper_recalc_rate);
+
+static unsigned long sprd_div_recalc_rate(struct clk_hw *hw,
+ unsigned long parent_rate)
+{
+   struct sprd_div *cd = hw_to_sprd_div(hw);
+
+   return sprd_div_helper_recalc_rate(>common, >div, parent_rate);
+}
+
+int sprd_div_helper_set_rate(const struct sprd_clk_common *common,
+const struct sprd_div_internal *div,
+unsigned long rate,
+unsigned long parent_rate)
+{
+   unsigned long flags;
+   unsigned long val;
+   unsigned int reg;
+
+   val = divider_get_val(rate, parent_rate, NULL,
+ div->width, 0);
+
+   spin_lock_irqsave(common->lock, flags);
+
+   sprd_regmap_read(common->regmap, common->reg, );
+   reg &= ~GENMASK(div->width + div->shift - 1, div->shift);
+
+   sprd_regmap_write(common->regmap, common->reg,
+ reg | (val << div->shift));
+
+   spin_unlock_irqrestore(common->lock, flags);
+
+   return 0;
+
+}
+EXPORT_SYMBOL_GPL(sprd_div_helper_set_rate);
+
+static int sprd_div_set_rate(struct clk_hw *hw, unsigned long rate,
+unsigned long parent_rate)
+{
+   struct sprd_div *cd = hw_to_sprd_div(hw);
+
+   return sprd_div_helper_set_rate(>common, >div,
+   rate, parent_rate);
+}
+
+const struct clk_ops sprd_div_ops = {
+   .recalc_rate = sprd_div_recalc_rate,
+   .round_rate = sprd_div_round_rate,
+   .set_rate = sprd_div_set_rate,
+};
+EXPORT_SYMBOL_GPL(sprd_div_ops);
diff --git a/drivers/clk/sprd/div.h b/drivers/clk/sprd/div.h
new file mode 100644
index 000..fa47773
--- /dev/null
+++ b/drivers/clk/sprd/div.h
@@ -0,0 +1,79 @@
+/*
+ * Spreadtrum divider clock driver
+ *
+ * Copyright (C) 2017 Spreadtrum, Inc.
+ * Author: Chunyan Zhang 
+ *
+ * SPDX-License-Identifier: GPL-2.0
+ */
+
+#ifndef _SPRD_DIV_H_
+#define _SPRD_DIV_H_
+
+#include "common.h"
+
+/**
+ * struct sprd_div_internal - Internal divider description
+ * @shift: Bit offset of the divider in its register
+ * @width: Width of the divider field in its register
+ *
+ * That structure represents a single divider, and is meant to be
+ * embedded in other structures representing the various clock
+ * classes.
+ */
+struct sprd_div_internal {
+   u8  shift;
+   u8  width;
+};
+
+#define _SPRD_DIV_CLK(_shift, _width)  \
+   {   \
+   .shift  = 

[PATCH V4 12/12] arm64: dts: add clocks for SC9860

2017-11-09 Thread Chunyan Zhang
Some clocks on SC9860 are in the same address area with syscon devices,
those are what have a property of 'sprd,syscon' which would refer to
syscon devices, others would have a reg property indicated their address
ranges.

Signed-off-by: Chunyan Zhang 
---
 arch/arm64/boot/dts/sprd/sc9860.dtsi | 115 +++
 arch/arm64/boot/dts/sprd/whale2.dtsi |   2 +-
 2 files changed, 116 insertions(+), 1 deletion(-)

diff --git a/arch/arm64/boot/dts/sprd/sc9860.dtsi 
b/arch/arm64/boot/dts/sprd/sc9860.dtsi
index 7b7d8ce..bf03da4 100644
--- a/arch/arm64/boot/dts/sprd/sc9860.dtsi
+++ b/arch/arm64/boot/dts/sprd/sc9860.dtsi
@@ -7,6 +7,7 @@
  */
 
 #include 
+#include 
 #include "whale2.dtsi"
 
 / {
@@ -183,6 +184,120 @@
};
 
soc {
+   pmu_gate: pmu-gate {
+   compatible = "sprd,sc9860-pmu-gate";
+   sprd,syscon = <_regs>; /* 0x402b */
+   clocks = <_26m>;
+   #clock-cells = <1>;
+   };
+
+   pll: pll {
+   compatible = "sprd,sc9860-pll";
+   sprd,syscon = <_regs>; /* 0x4040 */
+   clocks = <_gate 0>;
+   #clock-cells = <1>;
+   };
+
+   ap_clk: clock-controller@2000 {
+   compatible = "sprd,sc9860-ap-clk";
+   reg = <0 0x2000 0 0x400>;
+   clocks = <_26m>, < 0>,
+<_gate 0>;
+   #clock-cells = <1>;
+   };
+
+   aon_prediv: aon-prediv {
+   compatible = "sprd,sc9860-aon-prediv";
+   reg = <0 0x402d 0 0x400>;
+   clocks = <_26m>, < 0>,
+<_gate 0>;
+   #clock-cells = <1>;
+   };
+
+   apahb_gate: apahb-gate {
+   compatible = "sprd,sc9860-apahb-gate";
+   sprd,syscon = <_ahb_regs>; /* 0x2021 */
+   clocks = <_prediv 0>;
+   #clock-cells = <1>;
+   };
+
+   aon_gate: aon-gate {
+   compatible = "sprd,sc9860-aon-gate";
+   sprd,syscon = <_regs>; /* 0x402e */
+   clocks = <_prediv 0>;
+   #clock-cells = <1>;
+   };
+
+   aonsecure_clk: clock-controller@4088 {
+   compatible = "sprd,sc9860-aonsecure-clk";
+   reg = <0 0x4088 0 0x400>;
+   clocks = <_26m>, < 0>;
+   #clock-cells = <1>;
+   };
+
+   agcp_gate: agcp-gate {
+   compatible = "sprd,sc9860-agcp-gate";
+   sprd,syscon = <_regs>; /* 0x415e */
+   clocks = <_prediv 0>;
+   #clock-cells = <1>;
+   };
+
+   gpu_clk: clock-controller@6020 {
+   compatible = "sprd,sc9860-gpu-clk";
+   reg = <0 0x6020 0 0x400>;
+   clocks = < 0>;
+   #clock-cells = <1>;
+   };
+
+   vsp_clk: clock-controller@6100 {
+   compatible = "sprd,sc9860-vsp-clk";
+   reg = <0 0x6100 0 0x400>;
+   clocks = <_26m>, < 0>;
+   #clock-cells = <1>;
+   };
+
+   vsp_gate: vsp-gate {
+   compatible = "sprd,sc9860-vsp-gate";
+   sprd,syscon = <_regs>; /* 0x6110 */
+   clocks = <_clk 0>;
+   #clock-cells = <1>;
+   };
+
+   cam_clk: clock-controller@6200 {
+   compatible = "sprd,sc9860-cam-clk";
+   reg = <0 0x6200 0 0x4000>;
+   clocks = <_26m>, < 0>;
+   #clock-cells = <1>;
+   };
+
+   cam_gate: cam-gate {
+   compatible = "sprd,sc9860-cam-gate";
+   sprd,syscon = <_regs>; /* 0x6210 */
+   clocks = <_clk 0>;
+   #clock-cells = <1>;
+   };
+
+   disp_clk: clock-controller@6300 {
+   compatible = "sprd,sc9860-disp-clk";
+   reg = <0 0x6300 0 0x400>;
+   clocks = <_26m>, < 0>;
+   #clock-cells = <1>;
+   };
+
+   disp_gate: disp-gate {
+   compatible = "sprd,sc9860-disp-gate";
+   sprd,syscon = <_regs>; /* 0x6310 */
+   clocks = <_clk 0>;
+   #clock-cells = <1>;
+   

[PATCH V4 12/12] arm64: dts: add clocks for SC9860

2017-11-09 Thread Chunyan Zhang
Some clocks on SC9860 are in the same address area with syscon devices,
those are what have a property of 'sprd,syscon' which would refer to
syscon devices, others would have a reg property indicated their address
ranges.

Signed-off-by: Chunyan Zhang 
---
 arch/arm64/boot/dts/sprd/sc9860.dtsi | 115 +++
 arch/arm64/boot/dts/sprd/whale2.dtsi |   2 +-
 2 files changed, 116 insertions(+), 1 deletion(-)

diff --git a/arch/arm64/boot/dts/sprd/sc9860.dtsi 
b/arch/arm64/boot/dts/sprd/sc9860.dtsi
index 7b7d8ce..bf03da4 100644
--- a/arch/arm64/boot/dts/sprd/sc9860.dtsi
+++ b/arch/arm64/boot/dts/sprd/sc9860.dtsi
@@ -7,6 +7,7 @@
  */
 
 #include 
+#include 
 #include "whale2.dtsi"
 
 / {
@@ -183,6 +184,120 @@
};
 
soc {
+   pmu_gate: pmu-gate {
+   compatible = "sprd,sc9860-pmu-gate";
+   sprd,syscon = <_regs>; /* 0x402b */
+   clocks = <_26m>;
+   #clock-cells = <1>;
+   };
+
+   pll: pll {
+   compatible = "sprd,sc9860-pll";
+   sprd,syscon = <_regs>; /* 0x4040 */
+   clocks = <_gate 0>;
+   #clock-cells = <1>;
+   };
+
+   ap_clk: clock-controller@2000 {
+   compatible = "sprd,sc9860-ap-clk";
+   reg = <0 0x2000 0 0x400>;
+   clocks = <_26m>, < 0>,
+<_gate 0>;
+   #clock-cells = <1>;
+   };
+
+   aon_prediv: aon-prediv {
+   compatible = "sprd,sc9860-aon-prediv";
+   reg = <0 0x402d 0 0x400>;
+   clocks = <_26m>, < 0>,
+<_gate 0>;
+   #clock-cells = <1>;
+   };
+
+   apahb_gate: apahb-gate {
+   compatible = "sprd,sc9860-apahb-gate";
+   sprd,syscon = <_ahb_regs>; /* 0x2021 */
+   clocks = <_prediv 0>;
+   #clock-cells = <1>;
+   };
+
+   aon_gate: aon-gate {
+   compatible = "sprd,sc9860-aon-gate";
+   sprd,syscon = <_regs>; /* 0x402e */
+   clocks = <_prediv 0>;
+   #clock-cells = <1>;
+   };
+
+   aonsecure_clk: clock-controller@4088 {
+   compatible = "sprd,sc9860-aonsecure-clk";
+   reg = <0 0x4088 0 0x400>;
+   clocks = <_26m>, < 0>;
+   #clock-cells = <1>;
+   };
+
+   agcp_gate: agcp-gate {
+   compatible = "sprd,sc9860-agcp-gate";
+   sprd,syscon = <_regs>; /* 0x415e */
+   clocks = <_prediv 0>;
+   #clock-cells = <1>;
+   };
+
+   gpu_clk: clock-controller@6020 {
+   compatible = "sprd,sc9860-gpu-clk";
+   reg = <0 0x6020 0 0x400>;
+   clocks = < 0>;
+   #clock-cells = <1>;
+   };
+
+   vsp_clk: clock-controller@6100 {
+   compatible = "sprd,sc9860-vsp-clk";
+   reg = <0 0x6100 0 0x400>;
+   clocks = <_26m>, < 0>;
+   #clock-cells = <1>;
+   };
+
+   vsp_gate: vsp-gate {
+   compatible = "sprd,sc9860-vsp-gate";
+   sprd,syscon = <_regs>; /* 0x6110 */
+   clocks = <_clk 0>;
+   #clock-cells = <1>;
+   };
+
+   cam_clk: clock-controller@6200 {
+   compatible = "sprd,sc9860-cam-clk";
+   reg = <0 0x6200 0 0x4000>;
+   clocks = <_26m>, < 0>;
+   #clock-cells = <1>;
+   };
+
+   cam_gate: cam-gate {
+   compatible = "sprd,sc9860-cam-gate";
+   sprd,syscon = <_regs>; /* 0x6210 */
+   clocks = <_clk 0>;
+   #clock-cells = <1>;
+   };
+
+   disp_clk: clock-controller@6300 {
+   compatible = "sprd,sc9860-disp-clk";
+   reg = <0 0x6300 0 0x400>;
+   clocks = <_26m>, < 0>;
+   #clock-cells = <1>;
+   };
+
+   disp_gate: disp-gate {
+   compatible = "sprd,sc9860-disp-gate";
+   sprd,syscon = <_regs>; /* 0x6310 */
+   clocks = <_clk 0>;
+   #clock-cells = <1>;
+   };
+
+   

[PATCH V4 10/12] clk: sprd: add clocks support for SC9860

2017-11-09 Thread Chunyan Zhang
This patch added the list of clocks for Spreadtrum's SC9860 SoC,
together with clock initialization code.

Signed-off-by: Chunyan Zhang 
---
 drivers/clk/sprd/Kconfig  |   10 +
 drivers/clk/sprd/Makefile |3 +
 drivers/clk/sprd/sc9860-clk.c | 1987 +
 3 files changed, 2000 insertions(+)
 create mode 100644 drivers/clk/sprd/sc9860-clk.c

diff --git a/drivers/clk/sprd/Kconfig b/drivers/clk/sprd/Kconfig
index 67a3287..8789247 100644
--- a/drivers/clk/sprd/Kconfig
+++ b/drivers/clk/sprd/Kconfig
@@ -2,3 +2,13 @@ config SPRD_COMMON_CLK
tristate "Clock support for Spreadtrum SoCs"
depends on ARCH_SPRD || COMPILE_TEST
default ARCH_SPRD
+
+if SPRD_COMMON_CLK
+
+# SoC Drivers
+
+config SPRD_SC9860_CLK
+   tristate "Support for the Spreadtrum SC9860 clocks"
+   depends on (ARM64 && ARCH_SPRD) || COMPILE_TEST
+   default ARM64 && ARCH_SPRD
+endif
diff --git a/drivers/clk/sprd/Makefile b/drivers/clk/sprd/Makefile
index d693969..b0d81e5 100644
--- a/drivers/clk/sprd/Makefile
+++ b/drivers/clk/sprd/Makefile
@@ -6,3 +6,6 @@ clk-sprd-y  += mux.o
 clk-sprd-y += div.o
 clk-sprd-y += composite.o
 clk-sprd-y += pll.o
+
+## SoC support
+obj-$(CONFIG_SPRD_SC9860_CLK)  += sc9860-clk.o
diff --git a/drivers/clk/sprd/sc9860-clk.c b/drivers/clk/sprd/sc9860-clk.c
new file mode 100644
index 000..caf7194
--- /dev/null
+++ b/drivers/clk/sprd/sc9860-clk.c
@@ -0,0 +1,1987 @@
+/*
+ * Spreatrum SC9860 clock driver
+ *
+ * Copyright (C) 2017 Spreadtrum, Inc.
+ * Author: Chunyan Zhang 
+ *
+ * SPDX-License-Identifier: GPL-2.0
+ */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#include 
+
+#include "common.h"
+#include "composite.h"
+#include "div.h"
+#include "gate.h"
+#include "mux.h"
+#include "pll.h"
+
+static CLK_FIXED_RATE(ext_rco_100m, "ext-rco-100m", 0, 1, 0);
+static CLK_FIXED_RATE(ext_32k, "ext-32k", 0, 32768, 0);
+
+static CLK_FIXED_FACTOR(fac_4m,"fac-4m",   "ext-26m",
+   6, 1, 0);
+static CLK_FIXED_FACTOR(fac_2m,"fac-2m",   "ext-26m",
+   13, 1, 0);
+static CLK_FIXED_FACTOR(fac_1m,"fac-1m",   "ext-26m",
+   26, 1, 0);
+static CLK_FIXED_FACTOR(fac_250k,  "fac-250k", "ext-26m",
+   104, 1, 0);
+static CLK_FIXED_FACTOR(fac_rpll0_26m, "rpll0-26m","ext-26m",
+   1, 1, 0);
+static CLK_FIXED_FACTOR(fac_rpll1_26m, "rpll1-26m","ext-26m",
+   1, 1, 0);
+static CLK_FIXED_FACTOR(fac_rco_25m,   "rco-25m",  "ext-rc0-100m",
+   4, 1, 0);
+static CLK_FIXED_FACTOR(fac_rco_4m,"rco-4m",   "ext-rc0-100m",
+   25, 1, 0);
+static CLK_FIXED_FACTOR(fac_rco_2m,"rco-2m",   "ext-rc0-100m",
+   50, 1, 0);
+static CLK_FIXED_FACTOR(fac_3k2,   "fac-3k2",  "ext-32k",
+   10, 1, 0);
+static CLK_FIXED_FACTOR(fac_1k,"fac-1k",   "ext-32k",
+   32, 1, 0);
+
+static SPRD_SC_GATE_CLK(mpll0_gate,"mpll0-gate",   "ext-26m", 0xb0,
+0x1000, BIT(2), CLK_IGNORE_UNUSED, 0);
+static SPRD_SC_GATE_CLK(mpll1_gate,"mpll1-gate",   "ext-26m", 0xb0,
+0x1000, BIT(18), CLK_IGNORE_UNUSED, 0);
+static SPRD_SC_GATE_CLK(dpll0_gate,"dpll0-gate",   "ext-26m", 0xb4,
+0x1000, BIT(2), CLK_IGNORE_UNUSED, 0);
+static SPRD_SC_GATE_CLK(dpll1_gate,"dpll1-gate",   "ext-26m", 0xb4,
+0x1000, BIT(18), CLK_IGNORE_UNUSED, 0);
+static SPRD_SC_GATE_CLK(ltepll0_gate,  "ltepll0-gate", "ext-26m", 0xb8,
+0x1000, BIT(2), CLK_IGNORE_UNUSED, 0);
+static SPRD_SC_GATE_CLK(twpll_gate,"twpll-gate",   "ext-26m", 0xbc,
+0x1000, BIT(2), CLK_IGNORE_UNUSED, 0);
+static SPRD_SC_GATE_CLK(ltepll1_gate,  "ltepll1-gate", "ext-26m", 0x10c,
+0x1000, BIT(2), CLK_IGNORE_UNUSED, 0);
+static SPRD_SC_GATE_CLK(rpll0_gate,"rpll0-gate",   "ext-26m", 0x16c,
+0x1000, BIT(2), 0, 0);
+static SPRD_SC_GATE_CLK(rpll1_gate,"rpll1-gate",   "ext-26m", 0x16c,
+0x1000, BIT(18), 0, 0);
+static SPRD_SC_GATE_CLK(cppll_gate,"cppll-gate",   "ext-26m", 0x2b4,
+0x1000, BIT(2), CLK_IGNORE_UNUSED, 0);
+static SPRD_SC_GATE_CLK(gpll_gate, "gpll-gate","ext-26m", 0x32c,
+   0x1000, BIT(0), CLK_IGNORE_UNUSED, CLK_GATE_SET_TO_DISABLE);
+
+static struct sprd_clk_common *sc9860_pmu_gate_clks[] = {
+   /* address base is 0x402b */
+   _gate.common,
+   _gate.common,
+   _gate.common,
+   _gate.common,
+   _gate.common,
+   _gate.common,
+   _gate.common,
+   _gate.common,
+   _gate.common,
+   _gate.common,
+   _gate.common,

[PATCH V4 10/12] clk: sprd: add clocks support for SC9860

2017-11-09 Thread Chunyan Zhang
This patch added the list of clocks for Spreadtrum's SC9860 SoC,
together with clock initialization code.

Signed-off-by: Chunyan Zhang 
---
 drivers/clk/sprd/Kconfig  |   10 +
 drivers/clk/sprd/Makefile |3 +
 drivers/clk/sprd/sc9860-clk.c | 1987 +
 3 files changed, 2000 insertions(+)
 create mode 100644 drivers/clk/sprd/sc9860-clk.c

diff --git a/drivers/clk/sprd/Kconfig b/drivers/clk/sprd/Kconfig
index 67a3287..8789247 100644
--- a/drivers/clk/sprd/Kconfig
+++ b/drivers/clk/sprd/Kconfig
@@ -2,3 +2,13 @@ config SPRD_COMMON_CLK
tristate "Clock support for Spreadtrum SoCs"
depends on ARCH_SPRD || COMPILE_TEST
default ARCH_SPRD
+
+if SPRD_COMMON_CLK
+
+# SoC Drivers
+
+config SPRD_SC9860_CLK
+   tristate "Support for the Spreadtrum SC9860 clocks"
+   depends on (ARM64 && ARCH_SPRD) || COMPILE_TEST
+   default ARM64 && ARCH_SPRD
+endif
diff --git a/drivers/clk/sprd/Makefile b/drivers/clk/sprd/Makefile
index d693969..b0d81e5 100644
--- a/drivers/clk/sprd/Makefile
+++ b/drivers/clk/sprd/Makefile
@@ -6,3 +6,6 @@ clk-sprd-y  += mux.o
 clk-sprd-y += div.o
 clk-sprd-y += composite.o
 clk-sprd-y += pll.o
+
+## SoC support
+obj-$(CONFIG_SPRD_SC9860_CLK)  += sc9860-clk.o
diff --git a/drivers/clk/sprd/sc9860-clk.c b/drivers/clk/sprd/sc9860-clk.c
new file mode 100644
index 000..caf7194
--- /dev/null
+++ b/drivers/clk/sprd/sc9860-clk.c
@@ -0,0 +1,1987 @@
+/*
+ * Spreatrum SC9860 clock driver
+ *
+ * Copyright (C) 2017 Spreadtrum, Inc.
+ * Author: Chunyan Zhang 
+ *
+ * SPDX-License-Identifier: GPL-2.0
+ */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#include 
+
+#include "common.h"
+#include "composite.h"
+#include "div.h"
+#include "gate.h"
+#include "mux.h"
+#include "pll.h"
+
+static CLK_FIXED_RATE(ext_rco_100m, "ext-rco-100m", 0, 1, 0);
+static CLK_FIXED_RATE(ext_32k, "ext-32k", 0, 32768, 0);
+
+static CLK_FIXED_FACTOR(fac_4m,"fac-4m",   "ext-26m",
+   6, 1, 0);
+static CLK_FIXED_FACTOR(fac_2m,"fac-2m",   "ext-26m",
+   13, 1, 0);
+static CLK_FIXED_FACTOR(fac_1m,"fac-1m",   "ext-26m",
+   26, 1, 0);
+static CLK_FIXED_FACTOR(fac_250k,  "fac-250k", "ext-26m",
+   104, 1, 0);
+static CLK_FIXED_FACTOR(fac_rpll0_26m, "rpll0-26m","ext-26m",
+   1, 1, 0);
+static CLK_FIXED_FACTOR(fac_rpll1_26m, "rpll1-26m","ext-26m",
+   1, 1, 0);
+static CLK_FIXED_FACTOR(fac_rco_25m,   "rco-25m",  "ext-rc0-100m",
+   4, 1, 0);
+static CLK_FIXED_FACTOR(fac_rco_4m,"rco-4m",   "ext-rc0-100m",
+   25, 1, 0);
+static CLK_FIXED_FACTOR(fac_rco_2m,"rco-2m",   "ext-rc0-100m",
+   50, 1, 0);
+static CLK_FIXED_FACTOR(fac_3k2,   "fac-3k2",  "ext-32k",
+   10, 1, 0);
+static CLK_FIXED_FACTOR(fac_1k,"fac-1k",   "ext-32k",
+   32, 1, 0);
+
+static SPRD_SC_GATE_CLK(mpll0_gate,"mpll0-gate",   "ext-26m", 0xb0,
+0x1000, BIT(2), CLK_IGNORE_UNUSED, 0);
+static SPRD_SC_GATE_CLK(mpll1_gate,"mpll1-gate",   "ext-26m", 0xb0,
+0x1000, BIT(18), CLK_IGNORE_UNUSED, 0);
+static SPRD_SC_GATE_CLK(dpll0_gate,"dpll0-gate",   "ext-26m", 0xb4,
+0x1000, BIT(2), CLK_IGNORE_UNUSED, 0);
+static SPRD_SC_GATE_CLK(dpll1_gate,"dpll1-gate",   "ext-26m", 0xb4,
+0x1000, BIT(18), CLK_IGNORE_UNUSED, 0);
+static SPRD_SC_GATE_CLK(ltepll0_gate,  "ltepll0-gate", "ext-26m", 0xb8,
+0x1000, BIT(2), CLK_IGNORE_UNUSED, 0);
+static SPRD_SC_GATE_CLK(twpll_gate,"twpll-gate",   "ext-26m", 0xbc,
+0x1000, BIT(2), CLK_IGNORE_UNUSED, 0);
+static SPRD_SC_GATE_CLK(ltepll1_gate,  "ltepll1-gate", "ext-26m", 0x10c,
+0x1000, BIT(2), CLK_IGNORE_UNUSED, 0);
+static SPRD_SC_GATE_CLK(rpll0_gate,"rpll0-gate",   "ext-26m", 0x16c,
+0x1000, BIT(2), 0, 0);
+static SPRD_SC_GATE_CLK(rpll1_gate,"rpll1-gate",   "ext-26m", 0x16c,
+0x1000, BIT(18), 0, 0);
+static SPRD_SC_GATE_CLK(cppll_gate,"cppll-gate",   "ext-26m", 0x2b4,
+0x1000, BIT(2), CLK_IGNORE_UNUSED, 0);
+static SPRD_SC_GATE_CLK(gpll_gate, "gpll-gate","ext-26m", 0x32c,
+   0x1000, BIT(0), CLK_IGNORE_UNUSED, CLK_GATE_SET_TO_DISABLE);
+
+static struct sprd_clk_common *sc9860_pmu_gate_clks[] = {
+   /* address base is 0x402b */
+   _gate.common,
+   _gate.common,
+   _gate.common,
+   _gate.common,
+   _gate.common,
+   _gate.common,
+   _gate.common,
+   _gate.common,
+   _gate.common,
+   _gate.common,
+   _gate.common,
+};
+
+static struct clk_hw_onecell_data sc9860_pmu_gate_hws 

[PATCH V4 09/12] clk: sprd: Add dt-bindings include file for SC9860

2017-11-09 Thread Chunyan Zhang
This file defines all SC9860 clock indexes, it should be included in the
device tree in which there's device using the clocks.

Signed-off-by: Chunyan Zhang 
---
 include/dt-bindings/clock/sprd,sc9860-clk.h | 408 
 1 file changed, 408 insertions(+)
 create mode 100644 include/dt-bindings/clock/sprd,sc9860-clk.h

diff --git a/include/dt-bindings/clock/sprd,sc9860-clk.h 
b/include/dt-bindings/clock/sprd,sc9860-clk.h
new file mode 100644
index 000..48e6052
--- /dev/null
+++ b/include/dt-bindings/clock/sprd,sc9860-clk.h
@@ -0,0 +1,408 @@
+/*
+ * Spreadtrum SC9860 platform clocks
+ *
+ * Copyright (C) 2017, Spreadtrum Communications Inc.
+ *
+ * SPDX-License-Identifier: (GPL-2.0+ OR MIT)
+ */
+
+#ifndef _DT_BINDINGS_CLK_SC9860_H_
+#define _DT_BINDINGS_CLK_SC9860_H_
+
+#defineCLK_EXT_RCO_100M0
+#defineCLK_EXT_32K 1
+#defineCLK_FAC_4M  2
+#defineCLK_FAC_2M  3
+#defineCLK_FAC_1M  4
+#defineCLK_FAC_250K5
+#defineCLK_FAC_RPLL0_26M   6
+#defineCLK_FAC_RPLL1_26M   7
+#defineCLK_FAC_RCO25M  8
+#defineCLK_FAC_RCO4M   9
+#defineCLK_FAC_RCO2M   10
+#defineCLK_FAC_3K2 11
+#defineCLK_FAC_1K  12
+#defineCLK_MPLL0_GATE  13
+#defineCLK_MPLL1_GATE  14
+#defineCLK_DPLL0_GATE  15
+#defineCLK_DPLL1_GATE  16
+#defineCLK_LTEPLL0_GATE17
+#defineCLK_TWPLL_GATE  18
+#defineCLK_LTEPLL1_GATE19
+#defineCLK_RPLL0_GATE  20
+#defineCLK_RPLL1_GATE  21
+#defineCLK_CPPLL_GATE  22
+#defineCLK_GPLL_GATE   23
+#define CLK_PMU_GATE_NUM   (CLK_GPLL_GATE + 1)
+
+#defineCLK_MPLL0   0
+#defineCLK_MPLL1   1
+#defineCLK_DPLL0   2
+#defineCLK_DPLL1   3
+#defineCLK_RPLL0   4
+#defineCLK_RPLL1   5
+#defineCLK_TWPLL   6
+#defineCLK_LTEPLL0 7
+#defineCLK_LTEPLL1 8
+#defineCLK_GPLL9
+#defineCLK_CPPLL   10
+#defineCLK_GPLL_42M5   11
+#defineCLK_TWPLL_768M  12
+#defineCLK_TWPLL_384M  13
+#defineCLK_TWPLL_192M  14
+#defineCLK_TWPLL_96M   15
+#defineCLK_TWPLL_48M   16
+#defineCLK_TWPLL_24M   17
+#defineCLK_TWPLL_12M   18
+#defineCLK_TWPLL_512M  19
+#defineCLK_TWPLL_256M  20
+#defineCLK_TWPLL_128M  21
+#defineCLK_TWPLL_64M   22
+#defineCLK_TWPLL_307M2 23
+#defineCLK_TWPLL_153M6 24
+#defineCLK_TWPLL_76M8  25
+#defineCLK_TWPLL_51M2  26
+#defineCLK_TWPLL_38M4  27
+#defineCLK_TWPLL_19M2  28
+#defineCLK_L0_614M429
+#defineCLK_L0_409M630
+#defineCLK_L0_38M  31
+#defineCLK_L1_38M  32
+#defineCLK_RPLL0_192M  33
+#defineCLK_RPLL0_96M   34
+#defineCLK_RPLL0_48M   35
+#defineCLK_RPLL1_468M  36
+#defineCLK_RPLL1_192M  37
+#defineCLK_RPLL1_96M   38
+#defineCLK_RPLL1_64M   39
+#defineCLK_RPLL1_48M   40
+#defineCLK_DPLL0_50M   41
+#defineCLK_DPLL1_50M   42
+#defineCLK_CPPLL_50M   43
+#defineCLK_M0_39M  44
+#defineCLK_M1_63M  45
+#define CLK_PLL_NUM(CLK_M1_63M + 1)
+
+
+#defineCLK_AP_APB  0
+#defineCLK_AP_USB3 1
+#defineCLK_UART0   2
+#defineCLK_UART1   3
+#defineCLK_UART2   4
+#defineCLK_UART3   5
+#defineCLK_UART4   6
+#defineCLK_I2C07
+#defineCLK_I2C18
+#defineCLK_I2C29
+#defineCLK_I2C310
+#defineCLK_I2C411
+#defineCLK_I2C512
+#defineCLK_SPI013
+#defineCLK_SPI114
+#defineCLK_SPI215
+#defineCLK_SPI316
+#defineCLK_IIS017
+#defineCLK_IIS118
+#defineCLK_IIS219
+#defineCLK_IIS320
+#define CLK_AP_CLK_NUM (CLK_IIS3 + 1)
+
+#defineCLK_AON_APB 0
+#defineCLK_AUX01
+#defineCLK_AUX1

[PATCH V4 09/12] clk: sprd: Add dt-bindings include file for SC9860

2017-11-09 Thread Chunyan Zhang
This file defines all SC9860 clock indexes, it should be included in the
device tree in which there's device using the clocks.

Signed-off-by: Chunyan Zhang 
---
 include/dt-bindings/clock/sprd,sc9860-clk.h | 408 
 1 file changed, 408 insertions(+)
 create mode 100644 include/dt-bindings/clock/sprd,sc9860-clk.h

diff --git a/include/dt-bindings/clock/sprd,sc9860-clk.h 
b/include/dt-bindings/clock/sprd,sc9860-clk.h
new file mode 100644
index 000..48e6052
--- /dev/null
+++ b/include/dt-bindings/clock/sprd,sc9860-clk.h
@@ -0,0 +1,408 @@
+/*
+ * Spreadtrum SC9860 platform clocks
+ *
+ * Copyright (C) 2017, Spreadtrum Communications Inc.
+ *
+ * SPDX-License-Identifier: (GPL-2.0+ OR MIT)
+ */
+
+#ifndef _DT_BINDINGS_CLK_SC9860_H_
+#define _DT_BINDINGS_CLK_SC9860_H_
+
+#defineCLK_EXT_RCO_100M0
+#defineCLK_EXT_32K 1
+#defineCLK_FAC_4M  2
+#defineCLK_FAC_2M  3
+#defineCLK_FAC_1M  4
+#defineCLK_FAC_250K5
+#defineCLK_FAC_RPLL0_26M   6
+#defineCLK_FAC_RPLL1_26M   7
+#defineCLK_FAC_RCO25M  8
+#defineCLK_FAC_RCO4M   9
+#defineCLK_FAC_RCO2M   10
+#defineCLK_FAC_3K2 11
+#defineCLK_FAC_1K  12
+#defineCLK_MPLL0_GATE  13
+#defineCLK_MPLL1_GATE  14
+#defineCLK_DPLL0_GATE  15
+#defineCLK_DPLL1_GATE  16
+#defineCLK_LTEPLL0_GATE17
+#defineCLK_TWPLL_GATE  18
+#defineCLK_LTEPLL1_GATE19
+#defineCLK_RPLL0_GATE  20
+#defineCLK_RPLL1_GATE  21
+#defineCLK_CPPLL_GATE  22
+#defineCLK_GPLL_GATE   23
+#define CLK_PMU_GATE_NUM   (CLK_GPLL_GATE + 1)
+
+#defineCLK_MPLL0   0
+#defineCLK_MPLL1   1
+#defineCLK_DPLL0   2
+#defineCLK_DPLL1   3
+#defineCLK_RPLL0   4
+#defineCLK_RPLL1   5
+#defineCLK_TWPLL   6
+#defineCLK_LTEPLL0 7
+#defineCLK_LTEPLL1 8
+#defineCLK_GPLL9
+#defineCLK_CPPLL   10
+#defineCLK_GPLL_42M5   11
+#defineCLK_TWPLL_768M  12
+#defineCLK_TWPLL_384M  13
+#defineCLK_TWPLL_192M  14
+#defineCLK_TWPLL_96M   15
+#defineCLK_TWPLL_48M   16
+#defineCLK_TWPLL_24M   17
+#defineCLK_TWPLL_12M   18
+#defineCLK_TWPLL_512M  19
+#defineCLK_TWPLL_256M  20
+#defineCLK_TWPLL_128M  21
+#defineCLK_TWPLL_64M   22
+#defineCLK_TWPLL_307M2 23
+#defineCLK_TWPLL_153M6 24
+#defineCLK_TWPLL_76M8  25
+#defineCLK_TWPLL_51M2  26
+#defineCLK_TWPLL_38M4  27
+#defineCLK_TWPLL_19M2  28
+#defineCLK_L0_614M429
+#defineCLK_L0_409M630
+#defineCLK_L0_38M  31
+#defineCLK_L1_38M  32
+#defineCLK_RPLL0_192M  33
+#defineCLK_RPLL0_96M   34
+#defineCLK_RPLL0_48M   35
+#defineCLK_RPLL1_468M  36
+#defineCLK_RPLL1_192M  37
+#defineCLK_RPLL1_96M   38
+#defineCLK_RPLL1_64M   39
+#defineCLK_RPLL1_48M   40
+#defineCLK_DPLL0_50M   41
+#defineCLK_DPLL1_50M   42
+#defineCLK_CPPLL_50M   43
+#defineCLK_M0_39M  44
+#defineCLK_M1_63M  45
+#define CLK_PLL_NUM(CLK_M1_63M + 1)
+
+
+#defineCLK_AP_APB  0
+#defineCLK_AP_USB3 1
+#defineCLK_UART0   2
+#defineCLK_UART1   3
+#defineCLK_UART2   4
+#defineCLK_UART3   5
+#defineCLK_UART4   6
+#defineCLK_I2C07
+#defineCLK_I2C18
+#defineCLK_I2C29
+#defineCLK_I2C310
+#defineCLK_I2C411
+#defineCLK_I2C512
+#defineCLK_SPI013
+#defineCLK_SPI114
+#defineCLK_SPI215
+#defineCLK_SPI316
+#defineCLK_IIS017
+#defineCLK_IIS118
+#defineCLK_IIS219
+#defineCLK_IIS320
+#define CLK_AP_CLK_NUM (CLK_IIS3 + 1)
+
+#defineCLK_AON_APB 0
+#defineCLK_AUX01
+#defineCLK_AUX12
+#defineCLK_AUX2 

Re: [RFC PATCH 0/2] apply write hints to select the type of segments

2017-11-09 Thread Chao Yu
On 2017/11/10 8:23, Hyunchul Lee wrote:
> Hello, Chao
> 
> On 11/09/2017 06:12 PM, Chao Yu wrote:
>> On 2017/11/9 13:51, Hyunchul Lee wrote:
>>> From: Hyunchul Lee 
>>>
>>> Using write hints[1], applications can inform the life time of the data
>>> written to devices. and this[2] reported that the write hints patch
>>> decreased writes in NAND by 25%.
>>>
>>> This hints help F2FS to determine the followings.
>>>   1) the segment types where the data will be written.
>>>   2) the hints that will be passed down to devices with the data of 
>>> segments.
>>>
>>> This patch set implements the first mapping from write hints to segment 
>>> types
>>> as shown below.
>>>
>>>   hints segment type
>>>   - 
>>>   WRITE_LIFE_SHORT  CURSEG_COLD_DATA
>>>   WRITE_LIFE_EXTREMECURSEG_HOT_DATA
>>>   othersCURSEG_WARM_DATA
>>>
>>> The F2FS poliy for hot/cold seperation has precedence over this hints, And
>>> hints are not applied in in-place update.
>>
>> Could we change to disable IPU if file/inode write hint is existing?
>>
> 
> I am afraid that this makes side effects. for example, this could cause
> out-of-place updates even when there are not enough free segments. 
> I can write the patch that handles these situations. But I wonder 
> that this is required, and I am not sure which IPU polices can be disabled.

Oh, As I replied in another thread, I think IPU just affects filesystem
hot/cold separating, rather than this feature. So I think it will be okay
to not consider it.

> 
>>>
>>> Before the second mapping is implemented, write hints are not passed down
>>> to devices. Because it is better that the data of a segment have the same 
>>> hint.
>>>
>>> [1]: c75b1d9421f80f4143e389d2d50ddfc8a28c8c35
>>> [2]: https://lwn.net/Articles/726477/
>>
>> Could you write a patch to support passing write hint to block layer for
>> buffered writes as below commit:
>> 0127251c45ae ("ext4: add support for passing in write hints for buffered 
>> writes")
>>
> 
> Sure I will. I wrote it already ;)

Cool, ;)

> I think that datas from the same segment should be passed down with the same
> hint, and the following mapping is reasonable. I wonder what is your opinion
> about it.
> 
>   segment type   hints
>      -
>   CURSEG_COLD_DATA   WRITE_LIFE_EXTREME
>   CURSEG_HOT_DATAWRITE_LIFE_SHORT
>   CURSEG_COLD_NODE   WRITE_LIFE_NORMAL

We have WRITE_LIFE_LONG defined rather than WRITE_LIFE_NORMAL in fs.h?

>   CURSEG_HOT_NODEWRITE_LIFE_MEDIUM

As I know, in scenario of cell phone, data of meta_inode is hottest, then hot
data, warm node, and cold node should be coldest. So I suggested we can define
as below:

META_DATA   WRITE_LIFE_SHORT
HOT_DATA & WARM_NODEWRITE_LIFE_MEDIUM
HOT_NODE & WARM_DATAWRITE_LIFE_LONG
COLD_NODE & COLD_DATA   WRITE_LIFE_EXTREME

Thanks,

>   others WRITE_LIFE_NONE
>  
>> Thanks,
>>
>>>
>>> Hyunchul Lee (2):
>>>   f2fs: apply write hints to select the type of segments for buffered
>>> write
>>>   f2fs: apply write hints to select the type of segment for direct write
>>>
>>>  fs/f2fs/data.c| 101 
>>> --
>>>  fs/f2fs/f2fs.h|   1 +
>>>  fs/f2fs/segment.c |  14 +++-
>>>  3 files changed, 74 insertions(+), 42 deletions(-)
>>>
>>
>>
> 
> Thanks
> 
> .
> 



[PATCH V4 11/12] arm64: dts: add syscon for whale2 platform

2017-11-09 Thread Chunyan Zhang
Some clocks on SC9860 are in the same address area with syscon
devices, the proper syscon node will be quoted under the
definitions of those clocks in DT.

Signed-off-by: Chunyan Zhang 
---
 arch/arm64/boot/dts/sprd/whale2.dtsi | 46 +++-
 1 file changed, 45 insertions(+), 1 deletion(-)

diff --git a/arch/arm64/boot/dts/sprd/whale2.dtsi 
b/arch/arm64/boot/dts/sprd/whale2.dtsi
index 7c217c5..6ea3a75 100644
--- a/arch/arm64/boot/dts/sprd/whale2.dtsi
+++ b/arch/arm64/boot/dts/sprd/whale2.dtsi
@@ -17,6 +17,51 @@
#size-cells = <2>;
ranges;
 
+   ap_ahb_regs: syscon@2021 {
+   compatible = "syscon";
+   reg = <0 0x2021 0 0x1>;
+   };
+
+   pmu_regs: syscon@402b {
+   compatible = "syscon";
+   reg = <0 0x402b 0 0x1>;
+   };
+
+   aon_regs: syscon@402e {
+   compatible = "syscon";
+   reg = <0 0x402e 0 0x1>;
+   };
+
+   ana_regs: syscon@4040 {
+   compatible = "syscon";
+   reg = <0 0x4040 0 0x1>;
+   };
+
+   agcp_regs: syscon@415e {
+   compatible = "syscon";
+   reg = <0 0x415e 0 0x100>;
+   };
+
+   vsp_regs: syscon@6110 {
+   compatible = "syscon";
+   reg = <0 0x6110 0 0x1>;
+   };
+
+   cam_regs: syscon@6210 {
+   compatible = "syscon";
+   reg = <0 0x6210 0 0x1>;
+   };
+
+   disp_regs: syscon@6310 {
+   compatible = "syscon";
+   reg = <0 0x6310 0 0x1>;
+   };
+
+   ap_apb_regs: syscon@70b0 {
+   compatible = "syscon";
+   reg = <0 0x70b0 0 0x4>;
+   };
+
ap-apb {
compatible = "simple-bus";
#address-cells = <1>;
@@ -59,7 +104,6 @@
status = "disabled";
};
};
-
};
 
ext_26m: ext-26m {
-- 
2.7.4



Re: [RFC PATCH 0/2] apply write hints to select the type of segments

2017-11-09 Thread Chao Yu
On 2017/11/10 8:23, Hyunchul Lee wrote:
> Hello, Chao
> 
> On 11/09/2017 06:12 PM, Chao Yu wrote:
>> On 2017/11/9 13:51, Hyunchul Lee wrote:
>>> From: Hyunchul Lee 
>>>
>>> Using write hints[1], applications can inform the life time of the data
>>> written to devices. and this[2] reported that the write hints patch
>>> decreased writes in NAND by 25%.
>>>
>>> This hints help F2FS to determine the followings.
>>>   1) the segment types where the data will be written.
>>>   2) the hints that will be passed down to devices with the data of 
>>> segments.
>>>
>>> This patch set implements the first mapping from write hints to segment 
>>> types
>>> as shown below.
>>>
>>>   hints segment type
>>>   - 
>>>   WRITE_LIFE_SHORT  CURSEG_COLD_DATA
>>>   WRITE_LIFE_EXTREMECURSEG_HOT_DATA
>>>   othersCURSEG_WARM_DATA
>>>
>>> The F2FS poliy for hot/cold seperation has precedence over this hints, And
>>> hints are not applied in in-place update.
>>
>> Could we change to disable IPU if file/inode write hint is existing?
>>
> 
> I am afraid that this makes side effects. for example, this could cause
> out-of-place updates even when there are not enough free segments. 
> I can write the patch that handles these situations. But I wonder 
> that this is required, and I am not sure which IPU polices can be disabled.

Oh, As I replied in another thread, I think IPU just affects filesystem
hot/cold separating, rather than this feature. So I think it will be okay
to not consider it.

> 
>>>
>>> Before the second mapping is implemented, write hints are not passed down
>>> to devices. Because it is better that the data of a segment have the same 
>>> hint.
>>>
>>> [1]: c75b1d9421f80f4143e389d2d50ddfc8a28c8c35
>>> [2]: https://lwn.net/Articles/726477/
>>
>> Could you write a patch to support passing write hint to block layer for
>> buffered writes as below commit:
>> 0127251c45ae ("ext4: add support for passing in write hints for buffered 
>> writes")
>>
> 
> Sure I will. I wrote it already ;)

Cool, ;)

> I think that datas from the same segment should be passed down with the same
> hint, and the following mapping is reasonable. I wonder what is your opinion
> about it.
> 
>   segment type   hints
>      -
>   CURSEG_COLD_DATA   WRITE_LIFE_EXTREME
>   CURSEG_HOT_DATAWRITE_LIFE_SHORT
>   CURSEG_COLD_NODE   WRITE_LIFE_NORMAL

We have WRITE_LIFE_LONG defined rather than WRITE_LIFE_NORMAL in fs.h?

>   CURSEG_HOT_NODEWRITE_LIFE_MEDIUM

As I know, in scenario of cell phone, data of meta_inode is hottest, then hot
data, warm node, and cold node should be coldest. So I suggested we can define
as below:

META_DATA   WRITE_LIFE_SHORT
HOT_DATA & WARM_NODEWRITE_LIFE_MEDIUM
HOT_NODE & WARM_DATAWRITE_LIFE_LONG
COLD_NODE & COLD_DATA   WRITE_LIFE_EXTREME

Thanks,

>   others WRITE_LIFE_NONE
>  
>> Thanks,
>>
>>>
>>> Hyunchul Lee (2):
>>>   f2fs: apply write hints to select the type of segments for buffered
>>> write
>>>   f2fs: apply write hints to select the type of segment for direct write
>>>
>>>  fs/f2fs/data.c| 101 
>>> --
>>>  fs/f2fs/f2fs.h|   1 +
>>>  fs/f2fs/segment.c |  14 +++-
>>>  3 files changed, 74 insertions(+), 42 deletions(-)
>>>
>>
>>
> 
> Thanks
> 
> .
> 



[PATCH V4 11/12] arm64: dts: add syscon for whale2 platform

2017-11-09 Thread Chunyan Zhang
Some clocks on SC9860 are in the same address area with syscon
devices, the proper syscon node will be quoted under the
definitions of those clocks in DT.

Signed-off-by: Chunyan Zhang 
---
 arch/arm64/boot/dts/sprd/whale2.dtsi | 46 +++-
 1 file changed, 45 insertions(+), 1 deletion(-)

diff --git a/arch/arm64/boot/dts/sprd/whale2.dtsi 
b/arch/arm64/boot/dts/sprd/whale2.dtsi
index 7c217c5..6ea3a75 100644
--- a/arch/arm64/boot/dts/sprd/whale2.dtsi
+++ b/arch/arm64/boot/dts/sprd/whale2.dtsi
@@ -17,6 +17,51 @@
#size-cells = <2>;
ranges;
 
+   ap_ahb_regs: syscon@2021 {
+   compatible = "syscon";
+   reg = <0 0x2021 0 0x1>;
+   };
+
+   pmu_regs: syscon@402b {
+   compatible = "syscon";
+   reg = <0 0x402b 0 0x1>;
+   };
+
+   aon_regs: syscon@402e {
+   compatible = "syscon";
+   reg = <0 0x402e 0 0x1>;
+   };
+
+   ana_regs: syscon@4040 {
+   compatible = "syscon";
+   reg = <0 0x4040 0 0x1>;
+   };
+
+   agcp_regs: syscon@415e {
+   compatible = "syscon";
+   reg = <0 0x415e 0 0x100>;
+   };
+
+   vsp_regs: syscon@6110 {
+   compatible = "syscon";
+   reg = <0 0x6110 0 0x1>;
+   };
+
+   cam_regs: syscon@6210 {
+   compatible = "syscon";
+   reg = <0 0x6210 0 0x1>;
+   };
+
+   disp_regs: syscon@6310 {
+   compatible = "syscon";
+   reg = <0 0x6310 0 0x1>;
+   };
+
+   ap_apb_regs: syscon@70b0 {
+   compatible = "syscon";
+   reg = <0 0x70b0 0 0x4>;
+   };
+
ap-apb {
compatible = "simple-bus";
#address-cells = <1>;
@@ -59,7 +104,6 @@
status = "disabled";
};
};
-
};
 
ext_26m: ext-26m {
-- 
2.7.4



[PATCH v2] checkpatch: Fix checks for Kconfig help text

2017-11-09 Thread Leo Yan
If one patch has Kconfig section, the check script variable '$is_start'
will be set by first 'config' line and the variable '$is_end' is to be
set by the second 'config' line. But patches often only has one
'config' line so we have no chance to set '$is_end', as result below
condition is invalid and it skips check for Kconfig description:

if ($is_start && $is_end && $length < $min_conf_desc_length) {
..
}

When script runs to this condition sentence it means the Kconfig
section parsing has been completed, whatever '$is_end' is true
or not. So removes '$is_end' from condition sentence.

Another change is to change '$min_conf_desc_length' from 4 to 1; so can
pass the check if Kconfig description has at least one line.

Signed-off-by: Leo Yan 
---
 scripts/checkpatch.pl | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/scripts/checkpatch.pl b/scripts/checkpatch.pl
index 3453df9..ba724b0 100755
--- a/scripts/checkpatch.pl
+++ b/scripts/checkpatch.pl
@@ -51,7 +51,7 @@ my $configuration_file = ".checkpatch.conf";
 my $max_line_length = 80;
 my $ignore_perl_version = 0;
 my $minimum_perl_version = 5.10.0;
-my $min_conf_desc_length = 4;
+my $min_conf_desc_length = 1;
 my $spelling_file = "$D/spelling.txt";
 my $codespell = 0;
 my $codespellfile = "/usr/share/codespell/dictionary.txt";
@@ -2796,7 +2796,7 @@ sub process {
}
$length++;
}
-   if ($is_start && $is_end && $length < 
$min_conf_desc_length) {
+   if ($is_start && $length < $min_conf_desc_length) {
WARN("CONFIG_DESCRIPTION",
 "please write a paragraph that describes 
the config symbol fully\n" . $herecurr);
}
-- 
2.7.4



[PATCH V4 07/12] clk: sprd: add composite clock support

2017-11-09 Thread Chunyan Zhang
This patch introduced composite clock driver for Spreadtrum's SoCs.
The functions of this composite clock simply consists of divider
and mux clocks.

Signed-off-by: Chunyan Zhang 
---
 drivers/clk/sprd/Makefile|  1 +
 drivers/clk/sprd/composite.c | 65 
 drivers/clk/sprd/composite.h | 55 +
 3 files changed, 121 insertions(+)
 create mode 100644 drivers/clk/sprd/composite.c
 create mode 100644 drivers/clk/sprd/composite.h

diff --git a/drivers/clk/sprd/Makefile b/drivers/clk/sprd/Makefile
index 80e6039..2262e76 100644
--- a/drivers/clk/sprd/Makefile
+++ b/drivers/clk/sprd/Makefile
@@ -4,3 +4,4 @@ clk-sprd-y  += common.o
 clk-sprd-y += gate.o
 clk-sprd-y += mux.o
 clk-sprd-y += div.o
+clk-sprd-y += composite.o
diff --git a/drivers/clk/sprd/composite.c b/drivers/clk/sprd/composite.c
new file mode 100644
index 000..30d5b36
--- /dev/null
+++ b/drivers/clk/sprd/composite.c
@@ -0,0 +1,65 @@
+/*
+ * Spreadtrum composite clock driver
+ *
+ * Copyright (C) 2017 Spreadtrum, Inc.
+ * Author: Chunyan Zhang 
+ *
+ * SPDX-License-Identifier: GPL-2.0
+ */
+
+#include 
+
+#include "composite.h"
+
+DEFINE_SPINLOCK(sprd_comp_lock);
+EXPORT_SYMBOL_GPL(sprd_comp_lock);
+
+static long sprd_comp_round_rate(struct clk_hw *hw, unsigned long rate,
+   unsigned long *parent_rate)
+{
+   struct sprd_comp *cc = hw_to_sprd_comp(hw);
+
+   return sprd_div_helper_round_rate(>common, >div,
+rate, parent_rate);
+}
+
+static unsigned long sprd_comp_recalc_rate(struct clk_hw *hw,
+ unsigned long parent_rate)
+{
+   struct sprd_comp *cc = hw_to_sprd_comp(hw);
+
+   return sprd_div_helper_recalc_rate(>common, >div, parent_rate);
+}
+
+static int sprd_comp_set_rate(struct clk_hw *hw, unsigned long rate,
+unsigned long parent_rate)
+{
+   struct sprd_comp *cc = hw_to_sprd_comp(hw);
+
+   return sprd_div_helper_set_rate(>common, >div,
+  rate, parent_rate);
+}
+
+static u8 sprd_comp_get_parent(struct clk_hw *hw)
+{
+   struct sprd_comp *cc = hw_to_sprd_comp(hw);
+
+   return sprd_mux_helper_get_parent(>common, >mux);
+}
+
+static int sprd_comp_set_parent(struct clk_hw *hw, u8 index)
+{
+   struct sprd_comp *cc = hw_to_sprd_comp(hw);
+
+   return sprd_mux_helper_set_parent(>common, >mux, index);
+}
+
+const struct clk_ops sprd_comp_ops = {
+   .get_parent = sprd_comp_get_parent,
+   .set_parent = sprd_comp_set_parent,
+
+   .round_rate = sprd_comp_round_rate,
+   .recalc_rate= sprd_comp_recalc_rate,
+   .set_rate   = sprd_comp_set_rate,
+};
+EXPORT_SYMBOL_GPL(sprd_comp_ops);
diff --git a/drivers/clk/sprd/composite.h b/drivers/clk/sprd/composite.h
new file mode 100644
index 000..a9bd68d
--- /dev/null
+++ b/drivers/clk/sprd/composite.h
@@ -0,0 +1,55 @@
+/*
+ * Spreadtrum composite clock driver
+ *
+ * Copyright (C) 2017 Spreadtrum, Inc.
+ * Author: Chunyan Zhang 
+ *
+ * SPDX-License-Identifier: GPL-2.0
+ */
+
+#ifndef _SPRD_COMPOSITE_H_
+#define _SPRD_COMPOSITE_H_
+
+#include "common.h"
+#include "mux.h"
+#include "div.h"
+
+struct sprd_comp {
+   struct sprd_mux_sselmux;
+   struct sprd_div_internaldiv;
+   struct sprd_clk_common  common;
+};
+
+#define SPRD_COMP_CLK_TABLE(_struct, _name, _parent, _reg, _table, \
+   _mshift, _mwidth, _dshift, _dwidth, _flags) \
+   struct sprd_comp _struct = {\
+   .mux= _SPRD_MUX_CLK(_mshift, _mwidth, _table),  \
+   .div= _SPRD_DIV_CLK(_dshift, _dwidth),  \
+   .common = { \
+   .regmap = NULL, \
+   .reg= _reg, \
+   .lock   = _comp_lock,  \
+   .hw.init = CLK_HW_INIT_PARENTS(_name,   \
+  _parent, \
+  _comp_ops,  \
+  _flags), \
+}  \
+   }
+
+#define SPRD_COMP_CLK(_struct, _name, _parent, _reg, _mshift,  \
+   _mwidth, _dshift, _dwidth, _flags)  \
+   SPRD_COMP_CLK_TABLE(_struct, _name, _parent, _reg,  \
+   NULL, _mshift, _mwidth, \
+   _dshift, _dwidth, _flags)
+
+static inline struct sprd_comp *hw_to_sprd_comp(const struct clk_hw *hw)
+{
+   struct 

[PATCH V4 02/12] dt-bindings: Add Spreadtrum clock binding documentation

2017-11-09 Thread Chunyan Zhang
Introduce a new binding with its documentation for Spreadtrum clock
sub-framework.

Signed-off-by: Chunyan Zhang 
---
 Documentation/devicetree/bindings/clock/sprd.txt | 63 
 1 file changed, 63 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/clock/sprd.txt

diff --git a/Documentation/devicetree/bindings/clock/sprd.txt 
b/Documentation/devicetree/bindings/clock/sprd.txt
new file mode 100644
index 000..e9d179e
--- /dev/null
+++ b/Documentation/devicetree/bindings/clock/sprd.txt
@@ -0,0 +1,63 @@
+Spreadtrum Clock Binding
+
+
+Required properties:
+- compatible: should contain the following compatible strings:
+   - "sprd,sc9860-pmu-gate"
+   - "sprd,sc9860-pll"
+   - "sprd,sc9860-ap-clk"
+   - "sprd,sc9860-aon-prediv"
+   - "sprd,sc9860-apahb-gate"
+   - "sprd,sc9860-aon-gate"
+   - "sprd,sc9860-aonsecure-clk"
+   - "sprd,sc9860-agcp-gate"
+   - "sprd,sc9860-gpu-clk"
+   - "sprd,sc9860-vsp-clk"
+   - "sprd,sc9860-vsp-gate"
+   - "sprd,sc9860-cam-clk"
+   - "sprd,sc9860-cam-gate"
+   - "sprd,sc9860-disp-clk"
+   - "sprd,sc9860-disp-gate"
+   - "sprd,sc9860-apapb-gate"
+
+- #clock-cells: must be 1
+
+- clocks : Should be the input parent clock(s) phandle for the clock, this
+  property here just simply shows which clock group the clocks'
+  parents are in, since each clk node would represent many clocks
+  which are defined in the driver.  The detailed dependency
+  relationship (i.e. how many parents and which are the parents)
+  are implemented in driver code.
+
+Optional properties:
+
+- reg: Contain the registers base address and length. It must be configured
+   only if no 'sprd,syscon' under the node.
+
+- sprd,syscon: phandle to the syscon which is in the same address area with
+  the clock, and so we can get regmap for the clocks from the
+  syscon device.
+
+Example:
+
+   pmu_gate: pmu-gate {
+   compatible = "sprd,sc9860-pmu-gate";
+   sprd,syscon = <_regs>;
+   clocks = <_26m>;
+   #clock-cells = <1>;
+   };
+
+   pll: pll {
+   compatible = "sprd,sc9860-pll";
+   sprd,syscon = <_regs>;
+   clocks = <_gate 0>;
+   #clock-cells = <1>;
+   };
+
+   ap_clk: clock-controller@2000 {
+   compatible = "sprd,sc9860-ap-clk";
+   reg = <0 0x2000 0 0x400>;
+   clocks = <_26m>, < 0>,
+<_gate 0>;
+   #clock-cells = <1>;
+   };
-- 
2.7.4



[PATCH v2] checkpatch: Fix checks for Kconfig help text

2017-11-09 Thread Leo Yan
If one patch has Kconfig section, the check script variable '$is_start'
will be set by first 'config' line and the variable '$is_end' is to be
set by the second 'config' line. But patches often only has one
'config' line so we have no chance to set '$is_end', as result below
condition is invalid and it skips check for Kconfig description:

if ($is_start && $is_end && $length < $min_conf_desc_length) {
..
}

When script runs to this condition sentence it means the Kconfig
section parsing has been completed, whatever '$is_end' is true
or not. So removes '$is_end' from condition sentence.

Another change is to change '$min_conf_desc_length' from 4 to 1; so can
pass the check if Kconfig description has at least one line.

Signed-off-by: Leo Yan 
---
 scripts/checkpatch.pl | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/scripts/checkpatch.pl b/scripts/checkpatch.pl
index 3453df9..ba724b0 100755
--- a/scripts/checkpatch.pl
+++ b/scripts/checkpatch.pl
@@ -51,7 +51,7 @@ my $configuration_file = ".checkpatch.conf";
 my $max_line_length = 80;
 my $ignore_perl_version = 0;
 my $minimum_perl_version = 5.10.0;
-my $min_conf_desc_length = 4;
+my $min_conf_desc_length = 1;
 my $spelling_file = "$D/spelling.txt";
 my $codespell = 0;
 my $codespellfile = "/usr/share/codespell/dictionary.txt";
@@ -2796,7 +2796,7 @@ sub process {
}
$length++;
}
-   if ($is_start && $is_end && $length < 
$min_conf_desc_length) {
+   if ($is_start && $length < $min_conf_desc_length) {
WARN("CONFIG_DESCRIPTION",
 "please write a paragraph that describes 
the config symbol fully\n" . $herecurr);
}
-- 
2.7.4



[PATCH V4 07/12] clk: sprd: add composite clock support

2017-11-09 Thread Chunyan Zhang
This patch introduced composite clock driver for Spreadtrum's SoCs.
The functions of this composite clock simply consists of divider
and mux clocks.

Signed-off-by: Chunyan Zhang 
---
 drivers/clk/sprd/Makefile|  1 +
 drivers/clk/sprd/composite.c | 65 
 drivers/clk/sprd/composite.h | 55 +
 3 files changed, 121 insertions(+)
 create mode 100644 drivers/clk/sprd/composite.c
 create mode 100644 drivers/clk/sprd/composite.h

diff --git a/drivers/clk/sprd/Makefile b/drivers/clk/sprd/Makefile
index 80e6039..2262e76 100644
--- a/drivers/clk/sprd/Makefile
+++ b/drivers/clk/sprd/Makefile
@@ -4,3 +4,4 @@ clk-sprd-y  += common.o
 clk-sprd-y += gate.o
 clk-sprd-y += mux.o
 clk-sprd-y += div.o
+clk-sprd-y += composite.o
diff --git a/drivers/clk/sprd/composite.c b/drivers/clk/sprd/composite.c
new file mode 100644
index 000..30d5b36
--- /dev/null
+++ b/drivers/clk/sprd/composite.c
@@ -0,0 +1,65 @@
+/*
+ * Spreadtrum composite clock driver
+ *
+ * Copyright (C) 2017 Spreadtrum, Inc.
+ * Author: Chunyan Zhang 
+ *
+ * SPDX-License-Identifier: GPL-2.0
+ */
+
+#include 
+
+#include "composite.h"
+
+DEFINE_SPINLOCK(sprd_comp_lock);
+EXPORT_SYMBOL_GPL(sprd_comp_lock);
+
+static long sprd_comp_round_rate(struct clk_hw *hw, unsigned long rate,
+   unsigned long *parent_rate)
+{
+   struct sprd_comp *cc = hw_to_sprd_comp(hw);
+
+   return sprd_div_helper_round_rate(>common, >div,
+rate, parent_rate);
+}
+
+static unsigned long sprd_comp_recalc_rate(struct clk_hw *hw,
+ unsigned long parent_rate)
+{
+   struct sprd_comp *cc = hw_to_sprd_comp(hw);
+
+   return sprd_div_helper_recalc_rate(>common, >div, parent_rate);
+}
+
+static int sprd_comp_set_rate(struct clk_hw *hw, unsigned long rate,
+unsigned long parent_rate)
+{
+   struct sprd_comp *cc = hw_to_sprd_comp(hw);
+
+   return sprd_div_helper_set_rate(>common, >div,
+  rate, parent_rate);
+}
+
+static u8 sprd_comp_get_parent(struct clk_hw *hw)
+{
+   struct sprd_comp *cc = hw_to_sprd_comp(hw);
+
+   return sprd_mux_helper_get_parent(>common, >mux);
+}
+
+static int sprd_comp_set_parent(struct clk_hw *hw, u8 index)
+{
+   struct sprd_comp *cc = hw_to_sprd_comp(hw);
+
+   return sprd_mux_helper_set_parent(>common, >mux, index);
+}
+
+const struct clk_ops sprd_comp_ops = {
+   .get_parent = sprd_comp_get_parent,
+   .set_parent = sprd_comp_set_parent,
+
+   .round_rate = sprd_comp_round_rate,
+   .recalc_rate= sprd_comp_recalc_rate,
+   .set_rate   = sprd_comp_set_rate,
+};
+EXPORT_SYMBOL_GPL(sprd_comp_ops);
diff --git a/drivers/clk/sprd/composite.h b/drivers/clk/sprd/composite.h
new file mode 100644
index 000..a9bd68d
--- /dev/null
+++ b/drivers/clk/sprd/composite.h
@@ -0,0 +1,55 @@
+/*
+ * Spreadtrum composite clock driver
+ *
+ * Copyright (C) 2017 Spreadtrum, Inc.
+ * Author: Chunyan Zhang 
+ *
+ * SPDX-License-Identifier: GPL-2.0
+ */
+
+#ifndef _SPRD_COMPOSITE_H_
+#define _SPRD_COMPOSITE_H_
+
+#include "common.h"
+#include "mux.h"
+#include "div.h"
+
+struct sprd_comp {
+   struct sprd_mux_sselmux;
+   struct sprd_div_internaldiv;
+   struct sprd_clk_common  common;
+};
+
+#define SPRD_COMP_CLK_TABLE(_struct, _name, _parent, _reg, _table, \
+   _mshift, _mwidth, _dshift, _dwidth, _flags) \
+   struct sprd_comp _struct = {\
+   .mux= _SPRD_MUX_CLK(_mshift, _mwidth, _table),  \
+   .div= _SPRD_DIV_CLK(_dshift, _dwidth),  \
+   .common = { \
+   .regmap = NULL, \
+   .reg= _reg, \
+   .lock   = _comp_lock,  \
+   .hw.init = CLK_HW_INIT_PARENTS(_name,   \
+  _parent, \
+  _comp_ops,  \
+  _flags), \
+}  \
+   }
+
+#define SPRD_COMP_CLK(_struct, _name, _parent, _reg, _mshift,  \
+   _mwidth, _dshift, _dwidth, _flags)  \
+   SPRD_COMP_CLK_TABLE(_struct, _name, _parent, _reg,  \
+   NULL, _mshift, _mwidth, \
+   _dshift, _dwidth, _flags)
+
+static inline struct sprd_comp *hw_to_sprd_comp(const struct clk_hw *hw)
+{
+   struct sprd_clk_common *common = hw_to_sprd_clk_common(hw);
+
+   return container_of(common, struct 

[PATCH V4 02/12] dt-bindings: Add Spreadtrum clock binding documentation

2017-11-09 Thread Chunyan Zhang
Introduce a new binding with its documentation for Spreadtrum clock
sub-framework.

Signed-off-by: Chunyan Zhang 
---
 Documentation/devicetree/bindings/clock/sprd.txt | 63 
 1 file changed, 63 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/clock/sprd.txt

diff --git a/Documentation/devicetree/bindings/clock/sprd.txt 
b/Documentation/devicetree/bindings/clock/sprd.txt
new file mode 100644
index 000..e9d179e
--- /dev/null
+++ b/Documentation/devicetree/bindings/clock/sprd.txt
@@ -0,0 +1,63 @@
+Spreadtrum Clock Binding
+
+
+Required properties:
+- compatible: should contain the following compatible strings:
+   - "sprd,sc9860-pmu-gate"
+   - "sprd,sc9860-pll"
+   - "sprd,sc9860-ap-clk"
+   - "sprd,sc9860-aon-prediv"
+   - "sprd,sc9860-apahb-gate"
+   - "sprd,sc9860-aon-gate"
+   - "sprd,sc9860-aonsecure-clk"
+   - "sprd,sc9860-agcp-gate"
+   - "sprd,sc9860-gpu-clk"
+   - "sprd,sc9860-vsp-clk"
+   - "sprd,sc9860-vsp-gate"
+   - "sprd,sc9860-cam-clk"
+   - "sprd,sc9860-cam-gate"
+   - "sprd,sc9860-disp-clk"
+   - "sprd,sc9860-disp-gate"
+   - "sprd,sc9860-apapb-gate"
+
+- #clock-cells: must be 1
+
+- clocks : Should be the input parent clock(s) phandle for the clock, this
+  property here just simply shows which clock group the clocks'
+  parents are in, since each clk node would represent many clocks
+  which are defined in the driver.  The detailed dependency
+  relationship (i.e. how many parents and which are the parents)
+  are implemented in driver code.
+
+Optional properties:
+
+- reg: Contain the registers base address and length. It must be configured
+   only if no 'sprd,syscon' under the node.
+
+- sprd,syscon: phandle to the syscon which is in the same address area with
+  the clock, and so we can get regmap for the clocks from the
+  syscon device.
+
+Example:
+
+   pmu_gate: pmu-gate {
+   compatible = "sprd,sc9860-pmu-gate";
+   sprd,syscon = <_regs>;
+   clocks = <_26m>;
+   #clock-cells = <1>;
+   };
+
+   pll: pll {
+   compatible = "sprd,sc9860-pll";
+   sprd,syscon = <_regs>;
+   clocks = <_gate 0>;
+   #clock-cells = <1>;
+   };
+
+   ap_clk: clock-controller@2000 {
+   compatible = "sprd,sc9860-ap-clk";
+   reg = <0 0x2000 0 0x400>;
+   clocks = <_26m>, < 0>,
+<_gate 0>;
+   #clock-cells = <1>;
+   };
-- 
2.7.4



[PATCH V4 03/12] clk: sprd: Add common infrastructure

2017-11-09 Thread Chunyan Zhang
Added Spreadtrum's clock driver framework together with common
structures and interface functions.

Signed-off-by: Chunyan Zhang 
---
 drivers/clk/Kconfig   |   1 +
 drivers/clk/Makefile  |   1 +
 drivers/clk/sprd/Kconfig  |   4 ++
 drivers/clk/sprd/Makefile |   3 ++
 drivers/clk/sprd/common.c | 113 ++
 drivers/clk/sprd/common.h |  54 ++
 6 files changed, 176 insertions(+)
 create mode 100644 drivers/clk/sprd/Kconfig
 create mode 100644 drivers/clk/sprd/Makefile
 create mode 100644 drivers/clk/sprd/common.c
 create mode 100644 drivers/clk/sprd/common.h

diff --git a/drivers/clk/Kconfig b/drivers/clk/Kconfig
index 1c4e1aa..ce1a32be 100644
--- a/drivers/clk/Kconfig
+++ b/drivers/clk/Kconfig
@@ -236,6 +236,7 @@ source "drivers/clk/mvebu/Kconfig"
 source "drivers/clk/qcom/Kconfig"
 source "drivers/clk/renesas/Kconfig"
 source "drivers/clk/samsung/Kconfig"
+source "drivers/clk/sprd/Kconfig"
 source "drivers/clk/sunxi-ng/Kconfig"
 source "drivers/clk/tegra/Kconfig"
 source "drivers/clk/ti/Kconfig"
diff --git a/drivers/clk/Makefile b/drivers/clk/Makefile
index c99f363..fa33891 100644
--- a/drivers/clk/Makefile
+++ b/drivers/clk/Makefile
@@ -84,6 +84,7 @@ obj-$(CONFIG_COMMON_CLK_SAMSUNG)  += samsung/
 obj-$(CONFIG_ARCH_SIRF)+= sirf/
 obj-$(CONFIG_ARCH_SOCFPGA) += socfpga/
 obj-$(CONFIG_PLAT_SPEAR)   += spear/
+obj-$(CONFIG_ARCH_SPRD)+= sprd/
 obj-$(CONFIG_ARCH_STI) += st/
 obj-$(CONFIG_ARCH_SUNXI)   += sunxi/
 obj-$(CONFIG_ARCH_SUNXI)   += sunxi-ng/
diff --git a/drivers/clk/sprd/Kconfig b/drivers/clk/sprd/Kconfig
new file mode 100644
index 000..67a3287
--- /dev/null
+++ b/drivers/clk/sprd/Kconfig
@@ -0,0 +1,4 @@
+config SPRD_COMMON_CLK
+   tristate "Clock support for Spreadtrum SoCs"
+   depends on ARCH_SPRD || COMPILE_TEST
+   default ARCH_SPRD
diff --git a/drivers/clk/sprd/Makefile b/drivers/clk/sprd/Makefile
new file mode 100644
index 000..74f4b80
--- /dev/null
+++ b/drivers/clk/sprd/Makefile
@@ -0,0 +1,3 @@
+obj-$(CONFIG_SPRD_COMMON_CLK)  += clk-sprd.o
+
+clk-sprd-y += common.o
diff --git a/drivers/clk/sprd/common.c b/drivers/clk/sprd/common.c
new file mode 100644
index 000..c003f09
--- /dev/null
+++ b/drivers/clk/sprd/common.c
@@ -0,0 +1,113 @@
+/*
+ * Spreadtrum clock infrastructure
+ *
+ * Copyright (C) 2017 Spreadtrum, Inc.
+ * Author: Chunyan Zhang 
+ *
+ * SPDX-License-Identifier: GPL-2.0
+ */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#include "common.h"
+
+static const struct regmap_config sprdclk_regmap_config = {
+   .reg_bits   = 32,
+   .reg_stride = 4,
+   .val_bits   = 32,
+   .max_register   = 0x,
+   .fast_io= true,
+};
+
+static void sprd_clk_set_regmap(const struct sprd_clk_desc *desc,
+struct regmap *regmap)
+{
+   int i;
+   struct sprd_clk_common *cclk;
+
+   for (i = 0; i < desc->num_clk_clks; i++) {
+   cclk = desc->clk_clks[i];
+   if (!cclk)
+   continue;
+
+   cclk->regmap = regmap;
+   }
+}
+
+int sprd_clk_regmap_init(struct platform_device *pdev,
+const struct sprd_clk_desc *desc)
+{
+   void __iomem *base;
+   struct device_node *node = pdev->dev.of_node;
+   struct regmap *regmap = NULL;
+
+   if (of_find_property(node, "sprd,syscon", NULL)) {
+   regmap = syscon_regmap_lookup_by_phandle(node, "sprd,syscon");
+   if (IS_ERR(regmap)) {
+   pr_err("%s: failed to get syscon regmap\n", __func__);
+   return PTR_ERR(regmap);
+   }
+   } else {
+   base = of_iomap(node, 0);
+   regmap = devm_regmap_init_mmio(>dev, base,
+  _regmap_config);
+   if (IS_ERR(regmap)) {
+   pr_err("failed to init regmap.\n");
+   return PTR_ERR(regmap);
+   }
+   }
+
+   sprd_clk_set_regmap(desc, regmap);
+
+   return 0;
+}
+EXPORT_SYMBOL_GPL(sprd_clk_regmap_init);
+
+int sprd_clk_probe(struct device_node *node,
+  struct clk_hw_onecell_data *clkhw)
+{
+   int i, ret = 0;
+   struct clk_hw *hw;
+
+   for (i = 0; i < clkhw->num; i++) {
+
+   hw = clkhw->hws[i];
+
+   if (!hw)
+   continue;
+
+   ret = clk_hw_register(NULL, hw);
+   if (ret) {
+   pr_err("Couldn't register clock %d - %s\n",
+  i, hw->init->name);
+   goto err_clk_unreg;
+   }
+   }
+
+   ret = of_clk_add_hw_provider(node, of_clk_hw_onecell_get,
+  

[PATCH V4 03/12] clk: sprd: Add common infrastructure

2017-11-09 Thread Chunyan Zhang
Added Spreadtrum's clock driver framework together with common
structures and interface functions.

Signed-off-by: Chunyan Zhang 
---
 drivers/clk/Kconfig   |   1 +
 drivers/clk/Makefile  |   1 +
 drivers/clk/sprd/Kconfig  |   4 ++
 drivers/clk/sprd/Makefile |   3 ++
 drivers/clk/sprd/common.c | 113 ++
 drivers/clk/sprd/common.h |  54 ++
 6 files changed, 176 insertions(+)
 create mode 100644 drivers/clk/sprd/Kconfig
 create mode 100644 drivers/clk/sprd/Makefile
 create mode 100644 drivers/clk/sprd/common.c
 create mode 100644 drivers/clk/sprd/common.h

diff --git a/drivers/clk/Kconfig b/drivers/clk/Kconfig
index 1c4e1aa..ce1a32be 100644
--- a/drivers/clk/Kconfig
+++ b/drivers/clk/Kconfig
@@ -236,6 +236,7 @@ source "drivers/clk/mvebu/Kconfig"
 source "drivers/clk/qcom/Kconfig"
 source "drivers/clk/renesas/Kconfig"
 source "drivers/clk/samsung/Kconfig"
+source "drivers/clk/sprd/Kconfig"
 source "drivers/clk/sunxi-ng/Kconfig"
 source "drivers/clk/tegra/Kconfig"
 source "drivers/clk/ti/Kconfig"
diff --git a/drivers/clk/Makefile b/drivers/clk/Makefile
index c99f363..fa33891 100644
--- a/drivers/clk/Makefile
+++ b/drivers/clk/Makefile
@@ -84,6 +84,7 @@ obj-$(CONFIG_COMMON_CLK_SAMSUNG)  += samsung/
 obj-$(CONFIG_ARCH_SIRF)+= sirf/
 obj-$(CONFIG_ARCH_SOCFPGA) += socfpga/
 obj-$(CONFIG_PLAT_SPEAR)   += spear/
+obj-$(CONFIG_ARCH_SPRD)+= sprd/
 obj-$(CONFIG_ARCH_STI) += st/
 obj-$(CONFIG_ARCH_SUNXI)   += sunxi/
 obj-$(CONFIG_ARCH_SUNXI)   += sunxi-ng/
diff --git a/drivers/clk/sprd/Kconfig b/drivers/clk/sprd/Kconfig
new file mode 100644
index 000..67a3287
--- /dev/null
+++ b/drivers/clk/sprd/Kconfig
@@ -0,0 +1,4 @@
+config SPRD_COMMON_CLK
+   tristate "Clock support for Spreadtrum SoCs"
+   depends on ARCH_SPRD || COMPILE_TEST
+   default ARCH_SPRD
diff --git a/drivers/clk/sprd/Makefile b/drivers/clk/sprd/Makefile
new file mode 100644
index 000..74f4b80
--- /dev/null
+++ b/drivers/clk/sprd/Makefile
@@ -0,0 +1,3 @@
+obj-$(CONFIG_SPRD_COMMON_CLK)  += clk-sprd.o
+
+clk-sprd-y += common.o
diff --git a/drivers/clk/sprd/common.c b/drivers/clk/sprd/common.c
new file mode 100644
index 000..c003f09
--- /dev/null
+++ b/drivers/clk/sprd/common.c
@@ -0,0 +1,113 @@
+/*
+ * Spreadtrum clock infrastructure
+ *
+ * Copyright (C) 2017 Spreadtrum, Inc.
+ * Author: Chunyan Zhang 
+ *
+ * SPDX-License-Identifier: GPL-2.0
+ */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#include "common.h"
+
+static const struct regmap_config sprdclk_regmap_config = {
+   .reg_bits   = 32,
+   .reg_stride = 4,
+   .val_bits   = 32,
+   .max_register   = 0x,
+   .fast_io= true,
+};
+
+static void sprd_clk_set_regmap(const struct sprd_clk_desc *desc,
+struct regmap *regmap)
+{
+   int i;
+   struct sprd_clk_common *cclk;
+
+   for (i = 0; i < desc->num_clk_clks; i++) {
+   cclk = desc->clk_clks[i];
+   if (!cclk)
+   continue;
+
+   cclk->regmap = regmap;
+   }
+}
+
+int sprd_clk_regmap_init(struct platform_device *pdev,
+const struct sprd_clk_desc *desc)
+{
+   void __iomem *base;
+   struct device_node *node = pdev->dev.of_node;
+   struct regmap *regmap = NULL;
+
+   if (of_find_property(node, "sprd,syscon", NULL)) {
+   regmap = syscon_regmap_lookup_by_phandle(node, "sprd,syscon");
+   if (IS_ERR(regmap)) {
+   pr_err("%s: failed to get syscon regmap\n", __func__);
+   return PTR_ERR(regmap);
+   }
+   } else {
+   base = of_iomap(node, 0);
+   regmap = devm_regmap_init_mmio(>dev, base,
+  _regmap_config);
+   if (IS_ERR(regmap)) {
+   pr_err("failed to init regmap.\n");
+   return PTR_ERR(regmap);
+   }
+   }
+
+   sprd_clk_set_regmap(desc, regmap);
+
+   return 0;
+}
+EXPORT_SYMBOL_GPL(sprd_clk_regmap_init);
+
+int sprd_clk_probe(struct device_node *node,
+  struct clk_hw_onecell_data *clkhw)
+{
+   int i, ret = 0;
+   struct clk_hw *hw;
+
+   for (i = 0; i < clkhw->num; i++) {
+
+   hw = clkhw->hws[i];
+
+   if (!hw)
+   continue;
+
+   ret = clk_hw_register(NULL, hw);
+   if (ret) {
+   pr_err("Couldn't register clock %d - %s\n",
+  i, hw->init->name);
+   goto err_clk_unreg;
+   }
+   }
+
+   ret = of_clk_add_hw_provider(node, of_clk_hw_onecell_get,
+clkhw);
+   if (ret) {
+   pr_err("Failed 

[PATCH V4 08/12] clk: sprd: add adjustable pll support

2017-11-09 Thread Chunyan Zhang
Introduced a common adjustable pll clock driver for Spreadtrum SoCs.

Signed-off-by: Chunyan Zhang 
---
 drivers/clk/sprd/Makefile |   1 +
 drivers/clk/sprd/pll.c| 268 ++
 drivers/clk/sprd/pll.h| 110 +++
 3 files changed, 379 insertions(+)
 create mode 100644 drivers/clk/sprd/pll.c
 create mode 100644 drivers/clk/sprd/pll.h

diff --git a/drivers/clk/sprd/Makefile b/drivers/clk/sprd/Makefile
index 2262e76..d693969 100644
--- a/drivers/clk/sprd/Makefile
+++ b/drivers/clk/sprd/Makefile
@@ -5,3 +5,4 @@ clk-sprd-y  += gate.o
 clk-sprd-y += mux.o
 clk-sprd-y += div.o
 clk-sprd-y += composite.o
+clk-sprd-y += pll.o
diff --git a/drivers/clk/sprd/pll.c b/drivers/clk/sprd/pll.c
new file mode 100644
index 000..1fd8d32
--- /dev/null
+++ b/drivers/clk/sprd/pll.c
@@ -0,0 +1,268 @@
+/*
+ * Spreadtrum pll clock driver
+ *
+ * Copyright (C) 2015~2017 Spreadtrum, Inc.
+ * Author: Chunyan Zhang 
+ *
+ * SPDX-License-Identifier: GPL-2.0
+ */
+
+#include 
+#include 
+#include 
+#include 
+
+#include "pll.h"
+
+#define CLK_PLL_1M 100
+#define CLK_PLL_10M(CLK_PLL_1M * 10)
+
+#define pindex(pll, member)\
+   (pll->factors[member].shift / (8 * sizeof(pll->regs_num)))
+
+#define pshift(pll, member)\
+   (pll->factors[member].shift % (8 * sizeof(pll->regs_num)))
+
+#define pwidth(pll, member)\
+   pll->factors[member].width
+
+#define pmask(pll, member) \
+   ((pwidth(pll, member)) ?\
+   GENMASK(pwidth(pll, member) + pshift(pll, member) - 1,  \
+   pshift(pll, member)) : 0)
+
+#define pinternal(pll, cfg, member)\
+   (cfg[pindex(pll, member)] & pmask(pll, member))
+
+#define pinternal_val(pll, cfg, member)\
+   (pinternal(pll, cfg, member) >> pshift(pll, member))
+
+static inline unsigned int
+sprd_pll_read(const struct sprd_pll *pll, u8 index)
+{
+   const struct sprd_clk_common *common = >common;
+   unsigned int val = 0;
+
+   if (WARN_ON(index >= pll->regs_num))
+   return 0;
+
+   sprd_regmap_read(common->regmap, common->reg + index * 4, );
+
+   return val;
+}
+
+static inline void
+sprd_pll_write(const struct sprd_pll *pll, u8 index,
+ u32 msk, u32 val)
+{
+   const struct sprd_clk_common *common = >common;
+   unsigned int offset, reg;
+   int ret = 0;
+
+   if (WARN_ON(index >= pll->regs_num))
+   return;
+
+   offset = common->reg + index * 4;
+   ret = sprd_regmap_read(common->regmap, offset, );
+   if (!ret)
+   sprd_regmap_write(common->regmap, offset, (reg & ~msk) | val);
+}
+
+static unsigned long pll_get_refin(const struct sprd_pll *pll)
+{
+   u32 shift, mask, index, refin_id = 3;
+   const unsigned long refin[4] = { 2, 4, 13, 26 };
+
+   if (pwidth(pll, PLL_REFIN)) {
+   index = pindex(pll, PLL_REFIN);
+   shift = pshift(pll, PLL_REFIN);
+   mask = pmask(pll, PLL_REFIN);
+   refin_id = (sprd_pll_read(pll, index) & mask) >> shift;
+   if (refin_id > 3)
+   refin_id = 3;
+   }
+
+   return refin[refin_id];
+}
+
+static u32 pll_get_ibias(u64 rate, const u64 *table)
+{
+   u32 i, num = table[0];
+
+   for (i = 1; i < num + 1; i++)
+   if (rate <= table[i])
+   break;
+
+   return (i == num + 1) ? num : i;
+}
+
+static unsigned long _sprd_pll_recalc_rate(const struct sprd_pll *pll,
+  unsigned long parent_rate)
+{
+   u32 *cfg;
+   u32 i, mask, regs_num = pll->regs_num;
+   unsigned long rate, nint, kint = 0;
+   u64 refin;
+   u16 k1, k2;
+
+   cfg = kcalloc(regs_num, sizeof(*cfg), GFP_KERNEL);
+   if (!cfg)
+   return -ENOMEM;
+
+   for (i = 0; i < regs_num; i++)
+   cfg[i] = sprd_pll_read(pll, i);
+
+   refin = pll_get_refin(pll);
+
+   if (pinternal(pll, cfg, PLL_PREDIV))
+   refin = refin * 2;
+
+   if (pwidth(pll, PLL_POSTDIV) &&
+   ((pll->fflag == 1 && pinternal(pll, cfg, PLL_POSTDIV)) ||
+(!pll->fflag && !pinternal(pll, cfg, PLL_POSTDIV
+   refin = refin / 2;
+
+   if (!pinternal(pll, cfg, PLL_DIV_S)) {
+   rate = refin * pinternal_val(pll, cfg, PLL_N) * CLK_PLL_10M;
+   } else {
+   nint = pinternal_val(pll, cfg, PLL_NINT);
+   if (pinternal(pll, cfg, PLL_SDM_EN))
+   kint = pinternal_val(pll, cfg, PLL_KINT);
+
+   mask = pmask(pll, PLL_KINT);
+
+   k1 = pll->k1;
+   k2 = pll->k2;
+   rate = DIV_ROUND_CLOSEST_ULL(refin * kint * k1,
+((mask >> 

[PATCH V4 08/12] clk: sprd: add adjustable pll support

2017-11-09 Thread Chunyan Zhang
Introduced a common adjustable pll clock driver for Spreadtrum SoCs.

Signed-off-by: Chunyan Zhang 
---
 drivers/clk/sprd/Makefile |   1 +
 drivers/clk/sprd/pll.c| 268 ++
 drivers/clk/sprd/pll.h| 110 +++
 3 files changed, 379 insertions(+)
 create mode 100644 drivers/clk/sprd/pll.c
 create mode 100644 drivers/clk/sprd/pll.h

diff --git a/drivers/clk/sprd/Makefile b/drivers/clk/sprd/Makefile
index 2262e76..d693969 100644
--- a/drivers/clk/sprd/Makefile
+++ b/drivers/clk/sprd/Makefile
@@ -5,3 +5,4 @@ clk-sprd-y  += gate.o
 clk-sprd-y += mux.o
 clk-sprd-y += div.o
 clk-sprd-y += composite.o
+clk-sprd-y += pll.o
diff --git a/drivers/clk/sprd/pll.c b/drivers/clk/sprd/pll.c
new file mode 100644
index 000..1fd8d32
--- /dev/null
+++ b/drivers/clk/sprd/pll.c
@@ -0,0 +1,268 @@
+/*
+ * Spreadtrum pll clock driver
+ *
+ * Copyright (C) 2015~2017 Spreadtrum, Inc.
+ * Author: Chunyan Zhang 
+ *
+ * SPDX-License-Identifier: GPL-2.0
+ */
+
+#include 
+#include 
+#include 
+#include 
+
+#include "pll.h"
+
+#define CLK_PLL_1M 100
+#define CLK_PLL_10M(CLK_PLL_1M * 10)
+
+#define pindex(pll, member)\
+   (pll->factors[member].shift / (8 * sizeof(pll->regs_num)))
+
+#define pshift(pll, member)\
+   (pll->factors[member].shift % (8 * sizeof(pll->regs_num)))
+
+#define pwidth(pll, member)\
+   pll->factors[member].width
+
+#define pmask(pll, member) \
+   ((pwidth(pll, member)) ?\
+   GENMASK(pwidth(pll, member) + pshift(pll, member) - 1,  \
+   pshift(pll, member)) : 0)
+
+#define pinternal(pll, cfg, member)\
+   (cfg[pindex(pll, member)] & pmask(pll, member))
+
+#define pinternal_val(pll, cfg, member)\
+   (pinternal(pll, cfg, member) >> pshift(pll, member))
+
+static inline unsigned int
+sprd_pll_read(const struct sprd_pll *pll, u8 index)
+{
+   const struct sprd_clk_common *common = >common;
+   unsigned int val = 0;
+
+   if (WARN_ON(index >= pll->regs_num))
+   return 0;
+
+   sprd_regmap_read(common->regmap, common->reg + index * 4, );
+
+   return val;
+}
+
+static inline void
+sprd_pll_write(const struct sprd_pll *pll, u8 index,
+ u32 msk, u32 val)
+{
+   const struct sprd_clk_common *common = >common;
+   unsigned int offset, reg;
+   int ret = 0;
+
+   if (WARN_ON(index >= pll->regs_num))
+   return;
+
+   offset = common->reg + index * 4;
+   ret = sprd_regmap_read(common->regmap, offset, );
+   if (!ret)
+   sprd_regmap_write(common->regmap, offset, (reg & ~msk) | val);
+}
+
+static unsigned long pll_get_refin(const struct sprd_pll *pll)
+{
+   u32 shift, mask, index, refin_id = 3;
+   const unsigned long refin[4] = { 2, 4, 13, 26 };
+
+   if (pwidth(pll, PLL_REFIN)) {
+   index = pindex(pll, PLL_REFIN);
+   shift = pshift(pll, PLL_REFIN);
+   mask = pmask(pll, PLL_REFIN);
+   refin_id = (sprd_pll_read(pll, index) & mask) >> shift;
+   if (refin_id > 3)
+   refin_id = 3;
+   }
+
+   return refin[refin_id];
+}
+
+static u32 pll_get_ibias(u64 rate, const u64 *table)
+{
+   u32 i, num = table[0];
+
+   for (i = 1; i < num + 1; i++)
+   if (rate <= table[i])
+   break;
+
+   return (i == num + 1) ? num : i;
+}
+
+static unsigned long _sprd_pll_recalc_rate(const struct sprd_pll *pll,
+  unsigned long parent_rate)
+{
+   u32 *cfg;
+   u32 i, mask, regs_num = pll->regs_num;
+   unsigned long rate, nint, kint = 0;
+   u64 refin;
+   u16 k1, k2;
+
+   cfg = kcalloc(regs_num, sizeof(*cfg), GFP_KERNEL);
+   if (!cfg)
+   return -ENOMEM;
+
+   for (i = 0; i < regs_num; i++)
+   cfg[i] = sprd_pll_read(pll, i);
+
+   refin = pll_get_refin(pll);
+
+   if (pinternal(pll, cfg, PLL_PREDIV))
+   refin = refin * 2;
+
+   if (pwidth(pll, PLL_POSTDIV) &&
+   ((pll->fflag == 1 && pinternal(pll, cfg, PLL_POSTDIV)) ||
+(!pll->fflag && !pinternal(pll, cfg, PLL_POSTDIV
+   refin = refin / 2;
+
+   if (!pinternal(pll, cfg, PLL_DIV_S)) {
+   rate = refin * pinternal_val(pll, cfg, PLL_N) * CLK_PLL_10M;
+   } else {
+   nint = pinternal_val(pll, cfg, PLL_NINT);
+   if (pinternal(pll, cfg, PLL_SDM_EN))
+   kint = pinternal_val(pll, cfg, PLL_KINT);
+
+   mask = pmask(pll, PLL_KINT);
+
+   k1 = pll->k1;
+   k2 = pll->k2;
+   rate = DIV_ROUND_CLOSEST_ULL(refin * kint * k1,
+((mask >> __ffs(mask)) + 1)) *
+

[PATCH V4 05/12] clk: sprd: add mux clock support

2017-11-09 Thread Chunyan Zhang
This patch adds clock multiplexor support for Spreadtrum platforms,
the mux clocks also can be found in sprd composite clocks, so
provides two helpers that can be reused later on.

Signed-off-by: Chunyan Zhang 
---
 drivers/clk/sprd/Makefile |  1 +
 drivers/clk/sprd/mux.c| 86 +++
 drivers/clk/sprd/mux.h| 78 ++
 3 files changed, 165 insertions(+)
 create mode 100644 drivers/clk/sprd/mux.c
 create mode 100644 drivers/clk/sprd/mux.h

diff --git a/drivers/clk/sprd/Makefile b/drivers/clk/sprd/Makefile
index 8cd5592..cee36b5 100644
--- a/drivers/clk/sprd/Makefile
+++ b/drivers/clk/sprd/Makefile
@@ -2,3 +2,4 @@ obj-$(CONFIG_SPRD_COMMON_CLK)   += clk-sprd.o
 
 clk-sprd-y += common.o
 clk-sprd-y += gate.o
+clk-sprd-y += mux.o
diff --git a/drivers/clk/sprd/mux.c b/drivers/clk/sprd/mux.c
new file mode 100644
index 000..dacb5b4
--- /dev/null
+++ b/drivers/clk/sprd/mux.c
@@ -0,0 +1,86 @@
+/*
+ * Spreadtrum multiplexer clock driver
+ *
+ * Copyright (C) 2017 Spreadtrum, Inc.
+ * Author: Chunyan Zhang 
+ *
+ * SPDX-License-Identifier: GPL-2.0
+ */
+
+#include 
+#include 
+#include 
+
+#include "mux.h"
+
+DEFINE_SPINLOCK(sprd_mux_lock);
+EXPORT_SYMBOL_GPL(sprd_mux_lock);
+
+u8 sprd_mux_helper_get_parent(const struct sprd_clk_common *common,
+ const struct sprd_mux_ssel *mux)
+{
+   unsigned int reg;
+   u8 parent;
+   int num_parents;
+   int i;
+
+   sprd_regmap_read(common->regmap, common->reg, );
+   parent = reg >> mux->shift;
+   parent &= (1 << mux->width) - 1;
+
+   if (!mux->table)
+   return parent;
+
+   num_parents = clk_hw_get_num_parents(>hw);
+
+   for (i = 0; i < num_parents - 1; i++)
+   if (parent >= mux->table[i] && parent < mux->table[i + 1])
+   return i;
+
+   return num_parents - 1;
+}
+EXPORT_SYMBOL_GPL(sprd_mux_helper_get_parent);
+
+static u8 sprd_mux_get_parent(struct clk_hw *hw)
+{
+   struct sprd_mux *cm = hw_to_sprd_mux(hw);
+
+   return sprd_mux_helper_get_parent(>common, >mux);
+}
+
+int sprd_mux_helper_set_parent(const struct sprd_clk_common *common,
+  const struct sprd_mux_ssel *mux,
+  u8 index)
+{
+   unsigned long flags = 0;
+   unsigned int reg;
+
+   if (mux->table)
+   index = mux->table[index];
+
+   spin_lock_irqsave(common->lock, flags);
+
+   sprd_regmap_read(common->regmap, common->reg, );
+   reg &= ~GENMASK(mux->width + mux->shift - 1, mux->shift);
+   sprd_regmap_write(common->regmap, common->reg,
+ reg | (index << mux->shift));
+
+   spin_unlock_irqrestore(common->lock, flags);
+
+   return 0;
+}
+EXPORT_SYMBOL_GPL(sprd_mux_helper_set_parent);
+
+static int sprd_mux_set_parent(struct clk_hw *hw, u8 index)
+{
+   struct sprd_mux *cm = hw_to_sprd_mux(hw);
+
+   return sprd_mux_helper_set_parent(>common, >mux, index);
+}
+
+const struct clk_ops sprd_mux_ops = {
+   .get_parent = sprd_mux_get_parent,
+   .set_parent = sprd_mux_set_parent,
+   .determine_rate = __clk_mux_determine_rate,
+};
+EXPORT_SYMBOL_GPL(sprd_mux_ops);
diff --git a/drivers/clk/sprd/mux.h b/drivers/clk/sprd/mux.h
new file mode 100644
index 000..72a3f78
--- /dev/null
+++ b/drivers/clk/sprd/mux.h
@@ -0,0 +1,78 @@
+/*
+ * Spreadtrum multiplexer clock driver
+ *
+ * Copyright (C) 2017 Spreadtrum, Inc.
+ * Author: Chunyan Zhang 
+ *
+ * SPDX-License-Identifier: GPL-2.0
+ */
+
+#ifndef _SPRD_MUX_H_
+#define _SPRD_MUX_H_
+
+#include "common.h"
+
+/**
+ * struct sprd_mux_ssel - Mux clock's source select bits in its register
+ * @shift: Bit offset of the divider in its register
+ * @width: Width of the divider field in its register
+ * @table: For some mux clocks, not all sources are used on some special
+ *chips, this matches the value of mux clock's register and the
+ *sources which are used for this mux clock
+ */
+struct sprd_mux_ssel {
+   u8  shift;
+   u8  width;
+   const u8*table;
+};
+
+struct sprd_mux {
+   struct sprd_mux_ssel mux;
+   struct sprd_clk_common  common;
+};
+
+#define _SPRD_MUX_CLK(_shift, _width, _table)  \
+   {   \
+   .shift  = _shift,   \
+   .width  = _width,   \
+   .table  = _table,   \
+   }
+
+#define SPRD_MUX_CLK_TABLE(_struct, _name, _parents, _table,   \
+_reg, _shift, _width,  \
+_flags)\
+   struct sprd_mux _struct = { \
+ 

[PATCH V4 05/12] clk: sprd: add mux clock support

2017-11-09 Thread Chunyan Zhang
This patch adds clock multiplexor support for Spreadtrum platforms,
the mux clocks also can be found in sprd composite clocks, so
provides two helpers that can be reused later on.

Signed-off-by: Chunyan Zhang 
---
 drivers/clk/sprd/Makefile |  1 +
 drivers/clk/sprd/mux.c| 86 +++
 drivers/clk/sprd/mux.h| 78 ++
 3 files changed, 165 insertions(+)
 create mode 100644 drivers/clk/sprd/mux.c
 create mode 100644 drivers/clk/sprd/mux.h

diff --git a/drivers/clk/sprd/Makefile b/drivers/clk/sprd/Makefile
index 8cd5592..cee36b5 100644
--- a/drivers/clk/sprd/Makefile
+++ b/drivers/clk/sprd/Makefile
@@ -2,3 +2,4 @@ obj-$(CONFIG_SPRD_COMMON_CLK)   += clk-sprd.o
 
 clk-sprd-y += common.o
 clk-sprd-y += gate.o
+clk-sprd-y += mux.o
diff --git a/drivers/clk/sprd/mux.c b/drivers/clk/sprd/mux.c
new file mode 100644
index 000..dacb5b4
--- /dev/null
+++ b/drivers/clk/sprd/mux.c
@@ -0,0 +1,86 @@
+/*
+ * Spreadtrum multiplexer clock driver
+ *
+ * Copyright (C) 2017 Spreadtrum, Inc.
+ * Author: Chunyan Zhang 
+ *
+ * SPDX-License-Identifier: GPL-2.0
+ */
+
+#include 
+#include 
+#include 
+
+#include "mux.h"
+
+DEFINE_SPINLOCK(sprd_mux_lock);
+EXPORT_SYMBOL_GPL(sprd_mux_lock);
+
+u8 sprd_mux_helper_get_parent(const struct sprd_clk_common *common,
+ const struct sprd_mux_ssel *mux)
+{
+   unsigned int reg;
+   u8 parent;
+   int num_parents;
+   int i;
+
+   sprd_regmap_read(common->regmap, common->reg, );
+   parent = reg >> mux->shift;
+   parent &= (1 << mux->width) - 1;
+
+   if (!mux->table)
+   return parent;
+
+   num_parents = clk_hw_get_num_parents(>hw);
+
+   for (i = 0; i < num_parents - 1; i++)
+   if (parent >= mux->table[i] && parent < mux->table[i + 1])
+   return i;
+
+   return num_parents - 1;
+}
+EXPORT_SYMBOL_GPL(sprd_mux_helper_get_parent);
+
+static u8 sprd_mux_get_parent(struct clk_hw *hw)
+{
+   struct sprd_mux *cm = hw_to_sprd_mux(hw);
+
+   return sprd_mux_helper_get_parent(>common, >mux);
+}
+
+int sprd_mux_helper_set_parent(const struct sprd_clk_common *common,
+  const struct sprd_mux_ssel *mux,
+  u8 index)
+{
+   unsigned long flags = 0;
+   unsigned int reg;
+
+   if (mux->table)
+   index = mux->table[index];
+
+   spin_lock_irqsave(common->lock, flags);
+
+   sprd_regmap_read(common->regmap, common->reg, );
+   reg &= ~GENMASK(mux->width + mux->shift - 1, mux->shift);
+   sprd_regmap_write(common->regmap, common->reg,
+ reg | (index << mux->shift));
+
+   spin_unlock_irqrestore(common->lock, flags);
+
+   return 0;
+}
+EXPORT_SYMBOL_GPL(sprd_mux_helper_set_parent);
+
+static int sprd_mux_set_parent(struct clk_hw *hw, u8 index)
+{
+   struct sprd_mux *cm = hw_to_sprd_mux(hw);
+
+   return sprd_mux_helper_set_parent(>common, >mux, index);
+}
+
+const struct clk_ops sprd_mux_ops = {
+   .get_parent = sprd_mux_get_parent,
+   .set_parent = sprd_mux_set_parent,
+   .determine_rate = __clk_mux_determine_rate,
+};
+EXPORT_SYMBOL_GPL(sprd_mux_ops);
diff --git a/drivers/clk/sprd/mux.h b/drivers/clk/sprd/mux.h
new file mode 100644
index 000..72a3f78
--- /dev/null
+++ b/drivers/clk/sprd/mux.h
@@ -0,0 +1,78 @@
+/*
+ * Spreadtrum multiplexer clock driver
+ *
+ * Copyright (C) 2017 Spreadtrum, Inc.
+ * Author: Chunyan Zhang 
+ *
+ * SPDX-License-Identifier: GPL-2.0
+ */
+
+#ifndef _SPRD_MUX_H_
+#define _SPRD_MUX_H_
+
+#include "common.h"
+
+/**
+ * struct sprd_mux_ssel - Mux clock's source select bits in its register
+ * @shift: Bit offset of the divider in its register
+ * @width: Width of the divider field in its register
+ * @table: For some mux clocks, not all sources are used on some special
+ *chips, this matches the value of mux clock's register and the
+ *sources which are used for this mux clock
+ */
+struct sprd_mux_ssel {
+   u8  shift;
+   u8  width;
+   const u8*table;
+};
+
+struct sprd_mux {
+   struct sprd_mux_ssel mux;
+   struct sprd_clk_common  common;
+};
+
+#define _SPRD_MUX_CLK(_shift, _width, _table)  \
+   {   \
+   .shift  = _shift,   \
+   .width  = _width,   \
+   .table  = _table,   \
+   }
+
+#define SPRD_MUX_CLK_TABLE(_struct, _name, _parents, _table,   \
+_reg, _shift, _width,  \
+_flags)\
+   struct sprd_mux _struct = { \
+   .mux= _SPRD_MUX_CLK(_shift, _width, _table),\
+   .common = {   

[PATCH V4 01/12] drivers: move clock common macros out from vendor directories

2017-11-09 Thread Chunyan Zhang
These macros are used by more than one SoC vendor platforms, avoid to
have many copies of these code, this patch moves them to the common
clock directory which every clock drivers can access to.

Signed-off-by: Chunyan Zhang 
---
This patchset also added a few common clock mactos into 
drivers/clk/clk_common.h,
which are generally useful for all vendors' clock driver, sunxi-ng, zte, sprd
(added in this patchse) use them (or part of them) at present, once this patch
is merged, I can help to remove the duplicated code which is under the vendors'
respective directories.
---
 drivers/clk/clk_common.h | 60 
 1 file changed, 60 insertions(+)
 create mode 100644 drivers/clk/clk_common.h

diff --git a/drivers/clk/clk_common.h b/drivers/clk/clk_common.h
new file mode 100644
index 000..21e93d2
--- /dev/null
+++ b/drivers/clk/clk_common.h
@@ -0,0 +1,60 @@
+/*
+ * drivers/clk/clk_common.h
+ *
+ * SPDX-License-Identifier: GPL-2.0
+ */
+
+#ifndef _CLK_COMMON_H_
+#define _CLK_COMMON_H_
+
+#include 
+
+#define CLK_HW_INIT(_name, _parent, _ops, _flags)  \
+   (&(struct clk_init_data) {  \
+   .flags  = _flags,   \
+   .name   = _name,\
+   .parent_names   = (const char *[]) { _parent }, \
+   .num_parents= 1,\
+   .ops= _ops, \
+   })
+
+#define CLK_HW_INIT_PARENTS(_name, _parents, _ops, _flags) \
+   (&(struct clk_init_data) {  \
+   .flags  = _flags,   \
+   .name   = _name,\
+   .parent_names   = _parents, \
+   .num_parents= ARRAY_SIZE(_parents), \
+   .ops= _ops, \
+   })
+
+#define CLK_HW_INIT_NO_PARENT(_name, _ops, _flags) \
+   (&(struct clk_init_data) {  \
+   .flags  = _flags,   \
+   .name   = _name,\
+   .parent_names   = NULL, \
+   .num_parents= 0,\
+   .ops= _ops, \
+   })
+
+#define CLK_FIXED_FACTOR(_struct, _name, _parent,  \
+   _div, _mult, _flags)\
+   struct clk_fixed_factor _struct = { \
+   .div= _div, \
+   .mult   = _mult,\
+   .hw.init= CLK_HW_INIT(_name,\
+ _parent,  \
+ _fixed_factor_ops,\
+ _flags),  \
+   }
+
+#define CLK_FIXED_RATE(_struct, _name, _flags, \
+  _fixed_rate, _fixed_accuracy)\
+   struct clk_fixed_rate _struct = {   \
+   .fixed_rate = _fixed_rate,  \
+   .fixed_accuracy = _fixed_accuracy,  \
+   .hw.init= CLK_HW_INIT_NO_PARENT(_name,  \
+ _fixed_rate_ops,  \
+   _flags),\
+   }
+
+#endif /* _CLK_COMMON_H_ */
-- 
2.7.4



[PATCH V4 04/12] clk: sprd: add gate clock support

2017-11-09 Thread Chunyan Zhang
Some clocks on the Spreadtrum's SoCs are just simple gates. Add
support for those clocks.

Signed-off-by: Chunyan Zhang 
---
 drivers/clk/sprd/Makefile |   1 +
 drivers/clk/sprd/gate.c   | 124 ++
 drivers/clk/sprd/gate.h   |  63 +++
 3 files changed, 188 insertions(+)
 create mode 100644 drivers/clk/sprd/gate.c
 create mode 100644 drivers/clk/sprd/gate.h

diff --git a/drivers/clk/sprd/Makefile b/drivers/clk/sprd/Makefile
index 74f4b80..8cd5592 100644
--- a/drivers/clk/sprd/Makefile
+++ b/drivers/clk/sprd/Makefile
@@ -1,3 +1,4 @@
 obj-$(CONFIG_SPRD_COMMON_CLK)  += clk-sprd.o
 
 clk-sprd-y += common.o
+clk-sprd-y += gate.o
diff --git a/drivers/clk/sprd/gate.c b/drivers/clk/sprd/gate.c
new file mode 100644
index 000..fa0d9ee
--- /dev/null
+++ b/drivers/clk/sprd/gate.c
@@ -0,0 +1,124 @@
+/*
+ * Spreadtrum gate clock driver
+ *
+ * Copyright (C) 2017 Spreadtrum, Inc.
+ * Author: Chunyan Zhang 
+ *
+ * SPDX-License-Identifier: GPL-2.0
+ */
+
+#include 
+#include 
+
+#include "gate.h"
+
+DEFINE_SPINLOCK(sprd_gate_lock);
+EXPORT_SYMBOL_GPL(sprd_gate_lock);
+
+static void clk_gate_toggle(const struct sprd_gate *sg, bool en)
+{
+   const struct sprd_clk_common *common = >common;
+   unsigned long flags = 0;
+   unsigned int reg;
+   bool set = sg->flags & CLK_GATE_SET_TO_DISABLE ? true : false;
+
+   set ^= en;
+
+   spin_lock_irqsave(common->lock, flags);
+
+   sprd_regmap_read(common->regmap, common->reg, );
+
+   if (set)
+   reg |= sg->enable_mask;
+   else
+   reg &= ~sg->enable_mask;
+
+   sprd_regmap_write(common->regmap, common->reg, reg);
+
+   spin_unlock_irqrestore(common->lock, flags);
+}
+
+static void clk_sc_gate_toggle(const struct sprd_gate *sg, bool en)
+{
+   const struct sprd_clk_common *common = >common;
+   unsigned long flags = 0;
+   bool set = sg->flags & CLK_GATE_SET_TO_DISABLE ? 1 : 0;
+   unsigned int offset;
+
+   set ^= en;
+
+   /*
+* Each set/clear gate clock has three registers:
+* common->reg  - base register
+* common->reg + offset - set register
+* common->reg + 2 * offset - clear register
+*/
+   offset = set ? sg->sc_offset : sg->sc_offset * 2;
+
+   spin_lock_irqsave(common->lock, flags);
+   sprd_regmap_write(common->regmap, common->reg + offset,
+ sg->enable_mask);
+   spin_unlock_irqrestore(common->lock, flags);
+}
+
+static void sprd_gate_disable(struct clk_hw *hw)
+{
+   struct sprd_gate *sg = hw_to_sprd_gate(hw);
+
+   clk_gate_toggle(sg, false);
+}
+
+static int sprd_gate_enable(struct clk_hw *hw)
+{
+   struct sprd_gate *sg = hw_to_sprd_gate(hw);
+
+   clk_gate_toggle(sg, true);
+
+   return 0;
+}
+
+static void sprd_sc_gate_disable(struct clk_hw *hw)
+{
+   struct sprd_gate *sg = hw_to_sprd_gate(hw);
+
+   clk_sc_gate_toggle(sg, false);
+}
+
+static int sprd_sc_gate_enable(struct clk_hw *hw)
+{
+   struct sprd_gate *sg = hw_to_sprd_gate(hw);
+
+   clk_sc_gate_toggle(sg, true);
+
+   return 0;
+}
+static int sprd_gate_is_enabled(struct clk_hw *hw)
+{
+   struct sprd_gate *sg = hw_to_sprd_gate(hw);
+   struct sprd_clk_common *common = >common;
+   unsigned int reg;
+
+   sprd_regmap_read(common->regmap, common->reg, );
+
+   if (sg->flags & CLK_GATE_SET_TO_DISABLE)
+   reg ^= sg->enable_mask;
+
+   reg &= sg->enable_mask;
+
+   return reg ? 1 : 0;
+}
+
+const struct clk_ops sprd_gate_ops = {
+   .disable= sprd_gate_disable,
+   .enable = sprd_gate_enable,
+   .is_enabled = sprd_gate_is_enabled,
+};
+EXPORT_SYMBOL_GPL(sprd_gate_ops);
+
+const struct clk_ops sprd_sc_gate_ops = {
+   .disable= sprd_sc_gate_disable,
+   .enable = sprd_sc_gate_enable,
+   .is_enabled = sprd_gate_is_enabled,
+};
+EXPORT_SYMBOL_GPL(sprd_sc_gate_ops);
+
diff --git a/drivers/clk/sprd/gate.h b/drivers/clk/sprd/gate.h
new file mode 100644
index 000..dad8ba0
--- /dev/null
+++ b/drivers/clk/sprd/gate.h
@@ -0,0 +1,63 @@
+/*
+ * Spreadtrum gate clock driver
+ *
+ * Copyright (C) 2017 Spreadtrum, Inc.
+ * Author: Chunyan Zhang 
+ *
+ * SPDX-License-Identifier: GPL-2.0
+ */
+
+#ifndef _SPRD_GATE_H_
+#define _SPRD_GATE_H_
+
+#include "common.h"
+
+struct sprd_gate {
+   u32 enable_mask;
+   u16 flags;
+   u16 sc_offset;
+
+   struct sprd_clk_common  common;
+};
+
+#define SPRD_SC_GATE_CLK_OPS(_struct, _name, _parent, _reg, _sc_offset,
\
+_enable_mask, _flags, _gate_flags, _ops)   \
+   struct sprd_gate _struct = {\
+   .enable_mask= 

[PATCH V4 01/12] drivers: move clock common macros out from vendor directories

2017-11-09 Thread Chunyan Zhang
These macros are used by more than one SoC vendor platforms, avoid to
have many copies of these code, this patch moves them to the common
clock directory which every clock drivers can access to.

Signed-off-by: Chunyan Zhang 
---
This patchset also added a few common clock mactos into 
drivers/clk/clk_common.h,
which are generally useful for all vendors' clock driver, sunxi-ng, zte, sprd
(added in this patchse) use them (or part of them) at present, once this patch
is merged, I can help to remove the duplicated code which is under the vendors'
respective directories.
---
 drivers/clk/clk_common.h | 60 
 1 file changed, 60 insertions(+)
 create mode 100644 drivers/clk/clk_common.h

diff --git a/drivers/clk/clk_common.h b/drivers/clk/clk_common.h
new file mode 100644
index 000..21e93d2
--- /dev/null
+++ b/drivers/clk/clk_common.h
@@ -0,0 +1,60 @@
+/*
+ * drivers/clk/clk_common.h
+ *
+ * SPDX-License-Identifier: GPL-2.0
+ */
+
+#ifndef _CLK_COMMON_H_
+#define _CLK_COMMON_H_
+
+#include 
+
+#define CLK_HW_INIT(_name, _parent, _ops, _flags)  \
+   (&(struct clk_init_data) {  \
+   .flags  = _flags,   \
+   .name   = _name,\
+   .parent_names   = (const char *[]) { _parent }, \
+   .num_parents= 1,\
+   .ops= _ops, \
+   })
+
+#define CLK_HW_INIT_PARENTS(_name, _parents, _ops, _flags) \
+   (&(struct clk_init_data) {  \
+   .flags  = _flags,   \
+   .name   = _name,\
+   .parent_names   = _parents, \
+   .num_parents= ARRAY_SIZE(_parents), \
+   .ops= _ops, \
+   })
+
+#define CLK_HW_INIT_NO_PARENT(_name, _ops, _flags) \
+   (&(struct clk_init_data) {  \
+   .flags  = _flags,   \
+   .name   = _name,\
+   .parent_names   = NULL, \
+   .num_parents= 0,\
+   .ops= _ops, \
+   })
+
+#define CLK_FIXED_FACTOR(_struct, _name, _parent,  \
+   _div, _mult, _flags)\
+   struct clk_fixed_factor _struct = { \
+   .div= _div, \
+   .mult   = _mult,\
+   .hw.init= CLK_HW_INIT(_name,\
+ _parent,  \
+ _fixed_factor_ops,\
+ _flags),  \
+   }
+
+#define CLK_FIXED_RATE(_struct, _name, _flags, \
+  _fixed_rate, _fixed_accuracy)\
+   struct clk_fixed_rate _struct = {   \
+   .fixed_rate = _fixed_rate,  \
+   .fixed_accuracy = _fixed_accuracy,  \
+   .hw.init= CLK_HW_INIT_NO_PARENT(_name,  \
+ _fixed_rate_ops,  \
+   _flags),\
+   }
+
+#endif /* _CLK_COMMON_H_ */
-- 
2.7.4



[PATCH V4 04/12] clk: sprd: add gate clock support

2017-11-09 Thread Chunyan Zhang
Some clocks on the Spreadtrum's SoCs are just simple gates. Add
support for those clocks.

Signed-off-by: Chunyan Zhang 
---
 drivers/clk/sprd/Makefile |   1 +
 drivers/clk/sprd/gate.c   | 124 ++
 drivers/clk/sprd/gate.h   |  63 +++
 3 files changed, 188 insertions(+)
 create mode 100644 drivers/clk/sprd/gate.c
 create mode 100644 drivers/clk/sprd/gate.h

diff --git a/drivers/clk/sprd/Makefile b/drivers/clk/sprd/Makefile
index 74f4b80..8cd5592 100644
--- a/drivers/clk/sprd/Makefile
+++ b/drivers/clk/sprd/Makefile
@@ -1,3 +1,4 @@
 obj-$(CONFIG_SPRD_COMMON_CLK)  += clk-sprd.o
 
 clk-sprd-y += common.o
+clk-sprd-y += gate.o
diff --git a/drivers/clk/sprd/gate.c b/drivers/clk/sprd/gate.c
new file mode 100644
index 000..fa0d9ee
--- /dev/null
+++ b/drivers/clk/sprd/gate.c
@@ -0,0 +1,124 @@
+/*
+ * Spreadtrum gate clock driver
+ *
+ * Copyright (C) 2017 Spreadtrum, Inc.
+ * Author: Chunyan Zhang 
+ *
+ * SPDX-License-Identifier: GPL-2.0
+ */
+
+#include 
+#include 
+
+#include "gate.h"
+
+DEFINE_SPINLOCK(sprd_gate_lock);
+EXPORT_SYMBOL_GPL(sprd_gate_lock);
+
+static void clk_gate_toggle(const struct sprd_gate *sg, bool en)
+{
+   const struct sprd_clk_common *common = >common;
+   unsigned long flags = 0;
+   unsigned int reg;
+   bool set = sg->flags & CLK_GATE_SET_TO_DISABLE ? true : false;
+
+   set ^= en;
+
+   spin_lock_irqsave(common->lock, flags);
+
+   sprd_regmap_read(common->regmap, common->reg, );
+
+   if (set)
+   reg |= sg->enable_mask;
+   else
+   reg &= ~sg->enable_mask;
+
+   sprd_regmap_write(common->regmap, common->reg, reg);
+
+   spin_unlock_irqrestore(common->lock, flags);
+}
+
+static void clk_sc_gate_toggle(const struct sprd_gate *sg, bool en)
+{
+   const struct sprd_clk_common *common = >common;
+   unsigned long flags = 0;
+   bool set = sg->flags & CLK_GATE_SET_TO_DISABLE ? 1 : 0;
+   unsigned int offset;
+
+   set ^= en;
+
+   /*
+* Each set/clear gate clock has three registers:
+* common->reg  - base register
+* common->reg + offset - set register
+* common->reg + 2 * offset - clear register
+*/
+   offset = set ? sg->sc_offset : sg->sc_offset * 2;
+
+   spin_lock_irqsave(common->lock, flags);
+   sprd_regmap_write(common->regmap, common->reg + offset,
+ sg->enable_mask);
+   spin_unlock_irqrestore(common->lock, flags);
+}
+
+static void sprd_gate_disable(struct clk_hw *hw)
+{
+   struct sprd_gate *sg = hw_to_sprd_gate(hw);
+
+   clk_gate_toggle(sg, false);
+}
+
+static int sprd_gate_enable(struct clk_hw *hw)
+{
+   struct sprd_gate *sg = hw_to_sprd_gate(hw);
+
+   clk_gate_toggle(sg, true);
+
+   return 0;
+}
+
+static void sprd_sc_gate_disable(struct clk_hw *hw)
+{
+   struct sprd_gate *sg = hw_to_sprd_gate(hw);
+
+   clk_sc_gate_toggle(sg, false);
+}
+
+static int sprd_sc_gate_enable(struct clk_hw *hw)
+{
+   struct sprd_gate *sg = hw_to_sprd_gate(hw);
+
+   clk_sc_gate_toggle(sg, true);
+
+   return 0;
+}
+static int sprd_gate_is_enabled(struct clk_hw *hw)
+{
+   struct sprd_gate *sg = hw_to_sprd_gate(hw);
+   struct sprd_clk_common *common = >common;
+   unsigned int reg;
+
+   sprd_regmap_read(common->regmap, common->reg, );
+
+   if (sg->flags & CLK_GATE_SET_TO_DISABLE)
+   reg ^= sg->enable_mask;
+
+   reg &= sg->enable_mask;
+
+   return reg ? 1 : 0;
+}
+
+const struct clk_ops sprd_gate_ops = {
+   .disable= sprd_gate_disable,
+   .enable = sprd_gate_enable,
+   .is_enabled = sprd_gate_is_enabled,
+};
+EXPORT_SYMBOL_GPL(sprd_gate_ops);
+
+const struct clk_ops sprd_sc_gate_ops = {
+   .disable= sprd_sc_gate_disable,
+   .enable = sprd_sc_gate_enable,
+   .is_enabled = sprd_gate_is_enabled,
+};
+EXPORT_SYMBOL_GPL(sprd_sc_gate_ops);
+
diff --git a/drivers/clk/sprd/gate.h b/drivers/clk/sprd/gate.h
new file mode 100644
index 000..dad8ba0
--- /dev/null
+++ b/drivers/clk/sprd/gate.h
@@ -0,0 +1,63 @@
+/*
+ * Spreadtrum gate clock driver
+ *
+ * Copyright (C) 2017 Spreadtrum, Inc.
+ * Author: Chunyan Zhang 
+ *
+ * SPDX-License-Identifier: GPL-2.0
+ */
+
+#ifndef _SPRD_GATE_H_
+#define _SPRD_GATE_H_
+
+#include "common.h"
+
+struct sprd_gate {
+   u32 enable_mask;
+   u16 flags;
+   u16 sc_offset;
+
+   struct sprd_clk_common  common;
+};
+
+#define SPRD_SC_GATE_CLK_OPS(_struct, _name, _parent, _reg, _sc_offset,
\
+_enable_mask, _flags, _gate_flags, _ops)   \
+   struct sprd_gate _struct = {\
+   .enable_mask= _enable_mask, \
+   .sc_offset  = _sc_offset, 

Re: n900 in next-20170901

2017-11-09 Thread Joonsoo Kim
On Thu, Nov 09, 2017 at 10:23:40PM -0800, Tony Lindgren wrote:
> * Tony Lindgren  [171109 22:19]:
> > * Tony Lindgren  [171110 03:28]:
> > > Then I'll follow up on cleaning up save_secure_ram_context later.
> > 
> > Here's a better version, the static mapping did not get used.. It
> > just moved the area so it happened to work. It needs to be set
> > up as MT_MEMORY_RWX_NONCACHED instead.
> 

I see a better version now. Hmm... I guess that it also has the
problem that I mentioned on first version.

> And FYI, here's what I currently have for the follow-up patch,
> but that can wait a bit.

Okay. So, this patch should be applied on the top of above better version?

Thanks.



[PATCH V4 00/12] add clock driver for Spreadtrum platforms

2017-11-09 Thread Chunyan Zhang
This series adds Spreadtrum clock support together with its binding
documentation and devicetree data.

Any comments would be greatly appreciated.

This patchset also added a few common clock mactos into 
drivers/clk/clk_common.h,
which are generally useful for all vendors' clock driver, sunxi-ng, zte, sprd
(added in this patchse) use them (or part of them) at present, once this 
patchset
is merged, I can help to remove the duplicated code which is under the vendors'
respective directories.


Thanks,
Chunyan

Changes from V3: (https://lkml.org/lkml/2017/11/2/61)
* Addressed comments from Julien Thierry:
  - Clean the if branch of sprd_mux_helper_get_parent()
  - Have the Gate clock macros and ops for both mode (i.e. sc_gate and gate) 
separate;
  - Have the Mux clock macros with/without table separate, and same changes
for the composite clock.
* Switched the function name from _endisable to _toggle;
* Fixed Kbuild test error:
  - Added exporting sprd_clk_regmap_init() which would be used in other 
module(s);
* Change the function sprd_clk_set_regmap() to the static one, and removed the
  declear from the include file;
* Addressed comments from Rob:
  - Separate the dt-binding include file from the driver patch;
  - Documented more for the property "clocks"
* Changed the syscon device names;
* Changed the name of 'sprd_mux_internal' to 'sprd_mux_ssel'
  

Changes from V2: (http://lkml.iu.edu/hypermail/linux/kernel/1707.1/01504.html)
* Switch to use regmap to access registers;
* Splited all clocks into 16 separated nodes, for each belongs to a single 
address area; 
* Rearranged the order of clock declaration in sc9860-clk.c, sorted them upon 
the address area;
* Added syscon device tree nodes which will be quoted by the node of clocks 
which are in
  the same address area with the syscon device;
* Revised the binding documentation according to the dt modification. 

Changes from V1: (https://lkml.org/lkml/2017/6/17/356)
* Address Stephen's comments:
  - Switch to use platform device driver instead of the DT probing mechanism.
  - Move the common clock macro out from vendor directory, but need to remove 
those
overlap code from other vendors (such as sunxi-ng) once this get merged.
  - Add support to be built as a module.
  - Add 'sprd_' prefix for all spin locks used in these drivers.
  - Mark input parameter of sprd_x with const.
  - Remove unreasonable dependencies to CONFIG_64BIT.
  - Add readl() after writing the same register.
  - Remove CLK_IS_BASIC which is no longer used.
  - Remove unnecessery CLK_IGNORE_UNUSED when defining a clock.
  - Change to expose all clock index.
  - Use clk_ instead of ccu.
  - Add Kconfig for sprd clocks.
  - Move the fixed clocks out from the soc node.
  - Switch to use 64-bit math in pll driver instead of 32-bit math.
* Revise binding documentation according to dt modification.
* Rename sc9860.c to sc9860-clk.c


Chunyan Zhang (12):
  drivers: move clock common macros out from vendor directories
  dt-bindings: Add Spreadtrum clock binding documentation
  clk: sprd: Add common infrastructure
  clk: sprd: add gate clock support
  clk: sprd: add mux clock support
  clk: sprd: add divider clock support
  clk: sprd: add composite clock support
  clk: sprd: add adjustable pll support
  clk: sprd: Add dt-bindings include file for SC9860
  clk: sprd: add clocks support for SC9860
  arm64: dts: add syscon for whale2 platform
  arm64: dts: add clocks for SC9860

 Documentation/devicetree/bindings/clock/sprd.txt |   63 +
 arch/arm64/boot/dts/sprd/sc9860.dtsi |  115 ++
 arch/arm64/boot/dts/sprd/whale2.dtsi |   48 +-
 drivers/clk/Kconfig  |1 +
 drivers/clk/Makefile |1 +
 drivers/clk/clk_common.h |   60 +
 drivers/clk/sprd/Kconfig |   14 +
 drivers/clk/sprd/Makefile|   11 +
 drivers/clk/sprd/common.c|  113 ++
 drivers/clk/sprd/common.h|   54 +
 drivers/clk/sprd/composite.c |   65 +
 drivers/clk/sprd/composite.h |   55 +
 drivers/clk/sprd/div.c   |  100 ++
 drivers/clk/sprd/div.h   |   79 +
 drivers/clk/sprd/gate.c  |  124 ++
 drivers/clk/sprd/gate.h  |   63 +
 drivers/clk/sprd/mux.c   |   86 +
 drivers/clk/sprd/mux.h   |   78 +
 drivers/clk/sprd/pll.c   |  268 +++
 drivers/clk/sprd/pll.h   |  110 ++
 drivers/clk/sprd/sc9860-clk.c| 1987 ++
 include/dt-bindings/clock/sprd,sc9860-clk.h  |  408 +
 22 files changed, 3901 insertions(+), 2 deletions(-)
 create mode 100644 Documentation/devicetree/bindings/clock/sprd.txt
 create mode 100644 drivers/clk/clk_common.h
 create mode 100644 

Re: n900 in next-20170901

2017-11-09 Thread Joonsoo Kim
On Thu, Nov 09, 2017 at 10:23:40PM -0800, Tony Lindgren wrote:
> * Tony Lindgren  [171109 22:19]:
> > * Tony Lindgren  [171110 03:28]:
> > > Then I'll follow up on cleaning up save_secure_ram_context later.
> > 
> > Here's a better version, the static mapping did not get used.. It
> > just moved the area so it happened to work. It needs to be set
> > up as MT_MEMORY_RWX_NONCACHED instead.
> 

I see a better version now. Hmm... I guess that it also has the
problem that I mentioned on first version.

> And FYI, here's what I currently have for the follow-up patch,
> but that can wait a bit.

Okay. So, this patch should be applied on the top of above better version?

Thanks.



[PATCH V4 00/12] add clock driver for Spreadtrum platforms

2017-11-09 Thread Chunyan Zhang
This series adds Spreadtrum clock support together with its binding
documentation and devicetree data.

Any comments would be greatly appreciated.

This patchset also added a few common clock mactos into 
drivers/clk/clk_common.h,
which are generally useful for all vendors' clock driver, sunxi-ng, zte, sprd
(added in this patchse) use them (or part of them) at present, once this 
patchset
is merged, I can help to remove the duplicated code which is under the vendors'
respective directories.


Thanks,
Chunyan

Changes from V3: (https://lkml.org/lkml/2017/11/2/61)
* Addressed comments from Julien Thierry:
  - Clean the if branch of sprd_mux_helper_get_parent()
  - Have the Gate clock macros and ops for both mode (i.e. sc_gate and gate) 
separate;
  - Have the Mux clock macros with/without table separate, and same changes
for the composite clock.
* Switched the function name from _endisable to _toggle;
* Fixed Kbuild test error:
  - Added exporting sprd_clk_regmap_init() which would be used in other 
module(s);
* Change the function sprd_clk_set_regmap() to the static one, and removed the
  declear from the include file;
* Addressed comments from Rob:
  - Separate the dt-binding include file from the driver patch;
  - Documented more for the property "clocks"
* Changed the syscon device names;
* Changed the name of 'sprd_mux_internal' to 'sprd_mux_ssel'
  

Changes from V2: (http://lkml.iu.edu/hypermail/linux/kernel/1707.1/01504.html)
* Switch to use regmap to access registers;
* Splited all clocks into 16 separated nodes, for each belongs to a single 
address area; 
* Rearranged the order of clock declaration in sc9860-clk.c, sorted them upon 
the address area;
* Added syscon device tree nodes which will be quoted by the node of clocks 
which are in
  the same address area with the syscon device;
* Revised the binding documentation according to the dt modification. 

Changes from V1: (https://lkml.org/lkml/2017/6/17/356)
* Address Stephen's comments:
  - Switch to use platform device driver instead of the DT probing mechanism.
  - Move the common clock macro out from vendor directory, but need to remove 
those
overlap code from other vendors (such as sunxi-ng) once this get merged.
  - Add support to be built as a module.
  - Add 'sprd_' prefix for all spin locks used in these drivers.
  - Mark input parameter of sprd_x with const.
  - Remove unreasonable dependencies to CONFIG_64BIT.
  - Add readl() after writing the same register.
  - Remove CLK_IS_BASIC which is no longer used.
  - Remove unnecessery CLK_IGNORE_UNUSED when defining a clock.
  - Change to expose all clock index.
  - Use clk_ instead of ccu.
  - Add Kconfig for sprd clocks.
  - Move the fixed clocks out from the soc node.
  - Switch to use 64-bit math in pll driver instead of 32-bit math.
* Revise binding documentation according to dt modification.
* Rename sc9860.c to sc9860-clk.c


Chunyan Zhang (12):
  drivers: move clock common macros out from vendor directories
  dt-bindings: Add Spreadtrum clock binding documentation
  clk: sprd: Add common infrastructure
  clk: sprd: add gate clock support
  clk: sprd: add mux clock support
  clk: sprd: add divider clock support
  clk: sprd: add composite clock support
  clk: sprd: add adjustable pll support
  clk: sprd: Add dt-bindings include file for SC9860
  clk: sprd: add clocks support for SC9860
  arm64: dts: add syscon for whale2 platform
  arm64: dts: add clocks for SC9860

 Documentation/devicetree/bindings/clock/sprd.txt |   63 +
 arch/arm64/boot/dts/sprd/sc9860.dtsi |  115 ++
 arch/arm64/boot/dts/sprd/whale2.dtsi |   48 +-
 drivers/clk/Kconfig  |1 +
 drivers/clk/Makefile |1 +
 drivers/clk/clk_common.h |   60 +
 drivers/clk/sprd/Kconfig |   14 +
 drivers/clk/sprd/Makefile|   11 +
 drivers/clk/sprd/common.c|  113 ++
 drivers/clk/sprd/common.h|   54 +
 drivers/clk/sprd/composite.c |   65 +
 drivers/clk/sprd/composite.h |   55 +
 drivers/clk/sprd/div.c   |  100 ++
 drivers/clk/sprd/div.h   |   79 +
 drivers/clk/sprd/gate.c  |  124 ++
 drivers/clk/sprd/gate.h  |   63 +
 drivers/clk/sprd/mux.c   |   86 +
 drivers/clk/sprd/mux.h   |   78 +
 drivers/clk/sprd/pll.c   |  268 +++
 drivers/clk/sprd/pll.h   |  110 ++
 drivers/clk/sprd/sc9860-clk.c| 1987 ++
 include/dt-bindings/clock/sprd,sc9860-clk.h  |  408 +
 22 files changed, 3901 insertions(+), 2 deletions(-)
 create mode 100644 Documentation/devicetree/bindings/clock/sprd.txt
 create mode 100644 drivers/clk/clk_common.h
 create mode 100644 

Re: [PATCH] x86, pkeys: update documentation about availability

2017-11-09 Thread Dave Hansen
On 11/09/2017 10:12 PM, Ingo Molnar wrote:
> 
> * Dave Hansen  wrote:
> 
>>
>> From: Dave Hansen 
>>
>> Now that CPUs that implement Memory Protection Keys are publicly
>> available we can be a bit less oblique about where it is available.
>>
>> Signed-off-by: Dave Hansen 
>> ---
>>
>>  b/Documentation/x86/protection-keys.txt |9 +++--
>>  1 file changed, 7 insertions(+), 2 deletions(-)
>>
>> diff -puN Documentation/x86/protection-keys.txt~pkeys-update 
>> Documentation/x86/protection-keys.txt
>> --- a/Documentation/x86/protection-keys.txt~pkeys-update 2017-11-09 
>> 10:36:53.381467202 -0800
>> +++ b/Documentation/x86/protection-keys.txt  2017-11-09 10:43:15.527466249 
>> -0800
>> @@ -1,5 +1,10 @@
>> -Memory Protection Keys for Userspace (PKU aka PKEYs) is a CPU feature
>> -which will be found on future Intel CPUs.
>> +Memory Protection Keys for Userspace (PKU aka PKEYs) is a feature
>> +which is found on Intel's Skylake "Scalable Processor" Server CPUs.
>> +It will be avalable in future non-server parts.
>> +
>> +For anyone wishing to test or use this feature, it is available in
>> +Amazon's EC2 C5 instances and is known to work there using an Ubuntu
>> +17.04 image.
>>  
>>  Memory Protection Keys provides a mechanism for enforcing page-based
>>  protections, but without requiring modification of the page tables
> 
> Could we please first fix the pkeys self-test? One of the testcases doesn't 
> build 
> at all:
> 
>  gcc -m32 -o /home/mingo/tip/tools/testing/selftests/x86/protection_keys_32 
> -O2 -g -std=gnu99 -pthread -Wall -no-pie  protection_keys.c -lrt -ldl -lm
>  In file included from /usr/include/signal.h:57:0,
>   from protection_keys.c:33:
>  protection_keys.c: In function ‘signal_handler’:
>  protection_keys.c:253:6: error: expected ‘=’, ‘,’, ‘;’, ‘asm’ or 
> ‘__attribute__’ 
>  before ‘.’ token
>u64 si_pkey;

That's odd.  I build them all the time.  I compiled it just now with
4.14-rc8 and gcc 4.8.4.

I wonder if this is more fallout from the glibc headers getting updated
to now contain pkey-related stuff.  si_pkey might be getting #defined
over for the siginfo si_pkey.

What distro are you seeing this on?

> plus, on a related note, the MPX testcase produces annoying warnings:
> 
>  gcc -m32 -o /home/mingo/tip/tools/testing/selftests/x86/mpx-mini-test_32 -O2 
> -g -std=gnu99 -pthread -Wall -no-pie  mpx-mini-test.c -lrt -ldl -lm
>  mpx-mini-test.c: In function ‘insn_test_failed’:
>  mpx-mini-test.c:1406:3: warning: array subscript is above array bounds 
>  [-Warray-bounds]
> printf("bte[1]: %lx\n", bte->contents[1]);

This is kinda a weird structure:

> struct mpx_bt_entry {
> union {
> char x[MPX_BOUNDS_TABLE_ENTRY_SIZE_BYTES];
> unsigned long contents[1];
> };
> } __attribute__((packed));

I guess it should either be contents[0] or
contents[MPX_BOUNDS_TABLE_ENTRY_SIZE_BYTE/sizeof(long)].  But, the
warning is harmless at least.

What gcc is this, btw?  I must be behind the times.


Re: [PATCH] x86, pkeys: update documentation about availability

2017-11-09 Thread Dave Hansen
On 11/09/2017 10:12 PM, Ingo Molnar wrote:
> 
> * Dave Hansen  wrote:
> 
>>
>> From: Dave Hansen 
>>
>> Now that CPUs that implement Memory Protection Keys are publicly
>> available we can be a bit less oblique about where it is available.
>>
>> Signed-off-by: Dave Hansen 
>> ---
>>
>>  b/Documentation/x86/protection-keys.txt |9 +++--
>>  1 file changed, 7 insertions(+), 2 deletions(-)
>>
>> diff -puN Documentation/x86/protection-keys.txt~pkeys-update 
>> Documentation/x86/protection-keys.txt
>> --- a/Documentation/x86/protection-keys.txt~pkeys-update 2017-11-09 
>> 10:36:53.381467202 -0800
>> +++ b/Documentation/x86/protection-keys.txt  2017-11-09 10:43:15.527466249 
>> -0800
>> @@ -1,5 +1,10 @@
>> -Memory Protection Keys for Userspace (PKU aka PKEYs) is a CPU feature
>> -which will be found on future Intel CPUs.
>> +Memory Protection Keys for Userspace (PKU aka PKEYs) is a feature
>> +which is found on Intel's Skylake "Scalable Processor" Server CPUs.
>> +It will be avalable in future non-server parts.
>> +
>> +For anyone wishing to test or use this feature, it is available in
>> +Amazon's EC2 C5 instances and is known to work there using an Ubuntu
>> +17.04 image.
>>  
>>  Memory Protection Keys provides a mechanism for enforcing page-based
>>  protections, but without requiring modification of the page tables
> 
> Could we please first fix the pkeys self-test? One of the testcases doesn't 
> build 
> at all:
> 
>  gcc -m32 -o /home/mingo/tip/tools/testing/selftests/x86/protection_keys_32 
> -O2 -g -std=gnu99 -pthread -Wall -no-pie  protection_keys.c -lrt -ldl -lm
>  In file included from /usr/include/signal.h:57:0,
>   from protection_keys.c:33:
>  protection_keys.c: In function ‘signal_handler’:
>  protection_keys.c:253:6: error: expected ‘=’, ‘,’, ‘;’, ‘asm’ or 
> ‘__attribute__’ 
>  before ‘.’ token
>u64 si_pkey;

That's odd.  I build them all the time.  I compiled it just now with
4.14-rc8 and gcc 4.8.4.

I wonder if this is more fallout from the glibc headers getting updated
to now contain pkey-related stuff.  si_pkey might be getting #defined
over for the siginfo si_pkey.

What distro are you seeing this on?

> plus, on a related note, the MPX testcase produces annoying warnings:
> 
>  gcc -m32 -o /home/mingo/tip/tools/testing/selftests/x86/mpx-mini-test_32 -O2 
> -g -std=gnu99 -pthread -Wall -no-pie  mpx-mini-test.c -lrt -ldl -lm
>  mpx-mini-test.c: In function ‘insn_test_failed’:
>  mpx-mini-test.c:1406:3: warning: array subscript is above array bounds 
>  [-Warray-bounds]
> printf("bte[1]: %lx\n", bte->contents[1]);

This is kinda a weird structure:

> struct mpx_bt_entry {
> union {
> char x[MPX_BOUNDS_TABLE_ENTRY_SIZE_BYTES];
> unsigned long contents[1];
> };
> } __attribute__((packed));

I guess it should either be contents[0] or
contents[MPX_BOUNDS_TABLE_ENTRY_SIZE_BYTE/sizeof(long)].  But, the
warning is harmless at least.

What gcc is this, btw?  I must be behind the times.


Re: [PATCH] checkpatch: Fix checks for Kconfig help text

2017-11-09 Thread Leo Yan
On Fri, Nov 10, 2017 at 02:32:37PM +0800, Leo Yan wrote:
> If one patch has Kconfig section with only one 'config', then variable
> '$is_start' will be set by first 'config' line and '$is_end' set by the
> second 'config' line. But patches often has only one 'config' line so
> we have no chance to set '$is_end', as result below condition is invalid
> and it skips check for Kconfig description:

Sorry for the bad commit log, I will send v2 for this.

>   if ($is_start && $is_end && $length < $min_conf_desc_length) {
>   ..
>   }
> 
> When script runs to this condition sentence it means the Kconfig
> section parsing has been completed, whatever '$is_end' is true
> or not. So removes '$is_end' from condition sentence.
> 
> Another change is to change '$min_conf_desc_length' from 4 to 1; so can
> pass the check if the Kconfig description has at least one line.
> 
> Signed-off-by: Leo Yan 
> ---
>  scripts/checkpatch.pl | 4 ++--
>  1 file changed, 2 insertions(+), 2 deletions(-)
> 
> diff --git a/scripts/checkpatch.pl b/scripts/checkpatch.pl
> index 3453df9..ba724b0 100755
> --- a/scripts/checkpatch.pl
> +++ b/scripts/checkpatch.pl
> @@ -51,7 +51,7 @@ my $configuration_file = ".checkpatch.conf";
>  my $max_line_length = 80;
>  my $ignore_perl_version = 0;
>  my $minimum_perl_version = 5.10.0;
> -my $min_conf_desc_length = 4;
> +my $min_conf_desc_length = 1;
>  my $spelling_file = "$D/spelling.txt";
>  my $codespell = 0;
>  my $codespellfile = "/usr/share/codespell/dictionary.txt";
> @@ -2796,7 +2796,7 @@ sub process {
>   }
>   $length++;
>   }
> - if ($is_start && $is_end && $length < 
> $min_conf_desc_length) {
> + if ($is_start && $length < $min_conf_desc_length) {
>   WARN("CONFIG_DESCRIPTION",
>"please write a paragraph that describes 
> the config symbol fully\n" . $herecurr);
>   }
> -- 
> 2.7.4
> 


[tip:x86/urgent] x86/debug: Handle warnings before the notifier chain, to fix KGDB crash

2017-11-09 Thread tip-bot for Alexander Shishkin
Commit-ID:  a8d6c1bd62ffefb075c9d3570f07659e2a36ecb3
Gitweb: https://git.kernel.org/tip/a8d6c1bd62ffefb075c9d3570f07659e2a36ecb3
Author: Alexander Shishkin 
AuthorDate: Mon, 24 Jul 2017 13:04:28 +0300
Committer:  Ingo Molnar 
CommitDate: Fri, 10 Nov 2017 07:16:23 +0100

x86/debug: Handle warnings before the notifier chain, to fix KGDB crash

Commit:

  9a93848fe787 ("x86/debug: Implement __WARN() using UD0")

turned warnings into UD0, but the fixup code only runs after the
notify_die() chain. This is a problem, in particular, with kgdb,
which kicks in as if it was a BUG().

Fix this by running the fixup code before the notifier chain in
the invalid op handler path.

Signed-off-by: Alexander Shishkin 
Tested-by: Ilya Dryomov 
Acked-by: Daniel Thompson 
Cc: Jason Wessel 
Cc: Arjan van de Ven 
Cc: Borislav Petkov 
Cc: Linus Torvalds 
Cc: Peter Zijlstra 
Cc: Richard Weinberger 
Cc: Thomas Gleixner 
Cc:  # v4.12+
Link: 
http://lkml.kernel.org/r/20170724100428.19173-1-alexander.shish...@linux.intel.com
Signed-off-by: Ingo Molnar 
---
 arch/x86/kernel/traps.c | 10 +++---
 1 file changed, 7 insertions(+), 3 deletions(-)

diff --git a/arch/x86/kernel/traps.c b/arch/x86/kernel/traps.c
index 67db4f4..5a6b8f8 100644
--- a/arch/x86/kernel/traps.c
+++ b/arch/x86/kernel/traps.c
@@ -209,9 +209,6 @@ do_trap_no_signal(struct task_struct *tsk, int trapnr, char 
*str,
if (fixup_exception(regs, trapnr))
return 0;
 
-   if (fixup_bug(regs, trapnr))
-   return 0;
-
tsk->thread.error_code = error_code;
tsk->thread.trap_nr = trapnr;
die(str, regs, error_code);
@@ -292,6 +289,13 @@ static void do_error_trap(struct pt_regs *regs, long 
error_code, char *str,
 
RCU_LOCKDEP_WARN(!rcu_is_watching(), "entry code didn't wake RCU");
 
+   /*
+* WARN*()s end up here; fix them up before we call the
+* notifier chain.
+*/
+   if (!user_mode(regs) && fixup_bug(regs, trapnr))
+   return;
+
if (notify_die(DIE_TRAP, str, regs, error_code, trapnr, signr) !=
NOTIFY_STOP) {
cond_local_irq_enable(regs);


Re: [PATCH] checkpatch: Fix checks for Kconfig help text

2017-11-09 Thread Leo Yan
On Fri, Nov 10, 2017 at 02:32:37PM +0800, Leo Yan wrote:
> If one patch has Kconfig section with only one 'config', then variable
> '$is_start' will be set by first 'config' line and '$is_end' set by the
> second 'config' line. But patches often has only one 'config' line so
> we have no chance to set '$is_end', as result below condition is invalid
> and it skips check for Kconfig description:

Sorry for the bad commit log, I will send v2 for this.

>   if ($is_start && $is_end && $length < $min_conf_desc_length) {
>   ..
>   }
> 
> When script runs to this condition sentence it means the Kconfig
> section parsing has been completed, whatever '$is_end' is true
> or not. So removes '$is_end' from condition sentence.
> 
> Another change is to change '$min_conf_desc_length' from 4 to 1; so can
> pass the check if the Kconfig description has at least one line.
> 
> Signed-off-by: Leo Yan 
> ---
>  scripts/checkpatch.pl | 4 ++--
>  1 file changed, 2 insertions(+), 2 deletions(-)
> 
> diff --git a/scripts/checkpatch.pl b/scripts/checkpatch.pl
> index 3453df9..ba724b0 100755
> --- a/scripts/checkpatch.pl
> +++ b/scripts/checkpatch.pl
> @@ -51,7 +51,7 @@ my $configuration_file = ".checkpatch.conf";
>  my $max_line_length = 80;
>  my $ignore_perl_version = 0;
>  my $minimum_perl_version = 5.10.0;
> -my $min_conf_desc_length = 4;
> +my $min_conf_desc_length = 1;
>  my $spelling_file = "$D/spelling.txt";
>  my $codespell = 0;
>  my $codespellfile = "/usr/share/codespell/dictionary.txt";
> @@ -2796,7 +2796,7 @@ sub process {
>   }
>   $length++;
>   }
> - if ($is_start && $is_end && $length < 
> $min_conf_desc_length) {
> + if ($is_start && $length < $min_conf_desc_length) {
>   WARN("CONFIG_DESCRIPTION",
>"please write a paragraph that describes 
> the config symbol fully\n" . $herecurr);
>   }
> -- 
> 2.7.4
> 


[tip:x86/urgent] x86/debug: Handle warnings before the notifier chain, to fix KGDB crash

2017-11-09 Thread tip-bot for Alexander Shishkin
Commit-ID:  a8d6c1bd62ffefb075c9d3570f07659e2a36ecb3
Gitweb: https://git.kernel.org/tip/a8d6c1bd62ffefb075c9d3570f07659e2a36ecb3
Author: Alexander Shishkin 
AuthorDate: Mon, 24 Jul 2017 13:04:28 +0300
Committer:  Ingo Molnar 
CommitDate: Fri, 10 Nov 2017 07:16:23 +0100

x86/debug: Handle warnings before the notifier chain, to fix KGDB crash

Commit:

  9a93848fe787 ("x86/debug: Implement __WARN() using UD0")

turned warnings into UD0, but the fixup code only runs after the
notify_die() chain. This is a problem, in particular, with kgdb,
which kicks in as if it was a BUG().

Fix this by running the fixup code before the notifier chain in
the invalid op handler path.

Signed-off-by: Alexander Shishkin 
Tested-by: Ilya Dryomov 
Acked-by: Daniel Thompson 
Cc: Jason Wessel 
Cc: Arjan van de Ven 
Cc: Borislav Petkov 
Cc: Linus Torvalds 
Cc: Peter Zijlstra 
Cc: Richard Weinberger 
Cc: Thomas Gleixner 
Cc:  # v4.12+
Link: 
http://lkml.kernel.org/r/20170724100428.19173-1-alexander.shish...@linux.intel.com
Signed-off-by: Ingo Molnar 
---
 arch/x86/kernel/traps.c | 10 +++---
 1 file changed, 7 insertions(+), 3 deletions(-)

diff --git a/arch/x86/kernel/traps.c b/arch/x86/kernel/traps.c
index 67db4f4..5a6b8f8 100644
--- a/arch/x86/kernel/traps.c
+++ b/arch/x86/kernel/traps.c
@@ -209,9 +209,6 @@ do_trap_no_signal(struct task_struct *tsk, int trapnr, char 
*str,
if (fixup_exception(regs, trapnr))
return 0;
 
-   if (fixup_bug(regs, trapnr))
-   return 0;
-
tsk->thread.error_code = error_code;
tsk->thread.trap_nr = trapnr;
die(str, regs, error_code);
@@ -292,6 +289,13 @@ static void do_error_trap(struct pt_regs *regs, long 
error_code, char *str,
 
RCU_LOCKDEP_WARN(!rcu_is_watching(), "entry code didn't wake RCU");
 
+   /*
+* WARN*()s end up here; fix them up before we call the
+* notifier chain.
+*/
+   if (!user_mode(regs) && fixup_bug(regs, trapnr))
+   return;
+
if (notify_die(DIE_TRAP, str, regs, error_code, trapnr, signr) !=
NOTIFY_STOP) {
cond_local_irq_enable(regs);


Re: [PATCHv4 2/3] ARMv8: layerscape: add the pcie ep function support

2017-11-09 Thread Kishon Vijay Abraham I
Hi,

On Friday 10 November 2017 09:18 AM, Bao Xiaowei wrote:
> Add the pcie controller ep function support of layerscape base on
> pcie ep framework.
> 
> Signed-off-by: Bao Xiaowei 
> ---
>  v2:
>  - fix the ioremap function used but no ioumap issue
>  - optimize the code structure
>  - add code comments
>  v3:
>  - fix the msi outband window request failed issue
>  v4:
>  - optimize the code, adjust the format
> 
>  drivers/pci/dwc/pci-layerscape.c | 120 
> ---
>  1 file changed, 113 insertions(+), 7 deletions(-)

$subject should begin with
PCI: layerscape:
> 
> diff --git a/drivers/pci/dwc/pci-layerscape.c 
> b/drivers/pci/dwc/pci-layerscape.c
> index 87fa486bee2c..6f3e434599e0 100644
> --- a/drivers/pci/dwc/pci-layerscape.c
> +++ b/drivers/pci/dwc/pci-layerscape.c
> @@ -34,7 +34,12 @@
>  /* PEX Internal Configuration Registers */
>  #define PCIE_STRFMR1 0x71c /* Symbol Timer & Filter Mask Register1 */
>  
> +#define PCIE_DBI2_BASE   0x1000  /* DBI2 base address*/

The base address should come from dt.
> +#define PCIE_MSI_MSG_DATA_OFF0x5c/* MSI Data register address*/
> +#define PCIE_MSI_OB_SIZE 4096
> +#define PCIE_MSI_ADDR_OFFSET (1024 * 1024)
>  #define PCIE_IATU_NUM6
> +#define PCIE_EP_ADDR_SPACE_SIZE 0x1
>  
>  struct ls_pcie_drvdata {
>   u32 lut_offset;
> @@ -44,12 +49,20 @@ struct ls_pcie_drvdata {
>   const struct dw_pcie_ops *dw_pcie_ops;
>  };
>  
> +struct ls_pcie_ep {
> + dma_addr_t msi_phys_addr;
> + void __iomem *msi_virt_addr;
> + u64 msi_msg_addr;
> + u16 msi_msg_data;
> +};
> +
>  struct ls_pcie {
>   struct dw_pcie *pci;
>   void __iomem *lut;
>   struct regmap *scfg;
>   const struct ls_pcie_drvdata *drvdata;
>   int index;
> + struct ls_pcie_ep *pcie_ep;
>  };
>  
>  #define to_ls_pcie(x)dev_get_drvdata((x)->dev)
> @@ -263,6 +276,99 @@ static const struct of_device_id ls_pcie_of_match[] = {
>   { },
>  };
>  
> +static void ls_pcie_raise_msi_irq(struct ls_pcie_ep *pcie_ep)
> +{
> + iowrite32(pcie_ep->msi_msg_data, pcie_ep->msi_virt_addr);
> +}
> +
> +static int ls_pcie_raise_irq(struct dw_pcie_ep *ep,
> + enum pci_epc_irq_type type, u8 interrupt_num)
> +{
> + struct dw_pcie *pci = to_dw_pcie_from_ep(ep);
> + struct ls_pcie *pcie = to_ls_pcie(pci);
> + struct ls_pcie_ep *pcie_ep = pcie->pcie_ep;
> + u32 free_win;
> +
> + /* get the msi message address and msi message data */
> + pcie_ep->msi_msg_addr = ioread32(pci->dbi_base + MSI_MESSAGE_ADDR_L32) |
> + (((u64)ioread32(pci->dbi_base + MSI_MESSAGE_ADDR_U32)) << 32);
> + pcie_ep->msi_msg_data = ioread16(pci->dbi_base + PCIE_MSI_MSG_DATA_OFF);
> +
> + /* request and config the outband window for msi */
> + free_win = find_first_zero_bit(>ob_window_map,
> + sizeof(ep->ob_window_map));
> + if (free_win >= ep->num_ob_windows) {
> + dev_err(pci->dev, "no free outbound window\n");
> + return -ENOMEM;
> + }
> +
> + dw_pcie_prog_outbound_atu(pci, free_win, PCIE_ATU_TYPE_MEM,
> + pcie_ep->msi_phys_addr,
> + pcie_ep->msi_msg_addr,
> + PCIE_MSI_OB_SIZE);
> +
> + set_bit(free_win, >ob_window_map);

This custom logic is not required. You can use [1] instead

[1] -> https://lkml.org/lkml/2017/11/3/318
> +
> + /* generate the msi interrupt */
> + ls_pcie_raise_msi_irq(pcie_ep);
> +
> + /* release the outband window of msi */
> + dw_pcie_disable_atu(pci, free_win, DW_PCIE_REGION_OUTBOUND);
> + clear_bit(free_win, >ob_window_map);
> +
> + return 0;
> +}
> +
> +static struct dw_pcie_ep_ops pcie_ep_ops = {
> + .raise_irq = ls_pcie_raise_irq,
> +};
> +
> +static int __init ls_add_pcie_ep(struct ls_pcie *pcie,
> + struct platform_device *pdev)
> +{
> + struct dw_pcie *pci = pcie->pci;
> + struct device *dev = pci->dev;
> + struct dw_pcie_ep *ep;
> + struct ls_pcie_ep *pcie_ep;
> + struct resource *cfg_res;
> + int ret;
> +
> + ep = >ep;
> + ep->ops = _ep_ops;
> +
> + pcie_ep = devm_kzalloc(dev, sizeof(*pcie_ep), GFP_KERNEL);
> + if (!pcie_ep)
> + return -ENOMEM;
> +
> + pcie->pcie_ep = pcie_ep;
> +
> + cfg_res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "config");
> + if (cfg_res) {
> + ep->phys_base = cfg_res->start;
> + ep->addr_size = PCIE_EP_ADDR_SPACE_SIZE;
> + } else {
> + dev_err(dev, "missing *config* space\n");
> + return -ENODEV;
> + }
> +
> + pcie_ep->msi_phys_addr = ep->phys_base + PCIE_MSI_ADDR_OFFSET;
> +
> + pcie_ep->msi_virt_addr = ioremap(pcie_ep->msi_phys_addr,
> + 

Re: [PATCHv4 2/3] ARMv8: layerscape: add the pcie ep function support

2017-11-09 Thread Kishon Vijay Abraham I
Hi,

On Friday 10 November 2017 09:18 AM, Bao Xiaowei wrote:
> Add the pcie controller ep function support of layerscape base on
> pcie ep framework.
> 
> Signed-off-by: Bao Xiaowei 
> ---
>  v2:
>  - fix the ioremap function used but no ioumap issue
>  - optimize the code structure
>  - add code comments
>  v3:
>  - fix the msi outband window request failed issue
>  v4:
>  - optimize the code, adjust the format
> 
>  drivers/pci/dwc/pci-layerscape.c | 120 
> ---
>  1 file changed, 113 insertions(+), 7 deletions(-)

$subject should begin with
PCI: layerscape:
> 
> diff --git a/drivers/pci/dwc/pci-layerscape.c 
> b/drivers/pci/dwc/pci-layerscape.c
> index 87fa486bee2c..6f3e434599e0 100644
> --- a/drivers/pci/dwc/pci-layerscape.c
> +++ b/drivers/pci/dwc/pci-layerscape.c
> @@ -34,7 +34,12 @@
>  /* PEX Internal Configuration Registers */
>  #define PCIE_STRFMR1 0x71c /* Symbol Timer & Filter Mask Register1 */
>  
> +#define PCIE_DBI2_BASE   0x1000  /* DBI2 base address*/

The base address should come from dt.
> +#define PCIE_MSI_MSG_DATA_OFF0x5c/* MSI Data register address*/
> +#define PCIE_MSI_OB_SIZE 4096
> +#define PCIE_MSI_ADDR_OFFSET (1024 * 1024)
>  #define PCIE_IATU_NUM6
> +#define PCIE_EP_ADDR_SPACE_SIZE 0x1
>  
>  struct ls_pcie_drvdata {
>   u32 lut_offset;
> @@ -44,12 +49,20 @@ struct ls_pcie_drvdata {
>   const struct dw_pcie_ops *dw_pcie_ops;
>  };
>  
> +struct ls_pcie_ep {
> + dma_addr_t msi_phys_addr;
> + void __iomem *msi_virt_addr;
> + u64 msi_msg_addr;
> + u16 msi_msg_data;
> +};
> +
>  struct ls_pcie {
>   struct dw_pcie *pci;
>   void __iomem *lut;
>   struct regmap *scfg;
>   const struct ls_pcie_drvdata *drvdata;
>   int index;
> + struct ls_pcie_ep *pcie_ep;
>  };
>  
>  #define to_ls_pcie(x)dev_get_drvdata((x)->dev)
> @@ -263,6 +276,99 @@ static const struct of_device_id ls_pcie_of_match[] = {
>   { },
>  };
>  
> +static void ls_pcie_raise_msi_irq(struct ls_pcie_ep *pcie_ep)
> +{
> + iowrite32(pcie_ep->msi_msg_data, pcie_ep->msi_virt_addr);
> +}
> +
> +static int ls_pcie_raise_irq(struct dw_pcie_ep *ep,
> + enum pci_epc_irq_type type, u8 interrupt_num)
> +{
> + struct dw_pcie *pci = to_dw_pcie_from_ep(ep);
> + struct ls_pcie *pcie = to_ls_pcie(pci);
> + struct ls_pcie_ep *pcie_ep = pcie->pcie_ep;
> + u32 free_win;
> +
> + /* get the msi message address and msi message data */
> + pcie_ep->msi_msg_addr = ioread32(pci->dbi_base + MSI_MESSAGE_ADDR_L32) |
> + (((u64)ioread32(pci->dbi_base + MSI_MESSAGE_ADDR_U32)) << 32);
> + pcie_ep->msi_msg_data = ioread16(pci->dbi_base + PCIE_MSI_MSG_DATA_OFF);
> +
> + /* request and config the outband window for msi */
> + free_win = find_first_zero_bit(>ob_window_map,
> + sizeof(ep->ob_window_map));
> + if (free_win >= ep->num_ob_windows) {
> + dev_err(pci->dev, "no free outbound window\n");
> + return -ENOMEM;
> + }
> +
> + dw_pcie_prog_outbound_atu(pci, free_win, PCIE_ATU_TYPE_MEM,
> + pcie_ep->msi_phys_addr,
> + pcie_ep->msi_msg_addr,
> + PCIE_MSI_OB_SIZE);
> +
> + set_bit(free_win, >ob_window_map);

This custom logic is not required. You can use [1] instead

[1] -> https://lkml.org/lkml/2017/11/3/318
> +
> + /* generate the msi interrupt */
> + ls_pcie_raise_msi_irq(pcie_ep);
> +
> + /* release the outband window of msi */
> + dw_pcie_disable_atu(pci, free_win, DW_PCIE_REGION_OUTBOUND);
> + clear_bit(free_win, >ob_window_map);
> +
> + return 0;
> +}
> +
> +static struct dw_pcie_ep_ops pcie_ep_ops = {
> + .raise_irq = ls_pcie_raise_irq,
> +};
> +
> +static int __init ls_add_pcie_ep(struct ls_pcie *pcie,
> + struct platform_device *pdev)
> +{
> + struct dw_pcie *pci = pcie->pci;
> + struct device *dev = pci->dev;
> + struct dw_pcie_ep *ep;
> + struct ls_pcie_ep *pcie_ep;
> + struct resource *cfg_res;
> + int ret;
> +
> + ep = >ep;
> + ep->ops = _ep_ops;
> +
> + pcie_ep = devm_kzalloc(dev, sizeof(*pcie_ep), GFP_KERNEL);
> + if (!pcie_ep)
> + return -ENOMEM;
> +
> + pcie->pcie_ep = pcie_ep;
> +
> + cfg_res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "config");
> + if (cfg_res) {
> + ep->phys_base = cfg_res->start;
> + ep->addr_size = PCIE_EP_ADDR_SPACE_SIZE;
> + } else {
> + dev_err(dev, "missing *config* space\n");
> + return -ENODEV;
> + }
> +
> + pcie_ep->msi_phys_addr = ep->phys_base + PCIE_MSI_ADDR_OFFSET;
> +
> + pcie_ep->msi_virt_addr = ioremap(pcie_ep->msi_phys_addr,
> + PCIE_MSI_OB_SIZE);
> + if 

  1   2   3   4   5   6   7   8   9   10   >