[GIT PULL] Keys keyctl placeholder

2016-06-02 Thread James Morris
David Howells has asked that this be accepted before -rc2:

"Could you pass this along to Linus as soon as possible, please?  This 
alters a new keyctl function added in the current merge window to allow 
for a future extension planned for the next merge window."

Please pull.

The following changes since commit 4340fa55298d17049e71c7a34e04647379c269f3:

  Merge tag 'for-linus' of git://git.kernel.org/pub/scm/virt/kvm/kvm 
(2016-06-02 15:08:06 -0700)

are available in the git repository at:

  git://git.kernel.org/pub/scm/linux/kernel/git/jmorris/linux-security.git 
for-linus

Stephan Mueller (1):
  KEYS: Add placeholder for KDF usage with DH

 Documentation/security/keys.txt |5 -
 security/keys/compat.c  |2 +-
 security/keys/dh.c  |8 +++-
 security/keys/internal.h|5 +++--
 security/keys/keyctl.c  |4 ++--
 5 files changed, 17 insertions(+), 7 deletions(-)

-- 
commit 4693fc734d675c5518ea9bd4c9623db45bc37402
Author: Stephan Mueller 
Date:   Thu May 26 23:38:12 2016 +0200

KEYS: Add placeholder for KDF usage with DH

The values computed during Diffie-Hellman key exchange are often used
in combination with key derivation functions to create cryptographic
keys.  Add a placeholder for a later implementation to configure a
key derivation function that will transform the Diffie-Hellman
result returned by the KEYCTL_DH_COMPUTE command.

[This patch was stripped down from a patch produced by Mat Martineau that
 had a bug in the compat code - so for the moment Stephan's patch simply
 requires that the placeholder argument must be NULL]

Original-signed-off-by: Mat Martineau 
Signed-off-by: Stephan Mueller 
Signed-off-by: David Howells 
Signed-off-by: James Morris 

diff --git a/Documentation/security/keys.txt b/Documentation/security/keys.txt
index 20d0571..3849814 100644
--- a/Documentation/security/keys.txt
+++ b/Documentation/security/keys.txt
@@ -826,7 +826,8 @@ The keyctl syscall functions are:
  (*) Compute a Diffie-Hellman shared secret or public key
 
long keyctl(KEYCTL_DH_COMPUTE, struct keyctl_dh_params *params,
-  char *buffer, size_t buflen);
+  char *buffer, size_t buflen,
+  void *reserved);
 
  The params struct contains serial numbers for three keys:
 
@@ -843,6 +844,8 @@ The keyctl syscall functions are:
  public key.  If the base is the remote public key, the result is
  the shared secret.
 
+ The reserved argument must be set to NULL.
+
  The buffer length must be at least the length of the prime, or zero.
 
  If the buffer length is nonzero, the length of the result is
diff --git a/security/keys/compat.c b/security/keys/compat.c
index c8783b3..36c80bf 100644
--- a/security/keys/compat.c
+++ b/security/keys/compat.c
@@ -134,7 +134,7 @@ COMPAT_SYSCALL_DEFINE5(keyctl, u32, option,
 
case KEYCTL_DH_COMPUTE:
return keyctl_dh_compute(compat_ptr(arg2), compat_ptr(arg3),
-arg4);
+arg4, compat_ptr(arg5));
 
