[tip:x86/timers] x86/tsc: Mark Intel ATOM_GOLDMONT TSC reliable

2016-11-18 Thread tip-bot for Bin Gao
Commit-ID:  4635fdc696a8e89eead3ea1712ae6ada38538d40
Gitweb: http://git.kernel.org/tip/4635fdc696a8e89eead3ea1712ae6ada38538d40
Author: Bin Gao <bin@linux.intel.com>
AuthorDate: Tue, 15 Nov 2016 12:27:23 -0800
Committer:  Thomas Gleixner <t...@linutronix.de>
CommitDate: Fri, 18 Nov 2016 10:58:30 +0100

x86/tsc: Mark Intel ATOM_GOLDMONT TSC reliable

On Intel GOLDMONT Atom SoC TSC is the only available clocksource, so there
is no way to do software calibration or have a watchdog clocksource for it.
Software calibration is already disabled via the TSC_KNOWN_FREQ flag, but
the watchdog requirement still persists, so such systems cannot switch to
high resolution/nohz mode.

Mark it reliable, so it becomes usable. Hardware teams confirmed that this
is safe on that SoC.

Signed-off-by: Bin Gao <bin@intel.com>
Cc: Peter Zijlstra <pet...@infradead.org>
Link: 
http://lkml.kernel.org/r/1479241644-234277-4-git-send-email-bin@linux.intel.com
Signed-off-by: Thomas Gleixner <t...@linutronix.de>

---
 arch/x86/kernel/tsc.c | 7 +++
 1 file changed, 7 insertions(+)

diff --git a/arch/x86/kernel/tsc.c b/arch/x86/kernel/tsc.c
index e58c319..f4dfdaa 100644
--- a/arch/x86/kernel/tsc.c
+++ b/arch/x86/kernel/tsc.c
@@ -709,6 +709,13 @@ unsigned long native_calibrate_tsc(void)
 */
setup_force_cpu_cap(X86_FEATURE_TSC_KNOWN_FREQ);
 
+   /*
+* For Atom SoCs TSC is the only reliable clocksource.
+* Mark TSC reliable so no watchdog on it.
+*/
+   if (boot_cpu_data.x86_model == INTEL_FAM6_ATOM_GOLDMONT)
+   setup_force_cpu_cap(X86_FEATURE_TSC_RELIABLE);
+
return crystal_khz * ebx_numerator / eax_denominator;
 }
 


[tip:x86/timers] x86/tsc: Mark Intel ATOM_GOLDMONT TSC reliable

2016-11-18 Thread tip-bot for Bin Gao
Commit-ID:  4635fdc696a8e89eead3ea1712ae6ada38538d40
Gitweb: http://git.kernel.org/tip/4635fdc696a8e89eead3ea1712ae6ada38538d40
Author: Bin Gao 
AuthorDate: Tue, 15 Nov 2016 12:27:23 -0800
Committer:  Thomas Gleixner 
CommitDate: Fri, 18 Nov 2016 10:58:30 +0100

x86/tsc: Mark Intel ATOM_GOLDMONT TSC reliable

On Intel GOLDMONT Atom SoC TSC is the only available clocksource, so there
is no way to do software calibration or have a watchdog clocksource for it.
Software calibration is already disabled via the TSC_KNOWN_FREQ flag, but
the watchdog requirement still persists, so such systems cannot switch to
high resolution/nohz mode.

Mark it reliable, so it becomes usable. Hardware teams confirmed that this
is safe on that SoC.

Signed-off-by: Bin Gao 
Cc: Peter Zijlstra 
Link: 
http://lkml.kernel.org/r/1479241644-234277-4-git-send-email-bin@linux.intel.com
Signed-off-by: Thomas Gleixner 

---
 arch/x86/kernel/tsc.c | 7 +++
 1 file changed, 7 insertions(+)

diff --git a/arch/x86/kernel/tsc.c b/arch/x86/kernel/tsc.c
index e58c319..f4dfdaa 100644
--- a/arch/x86/kernel/tsc.c
+++ b/arch/x86/kernel/tsc.c
@@ -709,6 +709,13 @@ unsigned long native_calibrate_tsc(void)
 */
setup_force_cpu_cap(X86_FEATURE_TSC_KNOWN_FREQ);
 
+   /*
+* For Atom SoCs TSC is the only reliable clocksource.
+* Mark TSC reliable so no watchdog on it.
+*/
+   if (boot_cpu_data.x86_model == INTEL_FAM6_ATOM_GOLDMONT)
+   setup_force_cpu_cap(X86_FEATURE_TSC_RELIABLE);
+
return crystal_khz * ebx_numerator / eax_denominator;
 }
 


[tip:x86/timers] x86/tsc: Set TSC_KNOWN_FREQ and TSC_RELIABLE flags on Intel Atom SoCs

2016-11-18 Thread tip-bot for Bin Gao
Commit-ID:  f3a02ecebed7df7d5d68898628dea7a3bfcf03e3
Gitweb: http://git.kernel.org/tip/f3a02ecebed7df7d5d68898628dea7a3bfcf03e3
Author: Bin Gao <bin@linux.intel.com>
AuthorDate: Tue, 15 Nov 2016 12:27:24 -0800
Committer:  Thomas Gleixner <t...@linutronix.de>
CommitDate: Fri, 18 Nov 2016 10:58:31 +0100

x86/tsc: Set TSC_KNOWN_FREQ and TSC_RELIABLE flags on Intel Atom SoCs

TSC on Intel Atom SoCs capable of determining TSC frequency by MSR is
reliable and the frequency is known (provided by HW).

On these platforms PIT/HPET is generally not available so calibration won't
work at all and there is no other clocksource to act as a watchdog for the
TSC, so we have no other choice than to trust it.

Set both X86_FEATURE_TSC_KNOWN_FREQ and X86_FEATURE_TSC_RELIABLE flags to
make sure the calibration is skipped and no watchdog is required.

Signed-off-by: Bin Gao <bin@intel.com>
Cc: Peter Zijlstra <pet...@infradead.org>
Link: 
http://lkml.kernel.org/r/1479241644-234277-5-git-send-email-bin@linux.intel.com
Signed-off-by: Thomas Gleixner <t...@linutronix.de>

---
 arch/x86/kernel/tsc_msr.c   | 19 +++
 arch/x86/platform/intel-mid/mfld.c  |  9 +++--
 arch/x86/platform/intel-mid/mrfld.c |  8 ++--
 3 files changed, 32 insertions(+), 4 deletions(-)

diff --git a/arch/x86/kernel/tsc_msr.c b/arch/x86/kernel/tsc_msr.c
index 0fe720d..19afdbd 100644
--- a/arch/x86/kernel/tsc_msr.c
+++ b/arch/x86/kernel/tsc_msr.c
@@ -100,5 +100,24 @@ unsigned long cpu_khz_from_msr(void)
 #ifdef CONFIG_X86_LOCAL_APIC
lapic_timer_frequency = (freq * 1000) / HZ;
 #endif
+
+   /*
+* TSC frequency determined by MSR is always considered "known"
+* because it is reported by HW.
+* Another fact is that on MSR capable platforms, PIT/HPET is
+* generally not available so calibration won't work at all.
+*/
+   setup_force_cpu_cap(X86_FEATURE_TSC_KNOWN_FREQ);
+
+   /*
+* Unfortunately there is no way for hardware to tell whether the
+* TSC is reliable.  We were told by silicon design team that TSC
+* on Atom SoCs are always "reliable". TSC is also the only
+* reliable clocksource on these SoCs (HPET is either not present
+* or not functional) so mark TSC reliable which removes the
+* requirement for a watchdog clocksource.
+*/
+   setup_force_cpu_cap(X86_FEATURE_TSC_RELIABLE);
+
return res;
 }
diff --git a/arch/x86/platform/intel-mid/mfld.c 
b/arch/x86/platform/intel-mid/mfld.c
index 1eb47b6..e793fe5 100644
--- a/arch/x86/platform/intel-mid/mfld.c
+++ b/arch/x86/platform/intel-mid/mfld.c
@@ -49,8 +49,13 @@ static unsigned long __init mfld_calibrate_tsc(void)
fast_calibrate = ratio * fsb;
pr_debug("read penwell tsc %lu khz\n", fast_calibrate);
lapic_timer_frequency = fsb * 1000 / HZ;
-   /* mark tsc clocksource as reliable */
-   set_cpu_cap(_cpu_data, X86_FEATURE_TSC_RELIABLE);
+
+   /*
+* TSC on Intel Atom SoCs is reliable and of known frequency.
+* See tsc_msr.c for details.
+*/
+   setup_force_cpu_cap(X86_FEATURE_TSC_KNOWN_FREQ);
+   setup_force_cpu_cap(X86_FEATURE_TSC_RELIABLE);
 
return fast_calibrate;
 }
diff --git a/arch/x86/platform/intel-mid/mrfld.c 
b/arch/x86/platform/intel-mid/mrfld.c
index 59253db..e0607c7 100644
--- a/arch/x86/platform/intel-mid/mrfld.c
+++ b/arch/x86/platform/intel-mid/mrfld.c
@@ -78,8 +78,12 @@ static unsigned long __init tangier_calibrate_tsc(void)
pr_debug("Setting lapic_timer_frequency = %d\n",
lapic_timer_frequency);
 
-   /* mark tsc clocksource as reliable */
-   set_cpu_cap(_cpu_data, X86_FEATURE_TSC_RELIABLE);
+   /*
+* TSC on Intel Atom SoCs is reliable and of known frequency.
+* See tsc_msr.c for details.
+*/
+   setup_force_cpu_cap(X86_FEATURE_TSC_KNOWN_FREQ);
+   setup_force_cpu_cap(X86_FEATURE_TSC_RELIABLE);
 
return fast_calibrate;
 }


[tip:x86/timers] x86/tsc: Set TSC_KNOWN_FREQ and TSC_RELIABLE flags on Intel Atom SoCs

2016-11-18 Thread tip-bot for Bin Gao
Commit-ID:  f3a02ecebed7df7d5d68898628dea7a3bfcf03e3
Gitweb: http://git.kernel.org/tip/f3a02ecebed7df7d5d68898628dea7a3bfcf03e3
Author: Bin Gao 
AuthorDate: Tue, 15 Nov 2016 12:27:24 -0800
Committer:  Thomas Gleixner 
CommitDate: Fri, 18 Nov 2016 10:58:31 +0100

x86/tsc: Set TSC_KNOWN_FREQ and TSC_RELIABLE flags on Intel Atom SoCs

TSC on Intel Atom SoCs capable of determining TSC frequency by MSR is
reliable and the frequency is known (provided by HW).

On these platforms PIT/HPET is generally not available so calibration won't
work at all and there is no other clocksource to act as a watchdog for the
TSC, so we have no other choice than to trust it.

Set both X86_FEATURE_TSC_KNOWN_FREQ and X86_FEATURE_TSC_RELIABLE flags to
make sure the calibration is skipped and no watchdog is required.

Signed-off-by: Bin Gao 
Cc: Peter Zijlstra 
Link: 
http://lkml.kernel.org/r/1479241644-234277-5-git-send-email-bin@linux.intel.com
Signed-off-by: Thomas Gleixner 

---
 arch/x86/kernel/tsc_msr.c   | 19 +++
 arch/x86/platform/intel-mid/mfld.c  |  9 +++--
 arch/x86/platform/intel-mid/mrfld.c |  8 ++--
 3 files changed, 32 insertions(+), 4 deletions(-)

diff --git a/arch/x86/kernel/tsc_msr.c b/arch/x86/kernel/tsc_msr.c
index 0fe720d..19afdbd 100644
--- a/arch/x86/kernel/tsc_msr.c
+++ b/arch/x86/kernel/tsc_msr.c
@@ -100,5 +100,24 @@ unsigned long cpu_khz_from_msr(void)
 #ifdef CONFIG_X86_LOCAL_APIC
lapic_timer_frequency = (freq * 1000) / HZ;
 #endif
+
+   /*
+* TSC frequency determined by MSR is always considered "known"
+* because it is reported by HW.
+* Another fact is that on MSR capable platforms, PIT/HPET is
+* generally not available so calibration won't work at all.
+*/
+   setup_force_cpu_cap(X86_FEATURE_TSC_KNOWN_FREQ);
+
+   /*
+* Unfortunately there is no way for hardware to tell whether the
+* TSC is reliable.  We were told by silicon design team that TSC
+* on Atom SoCs are always "reliable". TSC is also the only
+* reliable clocksource on these SoCs (HPET is either not present
+* or not functional) so mark TSC reliable which removes the
+* requirement for a watchdog clocksource.
+*/
+   setup_force_cpu_cap(X86_FEATURE_TSC_RELIABLE);
+
return res;
 }
diff --git a/arch/x86/platform/intel-mid/mfld.c 
b/arch/x86/platform/intel-mid/mfld.c
index 1eb47b6..e793fe5 100644
--- a/arch/x86/platform/intel-mid/mfld.c
+++ b/arch/x86/platform/intel-mid/mfld.c
@@ -49,8 +49,13 @@ static unsigned long __init mfld_calibrate_tsc(void)
fast_calibrate = ratio * fsb;
pr_debug("read penwell tsc %lu khz\n", fast_calibrate);
lapic_timer_frequency = fsb * 1000 / HZ;
-   /* mark tsc clocksource as reliable */
-   set_cpu_cap(_cpu_data, X86_FEATURE_TSC_RELIABLE);
+
+   /*
+* TSC on Intel Atom SoCs is reliable and of known frequency.
+* See tsc_msr.c for details.
+*/
+   setup_force_cpu_cap(X86_FEATURE_TSC_KNOWN_FREQ);
+   setup_force_cpu_cap(X86_FEATURE_TSC_RELIABLE);
 
return fast_calibrate;
 }
diff --git a/arch/x86/platform/intel-mid/mrfld.c 
b/arch/x86/platform/intel-mid/mrfld.c
index 59253db..e0607c7 100644
--- a/arch/x86/platform/intel-mid/mrfld.c
+++ b/arch/x86/platform/intel-mid/mrfld.c
@@ -78,8 +78,12 @@ static unsigned long __init tangier_calibrate_tsc(void)
pr_debug("Setting lapic_timer_frequency = %d\n",
lapic_timer_frequency);
 
-   /* mark tsc clocksource as reliable */
-   set_cpu_cap(_cpu_data, X86_FEATURE_TSC_RELIABLE);
+   /*
+* TSC on Intel Atom SoCs is reliable and of known frequency.
+* See tsc_msr.c for details.
+*/
+   setup_force_cpu_cap(X86_FEATURE_TSC_KNOWN_FREQ);
+   setup_force_cpu_cap(X86_FEATURE_TSC_RELIABLE);
 
return fast_calibrate;
 }


[tip:x86/timers] x86/tsc: Mark TSC frequency determined by CPUID as known

2016-11-18 Thread tip-bot for Bin Gao
Commit-ID:  4ca4df0b7eb06df264b2919759957f6d6ea1822e
Gitweb: http://git.kernel.org/tip/4ca4df0b7eb06df264b2919759957f6d6ea1822e
Author: Bin Gao <bin@linux.intel.com>
AuthorDate: Tue, 15 Nov 2016 12:27:22 -0800
Committer:  Thomas Gleixner <t...@linutronix.de>
CommitDate: Fri, 18 Nov 2016 10:58:30 +0100

x86/tsc: Mark TSC frequency determined by CPUID as known

CPUs/SoCs with CPUID leaf 0x15 come with a known frequency and will report
the frequency to software via CPUID instruction. This hardware provided
frequency is the "real" frequency of TSC.

Set the X86_FEATURE_TSC_KNOWN_FREQ flag for such systems to skip the
software calibration process.

A 24 hours test on one of the CPUID 0x15 capable platforms was
conducted. PIT calibrated frequency resulted in more than 3 seconds drift
whereas the CPUID determined frequency showed less than 0.5 second
drift.

Signed-off-by: Bin Gao <bin@intel.com>
Cc: Peter Zijlstra <pet...@infradead.org>
Link: 
http://lkml.kernel.org/r/1479241644-234277-3-git-send-email-bin@linux.intel.com
Signed-off-by: Thomas Gleixner <t...@linutronix.de>

---
 arch/x86/kernel/tsc.c | 7 +++
 1 file changed, 7 insertions(+)

diff --git a/arch/x86/kernel/tsc.c b/arch/x86/kernel/tsc.c
index d2c4ee4..e58c319 100644
--- a/arch/x86/kernel/tsc.c
+++ b/arch/x86/kernel/tsc.c
@@ -702,6 +702,13 @@ unsigned long native_calibrate_tsc(void)
}
}
 
+   /*
+* TSC frequency determined by CPUID is a "hardware reported"
+* frequency and is the most accurate one so far we have. This
+* is considered a known frequency.
+*/
+   setup_force_cpu_cap(X86_FEATURE_TSC_KNOWN_FREQ);
+
return crystal_khz * ebx_numerator / eax_denominator;
 }
 


[tip:x86/timers] x86/tsc: Mark TSC frequency determined by CPUID as known

2016-11-18 Thread tip-bot for Bin Gao
Commit-ID:  4ca4df0b7eb06df264b2919759957f6d6ea1822e
Gitweb: http://git.kernel.org/tip/4ca4df0b7eb06df264b2919759957f6d6ea1822e
Author: Bin Gao 
AuthorDate: Tue, 15 Nov 2016 12:27:22 -0800
Committer:  Thomas Gleixner 
CommitDate: Fri, 18 Nov 2016 10:58:30 +0100

x86/tsc: Mark TSC frequency determined by CPUID as known

CPUs/SoCs with CPUID leaf 0x15 come with a known frequency and will report
the frequency to software via CPUID instruction. This hardware provided
frequency is the "real" frequency of TSC.

Set the X86_FEATURE_TSC_KNOWN_FREQ flag for such systems to skip the
software calibration process.

A 24 hours test on one of the CPUID 0x15 capable platforms was
conducted. PIT calibrated frequency resulted in more than 3 seconds drift
whereas the CPUID determined frequency showed less than 0.5 second
drift.

Signed-off-by: Bin Gao 
Cc: Peter Zijlstra 
Link: 
http://lkml.kernel.org/r/1479241644-234277-3-git-send-email-bin@linux.intel.com
Signed-off-by: Thomas Gleixner 

---
 arch/x86/kernel/tsc.c | 7 +++
 1 file changed, 7 insertions(+)

diff --git a/arch/x86/kernel/tsc.c b/arch/x86/kernel/tsc.c
index d2c4ee4..e58c319 100644
--- a/arch/x86/kernel/tsc.c
+++ b/arch/x86/kernel/tsc.c
@@ -702,6 +702,13 @@ unsigned long native_calibrate_tsc(void)
}
}
 
+   /*
+* TSC frequency determined by CPUID is a "hardware reported"
+* frequency and is the most accurate one so far we have. This
+* is considered a known frequency.
+*/
+   setup_force_cpu_cap(X86_FEATURE_TSC_KNOWN_FREQ);
+
return crystal_khz * ebx_numerator / eax_denominator;
 }
 


[tip:x86/timers] x86/tsc: Add X86_FEATURE_TSC_KNOWN_FREQ flag

2016-11-18 Thread tip-bot for Bin Gao
Commit-ID:  47c95a46d0fae07762f0a38aa3709ae63f307048
Gitweb: http://git.kernel.org/tip/47c95a46d0fae07762f0a38aa3709ae63f307048
Author: Bin Gao <bin@linux.intel.com>
AuthorDate: Tue, 15 Nov 2016 12:27:21 -0800
Committer:  Thomas Gleixner <t...@linutronix.de>
CommitDate: Fri, 18 Nov 2016 10:58:30 +0100

x86/tsc: Add X86_FEATURE_TSC_KNOWN_FREQ flag

The X86_FEATURE_TSC_RELIABLE flag in Linux kernel implies both reliable
(at runtime) and trustable (at calibration). But reliable running and
trustable calibration independent of each other. 

Add a new flag X86_FEATURE_TSC_KNOWN_FREQ, which denotes that the frequency
is known (via MSR/CPUID). This flag is only meant to skip the long term
calibration on systems which have a known frequency.

Add X86_FEATURE_TSC_KNOWN_FREQ to the skip the delayed calibration and
leave X86_FEATURE_TSC_RELIABLE in place.

After converting the existing users of X86_FEATURE_TSC_RELIABLE to use
either both flags or just X86_FEATURE_TSC_KNOWN_FREQ we can seperate the
functionality.

Suggested-by: Thomas Gleixner <t...@linutronix.de>
Signed-off-by: Bin Gao <bin@intel.com>
Cc: Peter Zijlstra <pet...@infradead.org>
Link: 
http://lkml.kernel.org/r/1479241644-234277-2-git-send-email-bin@linux.intel.com
Signed-off-by: Thomas Gleixner <t...@linutronix.de>

---
 arch/x86/include/asm/cpufeatures.h |  1 +
 arch/x86/kernel/tsc.c  | 11 ---
 2 files changed, 9 insertions(+), 3 deletions(-)

diff --git a/arch/x86/include/asm/cpufeatures.h 
b/arch/x86/include/asm/cpufeatures.h
index a396292..7f6a5f8 100644
--- a/arch/x86/include/asm/cpufeatures.h
+++ b/arch/x86/include/asm/cpufeatures.h
@@ -106,6 +106,7 @@
 #define X86_FEATURE_APERFMPERF ( 3*32+28) /* APERFMPERF */
 #define X86_FEATURE_EAGER_FPU  ( 3*32+29) /* "eagerfpu" Non lazy FPU restore */
 #define X86_FEATURE_NONSTOP_TSC_S3 ( 3*32+30) /* TSC doesn't stop in S3 state 
*/
+#define X86_FEATURE_TSC_KNOWN_FREQ ( 3*32+31) /* TSC has known frequency */
 
 /* Intel-defined CPU features, CPUID level 0x0001 (ecx), word 4 */
 #define X86_FEATURE_XMM3   ( 4*32+ 0) /* "pni" SSE-3 */
diff --git a/arch/x86/kernel/tsc.c b/arch/x86/kernel/tsc.c
index 46b2f41..d2c4ee4 100644
--- a/arch/x86/kernel/tsc.c
+++ b/arch/x86/kernel/tsc.c
@@ -1283,10 +1283,15 @@ static int __init init_tsc_clocksource(void)
clocksource_tsc.flags |= CLOCK_SOURCE_SUSPEND_NONSTOP;
 
/*
-* Trust the results of the earlier calibration on systems
-* exporting a reliable TSC.
+* When TSC frequency is known (retrieved via MSR or CPUID), we skip
+* the refined calibration and directly register it as a clocksource.
+*
+* We still keep the TSC_RELIABLE flag here to avoid regressions -
+* it will be removed after all the conversion for other code paths
+* connected to this flag is done.
 */
-   if (boot_cpu_has(X86_FEATURE_TSC_RELIABLE)) {
+   if (boot_cpu_has(X86_FEATURE_TSC_RELIABLE) ||
+   boot_cpu_has(X86_FEATURE_TSC_KNOWN_FREQ)) {
clocksource_register_khz(_tsc, tsc_khz);
return 0;
}


[tip:x86/timers] x86/tsc: Add X86_FEATURE_TSC_KNOWN_FREQ flag

2016-11-18 Thread tip-bot for Bin Gao
Commit-ID:  47c95a46d0fae07762f0a38aa3709ae63f307048
Gitweb: http://git.kernel.org/tip/47c95a46d0fae07762f0a38aa3709ae63f307048
Author: Bin Gao 
AuthorDate: Tue, 15 Nov 2016 12:27:21 -0800
Committer:  Thomas Gleixner 
CommitDate: Fri, 18 Nov 2016 10:58:30 +0100

x86/tsc: Add X86_FEATURE_TSC_KNOWN_FREQ flag

The X86_FEATURE_TSC_RELIABLE flag in Linux kernel implies both reliable
(at runtime) and trustable (at calibration). But reliable running and
trustable calibration independent of each other. 

Add a new flag X86_FEATURE_TSC_KNOWN_FREQ, which denotes that the frequency
is known (via MSR/CPUID). This flag is only meant to skip the long term
calibration on systems which have a known frequency.

Add X86_FEATURE_TSC_KNOWN_FREQ to the skip the delayed calibration and
leave X86_FEATURE_TSC_RELIABLE in place.

After converting the existing users of X86_FEATURE_TSC_RELIABLE to use
either both flags or just X86_FEATURE_TSC_KNOWN_FREQ we can seperate the
functionality.

Suggested-by: Thomas Gleixner 
Signed-off-by: Bin Gao 
Cc: Peter Zijlstra 
Link: 
http://lkml.kernel.org/r/1479241644-234277-2-git-send-email-bin@linux.intel.com
Signed-off-by: Thomas Gleixner 

---
 arch/x86/include/asm/cpufeatures.h |  1 +
 arch/x86/kernel/tsc.c  | 11 ---
 2 files changed, 9 insertions(+), 3 deletions(-)

diff --git a/arch/x86/include/asm/cpufeatures.h 
b/arch/x86/include/asm/cpufeatures.h
index a396292..7f6a5f8 100644
--- a/arch/x86/include/asm/cpufeatures.h
+++ b/arch/x86/include/asm/cpufeatures.h
@@ -106,6 +106,7 @@
 #define X86_FEATURE_APERFMPERF ( 3*32+28) /* APERFMPERF */
 #define X86_FEATURE_EAGER_FPU  ( 3*32+29) /* "eagerfpu" Non lazy FPU restore */
 #define X86_FEATURE_NONSTOP_TSC_S3 ( 3*32+30) /* TSC doesn't stop in S3 state 
*/
+#define X86_FEATURE_TSC_KNOWN_FREQ ( 3*32+31) /* TSC has known frequency */
 
 /* Intel-defined CPU features, CPUID level 0x0001 (ecx), word 4 */
 #define X86_FEATURE_XMM3   ( 4*32+ 0) /* "pni" SSE-3 */
diff --git a/arch/x86/kernel/tsc.c b/arch/x86/kernel/tsc.c
index 46b2f41..d2c4ee4 100644
--- a/arch/x86/kernel/tsc.c
+++ b/arch/x86/kernel/tsc.c
@@ -1283,10 +1283,15 @@ static int __init init_tsc_clocksource(void)
clocksource_tsc.flags |= CLOCK_SOURCE_SUSPEND_NONSTOP;
 
/*
-* Trust the results of the earlier calibration on systems
-* exporting a reliable TSC.
+* When TSC frequency is known (retrieved via MSR or CPUID), we skip
+* the refined calibration and directly register it as a clocksource.
+*
+* We still keep the TSC_RELIABLE flag here to avoid regressions -
+* it will be removed after all the conversion for other code paths
+* connected to this flag is done.
 */
-   if (boot_cpu_has(X86_FEATURE_TSC_RELIABLE)) {
+   if (boot_cpu_has(X86_FEATURE_TSC_RELIABLE) ||
+   boot_cpu_has(X86_FEATURE_TSC_KNOWN_FREQ)) {
clocksource_register_khz(_tsc, tsc_khz);
return 0;
}


[PATCH 1/4] x86/tsc: add X86_FEATURE_TSC_KNOWN_FREQ flag

2016-11-15 Thread Bin Gao
The X86_FEATURE_TSC_RELIABLE flag in Linux kernel implies both reliable
(at runtime) and trustable (at calibration). But reliable running and
trustable calibration are logically irrelevant. Per Thomas Gleixner's
suggestion we would like to split this flag into two separate flags:
X86_FEATURE_TSC_RELIABLE - running reliably
X86_FEATURE_TSC_KNOWN_FREQ - frequency is known (no calibration required)
These two flags allow Linux kernel to act differently based on
processor/SoC's capability, i.e. no watchdog on TSC if TSC is reliable,
and no calibration if TSC frequency is known.

Current Linux kernel already gurantees calibration is skipped for
processors that can report TSC frequency by CPUID or MSR. However, the
delayed calibration is still not skipped for these CPUID/MSR capable
processors. The new flag X86_FEATURE_TSC_KNOWN_FREQ added by this patch
will gurantee the delayed calibration is skipped.

Signed-off-by: Bin Gao <bin@intel.com>
---
 arch/x86/include/asm/cpufeatures.h |  1 +
 arch/x86/kernel/tsc.c  | 11 ---
 2 files changed, 9 insertions(+), 3 deletions(-)

diff --git a/arch/x86/include/asm/cpufeatures.h 
b/arch/x86/include/asm/cpufeatures.h
index a396292..7f6a5f8 100644
--- a/arch/x86/include/asm/cpufeatures.h
+++ b/arch/x86/include/asm/cpufeatures.h
@@ -106,6 +106,7 @@
 #define X86_FEATURE_APERFMPERF ( 3*32+28) /* APERFMPERF */
 #define X86_FEATURE_EAGER_FPU  ( 3*32+29) /* "eagerfpu" Non lazy FPU restore */
 #define X86_FEATURE_NONSTOP_TSC_S3 ( 3*32+30) /* TSC doesn't stop in S3 state 
*/
+#define X86_FEATURE_TSC_KNOWN_FREQ ( 3*32+31) /* TSC has known frequency */
 
 /* Intel-defined CPU features, CPUID level 0x0001 (ecx), word 4 */
 #define X86_FEATURE_XMM3   ( 4*32+ 0) /* "pni" SSE-3 */
diff --git a/arch/x86/kernel/tsc.c b/arch/x86/kernel/tsc.c
index 46b2f41..3ba146e 100644
--- a/arch/x86/kernel/tsc.c
+++ b/arch/x86/kernel/tsc.c
@@ -1283,10 +1283,15 @@ static int __init init_tsc_clocksource(void)
clocksource_tsc.flags |= CLOCK_SOURCE_SUSPEND_NONSTOP;
 
/*
-* Trust the results of the earlier calibration on systems
-* exporting a reliable TSC.
+* When TSC frequency is known (generally got by MSR or CPUID), we skip
+* the refined calibration and directly register it as a clocksource.
+*
+* We still keep the TSC_RELIABLE flag here to avoid regression -
+* it will be removed after all the conversion for other code paths
+* connected to this flag is done.
 */
-   if (boot_cpu_has(X86_FEATURE_TSC_RELIABLE)) {
+   if (boot_cpu_has(X86_FEATURE_TSC_RELIABLE) ||
+   boot_cpu_has(X86_FEATURE_TSC_KNOWN_FREQ)) {
clocksource_register_khz(_tsc, tsc_khz);
return 0;
}
-- 
1.9.1



[PATCH 3/4] x86/tsc: mark Intel ATOM_GOLDMONT TSC reliable

2016-11-15 Thread Bin Gao
On Intel GOLDMONT Atom SoC TSC is the only reliable clocksource.
We mark TSC reliable to avoid watchdog on it.

Signed-off-by: Bin Gao <bin@intel.com>
---
 arch/x86/kernel/tsc.c | 7 +++
 1 file changed, 7 insertions(+)

diff --git a/arch/x86/kernel/tsc.c b/arch/x86/kernel/tsc.c
index f1a7fb5..354b302 100644
--- a/arch/x86/kernel/tsc.c
+++ b/arch/x86/kernel/tsc.c
@@ -709,6 +709,13 @@ unsigned long native_calibrate_tsc(void)
 */
setup_force_cpu_cap(X86_FEATURE_TSC_KNOWN_FREQ);
 
+   /*
+* For Atom SoCs TSC is the only reliable clocksource.
+* Mark TSC reliable so no watchdog on it.
+*/
+   if (boot_cpu_data.x86_model == INTEL_FAM6_ATOM_GOLDMONT)
+   setup_force_cpu_cap(X86_FEATURE_TSC_RELIABLE);
+
return crystal_khz * ebx_numerator / eax_denominator;
 }
 
-- 
1.9.1



[PATCH 3/4] x86/tsc: mark Intel ATOM_GOLDMONT TSC reliable

2016-11-15 Thread Bin Gao
On Intel GOLDMONT Atom SoC TSC is the only reliable clocksource.
We mark TSC reliable to avoid watchdog on it.

Signed-off-by: Bin Gao 
---
 arch/x86/kernel/tsc.c | 7 +++
 1 file changed, 7 insertions(+)

diff --git a/arch/x86/kernel/tsc.c b/arch/x86/kernel/tsc.c
index f1a7fb5..354b302 100644
--- a/arch/x86/kernel/tsc.c
+++ b/arch/x86/kernel/tsc.c
@@ -709,6 +709,13 @@ unsigned long native_calibrate_tsc(void)
 */
setup_force_cpu_cap(X86_FEATURE_TSC_KNOWN_FREQ);
 
+   /*
+* For Atom SoCs TSC is the only reliable clocksource.
+* Mark TSC reliable so no watchdog on it.
+*/
+   if (boot_cpu_data.x86_model == INTEL_FAM6_ATOM_GOLDMONT)
+   setup_force_cpu_cap(X86_FEATURE_TSC_RELIABLE);
+
return crystal_khz * ebx_numerator / eax_denominator;
 }
 
-- 
1.9.1



[PATCH 1/4] x86/tsc: add X86_FEATURE_TSC_KNOWN_FREQ flag

2016-11-15 Thread Bin Gao
The X86_FEATURE_TSC_RELIABLE flag in Linux kernel implies both reliable
(at runtime) and trustable (at calibration). But reliable running and
trustable calibration are logically irrelevant. Per Thomas Gleixner's
suggestion we would like to split this flag into two separate flags:
X86_FEATURE_TSC_RELIABLE - running reliably
X86_FEATURE_TSC_KNOWN_FREQ - frequency is known (no calibration required)
These two flags allow Linux kernel to act differently based on
processor/SoC's capability, i.e. no watchdog on TSC if TSC is reliable,
and no calibration if TSC frequency is known.

Current Linux kernel already gurantees calibration is skipped for
processors that can report TSC frequency by CPUID or MSR. However, the
delayed calibration is still not skipped for these CPUID/MSR capable
processors. The new flag X86_FEATURE_TSC_KNOWN_FREQ added by this patch
will gurantee the delayed calibration is skipped.

Signed-off-by: Bin Gao 
---
 arch/x86/include/asm/cpufeatures.h |  1 +
 arch/x86/kernel/tsc.c  | 11 ---
 2 files changed, 9 insertions(+), 3 deletions(-)

diff --git a/arch/x86/include/asm/cpufeatures.h 
b/arch/x86/include/asm/cpufeatures.h
index a396292..7f6a5f8 100644
--- a/arch/x86/include/asm/cpufeatures.h
+++ b/arch/x86/include/asm/cpufeatures.h
@@ -106,6 +106,7 @@
 #define X86_FEATURE_APERFMPERF ( 3*32+28) /* APERFMPERF */
 #define X86_FEATURE_EAGER_FPU  ( 3*32+29) /* "eagerfpu" Non lazy FPU restore */
 #define X86_FEATURE_NONSTOP_TSC_S3 ( 3*32+30) /* TSC doesn't stop in S3 state 
*/
+#define X86_FEATURE_TSC_KNOWN_FREQ ( 3*32+31) /* TSC has known frequency */
 
 /* Intel-defined CPU features, CPUID level 0x0001 (ecx), word 4 */
 #define X86_FEATURE_XMM3   ( 4*32+ 0) /* "pni" SSE-3 */
diff --git a/arch/x86/kernel/tsc.c b/arch/x86/kernel/tsc.c
index 46b2f41..3ba146e 100644
--- a/arch/x86/kernel/tsc.c
+++ b/arch/x86/kernel/tsc.c
@@ -1283,10 +1283,15 @@ static int __init init_tsc_clocksource(void)
clocksource_tsc.flags |= CLOCK_SOURCE_SUSPEND_NONSTOP;
 
/*
-* Trust the results of the earlier calibration on systems
-* exporting a reliable TSC.
+* When TSC frequency is known (generally got by MSR or CPUID), we skip
+* the refined calibration and directly register it as a clocksource.
+*
+* We still keep the TSC_RELIABLE flag here to avoid regression -
+* it will be removed after all the conversion for other code paths
+* connected to this flag is done.
 */
-   if (boot_cpu_has(X86_FEATURE_TSC_RELIABLE)) {
+   if (boot_cpu_has(X86_FEATURE_TSC_RELIABLE) ||
+   boot_cpu_has(X86_FEATURE_TSC_KNOWN_FREQ)) {
clocksource_register_khz(_tsc, tsc_khz);
return 0;
}
-- 
1.9.1



[PATCH 4/4] x86/tsc: set TSC_KNOWN_FREQ and TSC_RELIABLE flags on Intel Atom SoCs

2016-11-15 Thread Bin Gao
TSC on Intel Atom SoCs capable of determining TSC frequency by MSR is
reliable and the frequency is known (because it's provided by HW).
On these platforms PIT/HPET is generally not available so
calibration won't work at all and also TSC is the only reliable
clocksource. So we set both X86_FEATURE_TSC_KNOWN_FREQ and
X86_FEATURE_TSC_RELIABLE flags to make sure the calibration is
skipped and no watchdog on TSC.

Signed-off-by: Bin Gao <bin@intel.com>
---
 arch/x86/kernel/tsc_msr.c   | 18 ++
 arch/x86/platform/intel-mid/mfld.c  |  9 +++--
 arch/x86/platform/intel-mid/mrfld.c |  8 ++--
 3 files changed, 31 insertions(+), 4 deletions(-)

diff --git a/arch/x86/kernel/tsc_msr.c b/arch/x86/kernel/tsc_msr.c
index 0fe720d..c0f137c 100644
--- a/arch/x86/kernel/tsc_msr.c
+++ b/arch/x86/kernel/tsc_msr.c
@@ -100,5 +100,23 @@ unsigned long cpu_khz_from_msr(void)
 #ifdef CONFIG_X86_LOCAL_APIC
lapic_timer_frequency = (freq * 1000) / HZ;
 #endif
+
+   /*
+* TSC frequency determined by MSR is always considered "known"
+* because it is reported by HW.
+* Another fact is that on MSR capable platforms, PIT/HPET is
+* generally not available so calibration won't work at all.
+*/
+   setup_force_cpu_cap(X86_FEATURE_TSC_KNOWN_FREQ);
+
+   /*
+* Unfortunately there is no a HW way to report TSC is reliable.
+* We were told by silicon design team that TSC on Atom SoCs are
+* always "reliable". TSC is also the only reliable clocksource
+* on these SoCs (HPET is either not present or not functional)
+* so marke TSC reliable to avoid watchdog on it.
+*/
+   setup_force_cpu_cap(X86_FEATURE_TSC_RELIABLE);
+
return res;
 }
diff --git a/arch/x86/platform/intel-mid/mfld.c 
b/arch/x86/platform/intel-mid/mfld.c
index 1eb47b6..e793fe5 100644
--- a/arch/x86/platform/intel-mid/mfld.c
+++ b/arch/x86/platform/intel-mid/mfld.c
@@ -49,8 +49,13 @@ static unsigned long __init mfld_calibrate_tsc(void)
fast_calibrate = ratio * fsb;
pr_debug("read penwell tsc %lu khz\n", fast_calibrate);
lapic_timer_frequency = fsb * 1000 / HZ;
-   /* mark tsc clocksource as reliable */
-   set_cpu_cap(_cpu_data, X86_FEATURE_TSC_RELIABLE);
+
+   /*
+* TSC on Intel Atom SoCs is reliable and of known frequency.
+* See tsc_msr.c for details.
+*/
+   setup_force_cpu_cap(X86_FEATURE_TSC_KNOWN_FREQ);
+   setup_force_cpu_cap(X86_FEATURE_TSC_RELIABLE);
 
return fast_calibrate;
 }
diff --git a/arch/x86/platform/intel-mid/mrfld.c 
b/arch/x86/platform/intel-mid/mrfld.c
index 59253db..e0607c7 100644
--- a/arch/x86/platform/intel-mid/mrfld.c
+++ b/arch/x86/platform/intel-mid/mrfld.c
@@ -78,8 +78,12 @@ static unsigned long __init tangier_calibrate_tsc(void)
pr_debug("Setting lapic_timer_frequency = %d\n",
lapic_timer_frequency);
 
-   /* mark tsc clocksource as reliable */
-   set_cpu_cap(_cpu_data, X86_FEATURE_TSC_RELIABLE);
+   /*
+* TSC on Intel Atom SoCs is reliable and of known frequency.
+* See tsc_msr.c for details.
+*/
+   setup_force_cpu_cap(X86_FEATURE_TSC_KNOWN_FREQ);
+   setup_force_cpu_cap(X86_FEATURE_TSC_RELIABLE);
 
return fast_calibrate;
 }
-- 
1.9.1



[PATCH 4/4] x86/tsc: set TSC_KNOWN_FREQ and TSC_RELIABLE flags on Intel Atom SoCs

2016-11-15 Thread Bin Gao
TSC on Intel Atom SoCs capable of determining TSC frequency by MSR is
reliable and the frequency is known (because it's provided by HW).
On these platforms PIT/HPET is generally not available so
calibration won't work at all and also TSC is the only reliable
clocksource. So we set both X86_FEATURE_TSC_KNOWN_FREQ and
X86_FEATURE_TSC_RELIABLE flags to make sure the calibration is
skipped and no watchdog on TSC.

Signed-off-by: Bin Gao 
---
 arch/x86/kernel/tsc_msr.c   | 18 ++
 arch/x86/platform/intel-mid/mfld.c  |  9 +++--
 arch/x86/platform/intel-mid/mrfld.c |  8 ++--
 3 files changed, 31 insertions(+), 4 deletions(-)

diff --git a/arch/x86/kernel/tsc_msr.c b/arch/x86/kernel/tsc_msr.c
index 0fe720d..c0f137c 100644
--- a/arch/x86/kernel/tsc_msr.c
+++ b/arch/x86/kernel/tsc_msr.c
@@ -100,5 +100,23 @@ unsigned long cpu_khz_from_msr(void)
 #ifdef CONFIG_X86_LOCAL_APIC
lapic_timer_frequency = (freq * 1000) / HZ;
 #endif
+
+   /*
+* TSC frequency determined by MSR is always considered "known"
+* because it is reported by HW.
+* Another fact is that on MSR capable platforms, PIT/HPET is
+* generally not available so calibration won't work at all.
+*/
+   setup_force_cpu_cap(X86_FEATURE_TSC_KNOWN_FREQ);
+
+   /*
+* Unfortunately there is no a HW way to report TSC is reliable.
+* We were told by silicon design team that TSC on Atom SoCs are
+* always "reliable". TSC is also the only reliable clocksource
+* on these SoCs (HPET is either not present or not functional)
+* so marke TSC reliable to avoid watchdog on it.
+*/
+   setup_force_cpu_cap(X86_FEATURE_TSC_RELIABLE);
+
return res;
 }
diff --git a/arch/x86/platform/intel-mid/mfld.c 
b/arch/x86/platform/intel-mid/mfld.c
index 1eb47b6..e793fe5 100644
--- a/arch/x86/platform/intel-mid/mfld.c
+++ b/arch/x86/platform/intel-mid/mfld.c
@@ -49,8 +49,13 @@ static unsigned long __init mfld_calibrate_tsc(void)
fast_calibrate = ratio * fsb;
pr_debug("read penwell tsc %lu khz\n", fast_calibrate);
lapic_timer_frequency = fsb * 1000 / HZ;
-   /* mark tsc clocksource as reliable */
-   set_cpu_cap(_cpu_data, X86_FEATURE_TSC_RELIABLE);
+
+   /*
+* TSC on Intel Atom SoCs is reliable and of known frequency.
+* See tsc_msr.c for details.
+*/
+   setup_force_cpu_cap(X86_FEATURE_TSC_KNOWN_FREQ);
+   setup_force_cpu_cap(X86_FEATURE_TSC_RELIABLE);
 
return fast_calibrate;
 }
diff --git a/arch/x86/platform/intel-mid/mrfld.c 
b/arch/x86/platform/intel-mid/mrfld.c
index 59253db..e0607c7 100644
--- a/arch/x86/platform/intel-mid/mrfld.c
+++ b/arch/x86/platform/intel-mid/mrfld.c
@@ -78,8 +78,12 @@ static unsigned long __init tangier_calibrate_tsc(void)
pr_debug("Setting lapic_timer_frequency = %d\n",
lapic_timer_frequency);
 
-   /* mark tsc clocksource as reliable */
-   set_cpu_cap(_cpu_data, X86_FEATURE_TSC_RELIABLE);
+   /*
+* TSC on Intel Atom SoCs is reliable and of known frequency.
+* See tsc_msr.c for details.
+*/
+   setup_force_cpu_cap(X86_FEATURE_TSC_KNOWN_FREQ);
+   setup_force_cpu_cap(X86_FEATURE_TSC_RELIABLE);
 
return fast_calibrate;
 }
-- 
1.9.1



[PATCH 0/4] x86/tsc: add X86_FEATURE_TSC_KNOWN_FREQ flag and hardware related changes

2016-11-15 Thread Bin Gao
This patch series adds X86_FEATURE_TSC_KNOWN_FREQ flag and modifies
Intel Atom SoC related TSC codes to use the new TSC_KNOWN_FREQ flag
and the existed TSC_RELIABLE flag.

Bin Gao (4):
  x86/tsc: add X86_FEATURE_TSC_KNOWN_FREQ flag
  x86/tsc: mark TSC frequency determined by CPUID as known
  x86/tsc: mark Intel ATOM_GOLDMONT TSC reliable
  x86/tsc: set TSC_KNOWN_FREQ and TSC_RELIABLE flags on Intel Atom SoCs

 arch/x86/include/asm/cpufeatures.h  |  1 +
 arch/x86/kernel/tsc.c   | 25 ++---
 arch/x86/kernel/tsc_msr.c   | 18 ++
 arch/x86/platform/intel-mid/mfld.c  |  9 +++--
 arch/x86/platform/intel-mid/mrfld.c |  8 ++--
 5 files changed, 54 insertions(+), 7 deletions(-)

-- 
1.9.1



[PATCH 2/4] x86/tsc: mark TSC frequency determined by CPUID as known

2016-11-15 Thread Bin Gao
Unlike TSC calibration where we determin TSC frequency by another timer
with known frequency, CPUs/SoCs with CPUID leaf 0x15 come with a known
frequency and will report the frequency to software via CPUID
instruction. This hardware provided frequency is the "real" frequency
of TSC so we set the X86_FEATURE_TSC_KNOWN_FREQ flag to skip the whole
software calibration process.

We had a 24 hours test on one of the CPUID 0x15 capable platforms. With
PIT calibrated frequency, we got more than 3 seconds drift whereas with
CPUID determined frequency we only got less than 0.5 second drift. This
makes us believe that we should prefer CPUID determined frequency over
software calibrated frequency.

Signed-off-by: Bin Gao <bin@intel.com>
---
 arch/x86/kernel/tsc.c | 7 +++
 1 file changed, 7 insertions(+)

diff --git a/arch/x86/kernel/tsc.c b/arch/x86/kernel/tsc.c
index 3ba146e..f1a7fb5 100644
--- a/arch/x86/kernel/tsc.c
+++ b/arch/x86/kernel/tsc.c
@@ -702,6 +702,13 @@ unsigned long native_calibrate_tsc(void)
}
}
 
+   /*
+* TSC frequency determined by CPUID is a "hardware reported"
+* frequency and is the most accurate one so far we have. This
+* is considered a known frequency.
+*/
+   setup_force_cpu_cap(X86_FEATURE_TSC_KNOWN_FREQ);
+
return crystal_khz * ebx_numerator / eax_denominator;
 }
 
-- 
1.9.1



[PATCH 0/4] x86/tsc: add X86_FEATURE_TSC_KNOWN_FREQ flag and hardware related changes

2016-11-15 Thread Bin Gao
This patch series adds X86_FEATURE_TSC_KNOWN_FREQ flag and modifies
Intel Atom SoC related TSC codes to use the new TSC_KNOWN_FREQ flag
and the existed TSC_RELIABLE flag.

Bin Gao (4):
  x86/tsc: add X86_FEATURE_TSC_KNOWN_FREQ flag
  x86/tsc: mark TSC frequency determined by CPUID as known
  x86/tsc: mark Intel ATOM_GOLDMONT TSC reliable
  x86/tsc: set TSC_KNOWN_FREQ and TSC_RELIABLE flags on Intel Atom SoCs

 arch/x86/include/asm/cpufeatures.h  |  1 +
 arch/x86/kernel/tsc.c   | 25 ++---
 arch/x86/kernel/tsc_msr.c   | 18 ++
 arch/x86/platform/intel-mid/mfld.c  |  9 +++--
 arch/x86/platform/intel-mid/mrfld.c |  8 ++--
 5 files changed, 54 insertions(+), 7 deletions(-)

-- 
1.9.1



[PATCH 2/4] x86/tsc: mark TSC frequency determined by CPUID as known

2016-11-15 Thread Bin Gao
Unlike TSC calibration where we determin TSC frequency by another timer
with known frequency, CPUs/SoCs with CPUID leaf 0x15 come with a known
frequency and will report the frequency to software via CPUID
instruction. This hardware provided frequency is the "real" frequency
of TSC so we set the X86_FEATURE_TSC_KNOWN_FREQ flag to skip the whole
software calibration process.

We had a 24 hours test on one of the CPUID 0x15 capable platforms. With
PIT calibrated frequency, we got more than 3 seconds drift whereas with
CPUID determined frequency we only got less than 0.5 second drift. This
makes us believe that we should prefer CPUID determined frequency over
software calibrated frequency.

Signed-off-by: Bin Gao 
---
 arch/x86/kernel/tsc.c | 7 +++
 1 file changed, 7 insertions(+)

diff --git a/arch/x86/kernel/tsc.c b/arch/x86/kernel/tsc.c
index 3ba146e..f1a7fb5 100644
--- a/arch/x86/kernel/tsc.c
+++ b/arch/x86/kernel/tsc.c
@@ -702,6 +702,13 @@ unsigned long native_calibrate_tsc(void)
}
}
 
+   /*
+* TSC frequency determined by CPUID is a "hardware reported"
+* frequency and is the most accurate one so far we have. This
+* is considered a known frequency.
+*/
+   setup_force_cpu_cap(X86_FEATURE_TSC_KNOWN_FREQ);
+
return crystal_khz * ebx_numerator / eax_denominator;
 }
 
-- 
1.9.1



Re: Re: [PATCH 2/2] x86: use KNOWN_FREQ and RELIABLE TSC flags on certain processors/SoCs

2016-11-10 Thread Bin Gao
On Fri, Nov 11, 2016 at 12:26:40AM +0100, Thomas Gleixner wrote:
> On Thu, 10 Nov 2016, Bin Gao wrote:
> > > > @@ -702,6 +702,15 @@ unsigned long native_calibrate_tsc(void)
> > > > }
> > > > }
> > > >  
> > > > +   setup_force_cpu_cap(X86_FEATURE_TSC_KNOWN_FREQ);
> > > 
> > > I can understand the one below, but this one changes existing behaviour 
> > > w/o explaining why this is correct and desired. If at all then this wants 
> > > to be a seperate patch and not just mingled in your goldmont update.
> > 
> > native_calibrate_tsc() implements determining TSC frequency via CPUID.
> > The purpose to add X86_FEATURE_TSC_KNOWN_FREQ flag is exactly for this case:
> > TSC frequency determined via CPUID or MSR are always correct and the whole
> > calibration should be skipped.
> 
> Did you actually verify that this is correct and does not introduce NTP
> issues compared to the long term calibration on such platforms?
> 
> We've been burnt before and myself and others wasted enough time already
> debugging that crap.

Yes, we had a 24 hours test before on one of the CPUID capable platforms.
With PIT calibrated frequency, we got more than 3 seconds drift whereas
with CPUID determined frequency we only got less than 0.5 second drift.

Another fact is that on MSR capable platforms, PIT/HPET is generally not
available so calibration won't work at all.


Re: Re: [PATCH 2/2] x86: use KNOWN_FREQ and RELIABLE TSC flags on certain processors/SoCs

2016-11-10 Thread Bin Gao
On Fri, Nov 11, 2016 at 12:26:40AM +0100, Thomas Gleixner wrote:
> On Thu, 10 Nov 2016, Bin Gao wrote:
> > > > @@ -702,6 +702,15 @@ unsigned long native_calibrate_tsc(void)
> > > > }
> > > > }
> > > >  
> > > > +   setup_force_cpu_cap(X86_FEATURE_TSC_KNOWN_FREQ);
> > > 
> > > I can understand the one below, but this one changes existing behaviour 
> > > w/o explaining why this is correct and desired. If at all then this wants 
> > > to be a seperate patch and not just mingled in your goldmont update.
> > 
> > native_calibrate_tsc() implements determining TSC frequency via CPUID.
> > The purpose to add X86_FEATURE_TSC_KNOWN_FREQ flag is exactly for this case:
> > TSC frequency determined via CPUID or MSR are always correct and the whole
> > calibration should be skipped.
> 
> Did you actually verify that this is correct and does not introduce NTP
> issues compared to the long term calibration on such platforms?
> 
> We've been burnt before and myself and others wasted enough time already
> debugging that crap.

Yes, we had a 24 hours test before on one of the CPUID capable platforms.
With PIT calibrated frequency, we got more than 3 seconds drift whereas
with CPUID determined frequency we only got less than 0.5 second drift.

Another fact is that on MSR capable platforms, PIT/HPET is generally not
available so calibration won't work at all.


Re: Re: [PATCH 2/2] x86: use KNOWN_FREQ and RELIABLE TSC flags on certain processors/SoCs

2016-11-10 Thread Bin Gao
> > @@ -702,6 +702,15 @@ unsigned long native_calibrate_tsc(void)
> > }
> > }
> >  
> > +   setup_force_cpu_cap(X86_FEATURE_TSC_KNOWN_FREQ);
> 
> I can understand the one below, but this one changes existing behaviour w/o 
> explaining why this is correct and desired. If at all then this wants to be a 
> seperate patch and not just mingled in your goldmont update.

native_calibrate_tsc() implements determining TSC frequency via CPUID.
The purpose to add X86_FEATURE_TSC_KNOWN_FREQ flag is exactly for this case:
TSC frequency determined via CPUID or MSR are always correct and the whole
calibration should be skipped.

I will create a seperate patch for this to ensure it's not confusing with
the MSR related change below.

> 
> > +   /*
> > +* For Atom SoCs TSC is the only reliable clocksource.
> > +* Mark TSC reliable so no watchdog on it.
> > +*/
> > +   if (boot_cpu_data.x86_model == INTEL_FAM6_ATOM_GOLDMONT)
> > +   setup_force_cpu_cap(X86_FEATURE_TSC_RELIABLE);
> > +
> > return crystal_khz * ebx_numerator / eax_denominator;  }
> >  
> > diff --git a/arch/x86/kernel/tsc_msr.c b/arch/x86/kernel/tsc_msr.c 
> > index 0fe720d..d6aa75a 100644
> > --- a/arch/x86/kernel/tsc_msr.c
> > +++ b/arch/x86/kernel/tsc_msr.c
> > @@ -100,5 +100,9 @@ unsigned long cpu_khz_from_msr(void)  #ifdef 
> > CONFIG_X86_LOCAL_APIC
> > lapic_timer_frequency = (freq * 1000) / HZ;  #endif
> > +
> > +   setup_force_cpu_cap(X86_FEATURE_TSC_KNOWN_FREQ);
> > +   setup_force_cpu_cap(X86_FEATURE_TSC_RELIABLE);
> 
> Why is this automatically reliable and of known frequency?

As I said above, TSC frequency determined by CPUID or MSR is always considered
"known" because it is reported by HW.
Regarding the reliable, unfortunately however, there is no a HW way to report
it. We were told by silicon design team it's "reliable".

> 
> This evades the long term TSC calibration and also disables the watchdog, 
> which might break stuff left and right.
> 
> Please makes these changes one by one and explain why they are correct on 
> their own, preferrably with some substantial backfrom from the hw folks.

Yes we confirmed with HW folks. TSC count is guaranteed to monotonically
increase at the fixed frequency even during S3/S0i3 state on these platforms.
This change will be seperate from CPUID related change in next revision.

> 
> Thanks,
> 
>   tglx
> 
> 


Re: Re: [PATCH 2/2] x86: use KNOWN_FREQ and RELIABLE TSC flags on certain processors/SoCs

2016-11-10 Thread Bin Gao
> > @@ -702,6 +702,15 @@ unsigned long native_calibrate_tsc(void)
> > }
> > }
> >  
> > +   setup_force_cpu_cap(X86_FEATURE_TSC_KNOWN_FREQ);
> 
> I can understand the one below, but this one changes existing behaviour w/o 
> explaining why this is correct and desired. If at all then this wants to be a 
> seperate patch and not just mingled in your goldmont update.

native_calibrate_tsc() implements determining TSC frequency via CPUID.
The purpose to add X86_FEATURE_TSC_KNOWN_FREQ flag is exactly for this case:
TSC frequency determined via CPUID or MSR are always correct and the whole
calibration should be skipped.

I will create a seperate patch for this to ensure it's not confusing with
the MSR related change below.

> 
> > +   /*
> > +* For Atom SoCs TSC is the only reliable clocksource.
> > +* Mark TSC reliable so no watchdog on it.
> > +*/
> > +   if (boot_cpu_data.x86_model == INTEL_FAM6_ATOM_GOLDMONT)
> > +   setup_force_cpu_cap(X86_FEATURE_TSC_RELIABLE);
> > +
> > return crystal_khz * ebx_numerator / eax_denominator;  }
> >  
> > diff --git a/arch/x86/kernel/tsc_msr.c b/arch/x86/kernel/tsc_msr.c 
> > index 0fe720d..d6aa75a 100644
> > --- a/arch/x86/kernel/tsc_msr.c
> > +++ b/arch/x86/kernel/tsc_msr.c
> > @@ -100,5 +100,9 @@ unsigned long cpu_khz_from_msr(void)  #ifdef 
> > CONFIG_X86_LOCAL_APIC
> > lapic_timer_frequency = (freq * 1000) / HZ;  #endif
> > +
> > +   setup_force_cpu_cap(X86_FEATURE_TSC_KNOWN_FREQ);
> > +   setup_force_cpu_cap(X86_FEATURE_TSC_RELIABLE);
> 
> Why is this automatically reliable and of known frequency?

As I said above, TSC frequency determined by CPUID or MSR is always considered
"known" because it is reported by HW.
Regarding the reliable, unfortunately however, there is no a HW way to report
it. We were told by silicon design team it's "reliable".

> 
> This evades the long term TSC calibration and also disables the watchdog, 
> which might break stuff left and right.
> 
> Please makes these changes one by one and explain why they are correct on 
> their own, preferrably with some substantial backfrom from the hw folks.

Yes we confirmed with HW folks. TSC count is guaranteed to monotonically
increase at the fixed frequency even during S3/S0i3 state on these platforms.
This change will be seperate from CPUID related change in next revision.

> 
> Thanks,
> 
>   tglx
> 
> 


Re: Re: [PATCH 1/2] x86/tsc: add X86_FEATURE_TSC_KNOWN_FREQ flag

2016-11-10 Thread Bin Gao
> > --- a/arch/x86/kernel/tsc.c
> > +++ b/arch/x86/kernel/tsc.c
> > @@ -1283,10 +1283,10 @@ static int __init init_tsc_clocksource(void)
> > clocksource_tsc.flags |= CLOCK_SOURCE_SUSPEND_NONSTOP;
> >  
> > /*
> > -* Trust the results of the earlier calibration on systems
> > -* exporting a reliable TSC.
> > +* When TSC frequency is known (generally got by MSR or CPUID), we skip
> > +* the refined calibration and directly register it as a clocksource.
> >  */
> > -   if (boot_cpu_has(X86_FEATURE_TSC_RELIABLE)) {
> > +   if (boot_cpu_has(X86_FEATURE_TSC_KNOWN_FREQ)) {
> 
> This causes a regression, because with only this patch applied the 
> architectures which use the reliable flag for this today are not longer 
> taking this path.
> 
> The proper thing to do here is to make this:
> 
>   if (boot_cpu_has(X86_FEATURE_TSC_RELIABLE) ||
>   boot_cpu_has(X86_FEATURE_TSC_KNOWN_FREQ)) {
> 
> and remove the RELIABLE flag ckeck after the existing users are converted.

I Will fix this in next revision.
 
> Thanks,
> 
>   tglx
> 


Re: Re: [PATCH 1/2] x86/tsc: add X86_FEATURE_TSC_KNOWN_FREQ flag

2016-11-10 Thread Bin Gao
> > --- a/arch/x86/kernel/tsc.c
> > +++ b/arch/x86/kernel/tsc.c
> > @@ -1283,10 +1283,10 @@ static int __init init_tsc_clocksource(void)
> > clocksource_tsc.flags |= CLOCK_SOURCE_SUSPEND_NONSTOP;
> >  
> > /*
> > -* Trust the results of the earlier calibration on systems
> > -* exporting a reliable TSC.
> > +* When TSC frequency is known (generally got by MSR or CPUID), we skip
> > +* the refined calibration and directly register it as a clocksource.
> >  */
> > -   if (boot_cpu_has(X86_FEATURE_TSC_RELIABLE)) {
> > +   if (boot_cpu_has(X86_FEATURE_TSC_KNOWN_FREQ)) {
> 
> This causes a regression, because with only this patch applied the 
> architectures which use the reliable flag for this today are not longer 
> taking this path.
> 
> The proper thing to do here is to make this:
> 
>   if (boot_cpu_has(X86_FEATURE_TSC_RELIABLE) ||
>   boot_cpu_has(X86_FEATURE_TSC_KNOWN_FREQ)) {
> 
> and remove the RELIABLE flag ckeck after the existing users are converted.

I Will fix this in next revision.
 
> Thanks,
> 
>   tglx
> 


[PATCH 0/2] x86/tsc: split X86_FEATURE_TSC_RELIABLE into two

2016-11-01 Thread Bin Gao
This patch series split X86_FEATURE_TSC_RELIABLE into two separate
flags: X86_FEATURE_TSC_RELIABLE and X86_FEATURE_TSC_KNOWN_FREQ.
This change allows us to redefine TSC features at fine granularity.
This is driven by certain Intel processors/SoCs with frequency-known
TSC so the whole calibration stuff should be skipped.

Bin Gao (2):
  x86/tsc: add X86_FEATURE_TSC_KNOWN_FREQ flag
  x86: use KNOWN_FREQ and RELIABLE TSC flags on certain processors/SoCs

 arch/x86/include/asm/cpufeatures.h  |  1 +
 arch/x86/kernel/tsc.c   | 15 ---
 arch/x86/kernel/tsc_msr.c   |  4 
 arch/x86/platform/intel-mid/mfld.c  |  5 +++--
 arch/x86/platform/intel-mid/mrfld.c |  4 ++--
 5 files changed, 22 insertions(+), 7 deletions(-)

-- 
1.9.1



[PATCH 0/2] x86/tsc: split X86_FEATURE_TSC_RELIABLE into two

2016-11-01 Thread Bin Gao
This patch series split X86_FEATURE_TSC_RELIABLE into two separate
flags: X86_FEATURE_TSC_RELIABLE and X86_FEATURE_TSC_KNOWN_FREQ.
This change allows us to redefine TSC features at fine granularity.
This is driven by certain Intel processors/SoCs with frequency-known
TSC so the whole calibration stuff should be skipped.

Bin Gao (2):
  x86/tsc: add X86_FEATURE_TSC_KNOWN_FREQ flag
  x86: use KNOWN_FREQ and RELIABLE TSC flags on certain processors/SoCs

 arch/x86/include/asm/cpufeatures.h  |  1 +
 arch/x86/kernel/tsc.c   | 15 ---
 arch/x86/kernel/tsc_msr.c   |  4 
 arch/x86/platform/intel-mid/mfld.c  |  5 +++--
 arch/x86/platform/intel-mid/mrfld.c |  4 ++--
 5 files changed, 22 insertions(+), 7 deletions(-)

-- 
1.9.1



[PATCH 2/2] x86: use KNOWN_FREQ and RELIABLE TSC flags on certain processors/SoCs

2016-11-01 Thread Bin Gao
With X86_FEATURE_TSC_RELIABLE is split into X86_FEATURE_TSC_KNOWN_FREQ
and X86_FEATURE_TSC_KNOWN_FREQ, some platforms with reliable and
frequency-known TSC have to be marked with these new flags. These platforms
are Intel processors/SoCs supporting getting TSC frequency by MSR or CPUID.

Signed-off-by: Bin Gao <bin@intel.com>
---
 arch/x86/kernel/tsc.c   | 9 +
 arch/x86/kernel/tsc_msr.c   | 4 
 arch/x86/platform/intel-mid/mfld.c  | 5 +++--
 arch/x86/platform/intel-mid/mrfld.c | 4 ++--
 4 files changed, 18 insertions(+), 4 deletions(-)

diff --git a/arch/x86/kernel/tsc.c b/arch/x86/kernel/tsc.c
index b4c82f8..4197768 100644
--- a/arch/x86/kernel/tsc.c
+++ b/arch/x86/kernel/tsc.c
@@ -702,6 +702,15 @@ unsigned long native_calibrate_tsc(void)
}
}
 
+   setup_force_cpu_cap(X86_FEATURE_TSC_KNOWN_FREQ);
+
+   /*
+* For Atom SoCs TSC is the only reliable clocksource.
+* Mark TSC reliable so no watchdog on it.
+*/
+   if (boot_cpu_data.x86_model == INTEL_FAM6_ATOM_GOLDMONT)
+   setup_force_cpu_cap(X86_FEATURE_TSC_RELIABLE);
+
return crystal_khz * ebx_numerator / eax_denominator;
 }
 
diff --git a/arch/x86/kernel/tsc_msr.c b/arch/x86/kernel/tsc_msr.c
index 0fe720d..d6aa75a 100644
--- a/arch/x86/kernel/tsc_msr.c
+++ b/arch/x86/kernel/tsc_msr.c
@@ -100,5 +100,9 @@ unsigned long cpu_khz_from_msr(void)
 #ifdef CONFIG_X86_LOCAL_APIC
lapic_timer_frequency = (freq * 1000) / HZ;
 #endif
+
+   setup_force_cpu_cap(X86_FEATURE_TSC_KNOWN_FREQ);
+   setup_force_cpu_cap(X86_FEATURE_TSC_RELIABLE);
+
return res;
 }
diff --git a/arch/x86/platform/intel-mid/mfld.c 
b/arch/x86/platform/intel-mid/mfld.c
index 1eb47b6..3fa41b4 100644
--- a/arch/x86/platform/intel-mid/mfld.c
+++ b/arch/x86/platform/intel-mid/mfld.c
@@ -49,8 +49,9 @@ static unsigned long __init mfld_calibrate_tsc(void)
fast_calibrate = ratio * fsb;
pr_debug("read penwell tsc %lu khz\n", fast_calibrate);
lapic_timer_frequency = fsb * 1000 / HZ;
-   /* mark tsc clocksource as reliable */
-   set_cpu_cap(_cpu_data, X86_FEATURE_TSC_RELIABLE);
+
+   setup_force_cpu_cap(X86_FEATURE_TSC_KNOWN_FREQ);
+   setup_force_cpu_cap(X86_FEATURE_TSC_RELIABLE);
 
return fast_calibrate;
 }
diff --git a/arch/x86/platform/intel-mid/mrfld.c 
b/arch/x86/platform/intel-mid/mrfld.c
index 59253db..9477b7e 100644
--- a/arch/x86/platform/intel-mid/mrfld.c
+++ b/arch/x86/platform/intel-mid/mrfld.c
@@ -78,8 +78,8 @@ static unsigned long __init tangier_calibrate_tsc(void)
pr_debug("Setting lapic_timer_frequency = %d\n",
lapic_timer_frequency);
 
-   /* mark tsc clocksource as reliable */
-   set_cpu_cap(_cpu_data, X86_FEATURE_TSC_RELIABLE);
+   setup_force_cpu_cap(X86_FEATURE_TSC_KNOWN_FREQ);
+   setup_force_cpu_cap(X86_FEATURE_TSC_RELIABLE);
 
return fast_calibrate;
 }
-- 
1.9.1



[PATCH 2/2] x86: use KNOWN_FREQ and RELIABLE TSC flags on certain processors/SoCs

2016-11-01 Thread Bin Gao
With X86_FEATURE_TSC_RELIABLE is split into X86_FEATURE_TSC_KNOWN_FREQ
and X86_FEATURE_TSC_KNOWN_FREQ, some platforms with reliable and
frequency-known TSC have to be marked with these new flags. These platforms
are Intel processors/SoCs supporting getting TSC frequency by MSR or CPUID.

Signed-off-by: Bin Gao 
---
 arch/x86/kernel/tsc.c   | 9 +
 arch/x86/kernel/tsc_msr.c   | 4 
 arch/x86/platform/intel-mid/mfld.c  | 5 +++--
 arch/x86/platform/intel-mid/mrfld.c | 4 ++--
 4 files changed, 18 insertions(+), 4 deletions(-)

diff --git a/arch/x86/kernel/tsc.c b/arch/x86/kernel/tsc.c
index b4c82f8..4197768 100644
--- a/arch/x86/kernel/tsc.c
+++ b/arch/x86/kernel/tsc.c
@@ -702,6 +702,15 @@ unsigned long native_calibrate_tsc(void)
}
}
 
+   setup_force_cpu_cap(X86_FEATURE_TSC_KNOWN_FREQ);
+
+   /*
+* For Atom SoCs TSC is the only reliable clocksource.
+* Mark TSC reliable so no watchdog on it.
+*/
+   if (boot_cpu_data.x86_model == INTEL_FAM6_ATOM_GOLDMONT)
+   setup_force_cpu_cap(X86_FEATURE_TSC_RELIABLE);
+
return crystal_khz * ebx_numerator / eax_denominator;
 }
 
diff --git a/arch/x86/kernel/tsc_msr.c b/arch/x86/kernel/tsc_msr.c
index 0fe720d..d6aa75a 100644
--- a/arch/x86/kernel/tsc_msr.c
+++ b/arch/x86/kernel/tsc_msr.c
@@ -100,5 +100,9 @@ unsigned long cpu_khz_from_msr(void)
 #ifdef CONFIG_X86_LOCAL_APIC
lapic_timer_frequency = (freq * 1000) / HZ;
 #endif
+
+   setup_force_cpu_cap(X86_FEATURE_TSC_KNOWN_FREQ);
+   setup_force_cpu_cap(X86_FEATURE_TSC_RELIABLE);
+
return res;
 }
diff --git a/arch/x86/platform/intel-mid/mfld.c 
b/arch/x86/platform/intel-mid/mfld.c
index 1eb47b6..3fa41b4 100644
--- a/arch/x86/platform/intel-mid/mfld.c
+++ b/arch/x86/platform/intel-mid/mfld.c
@@ -49,8 +49,9 @@ static unsigned long __init mfld_calibrate_tsc(void)
fast_calibrate = ratio * fsb;
pr_debug("read penwell tsc %lu khz\n", fast_calibrate);
lapic_timer_frequency = fsb * 1000 / HZ;
-   /* mark tsc clocksource as reliable */
-   set_cpu_cap(_cpu_data, X86_FEATURE_TSC_RELIABLE);
+
+   setup_force_cpu_cap(X86_FEATURE_TSC_KNOWN_FREQ);
+   setup_force_cpu_cap(X86_FEATURE_TSC_RELIABLE);
 
return fast_calibrate;
 }
diff --git a/arch/x86/platform/intel-mid/mrfld.c 
b/arch/x86/platform/intel-mid/mrfld.c
index 59253db..9477b7e 100644
--- a/arch/x86/platform/intel-mid/mrfld.c
+++ b/arch/x86/platform/intel-mid/mrfld.c
@@ -78,8 +78,8 @@ static unsigned long __init tangier_calibrate_tsc(void)
pr_debug("Setting lapic_timer_frequency = %d\n",
lapic_timer_frequency);
 
-   /* mark tsc clocksource as reliable */
-   set_cpu_cap(_cpu_data, X86_FEATURE_TSC_RELIABLE);
+   setup_force_cpu_cap(X86_FEATURE_TSC_KNOWN_FREQ);
+   setup_force_cpu_cap(X86_FEATURE_TSC_RELIABLE);
 
return fast_calibrate;
 }
-- 
1.9.1



[PATCH 1/2] x86/tsc: add X86_FEATURE_TSC_KNOWN_FREQ flag

2016-11-01 Thread Bin Gao
The X86_FEATURE_TSC_RELIABLE flag in Linux kernel implies both reliable
(at runtime) and trustable (at calibration). But reliable running and
trustable calibration are logically irrelevant. Per Thomas Gleixner's
suggestion we would like to split this flag into two separate flags:
X86_FEATURE_TSC_RELIABLE - running reliably
X86_FEATURE_TSC_KNOWN_FREQ - frequency is known (no calibration required)
These two flags allow Linux kernel to act differently based on
processor/SoC's capability, i.e. no watchdog on TSC if TSC is reliable,
and no calibration if TSC frequency is known.

Current Linux kernel already gurantees calibration is skipped for
processors that can report TSC frequency by CPUID or MSR. However, the
delayed calibration is still not skipped for these CPUID/MSR capable
processors. The new flag X86_FEATURE_TSC_KNOWN_FREQ added by this patch
will gurantee the delayed calibration is skipped.

Signed-off-by: Bin Gao <bin@intel.com>
---
 arch/x86/include/asm/cpufeatures.h | 1 +
 arch/x86/kernel/tsc.c  | 6 +++---
 2 files changed, 4 insertions(+), 3 deletions(-)

diff --git a/arch/x86/include/asm/cpufeatures.h 
b/arch/x86/include/asm/cpufeatures.h
index a396292..7f6a5f8 100644
--- a/arch/x86/include/asm/cpufeatures.h
+++ b/arch/x86/include/asm/cpufeatures.h
@@ -106,6 +106,7 @@
 #define X86_FEATURE_APERFMPERF ( 3*32+28) /* APERFMPERF */
 #define X86_FEATURE_EAGER_FPU  ( 3*32+29) /* "eagerfpu" Non lazy FPU restore */
 #define X86_FEATURE_NONSTOP_TSC_S3 ( 3*32+30) /* TSC doesn't stop in S3 state 
*/
+#define X86_FEATURE_TSC_KNOWN_FREQ ( 3*32+31) /* TSC has known frequency */
 
 /* Intel-defined CPU features, CPUID level 0x0001 (ecx), word 4 */
 #define X86_FEATURE_XMM3   ( 4*32+ 0) /* "pni" SSE-3 */
diff --git a/arch/x86/kernel/tsc.c b/arch/x86/kernel/tsc.c
index 46b2f41..b4c82f8 100644
--- a/arch/x86/kernel/tsc.c
+++ b/arch/x86/kernel/tsc.c
@@ -1283,10 +1283,10 @@ static int __init init_tsc_clocksource(void)
clocksource_tsc.flags |= CLOCK_SOURCE_SUSPEND_NONSTOP;
 
/*
-* Trust the results of the earlier calibration on systems
-* exporting a reliable TSC.
+* When TSC frequency is known (generally got by MSR or CPUID), we skip
+* the refined calibration and directly register it as a clocksource.
 */
-   if (boot_cpu_has(X86_FEATURE_TSC_RELIABLE)) {
+   if (boot_cpu_has(X86_FEATURE_TSC_KNOWN_FREQ)) {
clocksource_register_khz(_tsc, tsc_khz);
return 0;
}
-- 
1.9.1



[PATCH 1/2] x86/tsc: add X86_FEATURE_TSC_KNOWN_FREQ flag

2016-11-01 Thread Bin Gao
The X86_FEATURE_TSC_RELIABLE flag in Linux kernel implies both reliable
(at runtime) and trustable (at calibration). But reliable running and
trustable calibration are logically irrelevant. Per Thomas Gleixner's
suggestion we would like to split this flag into two separate flags:
X86_FEATURE_TSC_RELIABLE - running reliably
X86_FEATURE_TSC_KNOWN_FREQ - frequency is known (no calibration required)
These two flags allow Linux kernel to act differently based on
processor/SoC's capability, i.e. no watchdog on TSC if TSC is reliable,
and no calibration if TSC frequency is known.

Current Linux kernel already gurantees calibration is skipped for
processors that can report TSC frequency by CPUID or MSR. However, the
delayed calibration is still not skipped for these CPUID/MSR capable
processors. The new flag X86_FEATURE_TSC_KNOWN_FREQ added by this patch
will gurantee the delayed calibration is skipped.

Signed-off-by: Bin Gao 
---
 arch/x86/include/asm/cpufeatures.h | 1 +
 arch/x86/kernel/tsc.c  | 6 +++---
 2 files changed, 4 insertions(+), 3 deletions(-)

diff --git a/arch/x86/include/asm/cpufeatures.h 
b/arch/x86/include/asm/cpufeatures.h
index a396292..7f6a5f8 100644
--- a/arch/x86/include/asm/cpufeatures.h
+++ b/arch/x86/include/asm/cpufeatures.h
@@ -106,6 +106,7 @@
 #define X86_FEATURE_APERFMPERF ( 3*32+28) /* APERFMPERF */
 #define X86_FEATURE_EAGER_FPU  ( 3*32+29) /* "eagerfpu" Non lazy FPU restore */
 #define X86_FEATURE_NONSTOP_TSC_S3 ( 3*32+30) /* TSC doesn't stop in S3 state 
*/
+#define X86_FEATURE_TSC_KNOWN_FREQ ( 3*32+31) /* TSC has known frequency */
 
 /* Intel-defined CPU features, CPUID level 0x0001 (ecx), word 4 */
 #define X86_FEATURE_XMM3   ( 4*32+ 0) /* "pni" SSE-3 */
diff --git a/arch/x86/kernel/tsc.c b/arch/x86/kernel/tsc.c
index 46b2f41..b4c82f8 100644
--- a/arch/x86/kernel/tsc.c
+++ b/arch/x86/kernel/tsc.c
@@ -1283,10 +1283,10 @@ static int __init init_tsc_clocksource(void)
clocksource_tsc.flags |= CLOCK_SOURCE_SUSPEND_NONSTOP;
 
/*
-* Trust the results of the earlier calibration on systems
-* exporting a reliable TSC.
+* When TSC frequency is known (generally got by MSR or CPUID), we skip
+* the refined calibration and directly register it as a clocksource.
 */
-   if (boot_cpu_has(X86_FEATURE_TSC_RELIABLE)) {
+   if (boot_cpu_has(X86_FEATURE_TSC_KNOWN_FREQ)) {
clocksource_register_khz(_tsc, tsc_khz);
return 0;
}
-- 
1.9.1



[PATCH v3] x86/tsc: add X86_FEATURE_TSC_KNOWN_FREQ flag

2016-10-13 Thread Bin Gao
The X86_FEATURE_TSC_RELIABLE flag in Linux kernel implies both reliable
(at runtime) and trustable (at calibration). But reliable running and
trustable calibration are logically irrelevant. Per Thomas Gleixner's
suggestion we would like to split this flag into two separate flags:
X86_FEATURE_TSC_RELIABLE - running reliably
X86_FEATURE_TSC_KNOWN_FREQ - frequency is known (no calibration required)
These two flags allow Linux kernel to act differently based on
processor/SoC's capability, i.e. no watchdog on TSC if TSC is reliable,
and no calibration if TSC frequency is known.

Current Linux kernel already gurantees calibration is skipped for
processors that can report TSC frequency by CPUID or MSR. However, the
delayed calibration is still not skipped for these CPUID/MSR capable
processors. The new flag X86_FEATURE_TSC_KNOWN_FREQ added by this patch
will gurantee the delayed calibration is skipped.

Signed-off-by: Bin Gao <bin@intel.com>
---
 arch/x86/include/asm/cpufeatures.h  |  1 +
 arch/x86/kernel/tsc.c   | 11 ++-
 arch/x86/kernel/tsc_msr.c   |  6 ++
 arch/x86/platform/intel-mid/mfld.c  |  7 +--
 arch/x86/platform/intel-mid/mrfld.c |  6 --
 5 files changed, 26 insertions(+), 5 deletions(-)

diff --git a/arch/x86/include/asm/cpufeatures.h 
b/arch/x86/include/asm/cpufeatures.h
index 1188bc8..2df6e86 100644
--- a/arch/x86/include/asm/cpufeatures.h
+++ b/arch/x86/include/asm/cpufeatures.h
@@ -106,6 +106,7 @@
 #define X86_FEATURE_APERFMPERF ( 3*32+28) /* APERFMPERF */
 #define X86_FEATURE_EAGER_FPU  ( 3*32+29) /* "eagerfpu" Non lazy FPU restore */
 #define X86_FEATURE_NONSTOP_TSC_S3 ( 3*32+30) /* TSC doesn't stop in S3 state 
*/
+#define X86_FEATURE_TSC_KNOWN_FREQ ( 3*32+31) /* TSC has known frequency */
 
 /* Intel-defined CPU features, CPUID level 0x0001 (ecx), word 4 */
 #define X86_FEATURE_XMM3   ( 4*32+ 0) /* "pni" SSE-3 */
diff --git a/arch/x86/kernel/tsc.c b/arch/x86/kernel/tsc.c
index 46b2f41..aed2dc3 100644
--- a/arch/x86/kernel/tsc.c
+++ b/arch/x86/kernel/tsc.c
@@ -702,6 +702,15 @@ unsigned long native_calibrate_tsc(void)
}
}
 
+   setup_force_cpu_cap(X86_FEATURE_TSC_KNOWN_FREQ);
+
+   /*
+* For Atom SoCs TSC is the only reliable clocksource.
+* Mark TSC reliable so no watchdog on it.
+*/
+   if (boot_cpu_data.x86_model == INTEL_FAM6_ATOM_GOLDMONT)
+   setup_force_cpu_cap(X86_FEATURE_TSC_RELIABLE);
+
return crystal_khz * ebx_numerator / eax_denominator;
 }
 
@@ -1286,7 +1295,7 @@ static int __init init_tsc_clocksource(void)
 * Trust the results of the earlier calibration on systems
 * exporting a reliable TSC.
 */
-   if (boot_cpu_has(X86_FEATURE_TSC_RELIABLE)) {
+   if (boot_cpu_has(X86_FEATURE_TSC_KNOWN_FREQ)) {
clocksource_register_khz(_tsc, tsc_khz);
return 0;
}
diff --git a/arch/x86/kernel/tsc_msr.c b/arch/x86/kernel/tsc_msr.c
index 0fe720d..8c33292 100644
--- a/arch/x86/kernel/tsc_msr.c
+++ b/arch/x86/kernel/tsc_msr.c
@@ -100,5 +100,11 @@ unsigned long cpu_khz_from_msr(void)
 #ifdef CONFIG_X86_LOCAL_APIC
lapic_timer_frequency = (freq * 1000) / HZ;
 #endif
+
+   setup_force_cpu_cap(X86_FEATURE_TSC_KNOWN_FREQ);
+
+   /* Mark TSC reliable */
+   setup_force_cpu_cap(X86_FEATURE_TSC_RELIABLE);
+
return res;
 }
diff --git a/arch/x86/platform/intel-mid/mfld.c 
b/arch/x86/platform/intel-mid/mfld.c
index 1eb47b6..6724ab9b 100644
--- a/arch/x86/platform/intel-mid/mfld.c
+++ b/arch/x86/platform/intel-mid/mfld.c
@@ -49,8 +49,11 @@ static unsigned long __init mfld_calibrate_tsc(void)
fast_calibrate = ratio * fsb;
pr_debug("read penwell tsc %lu khz\n", fast_calibrate);
lapic_timer_frequency = fsb * 1000 / HZ;
-   /* mark tsc clocksource as reliable */
-   set_cpu_cap(_cpu_data, X86_FEATURE_TSC_RELIABLE);
+
+   setup_force_cpu_cap(X86_FEATURE_TSC_KNOWN_FREQ);
+
+   /* Mark TSC reliable */
+   setup_force_cpu_cap(X86_FEATURE_TSC_RELIABLE);
 
return fast_calibrate;
 }
diff --git a/arch/x86/platform/intel-mid/mrfld.c 
b/arch/x86/platform/intel-mid/mrfld.c
index 59253db..c8b9870 100644
--- a/arch/x86/platform/intel-mid/mrfld.c
+++ b/arch/x86/platform/intel-mid/mrfld.c
@@ -78,8 +78,10 @@ static unsigned long __init tangier_calibrate_tsc(void)
pr_debug("Setting lapic_timer_frequency = %d\n",
lapic_timer_frequency);
 
-   /* mark tsc clocksource as reliable */
-   set_cpu_cap(_cpu_data, X86_FEATURE_TSC_RELIABLE);
+   setup_force_cpu_cap(X86_FEATURE_TSC_KNOWN_FREQ);
+
+   /* Mark TSC reliable */
+   setup_force_cpu_cap(X86_FEATURE_TSC_RELIABLE);
 
return fast_calibrate;
 }
-- 
1.9.1



[PATCH v3] x86/tsc: add X86_FEATURE_TSC_KNOWN_FREQ flag

2016-10-13 Thread Bin Gao
The X86_FEATURE_TSC_RELIABLE flag in Linux kernel implies both reliable
(at runtime) and trustable (at calibration). But reliable running and
trustable calibration are logically irrelevant. Per Thomas Gleixner's
suggestion we would like to split this flag into two separate flags:
X86_FEATURE_TSC_RELIABLE - running reliably
X86_FEATURE_TSC_KNOWN_FREQ - frequency is known (no calibration required)
These two flags allow Linux kernel to act differently based on
processor/SoC's capability, i.e. no watchdog on TSC if TSC is reliable,
and no calibration if TSC frequency is known.

Current Linux kernel already gurantees calibration is skipped for
processors that can report TSC frequency by CPUID or MSR. However, the
delayed calibration is still not skipped for these CPUID/MSR capable
processors. The new flag X86_FEATURE_TSC_KNOWN_FREQ added by this patch
will gurantee the delayed calibration is skipped.

Signed-off-by: Bin Gao 
---
 arch/x86/include/asm/cpufeatures.h  |  1 +
 arch/x86/kernel/tsc.c   | 11 ++-
 arch/x86/kernel/tsc_msr.c   |  6 ++
 arch/x86/platform/intel-mid/mfld.c  |  7 +--
 arch/x86/platform/intel-mid/mrfld.c |  6 --
 5 files changed, 26 insertions(+), 5 deletions(-)

diff --git a/arch/x86/include/asm/cpufeatures.h 
b/arch/x86/include/asm/cpufeatures.h
index 1188bc8..2df6e86 100644
--- a/arch/x86/include/asm/cpufeatures.h
+++ b/arch/x86/include/asm/cpufeatures.h
@@ -106,6 +106,7 @@
 #define X86_FEATURE_APERFMPERF ( 3*32+28) /* APERFMPERF */
 #define X86_FEATURE_EAGER_FPU  ( 3*32+29) /* "eagerfpu" Non lazy FPU restore */
 #define X86_FEATURE_NONSTOP_TSC_S3 ( 3*32+30) /* TSC doesn't stop in S3 state 
*/
+#define X86_FEATURE_TSC_KNOWN_FREQ ( 3*32+31) /* TSC has known frequency */
 
 /* Intel-defined CPU features, CPUID level 0x0001 (ecx), word 4 */
 #define X86_FEATURE_XMM3   ( 4*32+ 0) /* "pni" SSE-3 */
diff --git a/arch/x86/kernel/tsc.c b/arch/x86/kernel/tsc.c
index 46b2f41..aed2dc3 100644
--- a/arch/x86/kernel/tsc.c
+++ b/arch/x86/kernel/tsc.c
@@ -702,6 +702,15 @@ unsigned long native_calibrate_tsc(void)
}
}
 
+   setup_force_cpu_cap(X86_FEATURE_TSC_KNOWN_FREQ);
+
+   /*
+* For Atom SoCs TSC is the only reliable clocksource.
+* Mark TSC reliable so no watchdog on it.
+*/
+   if (boot_cpu_data.x86_model == INTEL_FAM6_ATOM_GOLDMONT)
+   setup_force_cpu_cap(X86_FEATURE_TSC_RELIABLE);
+
return crystal_khz * ebx_numerator / eax_denominator;
 }
 
@@ -1286,7 +1295,7 @@ static int __init init_tsc_clocksource(void)
 * Trust the results of the earlier calibration on systems
 * exporting a reliable TSC.
 */
-   if (boot_cpu_has(X86_FEATURE_TSC_RELIABLE)) {
+   if (boot_cpu_has(X86_FEATURE_TSC_KNOWN_FREQ)) {
clocksource_register_khz(_tsc, tsc_khz);
return 0;
}
diff --git a/arch/x86/kernel/tsc_msr.c b/arch/x86/kernel/tsc_msr.c
index 0fe720d..8c33292 100644
--- a/arch/x86/kernel/tsc_msr.c
+++ b/arch/x86/kernel/tsc_msr.c
@@ -100,5 +100,11 @@ unsigned long cpu_khz_from_msr(void)
 #ifdef CONFIG_X86_LOCAL_APIC
lapic_timer_frequency = (freq * 1000) / HZ;
 #endif
+
+   setup_force_cpu_cap(X86_FEATURE_TSC_KNOWN_FREQ);
+
+   /* Mark TSC reliable */
+   setup_force_cpu_cap(X86_FEATURE_TSC_RELIABLE);
+
return res;
 }
diff --git a/arch/x86/platform/intel-mid/mfld.c 
b/arch/x86/platform/intel-mid/mfld.c
index 1eb47b6..6724ab9b 100644
--- a/arch/x86/platform/intel-mid/mfld.c
+++ b/arch/x86/platform/intel-mid/mfld.c
@@ -49,8 +49,11 @@ static unsigned long __init mfld_calibrate_tsc(void)
fast_calibrate = ratio * fsb;
pr_debug("read penwell tsc %lu khz\n", fast_calibrate);
lapic_timer_frequency = fsb * 1000 / HZ;
-   /* mark tsc clocksource as reliable */
-   set_cpu_cap(_cpu_data, X86_FEATURE_TSC_RELIABLE);
+
+   setup_force_cpu_cap(X86_FEATURE_TSC_KNOWN_FREQ);
+
+   /* Mark TSC reliable */
+   setup_force_cpu_cap(X86_FEATURE_TSC_RELIABLE);
 
return fast_calibrate;
 }
diff --git a/arch/x86/platform/intel-mid/mrfld.c 
b/arch/x86/platform/intel-mid/mrfld.c
index 59253db..c8b9870 100644
--- a/arch/x86/platform/intel-mid/mrfld.c
+++ b/arch/x86/platform/intel-mid/mrfld.c
@@ -78,8 +78,10 @@ static unsigned long __init tangier_calibrate_tsc(void)
pr_debug("Setting lapic_timer_frequency = %d\n",
lapic_timer_frequency);
 
-   /* mark tsc clocksource as reliable */
-   set_cpu_cap(_cpu_data, X86_FEATURE_TSC_RELIABLE);
+   setup_force_cpu_cap(X86_FEATURE_TSC_KNOWN_FREQ);
+
+   /* Mark TSC reliable */
+   setup_force_cpu_cap(X86_FEATURE_TSC_RELIABLE);
 
return fast_calibrate;
 }
-- 
1.9.1



Re: [PATCH v2] x86/tsc: Set X86_FEATURE_TSC_RELIABLE to skip refined calibration

2016-10-11 Thread Bin Gao
On Fri, Aug 26, 2016 at 12:14:58PM +0200, Thomas Gleixner wrote:
> On Fri, 26 Aug 2016, Thomas Gleixner wrote:
> > On Thu, 25 Aug 2016, Bin Gao wrote:
> > > On Wed, Aug 24, 2016 at 10:51:20AM +0200, Thomas Gleixner wrote:
> > > > On Tue, 16 Aug 2016, Bin Gao wrote:
> > > > > On some newer Intel x86 processors/SoCs the TSC frequency can be 
> > > > > directly
> > > > > calculated by factors read from specific MSR registers or from a cpuid
> > > > > leaf (0x15). TSC frequency calculated by native msr/cpuid is 
> > > > > absolutely
> > > > > accurate so we should always skip calibrating TSC aginst another 
> > > > > clock,
> > > > > e.g. PIT, HPET, etc. So we want to skip the refined calibration by 
> > > > > setting
> > > > > the X86_FEATURE_TSC_RELIABLE flag. Existing code setting the flag by
> > > > > set_cpu_cap() doesn't work as the flag is cleared later in 
> > > > > identify_cpu().
> > > > > A cpu caps flag is not cleared only if it's set by 
> > > > > setup_force_cpu_cap().
> > > > > This patch converted set_cpu_cap() to setup_force_cpu_cap() to ensure
> > > > > refined calibration is skipped.
> > > > > 
> > > > > We had a test on Intel CherryTrail platform: the 24 hours time drift 
> > > > > is
> > > > > 3.6 seconds if refined calibration was not skipped while the drift is 
> > > > > less
> > > > > than 0.6 second when refined calibration was skipped.
> > > > > 
> > > > > Correctly setting the X86_FEATURE_TSC_RELIABLE flag also guarantees 
> > > > > TSC is
> > > > > not monitored by timekeeping watchdog because on most of these system 
> > > > > TSC
> > > > > is the only reliable clocksource. HPET, for instance, works but may 
> > > > > not
> > > > > be reliable. So kernel may report a physically reliable TSC is not 
> > > > > reliable
> > > > > just because a physically not reliable HPET is acting as timekeeping
> > > > > watchdog.
> > > > 
> > > > What about non SoC systems where the MSR is available, but we still see 
> > > > that
> > > > cross socket TSC wreckage? This change will prevent the watchdog from
> > > > detecting that.
> > > 
> > > MSR is only available on Intel Atom SoCs. There is no such a multi-socket 
> > > system.
> > 
> > Fair enough.
> 
> Second thoughts. We should seperate the calibration aspect from the reliablity
> aspect.
> 
> If a MSR/CPUID readout provides reliable calibration then this does not tell
> us about the reliablity (i.e. no watchdog required). So having two flags for
> this - and sure you can set both on those SoCs is the proper solution.
> 
> Thanks,
> 
>   tglx


Hi Thomas,

The Linux kernel does think a reliable calibration implies the reliability (i.e.
no watchdog required). I'm posting some code pieces to explain.

X86_FEATURE_TSC_RELIABLE is referred only in two places as shown below.

As you can see from init_tsc_clocksource(), X86_FEATURE_TSC_RELIABLE acts
as a switch to launch the delayed calibration work. The delayed calibration
is skipped if X86_FEATURE_TSC_RELIABLE is set, else not.

In check_system_tsc_reliable(), X86_FEATURE_TSC_RELIABLE helps to set
tsc_clocksource_reliable which in turn enables TSC as a clocksource
watchdog, i.e. watching others instead of being watched by others.

So X86_FEATURE_TSC_RELIABLE really means two things:
1) Calibrated(or directly calculated) result is trustable so delayed
   calibration is skipped.
2) TSC is reliable so clocksource framework won't monitor it, instead
   TSC acts as a watchdog monitoring other clocksources.

X86_FEATURE_TSC_RELIABLE is set also only from two places:
arch/x86/platform/intel-mid/mrfld.c and arch/x86/platform/intel-mid/mrfld.c
which are for Intel Atom SoCs with MSR based TSC frequency calculation.

The patch I'm doing is to set this flag (X86_FEATURE_TSC_RELIABLE) for
another case: Intel processors/SoCs with CPUID based TSC frequency calculation.

arch/x86/kernel/tsc.c:
satic void __init check_system_tsc_reliable(void)
{
.. (lines ignored)

if (boot_cpu_has(X86_FEATURE_TSC_RELIABLE))
/* This flag is used by init_tsc_clocksource(), see below. */
tsc_clocksource_reliable = 1;
}

arch/x86/kernel/tsc.c:
static int __init init_tsc_clocksource(void)
{
.. (lines ignored)

if (tsc_clocksource_reliable)
clocksource_tsc.flags &= ~CLOCK_SOURCE_MUST_VERIFY;

.. (lines ignored)

/*
 * Trust the results of the earlier calibration on systems
 * exporting a reliable TSC.
 */
if (boot_cpu_has(X86_FEATURE_TSC_RELIABLE)) {
clocksource_register_khz(_tsc, tsc_khz);
return 0;
}
schedule_delayed_work(_irqwork, 0);
return 0;
}

Thanks,
Bin



Re: [PATCH v2] x86/tsc: Set X86_FEATURE_TSC_RELIABLE to skip refined calibration

2016-10-11 Thread Bin Gao
On Fri, Aug 26, 2016 at 12:14:58PM +0200, Thomas Gleixner wrote:
> On Fri, 26 Aug 2016, Thomas Gleixner wrote:
> > On Thu, 25 Aug 2016, Bin Gao wrote:
> > > On Wed, Aug 24, 2016 at 10:51:20AM +0200, Thomas Gleixner wrote:
> > > > On Tue, 16 Aug 2016, Bin Gao wrote:
> > > > > On some newer Intel x86 processors/SoCs the TSC frequency can be 
> > > > > directly
> > > > > calculated by factors read from specific MSR registers or from a cpuid
> > > > > leaf (0x15). TSC frequency calculated by native msr/cpuid is 
> > > > > absolutely
> > > > > accurate so we should always skip calibrating TSC aginst another 
> > > > > clock,
> > > > > e.g. PIT, HPET, etc. So we want to skip the refined calibration by 
> > > > > setting
> > > > > the X86_FEATURE_TSC_RELIABLE flag. Existing code setting the flag by
> > > > > set_cpu_cap() doesn't work as the flag is cleared later in 
> > > > > identify_cpu().
> > > > > A cpu caps flag is not cleared only if it's set by 
> > > > > setup_force_cpu_cap().
> > > > > This patch converted set_cpu_cap() to setup_force_cpu_cap() to ensure
> > > > > refined calibration is skipped.
> > > > > 
> > > > > We had a test on Intel CherryTrail platform: the 24 hours time drift 
> > > > > is
> > > > > 3.6 seconds if refined calibration was not skipped while the drift is 
> > > > > less
> > > > > than 0.6 second when refined calibration was skipped.
> > > > > 
> > > > > Correctly setting the X86_FEATURE_TSC_RELIABLE flag also guarantees 
> > > > > TSC is
> > > > > not monitored by timekeeping watchdog because on most of these system 
> > > > > TSC
> > > > > is the only reliable clocksource. HPET, for instance, works but may 
> > > > > not
> > > > > be reliable. So kernel may report a physically reliable TSC is not 
> > > > > reliable
> > > > > just because a physically not reliable HPET is acting as timekeeping
> > > > > watchdog.
> > > > 
> > > > What about non SoC systems where the MSR is available, but we still see 
> > > > that
> > > > cross socket TSC wreckage? This change will prevent the watchdog from
> > > > detecting that.
> > > 
> > > MSR is only available on Intel Atom SoCs. There is no such a multi-socket 
> > > system.
> > 
> > Fair enough.
> 
> Second thoughts. We should seperate the calibration aspect from the reliablity
> aspect.
> 
> If a MSR/CPUID readout provides reliable calibration then this does not tell
> us about the reliablity (i.e. no watchdog required). So having two flags for
> this - and sure you can set both on those SoCs is the proper solution.
> 
> Thanks,
> 
>   tglx


Hi Thomas,

The Linux kernel does think a reliable calibration implies the reliability (i.e.
no watchdog required). I'm posting some code pieces to explain.

X86_FEATURE_TSC_RELIABLE is referred only in two places as shown below.

As you can see from init_tsc_clocksource(), X86_FEATURE_TSC_RELIABLE acts
as a switch to launch the delayed calibration work. The delayed calibration
is skipped if X86_FEATURE_TSC_RELIABLE is set, else not.

In check_system_tsc_reliable(), X86_FEATURE_TSC_RELIABLE helps to set
tsc_clocksource_reliable which in turn enables TSC as a clocksource
watchdog, i.e. watching others instead of being watched by others.

So X86_FEATURE_TSC_RELIABLE really means two things:
1) Calibrated(or directly calculated) result is trustable so delayed
   calibration is skipped.
2) TSC is reliable so clocksource framework won't monitor it, instead
   TSC acts as a watchdog monitoring other clocksources.

X86_FEATURE_TSC_RELIABLE is set also only from two places:
arch/x86/platform/intel-mid/mrfld.c and arch/x86/platform/intel-mid/mrfld.c
which are for Intel Atom SoCs with MSR based TSC frequency calculation.

The patch I'm doing is to set this flag (X86_FEATURE_TSC_RELIABLE) for
another case: Intel processors/SoCs with CPUID based TSC frequency calculation.

arch/x86/kernel/tsc.c:
satic void __init check_system_tsc_reliable(void)
{
.. (lines ignored)

if (boot_cpu_has(X86_FEATURE_TSC_RELIABLE))
/* This flag is used by init_tsc_clocksource(), see below. */
tsc_clocksource_reliable = 1;
}

arch/x86/kernel/tsc.c:
static int __init init_tsc_clocksource(void)
{
.. (lines ignored)

if (tsc_clocksource_reliable)
clocksource_tsc.flags &= ~CLOCK_SOURCE_MUST_VERIFY;

.. (lines ignored)

/*
 * Trust the results of the earlier calibration on systems
 * exporting a reliable TSC.
 */
if (boot_cpu_has(X86_FEATURE_TSC_RELIABLE)) {
clocksource_register_khz(_tsc, tsc_khz);
return 0;
}
schedule_delayed_work(_irqwork, 0);
return 0;
}

Thanks,
Bin



Re: [PATCH] thermal: fix of_table.cocci warnings

2016-08-29 Thread Bin Gao
On Sat, Aug 27, 2016 at 08:59:12PM +0200, Julia Lawall wrote:
>  Make sure (of/i2c/platform)_device_id tables are NULL terminated
> Generated by: scripts/coccinelle/misc/of_table.cocci
> 
> CC: Yegnesh S Iyer 
> Signed-off-by: Julia Lawall 
> Signed-off-by: Fengguang Wu 
> ---
> 
> Please take the patch only if it's a positive warning. Thanks!
> 
>  intel_bxt_pmic_thermal.c |1 +
>  1 file changed, 1 insertion(+)
> 
> --- a/drivers/thermal/intel_bxt_pmic_thermal.c
> +++ b/drivers/thermal/intel_bxt_pmic_thermal.c
> @@ -281,6 +281,7 @@ static struct platform_device_id pmic_th
>   .name = "bxt_wcove_thermal",
>   .driver_data = (kernel_ulong_t)_thermal_data,
>   },
> + {},
>  };
> 
>  static struct platform_driver pmic_thermal_driver = {

Included in v5. Thanks.

-Bin


Re: [PATCH] thermal: fix of_table.cocci warnings

2016-08-29 Thread Bin Gao
On Sat, Aug 27, 2016 at 08:59:12PM +0200, Julia Lawall wrote:
>  Make sure (of/i2c/platform)_device_id tables are NULL terminated
> Generated by: scripts/coccinelle/misc/of_table.cocci
> 
> CC: Yegnesh S Iyer 
> Signed-off-by: Julia Lawall 
> Signed-off-by: Fengguang Wu 
> ---
> 
> Please take the patch only if it's a positive warning. Thanks!
> 
>  intel_bxt_pmic_thermal.c |1 +
>  1 file changed, 1 insertion(+)
> 
> --- a/drivers/thermal/intel_bxt_pmic_thermal.c
> +++ b/drivers/thermal/intel_bxt_pmic_thermal.c
> @@ -281,6 +281,7 @@ static struct platform_device_id pmic_th
>   .name = "bxt_wcove_thermal",
>   .driver_data = (kernel_ulong_t)_thermal_data,
>   },
> + {},
>  };
> 
>  static struct platform_driver pmic_thermal_driver = {

Included in v5. Thanks.

-Bin


[PATCH v5] thermal: add Intel BXT WhiskeyCove PMIC thermal driver

2016-08-29 Thread Bin Gao
This change adds support for Intel BXT Whiskey Cove PMIC thermal
driver which is intended to handle the alert interrupts triggered
upon thermal trip point cross and notify the thermal framework
appropriately with the zone, temp, crossed trip and event details.

Signed-off-by: Yegnesh S Iyer <yegnesh.s.i...@intel.com>
Signed-off-by: Bin Gao <bin@intel.com>
---
Changes in v5:
 - Applied patch Joe Perches <j...@perches.com> and reduced data
   segment size
 - Applied patch from Julia Lawall <julia.law...@lip6.fr> and fixed
   the platform_device_id to NULL entry terminated error
Changes in v4:
 - Fixed copyright year and changed GPL to GPL v2
Changes in v3:
 - Moved driver data from mfd domain to the driver
 - Minor coding style related cleanup
Changes in v2:
 - Removed unnecessary request_threaded_irq() - we should be only
   using devm_request_threaded_irq() with virq
 drivers/thermal/Kconfig  |  10 ++
 drivers/thermal/Makefile |   1 +
 drivers/thermal/intel_bxt_pmic_thermal.c | 299 +++
 3 files changed, 310 insertions(+)
 create mode 100644 drivers/thermal/intel_bxt_pmic_thermal.c

diff --git a/drivers/thermal/Kconfig b/drivers/thermal/Kconfig
index 2d702ca..9bdd624 100644
--- a/drivers/thermal/Kconfig
+++ b/drivers/thermal/Kconfig
@@ -332,6 +332,16 @@ menu "ACPI INT340X thermal drivers"
 source drivers/thermal/int340x_thermal/Kconfig
 endmenu
 
+config INTEL_BXT_PMIC_THERMAL
+   tristate "Intel Broxton PMIC thermal driver"
+   depends on X86 && INTEL_SOC_PMIC && REGMAP
+   help
+ Select this driver for Intel Broxton PMIC with ADC channels monitoring
+ system temperature measurements and alerts.
+ This driver is used for monitoring the ADC channels of PMIC and 
handles
+ the alert trip point interrupts and notifies the thermal framework 
with
+ the trip point and temperature details of the zone.
+
 config INTEL_PCH_THERMAL
tristate "Intel PCH Thermal Reporting Driver"
depends on X86 && PCI
diff --git a/drivers/thermal/Makefile b/drivers/thermal/Makefile
index 10b07c1..7aa7f4c 100644
--- a/drivers/thermal/Makefile
+++ b/drivers/thermal/Makefile
@@ -45,6 +45,7 @@ obj-$(CONFIG_INTEL_SOC_DTS_THERMAL)   += 
intel_soc_dts_thermal.o
 obj-$(CONFIG_INTEL_QUARK_DTS_THERMAL)  += intel_quark_dts_thermal.o
 obj-$(CONFIG_TI_SOC_THERMAL)   += ti-soc-thermal/
 obj-$(CONFIG_INT340X_THERMAL)  += int340x_thermal/
+obj-$(CONFIG_INTEL_BXT_PMIC_THERMAL) += intel_bxt_pmic_thermal.o
 obj-$(CONFIG_INTEL_PCH_THERMAL)+= intel_pch_thermal.o
 obj-$(CONFIG_ST_THERMAL)   += st/
 obj-$(CONFIG_TEGRA_SOCTHERM)   += tegra/
diff --git a/drivers/thermal/intel_bxt_pmic_thermal.c 
b/drivers/thermal/intel_bxt_pmic_thermal.c
new file mode 100644
index 000..4ae3e0c
--- /dev/null
+++ b/drivers/thermal/intel_bxt_pmic_thermal.c
@@ -0,0 +1,299 @@
+/*
+ * Intel Broxton PMIC thermal driver
+ *
+ * Copyright (C) 2016 Intel Corporation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License version
+ * 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#define BXTWC_THRM0IRQ 0x4E04
+#define BXTWC_THRM1IRQ 0x4E05
+#define BXTWC_THRM2IRQ 0x4E06
+#define BXTWC_MTHRM0IRQ0x4E12
+#define BXTWC_MTHRM1IRQ0x4E13
+#define BXTWC_MTHRM2IRQ0x4E14
+#define BXTWC_STHRM0IRQ0x4F19
+#define BXTWC_STHRM1IRQ0x4F1A
+#define BXTWC_STHRM2IRQ0x4F1B
+
+struct trip_config_map {
+   u16 irq_reg;
+   u16 irq_en;
+   u16 evt_stat;
+   u8 irq_mask;
+   u8 irq_en_mask;
+   u8 evt_mask;
+   u8 trip_num;
+};
+
+struct thermal_irq_map {
+   char handle[20];
+   int num_trips;
+   const struct trip_config_map *trip_config;
+};
+
+struct pmic_thermal_data {
+   const struct thermal_irq_map *maps;
+   int num_maps;
+};
+
+static const struct trip_config_map bxtwc_str0_trip_config[] = {
+   {
+   .irq_reg = BXTWC_THRM0IRQ,
+   .irq_mask = 0x01,
+   .irq_en = BXTWC_MTHRM0IRQ,
+   .irq_en_mask = 0x01,
+   .evt_stat = BXTWC_STHRM0IRQ,
+   .evt_mask = 0x01,
+   .trip_num = 0
+   },
+   {
+   .irq_reg = BXTWC_THRM0IRQ,
+   .irq_mask = 0x10,
+   .irq_en = BXTWC_MTHRM0IRQ,
+   .irq_en_mask = 0x10,

[PATCH v5] thermal: add Intel BXT WhiskeyCove PMIC thermal driver

2016-08-29 Thread Bin Gao
This change adds support for Intel BXT Whiskey Cove PMIC thermal
driver which is intended to handle the alert interrupts triggered
upon thermal trip point cross and notify the thermal framework
appropriately with the zone, temp, crossed trip and event details.

Signed-off-by: Yegnesh S Iyer 
Signed-off-by: Bin Gao 
---
Changes in v5:
 - Applied patch Joe Perches  and reduced data
   segment size
 - Applied patch from Julia Lawall  and fixed
   the platform_device_id to NULL entry terminated error
Changes in v4:
 - Fixed copyright year and changed GPL to GPL v2
Changes in v3:
 - Moved driver data from mfd domain to the driver
 - Minor coding style related cleanup
Changes in v2:
 - Removed unnecessary request_threaded_irq() - we should be only
   using devm_request_threaded_irq() with virq
 drivers/thermal/Kconfig  |  10 ++
 drivers/thermal/Makefile |   1 +
 drivers/thermal/intel_bxt_pmic_thermal.c | 299 +++
 3 files changed, 310 insertions(+)
 create mode 100644 drivers/thermal/intel_bxt_pmic_thermal.c

diff --git a/drivers/thermal/Kconfig b/drivers/thermal/Kconfig
index 2d702ca..9bdd624 100644
--- a/drivers/thermal/Kconfig
+++ b/drivers/thermal/Kconfig
@@ -332,6 +332,16 @@ menu "ACPI INT340X thermal drivers"
 source drivers/thermal/int340x_thermal/Kconfig
 endmenu
 
+config INTEL_BXT_PMIC_THERMAL
+   tristate "Intel Broxton PMIC thermal driver"
+   depends on X86 && INTEL_SOC_PMIC && REGMAP
+   help
+ Select this driver for Intel Broxton PMIC with ADC channels monitoring
+ system temperature measurements and alerts.
+ This driver is used for monitoring the ADC channels of PMIC and 
handles
+ the alert trip point interrupts and notifies the thermal framework 
with
+ the trip point and temperature details of the zone.
+
 config INTEL_PCH_THERMAL
tristate "Intel PCH Thermal Reporting Driver"
depends on X86 && PCI
diff --git a/drivers/thermal/Makefile b/drivers/thermal/Makefile
index 10b07c1..7aa7f4c 100644
--- a/drivers/thermal/Makefile
+++ b/drivers/thermal/Makefile
@@ -45,6 +45,7 @@ obj-$(CONFIG_INTEL_SOC_DTS_THERMAL)   += 
intel_soc_dts_thermal.o
 obj-$(CONFIG_INTEL_QUARK_DTS_THERMAL)  += intel_quark_dts_thermal.o
 obj-$(CONFIG_TI_SOC_THERMAL)   += ti-soc-thermal/
 obj-$(CONFIG_INT340X_THERMAL)  += int340x_thermal/
+obj-$(CONFIG_INTEL_BXT_PMIC_THERMAL) += intel_bxt_pmic_thermal.o
 obj-$(CONFIG_INTEL_PCH_THERMAL)+= intel_pch_thermal.o
 obj-$(CONFIG_ST_THERMAL)   += st/
 obj-$(CONFIG_TEGRA_SOCTHERM)   += tegra/
diff --git a/drivers/thermal/intel_bxt_pmic_thermal.c 
b/drivers/thermal/intel_bxt_pmic_thermal.c
new file mode 100644
index 000..4ae3e0c
--- /dev/null
+++ b/drivers/thermal/intel_bxt_pmic_thermal.c
@@ -0,0 +1,299 @@
+/*
+ * Intel Broxton PMIC thermal driver
+ *
+ * Copyright (C) 2016 Intel Corporation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License version
+ * 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#define BXTWC_THRM0IRQ 0x4E04
+#define BXTWC_THRM1IRQ 0x4E05
+#define BXTWC_THRM2IRQ 0x4E06
+#define BXTWC_MTHRM0IRQ0x4E12
+#define BXTWC_MTHRM1IRQ0x4E13
+#define BXTWC_MTHRM2IRQ0x4E14
+#define BXTWC_STHRM0IRQ0x4F19
+#define BXTWC_STHRM1IRQ0x4F1A
+#define BXTWC_STHRM2IRQ0x4F1B
+
+struct trip_config_map {
+   u16 irq_reg;
+   u16 irq_en;
+   u16 evt_stat;
+   u8 irq_mask;
+   u8 irq_en_mask;
+   u8 evt_mask;
+   u8 trip_num;
+};
+
+struct thermal_irq_map {
+   char handle[20];
+   int num_trips;
+   const struct trip_config_map *trip_config;
+};
+
+struct pmic_thermal_data {
+   const struct thermal_irq_map *maps;
+   int num_maps;
+};
+
+static const struct trip_config_map bxtwc_str0_trip_config[] = {
+   {
+   .irq_reg = BXTWC_THRM0IRQ,
+   .irq_mask = 0x01,
+   .irq_en = BXTWC_MTHRM0IRQ,
+   .irq_en_mask = 0x01,
+   .evt_stat = BXTWC_STHRM0IRQ,
+   .evt_mask = 0x01,
+   .trip_num = 0
+   },
+   {
+   .irq_reg = BXTWC_THRM0IRQ,
+   .irq_mask = 0x10,
+   .irq_en = BXTWC_MTHRM0IRQ,
+   .irq_en_mask = 0x10,
+   .evt_stat = BXTWC_STHRM0IRQ,
+   .evt_mask = 0x10,
+   .trip_num = 

[PATCH v4] thermal: add Intel BXT WhiskeyCove PMIC thermal driver

2016-08-26 Thread Bin Gao
From: Yegnesh S Iyer <yegnesh.s.i...@intel.com>

thermal: add Intel BXT Whiskey Cove PMIC thermal driver

This change adds support for Intel BXT Whiskey Cove PMIC thermal
driver which is intended to handle the alert interrupts triggered
upon thermal trip point cross and notify the thermal framework
appropriately with the zone, temp, crossed trip and event details.

Signed-off-by: Yegnesh S Iyer <yegnesh.s.i...@intel.com>
Signed-off-by: Bin Gao <bin@intel.com>
---
Changes in v4:
 - Fixed copyright year and changed GPL to GPL v2
Changes in v3:
 - Moved driver data from mfd domain to the driver
 - Minor coding style related cleanup
Changes in v2:
 - Removed unnecessary request_threaded_irq() - we should be only
   using devm_request_threaded_irq() with virq
 drivers/thermal/Kconfig  |  10 ++
 drivers/thermal/Makefile |   1 +
 drivers/thermal/intel_bxt_pmic_thermal.c | 299 +++
 3 files changed, 310 insertions(+)
 create mode 100644 drivers/thermal/intel_bxt_pmic_thermal.c

diff --git a/drivers/thermal/Kconfig b/drivers/thermal/Kconfig
index 2d702ca..9bdd624 100644
--- a/drivers/thermal/Kconfig
+++ b/drivers/thermal/Kconfig
@@ -332,6 +332,16 @@ menu "ACPI INT340X thermal drivers"
 source drivers/thermal/int340x_thermal/Kconfig
 endmenu
 
+config INTEL_BXT_PMIC_THERMAL
+   tristate "Intel Broxton PMIC thermal driver"
+   depends on X86 && INTEL_SOC_PMIC && REGMAP
+   help
+ Select this driver for Intel Broxton PMIC with ADC channels monitoring
+ system temperature measurements and alerts.
+ This driver is used for monitoring the ADC channels of PMIC and 
handles
+ the alert trip point interrupts and notifies the thermal framework 
with
+ the trip point and temperature details of the zone.
+
 config INTEL_PCH_THERMAL
tristate "Intel PCH Thermal Reporting Driver"
depends on X86 && PCI
diff --git a/drivers/thermal/Makefile b/drivers/thermal/Makefile
index 10b07c1..7aa7f4c 100644
--- a/drivers/thermal/Makefile
+++ b/drivers/thermal/Makefile
@@ -45,6 +45,7 @@ obj-$(CONFIG_INTEL_SOC_DTS_THERMAL)   += 
intel_soc_dts_thermal.o
 obj-$(CONFIG_INTEL_QUARK_DTS_THERMAL)  += intel_quark_dts_thermal.o
 obj-$(CONFIG_TI_SOC_THERMAL)   += ti-soc-thermal/
 obj-$(CONFIG_INT340X_THERMAL)  += int340x_thermal/
+obj-$(CONFIG_INTEL_BXT_PMIC_THERMAL) += intel_bxt_pmic_thermal.o
 obj-$(CONFIG_INTEL_PCH_THERMAL)+= intel_pch_thermal.o
 obj-$(CONFIG_ST_THERMAL)   += st/
 obj-$(CONFIG_TEGRA_SOCTHERM)   += tegra/
diff --git a/drivers/thermal/intel_bxt_pmic_thermal.c 
b/drivers/thermal/intel_bxt_pmic_thermal.c
new file mode 100644
index 000..dd175c0
--- /dev/null
+++ b/drivers/thermal/intel_bxt_pmic_thermal.c
@@ -0,0 +1,299 @@
+/*
+ * Intel Broxton PMIC thermal driver
+ *
+ * Copyright (C) 2016 Intel Corporation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License version
+ * 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#define BXTWC_THRM0IRQ 0x4E04
+#define BXTWC_THRM1IRQ 0x4E05
+#define BXTWC_THRM2IRQ 0x4E06
+#define BXTWC_MTHRM0IRQ0x4E12
+#define BXTWC_MTHRM1IRQ0x4E13
+#define BXTWC_MTHRM2IRQ0x4E14
+#define BXTWC_STHRM0IRQ0x4F19
+#define BXTWC_STHRM1IRQ0x4F1A
+#define BXTWC_STHRM2IRQ0x4F1B
+
+struct trip_config_map {
+   u16 irq_reg;
+   u16 irq_en;
+   u16 evt_stat;
+   u8 irq_mask;
+   u8 irq_en_mask;
+   u8 evt_mask;
+   u8 trip_num;
+};
+
+struct thermal_irq_map {
+   char handle[20];
+   int num_trips;
+   struct trip_config_map *trip_config;
+};
+
+struct pmic_thermal_data {
+   struct thermal_irq_map *maps;
+   int num_maps;
+};
+
+static struct trip_config_map bxtwc_str0_trip_config[] = {
+   {
+   .irq_reg = BXTWC_THRM0IRQ,
+   .irq_mask = 0x01,
+   .irq_en = BXTWC_MTHRM0IRQ,
+   .irq_en_mask = 0x01,
+   .evt_stat = BXTWC_STHRM0IRQ,
+   .evt_mask = 0x01,
+   .trip_num = 0
+   },
+   {
+   .irq_reg = BXTWC_THRM0IRQ,
+   .irq_mask = 0x10,
+   .irq_en = BXTWC_MTHRM0IRQ,
+   .irq_en_mask = 0x10,
+   .evt_stat = BXTWC_STHRM0IRQ,
+   .evt_mask = 0x10,
+   .trip_num =

[PATCH v4] thermal: add Intel BXT WhiskeyCove PMIC thermal driver

2016-08-26 Thread Bin Gao
From: Yegnesh S Iyer 

thermal: add Intel BXT Whiskey Cove PMIC thermal driver

This change adds support for Intel BXT Whiskey Cove PMIC thermal
driver which is intended to handle the alert interrupts triggered
upon thermal trip point cross and notify the thermal framework
appropriately with the zone, temp, crossed trip and event details.

Signed-off-by: Yegnesh S Iyer 
Signed-off-by: Bin Gao 
---
Changes in v4:
 - Fixed copyright year and changed GPL to GPL v2
Changes in v3:
 - Moved driver data from mfd domain to the driver
 - Minor coding style related cleanup
Changes in v2:
 - Removed unnecessary request_threaded_irq() - we should be only
   using devm_request_threaded_irq() with virq
 drivers/thermal/Kconfig  |  10 ++
 drivers/thermal/Makefile |   1 +
 drivers/thermal/intel_bxt_pmic_thermal.c | 299 +++
 3 files changed, 310 insertions(+)
 create mode 100644 drivers/thermal/intel_bxt_pmic_thermal.c

diff --git a/drivers/thermal/Kconfig b/drivers/thermal/Kconfig
index 2d702ca..9bdd624 100644
--- a/drivers/thermal/Kconfig
+++ b/drivers/thermal/Kconfig
@@ -332,6 +332,16 @@ menu "ACPI INT340X thermal drivers"
 source drivers/thermal/int340x_thermal/Kconfig
 endmenu
 
+config INTEL_BXT_PMIC_THERMAL
+   tristate "Intel Broxton PMIC thermal driver"
+   depends on X86 && INTEL_SOC_PMIC && REGMAP
+   help
+ Select this driver for Intel Broxton PMIC with ADC channels monitoring
+ system temperature measurements and alerts.
+ This driver is used for monitoring the ADC channels of PMIC and 
handles
+ the alert trip point interrupts and notifies the thermal framework 
with
+ the trip point and temperature details of the zone.
+
 config INTEL_PCH_THERMAL
tristate "Intel PCH Thermal Reporting Driver"
depends on X86 && PCI
diff --git a/drivers/thermal/Makefile b/drivers/thermal/Makefile
index 10b07c1..7aa7f4c 100644
--- a/drivers/thermal/Makefile
+++ b/drivers/thermal/Makefile
@@ -45,6 +45,7 @@ obj-$(CONFIG_INTEL_SOC_DTS_THERMAL)   += 
intel_soc_dts_thermal.o
 obj-$(CONFIG_INTEL_QUARK_DTS_THERMAL)  += intel_quark_dts_thermal.o
 obj-$(CONFIG_TI_SOC_THERMAL)   += ti-soc-thermal/
 obj-$(CONFIG_INT340X_THERMAL)  += int340x_thermal/
+obj-$(CONFIG_INTEL_BXT_PMIC_THERMAL) += intel_bxt_pmic_thermal.o
 obj-$(CONFIG_INTEL_PCH_THERMAL)+= intel_pch_thermal.o
 obj-$(CONFIG_ST_THERMAL)   += st/
 obj-$(CONFIG_TEGRA_SOCTHERM)   += tegra/
diff --git a/drivers/thermal/intel_bxt_pmic_thermal.c 
b/drivers/thermal/intel_bxt_pmic_thermal.c
new file mode 100644
index 000..dd175c0
--- /dev/null
+++ b/drivers/thermal/intel_bxt_pmic_thermal.c
@@ -0,0 +1,299 @@
+/*
+ * Intel Broxton PMIC thermal driver
+ *
+ * Copyright (C) 2016 Intel Corporation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License version
+ * 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#define BXTWC_THRM0IRQ 0x4E04
+#define BXTWC_THRM1IRQ 0x4E05
+#define BXTWC_THRM2IRQ 0x4E06
+#define BXTWC_MTHRM0IRQ0x4E12
+#define BXTWC_MTHRM1IRQ0x4E13
+#define BXTWC_MTHRM2IRQ0x4E14
+#define BXTWC_STHRM0IRQ0x4F19
+#define BXTWC_STHRM1IRQ0x4F1A
+#define BXTWC_STHRM2IRQ0x4F1B
+
+struct trip_config_map {
+   u16 irq_reg;
+   u16 irq_en;
+   u16 evt_stat;
+   u8 irq_mask;
+   u8 irq_en_mask;
+   u8 evt_mask;
+   u8 trip_num;
+};
+
+struct thermal_irq_map {
+   char handle[20];
+   int num_trips;
+   struct trip_config_map *trip_config;
+};
+
+struct pmic_thermal_data {
+   struct thermal_irq_map *maps;
+   int num_maps;
+};
+
+static struct trip_config_map bxtwc_str0_trip_config[] = {
+   {
+   .irq_reg = BXTWC_THRM0IRQ,
+   .irq_mask = 0x01,
+   .irq_en = BXTWC_MTHRM0IRQ,
+   .irq_en_mask = 0x01,
+   .evt_stat = BXTWC_STHRM0IRQ,
+   .evt_mask = 0x01,
+   .trip_num = 0
+   },
+   {
+   .irq_reg = BXTWC_THRM0IRQ,
+   .irq_mask = 0x10,
+   .irq_en = BXTWC_MTHRM0IRQ,
+   .irq_en_mask = 0x10,
+   .evt_stat = BXTWC_STHRM0IRQ,
+   .evt_mask = 0x10,
+   .trip_num = 1
+   }
+};
+
+static struct trip_config_map bxtwc_str1_trip_config[] = {
+   {
+   .irq_

Re: [PATCH v2] x86/tsc: Set X86_FEATURE_TSC_RELIABLE to skip refined calibration

2016-08-25 Thread Bin Gao
On Wed, Aug 24, 2016 at 10:51:20AM +0200, Thomas Gleixner wrote:
> On Tue, 16 Aug 2016, Bin Gao wrote:
> > On some newer Intel x86 processors/SoCs the TSC frequency can be directly
> > calculated by factors read from specific MSR registers or from a cpuid
> > leaf (0x15). TSC frequency calculated by native msr/cpuid is absolutely
> > accurate so we should always skip calibrating TSC aginst another clock,
> > e.g. PIT, HPET, etc. So we want to skip the refined calibration by setting
> > the X86_FEATURE_TSC_RELIABLE flag. Existing code setting the flag by
> > set_cpu_cap() doesn't work as the flag is cleared later in identify_cpu().
> > A cpu caps flag is not cleared only if it's set by setup_force_cpu_cap().
> > This patch converted set_cpu_cap() to setup_force_cpu_cap() to ensure
> > refined calibration is skipped.
> > 
> > We had a test on Intel CherryTrail platform: the 24 hours time drift is
> > 3.6 seconds if refined calibration was not skipped while the drift is less
> > than 0.6 second when refined calibration was skipped.
> > 
> > Correctly setting the X86_FEATURE_TSC_RELIABLE flag also guarantees TSC is
> > not monitored by timekeeping watchdog because on most of these system TSC
> > is the only reliable clocksource. HPET, for instance, works but may not
> > be reliable. So kernel may report a physically reliable TSC is not reliable
> > just because a physically not reliable HPET is acting as timekeeping
> > watchdog.
> 
> What about non SoC systems where the MSR is available, but we still see that
> cross socket TSC wreckage? This change will prevent the watchdog from
> detecting that.

MSR is only available on Intel Atom SoCs. There is no such a multi-socket 
system.

> 
> Thanks,
> 
>   tglx


Re: [PATCH v2] x86/tsc: Set X86_FEATURE_TSC_RELIABLE to skip refined calibration

2016-08-25 Thread Bin Gao
On Wed, Aug 24, 2016 at 10:51:20AM +0200, Thomas Gleixner wrote:
> On Tue, 16 Aug 2016, Bin Gao wrote:
> > On some newer Intel x86 processors/SoCs the TSC frequency can be directly
> > calculated by factors read from specific MSR registers or from a cpuid
> > leaf (0x15). TSC frequency calculated by native msr/cpuid is absolutely
> > accurate so we should always skip calibrating TSC aginst another clock,
> > e.g. PIT, HPET, etc. So we want to skip the refined calibration by setting
> > the X86_FEATURE_TSC_RELIABLE flag. Existing code setting the flag by
> > set_cpu_cap() doesn't work as the flag is cleared later in identify_cpu().
> > A cpu caps flag is not cleared only if it's set by setup_force_cpu_cap().
> > This patch converted set_cpu_cap() to setup_force_cpu_cap() to ensure
> > refined calibration is skipped.
> > 
> > We had a test on Intel CherryTrail platform: the 24 hours time drift is
> > 3.6 seconds if refined calibration was not skipped while the drift is less
> > than 0.6 second when refined calibration was skipped.
> > 
> > Correctly setting the X86_FEATURE_TSC_RELIABLE flag also guarantees TSC is
> > not monitored by timekeeping watchdog because on most of these system TSC
> > is the only reliable clocksource. HPET, for instance, works but may not
> > be reliable. So kernel may report a physically reliable TSC is not reliable
> > just because a physically not reliable HPET is acting as timekeeping
> > watchdog.
> 
> What about non SoC systems where the MSR is available, but we still see that
> cross socket TSC wreckage? This change will prevent the watchdog from
> detecting that.

MSR is only available on Intel Atom SoCs. There is no such a multi-socket 
system.

> 
> Thanks,
> 
>   tglx


[PATCH v2] x86/tsc: Set X86_FEATURE_TSC_RELIABLE to skip refined calibration

2016-08-16 Thread Bin Gao
On some newer Intel x86 processors/SoCs the TSC frequency can be directly
calculated by factors read from specific MSR registers or from a cpuid
leaf (0x15). TSC frequency calculated by native msr/cpuid is absolutely
accurate so we should always skip calibrating TSC aginst another clock,
e.g. PIT, HPET, etc. So we want to skip the refined calibration by setting
the X86_FEATURE_TSC_RELIABLE flag. Existing code setting the flag by
set_cpu_cap() doesn't work as the flag is cleared later in identify_cpu().
A cpu caps flag is not cleared only if it's set by setup_force_cpu_cap().
This patch converted set_cpu_cap() to setup_force_cpu_cap() to ensure
refined calibration is skipped.

We had a test on Intel CherryTrail platform: the 24 hours time drift is
3.6 seconds if refined calibration was not skipped while the drift is less
than 0.6 second when refined calibration was skipped.

Correctly setting the X86_FEATURE_TSC_RELIABLE flag also guarantees TSC is
not monitored by timekeeping watchdog because on most of these system TSC
is the only reliable clocksource. HPET, for instance, works but may not
be reliable. So kernel may report a physically reliable TSC is not reliable
just because a physically not reliable HPET is acting as timekeeping
watchdog.

Signed-off-by: Bin Gao <bin@intel.com>
---
Changes in v2:
 - Set X86_FEATURE_TSC_RELIABLE for cpuid case
 - Patch description change
 arch/x86/kernel/tsc.c   | 1 +
 arch/x86/kernel/tsc_msr.c   | 2 ++
 arch/x86/platform/intel-mid/mfld.c  | 2 +-
 arch/x86/platform/intel-mid/mrfld.c | 2 +-
 4 files changed, 5 insertions(+), 2 deletions(-)

diff --git a/arch/x86/kernel/tsc.c b/arch/x86/kernel/tsc.c
index 78b9cb5..e26f86b 100644
--- a/arch/x86/kernel/tsc.c
+++ b/arch/x86/kernel/tsc.c
@@ -696,6 +696,7 @@ unsigned long native_calibrate_tsc(void)
}
}
 
+   setup_force_cpu_cap(X86_FEATURE_TSC_RELIABLE);
return crystal_khz * ebx_numerator / eax_denominator;
 }
 
diff --git a/arch/x86/kernel/tsc_msr.c b/arch/x86/kernel/tsc_msr.c
index 0fe720d..42335fb 100644
--- a/arch/x86/kernel/tsc_msr.c
+++ b/arch/x86/kernel/tsc_msr.c
@@ -100,5 +100,7 @@ unsigned long cpu_khz_from_msr(void)
 #ifdef CONFIG_X86_LOCAL_APIC
lapic_timer_frequency = (freq * 1000) / HZ;
 #endif
+
+   setup_force_cpu_cap(X86_FEATURE_TSC_RELIABLE);
return res;
 }
diff --git a/arch/x86/platform/intel-mid/mfld.c 
b/arch/x86/platform/intel-mid/mfld.c
index 1eb47b6..c75e7a4 100644
--- a/arch/x86/platform/intel-mid/mfld.c
+++ b/arch/x86/platform/intel-mid/mfld.c
@@ -50,7 +50,7 @@ static unsigned long __init mfld_calibrate_tsc(void)
pr_debug("read penwell tsc %lu khz\n", fast_calibrate);
lapic_timer_frequency = fsb * 1000 / HZ;
/* mark tsc clocksource as reliable */
-   set_cpu_cap(_cpu_data, X86_FEATURE_TSC_RELIABLE);
+   setup_force_cpu_cap(X86_FEATURE_TSC_RELIABLE);
 
return fast_calibrate;
 }
diff --git a/arch/x86/platform/intel-mid/mrfld.c 
b/arch/x86/platform/intel-mid/mrfld.c
index 59253db..126330c 100644
--- a/arch/x86/platform/intel-mid/mrfld.c
+++ b/arch/x86/platform/intel-mid/mrfld.c
@@ -79,7 +79,7 @@ static unsigned long __init tangier_calibrate_tsc(void)
lapic_timer_frequency);
 
/* mark tsc clocksource as reliable */
-   set_cpu_cap(_cpu_data, X86_FEATURE_TSC_RELIABLE);
+   setup_force_cpu_cap(X86_FEATURE_TSC_RELIABLE);
 
return fast_calibrate;
 }
-- 
1.9.1



[PATCH v2] x86/tsc: Set X86_FEATURE_TSC_RELIABLE to skip refined calibration

2016-08-16 Thread Bin Gao
On some newer Intel x86 processors/SoCs the TSC frequency can be directly
calculated by factors read from specific MSR registers or from a cpuid
leaf (0x15). TSC frequency calculated by native msr/cpuid is absolutely
accurate so we should always skip calibrating TSC aginst another clock,
e.g. PIT, HPET, etc. So we want to skip the refined calibration by setting
the X86_FEATURE_TSC_RELIABLE flag. Existing code setting the flag by
set_cpu_cap() doesn't work as the flag is cleared later in identify_cpu().
A cpu caps flag is not cleared only if it's set by setup_force_cpu_cap().
This patch converted set_cpu_cap() to setup_force_cpu_cap() to ensure
refined calibration is skipped.

We had a test on Intel CherryTrail platform: the 24 hours time drift is
3.6 seconds if refined calibration was not skipped while the drift is less
than 0.6 second when refined calibration was skipped.

Correctly setting the X86_FEATURE_TSC_RELIABLE flag also guarantees TSC is
not monitored by timekeeping watchdog because on most of these system TSC
is the only reliable clocksource. HPET, for instance, works but may not
be reliable. So kernel may report a physically reliable TSC is not reliable
just because a physically not reliable HPET is acting as timekeeping
watchdog.

Signed-off-by: Bin Gao 
---
Changes in v2:
 - Set X86_FEATURE_TSC_RELIABLE for cpuid case
 - Patch description change
 arch/x86/kernel/tsc.c   | 1 +
 arch/x86/kernel/tsc_msr.c   | 2 ++
 arch/x86/platform/intel-mid/mfld.c  | 2 +-
 arch/x86/platform/intel-mid/mrfld.c | 2 +-
 4 files changed, 5 insertions(+), 2 deletions(-)

diff --git a/arch/x86/kernel/tsc.c b/arch/x86/kernel/tsc.c
index 78b9cb5..e26f86b 100644
--- a/arch/x86/kernel/tsc.c
+++ b/arch/x86/kernel/tsc.c
@@ -696,6 +696,7 @@ unsigned long native_calibrate_tsc(void)
}
}
 
+   setup_force_cpu_cap(X86_FEATURE_TSC_RELIABLE);
return crystal_khz * ebx_numerator / eax_denominator;
 }
 
diff --git a/arch/x86/kernel/tsc_msr.c b/arch/x86/kernel/tsc_msr.c
index 0fe720d..42335fb 100644
--- a/arch/x86/kernel/tsc_msr.c
+++ b/arch/x86/kernel/tsc_msr.c
@@ -100,5 +100,7 @@ unsigned long cpu_khz_from_msr(void)
 #ifdef CONFIG_X86_LOCAL_APIC
lapic_timer_frequency = (freq * 1000) / HZ;
 #endif
+
+   setup_force_cpu_cap(X86_FEATURE_TSC_RELIABLE);
return res;
 }
diff --git a/arch/x86/platform/intel-mid/mfld.c 
b/arch/x86/platform/intel-mid/mfld.c
index 1eb47b6..c75e7a4 100644
--- a/arch/x86/platform/intel-mid/mfld.c
+++ b/arch/x86/platform/intel-mid/mfld.c
@@ -50,7 +50,7 @@ static unsigned long __init mfld_calibrate_tsc(void)
pr_debug("read penwell tsc %lu khz\n", fast_calibrate);
lapic_timer_frequency = fsb * 1000 / HZ;
/* mark tsc clocksource as reliable */
-   set_cpu_cap(_cpu_data, X86_FEATURE_TSC_RELIABLE);
+   setup_force_cpu_cap(X86_FEATURE_TSC_RELIABLE);
 
return fast_calibrate;
 }
diff --git a/arch/x86/platform/intel-mid/mrfld.c 
b/arch/x86/platform/intel-mid/mrfld.c
index 59253db..126330c 100644
--- a/arch/x86/platform/intel-mid/mrfld.c
+++ b/arch/x86/platform/intel-mid/mrfld.c
@@ -79,7 +79,7 @@ static unsigned long __init tangier_calibrate_tsc(void)
lapic_timer_frequency);
 
/* mark tsc clocksource as reliable */
-   set_cpu_cap(_cpu_data, X86_FEATURE_TSC_RELIABLE);
+   setup_force_cpu_cap(X86_FEATURE_TSC_RELIABLE);
 
return fast_calibrate;
 }
-- 
1.9.1



[PATCH] gpio: wcove-gpio: add get_direction method

2016-08-15 Thread Bin Gao
This patch adds .get_direction method for the gpio_chip structure
of the wcove_gpio driver.

Signed-off-by: Bin Gao <bin@intel.com>
---
 drivers/gpio/gpio-wcove.c | 14 ++
 1 file changed, 14 insertions(+)

diff --git a/drivers/gpio/gpio-wcove.c b/drivers/gpio/gpio-wcove.c
index f5c88df..e11d6a3 100644
--- a/drivers/gpio/gpio-wcove.c
+++ b/drivers/gpio/gpio-wcove.c
@@ -164,6 +164,19 @@ static int wcove_gpio_dir_out(struct gpio_chip *chip, 
unsigned int gpio,
CTLO_OUTPUT_SET | value);
 }
 
+static int wcove_gpio_get_direction(struct gpio_chip *chip, unsigned int gpio)
+{
+   struct wcove_gpio *wg = gpiochip_get_data(chip);
+   unsigned int val;
+   int ret;
+
+   ret = regmap_read(wg->regmap, to_reg(gpio, CTRL_OUT), );
+   if (ret)
+   return ret;
+
+   return !(val & CTLO_DIR_OUT);
+}
+
 static int wcove_gpio_get(struct gpio_chip *chip, unsigned int gpio)
 {
struct wcove_gpio *wg = gpiochip_get_data(chip);
@@ -394,6 +407,7 @@ static int wcove_gpio_probe(struct platform_device *pdev)
wg->chip.label = KBUILD_MODNAME;
wg->chip.direction_input = wcove_gpio_dir_in;
wg->chip.direction_output = wcove_gpio_dir_out;
+   wg->chip.get_direction = wcove_gpio_get_direction;
wg->chip.get = wcove_gpio_get;
wg->chip.set = wcove_gpio_set;
wg->chip.set_single_ended = wcove_gpio_set_single_ended,
-- 
1.9.1



[PATCH] gpio: wcove-gpio: add get_direction method

2016-08-15 Thread Bin Gao
This patch adds .get_direction method for the gpio_chip structure
of the wcove_gpio driver.

Signed-off-by: Bin Gao 
---
 drivers/gpio/gpio-wcove.c | 14 ++
 1 file changed, 14 insertions(+)

diff --git a/drivers/gpio/gpio-wcove.c b/drivers/gpio/gpio-wcove.c
index f5c88df..e11d6a3 100644
--- a/drivers/gpio/gpio-wcove.c
+++ b/drivers/gpio/gpio-wcove.c
@@ -164,6 +164,19 @@ static int wcove_gpio_dir_out(struct gpio_chip *chip, 
unsigned int gpio,
CTLO_OUTPUT_SET | value);
 }
 
+static int wcove_gpio_get_direction(struct gpio_chip *chip, unsigned int gpio)
+{
+   struct wcove_gpio *wg = gpiochip_get_data(chip);
+   unsigned int val;
+   int ret;
+
+   ret = regmap_read(wg->regmap, to_reg(gpio, CTRL_OUT), );
+   if (ret)
+   return ret;
+
+   return !(val & CTLO_DIR_OUT);
+}
+
 static int wcove_gpio_get(struct gpio_chip *chip, unsigned int gpio)
 {
struct wcove_gpio *wg = gpiochip_get_data(chip);
@@ -394,6 +407,7 @@ static int wcove_gpio_probe(struct platform_device *pdev)
wg->chip.label = KBUILD_MODNAME;
wg->chip.direction_input = wcove_gpio_dir_in;
wg->chip.direction_output = wcove_gpio_dir_out;
+   wg->chip.get_direction = wcove_gpio_get_direction;
wg->chip.get = wcove_gpio_get;
wg->chip.set = wcove_gpio_set;
wg->chip.set_single_ended = wcove_gpio_set_single_ended,
-- 
1.9.1



Re: [PATCH v2 1/2] usb: typec: Add USB Power Delivery sink port support

2016-07-27 Thread Bin Gao
On Wed, Jul 27, 2016 at 11:13:43AM +0300, Felipe Balbi wrote:
> 
> Hi,
> 
> Bin Gao <bin@linux.intel.com> writes:
> > This patch implements a simple USB Power Delivery sink port state machine.
> > It assumes the hardware only handles PD packet transmitting and receiving
> > over the CC line of the USB Type-C connector. The state transition is
> > completely controlled by software. This patch only implement the sink port
> > function and it doesn't support source port and port swap yet.
> >
> > This patch depends on these two patches:
> > https://lkml.org/lkml/2016/6/29/349
> > https://lkml.org/lkml/2016/6/29/350
> >
> > Signed-off-by: Bin Gao <bin@intel.com>
> > Changes in v2:
> >  - Removed work queue so messages are directly handled in phy driver's 
> > interrupt context
> >  - used pr_debug instead of pr_info for message dump
> >  - Converted PD driver to tristate and typec driver is independent of it
> 
> this should be after the tearline (---) below. We don't want this in
> changelog ;-)
> 
> > +static void handle_source_cap(struct pd_sink_port *port, u8 msg_revision,
> > +   u8 nr_objs, u8 *buf)
> > +{
> > +   int i;
> > +   u32 *obj;
> > +   u8 type;
> > +   struct pd_source_cap *cap = port->source_caps;
> > +
> > +   /*
> > +* The PD spec revision included in SOURCE_CAPABILITY message is the
> > +* highest revision that the Source supports.
> > +*/
> > +   port->pd_rev = msg_revision;
> > +
> > +   /*
> > +* First we need to save all PDOs - they may be used in the future.
> > +* USB PD spec says we must use PDOs in the most recent
> > +* SOURCE_CAPABILITY message. Here we replace old PDOs with new ones.
> > +*/
> > +   port->nr_source_caps = 0;
> > +   for (i = 0; i < nr_objs; i++) {
> > +   obj = (u32 *)(buf + i * PD_OBJ_SIZE);
> > +   type = (*obj >> SOURCE_CAP_TYPE_BIT) & SOURCE_CAP_TYPE_MASK;
> > +   switch (type) {
> > +   case PS_TYPE_FIXED:
> > +   cap->ps_type = PS_TYPE_FIXED;
> > +   cap->fixed = *(struct pd_pdo_src_fixed *)obj;
> > +   break;
> > +   case PS_TYPE_VARIABLE:
> > +   cap->ps_type = PS_TYPE_VARIABLE;
> > +   cap->variable = *(struct pd_pdo_variable *)obj;
> > +   break;
> > +   case PS_TYPE_BATTERY:
> > +   cap->ps_type = PS_TYPE_BATTERY;
> > +   cap->battery = *(struct pd_pdo_battery *)obj;
> > +   break;
> > +   default: /* shouldn't come here */
> > +   pr_err("Invalid Source Capability type: %u.\n", type);
> > +   continue;
> > +   }
> > +   port->nr_source_caps++;
> > +   cap++;
> > +   }
> > +
> > +   if (port->nr_source_caps == 0) {
> > +   pr_err("There is no valid PDOs in SOURCE_CAPABILITY message\n");
> > +   return;
> > +   }
> > +
> > +   /* If a contract is not established, we need send a REQUEST message */
> > +   if (port->state == PD_SINK_STATE_WAIT_FOR_SRC_CAP) {
> 
> this is wrong. Read the fluxchart in figure 8-42. Source can decide to
> send another Source Capability before receiving our Good CRC and we need
> to work with that. This state check is, at a minimum, wrong. I'd
> actually just go ahead and remove it.
> 
> > +   if (!send_request(port))
> > +   port->state = PD_SINK_STATE_REQUEST_SENT;
> > +   }
> > +}
> 
> -- 
> balbi

I'll fix these in next revision. Thanks for your review.

-Bin


Re: [PATCH v2 1/2] usb: typec: Add USB Power Delivery sink port support

2016-07-27 Thread Bin Gao
On Wed, Jul 27, 2016 at 11:13:43AM +0300, Felipe Balbi wrote:
> 
> Hi,
> 
> Bin Gao  writes:
> > This patch implements a simple USB Power Delivery sink port state machine.
> > It assumes the hardware only handles PD packet transmitting and receiving
> > over the CC line of the USB Type-C connector. The state transition is
> > completely controlled by software. This patch only implement the sink port
> > function and it doesn't support source port and port swap yet.
> >
> > This patch depends on these two patches:
> > https://lkml.org/lkml/2016/6/29/349
> > https://lkml.org/lkml/2016/6/29/350
> >
> > Signed-off-by: Bin Gao 
> > Changes in v2:
> >  - Removed work queue so messages are directly handled in phy driver's 
> > interrupt context
> >  - used pr_debug instead of pr_info for message dump
> >  - Converted PD driver to tristate and typec driver is independent of it
> 
> this should be after the tearline (---) below. We don't want this in
> changelog ;-)
> 
> > +static void handle_source_cap(struct pd_sink_port *port, u8 msg_revision,
> > +   u8 nr_objs, u8 *buf)
> > +{
> > +   int i;
> > +   u32 *obj;
> > +   u8 type;
> > +   struct pd_source_cap *cap = port->source_caps;
> > +
> > +   /*
> > +* The PD spec revision included in SOURCE_CAPABILITY message is the
> > +* highest revision that the Source supports.
> > +*/
> > +   port->pd_rev = msg_revision;
> > +
> > +   /*
> > +* First we need to save all PDOs - they may be used in the future.
> > +* USB PD spec says we must use PDOs in the most recent
> > +* SOURCE_CAPABILITY message. Here we replace old PDOs with new ones.
> > +*/
> > +   port->nr_source_caps = 0;
> > +   for (i = 0; i < nr_objs; i++) {
> > +   obj = (u32 *)(buf + i * PD_OBJ_SIZE);
> > +   type = (*obj >> SOURCE_CAP_TYPE_BIT) & SOURCE_CAP_TYPE_MASK;
> > +   switch (type) {
> > +   case PS_TYPE_FIXED:
> > +   cap->ps_type = PS_TYPE_FIXED;
> > +   cap->fixed = *(struct pd_pdo_src_fixed *)obj;
> > +   break;
> > +   case PS_TYPE_VARIABLE:
> > +   cap->ps_type = PS_TYPE_VARIABLE;
> > +   cap->variable = *(struct pd_pdo_variable *)obj;
> > +   break;
> > +   case PS_TYPE_BATTERY:
> > +   cap->ps_type = PS_TYPE_BATTERY;
> > +   cap->battery = *(struct pd_pdo_battery *)obj;
> > +   break;
> > +   default: /* shouldn't come here */
> > +   pr_err("Invalid Source Capability type: %u.\n", type);
> > +   continue;
> > +   }
> > +   port->nr_source_caps++;
> > +   cap++;
> > +   }
> > +
> > +   if (port->nr_source_caps == 0) {
> > +   pr_err("There is no valid PDOs in SOURCE_CAPABILITY message\n");
> > +   return;
> > +   }
> > +
> > +   /* If a contract is not established, we need send a REQUEST message */
> > +   if (port->state == PD_SINK_STATE_WAIT_FOR_SRC_CAP) {
> 
> this is wrong. Read the fluxchart in figure 8-42. Source can decide to
> send another Source Capability before receiving our Good CRC and we need
> to work with that. This state check is, at a minimum, wrong. I'd
> actually just go ahead and remove it.
> 
> > +   if (!send_request(port))
> > +   port->state = PD_SINK_STATE_REQUEST_SENT;
> > +   }
> > +}
> 
> -- 
> balbi

I'll fix these in next revision. Thanks for your review.

-Bin


Re: [PATCH v2 1/2] usb: typec: Add USB Power Delivery sink port support

2016-07-27 Thread Bin Gao
On Wed, Jul 27, 2016 at 11:21:13AM +0200, Oliver Neukum wrote:
> On Tue, 2016-07-26 at 11:37 -0700, Bin Gao wrote:
> > +#define MAKE_HEADER(port, header, msg, objs) \
> > +do { \
> > +   header->type = msg; \
> > +   header->data_role = PD_DATA_ROLE_UFP; \
> > +   header->revision = port->pd_rev; \
> > +   header->power_role = PD_POWER_ROLE_SINK; \
> > +   header->id = roll_msg_id(port); \
> > +   header->nr_objs = objs; \
> > +   header->extended = PD_MSG_NOT_EXTENDED; \
> > +} while (0)
> > +
> > +static struct pd_sink_port *sink_ports[MAX_NR_SINK_PORTS];
> > +static int nr_ports;
> > +
> > +BLOCKING_NOTIFIER_HEAD(pd_sink_notifier_list);
> > +
> > +static char *state_strings[] = {
> > +   "WAIT_FOR_SOURCE_CAPABILITY",
> > +   "REQUEST_SENT",
> > +   "ACCEPT_RECEIVED",
> > +   "POWER_SUPPLY_READY",
> > +};
> > +
> > +/* Control messages */
> > +static char *cmsg_strings[] = {
> > +   "GOODCRC",  /* 1 */
> > +   "GOTOMIN",  /* 2 */
> > +   "ACCEPT",   /* 3 */
> > +   "REJECT",   /* 4 */
> > +   "PING", /* 5 */
> > +   "PS_RDY",   /* 6 */
> > +   "GET_SRC_CAP",  /* 7 */
> > +   "GET_SINK_CAP", /* 8 */
> > +   "DR_SWAP",  /* 9 */
> > +   "PR_SWAP",  /* 10 */
> > +   "VCONN_SWAP",   /* 11 */
> > +   "WAIT", /* 12 */
> > +   "SOFT_RESET",   /* 13 */
> > +   "RESERVED", /* 14 */
> > +   "RESERVED", /* 15 */
> > +   "NOT_SUPPORTED",/* 16 */
> > +   "GET_SOURCE_CAP_EXTENDED",  /* 17 */
> > +   "GET_STATUS",   /* 18 */
> > +   "FR_SWAP",  /* 19 */
> > +   /* RESERVED 20 - 31 */
> > +};
> > +
> > +/* Data messages */
> > +static char *dmsg_strings[] = {
> > +   "SOURCE_CAP",   /* 1 */
> > +   "REQUEST",  /* 2 */
> > +   "BIST", /* 3 */
> > +   "SINK_CAP", /* 4 */
> > +   "BATTERY_STATUS",   /* 5 */
> > +   "ALERT",/* 6 */
> > +   "RESERVED", /* 7 */
> > +   "RESERVED", /* 8 */
> > +   "RESERVED", /* 9 */
> > +   "RESERVED", /* 10 */
> > +   "RESERVED", /* 11 */
> > +   "RESERVED", /* 12 */
> > +   "RESERVED", /* 13 */
> > +   "RESERVED", /* 14 */
> > +   "VENDOR_DEFINED",   /* 15 */
> > +   /* RESERVED 16 - 31 */
> > +};
> > +
> > +static char *state_to_string(enum pd_sink_state state)
> > +{
> > +   if (state < ARRAY_SIZE(state_strings))
> > +   return state_strings[state];
> > +   else
> > +   return NULL;
> > +}
> > +
> > +static char *msg_to_string(bool is_cmsg, u8 msg)
> > +{
> > +   int nr = is_cmsg ? ARRAY_SIZE(cmsg_strings) :
> > ARRAY_SIZE(dmsg_strings);
> > +
> > +   if (msg <= nr)
> > +   return is_cmsg ? cmsg_strings[msg - 1] :
> > dmsg_strings[msg - 1];
> > +   else
> > +   return "RESERVED";
> > +}
> > +
> > +static void print_message(int port, bool is_cmsg, u8 msg, bool recv)
> > +{
> > +   pr_debug("sink port %d: %s message %s %s\n", port,
> > +   is_cmsg ? "Control" : "Data",
> > +   msg_to_string(is_cmsg, msg),
> > +recv ? "received" : "sent)");
> > +}
> > +
> > +static inline bool fixed_ps_equal(struct sink_ps *p1,
> > +   struct sink_ps *p2)
> > +{
> > +   return p1->ps_type == p2->ps_type &&
> > +   p1->ps_fixed.voltage_fixed ==
> > p2->ps_fixed.voltage_fixed &&
> > +   p1->ps_fixed.current_default ==
> > p2->ps_fixed.current_default;
> > +}
> > +
> > +/* The message ID increments each time we send out a new message */
> > +static u8 roll_msg_id(struct pd_sink_port *port)
> > +{
> > +   u8 msg_id = port->msg_id;
> > +
> > +   if (msg_id == PD_MSG_ID_MAX)
> > +   msg_id = PD_MSG_ID_MIN;
> > +   else
> > +   msg_id++;
> > +
> > +   port->msg_id = msg_id;
> > +   return msg_id;
> > +}
> > +
> 
> These pieces of code are completely generic. They should be shared
> among drivers. Please move them into the include files.
> 
>   Regards
>   Oliver
> 
> 

They are only internally used by this driver (USB PD state machine driver).
And they are not used by drivers (typicall USB Type-C phy drivers) which
use APIs exposed by this driver. So I think it's not appropriate to move
to include files.


Re: [PATCH v2 1/2] usb: typec: Add USB Power Delivery sink port support

2016-07-27 Thread Bin Gao
On Wed, Jul 27, 2016 at 11:21:13AM +0200, Oliver Neukum wrote:
> On Tue, 2016-07-26 at 11:37 -0700, Bin Gao wrote:
> > +#define MAKE_HEADER(port, header, msg, objs) \
> > +do { \
> > +   header->type = msg; \
> > +   header->data_role = PD_DATA_ROLE_UFP; \
> > +   header->revision = port->pd_rev; \
> > +   header->power_role = PD_POWER_ROLE_SINK; \
> > +   header->id = roll_msg_id(port); \
> > +   header->nr_objs = objs; \
> > +   header->extended = PD_MSG_NOT_EXTENDED; \
> > +} while (0)
> > +
> > +static struct pd_sink_port *sink_ports[MAX_NR_SINK_PORTS];
> > +static int nr_ports;
> > +
> > +BLOCKING_NOTIFIER_HEAD(pd_sink_notifier_list);
> > +
> > +static char *state_strings[] = {
> > +   "WAIT_FOR_SOURCE_CAPABILITY",
> > +   "REQUEST_SENT",
> > +   "ACCEPT_RECEIVED",
> > +   "POWER_SUPPLY_READY",
> > +};
> > +
> > +/* Control messages */
> > +static char *cmsg_strings[] = {
> > +   "GOODCRC",  /* 1 */
> > +   "GOTOMIN",  /* 2 */
> > +   "ACCEPT",   /* 3 */
> > +   "REJECT",   /* 4 */
> > +   "PING", /* 5 */
> > +   "PS_RDY",   /* 6 */
> > +   "GET_SRC_CAP",  /* 7 */
> > +   "GET_SINK_CAP", /* 8 */
> > +   "DR_SWAP",  /* 9 */
> > +   "PR_SWAP",  /* 10 */
> > +   "VCONN_SWAP",   /* 11 */
> > +   "WAIT", /* 12 */
> > +   "SOFT_RESET",   /* 13 */
> > +   "RESERVED", /* 14 */
> > +   "RESERVED", /* 15 */
> > +   "NOT_SUPPORTED",/* 16 */
> > +   "GET_SOURCE_CAP_EXTENDED",  /* 17 */
> > +   "GET_STATUS",   /* 18 */
> > +   "FR_SWAP",  /* 19 */
> > +   /* RESERVED 20 - 31 */
> > +};
> > +
> > +/* Data messages */
> > +static char *dmsg_strings[] = {
> > +   "SOURCE_CAP",   /* 1 */
> > +   "REQUEST",  /* 2 */
> > +   "BIST", /* 3 */
> > +   "SINK_CAP", /* 4 */
> > +   "BATTERY_STATUS",   /* 5 */
> > +   "ALERT",/* 6 */
> > +   "RESERVED", /* 7 */
> > +   "RESERVED", /* 8 */
> > +   "RESERVED", /* 9 */
> > +   "RESERVED", /* 10 */
> > +   "RESERVED", /* 11 */
> > +   "RESERVED", /* 12 */
> > +   "RESERVED", /* 13 */
> > +   "RESERVED", /* 14 */
> > +   "VENDOR_DEFINED",   /* 15 */
> > +   /* RESERVED 16 - 31 */
> > +};
> > +
> > +static char *state_to_string(enum pd_sink_state state)
> > +{
> > +   if (state < ARRAY_SIZE(state_strings))
> > +   return state_strings[state];
> > +   else
> > +   return NULL;
> > +}
> > +
> > +static char *msg_to_string(bool is_cmsg, u8 msg)
> > +{
> > +   int nr = is_cmsg ? ARRAY_SIZE(cmsg_strings) :
> > ARRAY_SIZE(dmsg_strings);
> > +
> > +   if (msg <= nr)
> > +   return is_cmsg ? cmsg_strings[msg - 1] :
> > dmsg_strings[msg - 1];
> > +   else
> > +   return "RESERVED";
> > +}
> > +
> > +static void print_message(int port, bool is_cmsg, u8 msg, bool recv)
> > +{
> > +   pr_debug("sink port %d: %s message %s %s\n", port,
> > +   is_cmsg ? "Control" : "Data",
> > +   msg_to_string(is_cmsg, msg),
> > +recv ? "received" : "sent)");
> > +}
> > +
> > +static inline bool fixed_ps_equal(struct sink_ps *p1,
> > +   struct sink_ps *p2)
> > +{
> > +   return p1->ps_type == p2->ps_type &&
> > +   p1->ps_fixed.voltage_fixed ==
> > p2->ps_fixed.voltage_fixed &&
> > +   p1->ps_fixed.current_default ==
> > p2->ps_fixed.current_default;
> > +}
> > +
> > +/* The message ID increments each time we send out a new message */
> > +static u8 roll_msg_id(struct pd_sink_port *port)
> > +{
> > +   u8 msg_id = port->msg_id;
> > +
> > +   if (msg_id == PD_MSG_ID_MAX)
> > +   msg_id = PD_MSG_ID_MIN;
> > +   else
> > +   msg_id++;
> > +
> > +   port->msg_id = msg_id;
> > +   return msg_id;
> > +}
> > +
> 
> These pieces of code are completely generic. They should be shared
> among drivers. Please move them into the include files.
> 
>   Regards
>   Oliver
> 
> 

They are only internally used by this driver (USB PD state machine driver).
And they are not used by drivers (typicall USB Type-C phy drivers) which
use APIs exposed by this driver. So I think it's not appropriate to move
to include files.


[PATCH v2 2/2] usb: typec: add PD sink port support for Intel Whiskey Cove PMIC Typc-C PHY driver

2016-07-26 Thread Bin Gao
From: Chandra Sekhar Anagani <chandra.sekhar.anag...@intel.com>

This adds PD sink port support for the USB Type-C PHY on Intel WhiskeyCove
PMIC which is available on some of the Intel Broxton SoC based platforms.

This patch depends on these two patches:
https://lkml.org/lkml/2016/6/29/349
https://lkml.org/lkml/2016/6/29/350

Signed-off-by: Chandra Sekhar Anagani <chandra.sekhar.anag...@intel.com>
Signed-off-by: Pranav Tipnis <pranav.tip...@intel.com>
Signed-off-by: Bin Gao <bin@intel.com>
Changes in v2:
 - Added PD support for cold boot case
---
 drivers/usb/typec/typec_wcove.c | 309 
 1 file changed, 285 insertions(+), 24 deletions(-)

diff --git a/drivers/usb/typec/typec_wcove.c b/drivers/usb/typec/typec_wcove.c
index c7c2d28..000d6ae 100644
--- a/drivers/usb/typec/typec_wcove.c
+++ b/drivers/usb/typec/typec_wcove.c
@@ -3,6 +3,7 @@
  *
  * Copyright (C) 2016 Intel Corporation
  * Author: Heikki Krogerus <heikki.kroge...@linux.intel.com>
+ * Author: Chandra Sekhar Anagani <chandra.sekhar.anag...@intel.com>
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License version 2 as
@@ -10,9 +11,11 @@
  */
 
 #include 
+#include 
 #include 
 #include 
 #include 
+#include 
 #include 
 #include 
 
@@ -25,6 +28,7 @@
 #define USBC_CONTROL3  0x7003
 #define USBC_CC1_CTRL  0x7004
 #define USBC_CC2_CTRL  0x7005
+#define USBC_CC_SEL0x7006
 #define USBC_STATUS1   0x7007
 #define USBC_STATUS2   0x7008
 #define USBC_STATUS3   0x7009
@@ -32,7 +36,16 @@
 #define USBC_IRQ2  0x7016
 #define USBC_IRQMASK1  0x7017
 #define USBC_IRQMASK2  0x7018
-
+#define USBC_PD_CFG1   0x7019
+#define USBC_PD_CFG2   0x701a
+#define USBC_PD_CFG3   0x701b
+#define USBC_PD_STATUS 0x701c
+#define USBC_RX_STATUS 0x701d
+#define USBC_RX_INFO   0x701e
+#define USBC_TX_CMD0x701f
+#define USBC_TX_INFO   0x7020
+#define USBC_RX_DATA_START 0x7028
+#define USBC_TX_DATA_START 0x7047
 /* Register bits */
 
 #define USBC_CONTROL1_MODE_DRP(r)  ((r & ~0x7) | 4)
@@ -44,7 +57,9 @@
 #define USBC_CONTROL3_PD_DIS   BIT(1)
 
 #define USBC_CC_CTRL_VCONN_EN  BIT(1)
+#define USBC_CC_CTRL_TX_EN BIT(2)
 
+#define USBC_CC_SEL_CCSEL  (BIT(0) | BIT(1))
 #define USBC_STATUS1_DET_ONGOING   BIT(6)
 #define USBC_STATUS1_RSLT(r)   (r & 0xf)
 #define USBC_RSLT_NOTHING  0
@@ -79,11 +94,44 @@
 USBC_IRQ2_RX_HR | USBC_IRQ2_RX_CR | \
 USBC_IRQ2_TX_SUCCESS | USBC_IRQ2_TX_FAIL)
 
+#define USBC_PD_CFG1_ID_FILL   BIT(7)
+
+#define USBC_PD_CFG2_SOP_RXBIT(0)
+
+#define USBC_PD_CFG3_SR_SOP2   (BIT(7) | BIT(6))
+#define USBC_PD_CFG3_SR_SOP1   (BIT(5) | BIT(4))
+#define USBC_PD_CFG3_SR_SOP0   (BIT(3) | BIT(2))
+#define USBC_PD_CFG3_DATAROLE  BIT(1)
+#define USBC_PD_CFG3_PWRROLE   BIT(0)
+
+#define USBC_TX_CMD_TXBUF_RDY  BIT(0)
+#define USBC_TX_CMD_TX_START   BIT(1)
+#define USBC_TX_CMD_TXBUF_CMD(r)   ((r >> 5) & 0x7)
+
+#define USBC_TX_INFO_TX_SOP(BIT(0) | BIT(1) | BIT(2))
+#define USBC_TX_INFO_TX_RETRIES(BIT(3) | BIT(4) | BIT(5))
+
+#define USBC_RX_STATUS_RX_DATA BIT(7)
+#define USBC_RX_STATUS_RX_OVERRUN  BIT(6)
+#define USBC_RX_STATUS_RX_CLEARBIT(0)
+
+#define USBC_PD_STATUS_RX_RSLT(r)  ((r >> 3) & 0x7)
+#define USBC_PD_STATUS_TX_RSLT(r)  (r & 0x7)
+
+#define USBC_RX_INFO_RXBYTES(r)((r >> 3) & 0x1f)
+#define USBC_RX_INFO_RX_SOP(r) (r & 0x7)
+
+#define USBC_PD_RX_BUF_LEN 30
+#define USBC_PD_TX_BUF_LEN 30
+#define USBC_PD_SEND_HR(3 << 5)
+
 struct wcove_typec {
+   int pd_port_num;
struct mutex lock; /* device lock */
struct device *dev;
struct regmap *regmap;
struct typec_port *port;
+   struct pd_sink_port pd_port;
struct typec_capability cap;
struct typec_connection con;
struct typec_partner partner;
@@ -106,6 +154,50 @@ enum wcove_typec_role {
WCOVE_ROLE_DEVICE,
 };
 
+static struct sink_ps profiles[] = {
+
+   {
+   .ps_type = PS_TYPE_FIXED,
+   .ps_fixed = {
+   .voltage_fixed  = 100,  /* 5V/50mV = 100 */
+   .current_default = 90,  /* 900mA/10mA = 90 */
+   .current_max= 90,   /* 900mA/10mA = 90 */
+   },
+
+   },
+
+   {
+   .ps_type = PS_TYPE_FIXED,
+   .ps_fixed = {
+   .voltage_fixed  = 100,
+

[PATCH v2 2/2] usb: typec: add PD sink port support for Intel Whiskey Cove PMIC Typc-C PHY driver

2016-07-26 Thread Bin Gao
From: Chandra Sekhar Anagani 

This adds PD sink port support for the USB Type-C PHY on Intel WhiskeyCove
PMIC which is available on some of the Intel Broxton SoC based platforms.

This patch depends on these two patches:
https://lkml.org/lkml/2016/6/29/349
https://lkml.org/lkml/2016/6/29/350

Signed-off-by: Chandra Sekhar Anagani 
Signed-off-by: Pranav Tipnis 
Signed-off-by: Bin Gao 
Changes in v2:
 - Added PD support for cold boot case
---
 drivers/usb/typec/typec_wcove.c | 309 
 1 file changed, 285 insertions(+), 24 deletions(-)

diff --git a/drivers/usb/typec/typec_wcove.c b/drivers/usb/typec/typec_wcove.c
index c7c2d28..000d6ae 100644
--- a/drivers/usb/typec/typec_wcove.c
+++ b/drivers/usb/typec/typec_wcove.c
@@ -3,6 +3,7 @@
  *
  * Copyright (C) 2016 Intel Corporation
  * Author: Heikki Krogerus 
+ * Author: Chandra Sekhar Anagani 
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License version 2 as
@@ -10,9 +11,11 @@
  */
 
 #include 
+#include 
 #include 
 #include 
 #include 
+#include 
 #include 
 #include 
 
@@ -25,6 +28,7 @@
 #define USBC_CONTROL3  0x7003
 #define USBC_CC1_CTRL  0x7004
 #define USBC_CC2_CTRL  0x7005
+#define USBC_CC_SEL0x7006
 #define USBC_STATUS1   0x7007
 #define USBC_STATUS2   0x7008
 #define USBC_STATUS3   0x7009
@@ -32,7 +36,16 @@
 #define USBC_IRQ2  0x7016
 #define USBC_IRQMASK1  0x7017
 #define USBC_IRQMASK2  0x7018
-
+#define USBC_PD_CFG1   0x7019
+#define USBC_PD_CFG2   0x701a
+#define USBC_PD_CFG3   0x701b
+#define USBC_PD_STATUS 0x701c
+#define USBC_RX_STATUS 0x701d
+#define USBC_RX_INFO   0x701e
+#define USBC_TX_CMD0x701f
+#define USBC_TX_INFO   0x7020
+#define USBC_RX_DATA_START 0x7028
+#define USBC_TX_DATA_START 0x7047
 /* Register bits */
 
 #define USBC_CONTROL1_MODE_DRP(r)  ((r & ~0x7) | 4)
@@ -44,7 +57,9 @@
 #define USBC_CONTROL3_PD_DIS   BIT(1)
 
 #define USBC_CC_CTRL_VCONN_EN  BIT(1)
+#define USBC_CC_CTRL_TX_EN BIT(2)
 
+#define USBC_CC_SEL_CCSEL  (BIT(0) | BIT(1))
 #define USBC_STATUS1_DET_ONGOING   BIT(6)
 #define USBC_STATUS1_RSLT(r)   (r & 0xf)
 #define USBC_RSLT_NOTHING  0
@@ -79,11 +94,44 @@
 USBC_IRQ2_RX_HR | USBC_IRQ2_RX_CR | \
 USBC_IRQ2_TX_SUCCESS | USBC_IRQ2_TX_FAIL)
 
+#define USBC_PD_CFG1_ID_FILL   BIT(7)
+
+#define USBC_PD_CFG2_SOP_RXBIT(0)
+
+#define USBC_PD_CFG3_SR_SOP2   (BIT(7) | BIT(6))
+#define USBC_PD_CFG3_SR_SOP1   (BIT(5) | BIT(4))
+#define USBC_PD_CFG3_SR_SOP0   (BIT(3) | BIT(2))
+#define USBC_PD_CFG3_DATAROLE  BIT(1)
+#define USBC_PD_CFG3_PWRROLE   BIT(0)
+
+#define USBC_TX_CMD_TXBUF_RDY  BIT(0)
+#define USBC_TX_CMD_TX_START   BIT(1)
+#define USBC_TX_CMD_TXBUF_CMD(r)   ((r >> 5) & 0x7)
+
+#define USBC_TX_INFO_TX_SOP(BIT(0) | BIT(1) | BIT(2))
+#define USBC_TX_INFO_TX_RETRIES(BIT(3) | BIT(4) | BIT(5))
+
+#define USBC_RX_STATUS_RX_DATA BIT(7)
+#define USBC_RX_STATUS_RX_OVERRUN  BIT(6)
+#define USBC_RX_STATUS_RX_CLEARBIT(0)
+
+#define USBC_PD_STATUS_RX_RSLT(r)  ((r >> 3) & 0x7)
+#define USBC_PD_STATUS_TX_RSLT(r)  (r & 0x7)
+
+#define USBC_RX_INFO_RXBYTES(r)((r >> 3) & 0x1f)
+#define USBC_RX_INFO_RX_SOP(r) (r & 0x7)
+
+#define USBC_PD_RX_BUF_LEN 30
+#define USBC_PD_TX_BUF_LEN 30
+#define USBC_PD_SEND_HR(3 << 5)
+
 struct wcove_typec {
+   int pd_port_num;
struct mutex lock; /* device lock */
struct device *dev;
struct regmap *regmap;
struct typec_port *port;
+   struct pd_sink_port pd_port;
struct typec_capability cap;
struct typec_connection con;
struct typec_partner partner;
@@ -106,6 +154,50 @@ enum wcove_typec_role {
WCOVE_ROLE_DEVICE,
 };
 
+static struct sink_ps profiles[] = {
+
+   {
+   .ps_type = PS_TYPE_FIXED,
+   .ps_fixed = {
+   .voltage_fixed  = 100,  /* 5V/50mV = 100 */
+   .current_default = 90,  /* 900mA/10mA = 90 */
+   .current_max= 90,   /* 900mA/10mA = 90 */
+   },
+
+   },
+
+   {
+   .ps_type = PS_TYPE_FIXED,
+   .ps_fixed = {
+   .voltage_fixed  = 100,
+   .current_default = 300,
+   .current_max= 300,
+   },
+   },
+
+   {
+   .ps_type = PS_TYPE_FIXED,
+   .ps_fixed = {
+   .voltage_fixed  =

[PATCH v2 1/2] usb: typec: Add USB Power Delivery sink port support

2016-07-26 Thread Bin Gao
This patch implements a simple USB Power Delivery sink port state machine.
It assumes the hardware only handles PD packet transmitting and receiving
over the CC line of the USB Type-C connector. The state transition is
completely controlled by software. This patch only implement the sink port
function and it doesn't support source port and port swap yet.

This patch depends on these two patches:
https://lkml.org/lkml/2016/6/29/349
https://lkml.org/lkml/2016/6/29/350

Signed-off-by: Bin Gao <bin@intel.com>
Changes in v2:
 - Removed work queue so messages are directly handled in phy driver's 
interrupt context
 - used pr_debug instead of pr_info for message dump
 - Converted PD driver to tristate and typec driver is independent of it
---
 drivers/usb/typec/Kconfig  |  11 +
 drivers/usb/typec/Makefile |   1 +
 drivers/usb/typec/pd_sink.c| 908 +
 include/linux/usb/pd_message.h | 369 +
 include/linux/usb/pd_sink.h| 299 ++
 5 files changed, 1588 insertions(+)
 create mode 100644 drivers/usb/typec/pd_sink.c
 create mode 100644 include/linux/usb/pd_message.h
 create mode 100644 include/linux/usb/pd_sink.h

diff --git a/drivers/usb/typec/Kconfig b/drivers/usb/typec/Kconfig
index 7a345a4..662aa54 100644
--- a/drivers/usb/typec/Kconfig
+++ b/drivers/usb/typec/Kconfig
@@ -4,6 +4,17 @@ menu "USB PD and Type-C drivers"
 config TYPEC
tristate
 
+config USB_PD_SINK
+   tristate "USB Power Delivery Sink Port State Machine Driver"
+   help
+ Enable this to support USB PD(Power Delivery) Sink port.
+ This driver implements a simple USB PD sink state machine.
+ The underlying TypeC phy driver is responsible for cable
+ plug/unplug event, port orientation detection, transmitting
+ and receiving PD messages. This driver only process messages
+ received by the TypeC phy driver and maintain the sink port's
+ state machine.
+
 config TYPEC_WCOVE
tristate "Intel WhiskeyCove PMIC USB Type-C PHY driver"
depends on ACPI
diff --git a/drivers/usb/typec/Makefile b/drivers/usb/typec/Makefile
index b9cb862..74aad6c 100644
--- a/drivers/usb/typec/Makefile
+++ b/drivers/usb/typec/Makefile
@@ -1,2 +1,3 @@
 obj-$(CONFIG_TYPEC)+= typec.o
+obj-$(CONFIG_USB_PD_SINK)  += pd_sink.o
 obj-$(CONFIG_TYPEC_WCOVE)  += typec_wcove.o
diff --git a/drivers/usb/typec/pd_sink.c b/drivers/usb/typec/pd_sink.c
new file mode 100644
index 000..1e46d3c
--- /dev/null
+++ b/drivers/usb/typec/pd_sink.c
@@ -0,0 +1,908 @@
+/*
+ * pd_sink.c - USB PD (Power Delivery) sink port state machine driver
+ *
+ * This driver implements a simple USB PD sink port state machine.
+ * It assumes the upper layer, i.e. the user of this driver, handles
+ * the PD message receiving and transmitting. The upper layer receives
+ * PD messages from the Source, queues them to us, and when processing
+ * the received message we'll call upper layer's transmitting function
+ * to send PD messages to the source.
+ * The sink port state machine is maintained in this driver but we also
+ * broadcast some important PD messages to upper layer as events.
+ *
+ * Copyright (C) 2016 Intel Corporation
+ *
+ * Author: Bin Gao <bin@intel.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ */
+
+#include 
+#include 
+#include 
+
+#define MAKE_HEADER(port, header, msg, objs) \
+do { \
+   header->type = msg; \
+   header->data_role = PD_DATA_ROLE_UFP; \
+   header->revision = port->pd_rev; \
+   header->power_role = PD_POWER_ROLE_SINK; \
+   header->id = roll_msg_id(port); \
+   header->nr_objs = objs; \
+   header->extended = PD_MSG_NOT_EXTENDED; \
+} while (0)
+
+static struct pd_sink_port *sink_ports[MAX_NR_SINK_PORTS];
+static int nr_ports;
+
+BLOCKING_NOTIFIER_HEAD(pd_sink_notifier_list);
+
+static char *state_strings[] = {
+   "WAIT_FOR_SOURCE_CAPABILITY",
+   "REQUEST_SENT",
+   "ACCEPT_RECEIVED",
+   "POWER_SUPPLY_READY",
+};
+
+/* Control messages */
+static char *cmsg_strings[] = {
+   "GOODCRC",  /* 1 */
+   "GOTOMIN",  /* 2 */
+   "ACCEPT",   /* 3 */
+   "REJECT",   /* 4 */
+   "PING", /* 5 */
+   "PS_RDY",   /* 6 */
+   "GET_SRC_CAP",  /* 7 */
+   "GET_SINK_CAP", /* 8 */
+   "DR_SWAP",  /* 9 */
+   "PR_SWAP", 

[PATCH v2 1/2] usb: typec: Add USB Power Delivery sink port support

2016-07-26 Thread Bin Gao
This patch implements a simple USB Power Delivery sink port state machine.
It assumes the hardware only handles PD packet transmitting and receiving
over the CC line of the USB Type-C connector. The state transition is
completely controlled by software. This patch only implement the sink port
function and it doesn't support source port and port swap yet.

This patch depends on these two patches:
https://lkml.org/lkml/2016/6/29/349
https://lkml.org/lkml/2016/6/29/350

Signed-off-by: Bin Gao 
Changes in v2:
 - Removed work queue so messages are directly handled in phy driver's 
interrupt context
 - used pr_debug instead of pr_info for message dump
 - Converted PD driver to tristate and typec driver is independent of it
---
 drivers/usb/typec/Kconfig  |  11 +
 drivers/usb/typec/Makefile |   1 +
 drivers/usb/typec/pd_sink.c| 908 +
 include/linux/usb/pd_message.h | 369 +
 include/linux/usb/pd_sink.h| 299 ++
 5 files changed, 1588 insertions(+)
 create mode 100644 drivers/usb/typec/pd_sink.c
 create mode 100644 include/linux/usb/pd_message.h
 create mode 100644 include/linux/usb/pd_sink.h

diff --git a/drivers/usb/typec/Kconfig b/drivers/usb/typec/Kconfig
index 7a345a4..662aa54 100644
--- a/drivers/usb/typec/Kconfig
+++ b/drivers/usb/typec/Kconfig
@@ -4,6 +4,17 @@ menu "USB PD and Type-C drivers"
 config TYPEC
tristate
 
+config USB_PD_SINK
+   tristate "USB Power Delivery Sink Port State Machine Driver"
+   help
+ Enable this to support USB PD(Power Delivery) Sink port.
+ This driver implements a simple USB PD sink state machine.
+ The underlying TypeC phy driver is responsible for cable
+ plug/unplug event, port orientation detection, transmitting
+ and receiving PD messages. This driver only process messages
+ received by the TypeC phy driver and maintain the sink port's
+ state machine.
+
 config TYPEC_WCOVE
tristate "Intel WhiskeyCove PMIC USB Type-C PHY driver"
depends on ACPI
diff --git a/drivers/usb/typec/Makefile b/drivers/usb/typec/Makefile
index b9cb862..74aad6c 100644
--- a/drivers/usb/typec/Makefile
+++ b/drivers/usb/typec/Makefile
@@ -1,2 +1,3 @@
 obj-$(CONFIG_TYPEC)+= typec.o
+obj-$(CONFIG_USB_PD_SINK)  += pd_sink.o
 obj-$(CONFIG_TYPEC_WCOVE)  += typec_wcove.o
diff --git a/drivers/usb/typec/pd_sink.c b/drivers/usb/typec/pd_sink.c
new file mode 100644
index 000..1e46d3c
--- /dev/null
+++ b/drivers/usb/typec/pd_sink.c
@@ -0,0 +1,908 @@
+/*
+ * pd_sink.c - USB PD (Power Delivery) sink port state machine driver
+ *
+ * This driver implements a simple USB PD sink port state machine.
+ * It assumes the upper layer, i.e. the user of this driver, handles
+ * the PD message receiving and transmitting. The upper layer receives
+ * PD messages from the Source, queues them to us, and when processing
+ * the received message we'll call upper layer's transmitting function
+ * to send PD messages to the source.
+ * The sink port state machine is maintained in this driver but we also
+ * broadcast some important PD messages to upper layer as events.
+ *
+ * Copyright (C) 2016 Intel Corporation
+ *
+ * Author: Bin Gao 
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ */
+
+#include 
+#include 
+#include 
+
+#define MAKE_HEADER(port, header, msg, objs) \
+do { \
+   header->type = msg; \
+   header->data_role = PD_DATA_ROLE_UFP; \
+   header->revision = port->pd_rev; \
+   header->power_role = PD_POWER_ROLE_SINK; \
+   header->id = roll_msg_id(port); \
+   header->nr_objs = objs; \
+   header->extended = PD_MSG_NOT_EXTENDED; \
+} while (0)
+
+static struct pd_sink_port *sink_ports[MAX_NR_SINK_PORTS];
+static int nr_ports;
+
+BLOCKING_NOTIFIER_HEAD(pd_sink_notifier_list);
+
+static char *state_strings[] = {
+   "WAIT_FOR_SOURCE_CAPABILITY",
+   "REQUEST_SENT",
+   "ACCEPT_RECEIVED",
+   "POWER_SUPPLY_READY",
+};
+
+/* Control messages */
+static char *cmsg_strings[] = {
+   "GOODCRC",  /* 1 */
+   "GOTOMIN",  /* 2 */
+   "ACCEPT",   /* 3 */
+   "REJECT",   /* 4 */
+   "PING", /* 5 */
+   "PS_RDY",   /* 6 */
+   "GET_SRC_CAP",  /* 7 */
+   "GET_SINK_CAP", /* 8 */
+   "DR_SWAP",  /* 9 */
+   "PR_SWAP",  /* 10 */
+   "VCONN

[PATCH v2 0/2] usb: typec: Introduce USB PD sink state machine driver and add PD sink support for Intel BXT PMIC Type-C phy

2016-07-26 Thread Bin Gao
This series introduce a USB PD(Power Delivery) sink port simple state
machine driver and adds USB PD sink port support for Intel BXT Whiskey
Cove PMIC Type-C phy driver.

This series depends on these two patches:
https://lkml.org/lkml/2016/6/29/349
https://lkml.org/lkml/2016/6/29/350

Bin Gao (1):
  usb: typec: Add USB Power Delivery sink port support

Chandra Sekhar Anagani (1):
  usb: typec: add PD sink port support for Intel Whiskey Cove PMIC USB
  Type-C PHY driver

 drivers/usb/typec/Kconfig   |  11 +
 drivers/usb/typec/Makefile  |   1 +
 drivers/usb/typec/pd_sink.c | 908 +
 include/linux/usb/pd_message.h  | 369 +
 include/linux/usb/pd_sink.h | 299 ++
 drivers/usb/typec/typec_wcove.c | 309 
 6 files changed, 1873 insertions(+), 24 deletions(-)
 create mode 100644 drivers/usb/typec/pd_sink.c
 create mode 100644 include/linux/usb/pd_message.h
 create mode 100644 include/linux/usb/pd_sink.h
--
1.9.1


[PATCH v2 0/2] usb: typec: Introduce USB PD sink state machine driver and add PD sink support for Intel BXT PMIC Type-C phy

2016-07-26 Thread Bin Gao
This series introduce a USB PD(Power Delivery) sink port simple state
machine driver and adds USB PD sink port support for Intel BXT Whiskey
Cove PMIC Type-C phy driver.

This series depends on these two patches:
https://lkml.org/lkml/2016/6/29/349
https://lkml.org/lkml/2016/6/29/350

Bin Gao (1):
  usb: typec: Add USB Power Delivery sink port support

Chandra Sekhar Anagani (1):
  usb: typec: add PD sink port support for Intel Whiskey Cove PMIC USB
  Type-C PHY driver

 drivers/usb/typec/Kconfig   |  11 +
 drivers/usb/typec/Makefile  |   1 +
 drivers/usb/typec/pd_sink.c | 908 +
 include/linux/usb/pd_message.h  | 369 +
 include/linux/usb/pd_sink.h | 299 ++
 drivers/usb/typec/typec_wcove.c | 309 
 6 files changed, 1873 insertions(+), 24 deletions(-)
 create mode 100644 drivers/usb/typec/pd_sink.c
 create mode 100644 include/linux/usb/pd_message.h
 create mode 100644 include/linux/usb/pd_sink.h
--
1.9.1


[PATCH v7] gpio: add Intel WhiskeyCove PMIC GPIO driver

2016-07-25 Thread Bin Gao
This patch introduces a separate GPIO driver for Intel WhiskeyCove PMIC.
This driver is based on gpio-crystalcove.c.

Signed-off-by: Ajay Thomas <ajay.thomas.david.rajamanic...@intel.com>
Signed-off-by: Bin Gao <bin@intel.com>
Reviewed-by: Andy Shevchenko <andy.shevche...@gmail.com>
Reviewed-by: Mika Westerberg <mika.westerb...@linux.intel.com>
---
Changes in v7:
 - Fixed various coding style comments from Andy Shevchenko
Changes in v6:
 - Removed unnecessary wcove_gpio_remove()
 - Used devm_gpiochip_remove() instead of gpiochip_remove()
 - Various coding style changes per Mika's comment
Changes in v5:
 - Revisited the interrupt handler code to iterate until all pending
   interrupts are handled. This change is to avoid missing interrupt
   when we're inside the interrupt handler.
 - Used regmap_bulk_read() to read address adjacent registers.
Changes in v4:
 - Converted CTLI_INTCNT_XX macros to less verbose ones INT_DETECT_XX.
 - Add comments about why there is no .pm for the driver.
 - Header files re-ordered.
 - Various coding style change to address Andy's comments.
Changes in v3:
 - Fixed the year in copyright line(2015-->2016).
 - Removed DRV_NAME macro.
 - Added kernel-doc for regmap_irq_chip of the wcove_gpio structure.
 - Line length fix.
Changes in v2:
 - Typo fix (Whsikey --> Whiskey).
 - Included linux/gpio/driver.h instead of linux/gpio.h
 - Implemented .set_single_ended().
 - Added GPIO register description.
 - Replaced container_of() with gpiochip_get_data().
 - Removed unnecessary "if (gpio > WCOVE_VGPIO_NUM" check.
 - Removed the device id table and added MODULE_ALIAS().
 drivers/gpio/Kconfig  |  13 ++
 drivers/gpio/Makefile |   1 +
 drivers/gpio/gpio-wcove.c | 455 ++
 3 files changed, 469 insertions(+)
 create mode 100644 drivers/gpio/gpio-wcove.c

diff --git a/drivers/gpio/Kconfig b/drivers/gpio/Kconfig
index 536112f..240ae7c 100644
--- a/drivers/gpio/Kconfig
+++ b/drivers/gpio/Kconfig
@@ -972,6 +972,19 @@ config GPIO_UCB1400
  This enables support for the Philips UCB1400 GPIO pins.
  The UCB1400 is an AC97 audio codec.
 
+config GPIO_WHISKEY_COVE
+   tristate "GPIO support for Whiskey Cove PMIC"
+   depends on INTEL_SOC_PMIC
+   select GPIOLIB_IRQCHIP
+   help
+ Support for GPIO pins on Whiskey Cove PMIC.
+
+ Say Yes if you have a Intel SoC based tablet with Whiskey Cove PMIC
+ inside.
+
+ This driver can also be built as a module. If so, the module will be
+ called gpio-wcove.
+
 config GPIO_WM831X
tristate "WM831x GPIOs"
depends on MFD_WM831X
diff --git a/drivers/gpio/Makefile b/drivers/gpio/Makefile
index 991598e..fff27b0 100644
--- a/drivers/gpio/Makefile
+++ b/drivers/gpio/Makefile
@@ -118,6 +118,7 @@ obj-$(CONFIG_GPIO_VF610)+= gpio-vf610.o
 obj-$(CONFIG_GPIO_VIPERBOARD)  += gpio-viperboard.o
 obj-$(CONFIG_GPIO_VR41XX)  += gpio-vr41xx.o
 obj-$(CONFIG_GPIO_VX855)   += gpio-vx855.o
+obj-$(CONFIG_GPIO_WHISKEY_COVE)+= gpio-wcove.o
 obj-$(CONFIG_GPIO_WM831X)  += gpio-wm831x.o
 obj-$(CONFIG_GPIO_WM8350)  += gpio-wm8350.o
 obj-$(CONFIG_GPIO_WM8994)  += gpio-wm8994.o
diff --git a/drivers/gpio/gpio-wcove.c b/drivers/gpio/gpio-wcove.c
new file mode 100644
index 000..f5c88df
--- /dev/null
+++ b/drivers/gpio/gpio-wcove.c
@@ -0,0 +1,455 @@
+/*
+ * Intel Whiskey Cove PMIC GPIO Driver
+ *
+ * This driver is written based on gpio-crystalcove.c
+ *
+ * Copyright (C) 2016 Intel Corporation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License version
+ * 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+/*
+ * Whiskey Cove PMIC has 13 physical GPIO pins divided into 3 banks:
+ * Bank 0: Pin 0 - 6
+ * Bank 1: Pin 7 - 10
+ * Bank 2: Pin 11 -12
+ * Each pin has one output control register and one input control register.
+ */
+#define BANK0_NR_PINS  7
+#define BANK1_NR_PINS  4
+#define BANK2_NR_PINS  2
+#define WCOVE_GPIO_NUM (BANK0_NR_PINS + BANK1_NR_PINS + BANK2_NR_PINS)
+#define WCOVE_VGPIO_NUM94
+/* GPIO output control registers (one per pin): 0x4e44 - 0x4e50 */
+#define GPIO_OUT_CTRL_BASE 0x4e44
+/* GPIO input control registers (one per pin): 0x4e51 - 0x4e5d */
+#define GPIO_IN_CTRL_BASE  0x4e51
+
+/*
+ * GPIO interrupts are organized in two groups:
+ * Group 0: Bank 0 pins (Pin 0 - 6)
+ * Group 1: Bank 1 and Bank 2 pins (Pin 7 - 12)
+ * Each group has two registers (

[PATCH v7] gpio: add Intel WhiskeyCove PMIC GPIO driver

2016-07-25 Thread Bin Gao
This patch introduces a separate GPIO driver for Intel WhiskeyCove PMIC.
This driver is based on gpio-crystalcove.c.

Signed-off-by: Ajay Thomas 
Signed-off-by: Bin Gao 
Reviewed-by: Andy Shevchenko 
Reviewed-by: Mika Westerberg 
---
Changes in v7:
 - Fixed various coding style comments from Andy Shevchenko
Changes in v6:
 - Removed unnecessary wcove_gpio_remove()
 - Used devm_gpiochip_remove() instead of gpiochip_remove()
 - Various coding style changes per Mika's comment
Changes in v5:
 - Revisited the interrupt handler code to iterate until all pending
   interrupts are handled. This change is to avoid missing interrupt
   when we're inside the interrupt handler.
 - Used regmap_bulk_read() to read address adjacent registers.
Changes in v4:
 - Converted CTLI_INTCNT_XX macros to less verbose ones INT_DETECT_XX.
 - Add comments about why there is no .pm for the driver.
 - Header files re-ordered.
 - Various coding style change to address Andy's comments.
Changes in v3:
 - Fixed the year in copyright line(2015-->2016).
 - Removed DRV_NAME macro.
 - Added kernel-doc for regmap_irq_chip of the wcove_gpio structure.
 - Line length fix.
Changes in v2:
 - Typo fix (Whsikey --> Whiskey).
 - Included linux/gpio/driver.h instead of linux/gpio.h
 - Implemented .set_single_ended().
 - Added GPIO register description.
 - Replaced container_of() with gpiochip_get_data().
 - Removed unnecessary "if (gpio > WCOVE_VGPIO_NUM" check.
 - Removed the device id table and added MODULE_ALIAS().
 drivers/gpio/Kconfig  |  13 ++
 drivers/gpio/Makefile |   1 +
 drivers/gpio/gpio-wcove.c | 455 ++
 3 files changed, 469 insertions(+)
 create mode 100644 drivers/gpio/gpio-wcove.c

diff --git a/drivers/gpio/Kconfig b/drivers/gpio/Kconfig
index 536112f..240ae7c 100644
--- a/drivers/gpio/Kconfig
+++ b/drivers/gpio/Kconfig
@@ -972,6 +972,19 @@ config GPIO_UCB1400
  This enables support for the Philips UCB1400 GPIO pins.
  The UCB1400 is an AC97 audio codec.
 
+config GPIO_WHISKEY_COVE
+   tristate "GPIO support for Whiskey Cove PMIC"
+   depends on INTEL_SOC_PMIC
+   select GPIOLIB_IRQCHIP
+   help
+ Support for GPIO pins on Whiskey Cove PMIC.
+
+ Say Yes if you have a Intel SoC based tablet with Whiskey Cove PMIC
+ inside.
+
+ This driver can also be built as a module. If so, the module will be
+ called gpio-wcove.
+
 config GPIO_WM831X
tristate "WM831x GPIOs"
depends on MFD_WM831X
diff --git a/drivers/gpio/Makefile b/drivers/gpio/Makefile
index 991598e..fff27b0 100644
--- a/drivers/gpio/Makefile
+++ b/drivers/gpio/Makefile
@@ -118,6 +118,7 @@ obj-$(CONFIG_GPIO_VF610)+= gpio-vf610.o
 obj-$(CONFIG_GPIO_VIPERBOARD)  += gpio-viperboard.o
 obj-$(CONFIG_GPIO_VR41XX)  += gpio-vr41xx.o
 obj-$(CONFIG_GPIO_VX855)   += gpio-vx855.o
+obj-$(CONFIG_GPIO_WHISKEY_COVE)+= gpio-wcove.o
 obj-$(CONFIG_GPIO_WM831X)  += gpio-wm831x.o
 obj-$(CONFIG_GPIO_WM8350)  += gpio-wm8350.o
 obj-$(CONFIG_GPIO_WM8994)  += gpio-wm8994.o
diff --git a/drivers/gpio/gpio-wcove.c b/drivers/gpio/gpio-wcove.c
new file mode 100644
index 000..f5c88df
--- /dev/null
+++ b/drivers/gpio/gpio-wcove.c
@@ -0,0 +1,455 @@
+/*
+ * Intel Whiskey Cove PMIC GPIO Driver
+ *
+ * This driver is written based on gpio-crystalcove.c
+ *
+ * Copyright (C) 2016 Intel Corporation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License version
+ * 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+/*
+ * Whiskey Cove PMIC has 13 physical GPIO pins divided into 3 banks:
+ * Bank 0: Pin 0 - 6
+ * Bank 1: Pin 7 - 10
+ * Bank 2: Pin 11 -12
+ * Each pin has one output control register and one input control register.
+ */
+#define BANK0_NR_PINS  7
+#define BANK1_NR_PINS  4
+#define BANK2_NR_PINS  2
+#define WCOVE_GPIO_NUM (BANK0_NR_PINS + BANK1_NR_PINS + BANK2_NR_PINS)
+#define WCOVE_VGPIO_NUM94
+/* GPIO output control registers (one per pin): 0x4e44 - 0x4e50 */
+#define GPIO_OUT_CTRL_BASE 0x4e44
+/* GPIO input control registers (one per pin): 0x4e51 - 0x4e5d */
+#define GPIO_IN_CTRL_BASE  0x4e51
+
+/*
+ * GPIO interrupts are organized in two groups:
+ * Group 0: Bank 0 pins (Pin 0 - 6)
+ * Group 1: Bank 1 and Bank 2 pins (Pin 7 - 12)
+ * Each group has two registers (one bit per pin): status and mask.
+ */
+#define GROUP0_NR_IRQS 7
+#define GROUP1_NR_IRQS 6
+#define IRQ_MASK_BASE  

[PATCH] mfd: intel_soc_pmic_bxtwc: add bxt_wcove_usbc device

2016-07-20 Thread Bin Gao
The Intel Whiskey Cove PMIC includes several function units, e.g.
ADC, thermal, USB Type-C, GPIO, etc. The corresponding device has
to be created in the mfd driver(intel_soc_pmic_bxtwc.c). This change
adds the USB Type-c device.

Signed-off-by: Bin Gao <bin@intel.com>
---
 drivers/mfd/intel_soc_pmic_bxtwc.c | 23 ++-
 1 file changed, 22 insertions(+), 1 deletion(-)

diff --git a/drivers/mfd/intel_soc_pmic_bxtwc.c 
b/drivers/mfd/intel_soc_pmic_bxtwc.c
index b942876..43e54b7 100644
--- a/drivers/mfd/intel_soc_pmic_bxtwc.c
+++ b/drivers/mfd/intel_soc_pmic_bxtwc.c
@@ -47,6 +47,8 @@
 #define BXTWC_MIRQLVL1 0x4E0E
 #define BXTWC_MPWRTNIRQ0x4E0F
 
+#define BXTWC_MIRQLVL1_MCHGR   BIT(5)
+
 #define BXTWC_MTHRM0IRQ0x4E12
 #define BXTWC_MTHRM1IRQ0x4E13
 #define BXTWC_MTHRM2IRQ0x4E14
@@ -109,7 +111,7 @@ static const struct regmap_irq bxtwc_regmap_irqs_level2[] = 
{
REGMAP_IRQ_REG(BXTWC_THRM2_IRQ, 2, 0xff),
REGMAP_IRQ_REG(BXTWC_BCU_IRQ, 3, 0x1f),
REGMAP_IRQ_REG(BXTWC_ADC_IRQ, 4, 0xff),
-   REGMAP_IRQ_REG(BXTWC_CHGR0_IRQ, 5, 0x1f),
+   REGMAP_IRQ_REG(BXTWC_CHGR0_IRQ, 5, 0x3f),
REGMAP_IRQ_REG(BXTWC_CHGR1_IRQ, 6, 0x1f),
REGMAP_IRQ_REG(BXTWC_GPIO0_IRQ, 7, 0xff),
REGMAP_IRQ_REG(BXTWC_GPIO1_IRQ, 8, 0x3f),
@@ -143,6 +145,10 @@ static struct resource adc_resources[] = {
DEFINE_RES_IRQ_NAMED(BXTWC_ADC_IRQ, "ADC"),
 };
 
+static struct resource usbc_resources[] = {
+   DEFINE_RES_IRQ_NAMED(BXTWC_CHGR0_IRQ, "USBC"),
+};
+
 static struct resource charger_resources[] = {
DEFINE_RES_IRQ_NAMED(BXTWC_CHGR0_IRQ, "CHARGER"),
DEFINE_RES_IRQ_NAMED(BXTWC_CHGR1_IRQ, "CHARGER1"),
@@ -170,6 +176,11 @@ static struct mfd_cell bxt_wc_dev[] = {
.resources = thermal_resources,
},
{
+   .name = "bxt_wcove_usbc",
+   .num_resources = ARRAY_SIZE(usbc_resources),
+   .resources = usbc_resources,
+   },
+   {
.name = "bxt_wcove_ext_charger",
.num_resources = ARRAY_SIZE(charger_resources),
.resources = charger_resources,
@@ -403,6 +414,16 @@ static int bxtwc_probe(struct platform_device *pdev)
goto err_sysfs;
}
 
+   /*
+* There is known hw bug. Upon reset BIT 5 of register
+* BXTWC_CHGR_LVL1_IRQ is 0 which is the expected value. However,
+* later it's set to 1(masked) automatically by hardware. So we
+* have the software workaround here to unmaksed it in order to let
+* charger interrutp work.
+*/
+   regmap_update_bits(pmic->regmap, BXTWC_MIRQLVL1,
+   BXTWC_MIRQLVL1_MCHGR, 0);
+
return 0;
 
 err_sysfs:
-- 
1.9.1



[PATCH] mfd: intel_soc_pmic_bxtwc: add bxt_wcove_usbc device

2016-07-20 Thread Bin Gao
The Intel Whiskey Cove PMIC includes several function units, e.g.
ADC, thermal, USB Type-C, GPIO, etc. The corresponding device has
to be created in the mfd driver(intel_soc_pmic_bxtwc.c). This change
adds the USB Type-c device.

Signed-off-by: Bin Gao 
---
 drivers/mfd/intel_soc_pmic_bxtwc.c | 23 ++-
 1 file changed, 22 insertions(+), 1 deletion(-)

diff --git a/drivers/mfd/intel_soc_pmic_bxtwc.c 
b/drivers/mfd/intel_soc_pmic_bxtwc.c
index b942876..43e54b7 100644
--- a/drivers/mfd/intel_soc_pmic_bxtwc.c
+++ b/drivers/mfd/intel_soc_pmic_bxtwc.c
@@ -47,6 +47,8 @@
 #define BXTWC_MIRQLVL1 0x4E0E
 #define BXTWC_MPWRTNIRQ0x4E0F
 
+#define BXTWC_MIRQLVL1_MCHGR   BIT(5)
+
 #define BXTWC_MTHRM0IRQ0x4E12
 #define BXTWC_MTHRM1IRQ0x4E13
 #define BXTWC_MTHRM2IRQ0x4E14
@@ -109,7 +111,7 @@ static const struct regmap_irq bxtwc_regmap_irqs_level2[] = 
{
REGMAP_IRQ_REG(BXTWC_THRM2_IRQ, 2, 0xff),
REGMAP_IRQ_REG(BXTWC_BCU_IRQ, 3, 0x1f),
REGMAP_IRQ_REG(BXTWC_ADC_IRQ, 4, 0xff),
-   REGMAP_IRQ_REG(BXTWC_CHGR0_IRQ, 5, 0x1f),
+   REGMAP_IRQ_REG(BXTWC_CHGR0_IRQ, 5, 0x3f),
REGMAP_IRQ_REG(BXTWC_CHGR1_IRQ, 6, 0x1f),
REGMAP_IRQ_REG(BXTWC_GPIO0_IRQ, 7, 0xff),
REGMAP_IRQ_REG(BXTWC_GPIO1_IRQ, 8, 0x3f),
@@ -143,6 +145,10 @@ static struct resource adc_resources[] = {
DEFINE_RES_IRQ_NAMED(BXTWC_ADC_IRQ, "ADC"),
 };
 
+static struct resource usbc_resources[] = {
+   DEFINE_RES_IRQ_NAMED(BXTWC_CHGR0_IRQ, "USBC"),
+};
+
 static struct resource charger_resources[] = {
DEFINE_RES_IRQ_NAMED(BXTWC_CHGR0_IRQ, "CHARGER"),
DEFINE_RES_IRQ_NAMED(BXTWC_CHGR1_IRQ, "CHARGER1"),
@@ -170,6 +176,11 @@ static struct mfd_cell bxt_wc_dev[] = {
.resources = thermal_resources,
},
{
+   .name = "bxt_wcove_usbc",
+   .num_resources = ARRAY_SIZE(usbc_resources),
+   .resources = usbc_resources,
+   },
+   {
.name = "bxt_wcove_ext_charger",
.num_resources = ARRAY_SIZE(charger_resources),
.resources = charger_resources,
@@ -403,6 +414,16 @@ static int bxtwc_probe(struct platform_device *pdev)
goto err_sysfs;
}
 
+   /*
+* There is known hw bug. Upon reset BIT 5 of register
+* BXTWC_CHGR_LVL1_IRQ is 0 which is the expected value. However,
+* later it's set to 1(masked) automatically by hardware. So we
+* have the software workaround here to unmaksed it in order to let
+* charger interrutp work.
+*/
+   regmap_update_bits(pmic->regmap, BXTWC_MIRQLVL1,
+   BXTWC_MIRQLVL1_MCHGR, 0);
+
return 0;
 
 err_sysfs:
-- 
1.9.1



Re: [PATCH v4] mfd: intel_soc_pmic_bxtwc: Add Intel BXT WhiskeyCove PMIC ADC thermal channel mapping and USB type-C resources

2016-07-20 Thread Bin Gao
On Tue, Jun 28, 2016 at 03:58:49PM +0100, Lee Jones wrote:
> On Mon, 27 Jun 2016, Bin Gao wrote:
> 
> > This patch adds the mapping of PMIC ADC channel to thermal zone and
> > USB type-C resources. This mapping is used in the pmic thermal driver
> > to notify the thermal zone with the pmic adc channel alert interrupts.
> 
> > This patch also adds three new data structures to
> > include/linux/mfd/intel_soc_pmic.h: struct trip_config_map{},
> > struct thermal_irq_map {} and struct pmic_thermal_data {} which are
> > required by changes we did on intel_soc_pmic_bxtwc.c.
> 
> No need for this section.
> 
> > Signed-off-by: Yegnesh S Iyer <yegnesh.s.i...@intel.com>
> > Signed-off-by: Rohit S Kenchanpura <rohit.s.kenchanp...@intel.com>
> > Signed-off-by: Bin Gao <bin@intel.com>
> > ---
> > Changes in v4:
> >  - Extended existing regmap reg instead of defining a new one:
> >REGMAP_IRQ_REG(BXTWC_CHGR0_IRQ, 5, 0x3f)
> > Changes in v3:
> >  - Added USB type-C resources.
> > Changes in v2:
> >  - Fixed subject line.
> >  - Combined two patches into one.
> >  drivers/mfd/intel_soc_pmic_bxtwc.c | 126 
> > -
> >  include/linux/mfd/intel_soc_pmic.h |  21 +++
> >  2 files changed, 146 insertions(+), 1 deletion(-)
> > 
> > diff --git a/drivers/mfd/intel_soc_pmic_bxtwc.c 
> > b/drivers/mfd/intel_soc_pmic_bxtwc.c
> > index b942876..e69eb86 100644
> > --- a/drivers/mfd/intel_soc_pmic_bxtwc.c
> > +++ b/drivers/mfd/intel_soc_pmic_bxtwc.c
> > @@ -47,6 +47,8 @@
> >  #define BXTWC_MIRQLVL1 0x4E0E
> >  #define BXTWC_MPWRTNIRQ0x4E0F
> >  
> > +#define BXTWC_MIRQLVL1_MCHGR   BIT(5)
> > +
> 
> This line looks very much out of place here.
> 
> >  #define BXTWC_MTHRM0IRQ0x4E12
> >  #define BXTWC_MTHRM1IRQ0x4E13
> >  #define BXTWC_MTHRM2IRQ0x4E14
> > @@ -58,6 +60,10 @@
> >  #define BXTWC_MGPIO1IRQ0x4E1A
> >  #define BXTWC_MCRITIRQ 0x4E1B
> >  
> > +#define BXTWC_STHRM0IRQ0x4F19
> > +#define BXTWC_STHRM1IRQ0x4F1A
> > +#define BXTWC_STHRM2IRQ0x4F1B
> > +
> >  /* Whiskey Cove PMIC share same ACPI ID between different platforms */
> >  #define BROXTON_PMIC_WC_HRV4
> >  
> > @@ -109,13 +115,116 @@ static const struct regmap_irq 
> > bxtwc_regmap_irqs_level2[] = {
> > REGMAP_IRQ_REG(BXTWC_THRM2_IRQ, 2, 0xff),
> > REGMAP_IRQ_REG(BXTWC_BCU_IRQ, 3, 0x1f),
> > REGMAP_IRQ_REG(BXTWC_ADC_IRQ, 4, 0xff),
> > -   REGMAP_IRQ_REG(BXTWC_CHGR0_IRQ, 5, 0x1f),
> > +   REGMAP_IRQ_REG(BXTWC_CHGR0_IRQ, 5, 0x3f),
> 
> Is the original code wrong?
> 
> If so, it's a fix and needs it's own patch
> .
> > REGMAP_IRQ_REG(BXTWC_CHGR1_IRQ, 6, 0x1f),
> > REGMAP_IRQ_REG(BXTWC_GPIO0_IRQ, 7, 0xff),
> > REGMAP_IRQ_REG(BXTWC_GPIO1_IRQ, 8, 0x3f),
> > REGMAP_IRQ_REG(BXTWC_CRIT_IRQ, 9, 0x03),
> >  };
> >  
> > +static struct trip_config_map str0_trip_config[] = {
> > +   {
> > +   .irq_reg = BXTWC_THRM0IRQ,
> > +   .irq_mask = 0x01,
> > +   .irq_en = BXTWC_MTHRM0IRQ,
> > +   .irq_en_mask = 0x01,
> > +   .evt_stat = BXTWC_STHRM0IRQ,
> > +   .evt_mask = 0x01,
> > +   .trip_num = 0
> > +   },
> > +   {
> > +   .irq_reg = BXTWC_THRM0IRQ,
> > +   .irq_mask = 0x10,
> > +   .irq_en = BXTWC_MTHRM0IRQ,
> > +   .irq_en_mask = 0x10,
> > +   .evt_stat = BXTWC_STHRM0IRQ,
> > +   .evt_mask = 0x10,
> > +   .trip_num = 1
> > +   }
> > +};
> > +
> > +static struct trip_config_map str1_trip_config[] = {
> > +   {
> > +   .irq_reg = BXTWC_THRM0IRQ,
> > +   .irq_mask = 0x02,
> > +   .irq_en = BXTWC_MTHRM0IRQ,
> > +   .irq_en_mask = 0x02,
> > +   .evt_stat = BXTWC_STHRM0IRQ,
> > +   .evt_mask = 0x02,
> > +   .trip_num = 0
> > +   },
> > +   {
> > +   .irq_reg = BXTWC_THRM0IRQ,
> > +   .irq_mask = 0x20,
> > +   .irq_en = BXTWC_MTHRM0IRQ,
> > +   .irq_en_mask = 0x20,
> > +   .evt_stat = BXTWC_STHRM0IRQ,
> > +   .evt_mask = 0x20,
> > +   .trip_num = 1
> > +   },
> > +};
> > +
> > +static struct trip_config_map str2_trip_config[] = {
> > +   {
> > +   .irq_reg = BXTWC_THRM0IRQ,
&

Re: [PATCH v4] mfd: intel_soc_pmic_bxtwc: Add Intel BXT WhiskeyCove PMIC ADC thermal channel mapping and USB type-C resources

2016-07-20 Thread Bin Gao
On Tue, Jun 28, 2016 at 03:58:49PM +0100, Lee Jones wrote:
> On Mon, 27 Jun 2016, Bin Gao wrote:
> 
> > This patch adds the mapping of PMIC ADC channel to thermal zone and
> > USB type-C resources. This mapping is used in the pmic thermal driver
> > to notify the thermal zone with the pmic adc channel alert interrupts.
> 
> > This patch also adds three new data structures to
> > include/linux/mfd/intel_soc_pmic.h: struct trip_config_map{},
> > struct thermal_irq_map {} and struct pmic_thermal_data {} which are
> > required by changes we did on intel_soc_pmic_bxtwc.c.
> 
> No need for this section.
> 
> > Signed-off-by: Yegnesh S Iyer 
> > Signed-off-by: Rohit S Kenchanpura 
> > Signed-off-by: Bin Gao 
> > ---
> > Changes in v4:
> >  - Extended existing regmap reg instead of defining a new one:
> >REGMAP_IRQ_REG(BXTWC_CHGR0_IRQ, 5, 0x3f)
> > Changes in v3:
> >  - Added USB type-C resources.
> > Changes in v2:
> >  - Fixed subject line.
> >  - Combined two patches into one.
> >  drivers/mfd/intel_soc_pmic_bxtwc.c | 126 
> > -
> >  include/linux/mfd/intel_soc_pmic.h |  21 +++
> >  2 files changed, 146 insertions(+), 1 deletion(-)
> > 
> > diff --git a/drivers/mfd/intel_soc_pmic_bxtwc.c 
> > b/drivers/mfd/intel_soc_pmic_bxtwc.c
> > index b942876..e69eb86 100644
> > --- a/drivers/mfd/intel_soc_pmic_bxtwc.c
> > +++ b/drivers/mfd/intel_soc_pmic_bxtwc.c
> > @@ -47,6 +47,8 @@
> >  #define BXTWC_MIRQLVL1 0x4E0E
> >  #define BXTWC_MPWRTNIRQ0x4E0F
> >  
> > +#define BXTWC_MIRQLVL1_MCHGR   BIT(5)
> > +
> 
> This line looks very much out of place here.
> 
> >  #define BXTWC_MTHRM0IRQ0x4E12
> >  #define BXTWC_MTHRM1IRQ0x4E13
> >  #define BXTWC_MTHRM2IRQ0x4E14
> > @@ -58,6 +60,10 @@
> >  #define BXTWC_MGPIO1IRQ0x4E1A
> >  #define BXTWC_MCRITIRQ 0x4E1B
> >  
> > +#define BXTWC_STHRM0IRQ0x4F19
> > +#define BXTWC_STHRM1IRQ0x4F1A
> > +#define BXTWC_STHRM2IRQ0x4F1B
> > +
> >  /* Whiskey Cove PMIC share same ACPI ID between different platforms */
> >  #define BROXTON_PMIC_WC_HRV4
> >  
> > @@ -109,13 +115,116 @@ static const struct regmap_irq 
> > bxtwc_regmap_irqs_level2[] = {
> > REGMAP_IRQ_REG(BXTWC_THRM2_IRQ, 2, 0xff),
> > REGMAP_IRQ_REG(BXTWC_BCU_IRQ, 3, 0x1f),
> > REGMAP_IRQ_REG(BXTWC_ADC_IRQ, 4, 0xff),
> > -   REGMAP_IRQ_REG(BXTWC_CHGR0_IRQ, 5, 0x1f),
> > +   REGMAP_IRQ_REG(BXTWC_CHGR0_IRQ, 5, 0x3f),
> 
> Is the original code wrong?
> 
> If so, it's a fix and needs it's own patch
> .
> > REGMAP_IRQ_REG(BXTWC_CHGR1_IRQ, 6, 0x1f),
> > REGMAP_IRQ_REG(BXTWC_GPIO0_IRQ, 7, 0xff),
> > REGMAP_IRQ_REG(BXTWC_GPIO1_IRQ, 8, 0x3f),
> > REGMAP_IRQ_REG(BXTWC_CRIT_IRQ, 9, 0x03),
> >  };
> >  
> > +static struct trip_config_map str0_trip_config[] = {
> > +   {
> > +   .irq_reg = BXTWC_THRM0IRQ,
> > +   .irq_mask = 0x01,
> > +   .irq_en = BXTWC_MTHRM0IRQ,
> > +   .irq_en_mask = 0x01,
> > +   .evt_stat = BXTWC_STHRM0IRQ,
> > +   .evt_mask = 0x01,
> > +   .trip_num = 0
> > +   },
> > +   {
> > +   .irq_reg = BXTWC_THRM0IRQ,
> > +   .irq_mask = 0x10,
> > +   .irq_en = BXTWC_MTHRM0IRQ,
> > +   .irq_en_mask = 0x10,
> > +   .evt_stat = BXTWC_STHRM0IRQ,
> > +   .evt_mask = 0x10,
> > +   .trip_num = 1
> > +   }
> > +};
> > +
> > +static struct trip_config_map str1_trip_config[] = {
> > +   {
> > +   .irq_reg = BXTWC_THRM0IRQ,
> > +   .irq_mask = 0x02,
> > +   .irq_en = BXTWC_MTHRM0IRQ,
> > +   .irq_en_mask = 0x02,
> > +   .evt_stat = BXTWC_STHRM0IRQ,
> > +   .evt_mask = 0x02,
> > +   .trip_num = 0
> > +   },
> > +   {
> > +   .irq_reg = BXTWC_THRM0IRQ,
> > +   .irq_mask = 0x20,
> > +   .irq_en = BXTWC_MTHRM0IRQ,
> > +   .irq_en_mask = 0x20,
> > +   .evt_stat = BXTWC_STHRM0IRQ,
> > +   .evt_mask = 0x20,
> > +   .trip_num = 1
> > +   },
> > +};
> > +
> > +static struct trip_config_map str2_trip_config[] = {
> > +   {
> > +   .irq_reg = BXTWC_THRM0IRQ,
> > +   .irq_mask = 0x04,
> > +   .irq_en = BX

[PATCH v3] thermal: add Intel BXT WhiskeyCove PMIC thermal driver

2016-07-20 Thread Bin Gao
From: Yegnesh S Iyer <yegnesh.s.i...@intel.com>

This change adds support for Intel BXT Whiskey Cove PMIC thermal
driver which is intended to handle the alert interrupts triggered
upon thermal trip point cross and notify the thermal framework
appropriately with the zone, temp, crossed trip and event details.

Signed-off-by: Yegnesh S Iyer <yegnesh.s.i...@intel.com>
Signed-off-by: Bin Gao <bin@intel.com>
Changes in v3:
 - Moved driver data from mfd domain to the driver
 - Minor coding style related cleanup
Changes in v2:
 - Removed unnecessary request_threaded_irq() - we should be only
   using devm_request_threaded_irq() with virq
---
 drivers/thermal/Kconfig  |  10 ++
 drivers/thermal/Makefile |   1 +
 drivers/thermal/intel_pmic_thermal.c | 299 +++
 3 files changed, 310 insertions(+)
 create mode 100644 drivers/thermal/intel_pmic_thermal.c

diff --git a/drivers/thermal/Kconfig b/drivers/thermal/Kconfig
index 2d702ca..9065ba7 100644
--- a/drivers/thermal/Kconfig
+++ b/drivers/thermal/Kconfig
@@ -332,6 +332,16 @@ menu "ACPI INT340X thermal drivers"
 source drivers/thermal/int340x_thermal/Kconfig
 endmenu
 
+config INTEL_PMIC_THERMAL
+   tristate "Intel PMIC thermal driver"
+   depends on X86 && INTEL_SOC_PMIC && REGMAP
+   help
+ Select this driver for Intel PMIC with ADC channels monitoring system
+ temperature measurements and alerts.
+ This driver is used for monitoring the ADC channels of PMIC and 
handles
+ the alert trip point interrupts and notifies the thermal framework 
with
+ the trip point and temperature details of the zone.
+
 config INTEL_PCH_THERMAL
tristate "Intel PCH Thermal Reporting Driver"
depends on X86 && PCI
diff --git a/drivers/thermal/Makefile b/drivers/thermal/Makefile
index 10b07c1..159efcc 100644
--- a/drivers/thermal/Makefile
+++ b/drivers/thermal/Makefile
@@ -45,6 +45,7 @@ obj-$(CONFIG_INTEL_SOC_DTS_THERMAL)   += 
intel_soc_dts_thermal.o
 obj-$(CONFIG_INTEL_QUARK_DTS_THERMAL)  += intel_quark_dts_thermal.o
 obj-$(CONFIG_TI_SOC_THERMAL)   += ti-soc-thermal/
 obj-$(CONFIG_INT340X_THERMAL)  += int340x_thermal/
+obj-$(CONFIG_INTEL_PMIC_THERMAL) += intel_pmic_thermal.o
 obj-$(CONFIG_INTEL_PCH_THERMAL)+= intel_pch_thermal.o
 obj-$(CONFIG_ST_THERMAL)   += st/
 obj-$(CONFIG_TEGRA_SOCTHERM)   += tegra/
diff --git a/drivers/thermal/intel_pmic_thermal.c 
b/drivers/thermal/intel_pmic_thermal.c
new file mode 100644
index 000..401e7a7
--- /dev/null
+++ b/drivers/thermal/intel_pmic_thermal.c
@@ -0,0 +1,299 @@
+/*
+ * pmic_thermal.c - PMIC thermal driver
+ *
+ * Copyright (C) 2015 Intel Corporation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License version
+ * 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#define BXTWC_THRM0IRQ 0x4E04
+#define BXTWC_THRM1IRQ 0x4E05
+#define BXTWC_THRM2IRQ 0x4E06
+#define BXTWC_MTHRM0IRQ0x4E12
+#define BXTWC_MTHRM1IRQ0x4E13
+#define BXTWC_MTHRM2IRQ0x4E14
+#define BXTWC_STHRM0IRQ0x4F19
+#define BXTWC_STHRM1IRQ0x4F1A
+#define BXTWC_STHRM2IRQ0x4F1B
+
+struct trip_config_map {
+   u16 irq_reg;
+   u16 irq_en;
+   u16 evt_stat;
+   u8 irq_mask;
+   u8 irq_en_mask;
+   u8 evt_mask;
+   u8 trip_num;
+};
+
+struct thermal_irq_map {
+   char handle[20];
+   int num_trips;
+   struct trip_config_map *trip_config;
+};
+
+struct pmic_thermal_data {
+   struct thermal_irq_map *maps;
+   int num_maps;
+};
+
+static struct trip_config_map bxtwc_str0_trip_config[] = {
+   {
+   .irq_reg = BXTWC_THRM0IRQ,
+   .irq_mask = 0x01,
+   .irq_en = BXTWC_MTHRM0IRQ,
+   .irq_en_mask = 0x01,
+   .evt_stat = BXTWC_STHRM0IRQ,
+   .evt_mask = 0x01,
+   .trip_num = 0
+   },
+   {
+   .irq_reg = BXTWC_THRM0IRQ,
+   .irq_mask = 0x10,
+   .irq_en = BXTWC_MTHRM0IRQ,
+   .irq_en_mask = 0x10,
+   .evt_stat = BXTWC_STHRM0IRQ,
+   .evt_mask = 0x10,
+   .trip_num = 1
+   }
+};
+
+static struct trip_config_map bxtwc_str1_trip_config[] = {
+   {
+   .irq_reg = BXTWC_THRM0IRQ,
+   .irq_mask = 0x02,
+   .irq_en = BXTWC_M

[PATCH v3] thermal: add Intel BXT WhiskeyCove PMIC thermal driver

2016-07-20 Thread Bin Gao
From: Yegnesh S Iyer 

This change adds support for Intel BXT Whiskey Cove PMIC thermal
driver which is intended to handle the alert interrupts triggered
upon thermal trip point cross and notify the thermal framework
appropriately with the zone, temp, crossed trip and event details.

Signed-off-by: Yegnesh S Iyer 
Signed-off-by: Bin Gao 
Changes in v3:
 - Moved driver data from mfd domain to the driver
 - Minor coding style related cleanup
Changes in v2:
 - Removed unnecessary request_threaded_irq() - we should be only
   using devm_request_threaded_irq() with virq
---
 drivers/thermal/Kconfig  |  10 ++
 drivers/thermal/Makefile |   1 +
 drivers/thermal/intel_pmic_thermal.c | 299 +++
 3 files changed, 310 insertions(+)
 create mode 100644 drivers/thermal/intel_pmic_thermal.c

diff --git a/drivers/thermal/Kconfig b/drivers/thermal/Kconfig
index 2d702ca..9065ba7 100644
--- a/drivers/thermal/Kconfig
+++ b/drivers/thermal/Kconfig
@@ -332,6 +332,16 @@ menu "ACPI INT340X thermal drivers"
 source drivers/thermal/int340x_thermal/Kconfig
 endmenu
 
+config INTEL_PMIC_THERMAL
+   tristate "Intel PMIC thermal driver"
+   depends on X86 && INTEL_SOC_PMIC && REGMAP
+   help
+ Select this driver for Intel PMIC with ADC channels monitoring system
+ temperature measurements and alerts.
+ This driver is used for monitoring the ADC channels of PMIC and 
handles
+ the alert trip point interrupts and notifies the thermal framework 
with
+ the trip point and temperature details of the zone.
+
 config INTEL_PCH_THERMAL
tristate "Intel PCH Thermal Reporting Driver"
depends on X86 && PCI
diff --git a/drivers/thermal/Makefile b/drivers/thermal/Makefile
index 10b07c1..159efcc 100644
--- a/drivers/thermal/Makefile
+++ b/drivers/thermal/Makefile
@@ -45,6 +45,7 @@ obj-$(CONFIG_INTEL_SOC_DTS_THERMAL)   += 
intel_soc_dts_thermal.o
 obj-$(CONFIG_INTEL_QUARK_DTS_THERMAL)  += intel_quark_dts_thermal.o
 obj-$(CONFIG_TI_SOC_THERMAL)   += ti-soc-thermal/
 obj-$(CONFIG_INT340X_THERMAL)  += int340x_thermal/
+obj-$(CONFIG_INTEL_PMIC_THERMAL) += intel_pmic_thermal.o
 obj-$(CONFIG_INTEL_PCH_THERMAL)+= intel_pch_thermal.o
 obj-$(CONFIG_ST_THERMAL)   += st/
 obj-$(CONFIG_TEGRA_SOCTHERM)   += tegra/
diff --git a/drivers/thermal/intel_pmic_thermal.c 
b/drivers/thermal/intel_pmic_thermal.c
new file mode 100644
index 000..401e7a7
--- /dev/null
+++ b/drivers/thermal/intel_pmic_thermal.c
@@ -0,0 +1,299 @@
+/*
+ * pmic_thermal.c - PMIC thermal driver
+ *
+ * Copyright (C) 2015 Intel Corporation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License version
+ * 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#define BXTWC_THRM0IRQ 0x4E04
+#define BXTWC_THRM1IRQ 0x4E05
+#define BXTWC_THRM2IRQ 0x4E06
+#define BXTWC_MTHRM0IRQ0x4E12
+#define BXTWC_MTHRM1IRQ0x4E13
+#define BXTWC_MTHRM2IRQ0x4E14
+#define BXTWC_STHRM0IRQ0x4F19
+#define BXTWC_STHRM1IRQ0x4F1A
+#define BXTWC_STHRM2IRQ0x4F1B
+
+struct trip_config_map {
+   u16 irq_reg;
+   u16 irq_en;
+   u16 evt_stat;
+   u8 irq_mask;
+   u8 irq_en_mask;
+   u8 evt_mask;
+   u8 trip_num;
+};
+
+struct thermal_irq_map {
+   char handle[20];
+   int num_trips;
+   struct trip_config_map *trip_config;
+};
+
+struct pmic_thermal_data {
+   struct thermal_irq_map *maps;
+   int num_maps;
+};
+
+static struct trip_config_map bxtwc_str0_trip_config[] = {
+   {
+   .irq_reg = BXTWC_THRM0IRQ,
+   .irq_mask = 0x01,
+   .irq_en = BXTWC_MTHRM0IRQ,
+   .irq_en_mask = 0x01,
+   .evt_stat = BXTWC_STHRM0IRQ,
+   .evt_mask = 0x01,
+   .trip_num = 0
+   },
+   {
+   .irq_reg = BXTWC_THRM0IRQ,
+   .irq_mask = 0x10,
+   .irq_en = BXTWC_MTHRM0IRQ,
+   .irq_en_mask = 0x10,
+   .evt_stat = BXTWC_STHRM0IRQ,
+   .evt_mask = 0x10,
+   .trip_num = 1
+   }
+};
+
+static struct trip_config_map bxtwc_str1_trip_config[] = {
+   {
+   .irq_reg = BXTWC_THRM0IRQ,
+   .irq_mask = 0x02,
+   .irq_en = BXTWC_MTHRM0IRQ,
+   .irq_en_mask = 0x02,
+   .evt_stat = BXTWC_STHRM0IRQ,
+

[PATCH v6] gpio: add Intel WhiskeyCove PMIC GPIO driver

2016-07-19 Thread Bin Gao
This patch introduces a separate GPIO driver for Intel WhiskeyCove PMIC.
This driver is based on gpio-crystalcove.c.

Signed-off-by: Ajay Thomas <ajay.thomas.david.rajamanic...@intel.com>
Signed-off-by: Bin Gao <bin@intel.com>
Reviewed-by: Andy Shevchenko <andy.shevche...@gmail.com>
Reviewed-by: Mika Westerberg <mika.westerb...@linux.intel.com>
---
Changes in v6:
 - Removed unnecessary wcove_gpio_remove()
 - Used devm_gpiochip_remove() instead of gpiochip_remove()
 - Various coding style changes per Mika's comment
Changes in v5:
 - Revisited the interrupt handler code to iterate until all pending
   interrupts are handled. This change is to avoid missing interrupt
   when we're inside the interrupt handler.
 - Used regmap_bulk_read() to read address adjacent registers.
Changes in v4:
 - Converted CTLI_INTCNT_XX macros to less verbose ones INT_DETECT_XX.
 - Add comments about why there is no .pm for the driver.
 - Header files re-ordered.
 - Various coding style change to address Andy's comments.
Changes in v3:
 - Fixed the year in copyright line(2015-->2016).
 - Removed DRV_NAME macro.
 - Added kernel-doc for regmap_irq_chip of the wcove_gpio structure.
 - Line length fix.
Changes in v2:
 - Typo fix (Whsikey --> Whiskey).
 - Included linux/gpio/driver.h instead of linux/gpio.h
 - Implemented .set_single_ended().
 - Added GPIO register description.
 - Replaced container_of() with gpiochip_get_data().
 - Removed unnecessary "if (gpio > WCOVE_VGPIO_NUM" check.
 - Removed the device id table and added MODULE_ALIAS().
 drivers/gpio/Kconfig  |  13 ++
 drivers/gpio/Makefile |   1 +
 drivers/gpio/gpio-wcove.c | 439 ++
 3 files changed, 453 insertions(+)
 create mode 100644 drivers/gpio/gpio-wcove.c

diff --git a/drivers/gpio/Kconfig b/drivers/gpio/Kconfig
index 536112f..0f33982 100644
--- a/drivers/gpio/Kconfig
+++ b/drivers/gpio/Kconfig
@@ -806,6 +806,19 @@ config GPIO_CRYSTAL_COVE
  This driver can also be built as a module. If so, the module will be
  called gpio-crystalcove.
 
+config GPIO_WHISKEY_COVE
+   tristate "GPIO support for Whiskey Cove PMIC"
+   depends on INTEL_SOC_PMIC
+   select GPIOLIB_IRQCHIP
+   help
+ Support for GPIO pins on Whiskey Cove PMIC.
+
+ Say Yes if you have a Intel SoC based tablet with Whiskey Cove PMIC
+ inside.
+
+ This driver can also be built as a module. If so, the module will be
+ called gpio-wcove.
+
 config GPIO_CS5535
tristate "AMD CS5535/CS5536 GPIO support"
depends on MFD_CS5535
diff --git a/drivers/gpio/Makefile b/drivers/gpio/Makefile
index 991598e..fff6914 100644
--- a/drivers/gpio/Makefile
+++ b/drivers/gpio/Makefile
@@ -34,6 +34,7 @@ obj-$(CONFIG_GPIO_BT8XX)  += gpio-bt8xx.o
 obj-$(CONFIG_GPIO_CLPS711X)+= gpio-clps711x.o
 obj-$(CONFIG_GPIO_CS5535)  += gpio-cs5535.o
 obj-$(CONFIG_GPIO_CRYSTAL_COVE)+= gpio-crystalcove.o
+obj-$(CONFIG_GPIO_WHISKEY_COVE)+= gpio-wcove.o
 obj-$(CONFIG_GPIO_DA9052)  += gpio-da9052.o
 obj-$(CONFIG_GPIO_DA9055)  += gpio-da9055.o
 obj-$(CONFIG_GPIO_DAVINCI) += gpio-davinci.o
diff --git a/drivers/gpio/gpio-wcove.c b/drivers/gpio/gpio-wcove.c
new file mode 100644
index 000..dc586e5
--- /dev/null
+++ b/drivers/gpio/gpio-wcove.c
@@ -0,0 +1,439 @@
+/*
+ * gpio-wcove.c - Intel Whiskey Cove GPIO Driver
+ *
+ * This driver is written based on gpio-crystalcove.c
+ *
+ * Copyright (C) 2016 Intel Corporation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License version
+ * 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+/*
+ * Whiskey Cove PMIC has 13 physical GPIO pins divided into 3 banks:
+ * Bank 0: Pin 0 - 6
+ * Bank 1: Pin 7 - 10
+ * Bank 2: Pin 11 -12
+ * Each pin has one output control register and one input control register.
+ */
+#define BANK0_NR_PINS  7
+#define BANK1_NR_PINS  4
+#define BANK2_NR_PINS  2
+#define WCOVE_GPIO_NUM (BANK0_NR_PINS + BANK1_NR_PINS + BANK2_NR_PINS)
+#define WCOVE_VGPIO_NUM94
+/* GPIO output control registers(one per pin): 0x4e44 - 0x4e50 */
+#define GPIO_OUT_CTRL_BASE 0x4e44
+/* GPIO input control registers(one per pin): 0x4e51 - 0x4e5d */
+#define GPIO_IN_CTRL_BASE  0x4e51
+
+/*
+ * GPIO interrupts are organized in two groups:
+ * Group 0: Bank 0 pins (Pin 0 - 6)
+ * Group 1: Bank 1 and Bank 2 pins (Pin 7 - 12)
+ * Each group has two registers(one bit per pin): status and mask.

[PATCH v6] gpio: add Intel WhiskeyCove PMIC GPIO driver

2016-07-19 Thread Bin Gao
This patch introduces a separate GPIO driver for Intel WhiskeyCove PMIC.
This driver is based on gpio-crystalcove.c.

Signed-off-by: Ajay Thomas 
Signed-off-by: Bin Gao 
Reviewed-by: Andy Shevchenko 
Reviewed-by: Mika Westerberg 
---
Changes in v6:
 - Removed unnecessary wcove_gpio_remove()
 - Used devm_gpiochip_remove() instead of gpiochip_remove()
 - Various coding style changes per Mika's comment
Changes in v5:
 - Revisited the interrupt handler code to iterate until all pending
   interrupts are handled. This change is to avoid missing interrupt
   when we're inside the interrupt handler.
 - Used regmap_bulk_read() to read address adjacent registers.
Changes in v4:
 - Converted CTLI_INTCNT_XX macros to less verbose ones INT_DETECT_XX.
 - Add comments about why there is no .pm for the driver.
 - Header files re-ordered.
 - Various coding style change to address Andy's comments.
Changes in v3:
 - Fixed the year in copyright line(2015-->2016).
 - Removed DRV_NAME macro.
 - Added kernel-doc for regmap_irq_chip of the wcove_gpio structure.
 - Line length fix.
Changes in v2:
 - Typo fix (Whsikey --> Whiskey).
 - Included linux/gpio/driver.h instead of linux/gpio.h
 - Implemented .set_single_ended().
 - Added GPIO register description.
 - Replaced container_of() with gpiochip_get_data().
 - Removed unnecessary "if (gpio > WCOVE_VGPIO_NUM" check.
 - Removed the device id table and added MODULE_ALIAS().
 drivers/gpio/Kconfig  |  13 ++
 drivers/gpio/Makefile |   1 +
 drivers/gpio/gpio-wcove.c | 439 ++
 3 files changed, 453 insertions(+)
 create mode 100644 drivers/gpio/gpio-wcove.c

diff --git a/drivers/gpio/Kconfig b/drivers/gpio/Kconfig
index 536112f..0f33982 100644
--- a/drivers/gpio/Kconfig
+++ b/drivers/gpio/Kconfig
@@ -806,6 +806,19 @@ config GPIO_CRYSTAL_COVE
  This driver can also be built as a module. If so, the module will be
  called gpio-crystalcove.
 
+config GPIO_WHISKEY_COVE
+   tristate "GPIO support for Whiskey Cove PMIC"
+   depends on INTEL_SOC_PMIC
+   select GPIOLIB_IRQCHIP
+   help
+ Support for GPIO pins on Whiskey Cove PMIC.
+
+ Say Yes if you have a Intel SoC based tablet with Whiskey Cove PMIC
+ inside.
+
+ This driver can also be built as a module. If so, the module will be
+ called gpio-wcove.
+
 config GPIO_CS5535
tristate "AMD CS5535/CS5536 GPIO support"
depends on MFD_CS5535
diff --git a/drivers/gpio/Makefile b/drivers/gpio/Makefile
index 991598e..fff6914 100644
--- a/drivers/gpio/Makefile
+++ b/drivers/gpio/Makefile
@@ -34,6 +34,7 @@ obj-$(CONFIG_GPIO_BT8XX)  += gpio-bt8xx.o
 obj-$(CONFIG_GPIO_CLPS711X)+= gpio-clps711x.o
 obj-$(CONFIG_GPIO_CS5535)  += gpio-cs5535.o
 obj-$(CONFIG_GPIO_CRYSTAL_COVE)+= gpio-crystalcove.o
+obj-$(CONFIG_GPIO_WHISKEY_COVE)+= gpio-wcove.o
 obj-$(CONFIG_GPIO_DA9052)  += gpio-da9052.o
 obj-$(CONFIG_GPIO_DA9055)  += gpio-da9055.o
 obj-$(CONFIG_GPIO_DAVINCI) += gpio-davinci.o
diff --git a/drivers/gpio/gpio-wcove.c b/drivers/gpio/gpio-wcove.c
new file mode 100644
index 000..dc586e5
--- /dev/null
+++ b/drivers/gpio/gpio-wcove.c
@@ -0,0 +1,439 @@
+/*
+ * gpio-wcove.c - Intel Whiskey Cove GPIO Driver
+ *
+ * This driver is written based on gpio-crystalcove.c
+ *
+ * Copyright (C) 2016 Intel Corporation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License version
+ * 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+/*
+ * Whiskey Cove PMIC has 13 physical GPIO pins divided into 3 banks:
+ * Bank 0: Pin 0 - 6
+ * Bank 1: Pin 7 - 10
+ * Bank 2: Pin 11 -12
+ * Each pin has one output control register and one input control register.
+ */
+#define BANK0_NR_PINS  7
+#define BANK1_NR_PINS  4
+#define BANK2_NR_PINS  2
+#define WCOVE_GPIO_NUM (BANK0_NR_PINS + BANK1_NR_PINS + BANK2_NR_PINS)
+#define WCOVE_VGPIO_NUM94
+/* GPIO output control registers(one per pin): 0x4e44 - 0x4e50 */
+#define GPIO_OUT_CTRL_BASE 0x4e44
+/* GPIO input control registers(one per pin): 0x4e51 - 0x4e5d */
+#define GPIO_IN_CTRL_BASE  0x4e51
+
+/*
+ * GPIO interrupts are organized in two groups:
+ * Group 0: Bank 0 pins (Pin 0 - 6)
+ * Group 1: Bank 1 and Bank 2 pins (Pin 7 - 12)
+ * Each group has two registers(one bit per pin): status and mask.
+ */
+#define GROUP0_NR_IRQS 7
+#define GROUP1_NR_IRQS 6
+#define IRQ_MASK_BASE  0x4e19
+#define IRQ_STATUS_BASE

Re: [PATCH 1/2] usb: typec: Add USB Power Delivery sink port support

2016-07-18 Thread Bin Gao
On Mon, Jul 18, 2016 at 10:07:24AM +0300, Felipe Balbi wrote:
> 
> Hi,
> 
> Bin Gao <bin@linux.intel.com> writes:
> >> > +int pd_sink_queue_msg(struct pd_sink_msg *msg)
> >> > +{
> >> > +unsigned long flags;
> >> > +struct pd_sink_port *port;
> >> > +
> >> > +if (msg->port < 0 || msg->port >= MAX_NR_SINK_PORTS) {
> >> > +pr_err("Invalid port number\n");
> >> > +return -EINVAL;
> >> > +}
> >> > +
> >> > +port = sink_ports[msg->port];
> >> > +
> >> > +spin_lock_irqsave(>rx_lock, flags);
> >> > +list_add_tail(>list, >rx_list);
> >> > +spin_unlock_irqrestore(>rx_lock, flags);
> >> > +
> >> > +queue_work(port->rx_wq, >rx_work);
> >> 
> >> can we really queue several messages at a time? It seems unfeasible to
> >> me. It's not like we can queue several power request in a role. Why do
> >> you need this workqueue? Why don't you process message here, in place?
> > Some Type-C chargers send two messages in a short duration(less than 1 ms),
> > e.g. a SOURCE_CAPABILITY follows the previous SOURCE_CAPABILITY, or a
> > GET_SINK_CAPABILITY follows a previous SOURCE_CAPABILITY, etc. Queuing
> > message to PD stack by Type-C phy driver typically happens in a interrupt
> > context. So in this case a nested interrupt may happen. Our whole PD
> > stack while processing one message is not re-entrant so the nested
> > interrupt would cause a problem.
> 
> keep interrupts masked for as long as necessary until your message is
> processed.

Yes, that's a right way to go. 
We'll have to document this because there might be other Type-C
PHY drivers(other than Intel Whiskey Cove PMIC) to use the PD stack.

> 
> -- 
> balbi




Re: [PATCH 1/2] usb: typec: Add USB Power Delivery sink port support

2016-07-18 Thread Bin Gao
On Mon, Jul 18, 2016 at 10:07:24AM +0300, Felipe Balbi wrote:
> 
> Hi,
> 
> Bin Gao  writes:
> >> > +int pd_sink_queue_msg(struct pd_sink_msg *msg)
> >> > +{
> >> > +unsigned long flags;
> >> > +struct pd_sink_port *port;
> >> > +
> >> > +if (msg->port < 0 || msg->port >= MAX_NR_SINK_PORTS) {
> >> > +pr_err("Invalid port number\n");
> >> > +return -EINVAL;
> >> > +}
> >> > +
> >> > +port = sink_ports[msg->port];
> >> > +
> >> > +spin_lock_irqsave(>rx_lock, flags);
> >> > +list_add_tail(>list, >rx_list);
> >> > +spin_unlock_irqrestore(>rx_lock, flags);
> >> > +
> >> > +queue_work(port->rx_wq, >rx_work);
> >> 
> >> can we really queue several messages at a time? It seems unfeasible to
> >> me. It's not like we can queue several power request in a role. Why do
> >> you need this workqueue? Why don't you process message here, in place?
> > Some Type-C chargers send two messages in a short duration(less than 1 ms),
> > e.g. a SOURCE_CAPABILITY follows the previous SOURCE_CAPABILITY, or a
> > GET_SINK_CAPABILITY follows a previous SOURCE_CAPABILITY, etc. Queuing
> > message to PD stack by Type-C phy driver typically happens in a interrupt
> > context. So in this case a nested interrupt may happen. Our whole PD
> > stack while processing one message is not re-entrant so the nested
> > interrupt would cause a problem.
> 
> keep interrupts masked for as long as necessary until your message is
> processed.

Yes, that's a right way to go. 
We'll have to document this because there might be other Type-C
PHY drivers(other than Intel Whiskey Cove PMIC) to use the PD stack.

> 
> -- 
> balbi




Re: [PATCH 1/2] usb: typec: Add USB Power Delivery sink port support

2016-07-18 Thread Bin Gao
On Sat, Jul 16, 2016 at 08:49:53AM +0900, Greg Kroah-Hartman wrote:
> On Fri, Jul 15, 2016 at 03:41:10PM -0700, Bin Gao wrote:
> > On Fri, Jul 15, 2016 at 02:21:48PM +0300, Felipe Balbi wrote:
> > > Greg Kroah-Hartman <gre...@linuxfoundation.org> writes:
> > > > On Fri, Jul 15, 2016 at 01:38:12PM +0300, Felipe Balbi wrote:
> > > >> 
> > > >> Hi,
> > > >> 
> > > >> Bin Gao <bin@linux.intel.com> writes:
> > > >> > +static void print_message(int port, bool is_cmsg, u8 msg, bool recv)
> > > >> > +{
> > > >> > +pr_info("sink port %d: %s message %s %s\n", port,
> > > >> > +is_cmsg ? "Control" : "Data",
> > > >> > +msg_to_string(is_cmsg, msg),
> > > >> > + recv ? "received" : "sent(wait GOODCRC)");
> > > >> > +}
> > > >> 
> > > >> this is problematic. By default, we're all using 115200 8N1 baud
> > > >> rate. This message alone prints anywhere from 50 to 100 characters (I
> > > >> didn't really count properly, these are rough numbers), and that takes:
> > > >> 
> > > >> n50chars_time = 50 / (115200 / 10) = 4.3ms
> > > >> n100chars_time = 100 / (115200 / 10) = 8.6ms
> > > >> 
> > > >> Considering you have 30ms to reply with Power Request after GoodCRC, 
> > > >> and
> > > >> considering you're printing several of these messages, they become
> > > >> really expensive and eat up valuable time from tSenderReply.
> > > >
> > > > printk() should be async, so it shouldn't be that big of a deal.
> > > 
> > > I can actually see this causing problems ;-) With this pr_info(),
> > > sometimes tSenderReply times out and Source gives a HardReset. Without
> > > pr_info(), type-c analyzer tells me we reply in less than 1ms.
> > > 
> > > > What is wrong is that this isn't using dev_info().
> > > 
> > > right, that too.
> > > 
> > > -- 
> > > balbi
> > 
> > When we don't have a struct device pointer for this driver,
> 
> Then you should fix that, as this is a driver for hardware :)
This is actualy a software stack to implement the USB PD spec.
Only the USB Type-C phy driver has a device pointer.
The PD stack vs. USB Type-C phy driver is similar to TCP/IP stack
vs. ethernet driver in the kernel. We don't have a device pointer
for TCP/IP stack code either.

Thanks,
Bin

> 
> thanks,
> 
> greg k-h


Re: [PATCH 1/2] usb: typec: Add USB Power Delivery sink port support

2016-07-18 Thread Bin Gao
On Sat, Jul 16, 2016 at 08:49:53AM +0900, Greg Kroah-Hartman wrote:
> On Fri, Jul 15, 2016 at 03:41:10PM -0700, Bin Gao wrote:
> > On Fri, Jul 15, 2016 at 02:21:48PM +0300, Felipe Balbi wrote:
> > > Greg Kroah-Hartman  writes:
> > > > On Fri, Jul 15, 2016 at 01:38:12PM +0300, Felipe Balbi wrote:
> > > >> 
> > > >> Hi,
> > > >> 
> > > >> Bin Gao  writes:
> > > >> > +static void print_message(int port, bool is_cmsg, u8 msg, bool recv)
> > > >> > +{
> > > >> > +pr_info("sink port %d: %s message %s %s\n", port,
> > > >> > +is_cmsg ? "Control" : "Data",
> > > >> > +msg_to_string(is_cmsg, msg),
> > > >> > + recv ? "received" : "sent(wait GOODCRC)");
> > > >> > +}
> > > >> 
> > > >> this is problematic. By default, we're all using 115200 8N1 baud
> > > >> rate. This message alone prints anywhere from 50 to 100 characters (I
> > > >> didn't really count properly, these are rough numbers), and that takes:
> > > >> 
> > > >> n50chars_time = 50 / (115200 / 10) = 4.3ms
> > > >> n100chars_time = 100 / (115200 / 10) = 8.6ms
> > > >> 
> > > >> Considering you have 30ms to reply with Power Request after GoodCRC, 
> > > >> and
> > > >> considering you're printing several of these messages, they become
> > > >> really expensive and eat up valuable time from tSenderReply.
> > > >
> > > > printk() should be async, so it shouldn't be that big of a deal.
> > > 
> > > I can actually see this causing problems ;-) With this pr_info(),
> > > sometimes tSenderReply times out and Source gives a HardReset. Without
> > > pr_info(), type-c analyzer tells me we reply in less than 1ms.
> > > 
> > > > What is wrong is that this isn't using dev_info().
> > > 
> > > right, that too.
> > > 
> > > -- 
> > > balbi
> > 
> > When we don't have a struct device pointer for this driver,
> 
> Then you should fix that, as this is a driver for hardware :)
This is actualy a software stack to implement the USB PD spec.
Only the USB Type-C phy driver has a device pointer.
The PD stack vs. USB Type-C phy driver is similar to TCP/IP stack
vs. ethernet driver in the kernel. We don't have a device pointer
for TCP/IP stack code either.

Thanks,
Bin

> 
> thanks,
> 
> greg k-h


Re: [PATCH 1/2] usb: typec: Add USB Power Delivery sink port support

2016-07-15 Thread Bin Gao
On Fri, Jul 15, 2016 at 10:25:36AM +0300, Felipe Balbi wrote:
> Bin Gao <bin@linux.intel.com> writes:
> 
> > This patch implements a simple USB Power Delivery sink port state machine.
> > It assumes the hardware only handles PD packet transmitting and receiving
> > over the CC line of the USB Type-C connector. The state transition is
> > completely controlled by software. This patch only implement the sink port
> > function and it doesn't support source port and port swap yet.
> >
> > This patch depends on these two patches:
> > https://lkml.org/lkml/2016/6/29/349
> > https://lkml.org/lkml/2016/6/29/350
> >
> > Signed-off-by: Bin Gao <bin@intel.com>
> > ---
> >  drivers/usb/typec/Kconfig  |  13 +
> >  drivers/usb/typec/Makefile |   1 +
> >  drivers/usb/typec/pd_sink.c| 967 
> > +
> >  include/linux/usb/pd_message.h | 371 
> >  include/linux/usb/pd_sink.h| 286 
> >  5 files changed, 1638 insertions(+)
> >  create mode 100644 drivers/usb/typec/pd_sink.c
> >  create mode 100644 include/linux/usb/pd_message.h
> >  create mode 100644 include/linux/usb/pd_sink.h
> >
> > diff --git a/drivers/usb/typec/Kconfig b/drivers/usb/typec/Kconfig
> > index 7a345a4..a04a900 100644
> > --- a/drivers/usb/typec/Kconfig
> > +++ b/drivers/usb/typec/Kconfig
> > @@ -4,12 +4,25 @@ menu "USB PD and Type-C drivers"
> >  config TYPEC
> > tristate
> >  
> > +config USB_PD_SINK
> > +   bool "USB Power Delivery Sink Port State Machine Driver"
> 
> tristate?
> 
> > +   select TYPEC
> 
> this should depend on TYPEC, not select it.
> 
> > +   help
> > + Enable this to support USB PD(Power Delivery) Sink port.
> > + This driver implements a simple USB PD sink state machine.
> > + The underlying TypeC phy driver is responsible for cable
> > + plug/unplug event, port orientation detection, transmitting
> > + and receiving PD messages. This driver only process messages
> > + received by the TypeC phy driver and maintain the sink port's
> > + state machine.
> > +
> >  config TYPEC_WCOVE
> > tristate "Intel WhiskeyCove PMIC USB Type-C PHY driver"
> > depends on ACPI
> > depends on INTEL_SOC_PMIC
> > depends on INTEL_PMC_IPC
> > select TYPEC
> > +   select USB_PD_SINK
> 
> TYPEC without PD is valid, let user select PD support.
Yes will fix the Kconfig in next revision.

> > +static void print_message(int port, bool is_cmsg, u8 msg, bool recv)
> > +{
> > +   pr_info("sink port %d: %s message %s %s\n", port,
> > +   is_cmsg ? "Control" : "Data",
> > +   msg_to_string(is_cmsg, msg),
> > +recv ? "received" : "sent(wait GOODCRC)");
> 
> looks like a debugging message to me. We don't want to spam dmesg with
> every single message transmission.
This should be a pr_debug().

> 
> > +static void start_timer(struct pd_sink_port *port, int timeout,
> > +   enum hrtimer_restart (*f)(struct hrtimer *))
> > +{
> > +   if (hrtimer_active(>tx_timer)) {
> > +   pr_err("Error: previous timer is still active\n");
> > +   return;
> > +   }
> > +
> > +   port->tx_timer.function = f;
> > +   /* timeout comes with ms but ktime_set takes seconds and nanoseconds */
> > +   hrtimer_start(>tx_timer, ktime_set(timeout / 1000,
> 
> I don't think you need HR timers here. A normal mod_timer() should do.
When hrtimer is in place, the old timer becomes "legacy". And the old timer
APIs are implemented on top of hrtimer. It's no harm to use hrtimers anywhere
in the kernel and it would be encouraged in my opinion:-)

> 
> > +static enum hrtimer_restart goodcrc_timeout(struct hrtimer *timer)
> > +{
> > +   pr_err("GOODCRC message is not received in %d ms: timeout\n",
> > +   PD_TIMEOUT_GOODCRC);
> > +   return HRTIMER_NORESTART;
> > +}
> > +
> > +/*
> > + * For any message we send, we must get a GOODCRC message from the Source.
> > + * The USB PD spec says the time should be measured between the last bit
> > + * of the sending message's EOP has been transmitted and the last bit of
> > + * the receiving GOODCRC message's EOP has been received. The allowed time
> > + * is minimal 0.9 ms and maximal 1.1 ms. However, this measurement is
> > + * performed in physical la

Re: [PATCH 1/2] usb: typec: Add USB Power Delivery sink port support

2016-07-15 Thread Bin Gao
On Fri, Jul 15, 2016 at 10:25:36AM +0300, Felipe Balbi wrote:
> Bin Gao  writes:
> 
> > This patch implements a simple USB Power Delivery sink port state machine.
> > It assumes the hardware only handles PD packet transmitting and receiving
> > over the CC line of the USB Type-C connector. The state transition is
> > completely controlled by software. This patch only implement the sink port
> > function and it doesn't support source port and port swap yet.
> >
> > This patch depends on these two patches:
> > https://lkml.org/lkml/2016/6/29/349
> > https://lkml.org/lkml/2016/6/29/350
> >
> > Signed-off-by: Bin Gao 
> > ---
> >  drivers/usb/typec/Kconfig  |  13 +
> >  drivers/usb/typec/Makefile |   1 +
> >  drivers/usb/typec/pd_sink.c| 967 
> > +
> >  include/linux/usb/pd_message.h | 371 
> >  include/linux/usb/pd_sink.h| 286 
> >  5 files changed, 1638 insertions(+)
> >  create mode 100644 drivers/usb/typec/pd_sink.c
> >  create mode 100644 include/linux/usb/pd_message.h
> >  create mode 100644 include/linux/usb/pd_sink.h
> >
> > diff --git a/drivers/usb/typec/Kconfig b/drivers/usb/typec/Kconfig
> > index 7a345a4..a04a900 100644
> > --- a/drivers/usb/typec/Kconfig
> > +++ b/drivers/usb/typec/Kconfig
> > @@ -4,12 +4,25 @@ menu "USB PD and Type-C drivers"
> >  config TYPEC
> > tristate
> >  
> > +config USB_PD_SINK
> > +   bool "USB Power Delivery Sink Port State Machine Driver"
> 
> tristate?
> 
> > +   select TYPEC
> 
> this should depend on TYPEC, not select it.
> 
> > +   help
> > + Enable this to support USB PD(Power Delivery) Sink port.
> > + This driver implements a simple USB PD sink state machine.
> > + The underlying TypeC phy driver is responsible for cable
> > + plug/unplug event, port orientation detection, transmitting
> > + and receiving PD messages. This driver only process messages
> > + received by the TypeC phy driver and maintain the sink port's
> > + state machine.
> > +
> >  config TYPEC_WCOVE
> > tristate "Intel WhiskeyCove PMIC USB Type-C PHY driver"
> > depends on ACPI
> > depends on INTEL_SOC_PMIC
> > depends on INTEL_PMC_IPC
> > select TYPEC
> > +   select USB_PD_SINK
> 
> TYPEC without PD is valid, let user select PD support.
Yes will fix the Kconfig in next revision.

> > +static void print_message(int port, bool is_cmsg, u8 msg, bool recv)
> > +{
> > +   pr_info("sink port %d: %s message %s %s\n", port,
> > +   is_cmsg ? "Control" : "Data",
> > +   msg_to_string(is_cmsg, msg),
> > +recv ? "received" : "sent(wait GOODCRC)");
> 
> looks like a debugging message to me. We don't want to spam dmesg with
> every single message transmission.
This should be a pr_debug().

> 
> > +static void start_timer(struct pd_sink_port *port, int timeout,
> > +   enum hrtimer_restart (*f)(struct hrtimer *))
> > +{
> > +   if (hrtimer_active(>tx_timer)) {
> > +   pr_err("Error: previous timer is still active\n");
> > +   return;
> > +   }
> > +
> > +   port->tx_timer.function = f;
> > +   /* timeout comes with ms but ktime_set takes seconds and nanoseconds */
> > +   hrtimer_start(>tx_timer, ktime_set(timeout / 1000,
> 
> I don't think you need HR timers here. A normal mod_timer() should do.
When hrtimer is in place, the old timer becomes "legacy". And the old timer
APIs are implemented on top of hrtimer. It's no harm to use hrtimers anywhere
in the kernel and it would be encouraged in my opinion:-)

> 
> > +static enum hrtimer_restart goodcrc_timeout(struct hrtimer *timer)
> > +{
> > +   pr_err("GOODCRC message is not received in %d ms: timeout\n",
> > +   PD_TIMEOUT_GOODCRC);
> > +   return HRTIMER_NORESTART;
> > +}
> > +
> > +/*
> > + * For any message we send, we must get a GOODCRC message from the Source.
> > + * The USB PD spec says the time should be measured between the last bit
> > + * of the sending message's EOP has been transmitted and the last bit of
> > + * the receiving GOODCRC message's EOP has been received. The allowed time
> > + * is minimal 0.9 ms and maximal 1.1 ms. However, this measurement is
> > + * performed in physical layer. When it reaches to the OS and this dri

Re: [PATCH 1/2] usb: typec: Add USB Power Delivery sink port support

2016-07-15 Thread Bin Gao
On Fri, Jul 15, 2016 at 02:21:48PM +0300, Felipe Balbi wrote:
> Greg Kroah-Hartman <gre...@linuxfoundation.org> writes:
> > On Fri, Jul 15, 2016 at 01:38:12PM +0300, Felipe Balbi wrote:
> >> 
> >> Hi,
> >> 
> >> Bin Gao <bin@linux.intel.com> writes:
> >> > +static void print_message(int port, bool is_cmsg, u8 msg, bool recv)
> >> > +{
> >> > +pr_info("sink port %d: %s message %s %s\n", port,
> >> > +is_cmsg ? "Control" : "Data",
> >> > +msg_to_string(is_cmsg, msg),
> >> > + recv ? "received" : "sent(wait GOODCRC)");
> >> > +}
> >> 
> >> this is problematic. By default, we're all using 115200 8N1 baud
> >> rate. This message alone prints anywhere from 50 to 100 characters (I
> >> didn't really count properly, these are rough numbers), and that takes:
> >> 
> >> n50chars_time = 50 / (115200 / 10) = 4.3ms
> >> n100chars_time = 100 / (115200 / 10) = 8.6ms
> >> 
> >> Considering you have 30ms to reply with Power Request after GoodCRC, and
> >> considering you're printing several of these messages, they become
> >> really expensive and eat up valuable time from tSenderReply.
> >
> > printk() should be async, so it shouldn't be that big of a deal.
> 
> I can actually see this causing problems ;-) With this pr_info(),
> sometimes tSenderReply times out and Source gives a HardReset. Without
> pr_info(), type-c analyzer tells me we reply in less than 1ms.
> 
> > What is wrong is that this isn't using dev_info().
> 
> right, that too.
> 
> -- 
> balbi

When we don't have a struct device pointer for this driver,
a dev_info(NULL, fmt, ...) is equivalent to pr_info(). So we have to
use dev_info() here?
But I agree at least it should be pr_debug().


Re: [PATCH 1/2] usb: typec: Add USB Power Delivery sink port support

2016-07-15 Thread Bin Gao
On Fri, Jul 15, 2016 at 02:21:48PM +0300, Felipe Balbi wrote:
> Greg Kroah-Hartman  writes:
> > On Fri, Jul 15, 2016 at 01:38:12PM +0300, Felipe Balbi wrote:
> >> 
> >> Hi,
> >> 
> >> Bin Gao  writes:
> >> > +static void print_message(int port, bool is_cmsg, u8 msg, bool recv)
> >> > +{
> >> > +pr_info("sink port %d: %s message %s %s\n", port,
> >> > +is_cmsg ? "Control" : "Data",
> >> > +msg_to_string(is_cmsg, msg),
> >> > + recv ? "received" : "sent(wait GOODCRC)");
> >> > +}
> >> 
> >> this is problematic. By default, we're all using 115200 8N1 baud
> >> rate. This message alone prints anywhere from 50 to 100 characters (I
> >> didn't really count properly, these are rough numbers), and that takes:
> >> 
> >> n50chars_time = 50 / (115200 / 10) = 4.3ms
> >> n100chars_time = 100 / (115200 / 10) = 8.6ms
> >> 
> >> Considering you have 30ms to reply with Power Request after GoodCRC, and
> >> considering you're printing several of these messages, they become
> >> really expensive and eat up valuable time from tSenderReply.
> >
> > printk() should be async, so it shouldn't be that big of a deal.
> 
> I can actually see this causing problems ;-) With this pr_info(),
> sometimes tSenderReply times out and Source gives a HardReset. Without
> pr_info(), type-c analyzer tells me we reply in less than 1ms.
> 
> > What is wrong is that this isn't using dev_info().
> 
> right, that too.
> 
> -- 
> balbi

When we don't have a struct device pointer for this driver,
a dev_info(NULL, fmt, ...) is equivalent to pr_info(). So we have to
use dev_info() here?
But I agree at least it should be pr_debug().


Re: [PATCH 1/2] usb: typec: Add USB Power Delivery sink port support

2016-07-15 Thread Bin Gao
On Fri, Jul 15, 2016 at 08:31:08AM +0200, Oliver Neukum wrote:
> > +static void ack_message(struct pd_sink_port *port, int msg_id)
> > +{
> > +   struct pd_msg_header *header = kzalloc(PD_MSG_HEADER_LEN, GFP_KERNEL);
> 
> This must be GFP_NOIO. We are in a cycle that can lead to deadlock.
> 
> Assume we are waiting for a request for more power to process IO
> which we need to ack.
> 
> 1. memory allocation leads to laundering, blocks on freeing memory
> 2. launderer decides to perform IO which needs more power
> 3. more power has already been requested, wait for it to be granted
> 
> 4. BANG - DEADLOCK
Agree, I'll change the GFP flag in next revision.

> > +   struct pd_msg_header *header = kzalloc(PD_MSG_HEADER_LEN +
> > +   port->nr_ps * PD_OBJ_SIZE, GFP_KERNEL);
> 
> Must be GFP_NOIO. For the same reason as above. We may be asked
> this to resolve a mismatch due to needing more power for IO.
Yes will do.

> > +static void handle_soft_reset(struct pd_sink_port *port)
> > +{
> > +   struct pd_msg_header *header = kzalloc(PD_MSG_HEADER_LEN, GFP_KERNEL);
> > +
> > +   if (!header)
> > +   return;
> > +
> > +   flush_workqueue(port->rx_wq);
> 
> That is problematic. We may be here precisely because something is wrong
> blocking progress. In particular what happens if another soft reset
> is queued?
I'm going to remove the workqueue.

> > +   struct pd_msg_header *header = kzalloc(PD_MSG_HEADER_LEN +
> > +   PD_OBJ_SIZE, GFP_KERNEL);
> 
> GFP_NOIO, same reasons
Yes.

> > +
> 
>   HTH
>   Oliver
Thanks for your review.


Re: [PATCH 1/2] usb: typec: Add USB Power Delivery sink port support

2016-07-15 Thread Bin Gao
On Fri, Jul 15, 2016 at 08:31:08AM +0200, Oliver Neukum wrote:
> > +static void ack_message(struct pd_sink_port *port, int msg_id)
> > +{
> > +   struct pd_msg_header *header = kzalloc(PD_MSG_HEADER_LEN, GFP_KERNEL);
> 
> This must be GFP_NOIO. We are in a cycle that can lead to deadlock.
> 
> Assume we are waiting for a request for more power to process IO
> which we need to ack.
> 
> 1. memory allocation leads to laundering, blocks on freeing memory
> 2. launderer decides to perform IO which needs more power
> 3. more power has already been requested, wait for it to be granted
> 
> 4. BANG - DEADLOCK
Agree, I'll change the GFP flag in next revision.

> > +   struct pd_msg_header *header = kzalloc(PD_MSG_HEADER_LEN +
> > +   port->nr_ps * PD_OBJ_SIZE, GFP_KERNEL);
> 
> Must be GFP_NOIO. For the same reason as above. We may be asked
> this to resolve a mismatch due to needing more power for IO.
Yes will do.

> > +static void handle_soft_reset(struct pd_sink_port *port)
> > +{
> > +   struct pd_msg_header *header = kzalloc(PD_MSG_HEADER_LEN, GFP_KERNEL);
> > +
> > +   if (!header)
> > +   return;
> > +
> > +   flush_workqueue(port->rx_wq);
> 
> That is problematic. We may be here precisely because something is wrong
> blocking progress. In particular what happens if another soft reset
> is queued?
I'm going to remove the workqueue.

> > +   struct pd_msg_header *header = kzalloc(PD_MSG_HEADER_LEN +
> > +   PD_OBJ_SIZE, GFP_KERNEL);
> 
> GFP_NOIO, same reasons
Yes.

> > +
> 
>   HTH
>   Oliver
Thanks for your review.


[PATCH 2/2] usb: typec: add PD sink port support for Intel Whiskey Cove PMIC Typc-C PHY driver

2016-07-14 Thread Bin Gao
From: Chandra Sekhar Anagani 

This adds PD sink port support for the USB Type-C PHY on Intel WhiskeyCove
PMIC which is available on some of the Intel Broxton SoC based platforms.

This patch depends on these two patches:
https://lkml.org/lkml/2016/6/29/349
https://lkml.org/lkml/2016/6/29/350

Signed-off-by: Chandra Sekhar Anagani 
---
 drivers/usb/typec/typec_wcove.c | 289 
 1 file changed, 263 insertions(+), 26 deletions(-)

diff --git a/drivers/usb/typec/typec_wcove.c b/drivers/usb/typec/typec_wcove.c
index c7c2d28..a4250ba 100644
--- a/drivers/usb/typec/typec_wcove.c
+++ b/drivers/usb/typec/typec_wcove.c
@@ -3,6 +3,7 @@
  *
  * Copyright (C) 2016 Intel Corporation
  * Author: Heikki Krogerus 
+ * Author: Chandra Sekhar Anagani 
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License version 2 as
@@ -10,9 +11,11 @@
  */
 
 #include 
+#include 
 #include 
 #include 
 #include 
+#include 
 #include 
 #include 
 
@@ -25,6 +28,7 @@
 #define USBC_CONTROL3  0x7003
 #define USBC_CC1_CTRL  0x7004
 #define USBC_CC2_CTRL  0x7005
+#define USBC_CC_SEL0x7006
 #define USBC_STATUS1   0x7007
 #define USBC_STATUS2   0x7008
 #define USBC_STATUS3   0x7009
@@ -32,7 +36,16 @@
 #define USBC_IRQ2  0x7016
 #define USBC_IRQMASK1  0x7017
 #define USBC_IRQMASK2  0x7018
-
+#define USBC_PD_CFG1   0x7019
+#define USBC_PD_CFG2   0x701a
+#define USBC_PD_CFG3   0x701b
+#define USBC_PD_STATUS 0x701c
+#define USBC_RX_STATUS 0x701d
+#define USBC_RX_INFO   0x701e
+#define USBC_TX_CMD0x701f
+#define USBC_TX_INFO   0x7020
+#define USBC_RX_DATA_START 0x7028
+#define USBC_TX_DATA_START 0x7047
 /* Register bits */
 
 #define USBC_CONTROL1_MODE_DRP(r)  ((r & ~0x7) | 4)
@@ -44,7 +57,9 @@
 #define USBC_CONTROL3_PD_DIS   BIT(1)
 
 #define USBC_CC_CTRL_VCONN_EN  BIT(1)
+#define USBC_CC_CTRL_TX_EN BIT(2)
 
+#define USBC_CC_SEL_CCSEL  (BIT(0) | BIT(1))
 #define USBC_STATUS1_DET_ONGOING   BIT(6)
 #define USBC_STATUS1_RSLT(r)   (r & 0xf)
 #define USBC_RSLT_NOTHING  0
@@ -79,11 +94,44 @@
 USBC_IRQ2_RX_HR | USBC_IRQ2_RX_CR | \
 USBC_IRQ2_TX_SUCCESS | USBC_IRQ2_TX_FAIL)
 
+#define USBC_PD_CFG1_ID_FILL   BIT(7)
+
+#define USBC_PD_CFG2_SOP_RXBIT(0)
+
+#define USBC_PD_CFG3_SR_SOP2   (BIT(7) | BIT(6))
+#define USBC_PD_CFG3_SR_SOP1   (BIT(5) | BIT(4))
+#define USBC_PD_CFG3_SR_SOP0   (BIT(3) | BIT(2))
+#define USBC_PD_CFG3_DATAROLE  BIT(1)
+#define USBC_PD_CFG3_PWRROLE   BIT(0)
+
+#define USBC_TX_CMD_TXBUF_RDY  BIT(0)
+#define USBC_TX_CMD_TX_START   BIT(1)
+#define USBC_TX_CMD_TXBUF_CMD(r)   ((r >> 5) & 0x7)
+
+#define USBC_TX_INFO_TX_SOP(BIT(0) | BIT(1) | BIT(2))
+#define USBC_TX_INFO_TX_RETRIES(BIT(3) | BIT(4) | BIT(5))
+
+#define USBC_RX_STATUS_RX_DATA BIT(7)
+#define USBC_RX_STATUS_RX_OVERRUN  BIT(6)
+#define USBC_RX_STATUS_RX_CLEARBIT(0)
+
+#define USBC_PD_STATUS_RX_RSLT(r)  ((r >> 3) & 0x7)
+#define USBC_PD_STATUS_TX_RSLT(r)  (r & 0x7)
+
+#define USBC_RX_INFO_RXBYTES(r)((r >> 3) & 0x1f)
+#define USBC_RX_INFO_RX_SOP(r) (r & 0x7)
+
+#define USBC_PD_RX_BUF_LEN 30
+#define USBC_PD_TX_BUF_LEN 30
+
 struct wcove_typec {
+   int pd_port_num;
struct mutex lock; /* device lock */
struct device *dev;
struct regmap *regmap;
struct typec_port *port;
+   struct pd_sink_port pd_port;
+   struct completion complete;
struct typec_capability cap;
struct typec_connection con;
struct typec_partner partner;
@@ -106,6 +154,50 @@ enum wcove_typec_role {
WCOVE_ROLE_DEVICE,
 };
 
+static struct sink_ps profiles[] = {
+
+   {
+   .ps_type = PS_TYPE_FIXED,
+   .ps_fixed = {
+   .voltage_fixed  = 100,  /* 5V/50mV = 100 */
+   .current_default = 90,  /* 900mA/10mA = 90 */
+   .current_max= 90,   /* 900mA/10mA = 90 */
+   },
+
+   },
+
+   {
+   .ps_type = PS_TYPE_FIXED,
+   .ps_fixed = {
+   .voltage_fixed  = 100,
+   .current_default = 300,
+   .current_max= 300,
+   },
+   },
+
+   {
+   .ps_type = PS_TYPE_FIXED,
+   .ps_fixed = {
+   .voltage_fixed  = 240,
+   .current_default = 300,
+

[PATCH 2/2] usb: typec: add PD sink port support for Intel Whiskey Cove PMIC Typc-C PHY driver

2016-07-14 Thread Bin Gao
From: Chandra Sekhar Anagani 

This adds PD sink port support for the USB Type-C PHY on Intel WhiskeyCove
PMIC which is available on some of the Intel Broxton SoC based platforms.

This patch depends on these two patches:
https://lkml.org/lkml/2016/6/29/349
https://lkml.org/lkml/2016/6/29/350

Signed-off-by: Chandra Sekhar Anagani 
---
 drivers/usb/typec/typec_wcove.c | 289 
 1 file changed, 263 insertions(+), 26 deletions(-)

diff --git a/drivers/usb/typec/typec_wcove.c b/drivers/usb/typec/typec_wcove.c
index c7c2d28..a4250ba 100644
--- a/drivers/usb/typec/typec_wcove.c
+++ b/drivers/usb/typec/typec_wcove.c
@@ -3,6 +3,7 @@
  *
  * Copyright (C) 2016 Intel Corporation
  * Author: Heikki Krogerus 
+ * Author: Chandra Sekhar Anagani 
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License version 2 as
@@ -10,9 +11,11 @@
  */
 
 #include 
+#include 
 #include 
 #include 
 #include 
+#include 
 #include 
 #include 
 
@@ -25,6 +28,7 @@
 #define USBC_CONTROL3  0x7003
 #define USBC_CC1_CTRL  0x7004
 #define USBC_CC2_CTRL  0x7005
+#define USBC_CC_SEL0x7006
 #define USBC_STATUS1   0x7007
 #define USBC_STATUS2   0x7008
 #define USBC_STATUS3   0x7009
@@ -32,7 +36,16 @@
 #define USBC_IRQ2  0x7016
 #define USBC_IRQMASK1  0x7017
 #define USBC_IRQMASK2  0x7018
-
+#define USBC_PD_CFG1   0x7019
+#define USBC_PD_CFG2   0x701a
+#define USBC_PD_CFG3   0x701b
+#define USBC_PD_STATUS 0x701c
+#define USBC_RX_STATUS 0x701d
+#define USBC_RX_INFO   0x701e
+#define USBC_TX_CMD0x701f
+#define USBC_TX_INFO   0x7020
+#define USBC_RX_DATA_START 0x7028
+#define USBC_TX_DATA_START 0x7047
 /* Register bits */
 
 #define USBC_CONTROL1_MODE_DRP(r)  ((r & ~0x7) | 4)
@@ -44,7 +57,9 @@
 #define USBC_CONTROL3_PD_DIS   BIT(1)
 
 #define USBC_CC_CTRL_VCONN_EN  BIT(1)
+#define USBC_CC_CTRL_TX_EN BIT(2)
 
+#define USBC_CC_SEL_CCSEL  (BIT(0) | BIT(1))
 #define USBC_STATUS1_DET_ONGOING   BIT(6)
 #define USBC_STATUS1_RSLT(r)   (r & 0xf)
 #define USBC_RSLT_NOTHING  0
@@ -79,11 +94,44 @@
 USBC_IRQ2_RX_HR | USBC_IRQ2_RX_CR | \
 USBC_IRQ2_TX_SUCCESS | USBC_IRQ2_TX_FAIL)
 
+#define USBC_PD_CFG1_ID_FILL   BIT(7)
+
+#define USBC_PD_CFG2_SOP_RXBIT(0)
+
+#define USBC_PD_CFG3_SR_SOP2   (BIT(7) | BIT(6))
+#define USBC_PD_CFG3_SR_SOP1   (BIT(5) | BIT(4))
+#define USBC_PD_CFG3_SR_SOP0   (BIT(3) | BIT(2))
+#define USBC_PD_CFG3_DATAROLE  BIT(1)
+#define USBC_PD_CFG3_PWRROLE   BIT(0)
+
+#define USBC_TX_CMD_TXBUF_RDY  BIT(0)
+#define USBC_TX_CMD_TX_START   BIT(1)
+#define USBC_TX_CMD_TXBUF_CMD(r)   ((r >> 5) & 0x7)
+
+#define USBC_TX_INFO_TX_SOP(BIT(0) | BIT(1) | BIT(2))
+#define USBC_TX_INFO_TX_RETRIES(BIT(3) | BIT(4) | BIT(5))
+
+#define USBC_RX_STATUS_RX_DATA BIT(7)
+#define USBC_RX_STATUS_RX_OVERRUN  BIT(6)
+#define USBC_RX_STATUS_RX_CLEARBIT(0)
+
+#define USBC_PD_STATUS_RX_RSLT(r)  ((r >> 3) & 0x7)
+#define USBC_PD_STATUS_TX_RSLT(r)  (r & 0x7)
+
+#define USBC_RX_INFO_RXBYTES(r)((r >> 3) & 0x1f)
+#define USBC_RX_INFO_RX_SOP(r) (r & 0x7)
+
+#define USBC_PD_RX_BUF_LEN 30
+#define USBC_PD_TX_BUF_LEN 30
+
 struct wcove_typec {
+   int pd_port_num;
struct mutex lock; /* device lock */
struct device *dev;
struct regmap *regmap;
struct typec_port *port;
+   struct pd_sink_port pd_port;
+   struct completion complete;
struct typec_capability cap;
struct typec_connection con;
struct typec_partner partner;
@@ -106,6 +154,50 @@ enum wcove_typec_role {
WCOVE_ROLE_DEVICE,
 };
 
+static struct sink_ps profiles[] = {
+
+   {
+   .ps_type = PS_TYPE_FIXED,
+   .ps_fixed = {
+   .voltage_fixed  = 100,  /* 5V/50mV = 100 */
+   .current_default = 90,  /* 900mA/10mA = 90 */
+   .current_max= 90,   /* 900mA/10mA = 90 */
+   },
+
+   },
+
+   {
+   .ps_type = PS_TYPE_FIXED,
+   .ps_fixed = {
+   .voltage_fixed  = 100,
+   .current_default = 300,
+   .current_max= 300,
+   },
+   },
+
+   {
+   .ps_type = PS_TYPE_FIXED,
+   .ps_fixed = {
+   .voltage_fixed  = 240,
+   .current_default = 300,
+   .current_max= 300,
+   },
+   },
+
+};
+
+static struct pd_sink_profile profile = {
+   .hw_goodcrc_tx 

[PATCH 1/2] usb: typec: Add USB Power Delivery sink port support

2016-07-14 Thread Bin Gao
This patch implements a simple USB Power Delivery sink port state machine.
It assumes the hardware only handles PD packet transmitting and receiving
over the CC line of the USB Type-C connector. The state transition is
completely controlled by software. This patch only implement the sink port
function and it doesn't support source port and port swap yet.

This patch depends on these two patches:
https://lkml.org/lkml/2016/6/29/349
https://lkml.org/lkml/2016/6/29/350

Signed-off-by: Bin Gao <bin@intel.com>
---
 drivers/usb/typec/Kconfig  |  13 +
 drivers/usb/typec/Makefile |   1 +
 drivers/usb/typec/pd_sink.c| 967 +
 include/linux/usb/pd_message.h | 371 
 include/linux/usb/pd_sink.h| 286 
 5 files changed, 1638 insertions(+)
 create mode 100644 drivers/usb/typec/pd_sink.c
 create mode 100644 include/linux/usb/pd_message.h
 create mode 100644 include/linux/usb/pd_sink.h

diff --git a/drivers/usb/typec/Kconfig b/drivers/usb/typec/Kconfig
index 7a345a4..a04a900 100644
--- a/drivers/usb/typec/Kconfig
+++ b/drivers/usb/typec/Kconfig
@@ -4,12 +4,25 @@ menu "USB PD and Type-C drivers"
 config TYPEC
tristate
 
+config USB_PD_SINK
+   bool "USB Power Delivery Sink Port State Machine Driver"
+   select TYPEC
+   help
+ Enable this to support USB PD(Power Delivery) Sink port.
+ This driver implements a simple USB PD sink state machine.
+ The underlying TypeC phy driver is responsible for cable
+ plug/unplug event, port orientation detection, transmitting
+ and receiving PD messages. This driver only process messages
+ received by the TypeC phy driver and maintain the sink port's
+ state machine.
+
 config TYPEC_WCOVE
tristate "Intel WhiskeyCove PMIC USB Type-C PHY driver"
depends on ACPI
depends on INTEL_SOC_PMIC
depends on INTEL_PMC_IPC
select TYPEC
+   select USB_PD_SINK
help
  This driver adds support for USB Type-C detection on Intel Broxton
  platforms that have Intel Whiskey Cove PMIC. The driver can detect the
diff --git a/drivers/usb/typec/Makefile b/drivers/usb/typec/Makefile
index b9cb862..a62eb57 100644
--- a/drivers/usb/typec/Makefile
+++ b/drivers/usb/typec/Makefile
@@ -1,2 +1,3 @@
 obj-$(CONFIG_TYPEC)+= typec.o
 obj-$(CONFIG_TYPEC_WCOVE)  += typec_wcove.o
+obj-$(CONFIG_USB_PD_SINK)  += pd_sink.o
diff --git a/drivers/usb/typec/pd_sink.c b/drivers/usb/typec/pd_sink.c
new file mode 100644
index 000..374bdef
--- /dev/null
+++ b/drivers/usb/typec/pd_sink.c
@@ -0,0 +1,967 @@
+/*
+ * pd_sink.c - USB PD (Power Delivery) sink port state machine driver
+ *
+ * This driver implements a simple USB PD sink port state machine.
+ * It assumes the upper layer, i.e. the user of this driver, handles
+ * the PD message receiving and transmitting. The upper layer receives
+ * PD messages from the Source, queues them to us, and when processing
+ * the received message we'll call upper layer's transmitting function
+ * to send PD messages to the source.
+ * The sink port state machine is maintained in this driver but we also
+ * broadcast some important PD messages to upper layer as events.
+ *
+ * Copyright (C) 2016 Intel Corporation
+ *
+ * Author: Bin Gao <bin@intel.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ */
+
+#include 
+#include 
+#include 
+
+#define MAKE_HEADER(port, header, msg, objs) \
+do { \
+   header->type = msg; \
+   header->data_role = PD_DATA_ROLE_UFP; \
+   header->revision = port->pd_rev; \
+   header->power_role = PD_POWER_ROLE_SINK; \
+   header->id = roll_msg_id(port); \
+   header->nr_objs = objs; \
+   header->extended = PD_MSG_NOT_EXTENDED; \
+} while (0)
+
+static struct pd_sink_port *sink_ports[MAX_NR_SINK_PORTS];
+static int nr_ports;
+
+BLOCKING_NOTIFIER_HEAD(pd_sink_notifier_list);
+
+static char *state_strings[] = {
+   "WAIT_FOR_SOURCE_CAPABILITY",
+   "REQUEST_SENT",
+   "ACCEPT_RECEIVED",
+   "POWER_SUPPLY_READY",
+};
+
+/* Control messages */
+static char *cmsg_strings[] = {
+   "GOODCRC",  /* 1 */
+   "GOTOMIN",  /* 2 */
+   "ACCEPT",   /* 3 */
+   "REJECT",   /* 4 */
+   "PING", /* 5 */
+   "PS_RDY",   /* 6 */
+   "GET_SRC_CAP",  /* 7 */
+   "GET_SINK_CAP", /* 8 */
+   "DR_SWAP",

[PATCH 1/2] usb: typec: Add USB Power Delivery sink port support

2016-07-14 Thread Bin Gao
This patch implements a simple USB Power Delivery sink port state machine.
It assumes the hardware only handles PD packet transmitting and receiving
over the CC line of the USB Type-C connector. The state transition is
completely controlled by software. This patch only implement the sink port
function and it doesn't support source port and port swap yet.

This patch depends on these two patches:
https://lkml.org/lkml/2016/6/29/349
https://lkml.org/lkml/2016/6/29/350

Signed-off-by: Bin Gao 
---
 drivers/usb/typec/Kconfig  |  13 +
 drivers/usb/typec/Makefile |   1 +
 drivers/usb/typec/pd_sink.c| 967 +
 include/linux/usb/pd_message.h | 371 
 include/linux/usb/pd_sink.h| 286 
 5 files changed, 1638 insertions(+)
 create mode 100644 drivers/usb/typec/pd_sink.c
 create mode 100644 include/linux/usb/pd_message.h
 create mode 100644 include/linux/usb/pd_sink.h

diff --git a/drivers/usb/typec/Kconfig b/drivers/usb/typec/Kconfig
index 7a345a4..a04a900 100644
--- a/drivers/usb/typec/Kconfig
+++ b/drivers/usb/typec/Kconfig
@@ -4,12 +4,25 @@ menu "USB PD and Type-C drivers"
 config TYPEC
tristate
 
+config USB_PD_SINK
+   bool "USB Power Delivery Sink Port State Machine Driver"
+   select TYPEC
+   help
+ Enable this to support USB PD(Power Delivery) Sink port.
+ This driver implements a simple USB PD sink state machine.
+ The underlying TypeC phy driver is responsible for cable
+ plug/unplug event, port orientation detection, transmitting
+ and receiving PD messages. This driver only process messages
+ received by the TypeC phy driver and maintain the sink port's
+ state machine.
+
 config TYPEC_WCOVE
tristate "Intel WhiskeyCove PMIC USB Type-C PHY driver"
depends on ACPI
depends on INTEL_SOC_PMIC
depends on INTEL_PMC_IPC
select TYPEC
+   select USB_PD_SINK
help
  This driver adds support for USB Type-C detection on Intel Broxton
  platforms that have Intel Whiskey Cove PMIC. The driver can detect the
diff --git a/drivers/usb/typec/Makefile b/drivers/usb/typec/Makefile
index b9cb862..a62eb57 100644
--- a/drivers/usb/typec/Makefile
+++ b/drivers/usb/typec/Makefile
@@ -1,2 +1,3 @@
 obj-$(CONFIG_TYPEC)+= typec.o
 obj-$(CONFIG_TYPEC_WCOVE)  += typec_wcove.o
+obj-$(CONFIG_USB_PD_SINK)  += pd_sink.o
diff --git a/drivers/usb/typec/pd_sink.c b/drivers/usb/typec/pd_sink.c
new file mode 100644
index 000..374bdef
--- /dev/null
+++ b/drivers/usb/typec/pd_sink.c
@@ -0,0 +1,967 @@
+/*
+ * pd_sink.c - USB PD (Power Delivery) sink port state machine driver
+ *
+ * This driver implements a simple USB PD sink port state machine.
+ * It assumes the upper layer, i.e. the user of this driver, handles
+ * the PD message receiving and transmitting. The upper layer receives
+ * PD messages from the Source, queues them to us, and when processing
+ * the received message we'll call upper layer's transmitting function
+ * to send PD messages to the source.
+ * The sink port state machine is maintained in this driver but we also
+ * broadcast some important PD messages to upper layer as events.
+ *
+ * Copyright (C) 2016 Intel Corporation
+ *
+ * Author: Bin Gao 
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ */
+
+#include 
+#include 
+#include 
+
+#define MAKE_HEADER(port, header, msg, objs) \
+do { \
+   header->type = msg; \
+   header->data_role = PD_DATA_ROLE_UFP; \
+   header->revision = port->pd_rev; \
+   header->power_role = PD_POWER_ROLE_SINK; \
+   header->id = roll_msg_id(port); \
+   header->nr_objs = objs; \
+   header->extended = PD_MSG_NOT_EXTENDED; \
+} while (0)
+
+static struct pd_sink_port *sink_ports[MAX_NR_SINK_PORTS];
+static int nr_ports;
+
+BLOCKING_NOTIFIER_HEAD(pd_sink_notifier_list);
+
+static char *state_strings[] = {
+   "WAIT_FOR_SOURCE_CAPABILITY",
+   "REQUEST_SENT",
+   "ACCEPT_RECEIVED",
+   "POWER_SUPPLY_READY",
+};
+
+/* Control messages */
+static char *cmsg_strings[] = {
+   "GOODCRC",  /* 1 */
+   "GOTOMIN",  /* 2 */
+   "ACCEPT",   /* 3 */
+   "REJECT",   /* 4 */
+   "PING", /* 5 */
+   "PS_RDY",   /* 6 */
+   "GET_SRC_CAP",  /* 7 */
+   "GET_SINK_CAP", /* 8 */
+   "DR_SWAP",  /* 9 */
+   

[PATCH 0/2] usb: typec: Introduce USB PD sink state machine driver and add PD sink support for Intel BXT PMIC Type-C phy

2016-07-14 Thread Bin Gao
This series introduce a USB PD(Power Delivery) sink port simple state
machine driver and adds USB PD sink port support for Intel BXT Whiskey
Cove PMIC Type-C phy driver.

This series depends on these two patches:
https://lkml.org/lkml/2016/6/29/349
https://lkml.org/lkml/2016/6/29/350

Bin Gao (1):
  usb: typec: Add USB Power Delivery sink port support

Chandra Sekhar Anagani (1):
  usb: typec: add PD sink port support for Intel Whiskey Cove PMIC USB
  Type-C PHY driver

 drivers/usb/typec/Kconfig   |  13 +
 drivers/usb/typec/Makefile  |   1 +
 drivers/usb/typec/pd_sink.c | 967 +
 include/linux/usb/pd_message.h  | 371 
 include/linux/usb/pd_sink.h | 286 
 drivers/usb/typec/typec_wcove.c | 289 
 6 files changed, 1901 insertions(+), 26 deletions(-)
 create mode 100644 drivers/usb/typec/pd_sink.c
 create mode 100644 include/linux/usb/pd_message.h
 create mode 100644 include/linux/usb/pd_sink.h
--
1.9.1


[PATCH 0/2] usb: typec: Introduce USB PD sink state machine driver and add PD sink support for Intel BXT PMIC Type-C phy

2016-07-14 Thread Bin Gao
This series introduce a USB PD(Power Delivery) sink port simple state
machine driver and adds USB PD sink port support for Intel BXT Whiskey
Cove PMIC Type-C phy driver.

This series depends on these two patches:
https://lkml.org/lkml/2016/6/29/349
https://lkml.org/lkml/2016/6/29/350

Bin Gao (1):
  usb: typec: Add USB Power Delivery sink port support

Chandra Sekhar Anagani (1):
  usb: typec: add PD sink port support for Intel Whiskey Cove PMIC USB
  Type-C PHY driver

 drivers/usb/typec/Kconfig   |  13 +
 drivers/usb/typec/Makefile  |   1 +
 drivers/usb/typec/pd_sink.c | 967 +
 include/linux/usb/pd_message.h  | 371 
 include/linux/usb/pd_sink.h | 286 
 drivers/usb/typec/typec_wcove.c | 289 
 6 files changed, 1901 insertions(+), 26 deletions(-)
 create mode 100644 drivers/usb/typec/pd_sink.c
 create mode 100644 include/linux/usb/pd_message.h
 create mode 100644 include/linux/usb/pd_sink.h
--
1.9.1


Re: [PATCH v4] gpio: add Intel WhiskeyCove GPIO driver

2016-07-11 Thread Bin Gao
On Wed, Jul 06, 2016 at 10:57:19AM +0200, Linus Walleij wrote:
> > +   gpiochip_irqchip_add(>chip, _irqchip, 0,
> > +handle_simple_irq, IRQ_TYPE_NONE);
> 
> Reexamine the use of handle_simple_irq() here. We have two kinds of
> irq hardware: those with one register for ACKing and reading the status
> of an IRQ, and those with two registers for it: one where you ACK the
> IRQ (so it can immediately re-trigger) and one to read the status of
> whether it happened. Sometimes different handling is needed for
> levek and edge IRQs even (c.f. gpio-pl061.c).
> 
> Only the hardware with just one register for both things should use
> handle_simple_irq(). This seems to be the case here but I want you
> to verify.

Yes, our case is handle_simple_irq(), not handle_edge_irq(), handle_level_irq() 
or
handle_fasteoi_irq(), etc. because there is no ACK mechanism inside the
GPIO controller's interrupt logic - all we need to do is read the status
register to get the status and write-to-clear the status register so that
a new interrupt can be triggered, i.e. there is only one register for both.

> 
> Yours,
> Linus Walleij


Re: [PATCH v4] gpio: add Intel WhiskeyCove GPIO driver

2016-07-11 Thread Bin Gao
On Wed, Jul 06, 2016 at 10:57:19AM +0200, Linus Walleij wrote:
> > +   gpiochip_irqchip_add(>chip, _irqchip, 0,
> > +handle_simple_irq, IRQ_TYPE_NONE);
> 
> Reexamine the use of handle_simple_irq() here. We have two kinds of
> irq hardware: those with one register for ACKing and reading the status
> of an IRQ, and those with two registers for it: one where you ACK the
> IRQ (so it can immediately re-trigger) and one to read the status of
> whether it happened. Sometimes different handling is needed for
> levek and edge IRQs even (c.f. gpio-pl061.c).
> 
> Only the hardware with just one register for both things should use
> handle_simple_irq(). This seems to be the case here but I want you
> to verify.

Yes, our case is handle_simple_irq(), not handle_edge_irq(), handle_level_irq() 
or
handle_fasteoi_irq(), etc. because there is no ACK mechanism inside the
GPIO controller's interrupt logic - all we need to do is read the status
register to get the status and write-to-clear the status register so that
a new interrupt can be triggered, i.e. there is only one register for both.

> 
> Yours,
> Linus Walleij


[PATCH v5] gpio: add Intel WhiskeyCove GPIO driver

2016-07-11 Thread Bin Gao
This patch introduces a separate GPIO driver for Intel WhiskeyCove PMIC.
This driver is based on gpio-crystalcove.c.

Signed-off-by: Ajay Thomas <ajay.thomas.david.rajamanic...@intel.com>
Signed-off-by: Bin Gao <bin@intel.com>
---
Changes in v5:
 - Revisited the interrupt handler code to iterate until all pending
   interrupts are handled. This change is to avoid missing interrupt
   when we're inside the interrupt handler.
 - Used regmap_bulk_read() to read address adjacent registers.
Changes in v4:
 - Converted CTLI_INTCNT_XX macros to less verbose ones INT_DETECT_XX.
 - Add comments about why there is no .pm for the driver.
 - Header files re-ordered.
 - Various coding style change to address Andy's comments.
Changes in v3:
 - Fixed the year in copyright line(2015-->2016).
 - Removed DRV_NAME macro.
 - Added kernel-doc for regmap_irq_chip of the wcove_gpio structure.
 - Line length fix.
Changes in v2:
 - Typo fix (Whsikey --> Whiskey).
 - Included linux/gpio/driver.h instead of linux/gpio.h
 - Implemented .set_single_ended().
 - Added GPIO register description.
 - Replaced container_of() with gpiochip_get_data().
 - Removed unnecessary "if (gpio > WCOVE_VGPIO_NUM" check.
 - Removed the device id table and added MODULE_ALIAS().
 drivers/gpio/Kconfig  |  13 ++
 drivers/gpio/Makefile |   1 +
 drivers/gpio/gpio-wcove.c | 444 ++
 3 files changed, 458 insertions(+)
 create mode 100644 drivers/gpio/gpio-wcove.c

diff --git a/drivers/gpio/Kconfig b/drivers/gpio/Kconfig
index 536112f..0f33982 100644
--- a/drivers/gpio/Kconfig
+++ b/drivers/gpio/Kconfig
@@ -806,6 +806,19 @@ config GPIO_CRYSTAL_COVE
  This driver can also be built as a module. If so, the module will be
  called gpio-crystalcove.
 
+config GPIO_WHISKEY_COVE
+   tristate "GPIO support for Whiskey Cove PMIC"
+   depends on INTEL_SOC_PMIC
+   select GPIOLIB_IRQCHIP
+   help
+ Support for GPIO pins on Whiskey Cove PMIC.
+
+ Say Yes if you have a Intel SoC based tablet with Whiskey Cove PMIC
+ inside.
+
+ This driver can also be built as a module. If so, the module will be
+ called gpio-wcove.
+
 config GPIO_CS5535
tristate "AMD CS5535/CS5536 GPIO support"
depends on MFD_CS5535
diff --git a/drivers/gpio/Makefile b/drivers/gpio/Makefile
index 991598e..fff6914 100644
--- a/drivers/gpio/Makefile
+++ b/drivers/gpio/Makefile
@@ -34,6 +34,7 @@ obj-$(CONFIG_GPIO_BT8XX)  += gpio-bt8xx.o
 obj-$(CONFIG_GPIO_CLPS711X)+= gpio-clps711x.o
 obj-$(CONFIG_GPIO_CS5535)  += gpio-cs5535.o
 obj-$(CONFIG_GPIO_CRYSTAL_COVE)+= gpio-crystalcove.o
+obj-$(CONFIG_GPIO_WHISKEY_COVE)+= gpio-wcove.o
 obj-$(CONFIG_GPIO_DA9052)  += gpio-da9052.o
 obj-$(CONFIG_GPIO_DA9055)  += gpio-da9055.o
 obj-$(CONFIG_GPIO_DAVINCI) += gpio-davinci.o
diff --git a/drivers/gpio/gpio-wcove.c b/drivers/gpio/gpio-wcove.c
new file mode 100644
index 000..e29e5a9
--- /dev/null
+++ b/drivers/gpio/gpio-wcove.c
@@ -0,0 +1,444 @@
+/*
+ * gpio-wcove.c - Intel Whiskey Cove GPIO Driver
+ *
+ * This driver is written based on gpio-crystalcove.c
+ *
+ * Copyright (C) 2016 Intel Corporation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License version
+ * 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+/*
+ * Whiskey Cove PMIC has 13 physical GPIO pins divided into 3 banks:
+ * Bank 0: Pin 0 - 6
+ * Bank 1: Pin 7 - 10
+ * Bank 2: Pin 11 -12
+ * Each pin has one output control register and one input control register.
+ */
+#define BANK0_NR_PINS  7
+#define BANK1_NR_PINS  4
+#define BANK2_NR_PINS  2
+#define WCOVE_GPIO_NUM (BANK0_NR_PINS + BANK1_NR_PINS + BANK2_NR_PINS)
+#define WCOVE_VGPIO_NUM94
+/* GPIO output control registers(one per pin): 0x4e44 - 0x4e50 */
+#define GPIO_OUT_CTRL_BASE 0x4e44
+/* GPIO input control registers(one per pin): 0x4e51 - 0x4e5d */
+#define GPIO_IN_CTRL_BASE  0x4e51
+
+/*
+ * GPIO interrupts are organized in two groups:
+ * Group 0: Bank 0 pins (Pin 0 - 6)
+ * Group 1: Bank 1 and Bank 2 pins (Pin 7 - 12)
+ * Each group has two registers(one bit per pin): status and mask.
+ */
+#define GROUP0_NR_IRQS 7
+#define GROUP1_NR_IRQS 6
+#define IRQ_MASK_BASE  0x4e19
+#define IRQ_STATUS_BASE0x4e0b
+#define UPDATE_IRQ_TYPEBIT(0)
+#define UPDATE_IRQ_MASKBIT(1)
+
+#define CTLI_INTCNT_DIS(0

[PATCH v5] gpio: add Intel WhiskeyCove GPIO driver

2016-07-11 Thread Bin Gao
This patch introduces a separate GPIO driver for Intel WhiskeyCove PMIC.
This driver is based on gpio-crystalcove.c.

Signed-off-by: Ajay Thomas 
Signed-off-by: Bin Gao 
---
Changes in v5:
 - Revisited the interrupt handler code to iterate until all pending
   interrupts are handled. This change is to avoid missing interrupt
   when we're inside the interrupt handler.
 - Used regmap_bulk_read() to read address adjacent registers.
Changes in v4:
 - Converted CTLI_INTCNT_XX macros to less verbose ones INT_DETECT_XX.
 - Add comments about why there is no .pm for the driver.
 - Header files re-ordered.
 - Various coding style change to address Andy's comments.
Changes in v3:
 - Fixed the year in copyright line(2015-->2016).
 - Removed DRV_NAME macro.
 - Added kernel-doc for regmap_irq_chip of the wcove_gpio structure.
 - Line length fix.
Changes in v2:
 - Typo fix (Whsikey --> Whiskey).
 - Included linux/gpio/driver.h instead of linux/gpio.h
 - Implemented .set_single_ended().
 - Added GPIO register description.
 - Replaced container_of() with gpiochip_get_data().
 - Removed unnecessary "if (gpio > WCOVE_VGPIO_NUM" check.
 - Removed the device id table and added MODULE_ALIAS().
 drivers/gpio/Kconfig  |  13 ++
 drivers/gpio/Makefile |   1 +
 drivers/gpio/gpio-wcove.c | 444 ++
 3 files changed, 458 insertions(+)
 create mode 100644 drivers/gpio/gpio-wcove.c

diff --git a/drivers/gpio/Kconfig b/drivers/gpio/Kconfig
index 536112f..0f33982 100644
--- a/drivers/gpio/Kconfig
+++ b/drivers/gpio/Kconfig
@@ -806,6 +806,19 @@ config GPIO_CRYSTAL_COVE
  This driver can also be built as a module. If so, the module will be
  called gpio-crystalcove.
 
+config GPIO_WHISKEY_COVE
+   tristate "GPIO support for Whiskey Cove PMIC"
+   depends on INTEL_SOC_PMIC
+   select GPIOLIB_IRQCHIP
+   help
+ Support for GPIO pins on Whiskey Cove PMIC.
+
+ Say Yes if you have a Intel SoC based tablet with Whiskey Cove PMIC
+ inside.
+
+ This driver can also be built as a module. If so, the module will be
+ called gpio-wcove.
+
 config GPIO_CS5535
tristate "AMD CS5535/CS5536 GPIO support"
depends on MFD_CS5535
diff --git a/drivers/gpio/Makefile b/drivers/gpio/Makefile
index 991598e..fff6914 100644
--- a/drivers/gpio/Makefile
+++ b/drivers/gpio/Makefile
@@ -34,6 +34,7 @@ obj-$(CONFIG_GPIO_BT8XX)  += gpio-bt8xx.o
 obj-$(CONFIG_GPIO_CLPS711X)+= gpio-clps711x.o
 obj-$(CONFIG_GPIO_CS5535)  += gpio-cs5535.o
 obj-$(CONFIG_GPIO_CRYSTAL_COVE)+= gpio-crystalcove.o
+obj-$(CONFIG_GPIO_WHISKEY_COVE)+= gpio-wcove.o
 obj-$(CONFIG_GPIO_DA9052)  += gpio-da9052.o
 obj-$(CONFIG_GPIO_DA9055)  += gpio-da9055.o
 obj-$(CONFIG_GPIO_DAVINCI) += gpio-davinci.o
diff --git a/drivers/gpio/gpio-wcove.c b/drivers/gpio/gpio-wcove.c
new file mode 100644
index 000..e29e5a9
--- /dev/null
+++ b/drivers/gpio/gpio-wcove.c
@@ -0,0 +1,444 @@
+/*
+ * gpio-wcove.c - Intel Whiskey Cove GPIO Driver
+ *
+ * This driver is written based on gpio-crystalcove.c
+ *
+ * Copyright (C) 2016 Intel Corporation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License version
+ * 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+/*
+ * Whiskey Cove PMIC has 13 physical GPIO pins divided into 3 banks:
+ * Bank 0: Pin 0 - 6
+ * Bank 1: Pin 7 - 10
+ * Bank 2: Pin 11 -12
+ * Each pin has one output control register and one input control register.
+ */
+#define BANK0_NR_PINS  7
+#define BANK1_NR_PINS  4
+#define BANK2_NR_PINS  2
+#define WCOVE_GPIO_NUM (BANK0_NR_PINS + BANK1_NR_PINS + BANK2_NR_PINS)
+#define WCOVE_VGPIO_NUM94
+/* GPIO output control registers(one per pin): 0x4e44 - 0x4e50 */
+#define GPIO_OUT_CTRL_BASE 0x4e44
+/* GPIO input control registers(one per pin): 0x4e51 - 0x4e5d */
+#define GPIO_IN_CTRL_BASE  0x4e51
+
+/*
+ * GPIO interrupts are organized in two groups:
+ * Group 0: Bank 0 pins (Pin 0 - 6)
+ * Group 1: Bank 1 and Bank 2 pins (Pin 7 - 12)
+ * Each group has two registers(one bit per pin): status and mask.
+ */
+#define GROUP0_NR_IRQS 7
+#define GROUP1_NR_IRQS 6
+#define IRQ_MASK_BASE  0x4e19
+#define IRQ_STATUS_BASE0x4e0b
+#define UPDATE_IRQ_TYPEBIT(0)
+#define UPDATE_IRQ_MASKBIT(1)
+
+#define CTLI_INTCNT_DIS(0)
+#define CTLI_INTCNT_NE (1 << 1)
+#define CTLI_INTCN

Re: [PATCH v4] gpio: add Intel WhiskeyCove GPIO driver

2016-07-06 Thread Bin Gao
On Wed, Jul 06, 2016 at 01:07:15PM +0300, Mika Westerberg wrote:
> On Wed, Jul 06, 2016 at 10:57:19AM +0200, Linus Walleij wrote:
> > On Tue, Jun 28, 2016 at 1:56 AM, Bin Gao <bin@linux.intel.com> wrote:
> > 
> > > This patch introduces a separate GPIO driver for Intel WhiskeyCove PMIC.
> > > This driver is based on gpio-crystalcove.c.
> > >
> > > Signed-off-by: Ajay Thomas <ajay.thomas.david.rajamanic...@intel.com>
> > > Signed-off-by: Bin Gao <bin@intel.com>
> > > ---
> > > Changes in v4:
> > >  - Converted CTLI_INTCNT_XX macros to less verbose ones INT_DETECT_XX.
> > >  - Add comments about why there is no .pm for the driver.
> > >  - Header files re-ordered.
> > >  - Various coding style change to address Andy's comments.
> > 
> > Mika can I have your ACK/review tag on this driver so I can merge it?
> > I prefer to have all Intel stuff bearing your seal of approval.
> 
> Thanks for your trust :)
> 
> I don't have much comments in addition to what you already pointed out.
> I'll just wait for the next revision and give my ack then.
> 
> > > +static irqreturn_t wcove_gpio_irq_handler(int irq, void *data)
> > > +{
> > > +   int pending;
> > > +   unsigned int p0, p1, virq, gpio;
> > > +   struct wcove_gpio *wg = data;
> 
> Bin,
> 
> Since you are going to make another iteration, please arrange the
> declarations like:
> 
>   unsigned int p0, p1, virq, gpio;
>   struct wcove_gpio *wg = data;
>   int pending;

Yes, will do. Thanks.

-Bin


Re: [PATCH v4] gpio: add Intel WhiskeyCove GPIO driver

2016-07-06 Thread Bin Gao
On Wed, Jul 06, 2016 at 01:07:15PM +0300, Mika Westerberg wrote:
> On Wed, Jul 06, 2016 at 10:57:19AM +0200, Linus Walleij wrote:
> > On Tue, Jun 28, 2016 at 1:56 AM, Bin Gao  wrote:
> > 
> > > This patch introduces a separate GPIO driver for Intel WhiskeyCove PMIC.
> > > This driver is based on gpio-crystalcove.c.
> > >
> > > Signed-off-by: Ajay Thomas 
> > > Signed-off-by: Bin Gao 
> > > ---
> > > Changes in v4:
> > >  - Converted CTLI_INTCNT_XX macros to less verbose ones INT_DETECT_XX.
> > >  - Add comments about why there is no .pm for the driver.
> > >  - Header files re-ordered.
> > >  - Various coding style change to address Andy's comments.
> > 
> > Mika can I have your ACK/review tag on this driver so I can merge it?
> > I prefer to have all Intel stuff bearing your seal of approval.
> 
> Thanks for your trust :)
> 
> I don't have much comments in addition to what you already pointed out.
> I'll just wait for the next revision and give my ack then.
> 
> > > +static irqreturn_t wcove_gpio_irq_handler(int irq, void *data)
> > > +{
> > > +   int pending;
> > > +   unsigned int p0, p1, virq, gpio;
> > > +   struct wcove_gpio *wg = data;
> 
> Bin,
> 
> Since you are going to make another iteration, please arrange the
> declarations like:
> 
>   unsigned int p0, p1, virq, gpio;
>   struct wcove_gpio *wg = data;
>   int pending;

Yes, will do. Thanks.

-Bin


Re: [PATCH v4] gpio: add Intel WhiskeyCove GPIO driver

2016-07-06 Thread Bin Gao
On Wed, Jul 06, 2016 at 10:57:19AM +0200, Linus Walleij wrote:
> > +static irqreturn_t wcove_gpio_irq_handler(int irq, void *data)
> > +{
> > +   int pending;
> > +   unsigned int p0, p1, virq, gpio;
> > +   struct wcove_gpio *wg = data;
> > +
> > +   if (regmap_read(wg->regmap, IRQ_STATUS_OFFSET + 0, ) ||
> > +   regmap_read(wg->regmap, IRQ_STATUS_OFFSET + 1, )) {
> 
> Why can't you use regmap_bulk_read() here?

Will fix this in v5.

> 
> > +   dev_err(wg->chip.parent, "%s(): regmap_read() failed.\n",
> > +   __func__);
> > +   return IRQ_NONE;
> > +   }
> > +
> > +   pending = p0 | (p1 << 8);
> > +
> > +   for (gpio = 0; gpio < WCOVE_GPIO_NUM; gpio++) {
> > +   if (pending & BIT(gpio)) {
> > +   virq = irq_find_mapping(wg->chip.irqdomain, gpio);
> > +   handle_nested_irq(virq);
> > +   }
> > +   }
> > +
> > +   regmap_write(wg->regmap, IRQ_STATUS_OFFSET + 0, p0);
> > +   regmap_write(wg->regmap, IRQ_STATUS_OFFSET + 1, p1);
> 
> Use regmap_bulk_write()?

Will fix this in v5.

> 
> Also you're ignoring the return error code. Check it and dev_err() if
> it fails.

Yes, will fix.

> 
> This loop seems like it could miss interrupts happening while
> processing. Especially edge interrupts, and thatr will lead to serious
> bugs later.
> 
> Please consider the following construction:
> 
> 1. read status register
> 2. Any IRQs active?
>   2.1 No IRQs active: if this is the FIRST iteration, exit with IRQ_NONE
>   2.2 No IRQs active If this the second iteration or later, exit with
> IRQ_HANDLED
>   2.3 IRQs active, continue
> 2. Find first active IRQ
> 3. Handle first active IRQ
> 4. ACK the first active IRQ by writing the status register
> 5. Reiterate from 1
> 
> This way, if two IRQs happen at the same time, or if a new IRQ appears
> while you're inside the interrupt handler, it gets served.

I agree. Writing to status register should be done bit by bit, instead of
one write for all bits. Will fix this in v5.

> 
> > +static void wcove_gpio_dbg_show(struct seq_file *s, struct gpio_chip *chip)
> > +{
> > +   struct wcove_gpio *wg = gpiochip_get_data(chip);
> > +   int gpio, offset, group;
> > +   unsigned int ctlo, ctli, irq_mask, irq_status;
> > +
> > +   for (gpio = 0; gpio < WCOVE_GPIO_NUM; gpio++) {
> > +   group = gpio < GROUP0_NR_IRQS ? 0 : 1;
> > +   regmap_read(wg->regmap, to_reg(gpio, CTRL_OUT), );
> > +   regmap_read(wg->regmap, to_reg(gpio, CTRL_IN), );
> > +   regmap_read(wg->regmap, IRQ_MASK_OFFSET + group, _mask);
> > +   regmap_read(wg->regmap, IRQ_STATUS_OFFSET + group, 
> > _status);
> 
> Ignoring error codes. Fix this.

Will Fix in v5.

> 
> > +   gpiochip_irqchip_add(>chip, _irqchip, 0,
> > +handle_simple_irq, IRQ_TYPE_NONE);
> 
> Reexamine the use of handle_simple_irq() here. We have two kinds of
> irq hardware: those with one register for ACKing and reading the status
> of an IRQ, and those with two registers for it: one where you ACK the
> IRQ (so it can immediately re-trigger) and one to read the status of
> whether it happened. Sometimes different handling is needed for
> levek and edge IRQs even (c.f. gpio-pl061.c).
> 
> Only the hardware with just one register for both things should use
> handle_simple_irq(). This seems to be the case here but I want you
> to verify.

I will check and fix if it's needed.

> 
> Yours,
> Linus Walleij

Thanks for your review.


Re: [PATCH v4] gpio: add Intel WhiskeyCove GPIO driver

2016-07-06 Thread Bin Gao
On Wed, Jul 06, 2016 at 10:57:19AM +0200, Linus Walleij wrote:
> > +static irqreturn_t wcove_gpio_irq_handler(int irq, void *data)
> > +{
> > +   int pending;
> > +   unsigned int p0, p1, virq, gpio;
> > +   struct wcove_gpio *wg = data;
> > +
> > +   if (regmap_read(wg->regmap, IRQ_STATUS_OFFSET + 0, ) ||
> > +   regmap_read(wg->regmap, IRQ_STATUS_OFFSET + 1, )) {
> 
> Why can't you use regmap_bulk_read() here?

Will fix this in v5.

> 
> > +   dev_err(wg->chip.parent, "%s(): regmap_read() failed.\n",
> > +   __func__);
> > +   return IRQ_NONE;
> > +   }
> > +
> > +   pending = p0 | (p1 << 8);
> > +
> > +   for (gpio = 0; gpio < WCOVE_GPIO_NUM; gpio++) {
> > +   if (pending & BIT(gpio)) {
> > +   virq = irq_find_mapping(wg->chip.irqdomain, gpio);
> > +   handle_nested_irq(virq);
> > +   }
> > +   }
> > +
> > +   regmap_write(wg->regmap, IRQ_STATUS_OFFSET + 0, p0);
> > +   regmap_write(wg->regmap, IRQ_STATUS_OFFSET + 1, p1);
> 
> Use regmap_bulk_write()?

Will fix this in v5.

> 
> Also you're ignoring the return error code. Check it and dev_err() if
> it fails.

Yes, will fix.

> 
> This loop seems like it could miss interrupts happening while
> processing. Especially edge interrupts, and thatr will lead to serious
> bugs later.
> 
> Please consider the following construction:
> 
> 1. read status register
> 2. Any IRQs active?
>   2.1 No IRQs active: if this is the FIRST iteration, exit with IRQ_NONE
>   2.2 No IRQs active If this the second iteration or later, exit with
> IRQ_HANDLED
>   2.3 IRQs active, continue
> 2. Find first active IRQ
> 3. Handle first active IRQ
> 4. ACK the first active IRQ by writing the status register
> 5. Reiterate from 1
> 
> This way, if two IRQs happen at the same time, or if a new IRQ appears
> while you're inside the interrupt handler, it gets served.

I agree. Writing to status register should be done bit by bit, instead of
one write for all bits. Will fix this in v5.

> 
> > +static void wcove_gpio_dbg_show(struct seq_file *s, struct gpio_chip *chip)
> > +{
> > +   struct wcove_gpio *wg = gpiochip_get_data(chip);
> > +   int gpio, offset, group;
> > +   unsigned int ctlo, ctli, irq_mask, irq_status;
> > +
> > +   for (gpio = 0; gpio < WCOVE_GPIO_NUM; gpio++) {
> > +   group = gpio < GROUP0_NR_IRQS ? 0 : 1;
> > +   regmap_read(wg->regmap, to_reg(gpio, CTRL_OUT), );
> > +   regmap_read(wg->regmap, to_reg(gpio, CTRL_IN), );
> > +   regmap_read(wg->regmap, IRQ_MASK_OFFSET + group, _mask);
> > +   regmap_read(wg->regmap, IRQ_STATUS_OFFSET + group, 
> > _status);
> 
> Ignoring error codes. Fix this.

Will Fix in v5.

> 
> > +   gpiochip_irqchip_add(>chip, _irqchip, 0,
> > +handle_simple_irq, IRQ_TYPE_NONE);
> 
> Reexamine the use of handle_simple_irq() here. We have two kinds of
> irq hardware: those with one register for ACKing and reading the status
> of an IRQ, and those with two registers for it: one where you ACK the
> IRQ (so it can immediately re-trigger) and one to read the status of
> whether it happened. Sometimes different handling is needed for
> levek and edge IRQs even (c.f. gpio-pl061.c).
> 
> Only the hardware with just one register for both things should use
> handle_simple_irq(). This seems to be the case here but I want you
> to verify.

I will check and fix if it's needed.

> 
> Yours,
> Linus Walleij

Thanks for your review.


[PATCH v2] thermal: add Intel BXT WhiskeyCove PMIC thermal driver

2016-06-28 Thread Bin Gao
This change add support for pmic thermal driver which is intended to
handle the alert interrupts triggered upon thermal trip point cross
and notify the thermal framework appropriately with the zone, temp,
crossed trip and event details.

Signed-off-by: Yegnesh S Iyer <yegnesh.s.i...@intel.com>
Signed-off-by: Bin Gao <bin@intel.com>
---
Changes in v2:
 - Removed unnecessary request_threaded_irq() - we should be only
   using devm_request_threaded_irq() with virq
 drivers/thermal/Kconfig  |  10 +++
 drivers/thermal/Makefile |   1 +
 drivers/thermal/intel_pmic_thermal.c | 155 +++
 include/linux/mfd/intel_soc_pmic.h   |  21 +
 4 files changed, 187 insertions(+)
 create mode 100644 drivers/thermal/intel_pmic_thermal.c

diff --git a/drivers/thermal/Kconfig b/drivers/thermal/Kconfig
index 2d702ca..9065ba7 100644
--- a/drivers/thermal/Kconfig
+++ b/drivers/thermal/Kconfig
@@ -332,6 +332,16 @@ menu "ACPI INT340X thermal drivers"
 source drivers/thermal/int340x_thermal/Kconfig
 endmenu
 
+config INTEL_PMIC_THERMAL
+   tristate "Intel PMIC thermal driver"
+   depends on X86 && INTEL_SOC_PMIC && REGMAP
+   help
+ Select this driver for Intel PMIC with ADC channels monitoring system
+ temperature measurements and alerts.
+ This driver is used for monitoring the ADC channels of PMIC and 
handles
+ the alert trip point interrupts and notifies the thermal framework 
with
+ the trip point and temperature details of the zone.
+
 config INTEL_PCH_THERMAL
tristate "Intel PCH Thermal Reporting Driver"
depends on X86 && PCI
diff --git a/drivers/thermal/Makefile b/drivers/thermal/Makefile
index 10b07c1..159efcc 100644
--- a/drivers/thermal/Makefile
+++ b/drivers/thermal/Makefile
@@ -45,6 +45,7 @@ obj-$(CONFIG_INTEL_SOC_DTS_THERMAL)   += 
intel_soc_dts_thermal.o
 obj-$(CONFIG_INTEL_QUARK_DTS_THERMAL)  += intel_quark_dts_thermal.o
 obj-$(CONFIG_TI_SOC_THERMAL)   += ti-soc-thermal/
 obj-$(CONFIG_INT340X_THERMAL)  += int340x_thermal/
+obj-$(CONFIG_INTEL_PMIC_THERMAL) += intel_pmic_thermal.o
 obj-$(CONFIG_INTEL_PCH_THERMAL)+= intel_pch_thermal.o
 obj-$(CONFIG_ST_THERMAL)   += st/
 obj-$(CONFIG_TEGRA_SOCTHERM)   += tegra/
diff --git a/drivers/thermal/intel_pmic_thermal.c 
b/drivers/thermal/intel_pmic_thermal.c
new file mode 100644
index 000..8c40a0a
--- /dev/null
+++ b/drivers/thermal/intel_pmic_thermal.c
@@ -0,0 +1,155 @@
+/*
+ * pmic_thermal.c - PMIC thermal driver
+ *
+ * Copyright (C) 2015 Intel Corporation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License version
+ * 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+static irqreturn_t pmic_thermal_irq_handler(int irq, void *data)
+{
+   struct platform_device *pdev = data;
+   struct pmic_thermal_data *td =
+   (struct pmic_thermal_data *)pdev->dev.platform_data;
+   struct intel_soc_pmic *pmic = dev_get_drvdata(pdev->dev.parent);
+   struct regmap *regmap = pmic->regmap;
+   struct thermal_zone_device *tzd;
+   int i, j, ret;
+   u16 reg, evt_stat_reg;
+   u8 reg_val, mask, irq_stat, trip;
+
+   /* Resolve thermal irqs */
+   for (i = 0; i < td->num_maps; i++) {
+   for (j = 0; j < td->maps[i].num_trips; j++) {
+   reg = td->maps[i].trip_config[j].irq_reg;
+   mask = td->maps[i].trip_config[j].irq_mask;
+   /*
+* Read the irq register to resolve whether the
+* interrupt was triggered for this sensor
+*/
+   if (regmap_read(regmap, reg, ))
+   return IRQ_HANDLED;
+
+   reg_val = (u8)ret;
+
+   irq_stat = ((u8)ret & mask);
+   if (irq_stat) {
+   /*
+* Read the status register to find out what
+* event occurred i.e a high or a low
+*/
+   evt_stat_reg =
+   td->maps[i].trip_config[j].evt_stat;
+   if (regmap_read(regmap, evt_stat_reg, ))
+   return IRQ_HANDLED;
+
+   trip = td-&

[PATCH v2] thermal: add Intel BXT WhiskeyCove PMIC thermal driver

2016-06-28 Thread Bin Gao
This change add support for pmic thermal driver which is intended to
handle the alert interrupts triggered upon thermal trip point cross
and notify the thermal framework appropriately with the zone, temp,
crossed trip and event details.

Signed-off-by: Yegnesh S Iyer 
Signed-off-by: Bin Gao 
---
Changes in v2:
 - Removed unnecessary request_threaded_irq() - we should be only
   using devm_request_threaded_irq() with virq
 drivers/thermal/Kconfig  |  10 +++
 drivers/thermal/Makefile |   1 +
 drivers/thermal/intel_pmic_thermal.c | 155 +++
 include/linux/mfd/intel_soc_pmic.h   |  21 +
 4 files changed, 187 insertions(+)
 create mode 100644 drivers/thermal/intel_pmic_thermal.c

diff --git a/drivers/thermal/Kconfig b/drivers/thermal/Kconfig
index 2d702ca..9065ba7 100644
--- a/drivers/thermal/Kconfig
+++ b/drivers/thermal/Kconfig
@@ -332,6 +332,16 @@ menu "ACPI INT340X thermal drivers"
 source drivers/thermal/int340x_thermal/Kconfig
 endmenu
 
+config INTEL_PMIC_THERMAL
+   tristate "Intel PMIC thermal driver"
+   depends on X86 && INTEL_SOC_PMIC && REGMAP
+   help
+ Select this driver for Intel PMIC with ADC channels monitoring system
+ temperature measurements and alerts.
+ This driver is used for monitoring the ADC channels of PMIC and 
handles
+ the alert trip point interrupts and notifies the thermal framework 
with
+ the trip point and temperature details of the zone.
+
 config INTEL_PCH_THERMAL
tristate "Intel PCH Thermal Reporting Driver"
depends on X86 && PCI
diff --git a/drivers/thermal/Makefile b/drivers/thermal/Makefile
index 10b07c1..159efcc 100644
--- a/drivers/thermal/Makefile
+++ b/drivers/thermal/Makefile
@@ -45,6 +45,7 @@ obj-$(CONFIG_INTEL_SOC_DTS_THERMAL)   += 
intel_soc_dts_thermal.o
 obj-$(CONFIG_INTEL_QUARK_DTS_THERMAL)  += intel_quark_dts_thermal.o
 obj-$(CONFIG_TI_SOC_THERMAL)   += ti-soc-thermal/
 obj-$(CONFIG_INT340X_THERMAL)  += int340x_thermal/
+obj-$(CONFIG_INTEL_PMIC_THERMAL) += intel_pmic_thermal.o
 obj-$(CONFIG_INTEL_PCH_THERMAL)+= intel_pch_thermal.o
 obj-$(CONFIG_ST_THERMAL)   += st/
 obj-$(CONFIG_TEGRA_SOCTHERM)   += tegra/
diff --git a/drivers/thermal/intel_pmic_thermal.c 
b/drivers/thermal/intel_pmic_thermal.c
new file mode 100644
index 000..8c40a0a
--- /dev/null
+++ b/drivers/thermal/intel_pmic_thermal.c
@@ -0,0 +1,155 @@
+/*
+ * pmic_thermal.c - PMIC thermal driver
+ *
+ * Copyright (C) 2015 Intel Corporation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License version
+ * 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+static irqreturn_t pmic_thermal_irq_handler(int irq, void *data)
+{
+   struct platform_device *pdev = data;
+   struct pmic_thermal_data *td =
+   (struct pmic_thermal_data *)pdev->dev.platform_data;
+   struct intel_soc_pmic *pmic = dev_get_drvdata(pdev->dev.parent);
+   struct regmap *regmap = pmic->regmap;
+   struct thermal_zone_device *tzd;
+   int i, j, ret;
+   u16 reg, evt_stat_reg;
+   u8 reg_val, mask, irq_stat, trip;
+
+   /* Resolve thermal irqs */
+   for (i = 0; i < td->num_maps; i++) {
+   for (j = 0; j < td->maps[i].num_trips; j++) {
+   reg = td->maps[i].trip_config[j].irq_reg;
+   mask = td->maps[i].trip_config[j].irq_mask;
+   /*
+* Read the irq register to resolve whether the
+* interrupt was triggered for this sensor
+*/
+   if (regmap_read(regmap, reg, ))
+   return IRQ_HANDLED;
+
+   reg_val = (u8)ret;
+
+   irq_stat = ((u8)ret & mask);
+   if (irq_stat) {
+   /*
+* Read the status register to find out what
+* event occurred i.e a high or a low
+*/
+   evt_stat_reg =
+   td->maps[i].trip_config[j].evt_stat;
+   if (regmap_read(regmap, evt_stat_reg, ))
+   return IRQ_HANDLED;
+
+   trip = td->maps[i].t

[PATCH] thermal: add Intel BXT WhiskeyCove PMIC thermal driver

2016-06-27 Thread Bin Gao
This patch adds Intel Whiskey Cove PMIC thermal driver which is intended
to handle the alert interrupts triggered upon thermal trip point cross
and notify the thermal framework appropriately with the zone, temp,
crossed trip and event details.

Signed-off-by: Yegnesh S Iyer <yegnesh.s.i...@intel.com>
Signed-off-by: Bin Gao <bin@intel.com>
---
 drivers/thermal/Kconfig  |  10 +++
 drivers/thermal/Makefile |   1 +
 drivers/thermal/intel_pmic_thermal.c | 158 +++
 include/linux/mfd/intel_soc_pmic.h   |  21 +
 4 files changed, 190 insertions(+)
 create mode 100644 drivers/thermal/intel_pmic_thermal.c

diff --git a/drivers/thermal/Kconfig b/drivers/thermal/Kconfig
index 2d702ca..9065ba7 100644
--- a/drivers/thermal/Kconfig
+++ b/drivers/thermal/Kconfig
@@ -332,6 +332,16 @@ menu "ACPI INT340X thermal drivers"
 source drivers/thermal/int340x_thermal/Kconfig
 endmenu
 
+config INTEL_PMIC_THERMAL
+   tristate "Intel PMIC thermal driver"
+   depends on X86 && INTEL_SOC_PMIC && REGMAP
+   help
+ Select this driver for Intel PMIC with ADC channels monitoring system
+ temperature measurements and alerts.
+ This driver is used for monitoring the ADC channels of PMIC and 
handles
+ the alert trip point interrupts and notifies the thermal framework 
with
+ the trip point and temperature details of the zone.
+
 config INTEL_PCH_THERMAL
tristate "Intel PCH Thermal Reporting Driver"
depends on X86 && PCI
diff --git a/drivers/thermal/Makefile b/drivers/thermal/Makefile
index 10b07c1..159efcc 100644
--- a/drivers/thermal/Makefile
+++ b/drivers/thermal/Makefile
@@ -45,6 +45,7 @@ obj-$(CONFIG_INTEL_SOC_DTS_THERMAL)   += 
intel_soc_dts_thermal.o
 obj-$(CONFIG_INTEL_QUARK_DTS_THERMAL)  += intel_quark_dts_thermal.o
 obj-$(CONFIG_TI_SOC_THERMAL)   += ti-soc-thermal/
 obj-$(CONFIG_INT340X_THERMAL)  += int340x_thermal/
+obj-$(CONFIG_INTEL_PMIC_THERMAL) += intel_pmic_thermal.o
 obj-$(CONFIG_INTEL_PCH_THERMAL)+= intel_pch_thermal.o
 obj-$(CONFIG_ST_THERMAL)   += st/
 obj-$(CONFIG_TEGRA_SOCTHERM)   += tegra/
diff --git a/drivers/thermal/intel_pmic_thermal.c 
b/drivers/thermal/intel_pmic_thermal.c
new file mode 100644
index 000..43881c7
--- /dev/null
+++ b/drivers/thermal/intel_pmic_thermal.c
@@ -0,0 +1,158 @@
+/*
+ * pmic_thermal.c - PMIC thermal driver
+ *
+ * Copyright (C) 2015 Intel Corporation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License version
+ * 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+static irqreturn_t pmic_thermal_irq_handler(int irq, void *data)
+{
+   struct platform_device *pdev = data;
+   struct pmic_thermal_data *td =
+   (struct pmic_thermal_data *)pdev->dev.platform_data;
+   struct intel_soc_pmic *pmic = dev_get_drvdata(pdev->dev.parent);
+   struct regmap *regmap = pmic->regmap;
+   struct thermal_zone_device *tzd;
+   int i, j, ret;
+   u16 reg, evt_stat_reg;
+   u8 reg_val, mask, irq_stat, trip;
+
+   /* Resolve thermal irqs */
+   for (i = 0; i < td->num_maps; i++) {
+   for (j = 0; j < td->maps[i].num_trips; j++) {
+   reg = td->maps[i].trip_config[j].irq_reg;
+   mask = td->maps[i].trip_config[j].irq_mask;
+   /*
+* Read the irq register to resolve whether the
+* interrupt was triggered for this sensor
+*/
+   if (regmap_read(regmap, reg, ))
+   return IRQ_HANDLED;
+
+   reg_val = (u8)ret;
+
+   irq_stat = ((u8)ret & mask);
+   if (irq_stat) {
+   /*
+* Read the status register to find out what
+* event occurred i.e a high or a low
+*/
+   evt_stat_reg =
+   td->maps[i].trip_config[j].evt_stat;
+   if (regmap_read(regmap, evt_stat_reg, ))
+   return IRQ_HANDLED;
+
+   trip = td->maps[i].trip_config[j].trip_num;
+   tzd = thermal_zone_get_zone_by_name(
+

[PATCH] thermal: add Intel BXT WhiskeyCove PMIC thermal driver

2016-06-27 Thread Bin Gao
This patch adds Intel Whiskey Cove PMIC thermal driver which is intended
to handle the alert interrupts triggered upon thermal trip point cross
and notify the thermal framework appropriately with the zone, temp,
crossed trip and event details.

Signed-off-by: Yegnesh S Iyer 
Signed-off-by: Bin Gao 
---
 drivers/thermal/Kconfig  |  10 +++
 drivers/thermal/Makefile |   1 +
 drivers/thermal/intel_pmic_thermal.c | 158 +++
 include/linux/mfd/intel_soc_pmic.h   |  21 +
 4 files changed, 190 insertions(+)
 create mode 100644 drivers/thermal/intel_pmic_thermal.c

diff --git a/drivers/thermal/Kconfig b/drivers/thermal/Kconfig
index 2d702ca..9065ba7 100644
--- a/drivers/thermal/Kconfig
+++ b/drivers/thermal/Kconfig
@@ -332,6 +332,16 @@ menu "ACPI INT340X thermal drivers"
 source drivers/thermal/int340x_thermal/Kconfig
 endmenu
 
+config INTEL_PMIC_THERMAL
+   tristate "Intel PMIC thermal driver"
+   depends on X86 && INTEL_SOC_PMIC && REGMAP
+   help
+ Select this driver for Intel PMIC with ADC channels monitoring system
+ temperature measurements and alerts.
+ This driver is used for monitoring the ADC channels of PMIC and 
handles
+ the alert trip point interrupts and notifies the thermal framework 
with
+ the trip point and temperature details of the zone.
+
 config INTEL_PCH_THERMAL
tristate "Intel PCH Thermal Reporting Driver"
depends on X86 && PCI
diff --git a/drivers/thermal/Makefile b/drivers/thermal/Makefile
index 10b07c1..159efcc 100644
--- a/drivers/thermal/Makefile
+++ b/drivers/thermal/Makefile
@@ -45,6 +45,7 @@ obj-$(CONFIG_INTEL_SOC_DTS_THERMAL)   += 
intel_soc_dts_thermal.o
 obj-$(CONFIG_INTEL_QUARK_DTS_THERMAL)  += intel_quark_dts_thermal.o
 obj-$(CONFIG_TI_SOC_THERMAL)   += ti-soc-thermal/
 obj-$(CONFIG_INT340X_THERMAL)  += int340x_thermal/
+obj-$(CONFIG_INTEL_PMIC_THERMAL) += intel_pmic_thermal.o
 obj-$(CONFIG_INTEL_PCH_THERMAL)+= intel_pch_thermal.o
 obj-$(CONFIG_ST_THERMAL)   += st/
 obj-$(CONFIG_TEGRA_SOCTHERM)   += tegra/
diff --git a/drivers/thermal/intel_pmic_thermal.c 
b/drivers/thermal/intel_pmic_thermal.c
new file mode 100644
index 000..43881c7
--- /dev/null
+++ b/drivers/thermal/intel_pmic_thermal.c
@@ -0,0 +1,158 @@
+/*
+ * pmic_thermal.c - PMIC thermal driver
+ *
+ * Copyright (C) 2015 Intel Corporation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License version
+ * 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+static irqreturn_t pmic_thermal_irq_handler(int irq, void *data)
+{
+   struct platform_device *pdev = data;
+   struct pmic_thermal_data *td =
+   (struct pmic_thermal_data *)pdev->dev.platform_data;
+   struct intel_soc_pmic *pmic = dev_get_drvdata(pdev->dev.parent);
+   struct regmap *regmap = pmic->regmap;
+   struct thermal_zone_device *tzd;
+   int i, j, ret;
+   u16 reg, evt_stat_reg;
+   u8 reg_val, mask, irq_stat, trip;
+
+   /* Resolve thermal irqs */
+   for (i = 0; i < td->num_maps; i++) {
+   for (j = 0; j < td->maps[i].num_trips; j++) {
+   reg = td->maps[i].trip_config[j].irq_reg;
+   mask = td->maps[i].trip_config[j].irq_mask;
+   /*
+* Read the irq register to resolve whether the
+* interrupt was triggered for this sensor
+*/
+   if (regmap_read(regmap, reg, ))
+   return IRQ_HANDLED;
+
+   reg_val = (u8)ret;
+
+   irq_stat = ((u8)ret & mask);
+   if (irq_stat) {
+   /*
+* Read the status register to find out what
+* event occurred i.e a high or a low
+*/
+   evt_stat_reg =
+   td->maps[i].trip_config[j].evt_stat;
+   if (regmap_read(regmap, evt_stat_reg, ))
+   return IRQ_HANDLED;
+
+   trip = td->maps[i].trip_config[j].trip_num;
+   tzd = thermal_zone_get_zone_by_name(
+

[PATCH v4] mfd: intel_soc_pmic_bxtwc: Add Intel BXT WhiskeyCove PMIC ADC thermal channel mapping and USB type-C resources

2016-06-27 Thread Bin Gao
This patch adds the mapping of PMIC ADC channel to thermal zone and
USB type-C resources. This mapping is used in the pmic thermal driver
to notify the thermal zone with the pmic adc channel alert interrupts.
This patch also adds three new data structures to
include/linux/mfd/intel_soc_pmic.h: struct trip_config_map{},
struct thermal_irq_map {} and struct pmic_thermal_data {} which are
required by changes we did on intel_soc_pmic_bxtwc.c.

Signed-off-by: Yegnesh S Iyer <yegnesh.s.i...@intel.com>
Signed-off-by: Rohit S Kenchanpura <rohit.s.kenchanp...@intel.com>
Signed-off-by: Bin Gao <bin@intel.com>
---
Changes in v4:
 - Extended existing regmap reg instead of defining a new one:
   REGMAP_IRQ_REG(BXTWC_CHGR0_IRQ, 5, 0x3f)
Changes in v3:
 - Added USB type-C resources.
Changes in v2:
 - Fixed subject line.
 - Combined two patches into one.
 drivers/mfd/intel_soc_pmic_bxtwc.c | 126 -
 include/linux/mfd/intel_soc_pmic.h |  21 +++
 2 files changed, 146 insertions(+), 1 deletion(-)

diff --git a/drivers/mfd/intel_soc_pmic_bxtwc.c 
b/drivers/mfd/intel_soc_pmic_bxtwc.c
index b942876..e69eb86 100644
--- a/drivers/mfd/intel_soc_pmic_bxtwc.c
+++ b/drivers/mfd/intel_soc_pmic_bxtwc.c
@@ -47,6 +47,8 @@
 #define BXTWC_MIRQLVL1 0x4E0E
 #define BXTWC_MPWRTNIRQ0x4E0F
 
+#define BXTWC_MIRQLVL1_MCHGR   BIT(5)
+
 #define BXTWC_MTHRM0IRQ0x4E12
 #define BXTWC_MTHRM1IRQ0x4E13
 #define BXTWC_MTHRM2IRQ0x4E14
@@ -58,6 +60,10 @@
 #define BXTWC_MGPIO1IRQ0x4E1A
 #define BXTWC_MCRITIRQ 0x4E1B
 
+#define BXTWC_STHRM0IRQ0x4F19
+#define BXTWC_STHRM1IRQ0x4F1A
+#define BXTWC_STHRM2IRQ0x4F1B
+
 /* Whiskey Cove PMIC share same ACPI ID between different platforms */
 #define BROXTON_PMIC_WC_HRV4
 
@@ -109,13 +115,116 @@ static const struct regmap_irq 
bxtwc_regmap_irqs_level2[] = {
REGMAP_IRQ_REG(BXTWC_THRM2_IRQ, 2, 0xff),
REGMAP_IRQ_REG(BXTWC_BCU_IRQ, 3, 0x1f),
REGMAP_IRQ_REG(BXTWC_ADC_IRQ, 4, 0xff),
-   REGMAP_IRQ_REG(BXTWC_CHGR0_IRQ, 5, 0x1f),
+   REGMAP_IRQ_REG(BXTWC_CHGR0_IRQ, 5, 0x3f),
REGMAP_IRQ_REG(BXTWC_CHGR1_IRQ, 6, 0x1f),
REGMAP_IRQ_REG(BXTWC_GPIO0_IRQ, 7, 0xff),
REGMAP_IRQ_REG(BXTWC_GPIO1_IRQ, 8, 0x3f),
REGMAP_IRQ_REG(BXTWC_CRIT_IRQ, 9, 0x03),
 };
 
+static struct trip_config_map str0_trip_config[] = {
+   {
+   .irq_reg = BXTWC_THRM0IRQ,
+   .irq_mask = 0x01,
+   .irq_en = BXTWC_MTHRM0IRQ,
+   .irq_en_mask = 0x01,
+   .evt_stat = BXTWC_STHRM0IRQ,
+   .evt_mask = 0x01,
+   .trip_num = 0
+   },
+   {
+   .irq_reg = BXTWC_THRM0IRQ,
+   .irq_mask = 0x10,
+   .irq_en = BXTWC_MTHRM0IRQ,
+   .irq_en_mask = 0x10,
+   .evt_stat = BXTWC_STHRM0IRQ,
+   .evt_mask = 0x10,
+   .trip_num = 1
+   }
+};
+
+static struct trip_config_map str1_trip_config[] = {
+   {
+   .irq_reg = BXTWC_THRM0IRQ,
+   .irq_mask = 0x02,
+   .irq_en = BXTWC_MTHRM0IRQ,
+   .irq_en_mask = 0x02,
+   .evt_stat = BXTWC_STHRM0IRQ,
+   .evt_mask = 0x02,
+   .trip_num = 0
+   },
+   {
+   .irq_reg = BXTWC_THRM0IRQ,
+   .irq_mask = 0x20,
+   .irq_en = BXTWC_MTHRM0IRQ,
+   .irq_en_mask = 0x20,
+   .evt_stat = BXTWC_STHRM0IRQ,
+   .evt_mask = 0x20,
+   .trip_num = 1
+   },
+};
+
+static struct trip_config_map str2_trip_config[] = {
+   {
+   .irq_reg = BXTWC_THRM0IRQ,
+   .irq_mask = 0x04,
+   .irq_en = BXTWC_MTHRM0IRQ,
+   .irq_en_mask = 0x04,
+   .evt_stat = BXTWC_STHRM0IRQ,
+   .evt_mask = 0x04,
+   .trip_num = 0
+   },
+   {
+   .irq_reg = BXTWC_THRM0IRQ,
+   .irq_mask = 0x40,
+   .irq_en = BXTWC_MTHRM0IRQ,
+   .irq_en_mask = 0x40,
+   .evt_stat = BXTWC_STHRM0IRQ,
+   .evt_mask = 0x40,
+   .trip_num = 1
+   },
+};
+
+static struct trip_config_map str3_trip_config[] = {
+   {
+   .irq_reg = BXTWC_THRM2IRQ,
+   .irq_mask = 0x10,
+   .irq_en = BXTWC_MTHRM2IRQ,
+   .irq_en_mask = 0x10,
+   .evt_stat = BXTWC_STHRM2IRQ,
+   .evt_mask = 0x10,
+   .trip_num = 0
+   },
+};
+
+static struct thermal_irq_map bxtwc_thermal_irq_map[] = {
+   {
+   .handle = "STR0",
+   .trip_config = str0_trip_config,
+   .num_trips = ARRAY_SIZE(str0_trip_config),
+   },
+   {
+   .handle = "STR1",
+

[PATCH v4] mfd: intel_soc_pmic_bxtwc: Add Intel BXT WhiskeyCove PMIC ADC thermal channel mapping and USB type-C resources

2016-06-27 Thread Bin Gao
This patch adds the mapping of PMIC ADC channel to thermal zone and
USB type-C resources. This mapping is used in the pmic thermal driver
to notify the thermal zone with the pmic adc channel alert interrupts.
This patch also adds three new data structures to
include/linux/mfd/intel_soc_pmic.h: struct trip_config_map{},
struct thermal_irq_map {} and struct pmic_thermal_data {} which are
required by changes we did on intel_soc_pmic_bxtwc.c.

Signed-off-by: Yegnesh S Iyer 
Signed-off-by: Rohit S Kenchanpura 
Signed-off-by: Bin Gao 
---
Changes in v4:
 - Extended existing regmap reg instead of defining a new one:
   REGMAP_IRQ_REG(BXTWC_CHGR0_IRQ, 5, 0x3f)
Changes in v3:
 - Added USB type-C resources.
Changes in v2:
 - Fixed subject line.
 - Combined two patches into one.
 drivers/mfd/intel_soc_pmic_bxtwc.c | 126 -
 include/linux/mfd/intel_soc_pmic.h |  21 +++
 2 files changed, 146 insertions(+), 1 deletion(-)

diff --git a/drivers/mfd/intel_soc_pmic_bxtwc.c 
b/drivers/mfd/intel_soc_pmic_bxtwc.c
index b942876..e69eb86 100644
--- a/drivers/mfd/intel_soc_pmic_bxtwc.c
+++ b/drivers/mfd/intel_soc_pmic_bxtwc.c
@@ -47,6 +47,8 @@
 #define BXTWC_MIRQLVL1 0x4E0E
 #define BXTWC_MPWRTNIRQ0x4E0F
 
+#define BXTWC_MIRQLVL1_MCHGR   BIT(5)
+
 #define BXTWC_MTHRM0IRQ0x4E12
 #define BXTWC_MTHRM1IRQ0x4E13
 #define BXTWC_MTHRM2IRQ0x4E14
@@ -58,6 +60,10 @@
 #define BXTWC_MGPIO1IRQ0x4E1A
 #define BXTWC_MCRITIRQ 0x4E1B
 
+#define BXTWC_STHRM0IRQ0x4F19
+#define BXTWC_STHRM1IRQ0x4F1A
+#define BXTWC_STHRM2IRQ0x4F1B
+
 /* Whiskey Cove PMIC share same ACPI ID between different platforms */
 #define BROXTON_PMIC_WC_HRV4
 
@@ -109,13 +115,116 @@ static const struct regmap_irq 
bxtwc_regmap_irqs_level2[] = {
REGMAP_IRQ_REG(BXTWC_THRM2_IRQ, 2, 0xff),
REGMAP_IRQ_REG(BXTWC_BCU_IRQ, 3, 0x1f),
REGMAP_IRQ_REG(BXTWC_ADC_IRQ, 4, 0xff),
-   REGMAP_IRQ_REG(BXTWC_CHGR0_IRQ, 5, 0x1f),
+   REGMAP_IRQ_REG(BXTWC_CHGR0_IRQ, 5, 0x3f),
REGMAP_IRQ_REG(BXTWC_CHGR1_IRQ, 6, 0x1f),
REGMAP_IRQ_REG(BXTWC_GPIO0_IRQ, 7, 0xff),
REGMAP_IRQ_REG(BXTWC_GPIO1_IRQ, 8, 0x3f),
REGMAP_IRQ_REG(BXTWC_CRIT_IRQ, 9, 0x03),
 };
 
+static struct trip_config_map str0_trip_config[] = {
+   {
+   .irq_reg = BXTWC_THRM0IRQ,
+   .irq_mask = 0x01,
+   .irq_en = BXTWC_MTHRM0IRQ,
+   .irq_en_mask = 0x01,
+   .evt_stat = BXTWC_STHRM0IRQ,
+   .evt_mask = 0x01,
+   .trip_num = 0
+   },
+   {
+   .irq_reg = BXTWC_THRM0IRQ,
+   .irq_mask = 0x10,
+   .irq_en = BXTWC_MTHRM0IRQ,
+   .irq_en_mask = 0x10,
+   .evt_stat = BXTWC_STHRM0IRQ,
+   .evt_mask = 0x10,
+   .trip_num = 1
+   }
+};
+
+static struct trip_config_map str1_trip_config[] = {
+   {
+   .irq_reg = BXTWC_THRM0IRQ,
+   .irq_mask = 0x02,
+   .irq_en = BXTWC_MTHRM0IRQ,
+   .irq_en_mask = 0x02,
+   .evt_stat = BXTWC_STHRM0IRQ,
+   .evt_mask = 0x02,
+   .trip_num = 0
+   },
+   {
+   .irq_reg = BXTWC_THRM0IRQ,
+   .irq_mask = 0x20,
+   .irq_en = BXTWC_MTHRM0IRQ,
+   .irq_en_mask = 0x20,
+   .evt_stat = BXTWC_STHRM0IRQ,
+   .evt_mask = 0x20,
+   .trip_num = 1
+   },
+};
+
+static struct trip_config_map str2_trip_config[] = {
+   {
+   .irq_reg = BXTWC_THRM0IRQ,
+   .irq_mask = 0x04,
+   .irq_en = BXTWC_MTHRM0IRQ,
+   .irq_en_mask = 0x04,
+   .evt_stat = BXTWC_STHRM0IRQ,
+   .evt_mask = 0x04,
+   .trip_num = 0
+   },
+   {
+   .irq_reg = BXTWC_THRM0IRQ,
+   .irq_mask = 0x40,
+   .irq_en = BXTWC_MTHRM0IRQ,
+   .irq_en_mask = 0x40,
+   .evt_stat = BXTWC_STHRM0IRQ,
+   .evt_mask = 0x40,
+   .trip_num = 1
+   },
+};
+
+static struct trip_config_map str3_trip_config[] = {
+   {
+   .irq_reg = BXTWC_THRM2IRQ,
+   .irq_mask = 0x10,
+   .irq_en = BXTWC_MTHRM2IRQ,
+   .irq_en_mask = 0x10,
+   .evt_stat = BXTWC_STHRM2IRQ,
+   .evt_mask = 0x10,
+   .trip_num = 0
+   },
+};
+
+static struct thermal_irq_map bxtwc_thermal_irq_map[] = {
+   {
+   .handle = "STR0",
+   .trip_config = str0_trip_config,
+   .num_trips = ARRAY_SIZE(str0_trip_config),
+   },
+   {
+   .handle = "STR1",
+   .trip_config = str1_trip_config,
+   .num_trips = ARRAY_S

[PATCH v4] gpio: add Intel WhiskeyCove GPIO driver

2016-06-27 Thread Bin Gao
This patch introduces a separate GPIO driver for Intel WhiskeyCove PMIC.
This driver is based on gpio-crystalcove.c.

Signed-off-by: Ajay Thomas <ajay.thomas.david.rajamanic...@intel.com>
Signed-off-by: Bin Gao <bin@intel.com>
---
Changes in v4:
 - Converted CTLI_INTCNT_XX macros to less verbose ones INT_DETECT_XX.
 - Add comments about why there is no .pm for the driver.
 - Header files re-ordered.
 - Various coding style change to address Andy's comments.
Changes in v3:
 - Fixed the year in copyright line(2015-->2016).
 - Removed DRV_NAME macro.
 - Added kernel-doc for regmap_irq_chip of the wcove_gpio structure.
 - Line length fix.
Changes in v2:
 - Typo fix (Whsikey --> Whiskey).
 - Included linux/gpio/driver.h instead of linux/gpio.h
 - Implemented .set_single_ended().
 - Added GPIO register description.
 - Replaced container_of() with gpiochip_get_data().
 - Removed unnecessary "if (gpio > WCOVE_VGPIO_NUM" check.
 - Removed the device id table and added MODULE_ALIAS().
 drivers/gpio/Kconfig  |  13 ++
 drivers/gpio/Makefile |   1 +
 drivers/gpio/gpio-wcove.c | 433 ++
 3 files changed, 447 insertions(+)
 create mode 100644 drivers/gpio/gpio-wcove.c

diff --git a/drivers/gpio/Kconfig b/drivers/gpio/Kconfig
index cebcb40..ac74299 100644
--- a/drivers/gpio/Kconfig
+++ b/drivers/gpio/Kconfig
@@ -806,6 +806,19 @@ config GPIO_CRYSTAL_COVE
  This driver can also be built as a module. If so, the module will be
  called gpio-crystalcove.
 
+config GPIO_WHISKEY_COVE
+   tristate "GPIO support for Whiskey Cove PMIC"
+   depends on INTEL_SOC_PMIC
+   select GPIOLIB_IRQCHIP
+   help
+ Support for GPIO pins on Whiskey Cove PMIC.
+
+ Say Yes if you have a Intel SoC based tablet with Whiskey Cove PMIC
+ inside.
+
+ This driver can also be built as a module. If so, the module will be
+ called gpio-wcove.
+
 config GPIO_CS5535
tristate "AMD CS5535/CS5536 GPIO support"
depends on MFD_CS5535
diff --git a/drivers/gpio/Makefile b/drivers/gpio/Makefile
index 991598e..fff6914 100644
--- a/drivers/gpio/Makefile
+++ b/drivers/gpio/Makefile
@@ -34,6 +34,7 @@ obj-$(CONFIG_GPIO_BT8XX)  += gpio-bt8xx.o
 obj-$(CONFIG_GPIO_CLPS711X)+= gpio-clps711x.o
 obj-$(CONFIG_GPIO_CS5535)  += gpio-cs5535.o
 obj-$(CONFIG_GPIO_CRYSTAL_COVE)+= gpio-crystalcove.o
+obj-$(CONFIG_GPIO_WHISKEY_COVE)+= gpio-wcove.o
 obj-$(CONFIG_GPIO_DA9052)  += gpio-da9052.o
 obj-$(CONFIG_GPIO_DA9055)  += gpio-da9055.o
 obj-$(CONFIG_GPIO_DAVINCI) += gpio-davinci.o
diff --git a/drivers/gpio/gpio-wcove.c b/drivers/gpio/gpio-wcove.c
new file mode 100644
index 000..9f1b25a
--- /dev/null
+++ b/drivers/gpio/gpio-wcove.c
@@ -0,0 +1,433 @@
+/*
+ * gpio-wcove.c - Intel Whiskey Cove GPIO Driver
+ *
+ * This driver is written based on gpio-crystalcove.c
+ *
+ * Copyright (C) 2016 Intel Corporation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License version
+ * 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+/*
+ * Whiskey Cove PMIC has 13 physical GPIO pins divided into 3 banks:
+ * Bank 0: Pin 0 - 6
+ * Bank 1: Pin 7 - 10
+ * Bank 2: Pin 11 -12
+ * Each pin has one output control register and one input control register.
+ */
+#define BANK0_NR_PINS  7
+#define BANK1_NR_PINS  4
+#define BANK2_NR_PINS  2
+#define WCOVE_GPIO_NUM (BANK0_NR_PINS + BANK1_NR_PINS + BANK2_NR_PINS)
+#define WCOVE_VGPIO_NUM94
+/* GPIO output control registers(one per pin): 0x4e44 - 0x4e50 */
+#define OUT_CTRL_OFFSET0x4e44
+/* GPIO input control registers(one per pin): 0x4e51 - 0x4e5d */
+#define IN_CTRL_OFFSET 0x4e51
+
+/*
+ * GPIO interrupts are organized in two groups:
+ * Group 0: Bank 0 pins (Pin 0 - 6)
+ * Group 1: Bank 1 and Bank 2 pins (Pin 7 - 12)
+ * Each group has two registers(one bit per pin): status and mask.
+ */
+#define GROUP0_NR_IRQS 7
+#define GROUP1_NR_IRQS 6
+#define IRQ_MASK_OFFSET0x4e19
+#define IRQ_STATUS_OFFSET  0x4e0b
+#define UPDATE_IRQ_TYPEBIT(0)
+#define UPDATE_IRQ_MASKBIT(1)
+
+#define LSHIFT_ONE(x)  ((x) << 1)
+
+/* GPIO Input Pin Interrupt Dectection */
+#define INT_DETECT_DISABLE LSHIFT_ONE(0) /* Disable interrupt input */
+#define INT_DETECT_FALLING LSHIFT_ONE(1) /* Detect falling edge */
+#define INT_DETECT_RISING  LSHIFT

[PATCH v4] gpio: add Intel WhiskeyCove GPIO driver

2016-06-27 Thread Bin Gao
This patch introduces a separate GPIO driver for Intel WhiskeyCove PMIC.
This driver is based on gpio-crystalcove.c.

Signed-off-by: Ajay Thomas 
Signed-off-by: Bin Gao 
---
Changes in v4:
 - Converted CTLI_INTCNT_XX macros to less verbose ones INT_DETECT_XX.
 - Add comments about why there is no .pm for the driver.
 - Header files re-ordered.
 - Various coding style change to address Andy's comments.
Changes in v3:
 - Fixed the year in copyright line(2015-->2016).
 - Removed DRV_NAME macro.
 - Added kernel-doc for regmap_irq_chip of the wcove_gpio structure.
 - Line length fix.
Changes in v2:
 - Typo fix (Whsikey --> Whiskey).
 - Included linux/gpio/driver.h instead of linux/gpio.h
 - Implemented .set_single_ended().
 - Added GPIO register description.
 - Replaced container_of() with gpiochip_get_data().
 - Removed unnecessary "if (gpio > WCOVE_VGPIO_NUM" check.
 - Removed the device id table and added MODULE_ALIAS().
 drivers/gpio/Kconfig  |  13 ++
 drivers/gpio/Makefile |   1 +
 drivers/gpio/gpio-wcove.c | 433 ++
 3 files changed, 447 insertions(+)
 create mode 100644 drivers/gpio/gpio-wcove.c

diff --git a/drivers/gpio/Kconfig b/drivers/gpio/Kconfig
index cebcb40..ac74299 100644
--- a/drivers/gpio/Kconfig
+++ b/drivers/gpio/Kconfig
@@ -806,6 +806,19 @@ config GPIO_CRYSTAL_COVE
  This driver can also be built as a module. If so, the module will be
  called gpio-crystalcove.
 
+config GPIO_WHISKEY_COVE
+   tristate "GPIO support for Whiskey Cove PMIC"
+   depends on INTEL_SOC_PMIC
+   select GPIOLIB_IRQCHIP
+   help
+ Support for GPIO pins on Whiskey Cove PMIC.
+
+ Say Yes if you have a Intel SoC based tablet with Whiskey Cove PMIC
+ inside.
+
+ This driver can also be built as a module. If so, the module will be
+ called gpio-wcove.
+
 config GPIO_CS5535
tristate "AMD CS5535/CS5536 GPIO support"
depends on MFD_CS5535
diff --git a/drivers/gpio/Makefile b/drivers/gpio/Makefile
index 991598e..fff6914 100644
--- a/drivers/gpio/Makefile
+++ b/drivers/gpio/Makefile
@@ -34,6 +34,7 @@ obj-$(CONFIG_GPIO_BT8XX)  += gpio-bt8xx.o
 obj-$(CONFIG_GPIO_CLPS711X)+= gpio-clps711x.o
 obj-$(CONFIG_GPIO_CS5535)  += gpio-cs5535.o
 obj-$(CONFIG_GPIO_CRYSTAL_COVE)+= gpio-crystalcove.o
+obj-$(CONFIG_GPIO_WHISKEY_COVE)+= gpio-wcove.o
 obj-$(CONFIG_GPIO_DA9052)  += gpio-da9052.o
 obj-$(CONFIG_GPIO_DA9055)  += gpio-da9055.o
 obj-$(CONFIG_GPIO_DAVINCI) += gpio-davinci.o
diff --git a/drivers/gpio/gpio-wcove.c b/drivers/gpio/gpio-wcove.c
new file mode 100644
index 000..9f1b25a
--- /dev/null
+++ b/drivers/gpio/gpio-wcove.c
@@ -0,0 +1,433 @@
+/*
+ * gpio-wcove.c - Intel Whiskey Cove GPIO Driver
+ *
+ * This driver is written based on gpio-crystalcove.c
+ *
+ * Copyright (C) 2016 Intel Corporation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License version
+ * 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+/*
+ * Whiskey Cove PMIC has 13 physical GPIO pins divided into 3 banks:
+ * Bank 0: Pin 0 - 6
+ * Bank 1: Pin 7 - 10
+ * Bank 2: Pin 11 -12
+ * Each pin has one output control register and one input control register.
+ */
+#define BANK0_NR_PINS  7
+#define BANK1_NR_PINS  4
+#define BANK2_NR_PINS  2
+#define WCOVE_GPIO_NUM (BANK0_NR_PINS + BANK1_NR_PINS + BANK2_NR_PINS)
+#define WCOVE_VGPIO_NUM94
+/* GPIO output control registers(one per pin): 0x4e44 - 0x4e50 */
+#define OUT_CTRL_OFFSET0x4e44
+/* GPIO input control registers(one per pin): 0x4e51 - 0x4e5d */
+#define IN_CTRL_OFFSET 0x4e51
+
+/*
+ * GPIO interrupts are organized in two groups:
+ * Group 0: Bank 0 pins (Pin 0 - 6)
+ * Group 1: Bank 1 and Bank 2 pins (Pin 7 - 12)
+ * Each group has two registers(one bit per pin): status and mask.
+ */
+#define GROUP0_NR_IRQS 7
+#define GROUP1_NR_IRQS 6
+#define IRQ_MASK_OFFSET0x4e19
+#define IRQ_STATUS_OFFSET  0x4e0b
+#define UPDATE_IRQ_TYPEBIT(0)
+#define UPDATE_IRQ_MASKBIT(1)
+
+#define LSHIFT_ONE(x)  ((x) << 1)
+
+/* GPIO Input Pin Interrupt Dectection */
+#define INT_DETECT_DISABLE LSHIFT_ONE(0) /* Disable interrupt input */
+#define INT_DETECT_FALLING LSHIFT_ONE(1) /* Detect falling edge */
+#define INT_DETECT_RISING  LSHIFT_ONE(2) /* Detect rising edge */
+#define INT_DETECT_BOTHLSHIFT_ONE(3) /

[PATCH v4 3/3] acpi/pmic: Add support for PMIC regs operation region

2016-06-23 Thread Bin Gao
Broxton platform firmware has defined new customized operation regions
called regs for PMIC chip - regs op region is used to handle the
PMIC gpio mainly intended for the TYPE-C VBUS and Orientation.

The intel_gpio_ctx  structure is created for the purpose of handling
the PMIC gpio register read and write.

Signed-off-by: Felipe Balbi <felipe.ba...@linux.intel.com>
Signed-off-by: Chandra Sekhar Anagani <chandra.sekhar.anag...@intel.com>
Signed-off-by: Bin Gao <bin@intel.com>
---
Changes in v4:
 - various fixes to address Aaron's comments.
Changes in v3: none
Changes in v2: none
 drivers/acpi/pmic/intel_pmic.c | 74 --
 drivers/acpi/pmic/intel_pmic.h |  5 +++
 2 files changed, 76 insertions(+), 3 deletions(-)

diff --git a/drivers/acpi/pmic/intel_pmic.c b/drivers/acpi/pmic/intel_pmic.c
index 410e96f..e11d1e0 100644
--- a/drivers/acpi/pmic/intel_pmic.c
+++ b/drivers/acpi/pmic/intel_pmic.c
@@ -21,12 +21,14 @@
 
 #define PMIC_POWER_OPREGION_ID 0x8d
 #define PMIC_THERMAL_OPREGION_ID   0x8c
+#define PMIC_REGS_OPREGION_ID  0x8f
 
 struct intel_pmic_opregion {
struct mutex lock;
struct acpi_lpat_conversion_table *lpat_table;
struct regmap *regmap;
struct intel_pmic_opregion_data *data;
+   struct pmic_gpio_ctxctx;
 };
 
 static int pmic_get_reg_bit(int address, struct pmic_table *table,
@@ -204,6 +206,56 @@ static acpi_status intel_pmic_thermal_handler(u32 function,
return AE_OK;
 }
 
+static acpi_status intel_pmic_gpio_handler(u32 function,
+   acpi_physical_address address, u32 bits, u64 *value64,
+   void *handler_context, void *region_context)
+{
+   struct intel_pmic_opregion *opregion = region_context;
+   int result;
+
+   switch (address) {
+   case 0:
+   return AE_OK;
+   case 1:
+   opregion->ctx.address |= (*value64 & 0xff) << 8;
+   return AE_OK;
+   case 2:
+   opregion->ctx.address |= *value64 & 0xff;
+   return AE_OK;
+   case 3:
+   opregion->ctx.value = *value64 & 0xff;
+   return AE_OK;
+   case 4:
+   if (*value64) {
+   result = regmap_write(opregion->regmap,
+opregion->ctx.address,
+   opregion->ctx.value);
+   } else {
+   result = regmap_read(opregion->regmap,
+   opregion->ctx.address,
+   >ctx.value);
+   if (result == 0)
+   *value64 = opregion->ctx.value;
+   }
+   memset(>ctx, 0x00, sizeof(opregion->ctx));
+   break;
+   default:
+   pr_err("%s(): Inavlid address %llu, please check the BIOS\n",
+__func__, address);
+   return AE_ERROR;
+   }
+
+   if (result < 0) {
+   if (result == -EINVAL)
+   return AE_BAD_PARAMETER;
+   else
+   return AE_ERROR;
+   }
+
+   return AE_OK;
+}
+
+
 int intel_pmic_install_opregion_handler(struct device *dev, acpi_handle handle,
struct regmap *regmap,
struct intel_pmic_opregion_data *d)
@@ -240,15 +292,31 @@ int intel_pmic_install_opregion_handler(struct device 
*dev, acpi_handle handle,
intel_pmic_thermal_handler,
NULL, opregion);
if (ACPI_FAILURE(status)) {
-   acpi_remove_address_space_handler(handle, 
PMIC_POWER_OPREGION_ID,
- intel_pmic_power_handler);
ret = -ENODEV;
-   goto out_error;
+   goto remove_pmic_power_handler;
+   }
+
+   status = acpi_install_address_space_handler(handle,
+   PMIC_REGS_OPREGION_ID,
+   intel_pmic_gpio_handler,
+   NULL, opregion);
+   if (ACPI_FAILURE(status)) {
+   ret = -ENODEV;
+   goto remove_pmic_thermal_handler;
}
 
opregion->data = d;
return 0;
 
+remove_pmic_thermal_handler:
+   acpi_remove_address_space_handler(handle,
+   PMIC_POWER_OPREGION_ID,
+   intel_pmic_thermal_handler);
+remove_pmic_power_handler:
+   acpi_remove_address_space_handler(handle,
+   PMIC_POWER_OPREGION_ID,

[PATCH v4 3/3] acpi/pmic: Add support for PMIC regs operation region

2016-06-23 Thread Bin Gao
Broxton platform firmware has defined new customized operation regions
called regs for PMIC chip - regs op region is used to handle the
PMIC gpio mainly intended for the TYPE-C VBUS and Orientation.

The intel_gpio_ctx  structure is created for the purpose of handling
the PMIC gpio register read and write.

Signed-off-by: Felipe Balbi 
Signed-off-by: Chandra Sekhar Anagani 
Signed-off-by: Bin Gao 
---
Changes in v4:
 - various fixes to address Aaron's comments.
Changes in v3: none
Changes in v2: none
 drivers/acpi/pmic/intel_pmic.c | 74 --
 drivers/acpi/pmic/intel_pmic.h |  5 +++
 2 files changed, 76 insertions(+), 3 deletions(-)

diff --git a/drivers/acpi/pmic/intel_pmic.c b/drivers/acpi/pmic/intel_pmic.c
index 410e96f..e11d1e0 100644
--- a/drivers/acpi/pmic/intel_pmic.c
+++ b/drivers/acpi/pmic/intel_pmic.c
@@ -21,12 +21,14 @@
 
 #define PMIC_POWER_OPREGION_ID 0x8d
 #define PMIC_THERMAL_OPREGION_ID   0x8c
+#define PMIC_REGS_OPREGION_ID  0x8f
 
 struct intel_pmic_opregion {
struct mutex lock;
struct acpi_lpat_conversion_table *lpat_table;
struct regmap *regmap;
struct intel_pmic_opregion_data *data;
+   struct pmic_gpio_ctxctx;
 };
 
 static int pmic_get_reg_bit(int address, struct pmic_table *table,
@@ -204,6 +206,56 @@ static acpi_status intel_pmic_thermal_handler(u32 function,
return AE_OK;
 }
 
+static acpi_status intel_pmic_gpio_handler(u32 function,
+   acpi_physical_address address, u32 bits, u64 *value64,
+   void *handler_context, void *region_context)
+{
+   struct intel_pmic_opregion *opregion = region_context;
+   int result;
+
+   switch (address) {
+   case 0:
+   return AE_OK;
+   case 1:
+   opregion->ctx.address |= (*value64 & 0xff) << 8;
+   return AE_OK;
+   case 2:
+   opregion->ctx.address |= *value64 & 0xff;
+   return AE_OK;
+   case 3:
+   opregion->ctx.value = *value64 & 0xff;
+   return AE_OK;
+   case 4:
+   if (*value64) {
+   result = regmap_write(opregion->regmap,
+opregion->ctx.address,
+   opregion->ctx.value);
+   } else {
+   result = regmap_read(opregion->regmap,
+   opregion->ctx.address,
+   >ctx.value);
+   if (result == 0)
+   *value64 = opregion->ctx.value;
+   }
+   memset(>ctx, 0x00, sizeof(opregion->ctx));
+   break;
+   default:
+   pr_err("%s(): Inavlid address %llu, please check the BIOS\n",
+__func__, address);
+   return AE_ERROR;
+   }
+
+   if (result < 0) {
+   if (result == -EINVAL)
+   return AE_BAD_PARAMETER;
+   else
+   return AE_ERROR;
+   }
+
+   return AE_OK;
+}
+
+
 int intel_pmic_install_opregion_handler(struct device *dev, acpi_handle handle,
struct regmap *regmap,
struct intel_pmic_opregion_data *d)
@@ -240,15 +292,31 @@ int intel_pmic_install_opregion_handler(struct device 
*dev, acpi_handle handle,
intel_pmic_thermal_handler,
NULL, opregion);
if (ACPI_FAILURE(status)) {
-   acpi_remove_address_space_handler(handle, 
PMIC_POWER_OPREGION_ID,
- intel_pmic_power_handler);
ret = -ENODEV;
-   goto out_error;
+   goto remove_pmic_power_handler;
+   }
+
+   status = acpi_install_address_space_handler(handle,
+   PMIC_REGS_OPREGION_ID,
+   intel_pmic_gpio_handler,
+   NULL, opregion);
+   if (ACPI_FAILURE(status)) {
+   ret = -ENODEV;
+   goto remove_pmic_thermal_handler;
}
 
opregion->data = d;
return 0;
 
+remove_pmic_thermal_handler:
+   acpi_remove_address_space_handler(handle,
+   PMIC_POWER_OPREGION_ID,
+   intel_pmic_thermal_handler);
+remove_pmic_power_handler:
+   acpi_remove_address_space_handler(handle,
+   PMIC_POWER_OPREGION_ID,
+   intel_pmic_power_handler);
+
 out_error:
acpi_lpat_free_

  1   2   3   >