Re: [alsa-devel] [PATCH v5] ASoC: rockchip: Add machine driver for RK3399 GRU Boards

2016-06-15 Thread Ben Zhang
On Wed, Jun 15, 2016 at 5:44 AM, Rob Herring  wrote:
> On Wed, Jun 15, 2016 at 4:53 AM, Mark Brown  wrote:
>> On Tue, Jun 14, 2016 at 05:38:10PM -0500, Rob Herring wrote:
>>> On Mon, Jun 13, 2016 at 04:42:18PM +0800, Xing Zheng wrote:
>>
>>> > +sound {
>>> > +   compatible = "rockchip,rk3399-gru-sound";
>>> > +   rockchip,cpu = <>;
>>> > +   rockchip,codec = <  >;
>>
>>> These seem fairly standard though a variety of versions in the bindings.
>>> Can we use audio-codec and audio-cpu (or cpu or audio-dai) here? Mark?
>>
>> Well, the roles aren't actually that standard (the fact that there's
>> multiple CODECs and one CPU DAI here is really odd and definitely needs
>> a very system specific interpretation).  If they were standard we
>> already have the simple-card binding that things should be using.
>> There's no point in standard property names if the interpretation has to
>> be non-standard.
>
> Okay, I agree with the system specific interpretation part. However, I
> don't think using simple-card or not determines using common
> properties.
>

Hi Mark, I have a question for the one CPU DAI + multiple CODECs
setup. The machine driver defines 3 DAI links, connecting the same CPU
DAI to 3 different CODEC DAIs. Does ASoC/DAPM support
enabling/disabling an individual DAI link based on the status of the
endpoint widget (e.g. DAPM_SPK) connected to the corresponding CODEC?

The goal is to let user select either headphone(da7219) or
speaker(max98357a) as output. max98357a driver does not expose a
kcontrol for mute. It sets a shutdown GPIO on PCM_TRIGGER_START/STOP.
And it seems soc_pcm_trigger calls the trigger op of all 3 CODEC DAIs,
even when the DAPM_SPK widget is disabled by its pin switch.

>> The vendor specific prefixes are there because all bindings are supposed
>> to add prefixes to property names.
>
> ...unless they are common.
>
> Rob
> ___
> Alsa-devel mailing list
> alsa-de...@alsa-project.org
> http://mailman.alsa-project.org/mailman/listinfo/alsa-devel

Thanks,
Ben


Re: [alsa-devel] [PATCH v5] ASoC: rockchip: Add machine driver for RK3399 GRU Boards

2016-06-15 Thread Ben Zhang
On Wed, Jun 15, 2016 at 5:44 AM, Rob Herring  wrote:
> On Wed, Jun 15, 2016 at 4:53 AM, Mark Brown  wrote:
>> On Tue, Jun 14, 2016 at 05:38:10PM -0500, Rob Herring wrote:
>>> On Mon, Jun 13, 2016 at 04:42:18PM +0800, Xing Zheng wrote:
>>
>>> > +sound {
>>> > +   compatible = "rockchip,rk3399-gru-sound";
>>> > +   rockchip,cpu = <>;
>>> > +   rockchip,codec = <  >;
>>
>>> These seem fairly standard though a variety of versions in the bindings.
>>> Can we use audio-codec and audio-cpu (or cpu or audio-dai) here? Mark?
>>
>> Well, the roles aren't actually that standard (the fact that there's
>> multiple CODECs and one CPU DAI here is really odd and definitely needs
>> a very system specific interpretation).  If they were standard we
>> already have the simple-card binding that things should be using.
>> There's no point in standard property names if the interpretation has to
>> be non-standard.
>
> Okay, I agree with the system specific interpretation part. However, I
> don't think using simple-card or not determines using common
> properties.
>

Hi Mark, I have a question for the one CPU DAI + multiple CODECs
setup. The machine driver defines 3 DAI links, connecting the same CPU
DAI to 3 different CODEC DAIs. Does ASoC/DAPM support
enabling/disabling an individual DAI link based on the status of the
endpoint widget (e.g. DAPM_SPK) connected to the corresponding CODEC?

The goal is to let user select either headphone(da7219) or
speaker(max98357a) as output. max98357a driver does not expose a
kcontrol for mute. It sets a shutdown GPIO on PCM_TRIGGER_START/STOP.
And it seems soc_pcm_trigger calls the trigger op of all 3 CODEC DAIs,
even when the DAPM_SPK widget is disabled by its pin switch.

>> The vendor specific prefixes are there because all bindings are supposed
>> to add prefixes to property names.
>
> ...unless they are common.
>
> Rob
> ___
> Alsa-devel mailing list
> alsa-de...@alsa-project.org
> http://mailman.alsa-project.org/mailman/listinfo/alsa-devel

Thanks,
Ben


Re: [PATCH] irqchip: gic-v3: Explicitly include linux/io.h