default:
return -EOPNOTSUPP;
diff --git a/security/keys/dh.c b/security/keys/dh.c
index 880505a..531ed2e 100644
--- a/security/keys/dh.c
+++ b/security/keys/dh.c
@@ -78,7 +78,8 @@ error:
 }
 
 long keyctl_dh_compute(struct keyctl_dh_params __user *params,
-  char __user *buffer, size_t buflen)
+  char __user *buffer, size_t buflen,
+  void __user *reserved)
 {
long ret;
MPI base, private, prime, result;
@@ -97,6 +98,11 @@ long keyctl_dh_compute(struct keyctl_dh_params __user 
*params,
goto out;
}
 
+   if (reserved) {
+   ret = -EINVAL;
+   goto out;
+   }
+
keylen = mpi_from_key(pcopy.prime, buflen, );
if (keylen < 0 || !prime) {
/* buflen == 0 may be used to query the required buffer size,
diff --git a/security/keys/internal.h b/security/keys/internal.h
index 8ec7a52..a705a7d 100644
--- a/security/keys/internal.h
+++ b/security/keys/internal.h
@@ -260,10 +260,11 @@ static inline long keyctl_get_persistent(uid_t uid, 
key_serial_t destring)
 
 #ifdef CONFIG_KEY_DH_OPERATIONS
 extern long keyctl_dh_compute(struct keyctl_dh_params __user *, char __user *,
- size_t);
+ size_t, void __user *);
 #else
 static inline long keyctl_dh_compute(struct keyctl_dh_params __user *params,
-char __user *buffer, size_t buflen)
+char __user *buffer, size_t buflen,
+void __user *reserved)
 {
return -EOPNOTSUPP;
 }
diff --git 

[GIT PULL] Keys keyctl placeholder

2016-06-02 Thread James Morris
David Howells has asked that this be accepted before -rc2:

"Could you pass this along to Linus as soon as possible, please?  This 
alters a new keyctl function added in the current merge window to allow 
for a future extension planned for the next merge window."

Please pull.

The following changes since commit 4340fa55298d17049e71c7a34e04647379c269f3:

  Merge tag 'for-linus' of git://git.kernel.org/pub/scm/virt/kvm/kvm 
(2016-06-02 15:08:06 -0700)

are available in the git repository at:

  git://git.kernel.org/pub/scm/linux/kernel/git/jmorris/linux-security.git 
for-linus

Stephan Mueller (1):
  KEYS: Add placeholder for KDF usage with DH

 Documentation/security/keys.txt |5 -
 security/keys/compat.c  |2 +-
 security/keys/dh.c  |8 +++-
 security/keys/internal.h|5 +++--
 security/keys/keyctl.c  |4 ++--
 5 files changed, 17 insertions(+), 7 deletions(-)

-- 
commit 4693fc734d675c5518ea9bd4c9623db45bc37402
Author: Stephan Mueller 
Date:   Thu May 26 23:38:12 2016 +0200

KEYS: Add placeholder for KDF usage with DH

The values computed during Diffie-Hellman key exchange are often used
in combination with key derivation functions to create cryptographic
keys.  Add a placeholder for a later implementation to configure a
key derivation function that will transform the Diffie-Hellman
result returned by the KEYCTL_DH_COMPUTE command.

[This patch was stripped down from a patch produced by Mat Martineau that
 had a bug in the compat code - so for the moment Stephan's patch simply
 requires that the placeholder argument must be NULL]

Original-signed-off-by: Mat Martineau 
Signed-off-by: Stephan Mueller 
Signed-off-by: David Howells 
Signed-off-by: James Morris 

diff --git a/Documentation/security/keys.txt b/Documentation/security/keys.txt
index 20d0571..3849814 100644
--- a/Documentation/security/keys.txt
+++ b/Documentation/security/keys.txt
@@ -826,7 +826,8 @@ The keyctl syscall functions are:
  (*) Compute a Diffie-Hellman shared secret or public key
 
long keyctl(KEYCTL_DH_COMPUTE, struct keyctl_dh_params *params,
-  char *buffer, size_t buflen);
+  char *buffer, size_t buflen,
+  void *reserved);
 
  The params struct contains serial numbers for three keys:
 
@@ -843,6 +844,8 @@ The keyctl syscall functions are:
  public key.  If the base is the remote public key, the result is
  the shared secret.
 
+ The reserved argument must be set to NULL.
+
  The buffer length must be at least the length of the prime, or zero.
 
  If the buffer length is nonzero, the length of the result is
diff --git a/security/keys/compat.c b/security/keys/compat.c
index c8783b3..36c80bf 100644
--- a/security/keys/compat.c
+++ b/security/keys/compat.c
@@ -134,7 +134,7 @@ COMPAT_SYSCALL_DEFINE5(keyctl, u32, option,
 
case KEYCTL_DH_COMPUTE:
return keyctl_dh_compute(compat_ptr(arg2), compat_ptr(arg3),
-arg4);
+arg4, compat_ptr(arg5));
 
default:
return -EOPNOTSUPP;
diff --git a/security/keys/dh.c b/security/keys/dh.c
index 880505a..531ed2e 100644
--- a/security/keys/dh.c
+++ b/security/keys/dh.c
@@ -78,7 +78,8 @@ error:
 }
 
 long keyctl_dh_compute(struct keyctl_dh_params __user *params,
-  char __user *buffer, size_t buflen)
+  char __user *buffer, size_t buflen,
+  void __user *reserved)
 {
long ret;
MPI base, private, prime, result;
@@ -97,6 +98,11 @@ long keyctl_dh_compute(struct keyctl_dh_params __user 
*params,
goto out;
}
 
+   if (reserved) {
+   ret = -EINVAL;
+   goto out;
+   }
+
keylen = mpi_from_key(pcopy.prime, buflen, );
if (keylen < 0 || !prime) {
/* buflen == 0 may be used to query the required buffer size,
diff --git a/security/keys/internal.h b/security/keys/internal.h
index 8ec7a52..a705a7d 100644
--- a/security/keys/internal.h
+++ b/security/keys/internal.h
@@ -260,10 +260,11 @@ static inline long keyctl_get_persistent(uid_t uid, 
key_serial_t destring)
 
 #ifdef CONFIG_KEY_DH_OPERATIONS
 extern long keyctl_dh_compute(struct keyctl_dh_params __user *, char __user *,
- size_t);
+ size_t, void __user *);
 #else
 static inline long keyctl_dh_compute(struct keyctl_dh_params __user *params,
-char __user *buffer, size_t buflen)
+char __user *buffer, size_t buflen,
+void __user *reserved)
 {
return -EOPNOTSUPP;
 }
diff --git a/security/keys/keyctl.c b/security/keys/keyctl.c
index 3b135a0..d580ad0 100644
--- a/security/keys/keyctl.c
+++ 

Re: NFS/d_splice_alias breakage

2016-06-02 Thread Al Viro
On Fri, Jun 03, 2016 at 12:58:10AM -0400, Oleg Drokin wrote:

> This one cures the insta-crash I was having, and I see no other ill-effects 
> so far.

OK...  I can take it through vfs.git, but I think it'd be better off in
NFS tree.  Is everyone OK with something like the following?

make nfs_atomic_open() call d_drop() on all ->open_context() errors.

In "NFSv4: Move dentry instantiation into the NFSv4-specific atomic open code"
unconditional d_drop() after the ->open_context() had been removed.  It had
been correct for success cases (there ->open_context() itself had been doing
dcache manipulations), but not for error ones.  Only one of those (ENOENT)
got a compensatory d_drop() added in that commit, but in fact it should've
been done for all errors.  As it is, the case of O_CREAT non-exclusive open
on a hashed negative dentry racing with e.g. symlink creation from another
client ended up with ->open_context() getting an error and proceeding to
call nfs_lookup().  On a hashed dentry, which would've instantly triggered
BUG_ON() in d_materialise_unique() (or, these days, its equivalent in
d_splice_alias()).

Cc: sta...@vger.kernel.org # v3.10+
Tested-by: Oleg Drokin 
Signed-off-by: Al Viro 
---
diff --git a/fs/nfs/dir.c b/fs/nfs/dir.c
index aaf7bd0..6e3a6f4 100644
--- a/fs/nfs/dir.c
+++ b/fs/nfs/dir.c
@@ -1536,9 +1536,9 @@ int nfs_atomic_open(struct inode *dir, struct dentry 
*dentry,
err = PTR_ERR(inode);
trace_nfs_atomic_open_exit(dir, ctx, open_flags, err);
put_nfs_open_context(ctx);
+   d_drop(dentry);
switch (err) {
case -ENOENT:
-   d_drop(dentry);
d_add(dentry, NULL);
nfs_set_verifier(dentry, 
nfs_save_change_attribute(dir));
break;


Re: NFS/d_splice_alias breakage

2016-06-02 Thread Al Viro
On Fri, Jun 03, 2016 at 12:58:10AM -0400, Oleg Drokin wrote:

> This one cures the insta-crash I was having, and I see no other ill-effects 
> so far.

OK...  I can take it through vfs.git, but I think it'd be better off in
NFS tree.  Is everyone OK with something like the following?

make nfs_atomic_open() call d_drop() on all ->open_context() errors.

In "NFSv4: Move dentry instantiation into the NFSv4-specific atomic open code"
unconditional d_drop() after the ->open_context() had been removed.  It had
been correct for success cases (there ->open_context() itself had been doing
dcache manipulations), but not for error ones.  Only one of those (ENOENT)
got a compensatory d_drop() added in that commit, but in fact it should've
been done for all errors.  As it is, the case of O_CREAT non-exclusive open
on a hashed negative dentry racing with e.g. symlink creation from another
client ended up with ->open_context() getting an error and proceeding to
call nfs_lookup().  On a hashed dentry, which would've instantly triggered
BUG_ON() in d_materialise_unique() (or, these days, its equivalent in
d_splice_alias()).

Cc: sta...@vger.kernel.org # v3.10+
Tested-by: Oleg Drokin 
Signed-off-by: Al Viro 
---
diff --git a/fs/nfs/dir.c b/fs/nfs/dir.c
index aaf7bd0..6e3a6f4 100644
--- a/fs/nfs/dir.c
+++ b/fs/nfs/dir.c
@@ -1536,9 +1536,9 @@ int nfs_atomic_open(struct inode *dir, struct dentry 
*dentry,
err = PTR_ERR(inode);
trace_nfs_atomic_open_exit(dir, ctx, open_flags, err);
put_nfs_open_context(ctx);
+   d_drop(dentry);
switch (err) {
case -ENOENT:
-   d_drop(dentry);
d_add(dentry, NULL);
nfs_set_verifier(dentry, 
nfs_save_change_attribute(dir));
break;


Re: ath9k gpio request

2016-06-02 Thread Pan, Miaoqing
Done, https://patchwork.kernel.org/patch/9151847/.

Thanks,
Miaoqing

From: Kalle Valo 
Sent: Friday, June 3, 2016 1:33 PM
To: Pan, Miaoqing
Cc: Sudip Mukherjee; Stephen Rothwell; ath9k-devel; linux-n...@vger.kernel.org; 
linux-kernel@vger.kernel.org; linux-wirel...@vger.kernel.org; 
ath9k-de...@lists.ath9k.org; net...@vger.kernel.org; Miaoqing Pan
Subject: Re: ath9k gpio request

Sudip Mukherjee  writes:

> On Thursday 02 June 2016 01:32 PM, Pan, Miaoqing wrote:
>> Seems there are something wrong in the datasheet,  try
>>
>> --- a/drivers/net/wireless/ath/ath9k/reg.h
>> +++ b/drivers/net/wireless/ath/ath9k/reg.h
>> @@ -1122,8 +1122,8 @@ enum {
>>   #define AR9300_NUM_GPIO  16
>>   #define AR9330_NUM_GPIO 16
>>   #define AR9340_NUM_GPIO 23
>> -#define AR9462_NUM_GPIO 10
>> -#define AR9485_NUM_GPIO 12
>> +#define AR9462_NUM_GPIO 14
>> +#define AR9485_NUM_GPIO 11
>>   #define AR9531_NUM_GPIO 18
>>   #define AR9550_NUM_GPIO 24
>>   #define AR9561_NUM_GPIO 23
>> @@ -1139,8 +1139,8 @@ enum {
>>   #define AR9300_GPIO_MASK0xF4FF
>>   #define AR9330_GPIO_MASK0xF4FF
>>   #define AR9340_GPIO_MASK0x000F
>> -#define AR9462_GPIO_MASK0x03FF
>> -#define AR9485_GPIO_MASK0x0FFF
>> +#define AR9462_GPIO_MASK0x3FFF
>> +#define AR9485_GPIO_MASK0x07FF
>>   #define AR9531_GPIO_MASK0x000F
>>   #define AR9550_GPIO_MASK0x000F
>>   #define AR9561_GPIO_MASK0x000F
>
> solves the problem.
>
> Tested-by: Sudip Mukherjee 

Great, thanks for testing everyone. Miaoqing, please send a proper patch
ASAP and I'll push it to 4.7.

--
Kalle Valo


Re: ath9k gpio request

2016-06-02 Thread Pan, Miaoqing
Done, https://patchwork.kernel.org/patch/9151847/.

Thanks,
Miaoqing

From: Kalle Valo 
Sent: Friday, June 3, 2016 1:33 PM
To: Pan, Miaoqing
Cc: Sudip Mukherjee; Stephen Rothwell; ath9k-devel; linux-n...@vger.kernel.org; 
linux-kernel@vger.kernel.org; linux-wirel...@vger.kernel.org; 
ath9k-de...@lists.ath9k.org; net...@vger.kernel.org; Miaoqing Pan
Subject: Re: ath9k gpio request

Sudip Mukherjee  writes:

> On Thursday 02 June 2016 01:32 PM, Pan, Miaoqing wrote:
>> Seems there are something wrong in the datasheet,  try
>>
>> --- a/drivers/net/wireless/ath/ath9k/reg.h
>> +++ b/drivers/net/wireless/ath/ath9k/reg.h
>> @@ -1122,8 +1122,8 @@ enum {
>>   #define AR9300_NUM_GPIO  16
>>   #define AR9330_NUM_GPIO 16
>>   #define AR9340_NUM_GPIO 23
>> -#define AR9462_NUM_GPIO 10
>> -#define AR9485_NUM_GPIO 12
>> +#define AR9462_NUM_GPIO 14
>> +#define AR9485_NUM_GPIO 11
>>   #define AR9531_NUM_GPIO 18
>>   #define AR9550_NUM_GPIO 24
>>   #define AR9561_NUM_GPIO 23
>> @@ -1139,8 +1139,8 @@ enum {
>>   #define AR9300_GPIO_MASK0xF4FF
>>   #define AR9330_GPIO_MASK0xF4FF
>>   #define AR9340_GPIO_MASK0x000F
>> -#define AR9462_GPIO_MASK0x03FF
>> -#define AR9485_GPIO_MASK0x0FFF
>> +#define AR9462_GPIO_MASK0x3FFF
>> +#define AR9485_GPIO_MASK0x07FF
>>   #define AR9531_GPIO_MASK0x000F
>>   #define AR9550_GPIO_MASK0x000F
>>   #define AR9561_GPIO_MASK0x000F
>
> solves the problem.
>
> Tested-by: Sudip Mukherjee 

Great, thanks for testing everyone. Miaoqing, please send a proper patch
ASAP and I'll push it to 4.7.

--
Kalle Valo


RE: [PATCH] ARM: dts: am335x-boneblack: add i2c1 DT entry

2016-06-02 Thread Li, Yong B
Hi Tony,

I can submit a V2 version about the "disabled", or just drop this patch?

Thanks,
Yong
-Original Message-
From: Tony Lindgren [mailto:t...@atomide.com] 
Sent: Friday, June 3, 2016 1:57 AM
To: Robert Nelson 
Cc: Li, Yong B ; Benoit Cousson ; 
Rob Herring ; Pawel Moll ; Mark Rutland 
; Ian Campbell ; Kumar 
Gala ; Russell King ; 
linux-o...@vger.kernel.org; devicetree ; 
linux-arm-ker...@lists.infradead.org; linux kernel 
; sdliy...@gmail.com
Subject: Re: [PATCH] ARM: dts: am335x-boneblack: add i2c1 DT entry

* Robert Nelson  [160602 10:48]:
> On Thu, Jun 2, 2016 at 12:39 PM, Tony Lindgren  wrote:
> >
> > * Robert Nelson  [160602 10:39]:
> > > On Thu, Jun 2, 2016 at 2:41 AM, Yong Li  wrote:
> > >
> > > > From: Yong Li 
> > > >
> > > > Without this patch, I2C-1 is missing on beaglebone black boards
> > > >
> > > > Signed-off-by: Yong Li 
> > > > ---
> > > >  arch/arm/boot/dts/am335x-boneblack.dts | 15 +++
> > > >  1 file changed, 15 insertions(+)
> > > >
> > >
> > >
> > > This is also 'common' for the white/green, if your really going to 
> > > push this, please add it to:
> > >
> > > am335x-bone-common.dtsi
> >
> > But isn't this exposed on the cape pins? So the use can be whatever 
> > for these pins?
> 
> That is correct, "i2c1" is on the cape connector, with no primary 
> function defined.
> 
> Currently on mainline, the board and cape eeprom i2c bus's are enabled.
> 
> i2c0 = board eeprom
> i2c2 = 'cape' eeprom
> 
> personally, nak by me to add i2c1 by default, should use overlay's to enable 
> it.

Yes sounds like the best we can do is define it but set it with status = 
"disabled" for now.

Regards,

Tony


RE: [PATCH] ARM: dts: am335x-boneblack: add i2c1 DT entry

2016-06-02 Thread Li, Yong B
Hi Tony,

I can submit a V2 version about the "disabled", or just drop this patch?

Thanks,
Yong
-Original Message-
From: Tony Lindgren [mailto:t...@atomide.com] 
Sent: Friday, June 3, 2016 1:57 AM
To: Robert Nelson 
Cc: Li, Yong B ; Benoit Cousson ; 
Rob Herring ; Pawel Moll ; Mark Rutland 
; Ian Campbell ; Kumar 
Gala ; Russell King ; 
linux-o...@vger.kernel.org; devicetree ; 
linux-arm-ker...@lists.infradead.org; linux kernel 
; sdliy...@gmail.com
Subject: Re: [PATCH] ARM: dts: am335x-boneblack: add i2c1 DT entry

* Robert Nelson  [160602 10:48]:
> On Thu, Jun 2, 2016 at 12:39 PM, Tony Lindgren  wrote:
> >
> > * Robert Nelson  [160602 10:39]:
> > > On Thu, Jun 2, 2016 at 2:41 AM, Yong Li  wrote:
> > >
> > > > From: Yong Li 
> > > >
> > > > Without this patch, I2C-1 is missing on beaglebone black boards
> > > >
> > > > Signed-off-by: Yong Li 
> > > > ---
> > > >  arch/arm/boot/dts/am335x-boneblack.dts | 15 +++
> > > >  1 file changed, 15 insertions(+)
> > > >
> > >
> > >
> > > This is also 'common' for the white/green, if your really going to 
> > > push this, please add it to:
> > >
> > > am335x-bone-common.dtsi
> >
> > But isn't this exposed on the cape pins? So the use can be whatever 
> > for these pins?
> 
> That is correct, "i2c1" is on the cape connector, with no primary 
> function defined.
> 
> Currently on mainline, the board and cape eeprom i2c bus's are enabled.
> 
> i2c0 = board eeprom
> i2c2 = 'cape' eeprom
> 
> personally, nak by me to add i2c1 by default, should use overlay's to enable 
> it.

Yes sounds like the best we can do is define it but set it with status = 
"disabled" for now.

Regards,

Tony


Re: [PATCH v2 1/3] regulator: DT: Add DT property for operation mode configuration

2016-06-02 Thread Fan Chen
Hi Mark,

On Fri, 2016-06-03 at 01:16 +0100, Mark Brown wrote:
> On Tue, May 31, 2016 at 04:20:35PM +0800, Fan Chen wrote:
> > On Mon, 2016-05-23 at 12:28 +0100, Mark Brown wrote:

> > In the case of svs[1], which Henry mentioned in cover letter, it can be
> > regarded as a special consumer who requires very accurate voltage for
> > calibration the hardware in its initialization stage. So, this kinds of
> > consumers know their regulator very well and only need to switch to the
> > modes they want in the particular conditions.
> 
> So what you're trying to do here is not so much set a specific mode as
> set maximum regulation accuracy for a period of time.

exactly.

> > However, IIUC, you want a proposal to provide a sort of QoS framework
> > which can cover most of use cases who care about the regular quality in
> > runtime, is that correct?
> 
> Well, we want a coherent general use case that doesn't require a user to
> know the specific details of the regulator they're working with since we
> need to hide that knowledge from the user.

Agreed, it is hard to control once expose too many details. But I think
maybe there still be some parameter user has to aware to decide the
performance/quality in the common use cases you said below.

> 
> > IMHO, some quality index can be considered, for example:
> > Minimum Current Requirement (mA): If a user specified this constraint in
> > runtime, it means that he cares more about the supplying quality like
> > transient voltage drop, ripple above certain load.
> > Maximum Current Requirement (mA): If a user specified this constraint in
> > runtime, it means that he cares more about the power consumption under
> > certain load.
> > It could be a flexible way instead to tie the operation modes directly.
> 
> I'm not sure I really understand these distinctions to be honest,
> and specifying minimum loads seems very tricky from a robustness point
> of view.
> 
> If all you need right now is a way to maximize regulation quality that's
> probably a lot easier than anything based on absolute loads or on
> multiple "normal operation" modes - it takes a lot of the complexity out
> of things as there's no need to consider things like the distinctions
> between modes.  We just need a standard operating mode and to know the
> highest available mode.  I'm not sure exactly how to do that as an API
> though, let me think about it...  your use case isn't one I'd come
> across before.
Thanks. Please kindly give us suggestion for this case.
> 
> > BTW, we should encourage people here to share more use cases related to
> > regulator quality issues, especially in runtime, so we can evaluate the
> > most suitable index to fit the requirements.
> 
> More common use cases are around manually doing adaptive mode switching
> for regulators that are poor at automatically adjusting performance and
> handling of very low standby current situations where the adaption can
> consume enough power to register.

Best regards,
Fan



Re: [PATCH v2 1/3] regulator: DT: Add DT property for operation mode configuration

2016-06-02 Thread Fan Chen
Hi Mark,

On Fri, 2016-06-03 at 01:16 +0100, Mark Brown wrote:
> On Tue, May 31, 2016 at 04:20:35PM +0800, Fan Chen wrote:
> > On Mon, 2016-05-23 at 12:28 +0100, Mark Brown wrote:

> > In the case of svs[1], which Henry mentioned in cover letter, it can be
> > regarded as a special consumer who requires very accurate voltage for
> > calibration the hardware in its initialization stage. So, this kinds of
> > consumers know their regulator very well and only need to switch to the
> > modes they want in the particular conditions.
> 
> So what you're trying to do here is not so much set a specific mode as
> set maximum regulation accuracy for a period of time.

exactly.

> > However, IIUC, you want a proposal to provide a sort of QoS framework
> > which can cover most of use cases who care about the regular quality in
> > runtime, is that correct?
> 
> Well, we want a coherent general use case that doesn't require a user to
> know the specific details of the regulator they're working with since we
> need to hide that knowledge from the user.

Agreed, it is hard to control once expose too many details. But I think
maybe there still be some parameter user has to aware to decide the
performance/quality in the common use cases you said below.

> 
> > IMHO, some quality index can be considered, for example:
> > Minimum Current Requirement (mA): If a user specified this constraint in
> > runtime, it means that he cares more about the supplying quality like
> > transient voltage drop, ripple above certain load.
> > Maximum Current Requirement (mA): If a user specified this constraint in
> > runtime, it means that he cares more about the power consumption under
> > certain load.
> > It could be a flexible way instead to tie the operation modes directly.
> 
> I'm not sure I really understand these distinctions to be honest,
> and specifying minimum loads seems very tricky from a robustness point
> of view.
> 
> If all you need right now is a way to maximize regulation quality that's
> probably a lot easier than anything based on absolute loads or on
> multiple "normal operation" modes - it takes a lot of the complexity out
> of things as there's no need to consider things like the distinctions
> between modes.  We just need a standard operating mode and to know the
> highest available mode.  I'm not sure exactly how to do that as an API
> though, let me think about it...  your use case isn't one I'd come
> across before.
Thanks. Please kindly give us suggestion for this case.
> 
> > BTW, we should encourage people here to share more use cases related to
> > regulator quality issues, especially in runtime, so we can evaluate the
> > most suitable index to fit the requirements.
> 
> More common use cases are around manually doing adaptive mode switching
> for regulators that are poor at automatically adjusting performance and
> handling of very low standby current situations where the adaption can
> consume enough power to register.

Best regards,
Fan



Let me know about regressions in 4.7 (was: Re: Linux 4.7-rc1)

2016-06-02 Thread Thorsten Leemhuis
On 29.05.2016 19:00, Linus Torvalds wrote:
> […] Anyway, enough blathering. Go out and test. […]

And if you find any regressions in 4.7 pre-releases let me know via
regressi...@leemhuis.info I'll try to compile them into a list and post
it on LKML once a week similar to how Rafael did it until a few years
ago. My plan is to do it for 4.7 and maybe 4.8. Don't expect me to do it
for the next few years or so, as I fear kernel regression tracking
might turn out to be quite a lot of work -- and it's work I'll be doing
in my spare time for fun, just because I think someone should do it.

I'll keep my eyes open on LKML and will run a bugzilla query now and
then to find regressions on my own. But you know how it is: it's easy to
miss a mail and there are a few other places where regressions get
reported to, so please forward/bounce them to me or drop me a line if
you see something which should be tracked. Be warned, I also might
encourage users to show up on the right mailing lists to get in contact
with developers that might be responsible for the regression in
question, to hopefully get the regression fixed in the end.

In case you wonder who I am and if I'm capable of doing what I plan to
do: I have some experience with contributing to open source projects,
as I did quite a few things in the Fedora world ten years ago. Apart
from that I earn my money a technical writer that for more than
ten years now watches kernel development quite closely, because I write
about it for a German publishing company. Use your favorite search
engine if you want to know more (for a few years some of the stuff I
wrote was translated to English and published on
http://www.h-online.com/open/). In the end it means: I'm not a
programmer and until now only read LKML, but I think I know quite well
how things work.

Ohh, and if you wonder why I so crazy and just for fun want to do
regression tracking: In the past few years I gave a bunch of talks about
improvements in the latest Linux kernel versions. During or after those
talks quite often someone complained about regressions in the kernel.
People said there were to many of them, complained that regression they
reported were ignored, or found it hard to find the right place to
report regressions.

Cu, knurd

P.S.: BTW for those that run Fedora releases: I maintain a RPM
repository that provides kernel packages build from recent mainline git
snapshots for recent Fedora releases; the latest stable releases are
available there, too. IOW: you can get everything in those repos to
easily run mainline kernels and check for regressions. Find more details
on https://fedoraproject.org/wiki/Kernel_Vanilla_Repositories


Let me know about regressions in 4.7 (was: Re: Linux 4.7-rc1)

2016-06-02 Thread Thorsten Leemhuis
On 29.05.2016 19:00, Linus Torvalds wrote:
> […] Anyway, enough blathering. Go out and test. […]

And if you find any regressions in 4.7 pre-releases let me know via
regressi...@leemhuis.info I'll try to compile them into a list and post
it on LKML once a week similar to how Rafael did it until a few years
ago. My plan is to do it for 4.7 and maybe 4.8. Don't expect me to do it
for the next few years or so, as I fear kernel regression tracking
might turn out to be quite a lot of work -- and it's work I'll be doing
in my spare time for fun, just because I think someone should do it.

I'll keep my eyes open on LKML and will run a bugzilla query now and
then to find regressions on my own. But you know how it is: it's easy to
miss a mail and there are a few other places where regressions get
reported to, so please forward/bounce them to me or drop me a line if
you see something which should be tracked. Be warned, I also might
encourage users to show up on the right mailing lists to get in contact
with developers that might be responsible for the regression in
question, to hopefully get the regression fixed in the end.

In case you wonder who I am and if I'm capable of doing what I plan to
do: I have some experience with contributing to open source projects,
as I did quite a few things in the Fedora world ten years ago. Apart
from that I earn my money a technical writer that for more than
ten years now watches kernel development quite closely, because I write
about it for a German publishing company. Use your favorite search
engine if you want to know more (for a few years some of the stuff I
wrote was translated to English and published on
http://www.h-online.com/open/). In the end it means: I'm not a
programmer and until now only read LKML, but I think I know quite well
how things work.

Ohh, and if you wonder why I so crazy and just for fun want to do
regression tracking: In the past few years I gave a bunch of talks about
improvements in the latest Linux kernel versions. During or after those
talks quite often someone complained about regressions in the kernel.
People said there were to many of them, complained that regression they
reported were ignored, or found it hard to find the right place to
report regressions.

Cu, knurd

P.S.: BTW for those that run Fedora releases: I maintain a RPM
repository that provides kernel packages build from recent mainline git
snapshots for recent Fedora releases; the latest stable releases are
available there, too. IOW: you can get everything in those repos to
easily run mainline kernels and check for regressions. Find more details
on https://fedoraproject.org/wiki/Kernel_Vanilla_Repositories


Re: [PATCH] sched/cputime: add steal clock warps handling during cpu hotplug

2016-06-02 Thread Wanpeng Li
2016-06-02 21:59 GMT+08:00 Rik van Riel :
> On Thu, 2016-06-02 at 14:00 +0200, Peter Zijlstra wrote:
>> On Thu, Jun 02, 2016 at 07:57:19PM +0800, Wanpeng Li wrote:
>> >
>> > From: Wanpeng Li 
>> >
>> > I observed that sometimes st is 100% instantaneous, then idle is
>> > 100%
>> > even if there is a cpu hog on the guest cpu after the cpu hotplug
>> > comes
>> > back(N.B. both guest and host are latest 4.7-rc1, this can not
>> > always
>> > be readily reproduced). I add trace to capture it as below:
>> >
>> > cpuhp/1-12[001] d.h1   167.461657: account_process_tick: steal
>> > = 1291385514, prev_steal_time = 0
>> > cpuhp/1-12[001] d.h1   167.461659: account_process_tick:
>> > steal_jiffies = 1291
>> > -0 [001] d.h1   167.462663: account_process_tick: steal =
>> > 18732255, prev_steal_time = 129100
>> > -0 [001] d.h1   167.462664: account_process_tick:
>> > steal_jiffies = 18446744072437
>> >
>> > The steal clock warps and then steal_jiffies overflow, this patch
>> > align
>> > prev_steal_time to the new steal clock timestamp, in order to
>> > avoid
>> > overflow and st stuff can continue to work.
>> I would rather suggest fixing the steal clock thing to not jump like
>> that; is that at all possible?
>
> Not always possible, I suspect.
>
> If a guest is saved to disk and later restored (eg. after
> a host reboot), or live migrated to another host, I would
> expect to get totally disjoint steal time statistics from
> the "new run" of the guest (which is the same run of the
> guest OS).
>
> In fact, this code may also need to deal with the case
> where steal time suddenly increases by a ludicrous amount,
> and ignore those events, too.
>
> A safe threshold might be to only apply steal times that
> are positive and smaller than one second (as long as nohz_full
> has the one second timer tick left), ignoring intervals that
> are negative or longer than a second, and using those to sync
> up the guest with the host.

Good point, thanks for your review, Rik. :) Just send out v2 to do it.

Regards,
Wanpeng Li


Re: [PATCH] sched/cputime: add steal clock warps handling during cpu hotplug

2016-06-02 Thread Wanpeng Li
2016-06-02 21:59 GMT+08:00 Rik van Riel :
> On Thu, 2016-06-02 at 14:00 +0200, Peter Zijlstra wrote:
>> On Thu, Jun 02, 2016 at 07:57:19PM +0800, Wanpeng Li wrote:
>> >
>> > From: Wanpeng Li 
>> >
>> > I observed that sometimes st is 100% instantaneous, then idle is
>> > 100%
>> > even if there is a cpu hog on the guest cpu after the cpu hotplug
>> > comes
>> > back(N.B. both guest and host are latest 4.7-rc1, this can not
>> > always
>> > be readily reproduced). I add trace to capture it as below:
>> >
>> > cpuhp/1-12[001] d.h1   167.461657: account_process_tick: steal
>> > = 1291385514, prev_steal_time = 0
>> > cpuhp/1-12[001] d.h1   167.461659: account_process_tick:
>> > steal_jiffies = 1291
>> > -0 [001] d.h1   167.462663: account_process_tick: steal =
>> > 18732255, prev_steal_time = 129100
>> > -0 [001] d.h1   167.462664: account_process_tick:
>> > steal_jiffies = 18446744072437
>> >
>> > The steal clock warps and then steal_jiffies overflow, this patch
>> > align
>> > prev_steal_time to the new steal clock timestamp, in order to
>> > avoid
>> > overflow and st stuff can continue to work.
>> I would rather suggest fixing the steal clock thing to not jump like
>> that; is that at all possible?
>
> Not always possible, I suspect.
>
> If a guest is saved to disk and later restored (eg. after
> a host reboot), or live migrated to another host, I would
> expect to get totally disjoint steal time statistics from
> the "new run" of the guest (which is the same run of the
> guest OS).
>
> In fact, this code may also need to deal with the case
> where steal time suddenly increases by a ludicrous amount,
> and ignore those events, too.
>
> A safe threshold might be to only apply steal times that
> are positive and smaller than one second (as long as nohz_full
> has the one second timer tick left), ignoring intervals that
> are negative or longer than a second, and using those to sync
> up the guest with the host.

Good point, thanks for your review, Rik. :) Just send out v2 to do it.

Regards,
Wanpeng Li


Re: ath9k gpio request

2016-06-02 Thread Kalle Valo
Sudip Mukherjee  writes:

> On Thursday 02 June 2016 01:32 PM, Pan, Miaoqing wrote:
>> Seems there are something wrong in the datasheet,  try
>>
>> --- a/drivers/net/wireless/ath/ath9k/reg.h
>> +++ b/drivers/net/wireless/ath/ath9k/reg.h
>> @@ -1122,8 +1122,8 @@ enum {
>>   #define AR9300_NUM_GPIO  16
>>   #define AR9330_NUM_GPIO 16
>>   #define AR9340_NUM_GPIO 23
>> -#define AR9462_NUM_GPIO 10
>> -#define AR9485_NUM_GPIO 12
>> +#define AR9462_NUM_GPIO 14
>> +#define AR9485_NUM_GPIO 11
>>   #define AR9531_NUM_GPIO 18
>>   #define AR9550_NUM_GPIO 24
>>   #define AR9561_NUM_GPIO 23
>> @@ -1139,8 +1139,8 @@ enum {
>>   #define AR9300_GPIO_MASK0xF4FF
>>   #define AR9330_GPIO_MASK0xF4FF
>>   #define AR9340_GPIO_MASK0x000F
>> -#define AR9462_GPIO_MASK0x03FF
>> -#define AR9485_GPIO_MASK0x0FFF
>> +#define AR9462_GPIO_MASK0x3FFF
>> +#define AR9485_GPIO_MASK0x07FF
>>   #define AR9531_GPIO_MASK0x000F
>>   #define AR9550_GPIO_MASK0x000F
>>   #define AR9561_GPIO_MASK0x000F
>
> solves the problem.
>
> Tested-by: Sudip Mukherjee 

Great, thanks for testing everyone. Miaoqing, please send a proper patch
ASAP and I'll push it to 4.7.

-- 
Kalle Valo


Re: ath9k gpio request

2016-06-02 Thread Kalle Valo
Sudip Mukherjee  writes:

> On Thursday 02 June 2016 01:32 PM, Pan, Miaoqing wrote:
>> Seems there are something wrong in the datasheet,  try
>>
>> --- a/drivers/net/wireless/ath/ath9k/reg.h
>> +++ b/drivers/net/wireless/ath/ath9k/reg.h
>> @@ -1122,8 +1122,8 @@ enum {
>>   #define AR9300_NUM_GPIO  16
>>   #define AR9330_NUM_GPIO 16
>>   #define AR9340_NUM_GPIO 23
>> -#define AR9462_NUM_GPIO 10
>> -#define AR9485_NUM_GPIO 12
>> +#define AR9462_NUM_GPIO 14
>> +#define AR9485_NUM_GPIO 11
>>   #define AR9531_NUM_GPIO 18
>>   #define AR9550_NUM_GPIO 24
>>   #define AR9561_NUM_GPIO 23
>> @@ -1139,8 +1139,8 @@ enum {
>>   #define AR9300_GPIO_MASK0xF4FF
>>   #define AR9330_GPIO_MASK0xF4FF
>>   #define AR9340_GPIO_MASK0x000F
>> -#define AR9462_GPIO_MASK0x03FF
>> -#define AR9485_GPIO_MASK0x0FFF
>> +#define AR9462_GPIO_MASK0x3FFF
>> +#define AR9485_GPIO_MASK0x07FF
>>   #define AR9531_GPIO_MASK0x000F
>>   #define AR9550_GPIO_MASK0x000F
>>   #define AR9561_GPIO_MASK0x000F
>
> solves the problem.
>
> Tested-by: Sudip Mukherjee 

Great, thanks for testing everyone. Miaoqing, please send a proper patch
ASAP and I'll push it to 4.7.

-- 
Kalle Valo


[PATCH V3 0/8] cpufreq: cleanups and reorganization

2016-06-02 Thread Viresh Kumar
Hi Rafael,

This cleans up cpufreq core and few platform drivers a bit. Its mostly
around cleaning up the usage of cpufreq_frequency_table_target(), which
will be optimized in a separate series.

V2->V3:
- Fixed an issue with cpu_cooling.c (Javi)
- Included 2 new patches from the other cleanup series.
- Added Acked-by: from Javi for cpu_cooling.c

Viresh Kumar (8):
  ARM: davinci: Sort frequency table
  cpufreq: s3c24xx: Remove useless checks
  cpufreq: Remove cpufreq_frequency_get_table()
  cpufreq: ondemand: Don't keep a copy of freq_table pointer
  cpufreq: Drop freq-table param to cpufreq_frequency_table_target()
  cpufreq: Drop 'freq_table' argument of __target_index()
  cpufreq: Return index from cpufreq_frequency_table_target()
  cpufreq: davinci: Reuse cpufreq_generic_frequency_table_verify()

 Documentation/cpu-freq/cpu-drivers.txt |  8 ++---
 arch/arm/mach-davinci/da850.c  | 16 +
 drivers/cpufreq/amd_freq_sensitivity.c | 10 +++---
 drivers/cpufreq/cpufreq.c  | 66 --
 drivers/cpufreq/cpufreq_ondemand.c | 25 ++---
 drivers/cpufreq/cpufreq_ondemand.h |  1 -
 drivers/cpufreq/cpufreq_stats.c|  3 +-
 drivers/cpufreq/davinci-cpufreq.c  | 22 +---
 drivers/cpufreq/freq_table.c   | 35 +-
 drivers/cpufreq/powernv-cpufreq.c  |  5 ++-
 drivers/cpufreq/ppc_cbe_cpufreq_pmi.c  |  3 +-
 drivers/cpufreq/s3c24xx-cpufreq.c  | 33 -
 drivers/cpufreq/s5pv210-cpufreq.c  |  8 ++---
 drivers/thermal/cpu_cooling.c  | 24 ++---
 include/linux/cpufreq.h|  6 +---
 15 files changed, 100 insertions(+), 165 deletions(-)

-- 
2.7.1.410.g6faf27b



[PATCH V3 0/8] cpufreq: cleanups and reorganization

2016-06-02 Thread Viresh Kumar
Hi Rafael,

This cleans up cpufreq core and few platform drivers a bit. Its mostly
around cleaning up the usage of cpufreq_frequency_table_target(), which
will be optimized in a separate series.

V2->V3:
- Fixed an issue with cpu_cooling.c (Javi)
- Included 2 new patches from the other cleanup series.
- Added Acked-by: from Javi for cpu_cooling.c

Viresh Kumar (8):
  ARM: davinci: Sort frequency table
  cpufreq: s3c24xx: Remove useless checks
  cpufreq: Remove cpufreq_frequency_get_table()
  cpufreq: ondemand: Don't keep a copy of freq_table pointer
  cpufreq: Drop freq-table param to cpufreq_frequency_table_target()
  cpufreq: Drop 'freq_table' argument of __target_index()
  cpufreq: Return index from cpufreq_frequency_table_target()
  cpufreq: davinci: Reuse cpufreq_generic_frequency_table_verify()

 Documentation/cpu-freq/cpu-drivers.txt |  8 ++---
 arch/arm/mach-davinci/da850.c  | 16 +
 drivers/cpufreq/amd_freq_sensitivity.c | 10 +++---
 drivers/cpufreq/cpufreq.c  | 66 --
 drivers/cpufreq/cpufreq_ondemand.c | 25 ++---
 drivers/cpufreq/cpufreq_ondemand.h |  1 -
 drivers/cpufreq/cpufreq_stats.c|  3 +-
 drivers/cpufreq/davinci-cpufreq.c  | 22 +---
 drivers/cpufreq/freq_table.c   | 35 +-
 drivers/cpufreq/powernv-cpufreq.c  |  5 ++-
 drivers/cpufreq/ppc_cbe_cpufreq_pmi.c  |  3 +-
 drivers/cpufreq/s3c24xx-cpufreq.c  | 33 -
 drivers/cpufreq/s5pv210-cpufreq.c  |  8 ++---
 drivers/thermal/cpu_cooling.c  | 24 ++---
 include/linux/cpufreq.h|  6 +---
 15 files changed, 100 insertions(+), 165 deletions(-)

-- 
2.7.1.410.g6faf27b



[PATCH V3 4/8] cpufreq: ondemand: Don't keep a copy of freq_table pointer

2016-06-02 Thread Viresh Kumar
There is absolutely no need to keep a copy to the freq-table in 'struct
od_policy_dbs_info'. Use policy->freq_table instead.

Signed-off-by: Viresh Kumar 
---
 drivers/cpufreq/amd_freq_sensitivity.c |  7 +++
 drivers/cpufreq/cpufreq_ondemand.c | 22 +++---
 drivers/cpufreq/cpufreq_ondemand.h |  1 -
 3 files changed, 14 insertions(+), 16 deletions(-)

diff --git a/drivers/cpufreq/amd_freq_sensitivity.c 
b/drivers/cpufreq/amd_freq_sensitivity.c
index 404360cad25c..bc86816693a8 100644
--- a/drivers/cpufreq/amd_freq_sensitivity.c
+++ b/drivers/cpufreq/amd_freq_sensitivity.c
@@ -48,9 +48,8 @@ static unsigned int amd_powersave_bias_target(struct 
cpufreq_policy *policy,
struct policy_dbs_info *policy_dbs = policy->governor_data;
struct dbs_data *od_data = policy_dbs->dbs_data;
struct od_dbs_tuners *od_tuners = od_data->tuners;
-   struct od_policy_dbs_info *od_info = to_dbs_info(policy_dbs);
 
-   if (!od_info->freq_table)
+   if (!policy->freq_table)
return freq_next;
 
rdmsr_on_cpu(policy->cpu, MSR_AMD64_FREQ_SENSITIVITY_ACTUAL,
@@ -93,9 +92,9 @@ static unsigned int amd_powersave_bias_target(struct 
cpufreq_policy *policy,
unsigned int index;
 
cpufreq_frequency_table_target(policy,
-   od_info->freq_table, policy->cur - 1,
+   policy->freq_table, policy->cur - 1,
CPUFREQ_RELATION_H, );
-   freq_next = od_info->freq_table[index].frequency;
+   freq_next = policy->freq_table[index].frequency;
}
 
data->freq_prev = freq_next;
diff --git a/drivers/cpufreq/cpufreq_ondemand.c 
b/drivers/cpufreq/cpufreq_ondemand.c
index 4d2fe2710c5d..528353f204fd 100644
--- a/drivers/cpufreq/cpufreq_ondemand.c
+++ b/drivers/cpufreq/cpufreq_ondemand.c
@@ -71,28 +71,29 @@ static unsigned int generic_powersave_bias_target(struct 
cpufreq_policy *policy,
struct od_policy_dbs_info *dbs_info = to_dbs_info(policy_dbs);
struct dbs_data *dbs_data = policy_dbs->dbs_data;
struct od_dbs_tuners *od_tuners = dbs_data->tuners;
+   struct cpufreq_frequency_table *freq_table = policy->freq_table;
 
-   if (!dbs_info->freq_table) {
+   if (!freq_table) {
dbs_info->freq_lo = 0;
dbs_info->freq_lo_delay_us = 0;
return freq_next;
}
 
-   cpufreq_frequency_table_target(policy, dbs_info->freq_table, freq_next,
-   relation, );
-   freq_req = dbs_info->freq_table[index].frequency;
+   cpufreq_frequency_table_target(policy, freq_table, freq_next, relation,
+  );
+   freq_req = freq_table[index].frequency;
freq_reduc = freq_req * od_tuners->powersave_bias / 1000;
freq_avg = freq_req - freq_reduc;
 
/* Find freq bounds for freq_avg in freq_table */
index = 0;
-   cpufreq_frequency_table_target(policy, dbs_info->freq_table, freq_avg,
-   CPUFREQ_RELATION_H, );
-   freq_lo = dbs_info->freq_table[index].frequency;
+   cpufreq_frequency_table_target(policy, freq_table, freq_avg,
+  CPUFREQ_RELATION_H, );
+   freq_lo = freq_table[index].frequency;
index = 0;
-   cpufreq_frequency_table_target(policy, dbs_info->freq_table, freq_avg,
-   CPUFREQ_RELATION_L, );
-   freq_hi = dbs_info->freq_table[index].frequency;
+   cpufreq_frequency_table_target(policy, freq_table, freq_avg,
+  CPUFREQ_RELATION_L, );
+   freq_hi = freq_table[index].frequency;
 
/* Find out how long we have to be in hi and lo freqs */
if (freq_hi == freq_lo) {
@@ -113,7 +114,6 @@ static void ondemand_powersave_bias_init(struct 
cpufreq_policy *policy)
 {
struct od_policy_dbs_info *dbs_info = 
to_dbs_info(policy->governor_data);
 
-   dbs_info->freq_table = policy->freq_table;
dbs_info->freq_lo = 0;
 }
 
diff --git a/drivers/cpufreq/cpufreq_ondemand.h 
b/drivers/cpufreq/cpufreq_ondemand.h
index f0121db3cd9e..640ea4e97106 100644
--- a/drivers/cpufreq/cpufreq_ondemand.h
+++ b/drivers/cpufreq/cpufreq_ondemand.h
@@ -13,7 +13,6 @@
 
 struct od_policy_dbs_info {
struct policy_dbs_info policy_dbs;
-   struct cpufreq_frequency_table *freq_table;
unsigned int freq_lo;
unsigned int freq_lo_delay_us;
unsigned int freq_hi_delay_us;
-- 
2.7.1.410.g6faf27b



[PATCH V3 1/8] ARM: davinci: Sort frequency table

2016-06-02 Thread Viresh Kumar
This is required for some of the changes in cpufreq core. There was only
one function dependent on the order of the table, that is fixed as well.

Cc: Sekhar Nori 
Cc: Kevin Hilman 
Signed-off-by: Viresh Kumar 
---
 arch/arm/mach-davinci/da850.c | 16 +---
 1 file changed, 9 insertions(+), 7 deletions(-)

diff --git a/arch/arm/mach-davinci/da850.c b/arch/arm/mach-davinci/da850.c
index 239886299968..f683c119cfed 100644
--- a/arch/arm/mach-davinci/da850.c
+++ b/arch/arm/mach-davinci/da850.c
@@ -1004,13 +1004,14 @@ static const struct da850_opp da850_opp_96 = {
.frequency = freq * 1000, \
}
 
+/* Table sorted in ascending order of frequencies */
 static struct cpufreq_frequency_table da850_freq_table[] = {
-   OPP(456),
-   OPP(408),
-   OPP(372),
-   OPP(300),
-   OPP(200),
OPP(96),
+   OPP(200),
+   OPP(300),
+   OPP(372),
+   OPP(408),
+   OPP(456),
{
.driver_data= 0,
.frequency  = CPUFREQ_TABLE_END,
@@ -1076,8 +1077,9 @@ int da850_register_cpufreq(char *async_clk)
clk_add_alias("async", da850_cpufreq_device.name,
async_clk, NULL);
for (i = 0; i < ARRAY_SIZE(da850_freq_table); i++) {
-   if (da850_freq_table[i].frequency <= da850_max_speed) {
-   cpufreq_info.freq_table = _freq_table[i];
+   if (da850_freq_table[i].frequency > da850_max_speed) {
+   _freq_table[i].driver_data = 0;
+   _freq_table[i].frequency = CPUFREQ_TABLE_END;
break;
}
}
-- 
2.7.1.410.g6faf27b



[PATCH V3 4/8] cpufreq: ondemand: Don't keep a copy of freq_table pointer

2016-06-02 Thread Viresh Kumar
There is absolutely no need to keep a copy to the freq-table in 'struct
od_policy_dbs_info'. Use policy->freq_table instead.

Signed-off-by: Viresh Kumar 
---
 drivers/cpufreq/amd_freq_sensitivity.c |  7 +++
 drivers/cpufreq/cpufreq_ondemand.c | 22 +++---
 drivers/cpufreq/cpufreq_ondemand.h |  1 -
 3 files changed, 14 insertions(+), 16 deletions(-)

diff --git a/drivers/cpufreq/amd_freq_sensitivity.c 
b/drivers/cpufreq/amd_freq_sensitivity.c
index 404360cad25c..bc86816693a8 100644
--- a/drivers/cpufreq/amd_freq_sensitivity.c
+++ b/drivers/cpufreq/amd_freq_sensitivity.c
@@ -48,9 +48,8 @@ static unsigned int amd_powersave_bias_target(struct 
cpufreq_policy *policy,
struct policy_dbs_info *policy_dbs = policy->governor_data;
struct dbs_data *od_data = policy_dbs->dbs_data;
struct od_dbs_tuners *od_tuners = od_data->tuners;
-   struct od_policy_dbs_info *od_info = to_dbs_info(policy_dbs);
 
-   if (!od_info->freq_table)
+   if (!policy->freq_table)
return freq_next;
 
rdmsr_on_cpu(policy->cpu, MSR_AMD64_FREQ_SENSITIVITY_ACTUAL,
@@ -93,9 +92,9 @@ static unsigned int amd_powersave_bias_target(struct 
cpufreq_policy *policy,
unsigned int index;
 
cpufreq_frequency_table_target(policy,
-   od_info->freq_table, policy->cur - 1,
+   policy->freq_table, policy->cur - 1,
CPUFREQ_RELATION_H, );
-   freq_next = od_info->freq_table[index].frequency;
+   freq_next = policy->freq_table[index].frequency;
}
 
data->freq_prev = freq_next;
diff --git a/drivers/cpufreq/cpufreq_ondemand.c 
b/drivers/cpufreq/cpufreq_ondemand.c
index 4d2fe2710c5d..528353f204fd 100644
--- a/drivers/cpufreq/cpufreq_ondemand.c
+++ b/drivers/cpufreq/cpufreq_ondemand.c
@@ -71,28 +71,29 @@ static unsigned int generic_powersave_bias_target(struct 
cpufreq_policy *policy,
struct od_policy_dbs_info *dbs_info = to_dbs_info(policy_dbs);
struct dbs_data *dbs_data = policy_dbs->dbs_data;
struct od_dbs_tuners *od_tuners = dbs_data->tuners;
+   struct cpufreq_frequency_table *freq_table = policy->freq_table;
 
-   if (!dbs_info->freq_table) {
+   if (!freq_table) {
dbs_info->freq_lo = 0;
dbs_info->freq_lo_delay_us = 0;
return freq_next;
}
 
-   cpufreq_frequency_table_target(policy, dbs_info->freq_table, freq_next,
-   relation, );
-   freq_req = dbs_info->freq_table[index].frequency;
+   cpufreq_frequency_table_target(policy, freq_table, freq_next, relation,
+  );
+   freq_req = freq_table[index].frequency;
freq_reduc = freq_req * od_tuners->powersave_bias / 1000;
freq_avg = freq_req - freq_reduc;
 
/* Find freq bounds for freq_avg in freq_table */
index = 0;
-   cpufreq_frequency_table_target(policy, dbs_info->freq_table, freq_avg,
-   CPUFREQ_RELATION_H, );
-   freq_lo = dbs_info->freq_table[index].frequency;
+   cpufreq_frequency_table_target(policy, freq_table, freq_avg,
+  CPUFREQ_RELATION_H, );
+   freq_lo = freq_table[index].frequency;
index = 0;
-   cpufreq_frequency_table_target(policy, dbs_info->freq_table, freq_avg,
-   CPUFREQ_RELATION_L, );
-   freq_hi = dbs_info->freq_table[index].frequency;
+   cpufreq_frequency_table_target(policy, freq_table, freq_avg,
+  CPUFREQ_RELATION_L, );
+   freq_hi = freq_table[index].frequency;
 
/* Find out how long we have to be in hi and lo freqs */
if (freq_hi == freq_lo) {
@@ -113,7 +114,6 @@ static void ondemand_powersave_bias_init(struct 
cpufreq_policy *policy)
 {
struct od_policy_dbs_info *dbs_info = 
to_dbs_info(policy->governor_data);
 
-   dbs_info->freq_table = policy->freq_table;
dbs_info->freq_lo = 0;
 }
 
diff --git a/drivers/cpufreq/cpufreq_ondemand.h 
b/drivers/cpufreq/cpufreq_ondemand.h
index f0121db3cd9e..640ea4e97106 100644
--- a/drivers/cpufreq/cpufreq_ondemand.h
+++ b/drivers/cpufreq/cpufreq_ondemand.h
@@ -13,7 +13,6 @@
 
 struct od_policy_dbs_info {
struct policy_dbs_info policy_dbs;
-   struct cpufreq_frequency_table *freq_table;
unsigned int freq_lo;
unsigned int freq_lo_delay_us;
unsigned int freq_hi_delay_us;
-- 
2.7.1.410.g6faf27b



[PATCH V3 1/8] ARM: davinci: Sort frequency table

2016-06-02 Thread Viresh Kumar
This is required for some of the changes in cpufreq core. There was only
one function dependent on the order of the table, that is fixed as well.

Cc: Sekhar Nori 
Cc: Kevin Hilman 
Signed-off-by: Viresh Kumar 
---
 arch/arm/mach-davinci/da850.c | 16 +---
 1 file changed, 9 insertions(+), 7 deletions(-)

diff --git a/arch/arm/mach-davinci/da850.c b/arch/arm/mach-davinci/da850.c
index 239886299968..f683c119cfed 100644
--- a/arch/arm/mach-davinci/da850.c
+++ b/arch/arm/mach-davinci/da850.c
@@ -1004,13 +1004,14 @@ static const struct da850_opp da850_opp_96 = {
.frequency = freq * 1000, \
}
 
+/* Table sorted in ascending order of frequencies */
 static struct cpufreq_frequency_table da850_freq_table[] = {
-   OPP(456),
-   OPP(408),
-   OPP(372),
-   OPP(300),
-   OPP(200),
OPP(96),
+   OPP(200),
+   OPP(300),
+   OPP(372),
+   OPP(408),
+   OPP(456),
{
.driver_data= 0,
.frequency  = CPUFREQ_TABLE_END,
@@ -1076,8 +1077,9 @@ int da850_register_cpufreq(char *async_clk)
clk_add_alias("async", da850_cpufreq_device.name,
async_clk, NULL);
for (i = 0; i < ARRAY_SIZE(da850_freq_table); i++) {
-   if (da850_freq_table[i].frequency <= da850_max_speed) {
-   cpufreq_info.freq_table = _freq_table[i];
+   if (da850_freq_table[i].frequency > da850_max_speed) {
+   _freq_table[i].driver_data = 0;
+   _freq_table[i].frequency = CPUFREQ_TABLE_END;
break;
}
}
-- 
2.7.1.410.g6faf27b



[PATCH V3 7/8] cpufreq: Return index from cpufreq_frequency_table_target()

2016-06-02 Thread Viresh Kumar
This routine can't fail unless the frequency table is invalid and
doesn't contain any valid entries.

Make it return the index and WARN() in case it is used for an invalid
table.

Signed-off-by: Viresh Kumar 
---
 Documentation/cpu-freq/cpu-drivers.txt |  7 +++
 drivers/cpufreq/amd_freq_sensitivity.c |  4 ++--
 drivers/cpufreq/cpufreq.c  |  9 ++---
 drivers/cpufreq/cpufreq_ondemand.c | 14 ++
 drivers/cpufreq/freq_table.c   | 24 +---
 drivers/cpufreq/powernv-cpufreq.c  |  4 ++--
 drivers/cpufreq/s3c24xx-cpufreq.c  | 26 ++
 drivers/cpufreq/s5pv210-cpufreq.c  |  7 ++-
 include/linux/cpufreq.h|  3 +--
 9 files changed, 37 insertions(+), 61 deletions(-)

diff --git a/Documentation/cpu-freq/cpu-drivers.txt 
b/Documentation/cpu-freq/cpu-drivers.txt
index 74e812f0719c..772b94fde264 100644
--- a/Documentation/cpu-freq/cpu-drivers.txt
+++ b/Documentation/cpu-freq/cpu-drivers.txt
@@ -245,12 +245,11 @@ policy->max, and all other criteria are met. This is 
helpful for the
 
 int cpufreq_frequency_table_target(struct cpufreq_policy *policy,
unsigned int target_freq,
-   unsigned int relation,
-   unsigned int *index);
+   unsigned int relation);
 
 is the corresponding frequency table helper for the ->target
-stage. Just pass the values to this function, and the unsigned int
-index returns the number of the frequency table entry which contains
+stage. Just pass the values to this function, and this function
+returns the number of the frequency table entry which contains
 the frequency the CPU shall be set to.
 
 The following macros can be used as iterators over cpufreq_frequency_table:
diff --git a/drivers/cpufreq/amd_freq_sensitivity.c 
b/drivers/cpufreq/amd_freq_sensitivity.c
index 3bea1bb791a9..6d5dc04c3a37 100644
--- a/drivers/cpufreq/amd_freq_sensitivity.c
+++ b/drivers/cpufreq/amd_freq_sensitivity.c
@@ -91,8 +91,8 @@ static unsigned int amd_powersave_bias_target(struct 
cpufreq_policy *policy,
else {
unsigned int index;
 
-   cpufreq_frequency_table_target(policy,
-   policy->cur - 1, CPUFREQ_RELATION_H, );
+   index = cpufreq_frequency_table_target(policy,
+   policy->cur - 1, CPUFREQ_RELATION_H);
freq_next = policy->freq_table[index].frequency;
}
 
diff --git a/drivers/cpufreq/cpufreq.c b/drivers/cpufreq/cpufreq.c
index 30f05dd5c872..9ae58a18ccb9 100644
--- a/drivers/cpufreq/cpufreq.c
+++ b/drivers/cpufreq/cpufreq.c
@@ -1914,7 +1914,7 @@ int __cpufreq_driver_target(struct cpufreq_policy *policy,
unsigned int relation)
 {
unsigned int old_target_freq = target_freq;
-   int index, retval;
+   int index;
 
if (cpufreq_disabled())
return -ENODEV;
@@ -1943,12 +1943,7 @@ int __cpufreq_driver_target(struct cpufreq_policy 
*policy,
if (!cpufreq_driver->target_index)
return -EINVAL;
 
-   retval = cpufreq_frequency_table_target(policy, target_freq, relation,
-   );
-   if (unlikely(retval)) {
-   pr_err("%s: Unable to find matching freq\n", __func__);
-   return retval;
-   }
+   index = cpufreq_frequency_table_target(policy, target_freq, relation);
 
return __target_index(policy, index);
 }
diff --git a/drivers/cpufreq/cpufreq_ondemand.c 
b/drivers/cpufreq/cpufreq_ondemand.c
index 2ee476f5a2bd..0c93cd9dee99 100644
--- a/drivers/cpufreq/cpufreq_ondemand.c
+++ b/drivers/cpufreq/cpufreq_ondemand.c
@@ -65,7 +65,7 @@ static unsigned int generic_powersave_bias_target(struct 
cpufreq_policy *policy,
 {
unsigned int freq_req, freq_reduc, freq_avg;
unsigned int freq_hi, freq_lo;
-   unsigned int index = 0;
+   unsigned int index;
unsigned int delay_hi_us;
struct policy_dbs_info *policy_dbs = policy->governor_data;
struct od_policy_dbs_info *dbs_info = to_dbs_info(policy_dbs);
@@ -79,19 +79,17 @@ static unsigned int generic_powersave_bias_target(struct 
cpufreq_policy *policy,
return freq_next;
}
 
-   cpufreq_frequency_table_target(policy, freq_next, relation, );
+   index = cpufreq_frequency_table_target(policy, freq_next, relation);
freq_req = freq_table[index].frequency;
freq_reduc = freq_req * od_tuners->powersave_bias / 1000;
freq_avg = freq_req - freq_reduc;
 
/* Find freq bounds for freq_avg in freq_table */
-   index = 0;
-   cpufreq_frequency_table_target(policy, freq_avg, CPUFREQ_RELATION_H,
-  );
+   index = 

[PATCH V3 7/8] cpufreq: Return index from cpufreq_frequency_table_target()

2016-06-02 Thread Viresh Kumar
This routine can't fail unless the frequency table is invalid and
doesn't contain any valid entries.

Make it return the index and WARN() in case it is used for an invalid
table.

Signed-off-by: Viresh Kumar 
---
 Documentation/cpu-freq/cpu-drivers.txt |  7 +++
 drivers/cpufreq/amd_freq_sensitivity.c |  4 ++--
 drivers/cpufreq/cpufreq.c  |  9 ++---
 drivers/cpufreq/cpufreq_ondemand.c | 14 ++
 drivers/cpufreq/freq_table.c   | 24 +---
 drivers/cpufreq/powernv-cpufreq.c  |  4 ++--
 drivers/cpufreq/s3c24xx-cpufreq.c  | 26 ++
 drivers/cpufreq/s5pv210-cpufreq.c  |  7 ++-
 include/linux/cpufreq.h|  3 +--
 9 files changed, 37 insertions(+), 61 deletions(-)

diff --git a/Documentation/cpu-freq/cpu-drivers.txt 
b/Documentation/cpu-freq/cpu-drivers.txt
index 74e812f0719c..772b94fde264 100644
--- a/Documentation/cpu-freq/cpu-drivers.txt
+++ b/Documentation/cpu-freq/cpu-drivers.txt
@@ -245,12 +245,11 @@ policy->max, and all other criteria are met. This is 
helpful for the
 
 int cpufreq_frequency_table_target(struct cpufreq_policy *policy,
unsigned int target_freq,
-   unsigned int relation,
-   unsigned int *index);
+   unsigned int relation);
 
 is the corresponding frequency table helper for the ->target
-stage. Just pass the values to this function, and the unsigned int
-index returns the number of the frequency table entry which contains
+stage. Just pass the values to this function, and this function
+returns the number of the frequency table entry which contains
 the frequency the CPU shall be set to.
 
 The following macros can be used as iterators over cpufreq_frequency_table:
diff --git a/drivers/cpufreq/amd_freq_sensitivity.c 
b/drivers/cpufreq/amd_freq_sensitivity.c
index 3bea1bb791a9..6d5dc04c3a37 100644
--- a/drivers/cpufreq/amd_freq_sensitivity.c
+++ b/drivers/cpufreq/amd_freq_sensitivity.c
@@ -91,8 +91,8 @@ static unsigned int amd_powersave_bias_target(struct 
cpufreq_policy *policy,
else {
unsigned int index;
 
-   cpufreq_frequency_table_target(policy,
-   policy->cur - 1, CPUFREQ_RELATION_H, );
+   index = cpufreq_frequency_table_target(policy,
+   policy->cur - 1, CPUFREQ_RELATION_H);
freq_next = policy->freq_table[index].frequency;
}
 
diff --git a/drivers/cpufreq/cpufreq.c b/drivers/cpufreq/cpufreq.c
index 30f05dd5c872..9ae58a18ccb9 100644
--- a/drivers/cpufreq/cpufreq.c
+++ b/drivers/cpufreq/cpufreq.c
@@ -1914,7 +1914,7 @@ int __cpufreq_driver_target(struct cpufreq_policy *policy,
unsigned int relation)
 {
unsigned int old_target_freq = target_freq;
-   int index, retval;
+   int index;
 
if (cpufreq_disabled())
return -ENODEV;
@@ -1943,12 +1943,7 @@ int __cpufreq_driver_target(struct cpufreq_policy 
*policy,
if (!cpufreq_driver->target_index)
return -EINVAL;
 
-   retval = cpufreq_frequency_table_target(policy, target_freq, relation,
-   );
-   if (unlikely(retval)) {
-   pr_err("%s: Unable to find matching freq\n", __func__);
-   return retval;
-   }
+   index = cpufreq_frequency_table_target(policy, target_freq, relation);
 
return __target_index(policy, index);
 }
diff --git a/drivers/cpufreq/cpufreq_ondemand.c 
b/drivers/cpufreq/cpufreq_ondemand.c
index 2ee476f5a2bd..0c93cd9dee99 100644
--- a/drivers/cpufreq/cpufreq_ondemand.c
+++ b/drivers/cpufreq/cpufreq_ondemand.c
@@ -65,7 +65,7 @@ static unsigned int generic_powersave_bias_target(struct 
cpufreq_policy *policy,
 {
unsigned int freq_req, freq_reduc, freq_avg;
unsigned int freq_hi, freq_lo;
-   unsigned int index = 0;
+   unsigned int index;
unsigned int delay_hi_us;
struct policy_dbs_info *policy_dbs = policy->governor_data;
struct od_policy_dbs_info *dbs_info = to_dbs_info(policy_dbs);
@@ -79,19 +79,17 @@ static unsigned int generic_powersave_bias_target(struct 
cpufreq_policy *policy,
return freq_next;
}
 
-   cpufreq_frequency_table_target(policy, freq_next, relation, );
+   index = cpufreq_frequency_table_target(policy, freq_next, relation);
freq_req = freq_table[index].frequency;
freq_reduc = freq_req * od_tuners->powersave_bias / 1000;
freq_avg = freq_req - freq_reduc;
 
/* Find freq bounds for freq_avg in freq_table */
-   index = 0;
-   cpufreq_frequency_table_target(policy, freq_avg, CPUFREQ_RELATION_H,
-  );
+   index = cpufreq_frequency_table_target(policy, freq_avg,
+  

[PATCH V3 6/8] cpufreq: Drop 'freq_table' argument of __target_index()

2016-06-02 Thread Viresh Kumar
It is already present as part of the policy and so no need to pass it
from the caller. Also, 'freq_table' is guaranteed to be valid in this
function and so no need to check it.

Signed-off-by: Viresh Kumar 
---
 drivers/cpufreq/cpufreq.c | 21 +++--
 1 file changed, 7 insertions(+), 14 deletions(-)

diff --git a/drivers/cpufreq/cpufreq.c b/drivers/cpufreq/cpufreq.c
index e68611a67bd9..30f05dd5c872 100644
--- a/drivers/cpufreq/cpufreq.c
+++ b/drivers/cpufreq/cpufreq.c
@@ -1852,14 +1852,17 @@ static int __target_intermediate(struct cpufreq_policy 
*policy,
return ret;
 }
 
-static int __target_index(struct cpufreq_policy *policy,
- struct cpufreq_frequency_table *freq_table, int index)
+static int __target_index(struct cpufreq_policy *policy, int index)
 {
struct cpufreq_freqs freqs = {.old = policy->cur, .flags = 0};
unsigned int intermediate_freq = 0;
+   unsigned int newfreq = policy->freq_table[index].frequency;
int retval = -EINVAL;
bool notify;
 
+   if (newfreq == policy->cur)
+   return 0;
+
notify = !(cpufreq_driver->flags & CPUFREQ_ASYNC_NOTIFICATION);
if (notify) {
/* Handle switching to intermediate frequency */
@@ -1874,7 +1877,7 @@ static int __target_index(struct cpufreq_policy *policy,
freqs.old = freqs.new;
}
 
-   freqs.new = freq_table[index].frequency;
+   freqs.new = newfreq;
pr_debug("%s: cpu: %d, oldfreq: %u, new freq: %u\n",
 __func__, policy->cpu, freqs.old, freqs.new);
 
@@ -1911,7 +1914,6 @@ int __cpufreq_driver_target(struct cpufreq_policy *policy,
unsigned int relation)
 {
unsigned int old_target_freq = target_freq;
-   struct cpufreq_frequency_table *freq_table;
int index, retval;
 
if (cpufreq_disabled())
@@ -1941,12 +1943,6 @@ int __cpufreq_driver_target(struct cpufreq_policy 
*policy,
if (!cpufreq_driver->target_index)
return -EINVAL;
 
-   freq_table = policy->freq_table;
-   if (unlikely(!freq_table)) {
-   pr_err("%s: Unable to find freq_table\n", __func__);
-   return -EINVAL;
-   }
-
retval = cpufreq_frequency_table_target(policy, target_freq, relation,
);
if (unlikely(retval)) {
@@ -1954,10 +1950,7 @@ int __cpufreq_driver_target(struct cpufreq_policy 
*policy,
return retval;
}
 
-   if (freq_table[index].frequency == policy->cur)
-   return 0;
-
-   return __target_index(policy, freq_table, index);
+   return __target_index(policy, index);
 }
 EXPORT_SYMBOL_GPL(__cpufreq_driver_target);
 
-- 
2.7.1.410.g6faf27b



[PATCH V3 8/8] cpufreq: davinci: Reuse cpufreq_generic_frequency_table_verify()

2016-06-02 Thread Viresh Kumar
policy->freq_table will always be valid for this platform, otherwise
driver's probe() would fail. And so this routine will *always* return
after calling cpufreq_frequency_table_verify().

This can be done using the generic callback provided by core, lets use
it instead.

Cc: Sekhar Nori 
Signed-off-by: Viresh Kumar 
---
 drivers/cpufreq/davinci-cpufreq.c | 22 +-
 1 file changed, 1 insertion(+), 21 deletions(-)

diff --git a/drivers/cpufreq/davinci-cpufreq.c 
b/drivers/cpufreq/davinci-cpufreq.c
index 7e336d20c184..b95a872800ec 100644
--- a/drivers/cpufreq/davinci-cpufreq.c
+++ b/drivers/cpufreq/davinci-cpufreq.c
@@ -38,26 +38,6 @@ struct davinci_cpufreq {
 };
 static struct davinci_cpufreq cpufreq;
 
-static int davinci_verify_speed(struct cpufreq_policy *policy)
-{
-   struct davinci_cpufreq_config *pdata = cpufreq.dev->platform_data;
-   struct cpufreq_frequency_table *freq_table = pdata->freq_table;
-   struct clk *armclk = cpufreq.armclk;
-
-   if (freq_table)
-   return cpufreq_frequency_table_verify(policy, freq_table);
-
-   if (policy->cpu)
-   return -EINVAL;
-
-   cpufreq_verify_within_cpu_limits(policy);
-   policy->min = clk_round_rate(armclk, policy->min * 1000) / 1000;
-   policy->max = clk_round_rate(armclk, policy->max * 1000) / 1000;
-   cpufreq_verify_within_limits(policy, policy->cpuinfo.min_freq,
-   policy->cpuinfo.max_freq);
-   return 0;
-}
-
 static int davinci_target(struct cpufreq_policy *policy, unsigned int idx)
 {
struct davinci_cpufreq_config *pdata = cpufreq.dev->platform_data;
@@ -121,7 +101,7 @@ static int davinci_cpu_init(struct cpufreq_policy *policy)
 
 static struct cpufreq_driver davinci_driver = {
.flags  = CPUFREQ_STICKY | CPUFREQ_NEED_INITIAL_FREQ_CHECK,
-   .verify = davinci_verify_speed,
+   .verify = cpufreq_generic_frequency_table_verify,
.target_index   = davinci_target,
.get= cpufreq_generic_get,
.init   = davinci_cpu_init,
-- 
2.7.1.410.g6faf27b



[PATCH V3 6/8] cpufreq: Drop 'freq_table' argument of __target_index()

2016-06-02 Thread Viresh Kumar
It is already present as part of the policy and so no need to pass it
from the caller. Also, 'freq_table' is guaranteed to be valid in this
function and so no need to check it.

Signed-off-by: Viresh Kumar 
---
 drivers/cpufreq/cpufreq.c | 21 +++--
 1 file changed, 7 insertions(+), 14 deletions(-)

diff --git a/drivers/cpufreq/cpufreq.c b/drivers/cpufreq/cpufreq.c
index e68611a67bd9..30f05dd5c872 100644
--- a/drivers/cpufreq/cpufreq.c
+++ b/drivers/cpufreq/cpufreq.c
@@ -1852,14 +1852,17 @@ static int __target_intermediate(struct cpufreq_policy 
*policy,
return ret;
 }
 
-static int __target_index(struct cpufreq_policy *policy,
- struct cpufreq_frequency_table *freq_table, int index)
+static int __target_index(struct cpufreq_policy *policy, int index)
 {
struct cpufreq_freqs freqs = {.old = policy->cur, .flags = 0};
unsigned int intermediate_freq = 0;
+   unsigned int newfreq = policy->freq_table[index].frequency;
int retval = -EINVAL;
bool notify;
 
+   if (newfreq == policy->cur)
+   return 0;
+
notify = !(cpufreq_driver->flags & CPUFREQ_ASYNC_NOTIFICATION);
if (notify) {
/* Handle switching to intermediate frequency */
@@ -1874,7 +1877,7 @@ static int __target_index(struct cpufreq_policy *policy,
freqs.old = freqs.new;
}
 
-   freqs.new = freq_table[index].frequency;
+   freqs.new = newfreq;
pr_debug("%s: cpu: %d, oldfreq: %u, new freq: %u\n",
 __func__, policy->cpu, freqs.old, freqs.new);
 
@@ -1911,7 +1914,6 @@ int __cpufreq_driver_target(struct cpufreq_policy *policy,
unsigned int relation)
 {
unsigned int old_target_freq = target_freq;
-   struct cpufreq_frequency_table *freq_table;
int index, retval;
 
if (cpufreq_disabled())
@@ -1941,12 +1943,6 @@ int __cpufreq_driver_target(struct cpufreq_policy 
*policy,
if (!cpufreq_driver->target_index)
return -EINVAL;
 
-   freq_table = policy->freq_table;
-   if (unlikely(!freq_table)) {
-   pr_err("%s: Unable to find freq_table\n", __func__);
-   return -EINVAL;
-   }
-
retval = cpufreq_frequency_table_target(policy, target_freq, relation,
);
if (unlikely(retval)) {
@@ -1954,10 +1950,7 @@ int __cpufreq_driver_target(struct cpufreq_policy 
*policy,
return retval;
}
 
-   if (freq_table[index].frequency == policy->cur)
-   return 0;
-
-   return __target_index(policy, freq_table, index);
+   return __target_index(policy, index);
 }
 EXPORT_SYMBOL_GPL(__cpufreq_driver_target);
 
-- 
2.7.1.410.g6faf27b



[PATCH V3 8/8] cpufreq: davinci: Reuse cpufreq_generic_frequency_table_verify()

2016-06-02 Thread Viresh Kumar
policy->freq_table will always be valid for this platform, otherwise
driver's probe() would fail. And so this routine will *always* return
after calling cpufreq_frequency_table_verify().

This can be done using the generic callback provided by core, lets use
it instead.

Cc: Sekhar Nori 
Signed-off-by: Viresh Kumar 
---
 drivers/cpufreq/davinci-cpufreq.c | 22 +-
 1 file changed, 1 insertion(+), 21 deletions(-)

diff --git a/drivers/cpufreq/davinci-cpufreq.c 
b/drivers/cpufreq/davinci-cpufreq.c
index 7e336d20c184..b95a872800ec 100644
--- a/drivers/cpufreq/davinci-cpufreq.c
+++ b/drivers/cpufreq/davinci-cpufreq.c
@@ -38,26 +38,6 @@ struct davinci_cpufreq {
 };
 static struct davinci_cpufreq cpufreq;
 
-static int davinci_verify_speed(struct cpufreq_policy *policy)
-{
-   struct davinci_cpufreq_config *pdata = cpufreq.dev->platform_data;
-   struct cpufreq_frequency_table *freq_table = pdata->freq_table;
-   struct clk *armclk = cpufreq.armclk;
-
-   if (freq_table)
-   return cpufreq_frequency_table_verify(policy, freq_table);
-
-   if (policy->cpu)
-   return -EINVAL;
-
-   cpufreq_verify_within_cpu_limits(policy);
-   policy->min = clk_round_rate(armclk, policy->min * 1000) / 1000;
-   policy->max = clk_round_rate(armclk, policy->max * 1000) / 1000;
-   cpufreq_verify_within_limits(policy, policy->cpuinfo.min_freq,
-   policy->cpuinfo.max_freq);
-   return 0;
-}
-
 static int davinci_target(struct cpufreq_policy *policy, unsigned int idx)
 {
struct davinci_cpufreq_config *pdata = cpufreq.dev->platform_data;
@@ -121,7 +101,7 @@ static int davinci_cpu_init(struct cpufreq_policy *policy)
 
 static struct cpufreq_driver davinci_driver = {
.flags  = CPUFREQ_STICKY | CPUFREQ_NEED_INITIAL_FREQ_CHECK,
-   .verify = davinci_verify_speed,
+   .verify = cpufreq_generic_frequency_table_verify,
.target_index   = davinci_target,
.get= cpufreq_generic_get,
.init   = davinci_cpu_init,
-- 
2.7.1.410.g6faf27b



[PATCH V3 2/8] cpufreq: s3c24xx: Remove useless checks

2016-06-02 Thread Viresh Kumar
These aren't required at all, remove them.

Reviewed-by: Krzysztof Kozlowski 
Signed-off-by: Viresh Kumar 
---
 drivers/cpufreq/s3c24xx-cpufreq.c | 4 
 1 file changed, 4 deletions(-)

diff --git a/drivers/cpufreq/s3c24xx-cpufreq.c 
b/drivers/cpufreq/s3c24xx-cpufreq.c
index ae8eaed77b70..4567c3cab095 100644
--- a/drivers/cpufreq/s3c24xx-cpufreq.c
+++ b/drivers/cpufreq/s3c24xx-cpufreq.c
@@ -571,11 +571,7 @@ static int s3c_cpufreq_build_freq(void)
 {
int size, ret;
 
-   if (!cpu_cur.info->calc_freqtable)
-   return -EINVAL;
-
kfree(ftab);
-   ftab = NULL;
 
size = cpu_cur.info->calc_freqtable(_cur, NULL, 0);
size++;
-- 
2.7.1.410.g6faf27b



[PATCH V3 2/8] cpufreq: s3c24xx: Remove useless checks

2016-06-02 Thread Viresh Kumar
These aren't required at all, remove them.

Reviewed-by: Krzysztof Kozlowski 
Signed-off-by: Viresh Kumar 
---
 drivers/cpufreq/s3c24xx-cpufreq.c | 4 
 1 file changed, 4 deletions(-)

diff --git a/drivers/cpufreq/s3c24xx-cpufreq.c 
b/drivers/cpufreq/s3c24xx-cpufreq.c
index ae8eaed77b70..4567c3cab095 100644
--- a/drivers/cpufreq/s3c24xx-cpufreq.c
+++ b/drivers/cpufreq/s3c24xx-cpufreq.c
@@ -571,11 +571,7 @@ static int s3c_cpufreq_build_freq(void)
 {
int size, ret;
 
-   if (!cpu_cur.info->calc_freqtable)
-   return -EINVAL;
-
kfree(ftab);
-   ftab = NULL;
 
size = cpu_cur.info->calc_freqtable(_cur, NULL, 0);
size++;
-- 
2.7.1.410.g6faf27b



[PATCH V3 3/8] cpufreq: Remove cpufreq_frequency_get_table()

2016-06-02 Thread Viresh Kumar
Most of the callers of cpufreq_frequency_get_table() already have the
pointer to a valid 'policy' structure and they don't really need to go
through the per-cpu variable first and then a check to validate the
frequency, in order to find the freq-table for the policy.

Directly use the policy->freq_table field instead for them.

Only one user of that API is left after above changes, cpu_cooling.c and
it accesses the freq_table in a racy way as the policy can get freed in
between.

Fix it by using cpufreq_cpu_get() properly.

Since there are no more users of cpufreq_frequency_get_table() left, get
rid of it.

Signed-off-by: Viresh Kumar 
Acked-by: Javi Merino  (cpu_cooling.c)
---
 drivers/cpufreq/cpufreq.c | 38 +--
 drivers/cpufreq/cpufreq_ondemand.c|  2 +-
 drivers/cpufreq/cpufreq_stats.c   |  3 +--
 drivers/cpufreq/freq_table.c  |  9 +++--
 drivers/cpufreq/ppc_cbe_cpufreq_pmi.c |  3 +--
 drivers/thermal/cpu_cooling.c | 24 +-
 include/linux/cpufreq.h   |  2 --
 7 files changed, 39 insertions(+), 42 deletions(-)

diff --git a/drivers/cpufreq/cpufreq.c b/drivers/cpufreq/cpufreq.c
index fbc97b1fa371..1833eda1f9d4 100644
--- a/drivers/cpufreq/cpufreq.c
+++ b/drivers/cpufreq/cpufreq.c
@@ -126,15 +126,6 @@ struct kobject *get_governor_parent_kobj(struct 
cpufreq_policy *policy)
 }
 EXPORT_SYMBOL_GPL(get_governor_parent_kobj);
 
-struct cpufreq_frequency_table *cpufreq_frequency_get_table(unsigned int cpu)
-{
-   struct cpufreq_policy *policy = per_cpu(cpufreq_cpu_data, cpu);
-
-   return policy && !policy_is_inactive(policy) ?
-   policy->freq_table : NULL;
-}
-EXPORT_SYMBOL_GPL(cpufreq_frequency_get_table);
-
 static inline u64 get_cpu_idle_time_jiffy(unsigned int cpu, u64 *wall)
 {
u64 idle_time;
@@ -1950,7 +1941,7 @@ int __cpufreq_driver_target(struct cpufreq_policy *policy,
if (!cpufreq_driver->target_index)
return -EINVAL;
 
-   freq_table = cpufreq_frequency_get_table(policy->cpu);
+   freq_table = policy->freq_table;
if (unlikely(!freq_table)) {
pr_err("%s: Unable to find freq_table\n", __func__);
return -EINVAL;
@@ -2345,26 +2336,25 @@ static struct notifier_block __refdata 
cpufreq_cpu_notifier = {
  */
 static int cpufreq_boost_set_sw(int state)
 {
-   struct cpufreq_frequency_table *freq_table;
struct cpufreq_policy *policy;
int ret = -EINVAL;
 
for_each_active_policy(policy) {
-   freq_table = cpufreq_frequency_get_table(policy->cpu);
-   if (freq_table) {
-   ret = cpufreq_frequency_table_cpuinfo(policy,
-   freq_table);
-   if (ret) {
-   pr_err("%s: Policy frequency update failed\n",
-  __func__);
-   break;
-   }
+   if (!policy->freq_table)
+   continue;
 
-   down_write(>rwsem);
-   policy->user_policy.max = policy->max;
-   cpufreq_governor_limits(policy);
-   up_write(>rwsem);
+   ret = cpufreq_frequency_table_cpuinfo(policy,
+ policy->freq_table);
+   if (ret) {
+   pr_err("%s: Policy frequency update failed\n",
+  __func__);
+   break;
}
+
+   down_write(>rwsem);
+   policy->user_policy.max = policy->max;
+   cpufreq_governor_limits(policy);
+   up_write(>rwsem);
}
 
return ret;
diff --git a/drivers/cpufreq/cpufreq_ondemand.c 
b/drivers/cpufreq/cpufreq_ondemand.c
index c84fc2240d49..4d2fe2710c5d 100644
--- a/drivers/cpufreq/cpufreq_ondemand.c
+++ b/drivers/cpufreq/cpufreq_ondemand.c
@@ -113,7 +113,7 @@ static void ondemand_powersave_bias_init(struct 
cpufreq_policy *policy)
 {
struct od_policy_dbs_info *dbs_info = 
to_dbs_info(policy->governor_data);
 
-   dbs_info->freq_table = cpufreq_frequency_get_table(policy->cpu);
+   dbs_info->freq_table = policy->freq_table;
dbs_info->freq_lo = 0;
 }
 
diff --git a/drivers/cpufreq/cpufreq_stats.c b/drivers/cpufreq/cpufreq_stats.c
index c6e7f81a0397..06d3abdffd3a 100644
--- a/drivers/cpufreq/cpufreq_stats.c
+++ b/drivers/cpufreq/cpufreq_stats.c
@@ -157,11 +157,10 @@ void cpufreq_stats_create_table(struct cpufreq_policy 
*policy)
unsigned int i = 0, count = 0, ret = -ENOMEM;
struct cpufreq_stats *stats;
unsigned int alloc_size;
-   unsigned int cpu = policy->cpu;
struct cpufreq_frequency_table *pos, 

[PATCH V3 5/8] cpufreq: Drop freq-table param to cpufreq_frequency_table_target()

2016-06-02 Thread Viresh Kumar
The policy already has this pointer set, use it instead.

Signed-off-by: Viresh Kumar 
---
 Documentation/cpu-freq/cpu-drivers.txt |  1 -
 drivers/cpufreq/amd_freq_sensitivity.c |  3 +--
 drivers/cpufreq/cpufreq.c  |  4 ++--
 drivers/cpufreq/cpufreq_ondemand.c | 11 +--
 drivers/cpufreq/freq_table.c   |  2 +-
 drivers/cpufreq/powernv-cpufreq.c  |  3 +--
 drivers/cpufreq/s3c24xx-cpufreq.c  | 11 +--
 drivers/cpufreq/s5pv210-cpufreq.c  |  3 +--
 include/linux/cpufreq.h|  1 -
 9 files changed, 16 insertions(+), 23 deletions(-)

diff --git a/Documentation/cpu-freq/cpu-drivers.txt 
b/Documentation/cpu-freq/cpu-drivers.txt
index decbb8cb5573..74e812f0719c 100644
--- a/Documentation/cpu-freq/cpu-drivers.txt
+++ b/Documentation/cpu-freq/cpu-drivers.txt
@@ -244,7 +244,6 @@ policy->max, and all other criteria are met. This is 
helpful for the
 ->verify call.
 
 int cpufreq_frequency_table_target(struct cpufreq_policy *policy,
-   struct cpufreq_frequency_table *table,
unsigned int target_freq,
unsigned int relation,
unsigned int *index);
diff --git a/drivers/cpufreq/amd_freq_sensitivity.c 
b/drivers/cpufreq/amd_freq_sensitivity.c
index bc86816693a8..3bea1bb791a9 100644
--- a/drivers/cpufreq/amd_freq_sensitivity.c
+++ b/drivers/cpufreq/amd_freq_sensitivity.c
@@ -92,8 +92,7 @@ static unsigned int amd_powersave_bias_target(struct 
cpufreq_policy *policy,
unsigned int index;
 
cpufreq_frequency_table_target(policy,
-   policy->freq_table, policy->cur - 1,
-   CPUFREQ_RELATION_H, );
+   policy->cur - 1, CPUFREQ_RELATION_H, );
freq_next = policy->freq_table[index].frequency;
}
 
diff --git a/drivers/cpufreq/cpufreq.c b/drivers/cpufreq/cpufreq.c
index 1833eda1f9d4..e68611a67bd9 100644
--- a/drivers/cpufreq/cpufreq.c
+++ b/drivers/cpufreq/cpufreq.c
@@ -1947,8 +1947,8 @@ int __cpufreq_driver_target(struct cpufreq_policy *policy,
return -EINVAL;
}
 
-   retval = cpufreq_frequency_table_target(policy, freq_table, target_freq,
-   relation, );
+   retval = cpufreq_frequency_table_target(policy, target_freq, relation,
+   );
if (unlikely(retval)) {
pr_err("%s: Unable to find matching freq\n", __func__);
return retval;
diff --git a/drivers/cpufreq/cpufreq_ondemand.c 
b/drivers/cpufreq/cpufreq_ondemand.c
index 528353f204fd..2ee476f5a2bd 100644
--- a/drivers/cpufreq/cpufreq_ondemand.c
+++ b/drivers/cpufreq/cpufreq_ondemand.c
@@ -79,20 +79,19 @@ static unsigned int generic_powersave_bias_target(struct 
cpufreq_policy *policy,
return freq_next;
}
 
-   cpufreq_frequency_table_target(policy, freq_table, freq_next, relation,
-  );
+   cpufreq_frequency_table_target(policy, freq_next, relation, );
freq_req = freq_table[index].frequency;
freq_reduc = freq_req * od_tuners->powersave_bias / 1000;
freq_avg = freq_req - freq_reduc;
 
/* Find freq bounds for freq_avg in freq_table */
index = 0;
-   cpufreq_frequency_table_target(policy, freq_table, freq_avg,
-  CPUFREQ_RELATION_H, );
+   cpufreq_frequency_table_target(policy, freq_avg, CPUFREQ_RELATION_H,
+  );
freq_lo = freq_table[index].frequency;
index = 0;
-   cpufreq_frequency_table_target(policy, freq_table, freq_avg,
-  CPUFREQ_RELATION_L, );
+   cpufreq_frequency_table_target(policy, freq_avg, CPUFREQ_RELATION_L,
+  );
freq_hi = freq_table[index].frequency;
 
/* Find out how long we have to be in hi and lo freqs */
diff --git a/drivers/cpufreq/freq_table.c b/drivers/cpufreq/freq_table.c
index f52b5473b1f4..f145b64649ef 100644
--- a/drivers/cpufreq/freq_table.c
+++ b/drivers/cpufreq/freq_table.c
@@ -114,7 +114,6 @@ int cpufreq_generic_frequency_table_verify(struct 
cpufreq_policy *policy)
 EXPORT_SYMBOL_GPL(cpufreq_generic_frequency_table_verify);
 
 int cpufreq_frequency_table_target(struct cpufreq_policy *policy,
-  struct cpufreq_frequency_table *table,
   unsigned int target_freq,
   unsigned int relation,
   unsigned int *index)
@@ -128,6 +127,7 @@ int cpufreq_frequency_table_target(struct cpufreq_policy 
*policy,
.frequency = 0,
};
struct cpufreq_frequency_table *pos;
+   

[PATCH V3 5/8] cpufreq: Drop freq-table param to cpufreq_frequency_table_target()

2016-06-02 Thread Viresh Kumar
The policy already has this pointer set, use it instead.

Signed-off-by: Viresh Kumar 
---
 Documentation/cpu-freq/cpu-drivers.txt |  1 -
 drivers/cpufreq/amd_freq_sensitivity.c |  3 +--
 drivers/cpufreq/cpufreq.c  |  4 ++--
 drivers/cpufreq/cpufreq_ondemand.c | 11 +--
 drivers/cpufreq/freq_table.c   |  2 +-
 drivers/cpufreq/powernv-cpufreq.c  |  3 +--
 drivers/cpufreq/s3c24xx-cpufreq.c  | 11 +--
 drivers/cpufreq/s5pv210-cpufreq.c  |  3 +--
 include/linux/cpufreq.h|  1 -
 9 files changed, 16 insertions(+), 23 deletions(-)

diff --git a/Documentation/cpu-freq/cpu-drivers.txt 
b/Documentation/cpu-freq/cpu-drivers.txt
index decbb8cb5573..74e812f0719c 100644
--- a/Documentation/cpu-freq/cpu-drivers.txt
+++ b/Documentation/cpu-freq/cpu-drivers.txt
@@ -244,7 +244,6 @@ policy->max, and all other criteria are met. This is 
helpful for the
 ->verify call.
 
 int cpufreq_frequency_table_target(struct cpufreq_policy *policy,
-   struct cpufreq_frequency_table *table,
unsigned int target_freq,
unsigned int relation,
unsigned int *index);
diff --git a/drivers/cpufreq/amd_freq_sensitivity.c 
b/drivers/cpufreq/amd_freq_sensitivity.c
index bc86816693a8..3bea1bb791a9 100644
--- a/drivers/cpufreq/amd_freq_sensitivity.c
+++ b/drivers/cpufreq/amd_freq_sensitivity.c
@@ -92,8 +92,7 @@ static unsigned int amd_powersave_bias_target(struct 
cpufreq_policy *policy,
unsigned int index;
 
cpufreq_frequency_table_target(policy,
-   policy->freq_table, policy->cur - 1,
-   CPUFREQ_RELATION_H, );
+   policy->cur - 1, CPUFREQ_RELATION_H, );
freq_next = policy->freq_table[index].frequency;
}
 
diff --git a/drivers/cpufreq/cpufreq.c b/drivers/cpufreq/cpufreq.c
index 1833eda1f9d4..e68611a67bd9 100644
--- a/drivers/cpufreq/cpufreq.c
+++ b/drivers/cpufreq/cpufreq.c
@@ -1947,8 +1947,8 @@ int __cpufreq_driver_target(struct cpufreq_policy *policy,
return -EINVAL;
}
 
-   retval = cpufreq_frequency_table_target(policy, freq_table, target_freq,
-   relation, );
+   retval = cpufreq_frequency_table_target(policy, target_freq, relation,
+   );
if (unlikely(retval)) {
pr_err("%s: Unable to find matching freq\n", __func__);
return retval;
diff --git a/drivers/cpufreq/cpufreq_ondemand.c 
b/drivers/cpufreq/cpufreq_ondemand.c
index 528353f204fd..2ee476f5a2bd 100644
--- a/drivers/cpufreq/cpufreq_ondemand.c
+++ b/drivers/cpufreq/cpufreq_ondemand.c
@@ -79,20 +79,19 @@ static unsigned int generic_powersave_bias_target(struct 
cpufreq_policy *policy,
return freq_next;
}
 
-   cpufreq_frequency_table_target(policy, freq_table, freq_next, relation,
-  );
+   cpufreq_frequency_table_target(policy, freq_next, relation, );
freq_req = freq_table[index].frequency;
freq_reduc = freq_req * od_tuners->powersave_bias / 1000;
freq_avg = freq_req - freq_reduc;
 
/* Find freq bounds for freq_avg in freq_table */
index = 0;
-   cpufreq_frequency_table_target(policy, freq_table, freq_avg,
-  CPUFREQ_RELATION_H, );
+   cpufreq_frequency_table_target(policy, freq_avg, CPUFREQ_RELATION_H,
+  );
freq_lo = freq_table[index].frequency;
index = 0;
-   cpufreq_frequency_table_target(policy, freq_table, freq_avg,
-  CPUFREQ_RELATION_L, );
+   cpufreq_frequency_table_target(policy, freq_avg, CPUFREQ_RELATION_L,
+  );
freq_hi = freq_table[index].frequency;
 
/* Find out how long we have to be in hi and lo freqs */
diff --git a/drivers/cpufreq/freq_table.c b/drivers/cpufreq/freq_table.c
index f52b5473b1f4..f145b64649ef 100644
--- a/drivers/cpufreq/freq_table.c
+++ b/drivers/cpufreq/freq_table.c
@@ -114,7 +114,6 @@ int cpufreq_generic_frequency_table_verify(struct 
cpufreq_policy *policy)
 EXPORT_SYMBOL_GPL(cpufreq_generic_frequency_table_verify);
 
 int cpufreq_frequency_table_target(struct cpufreq_policy *policy,
-  struct cpufreq_frequency_table *table,
   unsigned int target_freq,
   unsigned int relation,
   unsigned int *index)
@@ -128,6 +127,7 @@ int cpufreq_frequency_table_target(struct cpufreq_policy 
*policy,
.frequency = 0,
};
struct cpufreq_frequency_table *pos;
+   struct 

[PATCH V3 3/8] cpufreq: Remove cpufreq_frequency_get_table()

2016-06-02 Thread Viresh Kumar
Most of the callers of cpufreq_frequency_get_table() already have the
pointer to a valid 'policy' structure and they don't really need to go
through the per-cpu variable first and then a check to validate the
frequency, in order to find the freq-table for the policy.

Directly use the policy->freq_table field instead for them.

Only one user of that API is left after above changes, cpu_cooling.c and
it accesses the freq_table in a racy way as the policy can get freed in
between.

Fix it by using cpufreq_cpu_get() properly.

Since there are no more users of cpufreq_frequency_get_table() left, get
rid of it.

Signed-off-by: Viresh Kumar 
Acked-by: Javi Merino  (cpu_cooling.c)
---
 drivers/cpufreq/cpufreq.c | 38 +--
 drivers/cpufreq/cpufreq_ondemand.c|  2 +-
 drivers/cpufreq/cpufreq_stats.c   |  3 +--
 drivers/cpufreq/freq_table.c  |  9 +++--
 drivers/cpufreq/ppc_cbe_cpufreq_pmi.c |  3 +--
 drivers/thermal/cpu_cooling.c | 24 +-
 include/linux/cpufreq.h   |  2 --
 7 files changed, 39 insertions(+), 42 deletions(-)

diff --git a/drivers/cpufreq/cpufreq.c b/drivers/cpufreq/cpufreq.c
index fbc97b1fa371..1833eda1f9d4 100644
--- a/drivers/cpufreq/cpufreq.c
+++ b/drivers/cpufreq/cpufreq.c
@@ -126,15 +126,6 @@ struct kobject *get_governor_parent_kobj(struct 
cpufreq_policy *policy)
 }
 EXPORT_SYMBOL_GPL(get_governor_parent_kobj);
 
-struct cpufreq_frequency_table *cpufreq_frequency_get_table(unsigned int cpu)
-{
-   struct cpufreq_policy *policy = per_cpu(cpufreq_cpu_data, cpu);
-
-   return policy && !policy_is_inactive(policy) ?
-   policy->freq_table : NULL;
-}
-EXPORT_SYMBOL_GPL(cpufreq_frequency_get_table);
-
 static inline u64 get_cpu_idle_time_jiffy(unsigned int cpu, u64 *wall)
 {
u64 idle_time;
@@ -1950,7 +1941,7 @@ int __cpufreq_driver_target(struct cpufreq_policy *policy,
if (!cpufreq_driver->target_index)
return -EINVAL;
 
-   freq_table = cpufreq_frequency_get_table(policy->cpu);
+   freq_table = policy->freq_table;
if (unlikely(!freq_table)) {
pr_err("%s: Unable to find freq_table\n", __func__);
return -EINVAL;
@@ -2345,26 +2336,25 @@ static struct notifier_block __refdata 
cpufreq_cpu_notifier = {
  */
 static int cpufreq_boost_set_sw(int state)
 {
-   struct cpufreq_frequency_table *freq_table;
struct cpufreq_policy *policy;
int ret = -EINVAL;
 
for_each_active_policy(policy) {
-   freq_table = cpufreq_frequency_get_table(policy->cpu);
-   if (freq_table) {
-   ret = cpufreq_frequency_table_cpuinfo(policy,
-   freq_table);
-   if (ret) {
-   pr_err("%s: Policy frequency update failed\n",
-  __func__);
-   break;
-   }
+   if (!policy->freq_table)
+   continue;
 
-   down_write(>rwsem);
-   policy->user_policy.max = policy->max;
-   cpufreq_governor_limits(policy);
-   up_write(>rwsem);
+   ret = cpufreq_frequency_table_cpuinfo(policy,
+ policy->freq_table);
+   if (ret) {
+   pr_err("%s: Policy frequency update failed\n",
+  __func__);
+   break;
}
+
+   down_write(>rwsem);
+   policy->user_policy.max = policy->max;
+   cpufreq_governor_limits(policy);
+   up_write(>rwsem);
}
 
return ret;
diff --git a/drivers/cpufreq/cpufreq_ondemand.c 
b/drivers/cpufreq/cpufreq_ondemand.c
index c84fc2240d49..4d2fe2710c5d 100644
--- a/drivers/cpufreq/cpufreq_ondemand.c
+++ b/drivers/cpufreq/cpufreq_ondemand.c
@@ -113,7 +113,7 @@ static void ondemand_powersave_bias_init(struct 
cpufreq_policy *policy)
 {
struct od_policy_dbs_info *dbs_info = 
to_dbs_info(policy->governor_data);
 
-   dbs_info->freq_table = cpufreq_frequency_get_table(policy->cpu);
+   dbs_info->freq_table = policy->freq_table;
dbs_info->freq_lo = 0;
 }
 
diff --git a/drivers/cpufreq/cpufreq_stats.c b/drivers/cpufreq/cpufreq_stats.c
index c6e7f81a0397..06d3abdffd3a 100644
--- a/drivers/cpufreq/cpufreq_stats.c
+++ b/drivers/cpufreq/cpufreq_stats.c
@@ -157,11 +157,10 @@ void cpufreq_stats_create_table(struct cpufreq_policy 
*policy)
unsigned int i = 0, count = 0, ret = -ENOMEM;
struct cpufreq_stats *stats;
unsigned int alloc_size;
-   unsigned int cpu = policy->cpu;
struct cpufreq_frequency_table *pos, *table;
 
/* We need cpufreq table for 

Zpráva pro vás!

2016-06-02 Thread messg1



Jsem zastupujicí investicní zajem ze strany Dubaji, pro ktere hledáme vasi
ucast. Odpoved na e-mailu nize v pripade zajmu.

E-mail: pbrt...@gmail.com




Zpráva pro vás!

2016-06-02 Thread messg1



Jsem zastupujicí investicní zajem ze strany Dubaji, pro ktere hledáme vasi
ucast. Odpoved na e-mailu nize v pripade zajmu.

E-mail: pbrt...@gmail.com




[PATCH v2] sched/cputime: add steal clock warp handling

2016-06-02 Thread Wanpeng Li
From: Wanpeng Li 

I observed that sometimes st is 100% instantaneous, then idle is 100% 
even if there is a cpu hog on the guest cpu after the cpu hotplug comes 
back(N.B. this can not always be readily reproduced). I add trace to 
capture it as below:

cpuhp/1-12[001] d.h1   167.461657: account_process_tick: steal = 
1291385514, prev_steal_time = 0 
cpuhp/1-12[001] d.h1   167.461659: account_process_tick: steal_jiffies = 
1291  
-0 [001] d.h1   167.462663: account_process_tick: steal = 18732255, 
prev_steal_time = 129100  
-0 [001] d.h1   167.462664: account_process_tick: steal_jiffies = 
18446744072437

The steal clock warp and then steal_jiffies overflow.

Rik also pointed out to me:
 
| I have seen stuff like that with live migration too, in the past 

This patch adds steal clock warp handling by a safe threshold to only 
apply steal times that are positive and smaller than one second (as 
long as nohz_full has the one second timer tick left), ignoring intervals 
that are negative or longer than a second, and using those to sync up 
the guest with the host.

Cc: Ingo Molnar 
Cc: Peter Zijlstra (Intel) 
Cc: Rik van Riel 
Cc: Thomas Gleixner 
Cc: Frederic Weisbecker 
Cc: Paolo Bonzini 
Cc: Radim 
Signed-off-by: Wanpeng Li 
---
v1 -> v2:
 * update patch subject, description and comments
 * deal with the case where steal time suddenly increases by a ludicrous amount

 kernel/sched/cputime.c | 15 +--
 1 file changed, 13 insertions(+), 2 deletions(-)

diff --git a/kernel/sched/cputime.c b/kernel/sched/cputime.c
index f51c98c..751798a 100644
--- a/kernel/sched/cputime.c
+++ b/kernel/sched/cputime.c
@@ -262,17 +262,28 @@ static __always_inline unsigned long 
steal_account_process_tick(void)
 #ifdef CONFIG_PARAVIRT
if (static_key_false(_steal_enabled)) {
u64 steal;
+   s64 delta;
unsigned long steal_jiffies;
 
steal = paravirt_steal_clock(smp_processor_id());
-   steal -= this_rq()->prev_steal_time;
+   delta = steal - this_rq()->prev_steal_time;
+   /*
+* Ignore this steal time difference if the guest and the host 
got
+* out of sync. This can happen due to events like live 
migration,
+* or CPU hotplug. The upper threshold is set to one second to 
match
+* the one second timer tick with nohz_full.
+*/
+   if (unlikely(delta < 0 || delta > NSEC_PER_SEC)) {
+   this_rq()->prev_steal_time = steal;
+   return 0;
+   }
 
/*
 * steal is in nsecs but our caller is expecting steal
 * time in jiffies. Lets cast the result to jiffies
 * granularity and account the rest on the next rounds.
 */
-   steal_jiffies = nsecs_to_jiffies(steal);
+   steal_jiffies = nsecs_to_jiffies(delta);
this_rq()->prev_steal_time += jiffies_to_nsecs(steal_jiffies);
 
account_steal_time(jiffies_to_cputime(steal_jiffies));
-- 
1.9.1



[PATCH v2] sched/cputime: add steal clock warp handling

2016-06-02 Thread Wanpeng Li
From: Wanpeng Li 

I observed that sometimes st is 100% instantaneous, then idle is 100% 
even if there is a cpu hog on the guest cpu after the cpu hotplug comes 
back(N.B. this can not always be readily reproduced). I add trace to 
capture it as below:

cpuhp/1-12[001] d.h1   167.461657: account_process_tick: steal = 
1291385514, prev_steal_time = 0 
cpuhp/1-12[001] d.h1   167.461659: account_process_tick: steal_jiffies = 
1291  
-0 [001] d.h1   167.462663: account_process_tick: steal = 18732255, 
prev_steal_time = 129100  
-0 [001] d.h1   167.462664: account_process_tick: steal_jiffies = 
18446744072437

The steal clock warp and then steal_jiffies overflow.

Rik also pointed out to me:
 
| I have seen stuff like that with live migration too, in the past 

This patch adds steal clock warp handling by a safe threshold to only 
apply steal times that are positive and smaller than one second (as 
long as nohz_full has the one second timer tick left), ignoring intervals 
that are negative or longer than a second, and using those to sync up 
the guest with the host.

Cc: Ingo Molnar 
Cc: Peter Zijlstra (Intel) 
Cc: Rik van Riel 
Cc: Thomas Gleixner 
Cc: Frederic Weisbecker 
Cc: Paolo Bonzini 
Cc: Radim 
Signed-off-by: Wanpeng Li 
---
v1 -> v2:
 * update patch subject, description and comments
 * deal with the case where steal time suddenly increases by a ludicrous amount

 kernel/sched/cputime.c | 15 +--
 1 file changed, 13 insertions(+), 2 deletions(-)

diff --git a/kernel/sched/cputime.c b/kernel/sched/cputime.c
index f51c98c..751798a 100644
--- a/kernel/sched/cputime.c
+++ b/kernel/sched/cputime.c
@@ -262,17 +262,28 @@ static __always_inline unsigned long 
steal_account_process_tick(void)
 #ifdef CONFIG_PARAVIRT
if (static_key_false(_steal_enabled)) {
u64 steal;
+   s64 delta;
unsigned long steal_jiffies;
 
steal = paravirt_steal_clock(smp_processor_id());
-   steal -= this_rq()->prev_steal_time;
+   delta = steal - this_rq()->prev_steal_time;
+   /*
+* Ignore this steal time difference if the guest and the host 
got
+* out of sync. This can happen due to events like live 
migration,
+* or CPU hotplug. The upper threshold is set to one second to 
match
+* the one second timer tick with nohz_full.
+*/
+   if (unlikely(delta < 0 || delta > NSEC_PER_SEC)) {
+   this_rq()->prev_steal_time = steal;
+   return 0;
+   }
 
/*
 * steal is in nsecs but our caller is expecting steal
 * time in jiffies. Lets cast the result to jiffies
 * granularity and account the rest on the next rounds.
 */
-   steal_jiffies = nsecs_to_jiffies(steal);
+   steal_jiffies = nsecs_to_jiffies(delta);
this_rq()->prev_steal_time += jiffies_to_nsecs(steal_jiffies);
 
account_steal_time(jiffies_to_cputime(steal_jiffies));
-- 
1.9.1



Re: [PATCH] f2fs: fix to redirty page if fail to gc data page

2016-06-02 Thread Jaegeuk Kim
On Fri, Jun 03, 2016 at 01:13:21PM +0800, Chao Yu wrote:
> On 2016/6/3 13:08, Jaegeuk Kim wrote:
> > On Tue, May 31, 2016 at 02:10:50PM +0800, Chao Yu wrote:
> >> Hi Jaegeuk,
> >>
> >> On 2016/5/30 10:37, Jaegeuk Kim wrote:
> >>> Hi Chao,
> >>>
> >>> On Sat, May 21, 2016 at 01:19:11PM +0800, Chao Yu wrote:
>  From: Chao Yu 
> 
>  If we fail to move data page during foreground GC, we should give another
>  chance to writeback that page which was set dirty previously by writer.
> 
>  Signed-off-by: Chao Yu 
>  ---
>   fs/f2fs/gc.c | 5 -
>   1 file changed, 4 insertions(+), 1 deletion(-)
> 
>  diff --git a/fs/f2fs/gc.c b/fs/f2fs/gc.c
>  index 38d56f6..ee213a8 100644
>  --- a/fs/f2fs/gc.c
>  +++ b/fs/f2fs/gc.c
>  @@ -653,12 +653,15 @@ static void move_data_page(struct inode *inode, 
>  block_t bidx, int gc_type)
>   .page = page,
>   .encrypted_page = NULL,
>   };
>  +bool is_dirty = PageDirty(page);
>  +
>   set_page_dirty(page);
>   f2fs_wait_on_page_writeback(page, DATA, true);
>   if (clear_page_dirty_for_io(page))
>   inode_dec_dirty_pages(inode);
>   set_cold_data(page);
>  -do_write_data_page();
>  +if (do_write_data_page() && is_dirty)
>  +set_page_dirty(page);
> >>>
> >>> If this page is truncated with -ENOENT, we don't need to set it dirty 
> >>> again.
> >>
> >> Agree
> >>
> >>> I expect that, if we get an error here, do_garbage_collect() would retry 
> >>> FG_GC
> >>
> >> IIRC, you have reworked the FG_GC flows changed from an infinite loop to 
> >> trying
> >> do the movement just one time. Here, I think if there are just few of 
> >> blocks are
> >> failed to be moved, we can give one more time for retrying. How do you 
> >> think?
> > 
> > Mostly I expected here -ENOENT caused by race condition.
> 
> If we hit ENOENT case, we can pass get_valid_blocks check, so we don't need to
> worry about this case, right?
> 
> > Do we have another expectation?
> 
> ENOMEM or EIO?

EIO will stop everything.
ENOMEM would be better to wait for a while from page reclaim?

> 
> Thanks,
> 
> > 
> > Thanks,
> > 
> >>
> >>> again.
> >>>
> >>> Thanks,
> >>>
>   clear_cold_data(page);
>   }
>   out:
>  -- 
>  2.7.2
> >>> .
> >>>
> > .
> > 


Re: [PATCH 4/6] clocksource/drivers/armv7m_systick: Add the COMPILE_TEST option

2016-06-02 Thread kbuild test robot
Hi,

[auto build test ERROR on tip/timers/core]
[also build test ERROR on v4.7-rc1 next-20160602]
[if your patch is applied to the wrong git tree, please drop us a note to help 
improve the system]

url:
https://github.com/0day-ci/linux/commits/Daniel-Lezcano/clk-Add-missing-clk_get_sys-stub/20160603-054643
config: um-allmodconfig (attached as .config)
compiler: gcc-6 (Debian 6.1.1-1) 6.1.1 20160430
reproduce:
# save the attached .config to linux build tree
make ARCH=um 

All errors (new ones prefixed by >>):

   drivers/clocksource/armv7m_systick.c: In function 'system_timer_of_register':
>> drivers/clocksource/armv7m_systick.c:74:2: error: implicit declaration of 
>> function 'iounmap' [-Werror=implicit-function-declaration]
 iounmap(base);
 ^~~
   cc1: some warnings being treated as errors

vim +/iounmap +74 drivers/clocksource/armv7m_systick.c

4958ebb3 Maxime Coquelin 2015-05-09  58 pr_err("failed to init 
clocksource (%d)\n", ret);
4958ebb3 Maxime Coquelin 2015-05-09  59 if (clk)
4958ebb3 Maxime Coquelin 2015-05-09  60 goto 
out_clk_disable;
4958ebb3 Maxime Coquelin 2015-05-09  61 else
4958ebb3 Maxime Coquelin 2015-05-09  62 goto out_unmap;
4958ebb3 Maxime Coquelin 2015-05-09  63 }
4958ebb3 Maxime Coquelin 2015-05-09  64  
4958ebb3 Maxime Coquelin 2015-05-09  65 pr_info("ARM System timer 
initialized as clocksource\n");
4958ebb3 Maxime Coquelin 2015-05-09  66  
4958ebb3 Maxime Coquelin 2015-05-09  67 return;
4958ebb3 Maxime Coquelin 2015-05-09  68  
4958ebb3 Maxime Coquelin 2015-05-09  69  out_clk_disable:
4958ebb3 Maxime Coquelin 2015-05-09  70 clk_disable_unprepare(clk);
4958ebb3 Maxime Coquelin 2015-05-09  71  out_clk_put:
4958ebb3 Maxime Coquelin 2015-05-09  72 clk_put(clk);
4958ebb3 Maxime Coquelin 2015-05-09  73  out_unmap:
4958ebb3 Maxime Coquelin 2015-05-09 @74 iounmap(base);
4958ebb3 Maxime Coquelin 2015-05-09  75 pr_warn("ARM System timer 
register failed (%d)\n", ret);
4958ebb3 Maxime Coquelin 2015-05-09  76  }
4958ebb3 Maxime Coquelin 2015-05-09  77  
4958ebb3 Maxime Coquelin 2015-05-09  78  CLOCKSOURCE_OF_DECLARE(arm_systick, 
"arm,armv7m-systick",
4958ebb3 Maxime Coquelin 2015-05-09  79 
system_timer_of_register);

:: The code at line 74 was first introduced by commit
:: 4958ebb3d027886c46b936453745dba59b09c578 
clocksource/drivers/armv7m_systick: Add ARM System timer driver

:: TO: Maxime Coquelin <mcoquelin.st...@gmail.com>
:: CC: Daniel Lezcano <daniel.lezc...@linaro.org>

---
0-DAY kernel test infrastructureOpen Source Technology Center
https://lists.01.org/pipermail/kbuild-all   Intel Corporation


.config.gz
Description: Binary data


Re: [PATCH 4/6] clocksource/drivers/armv7m_systick: Add the COMPILE_TEST option

2016-06-02 Thread kbuild test robot
Hi,

[auto build test ERROR on tip/timers/core]
[also build test ERROR on v4.7-rc1 next-20160602]
[if your patch is applied to the wrong git tree, please drop us a note to help 
improve the system]

url:
https://github.com/0day-ci/linux/commits/Daniel-Lezcano/clk-Add-missing-clk_get_sys-stub/20160603-054643
config: um-allmodconfig (attached as .config)
compiler: gcc-6 (Debian 6.1.1-1) 6.1.1 20160430
reproduce:
# save the attached .config to linux build tree
make ARCH=um 

All errors (new ones prefixed by >>):

   drivers/clocksource/armv7m_systick.c: In function 'system_timer_of_register':
>> drivers/clocksource/armv7m_systick.c:74:2: error: implicit declaration of 
>> function 'iounmap' [-Werror=implicit-function-declaration]
 iounmap(base);
 ^~~
   cc1: some warnings being treated as errors

vim +/iounmap +74 drivers/clocksource/armv7m_systick.c

4958ebb3 Maxime Coquelin 2015-05-09  58 pr_err("failed to init 
clocksource (%d)\n", ret);
4958ebb3 Maxime Coquelin 2015-05-09  59 if (clk)
4958ebb3 Maxime Coquelin 2015-05-09  60 goto 
out_clk_disable;
4958ebb3 Maxime Coquelin 2015-05-09  61 else
4958ebb3 Maxime Coquelin 2015-05-09  62 goto out_unmap;
4958ebb3 Maxime Coquelin 2015-05-09  63 }
4958ebb3 Maxime Coquelin 2015-05-09  64  
4958ebb3 Maxime Coquelin 2015-05-09  65 pr_info("ARM System timer 
initialized as clocksource\n");
4958ebb3 Maxime Coquelin 2015-05-09  66  
4958ebb3 Maxime Coquelin 2015-05-09  67 return;
4958ebb3 Maxime Coquelin 2015-05-09  68  
4958ebb3 Maxime Coquelin 2015-05-09  69  out_clk_disable:
4958ebb3 Maxime Coquelin 2015-05-09  70 clk_disable_unprepare(clk);
4958ebb3 Maxime Coquelin 2015-05-09  71  out_clk_put:
4958ebb3 Maxime Coquelin 2015-05-09  72 clk_put(clk);
4958ebb3 Maxime Coquelin 2015-05-09  73  out_unmap:
4958ebb3 Maxime Coquelin 2015-05-09 @74 iounmap(base);
4958ebb3 Maxime Coquelin 2015-05-09  75 pr_warn("ARM System timer 
register failed (%d)\n", ret);
4958ebb3 Maxime Coquelin 2015-05-09  76  }
4958ebb3 Maxime Coquelin 2015-05-09  77  
4958ebb3 Maxime Coquelin 2015-05-09  78  CLOCKSOURCE_OF_DECLARE(arm_systick, 
"arm,armv7m-systick",
4958ebb3 Maxime Coquelin 2015-05-09  79 
system_timer_of_register);

:: The code at line 74 was first introduced by commit
:: 4958ebb3d027886c46b936453745dba59b09c578 
clocksource/drivers/armv7m_systick: Add ARM System timer driver

:: TO: Maxime Coquelin 
:: CC: Daniel Lezcano 

---
0-DAY kernel test infrastructureOpen Source Technology Center
https://lists.01.org/pipermail/kbuild-all   Intel Corporation


.config.gz
Description: Binary data


Re: [PATCH] f2fs: fix to redirty page if fail to gc data page

2016-06-02 Thread Jaegeuk Kim
On Fri, Jun 03, 2016 at 01:13:21PM +0800, Chao Yu wrote:
> On 2016/6/3 13:08, Jaegeuk Kim wrote:
> > On Tue, May 31, 2016 at 02:10:50PM +0800, Chao Yu wrote:
> >> Hi Jaegeuk,
> >>
> >> On 2016/5/30 10:37, Jaegeuk Kim wrote:
> >>> Hi Chao,
> >>>
> >>> On Sat, May 21, 2016 at 01:19:11PM +0800, Chao Yu wrote:
>  From: Chao Yu 
> 
>  If we fail to move data page during foreground GC, we should give another
>  chance to writeback that page which was set dirty previously by writer.
> 
>  Signed-off-by: Chao Yu 
>  ---
>   fs/f2fs/gc.c | 5 -
>   1 file changed, 4 insertions(+), 1 deletion(-)
> 
>  diff --git a/fs/f2fs/gc.c b/fs/f2fs/gc.c
>  index 38d56f6..ee213a8 100644
>  --- a/fs/f2fs/gc.c
>  +++ b/fs/f2fs/gc.c
>  @@ -653,12 +653,15 @@ static void move_data_page(struct inode *inode, 
>  block_t bidx, int gc_type)
>   .page = page,
>   .encrypted_page = NULL,
>   };
>  +bool is_dirty = PageDirty(page);
>  +
>   set_page_dirty(page);
>   f2fs_wait_on_page_writeback(page, DATA, true);
>   if (clear_page_dirty_for_io(page))
>   inode_dec_dirty_pages(inode);
>   set_cold_data(page);
>  -do_write_data_page();
>  +if (do_write_data_page() && is_dirty)
>  +set_page_dirty(page);
> >>>
> >>> If this page is truncated with -ENOENT, we don't need to set it dirty 
> >>> again.
> >>
> >> Agree
> >>
> >>> I expect that, if we get an error here, do_garbage_collect() would retry 
> >>> FG_GC
> >>
> >> IIRC, you have reworked the FG_GC flows changed from an infinite loop to 
> >> trying
> >> do the movement just one time. Here, I think if there are just few of 
> >> blocks are
> >> failed to be moved, we can give one more time for retrying. How do you 
> >> think?
> > 
> > Mostly I expected here -ENOENT caused by race condition.
> 
> If we hit ENOENT case, we can pass get_valid_blocks check, so we don't need to
> worry about this case, right?
> 
> > Do we have another expectation?
> 
> ENOMEM or EIO?

EIO will stop everything.
ENOMEM would be better to wait for a while from page reclaim?

> 
> Thanks,
> 
> > 
> > Thanks,
> > 
> >>
> >>> again.
> >>>
> >>> Thanks,
> >>>
>   clear_cold_data(page);
>   }
>   out:
>  -- 
>  2.7.2
> >>> .
> >>>
> > .
> > 


Good News

2016-06-02 Thread Pedro Quezada
You are a recipient to Mr Pedro Quezada Donation of 2M USD. Contact 
(qpedro...@gmail.com) for claims.


Good News

2016-06-02 Thread Pedro Quezada
You are a recipient to Mr Pedro Quezada Donation of 2M USD. Contact 
(qpedro...@gmail.com) for claims.


Offer

2016-06-02 Thread Pedro Quezada
You are a recipient to Mr Pedro Quezada Donation of 2M USD. Contact 
(qpedro...@gmail.com) for claims.


Offer

2016-06-02 Thread Pedro Quezada
You are a recipient to Mr Pedro Quezada Donation of 2M USD. Contact 
(qpedro...@gmail.com) for claims.


Re: [PATCH] f2fs: fix to redirty page if fail to gc data page

2016-06-02 Thread Chao Yu
On 2016/6/3 13:08, Jaegeuk Kim wrote:
> On Tue, May 31, 2016 at 02:10:50PM +0800, Chao Yu wrote:
>> Hi Jaegeuk,
>>
>> On 2016/5/30 10:37, Jaegeuk Kim wrote:
>>> Hi Chao,
>>>
>>> On Sat, May 21, 2016 at 01:19:11PM +0800, Chao Yu wrote:
 From: Chao Yu 

 If we fail to move data page during foreground GC, we should give another
 chance to writeback that page which was set dirty previously by writer.

 Signed-off-by: Chao Yu 
 ---
  fs/f2fs/gc.c | 5 -
  1 file changed, 4 insertions(+), 1 deletion(-)

 diff --git a/fs/f2fs/gc.c b/fs/f2fs/gc.c
 index 38d56f6..ee213a8 100644
 --- a/fs/f2fs/gc.c
 +++ b/fs/f2fs/gc.c
 @@ -653,12 +653,15 @@ static void move_data_page(struct inode *inode, 
 block_t bidx, int gc_type)
.page = page,
.encrypted_page = NULL,
};
 +  bool is_dirty = PageDirty(page);
 +
set_page_dirty(page);
f2fs_wait_on_page_writeback(page, DATA, true);
if (clear_page_dirty_for_io(page))
inode_dec_dirty_pages(inode);
set_cold_data(page);
 -  do_write_data_page();
 +  if (do_write_data_page() && is_dirty)
 +  set_page_dirty(page);
>>>
>>> If this page is truncated with -ENOENT, we don't need to set it dirty again.
>>
>> Agree
>>
>>> I expect that, if we get an error here, do_garbage_collect() would retry 
>>> FG_GC
>>
>> IIRC, you have reworked the FG_GC flows changed from an infinite loop to 
>> trying
>> do the movement just one time. Here, I think if there are just few of blocks 
>> are
>> failed to be moved, we can give one more time for retrying. How do you think?
> 
> Mostly I expected here -ENOENT caused by race condition.

If we hit ENOENT case, we can pass get_valid_blocks check, so we don't need to
worry about this case, right?

> Do we have another expectation?

ENOMEM or EIO?

Thanks,

> 
> Thanks,
> 
>>
>>> again.
>>>
>>> Thanks,
>>>
clear_cold_data(page);
}
  out:
 -- 
 2.7.2
>>> .
>>>
> .
> 



Re: [PATCH] f2fs: fix to redirty page if fail to gc data page

2016-06-02 Thread Chao Yu
On 2016/6/3 13:08, Jaegeuk Kim wrote:
> On Tue, May 31, 2016 at 02:10:50PM +0800, Chao Yu wrote:
>> Hi Jaegeuk,
>>
>> On 2016/5/30 10:37, Jaegeuk Kim wrote:
>>> Hi Chao,
>>>
>>> On Sat, May 21, 2016 at 01:19:11PM +0800, Chao Yu wrote:
 From: Chao Yu 

 If we fail to move data page during foreground GC, we should give another
 chance to writeback that page which was set dirty previously by writer.

 Signed-off-by: Chao Yu 
 ---
  fs/f2fs/gc.c | 5 -
  1 file changed, 4 insertions(+), 1 deletion(-)

 diff --git a/fs/f2fs/gc.c b/fs/f2fs/gc.c
 index 38d56f6..ee213a8 100644
 --- a/fs/f2fs/gc.c
 +++ b/fs/f2fs/gc.c
 @@ -653,12 +653,15 @@ static void move_data_page(struct inode *inode, 
 block_t bidx, int gc_type)
.page = page,
.encrypted_page = NULL,
};
 +  bool is_dirty = PageDirty(page);
 +
set_page_dirty(page);
f2fs_wait_on_page_writeback(page, DATA, true);
if (clear_page_dirty_for_io(page))
inode_dec_dirty_pages(inode);
set_cold_data(page);
 -  do_write_data_page();
 +  if (do_write_data_page() && is_dirty)
 +  set_page_dirty(page);
>>>
>>> If this page is truncated with -ENOENT, we don't need to set it dirty again.
>>
>> Agree
>>
>>> I expect that, if we get an error here, do_garbage_collect() would retry 
>>> FG_GC
>>
>> IIRC, you have reworked the FG_GC flows changed from an infinite loop to 
>> trying
>> do the movement just one time. Here, I think if there are just few of blocks 
>> are
>> failed to be moved, we can give one more time for retrying. How do you think?
> 
> Mostly I expected here -ENOENT caused by race condition.

If we hit ENOENT case, we can pass get_valid_blocks check, so we don't need to
worry about this case, right?

> Do we have another expectation?

ENOMEM or EIO?

Thanks,

> 
> Thanks,
> 
>>
>>> again.
>>>
>>> Thanks,
>>>
clear_cold_data(page);
}
  out:
 -- 
 2.7.2
>>> .
>>>
> .
> 



Re: [PATCH V2 2/6] cpufreq: Remove cpufreq_frequency_get_table()

2016-06-02 Thread Viresh Kumar
On 02-06-16, 19:02, Javi Merino wrote:
> On Thu, Jun 02, 2016 at 09:06:26PM +0530, Viresh Kumar wrote:
> > On 2 June 2016 at 20:29, Javi Merino  wrote:
> > > In 5a31d594a973 ("cpufreq: Allow freq_table to be obtained for offline
> > > CPUs") you did the opposite: don't use cpufreq_cpu_get_raw() because
> > > it won't give you the policy of a cpu that is offline.  Now you are
> > > arguing that we should go back to cpufreq_cpu_get() which implicitly
> > > calls cpufreq_cpu_get_raw().  Won't we hit the same issue that
> > > 5a31d594a973 was trying to prevent: that we can't get a freq_table for
> > > a cpu that is offline?
> > 
> > Yes, that should be fixed. Thanks for letting me know about it :)
> 
> Ok, that was my only nit.  Other than that, it looks good to me.  For 
> cpu_cooling.c 
> 
> Acked-by: Javi Merino 

Thanks, I will be adding this to the original patch.

diff --git a/drivers/thermal/cpu_cooling.c b/drivers/thermal/cpu_cooling.c
index 63f760869651..4d678cfc81b1 100644
--- a/drivers/thermal/cpu_cooling.c
+++ b/drivers/thermal/cpu_cooling.c
@@ -792,10 +792,12 @@ __cpufreq_cooling_register(struct device_node *np,
struct cpufreq_cooling_device *cpufreq_dev;
char dev_name[THERMAL_NAME_LENGTH];
struct cpufreq_frequency_table *pos, *table;
+   struct cpumask temp_mask;
unsigned int freq, i, num_cpus;
int ret;
 
-   policy = cpufreq_cpu_get(cpumask_first(clip_cpus));
+   cpumask_and(_mask, clip_cpus, cpu_online_mask);
+   policy = cpufreq_cpu_get(cpumask_first(_mask));
if (!policy) {
pr_debug("%s: CPUFreq policy not found\n", __func__);
return ERR_PTR(-EPROBE_DEFER);


This will also make this problem clear, otherwise it was just hidden in the
function call which was really easy to miss, as I missed it as well :(

-- 
viresh


Re: [PATCH V2 2/6] cpufreq: Remove cpufreq_frequency_get_table()

2016-06-02 Thread Viresh Kumar
On 02-06-16, 19:02, Javi Merino wrote:
> On Thu, Jun 02, 2016 at 09:06:26PM +0530, Viresh Kumar wrote:
> > On 2 June 2016 at 20:29, Javi Merino  wrote:
> > > In 5a31d594a973 ("cpufreq: Allow freq_table to be obtained for offline
> > > CPUs") you did the opposite: don't use cpufreq_cpu_get_raw() because
> > > it won't give you the policy of a cpu that is offline.  Now you are
> > > arguing that we should go back to cpufreq_cpu_get() which implicitly
> > > calls cpufreq_cpu_get_raw().  Won't we hit the same issue that
> > > 5a31d594a973 was trying to prevent: that we can't get a freq_table for
> > > a cpu that is offline?
> > 
> > Yes, that should be fixed. Thanks for letting me know about it :)
> 
> Ok, that was my only nit.  Other than that, it looks good to me.  For 
> cpu_cooling.c 
> 
> Acked-by: Javi Merino 

Thanks, I will be adding this to the original patch.

diff --git a/drivers/thermal/cpu_cooling.c b/drivers/thermal/cpu_cooling.c
index 63f760869651..4d678cfc81b1 100644
--- a/drivers/thermal/cpu_cooling.c
+++ b/drivers/thermal/cpu_cooling.c
@@ -792,10 +792,12 @@ __cpufreq_cooling_register(struct device_node *np,
struct cpufreq_cooling_device *cpufreq_dev;
char dev_name[THERMAL_NAME_LENGTH];
struct cpufreq_frequency_table *pos, *table;
+   struct cpumask temp_mask;
unsigned int freq, i, num_cpus;
int ret;
 
-   policy = cpufreq_cpu_get(cpumask_first(clip_cpus));
+   cpumask_and(_mask, clip_cpus, cpu_online_mask);
+   policy = cpufreq_cpu_get(cpumask_first(_mask));
if (!policy) {
pr_debug("%s: CPUFreq policy not found\n", __func__);
return ERR_PTR(-EPROBE_DEFER);


This will also make this problem clear, otherwise it was just hidden in the
function call which was really easy to miss, as I missed it as well :(

-- 
viresh


Re: [PATCH] f2fs: fix to redirty page if fail to gc data page

2016-06-02 Thread Jaegeuk Kim
On Tue, May 31, 2016 at 02:10:50PM +0800, Chao Yu wrote:
> Hi Jaegeuk,
> 
> On 2016/5/30 10:37, Jaegeuk Kim wrote:
> > Hi Chao,
> > 
> > On Sat, May 21, 2016 at 01:19:11PM +0800, Chao Yu wrote:
> >> From: Chao Yu 
> >>
> >> If we fail to move data page during foreground GC, we should give another
> >> chance to writeback that page which was set dirty previously by writer.
> >>
> >> Signed-off-by: Chao Yu 
> >> ---
> >>  fs/f2fs/gc.c | 5 -
> >>  1 file changed, 4 insertions(+), 1 deletion(-)
> >>
> >> diff --git a/fs/f2fs/gc.c b/fs/f2fs/gc.c
> >> index 38d56f6..ee213a8 100644
> >> --- a/fs/f2fs/gc.c
> >> +++ b/fs/f2fs/gc.c
> >> @@ -653,12 +653,15 @@ static void move_data_page(struct inode *inode, 
> >> block_t bidx, int gc_type)
> >>.page = page,
> >>.encrypted_page = NULL,
> >>};
> >> +  bool is_dirty = PageDirty(page);
> >> +
> >>set_page_dirty(page);
> >>f2fs_wait_on_page_writeback(page, DATA, true);
> >>if (clear_page_dirty_for_io(page))
> >>inode_dec_dirty_pages(inode);
> >>set_cold_data(page);
> >> -  do_write_data_page();
> >> +  if (do_write_data_page() && is_dirty)
> >> +  set_page_dirty(page);
> > 
> > If this page is truncated with -ENOENT, we don't need to set it dirty again.
> 
> Agree
> 
> > I expect that, if we get an error here, do_garbage_collect() would retry 
> > FG_GC
> 
> IIRC, you have reworked the FG_GC flows changed from an infinite loop to 
> trying
> do the movement just one time. Here, I think if there are just few of blocks 
> are
> failed to be moved, we can give one more time for retrying. How do you think?

Mostly I expected here -ENOENT caused by race condition.
Do we have another expectation?

Thanks,

> 
> > again.
> > 
> > Thanks,
> > 
> >>clear_cold_data(page);
> >>}
> >>  out:
> >> -- 
> >> 2.7.2
> > .
> > 


Re: [PATCH] f2fs: fix to redirty page if fail to gc data page

2016-06-02 Thread Jaegeuk Kim
On Tue, May 31, 2016 at 02:10:50PM +0800, Chao Yu wrote:
> Hi Jaegeuk,
> 
> On 2016/5/30 10:37, Jaegeuk Kim wrote:
> > Hi Chao,
> > 
> > On Sat, May 21, 2016 at 01:19:11PM +0800, Chao Yu wrote:
> >> From: Chao Yu 
> >>
> >> If we fail to move data page during foreground GC, we should give another
> >> chance to writeback that page which was set dirty previously by writer.
> >>
> >> Signed-off-by: Chao Yu 
> >> ---
> >>  fs/f2fs/gc.c | 5 -
> >>  1 file changed, 4 insertions(+), 1 deletion(-)
> >>
> >> diff --git a/fs/f2fs/gc.c b/fs/f2fs/gc.c
> >> index 38d56f6..ee213a8 100644
> >> --- a/fs/f2fs/gc.c
> >> +++ b/fs/f2fs/gc.c
> >> @@ -653,12 +653,15 @@ static void move_data_page(struct inode *inode, 
> >> block_t bidx, int gc_type)
> >>.page = page,
> >>.encrypted_page = NULL,
> >>};
> >> +  bool is_dirty = PageDirty(page);
> >> +
> >>set_page_dirty(page);
> >>f2fs_wait_on_page_writeback(page, DATA, true);
> >>if (clear_page_dirty_for_io(page))
> >>inode_dec_dirty_pages(inode);
> >>set_cold_data(page);
> >> -  do_write_data_page();
> >> +  if (do_write_data_page() && is_dirty)
> >> +  set_page_dirty(page);
> > 
> > If this page is truncated with -ENOENT, we don't need to set it dirty again.
> 
> Agree
> 
> > I expect that, if we get an error here, do_garbage_collect() would retry 
> > FG_GC
> 
> IIRC, you have reworked the FG_GC flows changed from an infinite loop to 
> trying
> do the movement just one time. Here, I think if there are just few of blocks 
> are
> failed to be moved, we can give one more time for retrying. How do you think?

Mostly I expected here -ENOENT caused by race condition.
Do we have another expectation?

Thanks,

> 
> > again.
> > 
> > Thanks,
> > 
> >>clear_cold_data(page);
> >>}
> >>  out:
> >> -- 
> >> 2.7.2
> > .
> > 


[alsa-devel] [PATCH v2 8/9] ASoC: mediatek: add BT implementation

2016-06-02 Thread Garlic Tseng
Add BT implementation for mt2701 platform driver.

Signed-off-by: Garlic Tseng 
---
 sound/soc/mediatek/mt2701/mt2701-afe-pcm.c | 141 +
 1 file changed, 141 insertions(+)

diff --git a/sound/soc/mediatek/mt2701/mt2701-afe-pcm.c 
b/sound/soc/mediatek/mt2701/mt2701-afe-pcm.c
index 4c22ca0..9215b71 100644
--- a/sound/soc/mediatek/mt2701/mt2701-afe-pcm.c
+++ b/sound/soc/mediatek/mt2701/mt2701-afe-pcm.c
@@ -346,6 +346,88 @@ static int mt2701_afe_i2s_set_fmt(struct snd_soc_dai *dai, 
unsigned int fmt)
return 0;
 }
 
+static int mt2701_btmrg_startup(struct snd_pcm_substream *substream,
+   struct snd_soc_dai *dai)
+{
+   struct snd_soc_pcm_runtime *rtd = substream->private_data;
+   struct mtk_base_afe *afe = snd_soc_platform_get_drvdata(rtd->platform);
+   struct mt2701_afe_private *afe_priv = afe->platform_priv;
+
+   regmap_update_bits(afe->regmap, AUDIO_TOP_CON4,
+  AUDIO_TOP_CON4_PDN_MRGIF, 0);
+
+   afe_priv->mrg_enable[substream->stream] = 1;
+   return 0;
+}
+
+static int mt2701_btmrg_hw_params(struct snd_pcm_substream *substream,
+ struct snd_pcm_hw_params *params,
+ struct snd_soc_dai *dai)
+{
+   struct snd_soc_pcm_runtime *rtd = substream->private_data;
+   struct mtk_base_afe *afe = snd_soc_platform_get_drvdata(rtd->platform);
+   int stream_fs;
+   u32 val, msk;
+
+   pr_debug("%s() cpu_dai id %d\n", __func__, dai->id);
+   stream_fs = params_rate(params);
+
+   if ((stream_fs != 8000) && (stream_fs != 16000)) {
+   pr_err("%s() btmgr not supprt this stream_fs %d\n",
+  __func__, stream_fs);
+   return -EINVAL;
+   }
+
+   regmap_update_bits(afe->regmap, AFE_MRGIF_CON,
+  AFE_MRGIF_CON_I2S_MODE_MASK,
+  AFE_MRGIF_CON_I2S_MODE_32K);
+
+   val = AFE_DAIBT_CON0_BT_FUNC_EN | AFE_DAIBT_CON0_BT_FUNC_RDY
+ | AFE_DAIBT_CON0_MRG_USE;
+   msk = val;
+
+   if (stream_fs == 16000)
+   val |= AFE_DAIBT_CON0_BT_WIDE_MODE_EN;
+
+   msk |= AFE_DAIBT_CON0_BT_WIDE_MODE_EN;
+
+   regmap_update_bits(afe->regmap, AFE_DAIBT_CON0, msk, val);
+
+   regmap_update_bits(afe->regmap, AFE_DAIBT_CON0,
+  AFE_DAIBT_CON0_DAIBT_EN,
+  AFE_DAIBT_CON0_DAIBT_EN);
+   regmap_update_bits(afe->regmap, AFE_MRGIF_CON,
+  AFE_MRGIF_CON_MRG_I2S_EN,
+  AFE_MRGIF_CON_MRG_I2S_EN);
+   regmap_update_bits(afe->regmap, AFE_MRGIF_CON,
+  AFE_MRGIF_CON_MRG_EN,
+  AFE_MRGIF_CON_MRG_EN);
+   return 0;
+}
+
+static void mt2701_btmrg_shutdown(struct snd_pcm_substream *substream,
+ struct snd_soc_dai *dai)
+{
+   struct snd_soc_pcm_runtime *rtd = substream->private_data;
+   struct mtk_base_afe *afe = snd_soc_platform_get_drvdata(rtd->platform);
+   struct mt2701_afe_private *afe_priv = afe->platform_priv;
+
+   pr_debug("%s() cpu_dai id %d\n", __func__, dai->id);
+   /* if the other direction stream is not occupied */
+   if (!afe_priv->mrg_enable[!substream->stream]) {
+   regmap_update_bits(afe->regmap, AFE_DAIBT_CON0,
+  AFE_DAIBT_CON0_DAIBT_EN, 0);
+   regmap_update_bits(afe->regmap, AFE_MRGIF_CON,
+  AFE_MRGIF_CON_MRG_EN, 0);
+   regmap_update_bits(afe->regmap, AFE_MRGIF_CON,
+  AFE_MRGIF_CON_MRG_I2S_EN, 0);
+   regmap_update_bits(afe->regmap, AUDIO_TOP_CON4,
+  AUDIO_TOP_CON4_PDN_MRGIF,
+  AUDIO_TOP_CON4_PDN_MRGIF);
+   }
+   afe_priv->mrg_enable[substream->stream] = 0;
+}
+
 static int mt2701_simple_fe_startup(struct snd_pcm_substream *substream,
struct snd_soc_dai *dai)
 {
@@ -529,6 +611,13 @@ static const struct snd_soc_dai_ops mt2701_afe_i2s_ops = {
.set_fmt= mt2701_afe_i2s_set_fmt,
 };
 
+/* MRG BE DAIs*/
+static struct snd_soc_dai_ops mt2701_btmrg_ops = {
+   .startup = mt2701_btmrg_startup,
+   .shutdown = mt2701_btmrg_shutdown,
+   .hw_params = mt2701_btmrg_hw_params,
+};
+
 static struct snd_soc_dai_driver mt2701_afe_pcm_dais[] = {
/* FE DAIs: memory intefaces to CPU */
{
@@ -579,6 +668,36 @@ static struct snd_soc_dai_driver mt2701_afe_pcm_dais[] = {
},
.ops = _single_memif_dai_ops,
},
+   {
+   .name = "PCM_BT_DL",
+   .id = MT2701_MEMIF_DLBT,
+   .suspend = mtk_afe_dai_suspend,
+   .resume = mtk_afe_dai_resume,
+   .playback = {
+   

[alsa-devel] [PATCH v2 8/9] ASoC: mediatek: add BT implementation

2016-06-02 Thread Garlic Tseng
Add BT implementation for mt2701 platform driver.

Signed-off-by: Garlic Tseng 
---
 sound/soc/mediatek/mt2701/mt2701-afe-pcm.c | 141 +
 1 file changed, 141 insertions(+)

diff --git a/sound/soc/mediatek/mt2701/mt2701-afe-pcm.c 
b/sound/soc/mediatek/mt2701/mt2701-afe-pcm.c
index 4c22ca0..9215b71 100644
--- a/sound/soc/mediatek/mt2701/mt2701-afe-pcm.c
+++ b/sound/soc/mediatek/mt2701/mt2701-afe-pcm.c
@@ -346,6 +346,88 @@ static int mt2701_afe_i2s_set_fmt(struct snd_soc_dai *dai, 
unsigned int fmt)
return 0;
 }
 
+static int mt2701_btmrg_startup(struct snd_pcm_substream *substream,
+   struct snd_soc_dai *dai)
+{
+   struct snd_soc_pcm_runtime *rtd = substream->private_data;
+   struct mtk_base_afe *afe = snd_soc_platform_get_drvdata(rtd->platform);
+   struct mt2701_afe_private *afe_priv = afe->platform_priv;
+
+   regmap_update_bits(afe->regmap, AUDIO_TOP_CON4,
+  AUDIO_TOP_CON4_PDN_MRGIF, 0);
+
+   afe_priv->mrg_enable[substream->stream] = 1;
+   return 0;
+}
+
+static int mt2701_btmrg_hw_params(struct snd_pcm_substream *substream,
+ struct snd_pcm_hw_params *params,
+ struct snd_soc_dai *dai)
+{
+   struct snd_soc_pcm_runtime *rtd = substream->private_data;
+   struct mtk_base_afe *afe = snd_soc_platform_get_drvdata(rtd->platform);
+   int stream_fs;
+   u32 val, msk;
+
+   pr_debug("%s() cpu_dai id %d\n", __func__, dai->id);
+   stream_fs = params_rate(params);
+
+   if ((stream_fs != 8000) && (stream_fs != 16000)) {
+   pr_err("%s() btmgr not supprt this stream_fs %d\n",
+  __func__, stream_fs);
+   return -EINVAL;
+   }
+
+   regmap_update_bits(afe->regmap, AFE_MRGIF_CON,
+  AFE_MRGIF_CON_I2S_MODE_MASK,
+  AFE_MRGIF_CON_I2S_MODE_32K);
+
+   val = AFE_DAIBT_CON0_BT_FUNC_EN | AFE_DAIBT_CON0_BT_FUNC_RDY
+ | AFE_DAIBT_CON0_MRG_USE;
+   msk = val;
+
+   if (stream_fs == 16000)
+   val |= AFE_DAIBT_CON0_BT_WIDE_MODE_EN;
+
+   msk |= AFE_DAIBT_CON0_BT_WIDE_MODE_EN;
+
+   regmap_update_bits(afe->regmap, AFE_DAIBT_CON0, msk, val);
+
+   regmap_update_bits(afe->regmap, AFE_DAIBT_CON0,
+  AFE_DAIBT_CON0_DAIBT_EN,
+  AFE_DAIBT_CON0_DAIBT_EN);
+   regmap_update_bits(afe->regmap, AFE_MRGIF_CON,
+  AFE_MRGIF_CON_MRG_I2S_EN,
+  AFE_MRGIF_CON_MRG_I2S_EN);
+   regmap_update_bits(afe->regmap, AFE_MRGIF_CON,
+  AFE_MRGIF_CON_MRG_EN,
+  AFE_MRGIF_CON_MRG_EN);
+   return 0;
+}
+
+static void mt2701_btmrg_shutdown(struct snd_pcm_substream *substream,
+ struct snd_soc_dai *dai)
+{
+   struct snd_soc_pcm_runtime *rtd = substream->private_data;
+   struct mtk_base_afe *afe = snd_soc_platform_get_drvdata(rtd->platform);
+   struct mt2701_afe_private *afe_priv = afe->platform_priv;
+
+   pr_debug("%s() cpu_dai id %d\n", __func__, dai->id);
+   /* if the other direction stream is not occupied */
+   if (!afe_priv->mrg_enable[!substream->stream]) {
+   regmap_update_bits(afe->regmap, AFE_DAIBT_CON0,
+  AFE_DAIBT_CON0_DAIBT_EN, 0);
+   regmap_update_bits(afe->regmap, AFE_MRGIF_CON,
+  AFE_MRGIF_CON_MRG_EN, 0);
+   regmap_update_bits(afe->regmap, AFE_MRGIF_CON,
+  AFE_MRGIF_CON_MRG_I2S_EN, 0);
+   regmap_update_bits(afe->regmap, AUDIO_TOP_CON4,
+  AUDIO_TOP_CON4_PDN_MRGIF,
+  AUDIO_TOP_CON4_PDN_MRGIF);
+   }
+   afe_priv->mrg_enable[substream->stream] = 0;
+}
+
 static int mt2701_simple_fe_startup(struct snd_pcm_substream *substream,
struct snd_soc_dai *dai)
 {
@@ -529,6 +611,13 @@ static const struct snd_soc_dai_ops mt2701_afe_i2s_ops = {
.set_fmt= mt2701_afe_i2s_set_fmt,
 };
 
+/* MRG BE DAIs*/
+static struct snd_soc_dai_ops mt2701_btmrg_ops = {
+   .startup = mt2701_btmrg_startup,
+   .shutdown = mt2701_btmrg_shutdown,
+   .hw_params = mt2701_btmrg_hw_params,
+};
+
 static struct snd_soc_dai_driver mt2701_afe_pcm_dais[] = {
/* FE DAIs: memory intefaces to CPU */
{
@@ -579,6 +668,36 @@ static struct snd_soc_dai_driver mt2701_afe_pcm_dais[] = {
},
.ops = _single_memif_dai_ops,
},
+   {
+   .name = "PCM_BT_DL",
+   .id = MT2701_MEMIF_DLBT,
+   .suspend = mtk_afe_dai_suspend,
+   .resume = mtk_afe_dai_resume,
+   .playback = {
+   .stream_name = "DLBT",
+   

[alsa-devel] [PATCH v2 7/9] ASoC: bt-sco: extend rate and add a general compatible string

2016-06-02 Thread Garlic Tseng
Add supports for 16k (wideband BT) and add a general compatible
string "linux,bt-sco"

Signed-off-by: Garlic Tseng 
---
 Documentation/devicetree/bindings/sound/bt-sco.txt | 2 +-
 sound/soc/codecs/bt-sco.c  | 5 +++--
 2 files changed, 4 insertions(+), 3 deletions(-)

diff --git a/Documentation/devicetree/bindings/sound/bt-sco.txt 
b/Documentation/devicetree/bindings/sound/bt-sco.txt
index 29b8e5d..641edf7 100644
--- a/Documentation/devicetree/bindings/sound/bt-sco.txt
+++ b/Documentation/devicetree/bindings/sound/bt-sco.txt
@@ -4,7 +4,7 @@ This device support generic Bluetooth SCO link.
 
 Required properties:
 
-  - compatible : "delta,dfbmcs320"
+  - compatible : "delta,dfbmcs320" or "linux,bt-sco"
 
 Example:
 
diff --git a/sound/soc/codecs/bt-sco.c b/sound/soc/codecs/bt-sco.c
index b084ad1..101b384 100644
--- a/sound/soc/codecs/bt-sco.c
+++ b/sound/soc/codecs/bt-sco.c
@@ -31,14 +31,14 @@ static struct snd_soc_dai_driver bt_sco_dai = {
.stream_name = "Playback",
.channels_min = 1,
.channels_max = 1,
-   .rates = SNDRV_PCM_RATE_8000,
+   .rates = SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_16000,
.formats = SNDRV_PCM_FMTBIT_S16_LE,
},
.capture = {
 .stream_name = "Capture",
.channels_min = 1,
.channels_max = 1,
-   .rates = SNDRV_PCM_RATE_8000,
+   .rates = SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_16000,
.formats = SNDRV_PCM_FMTBIT_S16_LE,
},
 };
@@ -77,6 +77,7 @@ MODULE_DEVICE_TABLE(platform, bt_sco_driver_ids);
 #if defined(CONFIG_OF)
 static const struct of_device_id bt_sco_codec_of_match[] = {
{ .compatible = "delta,dfbmcs320", },
+   { .compatible = "linux,bt-sco", },
{},
 };
 MODULE_DEVICE_TABLE(of, bt_sco_codec_of_match);
-- 
1.9.1



[alsa-devel] [PATCH v2 5/9] ASoC: mediatek: add structure define and clock control for 2701

2016-06-02 Thread Garlic Tseng
add structure define and clock control function for 2701.

Signed-off-by: Garlic Tseng 
---
 sound/soc/mediatek/mt2701/mt2701-afe-clock-ctrl.c | 357 ++
 sound/soc/mediatek/mt2701/mt2701-afe-clock-ctrl.h |  33 ++
 sound/soc/mediatek/mt2701/mt2701-afe-common.h | 185 +++
 sound/soc/mediatek/mt2701/mt2701-reg.h| 186 +++
 4 files changed, 761 insertions(+)
 create mode 100644 sound/soc/mediatek/mt2701/mt2701-afe-clock-ctrl.c
 create mode 100644 sound/soc/mediatek/mt2701/mt2701-afe-clock-ctrl.h
 create mode 100644 sound/soc/mediatek/mt2701/mt2701-afe-common.h
 create mode 100644 sound/soc/mediatek/mt2701/mt2701-reg.h

diff --git a/sound/soc/mediatek/mt2701/mt2701-afe-clock-ctrl.c 
b/sound/soc/mediatek/mt2701/mt2701-afe-clock-ctrl.c
new file mode 100644
index 000..479cd5a
--- /dev/null
+++ b/sound/soc/mediatek/mt2701/mt2701-afe-clock-ctrl.c
@@ -0,0 +1,357 @@
+/*
+ * mt2701-afe-clock-ctrl.c  --  Mediatek 2701 afe clock ctrl
+ *
+ * Copyright (c) 2016 MediaTek Inc.
+ * Author: Garlic Tseng 
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only 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 "mt2701-afe-common.h"
+#include "mt2701-afe-clock-ctrl.h"
+
+static const char *aud_clks[MT2701_CLOCK_NUM] = {
+   [MT2701_AUD_INFRA_SYS_AUDIO] = "infra_sys_audio_clk",
+   [MT2701_AUD_AUD_MUX1_SEL] = "top_audio_mux1_sel",
+   [MT2701_AUD_AUD_MUX2_SEL] = "top_audio_mux2_sel",
+   [MT2701_AUD_AUD_MUX1_DIV] = "top_audio_mux1_div",
+   [MT2701_AUD_AUD_MUX2_DIV] = "top_audio_mux2_div",
+   [MT2701_AUD_AUD_48K_TIMING] = "top_audio_48k_timing",
+   [MT2701_AUD_AUD_44K_TIMING] = "top_audio_44k_timing",
+   [MT2701_AUD_AUDPLL_MUX_SEL] = "top_audpll_mux_sel",
+   [MT2701_AUD_APLL_SEL] = "top_apll_sel",
+   [MT2701_AUD_AUD1PLL_98M] = "top_aud1_pll_98M",
+   [MT2701_AUD_AUD2PLL_90M] = "top_aud2_pll_90M",
+   [MT2701_AUD_HADDS2PLL_98M] = "top_hadds2_pll_98M",
+   [MT2701_AUD_HADDS2PLL_294M] = "top_hadds2_pll_294M",
+   [MT2701_AUD_AUDPLL] = "top_audpll",
+   [MT2701_AUD_AUDPLL_D4] = "top_audpll_d4",
+   [MT2701_AUD_AUDPLL_D8] = "top_audpll_d8",
+   [MT2701_AUD_AUDPLL_D16] = "top_audpll_d16",
+   [MT2701_AUD_AUDPLL_D24] = "top_audpll_d24",
+   [MT2701_AUD_AUDINTBUS] = "top_audintbus_sel",
+   [MT2701_AUD_CLK_26M] = "clk_26m",
+   [MT2701_AUD_SYSPLL1_D4] = "top_syspll1_d4",
+   [MT2701_AUD_AUD_K1_SRC_SEL] = "top_aud_k1_src_sel",
+   [MT2701_AUD_AUD_K2_SRC_SEL] = "top_aud_k2_src_sel",
+   [MT2701_AUD_AUD_K3_SRC_SEL] = "top_aud_k3_src_sel",
+   [MT2701_AUD_AUD_K4_SRC_SEL] = "top_aud_k4_src_sel",
+   [MT2701_AUD_AUD_K5_SRC_SEL] = "top_aud_k5_src_sel",
+   [MT2701_AUD_AUD_K6_SRC_SEL] = "top_aud_k6_src_sel",
+   [MT2701_AUD_AUD_K1_SRC_DIV] = "top_aud_k1_src_div",
+   [MT2701_AUD_AUD_K2_SRC_DIV] = "top_aud_k2_src_div",
+   [MT2701_AUD_AUD_K3_SRC_DIV] = "top_aud_k3_src_div",
+   [MT2701_AUD_AUD_K4_SRC_DIV] = "top_aud_k4_src_div",
+   [MT2701_AUD_AUD_K5_SRC_DIV] = "top_aud_k5_src_div",
+   [MT2701_AUD_AUD_K6_SRC_DIV] = "top_aud_k6_src_div",
+   [MT2701_AUD_AUD_I2S1_MCLK] = "top_aud_i2s1_mclk",
+   [MT2701_AUD_AUD_I2S2_MCLK] = "top_aud_i2s2_mclk",
+   [MT2701_AUD_AUD_I2S3_MCLK] = "top_aud_i2s3_mclk",
+   [MT2701_AUD_AUD_I2S4_MCLK] = "top_aud_i2s4_mclk",
+   [MT2701_AUD_AUD_I2S5_MCLK] = "top_aud_i2s5_mclk",
+   [MT2701_AUD_AUD_I2S6_MCLK] = "top_aud_i2s6_mclk",
+   [MT2701_AUD_ASM_M_SEL] = "top_asm_m_sel",
+   [MT2701_AUD_ASM_H_SEL] = "top_asm_h_sel",
+   [MT2701_AUD_UNIVPLL2_D4] = "top_univpll2_d4",
+   [MT2701_AUD_UNIVPLL2_D2] = "top_univpll2_d2",
+   [MT2701_AUD_SYSPLL_D5] = "top_syspll_d5",
+};
+
+void mt2701_init_clock(struct mtk_base_afe *afe)
+{
+   struct mt2701_afe_private *afe_priv = afe->platform_priv;
+   int i = 0;
+
+   for (i = 0; i < MT2701_CLOCK_NUM; i++) {
+   afe_priv->clocks[i] = devm_clk_get(afe->dev, aud_clks[i]);
+   if (IS_ERR(aud_clks[i]))
+   dev_warn(afe->dev, "%s devm_clk_get %s fail\n",
+__func__, aud_clks[i]);
+   }
+}
+
+void mt2701_afe_enable_clock(struct mtk_base_afe *afe, int en)
+{
+   if (en) {
+   mt2701_turn_on_a1sys_clock(afe);
+   mt2701_turn_on_a2sys_clock(afe);
+   mt2701_turn_on_afe_clock(afe);
+   regmap_update_bits(afe->regmap, ASYS_TOP_CON,
+  

Re: NFS/d_splice_alias breakage

2016-06-02 Thread Oleg Drokin

On Jun 3, 2016, at 12:26 AM, Al Viro wrote:

> On Thu, Jun 02, 2016 at 11:43:59PM -0400, Oleg Drokin wrote:
> 
>>> Which of the call sites had that been and how does one reproduce that fun?
>>> If you feel that posting a reproducer in the open is a bad idea, just send
>>> it off-list...
>> 
>> This is fs/nfs/dir.c::nfs_lookup() right after no_entry label.
> 
> Bloody hell...  Was that sucker hashed on the entry into nfs_lookup()?
> If we get that with call as a method, we are really fucked.
> 
> 
> 
> Ho-hum...  One of the goto no_open; in nfs_atomic_open()?  That would
> mean a stale negative dentry in dcache that has escaped revalidation...
> Wait a minute, didn't nfs ->d_revalidate() skip everything in some
> cases, leaving it to ->atomic_open()?
> 
> Looks like the right thing to do would be to do d_drop() at no_open:,
> just before we call nfs_lookup().  If not earlier, actually...  How
> about the following?

This one cures the insta-crash I was having, and I see no other ill-effects so 
far.

> 
> diff --git a/fs/nfs/dir.c b/fs/nfs/dir.c
> index aaf7bd0..6e3a6f4 100644
> --- a/fs/nfs/dir.c
> +++ b/fs/nfs/dir.c
> @@ -1536,9 +1536,9 @@ int nfs_atomic_open(struct inode *dir, struct dentry 
> *dentry,
>   err = PTR_ERR(inode);
>   trace_nfs_atomic_open_exit(dir, ctx, open_flags, err);
>   put_nfs_open_context(ctx);
> + d_drop(dentry);
>   switch (err) {
>   case -ENOENT:
> - d_drop(dentry);
>   d_add(dentry, NULL);
>   nfs_set_verifier(dentry, 
> nfs_save_change_attribute(dir));
>   break;



[alsa-devel] [PATCH v2 4/9] ASoC: mediatek: add documents for mt2701

2016-06-02 Thread Garlic Tseng
add mt2701-afe-pcm.txt and mt2701-cs42448.txt for mt2701

Signed-off-by: Garlic Tseng 
---
 .../devicetree/bindings/sound/mt2701-afe-pcm.txt   | 150 +
 .../devicetree/bindings/sound/mt2701-cs42448.txt   |  43 ++
 2 files changed, 193 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/sound/mt2701-afe-pcm.txt
 create mode 100644 Documentation/devicetree/bindings/sound/mt2701-cs42448.txt

diff --git a/Documentation/devicetree/bindings/sound/mt2701-afe-pcm.txt 
b/Documentation/devicetree/bindings/sound/mt2701-afe-pcm.txt
new file mode 100644
index 000..3e623a7
--- /dev/null
+++ b/Documentation/devicetree/bindings/sound/mt2701-afe-pcm.txt
@@ -0,0 +1,150 @@
+Mediatek AFE PCM controller for mt2701
+
+Required properties:
+- compatible = "mediatek,mt2701-audio";
+- reg: register location and size
+- interrupts: Should contain AFE interrupt
+- clock-names: should have these clock names:
+   "infra_sys_audio_clk",
+   "top_audio_mux1_sel",
+   "top_audio_mux2_sel",
+   "top_audio_mux1_div",
+   "top_audio_mux2_div",
+   "top_audio_48k_timing",
+   "top_audio_44k_timing",
+   "top_audpll_mux_sel",
+   "top_apll_sel",
+   "top_aud1_pll_98M",
+   "top_aud2_pll_90M",
+   "top_hadds2_pll_98M",
+   "top_hadds2_pll_294M",
+   "top_audpll",
+   "top_audpll_d4",
+   "top_audpll_d8",
+   "top_audpll_d16",
+   "top_audpll_d24",
+   "top_audintbus_sel",
+   "clk_26m",
+   "top_syspll1_d4",
+   "top_aud_k1_src_sel",
+   "top_aud_k2_src_sel",
+   "top_aud_k3_src_sel",
+   "top_aud_k4_src_sel",
+   "top_aud_k5_src_sel",
+   "top_aud_k6_src_sel",
+   "top_aud_k1_src_div",
+   "top_aud_k2_src_div",
+   "top_aud_k3_src_div",
+   "top_aud_k4_src_div",
+   "top_aud_k5_src_div",
+   "top_aud_k6_src_div",
+   "top_aud_i2s1_mclk",
+   "top_aud_i2s2_mclk",
+   "top_aud_i2s3_mclk",
+   "top_aud_i2s4_mclk",
+   "top_aud_i2s5_mclk",
+   "top_aud_i2s6_mclk",
+   "top_asm_m_sel",
+   "top_asm_h_sel",
+   "top_univpll2_d4",
+   "top_univpll2_d2",
+   "top_syspll_d5";
+
+Example:
+
+   afe: mt2701-afe-pcm@1122 {
+   compatible = "mediatek,mt2701-audio";
+   reg = <0 0x1122 0 0x2000>,
+ <0 0x112A 0 0x2>;
+   interrupts = ,
+;
+   clocks = < CLK_INFRA_AUDIO>,
+< CLK_TOP_AUD_MUX1_SEL>,
+< CLK_TOP_AUD_MUX2_SEL>,
+< CLK_TOP_AUD_MUX1_DIV>,
+< CLK_TOP_AUD_MUX2_DIV>,
+< CLK_TOP_AUD_48K_TIMING>,
+< CLK_TOP_AUD_44K_TIMING>,
+< CLK_TOP_AUDPLL_MUX_SEL>,
+< CLK_TOP_APLL_SEL>,
+< CLK_TOP_AUD1PLL_98M>,
+< CLK_TOP_AUD2PLL_90M>,
+< CLK_TOP_HADDS2PLL_98M>,
+< CLK_TOP_HADDS2PLL_294M>,
+< CLK_TOP_AUDPLL>,
+< CLK_TOP_AUDPLL_D4>,
+< CLK_TOP_AUDPLL_D8>,
+< CLK_TOP_AUDPLL_D16>,
+< CLK_TOP_AUDPLL_D24>,
+< CLK_TOP_AUDINTBUS_SEL>,
+<>,
+< CLK_TOP_SYSPLL1_D4>,
+< CLK_TOP_AUD_K1_SRC_SEL>,
+< CLK_TOP_AUD_K2_SRC_SEL>,
+< CLK_TOP_AUD_K3_SRC_SEL>,
+< CLK_TOP_AUD_K4_SRC_SEL>,
+< CLK_TOP_AUD_K5_SRC_SEL>,
+< CLK_TOP_AUD_K6_SRC_SEL>,
+< CLK_TOP_AUD_K1_SRC_DIV>,
+< CLK_TOP_AUD_K2_SRC_DIV>,
+< CLK_TOP_AUD_K3_SRC_DIV>,
+< CLK_TOP_AUD_K4_SRC_DIV>,
+< CLK_TOP_AUD_K5_SRC_DIV>,
+< CLK_TOP_AUD_K6_SRC_DIV>,
+< CLK_TOP_AUD_I2S1_MCLK>,
+< CLK_TOP_AUD_I2S2_MCLK>,
+< CLK_TOP_AUD_I2S3_MCLK>,
+< CLK_TOP_AUD_I2S4_MCLK>,
+< CLK_TOP_AUD_I2S5_MCLK>,
+< CLK_TOP_AUD_I2S6_MCLK>,
+< CLK_TOP_ASM_M_SEL>,
+< CLK_TOP_ASM_H_SEL>,
+< CLK_TOP_UNIVPLL2_D4>,
+< CLK_TOP_UNIVPLL2_D2>,
+< 

[alsa-devel] [PATCH v2 7/9] ASoC: bt-sco: extend rate and add a general compatible string

2016-06-02 Thread Garlic Tseng
Add supports for 16k (wideband BT) and add a general compatible
string "linux,bt-sco"

Signed-off-by: Garlic Tseng 
---
 Documentation/devicetree/bindings/sound/bt-sco.txt | 2 +-
 sound/soc/codecs/bt-sco.c  | 5 +++--
 2 files changed, 4 insertions(+), 3 deletions(-)

diff --git a/Documentation/devicetree/bindings/sound/bt-sco.txt 
b/Documentation/devicetree/bindings/sound/bt-sco.txt
index 29b8e5d..641edf7 100644
--- a/Documentation/devicetree/bindings/sound/bt-sco.txt
+++ b/Documentation/devicetree/bindings/sound/bt-sco.txt
@@ -4,7 +4,7 @@ This device support generic Bluetooth SCO link.
 
 Required properties:
 
-  - compatible : "delta,dfbmcs320"
+  - compatible : "delta,dfbmcs320" or "linux,bt-sco"
 
 Example:
 
diff --git a/sound/soc/codecs/bt-sco.c b/sound/soc/codecs/bt-sco.c
index b084ad1..101b384 100644
--- a/sound/soc/codecs/bt-sco.c
+++ b/sound/soc/codecs/bt-sco.c
@@ -31,14 +31,14 @@ static struct snd_soc_dai_driver bt_sco_dai = {
.stream_name = "Playback",
.channels_min = 1,
.channels_max = 1,
-   .rates = SNDRV_PCM_RATE_8000,
+   .rates = SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_16000,
.formats = SNDRV_PCM_FMTBIT_S16_LE,
},
.capture = {
 .stream_name = "Capture",
.channels_min = 1,
.channels_max = 1,
-   .rates = SNDRV_PCM_RATE_8000,
+   .rates = SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_16000,
.formats = SNDRV_PCM_FMTBIT_S16_LE,
},
 };
@@ -77,6 +77,7 @@ MODULE_DEVICE_TABLE(platform, bt_sco_driver_ids);
 #if defined(CONFIG_OF)
 static const struct of_device_id bt_sco_codec_of_match[] = {
{ .compatible = "delta,dfbmcs320", },
+   { .compatible = "linux,bt-sco", },
{},
 };
 MODULE_DEVICE_TABLE(of, bt_sco_codec_of_match);
-- 
1.9.1



[alsa-devel] [PATCH v2 5/9] ASoC: mediatek: add structure define and clock control for 2701

2016-06-02 Thread Garlic Tseng
add structure define and clock control function for 2701.

Signed-off-by: Garlic Tseng 
---
 sound/soc/mediatek/mt2701/mt2701-afe-clock-ctrl.c | 357 ++
 sound/soc/mediatek/mt2701/mt2701-afe-clock-ctrl.h |  33 ++
 sound/soc/mediatek/mt2701/mt2701-afe-common.h | 185 +++
 sound/soc/mediatek/mt2701/mt2701-reg.h| 186 +++
 4 files changed, 761 insertions(+)
 create mode 100644 sound/soc/mediatek/mt2701/mt2701-afe-clock-ctrl.c
 create mode 100644 sound/soc/mediatek/mt2701/mt2701-afe-clock-ctrl.h
 create mode 100644 sound/soc/mediatek/mt2701/mt2701-afe-common.h
 create mode 100644 sound/soc/mediatek/mt2701/mt2701-reg.h

diff --git a/sound/soc/mediatek/mt2701/mt2701-afe-clock-ctrl.c 
b/sound/soc/mediatek/mt2701/mt2701-afe-clock-ctrl.c
new file mode 100644
index 000..479cd5a
--- /dev/null
+++ b/sound/soc/mediatek/mt2701/mt2701-afe-clock-ctrl.c
@@ -0,0 +1,357 @@
+/*
+ * mt2701-afe-clock-ctrl.c  --  Mediatek 2701 afe clock ctrl
+ *
+ * Copyright (c) 2016 MediaTek Inc.
+ * Author: Garlic Tseng 
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only 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 "mt2701-afe-common.h"
+#include "mt2701-afe-clock-ctrl.h"
+
+static const char *aud_clks[MT2701_CLOCK_NUM] = {
+   [MT2701_AUD_INFRA_SYS_AUDIO] = "infra_sys_audio_clk",
+   [MT2701_AUD_AUD_MUX1_SEL] = "top_audio_mux1_sel",
+   [MT2701_AUD_AUD_MUX2_SEL] = "top_audio_mux2_sel",
+   [MT2701_AUD_AUD_MUX1_DIV] = "top_audio_mux1_div",
+   [MT2701_AUD_AUD_MUX2_DIV] = "top_audio_mux2_div",
+   [MT2701_AUD_AUD_48K_TIMING] = "top_audio_48k_timing",
+   [MT2701_AUD_AUD_44K_TIMING] = "top_audio_44k_timing",
+   [MT2701_AUD_AUDPLL_MUX_SEL] = "top_audpll_mux_sel",
+   [MT2701_AUD_APLL_SEL] = "top_apll_sel",
+   [MT2701_AUD_AUD1PLL_98M] = "top_aud1_pll_98M",
+   [MT2701_AUD_AUD2PLL_90M] = "top_aud2_pll_90M",
+   [MT2701_AUD_HADDS2PLL_98M] = "top_hadds2_pll_98M",
+   [MT2701_AUD_HADDS2PLL_294M] = "top_hadds2_pll_294M",
+   [MT2701_AUD_AUDPLL] = "top_audpll",
+   [MT2701_AUD_AUDPLL_D4] = "top_audpll_d4",
+   [MT2701_AUD_AUDPLL_D8] = "top_audpll_d8",
+   [MT2701_AUD_AUDPLL_D16] = "top_audpll_d16",
+   [MT2701_AUD_AUDPLL_D24] = "top_audpll_d24",
+   [MT2701_AUD_AUDINTBUS] = "top_audintbus_sel",
+   [MT2701_AUD_CLK_26M] = "clk_26m",
+   [MT2701_AUD_SYSPLL1_D4] = "top_syspll1_d4",
+   [MT2701_AUD_AUD_K1_SRC_SEL] = "top_aud_k1_src_sel",
+   [MT2701_AUD_AUD_K2_SRC_SEL] = "top_aud_k2_src_sel",
+   [MT2701_AUD_AUD_K3_SRC_SEL] = "top_aud_k3_src_sel",
+   [MT2701_AUD_AUD_K4_SRC_SEL] = "top_aud_k4_src_sel",
+   [MT2701_AUD_AUD_K5_SRC_SEL] = "top_aud_k5_src_sel",
+   [MT2701_AUD_AUD_K6_SRC_SEL] = "top_aud_k6_src_sel",
+   [MT2701_AUD_AUD_K1_SRC_DIV] = "top_aud_k1_src_div",
+   [MT2701_AUD_AUD_K2_SRC_DIV] = "top_aud_k2_src_div",
+   [MT2701_AUD_AUD_K3_SRC_DIV] = "top_aud_k3_src_div",
+   [MT2701_AUD_AUD_K4_SRC_DIV] = "top_aud_k4_src_div",
+   [MT2701_AUD_AUD_K5_SRC_DIV] = "top_aud_k5_src_div",
+   [MT2701_AUD_AUD_K6_SRC_DIV] = "top_aud_k6_src_div",
+   [MT2701_AUD_AUD_I2S1_MCLK] = "top_aud_i2s1_mclk",
+   [MT2701_AUD_AUD_I2S2_MCLK] = "top_aud_i2s2_mclk",
+   [MT2701_AUD_AUD_I2S3_MCLK] = "top_aud_i2s3_mclk",
+   [MT2701_AUD_AUD_I2S4_MCLK] = "top_aud_i2s4_mclk",
+   [MT2701_AUD_AUD_I2S5_MCLK] = "top_aud_i2s5_mclk",
+   [MT2701_AUD_AUD_I2S6_MCLK] = "top_aud_i2s6_mclk",
+   [MT2701_AUD_ASM_M_SEL] = "top_asm_m_sel",
+   [MT2701_AUD_ASM_H_SEL] = "top_asm_h_sel",
+   [MT2701_AUD_UNIVPLL2_D4] = "top_univpll2_d4",
+   [MT2701_AUD_UNIVPLL2_D2] = "top_univpll2_d2",
+   [MT2701_AUD_SYSPLL_D5] = "top_syspll_d5",
+};
+
+void mt2701_init_clock(struct mtk_base_afe *afe)
+{
+   struct mt2701_afe_private *afe_priv = afe->platform_priv;
+   int i = 0;
+
+   for (i = 0; i < MT2701_CLOCK_NUM; i++) {
+   afe_priv->clocks[i] = devm_clk_get(afe->dev, aud_clks[i]);
+   if (IS_ERR(aud_clks[i]))
+   dev_warn(afe->dev, "%s devm_clk_get %s fail\n",
+__func__, aud_clks[i]);
+   }
+}
+
+void mt2701_afe_enable_clock(struct mtk_base_afe *afe, int en)
+{
+   if (en) {
+   mt2701_turn_on_a1sys_clock(afe);
+   mt2701_turn_on_a2sys_clock(afe);
+   mt2701_turn_on_afe_clock(afe);
+   regmap_update_bits(afe->regmap, ASYS_TOP_CON,
+  AUDIO_TOP_CON0_A1SYS_A2SYS_ON,
+

Re: NFS/d_splice_alias breakage

2016-06-02 Thread Oleg Drokin

On Jun 3, 2016, at 12:26 AM, Al Viro wrote:

> On Thu, Jun 02, 2016 at 11:43:59PM -0400, Oleg Drokin wrote:
> 
>>> Which of the call sites had that been and how does one reproduce that fun?
>>> If you feel that posting a reproducer in the open is a bad idea, just send
>>> it off-list...
>> 
>> This is fs/nfs/dir.c::nfs_lookup() right after no_entry label.
> 
> Bloody hell...  Was that sucker hashed on the entry into nfs_lookup()?
> If we get that with call as a method, we are really fucked.
> 
> 
> 
> Ho-hum...  One of the goto no_open; in nfs_atomic_open()?  That would
> mean a stale negative dentry in dcache that has escaped revalidation...
> Wait a minute, didn't nfs ->d_revalidate() skip everything in some
> cases, leaving it to ->atomic_open()?
> 
> Looks like the right thing to do would be to do d_drop() at no_open:,
> just before we call nfs_lookup().  If not earlier, actually...  How
> about the following?

This one cures the insta-crash I was having, and I see no other ill-effects so 
far.

> 
> diff --git a/fs/nfs/dir.c b/fs/nfs/dir.c
> index aaf7bd0..6e3a6f4 100644
> --- a/fs/nfs/dir.c
> +++ b/fs/nfs/dir.c
> @@ -1536,9 +1536,9 @@ int nfs_atomic_open(struct inode *dir, struct dentry 
> *dentry,
>   err = PTR_ERR(inode);
>   trace_nfs_atomic_open_exit(dir, ctx, open_flags, err);
>   put_nfs_open_context(ctx);
> + d_drop(dentry);
>   switch (err) {
>   case -ENOENT:
> - d_drop(dentry);
>   d_add(dentry, NULL);
>   nfs_set_verifier(dentry, 
> nfs_save_change_attribute(dir));
>   break;



[alsa-devel] [PATCH v2 4/9] ASoC: mediatek: add documents for mt2701

2016-06-02 Thread Garlic Tseng
add mt2701-afe-pcm.txt and mt2701-cs42448.txt for mt2701

Signed-off-by: Garlic Tseng 
---
 .../devicetree/bindings/sound/mt2701-afe-pcm.txt   | 150 +
 .../devicetree/bindings/sound/mt2701-cs42448.txt   |  43 ++
 2 files changed, 193 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/sound/mt2701-afe-pcm.txt
 create mode 100644 Documentation/devicetree/bindings/sound/mt2701-cs42448.txt

diff --git a/Documentation/devicetree/bindings/sound/mt2701-afe-pcm.txt 
b/Documentation/devicetree/bindings/sound/mt2701-afe-pcm.txt
new file mode 100644
index 000..3e623a7
--- /dev/null
+++ b/Documentation/devicetree/bindings/sound/mt2701-afe-pcm.txt
@@ -0,0 +1,150 @@
+Mediatek AFE PCM controller for mt2701
+
+Required properties:
+- compatible = "mediatek,mt2701-audio";
+- reg: register location and size
+- interrupts: Should contain AFE interrupt
+- clock-names: should have these clock names:
+   "infra_sys_audio_clk",
+   "top_audio_mux1_sel",
+   "top_audio_mux2_sel",
+   "top_audio_mux1_div",
+   "top_audio_mux2_div",
+   "top_audio_48k_timing",
+   "top_audio_44k_timing",
+   "top_audpll_mux_sel",
+   "top_apll_sel",
+   "top_aud1_pll_98M",
+   "top_aud2_pll_90M",
+   "top_hadds2_pll_98M",
+   "top_hadds2_pll_294M",
+   "top_audpll",
+   "top_audpll_d4",
+   "top_audpll_d8",
+   "top_audpll_d16",
+   "top_audpll_d24",
+   "top_audintbus_sel",
+   "clk_26m",
+   "top_syspll1_d4",
+   "top_aud_k1_src_sel",
+   "top_aud_k2_src_sel",
+   "top_aud_k3_src_sel",
+   "top_aud_k4_src_sel",
+   "top_aud_k5_src_sel",
+   "top_aud_k6_src_sel",
+   "top_aud_k1_src_div",
+   "top_aud_k2_src_div",
+   "top_aud_k3_src_div",
+   "top_aud_k4_src_div",
+   "top_aud_k5_src_div",
+   "top_aud_k6_src_div",
+   "top_aud_i2s1_mclk",
+   "top_aud_i2s2_mclk",
+   "top_aud_i2s3_mclk",
+   "top_aud_i2s4_mclk",
+   "top_aud_i2s5_mclk",
+   "top_aud_i2s6_mclk",
+   "top_asm_m_sel",
+   "top_asm_h_sel",
+   "top_univpll2_d4",
+   "top_univpll2_d2",
+   "top_syspll_d5";
+
+Example:
+
+   afe: mt2701-afe-pcm@1122 {
+   compatible = "mediatek,mt2701-audio";
+   reg = <0 0x1122 0 0x2000>,
+ <0 0x112A 0 0x2>;
+   interrupts = ,
+;
+   clocks = < CLK_INFRA_AUDIO>,
+< CLK_TOP_AUD_MUX1_SEL>,
+< CLK_TOP_AUD_MUX2_SEL>,
+< CLK_TOP_AUD_MUX1_DIV>,
+< CLK_TOP_AUD_MUX2_DIV>,
+< CLK_TOP_AUD_48K_TIMING>,
+< CLK_TOP_AUD_44K_TIMING>,
+< CLK_TOP_AUDPLL_MUX_SEL>,
+< CLK_TOP_APLL_SEL>,
+< CLK_TOP_AUD1PLL_98M>,
+< CLK_TOP_AUD2PLL_90M>,
+< CLK_TOP_HADDS2PLL_98M>,
+< CLK_TOP_HADDS2PLL_294M>,
+< CLK_TOP_AUDPLL>,
+< CLK_TOP_AUDPLL_D4>,
+< CLK_TOP_AUDPLL_D8>,
+< CLK_TOP_AUDPLL_D16>,
+< CLK_TOP_AUDPLL_D24>,
+< CLK_TOP_AUDINTBUS_SEL>,
+<>,
+< CLK_TOP_SYSPLL1_D4>,
+< CLK_TOP_AUD_K1_SRC_SEL>,
+< CLK_TOP_AUD_K2_SRC_SEL>,
+< CLK_TOP_AUD_K3_SRC_SEL>,
+< CLK_TOP_AUD_K4_SRC_SEL>,
+< CLK_TOP_AUD_K5_SRC_SEL>,
+< CLK_TOP_AUD_K6_SRC_SEL>,
+< CLK_TOP_AUD_K1_SRC_DIV>,
+< CLK_TOP_AUD_K2_SRC_DIV>,
+< CLK_TOP_AUD_K3_SRC_DIV>,
+< CLK_TOP_AUD_K4_SRC_DIV>,
+< CLK_TOP_AUD_K5_SRC_DIV>,
+< CLK_TOP_AUD_K6_SRC_DIV>,
+< CLK_TOP_AUD_I2S1_MCLK>,
+< CLK_TOP_AUD_I2S2_MCLK>,
+< CLK_TOP_AUD_I2S3_MCLK>,
+< CLK_TOP_AUD_I2S4_MCLK>,
+< CLK_TOP_AUD_I2S5_MCLK>,
+< CLK_TOP_AUD_I2S6_MCLK>,
+< CLK_TOP_ASM_M_SEL>,
+< CLK_TOP_ASM_H_SEL>,
+< CLK_TOP_UNIVPLL2_D4>,
+< CLK_TOP_UNIVPLL2_D2>,
+< CLK_TOP_SYSPLL_D5>;
+
+   

[alsa-devel] [PATCH v2 0/9] ASoC: Mediatek: Add support for MT2701 SOC

2016-06-02 Thread Garlic Tseng
This patch adds basic support for Mediatek AFE for MT2701 SoC.
The patch is based on broonie tree "for-next" branch.

Change since v1:

implement common private structure, fe dai and platform driver.
let mt8173 and mt2701 use the common structure.

Garlic Tseng (9):
  ASoC: mediatek: Refine mt8173 driver and change config option
  ASoC: mediatek: implement mediatek common structure
  ASoC: mediatek: let mt8173 use mediatek common structure
  ASoC: mediatek: add documents for mt2701
  ASoC: mediatek: add structure define and clock control for 2701
  ASoC: mediatek: add mt2701 platform driver implementation.
  ASoC: bt-sco: extend rate and add a general compatible string
  ASoC: mediatek: add BT implementation
  ASoC: mediatek: Add mt2701-cs42448 driver and config option.

 Documentation/devicetree/bindings/sound/bt-sco.txt |2 +-
 .../devicetree/bindings/sound/mt2701-afe-pcm.txt   |  150 ++
 .../devicetree/bindings/sound/mt2701-cs42448.txt   |   43 +
 sound/soc/codecs/bt-sco.c  |5 +-
 sound/soc/mediatek/Kconfig |   44 +-
 sound/soc/mediatek/Makefile|   11 +-
 sound/soc/mediatek/common/Makefile |   17 +
 sound/soc/mediatek/common/mtk-afe-fe-dai.c |  387 +
 sound/soc/mediatek/common/mtk-afe-fe-dai.h |   47 +
 .../soc/mediatek/common/mtk-afe-platform-driver.c  |   90 ++
 .../soc/mediatek/common/mtk-afe-platform-driver.h  |   23 +
 sound/soc/mediatek/common/mtk-base-afe.h   |  103 ++
 sound/soc/mediatek/mt2701/Makefile |   19 +
 sound/soc/mediatek/mt2701/mt2701-afe-clock-ctrl.c  |  357 +
 sound/soc/mediatek/mt2701/mt2701-afe-clock-ctrl.h  |   33 +
 sound/soc/mediatek/mt2701/mt2701-afe-common.h  |  185 +++
 sound/soc/mediatek/mt2701/mt2701-afe-pcm.c | 1664 
 sound/soc/mediatek/mt2701/mt2701-cs42448.c |  422 +
 sound/soc/mediatek/mt2701/mt2701-reg.h |  186 +++
 sound/soc/mediatek/mt8173/Makefile |7 +
 sound/soc/mediatek/mt8173/mt8173-afe-common.h  |   73 +
 .../{mtk-afe-pcm.c => mt8173/mt8173-afe-pcm.c} |  923 +--
 sound/soc/mediatek/{ => mt8173}/mt8173-max98090.c  |2 +-
 .../mediatek/{ => mt8173}/mt8173-rt5650-rt5514.c   |2 +-
 .../mediatek/{ => mt8173}/mt8173-rt5650-rt5676.c   |4 +-
 sound/soc/mediatek/{ => mt8173}/mt8173-rt5650.c|2 +-
 sound/soc/mediatek/mtk-afe-common.h|  101 --
 27 files changed, 4267 insertions(+), 635 deletions(-)
 create mode 100644 Documentation/devicetree/bindings/sound/mt2701-afe-pcm.txt
 create mode 100644 Documentation/devicetree/bindings/sound/mt2701-cs42448.txt
 create mode 100644 sound/soc/mediatek/common/Makefile
 create mode 100644 sound/soc/mediatek/common/mtk-afe-fe-dai.c
 create mode 100644 sound/soc/mediatek/common/mtk-afe-fe-dai.h
 create mode 100644 sound/soc/mediatek/common/mtk-afe-platform-driver.c
 create mode 100644 sound/soc/mediatek/common/mtk-afe-platform-driver.h
 create mode 100644 sound/soc/mediatek/common/mtk-base-afe.h
 create mode 100644 sound/soc/mediatek/mt2701/Makefile
 create mode 100644 sound/soc/mediatek/mt2701/mt2701-afe-clock-ctrl.c
 create mode 100644 sound/soc/mediatek/mt2701/mt2701-afe-clock-ctrl.h
 create mode 100644 sound/soc/mediatek/mt2701/mt2701-afe-common.h
 create mode 100644 sound/soc/mediatek/mt2701/mt2701-afe-pcm.c
 create mode 100644 sound/soc/mediatek/mt2701/mt2701-cs42448.c
 create mode 100644 sound/soc/mediatek/mt2701/mt2701-reg.h
 create mode 100644 sound/soc/mediatek/mt8173/Makefile
 create mode 100644 sound/soc/mediatek/mt8173/mt8173-afe-common.h
 rename sound/soc/mediatek/{mtk-afe-pcm.c => mt8173/mt8173-afe-pcm.c} (51%)
 rename sound/soc/mediatek/{ => mt8173}/mt8173-max98090.c (99%)
 rename sound/soc/mediatek/{ => mt8173}/mt8173-rt5650-rt5514.c (99%)
 rename sound/soc/mediatek/{ => mt8173}/mt8173-rt5650-rt5676.c (99%)
 rename sound/soc/mediatek/{ => mt8173}/mt8173-rt5650.c (99%)
 delete mode 100644 sound/soc/mediatek/mtk-afe-common.h

-- 
1.9.1



[alsa-devel] [PATCH v2 3/9] ASoC: mediatek: let mt8173 use mediatek common structure

2016-06-02 Thread Garlic Tseng
Modify mt8173 driver implementation to use common structure.

Signed-off-by: Garlic Tseng 
---
 sound/soc/mediatek/Kconfig|  11 +
 sound/soc/mediatek/Makefile   |   3 +-
 sound/soc/mediatek/common/Makefile|  17 +
 sound/soc/mediatek/mt8173/mt8173-afe-common.h |  42 +-
 sound/soc/mediatek/mt8173/mt8173-afe-pcm.c| 681 +++---
 5 files changed, 328 insertions(+), 426 deletions(-)
 create mode 100644 sound/soc/mediatek/common/Makefile

diff --git a/sound/soc/mediatek/Kconfig b/sound/soc/mediatek/Kconfig
index ae9f664..ff1a419 100644
--- a/sound/soc/mediatek/Kconfig
+++ b/sound/soc/mediatek/Kconfig
@@ -1,6 +1,16 @@
+config SND_SOC_MEDIATEK
+   tristate "SND_SOC_MEDIATEK"
+   depends on ARCH_MEDIATEK
+   help
+ This adds ASoC driver for Mediatek boards
+ that can be used with other codecs.
+ Select Y if you have such device.
+ If unsure select "N".
+
 config SND_SOC_MT8173
tristate "ASoC support for Mediatek MT8173 chip"
depends on ARCH_MEDIATEK
+   select SND_SOC_MEDIATEK
help
  This adds ASoC platform driver support for Mediatek MT8173 chip
  that can be used with other codecs.
@@ -49,3 +59,4 @@ config SND_SOC_MT8173_RT5650_RT5676
  with the RT5650 and RT5676 codecs.
  Select Y if you have such device.
  If unsure select "N".
+
diff --git a/sound/soc/mediatek/Makefile b/sound/soc/mediatek/Makefile
index 240dfc70..3d893be 100644
--- a/sound/soc/mediatek/Makefile
+++ b/sound/soc/mediatek/Makefile
@@ -1,2 +1,3 @@
-# 8173 Machine support
+obj-$(CONFIG_SND_SOC_MEDIATEK) += common/
 obj-$(CONFIG_SND_SOC_MT8173) += mt8173/
+
diff --git a/sound/soc/mediatek/common/Makefile 
b/sound/soc/mediatek/common/Makefile
new file mode 100644
index 000..0fcd921
--- /dev/null
+++ b/sound/soc/mediatek/common/Makefile
@@ -0,0 +1,17 @@
+#
+# Copyright (C) 2015 MediaTek Inc.
+#
+# 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.
+#
+
+# platform driver
+snd-soc-mtk-common-objs := mtk-afe-platform-driver.o mtk-afe-fe-dai.o
+obj-$(CONFIG_SND_SOC_MEDIATEK) += snd-soc-mtk-common.o
+
diff --git a/sound/soc/mediatek/mt8173/mt8173-afe-common.h 
b/sound/soc/mediatek/mt8173/mt8173-afe-common.h
index 8f2936d..9a4837c 100644
--- a/sound/soc/mediatek/mt8173/mt8173-afe-common.h
+++ b/sound/soc/mediatek/mt8173/mt8173-afe-common.h
@@ -46,14 +46,13 @@ enum {
 };
 
 enum {
-   MT8173_AFE_IRQ_1,
-   MT8173_AFE_IRQ_2,
-   MT8173_AFE_IRQ_3,
-   MT8173_AFE_IRQ_4,
-   MT8173_AFE_IRQ_5,
-   MT8173_AFE_IRQ_6,
-   MT8173_AFE_IRQ_7,
-   MT8173_AFE_IRQ_8,
+   MT8173_AFE_IRQ_DL1,
+   MT8173_AFE_IRQ_DL2,
+   MT8173_AFE_IRQ_VUL,
+   MT8173_AFE_IRQ_DAI,
+   MT8173_AFE_IRQ_AWB,
+   MT8173_AFE_IRQ_MOD_DAI,
+   MT8173_AFE_IRQ_HDMI,
MT8173_AFE_IRQ_NUM,
 };
 
@@ -71,31 +70,4 @@ enum {
MT8173_CLK_NUM
 };
 
-struct mt8173_afe;
-struct snd_pcm_substream;
-
-struct mt8173_afe_memif_data {
-   int id;
-   const char *name;
-   int reg_ofs_base;
-   int reg_ofs_cur;
-   int fs_shift;
-   int mono_shift;
-   int enable_shift;
-   int irq_reg_cnt;
-   int irq_cnt_shift;
-   int irq_en_shift;
-   int irq_fs_shift;
-   int irq_clr_shift;
-   int msb_shift;
-};
-
-struct mt8173_afe_memif {
-   unsigned int phys_buf_addr;
-   int buffer_size;
-   struct snd_pcm_substream *substream;
-   const struct mt8173_afe_memif_data *data;
-   const struct mt8173_afe_irq_data *irqdata;
-};
-
 #endif
diff --git a/sound/soc/mediatek/mt8173/mt8173-afe-pcm.c 
b/sound/soc/mediatek/mt8173/mt8173-afe-pcm.c
index 4fc52bc..d58bac4b 100644
--- a/sound/soc/mediatek/mt8173/mt8173-afe-pcm.c
+++ b/sound/soc/mediatek/mt8173/mt8173-afe-pcm.c
@@ -25,6 +25,9 @@
 #include 
 #include 
 #include "mt8173-afe-common.h"
+#include "../common/mtk-base-afe.h"
+#include "../common/mtk-afe-platform-driver.h"
+#include "../common/mtk-afe-fe-dai.h"
 
 /*
  *  R E G I S T E R   D E F I N I T I O N
@@ -81,7 +84,6 @@
 #define AFE_TDM_CON1   0x0548
 #define AFE_TDM_CON2   0x054c
 
-#define AFE_BASE_END_OFFSET8
 #define AFE_IRQ_STATUS_BITS0xff
 
 /* AUDIO_TOP_CON0 (0x) */
@@ -152,15 +154,8 @@ static const unsigned int mt8173_afe_backup_list[] = {
AFE_DAC_CON0,
 };
 
-struct mt8173_afe {
-   /* address for ioremap audio hardware register */
-   void __iomem 

[alsa-devel] [PATCH v2 0/9] ASoC: Mediatek: Add support for MT2701 SOC

2016-06-02 Thread Garlic Tseng
This patch adds basic support for Mediatek AFE for MT2701 SoC.
The patch is based on broonie tree "for-next" branch.

Change since v1:

implement common private structure, fe dai and platform driver.
let mt8173 and mt2701 use the common structure.

Garlic Tseng (9):
  ASoC: mediatek: Refine mt8173 driver and change config option
  ASoC: mediatek: implement mediatek common structure
  ASoC: mediatek: let mt8173 use mediatek common structure
  ASoC: mediatek: add documents for mt2701
  ASoC: mediatek: add structure define and clock control for 2701
  ASoC: mediatek: add mt2701 platform driver implementation.
  ASoC: bt-sco: extend rate and add a general compatible string
  ASoC: mediatek: add BT implementation
  ASoC: mediatek: Add mt2701-cs42448 driver and config option.

 Documentation/devicetree/bindings/sound/bt-sco.txt |2 +-
 .../devicetree/bindings/sound/mt2701-afe-pcm.txt   |  150 ++
 .../devicetree/bindings/sound/mt2701-cs42448.txt   |   43 +
 sound/soc/codecs/bt-sco.c  |5 +-
 sound/soc/mediatek/Kconfig |   44 +-
 sound/soc/mediatek/Makefile|   11 +-
 sound/soc/mediatek/common/Makefile |   17 +
 sound/soc/mediatek/common/mtk-afe-fe-dai.c |  387 +
 sound/soc/mediatek/common/mtk-afe-fe-dai.h |   47 +
 .../soc/mediatek/common/mtk-afe-platform-driver.c  |   90 ++
 .../soc/mediatek/common/mtk-afe-platform-driver.h  |   23 +
 sound/soc/mediatek/common/mtk-base-afe.h   |  103 ++
 sound/soc/mediatek/mt2701/Makefile |   19 +
 sound/soc/mediatek/mt2701/mt2701-afe-clock-ctrl.c  |  357 +
 sound/soc/mediatek/mt2701/mt2701-afe-clock-ctrl.h  |   33 +
 sound/soc/mediatek/mt2701/mt2701-afe-common.h  |  185 +++
 sound/soc/mediatek/mt2701/mt2701-afe-pcm.c | 1664 
 sound/soc/mediatek/mt2701/mt2701-cs42448.c |  422 +
 sound/soc/mediatek/mt2701/mt2701-reg.h |  186 +++
 sound/soc/mediatek/mt8173/Makefile |7 +
 sound/soc/mediatek/mt8173/mt8173-afe-common.h  |   73 +
 .../{mtk-afe-pcm.c => mt8173/mt8173-afe-pcm.c} |  923 +--
 sound/soc/mediatek/{ => mt8173}/mt8173-max98090.c  |2 +-
 .../mediatek/{ => mt8173}/mt8173-rt5650-rt5514.c   |2 +-
 .../mediatek/{ => mt8173}/mt8173-rt5650-rt5676.c   |4 +-
 sound/soc/mediatek/{ => mt8173}/mt8173-rt5650.c|2 +-
 sound/soc/mediatek/mtk-afe-common.h|  101 --
 27 files changed, 4267 insertions(+), 635 deletions(-)
 create mode 100644 Documentation/devicetree/bindings/sound/mt2701-afe-pcm.txt
 create mode 100644 Documentation/devicetree/bindings/sound/mt2701-cs42448.txt
 create mode 100644 sound/soc/mediatek/common/Makefile
 create mode 100644 sound/soc/mediatek/common/mtk-afe-fe-dai.c
 create mode 100644 sound/soc/mediatek/common/mtk-afe-fe-dai.h
 create mode 100644 sound/soc/mediatek/common/mtk-afe-platform-driver.c
 create mode 100644 sound/soc/mediatek/common/mtk-afe-platform-driver.h
 create mode 100644 sound/soc/mediatek/common/mtk-base-afe.h
 create mode 100644 sound/soc/mediatek/mt2701/Makefile
 create mode 100644 sound/soc/mediatek/mt2701/mt2701-afe-clock-ctrl.c
 create mode 100644 sound/soc/mediatek/mt2701/mt2701-afe-clock-ctrl.h
 create mode 100644 sound/soc/mediatek/mt2701/mt2701-afe-common.h
 create mode 100644 sound/soc/mediatek/mt2701/mt2701-afe-pcm.c
 create mode 100644 sound/soc/mediatek/mt2701/mt2701-cs42448.c
 create mode 100644 sound/soc/mediatek/mt2701/mt2701-reg.h
 create mode 100644 sound/soc/mediatek/mt8173/Makefile
 create mode 100644 sound/soc/mediatek/mt8173/mt8173-afe-common.h
 rename sound/soc/mediatek/{mtk-afe-pcm.c => mt8173/mt8173-afe-pcm.c} (51%)
 rename sound/soc/mediatek/{ => mt8173}/mt8173-max98090.c (99%)
 rename sound/soc/mediatek/{ => mt8173}/mt8173-rt5650-rt5514.c (99%)
 rename sound/soc/mediatek/{ => mt8173}/mt8173-rt5650-rt5676.c (99%)
 rename sound/soc/mediatek/{ => mt8173}/mt8173-rt5650.c (99%)
 delete mode 100644 sound/soc/mediatek/mtk-afe-common.h

-- 
1.9.1



[alsa-devel] [PATCH v2 3/9] ASoC: mediatek: let mt8173 use mediatek common structure

2016-06-02 Thread Garlic Tseng
Modify mt8173 driver implementation to use common structure.

Signed-off-by: Garlic Tseng 
---
 sound/soc/mediatek/Kconfig|  11 +
 sound/soc/mediatek/Makefile   |   3 +-
 sound/soc/mediatek/common/Makefile|  17 +
 sound/soc/mediatek/mt8173/mt8173-afe-common.h |  42 +-
 sound/soc/mediatek/mt8173/mt8173-afe-pcm.c| 681 +++---
 5 files changed, 328 insertions(+), 426 deletions(-)
 create mode 100644 sound/soc/mediatek/common/Makefile

diff --git a/sound/soc/mediatek/Kconfig b/sound/soc/mediatek/Kconfig
index ae9f664..ff1a419 100644
--- a/sound/soc/mediatek/Kconfig
+++ b/sound/soc/mediatek/Kconfig
@@ -1,6 +1,16 @@
+config SND_SOC_MEDIATEK
+   tristate "SND_SOC_MEDIATEK"
+   depends on ARCH_MEDIATEK
+   help
+ This adds ASoC driver for Mediatek boards
+ that can be used with other codecs.
+ Select Y if you have such device.
+ If unsure select "N".
+
 config SND_SOC_MT8173
tristate "ASoC support for Mediatek MT8173 chip"
depends on ARCH_MEDIATEK
+   select SND_SOC_MEDIATEK
help
  This adds ASoC platform driver support for Mediatek MT8173 chip
  that can be used with other codecs.
@@ -49,3 +59,4 @@ config SND_SOC_MT8173_RT5650_RT5676
  with the RT5650 and RT5676 codecs.
  Select Y if you have such device.
  If unsure select "N".
+
diff --git a/sound/soc/mediatek/Makefile b/sound/soc/mediatek/Makefile
index 240dfc70..3d893be 100644
--- a/sound/soc/mediatek/Makefile
+++ b/sound/soc/mediatek/Makefile
@@ -1,2 +1,3 @@
-# 8173 Machine support
+obj-$(CONFIG_SND_SOC_MEDIATEK) += common/
 obj-$(CONFIG_SND_SOC_MT8173) += mt8173/
+
diff --git a/sound/soc/mediatek/common/Makefile 
b/sound/soc/mediatek/common/Makefile
new file mode 100644
index 000..0fcd921
--- /dev/null
+++ b/sound/soc/mediatek/common/Makefile
@@ -0,0 +1,17 @@
+#
+# Copyright (C) 2015 MediaTek Inc.
+#
+# 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.
+#
+
+# platform driver
+snd-soc-mtk-common-objs := mtk-afe-platform-driver.o mtk-afe-fe-dai.o
+obj-$(CONFIG_SND_SOC_MEDIATEK) += snd-soc-mtk-common.o
+
diff --git a/sound/soc/mediatek/mt8173/mt8173-afe-common.h 
b/sound/soc/mediatek/mt8173/mt8173-afe-common.h
index 8f2936d..9a4837c 100644
--- a/sound/soc/mediatek/mt8173/mt8173-afe-common.h
+++ b/sound/soc/mediatek/mt8173/mt8173-afe-common.h
@@ -46,14 +46,13 @@ enum {
 };
 
 enum {
-   MT8173_AFE_IRQ_1,
-   MT8173_AFE_IRQ_2,
-   MT8173_AFE_IRQ_3,
-   MT8173_AFE_IRQ_4,
-   MT8173_AFE_IRQ_5,
-   MT8173_AFE_IRQ_6,
-   MT8173_AFE_IRQ_7,
-   MT8173_AFE_IRQ_8,
+   MT8173_AFE_IRQ_DL1,
+   MT8173_AFE_IRQ_DL2,
+   MT8173_AFE_IRQ_VUL,
+   MT8173_AFE_IRQ_DAI,
+   MT8173_AFE_IRQ_AWB,
+   MT8173_AFE_IRQ_MOD_DAI,
+   MT8173_AFE_IRQ_HDMI,
MT8173_AFE_IRQ_NUM,
 };
 
@@ -71,31 +70,4 @@ enum {
MT8173_CLK_NUM
 };
 
-struct mt8173_afe;
-struct snd_pcm_substream;
-
-struct mt8173_afe_memif_data {
-   int id;
-   const char *name;
-   int reg_ofs_base;
-   int reg_ofs_cur;
-   int fs_shift;
-   int mono_shift;
-   int enable_shift;
-   int irq_reg_cnt;
-   int irq_cnt_shift;
-   int irq_en_shift;
-   int irq_fs_shift;
-   int irq_clr_shift;
-   int msb_shift;
-};
-
-struct mt8173_afe_memif {
-   unsigned int phys_buf_addr;
-   int buffer_size;
-   struct snd_pcm_substream *substream;
-   const struct mt8173_afe_memif_data *data;
-   const struct mt8173_afe_irq_data *irqdata;
-};
-
 #endif
diff --git a/sound/soc/mediatek/mt8173/mt8173-afe-pcm.c 
b/sound/soc/mediatek/mt8173/mt8173-afe-pcm.c
index 4fc52bc..d58bac4b 100644
--- a/sound/soc/mediatek/mt8173/mt8173-afe-pcm.c
+++ b/sound/soc/mediatek/mt8173/mt8173-afe-pcm.c
@@ -25,6 +25,9 @@
 #include 
 #include 
 #include "mt8173-afe-common.h"
+#include "../common/mtk-base-afe.h"
+#include "../common/mtk-afe-platform-driver.h"
+#include "../common/mtk-afe-fe-dai.h"
 
 /*
  *  R E G I S T E R   D E F I N I T I O N
@@ -81,7 +84,6 @@
 #define AFE_TDM_CON1   0x0548
 #define AFE_TDM_CON2   0x054c
 
-#define AFE_BASE_END_OFFSET8
 #define AFE_IRQ_STATUS_BITS0xff
 
 /* AUDIO_TOP_CON0 (0x) */
@@ -152,15 +154,8 @@ static const unsigned int mt8173_afe_backup_list[] = {
AFE_DAC_CON0,
 };
 
-struct mt8173_afe {
-   /* address for ioremap audio hardware register */
-   void __iomem *base_addr;
-   struct 

[alsa-devel] [PATCH v2 1/9] ASoC: mediatek: Refine mt8173 driver and change config option

2016-06-02 Thread Garlic Tseng
move mt8173 driver to another folder and add prefix.
add config option SND_SOC_MT8173

Signed-off-by: Garlic Tseng 
---
 sound/soc/mediatek/Kconfig |  14 +-
 sound/soc/mediatek/Makefile|   9 +-
 sound/soc/mediatek/mt8173/Makefile |   7 +
 sound/soc/mediatek/mt8173/mt8173-afe-common.h  | 101 +
 .../{mtk-afe-pcm.c => mt8173/mt8173-afe-pcm.c} | 494 ++---
 sound/soc/mediatek/{ => mt8173}/mt8173-max98090.c  |   2 +-
 .../mediatek/{ => mt8173}/mt8173-rt5650-rt5514.c   |   2 +-
 .../mediatek/{ => mt8173}/mt8173-rt5650-rt5676.c   |   4 +-
 sound/soc/mediatek/{ => mt8173}/mt8173-rt5650.c|   2 +-
 sound/soc/mediatek/mtk-afe-common.h| 101 -
 10 files changed, 367 insertions(+), 369 deletions(-)
 create mode 100644 sound/soc/mediatek/mt8173/Makefile
 create mode 100644 sound/soc/mediatek/mt8173/mt8173-afe-common.h
 rename sound/soc/mediatek/{mtk-afe-pcm.c => mt8173/mt8173-afe-pcm.c} (66%)
 rename sound/soc/mediatek/{ => mt8173}/mt8173-max98090.c (99%)
 rename sound/soc/mediatek/{ => mt8173}/mt8173-rt5650-rt5514.c (99%)
 rename sound/soc/mediatek/{ => mt8173}/mt8173-rt5650-rt5676.c (99%)
 rename sound/soc/mediatek/{ => mt8173}/mt8173-rt5650.c (99%)
 delete mode 100644 sound/soc/mediatek/mtk-afe-common.h

diff --git a/sound/soc/mediatek/Kconfig b/sound/soc/mediatek/Kconfig
index 3abf51c..ae9f664 100644
--- a/sound/soc/mediatek/Kconfig
+++ b/sound/soc/mediatek/Kconfig
@@ -1,15 +1,15 @@
-config SND_SOC_MEDIATEK
-   tristate "ASoC support for Mediatek chip"
+config SND_SOC_MT8173
+   tristate "ASoC support for Mediatek MT8173 chip"
depends on ARCH_MEDIATEK
help
- This adds ASoC platform driver support for Mediatek chip
+ This adds ASoC platform driver support for Mediatek MT8173 chip
  that can be used with other codecs.
  Select Y if you have such device.
  Ex: MT8173
 
 config SND_SOC_MT8173_MAX98090
tristate "ASoC Audio driver for MT8173 with MAX98090 codec"
-   depends on SND_SOC_MEDIATEK && I2C
+   depends on SND_SOC_MT8173 && I2C
select SND_SOC_MAX98090
help
  This adds ASoC driver for Mediatek MT8173 boards
@@ -19,7 +19,7 @@ config SND_SOC_MT8173_MAX98090
 
 config SND_SOC_MT8173_RT5650
tristate "ASoC Audio driver for MT8173 with RT5650 codec"
-   depends on SND_SOC_MEDIATEK && I2C
+   depends on SND_SOC_MT8173 && I2C
select SND_SOC_RT5645
help
  This adds ASoC driver for Mediatek MT8173 boards
@@ -29,7 +29,7 @@ config SND_SOC_MT8173_RT5650
 
 config SND_SOC_MT8173_RT5650_RT5514
tristate "ASoC Audio driver for MT8173 with RT5650 RT5514 codecs"
-   depends on SND_SOC_MEDIATEK && I2C
+   depends on SND_SOC_MT8173 && I2C
select SND_SOC_RT5645
select SND_SOC_RT5514
help
@@ -40,7 +40,7 @@ config SND_SOC_MT8173_RT5650_RT5514
 
 config SND_SOC_MT8173_RT5650_RT5676
tristate "ASoC Audio driver for MT8173 with RT5650 RT5676 codecs"
-   depends on SND_SOC_MEDIATEK && I2C
+   depends on SND_SOC_MT8173 && I2C
select SND_SOC_RT5645
select SND_SOC_RT5677
select SND_SOC_HDMI_CODEC
diff --git a/sound/soc/mediatek/Makefile b/sound/soc/mediatek/Makefile
index d486860..240dfc70 100644
--- a/sound/soc/mediatek/Makefile
+++ b/sound/soc/mediatek/Makefile
@@ -1,7 +1,2 @@
-# MTK Platform Support
-obj-$(CONFIG_SND_SOC_MEDIATEK) += mtk-afe-pcm.o
-# Machine support
-obj-$(CONFIG_SND_SOC_MT8173_MAX98090) += mt8173-max98090.o
-obj-$(CONFIG_SND_SOC_MT8173_RT5650) += mt8173-rt5650.o
-obj-$(CONFIG_SND_SOC_MT8173_RT5650_RT5514) += mt8173-rt5650-rt5514.o
-obj-$(CONFIG_SND_SOC_MT8173_RT5650_RT5676) += mt8173-rt5650-rt5676.o
+# 8173 Machine support
+obj-$(CONFIG_SND_SOC_MT8173) += mt8173/
diff --git a/sound/soc/mediatek/mt8173/Makefile 
b/sound/soc/mediatek/mt8173/Makefile
new file mode 100644
index 000..0357b27
--- /dev/null
+++ b/sound/soc/mediatek/mt8173/Makefile
@@ -0,0 +1,7 @@
+# MTK Platform Support
+obj-$(CONFIG_SND_SOC_MT8173) += mt8173-afe-pcm.o
+# Machine support
+obj-$(CONFIG_SND_SOC_MT8173_MAX98090) += mt8173-max98090.o
+obj-$(CONFIG_SND_SOC_MT8173_RT5650) += mt8173-rt5650.o
+obj-$(CONFIG_SND_SOC_MT8173_RT5650_RT5514) += mt8173-rt5650-rt5514.o
+obj-$(CONFIG_SND_SOC_MT8173_RT5650_RT5676) += mt8173-rt5650-rt5676.o
diff --git a/sound/soc/mediatek/mt8173/mt8173-afe-common.h 
b/sound/soc/mediatek/mt8173/mt8173-afe-common.h
new file mode 100644
index 000..8f2936d
--- /dev/null
+++ b/sound/soc/mediatek/mt8173/mt8173-afe-common.h
@@ -0,0 +1,101 @@
+/*
+ * mt8173_afe_common.h  --  Mediatek 8173 audio driver common definitions
+ *
+ * Copyright (c) 2015 MediaTek Inc.
+ * Author: Koro Chen 
+ * Sascha Hauer 
+ * Hidalgo Huang 
+ * Ir Lian 
+ *
+ * 

[alsa-devel] [PATCH v2 6/9] ASoC: mediatek: add mt2701 platform driver implementation.

2016-06-02 Thread Garlic Tseng
Add mt2701 platform driver implementation for playback and capture.
The implement follow DAPM structure (memory interface as FE and I2S
as BE).
Because of the hardware design, i2s out required to be enabled when
we need to enable i2s in. This patch includes the implementation.

Signed-off-by: Garlic Tseng 
---
 sound/soc/mediatek/mt2701/mt2701-afe-pcm.c | 1523 
 1 file changed, 1523 insertions(+)
 create mode 100644 sound/soc/mediatek/mt2701/mt2701-afe-pcm.c

diff --git a/sound/soc/mediatek/mt2701/mt2701-afe-pcm.c 
b/sound/soc/mediatek/mt2701/mt2701-afe-pcm.c
new file mode 100644
index 000..4c22ca0
--- /dev/null
+++ b/sound/soc/mediatek/mt2701/mt2701-afe-pcm.c
@@ -0,0 +1,1523 @@
+/*
+ * Mediatek ALSA SoC AFE platform driver for 2701
+ *
+ * Copyright (c) 2016 MediaTek Inc.
+ * Author: Garlic Tseng 
+ * Koro Chen 
+ * Hidalgo Huang 
+ * Ir Lian 
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only 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 "mt2701-afe-common.h"
+
+#include "mt2701-afe-clock-ctrl.h"
+#include "../common/mtk-afe-platform-driver.h"
+#include "../common/mtk-afe-fe-dai.h"
+
+#define AFE_IRQ_STATUS_BITS0xff
+
+static const struct snd_pcm_hardware mt2701_afe_hardware = {
+   .info = SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED
+   | SNDRV_PCM_INFO_RESUME | SNDRV_PCM_INFO_MMAP_VALID,
+   .formats = SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S24_LE
+  | SNDRV_PCM_FMTBIT_S32_LE,
+   .period_bytes_min = 1024,
+   .period_bytes_max = 1024 * 256,
+   .periods_min = 4,
+   .periods_max = 1024,
+   .buffer_bytes_max = 1024 * 1024 * 16,
+   .fifo_size = 0,
+};
+
+struct mt2701_afe_rate {
+   unsigned int rate;
+   unsigned int regvalue;
+};
+
+static const struct mt2701_afe_rate mt2701_afe_i2s_rates[] = {
+   { .rate = 8000, .regvalue = 0 },
+   { .rate = 12000, .regvalue = 1 },
+   { .rate = 16000, .regvalue = 2 },
+   { .rate = 24000, .regvalue = 3 },
+   { .rate = 32000, .regvalue = 4 },
+   { .rate = 48000, .regvalue = 5 },
+   { .rate = 96000, .regvalue = 6 },
+   { .rate = 192000, .regvalue = 7 },
+   { .rate = 384000, .regvalue = 8 },
+   { .rate = 7350, .regvalue = 16 },
+   { .rate = 11025, .regvalue = 17 },
+   { .rate = 14700, .regvalue = 18 },
+   { .rate = 22050, .regvalue = 19 },
+   { .rate = 29400, .regvalue = 20 },
+   { .rate = 44100, .regvalue = 21 },
+   { .rate = 88200, .regvalue = 22 },
+   { .rate = 176400, .regvalue = 23 },
+   { .rate = 352800, .regvalue = 24 },
+};
+
+int mt2701_dai_num_to_i2s(struct mtk_base_afe *afe, int num)
+{
+   int val = num - MT2701_IO_I2S;
+
+   if (val < 0 || val > MT2701_I2S_NUM) {
+   dev_err(afe->dev, "%s, num not available, num %d, val %d\n",
+   __func__, num, val);
+   return -1;
+   }
+   return val;
+}
+
+static int mt2701_afe_i2s_fs(unsigned int sample_rate)
+{
+   int i;
+
+   for (i = 0; i < ARRAY_SIZE(mt2701_afe_i2s_rates); i++)
+   if (mt2701_afe_i2s_rates[i].rate == sample_rate)
+   return mt2701_afe_i2s_rates[i].regvalue;
+
+   return -EINVAL;
+}
+
+static int mt2701_afe_i2s_startup(struct snd_pcm_substream *substream,
+ struct snd_soc_dai *dai)
+{
+   struct snd_soc_pcm_runtime *rtd = substream->private_data;
+   struct mtk_base_afe *afe = snd_soc_platform_get_drvdata(rtd->platform);
+   struct mt2701_afe_private *afe_priv = afe->platform_priv;
+   int i2s_num = mt2701_dai_num_to_i2s(afe, dai->id);
+   int clk_num = MT2701_AUD_AUD_I2S1_MCLK + i2s_num;
+   int ret = 0;
+
+   /*enable mclk*/
+   ret = clk_prepare_enable(afe_priv->clocks[clk_num]);
+   if (ret)
+   dev_err(afe->dev, "Failed to enable mclk for I2S: %d\n",
+   i2s_num);
+
+   return ret;
+}
+
+static int mt2701_afe_i2s_path_shutdown(struct snd_pcm_substream *substream,
+   struct snd_soc_dai *dai,
+   int dir_invert)
+{
+   struct snd_soc_pcm_runtime *rtd = substream->private_data;
+   struct mtk_base_afe *afe = snd_soc_platform_get_drvdata(rtd->platform);
+   struct mt2701_afe_private *afe_priv = 

[alsa-devel] [PATCH v2 6/9] ASoC: mediatek: add mt2701 platform driver implementation.

2016-06-02 Thread Garlic Tseng
Add mt2701 platform driver implementation for playback and capture.
The implement follow DAPM structure (memory interface as FE and I2S
as BE).
Because of the hardware design, i2s out required to be enabled when
we need to enable i2s in. This patch includes the implementation.

Signed-off-by: Garlic Tseng 
---
 sound/soc/mediatek/mt2701/mt2701-afe-pcm.c | 1523 
 1 file changed, 1523 insertions(+)
 create mode 100644 sound/soc/mediatek/mt2701/mt2701-afe-pcm.c

diff --git a/sound/soc/mediatek/mt2701/mt2701-afe-pcm.c 
b/sound/soc/mediatek/mt2701/mt2701-afe-pcm.c
new file mode 100644
index 000..4c22ca0
--- /dev/null
+++ b/sound/soc/mediatek/mt2701/mt2701-afe-pcm.c
@@ -0,0 +1,1523 @@
+/*
+ * Mediatek ALSA SoC AFE platform driver for 2701
+ *
+ * Copyright (c) 2016 MediaTek Inc.
+ * Author: Garlic Tseng 
+ * Koro Chen 
+ * Hidalgo Huang 
+ * Ir Lian 
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only 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 "mt2701-afe-common.h"
+
+#include "mt2701-afe-clock-ctrl.h"
+#include "../common/mtk-afe-platform-driver.h"
+#include "../common/mtk-afe-fe-dai.h"
+
+#define AFE_IRQ_STATUS_BITS0xff
+
+static const struct snd_pcm_hardware mt2701_afe_hardware = {
+   .info = SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED
+   | SNDRV_PCM_INFO_RESUME | SNDRV_PCM_INFO_MMAP_VALID,
+   .formats = SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S24_LE
+  | SNDRV_PCM_FMTBIT_S32_LE,
+   .period_bytes_min = 1024,
+   .period_bytes_max = 1024 * 256,
+   .periods_min = 4,
+   .periods_max = 1024,
+   .buffer_bytes_max = 1024 * 1024 * 16,
+   .fifo_size = 0,
+};
+
+struct mt2701_afe_rate {
+   unsigned int rate;
+   unsigned int regvalue;
+};
+
+static const struct mt2701_afe_rate mt2701_afe_i2s_rates[] = {
+   { .rate = 8000, .regvalue = 0 },
+   { .rate = 12000, .regvalue = 1 },
+   { .rate = 16000, .regvalue = 2 },
+   { .rate = 24000, .regvalue = 3 },
+   { .rate = 32000, .regvalue = 4 },
+   { .rate = 48000, .regvalue = 5 },
+   { .rate = 96000, .regvalue = 6 },
+   { .rate = 192000, .regvalue = 7 },
+   { .rate = 384000, .regvalue = 8 },
+   { .rate = 7350, .regvalue = 16 },
+   { .rate = 11025, .regvalue = 17 },
+   { .rate = 14700, .regvalue = 18 },
+   { .rate = 22050, .regvalue = 19 },
+   { .rate = 29400, .regvalue = 20 },
+   { .rate = 44100, .regvalue = 21 },
+   { .rate = 88200, .regvalue = 22 },
+   { .rate = 176400, .regvalue = 23 },
+   { .rate = 352800, .regvalue = 24 },
+};
+
+int mt2701_dai_num_to_i2s(struct mtk_base_afe *afe, int num)
+{
+   int val = num - MT2701_IO_I2S;
+
+   if (val < 0 || val > MT2701_I2S_NUM) {
+   dev_err(afe->dev, "%s, num not available, num %d, val %d\n",
+   __func__, num, val);
+   return -1;
+   }
+   return val;
+}
+
+static int mt2701_afe_i2s_fs(unsigned int sample_rate)
+{
+   int i;
+
+   for (i = 0; i < ARRAY_SIZE(mt2701_afe_i2s_rates); i++)
+   if (mt2701_afe_i2s_rates[i].rate == sample_rate)
+   return mt2701_afe_i2s_rates[i].regvalue;
+
+   return -EINVAL;
+}
+
+static int mt2701_afe_i2s_startup(struct snd_pcm_substream *substream,
+ struct snd_soc_dai *dai)
+{
+   struct snd_soc_pcm_runtime *rtd = substream->private_data;
+   struct mtk_base_afe *afe = snd_soc_platform_get_drvdata(rtd->platform);
+   struct mt2701_afe_private *afe_priv = afe->platform_priv;
+   int i2s_num = mt2701_dai_num_to_i2s(afe, dai->id);
+   int clk_num = MT2701_AUD_AUD_I2S1_MCLK + i2s_num;
+   int ret = 0;
+
+   /*enable mclk*/
+   ret = clk_prepare_enable(afe_priv->clocks[clk_num]);
+   if (ret)
+   dev_err(afe->dev, "Failed to enable mclk for I2S: %d\n",
+   i2s_num);
+
+   return ret;
+}
+
+static int mt2701_afe_i2s_path_shutdown(struct snd_pcm_substream *substream,
+   struct snd_soc_dai *dai,
+   int dir_invert)
+{
+   struct snd_soc_pcm_runtime *rtd = substream->private_data;
+   struct mtk_base_afe *afe = snd_soc_platform_get_drvdata(rtd->platform);
+   struct mt2701_afe_private *afe_priv = afe->platform_priv;
+   int i2s_num = mt2701_dai_num_to_i2s(afe, dai->id);
+   struct mt2701_i2s_path *i2s_path = 

[alsa-devel] [PATCH v2 1/9] ASoC: mediatek: Refine mt8173 driver and change config option

2016-06-02 Thread Garlic Tseng
move mt8173 driver to another folder and add prefix.
add config option SND_SOC_MT8173

Signed-off-by: Garlic Tseng 
---
 sound/soc/mediatek/Kconfig |  14 +-
 sound/soc/mediatek/Makefile|   9 +-
 sound/soc/mediatek/mt8173/Makefile |   7 +
 sound/soc/mediatek/mt8173/mt8173-afe-common.h  | 101 +
 .../{mtk-afe-pcm.c => mt8173/mt8173-afe-pcm.c} | 494 ++---
 sound/soc/mediatek/{ => mt8173}/mt8173-max98090.c  |   2 +-
 .../mediatek/{ => mt8173}/mt8173-rt5650-rt5514.c   |   2 +-
 .../mediatek/{ => mt8173}/mt8173-rt5650-rt5676.c   |   4 +-
 sound/soc/mediatek/{ => mt8173}/mt8173-rt5650.c|   2 +-
 sound/soc/mediatek/mtk-afe-common.h| 101 -
 10 files changed, 367 insertions(+), 369 deletions(-)
 create mode 100644 sound/soc/mediatek/mt8173/Makefile
 create mode 100644 sound/soc/mediatek/mt8173/mt8173-afe-common.h
 rename sound/soc/mediatek/{mtk-afe-pcm.c => mt8173/mt8173-afe-pcm.c} (66%)
 rename sound/soc/mediatek/{ => mt8173}/mt8173-max98090.c (99%)
 rename sound/soc/mediatek/{ => mt8173}/mt8173-rt5650-rt5514.c (99%)
 rename sound/soc/mediatek/{ => mt8173}/mt8173-rt5650-rt5676.c (99%)
 rename sound/soc/mediatek/{ => mt8173}/mt8173-rt5650.c (99%)
 delete mode 100644 sound/soc/mediatek/mtk-afe-common.h

diff --git a/sound/soc/mediatek/Kconfig b/sound/soc/mediatek/Kconfig
index 3abf51c..ae9f664 100644
--- a/sound/soc/mediatek/Kconfig
+++ b/sound/soc/mediatek/Kconfig
@@ -1,15 +1,15 @@
-config SND_SOC_MEDIATEK
-   tristate "ASoC support for Mediatek chip"
+config SND_SOC_MT8173
+   tristate "ASoC support for Mediatek MT8173 chip"
depends on ARCH_MEDIATEK
help
- This adds ASoC platform driver support for Mediatek chip
+ This adds ASoC platform driver support for Mediatek MT8173 chip
  that can be used with other codecs.
  Select Y if you have such device.
  Ex: MT8173
 
 config SND_SOC_MT8173_MAX98090
tristate "ASoC Audio driver for MT8173 with MAX98090 codec"
-   depends on SND_SOC_MEDIATEK && I2C
+   depends on SND_SOC_MT8173 && I2C
select SND_SOC_MAX98090
help
  This adds ASoC driver for Mediatek MT8173 boards
@@ -19,7 +19,7 @@ config SND_SOC_MT8173_MAX98090
 
 config SND_SOC_MT8173_RT5650
tristate "ASoC Audio driver for MT8173 with RT5650 codec"
-   depends on SND_SOC_MEDIATEK && I2C
+   depends on SND_SOC_MT8173 && I2C
select SND_SOC_RT5645
help
  This adds ASoC driver for Mediatek MT8173 boards
@@ -29,7 +29,7 @@ config SND_SOC_MT8173_RT5650
 
 config SND_SOC_MT8173_RT5650_RT5514
tristate "ASoC Audio driver for MT8173 with RT5650 RT5514 codecs"
-   depends on SND_SOC_MEDIATEK && I2C
+   depends on SND_SOC_MT8173 && I2C
select SND_SOC_RT5645
select SND_SOC_RT5514
help
@@ -40,7 +40,7 @@ config SND_SOC_MT8173_RT5650_RT5514
 
 config SND_SOC_MT8173_RT5650_RT5676
tristate "ASoC Audio driver for MT8173 with RT5650 RT5676 codecs"
-   depends on SND_SOC_MEDIATEK && I2C
+   depends on SND_SOC_MT8173 && I2C
select SND_SOC_RT5645
select SND_SOC_RT5677
select SND_SOC_HDMI_CODEC
diff --git a/sound/soc/mediatek/Makefile b/sound/soc/mediatek/Makefile
index d486860..240dfc70 100644
--- a/sound/soc/mediatek/Makefile
+++ b/sound/soc/mediatek/Makefile
@@ -1,7 +1,2 @@
-# MTK Platform Support
-obj-$(CONFIG_SND_SOC_MEDIATEK) += mtk-afe-pcm.o
-# Machine support
-obj-$(CONFIG_SND_SOC_MT8173_MAX98090) += mt8173-max98090.o
-obj-$(CONFIG_SND_SOC_MT8173_RT5650) += mt8173-rt5650.o
-obj-$(CONFIG_SND_SOC_MT8173_RT5650_RT5514) += mt8173-rt5650-rt5514.o
-obj-$(CONFIG_SND_SOC_MT8173_RT5650_RT5676) += mt8173-rt5650-rt5676.o
+# 8173 Machine support
+obj-$(CONFIG_SND_SOC_MT8173) += mt8173/
diff --git a/sound/soc/mediatek/mt8173/Makefile 
b/sound/soc/mediatek/mt8173/Makefile
new file mode 100644
index 000..0357b27
--- /dev/null
+++ b/sound/soc/mediatek/mt8173/Makefile
@@ -0,0 +1,7 @@
+# MTK Platform Support
+obj-$(CONFIG_SND_SOC_MT8173) += mt8173-afe-pcm.o
+# Machine support
+obj-$(CONFIG_SND_SOC_MT8173_MAX98090) += mt8173-max98090.o
+obj-$(CONFIG_SND_SOC_MT8173_RT5650) += mt8173-rt5650.o
+obj-$(CONFIG_SND_SOC_MT8173_RT5650_RT5514) += mt8173-rt5650-rt5514.o
+obj-$(CONFIG_SND_SOC_MT8173_RT5650_RT5676) += mt8173-rt5650-rt5676.o
diff --git a/sound/soc/mediatek/mt8173/mt8173-afe-common.h 
b/sound/soc/mediatek/mt8173/mt8173-afe-common.h
new file mode 100644
index 000..8f2936d
--- /dev/null
+++ b/sound/soc/mediatek/mt8173/mt8173-afe-common.h
@@ -0,0 +1,101 @@
+/*
+ * mt8173_afe_common.h  --  Mediatek 8173 audio driver common definitions
+ *
+ * Copyright (c) 2015 MediaTek Inc.
+ * Author: Koro Chen 
+ * Sascha Hauer 
+ * Hidalgo Huang 
+ * Ir Lian 
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License 

[alsa-devel] [PATCH v2 2/9] ASoC: mediatek: implement mediatek common structure

2016-06-02 Thread Garlic Tseng
implement mediatek basic structure, include common private data,
afe fe dai operator and afe platform driver.

Signed-off-by: Garlic Tseng 
---
 sound/soc/mediatek/common/mtk-afe-fe-dai.c | 387 +
 sound/soc/mediatek/common/mtk-afe-fe-dai.h |  47 +++
 .../soc/mediatek/common/mtk-afe-platform-driver.c  |  90 +
 .../soc/mediatek/common/mtk-afe-platform-driver.h  |  23 ++
 sound/soc/mediatek/common/mtk-base-afe.h   | 103 ++
 5 files changed, 650 insertions(+)
 create mode 100644 sound/soc/mediatek/common/mtk-afe-fe-dai.c
 create mode 100644 sound/soc/mediatek/common/mtk-afe-fe-dai.h
 create mode 100644 sound/soc/mediatek/common/mtk-afe-platform-driver.c
 create mode 100644 sound/soc/mediatek/common/mtk-afe-platform-driver.h
 create mode 100644 sound/soc/mediatek/common/mtk-base-afe.h

diff --git a/sound/soc/mediatek/common/mtk-afe-fe-dai.c 
b/sound/soc/mediatek/common/mtk-afe-fe-dai.c
new file mode 100644
index 000..02d454d
--- /dev/null
+++ b/sound/soc/mediatek/common/mtk-afe-fe-dai.c
@@ -0,0 +1,387 @@
+/*
+ * mtk-afe-fe-dais.c  --  Mediatek afe fe dai operator
+ *
+ * Copyright (c) 2016 MediaTek Inc.
+ * Author: Garlic Tseng 
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only 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 "mtk-afe-fe-dai.h"
+#include "mtk-base-afe.h"
+
+#define AFE_BASE_END_OFFSET 8
+
+int mtk_regmap_update_bits(struct regmap *map, int reg, unsigned int mask,
+  unsigned int val)
+{
+   if (reg < 0)
+   return 0;
+   return regmap_update_bits(map, reg, mask, val);
+}
+
+int mtk_regmap_write(struct regmap *map, int reg, unsigned int val)
+{
+   if (reg < 0)
+   return 0;
+   return regmap_write(map, reg, val);
+}
+
+int mtk_afe_fe_startup(struct snd_pcm_substream *substream,
+  struct snd_soc_dai *dai)
+{
+   struct snd_soc_pcm_runtime *rtd = substream->private_data;
+   struct mtk_base_afe *afe = snd_soc_platform_get_drvdata(rtd->platform);
+   struct snd_pcm_runtime *runtime = substream->runtime;
+   int memif_num = rtd->cpu_dai->id;
+   struct mtk_base_afe_memif *memif = >memif[memif_num];
+   const struct snd_pcm_hardware *mtk_afe_hardware = afe->mtk_afe_hardware;
+   int ret;
+
+   memif->substream = substream;
+
+   snd_pcm_hw_constraint_step(substream->runtime, 0,
+  SNDRV_PCM_HW_PARAM_BUFFER_BYTES, 16);
+   /*enable agent*/
+   mtk_regmap_update_bits(afe->regmap, memif->data->agent_disable_reg,
+  1 << memif->data->agent_disable_shift,
+  0 << memif->data->agent_disable_shift);
+
+   snd_soc_set_runtime_hwparams(substream, mtk_afe_hardware);
+
+   /*
+* Capture cannot use ping-pong buffer since hw_ptr at IRQ may be
+* smaller than period_size due to AFE's internal buffer.
+* This easily leads to overrun when avail_min is period_size.
+* One more period can hold the possible unread buffer.
+*/
+   if (substream->stream == SNDRV_PCM_STREAM_CAPTURE) {
+   int periods_max = mtk_afe_hardware->periods_max;
+
+   ret = snd_pcm_hw_constraint_minmax(runtime,
+  SNDRV_PCM_HW_PARAM_PERIODS,
+  3, periods_max);
+   if (ret < 0) {
+   dev_err(afe->dev, "hw_constraint_minmax failed\n");
+   return ret;
+   }
+   }
+
+   ret = snd_pcm_hw_constraint_integer(runtime,
+   SNDRV_PCM_HW_PARAM_PERIODS);
+   if (ret < 0)
+   dev_err(afe->dev, "snd_pcm_hw_constraint_integer failed\n");
+
+   /*dynamic allocate irq to memif */
+   if (memif->irq_usage < 0) {
+   int irq_id = mtk_dynamic_irq_acquire(afe);
+
+   if (irq_id != afe->irqs_size) {
+   /* link */
+   memif->irq_usage = irq_id;
+   } else {
+   dev_err(afe->dev, "%s() error: no more asys irq\n",
+   __func__);
+   ret = -EBUSY;
+   }
+   }
+   return ret;
+}
+EXPORT_SYMBOL(mtk_afe_fe_startup);
+
+void mtk_afe_fe_shutdown(struct snd_pcm_substream *substream,
+struct snd_soc_dai *dai)
+{
+   struct snd_soc_pcm_runtime 

[alsa-devel] [PATCH v2 9/9] ASoC: mediatek: Add mt2701-cs42448 driver and config option.

2016-06-02 Thread Garlic Tseng
Add machine driver and config option for MT2701.

Signed-off-by: Garlic Tseng 
---
 sound/soc/mediatek/Kconfig |  21 ++
 sound/soc/mediatek/Makefile|   1 +
 sound/soc/mediatek/mt2701/Makefile |  19 ++
 sound/soc/mediatek/mt2701/mt2701-cs42448.c | 422 +
 4 files changed, 463 insertions(+)
 create mode 100644 sound/soc/mediatek/mt2701/Makefile
 create mode 100644 sound/soc/mediatek/mt2701/mt2701-cs42448.c

diff --git a/sound/soc/mediatek/Kconfig b/sound/soc/mediatek/Kconfig
index ff1a419..0ecb785 100644
--- a/sound/soc/mediatek/Kconfig
+++ b/sound/soc/mediatek/Kconfig
@@ -7,6 +7,27 @@ config SND_SOC_MEDIATEK
  Select Y if you have such device.
  If unsure select "N".
 
+config SND_SOC_MT2701
+   tristate "ASoC support for Mediatek MT2701 chip"
+   depends on ARCH_MEDIATEK
+   select SND_SOC_MEDIATEK
+   help
+ This adds ASoC driver for Mediatek MT2701 boards
+ that can be used with other codecs.
+ Select Y if you have such device.
+ If unsure select "N".
+
+config SND_SOC_MT2701_CS42448
+   tristate "SND_SOC_MT2701_CS42448"
+   depends on SND_SOC_MT2701
+   select SND_SOC_CS42XX8_I2C
+   select SND_SOC_BT_SCO
+   help
+ This adds ASoC driver for Mediatek MT2701 boards
+ with the CS42448 codecs.
+ Select Y if you have such device.
+ If unsure select "N".
+
 config SND_SOC_MT8173
tristate "ASoC support for Mediatek MT8173 chip"
depends on ARCH_MEDIATEK
diff --git a/sound/soc/mediatek/Makefile b/sound/soc/mediatek/Makefile
index 3d893be..5133215 100644
--- a/sound/soc/mediatek/Makefile
+++ b/sound/soc/mediatek/Makefile
@@ -1,3 +1,4 @@
 obj-$(CONFIG_SND_SOC_MEDIATEK) += common/
+obj-$(CONFIG_SND_SOC_MT2701) += mt2701/
 obj-$(CONFIG_SND_SOC_MT8173) += mt8173/
 
diff --git a/sound/soc/mediatek/mt2701/Makefile 
b/sound/soc/mediatek/mt2701/Makefile
new file mode 100644
index 000..31c3d04
--- /dev/null
+++ b/sound/soc/mediatek/mt2701/Makefile
@@ -0,0 +1,19 @@
+#
+# Copyright (C) 2015 MediaTek Inc.
+#
+# 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.
+#
+
+# platform driver
+snd-soc-mt2701-afe-objs := mt2701-afe-pcm.o mt2701-afe-clock-ctrl.o
+obj-$(CONFIG_SND_SOC_MT2701) += snd-soc-mt2701-afe.o
+
+# machine driver
+obj-$(CONFIG_SND_SOC_MT2701_CS42448) += mt2701-cs42448.o
diff --git a/sound/soc/mediatek/mt2701/mt2701-cs42448.c 
b/sound/soc/mediatek/mt2701/mt2701-cs42448.c
new file mode 100644
index 000..fce159f
--- /dev/null
+++ b/sound/soc/mediatek/mt2701/mt2701-cs42448.c
@@ -0,0 +1,422 @@
+/*
+ * mt2701-cs42448.c  --  MT2701 CS42448 ALSA SoC machine driver
+ *
+ * Copyright (c) 2016 MediaTek Inc.
+ * Author: Ir Lian 
+ *  Garlic Tseng 
+ *
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only 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 "mt2701-afe-common.h"
+
+struct mt2701_cs42448_private {
+   int i2s1_in_mux;
+   int i2s1_in_mux_gpio_sel_1;
+   int i2s1_in_mux_gpio_sel_2;
+};
+
+static const char * const i2sin_mux_switch_text[] = {
+   "ADC_SDOUT2",
+   "ADC_SDOUT3",
+   "I2S_IN_1",
+   "I2S_IN_2",
+};
+
+static const struct soc_enum i2sin_mux_enum =
+   SOC_ENUM_SINGLE_EXT(4, i2sin_mux_switch_text);
+
+static int mt2701_cs42448_i2sin1_mux_get(struct snd_kcontrol *kcontrol,
+struct snd_ctl_elem_value *ucontrol)
+{
+   struct snd_soc_card *card = snd_kcontrol_chip(kcontrol);
+   struct mt2701_cs42448_private *priv = snd_soc_card_get_drvdata(card);
+
+   ucontrol->value.integer.value[0] = priv->i2s1_in_mux;
+   return 0;
+}
+
+static int mt2701_cs42448_i2sin1_mux_set(struct snd_kcontrol *kcontrol,
+struct snd_ctl_elem_value *ucontrol)
+{
+   struct snd_soc_card *card = snd_kcontrol_chip(kcontrol);
+   struct mt2701_cs42448_private *priv = snd_soc_card_get_drvdata(card);
+
+   if (ucontrol->value.integer.value[0] == priv->i2s1_in_mux)
+   return 0;
+
+   

[alsa-devel] [PATCH v2 2/9] ASoC: mediatek: implement mediatek common structure

2016-06-02 Thread Garlic Tseng
implement mediatek basic structure, include common private data,
afe fe dai operator and afe platform driver.

Signed-off-by: Garlic Tseng 
---
 sound/soc/mediatek/common/mtk-afe-fe-dai.c | 387 +
 sound/soc/mediatek/common/mtk-afe-fe-dai.h |  47 +++
 .../soc/mediatek/common/mtk-afe-platform-driver.c  |  90 +
 .../soc/mediatek/common/mtk-afe-platform-driver.h  |  23 ++
 sound/soc/mediatek/common/mtk-base-afe.h   | 103 ++
 5 files changed, 650 insertions(+)
 create mode 100644 sound/soc/mediatek/common/mtk-afe-fe-dai.c
 create mode 100644 sound/soc/mediatek/common/mtk-afe-fe-dai.h
 create mode 100644 sound/soc/mediatek/common/mtk-afe-platform-driver.c
 create mode 100644 sound/soc/mediatek/common/mtk-afe-platform-driver.h
 create mode 100644 sound/soc/mediatek/common/mtk-base-afe.h

diff --git a/sound/soc/mediatek/common/mtk-afe-fe-dai.c 
b/sound/soc/mediatek/common/mtk-afe-fe-dai.c
new file mode 100644
index 000..02d454d
--- /dev/null
+++ b/sound/soc/mediatek/common/mtk-afe-fe-dai.c
@@ -0,0 +1,387 @@
+/*
+ * mtk-afe-fe-dais.c  --  Mediatek afe fe dai operator
+ *
+ * Copyright (c) 2016 MediaTek Inc.
+ * Author: Garlic Tseng 
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only 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 "mtk-afe-fe-dai.h"
+#include "mtk-base-afe.h"
+
+#define AFE_BASE_END_OFFSET 8
+
+int mtk_regmap_update_bits(struct regmap *map, int reg, unsigned int mask,
+  unsigned int val)
+{
+   if (reg < 0)
+   return 0;
+   return regmap_update_bits(map, reg, mask, val);
+}
+
+int mtk_regmap_write(struct regmap *map, int reg, unsigned int val)
+{
+   if (reg < 0)
+   return 0;
+   return regmap_write(map, reg, val);
+}
+
+int mtk_afe_fe_startup(struct snd_pcm_substream *substream,
+  struct snd_soc_dai *dai)
+{
+   struct snd_soc_pcm_runtime *rtd = substream->private_data;
+   struct mtk_base_afe *afe = snd_soc_platform_get_drvdata(rtd->platform);
+   struct snd_pcm_runtime *runtime = substream->runtime;
+   int memif_num = rtd->cpu_dai->id;
+   struct mtk_base_afe_memif *memif = >memif[memif_num];
+   const struct snd_pcm_hardware *mtk_afe_hardware = afe->mtk_afe_hardware;
+   int ret;
+
+   memif->substream = substream;
+
+   snd_pcm_hw_constraint_step(substream->runtime, 0,
+  SNDRV_PCM_HW_PARAM_BUFFER_BYTES, 16);
+   /*enable agent*/
+   mtk_regmap_update_bits(afe->regmap, memif->data->agent_disable_reg,
+  1 << memif->data->agent_disable_shift,
+  0 << memif->data->agent_disable_shift);
+
+   snd_soc_set_runtime_hwparams(substream, mtk_afe_hardware);
+
+   /*
+* Capture cannot use ping-pong buffer since hw_ptr at IRQ may be
+* smaller than period_size due to AFE's internal buffer.
+* This easily leads to overrun when avail_min is period_size.
+* One more period can hold the possible unread buffer.
+*/
+   if (substream->stream == SNDRV_PCM_STREAM_CAPTURE) {
+   int periods_max = mtk_afe_hardware->periods_max;
+
+   ret = snd_pcm_hw_constraint_minmax(runtime,
+  SNDRV_PCM_HW_PARAM_PERIODS,
+  3, periods_max);
+   if (ret < 0) {
+   dev_err(afe->dev, "hw_constraint_minmax failed\n");
+   return ret;
+   }
+   }
+
+   ret = snd_pcm_hw_constraint_integer(runtime,
+   SNDRV_PCM_HW_PARAM_PERIODS);
+   if (ret < 0)
+   dev_err(afe->dev, "snd_pcm_hw_constraint_integer failed\n");
+
+   /*dynamic allocate irq to memif */
+   if (memif->irq_usage < 0) {
+   int irq_id = mtk_dynamic_irq_acquire(afe);
+
+   if (irq_id != afe->irqs_size) {
+   /* link */
+   memif->irq_usage = irq_id;
+   } else {
+   dev_err(afe->dev, "%s() error: no more asys irq\n",
+   __func__);
+   ret = -EBUSY;
+   }
+   }
+   return ret;
+}
+EXPORT_SYMBOL(mtk_afe_fe_startup);
+
+void mtk_afe_fe_shutdown(struct snd_pcm_substream *substream,
+struct snd_soc_dai *dai)
+{
+   struct snd_soc_pcm_runtime *rtd = substream->private_data;
+   struct 

[alsa-devel] [PATCH v2 9/9] ASoC: mediatek: Add mt2701-cs42448 driver and config option.

2016-06-02 Thread Garlic Tseng
Add machine driver and config option for MT2701.

Signed-off-by: Garlic Tseng 
---
 sound/soc/mediatek/Kconfig |  21 ++
 sound/soc/mediatek/Makefile|   1 +
 sound/soc/mediatek/mt2701/Makefile |  19 ++
 sound/soc/mediatek/mt2701/mt2701-cs42448.c | 422 +
 4 files changed, 463 insertions(+)
 create mode 100644 sound/soc/mediatek/mt2701/Makefile
 create mode 100644 sound/soc/mediatek/mt2701/mt2701-cs42448.c

diff --git a/sound/soc/mediatek/Kconfig b/sound/soc/mediatek/Kconfig
index ff1a419..0ecb785 100644
--- a/sound/soc/mediatek/Kconfig
+++ b/sound/soc/mediatek/Kconfig
@@ -7,6 +7,27 @@ config SND_SOC_MEDIATEK
  Select Y if you have such device.
  If unsure select "N".
 
+config SND_SOC_MT2701
+   tristate "ASoC support for Mediatek MT2701 chip"
+   depends on ARCH_MEDIATEK
+   select SND_SOC_MEDIATEK
+   help
+ This adds ASoC driver for Mediatek MT2701 boards
+ that can be used with other codecs.
+ Select Y if you have such device.
+ If unsure select "N".
+
+config SND_SOC_MT2701_CS42448
+   tristate "SND_SOC_MT2701_CS42448"
+   depends on SND_SOC_MT2701
+   select SND_SOC_CS42XX8_I2C
+   select SND_SOC_BT_SCO
+   help
+ This adds ASoC driver for Mediatek MT2701 boards
+ with the CS42448 codecs.
+ Select Y if you have such device.
+ If unsure select "N".
+
 config SND_SOC_MT8173
tristate "ASoC support for Mediatek MT8173 chip"
depends on ARCH_MEDIATEK
diff --git a/sound/soc/mediatek/Makefile b/sound/soc/mediatek/Makefile
index 3d893be..5133215 100644
--- a/sound/soc/mediatek/Makefile
+++ b/sound/soc/mediatek/Makefile
@@ -1,3 +1,4 @@
 obj-$(CONFIG_SND_SOC_MEDIATEK) += common/
+obj-$(CONFIG_SND_SOC_MT2701) += mt2701/
 obj-$(CONFIG_SND_SOC_MT8173) += mt8173/
 
diff --git a/sound/soc/mediatek/mt2701/Makefile 
b/sound/soc/mediatek/mt2701/Makefile
new file mode 100644
index 000..31c3d04
--- /dev/null
+++ b/sound/soc/mediatek/mt2701/Makefile
@@ -0,0 +1,19 @@
+#
+# Copyright (C) 2015 MediaTek Inc.
+#
+# 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.
+#
+
+# platform driver
+snd-soc-mt2701-afe-objs := mt2701-afe-pcm.o mt2701-afe-clock-ctrl.o
+obj-$(CONFIG_SND_SOC_MT2701) += snd-soc-mt2701-afe.o
+
+# machine driver
+obj-$(CONFIG_SND_SOC_MT2701_CS42448) += mt2701-cs42448.o
diff --git a/sound/soc/mediatek/mt2701/mt2701-cs42448.c 
b/sound/soc/mediatek/mt2701/mt2701-cs42448.c
new file mode 100644
index 000..fce159f
--- /dev/null
+++ b/sound/soc/mediatek/mt2701/mt2701-cs42448.c
@@ -0,0 +1,422 @@
+/*
+ * mt2701-cs42448.c  --  MT2701 CS42448 ALSA SoC machine driver
+ *
+ * Copyright (c) 2016 MediaTek Inc.
+ * Author: Ir Lian 
+ *  Garlic Tseng 
+ *
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only 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 "mt2701-afe-common.h"
+
+struct mt2701_cs42448_private {
+   int i2s1_in_mux;
+   int i2s1_in_mux_gpio_sel_1;
+   int i2s1_in_mux_gpio_sel_2;
+};
+
+static const char * const i2sin_mux_switch_text[] = {
+   "ADC_SDOUT2",
+   "ADC_SDOUT3",
+   "I2S_IN_1",
+   "I2S_IN_2",
+};
+
+static const struct soc_enum i2sin_mux_enum =
+   SOC_ENUM_SINGLE_EXT(4, i2sin_mux_switch_text);
+
+static int mt2701_cs42448_i2sin1_mux_get(struct snd_kcontrol *kcontrol,
+struct snd_ctl_elem_value *ucontrol)
+{
+   struct snd_soc_card *card = snd_kcontrol_chip(kcontrol);
+   struct mt2701_cs42448_private *priv = snd_soc_card_get_drvdata(card);
+
+   ucontrol->value.integer.value[0] = priv->i2s1_in_mux;
+   return 0;
+}
+
+static int mt2701_cs42448_i2sin1_mux_set(struct snd_kcontrol *kcontrol,
+struct snd_ctl_elem_value *ucontrol)
+{
+   struct snd_soc_card *card = snd_kcontrol_chip(kcontrol);
+   struct mt2701_cs42448_private *priv = snd_soc_card_get_drvdata(card);
+
+   if (ucontrol->value.integer.value[0] == priv->i2s1_in_mux)
+   return 0;
+
+   switch (ucontrol->value.integer.value[0]) {
+   case 0:
+   

Re: NFS/d_splice_alias breakage

2016-06-02 Thread Al Viro
On Fri, Jun 03, 2016 at 05:42:53AM +0100, Al Viro wrote:
> On Fri, Jun 03, 2016 at 05:26:48AM +0100, Al Viro wrote:
> 
> > Looks like the right thing to do would be to do d_drop() at no_open:,
> > just before we call nfs_lookup().  If not earlier, actually...  How
> > about the following?
> 
> A bit of rationale: dentry in question is negative and attempt to open
> it has just failed; in case it's really negative we did that d_drop()
> anyway (and then unconditionally rehashed it).  In case when we proceed to
> nfs_lookup() and it does not fail, we'll have it rehashed there (with the
> right inode).  What do we lose from doing d_drop() on *any* error here?
> It's negative, with dubious validity.  In the worst case, we had open
> and lookup fail, but it's just us - the sucker really is negative and
> somebody else would be able to revalidate it.  If we drop it here (and
> not rehash later), that somebody else will have to allocate an in-core
> dentry before doing lookup or atomic_open.  Which is negligible extra
> burden.

I suspect that it got broken in commit 275bb3078 (NFSv4: Move dentry
instantiation into the NFSv4-specific atomic open code).  Prior to that
commit, d_drop() was there (error or no error).  Looks like 3.10+, indeed.
I agree that we shouldn't drop it on successful open, but it needs to be
done on errors.  All of them, not just ENOENT, as in that commit.


Re: NFS/d_splice_alias breakage

2016-06-02 Thread Al Viro
On Fri, Jun 03, 2016 at 05:42:53AM +0100, Al Viro wrote:
> On Fri, Jun 03, 2016 at 05:26:48AM +0100, Al Viro wrote:
> 
> > Looks like the right thing to do would be to do d_drop() at no_open:,
> > just before we call nfs_lookup().  If not earlier, actually...  How
> > about the following?
> 
> A bit of rationale: dentry in question is negative and attempt to open
> it has just failed; in case it's really negative we did that d_drop()
> anyway (and then unconditionally rehashed it).  In case when we proceed to
> nfs_lookup() and it does not fail, we'll have it rehashed there (with the
> right inode).  What do we lose from doing d_drop() on *any* error here?
> It's negative, with dubious validity.  In the worst case, we had open
> and lookup fail, but it's just us - the sucker really is negative and
> somebody else would be able to revalidate it.  If we drop it here (and
> not rehash later), that somebody else will have to allocate an in-core
> dentry before doing lookup or atomic_open.  Which is negligible extra
> burden.

I suspect that it got broken in commit 275bb3078 (NFSv4: Move dentry
instantiation into the NFSv4-specific atomic open code).  Prior to that
commit, d_drop() was there (error or no error).  Looks like 3.10+, indeed.
I agree that we shouldn't drop it on successful open, but it needs to be
done on errors.  All of them, not just ENOENT, as in that commit.


[PATCH RESEND 1/2] kernel: Add noaudit variant of ns_capable()

2016-06-02 Thread Tyler Hicks
When checking the current cred for a capability in a specific user
namespace, it isn't always desirable to have the LSMs audit the check.
This patch adds a noaudit variant of ns_capable() for when those
situations arise.

The common logic between ns_capable() and the new ns_capable_noaudit()
is moved into a single, shared function to keep duplicated code to a
minimum and ease maintainability.

Signed-off-by: Tyler Hicks 
Acked-by: Serge E. Hallyn 
---
 include/linux/capability.h |  5 +
 kernel/capability.c| 46 --
 2 files changed, 41 insertions(+), 10 deletions(-)

diff --git a/include/linux/capability.h b/include/linux/capability.h
index 00690ff..5f3c63d 100644
--- a/include/linux/capability.h
+++ b/include/linux/capability.h
@@ -206,6 +206,7 @@ extern bool has_ns_capability_noaudit(struct task_struct *t,
  struct user_namespace *ns, int cap);
 extern bool capable(int cap);
 extern bool ns_capable(struct user_namespace *ns, int cap);
+extern bool ns_capable_noaudit(struct user_namespace *ns, int cap);
 #else
 static inline bool has_capability(struct task_struct *t, int cap)
 {
@@ -233,6 +234,10 @@ static inline bool ns_capable(struct user_namespace *ns, 
int cap)
 {
return true;
 }
+static inline bool ns_capable_noaudit(struct user_namespace *ns, int cap)
+{
+   return true;
+}
 #endif /* CONFIG_MULTIUSER */
 extern bool capable_wrt_inode_uidgid(const struct inode *inode, int cap);
 extern bool file_ns_capable(const struct file *file, struct user_namespace 
*ns, int cap);
diff --git a/kernel/capability.c b/kernel/capability.c
index 45432b5..00411c8 100644
--- a/kernel/capability.c
+++ b/kernel/capability.c
@@ -361,6 +361,24 @@ bool has_capability_noaudit(struct task_struct *t, int cap)
return has_ns_capability_noaudit(t, _user_ns, cap);
 }
 
+static bool ns_capable_common(struct user_namespace *ns, int cap, bool audit)
+{
+   int capable;
+
+   if (unlikely(!cap_valid(cap))) {
+   pr_crit("capable() called with invalid cap=%u\n", cap);
+   BUG();
+   }
+
+   capable = audit ? security_capable(current_cred(), ns, cap) :
+ security_capable_noaudit(current_cred(), ns, cap);
+   if (capable == 0) {
+   current->flags |= PF_SUPERPRIV;
+   return true;
+   }
+   return false;
+}
+
 /**
  * ns_capable - Determine if the current task has a superior capability in 
effect
  * @ns:  The usernamespace we want the capability in
@@ -374,19 +392,27 @@ bool has_capability_noaudit(struct task_struct *t, int 
cap)
  */
 bool ns_capable(struct user_namespace *ns, int cap)
 {
-   if (unlikely(!cap_valid(cap))) {
-   pr_crit("capable() called with invalid cap=%u\n", cap);
-   BUG();
-   }
-
-   if (security_capable(current_cred(), ns, cap) == 0) {
-   current->flags |= PF_SUPERPRIV;
-   return true;
-   }
-   return false;
+   return ns_capable_common(ns, cap, true);
 }
 EXPORT_SYMBOL(ns_capable);
 
+/**
+ * ns_capable_noaudit - Determine if the current task has a superior capability
+ * (unaudited) in effect
+ * @ns:  The usernamespace we want the capability in
+ * @cap: The capability to be tested for
+ *
+ * Return true if the current task has the given superior capability currently
+ * available for use, false if not.
+ *
+ * This sets PF_SUPERPRIV on the task if the capability is available on the
+ * assumption that it's about to be used.
+ */
+bool ns_capable_noaudit(struct user_namespace *ns, int cap)
+{
+   return ns_capable_common(ns, cap, false);
+}
+EXPORT_SYMBOL(ns_capable_noaudit);
 
 /**
  * capable - Determine if the current task has a superior capability in effect
-- 
2.7.4



[PATCH RESEND 1/2] kernel: Add noaudit variant of ns_capable()

2016-06-02 Thread Tyler Hicks
When checking the current cred for a capability in a specific user
namespace, it isn't always desirable to have the LSMs audit the check.
This patch adds a noaudit variant of ns_capable() for when those
situations arise.

The common logic between ns_capable() and the new ns_capable_noaudit()
is moved into a single, shared function to keep duplicated code to a
minimum and ease maintainability.

Signed-off-by: Tyler Hicks 
Acked-by: Serge E. Hallyn 
---
 include/linux/capability.h |  5 +
 kernel/capability.c| 46 --
 2 files changed, 41 insertions(+), 10 deletions(-)

diff --git a/include/linux/capability.h b/include/linux/capability.h
index 00690ff..5f3c63d 100644
--- a/include/linux/capability.h
+++ b/include/linux/capability.h
@@ -206,6 +206,7 @@ extern bool has_ns_capability_noaudit(struct task_struct *t,
  struct user_namespace *ns, int cap);
 extern bool capable(int cap);
 extern bool ns_capable(struct user_namespace *ns, int cap);
+extern bool ns_capable_noaudit(struct user_namespace *ns, int cap);
 #else
 static inline bool has_capability(struct task_struct *t, int cap)
 {
@@ -233,6 +234,10 @@ static inline bool ns_capable(struct user_namespace *ns, 
int cap)
 {
return true;
 }
+static inline bool ns_capable_noaudit(struct user_namespace *ns, int cap)
+{
+   return true;
+}
 #endif /* CONFIG_MULTIUSER */
 extern bool capable_wrt_inode_uidgid(const struct inode *inode, int cap);
 extern bool file_ns_capable(const struct file *file, struct user_namespace 
*ns, int cap);
diff --git a/kernel/capability.c b/kernel/capability.c
index 45432b5..00411c8 100644
--- a/kernel/capability.c
+++ b/kernel/capability.c
@@ -361,6 +361,24 @@ bool has_capability_noaudit(struct task_struct *t, int cap)
return has_ns_capability_noaudit(t, _user_ns, cap);
 }
 
+static bool ns_capable_common(struct user_namespace *ns, int cap, bool audit)
+{
+   int capable;
+
+   if (unlikely(!cap_valid(cap))) {
+   pr_crit("capable() called with invalid cap=%u\n", cap);
+   BUG();
+   }
+
+   capable = audit ? security_capable(current_cred(), ns, cap) :
+ security_capable_noaudit(current_cred(), ns, cap);
+   if (capable == 0) {
+   current->flags |= PF_SUPERPRIV;
+   return true;
+   }
+   return false;
+}
+
 /**
  * ns_capable - Determine if the current task has a superior capability in 
effect
  * @ns:  The usernamespace we want the capability in
@@ -374,19 +392,27 @@ bool has_capability_noaudit(struct task_struct *t, int 
cap)
  */
 bool ns_capable(struct user_namespace *ns, int cap)
 {
-   if (unlikely(!cap_valid(cap))) {
-   pr_crit("capable() called with invalid cap=%u\n", cap);
-   BUG();
-   }
-
-   if (security_capable(current_cred(), ns, cap) == 0) {
-   current->flags |= PF_SUPERPRIV;
-   return true;
-   }
-   return false;
+   return ns_capable_common(ns, cap, true);
 }
 EXPORT_SYMBOL(ns_capable);
 
+/**
+ * ns_capable_noaudit - Determine if the current task has a superior capability
+ * (unaudited) in effect
+ * @ns:  The usernamespace we want the capability in
+ * @cap: The capability to be tested for
+ *
+ * Return true if the current task has the given superior capability currently
+ * available for use, false if not.
+ *
+ * This sets PF_SUPERPRIV on the task if the capability is available on the
+ * assumption that it's about to be used.
+ */
+bool ns_capable_noaudit(struct user_namespace *ns, int cap)
+{
+   return ns_capable_common(ns, cap, false);
+}
+EXPORT_SYMBOL(ns_capable_noaudit);
 
 /**
  * capable - Determine if the current task has a superior capability in effect
-- 
2.7.4



[PATCH RESEND 2/2] net: Use ns_capable_noaudit() when determining net sysctl permissions

2016-06-02 Thread Tyler Hicks
The capability check should not be audited since it is only being used
to determine the inode permissions. A failed check does not indicate a
violation of security policy but, when an LSM is enabled, a denial audit
message was being generated.

The denial audit message caused confusion for some application authors
because root-running Go applications always triggered the denial. To
prevent this confusion, the capability check in net_ctl_permissions() is
switched to the noaudit variant.

BugLink: https://launchpad.net/bugs/1465724

Signed-off-by: Tyler Hicks 
Acked-by: Serge E. Hallyn 
---
 net/sysctl_net.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/net/sysctl_net.c b/net/sysctl_net.c
index ed98c1f..46a71c7 100644
--- a/net/sysctl_net.c
+++ b/net/sysctl_net.c
@@ -46,7 +46,7 @@ static int net_ctl_permissions(struct ctl_table_header *head,
kgid_t root_gid = make_kgid(net->user_ns, 0);
 
/* Allow network administrator to have same access as root. */
-   if (ns_capable(net->user_ns, CAP_NET_ADMIN) ||
+   if (ns_capable_noaudit(net->user_ns, CAP_NET_ADMIN) ||
uid_eq(root_uid, current_euid())) {
int mode = (table->mode >> 6) & 7;
return (mode << 6) | (mode << 3) | mode;
-- 
2.7.4



[PATCH RESEND 0/2] Quiet noisy LSM denial when accessing net sysctl

2016-06-02 Thread Tyler Hicks
I'm resending this patch set at the request of James Morris. This pair of
patches does away with what I believe is a useless denial audit message
when a privileged process initially accesses a net sysctl.

The bug was first discovered when running Go applications under AppArmor
confinement. It can be triggered like so:

  $ echo "profile test { file, }" | sudo apparmor_parser -rq

Once the profile is loaded, invoke Go as root under confinement:

  $ sudo aa-exec -p test -- go version
  go version go1.6.1 linux/amd64

Here's the denial:

  audit: type=1400 audit(1462575436.832:29): apparmor="DENIED" 
operation="capable" profile="test" pid=1157 comm="go" capability=12  
capname="net_admin"

The reproducer in minimal form is:

  $ sudo aa-exec -p test -- cat /proc/sys/net/core/somaxconn
  128

The denial:

  audit: type=1400 audit(1462575670.000:29): apparmor="DENIED" 
operation="capable" profile="test" pid=1161 comm="cat" capability=12  
capname="net_admin"

Thanks!

Tyler



[PATCH RESEND 2/2] net: Use ns_capable_noaudit() when determining net sysctl permissions

2016-06-02 Thread Tyler Hicks
The capability check should not be audited since it is only being used
to determine the inode permissions. A failed check does not indicate a
violation of security policy but, when an LSM is enabled, a denial audit
message was being generated.

The denial audit message caused confusion for some application authors
because root-running Go applications always triggered the denial. To
prevent this confusion, the capability check in net_ctl_permissions() is
switched to the noaudit variant.

BugLink: https://launchpad.net/bugs/1465724

Signed-off-by: Tyler Hicks 
Acked-by: Serge E. Hallyn 
---
 net/sysctl_net.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/net/sysctl_net.c b/net/sysctl_net.c
index ed98c1f..46a71c7 100644
--- a/net/sysctl_net.c
+++ b/net/sysctl_net.c
@@ -46,7 +46,7 @@ static int net_ctl_permissions(struct ctl_table_header *head,
kgid_t root_gid = make_kgid(net->user_ns, 0);
 
/* Allow network administrator to have same access as root. */
-   if (ns_capable(net->user_ns, CAP_NET_ADMIN) ||
+   if (ns_capable_noaudit(net->user_ns, CAP_NET_ADMIN) ||
uid_eq(root_uid, current_euid())) {
int mode = (table->mode >> 6) & 7;
return (mode << 6) | (mode << 3) | mode;
-- 
2.7.4



[PATCH RESEND 0/2] Quiet noisy LSM denial when accessing net sysctl

2016-06-02 Thread Tyler Hicks
I'm resending this patch set at the request of James Morris. This pair of
patches does away with what I believe is a useless denial audit message
when a privileged process initially accesses a net sysctl.

The bug was first discovered when running Go applications under AppArmor
confinement. It can be triggered like so:

  $ echo "profile test { file, }" | sudo apparmor_parser -rq

Once the profile is loaded, invoke Go as root under confinement:

  $ sudo aa-exec -p test -- go version
  go version go1.6.1 linux/amd64

Here's the denial:

  audit: type=1400 audit(1462575436.832:29): apparmor="DENIED" 
operation="capable" profile="test" pid=1157 comm="go" capability=12  
capname="net_admin"

The reproducer in minimal form is:

  $ sudo aa-exec -p test -- cat /proc/sys/net/core/somaxconn
  128

The denial:

  audit: type=1400 audit(1462575670.000:29): apparmor="DENIED" 
operation="capable" profile="test" pid=1161 comm="cat" capability=12  
capname="net_admin"

Thanks!

Tyler



Re: NFS/d_splice_alias breakage

2016-06-02 Thread Al Viro
On Fri, Jun 03, 2016 at 05:26:48AM +0100, Al Viro wrote:

> Looks like the right thing to do would be to do d_drop() at no_open:,
> just before we call nfs_lookup().  If not earlier, actually...  How
> about the following?

A bit of rationale: dentry in question is negative and attempt to open
it has just failed; in case it's really negative we did that d_drop()
anyway (and then unconditionally rehashed it).  In case when we proceed to
nfs_lookup() and it does not fail, we'll have it rehashed there (with the
right inode).  What do we lose from doing d_drop() on *any* error here?
It's negative, with dubious validity.  In the worst case, we had open
and lookup fail, but it's just us - the sucker really is negative and
somebody else would be able to revalidate it.  If we drop it here (and
not rehash later), that somebody else will have to allocate an in-core
dentry before doing lookup or atomic_open.  Which is negligible extra
burden.

> diff --git a/fs/nfs/dir.c b/fs/nfs/dir.c
> index aaf7bd0..6e3a6f4 100644
> --- a/fs/nfs/dir.c
> +++ b/fs/nfs/dir.c
> @@ -1536,9 +1536,9 @@ int nfs_atomic_open(struct inode *dir, struct dentry 
> *dentry,
>   err = PTR_ERR(inode);
>   trace_nfs_atomic_open_exit(dir, ctx, open_flags, err);
>   put_nfs_open_context(ctx);
> + d_drop(dentry);
>   switch (err) {
>   case -ENOENT:
> - d_drop(dentry);
>   d_add(dentry, NULL);
>   nfs_set_verifier(dentry, 
> nfs_save_change_attribute(dir));
>   break;


Re: NFS/d_splice_alias breakage

2016-06-02 Thread Al Viro
On Fri, Jun 03, 2016 at 05:26:48AM +0100, Al Viro wrote:

> Looks like the right thing to do would be to do d_drop() at no_open:,
> just before we call nfs_lookup().  If not earlier, actually...  How
> about the following?

A bit of rationale: dentry in question is negative and attempt to open
it has just failed; in case it's really negative we did that d_drop()
anyway (and then unconditionally rehashed it).  In case when we proceed to
nfs_lookup() and it does not fail, we'll have it rehashed there (with the
right inode).  What do we lose from doing d_drop() on *any* error here?
It's negative, with dubious validity.  In the worst case, we had open
and lookup fail, but it's just us - the sucker really is negative and
somebody else would be able to revalidate it.  If we drop it here (and
not rehash later), that somebody else will have to allocate an in-core
dentry before doing lookup or atomic_open.  Which is negligible extra
burden.

> diff --git a/fs/nfs/dir.c b/fs/nfs/dir.c
> index aaf7bd0..6e3a6f4 100644
> --- a/fs/nfs/dir.c
> +++ b/fs/nfs/dir.c
> @@ -1536,9 +1536,9 @@ int nfs_atomic_open(struct inode *dir, struct dentry 
> *dentry,
>   err = PTR_ERR(inode);
>   trace_nfs_atomic_open_exit(dir, ctx, open_flags, err);
>   put_nfs_open_context(ctx);
> + d_drop(dentry);
>   switch (err) {
>   case -ENOENT:
> - d_drop(dentry);
>   d_add(dentry, NULL);
>   nfs_set_verifier(dentry, 
> nfs_save_change_attribute(dir));
>   break;


Re: [PATCH v5 1/6] qspinlock: powerpc support qspinlock

2016-06-02 Thread Benjamin Herrenschmidt
On Fri, 2016-06-03 at 12:10 +0800, xinhui wrote:
> On 2016年06月03日 09:32, Benjamin Herrenschmidt wrote:
> > On Fri, 2016-06-03 at 11:32 +1000, Benjamin Herrenschmidt wrote:
> >> On Thu, 2016-06-02 at 17:22 +0800, Pan Xinhui wrote:
> >>>
> >>> Base code to enable qspinlock on powerpc. this patch add some
> >>> #ifdef
> >>> here and there. Although there is no paravirt related code, we
> can
> >>> successfully build a qspinlock kernel after apply this patch.
> >> This is missing the IO_SYNC stuff ... It means we'll fail to do a
> >> full
> >> sync to order vs MMIOs.
> >>
> >> You need to add that back in the unlock path.
> >
> > Well, and in the lock path as well...
> >
> Oh, yes. I missed IO_SYNC stuff.
> 
> thank you, Ben :)

Ok couple of other things that would be nice from my perspective (and
Michael's) if you can produce them:

 - Some benchmarks of the qspinlock alone, without the PV stuff,
   so we understand how much of the overhead is inherent to the
   qspinlock and how much is introduced by the PV bits.

 - For the above, can you show (or describe) where the qspinlock
   improves things compared to our current locks. While there's
   theory and to some extent practice on x86, it would be nice to
   validate the effects on POWER.

 - Comparative benchmark with the PV stuff in on a bare metal system
   to understand the overhead there.

 - Comparative benchmark with the PV stuff under pHyp and KVM

Spinlocks are fiddly and a critical piece of infrastructure, it's
important we fully understand the performance implications before we
decide to switch to a new model.

Cheers,
Ben.



Re: [PATCH v5 1/6] qspinlock: powerpc support qspinlock

2016-06-02 Thread Benjamin Herrenschmidt
On Fri, 2016-06-03 at 12:10 +0800, xinhui wrote:
> On 2016年06月03日 09:32, Benjamin Herrenschmidt wrote:
> > On Fri, 2016-06-03 at 11:32 +1000, Benjamin Herrenschmidt wrote:
> >> On Thu, 2016-06-02 at 17:22 +0800, Pan Xinhui wrote:
> >>>
> >>> Base code to enable qspinlock on powerpc. this patch add some
> >>> #ifdef
> >>> here and there. Although there is no paravirt related code, we
> can
> >>> successfully build a qspinlock kernel after apply this patch.
> >> This is missing the IO_SYNC stuff ... It means we'll fail to do a
> >> full
> >> sync to order vs MMIOs.
> >>
> >> You need to add that back in the unlock path.
> >
> > Well, and in the lock path as well...
> >
> Oh, yes. I missed IO_SYNC stuff.
> 
> thank you, Ben :)

Ok couple of other things that would be nice from my perspective (and
Michael's) if you can produce them:

 - Some benchmarks of the qspinlock alone, without the PV stuff,
   so we understand how much of the overhead is inherent to the
   qspinlock and how much is introduced by the PV bits.

 - For the above, can you show (or describe) where the qspinlock
   improves things compared to our current locks. While there's
   theory and to some extent practice on x86, it would be nice to
   validate the effects on POWER.

 - Comparative benchmark with the PV stuff in on a bare metal system
   to understand the overhead there.

 - Comparative benchmark with the PV stuff under pHyp and KVM

Spinlocks are fiddly and a critical piece of infrastructure, it's
important we fully understand the performance implications before we
decide to switch to a new model.

Cheers,
Ben.



RE: [PATCH v2 10/27] staging: unisys: visorinput: remove unnecessary locking

2016-06-02 Thread Sell, Timothy C
> -Original Message-
> From: Thomas Gleixner [mailto:t...@linutronix.de]
> Sent: Wednesday, June 01, 2016 2:41 AM
> To: Kershner, David A
> Cc: cor...@lwn.net; mi...@redhat.com; h...@zytor.com;
> gre...@linuxfoundation.org; Arfvidson, Erik; Sell, Timothy C;
> hof...@osadl.org; dzic...@redhat.com; jes.soren...@redhat.com; Curtin,
> Alexander Paul; janani.rvchn...@gmail.com;
> sudipm.mukher...@gmail.com; pra...@redhat.com; Binder, David Anthony;
> nhor...@redhat.com; dan.j.willi...@intel.com; linux-
> ker...@vger.kernel.org; linux-...@vger.kernel.org; driverdev-
> de...@linuxdriverproject.org; *S-Par-Maintainer
> Subject: Re: [PATCH v2 10/27] staging: unisys: visorinput: remove
> unnecessary locking
> 
> On Tue, 31 May 2016, David Kershner wrote:
> > +   /*
> > +* If we're not paused, really enable interrupts.
> > +* Regardless of whether we are paused, set a flag indicating
> > +* interrupts should be enabled so when we resume, interrupts
> > +* will really be enabled.
> > +*/
> > +   down_write(>lock_visor_dev);
> 
> Why is this a rw_semaphore? It's only ever taken with down_write() and it's
> always the same context. Should be a mutex, right?
> 

Correct.  We have a local patch that addresses this, but would like
to submit this via a follow-on patchset if possible.  I'll explain.

Rationale: our intent for this patchset was to focus on the visorbus
driver ONLY.  The only reason visorinput got involved in the first place
was due to the visorbus change that necessitated that we remove the locking
from visorinput_channel_interrupt(), due to that now being called from atomic
context.

If the semaphore --> mutex change would have been as simple as it sounds,
we would have had NO problem including it with the next version (v3) of this
patchset.  But unfortunately, this change uncovered a latent defect, which
necessitated yet another patch.  (I know... hard to believe that something
this simple would do that, but it did.)  Rather than further complicating this
patchset, we thought it would be better to address the visorinput issues via a
separate follow-on patchset.

Is that acceptable for you?

> While at it, please convert the notifier_lock to a mutex as well.

Thanks.  Since this is visorbus-specific, we DO plan to address this in v3 of
this patchset, which will most-likely just be REMOVING notifier_lock altogether.

Tim Sell

> 
> Thanks,
> 
>   tglx


RE: [PATCH v2 10/27] staging: unisys: visorinput: remove unnecessary locking

2016-06-02 Thread Sell, Timothy C
> -Original Message-
> From: Thomas Gleixner [mailto:t...@linutronix.de]
> Sent: Wednesday, June 01, 2016 2:41 AM
> To: Kershner, David A
> Cc: cor...@lwn.net; mi...@redhat.com; h...@zytor.com;
> gre...@linuxfoundation.org; Arfvidson, Erik; Sell, Timothy C;
> hof...@osadl.org; dzic...@redhat.com; jes.soren...@redhat.com; Curtin,
> Alexander Paul; janani.rvchn...@gmail.com;
> sudipm.mukher...@gmail.com; pra...@redhat.com; Binder, David Anthony;
> nhor...@redhat.com; dan.j.willi...@intel.com; linux-
> ker...@vger.kernel.org; linux-...@vger.kernel.org; driverdev-
> de...@linuxdriverproject.org; *S-Par-Maintainer
> Subject: Re: [PATCH v2 10/27] staging: unisys: visorinput: remove
> unnecessary locking
> 
> On Tue, 31 May 2016, David Kershner wrote:
> > +   /*
> > +* If we're not paused, really enable interrupts.
> > +* Regardless of whether we are paused, set a flag indicating
> > +* interrupts should be enabled so when we resume, interrupts
> > +* will really be enabled.
> > +*/
> > +   down_write(>lock_visor_dev);
> 
> Why is this a rw_semaphore? It's only ever taken with down_write() and it's
> always the same context. Should be a mutex, right?
> 

Correct.  We have a local patch that addresses this, but would like
to submit this via a follow-on patchset if possible.  I'll explain.

Rationale: our intent for this patchset was to focus on the visorbus
driver ONLY.  The only reason visorinput got involved in the first place
was due to the visorbus change that necessitated that we remove the locking
from visorinput_channel_interrupt(), due to that now being called from atomic
context.

If the semaphore --> mutex change would have been as simple as it sounds,
we would have had NO problem including it with the next version (v3) of this
patchset.  But unfortunately, this change uncovered a latent defect, which
necessitated yet another patch.  (I know... hard to believe that something
this simple would do that, but it did.)  Rather than further complicating this
patchset, we thought it would be better to address the visorinput issues via a
separate follow-on patchset.

Is that acceptable for you?

> While at it, please convert the notifier_lock to a mutex as well.

Thanks.  Since this is visorbus-specific, we DO plan to address this in v3 of
this patchset, which will most-likely just be REMOVING notifier_lock altogether.

Tim Sell

> 
> Thanks,
> 
>   tglx


Re: [PATCH] rds: fix an infoleak in rds_inc_info_copy

2016-06-02 Thread David Miller
From: Kangjie Lu 
Date: Thu,  2 Jun 2016 04:11:20 -0400

> The last field "flags" of object "minfo" is not initialized.
> Copying this object out may leak kernel stack data.
> Assign 0 to it to avoid leak.
> 
> Signed-off-by: Kangjie Lu 

Applied.


Re: [PATCH] rds: fix an infoleak in rds_inc_info_copy

2016-06-02 Thread David Miller
From: Kangjie Lu 
Date: Thu,  2 Jun 2016 04:11:20 -0400

> The last field "flags" of object "minfo" is not initialized.
> Copying this object out may leak kernel stack data.
> Assign 0 to it to avoid leak.
> 
> Signed-off-by: Kangjie Lu 

Applied.


Re: [PATCH] tipc: fix an infoleak in tipc_nl_compat_link_dump

2016-06-02 Thread David Miller
From: Kangjie Lu 
Date: Thu,  2 Jun 2016 04:04:56 -0400

> link_info.str is a char array of size 60. Memory after the NULL
> byte is not initialized. Sending the whole object out can cause
> a leak.
> 
> Signed-off-by: Kangjie Lu 

Applied.


Re: [PATCH] tipc: fix an infoleak in tipc_nl_compat_link_dump

2016-06-02 Thread David Miller
From: Kangjie Lu 
Date: Thu,  2 Jun 2016 04:04:56 -0400

> link_info.str is a char array of size 60. Memory after the NULL
> byte is not initialized. Sending the whole object out can cause
> a leak.
> 
> Signed-off-by: Kangjie Lu 

Applied.


Re: NFS/d_splice_alias breakage

2016-06-02 Thread Al Viro
On Thu, Jun 02, 2016 at 11:43:59PM -0400, Oleg Drokin wrote:

> > Which of the call sites had that been and how does one reproduce that fun?
> > If you feel that posting a reproducer in the open is a bad idea, just send
> > it off-list...
> 
> This is fs/nfs/dir.c::nfs_lookup() right after no_entry label.

Bloody hell...  Was that sucker hashed on the entry into nfs_lookup()?
If we get that with call as a method, we are really fucked.



Ho-hum...  One of the goto no_open; in nfs_atomic_open()?  That would
mean a stale negative dentry in dcache that has escaped revalidation...
Wait a minute, didn't nfs ->d_revalidate() skip everything in some
cases, leaving it to ->atomic_open()?

Looks like the right thing to do would be to do d_drop() at no_open:,
just before we call nfs_lookup().  If not earlier, actually...  How
about the following?

diff --git a/fs/nfs/dir.c b/fs/nfs/dir.c
index aaf7bd0..6e3a6f4 100644
--- a/fs/nfs/dir.c
+++ b/fs/nfs/dir.c
@@ -1536,9 +1536,9 @@ int nfs_atomic_open(struct inode *dir, struct dentry 
*dentry,
err = PTR_ERR(inode);
trace_nfs_atomic_open_exit(dir, ctx, open_flags, err);
put_nfs_open_context(ctx);
+   d_drop(dentry);
switch (err) {
case -ENOENT:
-   d_drop(dentry);
d_add(dentry, NULL);
nfs_set_verifier(dentry, 
nfs_save_change_attribute(dir));
break;


Re: NFS/d_splice_alias breakage

2016-06-02 Thread Al Viro
On Thu, Jun 02, 2016 at 11:43:59PM -0400, Oleg Drokin wrote:

> > Which of the call sites had that been and how does one reproduce that fun?
> > If you feel that posting a reproducer in the open is a bad idea, just send
> > it off-list...
> 
> This is fs/nfs/dir.c::nfs_lookup() right after no_entry label.

Bloody hell...  Was that sucker hashed on the entry into nfs_lookup()?
If we get that with call as a method, we are really fucked.



Ho-hum...  One of the goto no_open; in nfs_atomic_open()?  That would
mean a stale negative dentry in dcache that has escaped revalidation...
Wait a minute, didn't nfs ->d_revalidate() skip everything in some
cases, leaving it to ->atomic_open()?

Looks like the right thing to do would be to do d_drop() at no_open:,
just before we call nfs_lookup().  If not earlier, actually...  How
about the following?

diff --git a/fs/nfs/dir.c b/fs/nfs/dir.c
index aaf7bd0..6e3a6f4 100644
--- a/fs/nfs/dir.c
+++ b/fs/nfs/dir.c
@@ -1536,9 +1536,9 @@ int nfs_atomic_open(struct inode *dir, struct dentry 
*dentry,
err = PTR_ERR(inode);
trace_nfs_atomic_open_exit(dir, ctx, open_flags, err);
put_nfs_open_context(ctx);
+   d_drop(dentry);
switch (err) {
case -ENOENT:
-   d_drop(dentry);
d_add(dentry, NULL);
nfs_set_verifier(dentry, 
nfs_save_change_attribute(dir));
break;


Re: [linux-next: Tree for Jun 1] __khugepaged_exit rwsem_down_write_failed lockup

2016-06-02 Thread Sergey Senozhatsky
On (06/03/16 10:29), Sergey Senozhatsky wrote:
> > if (allocstall == curr_allocstall && swap != 0) {
> > if (!__collapse_huge_page_swapin(mm, vma, address, pmd)) {
> > {
> > :   if (ret & VM_FAULT_RETRY) {
> > :   down_read(>mmap_sem);
> > :   ^
> 
> oh... it's in a loop
> 
>   for (_address = address; _address < address + 
> HPAGE_PMD_NR*PAGE_SIZE;
>   pte++, _address += PAGE_SIZE) {
>   ret = do_swap_page()
>   if (ret & VM_FAULT_RETRY) {
>   down_read(>mmap_sem);
>   ^
>   ...
>   }
>   }
> 
> so there can be multiple sem->count++ in __collapse_huge_page_swapin(),
> and you don't know how many sem->count-- you need to do later? is this
> correct or am I hallucinating?

No, I was wrong, sorry for the noise.

it's getting unlocked in

__collapse_huge_page_swapin()
do_swap_page()
lock_page_or_retry()
if (flags & FAULT_FLAG_ALLOW_RETRY)
up_read(>mmap_sem);
return VM_FAULT_RETRY

-ss


Re: [linux-next: Tree for Jun 1] __khugepaged_exit rwsem_down_write_failed lockup

2016-06-02 Thread Sergey Senozhatsky
On (06/03/16 10:29), Sergey Senozhatsky wrote:
> > if (allocstall == curr_allocstall && swap != 0) {
> > if (!__collapse_huge_page_swapin(mm, vma, address, pmd)) {
> > {
> > :   if (ret & VM_FAULT_RETRY) {
> > :   down_read(>mmap_sem);
> > :   ^
> 
> oh... it's in a loop
> 
>   for (_address = address; _address < address + 
> HPAGE_PMD_NR*PAGE_SIZE;
>   pte++, _address += PAGE_SIZE) {
>   ret = do_swap_page()
>   if (ret & VM_FAULT_RETRY) {
>   down_read(>mmap_sem);
>   ^
>   ...
>   }
>   }
> 
> so there can be multiple sem->count++ in __collapse_huge_page_swapin(),
> and you don't know how many sem->count-- you need to do later? is this
> correct or am I hallucinating?

No, I was wrong, sorry for the noise.

it's getting unlocked in

__collapse_huge_page_swapin()
do_swap_page()
lock_page_or_retry()
if (flags & FAULT_FLAG_ALLOW_RETRY)
up_read(>mmap_sem);
return VM_FAULT_RETRY

-ss


Re: [PATCH v5 1/6] qspinlock: powerpc support qspinlock

2016-06-02 Thread xinhui


On 2016年06月03日 09:32, Benjamin Herrenschmidt wrote:

On Fri, 2016-06-03 at 11:32 +1000, Benjamin Herrenschmidt wrote:

On Thu, 2016-06-02 at 17:22 +0800, Pan Xinhui wrote:


Base code to enable qspinlock on powerpc. this patch add some
#ifdef
here and there. Although there is no paravirt related code, we can
successfully build a qspinlock kernel after apply this patch.

This is missing the IO_SYNC stuff ... It means we'll fail to do a
full
sync to order vs MMIOs.

You need to add that back in the unlock path.


Well, and in the lock path as well...


Oh, yes. I missed IO_SYNC stuff.

thank you, Ben :)


Cheers,
Ben.



Signed-off-by: Pan Xinhui 
---
  arch/powerpc/include/asm/qspinlock.h  | 26
++
  arch/powerpc/include/asm/spinlock.h   | 27 +++

  arch/powerpc/include/asm/spinlock_types.h |  4 
  arch/powerpc/lib/locks.c  |  4 
  4 files changed, 49 insertions(+), 12 deletions(-)
  create mode 100644 arch/powerpc/include/asm/qspinlock.h

diff --git a/arch/powerpc/include/asm/qspinlock.h
b/arch/powerpc/include/asm/qspinlock.h
new file mode 100644
index 000..fc83cd2
--- /dev/null
+++ b/arch/powerpc/include/asm/qspinlock.h
@@ -0,0 +1,26 @@
+#ifndef _ASM_POWERPC_QSPINLOCK_H
+#define _ASM_POWERPC_QSPINLOCK_H
+
+#include 
+
+#define SPIN_THRESHOLD (1 << 15)
+#define queued_spin_unlock queued_spin_unlock
+
+static inline void native_queued_spin_unlock(struct qspinlock
*lock)
+{
+   u8 *locked = (u8 *)lock;
+#ifdef __BIG_ENDIAN
+   locked += 3;
+#endif
+   /* no load/store can be across the unlock()*/
+   smp_store_release(locked, 0);
+}
+
+static inline void queued_spin_unlock(struct qspinlock *lock)
+{
+   native_queued_spin_unlock(lock);
+}
+
+#include 
+
+#endif /* _ASM_POWERPC_QSPINLOCK_H */
diff --git a/arch/powerpc/include/asm/spinlock.h
b/arch/powerpc/include/asm/spinlock.h
index 523673d..4359ee6 100644
--- a/arch/powerpc/include/asm/spinlock.h
+++ b/arch/powerpc/include/asm/spinlock.h
@@ -52,6 +52,20 @@
  #define SYNC_IO
  #endif

+#if defined(CONFIG_PPC_SPLPAR)
+/* We only yield to the hypervisor if we are in shared processor
mode */
+#define SHARED_PROCESSOR (lppaca_shared_proc(local_paca-


lppaca_ptr))

+extern void __spin_yield(arch_spinlock_t *lock);
+extern void __rw_yield(arch_rwlock_t *lock);
+#else /* SPLPAR */
+#define __spin_yield(x)barrier()
+#define __rw_yield(x)  barrier()
+#define SHARED_PROCESSOR   0
+#endif
+
+#ifdef CONFIG_QUEUED_SPINLOCKS
+#include 
+#else
  static __always_inline int
arch_spin_value_unlocked(arch_spinlock_t
lock)
  {
return lock.slock == 0;
@@ -106,18 +120,6 @@ static inline int
arch_spin_trylock(arch_spinlock_t *lock)
   * held.  Conveniently, we have a word in the paca that holds this
   * value.
   */
-
-#if defined(CONFIG_PPC_SPLPAR)
-/* We only yield to the hypervisor if we are in shared processor
mode */
-#define SHARED_PROCESSOR (lppaca_shared_proc(local_paca-


lppaca_ptr))

-extern void __spin_yield(arch_spinlock_t *lock);
-extern void __rw_yield(arch_rwlock_t *lock);
-#else /* SPLPAR */
-#define __spin_yield(x)barrier()
-#define __rw_yield(x)  barrier()
-#define SHARED_PROCESSOR   0
-#endif
-
  static inline void arch_spin_lock(arch_spinlock_t *lock)
  {
CLEAR_IO_SYNC;
@@ -169,6 +171,7 @@ extern void
arch_spin_unlock_wait(arch_spinlock_t
*lock);
do { while (arch_spin_is_locked(lock)) cpu_relax(); }
while
(0)
  #endif

+#endif /* !CONFIG_QUEUED_SPINLOCKS */
  /*
   * Read-write spinlocks, allowing multiple readers
   * but only one writer.
diff --git a/arch/powerpc/include/asm/spinlock_types.h
b/arch/powerpc/include/asm/spinlock_types.h
index 2351adc..bd7144e 100644
--- a/arch/powerpc/include/asm/spinlock_types.h
+++ b/arch/powerpc/include/asm/spinlock_types.h
@@ -5,11 +5,15 @@
  # error "please don't include this file directly"
  #endif

+#ifdef CONFIG_QUEUED_SPINLOCKS
+#include 
+#else
  typedef struct {
volatile unsigned int slock;
  } arch_spinlock_t;

  #define __ARCH_SPIN_LOCK_UNLOCKED { 0 }
+#endif

  typedef struct {
volatile signed int lock;
diff --git a/arch/powerpc/lib/locks.c b/arch/powerpc/lib/locks.c
index f7deebd..a9ebd71 100644
--- a/arch/powerpc/lib/locks.c
+++ b/arch/powerpc/lib/locks.c
@@ -23,6 +23,7 @@
  #include 
  #include 

+#ifndef CONFIG_QUEUED_SPINLOCKS
  void __spin_yield(arch_spinlock_t *lock)
  {
unsigned int lock_value, holder_cpu, yield_count;
@@ -42,6 +43,7 @@ void __spin_yield(arch_spinlock_t *lock)
get_hard_smp_processor_id(holder_cpu),
yield_count);
  }
  EXPORT_SYMBOL_GPL(__spin_yield);
+#endif

  /*
   * Waiting for a read lock or a write lock on a rwlock...
@@ -69,6 +71,7 @@ void __rw_yield(arch_rwlock_t *rw)
  }
  #endif

+#ifndef CONFIG_QUEUED_SPINLOCKS
  void arch_spin_unlock_wait(arch_spinlock_t *lock)
  {
smp_mb();
@@ -84,3 +87,4 @@ void arch_spin_unlock_wait(arch_spinlock_t *lock)
  

Re: [PATCH v5 1/6] qspinlock: powerpc support qspinlock

2016-06-02 Thread xinhui


On 2016年06月03日 09:32, Benjamin Herrenschmidt wrote:

On Fri, 2016-06-03 at 11:32 +1000, Benjamin Herrenschmidt wrote:

On Thu, 2016-06-02 at 17:22 +0800, Pan Xinhui wrote:


Base code to enable qspinlock on powerpc. this patch add some
#ifdef
here and there. Although there is no paravirt related code, we can
successfully build a qspinlock kernel after apply this patch.

This is missing the IO_SYNC stuff ... It means we'll fail to do a
full
sync to order vs MMIOs.

You need to add that back in the unlock path.


Well, and in the lock path as well...


Oh, yes. I missed IO_SYNC stuff.

thank you, Ben :)


Cheers,
Ben.



Signed-off-by: Pan Xinhui 
---
  arch/powerpc/include/asm/qspinlock.h  | 26
++
  arch/powerpc/include/asm/spinlock.h   | 27 +++

  arch/powerpc/include/asm/spinlock_types.h |  4 
  arch/powerpc/lib/locks.c  |  4 
  4 files changed, 49 insertions(+), 12 deletions(-)
  create mode 100644 arch/powerpc/include/asm/qspinlock.h

diff --git a/arch/powerpc/include/asm/qspinlock.h
b/arch/powerpc/include/asm/qspinlock.h
new file mode 100644
index 000..fc83cd2
--- /dev/null
+++ b/arch/powerpc/include/asm/qspinlock.h
@@ -0,0 +1,26 @@
+#ifndef _ASM_POWERPC_QSPINLOCK_H
+#define _ASM_POWERPC_QSPINLOCK_H
+
+#include 
+
+#define SPIN_THRESHOLD (1 << 15)
+#define queued_spin_unlock queued_spin_unlock
+
+static inline void native_queued_spin_unlock(struct qspinlock
*lock)
+{
+   u8 *locked = (u8 *)lock;
+#ifdef __BIG_ENDIAN
+   locked += 3;
+#endif
+   /* no load/store can be across the unlock()*/
+   smp_store_release(locked, 0);
+}
+
+static inline void queued_spin_unlock(struct qspinlock *lock)
+{
+   native_queued_spin_unlock(lock);
+}
+
+#include 
+
+#endif /* _ASM_POWERPC_QSPINLOCK_H */
diff --git a/arch/powerpc/include/asm/spinlock.h
b/arch/powerpc/include/asm/spinlock.h
index 523673d..4359ee6 100644
--- a/arch/powerpc/include/asm/spinlock.h
+++ b/arch/powerpc/include/asm/spinlock.h
@@ -52,6 +52,20 @@
  #define SYNC_IO
  #endif

+#if defined(CONFIG_PPC_SPLPAR)
+/* We only yield to the hypervisor if we are in shared processor
mode */
+#define SHARED_PROCESSOR (lppaca_shared_proc(local_paca-


lppaca_ptr))

+extern void __spin_yield(arch_spinlock_t *lock);
+extern void __rw_yield(arch_rwlock_t *lock);
+#else /* SPLPAR */
+#define __spin_yield(x)barrier()
+#define __rw_yield(x)  barrier()
+#define SHARED_PROCESSOR   0
+#endif
+
+#ifdef CONFIG_QUEUED_SPINLOCKS
+#include 
+#else
  static __always_inline int
arch_spin_value_unlocked(arch_spinlock_t
lock)
  {
return lock.slock == 0;
@@ -106,18 +120,6 @@ static inline int
arch_spin_trylock(arch_spinlock_t *lock)
   * held.  Conveniently, we have a word in the paca that holds this
   * value.
   */
-
-#if defined(CONFIG_PPC_SPLPAR)
-/* We only yield to the hypervisor if we are in shared processor
mode */
-#define SHARED_PROCESSOR (lppaca_shared_proc(local_paca-


lppaca_ptr))

-extern void __spin_yield(arch_spinlock_t *lock);
-extern void __rw_yield(arch_rwlock_t *lock);
-#else /* SPLPAR */
-#define __spin_yield(x)barrier()
-#define __rw_yield(x)  barrier()
-#define SHARED_PROCESSOR   0
-#endif
-
  static inline void arch_spin_lock(arch_spinlock_t *lock)
  {
CLEAR_IO_SYNC;
@@ -169,6 +171,7 @@ extern void
arch_spin_unlock_wait(arch_spinlock_t
*lock);
do { while (arch_spin_is_locked(lock)) cpu_relax(); }
while
(0)
  #endif

+#endif /* !CONFIG_QUEUED_SPINLOCKS */
  /*
   * Read-write spinlocks, allowing multiple readers
   * but only one writer.
diff --git a/arch/powerpc/include/asm/spinlock_types.h
b/arch/powerpc/include/asm/spinlock_types.h
index 2351adc..bd7144e 100644
--- a/arch/powerpc/include/asm/spinlock_types.h
+++ b/arch/powerpc/include/asm/spinlock_types.h
@@ -5,11 +5,15 @@
  # error "please don't include this file directly"
  #endif

+#ifdef CONFIG_QUEUED_SPINLOCKS
+#include 
+#else
  typedef struct {
volatile unsigned int slock;
  } arch_spinlock_t;

  #define __ARCH_SPIN_LOCK_UNLOCKED { 0 }
+#endif

  typedef struct {
volatile signed int lock;
diff --git a/arch/powerpc/lib/locks.c b/arch/powerpc/lib/locks.c
index f7deebd..a9ebd71 100644
--- a/arch/powerpc/lib/locks.c
+++ b/arch/powerpc/lib/locks.c
@@ -23,6 +23,7 @@
  #include 
  #include 

+#ifndef CONFIG_QUEUED_SPINLOCKS
  void __spin_yield(arch_spinlock_t *lock)
  {
unsigned int lock_value, holder_cpu, yield_count;
@@ -42,6 +43,7 @@ void __spin_yield(arch_spinlock_t *lock)
get_hard_smp_processor_id(holder_cpu),
yield_count);
  }
  EXPORT_SYMBOL_GPL(__spin_yield);
+#endif

  /*
   * Waiting for a read lock or a write lock on a rwlock...
@@ -69,6 +71,7 @@ void __rw_yield(arch_rwlock_t *rw)
  }
  #endif

+#ifndef CONFIG_QUEUED_SPINLOCKS
  void arch_spin_unlock_wait(arch_spinlock_t *lock)
  {
smp_mb();
@@ -84,3 +87,4 @@ void arch_spin_unlock_wait(arch_spinlock_t *lock)
  }

  

Re: [PATCH 2/2] aer: add support aer interrupt with none MSI/MSI-X/INTx mode

2016-06-02 Thread Bjorn Helgaas
On Thu, Jun 02, 2016 at 11:37:28AM -0400, Murali Karicheri wrote:
> On 06/02/2016 09:55 AM, Bjorn Helgaas wrote:
> > On Thu, Jun 02, 2016 at 05:01:19AM +, Po Liu wrote:
> >>>  -Original Message-
> >>>  From: Bjorn Helgaas [mailto:helg...@kernel.org]
> >>>  Sent: Thursday, June 02, 2016 11:48 AM
> >>>  To: Po Liu
> >>>  Cc: linux-...@vger.kernel.org; linux-arm-ker...@lists.infradead.org;
> >>>  linux-kernel@vger.kernel.org; devicet...@vger.kernel.org; Arnd Bergmann;
> >>>  Roy Zang; Marc Zyngier; Stuart Yoder; Yang-Leo Li; Minghuan Lian; Bjorn
> >>>  Helgaas; Shawn Guo; Mingkai Hu; Rob Herring
> >>>  Subject: Re: [PATCH 2/2] aer: add support aer interrupt with none
> >>>  MSI/MSI-X/INTx mode
> >>>  
> >>>  [+cc Rob]
> >>>  
> >>>  Hi Po,
> >>>  
> >>>  On Thu, May 26, 2016 at 02:00:06PM +0800, Po Liu wrote:
> >>>  > On some platforms, root port doesn't support MSI/MSI-X/INTx in RC mode.
> >>>  > When chip support the aer interrupt with none MSI/MSI-X/INTx mode,
> >>>  > maybe there is interrupt line for aer pme etc. Search the interrupt
> >>>  > number in the fdt file.
> >>>  
> >>>  My understanding is that AER interrupt signaling can be done via INTx,
> >>>  MSI, or MSI-X (PCIe spec r3.0, sec 6.2.4.1.2).  Apparently your device
> >>>  doesn't support MSI or MSI-X.  Are you saying it doesn't support INTx
> >>>  either?  How is the interrupt you're requesting here different from INTx?
> >>
> >> Layerscape use none of MSI or MSI-X or INTx to indicate the devices
> >> or root error in RC mode. But use an independent SPI interrupt(arm
> >> interrupt controller) line.  
> > 
> > The Root Port is a PCI device and should follow the normal PCI rules
> > for interrupts.  As far as I understand, that means it should use MSI,
> > MSI-X, or INTx.  If your Root Port doesn't use MSI or MSI-X, it should
> > use INTx, the PCI_INTERRUPT_PIN register should tell us which (INTA/
> > INTB/etc.), and PCI_COMMAND_INTX_DISABLE should work to disable it.
> > That's all from the PCI point of view, of course.
> 
> I am faced with the same issue on Keystone PCI hardware and it has been
> on my TODO list  for quite some time. Keystone PCI hardware also doesn't
> use MSI or MSI-X or INTx for reporting errors received at the root port,
> but use a platform interrupt instead (not complaint to PCI standard as
> per PCI base spec). So I would need similar change to have the error
> interrupt passed to the aer driver. So there are hardware out there
> like Keystone which requires to support this through platform IRQ.

This is not a new area of the spec, and it's hard for me to believe
that these two new PCIe controllers are both broken the same way
(although I guess both are DesignWare-based, so maybe this is the same
underlying problem in both cases?).  I think it's more likely that we
just haven't figured out the right way to describe this in the DT.

I assume you have a Root Port with an AER capability, no MSI
capability, and no MSI-X capability, right?  What does its Interrupt
Pin register contain?  If it's zero, it doesn't use INTx either, so
according to the spec it should generate no interrupts.

But if Interrupt Pin is non-zero, that means the Root Port should be
able to generate virtual INTx interrupts.  Presumably the Root Complex
connects those interrupts to something; maybe to your platform
interrupt?

PCI doesn't say anything about an interrupt after it leaves the Root
Complex, so the fact that it's connected to a "platform interrupt" or
"SPI interrupt" or "IOAPIC interrupt" doesn't make it non-compliant.
Shouldn't we be able to use the interrupt-map and related DT
properties to express the fact that Root Port virtual INTx is routed
to platform interrupt Y, even without any special-case code in
portdrv?

> > What's on the other end of those interrupts is outside the scope of
> > PCI.  An INTx interrupt (either a conventional PCI wire or a PCIe
> > virtual INTx wire) might be connected to an IOAPIC, an ARM SPI, or
> > something else.  Drivers should not care about how it is connected,
> > and that's why I don't think this code really fits in portdrv.
> > 
> > Maybe your Root Port is non-compliant in some way and maybe we need a
> > quirk or something to work around that hardware defect.  But I'm not
> > convinced yet that we have that sort of problem.  It seems like we
> > just don't have the correct DT description.
> 
> Is quirk is what is suggested here to support this?

No, I don't understand the problem yet, so I'm not ready to suggest a
solution.

> >> And at same time, AER capability list
> >> in PCIe register descriptors. And also, The Root Error
> >> Command/status register was proper to enable/disable the AER
> >> interrupt.
> > 
> > I'm not sure what you're saying here.  Here's what I think you said;
> > please correct me if I'm wrong:
> > 
> >   - Your Root Port has an AER capability.
> > 
> >   - Your Root Port does not support MSI or MSI-X.  (This would
> > actually be a spec violation because the 

Re: [PATCH 2/2] aer: add support aer interrupt with none MSI/MSI-X/INTx mode

2016-06-02 Thread Bjorn Helgaas
On Thu, Jun 02, 2016 at 11:37:28AM -0400, Murali Karicheri wrote:
> On 06/02/2016 09:55 AM, Bjorn Helgaas wrote:
> > On Thu, Jun 02, 2016 at 05:01:19AM +, Po Liu wrote:
> >>>  -Original Message-
> >>>  From: Bjorn Helgaas [mailto:helg...@kernel.org]
> >>>  Sent: Thursday, June 02, 2016 11:48 AM
> >>>  To: Po Liu
> >>>  Cc: linux-...@vger.kernel.org; linux-arm-ker...@lists.infradead.org;
> >>>  linux-kernel@vger.kernel.org; devicet...@vger.kernel.org; Arnd Bergmann;
> >>>  Roy Zang; Marc Zyngier; Stuart Yoder; Yang-Leo Li; Minghuan Lian; Bjorn
> >>>  Helgaas; Shawn Guo; Mingkai Hu; Rob Herring
> >>>  Subject: Re: [PATCH 2/2] aer: add support aer interrupt with none
> >>>  MSI/MSI-X/INTx mode
> >>>  
> >>>  [+cc Rob]
> >>>  
> >>>  Hi Po,
> >>>  
> >>>  On Thu, May 26, 2016 at 02:00:06PM +0800, Po Liu wrote:
> >>>  > On some platforms, root port doesn't support MSI/MSI-X/INTx in RC mode.
> >>>  > When chip support the aer interrupt with none MSI/MSI-X/INTx mode,
> >>>  > maybe there is interrupt line for aer pme etc. Search the interrupt
> >>>  > number in the fdt file.
> >>>  
> >>>  My understanding is that AER interrupt signaling can be done via INTx,
> >>>  MSI, or MSI-X (PCIe spec r3.0, sec 6.2.4.1.2).  Apparently your device
> >>>  doesn't support MSI or MSI-X.  Are you saying it doesn't support INTx
> >>>  either?  How is the interrupt you're requesting here different from INTx?
> >>
> >> Layerscape use none of MSI or MSI-X or INTx to indicate the devices
> >> or root error in RC mode. But use an independent SPI interrupt(arm
> >> interrupt controller) line.  
> > 
> > The Root Port is a PCI device and should follow the normal PCI rules
> > for interrupts.  As far as I understand, that means it should use MSI,
> > MSI-X, or INTx.  If your Root Port doesn't use MSI or MSI-X, it should
> > use INTx, the PCI_INTERRUPT_PIN register should tell us which (INTA/
> > INTB/etc.), and PCI_COMMAND_INTX_DISABLE should work to disable it.
> > That's all from the PCI point of view, of course.
> 
> I am faced with the same issue on Keystone PCI hardware and it has been
> on my TODO list  for quite some time. Keystone PCI hardware also doesn't
> use MSI or MSI-X or INTx for reporting errors received at the root port,
> but use a platform interrupt instead (not complaint to PCI standard as
> per PCI base spec). So I would need similar change to have the error
> interrupt passed to the aer driver. So there are hardware out there
> like Keystone which requires to support this through platform IRQ.

This is not a new area of the spec, and it's hard for me to believe
that these two new PCIe controllers are both broken the same way
(although I guess both are DesignWare-based, so maybe this is the same
underlying problem in both cases?).  I think it's more likely that we
just haven't figured out the right way to describe this in the DT.

I assume you have a Root Port with an AER capability, no MSI
capability, and no MSI-X capability, right?  What does its Interrupt
Pin register contain?  If it's zero, it doesn't use INTx either, so
according to the spec it should generate no interrupts.

But if Interrupt Pin is non-zero, that means the Root Port should be
able to generate virtual INTx interrupts.  Presumably the Root Complex
connects those interrupts to something; maybe to your platform
interrupt?

PCI doesn't say anything about an interrupt after it leaves the Root
Complex, so the fact that it's connected to a "platform interrupt" or
"SPI interrupt" or "IOAPIC interrupt" doesn't make it non-compliant.
Shouldn't we be able to use the interrupt-map and related DT
properties to express the fact that Root Port virtual INTx is routed
to platform interrupt Y, even without any special-case code in
portdrv?

> > What's on the other end of those interrupts is outside the scope of
> > PCI.  An INTx interrupt (either a conventional PCI wire or a PCIe
> > virtual INTx wire) might be connected to an IOAPIC, an ARM SPI, or
> > something else.  Drivers should not care about how it is connected,
> > and that's why I don't think this code really fits in portdrv.
> > 
> > Maybe your Root Port is non-compliant in some way and maybe we need a
> > quirk or something to work around that hardware defect.  But I'm not
> > convinced yet that we have that sort of problem.  It seems like we
> > just don't have the correct DT description.
> 
> Is quirk is what is suggested here to support this?

No, I don't understand the problem yet, so I'm not ready to suggest a
solution.

> >> And at same time, AER capability list
> >> in PCIe register descriptors. And also, The Root Error
> >> Command/status register was proper to enable/disable the AER
> >> interrupt.
> > 
> > I'm not sure what you're saying here.  Here's what I think you said;
> > please correct me if I'm wrong:
> > 
> >   - Your Root Port has an AER capability.
> > 
> >   - Your Root Port does not support MSI or MSI-X.  (This would
> > actually be a spec violation because the 

  1   2   3   4   5   6   7   8   9   10   >