2015-08-19 Thread Ben Zhang
This patch is not really needed. The build failure on our v3.18-based
kernel is fixed by cherry-picking commit 332fd7c4fef5 ("genirq:
Generic chip: Change irq_reg_{readl,writel} arguments") which is
actually a functional no-op. This patch could help prevent future
build failure in case linux/io.h is later removed from linux/irq.h.
Since the irq-gic-v3 driver uses the read/write io functions, it might
be better to include linux/io.h explicitly.

Thanks,
Ben

On Wed, Aug 19, 2015 at 2:13 PM, Thomas Gleixner  wrote:
> On Fri, 7 Aug 2015, Ben Zhang wrote:
>> Mainline build is fine because commit 332fd7c4fef5("genirq: Generic
>> chip: Change irq_reg_{readl,writel} arguments") landed before the
>> timecounter patch, and it creates a new include path to the io.h
>> header:
>> arch/arm64/include/asm/io.h
>> include/linux/io.h
>> include/linux/irq.h
>> include/linux/of_irq.h
>> drivers/irqchip/irq-gic-v3.c
>
> And why do we need to include it once more then?
>
> Thanks,
>
> tglx
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [PATCH] irqchip: gic-v3: Explicitly include linux/io.h

2015-08-19 Thread Ben Zhang
This patch is not really needed. The build failure on our v3.18-based
kernel is fixed by cherry-picking commit 332fd7c4fef5 (genirq:
Generic chip: Change irq_reg_{readl,writel} arguments) which is
actually a functional no-op. This patch could help prevent future
build failure in case linux/io.h is later removed from linux/irq.h.
Since the irq-gic-v3 driver uses the read/write io functions, it might
be better to include linux/io.h explicitly.

Thanks,
Ben

On Wed, Aug 19, 2015 at 2:13 PM, Thomas Gleixner t...@linutronix.de wrote:
 On Fri, 7 Aug 2015, Ben Zhang wrote:
 Mainline build is fine because commit 332fd7c4fef5(genirq: Generic
 chip: Change irq_reg_{readl,writel} arguments) landed before the
 timecounter patch, and it creates a new include path to the io.h
 header:
 arch/arm64/include/asm/io.h
 include/linux/io.h
 include/linux/irq.h
 include/linux/of_irq.h
 drivers/irqchip/irq-gic-v3.c

 And why do we need to include it once more then?

 Thanks,

 tglx
--
To unsubscribe from this list: send the line unsubscribe linux-kernel in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [PATCH] irqchip: gic-v3: Explicitly include linux/io.h

2015-08-07 Thread Ben Zhang
On Fri, Aug 7, 2015 at 1:40 AM, Marc Zyngier  wrote:
> Hi Ben,
>
> On 07/08/15 06:31, Ben Zhang wrote:
>> linux/io.h is needed because the driver uses:
>> readl_relaxed
>> writel_relaxed
>> writeq_relaxed
>> readq_relaxed
>> iounmap
>>
>> The header was implicitly included by an unrelated
>> commit 332fd7c4fef5
>> ("genirq: Generic chip: Change irq_reg_{readl,writel} arguments")
>> from the path below:
>> include/linux/io.h
>> include/linux/irq.h
>> include/linux/of_irq.h
>> drivers/irqchip/irq-gic-v3.c
>>
>> Signed-off-by: Ben Zhang 
>> ---
>>  drivers/irqchip/irq-gic-v3.c | 1 +
>>  1 file changed, 1 insertion(+)
>>
>> diff --git a/drivers/irqchip/irq-gic-v3.c b/drivers/irqchip/irq-gic-v3.c
>> index e406bc5..3350b8d 100644
>> --- a/drivers/irqchip/irq-gic-v3.c
>> +++ b/drivers/irqchip/irq-gic-v3.c
>> @@ -19,6 +19,7 @@
>>  #include 
>>  #include 
>>  #include 
>> +#include 
>>  #include 
>>  #include 
>>  #include 
>>
>
> This seems valid, but out of curiosity: Has this triggered any
> observable build failure? Or is that something you found by inspection?
>
> Thanks,
>
> M.
> --
> Jazz is not dead. It just smells funny...


Hi Marc,

We have seen a build failure on the v3.18-based kernel for ChromeOS.
After cherry-picking commit 74d23cc704d1 ("time: move the
timecounter/cyclecounter code into its own file.") into the kernel,
irq-gic-v3 build is broken:

/mnt/host/source/src/third_party/kernel/v3.18/drivers/irqchip/irq-gic-v3.c:
In function 'gic_do_wait_for_rwp':
/mnt/host/source/src/third_party/kernel/v3.18/drivers/irqchip/irq-gic-v3.c:84:2:
error: implicit declaration of function 'readl_relaxed'
[-Werror=implicit-function-declaration]
  while (readl_relaxed(base + GICD_CTLR) & GICD_CTLR_RWP) {
  ^
...

The timecounter patch removes #include  in
include/clocksource/arm_arch_timer.h, and breaks all include paths to
the arm64 io.h header, e.g.
arch/arm64/include/asm/io.h
include/linux/clocksource.h
include/clocksource/arm_arch_timer.h
arch/arm64/include/asm/arch_timer.h
arch/arm64/include/asm/timex.h
include/linux/timex.h
include/linux/sched.h
arch/arm64/include/asm/compat.h
arch/arm64/include/asm/stat.h
include/linux/stat.h
include/linux/sysfs.h
include/linux/kobject.h
include/linux/device.h
include/linux/node.h
include/linux/cpu.h
drivers/irqchip/irq-gic-v3.c

Mainline build is fine because commit 332fd7c4fef5("genirq: Generic
chip: Change irq_reg_{readl,writel} arguments") landed before the
timecounter patch, and it creates a new include path to the io.h
header:
arch/arm64/include/asm/io.h
include/linux/io.h
include/linux/irq.h
include/linux/of_irq.h
drivers/irqchip/irq-gic-v3.c

Thanks,
Ben
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [PATCH] irqchip: gic-v3: Explicitly include linux/io.h

2015-08-07 Thread Ben Zhang
On Fri, Aug 7, 2015 at 1:40 AM, Marc Zyngier marc.zyng...@arm.com wrote:
 Hi Ben,

 On 07/08/15 06:31, Ben Zhang wrote:
 linux/io.h is needed because the driver uses:
 readl_relaxed
 writel_relaxed
 writeq_relaxed
 readq_relaxed
 iounmap

 The header was implicitly included by an unrelated
 commit 332fd7c4fef5
 (genirq: Generic chip: Change irq_reg_{readl,writel} arguments)
 from the path below:
 include/linux/io.h
 include/linux/irq.h
 include/linux/of_irq.h
 drivers/irqchip/irq-gic-v3.c

 Signed-off-by: Ben Zhang be...@chromium.org
 ---
  drivers/irqchip/irq-gic-v3.c | 1 +
  1 file changed, 1 insertion(+)

 diff --git a/drivers/irqchip/irq-gic-v3.c b/drivers/irqchip/irq-gic-v3.c
 index e406bc5..3350b8d 100644
 --- a/drivers/irqchip/irq-gic-v3.c
 +++ b/drivers/irqchip/irq-gic-v3.c
 @@ -19,6 +19,7 @@
  #include linux/cpu_pm.h
  #include linux/delay.h
  #include linux/interrupt.h
 +#include linux/io.h
  #include linux/of.h
  #include linux/of_address.h
  #include linux/of_irq.h


 This seems valid, but out of curiosity: Has this triggered any
 observable build failure? Or is that something you found by inspection?

 Thanks,

 M.
 --
 Jazz is not dead. It just smells funny...


Hi Marc,

We have seen a build failure on the v3.18-based kernel for ChromeOS.
After cherry-picking commit 74d23cc704d1 (time: move the
timecounter/cyclecounter code into its own file.) into the kernel,
irq-gic-v3 build is broken:

/mnt/host/source/src/third_party/kernel/v3.18/drivers/irqchip/irq-gic-v3.c:
In function 'gic_do_wait_for_rwp':
/mnt/host/source/src/third_party/kernel/v3.18/drivers/irqchip/irq-gic-v3.c:84:2:
error: implicit declaration of function 'readl_relaxed'
[-Werror=implicit-function-declaration]
  while (readl_relaxed(base + GICD_CTLR)  GICD_CTLR_RWP) {
  ^
...

The timecounter patch removes #include linux/clocksource.h in
include/clocksource/arm_arch_timer.h, and breaks all include paths to
the arm64 io.h header, e.g.
arch/arm64/include/asm/io.h
include/linux/clocksource.h
include/clocksource/arm_arch_timer.h
arch/arm64/include/asm/arch_timer.h
arch/arm64/include/asm/timex.h
include/linux/timex.h
include/linux/sched.h
arch/arm64/include/asm/compat.h
arch/arm64/include/asm/stat.h
include/linux/stat.h
include/linux/sysfs.h
include/linux/kobject.h
include/linux/device.h
include/linux/node.h
include/linux/cpu.h
drivers/irqchip/irq-gic-v3.c

Mainline build is fine because commit 332fd7c4fef5(genirq: Generic
chip: Change irq_reg_{readl,writel} arguments) landed before the
timecounter patch, and it creates a new include path to the io.h
header:
arch/arm64/include/asm/io.h
include/linux/io.h
include/linux/irq.h
include/linux/of_irq.h
drivers/irqchip/irq-gic-v3.c

Thanks,
Ben
--
To unsubscribe from this list: send the line unsubscribe linux-kernel in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


[PATCH] irqchip: gic-v3: Explicitly include linux/io.h

2015-08-06 Thread Ben Zhang
linux/io.h is needed because the driver uses:
readl_relaxed
writel_relaxed
writeq_relaxed
readq_relaxed
iounmap

The header was implicitly included by an unrelated
commit 332fd7c4fef5
("genirq: Generic chip: Change irq_reg_{readl,writel} arguments")
from the path below:
include/linux/io.h
include/linux/irq.h
include/linux/of_irq.h
drivers/irqchip/irq-gic-v3.c

Signed-off-by: Ben Zhang 
---
 drivers/irqchip/irq-gic-v3.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/drivers/irqchip/irq-gic-v3.c b/drivers/irqchip/irq-gic-v3.c
index e406bc5..3350b8d 100644
--- a/drivers/irqchip/irq-gic-v3.c
+++ b/drivers/irqchip/irq-gic-v3.c
@@ -19,6 +19,7 @@
 #include 
 #include 
 #include 
+#include 
 #include 
 #include 
 #include 
-- 
2.5.0.rc2.392.g76e840b

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


[PATCH] irqchip: gic-v3: Explicitly include linux/io.h

2015-08-06 Thread Ben Zhang
linux/io.h is needed because the driver uses:
readl_relaxed
writel_relaxed
writeq_relaxed
readq_relaxed
iounmap

The header was implicitly included by an unrelated
commit 332fd7c4fef5
(genirq: Generic chip: Change irq_reg_{readl,writel} arguments)
from the path below:
include/linux/io.h
include/linux/irq.h
include/linux/of_irq.h
drivers/irqchip/irq-gic-v3.c

Signed-off-by: Ben Zhang be...@chromium.org
---
 drivers/irqchip/irq-gic-v3.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/drivers/irqchip/irq-gic-v3.c b/drivers/irqchip/irq-gic-v3.c
index e406bc5..3350b8d 100644
--- a/drivers/irqchip/irq-gic-v3.c
+++ b/drivers/irqchip/irq-gic-v3.c
@@ -19,6 +19,7 @@
 #include linux/cpu_pm.h
 #include linux/delay.h
 #include linux/interrupt.h
+#include linux/io.h
 #include linux/of.h
 #include linux/of_address.h
 #include linux/of_irq.h
-- 
2.5.0.rc2.392.g76e840b

--
To unsubscribe from this list: send the line unsubscribe linux-kernel in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [PATCH] ASoC: core: Pass kcontrol pointer to bytes tlv callbacks

2015-06-03 Thread Ben Zhang
On Wed, Jun 3, 2015 at 4:59 AM, Mark Brown  wrote:
> On Tue, Jun 02, 2015 at 03:24:03PM -0700, Ben Zhang wrote:
>
>> - int (*get)(unsigned int __user *bytes, unsigned int size);
>> - int (*put)(const unsigned int __user *bytes, unsigned int size);
>> + int (*get)(struct snd_kcontrol *kcontrol,
>> +unsigned int __user *bytes, unsigned int size);
>> + int (*put)(struct snd_kcontrol *kcontrol,
>> +const unsigned int __user *bytes, unsigned int size);
>
> This doesn't update any users and we do have some like the Haswell PCM
> driver.

Hi Mark,

I couldn't find any existing users of the callbacks. It looks like the
modified callbacks are used by SND_SOC_BYTES_TLV only, and there is no
reference to SND_SOC_BYTES_TLV in the kernel.

The Haswell PCM driver uses SND_SOC_BYTES_EXT which doesn't use the
callbacks in struct soc_bytes_ext. The xhandler_get/put are assigned
to snd_kcontrol_new.get/put instead.

Ben
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [PATCH] ASoC: core: Pass kcontrol pointer to bytes tlv callbacks

2015-06-03 Thread Ben Zhang
On Wed, Jun 3, 2015 at 4:59 AM, Mark Brown broo...@kernel.org wrote:
 On Tue, Jun 02, 2015 at 03:24:03PM -0700, Ben Zhang wrote:

 - int (*get)(unsigned int __user *bytes, unsigned int size);
 - int (*put)(const unsigned int __user *bytes, unsigned int size);
 + int (*get)(struct snd_kcontrol *kcontrol,
 +unsigned int __user *bytes, unsigned int size);
 + int (*put)(struct snd_kcontrol *kcontrol,
 +const unsigned int __user *bytes, unsigned int size);

 This doesn't update any users and we do have some like the Haswell PCM
 driver.

Hi Mark,

I couldn't find any existing users of the callbacks. It looks like the
modified callbacks are used by SND_SOC_BYTES_TLV only, and there is no
reference to SND_SOC_BYTES_TLV in the kernel.

The Haswell PCM driver uses SND_SOC_BYTES_EXT which doesn't use the
callbacks in struct soc_bytes_ext. The xhandler_get/put are assigned
to snd_kcontrol_new.get/put instead.

Ben
--
To unsubscribe from this list: send the line unsubscribe linux-kernel in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


[PATCH] ASoC: core: Pass kcontrol pointer to bytes tlv callbacks

2015-06-02 Thread Ben Zhang
The get/put callbacks need the kcontrol pointer to get context
information like snd_soc_codec and drvdata.

Signed-off-by: Ben Zhang 
---
 include/sound/soc.h | 6 --
 sound/soc/soc-ops.c | 4 ++--
 2 files changed, 6 insertions(+), 4 deletions(-)

diff --git a/include/sound/soc.h b/include/sound/soc.h
index fcb312b..404265d 100644
--- a/include/sound/soc.h
+++ b/include/sound/soc.h
@@ -1169,8 +1169,10 @@ struct soc_bytes {
 struct soc_bytes_ext {
int max;
/* used for TLV byte control */
-   int (*get)(unsigned int __user *bytes, unsigned int size);
-   int (*put)(const unsigned int __user *bytes, unsigned int size);
+   int (*get)(struct snd_kcontrol *kcontrol,
+  unsigned int __user *bytes, unsigned int size);
+   int (*put)(struct snd_kcontrol *kcontrol,
+  const unsigned int __user *bytes, unsigned int size);
 };
 
 /* multi register control */
diff --git a/sound/soc/soc-ops.c b/sound/soc/soc-ops.c
index 100d92b..7f53da9 100644
--- a/sound/soc/soc-ops.c
+++ b/sound/soc/soc-ops.c
@@ -751,11 +751,11 @@ int snd_soc_bytes_tlv_callback(struct snd_kcontrol 
*kcontrol, int op_flag,
switch (op_flag) {
case SNDRV_CTL_TLV_OP_READ:
if (params->get)
-   ret = params->get(tlv, count);
+   ret = params->get(kcontrol, tlv, count);
break;
case SNDRV_CTL_TLV_OP_WRITE:
if (params->put)
-   ret = params->put(tlv, count);
+   ret = params->put(kcontrol, tlv, count);
break;
}
return ret;
-- 
2.2.0.rc0.207.ga3a616c

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


[PATCH] ASoC: core: Pass kcontrol pointer to bytes tlv callbacks

2015-06-02 Thread Ben Zhang
The get/put callbacks need the kcontrol pointer to get context
information like snd_soc_codec and drvdata.

Signed-off-by: Ben Zhang be...@chromium.org
---
 include/sound/soc.h | 6 --
 sound/soc/soc-ops.c | 4 ++--
 2 files changed, 6 insertions(+), 4 deletions(-)

diff --git a/include/sound/soc.h b/include/sound/soc.h
index fcb312b..404265d 100644
--- a/include/sound/soc.h
+++ b/include/sound/soc.h
@@ -1169,8 +1169,10 @@ struct soc_bytes {
 struct soc_bytes_ext {
int max;
/* used for TLV byte control */
-   int (*get)(unsigned int __user *bytes, unsigned int size);
-   int (*put)(const unsigned int __user *bytes, unsigned int size);
+   int (*get)(struct snd_kcontrol *kcontrol,
+  unsigned int __user *bytes, unsigned int size);
+   int (*put)(struct snd_kcontrol *kcontrol,
+  const unsigned int __user *bytes, unsigned int size);
 };
 
 /* multi register control */
diff --git a/sound/soc/soc-ops.c b/sound/soc/soc-ops.c
index 100d92b..7f53da9 100644
--- a/sound/soc/soc-ops.c
+++ b/sound/soc/soc-ops.c
@@ -751,11 +751,11 @@ int snd_soc_bytes_tlv_callback(struct snd_kcontrol 
*kcontrol, int op_flag,
switch (op_flag) {
case SNDRV_CTL_TLV_OP_READ:
if (params-get)
-   ret = params-get(tlv, count);
+   ret = params-get(kcontrol, tlv, count);
break;
case SNDRV_CTL_TLV_OP_WRITE:
if (params-put)
-   ret = params-put(tlv, count);
+   ret = params-put(kcontrol, tlv, count);
break;
}
return ret;
-- 
2.2.0.rc0.207.ga3a616c

--
To unsubscribe from this list: send the line unsubscribe linux-kernel in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


[PATCH] pstore/ram: verify ramoops header before saving record

2015-03-27 Thread Ben Zhang
On some devices the persistent memory contains junk after a cold boot,
and /dev/pstore/dmesg-ramoops-* are created with random data which is
not the result of a kernel crash.

This patch adds a ramoops header check and skips any
persistent_ram_zone that does not have a valid header.

Signed-off-by: Ben Zhang 
---
 fs/pstore/ram.c | 40 
 1 file changed, 28 insertions(+), 12 deletions(-)

diff --git a/fs/pstore/ram.c b/fs/pstore/ram.c
index 44a549b..e16af43 100644
--- a/fs/pstore/ram.c
+++ b/fs/pstore/ram.c
@@ -186,12 +186,34 @@ static ssize_t ramoops_pstore_read(u64 *id, enum 
pstore_type_id *type,
ssize_t size;
ssize_t ecc_notice_size;
struct ramoops_context *cxt = psi->data;
-   struct persistent_ram_zone *prz;
-   int header_length;
+   struct persistent_ram_zone *prz = NULL;
+   int header_length = 0;
+
+   /* Ramoops headers provide time stamps for PSTORE_TYPE_DMESG, but
+* PSTORE_TYPE_CONSOLE and PSTORE_TYPE_FTRACE don't currently have
+* valid time stamps, so it is initialized to zero.
+*/
+   time->tv_sec = 0;
+   time->tv_nsec = 0;
+   *compressed = false;
+
+   /* Find the next valid persistent_ram_zone for DMESG */
+   while (cxt->dump_read_cnt < cxt->max_dump_cnt && !prz) {
+   prz = ramoops_get_next_prz(cxt->przs, >dump_read_cnt,
+  cxt->max_dump_cnt, id, type,
+  PSTORE_TYPE_DMESG, 1);
+   if (!prz_ok(prz))
+   continue;
+   header_length = ramoops_read_kmsg_hdr(persistent_ram_old(prz),
+ time, compressed);
+   /* Clear and skip this DMESG record if it has no valid header */
+   if (!header_length) {
+   persistent_ram_free_old(prz);
+   persistent_ram_zap(prz);
+   prz = NULL;
+   }
+   }
 
-   prz = ramoops_get_next_prz(cxt->przs, >dump_read_cnt,
-  cxt->max_dump_cnt, id, type,
-  PSTORE_TYPE_DMESG, 1);
if (!prz_ok(prz))
prz = ramoops_get_next_prz(>cprz, >console_read_cnt,
   1, id, type, PSTORE_TYPE_CONSOLE, 0);
@@ -204,13 +226,7 @@ static ssize_t ramoops_pstore_read(u64 *id, enum 
pstore_type_id *type,
if (!prz_ok(prz))
return 0;
 
-   if (!persistent_ram_old(prz))
-   return 0;
-
-   size = persistent_ram_old_size(prz);
-   header_length = ramoops_read_kmsg_hdr(persistent_ram_old(prz), time,
-   compressed);
-   size -= header_length;
+   size = persistent_ram_old_size(prz) - header_length;
 
/* ECC correction notice */
ecc_notice_size = persistent_ram_ecc_string(prz, NULL, 0);
-- 
2.2.0.rc0.207.ga3a616c

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


[PATCH] pstore/ram: verify ramoops header before saving record

2015-03-27 Thread Ben Zhang
On some devices the persistent memory contains junk after a cold boot,
and /dev/pstore/dmesg-ramoops-* are created with random data which is
not the result of a kernel crash.

This patch adds a ramoops header check and skips any
persistent_ram_zone that does not have a valid header.

Signed-off-by: Ben Zhang be...@chromium.org
---
 fs/pstore/ram.c | 40 
 1 file changed, 28 insertions(+), 12 deletions(-)

diff --git a/fs/pstore/ram.c b/fs/pstore/ram.c
index 44a549b..e16af43 100644
--- a/fs/pstore/ram.c
+++ b/fs/pstore/ram.c
@@ -186,12 +186,34 @@ static ssize_t ramoops_pstore_read(u64 *id, enum 
pstore_type_id *type,
ssize_t size;
ssize_t ecc_notice_size;
struct ramoops_context *cxt = psi-data;
-   struct persistent_ram_zone *prz;
-   int header_length;
+   struct persistent_ram_zone *prz = NULL;
+   int header_length = 0;
+
+   /* Ramoops headers provide time stamps for PSTORE_TYPE_DMESG, but
+* PSTORE_TYPE_CONSOLE and PSTORE_TYPE_FTRACE don't currently have
+* valid time stamps, so it is initialized to zero.
+*/
+   time-tv_sec = 0;
+   time-tv_nsec = 0;
+   *compressed = false;
+
+   /* Find the next valid persistent_ram_zone for DMESG */
+   while (cxt-dump_read_cnt  cxt-max_dump_cnt  !prz) {
+   prz = ramoops_get_next_prz(cxt-przs, cxt-dump_read_cnt,
+  cxt-max_dump_cnt, id, type,
+  PSTORE_TYPE_DMESG, 1);
+   if (!prz_ok(prz))
+   continue;
+   header_length = ramoops_read_kmsg_hdr(persistent_ram_old(prz),
+ time, compressed);
+   /* Clear and skip this DMESG record if it has no valid header */
+   if (!header_length) {
+   persistent_ram_free_old(prz);
+   persistent_ram_zap(prz);
+   prz = NULL;
+   }
+   }
 
-   prz = ramoops_get_next_prz(cxt-przs, cxt-dump_read_cnt,
-  cxt-max_dump_cnt, id, type,
-  PSTORE_TYPE_DMESG, 1);
if (!prz_ok(prz))
prz = ramoops_get_next_prz(cxt-cprz, cxt-console_read_cnt,
   1, id, type, PSTORE_TYPE_CONSOLE, 0);
@@ -204,13 +226,7 @@ static ssize_t ramoops_pstore_read(u64 *id, enum 
pstore_type_id *type,
if (!prz_ok(prz))
return 0;
 
-   if (!persistent_ram_old(prz))
-   return 0;
-
-   size = persistent_ram_old_size(prz);
-   header_length = ramoops_read_kmsg_hdr(persistent_ram_old(prz), time,
-   compressed);
-   size -= header_length;
+   size = persistent_ram_old_size(prz) - header_length;
 
/* ECC correction notice */
ecc_notice_size = persistent_ram_ecc_string(prz, NULL, 0);
-- 
2.2.0.rc0.207.ga3a616c

--
To unsubscribe from this list: send the line unsubscribe linux-kernel in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [PATCH 2/3] ASoC: rt5677: add a platform config option for MICBIAS voltage

2014-12-12 Thread Ben Zhang
On Fri, Dec 12, 2014 at 5:27 AM, Mark Brown  wrote:
> On Wed, Dec 10, 2014 at 08:15:26PM -0800, Ben Zhang wrote:
>
>> The MICBIAS voltage for IN1 can be set to 1.476V/2.970V/1.242V/2.475V
>
> The changelog says "platform config" but this is adding DT binding.
>
>> +- realtek,micbias1
>> +  Select 0/1/2/3 to set MICBIAS1 voltage to 1.476V/2.970V/1.242V/2.475V
>> +
>
> Why is this being specified as some magic number rather than using the
> voltage (or at least providing defines for the voltage) - this is going
> to do little to make the DT legible and...
>
>> +enum rt5677_micbias {
>> + RT5677_MICBIAS_1_476V = 0,
>> + RT5677_MICBIAS_2_970V = 1,
>> + RT5677_MICBIAS_1_242V = 2,
>> + RT5677_MICBIAS_2_475V = 3,
>> +};
>
> ...I see there are defined for platform data.

This patch adds both an entry to the platform data and a DT binding
for MICBIAS level selection. The 4 voltage options
(1.476V/2.970V/1.242V/2.475V) are the only ones supported by the codec
hardware, so it seems an enum is better than specifying the exact
voltage directly. I was following the two examples below:

Documentation/devicetree/bindings/sound/cs42l52.txt (cirrus,micbias-lvl)
Documentation/devicetree/bindings/sound/tlv320aic3x.txt (ai3x-micbias-vg)

I'm new to devicetree bindings. Is there something like an enum in DT?
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [PATCH 2/3] ASoC: rt5677: add a platform config option for MICBIAS voltage

2014-12-12 Thread Ben Zhang
On Fri, Dec 12, 2014 at 5:27 AM, Mark Brown broo...@kernel.org wrote:
 On Wed, Dec 10, 2014 at 08:15:26PM -0800, Ben Zhang wrote:

 The MICBIAS voltage for IN1 can be set to 1.476V/2.970V/1.242V/2.475V

 The changelog says platform config but this is adding DT binding.

 +- realtek,micbias1
 +  Select 0/1/2/3 to set MICBIAS1 voltage to 1.476V/2.970V/1.242V/2.475V
 +

 Why is this being specified as some magic number rather than using the
 voltage (or at least providing defines for the voltage) - this is going
 to do little to make the DT legible and...

 +enum rt5677_micbias {
 + RT5677_MICBIAS_1_476V = 0,
 + RT5677_MICBIAS_2_970V = 1,
 + RT5677_MICBIAS_1_242V = 2,
 + RT5677_MICBIAS_2_475V = 3,
 +};

 ...I see there are defined for platform data.

This patch adds both an entry to the platform data and a DT binding
for MICBIAS level selection. The 4 voltage options
(1.476V/2.970V/1.242V/2.475V) are the only ones supported by the codec
hardware, so it seems an enum is better than specifying the exact
voltage directly. I was following the two examples below:

Documentation/devicetree/bindings/sound/cs42l52.txt (cirrus,micbias-lvl)
Documentation/devicetree/bindings/sound/tlv320aic3x.txt (ai3x-micbias-vg)

I'm new to devicetree bindings. Is there something like an enum in DT?
--
To unsubscribe from this list: send the line unsubscribe linux-kernel in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


[PATCH 3/3] ASoC: rt5677: add a platform config option for DACREF source

2014-12-10 Thread Ben Zhang
DACREF power source can come from external 1.8V or codec internal 1.8V.
This patch adds the option to enable the internal DACREF power source.

Signed-off-by: Ben Zhang 
---
 Documentation/devicetree/bindings/sound/rt5677.txt | 3 +++
 include/sound/rt5677.h | 2 ++
 sound/soc/codecs/rt5677.c  | 9 +
 3 files changed, 14 insertions(+)

diff --git a/Documentation/devicetree/bindings/sound/rt5677.txt 
b/Documentation/devicetree/bindings/sound/rt5677.txt
index f54d0dd..f06d52a 100644
--- a/Documentation/devicetree/bindings/sound/rt5677.txt
+++ b/Documentation/devicetree/bindings/sound/rt5677.txt
@@ -22,6 +22,9 @@ Optional properties:
 - realtek,micbias1
   Select 0/1/2/3 to set MICBIAS1 voltage to 1.476V/2.970V/1.242V/2.475V
 
+- realtek,internal-dacref-en
+  Select codec internal 1.8V as DACREF source optionally.
+
 - realtek,in1-differential
 - realtek,in2-differential
 - realtek,lout1-differential
diff --git a/include/sound/rt5677.h b/include/sound/rt5677.h
index efa74bb..42866f3 100644
--- a/include/sound/rt5677.h
+++ b/include/sound/rt5677.h
@@ -28,6 +28,8 @@ enum rt5677_dmic2_clk {
 struct rt5677_platform_data {
/* MICBIAS output voltage control */
enum rt5677_micbias micbias1;
+   /* Select codec internal 1.8V as DACREF source optionally */
+   bool internal_dacref_en;
/* IN1/IN2/LOUT1/LOUT2/LOUT3 can optionally be differential */
bool in1_diff;
bool in2_diff;
diff --git a/sound/soc/codecs/rt5677.c b/sound/soc/codecs/rt5677.c
index ac4bee8..e6d7bb4 100644
--- a/sound/soc/codecs/rt5677.c
+++ b/sound/soc/codecs/rt5677.c
@@ -4552,6 +4552,8 @@ MODULE_DEVICE_TABLE(i2c, rt5677_i2c_id);
 static int rt5677_parse_dt(struct rt5677_priv *rt5677, struct device_node *np)
 {
of_property_read_u32(np, "realtek,micbias1", >pdata.micbias1);
+   rt5677->pdata.internal_dacref_en = of_property_read_bool(np,
+   "realtek,internal-dacref-en");
rt5677->pdata.in1_diff = of_property_read_bool(np,
"realtek,in1-differential");
rt5677->pdata.in2_diff = of_property_read_bool(np,
@@ -4728,6 +4730,13 @@ static int rt5677_i2c_probe(struct i2c_client *i2c,
RT5677_MICBIAS1_CTRL_VDD_MASK,
rt5677->pdata.micbias1 << RT5677_MICBIAS1_CTRL_VDD_SFT);
 
+   if (rt5677->pdata.internal_dacref_en) {
+   regmap_update_bits(rt5677->regmap, RT5677_PR_BASE +
+   RT5677_TEST_CTRL1, 1 << 9, 1 << 9);
+   regmap_update_bits(rt5677->regmap, RT5677_PR_BASE +
+   RT5677_SOFT_DEPOP_DAC_CLK_CTRL, 1 << 5, 1 << 5);
+   }
+
if (rt5677->pdata.in1_diff)
regmap_update_bits(rt5677->regmap, RT5677_IN1,
RT5677_IN_DF1, RT5677_IN_DF1);
-- 
2.2.0.rc0.207.ga3a616c

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


[PATCH 2/3] ASoC: rt5677: add a platform config option for MICBIAS voltage

2014-12-10 Thread Ben Zhang
The MICBIAS voltage for IN1 can be set to 1.476V/2.970V/1.242V/2.475V

Signed-off-by: Ben Zhang 
---
 Documentation/devicetree/bindings/sound/rt5677.txt | 4 
 include/sound/rt5677.h | 9 +
 sound/soc/codecs/rt5677.c  | 6 ++
 3 files changed, 19 insertions(+)

diff --git a/Documentation/devicetree/bindings/sound/rt5677.txt 
b/Documentation/devicetree/bindings/sound/rt5677.txt
index 740ff77..f54d0dd 100644
--- a/Documentation/devicetree/bindings/sound/rt5677.txt
+++ b/Documentation/devicetree/bindings/sound/rt5677.txt
@@ -19,6 +19,9 @@ Optional properties:
 
 - realtek,pow-ldo2-gpio : The GPIO that controls the CODEC's POW_LDO2 pin.
 
+- realtek,micbias1
+  Select 0/1/2/3 to set MICBIAS1 voltage to 1.476V/2.970V/1.242V/2.475V
+
 - realtek,in1-differential
 - realtek,in2-differential
 - realtek,lout1-differential
@@ -70,6 +73,7 @@ rt5677 {
 
realtek,pow-ldo2-gpio =
< TEGRA_GPIO(V, 3) GPIO_ACTIVE_HIGH>;
+   realtek,micbias1 = <1>  /* MICBIAS1 = 2.970V */
realtek,in1-differential = "true";
realtek,gpio-config = /bits/ 8  <0 0 0 0 0 2>;   /* pull up GPIO6 */
realtek,jd2-gpio = <3>;  /* Enables Jack detection for GPIO6 */
diff --git a/include/sound/rt5677.h b/include/sound/rt5677.h
index d9eb7d8..efa74bb 100644
--- a/include/sound/rt5677.h
+++ b/include/sound/rt5677.h
@@ -12,6 +12,13 @@
 #ifndef __LINUX_SND_RT5677_H
 #define __LINUX_SND_RT5677_H
 
+enum rt5677_micbias {
+   RT5677_MICBIAS_1_476V = 0,
+   RT5677_MICBIAS_2_970V = 1,
+   RT5677_MICBIAS_1_242V = 2,
+   RT5677_MICBIAS_2_475V = 3,
+};
+
 enum rt5677_dmic2_clk {
RT5677_DMIC_CLK1 = 0,
RT5677_DMIC_CLK2 = 1,
@@ -19,6 +26,8 @@ enum rt5677_dmic2_clk {
 
 
 struct rt5677_platform_data {
+   /* MICBIAS output voltage control */
+   enum rt5677_micbias micbias1;
/* IN1/IN2/LOUT1/LOUT2/LOUT3 can optionally be differential */
bool in1_diff;
bool in2_diff;
diff --git a/sound/soc/codecs/rt5677.c b/sound/soc/codecs/rt5677.c
index 81fe146..ac4bee8 100644
--- a/sound/soc/codecs/rt5677.c
+++ b/sound/soc/codecs/rt5677.c
@@ -4551,6 +4551,7 @@ MODULE_DEVICE_TABLE(i2c, rt5677_i2c_id);
 
 static int rt5677_parse_dt(struct rt5677_priv *rt5677, struct device_node *np)
 {
+   of_property_read_u32(np, "realtek,micbias1", >pdata.micbias1);
rt5677->pdata.in1_diff = of_property_read_bool(np,
"realtek,in1-differential");
rt5677->pdata.in2_diff = of_property_read_bool(np,
@@ -4722,6 +4723,11 @@ static int rt5677_i2c_probe(struct i2c_client *i2c,
if (ret != 0)
dev_warn(>dev, "Failed to apply regmap patch: %d\n", ret);
 
+   regmap_update_bits(rt5677->regmap, RT5677_MICBIAS,
+   RT5677_MICBIAS1_OUTVOLT_MASK |
+   RT5677_MICBIAS1_CTRL_VDD_MASK,
+   rt5677->pdata.micbias1 << RT5677_MICBIAS1_CTRL_VDD_SFT);
+
if (rt5677->pdata.in1_diff)
regmap_update_bits(rt5677->regmap, RT5677_IN1,
RT5677_IN_DF1, RT5677_IN_DF1);
-- 
2.2.0.rc0.207.ga3a616c

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


[PATCH 1/3] ASoC: rt5677: add REGMAP_I2C and REGMAP_IRQ dependency

2014-12-10 Thread Ben Zhang
The codec driver uses regmap to do i2c read/write.
The codec driver started to use REGMAP_IRQ since:

5e3363ad1b7b2e1f197a3f56b01e21cb155ad454
ASoC: rt5677: add GPIO IRQ support

Signed-off-by: Ben Zhang 
---
 sound/soc/codecs/Kconfig | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/sound/soc/codecs/Kconfig b/sound/soc/codecs/Kconfig
index 6f21a76..60f9425 100644
--- a/sound/soc/codecs/Kconfig
+++ b/sound/soc/codecs/Kconfig
@@ -503,6 +503,8 @@ config SND_SOC_RT5670
 
 config SND_SOC_RT5677
tristate
+   select REGMAP_I2C
+   select REGMAP_IRQ
 
 config SND_SOC_RT5677_SPI
tristate
-- 
2.2.0.rc0.207.ga3a616c

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


[PATCH 1/3] ASoC: rt5677: add REGMAP_I2C and REGMAP_IRQ dependency

2014-12-10 Thread Ben Zhang
The codec driver uses regmap to do i2c read/write.
The codec driver started to use REGMAP_IRQ since:

5e3363ad1b7b2e1f197a3f56b01e21cb155ad454
ASoC: rt5677: add GPIO IRQ support

Signed-off-by: Ben Zhang be...@chromium.org
---
 sound/soc/codecs/Kconfig | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/sound/soc/codecs/Kconfig b/sound/soc/codecs/Kconfig
index 6f21a76..60f9425 100644
--- a/sound/soc/codecs/Kconfig
+++ b/sound/soc/codecs/Kconfig
@@ -503,6 +503,8 @@ config SND_SOC_RT5670
 
 config SND_SOC_RT5677
tristate
+   select REGMAP_I2C
+   select REGMAP_IRQ
 
 config SND_SOC_RT5677_SPI
tristate
-- 
2.2.0.rc0.207.ga3a616c

--
To unsubscribe from this list: send the line unsubscribe linux-kernel in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


[PATCH 2/3] ASoC: rt5677: add a platform config option for MICBIAS voltage

2014-12-10 Thread Ben Zhang
The MICBIAS voltage for IN1 can be set to 1.476V/2.970V/1.242V/2.475V

Signed-off-by: Ben Zhang be...@chromium.org
---
 Documentation/devicetree/bindings/sound/rt5677.txt | 4 
 include/sound/rt5677.h | 9 +
 sound/soc/codecs/rt5677.c  | 6 ++
 3 files changed, 19 insertions(+)

diff --git a/Documentation/devicetree/bindings/sound/rt5677.txt 
b/Documentation/devicetree/bindings/sound/rt5677.txt
index 740ff77..f54d0dd 100644
--- a/Documentation/devicetree/bindings/sound/rt5677.txt
+++ b/Documentation/devicetree/bindings/sound/rt5677.txt
@@ -19,6 +19,9 @@ Optional properties:
 
 - realtek,pow-ldo2-gpio : The GPIO that controls the CODEC's POW_LDO2 pin.
 
+- realtek,micbias1
+  Select 0/1/2/3 to set MICBIAS1 voltage to 1.476V/2.970V/1.242V/2.475V
+
 - realtek,in1-differential
 - realtek,in2-differential
 - realtek,lout1-differential
@@ -70,6 +73,7 @@ rt5677 {
 
realtek,pow-ldo2-gpio =
gpio TEGRA_GPIO(V, 3) GPIO_ACTIVE_HIGH;
+   realtek,micbias1 = 1  /* MICBIAS1 = 2.970V */
realtek,in1-differential = true;
realtek,gpio-config = /bits/ 8  0 0 0 0 0 2;   /* pull up GPIO6 */
realtek,jd2-gpio = 3;  /* Enables Jack detection for GPIO6 */
diff --git a/include/sound/rt5677.h b/include/sound/rt5677.h
index d9eb7d8..efa74bb 100644
--- a/include/sound/rt5677.h
+++ b/include/sound/rt5677.h
@@ -12,6 +12,13 @@
 #ifndef __LINUX_SND_RT5677_H
 #define __LINUX_SND_RT5677_H
 
+enum rt5677_micbias {
+   RT5677_MICBIAS_1_476V = 0,
+   RT5677_MICBIAS_2_970V = 1,
+   RT5677_MICBIAS_1_242V = 2,
+   RT5677_MICBIAS_2_475V = 3,
+};
+
 enum rt5677_dmic2_clk {
RT5677_DMIC_CLK1 = 0,
RT5677_DMIC_CLK2 = 1,
@@ -19,6 +26,8 @@ enum rt5677_dmic2_clk {
 
 
 struct rt5677_platform_data {
+   /* MICBIAS output voltage control */
+   enum rt5677_micbias micbias1;
/* IN1/IN2/LOUT1/LOUT2/LOUT3 can optionally be differential */
bool in1_diff;
bool in2_diff;
diff --git a/sound/soc/codecs/rt5677.c b/sound/soc/codecs/rt5677.c
index 81fe146..ac4bee8 100644
--- a/sound/soc/codecs/rt5677.c
+++ b/sound/soc/codecs/rt5677.c
@@ -4551,6 +4551,7 @@ MODULE_DEVICE_TABLE(i2c, rt5677_i2c_id);
 
 static int rt5677_parse_dt(struct rt5677_priv *rt5677, struct device_node *np)
 {
+   of_property_read_u32(np, realtek,micbias1, rt5677-pdata.micbias1);
rt5677-pdata.in1_diff = of_property_read_bool(np,
realtek,in1-differential);
rt5677-pdata.in2_diff = of_property_read_bool(np,
@@ -4722,6 +4723,11 @@ static int rt5677_i2c_probe(struct i2c_client *i2c,
if (ret != 0)
dev_warn(i2c-dev, Failed to apply regmap patch: %d\n, ret);
 
+   regmap_update_bits(rt5677-regmap, RT5677_MICBIAS,
+   RT5677_MICBIAS1_OUTVOLT_MASK |
+   RT5677_MICBIAS1_CTRL_VDD_MASK,
+   rt5677-pdata.micbias1  RT5677_MICBIAS1_CTRL_VDD_SFT);
+
if (rt5677-pdata.in1_diff)
regmap_update_bits(rt5677-regmap, RT5677_IN1,
RT5677_IN_DF1, RT5677_IN_DF1);
-- 
2.2.0.rc0.207.ga3a616c

--
To unsubscribe from this list: send the line unsubscribe linux-kernel in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


[PATCH 3/3] ASoC: rt5677: add a platform config option for DACREF source

2014-12-10 Thread Ben Zhang
DACREF power source can come from external 1.8V or codec internal 1.8V.
This patch adds the option to enable the internal DACREF power source.

Signed-off-by: Ben Zhang be...@chromium.org
---
 Documentation/devicetree/bindings/sound/rt5677.txt | 3 +++
 include/sound/rt5677.h | 2 ++
 sound/soc/codecs/rt5677.c  | 9 +
 3 files changed, 14 insertions(+)

diff --git a/Documentation/devicetree/bindings/sound/rt5677.txt 
b/Documentation/devicetree/bindings/sound/rt5677.txt
index f54d0dd..f06d52a 100644
--- a/Documentation/devicetree/bindings/sound/rt5677.txt
+++ b/Documentation/devicetree/bindings/sound/rt5677.txt
@@ -22,6 +22,9 @@ Optional properties:
 - realtek,micbias1
   Select 0/1/2/3 to set MICBIAS1 voltage to 1.476V/2.970V/1.242V/2.475V
 
+- realtek,internal-dacref-en
+  Select codec internal 1.8V as DACREF source optionally.
+
 - realtek,in1-differential
 - realtek,in2-differential
 - realtek,lout1-differential
diff --git a/include/sound/rt5677.h b/include/sound/rt5677.h
index efa74bb..42866f3 100644
--- a/include/sound/rt5677.h
+++ b/include/sound/rt5677.h
@@ -28,6 +28,8 @@ enum rt5677_dmic2_clk {
 struct rt5677_platform_data {
/* MICBIAS output voltage control */
enum rt5677_micbias micbias1;
+   /* Select codec internal 1.8V as DACREF source optionally */
+   bool internal_dacref_en;
/* IN1/IN2/LOUT1/LOUT2/LOUT3 can optionally be differential */
bool in1_diff;
bool in2_diff;
diff --git a/sound/soc/codecs/rt5677.c b/sound/soc/codecs/rt5677.c
index ac4bee8..e6d7bb4 100644
--- a/sound/soc/codecs/rt5677.c
+++ b/sound/soc/codecs/rt5677.c
@@ -4552,6 +4552,8 @@ MODULE_DEVICE_TABLE(i2c, rt5677_i2c_id);
 static int rt5677_parse_dt(struct rt5677_priv *rt5677, struct device_node *np)
 {
of_property_read_u32(np, realtek,micbias1, rt5677-pdata.micbias1);
+   rt5677-pdata.internal_dacref_en = of_property_read_bool(np,
+   realtek,internal-dacref-en);
rt5677-pdata.in1_diff = of_property_read_bool(np,
realtek,in1-differential);
rt5677-pdata.in2_diff = of_property_read_bool(np,
@@ -4728,6 +4730,13 @@ static int rt5677_i2c_probe(struct i2c_client *i2c,
RT5677_MICBIAS1_CTRL_VDD_MASK,
rt5677-pdata.micbias1  RT5677_MICBIAS1_CTRL_VDD_SFT);
 
+   if (rt5677-pdata.internal_dacref_en) {
+   regmap_update_bits(rt5677-regmap, RT5677_PR_BASE +
+   RT5677_TEST_CTRL1, 1  9, 1  9);
+   regmap_update_bits(rt5677-regmap, RT5677_PR_BASE +
+   RT5677_SOFT_DEPOP_DAC_CLK_CTRL, 1  5, 1  5);
+   }
+
if (rt5677-pdata.in1_diff)
regmap_update_bits(rt5677-regmap, RT5677_IN1,
RT5677_IN_DF1, RT5677_IN_DF1);
-- 
2.2.0.rc0.207.ga3a616c

--
To unsubscribe from this list: send the line unsubscribe linux-kernel in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [PATCH 1/2] ASoC: rt5677: Add ACPI device probing

2014-11-25 Thread Ben Zhang
+Duncan who works on our firmware project.

Please correct me if I'm wrong. Here is the summary of what I understand. Looks
like the recommended practice for passing device platform data is using _DSD and
the new device_property_read_ API from include/linux/property.h

For example, the firmware (coreboot) should specify something like:
Device (CODC)
{
Name (_HID, "RT5677CE")
...
Name (_DSD, Package () {
ToUUID("daffd814-6eba-4d8c-8a91-bc9bbf4aa301"),
Package () {
Package (2) {"realtek,in1-differential", 1},
Package (2) {"realtek,in2-differential", 0},
Package (2) {"realtek,gpio-config",  Package (6)  { 0, 0,
0, 0, 0, 2 }},
...
}
})
...
}

And the kernel driver should query with something like:
static void rt5677_read_platform_data(struct rt5677_priv *rt5677,
struct device *dev)
{
u8 val;

device_property_read_u8_array(dev, "realtek,in1-differential", , 1);
rt5677->pdata.in1_diff = (bool)val;
device_property_read_u8_array(dev, "realtek,in2-differential", , 1);
rt5677->pdata.in2_diff = (bool)val;

device_property_read_u8_array(dev, "realtek,gpio-config",
rt5677->pdata.gpio_config, RT5677_GPIO_NUM);
...
}
And the device property API should work for both DT and ACPI.

Also these device property name keys should be registered with the
ACPI working group
following http://www.uefi.org/sites/default/files/resources/web-page-v2.pdf


On Tue, Nov 25, 2014 at 1:40 PM, Rafael J. Wysocki  wrote:
> On Tuesday, November 25, 2014 08:27:22 PM Mark Brown wrote:
>>
>> --ReaqsoxgOBHFXBhH
>> Content-Type: text/plain; charset=us-ascii
>> Content-Disposition: inline
>>
>> On Tue, Nov 25, 2014 at 09:31:27PM +0100, Rafael J. Wysocki wrote:
>> > On Tuesday, November 25, 2014 11:07:06 AM Darren Hart wrote:
>>
>> > > This is a current topic with the ACPI working group. We have the
>> > > following document:
>>
>> > > http://www.uefi.org/sites/default/files/resources/_DSD-device-properties-UUID.pdf
>>
>> > This hasn't been discussed a lot at the meetings I attended.
>>
>> > The bindings management process is being set up within the UEFI Forum, but 
>> > I'm
>> > not sure if/how the existing DT bindings documented in the kernel tree are
>> > going to be covered by it ATM.
>>
>> Al Stone (CCed) pointed me at the following two documents:
>>
>> http://www.uefi.org/sites/default/files/resources/web-page-v2.pdf
>> http://www.uefi.org/sites/default/files/resources/nic-request-v2.pdf
>>
>> (the first one being the actual process in so far as it exists).  The
>> process appears to be to mail requests in a specific format to the ASWG
>> chairperson (the address is apparently supposed to be a...@uefi.org).
>> It looks like all the properties are expected to end up in one or more
>> PDF files like the second one.
>>
>> My initial thought would be to require that we send any DT properties
>> defined for devices with ACPI identifiers registered there and hope the
>> volume doesn't DoS them.
>
> We absolutely need to start registering the existing bindings in there, but
> that needs to be rate limited somehow, because the process may not be very
> efficient to start with.
>
>> A more defined format for DT documentation that we can script into the
>> ASWG format (or vice versa) might be helpful here, and we should add
>> notes to the DT documentation if this is how we want to proceed.
>
> That's a good point.
>
> Unfortunately, the timing is pretty bad (Thanksgiving) and the closest
> ASWG meeting is next Thursday, but that one's likely to be busy for other
> reasons.  I presume, then, that the earliest we can seriously get back to
> that in the ASWG is mid-December.
>
> --
> I speak only for myself.
> Rafael J. Wysocki, Intel Open Source Technology Center.
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [PATCH 1/2] ASoC: rt5677: Add ACPI device probing

2014-11-25 Thread Ben Zhang
+Duncan who works on our firmware project.

Please correct me if I'm wrong. Here is the summary of what I understand. Looks
like the recommended practice for passing device platform data is using _DSD and
the new device_property_read_ API from include/linux/property.h

For example, the firmware (coreboot) should specify something like:
Device (CODC)
{
Name (_HID, RT5677CE)
...
Name (_DSD, Package () {
ToUUID(daffd814-6eba-4d8c-8a91-bc9bbf4aa301),
Package () {
Package (2) {realtek,in1-differential, 1},
Package (2) {realtek,in2-differential, 0},
Package (2) {realtek,gpio-config,  Package (6)  { 0, 0,
0, 0, 0, 2 }},
...
}
})
...
}

And the kernel driver should query with something like:
static void rt5677_read_platform_data(struct rt5677_priv *rt5677,
struct device *dev)
{
u8 val;

device_property_read_u8_array(dev, realtek,in1-differential, val, 1);
rt5677-pdata.in1_diff = (bool)val;
device_property_read_u8_array(dev, realtek,in2-differential, val, 1);
rt5677-pdata.in2_diff = (bool)val;

device_property_read_u8_array(dev, realtek,gpio-config,
rt5677-pdata.gpio_config, RT5677_GPIO_NUM);
...
}
And the device property API should work for both DT and ACPI.

Also these device property name keys should be registered with the
ACPI working group
following http://www.uefi.org/sites/default/files/resources/web-page-v2.pdf


On Tue, Nov 25, 2014 at 1:40 PM, Rafael J. Wysocki r...@rjwysocki.net wrote:
 On Tuesday, November 25, 2014 08:27:22 PM Mark Brown wrote:

 --ReaqsoxgOBHFXBhH
 Content-Type: text/plain; charset=us-ascii
 Content-Disposition: inline

 On Tue, Nov 25, 2014 at 09:31:27PM +0100, Rafael J. Wysocki wrote:
  On Tuesday, November 25, 2014 11:07:06 AM Darren Hart wrote:

   This is a current topic with the ACPI working group. We have the
   following document:

   http://www.uefi.org/sites/default/files/resources/_DSD-device-properties-UUID.pdf

  This hasn't been discussed a lot at the meetings I attended.

  The bindings management process is being set up within the UEFI Forum, but 
  I'm
  not sure if/how the existing DT bindings documented in the kernel tree are
  going to be covered by it ATM.

 Al Stone (CCed) pointed me at the following two documents:

 http://www.uefi.org/sites/default/files/resources/web-page-v2.pdf
 http://www.uefi.org/sites/default/files/resources/nic-request-v2.pdf

 (the first one being the actual process in so far as it exists).  The
 process appears to be to mail requests in a specific format to the ASWG
 chairperson (the address is apparently supposed to be a...@uefi.org).
 It looks like all the properties are expected to end up in one or more
 PDF files like the second one.

 My initial thought would be to require that we send any DT properties
 defined for devices with ACPI identifiers registered there and hope the
 volume doesn't DoS them.

 We absolutely need to start registering the existing bindings in there, but
 that needs to be rate limited somehow, because the process may not be very
 efficient to start with.

 A more defined format for DT documentation that we can script into the
 ASWG format (or vice versa) might be helpful here, and we should add
 notes to the DT documentation if this is how we want to proceed.

 That's a good point.

 Unfortunately, the timing is pretty bad (Thanksgiving) and the closest
 ASWG meeting is next Thursday, but that one's likely to be busy for other
 reasons.  I presume, then, that the earliest we can seriously get back to
 that in the ASWG is mid-December.

 --
 I speak only for myself.
 Rafael J. Wysocki, Intel Open Source Technology Center.
--
To unsubscribe from this list: send the line unsubscribe linux-kernel in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


[PATCH 2/2] ASoC: rt5677: add a platform config option for PDM clock divider

2014-11-14 Thread Ben Zhang
The PDM output clock can use a divider of 1/2/3/4 based on the system clock

Signed-off-by: Ben Zhang 
---
 Documentation/devicetree/bindings/sound/rt5677.txt | 5 +
 include/sound/rt5677.h | 8 
 sound/soc/codecs/rt5677.c  | 7 +++
 3 files changed, 20 insertions(+)

diff --git a/Documentation/devicetree/bindings/sound/rt5677.txt 
b/Documentation/devicetree/bindings/sound/rt5677.txt
index 740ff77..141f3e1 100644
--- a/Documentation/devicetree/bindings/sound/rt5677.txt
+++ b/Documentation/devicetree/bindings/sound/rt5677.txt
@@ -27,6 +27,10 @@ Optional properties:
   Boolean. Indicate MIC1/2 input and LOUT1/2/3 outputs are differential,
   rather than single-ended.
 
+- realtek,pdm_clk_div
+  Select 0/1/2/3 as PDM clock divider 1/2/4/3 respectively.
+  PDM clock = system clock / PDM clock divider
+
 - realtek,gpio-config
   Array of six 8bit elements that configures GPIO.
 0 - floating (reset value)
@@ -71,6 +75,7 @@ rt5677 {
realtek,pow-ldo2-gpio =
< TEGRA_GPIO(V, 3) GPIO_ACTIVE_HIGH>;
realtek,in1-differential = "true";
+   realtek,pdm_clk_div = <1>  /* PDM clock = system clock / 2 */
realtek,gpio-config = /bits/ 8  <0 0 0 0 0 2>;   /* pull up GPIO6 */
realtek,jd2-gpio = <3>;  /* Enables Jack detection for GPIO6 */
 };
diff --git a/include/sound/rt5677.h b/include/sound/rt5677.h
index d9eb7d8..368aa33 100644
--- a/include/sound/rt5677.h
+++ b/include/sound/rt5677.h
@@ -17,6 +17,12 @@ enum rt5677_dmic2_clk {
RT5677_DMIC_CLK2 = 1,
 };
 
+enum rt5677_pdm_clk_div {
+   RT5677_PDM_CLK_DIV1 = 0,
+   RT5677_PDM_CLK_DIV2 = 1,
+   RT5677_PDM_CLK_DIV4 = 2,
+   RT5677_PDM_CLK_DIV3 = 3,
+};
 
 struct rt5677_platform_data {
/* IN1/IN2/LOUT1/LOUT2/LOUT3 can optionally be differential */
@@ -27,6 +33,8 @@ struct rt5677_platform_data {
bool lout3_diff;
/* DMIC2 clock source selection */
enum rt5677_dmic2_clk dmic2_clk_pin;
+   /* System clock to PDM filter divider */
+   enum rt5677_pdm_clk_div pdm_clk_div;
 
/* configures GPIO, 0 - floating, 1 - pulldown, 2 - pullup */
u8 gpio_config[6];
diff --git a/sound/soc/codecs/rt5677.c b/sound/soc/codecs/rt5677.c
index 384281d..383cb61 100644
--- a/sound/soc/codecs/rt5677.c
+++ b/sound/soc/codecs/rt5677.c
@@ -4502,6 +4502,8 @@ static int rt5677_parse_dt(struct rt5677_priv *rt5677, 
struct device_node *np)
"realtek,lout2-differential");
rt5677->pdata.lout3_diff = of_property_read_bool(np,
"realtek,lout3-differential");
+   of_property_read_u32(np, "realtek,pdm_clk_div",
+   >pdata.pdm_clk_div);
 
rt5677->pow_ldo2 = of_get_named_gpio(np,
"realtek,pow-ldo2-gpio", 0);
@@ -4548,6 +4550,8 @@ static void rt5677_parse_acpi(struct rt5677_priv *rt5677, 
struct device *dev)
 {
rt5677->pdata.dmic2_clk_pin = (enum rt5677_dmic2_clk)
rt5677_parse_acpi_entry(dev, "DCLK");
+   rt5677->pdata.pdm_clk_div = (enum rt5677_pdm_clk_div)
+   rt5677_parse_acpi_entry(dev, "PCLK");
rt5677->pdata.in1_diff = (bool)rt5677_parse_acpi_entry(dev, "IN1");
rt5677->pdata.in2_diff = (bool)rt5677_parse_acpi_entry(dev, "IN2");
rt5677->pdata.lout1_diff = (bool)rt5677_parse_acpi_entry(dev, "OUT1");
@@ -4730,6 +4734,9 @@ static int rt5677_i2c_probe(struct i2c_client *i2c,
RT5677_GPIO5_DIR_OUT);
}
 
+   regmap_update_bits(rt5677->regmap, RT5677_PDM_DATA_CTRL1,
+   RT5677_PDM_DIV_MASK, rt5677->pdata.pdm_clk_div);
+
rt5677_init_gpio(i2c);
rt5677_irq_init(i2c);
 
-- 
2.1.0.rc2.206.gedb03e5

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


[PATCH 1/2] ASoC: rt5677: Add ACPI device probing

2014-11-14 Thread Ben Zhang
The rt5677 codec driver looks for ACPI device ID "RT5677CE",
which is specified in coreboot. This patch allows platform
data to be obtained via ACPI

Signed-off-by: Ben Zhang 
---
 sound/soc/codecs/rt5677.c | 52 +--
 1 file changed, 50 insertions(+), 2 deletions(-)

diff --git a/sound/soc/codecs/rt5677.c b/sound/soc/codecs/rt5677.c
index 5d317c68..384281d 100644
--- a/sound/soc/codecs/rt5677.c
+++ b/sound/soc/codecs/rt5677.c
@@ -20,6 +20,7 @@
 #include 
 #include 
 #include 
+#include 
 #include 
 #include 
 #include 
@@ -4525,6 +4526,43 @@ static int rt5677_parse_dt(struct rt5677_priv *rt5677, 
struct device_node *np)
return 0;
 }
 
+#ifdef CONFIG_ACPI
+
+static unsigned long long rt5677_parse_acpi_entry(struct device *dev,
+   acpi_string name)
+{
+   acpi_handle handle = ACPI_HANDLE(dev);
+   unsigned long long val;
+   acpi_status status;
+
+   status = acpi_evaluate_integer(handle, name, NULL, );
+   if (ACPI_FAILURE(status)) {
+   dev_err(dev, "Failed to parse ACPI entry %s, default to 0: 
%d\n",
+   name, status);
+   return 0;
+   }
+   return val;
+}
+
+static void rt5677_parse_acpi(struct rt5677_priv *rt5677, struct device *dev)
+{
+   rt5677->pdata.dmic2_clk_pin = (enum rt5677_dmic2_clk)
+   rt5677_parse_acpi_entry(dev, "DCLK");
+   rt5677->pdata.in1_diff = (bool)rt5677_parse_acpi_entry(dev, "IN1");
+   rt5677->pdata.in2_diff = (bool)rt5677_parse_acpi_entry(dev, "IN2");
+   rt5677->pdata.lout1_diff = (bool)rt5677_parse_acpi_entry(dev, "OUT1");
+   rt5677->pdata.lout2_diff = (bool)rt5677_parse_acpi_entry(dev, "OUT2");
+   rt5677->pdata.lout3_diff = (bool)rt5677_parse_acpi_entry(dev, "OUT3");
+   rt5677->pdata.jd1_gpio = rt5677_parse_acpi_entry(dev, "JD1");
+   rt5677->pdata.jd2_gpio = rt5677_parse_acpi_entry(dev, "JD2");
+   rt5677->pdata.jd3_gpio = rt5677_parse_acpi_entry(dev, "JD3");
+}
+#else
+static void rt5677_parse_acpi(struct rt5677_priv *rt5677, struct device *dev)
+{
+}
+#endif
+
 static struct regmap_irq rt5677_irqs[] = {
[RT5677_IRQ_JD1] = {
.reg_offset = 0,
@@ -4604,6 +4642,7 @@ static int rt5677_i2c_probe(struct i2c_client *i2c,
if (pdata)
rt5677->pdata = *pdata;
 
+   rt5677->pow_ldo2 = -EINVAL;
if (i2c->dev.of_node) {
ret = rt5677_parse_dt(rt5677, i2c->dev.of_node);
if (ret) {
@@ -4611,8 +4650,8 @@ static int rt5677_i2c_probe(struct i2c_client *i2c,
ret);
return ret;
}
-   } else {
-   rt5677->pow_ldo2 = -EINVAL;
+   } else if (ACPI_HANDLE(>dev)) {
+   rt5677_parse_acpi(rt5677, >dev);
}
 
if (gpio_is_valid(rt5677->pow_ldo2)) {
@@ -4708,10 +4747,19 @@ static int rt5677_i2c_remove(struct i2c_client *i2c)
return 0;
 }
 
+#ifdef CONFIG_ACPI
+static const struct acpi_device_id rt5677_acpi_id[] = {
+   { "RT5677CE", 0 },
+   { }
+};
+MODULE_DEVICE_TABLE(acpi, rt5677_acpi_id);
+#endif
+
 static struct i2c_driver rt5677_i2c_driver = {
.driver = {
.name = "rt5677",
.owner = THIS_MODULE,
+   .acpi_match_table = ACPI_PTR(rt5677_acpi_id),
},
.probe = rt5677_i2c_probe,
.remove   = rt5677_i2c_remove,
-- 
2.1.0.rc2.206.gedb03e5

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


[PATCH 2/2] ASoC: rt5677: add a platform config option for PDM clock divider

2014-11-14 Thread Ben Zhang
The PDM output clock can use a divider of 1/2/3/4 based on the system clock

Signed-off-by: Ben Zhang be...@chromium.org
---
 Documentation/devicetree/bindings/sound/rt5677.txt | 5 +
 include/sound/rt5677.h | 8 
 sound/soc/codecs/rt5677.c  | 7 +++
 3 files changed, 20 insertions(+)

diff --git a/Documentation/devicetree/bindings/sound/rt5677.txt 
b/Documentation/devicetree/bindings/sound/rt5677.txt
index 740ff77..141f3e1 100644
--- a/Documentation/devicetree/bindings/sound/rt5677.txt
+++ b/Documentation/devicetree/bindings/sound/rt5677.txt
@@ -27,6 +27,10 @@ Optional properties:
   Boolean. Indicate MIC1/2 input and LOUT1/2/3 outputs are differential,
   rather than single-ended.
 
+- realtek,pdm_clk_div
+  Select 0/1/2/3 as PDM clock divider 1/2/4/3 respectively.
+  PDM clock = system clock / PDM clock divider
+
 - realtek,gpio-config
   Array of six 8bit elements that configures GPIO.
 0 - floating (reset value)
@@ -71,6 +75,7 @@ rt5677 {
realtek,pow-ldo2-gpio =
gpio TEGRA_GPIO(V, 3) GPIO_ACTIVE_HIGH;
realtek,in1-differential = true;
+   realtek,pdm_clk_div = 1  /* PDM clock = system clock / 2 */
realtek,gpio-config = /bits/ 8  0 0 0 0 0 2;   /* pull up GPIO6 */
realtek,jd2-gpio = 3;  /* Enables Jack detection for GPIO6 */
 };
diff --git a/include/sound/rt5677.h b/include/sound/rt5677.h
index d9eb7d8..368aa33 100644
--- a/include/sound/rt5677.h
+++ b/include/sound/rt5677.h
@@ -17,6 +17,12 @@ enum rt5677_dmic2_clk {
RT5677_DMIC_CLK2 = 1,
 };
 
+enum rt5677_pdm_clk_div {
+   RT5677_PDM_CLK_DIV1 = 0,
+   RT5677_PDM_CLK_DIV2 = 1,
+   RT5677_PDM_CLK_DIV4 = 2,
+   RT5677_PDM_CLK_DIV3 = 3,
+};
 
 struct rt5677_platform_data {
/* IN1/IN2/LOUT1/LOUT2/LOUT3 can optionally be differential */
@@ -27,6 +33,8 @@ struct rt5677_platform_data {
bool lout3_diff;
/* DMIC2 clock source selection */
enum rt5677_dmic2_clk dmic2_clk_pin;
+   /* System clock to PDM filter divider */
+   enum rt5677_pdm_clk_div pdm_clk_div;
 
/* configures GPIO, 0 - floating, 1 - pulldown, 2 - pullup */
u8 gpio_config[6];
diff --git a/sound/soc/codecs/rt5677.c b/sound/soc/codecs/rt5677.c
index 384281d..383cb61 100644
--- a/sound/soc/codecs/rt5677.c
+++ b/sound/soc/codecs/rt5677.c
@@ -4502,6 +4502,8 @@ static int rt5677_parse_dt(struct rt5677_priv *rt5677, 
struct device_node *np)
realtek,lout2-differential);
rt5677-pdata.lout3_diff = of_property_read_bool(np,
realtek,lout3-differential);
+   of_property_read_u32(np, realtek,pdm_clk_div,
+   rt5677-pdata.pdm_clk_div);
 
rt5677-pow_ldo2 = of_get_named_gpio(np,
realtek,pow-ldo2-gpio, 0);
@@ -4548,6 +4550,8 @@ static void rt5677_parse_acpi(struct rt5677_priv *rt5677, 
struct device *dev)
 {
rt5677-pdata.dmic2_clk_pin = (enum rt5677_dmic2_clk)
rt5677_parse_acpi_entry(dev, DCLK);
+   rt5677-pdata.pdm_clk_div = (enum rt5677_pdm_clk_div)
+   rt5677_parse_acpi_entry(dev, PCLK);
rt5677-pdata.in1_diff = (bool)rt5677_parse_acpi_entry(dev, IN1);
rt5677-pdata.in2_diff = (bool)rt5677_parse_acpi_entry(dev, IN2);
rt5677-pdata.lout1_diff = (bool)rt5677_parse_acpi_entry(dev, OUT1);
@@ -4730,6 +4734,9 @@ static int rt5677_i2c_probe(struct i2c_client *i2c,
RT5677_GPIO5_DIR_OUT);
}
 
+   regmap_update_bits(rt5677-regmap, RT5677_PDM_DATA_CTRL1,
+   RT5677_PDM_DIV_MASK, rt5677-pdata.pdm_clk_div);
+
rt5677_init_gpio(i2c);
rt5677_irq_init(i2c);
 
-- 
2.1.0.rc2.206.gedb03e5

--
To unsubscribe from this list: send the line unsubscribe linux-kernel in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


[PATCH 1/2] ASoC: rt5677: Add ACPI device probing

2014-11-14 Thread Ben Zhang
The rt5677 codec driver looks for ACPI device ID RT5677CE,
which is specified in coreboot. This patch allows platform
data to be obtained via ACPI

Signed-off-by: Ben Zhang be...@chromium.org
---
 sound/soc/codecs/rt5677.c | 52 +--
 1 file changed, 50 insertions(+), 2 deletions(-)

diff --git a/sound/soc/codecs/rt5677.c b/sound/soc/codecs/rt5677.c
index 5d317c68..384281d 100644
--- a/sound/soc/codecs/rt5677.c
+++ b/sound/soc/codecs/rt5677.c
@@ -20,6 +20,7 @@
 #include linux/i2c.h
 #include linux/platform_device.h
 #include linux/spi/spi.h
+#include linux/acpi.h
 #include linux/firmware.h
 #include linux/gpio.h
 #include sound/core.h
@@ -4525,6 +4526,43 @@ static int rt5677_parse_dt(struct rt5677_priv *rt5677, 
struct device_node *np)
return 0;
 }
 
+#ifdef CONFIG_ACPI
+
+static unsigned long long rt5677_parse_acpi_entry(struct device *dev,
+   acpi_string name)
+{
+   acpi_handle handle = ACPI_HANDLE(dev);
+   unsigned long long val;
+   acpi_status status;
+
+   status = acpi_evaluate_integer(handle, name, NULL, val);
+   if (ACPI_FAILURE(status)) {
+   dev_err(dev, Failed to parse ACPI entry %s, default to 0: 
%d\n,
+   name, status);
+   return 0;
+   }
+   return val;
+}
+
+static void rt5677_parse_acpi(struct rt5677_priv *rt5677, struct device *dev)
+{
+   rt5677-pdata.dmic2_clk_pin = (enum rt5677_dmic2_clk)
+   rt5677_parse_acpi_entry(dev, DCLK);
+   rt5677-pdata.in1_diff = (bool)rt5677_parse_acpi_entry(dev, IN1);
+   rt5677-pdata.in2_diff = (bool)rt5677_parse_acpi_entry(dev, IN2);
+   rt5677-pdata.lout1_diff = (bool)rt5677_parse_acpi_entry(dev, OUT1);
+   rt5677-pdata.lout2_diff = (bool)rt5677_parse_acpi_entry(dev, OUT2);
+   rt5677-pdata.lout3_diff = (bool)rt5677_parse_acpi_entry(dev, OUT3);
+   rt5677-pdata.jd1_gpio = rt5677_parse_acpi_entry(dev, JD1);
+   rt5677-pdata.jd2_gpio = rt5677_parse_acpi_entry(dev, JD2);
+   rt5677-pdata.jd3_gpio = rt5677_parse_acpi_entry(dev, JD3);
+}
+#else
+static void rt5677_parse_acpi(struct rt5677_priv *rt5677, struct device *dev)
+{
+}
+#endif
+
 static struct regmap_irq rt5677_irqs[] = {
[RT5677_IRQ_JD1] = {
.reg_offset = 0,
@@ -4604,6 +4642,7 @@ static int rt5677_i2c_probe(struct i2c_client *i2c,
if (pdata)
rt5677-pdata = *pdata;
 
+   rt5677-pow_ldo2 = -EINVAL;
if (i2c-dev.of_node) {
ret = rt5677_parse_dt(rt5677, i2c-dev.of_node);
if (ret) {
@@ -4611,8 +4650,8 @@ static int rt5677_i2c_probe(struct i2c_client *i2c,
ret);
return ret;
}
-   } else {
-   rt5677-pow_ldo2 = -EINVAL;
+   } else if (ACPI_HANDLE(i2c-dev)) {
+   rt5677_parse_acpi(rt5677, i2c-dev);
}
 
if (gpio_is_valid(rt5677-pow_ldo2)) {
@@ -4708,10 +4747,19 @@ static int rt5677_i2c_remove(struct i2c_client *i2c)
return 0;
 }
 
+#ifdef CONFIG_ACPI
+static const struct acpi_device_id rt5677_acpi_id[] = {
+   { RT5677CE, 0 },
+   { }
+};
+MODULE_DEVICE_TABLE(acpi, rt5677_acpi_id);
+#endif
+
 static struct i2c_driver rt5677_i2c_driver = {
.driver = {
.name = rt5677,
.owner = THIS_MODULE,
+   .acpi_match_table = ACPI_PTR(rt5677_acpi_id),
},
.probe = rt5677_i2c_probe,
.remove   = rt5677_i2c_remove,
-- 
2.1.0.rc2.206.gedb03e5

--
To unsubscribe from this list: send the line unsubscribe linux-kernel in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


[PATCH] pstore/ram: strip ramoops header for correct decompression

2014-10-30 Thread Ben Zhang
pstore compression/decompression was added during 3.12.
The ramoops driver prepends a "timestamp.timestamp-C|D\n"
header to the compressed record before handing it over to pstore
driver which doesn't know about the header. In pstore_decompress(),
the pstore driver reads the first "==" as a zlib header, so the
decompression always fails. For example, this causes the driver
to write /dev/pstore/dmesg-ramoops-0.enc.z instead of
/dev/pstore/dmesg-ramoops-0.

This patch makes the ramoops driver remove the header before
pstore decompression.

Signed-off-by: Ben Zhang 
---
 fs/pstore/ram.c | 22 +++---
 1 file changed, 15 insertions(+), 7 deletions(-)

diff --git a/fs/pstore/ram.c b/fs/pstore/ram.c
index 3b57443..ec881b3 100644
--- a/fs/pstore/ram.c
+++ b/fs/pstore/ram.c
@@ -135,25 +135,27 @@ ramoops_get_next_prz(struct persistent_ram_zone *przs[], 
uint *c, uint max,
return prz;
 }
 
-static void ramoops_read_kmsg_hdr(char *buffer, struct timespec *time,
+static int ramoops_read_kmsg_hdr(char *buffer, struct timespec *time,
  bool *compressed)
 {
char data_type;
+   int header_length = 0;
 
-   if (sscanf(buffer, RAMOOPS_KERNMSG_HDR "%lu.%lu-%c\n",
-   >tv_sec, >tv_nsec, _type) == 3) {
+   if (sscanf(buffer, RAMOOPS_KERNMSG_HDR "%lu.%lu-%c\n%n", >tv_sec,
+   >tv_nsec, _type, _length) == 3) {
if (data_type == 'C')
*compressed = true;
else
*compressed = false;
-   } else if (sscanf(buffer, RAMOOPS_KERNMSG_HDR "%lu.%lu\n",
-   >tv_sec, >tv_nsec) == 2) {
+   } else if (sscanf(buffer, RAMOOPS_KERNMSG_HDR "%lu.%lu\n%n",
+   >tv_sec, >tv_nsec, _length) == 2) {
*compressed = false;
} else {
time->tv_sec = 0;
time->tv_nsec = 0;
*compressed = false;
}
+   return header_length;
 }
 
 static ssize_t ramoops_pstore_read(u64 *id, enum pstore_type_id *type,
@@ -165,6 +167,7 @@ static ssize_t ramoops_pstore_read(u64 *id, enum 
pstore_type_id *type,
ssize_t ecc_notice_size;
struct ramoops_context *cxt = psi->data;
struct persistent_ram_zone *prz;
+   int header_length;
 
prz = ramoops_get_next_prz(cxt->przs, >dump_read_cnt,
   cxt->max_dump_cnt, id, type,
@@ -178,7 +181,13 @@ static ssize_t ramoops_pstore_read(u64 *id, enum 
pstore_type_id *type,
if (!prz)
return 0;
 
+   if (!persistent_ram_old(prz))
+   return 0;
+
size = persistent_ram_old_size(prz);
+   header_length = ramoops_read_kmsg_hdr(persistent_ram_old(prz), time,
+   compressed);
+   size -= header_length;
 
/* ECC correction notice */
ecc_notice_size = persistent_ram_ecc_string(prz, NULL, 0);
@@ -187,8 +196,7 @@ static ssize_t ramoops_pstore_read(u64 *id, enum 
pstore_type_id *type,
if (*buf == NULL)
return -ENOMEM;
 
-   memcpy(*buf, persistent_ram_old(prz), size);
-   ramoops_read_kmsg_hdr(*buf, time, compressed);
+   memcpy(*buf, (char *)persistent_ram_old(prz) + header_length, size);
persistent_ram_ecc_string(prz, *buf + size, ecc_notice_size + 1);
 
return size + ecc_notice_size;
-- 
2.1.0.rc2.206.gedb03e5

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


[PATCH] pstore/ram: strip ramoops header for correct decompression

2014-10-30 Thread Ben Zhang
pstore compression/decompression was added during 3.12.
The ramoops driver prepends a timestamp.timestamp-C|D\n
header to the compressed record before handing it over to pstore
driver which doesn't know about the header. In pstore_decompress(),
the pstore driver reads the first == as a zlib header, so the
decompression always fails. For example, this causes the driver
to write /dev/pstore/dmesg-ramoops-0.enc.z instead of
/dev/pstore/dmesg-ramoops-0.

This patch makes the ramoops driver remove the header before
pstore decompression.

Signed-off-by: Ben Zhang be...@chromium.org
---
 fs/pstore/ram.c | 22 +++---
 1 file changed, 15 insertions(+), 7 deletions(-)

diff --git a/fs/pstore/ram.c b/fs/pstore/ram.c
index 3b57443..ec881b3 100644
--- a/fs/pstore/ram.c
+++ b/fs/pstore/ram.c
@@ -135,25 +135,27 @@ ramoops_get_next_prz(struct persistent_ram_zone *przs[], 
uint *c, uint max,
return prz;
 }
 
-static void ramoops_read_kmsg_hdr(char *buffer, struct timespec *time,
+static int ramoops_read_kmsg_hdr(char *buffer, struct timespec *time,
  bool *compressed)
 {
char data_type;
+   int header_length = 0;
 
-   if (sscanf(buffer, RAMOOPS_KERNMSG_HDR %lu.%lu-%c\n,
-   time-tv_sec, time-tv_nsec, data_type) == 3) {
+   if (sscanf(buffer, RAMOOPS_KERNMSG_HDR %lu.%lu-%c\n%n, time-tv_sec,
+   time-tv_nsec, data_type, header_length) == 3) {
if (data_type == 'C')
*compressed = true;
else
*compressed = false;
-   } else if (sscanf(buffer, RAMOOPS_KERNMSG_HDR %lu.%lu\n,
-   time-tv_sec, time-tv_nsec) == 2) {
+   } else if (sscanf(buffer, RAMOOPS_KERNMSG_HDR %lu.%lu\n%n,
+   time-tv_sec, time-tv_nsec, header_length) == 2) {
*compressed = false;
} else {
time-tv_sec = 0;
time-tv_nsec = 0;
*compressed = false;
}
+   return header_length;
 }
 
 static ssize_t ramoops_pstore_read(u64 *id, enum pstore_type_id *type,
@@ -165,6 +167,7 @@ static ssize_t ramoops_pstore_read(u64 *id, enum 
pstore_type_id *type,
ssize_t ecc_notice_size;
struct ramoops_context *cxt = psi-data;
struct persistent_ram_zone *prz;
+   int header_length;
 
prz = ramoops_get_next_prz(cxt-przs, cxt-dump_read_cnt,
   cxt-max_dump_cnt, id, type,
@@ -178,7 +181,13 @@ static ssize_t ramoops_pstore_read(u64 *id, enum 
pstore_type_id *type,
if (!prz)
return 0;
 
+   if (!persistent_ram_old(prz))
+   return 0;
+
size = persistent_ram_old_size(prz);
+   header_length = ramoops_read_kmsg_hdr(persistent_ram_old(prz), time,
+   compressed);
+   size -= header_length;
 
/* ECC correction notice */
ecc_notice_size = persistent_ram_ecc_string(prz, NULL, 0);
@@ -187,8 +196,7 @@ static ssize_t ramoops_pstore_read(u64 *id, enum 
pstore_type_id *type,
if (*buf == NULL)
return -ENOMEM;
 
-   memcpy(*buf, persistent_ram_old(prz), size);
-   ramoops_read_kmsg_hdr(*buf, time, compressed);
+   memcpy(*buf, (char *)persistent_ram_old(prz) + header_length, size);
persistent_ram_ecc_string(prz, *buf + size, ecc_notice_size + 1);
 
return size + ecc_notice_size;
-- 
2.1.0.rc2.206.gedb03e5

--
To unsubscribe from this list: send the line unsubscribe linux-kernel in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


[PATCH] ASoC: rt5677: fix rt5677 spi driver build

2014-10-20 Thread Ben Zhang
Create a separate module for rt5677 spi driver. Without
this patch, the build fails due to multiple defs of
'init_module' and 'cleanup_module'. module_spi_driver()
defines its own module, so it can't be part of the rt5677
module.

Signed-off-by: Ben Zhang 
---
 sound/soc/codecs/Kconfig  | 4 
 sound/soc/codecs/Makefile | 4 +++-
 sound/soc/codecs/rt5677-spi.c | 2 ++
 3 files changed, 9 insertions(+), 1 deletion(-)

diff --git a/sound/soc/codecs/Kconfig b/sound/soc/codecs/Kconfig
index 2c7482e..6f21a76 100644
--- a/sound/soc/codecs/Kconfig
+++ b/sound/soc/codecs/Kconfig
@@ -504,6 +504,10 @@ config SND_SOC_RT5670
 config SND_SOC_RT5677
tristate
 
+config SND_SOC_RT5677_SPI
+   tristate
+   default SND_SOC_RT5677
+
 #Freescale sgtl5000 codec
 config SND_SOC_SGTL5000
tristate "Freescale SGTL5000 CODEC"
diff --git a/sound/soc/codecs/Makefile b/sound/soc/codecs/Makefile
index 4435f9f..3e57edc 100644
--- a/sound/soc/codecs/Makefile
+++ b/sound/soc/codecs/Makefile
@@ -79,7 +79,8 @@ snd-soc-rt5640-objs := rt5640.o
 snd-soc-rt5645-objs := rt5645.o
 snd-soc-rt5651-objs := rt5651.o
 snd-soc-rt5670-objs := rt5670.o
-snd-soc-rt5677-objs := rt5677.o rt5677-spi.o
+snd-soc-rt5677-objs := rt5677.o
+snd-soc-rt5677-spi-objs := rt5677-spi.o
 snd-soc-sgtl5000-objs := sgtl5000.o
 snd-soc-alc5623-objs := alc5623.o
 snd-soc-alc5632-objs := alc5632.o
@@ -256,6 +257,7 @@ obj-$(CONFIG_SND_SOC_RT5645)+= snd-soc-rt5645.o
 obj-$(CONFIG_SND_SOC_RT5651)   += snd-soc-rt5651.o
 obj-$(CONFIG_SND_SOC_RT5670)   += snd-soc-rt5670.o
 obj-$(CONFIG_SND_SOC_RT5677)   += snd-soc-rt5677.o
+obj-$(CONFIG_SND_SOC_RT5677_SPI)   += snd-soc-rt5677-spi.o
 obj-$(CONFIG_SND_SOC_SGTL5000)  += snd-soc-sgtl5000.o
 obj-$(CONFIG_SND_SOC_SIGMADSP) += snd-soc-sigmadsp.o
 obj-$(CONFIG_SND_SOC_SIGMADSP_I2C) += snd-soc-sigmadsp-i2c.o
diff --git a/sound/soc/codecs/rt5677-spi.c b/sound/soc/codecs/rt5677-spi.c
index 11c38f3..ef6348c 100644
--- a/sound/soc/codecs/rt5677-spi.c
+++ b/sound/soc/codecs/rt5677-spi.c
@@ -52,6 +52,7 @@ int rt5677_spi_write(u8 *txbuf, size_t len)
 
return status;
 }
+EXPORT_SYMBOL_GPL(rt5677_spi_write);
 
 /**
  * rt5677_spi_burst_write - Write data to SPI by rt5677 dsp memory address.
@@ -107,6 +108,7 @@ int rt5677_spi_burst_write(u32 addr, const struct firmware 
*fw)
 
return 0;
 }
+EXPORT_SYMBOL_GPL(rt5677_spi_burst_write);
 
 static int rt5677_spi_probe(struct spi_device *spi)
 {
-- 
2.1.0.rc2.206.gedb03e5

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


[PATCH] ASoC: rt5677: fix rt5677 spi driver build

2014-10-20 Thread Ben Zhang
Create a separate module for rt5677 spi driver. Without
this patch, the build fails due to multiple defs of
'init_module' and 'cleanup_module'. module_spi_driver()
defines its own module, so it can't be part of the rt5677
module.

Signed-off-by: Ben Zhang be...@chromium.org
---
 sound/soc/codecs/Kconfig  | 4 
 sound/soc/codecs/Makefile | 4 +++-
 sound/soc/codecs/rt5677-spi.c | 2 ++
 3 files changed, 9 insertions(+), 1 deletion(-)

diff --git a/sound/soc/codecs/Kconfig b/sound/soc/codecs/Kconfig
index 2c7482e..6f21a76 100644
--- a/sound/soc/codecs/Kconfig
+++ b/sound/soc/codecs/Kconfig
@@ -504,6 +504,10 @@ config SND_SOC_RT5670
 config SND_SOC_RT5677
tristate
 
+config SND_SOC_RT5677_SPI
+   tristate
+   default SND_SOC_RT5677
+
 #Freescale sgtl5000 codec
 config SND_SOC_SGTL5000
tristate Freescale SGTL5000 CODEC
diff --git a/sound/soc/codecs/Makefile b/sound/soc/codecs/Makefile
index 4435f9f..3e57edc 100644
--- a/sound/soc/codecs/Makefile
+++ b/sound/soc/codecs/Makefile
@@ -79,7 +79,8 @@ snd-soc-rt5640-objs := rt5640.o
 snd-soc-rt5645-objs := rt5645.o
 snd-soc-rt5651-objs := rt5651.o
 snd-soc-rt5670-objs := rt5670.o
-snd-soc-rt5677-objs := rt5677.o rt5677-spi.o
+snd-soc-rt5677-objs := rt5677.o
+snd-soc-rt5677-spi-objs := rt5677-spi.o
 snd-soc-sgtl5000-objs := sgtl5000.o
 snd-soc-alc5623-objs := alc5623.o
 snd-soc-alc5632-objs := alc5632.o
@@ -256,6 +257,7 @@ obj-$(CONFIG_SND_SOC_RT5645)+= snd-soc-rt5645.o
 obj-$(CONFIG_SND_SOC_RT5651)   += snd-soc-rt5651.o
 obj-$(CONFIG_SND_SOC_RT5670)   += snd-soc-rt5670.o
 obj-$(CONFIG_SND_SOC_RT5677)   += snd-soc-rt5677.o
+obj-$(CONFIG_SND_SOC_RT5677_SPI)   += snd-soc-rt5677-spi.o
 obj-$(CONFIG_SND_SOC_SGTL5000)  += snd-soc-sgtl5000.o
 obj-$(CONFIG_SND_SOC_SIGMADSP) += snd-soc-sigmadsp.o
 obj-$(CONFIG_SND_SOC_SIGMADSP_I2C) += snd-soc-sigmadsp-i2c.o
diff --git a/sound/soc/codecs/rt5677-spi.c b/sound/soc/codecs/rt5677-spi.c
index 11c38f3..ef6348c 100644
--- a/sound/soc/codecs/rt5677-spi.c
+++ b/sound/soc/codecs/rt5677-spi.c
@@ -52,6 +52,7 @@ int rt5677_spi_write(u8 *txbuf, size_t len)
 
return status;
 }
+EXPORT_SYMBOL_GPL(rt5677_spi_write);
 
 /**
  * rt5677_spi_burst_write - Write data to SPI by rt5677 dsp memory address.
@@ -107,6 +108,7 @@ int rt5677_spi_burst_write(u32 addr, const struct firmware 
*fw)
 
return 0;
 }
+EXPORT_SYMBOL_GPL(rt5677_spi_burst_write);
 
 static int rt5677_spi_probe(struct spi_device *spi)
 {
-- 
2.1.0.rc2.206.gedb03e5

--
To unsubscribe from this list: send the line unsubscribe linux-kernel in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


[PATCH 3/3] ASoC: rt5677: Add jack detection support

2014-10-03 Thread Ben Zhang
This patch adds support for jack detection using GPIOs on the codec.
Plug detect signal and mic present signal can be routed from the physical
audio jack to GPIOs on the codec. The codec is configured so that upon
signal change, an IRQ(GPIO1) is fired. The codec interrupt handler reads
related status registers, figures out what has been plugged/unplugged from
the audio jack, and report jack states via snd_soc_jack_report().

ASoC machine driver should register audio jacks for detection with the
codec driver using rt5677_register_jack_detect().

Board setup code should assign GPIOs receiving plug detect/mic present
signal to the codec device itself, via Device Tree, ACPI or platform data.
The corresponding GPIO indexes are:
RT5677_GPIO_PLUG_DET - 0
RT5677_GPIO_MIC_PRESENT_L - 1

Signed-off-by: Ben Zhang 
---
 sound/soc/codecs/rt5677.c | 179 ++
 sound/soc/codecs/rt5677.h |  92 
 2 files changed, 271 insertions(+)

diff --git a/sound/soc/codecs/rt5677.c b/sound/soc/codecs/rt5677.c
index 19dbb8a..99f4d1a 100644
--- a/sound/soc/codecs/rt5677.c
+++ b/sound/soc/codecs/rt5677.c
@@ -29,6 +29,7 @@
 #include 
 #include 
 #include 
+#include 
 
 #include "rl6231.h"
 #include "rt5677.h"
@@ -3341,6 +3342,25 @@ static void rt5677_free_gpio(struct i2c_client *i2c)
 
gpiochip_remove(>gpio_chip);
 }
+
+static void rt5677_request_codec_gpios(struct rt5677_priv *rt5677,
+   struct i2c_client *i2c)
+{
+   struct gpio_desc *desc;
+
+   desc = devm_gpiod_get_index(>dev, "RT5677_GPIO",
+   RT5677_GPIO_PLUG_DET);
+   if (!IS_ERR(desc) && !gpiod_direction_input(desc))
+   rt5677->gpio_plug_det = desc_to_gpio(desc)
+   - rt5677->gpio_chip.base + 1;
+
+   desc = devm_gpiod_get_index(>dev, "RT5677_GPIO",
+   RT5677_GPIO_MIC_PRESENT_L);
+   if (!IS_ERR(desc) && !gpiod_direction_input(desc))
+   rt5677->gpio_mic_present_l = desc_to_gpio(desc)
+   - rt5677->gpio_chip.base + 1;
+}
+
 #else
 static void rt5677_init_gpio(struct i2c_client *i2c)
 {
@@ -3349,8 +3369,155 @@ static void rt5677_init_gpio(struct i2c_client *i2c)
 static void rt5677_free_gpio(struct i2c_client *i2c)
 {
 }
+static void rt5677_request_codec_gpios(struct rt5677_priv *rt5677,
+   struct i2c_client *i2c)
+{
+}
 #endif
 
+static void rt5677_report_jack_status(struct rt5677_priv *rt5677, int reg_irq)
+{
+   /* reg_irq: IRQ Control register MX-BDh */
+   int polarity;
+   if (reg_irq & RT5677_JD2_STATUS_MASK) {
+   polarity = reg_irq & RT5677_JD2_POLARITY_MASK;
+   if (rt5677->headphone_jack) {
+   snd_soc_jack_report(rt5677->headphone_jack,
+   polarity ? SND_JACK_HEADPHONE : 0,
+   SND_JACK_HEADPHONE);
+   }
+   }
+
+   if (reg_irq & RT5677_JD3_STATUS_MASK) {
+   polarity = reg_irq & RT5677_JD3_POLARITY_MASK;
+   if (rt5677->mic_jack) {
+   snd_soc_jack_report(rt5677->mic_jack,
+   polarity ? 0 : SND_JACK_MICROPHONE,
+   SND_JACK_MICROPHONE);
+   }
+   }
+}
+
+static irqreturn_t rt5677_irq(int unused, void *data)
+{
+   struct rt5677_priv *rt5677 = data;
+   int ret = 0, i;
+   bool irq_fired;
+   int reg_irq;
+
+   /*
+* Loop to handle interrupts until the last i2c read shows no pending
+* irqs with a safeguard of 20 loops
+*/
+   for (i = 0; i < 20; i++) {
+   /* Read interrupt status */
+   ret = regmap_read(rt5677->regmap, RT5677_IRQ_CTRL1, _irq);
+   if (ret)
+   break;
+
+   /* Flip polarity for interrupts that just fired  */
+   irq_fired = false;
+   if (reg_irq & RT5677_JD2_STATUS_MASK) {
+   reg_irq ^= RT5677_JD2_POLARITY_MASK;
+   irq_fired = true;
+   }
+
+   if (reg_irq & RT5677_JD3_STATUS_MASK) {
+   reg_irq ^= RT5677_JD3_POLARITY_MASK;
+   irq_fired = true;
+   }
+
+   if (!irq_fired)
+   break;
+
+   /* Clear interrupts */
+   ret = regmap_write(rt5677->regmap, RT5677_IRQ_CTRL1, reg_irq);
+   if (ret)
+   break;
+
+   /* Process interrupts */
+   rt5677_report_jack_status(rt5677, reg_irq);
+   }
+   return IRQ_HANDLED;
+}
+
+int rt5677_register_jack_detect(struct snd_soc_codec *codec,
+   struct snd_soc_jack *headphone_jack, struct snd_soc_jack *mic_jack)
+{
+   struct rt5677_pr

[PATCH 2/3] ASoC: rt5677: Add ACPI device probing

2014-10-03 Thread Ben Zhang
The rt5677 codec driver looks for ACPI device ID "RT5677CE",
which is specified in coreboot.

Signed-off-by: Ben Zhang 
Reviewed-on: https://chromium-review.googlesource.com/207622
Reviewed-by: Dylan Reid 
Reviewed-by: AndyX C Huang 
---
 sound/soc/codecs/rt5677.c | 12 
 1 file changed, 12 insertions(+)

diff --git a/sound/soc/codecs/rt5677.c b/sound/soc/codecs/rt5677.c
index cecbdb1..19dbb8a 100644
--- a/sound/soc/codecs/rt5677.c
+++ b/sound/soc/codecs/rt5677.c
@@ -20,6 +20,7 @@
 #include 
 #include 
 #include 
+#include 
 #include 
 #include 
 #include 
@@ -3680,10 +3681,21 @@ static int rt5677_i2c_remove(struct i2c_client *i2c)
return 0;
 }
 
+#ifdef CONFIG_ACPI
+static const struct acpi_device_id rt5677_acpi_id[] = {
+   { "RT5677CE", 0 },
+   { }
+};
+MODULE_DEVICE_TABLE(acpi, rt5677_acpi_id);
+#endif
+
 static struct i2c_driver rt5677_i2c_driver = {
.driver = {
.name = "rt5677",
.owner = THIS_MODULE,
+#ifdef CONFIG_ACPI
+   .acpi_match_table = ACPI_PTR(rt5677_acpi_id),
+#endif
},
.probe = rt5677_i2c_probe,
.remove   = rt5677_i2c_remove,
-- 
2.1.0.rc2.206.gedb03e5

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


[PATCH 1/3] ASoC: rt5677: Include gpio driver header

2014-10-03 Thread Ben Zhang
The header file is needed because struct gpio_chip is
placed in struct rt5677_priv.

Signed-off-by: Ben Zhang 
---
 sound/soc/codecs/rt5677.h | 1 +
 1 file changed, 1 insertion(+)

diff --git a/sound/soc/codecs/rt5677.h b/sound/soc/codecs/rt5677.h
index d4eb6d5..99fd023 100644
--- a/sound/soc/codecs/rt5677.h
+++ b/sound/soc/codecs/rt5677.h
@@ -13,6 +13,7 @@
 #define __RT5677_H__
 
 #include 
+#include 
 
 /* Info */
 #define RT5677_RESET   0x00
-- 
2.1.0.rc2.206.gedb03e5

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


[PATCH 1/3] ASoC: rt5677: Include gpio driver header

2014-10-03 Thread Ben Zhang
The header file is needed because struct gpio_chip is
placed in struct rt5677_priv.

Signed-off-by: Ben Zhang be...@chromium.org
---
 sound/soc/codecs/rt5677.h | 1 +
 1 file changed, 1 insertion(+)

diff --git a/sound/soc/codecs/rt5677.h b/sound/soc/codecs/rt5677.h
index d4eb6d5..99fd023 100644
--- a/sound/soc/codecs/rt5677.h
+++ b/sound/soc/codecs/rt5677.h
@@ -13,6 +13,7 @@
 #define __RT5677_H__
 
 #include sound/rt5677.h
+#include linux/gpio/driver.h
 
 /* Info */
 #define RT5677_RESET   0x00
-- 
2.1.0.rc2.206.gedb03e5

--
To unsubscribe from this list: send the line unsubscribe linux-kernel in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


[PATCH 2/3] ASoC: rt5677: Add ACPI device probing

2014-10-03 Thread Ben Zhang
The rt5677 codec driver looks for ACPI device ID RT5677CE,
which is specified in coreboot.

Signed-off-by: Ben Zhang be...@chromium.org
Reviewed-on: https://chromium-review.googlesource.com/207622
Reviewed-by: Dylan Reid dgr...@chromium.org
Reviewed-by: AndyX C Huang andyx.c.hu...@intel.com
---
 sound/soc/codecs/rt5677.c | 12 
 1 file changed, 12 insertions(+)

diff --git a/sound/soc/codecs/rt5677.c b/sound/soc/codecs/rt5677.c
index cecbdb1..19dbb8a 100644
--- a/sound/soc/codecs/rt5677.c
+++ b/sound/soc/codecs/rt5677.c
@@ -20,6 +20,7 @@
 #include linux/i2c.h
 #include linux/platform_device.h
 #include linux/spi/spi.h
+#include linux/acpi.h
 #include linux/gpio.h
 #include sound/core.h
 #include sound/pcm.h
@@ -3680,10 +3681,21 @@ static int rt5677_i2c_remove(struct i2c_client *i2c)
return 0;
 }
 
+#ifdef CONFIG_ACPI
+static const struct acpi_device_id rt5677_acpi_id[] = {
+   { RT5677CE, 0 },
+   { }
+};
+MODULE_DEVICE_TABLE(acpi, rt5677_acpi_id);
+#endif
+
 static struct i2c_driver rt5677_i2c_driver = {
.driver = {
.name = rt5677,
.owner = THIS_MODULE,
+#ifdef CONFIG_ACPI
+   .acpi_match_table = ACPI_PTR(rt5677_acpi_id),
+#endif
},
.probe = rt5677_i2c_probe,
.remove   = rt5677_i2c_remove,
-- 
2.1.0.rc2.206.gedb03e5

--
To unsubscribe from this list: send the line unsubscribe linux-kernel in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


[PATCH 3/3] ASoC: rt5677: Add jack detection support

2014-10-03 Thread Ben Zhang
This patch adds support for jack detection using GPIOs on the codec.
Plug detect signal and mic present signal can be routed from the physical
audio jack to GPIOs on the codec. The codec is configured so that upon
signal change, an IRQ(GPIO1) is fired. The codec interrupt handler reads
related status registers, figures out what has been plugged/unplugged from
the audio jack, and report jack states via snd_soc_jack_report().

ASoC machine driver should register audio jacks for detection with the
codec driver using rt5677_register_jack_detect().

Board setup code should assign GPIOs receiving plug detect/mic present
signal to the codec device itself, via Device Tree, ACPI or platform data.
The corresponding GPIO indexes are:
RT5677_GPIO_PLUG_DET - 0
RT5677_GPIO_MIC_PRESENT_L - 1

Signed-off-by: Ben Zhang be...@chromium.org
---
 sound/soc/codecs/rt5677.c | 179 ++
 sound/soc/codecs/rt5677.h |  92 
 2 files changed, 271 insertions(+)

diff --git a/sound/soc/codecs/rt5677.c b/sound/soc/codecs/rt5677.c
index 19dbb8a..99f4d1a 100644
--- a/sound/soc/codecs/rt5677.c
+++ b/sound/soc/codecs/rt5677.c
@@ -29,6 +29,7 @@
 #include sound/soc-dapm.h
 #include sound/initval.h
 #include sound/tlv.h
+#include sound/jack.h
 
 #include rl6231.h
 #include rt5677.h
@@ -3341,6 +3342,25 @@ static void rt5677_free_gpio(struct i2c_client *i2c)
 
gpiochip_remove(rt5677-gpio_chip);
 }
+
+static void rt5677_request_codec_gpios(struct rt5677_priv *rt5677,
+   struct i2c_client *i2c)
+{
+   struct gpio_desc *desc;
+
+   desc = devm_gpiod_get_index(i2c-dev, RT5677_GPIO,
+   RT5677_GPIO_PLUG_DET);
+   if (!IS_ERR(desc)  !gpiod_direction_input(desc))
+   rt5677-gpio_plug_det = desc_to_gpio(desc)
+   - rt5677-gpio_chip.base + 1;
+
+   desc = devm_gpiod_get_index(i2c-dev, RT5677_GPIO,
+   RT5677_GPIO_MIC_PRESENT_L);
+   if (!IS_ERR(desc)  !gpiod_direction_input(desc))
+   rt5677-gpio_mic_present_l = desc_to_gpio(desc)
+   - rt5677-gpio_chip.base + 1;
+}
+
 #else
 static void rt5677_init_gpio(struct i2c_client *i2c)
 {
@@ -3349,8 +3369,155 @@ static void rt5677_init_gpio(struct i2c_client *i2c)
 static void rt5677_free_gpio(struct i2c_client *i2c)
 {
 }
+static void rt5677_request_codec_gpios(struct rt5677_priv *rt5677,
+   struct i2c_client *i2c)
+{
+}
 #endif
 
+static void rt5677_report_jack_status(struct rt5677_priv *rt5677, int reg_irq)
+{
+   /* reg_irq: IRQ Control register MX-BDh */
+   int polarity;
+   if (reg_irq  RT5677_JD2_STATUS_MASK) {
+   polarity = reg_irq  RT5677_JD2_POLARITY_MASK;
+   if (rt5677-headphone_jack) {
+   snd_soc_jack_report(rt5677-headphone_jack,
+   polarity ? SND_JACK_HEADPHONE : 0,
+   SND_JACK_HEADPHONE);
+   }
+   }
+
+   if (reg_irq  RT5677_JD3_STATUS_MASK) {
+   polarity = reg_irq  RT5677_JD3_POLARITY_MASK;
+   if (rt5677-mic_jack) {
+   snd_soc_jack_report(rt5677-mic_jack,
+   polarity ? 0 : SND_JACK_MICROPHONE,
+   SND_JACK_MICROPHONE);
+   }
+   }
+}
+
+static irqreturn_t rt5677_irq(int unused, void *data)
+{
+   struct rt5677_priv *rt5677 = data;
+   int ret = 0, i;
+   bool irq_fired;
+   int reg_irq;
+
+   /*
+* Loop to handle interrupts until the last i2c read shows no pending
+* irqs with a safeguard of 20 loops
+*/
+   for (i = 0; i  20; i++) {
+   /* Read interrupt status */
+   ret = regmap_read(rt5677-regmap, RT5677_IRQ_CTRL1, reg_irq);
+   if (ret)
+   break;
+
+   /* Flip polarity for interrupts that just fired  */
+   irq_fired = false;
+   if (reg_irq  RT5677_JD2_STATUS_MASK) {
+   reg_irq ^= RT5677_JD2_POLARITY_MASK;
+   irq_fired = true;
+   }
+
+   if (reg_irq  RT5677_JD3_STATUS_MASK) {
+   reg_irq ^= RT5677_JD3_POLARITY_MASK;
+   irq_fired = true;
+   }
+
+   if (!irq_fired)
+   break;
+
+   /* Clear interrupts */
+   ret = regmap_write(rt5677-regmap, RT5677_IRQ_CTRL1, reg_irq);
+   if (ret)
+   break;
+
+   /* Process interrupts */
+   rt5677_report_jack_status(rt5677, reg_irq);
+   }
+   return IRQ_HANDLED;
+}
+
+int rt5677_register_jack_detect(struct snd_soc_codec *codec,
+   struct snd_soc_jack *headphone_jack, struct snd_soc_jack *mic_jack)
+{
+   struct rt5677_priv *rt5677 = snd_soc_codec_get_drvdata(codec);
+
+   rt5677

[PATCH] watchdog: touch_nmi_watchdog should only touch local cpu not every one

2013-12-05 Thread Ben Zhang
I ran into a scenario where while one cpu was stuck and should have panic'd
because of the NMI watchdog, it didn't.  The reason was another cpu was spewing
stack dumps on to the console.  Upon investigation, I noticed that when writing
to the console and also when dumping the stack, the watchdog is touched.

This causes all the cpus to reset their NMI watchdog flags and the 'stuck' cpu
just spins forever.

This change causes the semantics of touch_nmi_watchdog to be changed slightly.
Previously, I accidentally changed the semantics and we noticed there was a
codepath in which touch_nmi_watchdog could be touched from a preemtible area.
That caused a BUG() to happen when CONFIG_DEBUG_PREEMPT was enabled.  I believe
it was the acpi code.

My attempt here re-introduces the change to have the touch_nmi_watchdog() code
only touch the local cpu instead of all of the cpus.  But instead of using
__get_cpu_var(), I use the __raw_get_cpu_var() version.

This avoids the preemption problem.  However my reasoning wasn't because I was
trying to be lazy.  Instead I rationalized it as, well if preemption is enabled
then interrupts should be enabled to and the NMI watchdog will have no reason
to trigger.  So it won't matter if the wrong cpu is touched because the percpu
interrupt counters the NMI watchdog uses should still be incrementing.

Signed-off-by: Don Zickus 
Signed-off-by: Ben Zhang 
---
 kernel/watchdog.c | 16 
 1 file changed, 8 insertions(+), 8 deletions(-)

diff --git a/kernel/watchdog.c b/kernel/watchdog.c
index 4431610..613f611 100644
--- a/kernel/watchdog.c
+++ b/kernel/watchdog.c
@@ -158,14 +158,14 @@ void touch_all_softlockup_watchdogs(void)
 #ifdef CONFIG_HARDLOCKUP_DETECTOR
 void touch_nmi_watchdog(void)
 {
-   if (watchdog_user_enabled) {
-   unsigned cpu;
-
-   for_each_present_cpu(cpu) {
-   if (per_cpu(watchdog_nmi_touch, cpu) != true)
-   per_cpu(watchdog_nmi_touch, cpu) = true;
-   }
-   }
+   /*
+* Using __raw here because some code paths have
+* preemption enabled.  If preemption is enabled
+* then interrupts should be enabled too, in which
+* case we shouldn't have to worry about the watchdog
+* going off.
+*/
+   __raw_get_cpu_var(watchdog_nmi_touch) = true;
touch_softlockup_watchdog();
 }
 EXPORT_SYMBOL(touch_nmi_watchdog);
-- 
1.8.5.1

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


[PATCH] watchdog: touch_nmi_watchdog should only touch local cpu not every one

2013-12-05 Thread Ben Zhang
I ran into a scenario where while one cpu was stuck and should have panic'd
because of the NMI watchdog, it didn't.  The reason was another cpu was spewing
stack dumps on to the console.  Upon investigation, I noticed that when writing
to the console and also when dumping the stack, the watchdog is touched.

This causes all the cpus to reset their NMI watchdog flags and the 'stuck' cpu
just spins forever.

This change causes the semantics of touch_nmi_watchdog to be changed slightly.
Previously, I accidentally changed the semantics and we noticed there was a
codepath in which touch_nmi_watchdog could be touched from a preemtible area.
That caused a BUG() to happen when CONFIG_DEBUG_PREEMPT was enabled.  I believe
it was the acpi code.

My attempt here re-introduces the change to have the touch_nmi_watchdog() code
only touch the local cpu instead of all of the cpus.  But instead of using
__get_cpu_var(), I use the __raw_get_cpu_var() version.

This avoids the preemption problem.  However my reasoning wasn't because I was
trying to be lazy.  Instead I rationalized it as, well if preemption is enabled
then interrupts should be enabled to and the NMI watchdog will have no reason
to trigger.  So it won't matter if the wrong cpu is touched because the percpu
interrupt counters the NMI watchdog uses should still be incrementing.

Signed-off-by: Don Zickus dzic...@redhat.com
Signed-off-by: Ben Zhang be...@chromium.org
---
 kernel/watchdog.c | 16 
 1 file changed, 8 insertions(+), 8 deletions(-)

diff --git a/kernel/watchdog.c b/kernel/watchdog.c
index 4431610..613f611 100644
--- a/kernel/watchdog.c
+++ b/kernel/watchdog.c
@@ -158,14 +158,14 @@ void touch_all_softlockup_watchdogs(void)
 #ifdef CONFIG_HARDLOCKUP_DETECTOR
 void touch_nmi_watchdog(void)
 {
-   if (watchdog_user_enabled) {
-   unsigned cpu;
-
-   for_each_present_cpu(cpu) {
-   if (per_cpu(watchdog_nmi_touch, cpu) != true)
-   per_cpu(watchdog_nmi_touch, cpu) = true;
-   }
-   }
+   /*
+* Using __raw here because some code paths have
+* preemption enabled.  If preemption is enabled
+* then interrupts should be enabled too, in which
+* case we shouldn't have to worry about the watchdog
+* going off.
+*/
+   __raw_get_cpu_var(watchdog_nmi_touch) = true;
touch_softlockup_watchdog();
 }
 EXPORT_SYMBOL(touch_nmi_watchdog);
-- 
1.8.5.1

--
To unsubscribe from this list: send the line unsubscribe linux-kernel in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


[PATCH v2] watchdog: Add a sysctl to disable soft lockup detector

2013-12-04 Thread Ben Zhang
Currently, the soft lockup detector and hard lockup detector
can be enabled or disabled together via the flag variable
watchdog_user_enabled. There isn't a way to disable only the
soft lockup detector while keeping the hard lockup detector
running.

The hard lockup detector sometimes does not work on a x86
machine with multiple cpus when softlockup_panic is set to 0.
For example:
1. Hard lockup occurs on cpu0 ("cli" followed by a infinite loop).
2. Soft lockup occurs on cpu1 shortly after because cpu1 tries to
send a function to cpu0 via smp_call_function_single().
3. watchdog_timer_fn() detects the soft lockup on cpu1 and
dumps the stack. dump_stack() eventually calls touch_nmi_watchdog()
which sets watchdog_nmi_touch=true for all cpus and sets
watchdog_touch_ts=0 for cpu1.
4. NMI fires on cpu0. watchdog_overflow_callback() sees
watchdog_nmi_touch=true, so it does not do anything except setting
watchdog_nmi_touch=false.
5. watchdog_timer_fn() is called again on cpu1, it sees
watchdog_touch_ts=0, so reloads it with the current tick. Thus,
is_softlockup() returns false, and soft_watchdog_warn is set to false.
6. Before NMI can fire on cpu0 again with watchdog_nmi_touch=false,
watchdog_timer_fn() reports the soft lockup on cpu1 again
and we go back to #3.

The machine stays locked up and the log shows repeated reports of
soft lockup on cpu1. Therefore, we need a way to disable the soft
lockup check so that the hard lockup detector can reboot the machine.


* Existing boot options for the watchdog:
nmi_watchdog=panic/nopanic/0
softlockup_panic=0/1
nowatchdog
nosoftlockup

* Variables modified by the boot options:
int watchdog_user_enabled;
unsigned int softlockup_panic;
unsigned int hardlockup_panic;

* Existing sysctls at /proc/sys/kernel/... for the watchdog:
nmi_watchdog=0/1
watchdog=0/1
softlockup_panic=0/1
watchdog_thresh=0~60

* Variables modified by the sysctls:
int watchdog_user_enabled;
unsigned int softlockup_panic;
int watchdog_thresh;


This patch adds a new boot option softlockup_detector_enable
and a sysctl at /proc/sys/kernel/softlockup_detector_enable to
allow disabling only the soft lockup detector.

softlockup_detector_enable=1:
This is the default. The soft lockup detector is enabled.
When a soft lockup is detected, a warning message with
debug info is printed. The kernel may be configured to
panics in this case via the sysctl kernel.softlockup_panic.

softlockup_detector_enable=0:
The soft lockup detector is disabled. Warning message is
not printed on soft lockup. The kernel does not panic on
soft lockup regardless of the value of kernel.softlockup_panic.
Note kernel.softlockup_detector_enable does not affect
the hard lockup detector.

Signed-off-by: Ben Zhang 
---
 Documentation/kernel-parameters.txt | 11 +++
 Documentation/sysctl/kernel.txt | 20 
 include/linux/sched.h   |  3 ++-
 kernel/sysctl.c |  9 +
 kernel/watchdog.c   | 15 +++
 5 files changed, 57 insertions(+), 1 deletion(-)

diff --git a/Documentation/kernel-parameters.txt 
b/Documentation/kernel-parameters.txt
index 50680a5..5678ac3 100644
--- a/Documentation/kernel-parameters.txt
+++ b/Documentation/kernel-parameters.txt
@@ -2980,6 +2980,17 @@ bytes respectively. Such letter suffixes can also be 
entirely omitted.
1: Fast pin select (default)
2: ATC IRMode
 
+   softlockup_detector_enable=
+   [KNL] Should the soft-lockup detector be enabled. If
+   the soft-lockup detector is disabled, no warning
+   message is printed on soft lockup, and the kernel does
+   not panic on soft lockup regardless of the value of
+   softlockup_panic. softlockup_detector_enable does not
+   affect the hard lockup detector.
+   If this parameter is not present, the soft-lockup
+   detector is enabled by default.
+   Format: 
+
softlockup_panic=
[KNL] Should the soft-lockup detector generate panics.
Format: 
diff --git a/Documentation/sysctl/kernel.txt b/Documentation/sysctl/kernel.txt
index 26b7ee4..209212e 100644
--- a/Documentation/sysctl/kernel.txt
+++ b/Documentation/sysctl/kernel.txt
@@ -70,6 +70,7 @@ show up in /proc/sys/kernel:
 - shmall
 - shmmax  [ sysv ipc ]
 - shmmni
+- softlockup_detector_enable
 - stop-a  [ SPARC only ]
 - sysrq   ==> Documentation/sysrq.txt
 - tainted
@@ -718,6 +719,25 @@ without users and with a dead originative process will be 
destroyed.
 
 ==
 
+softlockup_detector_enable:
+
+Should the soft-lockup detector be enabled.
+
+softlockup_detector_enable=1:
+This is the default. The soft lo

[PATCH v2] watchdog: Add a sysctl to disable soft lockup detector

2013-12-04 Thread Ben Zhang
Currently, the soft lockup detector and hard lockup detector
can be enabled or disabled together via the flag variable
watchdog_user_enabled. There isn't a way to disable only the
soft lockup detector while keeping the hard lockup detector
running.

The hard lockup detector sometimes does not work on a x86
machine with multiple cpus when softlockup_panic is set to 0.
For example:
1. Hard lockup occurs on cpu0 (cli followed by a infinite loop).
2. Soft lockup occurs on cpu1 shortly after because cpu1 tries to
send a function to cpu0 via smp_call_function_single().
3. watchdog_timer_fn() detects the soft lockup on cpu1 and
dumps the stack. dump_stack() eventually calls touch_nmi_watchdog()
which sets watchdog_nmi_touch=true for all cpus and sets
watchdog_touch_ts=0 for cpu1.
4. NMI fires on cpu0. watchdog_overflow_callback() sees
watchdog_nmi_touch=true, so it does not do anything except setting
watchdog_nmi_touch=false.
5. watchdog_timer_fn() is called again on cpu1, it sees
watchdog_touch_ts=0, so reloads it with the current tick. Thus,
is_softlockup() returns false, and soft_watchdog_warn is set to false.
6. Before NMI can fire on cpu0 again with watchdog_nmi_touch=false,
watchdog_timer_fn() reports the soft lockup on cpu1 again
and we go back to #3.

The machine stays locked up and the log shows repeated reports of
soft lockup on cpu1. Therefore, we need a way to disable the soft
lockup check so that the hard lockup detector can reboot the machine.


* Existing boot options for the watchdog:
nmi_watchdog=panic/nopanic/0
softlockup_panic=0/1
nowatchdog
nosoftlockup

* Variables modified by the boot options:
int watchdog_user_enabled;
unsigned int softlockup_panic;
unsigned int hardlockup_panic;

* Existing sysctls at /proc/sys/kernel/... for the watchdog:
nmi_watchdog=0/1
watchdog=0/1
softlockup_panic=0/1
watchdog_thresh=0~60

* Variables modified by the sysctls:
int watchdog_user_enabled;
unsigned int softlockup_panic;
int watchdog_thresh;


This patch adds a new boot option softlockup_detector_enable
and a sysctl at /proc/sys/kernel/softlockup_detector_enable to
allow disabling only the soft lockup detector.

softlockup_detector_enable=1:
This is the default. The soft lockup detector is enabled.
When a soft lockup is detected, a warning message with
debug info is printed. The kernel may be configured to
panics in this case via the sysctl kernel.softlockup_panic.

softlockup_detector_enable=0:
The soft lockup detector is disabled. Warning message is
not printed on soft lockup. The kernel does not panic on
soft lockup regardless of the value of kernel.softlockup_panic.
Note kernel.softlockup_detector_enable does not affect
the hard lockup detector.

Signed-off-by: Ben Zhang be...@chromium.org
---
 Documentation/kernel-parameters.txt | 11 +++
 Documentation/sysctl/kernel.txt | 20 
 include/linux/sched.h   |  3 ++-
 kernel/sysctl.c |  9 +
 kernel/watchdog.c   | 15 +++
 5 files changed, 57 insertions(+), 1 deletion(-)

diff --git a/Documentation/kernel-parameters.txt 
b/Documentation/kernel-parameters.txt
index 50680a5..5678ac3 100644
--- a/Documentation/kernel-parameters.txt
+++ b/Documentation/kernel-parameters.txt
@@ -2980,6 +2980,17 @@ bytes respectively. Such letter suffixes can also be 
entirely omitted.
1: Fast pin select (default)
2: ATC IRMode
 
+   softlockup_detector_enable=
+   [KNL] Should the soft-lockup detector be enabled. If
+   the soft-lockup detector is disabled, no warning
+   message is printed on soft lockup, and the kernel does
+   not panic on soft lockup regardless of the value of
+   softlockup_panic. softlockup_detector_enable does not
+   affect the hard lockup detector.
+   If this parameter is not present, the soft-lockup
+   detector is enabled by default.
+   Format: integer
+
softlockup_panic=
[KNL] Should the soft-lockup detector generate panics.
Format: integer
diff --git a/Documentation/sysctl/kernel.txt b/Documentation/sysctl/kernel.txt
index 26b7ee4..209212e 100644
--- a/Documentation/sysctl/kernel.txt
+++ b/Documentation/sysctl/kernel.txt
@@ -70,6 +70,7 @@ show up in /proc/sys/kernel:
 - shmall
 - shmmax  [ sysv ipc ]
 - shmmni
+- softlockup_detector_enable
 - stop-a  [ SPARC only ]
 - sysrq   == Documentation/sysrq.txt
 - tainted
@@ -718,6 +719,25 @@ without users and with a dead originative process will be 
destroyed.
 
 ==
 
+softlockup_detector_enable:
+
+Should the soft-lockup detector be enabled.
+
+softlockup_detector_enable=1

[PATCH] watchdog: Add a sysctl to disable soft lockup detector

2013-12-03 Thread Ben Zhang
This provides usermode a way to disable only the soft
lockup detector while keeping the hard lockup detector
running.

kernel.softlockup_detector_enable=1:
This is the default. The soft lockup detector is enabled.
When a soft lockup is detected, a warning message with
debug info is printed. The kernel may be configured to
panics in this case via the sysctl kernel.softlockup_panic.

kernel.softlockup_detector_enable=0:
The soft lockup detector is disabled. Warning message is
not printed on soft lockup. The kernel does not panic on
soft lockup regardless of the value of kernel.softlockup_panic.
Note kernel.softlockup_detector_enable does not affect
the hard lockup detector.

Signed-off-by: Ben Zhang 
---
 include/linux/sched.h |  1 +
 kernel/sysctl.c   |  9 +
 kernel/watchdog.c | 15 +++
 3 files changed, 25 insertions(+)

diff --git a/include/linux/sched.h b/include/linux/sched.h
index 768b037..93ebec4 100644
--- a/include/linux/sched.h
+++ b/include/linux/sched.h
@@ -270,6 +270,7 @@ extern int proc_dowatchdog_thresh(struct ctl_table *table, 
int write,
  void __user *buffer,
  size_t *lenp, loff_t *ppos);
 extern unsigned int  softlockup_panic;
+extern unsigned int  softlockup_detector_enable;
 void lockup_detector_init(void);
 #else
 static inline void touch_softlockup_watchdog(void)
diff --git a/kernel/sysctl.c b/kernel/sysctl.c
index 34a6047..8ae1f36 100644
--- a/kernel/sysctl.c
+++ b/kernel/sysctl.c
@@ -840,6 +840,15 @@ static struct ctl_table kern_table[] = {
.extra2 = ,
},
{
+   .procname   = "softlockup_detector_enable",
+   .data   = _detector_enable,
+   .maxlen = sizeof(int),
+   .mode   = 0644,
+   .proc_handler   = proc_dointvec_minmax,
+   .extra1 = ,
+   .extra2 = ,
+   },
+   {
.procname   = "nmi_watchdog",
.data   = _user_enabled,
.maxlen = sizeof (int),
diff --git a/kernel/watchdog.c b/kernel/watchdog.c
index 4431610..b9594e6 100644
--- a/kernel/watchdog.c
+++ b/kernel/watchdog.c
@@ -80,6 +80,18 @@ static int __init softlockup_panic_setup(char *str)
 }
 __setup("softlockup_panic=", softlockup_panic_setup);
 
+unsigned int __read_mostly softlockup_detector_enable = 1;
+
+static int __init softlockup_detector_enable_setup(char *str)
+{
+   unsigned long res;
+   if (kstrtoul(str, 0, ))
+   res = 1;
+   softlockup_detector_enable = res;
+   return 1;
+}
+__setup("softlockup_detector_enable=", softlockup_detector_enable_setup);
+
 static int __init nowatchdog_setup(char *str)
 {
watchdog_user_enabled = 0;
@@ -293,6 +305,9 @@ static enum hrtimer_restart watchdog_timer_fn(struct 
hrtimer *hrtimer)
return HRTIMER_RESTART;
}
 
+   if (!softlockup_detector_enable)
+   return HRTIMER_RESTART;
+
/* check for a softlockup
 * This is done by making sure a high priority task is
 * being scheduled.  The task touches the watchdog to
-- 
1.8.4.1

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


[PATCH] watchdog: Add a sysctl to disable soft lockup detector

2013-12-03 Thread Ben Zhang
This provides usermode a way to disable only the soft
lockup detector while keeping the hard lockup detector
running.

kernel.softlockup_detector_enable=1:
This is the default. The soft lockup detector is enabled.
When a soft lockup is detected, a warning message with
debug info is printed. The kernel may be configured to
panics in this case via the sysctl kernel.softlockup_panic.

kernel.softlockup_detector_enable=0:
The soft lockup detector is disabled. Warning message is
not printed on soft lockup. The kernel does not panic on
soft lockup regardless of the value of kernel.softlockup_panic.
Note kernel.softlockup_detector_enable does not affect
the hard lockup detector.

Signed-off-by: Ben Zhang be...@chromium.org
---
 include/linux/sched.h |  1 +
 kernel/sysctl.c   |  9 +
 kernel/watchdog.c | 15 +++
 3 files changed, 25 insertions(+)

diff --git a/include/linux/sched.h b/include/linux/sched.h
index 768b037..93ebec4 100644
--- a/include/linux/sched.h
+++ b/include/linux/sched.h
@@ -270,6 +270,7 @@ extern int proc_dowatchdog_thresh(struct ctl_table *table, 
int write,
  void __user *buffer,
  size_t *lenp, loff_t *ppos);
 extern unsigned int  softlockup_panic;
+extern unsigned int  softlockup_detector_enable;
 void lockup_detector_init(void);
 #else
 static inline void touch_softlockup_watchdog(void)
diff --git a/kernel/sysctl.c b/kernel/sysctl.c
index 34a6047..8ae1f36 100644
--- a/kernel/sysctl.c
+++ b/kernel/sysctl.c
@@ -840,6 +840,15 @@ static struct ctl_table kern_table[] = {
.extra2 = one,
},
{
+   .procname   = softlockup_detector_enable,
+   .data   = softlockup_detector_enable,
+   .maxlen = sizeof(int),
+   .mode   = 0644,
+   .proc_handler   = proc_dointvec_minmax,
+   .extra1 = zero,
+   .extra2 = one,
+   },
+   {
.procname   = nmi_watchdog,
.data   = watchdog_user_enabled,
.maxlen = sizeof (int),
diff --git a/kernel/watchdog.c b/kernel/watchdog.c
index 4431610..b9594e6 100644
--- a/kernel/watchdog.c
+++ b/kernel/watchdog.c
@@ -80,6 +80,18 @@ static int __init softlockup_panic_setup(char *str)
 }
 __setup(softlockup_panic=, softlockup_panic_setup);
 
+unsigned int __read_mostly softlockup_detector_enable = 1;
+
+static int __init softlockup_detector_enable_setup(char *str)
+{
+   unsigned long res;
+   if (kstrtoul(str, 0, res))
+   res = 1;
+   softlockup_detector_enable = res;
+   return 1;
+}
+__setup(softlockup_detector_enable=, softlockup_detector_enable_setup);
+
 static int __init nowatchdog_setup(char *str)
 {
watchdog_user_enabled = 0;
@@ -293,6 +305,9 @@ static enum hrtimer_restart watchdog_timer_fn(struct 
hrtimer *hrtimer)
return HRTIMER_RESTART;
}
 
+   if (!softlockup_detector_enable)
+   return HRTIMER_RESTART;
+
/* check for a softlockup
 * This is done by making sure a high priority task is
 * being scheduled.  The task touches the watchdog to
-- 
1.8.4.1

--
To unsubscribe from this list: send the line unsubscribe linux-kernel in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/