Re: [PATCH v7 00/24] i2c mux cleanup and locking update

2016-04-20 Thread Antti Palosaari

On 04/20/2016 06:17 PM, Peter Rosin wrote:

Retested all the previously tested + now I tested also cx231xx with 
Hauppauge 930C HD device having eeprom other mux port and demod on the 
other port.



   [media] si2168: change the i2c gate to be mux-locked
   [media] m88ds3103: convert to use an explicit i2c mux core
   [media] rtl2830: convert to use an explicit i2c mux core
   [media] rtl2832: convert to use an explicit i2c mux core
   [media] si2168: convert to use an explicit i2c mux core
   [media] cx231xx: convert to use an explicit i2c mux core
   [media] rtl2832: change the i2c gate to be mux-locked
   [media] rtl2832_sdr: get rid of empty regmap wrappers
   [media] rtl2832: regmap is aware of lockdep, drop local locking hack


I really hope that this whole patch series will arrive asap to mainline.

regards
Antti

--
http://palosaari.fi/
--
To unsubscribe from this list: send the line "unsubscribe linux-doc" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH v5 0/6] LSM: LoadPin for kernel file loading restrictions

2016-04-20 Thread James Morris
On Wed, 20 Apr 2016, Kees Cook wrote:

> This provides the mini-LSM "loadpin" that intercepts the now consolidated
> kernel_file_read LSM hook so that a system can keep all loads coming from
> a single trusted filesystem. This is what Chrome OS uses to pin kernel
> module and firmware loading to the read-only crypto-verified dm-verity
> partition so that kernel module signing is not needed.
> 

Applied to
git://git.kernel.org/pub/scm/linux/kernel/git/jmorris/linux-security.git next


-- 
James Morris


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


[PATCH 3/6] string_helpers: add kstrdup_quotable_file

2016-04-20 Thread Kees Cook
Allocate a NULL-terminated file path with special characters escaped,
safe for logging.

Signed-off-by: Kees Cook 
---
 include/linux/string_helpers.h |  3 +++
 lib/string_helpers.c   | 30 ++
 2 files changed, 33 insertions(+)

diff --git a/include/linux/string_helpers.h b/include/linux/string_helpers.h
index 684d2695fc36..5ce9538f290e 100644
--- a/include/linux/string_helpers.h
+++ b/include/linux/string_helpers.h
@@ -3,6 +3,8 @@
 
 #include 
 
+struct file;
+
 /* Descriptions of the types of units to
  * print in */
 enum string_size_units {
@@ -70,5 +72,6 @@ static inline int string_escape_str_any_np(const char *src, 
char *dst,
 
 char *kstrdup_quotable(const char *src, gfp_t gfp);
 char *kstrdup_quotable_cmdline(struct task_struct *task, gfp_t gfp);
+char *kstrdup_quotable_file(struct file *file, gfp_t gfp);
 
 #endif
diff --git a/lib/string_helpers.c b/lib/string_helpers.c
index b16ee85aaf87..ecaac2c0526f 100644
--- a/lib/string_helpers.c
+++ b/lib/string_helpers.c
@@ -10,6 +10,8 @@
 #include 
 #include 
 #include 
+#include 
+#include 
 #include 
 #include 
 #include 
@@ -596,3 +598,31 @@ char *kstrdup_quotable_cmdline(struct task_struct *task, 
gfp_t gfp)
return quoted;
 }
 EXPORT_SYMBOL_GPL(kstrdup_quotable_cmdline);
+
+/*
+ * Returns allocated NULL-terminated string containing pathname,
+ * with special characters escaped, able to be safely logged. If
+ * there is an error, the leading character will be "<".
+ */
+char *kstrdup_quotable_file(struct file *file, gfp_t gfp)
+{
+   char *temp, *pathname;
+
+   if (!file)
+   return kstrdup("", gfp);
+
+   /* We add 11 spaces for ' (deleted)' to be appended */
+   temp = kmalloc(PATH_MAX + 11, GFP_TEMPORARY);
+   if (!temp)
+   return kstrdup("", gfp);
+
+   pathname = file_path(file, temp, PATH_MAX + 11);
+   if (IS_ERR(pathname))
+   pathname = kstrdup("", gfp);
+   else
+   pathname = kstrdup_quotable(pathname, gfp);
+
+   kfree(temp);
+   return pathname;
+}
+EXPORT_SYMBOL_GPL(kstrdup_quotable_file);
-- 
2.6.3

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


[PATCH 5/6] fs: define a string representation of the kernel_read_file_id enumeration

2016-04-20 Thread Kees Cook
From: Mimi Zohar 

A string representation of the kernel_read_file_id enumeration is
needed for displaying messages (eg. pr_info, auditing) that can be
used by multiple LSMs and the integrity subsystem.  To simplify
keeping the list of strings up to date with the enumeration, this
patch defines two new preprocessing macros named __fid_enumify and
__fid_stringify to create the enumeration and an array of strings.
kernel_read_file_id_str() returns a string based on the enumeration.

Signed-off-by: Mimi Zohar 
[kees: removed removal of my old version, constified pointer values]
Signed-off-by: Kees Cook 
---
 include/linux/fs.h | 31 +--
 1 file changed, 25 insertions(+), 6 deletions(-)

diff --git a/include/linux/fs.h b/include/linux/fs.h
index 70e61b58baaf..518716b4834e 100644
--- a/include/linux/fs.h
+++ b/include/linux/fs.h
@@ -2590,15 +2590,34 @@ static inline void i_readcount_inc(struct inode *inode)
 #endif
 extern int do_pipe_flags(int *, int);
 
+#define __kernel_read_file_id(id) \
+   id(UNKNOWN, unknown)\
+   id(FIRMWARE, firmware)  \
+   id(MODULE, kernel-module)   \
+   id(KEXEC_IMAGE, kexec-image)\
+   id(KEXEC_INITRAMFS, kexec-initramfs)\
+   id(POLICY, security-policy) \
+   id(MAX_ID, )
+
+#define __fid_enumify(ENUM, dummy) READING_ ## ENUM,
+#define __fid_stringify(dummy, str) #str,
+
 enum kernel_read_file_id {
-   READING_FIRMWARE = 1,
-   READING_MODULE,
-   READING_KEXEC_IMAGE,
-   READING_KEXEC_INITRAMFS,
-   READING_POLICY,
-   READING_MAX_ID
+   __kernel_read_file_id(__fid_enumify)
+};
+
+static const char * const kernel_read_file_str[] = {
+   __kernel_read_file_id(__fid_stringify)
 };
 
+static inline const char * const kernel_read_file_id_str(enum 
kernel_read_file_id id)
+{
+   if (id < 0 || id >= READING_MAX_ID)
+   return kernel_read_file_str[READING_UNKNOWN];
+
+   return kernel_read_file_str[id];
+}
+
 extern int kernel_read(struct file *, loff_t, char *, unsigned long);
 extern int kernel_read_file(struct file *, void **, loff_t *, loff_t,
enum kernel_read_file_id);
-- 
2.6.3

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


[PATCH 6/6] LSM: LoadPin for kernel file loading restrictions

2016-04-20 Thread Kees Cook
This LSM enforces that kernel-loaded files (modules, firmware, etc)
must all come from the same filesystem, with the expectation that
such a filesystem is backed by a read-only device such as dm-verity
or CDROM. This allows systems that have a verified and/or unchangeable
filesystem to enforce module and firmware loading restrictions without
needing to sign the files individually.

Signed-off-by: Kees Cook 
Acked-by: Serge Hallyn 
---
 Documentation/security/LoadPin.txt |  17 
 MAINTAINERS|   6 ++
 include/linux/lsm_hooks.h  |   5 +
 security/Kconfig   |   1 +
 security/Makefile  |   2 +
 security/loadpin/Kconfig   |  10 ++
 security/loadpin/Makefile  |   1 +
 security/loadpin/loadpin.c | 190 +
 security/security.c|   1 +
 9 files changed, 233 insertions(+)
 create mode 100644 Documentation/security/LoadPin.txt
 create mode 100644 security/loadpin/Kconfig
 create mode 100644 security/loadpin/Makefile
 create mode 100644 security/loadpin/loadpin.c

diff --git a/Documentation/security/LoadPin.txt 
b/Documentation/security/LoadPin.txt
new file mode 100644
index ..e11877f5d3d4
--- /dev/null
+++ b/Documentation/security/LoadPin.txt
@@ -0,0 +1,17 @@
+LoadPin is a Linux Security Module that ensures all kernel-loaded files
+(modules, firmware, etc) all originate from the same filesystem, with
+the expectation that such a filesystem is backed by a read-only device
+such as dm-verity or CDROM. This allows systems that have a verified
+and/or unchangeable filesystem to enforce module and firmware loading
+restrictions without needing to sign the files individually.
+
+The LSM is selectable at build-time with CONFIG_SECURITY_LOADPIN, and
+can be controlled at boot-time with the kernel command line option
+"loadpin.enabled". By default, it is enabled, but can be disabled at
+boot ("loadpin.enabled=0").
+
+LoadPin starts pinning when it sees the first file loaded. If the
+block device backing the filesystem is not read-only, a sysctl is
+created to toggle pinning: /proc/sys/kernel/loadpin/enabled. (Having
+a mutable filesystem means pinning is mutable too, but having the
+sysctl allows for easy testing on systems with a mutable filesystem.)
diff --git a/MAINTAINERS b/MAINTAINERS
index 1d5b4becab6f..6042f6318c8f 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -9971,6 +9971,12 @@ T:   git 
git://git.kernel.org/pub/scm/linux/kernel/git/jj/apparmor-dev.git
 S: Supported
 F: security/apparmor/
 
+LOADPIN SECURITY MODULE
+M: Kees Cook 
+T: git git://git.kernel.org/pub/scm/linux/kernel/git/kees/linux.git 
lsm/loadpin
+S: Supported
+F: security/loadpin/
+
 YAMA SECURITY MODULE
 M: Kees Cook 
 T: git git://git.kernel.org/pub/scm/linux/kernel/git/kees/linux.git 
yama/tip
diff --git a/include/linux/lsm_hooks.h b/include/linux/lsm_hooks.h
index cdee11cbcdf1..f3402aab1927 100644
--- a/include/linux/lsm_hooks.h
+++ b/include/linux/lsm_hooks.h
@@ -1893,5 +1893,10 @@ extern void __init yama_add_hooks(void);
 #else
 static inline void __init yama_add_hooks(void) { }
 #endif
+#ifdef CONFIG_SECURITY_LOADPIN
+void __init loadpin_add_hooks(void);
+#else
+static inline void loadpin_add_hooks(void) { };
+#endif
 
 #endif /* ! __LINUX_LSM_HOOKS_H */
diff --git a/security/Kconfig b/security/Kconfig
index e45237897b43..176758cdfa57 100644
--- a/security/Kconfig
+++ b/security/Kconfig
@@ -122,6 +122,7 @@ source security/selinux/Kconfig
 source security/smack/Kconfig
 source security/tomoyo/Kconfig
 source security/apparmor/Kconfig
+source security/loadpin/Kconfig
 source security/yama/Kconfig
 
 source security/integrity/Kconfig
diff --git a/security/Makefile b/security/Makefile
index c9bfbc84ff50..f2d71cdb8e19 100644
--- a/security/Makefile
+++ b/security/Makefile
@@ -8,6 +8,7 @@ subdir-$(CONFIG_SECURITY_SMACK) += smack
 subdir-$(CONFIG_SECURITY_TOMOYO)+= tomoyo
 subdir-$(CONFIG_SECURITY_APPARMOR) += apparmor
 subdir-$(CONFIG_SECURITY_YAMA) += yama
+subdir-$(CONFIG_SECURITY_LOADPIN)  += loadpin
 
 # always enable default capabilities
 obj-y  += commoncap.o
@@ -22,6 +23,7 @@ obj-$(CONFIG_AUDIT)   += lsm_audit.o
 obj-$(CONFIG_SECURITY_TOMOYO)  += tomoyo/
 obj-$(CONFIG_SECURITY_APPARMOR)+= apparmor/
 obj-$(CONFIG_SECURITY_YAMA)+= yama/
+obj-$(CONFIG_SECURITY_LOADPIN) += loadpin/
 obj-$(CONFIG_CGROUP_DEVICE)+= device_cgroup.o
 
 # Object integrity file lists
diff --git a/security/loadpin/Kconfig b/security/loadpin/Kconfig
new file mode 100644
index ..c668ac4eda65
--- /dev/null
+++ b/security/loadpin/Kconfig
@@ -0,0 +1,10 @@
+config SECURITY_LOADPIN
+   bool "Pin load of kernel files (modules, fw, etc) to one 

[PATCH 2/6] string_helpers: add kstrdup_quotable_cmdline

2016-04-20 Thread Kees Cook
Provide an escaped (but readable: no inter-argument NULLs) commandline
safe for logging.

Signed-off-by: Kees Cook 
---
 include/linux/string_helpers.h |  1 +
 lib/string_helpers.c   | 34 ++
 2 files changed, 35 insertions(+)

diff --git a/include/linux/string_helpers.h b/include/linux/string_helpers.h
index 9de228af00c1..684d2695fc36 100644
--- a/include/linux/string_helpers.h
+++ b/include/linux/string_helpers.h
@@ -69,5 +69,6 @@ static inline int string_escape_str_any_np(const char *src, 
char *dst,
 }
 
 char *kstrdup_quotable(const char *src, gfp_t gfp);
+char *kstrdup_quotable_cmdline(struct task_struct *task, gfp_t gfp);
 
 #endif
diff --git a/lib/string_helpers.c b/lib/string_helpers.c
index aa00c9f989ee..b16ee85aaf87 100644
--- a/lib/string_helpers.c
+++ b/lib/string_helpers.c
@@ -10,6 +10,7 @@
 #include 
 #include 
 #include 
+#include 
 #include 
 #include 
 #include 
@@ -562,3 +563,36 @@ char *kstrdup_quotable(const char *src, gfp_t gfp)
return dst;
 }
 EXPORT_SYMBOL_GPL(kstrdup_quotable);
+
+/*
+ * Returns allocated NULL-terminated string containing process
+ * command line, with inter-argument NULLs replaced with spaces,
+ * and other special characters escaped.
+ */
+char *kstrdup_quotable_cmdline(struct task_struct *task, gfp_t gfp)
+{
+   char *buffer, *quoted;
+   int i, res;
+
+   buffer = kmalloc(PAGE_SIZE, GFP_TEMPORARY);
+   if (!buffer)
+   return NULL;
+
+   res = get_cmdline(task, buffer, PAGE_SIZE - 1);
+   buffer[res] = '\0';
+
+   /* Collapse trailing NULLs, leave res pointing to last non-NULL. */
+   while (--res >= 0 && buffer[res] == '\0')
+   ;
+
+   /* Replace inter-argument NULLs. */
+   for (i = 0; i <= res; i++)
+   if (buffer[i] == '\0')
+   buffer[i] = ' ';
+
+   /* Make sure result is printable. */
+   quoted = kstrdup_quotable(buffer, gfp);
+   kfree(buffer);
+   return quoted;
+}
+EXPORT_SYMBOL_GPL(kstrdup_quotable_cmdline);
-- 
2.6.3

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


[PATCH v5 0/6] LSM: LoadPin for kernel file loading restrictions

2016-04-20 Thread Kees Cook
This provides the mini-LSM "loadpin" that intercepts the now consolidated
kernel_file_read LSM hook so that a system can keep all loads coming from
a single trusted filesystem. This is what Chrome OS uses to pin kernel
module and firmware loading to the read-only crypto-verified dm-verity
partition so that kernel module signing is not needed.

-Kees

v5:
- replace enum-to-str code, mimi
v4:
- add missing "const" to char * src, joe
v3:
- changed module parameter to "loadpin.enabled"
- add sysctl docs, akpm
- add general use function for enum, zohar
- add gfp_t, joe
- clean up loops, andriy.shevchenko
- reduce BUG_ON to WARN_ON, joe
v2:
- break out utility helpers into separate functions
- have Yama use new helpers too

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


[PATCH 1/6] string_helpers: add kstrdup_quotable

2016-04-20 Thread Kees Cook
Handle allocating and escaping a string safe for logging.

Signed-off-by: Kees Cook 
---
 include/linux/string_helpers.h |  2 ++
 lib/string_helpers.c   | 28 
 2 files changed, 30 insertions(+)

diff --git a/include/linux/string_helpers.h b/include/linux/string_helpers.h
index dabe643eb5fa..9de228af00c1 100644
--- a/include/linux/string_helpers.h
+++ b/include/linux/string_helpers.h
@@ -68,4 +68,6 @@ static inline int string_escape_str_any_np(const char *src, 
char *dst,
return string_escape_str(src, dst, sz, ESCAPE_ANY_NP, only);
 }
 
+char *kstrdup_quotable(const char *src, gfp_t gfp);
+
 #endif
diff --git a/lib/string_helpers.c b/lib/string_helpers.c
index 5c88204b6f1f..aa00c9f989ee 100644
--- a/lib/string_helpers.c
+++ b/lib/string_helpers.c
@@ -10,6 +10,7 @@
 #include 
 #include 
 #include 
+#include 
 #include 
 #include 
 
@@ -534,3 +535,30 @@ int string_escape_mem(const char *src, size_t isz, char 
*dst, size_t osz,
return p - dst;
 }
 EXPORT_SYMBOL(string_escape_mem);
+
+/*
+ * Return an allocated string that has been escaped of special characters
+ * and double quotes, making it safe to log in quotes.
+ */
+char *kstrdup_quotable(const char *src, gfp_t gfp)
+{
+   size_t slen, dlen;
+   char *dst;
+   const int flags = ESCAPE_HEX;
+   const char esc[] = "\f\n\r\t\v\a\e\\\"";
+
+   if (!src)
+   return NULL;
+   slen = strlen(src);
+
+   dlen = string_escape_mem(src, slen, NULL, 0, flags, esc);
+   dst = kmalloc(dlen + 1, gfp);
+   if (!dst)
+   return NULL;
+
+   WARN_ON(string_escape_mem(src, slen, dst, dlen, flags, esc) != dlen);
+   dst[dlen] = '\0';
+
+   return dst;
+}
+EXPORT_SYMBOL_GPL(kstrdup_quotable);
-- 
2.6.3

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


[PATCH 4/6] Yama: consolidate error reporting

2016-04-20 Thread Kees Cook
Use a common error reporting function for Yama violation reports, and give
more detail into the process command lines.

Signed-off-by: Kees Cook 
---
 security/yama/yama_lsm.c | 31 +--
 1 file changed, 21 insertions(+), 10 deletions(-)

diff --git a/security/yama/yama_lsm.c b/security/yama/yama_lsm.c
index cb6ed10816d4..c19f6e5df9a3 100644
--- a/security/yama/yama_lsm.c
+++ b/security/yama/yama_lsm.c
@@ -18,6 +18,7 @@
 #include 
 #include 
 #include 
+#include 
 
 #define YAMA_SCOPE_DISABLED0
 #define YAMA_SCOPE_RELATIONAL  1
@@ -41,6 +42,22 @@ static DEFINE_SPINLOCK(ptracer_relations_lock);
 static void yama_relation_cleanup(struct work_struct *work);
 static DECLARE_WORK(yama_relation_work, yama_relation_cleanup);
 
+static void report_access(const char *access, struct task_struct *target,
+ struct task_struct *agent)
+{
+   char *target_cmd, *agent_cmd;
+
+   target_cmd = kstrdup_quotable_cmdline(target, GFP_KERNEL);
+   agent_cmd = kstrdup_quotable_cmdline(agent, GFP_KERNEL);
+
+   pr_notice_ratelimited(
+   "ptrace %s of \"%s\"[%d] was attempted by \"%s\"[%d]\n",
+   access, target_cmd, target->pid, agent_cmd, agent->pid);
+
+   kfree(agent_cmd);
+   kfree(target_cmd);
+}
+
 /**
  * yama_relation_cleanup - remove invalid entries from the relation list
  *
@@ -307,11 +324,8 @@ static int yama_ptrace_access_check(struct task_struct 
*child,
}
}
 
-   if (rc && (mode & PTRACE_MODE_NOAUDIT) == 0) {
-   printk_ratelimited(KERN_NOTICE
-   "ptrace of pid %d was attempted by: %s (pid %d)\n",
-   child->pid, current->comm, current->pid);
-   }
+   if (rc && (mode & PTRACE_MODE_NOAUDIT) == 0)
+   report_access("attach", child, current);
 
return rc;
 }
@@ -337,11 +351,8 @@ int yama_ptrace_traceme(struct task_struct *parent)
break;
}
 
-   if (rc) {
-   printk_ratelimited(KERN_NOTICE
-   "ptraceme of pid %d was attempted by: %s (pid %d)\n",
-   current->pid, parent->comm, parent->pid);
-   }
+   if (rc)
+   report_access("traceme", current, parent);
 
return rc;
 }
-- 
2.6.3

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


Re: [PATCH 0/2] memory_hotplug: introduce config and command line options to set the default onlining policy

2016-04-20 Thread David Rientjes
On Tue, 19 Apr 2016, Vitaly Kuznetsov wrote:

> > I'd personally disagree that we need more and more config options to take 
> > care of something that an initscript can easily do and most distros 
> > already have their own initscripts that this can be added to.  I don't see 
> > anything that the config option adds.
> 
> Yes, but why does every distro need to solve the exact same issue by 
> a distro-specific init script when we can allow setting reasonable
> default in kernel?
> 

No, only distros that want to change the long-standing default which is 
"offline" since they apparently aren't worried about breaking existing 
userspace.

Changing defaults is always risky business in the kernel, especially when 
it's long standing.  If the default behavior is changeable, userspace 
needs to start testing for that and acting accordingly if it actually 
wants to default to offline (and there are existing tools that suppose the 
long-standing default).  The end result is that the kernel default doesn't 
matter anymore, we've just pushed it to userspace to either online or 
offline at the time of hotplug.

> If the config option itself is a problem (though I don't understand why)
> we can get rid of it making the default 'online' and keeping the command
> line parameter to disable it for cases when something goes wrong but why
> not leave an option for those who want it the other way around?
> 

That could break existing userspace that assumes the default is offline; 
if users are currently hotadding memory and then onlining it when needed 
rather than immediately, they break.  So that's not a possibility.

> Other than the above, let's imagine a 'unikernel' scenario when there
> are no initscripts and we're in a virtualized environment. We may want to
> have memory hotplug there too, but where would we put the 'onlining'
> logic? In every userspace we want to run? This doesn't sound right.
> 

Nobody is resisting hotplug notifiers.
--
To unsubscribe from this list: send the line "unsubscribe linux-doc" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH v7 00/24] i2c mux cleanup and locking update

2016-04-20 Thread Wolfram Sang

This was the diff of v6:

>  32 files changed, 1277 insertions(+), 915 deletions(-)

This is v7:

>  32 files changed, 1225 insertions(+), 916 deletions(-)

So, we gained a little overall. And while the individual drivers have a
few lines more now, I still think it is more readable.

So, thanks for doing that!

I'll give people some time for testing. I'll have a further look, too.
Hopefully, I can pick up patches 1-14 by the end of the week.

   Wolfram



signature.asc
Description: PGP signature


Re: [PATCH] Documentation: cgroup: "unshare -C" to unshare cgroup namespace

2016-04-20 Thread Tejun Heo
On Thu, Apr 14, 2016 at 11:18:31PM +0200, Josef Lusticky wrote:
> Use "unshare -C" to be consistent with the unshare utility from util-linux
> 
> Signed-off-by: Josef Lusticky 

Applied to cgroup/for-4.6-ns.

Thanks.

-- 
tejun
--
To unsubscribe from this list: send the line "unsubscribe linux-doc" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH v7 03/24] i2c: i2c-mux-pinctrl: convert to use an explicit i2c mux core

2016-04-20 Thread Peter Rosin
Allocate an explicit i2c mux core to handle parent and child adapters
etc. Update the select/deselect ops to be in terms of the i2c mux core
instead of the child adapter.

Signed-off-by: Peter Rosin 
---
 drivers/i2c/muxes/i2c-mux-pinctrl.c | 83 ++---
 1 file changed, 30 insertions(+), 53 deletions(-)

diff --git a/drivers/i2c/muxes/i2c-mux-pinctrl.c 
b/drivers/i2c/muxes/i2c-mux-pinctrl.c
index b5a982ba8898..1b8dc711815e 100644
--- a/drivers/i2c/muxes/i2c-mux-pinctrl.c
+++ b/drivers/i2c/muxes/i2c-mux-pinctrl.c
@@ -26,34 +26,29 @@
 #include 
 
 struct i2c_mux_pinctrl {
-   struct device *dev;
struct i2c_mux_pinctrl_platform_data *pdata;
struct pinctrl *pinctrl;
struct pinctrl_state **states;
struct pinctrl_state *state_idle;
-   struct i2c_adapter *parent;
-   struct i2c_adapter **busses;
 };
 
-static int i2c_mux_pinctrl_select(struct i2c_adapter *adap, void *data,
- u32 chan)
+static int i2c_mux_pinctrl_select(struct i2c_mux_core *muxc, u32 chan)
 {
-   struct i2c_mux_pinctrl *mux = data;
+   struct i2c_mux_pinctrl *mux = i2c_mux_priv(muxc);
 
return pinctrl_select_state(mux->pinctrl, mux->states[chan]);
 }
 
-static int i2c_mux_pinctrl_deselect(struct i2c_adapter *adap, void *data,
-   u32 chan)
+static int i2c_mux_pinctrl_deselect(struct i2c_mux_core *muxc, u32 chan)
 {
-   struct i2c_mux_pinctrl *mux = data;
+   struct i2c_mux_pinctrl *mux = i2c_mux_priv(muxc);
 
return pinctrl_select_state(mux->pinctrl, mux->state_idle);
 }
 
 #ifdef CONFIG_OF
 static int i2c_mux_pinctrl_parse_dt(struct i2c_mux_pinctrl *mux,
-   struct platform_device *pdev)
+   struct platform_device *pdev)
 {
struct device_node *np = pdev->dev.of_node;
int num_names, i, ret;
@@ -64,15 +59,12 @@ static int i2c_mux_pinctrl_parse_dt(struct i2c_mux_pinctrl 
*mux,
return 0;
 
mux->pdata = devm_kzalloc(>dev, sizeof(*mux->pdata), GFP_KERNEL);
-   if (!mux->pdata) {
-   dev_err(mux->dev,
-   "Cannot allocate i2c_mux_pinctrl_platform_data\n");
+   if (!mux->pdata)
return -ENOMEM;
-   }
 
num_names = of_property_count_strings(np, "pinctrl-names");
if (num_names < 0) {
-   dev_err(mux->dev, "Cannot parse pinctrl-names: %d\n",
+   dev_err(>dev, "Cannot parse pinctrl-names: %d\n",
num_names);
return num_names;
}
@@ -80,23 +72,22 @@ static int i2c_mux_pinctrl_parse_dt(struct i2c_mux_pinctrl 
*mux,
mux->pdata->pinctrl_states = devm_kzalloc(>dev,
sizeof(*mux->pdata->pinctrl_states) * num_names,
GFP_KERNEL);
-   if (!mux->pdata->pinctrl_states) {
-   dev_err(mux->dev, "Cannot allocate pinctrl_states\n");
+   if (!mux->pdata->pinctrl_states)
return -ENOMEM;
-   }
 
for (i = 0; i < num_names; i++) {
ret = of_property_read_string_index(np, "pinctrl-names", i,
>pdata->pinctrl_states[mux->pdata->bus_count]);
if (ret < 0) {
-   dev_err(mux->dev, "Cannot parse pinctrl-names: %d\n",
+   dev_err(>dev, "Cannot parse pinctrl-names: %d\n",
ret);
return ret;
}
if (!strcmp(mux->pdata->pinctrl_states[mux->pdata->bus_count],
"idle")) {
if (i != num_names - 1) {
-   dev_err(mux->dev, "idle state must be last\n");
+   dev_err(>dev,
+   "idle state must be last\n");
return -EINVAL;
}
mux->pdata->pinctrl_state_idle = "idle";
@@ -107,13 +98,13 @@ static int i2c_mux_pinctrl_parse_dt(struct i2c_mux_pinctrl 
*mux,
 
adapter_np = of_parse_phandle(np, "i2c-parent", 0);
if (!adapter_np) {
-   dev_err(mux->dev, "Cannot parse i2c-parent\n");
+   dev_err(>dev, "Cannot parse i2c-parent\n");
return -ENODEV;
}
adapter = of_find_i2c_adapter_by_node(adapter_np);
of_node_put(adapter_np);
if (!adapter) {
-   dev_err(mux->dev, "Cannot find parent bus\n");
+   dev_err(>dev, "Cannot find parent bus\n");
return -EPROBE_DEFER;
}
mux->pdata->parent_bus_num = i2c_adapter_id(adapter);
@@ -131,19 +122,15 @@ static inline int i2c_mux_pinctrl_parse_dt(struct 
i2c_mux_pinctrl *mux,
 
 static int i2c_mux_pinctrl_probe(struct platform_device *pdev)
 {
+   struct i2c_mux_core *muxc;
struct i2c_mux_pinctrl *mux;
-   int 

[PATCH v7 04/24] i2c: i2c-arb-gpio-challenge: convert to use an explicit i2c mux core

2016-04-20 Thread Peter Rosin
Allocate an explicit i2c mux core to handle parent and child adapters
etc. Update the select/deselect ops to be in terms of the i2c mux core
instead of the child adapter.

Signed-off-by: Peter Rosin 
---
 drivers/i2c/muxes/i2c-arb-gpio-challenge.c | 47 +-
 1 file changed, 20 insertions(+), 27 deletions(-)

diff --git a/drivers/i2c/muxes/i2c-arb-gpio-challenge.c 
b/drivers/i2c/muxes/i2c-arb-gpio-challenge.c
index 402e3a6c671a..a90bbc4037dd 100644
--- a/drivers/i2c/muxes/i2c-arb-gpio-challenge.c
+++ b/drivers/i2c/muxes/i2c-arb-gpio-challenge.c
@@ -28,8 +28,6 @@
 /**
  * struct i2c_arbitrator_data - Driver data for I2C arbitrator
  *
- * @parent: Parent adapter
- * @child: Child bus
  * @our_gpio: GPIO we'll use to claim.
  * @our_gpio_release: 0 if active high; 1 if active low; AKA if the GPIO ==
  *   this then consider it released.
@@ -42,8 +40,6 @@
  */
 
 struct i2c_arbitrator_data {
-   struct i2c_adapter *parent;
-   struct i2c_adapter *child;
int our_gpio;
int our_gpio_release;
int their_gpio;
@@ -59,9 +55,9 @@ struct i2c_arbitrator_data {
  *
  * Use the GPIO-based signalling protocol; return -EBUSY if we fail.
  */
-static int i2c_arbitrator_select(struct i2c_adapter *adap, void *data, u32 
chan)
+static int i2c_arbitrator_select(struct i2c_mux_core *muxc, u32 chan)
 {
-   const struct i2c_arbitrator_data *arb = data;
+   const struct i2c_arbitrator_data *arb = i2c_mux_priv(muxc);
unsigned long stop_retry, stop_time;
 
/* Start a round of trying to claim the bus */
@@ -93,7 +89,7 @@ static int i2c_arbitrator_select(struct i2c_adapter *adap, 
void *data, u32 chan)
/* Give up, release our claim */
gpio_set_value(arb->our_gpio, arb->our_gpio_release);
udelay(arb->slew_delay_us);
-   dev_err(>dev, "Could not claim bus, timeout\n");
+   dev_err(muxc->dev, "Could not claim bus, timeout\n");
return -EBUSY;
 }
 
@@ -102,10 +98,9 @@ static int i2c_arbitrator_select(struct i2c_adapter *adap, 
void *data, u32 chan)
  *
  * Release the I2C bus using the GPIO-based signalling protocol.
  */
-static int i2c_arbitrator_deselect(struct i2c_adapter *adap, void *data,
-  u32 chan)
+static int i2c_arbitrator_deselect(struct i2c_mux_core *muxc, u32 chan)
 {
-   const struct i2c_arbitrator_data *arb = data;
+   const struct i2c_arbitrator_data *arb = i2c_mux_priv(muxc);
 
/* Release the bus and wait for the other master to notice */
gpio_set_value(arb->our_gpio, arb->our_gpio_release);
@@ -119,6 +114,7 @@ static int i2c_arbitrator_probe(struct platform_device 
*pdev)
struct device *dev = >dev;
struct device_node *np = dev->of_node;
struct device_node *parent_np;
+   struct i2c_mux_core *muxc;
struct i2c_arbitrator_data *arb;
enum of_gpio_flags gpio_flags;
unsigned long out_init;
@@ -134,12 +130,13 @@ static int i2c_arbitrator_probe(struct platform_device 
*pdev)
return -EINVAL;
}
 
-   arb = devm_kzalloc(dev, sizeof(*arb), GFP_KERNEL);
-   if (!arb) {
-   dev_err(dev, "Cannot allocate i2c_arbitrator_data\n");
+   muxc = i2c_mux_alloc(NULL, dev, 1, sizeof(*arb), 0,
+i2c_arbitrator_select, i2c_arbitrator_deselect);
+   if (!muxc)
return -ENOMEM;
-   }
-   platform_set_drvdata(pdev, arb);
+   arb = i2c_mux_priv(muxc);
+
+   platform_set_drvdata(pdev, muxc);
 
/* Request GPIOs */
ret = of_get_named_gpio_flags(np, "our-claim-gpio", 0, _flags);
@@ -196,21 +193,18 @@ static int i2c_arbitrator_probe(struct platform_device 
*pdev)
dev_err(dev, "Cannot parse i2c-parent\n");
return -EINVAL;
}
-   arb->parent = of_get_i2c_adapter_by_node(parent_np);
+   muxc->parent = of_get_i2c_adapter_by_node(parent_np);
of_node_put(parent_np);
-   if (!arb->parent) {
+   if (!muxc->parent) {
dev_err(dev, "Cannot find parent bus\n");
return -EPROBE_DEFER;
}
 
/* Actually add the mux adapter */
-   arb->child = i2c_add_mux_adapter(arb->parent, dev, arb, 0, 0, 0,
-i2c_arbitrator_select,
-i2c_arbitrator_deselect);
-   if (!arb->child) {
+   ret = i2c_mux_add_adapter(muxc, 0, 0, 0);
+   if (ret) {
dev_err(dev, "Failed to add adapter\n");
-   ret = -ENODEV;
-   i2c_put_adapter(arb->parent);
+   i2c_put_adapter(muxc->parent);
}
 
return ret;
@@ -218,11 +212,10 @@ static int i2c_arbitrator_probe(struct platform_device 
*pdev)
 
 static int i2c_arbitrator_remove(struct platform_device *pdev)
 {
-   struct i2c_arbitrator_data *arb = platform_get_drvdata(pdev);
-
-   i2c_del_mux_adapter(arb->child);
-   

[PATCH v7 05/24] i2c: i2c-mux-pca9541: convert to use an explicit i2c mux core

2016-04-20 Thread Peter Rosin
Allocate an explicit i2c mux core to handle parent and child adapters
etc. Update the select/deselect ops to be in terms of the i2c mux core
instead of the child adapter.

Signed-off-by: Peter Rosin 
---
 drivers/i2c/muxes/i2c-mux-pca9541.c | 58 +
 1 file changed, 27 insertions(+), 31 deletions(-)

diff --git a/drivers/i2c/muxes/i2c-mux-pca9541.c 
b/drivers/i2c/muxes/i2c-mux-pca9541.c
index d0ba424adebc..3cb8af635db5 100644
--- a/drivers/i2c/muxes/i2c-mux-pca9541.c
+++ b/drivers/i2c/muxes/i2c-mux-pca9541.c
@@ -73,7 +73,7 @@
 #define SELECT_DELAY_LONG  1000
 
 struct pca9541 {
-   struct i2c_adapter *mux_adap;
+   struct i2c_client *client;
unsigned long select_timeout;
unsigned long arb_timeout;
 };
@@ -217,7 +217,8 @@ static const u8 pca9541_control[16] = {
  */
 static int pca9541_arbitrate(struct i2c_client *client)
 {
-   struct pca9541 *data = i2c_get_clientdata(client);
+   struct i2c_mux_core *muxc = i2c_get_clientdata(client);
+   struct pca9541 *data = i2c_mux_priv(muxc);
int reg;
 
reg = pca9541_reg_read(client, PCA9541_CONTROL);
@@ -285,9 +286,10 @@ static int pca9541_arbitrate(struct i2c_client *client)
return 0;
 }
 
-static int pca9541_select_chan(struct i2c_adapter *adap, void *client, u32 
chan)
+static int pca9541_select_chan(struct i2c_mux_core *muxc, u32 chan)
 {
-   struct pca9541 *data = i2c_get_clientdata(client);
+   struct pca9541 *data = i2c_mux_priv(muxc);
+   struct i2c_client *client = data->client;
int ret;
unsigned long timeout = jiffies + ARB2_TIMEOUT;
/* give up after this time */
@@ -309,9 +311,11 @@ static int pca9541_select_chan(struct i2c_adapter *adap, 
void *client, u32 chan)
return -ETIMEDOUT;
 }
 
-static int pca9541_release_chan(struct i2c_adapter *adap,
-   void *client, u32 chan)
+static int pca9541_release_chan(struct i2c_mux_core *muxc, u32 chan)
 {
+   struct pca9541 *data = i2c_mux_priv(muxc);
+   struct i2c_client *client = data->client;
+
pca9541_release_bus(client);
return 0;
 }
@@ -324,20 +328,13 @@ static int pca9541_probe(struct i2c_client *client,
 {
struct i2c_adapter *adap = client->adapter;
struct pca954x_platform_data *pdata = dev_get_platdata(>dev);
+   struct i2c_mux_core *muxc;
struct pca9541 *data;
int force;
-   int ret = -ENODEV;
+   int ret;
 
if (!i2c_check_functionality(adap, I2C_FUNC_SMBUS_BYTE_DATA))
-   goto err;
-
-   data = kzalloc(sizeof(struct pca9541), GFP_KERNEL);
-   if (!data) {
-   ret = -ENOMEM;
-   goto err;
-   }
-
-   i2c_set_clientdata(client, data);
+   return -ENODEV;
 
/*
 * I2C accesses are unprotected here.
@@ -352,34 +349,33 @@ static int pca9541_probe(struct i2c_client *client,
force = 0;
if (pdata)
force = pdata->modes[0].adap_id;
-   data->mux_adap = i2c_add_mux_adapter(adap, >dev, client,
-force, 0, 0,
-pca9541_select_chan,
-pca9541_release_chan);
+   muxc = i2c_mux_alloc(adap, >dev, 1, sizeof(*data), 0,
+pca9541_select_chan, pca9541_release_chan);
+   if (!muxc)
+   return -ENOMEM;
 
-   if (data->mux_adap == NULL) {
+   data = i2c_mux_priv(muxc);
+   data->client = client;
+
+   i2c_set_clientdata(client, muxc);
+
+   ret = i2c_mux_add_adapter(muxc, force, 0, 0);
+   if (ret) {
dev_err(>dev, "failed to register master selector\n");
-   goto exit_free;
+   return ret;
}
 
dev_info(>dev, "registered master selector for I2C %s\n",
 client->name);
 
return 0;
-
-exit_free:
-   kfree(data);
-err:
-   return ret;
 }
 
 static int pca9541_remove(struct i2c_client *client)
 {
-   struct pca9541 *data = i2c_get_clientdata(client);
-
-   i2c_del_mux_adapter(data->mux_adap);
+   struct i2c_mux_core *muxc = i2c_get_clientdata(client);
 
-   kfree(data);
+   i2c_mux_del_adapters(muxc);
return 0;
 }
 
-- 
2.1.4

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


[PATCH v7 08/24] iio: imu: inv_mpu6050: convert to use an explicit i2c mux core

2016-04-20 Thread Peter Rosin
Allocate an explicit i2c mux core to handle parent and child adapters
etc. Update the select/deselect ops to be in terms of the i2c mux core
instead of the child adapter.

Acked-by: Jonathan Cameron 
Signed-off-by: Peter Rosin 
---
 drivers/iio/imu/inv_mpu6050/inv_mpu_acpi.c |  2 +-
 drivers/iio/imu/inv_mpu6050/inv_mpu_core.c |  1 -
 drivers/iio/imu/inv_mpu6050/inv_mpu_i2c.c  | 35 +++---
 drivers/iio/imu/inv_mpu6050/inv_mpu_iio.h  |  3 ++-
 4 files changed, 20 insertions(+), 21 deletions(-)

diff --git a/drivers/iio/imu/inv_mpu6050/inv_mpu_acpi.c 
b/drivers/iio/imu/inv_mpu6050/inv_mpu_acpi.c
index 2771106fd650..f62b8bd9ad7e 100644
--- a/drivers/iio/imu/inv_mpu6050/inv_mpu_acpi.c
+++ b/drivers/iio/imu/inv_mpu6050/inv_mpu_acpi.c
@@ -183,7 +183,7 @@ int inv_mpu_acpi_create_mux_client(struct i2c_client 
*client)
} else
return 0; /* no secondary addr, which is OK */
}
-   st->mux_client = i2c_new_device(st->mux_adapter, );
+   st->mux_client = i2c_new_device(st->muxc->adapter[0], );
if (!st->mux_client)
return -ENODEV;
}
diff --git a/drivers/iio/imu/inv_mpu6050/inv_mpu_core.c 
b/drivers/iio/imu/inv_mpu6050/inv_mpu_core.c
index d192953e9a38..0c2bded2b5b7 100644
--- a/drivers/iio/imu/inv_mpu6050/inv_mpu_core.c
+++ b/drivers/iio/imu/inv_mpu6050/inv_mpu_core.c
@@ -23,7 +23,6 @@
 #include 
 #include 
 #include 
-#include 
 #include 
 #include "inv_mpu_iio.h"
 
diff --git a/drivers/iio/imu/inv_mpu6050/inv_mpu_i2c.c 
b/drivers/iio/imu/inv_mpu6050/inv_mpu_i2c.c
index f581256d9d4c..664a45082d39 100644
--- a/drivers/iio/imu/inv_mpu6050/inv_mpu_i2c.c
+++ b/drivers/iio/imu/inv_mpu6050/inv_mpu_i2c.c
@@ -15,7 +15,6 @@
 #include 
 #include 
 #include 
-#include 
 #include 
 #include 
 #include "inv_mpu_iio.h"
@@ -52,10 +51,9 @@ static int inv_mpu6050_write_reg_unlocked(struct i2c_client 
*client,
return 0;
 }
 
-static int inv_mpu6050_select_bypass(struct i2c_adapter *adap, void *mux_priv,
-u32 chan_id)
+static int inv_mpu6050_select_bypass(struct i2c_mux_core *muxc, u32 chan_id)
 {
-   struct i2c_client *client = mux_priv;
+   struct i2c_client *client = i2c_mux_priv(muxc);
struct iio_dev *indio_dev = dev_get_drvdata(>dev);
struct inv_mpu6050_state *st = iio_priv(indio_dev);
int ret = 0;
@@ -84,10 +82,9 @@ write_error:
return ret;
 }
 
-static int inv_mpu6050_deselect_bypass(struct i2c_adapter *adap,
-  void *mux_priv, u32 chan_id)
+static int inv_mpu6050_deselect_bypass(struct i2c_mux_core *muxc, u32 chan_id)
 {
-   struct i2c_client *client = mux_priv;
+   struct i2c_client *client = i2c_mux_priv(muxc);
struct iio_dev *indio_dev = dev_get_drvdata(>dev);
struct inv_mpu6050_state *st = iio_priv(indio_dev);
 
@@ -136,16 +133,18 @@ static int inv_mpu_probe(struct i2c_client *client,
return result;
 
st = iio_priv(dev_get_drvdata(>dev));
-   st->mux_adapter = i2c_add_mux_adapter(client->adapter,
- >dev,
- client,
- 0, 0, 0,
- inv_mpu6050_select_bypass,
- inv_mpu6050_deselect_bypass);
-   if (!st->mux_adapter) {
-   result = -ENODEV;
+   st->muxc = i2c_mux_alloc(client->adapter, >dev,
+1, 0, 0,
+inv_mpu6050_select_bypass,
+inv_mpu6050_deselect_bypass);
+   if (!st->muxc) {
+   result = -ENOMEM;
goto out_unreg_device;
}
+   st->muxc->priv = dev_get_drvdata(>dev);
+   result = i2c_mux_add_adapter(st->muxc, 0, 0, 0);
+   if (result)
+   goto out_unreg_device;
 
result = inv_mpu_acpi_create_mux_client(client);
if (result)
@@ -154,7 +153,7 @@ static int inv_mpu_probe(struct i2c_client *client,
return 0;
 
 out_del_mux:
-   i2c_del_mux_adapter(st->mux_adapter);
+   i2c_mux_del_adapters(st->muxc);
 out_unreg_device:
inv_mpu_core_remove(>dev);
return result;
@@ -162,11 +161,11 @@ out_unreg_device:
 
 static int inv_mpu_remove(struct i2c_client *client)
 {
-   struct iio_dev *indio_dev = i2c_get_clientdata(client);
+   struct iio_dev *indio_dev = dev_get_drvdata(>dev);
struct inv_mpu6050_state *st = iio_priv(indio_dev);
 
inv_mpu_acpi_delete_mux_client(client);
-   i2c_del_mux_adapter(st->mux_adapter);
+   i2c_mux_del_adapters(st->muxc);
 
return inv_mpu_core_remove(>dev);
 }
diff --git a/drivers/iio/imu/inv_mpu6050/inv_mpu_iio.h 
b/drivers/iio/imu/inv_mpu6050/inv_mpu_iio.h
index 

[PATCH v7 10/24] [media] rtl2830: convert to use an explicit i2c mux core

2016-04-20 Thread Peter Rosin
Allocate an explicit i2c mux core to handle parent and child adapters
etc. Update the select op to be in terms of the i2c mux core instead
of the child adapter.

Reviewed-by: Antti Palosaari 
Signed-off-by: Peter Rosin 
---
 drivers/media/dvb-frontends/rtl2830.c  | 20 
 drivers/media/dvb-frontends/rtl2830_priv.h |  2 +-
 2 files changed, 13 insertions(+), 9 deletions(-)

diff --git a/drivers/media/dvb-frontends/rtl2830.c 
b/drivers/media/dvb-frontends/rtl2830.c
index 3f96429af0e5..d25d1e0cd4ca 100644
--- a/drivers/media/dvb-frontends/rtl2830.c
+++ b/drivers/media/dvb-frontends/rtl2830.c
@@ -677,9 +677,9 @@ err:
  * adapter lock is already taken by tuner driver.
  * Gate is closed automatically after single I2C transfer.
  */
-static int rtl2830_select(struct i2c_adapter *adap, void *mux_priv, u32 
chan_id)
+static int rtl2830_select(struct i2c_mux_core *muxc, u32 chan_id)
 {
-   struct i2c_client *client = mux_priv;
+   struct i2c_client *client = i2c_mux_priv(muxc);
struct rtl2830_dev *dev = i2c_get_clientdata(client);
int ret;
 
@@ -712,7 +712,7 @@ static struct i2c_adapter *rtl2830_get_i2c_adapter(struct 
i2c_client *client)
 
dev_dbg(>dev, "\n");
 
-   return dev->adapter;
+   return dev->muxc->adapter[0];
 }
 
 /*
@@ -865,12 +865,16 @@ static int rtl2830_probe(struct i2c_client *client,
goto err_regmap_exit;
 
/* create muxed i2c adapter for tuner */
-   dev->adapter = i2c_add_mux_adapter(client->adapter, >dev,
-   client, 0, 0, 0, rtl2830_select, NULL);
-   if (dev->adapter == NULL) {
-   ret = -ENODEV;
+   dev->muxc = i2c_mux_alloc(client->adapter, >dev, 1, 0, 0,
+ rtl2830_select, NULL);
+   if (!dev->muxc) {
+   ret = -ENOMEM;
goto err_regmap_exit;
}
+   dev->muxc->priv = client;
+   ret = i2c_mux_add_adapter(dev->muxc, 0, 0, 0);
+   if (ret)
+   goto err_regmap_exit;
 
/* create dvb frontend */
memcpy(>fe.ops, _ops, sizeof(dev->fe.ops));
@@ -903,7 +907,7 @@ static int rtl2830_remove(struct i2c_client *client)
/* stop statistics polling */
cancel_delayed_work_sync(>stat_work);
 
-   i2c_del_mux_adapter(dev->adapter);
+   i2c_mux_del_adapters(dev->muxc);
regmap_exit(dev->regmap);
kfree(dev);
 
diff --git a/drivers/media/dvb-frontends/rtl2830_priv.h 
b/drivers/media/dvb-frontends/rtl2830_priv.h
index cf793f39a09b..da4909543da2 100644
--- a/drivers/media/dvb-frontends/rtl2830_priv.h
+++ b/drivers/media/dvb-frontends/rtl2830_priv.h
@@ -29,7 +29,7 @@ struct rtl2830_dev {
struct rtl2830_platform_data *pdata;
struct i2c_client *client;
struct regmap *regmap;
-   struct i2c_adapter *adapter;
+   struct i2c_mux_core *muxc;
struct dvb_frontend fe;
bool sleeping;
unsigned long filters;
-- 
2.1.4

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


[PATCH v7 09/24] [media] m88ds3103: convert to use an explicit i2c mux core

2016-04-20 Thread Peter Rosin
Allocate an explicit i2c mux core to handle parent and child adapters
etc. Update the select op to be in terms of the i2c mux core instead
of the child adapter.

Reviewed-by: Antti Palosaari 
Signed-off-by: Peter Rosin 
---
 drivers/media/dvb-frontends/m88ds3103.c  | 19 +++
 drivers/media/dvb-frontends/m88ds3103_priv.h |  2 +-
 2 files changed, 12 insertions(+), 9 deletions(-)

diff --git a/drivers/media/dvb-frontends/m88ds3103.c 
b/drivers/media/dvb-frontends/m88ds3103.c
index 76883600ec6f..5557ef8fc704 100644
--- a/drivers/media/dvb-frontends/m88ds3103.c
+++ b/drivers/media/dvb-frontends/m88ds3103.c
@@ -1251,9 +1251,9 @@ static void m88ds3103_release(struct dvb_frontend *fe)
i2c_unregister_device(client);
 }
 
-static int m88ds3103_select(struct i2c_adapter *adap, void *mux_priv, u32 chan)
+static int m88ds3103_select(struct i2c_mux_core *muxc, u32 chan)
 {
-   struct m88ds3103_dev *dev = mux_priv;
+   struct m88ds3103_dev *dev = i2c_mux_priv(muxc);
struct i2c_client *client = dev->client;
int ret;
struct i2c_msg msg = {
@@ -1374,7 +1374,7 @@ static struct i2c_adapter 
*m88ds3103_get_i2c_adapter(struct i2c_client *client)
 
dev_dbg(>dev, "\n");
 
-   return dev->i2c_adapter;
+   return dev->muxc->adapter[0];
 }
 
 static int m88ds3103_probe(struct i2c_client *client,
@@ -1467,13 +1467,16 @@ static int m88ds3103_probe(struct i2c_client *client,
goto err_kfree;
 
/* create mux i2c adapter for tuner */
-   dev->i2c_adapter = i2c_add_mux_adapter(client->adapter, >dev,
-  dev, 0, 0, 0, m88ds3103_select,
-  NULL);
-   if (dev->i2c_adapter == NULL) {
+   dev->muxc = i2c_mux_alloc(client->adapter, >dev, 1, 0, 0,
+ m88ds3103_select, NULL);
+   if (!dev->muxc) {
ret = -ENOMEM;
goto err_kfree;
}
+   dev->muxc->priv = dev;
+   ret = i2c_mux_add_adapter(dev->muxc, 0, 0, 0);
+   if (ret)
+   goto err_kfree;
 
/* create dvb_frontend */
memcpy(>fe.ops, _ops, sizeof(struct dvb_frontend_ops));
@@ -1502,7 +1505,7 @@ static int m88ds3103_remove(struct i2c_client *client)
 
dev_dbg(>dev, "\n");
 
-   i2c_del_mux_adapter(dev->i2c_adapter);
+   i2c_mux_del_adapters(dev->muxc);
 
kfree(dev);
return 0;
diff --git a/drivers/media/dvb-frontends/m88ds3103_priv.h 
b/drivers/media/dvb-frontends/m88ds3103_priv.h
index eee8c22c51ec..c5b4e177c6ea 100644
--- a/drivers/media/dvb-frontends/m88ds3103_priv.h
+++ b/drivers/media/dvb-frontends/m88ds3103_priv.h
@@ -42,7 +42,7 @@ struct m88ds3103_dev {
enum fe_status fe_status;
u32 dvbv3_ber; /* for old DVBv3 API read_ber */
bool warm; /* FW running */
-   struct i2c_adapter *i2c_adapter;
+   struct i2c_mux_core *muxc;
/* auto detect chip id to do different config */
u8 chip_id;
/* main mclk is calculated for M88RS6000 dynamically */
-- 
2.1.4

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


[PATCH v7 11/24] [media] rtl2832: convert to use an explicit i2c mux core

2016-04-20 Thread Peter Rosin
Allocate an explicit i2c mux core to handle parent and child adapters
etc. Update the select/deselect ops to be in terms of the i2c mux core
instead of the child adapter.

Reviewed-by: Antti Palosaari 
Signed-off-by: Peter Rosin 
---
 drivers/media/dvb-frontends/rtl2832.c  | 25 ++---
 drivers/media/dvb-frontends/rtl2832_priv.h |  2 +-
 2 files changed, 15 insertions(+), 12 deletions(-)

diff --git a/drivers/media/dvb-frontends/rtl2832.c 
b/drivers/media/dvb-frontends/rtl2832.c
index 7c96f7679669..1b23788797b5 100644
--- a/drivers/media/dvb-frontends/rtl2832.c
+++ b/drivers/media/dvb-frontends/rtl2832.c
@@ -847,9 +847,9 @@ err:
dev_dbg(>dev, "failed=%d\n", ret);
 }
 
-static int rtl2832_select(struct i2c_adapter *adap, void *mux_priv, u32 
chan_id)
+static int rtl2832_select(struct i2c_mux_core *muxc, u32 chan_id)
 {
-   struct rtl2832_dev *dev = mux_priv;
+   struct rtl2832_dev *dev = i2c_mux_priv(muxc);
struct i2c_client *client = dev->client;
int ret;
 
@@ -870,10 +870,9 @@ err:
return ret;
 }
 
-static int rtl2832_deselect(struct i2c_adapter *adap, void *mux_priv,
-   u32 chan_id)
+static int rtl2832_deselect(struct i2c_mux_core *muxc, u32 chan_id)
 {
-   struct rtl2832_dev *dev = mux_priv;
+   struct rtl2832_dev *dev = i2c_mux_priv(muxc);
 
schedule_delayed_work(>i2c_gate_work, usecs_to_jiffies(100));
return 0;
@@ -1059,7 +1058,7 @@ static struct i2c_adapter *rtl2832_get_i2c_adapter(struct 
i2c_client *client)
struct rtl2832_dev *dev = i2c_get_clientdata(client);
 
dev_dbg(>dev, "\n");
-   return dev->i2c_adapter_tuner;
+   return dev->muxc->adapter[0];
 }
 
 static int rtl2832_slave_ts_ctrl(struct i2c_client *client, bool enable)
@@ -1242,12 +1241,16 @@ static int rtl2832_probe(struct i2c_client *client,
goto err_regmap_exit;
 
/* create muxed i2c adapter for demod tuner bus */
-   dev->i2c_adapter_tuner = i2c_add_mux_adapter(i2c, >dev, dev,
-   0, 0, 0, rtl2832_select, rtl2832_deselect);
-   if (dev->i2c_adapter_tuner == NULL) {
-   ret = -ENODEV;
+   dev->muxc = i2c_mux_alloc(i2c, >dev, 1, 0, 0,
+ rtl2832_select, rtl2832_deselect);
+   if (!dev->muxc) {
+   ret = -ENOMEM;
goto err_regmap_exit;
}
+   dev->muxc->priv = dev;
+   ret = i2c_mux_add_adapter(dev->muxc, 0, 0, 0);
+   if (ret)
+   goto err_regmap_exit;
 
/* create dvb_frontend */
memcpy(>fe.ops, _ops, sizeof(struct dvb_frontend_ops));
@@ -1282,7 +1285,7 @@ static int rtl2832_remove(struct i2c_client *client)
 
cancel_delayed_work_sync(>i2c_gate_work);
 
-   i2c_del_mux_adapter(dev->i2c_adapter_tuner);
+   i2c_mux_del_adapters(dev->muxc);
 
regmap_exit(dev->regmap);
 
diff --git a/drivers/media/dvb-frontends/rtl2832_priv.h 
b/drivers/media/dvb-frontends/rtl2832_priv.h
index 6b875f462f8b..d8f97d14f6fd 100644
--- a/drivers/media/dvb-frontends/rtl2832_priv.h
+++ b/drivers/media/dvb-frontends/rtl2832_priv.h
@@ -36,7 +36,7 @@ struct rtl2832_dev {
struct mutex regmap_mutex;
struct regmap_config regmap_config;
struct regmap *regmap;
-   struct i2c_adapter *i2c_adapter_tuner;
+   struct i2c_mux_core *muxc;
struct dvb_frontend fe;
enum fe_status fe_status;
u64 post_bit_error_prev; /* for old DVBv3 read_ber() calculation */
-- 
2.1.4

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


[PATCH v7 12/24] [media] si2168: convert to use an explicit i2c mux core

2016-04-20 Thread Peter Rosin
Allocate an explicit i2c mux core to handle parent and child adapters
etc. Update the select/deselect ops to be in terms of the i2c mux core
instead of the child adapter.

Reviewed-by: Antti Palosaari 
Signed-off-by: Peter Rosin 
---
 drivers/media/dvb-frontends/si2168.c  | 25 +++--
 drivers/media/dvb-frontends/si2168_priv.h |  2 +-
 2 files changed, 16 insertions(+), 11 deletions(-)

diff --git a/drivers/media/dvb-frontends/si2168.c 
b/drivers/media/dvb-frontends/si2168.c
index 821a8f481507..5583827c386e 100644
--- a/drivers/media/dvb-frontends/si2168.c
+++ b/drivers/media/dvb-frontends/si2168.c
@@ -615,9 +615,9 @@ static int si2168_get_tune_settings(struct dvb_frontend *fe,
  * We must use unlocked I2C I/O because I2C adapter lock is already taken
  * by the caller (usually tuner driver).
  */
-static int si2168_select(struct i2c_adapter *adap, void *mux_priv, u32 chan)
+static int si2168_select(struct i2c_mux_core *muxc, u32 chan)
 {
-   struct i2c_client *client = mux_priv;
+   struct i2c_client *client = i2c_mux_priv(muxc);
int ret;
struct si2168_cmd cmd;
 
@@ -635,9 +635,9 @@ err:
return ret;
 }
 
-static int si2168_deselect(struct i2c_adapter *adap, void *mux_priv, u32 chan)
+static int si2168_deselect(struct i2c_mux_core *muxc, u32 chan)
 {
-   struct i2c_client *client = mux_priv;
+   struct i2c_client *client = i2c_mux_priv(muxc);
int ret;
struct si2168_cmd cmd;
 
@@ -709,17 +709,22 @@ static int si2168_probe(struct i2c_client *client,
}
 
/* create mux i2c adapter for tuner */
-   dev->adapter = i2c_add_mux_adapter(client->adapter, >dev,
-   client, 0, 0, 0, si2168_select, si2168_deselect);
-   if (dev->adapter == NULL) {
-   ret = -ENODEV;
+   dev->muxc = i2c_mux_alloc(client->adapter, >dev,
+ 1, 0, 0,
+ si2168_select, si2168_deselect);
+   if (!dev->muxc) {
+   ret = -ENOMEM;
goto err_kfree;
}
+   dev->muxc->priv = client;
+   ret = i2c_mux_add_adapter(dev->muxc, 0, 0, 0);
+   if (ret)
+   goto err_kfree;
 
/* create dvb_frontend */
memcpy(>fe.ops, _ops, sizeof(struct dvb_frontend_ops));
dev->fe.demodulator_priv = client;
-   *config->i2c_adapter = dev->adapter;
+   *config->i2c_adapter = dev->muxc->adapter[0];
*config->fe = >fe;
dev->ts_mode = config->ts_mode;
dev->ts_clock_inv = config->ts_clock_inv;
@@ -743,7 +748,7 @@ static int si2168_remove(struct i2c_client *client)
 
dev_dbg(>dev, "\n");
 
-   i2c_del_mux_adapter(dev->adapter);
+   i2c_mux_del_adapters(dev->muxc);
 
dev->fe.ops.release = NULL;
dev->fe.demodulator_priv = NULL;
diff --git a/drivers/media/dvb-frontends/si2168_priv.h 
b/drivers/media/dvb-frontends/si2168_priv.h
index c07e6fe2cb10..165bf1412063 100644
--- a/drivers/media/dvb-frontends/si2168_priv.h
+++ b/drivers/media/dvb-frontends/si2168_priv.h
@@ -29,7 +29,7 @@
 
 /* state struct */
 struct si2168_dev {
-   struct i2c_adapter *adapter;
+   struct i2c_mux_core *muxc;
struct dvb_frontend fe;
enum fe_delivery_system delivery_system;
enum fe_status fe_status;
-- 
2.1.4

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


[PATCH v7 15/24] i2c-mux: drop old unused i2c-mux api

2016-04-20 Thread Peter Rosin
All i2c mux users are using an explicit i2c mux core, drop support
for implicit i2c mux cores.

Signed-off-by: Peter Rosin 
---
 drivers/i2c/i2c-mux.c   | 63 -
 include/linux/i2c-mux.h | 15 
 2 files changed, 78 deletions(-)

diff --git a/drivers/i2c/i2c-mux.c b/drivers/i2c/i2c-mux.c
index 5ce1b0704cb5..25e9336b0e6e 100644
--- a/drivers/i2c/i2c-mux.c
+++ b/drivers/i2c/i2c-mux.c
@@ -28,12 +28,6 @@
 #include 
 
 /* multiplexer per channel data */
-struct i2c_mux_priv_old {
-   void *mux_priv;
-   int (*select)(struct i2c_adapter *, void *mux_priv, u32 chan_id);
-   int (*deselect)(struct i2c_adapter *, void *mux_priv, u32 chan_id);
-};
-
 struct i2c_mux_priv {
struct i2c_adapter adap;
struct i2c_algorithm algo;
@@ -104,53 +98,6 @@ static unsigned int i2c_mux_parent_classes(struct 
i2c_adapter *parent)
return class;
 }
 
-static int i2c_mux_select(struct i2c_mux_core *muxc, u32 chan)
-{
-   struct i2c_mux_priv_old *priv = i2c_mux_priv(muxc);
-
-   return priv->select(muxc->parent, priv->mux_priv, chan);
-}
-
-static int i2c_mux_deselect(struct i2c_mux_core *muxc, u32 chan)
-{
-   struct i2c_mux_priv_old *priv = i2c_mux_priv(muxc);
-
-   return priv->deselect(muxc->parent, priv->mux_priv, chan);
-}
-
-struct i2c_adapter *i2c_add_mux_adapter(struct i2c_adapter *parent,
-   struct device *mux_dev,
-   void *mux_priv, u32 force_nr, u32 chan_id,
-   unsigned int class,
-   int (*select) (struct i2c_adapter *,
-  void *, u32),
-   int (*deselect) (struct i2c_adapter *,
-void *, u32))
-{
-   struct i2c_mux_core *muxc;
-   struct i2c_mux_priv_old *priv;
-   int ret;
-
-   muxc = i2c_mux_alloc(parent, mux_dev, 1, sizeof(*priv), 0,
-i2c_mux_select, i2c_mux_deselect);
-   if (!muxc)
-   return NULL;
-
-   priv = i2c_mux_priv(muxc);
-   priv->select = select;
-   priv->deselect = deselect;
-   priv->mux_priv = mux_priv;
-
-   ret = i2c_mux_add_adapter(muxc, force_nr, chan_id, class);
-   if (ret) {
-   devm_kfree(mux_dev, muxc);
-   return NULL;
-   }
-
-   return muxc->adapter[0];
-}
-EXPORT_SYMBOL_GPL(i2c_add_mux_adapter);
-
 struct i2c_mux_core *i2c_mux_alloc(struct i2c_adapter *parent,
   struct device *dev, int max_adapters,
   int sizeof_priv, u32 flags,
@@ -305,16 +252,6 @@ void i2c_mux_del_adapters(struct i2c_mux_core *muxc)
 }
 EXPORT_SYMBOL_GPL(i2c_mux_del_adapters);
 
-void i2c_del_mux_adapter(struct i2c_adapter *adap)
-{
-   struct i2c_mux_priv *priv = adap->algo_data;
-   struct i2c_mux_core *muxc = priv->muxc;
-
-   i2c_mux_del_adapters(muxc);
-   devm_kfree(muxc->dev, muxc);
-}
-EXPORT_SYMBOL_GPL(i2c_del_mux_adapter);
-
 MODULE_AUTHOR("Rodolfo Giometti ");
 MODULE_DESCRIPTION("I2C driver for multiplexed I2C busses");
 MODULE_LICENSE("GPL v2");
diff --git a/include/linux/i2c-mux.h b/include/linux/i2c-mux.h
index 71ac1b3f4f68..2fa93fe1345e 100644
--- a/include/linux/i2c-mux.h
+++ b/include/linux/i2c-mux.h
@@ -53,20 +53,6 @@ static inline void *i2c_mux_priv(struct i2c_mux_core *muxc)
 }
 
 /*
- * Called to create a i2c bus on a multiplexed bus segment.
- * The mux_dev and chan_id parameters are passed to the select
- * and deselect callback functions to perform hardware-specific
- * mux control.
- */
-struct i2c_adapter *i2c_add_mux_adapter(struct i2c_adapter *parent,
-   struct device *mux_dev,
-   void *mux_priv, u32 force_nr, u32 chan_id,
-   unsigned int class,
-   int (*select) (struct i2c_adapter *,
-  void *mux_dev, u32 chan_id),
-   int (*deselect) (struct i2c_adapter *,
-void *mux_dev, u32 chan_id));
-/*
  * Called to create an i2c bus on a multiplexed bus segment.
  * The chan_id parameter is passed to the select and deselect
  * callback functions to perform hardware-specific mux control.
@@ -75,7 +61,6 @@ int i2c_mux_add_adapter(struct i2c_mux_core *muxc,
u32 force_nr, u32 chan_id,
unsigned int class);
 
-void i2c_del_mux_adapter(struct i2c_adapter *adap);
 void i2c_mux_del_adapters(struct i2c_mux_core *muxc);
 
 #endif /* __KERNEL__ */
-- 
2.1.4

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


[PATCH v7 17/24] i2c: muxes always lock the parent adapter

2016-04-20 Thread Peter Rosin
Instead of checking for i2c parent adapters for every lock/unlock, simply
override the locking for muxes to always lock/unlock the parent adapter
directly.

Signed-off-by: Peter Rosin 
---
 drivers/i2c/i2c-core.c | 21 +++--
 drivers/i2c/i2c-mux.c  | 27 +++
 2 files changed, 30 insertions(+), 18 deletions(-)

diff --git a/drivers/i2c/i2c-core.c b/drivers/i2c/i2c-core.c
index 21f46d011c33..5314434c2b5d 100644
--- a/drivers/i2c/i2c-core.c
+++ b/drivers/i2c/i2c-core.c
@@ -967,12 +967,7 @@ static int i2c_check_addr_busy(struct i2c_adapter 
*adapter, int addr)
  */
 static void i2c_adapter_lock_bus(struct i2c_adapter *adapter, int flags)
 {
-   struct i2c_adapter *parent = i2c_parent_is_i2c_adapter(adapter);
-
-   if (parent)
-   i2c_lock_adapter(parent);
-   else
-   rt_mutex_lock(>bus_lock);
+   rt_mutex_lock(>bus_lock);
 }
 
 /**
@@ -983,12 +978,7 @@ static void i2c_adapter_lock_bus(struct i2c_adapter 
*adapter, int flags)
  */
 static int i2c_adapter_trylock_bus(struct i2c_adapter *adapter, int flags)
 {
-   struct i2c_adapter *parent = i2c_parent_is_i2c_adapter(adapter);
-
-   if (parent)
-   return parent->trylock_bus(parent, flags);
-   else
-   return rt_mutex_trylock(>bus_lock);
+   return rt_mutex_trylock(>bus_lock);
 }
 
 /**
@@ -999,12 +989,7 @@ static int i2c_adapter_trylock_bus(struct i2c_adapter 
*adapter, int flags)
  */
 static void i2c_adapter_unlock_bus(struct i2c_adapter *adapter, int flags)
 {
-   struct i2c_adapter *parent = i2c_parent_is_i2c_adapter(adapter);
-
-   if (parent)
-   i2c_unlock_adapter(parent);
-   else
-   rt_mutex_unlock(>bus_lock);
+   rt_mutex_unlock(>bus_lock);
 }
 
 static void i2c_dev_set_name(struct i2c_adapter *adap,
diff --git a/drivers/i2c/i2c-mux.c b/drivers/i2c/i2c-mux.c
index 25e9336b0e6e..dc958eebdbb4 100644
--- a/drivers/i2c/i2c-mux.c
+++ b/drivers/i2c/i2c-mux.c
@@ -98,6 +98,30 @@ static unsigned int i2c_mux_parent_classes(struct 
i2c_adapter *parent)
return class;
 }
 
+static void i2c_parent_lock_bus(struct i2c_adapter *adapter, int flags)
+{
+   struct i2c_mux_priv *priv = adapter->algo_data;
+   struct i2c_adapter *parent = priv->muxc->parent;
+
+   parent->lock_bus(parent, flags);
+}
+
+static int i2c_parent_trylock_bus(struct i2c_adapter *adapter, int flags)
+{
+   struct i2c_mux_priv *priv = adapter->algo_data;
+   struct i2c_adapter *parent = priv->muxc->parent;
+
+   return parent->trylock_bus(parent, flags);
+}
+
+static void i2c_parent_unlock_bus(struct i2c_adapter *adapter, int flags)
+{
+   struct i2c_mux_priv *priv = adapter->algo_data;
+   struct i2c_adapter *parent = priv->muxc->parent;
+
+   parent->unlock_bus(parent, flags);
+}
+
 struct i2c_mux_core *i2c_mux_alloc(struct i2c_adapter *parent,
   struct device *dev, int max_adapters,
   int sizeof_priv, u32 flags,
@@ -165,6 +189,9 @@ int i2c_mux_add_adapter(struct i2c_mux_core *muxc,
priv->adap.retries = parent->retries;
priv->adap.timeout = parent->timeout;
priv->adap.quirks = parent->quirks;
+   priv->adap.lock_bus = i2c_parent_lock_bus;
+   priv->adap.trylock_bus = i2c_parent_trylock_bus;
+   priv->adap.unlock_bus = i2c_parent_unlock_bus;
 
/* Sanity check on class */
if (i2c_mux_parent_classes(parent) & class)
-- 
2.1.4

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


[PATCH v7 18/24] i2c-mux: relax locking of the top i2c adapter during mux-locked muxing

2016-04-20 Thread Peter Rosin
With a i2c topology like the following

   GPIO ---|  -- BAT1
|  v /
   I2C  -+--+ MUX
 |   \
   EEPROM -- BAT2

there is a locking problem with the GPIO controller since it is a client
on the same i2c bus that it muxes. Transfers to the mux clients (e.g. BAT1)
will lock the whole i2c bus prior to attempting to switch the mux to the
correct i2c segment. In the above case, the GPIO device is an I/O expander
with an i2c interface, and since the GPIO subsystem knows nothing (and
rightfully so) about the lockless needs of the i2c mux code, this results
in a deadlock when the GPIO driver issues i2c transfers to modify the
mux.

So, observing that while it is needed to have the i2c bus locked during the
actual MUX update in order to avoid random garbage on the slave side, it
is not strictly a must to have it locked over the whole sequence of a full
select-transfer-deselect mux client operation. The mux itself needs to be
locked, so transfers to clients behind the mux are serialized, and the mux
needs to be stable during all i2c traffic (otherwise individual mux slave
segments might see garbage, or worse).

Introduce this new locking concept as "mux-locked" muxes, and call the
pre-existing mux locking scheme "parent-locked".

Modify the i2c mux locking so that muxes that are "mux-locked" locks only
the muxes on the parent adapter instead of the whole i2c bus when there is
a transfer to the slave side of the mux. This lock serializes transfers to
the slave side of the muxes on the parent adapter.

Add code to i2c-mux-gpio and i2c-mux-pinctrl that checks if all involved
gpio/pinctrl devices have a parent that is an i2c adapter in the same
adapter tree that is muxed, and request a "mux-locked mux" if that is the
case.

Modify the select-transfer-deselect code for "mux-locked" muxes so
that each of the select-transfer-deselect ops locks the mux parent
adapter individually.

Signed-off-by: Peter Rosin 
---
 drivers/i2c/i2c-core.c  |   1 +
 drivers/i2c/i2c-mux.c   | 152 +---
 drivers/i2c/muxes/i2c-mux-gpio.c|  18 +
 drivers/i2c/muxes/i2c-mux-pinctrl.c |  38 +
 include/linux/i2c-mux.h |   6 ++
 include/linux/i2c.h |   1 +
 6 files changed, 203 insertions(+), 13 deletions(-)

diff --git a/drivers/i2c/i2c-core.c b/drivers/i2c/i2c-core.c
index 5314434c2b5d..53514ea314cd 100644
--- a/drivers/i2c/i2c-core.c
+++ b/drivers/i2c/i2c-core.c
@@ -1543,6 +1543,7 @@ static int i2c_register_adapter(struct i2c_adapter *adap)
}
 
rt_mutex_init(>bus_lock);
+   rt_mutex_init(>mux_lock);
mutex_init(>userspace_clients_lock);
INIT_LIST_HEAD(>userspace_clients);
 
diff --git a/drivers/i2c/i2c-mux.c b/drivers/i2c/i2c-mux.c
index dc958eebdbb4..364319c3c95f 100644
--- a/drivers/i2c/i2c-mux.c
+++ b/drivers/i2c/i2c-mux.c
@@ -35,6 +35,25 @@ struct i2c_mux_priv {
u32 chan_id;
 };
 
+static int __i2c_mux_master_xfer(struct i2c_adapter *adap,
+struct i2c_msg msgs[], int num)
+{
+   struct i2c_mux_priv *priv = adap->algo_data;
+   struct i2c_mux_core *muxc = priv->muxc;
+   struct i2c_adapter *parent = muxc->parent;
+   int ret;
+
+   /* Switch to the right mux port and perform the transfer. */
+
+   ret = muxc->select(muxc, priv->chan_id);
+   if (ret >= 0)
+   ret = __i2c_transfer(parent, msgs, num);
+   if (muxc->deselect)
+   muxc->deselect(muxc, priv->chan_id);
+
+   return ret;
+}
+
 static int i2c_mux_master_xfer(struct i2c_adapter *adap,
   struct i2c_msg msgs[], int num)
 {
@@ -47,7 +66,29 @@ static int i2c_mux_master_xfer(struct i2c_adapter *adap,
 
ret = muxc->select(muxc, priv->chan_id);
if (ret >= 0)
-   ret = __i2c_transfer(parent, msgs, num);
+   ret = i2c_transfer(parent, msgs, num);
+   if (muxc->deselect)
+   muxc->deselect(muxc, priv->chan_id);
+
+   return ret;
+}
+
+static int __i2c_mux_smbus_xfer(struct i2c_adapter *adap,
+   u16 addr, unsigned short flags,
+   char read_write, u8 command,
+   int size, union i2c_smbus_data *data)
+{
+   struct i2c_mux_priv *priv = adap->algo_data;
+   struct i2c_mux_core *muxc = priv->muxc;
+   struct i2c_adapter *parent = muxc->parent;
+   int ret;
+
+   /* Select the right mux port and perform the transfer. */
+
+   ret = muxc->select(muxc, priv->chan_id);
+   if (ret >= 0)
+   ret = parent->algo->smbus_xfer(parent, addr, flags,
+   read_write, command, size, data);
if (muxc->deselect)
muxc->deselect(muxc, priv->chan_id);
 
@@ -68,8 +109,8 @@ static int 

[PATCH v7 20/24] iio: imu: inv_mpu6050: change the i2c gate to be mux-locked

2016-04-20 Thread Peter Rosin
The root i2c adapter lock is then no longer held by the i2c mux during
accesses behind the i2c gate, and such accesses need to take that lock
just like any other ordinary i2c accesses do.

So, declare the i2c gate mux-locked, and zap the code that makes the
unlocked i2c accesses and just use ordinary regmap_write accesses.

This also happens to fix the deadlock described in
http://patchwork.ozlabs.org/patch/584776/ authored by
Adriana Reus  and submitted by
Daniel Baluta 

--8<--
iio: imu: inv_mpu6050: Fix deadlock between i2c adapter lock and mpu lock

This deadlock occurs if the accel/gyro and the sensor on the auxiliary
I2C (in my setup it's an ak8975) are working at the same time.

Scenario:

  T1T2
   
inv_mpu6050_read_fifo  aux sensor op (eg. ak8975_read_raw)
| |
mutex_lock(_dev->mlock)   i2c_transfer
| |
i2c transaction i2c adapter lock
| |
i2c adapter locki2c_mux_master_xfer
  |
inv_mpu6050_select_bypass
  |
mutex_lock(_dev->mlock)

When we operate on an mpu sensor the order of locking is mpu lock
followed by the i2c adapter lock. However, when we operate the auxiliary
sensor the order of locking is the other way around.

...
--8<--

The reason this patch fixes the deadlock is that T2 does not grab the
i2c adapter lock until the very end (and grabs the newfangled i2c mux
lock where it previously grabbed the i2c adapter lock).

Acked-by: Jonathan Cameron 
Acked-by: Daniel Baluta 
Signed-off-by: Peter Rosin 
---
 Documentation/i2c/i2c-topology|  2 +-
 drivers/iio/imu/inv_mpu6050/inv_mpu_i2c.c | 52 ++-
 2 files changed, 11 insertions(+), 43 deletions(-)

diff --git a/Documentation/i2c/i2c-topology b/Documentation/i2c/i2c-topology
index 27bfd682808d..69b008518454 100644
--- a/Documentation/i2c/i2c-topology
+++ b/Documentation/i2c/i2c-topology
@@ -50,7 +50,7 @@ i2c-mux-pinctrl   Normally parent-locked, mux-locked 
iff
 i2c-mux-reg   Parent-locked
 
 In drivers/iio/
-imu/inv_mpu6050/  Parent-locked
+imu/inv_mpu6050/  Mux-locked
 
 In drivers/media/
 dvb-frontends/m88ds3103   Parent-locked
diff --git a/drivers/iio/imu/inv_mpu6050/inv_mpu_i2c.c 
b/drivers/iio/imu/inv_mpu6050/inv_mpu_i2c.c
index 664a45082d39..2c4188db8634 100644
--- a/drivers/iio/imu/inv_mpu6050/inv_mpu_i2c.c
+++ b/drivers/iio/imu/inv_mpu6050/inv_mpu_i2c.c
@@ -24,45 +24,16 @@ static const struct regmap_config inv_mpu_regmap_config = {
.val_bits = 8,
 };
 
-/*
- * The i2c read/write needs to happen in unlocked mode. As the parent
- * adapter is common. If we use locked versions, it will fail as
- * the mux adapter will lock the parent i2c adapter, while calling
- * select/deselect functions.
- */
-static int inv_mpu6050_write_reg_unlocked(struct i2c_client *client,
- u8 reg, u8 d)
-{
-   int ret;
-   u8 buf[2] = {reg, d};
-   struct i2c_msg msg[1] = {
-   {
-   .addr = client->addr,
-   .flags = 0,
-   .len = sizeof(buf),
-   .buf = buf,
-   }
-   };
-
-   ret = __i2c_transfer(client->adapter, msg, 1);
-   if (ret != 1)
-   return ret;
-
-   return 0;
-}
-
 static int inv_mpu6050_select_bypass(struct i2c_mux_core *muxc, u32 chan_id)
 {
-   struct i2c_client *client = i2c_mux_priv(muxc);
-   struct iio_dev *indio_dev = dev_get_drvdata(>dev);
+   struct iio_dev *indio_dev = i2c_mux_priv(muxc);
struct inv_mpu6050_state *st = iio_priv(indio_dev);
int ret = 0;
 
/* Use the same mutex which was used everywhere to protect power-op */
mutex_lock(_dev->mlock);
if (!st->powerup_count) {
-   ret = inv_mpu6050_write_reg_unlocked(client,
-st->reg->pwr_mgmt_1, 0);
+   ret = regmap_write(st->map, st->reg->pwr_mgmt_1, 0);
if (ret)
goto write_error;
 
@@ -71,10 +42,9 @@ static int inv_mpu6050_select_bypass(struct i2c_mux_core 
*muxc, u32 chan_id)
}
if (!ret) {
st->powerup_count++;
-   ret = inv_mpu6050_write_reg_unlocked(client,
-st->reg->int_pin_cfg,
-INV_MPU6050_INT_PIN_CFG |
- 

[PATCH v7 21/24] [media] si2168: change the i2c gate to be mux-locked

2016-04-20 Thread Peter Rosin
From: Antti Palosaari 

The root i2c adapter lock is then no longer held by the i2c mux during
accesses behind the i2c gate, and such accesses need to take that lock
just like any other ordinary i2c accesses do.

So, declare the i2c gate mux-locked, and zap the code that makes the
i2c accesses unlocked. But add a mutex so that firmware commands are
still serialized.

Signed-off-by: Antti Palosaari 
Signed-off-by: Peter Rosin 
---
 Documentation/i2c/i2c-topology|  2 +-
 drivers/media/dvb-frontends/si2168.c  | 83 ---
 drivers/media/dvb-frontends/si2168_priv.h |  1 +
 3 files changed, 22 insertions(+), 64 deletions(-)

diff --git a/Documentation/i2c/i2c-topology b/Documentation/i2c/i2c-topology
index 69b008518454..5e40802f0be2 100644
--- a/Documentation/i2c/i2c-topology
+++ b/Documentation/i2c/i2c-topology
@@ -56,7 +56,7 @@ In drivers/media/
 dvb-frontends/m88ds3103   Parent-locked
 dvb-frontends/rtl2830 Parent-locked
 dvb-frontends/rtl2832 Parent-locked
-dvb-frontends/si2168  Parent-locked
+dvb-frontends/si2168  Mux-locked
 usb/cx231xx/  Parent-locked
 
 
diff --git a/drivers/media/dvb-frontends/si2168.c 
b/drivers/media/dvb-frontends/si2168.c
index 5583827c386e..108a069fa1ae 100644
--- a/drivers/media/dvb-frontends/si2168.c
+++ b/drivers/media/dvb-frontends/si2168.c
@@ -18,53 +18,23 @@
 
 static const struct dvb_frontend_ops si2168_ops;
 
-/* Own I2C adapter locking is needed because of I2C gate logic. */
-static int si2168_i2c_master_send_unlocked(const struct i2c_client *client,
-  const char *buf, int count)
-{
-   int ret;
-   struct i2c_msg msg = {
-   .addr = client->addr,
-   .flags = 0,
-   .len = count,
-   .buf = (char *)buf,
-   };
-
-   ret = __i2c_transfer(client->adapter, , 1);
-   return (ret == 1) ? count : ret;
-}
-
-static int si2168_i2c_master_recv_unlocked(const struct i2c_client *client,
-  char *buf, int count)
-{
-   int ret;
-   struct i2c_msg msg = {
-   .addr = client->addr,
-   .flags = I2C_M_RD,
-   .len = count,
-   .buf = buf,
-   };
-
-   ret = __i2c_transfer(client->adapter, , 1);
-   return (ret == 1) ? count : ret;
-}
-
 /* execute firmware command */
-static int si2168_cmd_execute_unlocked(struct i2c_client *client,
-  struct si2168_cmd *cmd)
+static int si2168_cmd_execute(struct i2c_client *client, struct si2168_cmd 
*cmd)
 {
+   struct si2168_dev *dev = i2c_get_clientdata(client);
int ret;
unsigned long timeout;
 
+   mutex_lock(>i2c_mutex);
+
if (cmd->wlen) {
/* write cmd and args for firmware */
-   ret = si2168_i2c_master_send_unlocked(client, cmd->args,
- cmd->wlen);
+   ret = i2c_master_send(client, cmd->args, cmd->wlen);
if (ret < 0) {
-   goto err;
+   goto err_mutex_unlock;
} else if (ret != cmd->wlen) {
ret = -EREMOTEIO;
-   goto err;
+   goto err_mutex_unlock;
}
}
 
@@ -73,13 +43,12 @@ static int si2168_cmd_execute_unlocked(struct i2c_client 
*client,
#define TIMEOUT 70
timeout = jiffies + msecs_to_jiffies(TIMEOUT);
while (!time_after(jiffies, timeout)) {
-   ret = si2168_i2c_master_recv_unlocked(client, cmd->args,
- cmd->rlen);
+   ret = i2c_master_recv(client, cmd->args, cmd->rlen);
if (ret < 0) {
-   goto err;
+   goto err_mutex_unlock;
} else if (ret != cmd->rlen) {
ret = -EREMOTEIO;
-   goto err;
+   goto err_mutex_unlock;
}
 
/* firmware ready? */
@@ -94,32 +63,23 @@ static int si2168_cmd_execute_unlocked(struct i2c_client 
*client,
/* error bit set? */
if ((cmd->args[0] >> 6) & 0x01) {
ret = -EREMOTEIO;
-   goto err;
+   goto err_mutex_unlock;
}
 
if (!((cmd->args[0] >> 7) & 0x01)) {
ret = -ETIMEDOUT;
-   goto err;
+   goto err_mutex_unlock;
}
}
 
+   mutex_unlock(>i2c_mutex);
return 0;
-err:
+err_mutex_unlock:
+   mutex_unlock(>i2c_mutex);
dev_dbg(>dev, "failed=%d\n", ret);
return ret;
 }

[PATCH v7 23/24] [media] rtl2832_sdr: get rid of empty regmap wrappers

2016-04-20 Thread Peter Rosin
Reviewed-by: Antti Palosaari 
Signed-off-by: Peter Rosin 
---
 drivers/media/dvb-frontends/rtl2832_sdr.c | 302 +-
 1 file changed, 132 insertions(+), 170 deletions(-)

diff --git a/drivers/media/dvb-frontends/rtl2832_sdr.c 
b/drivers/media/dvb-frontends/rtl2832_sdr.c
index 6a6b1debe277..47a480a7d46c 100644
--- a/drivers/media/dvb-frontends/rtl2832_sdr.c
+++ b/drivers/media/dvb-frontends/rtl2832_sdr.c
@@ -120,6 +120,7 @@ struct rtl2832_sdr_dev {
unsigned long flags;
 
struct platform_device *pdev;
+   struct regmap *regmap;
 
struct video_device vdev;
struct v4l2_device v4l2_dev;
@@ -164,47 +165,6 @@ struct rtl2832_sdr_dev {
unsigned long jiffies_next;
 };
 
-/* write multiple registers */
-static int rtl2832_sdr_wr_regs(struct rtl2832_sdr_dev *dev, u16 reg,
-   const u8 *val, int len)
-{
-   struct platform_device *pdev = dev->pdev;
-   struct rtl2832_sdr_platform_data *pdata = pdev->dev.platform_data;
-   struct regmap *regmap = pdata->regmap;
-
-   return regmap_bulk_write(regmap, reg, val, len);
-}
-
-#if 0
-/* read multiple registers */
-static int rtl2832_sdr_rd_regs(struct rtl2832_sdr_dev *dev, u16 reg, u8 *val,
-   int len)
-{
-   struct platform_device *pdev = dev->pdev;
-   struct rtl2832_sdr_platform_data *pdata = pdev->dev.platform_data;
-   struct regmap *regmap = pdata->regmap;
-
-   return regmap_bulk_read(regmap, reg, val, len);
-}
-#endif
-
-/* write single register */
-static int rtl2832_sdr_wr_reg(struct rtl2832_sdr_dev *dev, u16 reg, u8 val)
-{
-   return rtl2832_sdr_wr_regs(dev, reg, , 1);
-}
-
-/* write single register with mask */
-static int rtl2832_sdr_wr_reg_mask(struct rtl2832_sdr_dev *dev, u16 reg,
-   u8 val, u8 mask)
-{
-   struct platform_device *pdev = dev->pdev;
-   struct rtl2832_sdr_platform_data *pdata = pdev->dev.platform_data;
-   struct regmap *regmap = pdata->regmap;
-
-   return regmap_update_bits(regmap, reg, mask, val);
-}
-
 /* Private functions */
 static struct rtl2832_sdr_frame_buf *rtl2832_sdr_get_next_fill_buf(
struct rtl2832_sdr_dev *dev)
@@ -559,11 +519,11 @@ static int rtl2832_sdr_set_adc(struct rtl2832_sdr_dev 
*dev)
 
f_sr = dev->f_adc;
 
-   ret = rtl2832_sdr_wr_regs(dev, 0x13e, "\x00\x00", 2);
+   ret = regmap_bulk_write(dev->regmap, 0x13e, "\x00\x00", 2);
if (ret)
goto err;
 
-   ret = rtl2832_sdr_wr_regs(dev, 0x115, "\x00\x00\x00\x00", 4);
+   ret = regmap_bulk_write(dev->regmap, 0x115, "\x00\x00\x00\x00", 4);
if (ret)
goto err;
 
@@ -589,7 +549,7 @@ static int rtl2832_sdr_set_adc(struct rtl2832_sdr_dev *dev)
buf[1] = (u32tmp >>  8) & 0xff;
buf[2] = (u32tmp >>  0) & 0xff;
 
-   ret = rtl2832_sdr_wr_regs(dev, 0x119, buf, 3);
+   ret = regmap_bulk_write(dev->regmap, 0x119, buf, 3);
if (ret)
goto err;
 
@@ -603,15 +563,15 @@ static int rtl2832_sdr_set_adc(struct rtl2832_sdr_dev 
*dev)
u8tmp2 = 0xcd; /* enable ADC I, ADC Q */
}
 
-   ret = rtl2832_sdr_wr_reg(dev, 0x1b1, u8tmp1);
+   ret = regmap_write(dev->regmap, 0x1b1, u8tmp1);
if (ret)
goto err;
 
-   ret = rtl2832_sdr_wr_reg(dev, 0x008, u8tmp2);
+   ret = regmap_write(dev->regmap, 0x008, u8tmp2);
if (ret)
goto err;
 
-   ret = rtl2832_sdr_wr_reg(dev, 0x006, 0x80);
+   ret = regmap_write(dev->regmap, 0x006, 0x80);
if (ret)
goto err;
 
@@ -622,168 +582,169 @@ static int rtl2832_sdr_set_adc(struct rtl2832_sdr_dev 
*dev)
buf[1] = (u32tmp >> 16) & 0xff;
buf[2] = (u32tmp >>  8) & 0xff;
buf[3] = (u32tmp >>  0) & 0xff;
-   ret = rtl2832_sdr_wr_regs(dev, 0x19f, buf, 4);
+   ret = regmap_bulk_write(dev->regmap, 0x19f, buf, 4);
if (ret)
goto err;
 
/* low-pass filter */
-   ret = rtl2832_sdr_wr_regs(dev, 0x11c,
-   
"\xca\xdc\xd7\xd8\xe0\xf2\x0e\x35\x06\x50\x9c\x0d\x71\x11\x14\x71\x74\x19\x41\xa5",
-   20);
+   ret = regmap_bulk_write(dev->regmap, 0x11c,
+   
"\xca\xdc\xd7\xd8\xe0\xf2\x0e\x35\x06\x50\x9c\x0d\x71\x11\x14\x71\x74\x19\x41\xa5",
+   20);
if (ret)
goto err;
 
-   ret = rtl2832_sdr_wr_regs(dev, 0x017, "\x11\x10", 2);
+   ret = regmap_bulk_write(dev->regmap, 0x017, "\x11\x10", 2);
if (ret)
goto err;
 
/* mode */
-   ret = rtl2832_sdr_wr_regs(dev, 0x019, "\x05", 1);
+   ret = regmap_write(dev->regmap, 0x019, 0x05);
if (ret)
goto err;
 
-   ret = rtl2832_sdr_wr_regs(dev, 0x01a, "\x1b\x16\x0d\x06\x01\xff", 6);
+   ret = regmap_bulk_write(dev->regmap, 0x01a,
+   

[PATCH v7 13/24] [media] cx231xx: convert to use an explicit i2c mux core

2016-04-20 Thread Peter Rosin
Allocate an explicit i2c mux core to handle parent and child adapters
etc. Update the select op to be in terms of the i2c mux core instead
of the child adapter.

Signed-off-by: Peter Rosin 
---
 drivers/media/usb/cx231xx/cx231xx-core.c |  6 ++--
 drivers/media/usb/cx231xx/cx231xx-i2c.c  | 47 
 drivers/media/usb/cx231xx/cx231xx.h  |  4 ++-
 3 files changed, 31 insertions(+), 26 deletions(-)

diff --git a/drivers/media/usb/cx231xx/cx231xx-core.c 
b/drivers/media/usb/cx231xx/cx231xx-core.c
index f497888d94bf..f7aac2abd783 100644
--- a/drivers/media/usb/cx231xx/cx231xx-core.c
+++ b/drivers/media/usb/cx231xx/cx231xx-core.c
@@ -1304,6 +1304,9 @@ int cx231xx_dev_init(struct cx231xx *dev)
cx231xx_i2c_register(>i2c_bus[1]);
cx231xx_i2c_register(>i2c_bus[2]);
 
+   errCode = cx231xx_i2c_mux_create(dev);
+   if (errCode < 0)
+   return errCode;
cx231xx_i2c_mux_register(dev, 0);
cx231xx_i2c_mux_register(dev, 1);
 
@@ -1426,8 +1429,7 @@ EXPORT_SYMBOL_GPL(cx231xx_dev_init);
 void cx231xx_dev_uninit(struct cx231xx *dev)
 {
/* Un Initialize I2C bus */
-   cx231xx_i2c_mux_unregister(dev, 1);
-   cx231xx_i2c_mux_unregister(dev, 0);
+   cx231xx_i2c_mux_unregister(dev);
cx231xx_i2c_unregister(>i2c_bus[2]);
cx231xx_i2c_unregister(>i2c_bus[1]);
cx231xx_i2c_unregister(>i2c_bus[0]);
diff --git a/drivers/media/usb/cx231xx/cx231xx-i2c.c 
b/drivers/media/usb/cx231xx/cx231xx-i2c.c
index a29c345b027d..473cd3433fe5 100644
--- a/drivers/media/usb/cx231xx/cx231xx-i2c.c
+++ b/drivers/media/usb/cx231xx/cx231xx-i2c.c
@@ -557,40 +557,41 @@ int cx231xx_i2c_unregister(struct cx231xx_i2c *bus)
  * cx231xx_i2c_mux_select()
  * switch i2c master number 1 between port1 and port3
  */
-static int cx231xx_i2c_mux_select(struct i2c_adapter *adap,
-   void *mux_priv, u32 chan_id)
+static int cx231xx_i2c_mux_select(struct i2c_mux_core *muxc, u32 chan_id)
 {
-   struct cx231xx *dev = mux_priv;
+   struct cx231xx *dev = i2c_mux_priv(muxc);
 
return cx231xx_enable_i2c_port_3(dev, chan_id);
 }
 
+int cx231xx_i2c_mux_create(struct cx231xx *dev)
+{
+   dev->muxc = i2c_mux_alloc(>i2c_bus[1].i2c_adap, dev->dev, 2, 0, 0,
+ cx231xx_i2c_mux_select, NULL);
+   if (!dev->muxc)
+   return -ENOMEM;
+   dev->muxc->priv = dev;
+   return 0;
+}
+
 int cx231xx_i2c_mux_register(struct cx231xx *dev, int mux_no)
 {
-   struct i2c_adapter *i2c_parent = >i2c_bus[1].i2c_adap;
-   /* what is the correct mux_dev? */
-   struct device *mux_dev = dev->dev;
-
-   dev->i2c_mux_adap[mux_no] = i2c_add_mux_adapter(i2c_parent,
-   mux_dev,
-   dev /* mux_priv */,
-   0,
-   mux_no /* chan_id */,
-   0 /* class */,
-   _i2c_mux_select,
-   NULL);
-
-   if (!dev->i2c_mux_adap[mux_no])
+   int rc;
+
+   rc = i2c_mux_add_adapter(dev->muxc,
+0,
+mux_no /* chan_id */,
+0 /* class */);
+   if (rc)
dev_warn(dev->dev,
 "i2c mux %d register FAILED\n", mux_no);
 
-   return 0;
+   return rc;
 }
 
-void cx231xx_i2c_mux_unregister(struct cx231xx *dev, int mux_no)
+void cx231xx_i2c_mux_unregister(struct cx231xx *dev)
 {
-   i2c_del_mux_adapter(dev->i2c_mux_adap[mux_no]);
-   dev->i2c_mux_adap[mux_no] = NULL;
+   i2c_mux_del_adapters(dev->muxc);
 }
 
 struct i2c_adapter *cx231xx_get_i2c_adap(struct cx231xx *dev, int i2c_port)
@@ -603,9 +604,9 @@ struct i2c_adapter *cx231xx_get_i2c_adap(struct cx231xx 
*dev, int i2c_port)
case I2C_2:
return >i2c_bus[2].i2c_adap;
case I2C_1_MUX_1:
-   return dev->i2c_mux_adap[0];
+   return dev->muxc->adapter[0];
case I2C_1_MUX_3:
-   return dev->i2c_mux_adap[1];
+   return dev->muxc->adapter[1];
default:
return NULL;
}
diff --git a/drivers/media/usb/cx231xx/cx231xx.h 
b/drivers/media/usb/cx231xx/cx231xx.h
index 69f6d20870f5..90c867683076 100644
--- a/drivers/media/usb/cx231xx/cx231xx.h
+++ b/drivers/media/usb/cx231xx/cx231xx.h
@@ -624,6 +624,7 @@ struct cx231xx {
 
/* I2C adapters: Master 1 & 2 (External) & Master 3 (Internal only) */
struct cx231xx_i2c i2c_bus[3];
+   struct i2c_mux_core *muxc;
struct i2c_adapter *i2c_mux_adap[2];
 
unsigned int xc_fw_load_done:1;
@@ -760,8 +761,9 @@ int cx231xx_reset_analog_tuner(struct cx231xx *dev);
 void cx231xx_do_i2c_scan(struct cx231xx *dev, int i2c_port);
 int cx231xx_i2c_register(struct cx231xx_i2c *bus);
 int cx231xx_i2c_unregister(struct cx231xx_i2c 

[PATCH v7 16/24] i2c: allow adapter drivers to override the adapter locking

2016-04-20 Thread Peter Rosin
Add i2c_lock_bus() and i2c_unlock_bus(), which call the new lock_bus and
unlock_bus ops in the adapter. These funcs/ops take an additional flags
argument that indicates for what purpose the adapter is locked.

There are two flags, I2C_LOCK_ADAPTER and I2C_LOCK_SEGMENT, but they are
both implemented the same. For now. Locking the adapter means that the
whole bus is locked, locking the segment means that only the current bus
segment is locked (i.e. i2c traffic on the parent side of mux is still
allowed even if the child side of the mux is locked.

Also support a trylock_bus op (but no function to call it, as it is not
expected to be needed outside of the i2c core).

Implement i2c_lock_adapter/i2c_unlock_adapter in terms of the new locking
scheme (i.e. lock with the I2C_LOCK_ADAPTER flag).

Annotate some of the locking with explicit I2C_LOCK_SEGMENT flags.

Signed-off-by: Peter Rosin 
---
 drivers/i2c/i2c-core.c | 46 --
 include/linux/i2c.h| 28 ++--
 2 files changed, 54 insertions(+), 20 deletions(-)

diff --git a/drivers/i2c/i2c-core.c b/drivers/i2c/i2c-core.c
index 0f2f8484e8ec..21f46d011c33 100644
--- a/drivers/i2c/i2c-core.c
+++ b/drivers/i2c/i2c-core.c
@@ -960,10 +960,12 @@ static int i2c_check_addr_busy(struct i2c_adapter 
*adapter, int addr)
 }
 
 /**
- * i2c_lock_adapter - Get exclusive access to an I2C bus segment
+ * i2c_adapter_lock_bus - Get exclusive access to an I2C bus segment
  * @adapter: Target I2C bus segment
+ * @flags: I2C_LOCK_ADAPTER locks the root i2c adapter, I2C_LOCK_SEGMENT
+ * locks only this branch in the adapter tree
  */
-void i2c_lock_adapter(struct i2c_adapter *adapter)
+static void i2c_adapter_lock_bus(struct i2c_adapter *adapter, int flags)
 {
struct i2c_adapter *parent = i2c_parent_is_i2c_adapter(adapter);
 
@@ -972,27 +974,30 @@ void i2c_lock_adapter(struct i2c_adapter *adapter)
else
rt_mutex_lock(>bus_lock);
 }
-EXPORT_SYMBOL_GPL(i2c_lock_adapter);
 
 /**
- * i2c_trylock_adapter - Try to get exclusive access to an I2C bus segment
+ * i2c_adapter_trylock_bus - Try to get exclusive access to an I2C bus segment
  * @adapter: Target I2C bus segment
+ * @flags: I2C_LOCK_ADAPTER trylocks the root i2c adapter, I2C_LOCK_SEGMENT
+ * trylocks only this branch in the adapter tree
  */
-static int i2c_trylock_adapter(struct i2c_adapter *adapter)
+static int i2c_adapter_trylock_bus(struct i2c_adapter *adapter, int flags)
 {
struct i2c_adapter *parent = i2c_parent_is_i2c_adapter(adapter);
 
if (parent)
-   return i2c_trylock_adapter(parent);
+   return parent->trylock_bus(parent, flags);
else
return rt_mutex_trylock(>bus_lock);
 }
 
 /**
- * i2c_unlock_adapter - Release exclusive access to an I2C bus segment
+ * i2c_adapter_unlock_bus - Release exclusive access to an I2C bus segment
  * @adapter: Target I2C bus segment
+ * @flags: I2C_LOCK_ADAPTER unlocks the root i2c adapter, I2C_LOCK_SEGMENT
+ * unlocks only this branch in the adapter tree
  */
-void i2c_unlock_adapter(struct i2c_adapter *adapter)
+static void i2c_adapter_unlock_bus(struct i2c_adapter *adapter, int flags)
 {
struct i2c_adapter *parent = i2c_parent_is_i2c_adapter(adapter);
 
@@ -1001,7 +1006,6 @@ void i2c_unlock_adapter(struct i2c_adapter *adapter)
else
rt_mutex_unlock(>bus_lock);
 }
-EXPORT_SYMBOL_GPL(i2c_unlock_adapter);
 
 static void i2c_dev_set_name(struct i2c_adapter *adap,
 struct i2c_client *client)
@@ -1547,6 +1551,12 @@ static int i2c_register_adapter(struct i2c_adapter *adap)
return -EINVAL;
}
 
+   if (!adap->lock_bus) {
+   adap->lock_bus = i2c_adapter_lock_bus;
+   adap->trylock_bus = i2c_adapter_trylock_bus;
+   adap->unlock_bus = i2c_adapter_unlock_bus;
+   }
+
rt_mutex_init(>bus_lock);
mutex_init(>userspace_clients_lock);
INIT_LIST_HEAD(>userspace_clients);
@@ -2315,16 +2325,16 @@ int i2c_transfer(struct i2c_adapter *adap, struct 
i2c_msg *msgs, int num)
 #endif
 
if (in_atomic() || irqs_disabled()) {
-   ret = i2c_trylock_adapter(adap);
+   ret = adap->trylock_bus(adap, I2C_LOCK_SEGMENT);
if (!ret)
/* I2C activity is ongoing. */
return -EAGAIN;
} else {
-   i2c_lock_adapter(adap);
+   i2c_lock_bus(adap, I2C_LOCK_SEGMENT);
}
 
ret = __i2c_transfer(adap, msgs, num);
-   i2c_unlock_adapter(adap);
+   i2c_unlock_bus(adap, I2C_LOCK_SEGMENT);
 
return ret;
} else {
@@ -3099,7 +3109,7 @@ s32 i2c_smbus_xfer(struct i2c_adapter *adapter, u16 addr, 
unsigned short flags,
flags &= 

[PATCH v7 01/24] i2c-mux: add common data for every i2c-mux instance

2016-04-20 Thread Peter Rosin
All i2c-muxes have a parent adapter and one or many child
adapters. A mux also has some means of selection. Previously,
this was stored per child adapter, but it is only needed
to keep track of this per mux.

Add an i2c mux core, that keeps track of this consistently.

Also add some glue for users of the old interface, which will
create one implicit mux core per child adapter.

Signed-off-by: Peter Rosin 
---
 drivers/i2c/i2c-mux.c   | 175 
 include/linux/i2c-mux.h |  34 ++
 2 files changed, 168 insertions(+), 41 deletions(-)

diff --git a/drivers/i2c/i2c-mux.c b/drivers/i2c/i2c-mux.c
index d4022878b2f0..5ce1b0704cb5 100644
--- a/drivers/i2c/i2c-mux.c
+++ b/drivers/i2c/i2c-mux.c
@@ -28,33 +28,34 @@
 #include 
 
 /* multiplexer per channel data */
+struct i2c_mux_priv_old {
+   void *mux_priv;
+   int (*select)(struct i2c_adapter *, void *mux_priv, u32 chan_id);
+   int (*deselect)(struct i2c_adapter *, void *mux_priv, u32 chan_id);
+};
+
 struct i2c_mux_priv {
struct i2c_adapter adap;
struct i2c_algorithm algo;
-
-   struct i2c_adapter *parent;
-   struct device *mux_dev;
-   void *mux_priv;
+   struct i2c_mux_core *muxc;
u32 chan_id;
-
-   int (*select)(struct i2c_adapter *, void *mux_priv, u32 chan_id);
-   int (*deselect)(struct i2c_adapter *, void *mux_priv, u32 chan_id);
 };
 
 static int i2c_mux_master_xfer(struct i2c_adapter *adap,
   struct i2c_msg msgs[], int num)
 {
struct i2c_mux_priv *priv = adap->algo_data;
-   struct i2c_adapter *parent = priv->parent;
+   struct i2c_mux_core *muxc = priv->muxc;
+   struct i2c_adapter *parent = muxc->parent;
int ret;
 
/* Switch to the right mux port and perform the transfer. */
 
-   ret = priv->select(parent, priv->mux_priv, priv->chan_id);
+   ret = muxc->select(muxc, priv->chan_id);
if (ret >= 0)
ret = __i2c_transfer(parent, msgs, num);
-   if (priv->deselect)
-   priv->deselect(parent, priv->mux_priv, priv->chan_id);
+   if (muxc->deselect)
+   muxc->deselect(muxc, priv->chan_id);
 
return ret;
 }
@@ -65,17 +66,18 @@ static int i2c_mux_smbus_xfer(struct i2c_adapter *adap,
  int size, union i2c_smbus_data *data)
 {
struct i2c_mux_priv *priv = adap->algo_data;
-   struct i2c_adapter *parent = priv->parent;
+   struct i2c_mux_core *muxc = priv->muxc;
+   struct i2c_adapter *parent = muxc->parent;
int ret;
 
/* Select the right mux port and perform the transfer. */
 
-   ret = priv->select(parent, priv->mux_priv, priv->chan_id);
+   ret = muxc->select(muxc, priv->chan_id);
if (ret >= 0)
ret = parent->algo->smbus_xfer(parent, addr, flags,
read_write, command, size, data);
-   if (priv->deselect)
-   priv->deselect(parent, priv->mux_priv, priv->chan_id);
+   if (muxc->deselect)
+   muxc->deselect(muxc, priv->chan_id);
 
return ret;
 }
@@ -84,7 +86,7 @@ static int i2c_mux_smbus_xfer(struct i2c_adapter *adap,
 static u32 i2c_mux_functionality(struct i2c_adapter *adap)
 {
struct i2c_mux_priv *priv = adap->algo_data;
-   struct i2c_adapter *parent = priv->parent;
+   struct i2c_adapter *parent = priv->muxc->parent;
 
return parent->algo->functionality(parent);
 }
@@ -102,6 +104,20 @@ static unsigned int i2c_mux_parent_classes(struct 
i2c_adapter *parent)
return class;
 }
 
+static int i2c_mux_select(struct i2c_mux_core *muxc, u32 chan)
+{
+   struct i2c_mux_priv_old *priv = i2c_mux_priv(muxc);
+
+   return priv->select(muxc->parent, priv->mux_priv, chan);
+}
+
+static int i2c_mux_deselect(struct i2c_mux_core *muxc, u32 chan)
+{
+   struct i2c_mux_priv_old *priv = i2c_mux_priv(muxc);
+
+   return priv->deselect(muxc->parent, priv->mux_priv, chan);
+}
+
 struct i2c_adapter *i2c_add_mux_adapter(struct i2c_adapter *parent,
struct device *mux_dev,
void *mux_priv, u32 force_nr, u32 chan_id,
@@ -111,21 +127,77 @@ struct i2c_adapter *i2c_add_mux_adapter(struct 
i2c_adapter *parent,
int (*deselect) (struct i2c_adapter *,
 void *, u32))
 {
+   struct i2c_mux_core *muxc;
+   struct i2c_mux_priv_old *priv;
+   int ret;
+
+   muxc = i2c_mux_alloc(parent, mux_dev, 1, sizeof(*priv), 0,
+i2c_mux_select, i2c_mux_deselect);
+   if (!muxc)
+   return NULL;
+
+   priv = i2c_mux_priv(muxc);
+   priv->select = select;
+   priv->deselect = deselect;
+   priv->mux_priv = mux_priv;
+
+   ret = i2c_mux_add_adapter(muxc, force_nr, chan_id, class);
+   if (ret) {
+   

[PATCH v7 06/24] i2c: i2c-mux-pca954x: convert to use an explicit i2c mux core

2016-04-20 Thread Peter Rosin
Allocate an explicit i2c mux core to handle parent and child adapters
etc. Update the select/deselect ops to be in terms of the i2c mux core
instead of the child adapter.

Add a mask to handle the case where not all child adapters should
cause a mux deselect to happen, now that there is a common deselect op
for all child adapters.

Signed-off-by: Peter Rosin 
---
 drivers/i2c/muxes/i2c-mux-pca954x.c | 61 ++---
 1 file changed, 30 insertions(+), 31 deletions(-)

diff --git a/drivers/i2c/muxes/i2c-mux-pca954x.c 
b/drivers/i2c/muxes/i2c-mux-pca954x.c
index acfcef3d4068..528e755c468f 100644
--- a/drivers/i2c/muxes/i2c-mux-pca954x.c
+++ b/drivers/i2c/muxes/i2c-mux-pca954x.c
@@ -60,9 +60,10 @@ enum pca_type {
 
 struct pca954x {
enum pca_type type;
-   struct i2c_adapter *virt_adaps[PCA954X_MAX_NCHANS];
 
u8 last_chan;   /* last register value */
+   u8 deselect;
+   struct i2c_client *client;
 };
 
 struct chip_desc {
@@ -146,10 +147,10 @@ static int pca954x_reg_write(struct i2c_adapter *adap,
return ret;
 }
 
-static int pca954x_select_chan(struct i2c_adapter *adap,
-  void *client, u32 chan)
+static int pca954x_select_chan(struct i2c_mux_core *muxc, u32 chan)
 {
-   struct pca954x *data = i2c_get_clientdata(client);
+   struct pca954x *data = i2c_mux_priv(muxc);
+   struct i2c_client *client = data->client;
const struct chip_desc *chip = [data->type];
u8 regval;
int ret = 0;
@@ -162,21 +163,24 @@ static int pca954x_select_chan(struct i2c_adapter *adap,
 
/* Only select the channel if its different from the last channel */
if (data->last_chan != regval) {
-   ret = pca954x_reg_write(adap, client, regval);
+   ret = pca954x_reg_write(muxc->parent, client, regval);
data->last_chan = regval;
}
 
return ret;
 }
 
-static int pca954x_deselect_mux(struct i2c_adapter *adap,
-   void *client, u32 chan)
+static int pca954x_deselect_mux(struct i2c_mux_core *muxc, u32 chan)
 {
-   struct pca954x *data = i2c_get_clientdata(client);
+   struct pca954x *data = i2c_mux_priv(muxc);
+   struct i2c_client *client = data->client;
+
+   if (!(data->deselect & (1 << chan)))
+   return 0;
 
/* Deselect active channel */
data->last_chan = 0;
-   return pca954x_reg_write(adap, client, data->last_chan);
+   return pca954x_reg_write(muxc->parent, client, data->last_chan);
 }
 
 /*
@@ -191,17 +195,22 @@ static int pca954x_probe(struct i2c_client *client,
bool idle_disconnect_dt;
struct gpio_desc *gpio;
int num, force, class;
+   struct i2c_mux_core *muxc;
struct pca954x *data;
int ret;
 
if (!i2c_check_functionality(adap, I2C_FUNC_SMBUS_BYTE))
return -ENODEV;
 
-   data = devm_kzalloc(>dev, sizeof(struct pca954x), GFP_KERNEL);
-   if (!data)
+   muxc = i2c_mux_alloc(adap, >dev,
+PCA954X_MAX_NCHANS, sizeof(*data), 0,
+pca954x_select_chan, pca954x_deselect_mux);
+   if (!muxc)
return -ENOMEM;
+   data = i2c_mux_priv(muxc);
 
-   i2c_set_clientdata(client, data);
+   i2c_set_clientdata(client, muxc);
+   data->client = client;
 
/* Get the mux out of reset if a reset GPIO is specified. */
gpio = devm_gpiod_get_optional(>dev, "reset", GPIOD_OUT_LOW);
@@ -238,16 +247,13 @@ static int pca954x_probe(struct i2c_client *client,
/* discard unconfigured channels */
break;
idle_disconnect_pd = pdata->modes[num].deselect_on_exit;
+   data->deselect |= (idle_disconnect_pd
+  || idle_disconnect_dt) << num;
}
 
-   data->virt_adaps[num] =
-   i2c_add_mux_adapter(adap, >dev, client,
-   force, num, class, pca954x_select_chan,
-   (idle_disconnect_pd || idle_disconnect_dt)
-   ? pca954x_deselect_mux : NULL);
+   ret = i2c_mux_add_adapter(muxc, force, num, class);
 
-   if (data->virt_adaps[num] == NULL) {
-   ret = -ENODEV;
+   if (ret) {
dev_err(>dev,
"failed to register multiplexed adapter"
" %d as bus %d\n", num, force);
@@ -263,23 +269,15 @@ static int pca954x_probe(struct i2c_client *client,
return 0;
 
 virt_reg_failed:
-   for (num--; num >= 0; num--)
-   i2c_del_mux_adapter(data->virt_adaps[num]);
+   i2c_mux_del_adapters(muxc);
return ret;
 }
 
 static int pca954x_remove(struct i2c_client *client)
 

[PATCH v7 00/24] i2c mux cleanup and locking update

2016-04-20 Thread Peter Rosin
Hi!

I have a pair of boards with this i2c topology:

   GPIO ---|  -- BAT1
|  v /
   I2C  -+--B---+ MUX
 |   \
   EEPROM -- BAT2

(B denotes the boundary between the boards)

The problem with this is that the GPIO controller sits on the same i2c bus
that it MUXes. For pca954x devices this is worked around by using unlocked
transfers when updating the MUX. I have no such luck as the GPIO is a general
purpose IO expander and the MUX is just a random bidirectional MUX, unaware
of the fact that it is muxing an i2c bus. Extending unlocked transfers
into the GPIO subsystem is too ugly to even think about. But the general hw
approach is sane in my opinion, with the number of connections between the
two boards minimized. To put it plainly, I need support for it.

So, I observe that while it is needed to have the i2c bus locked during the
actual MUX update in order to avoid random garbage on the slave side, it
is not strictly a must to have it locked over the whole sequence of a full
select-transfer-deselect operation. The MUX itself needs to be locked, so
transfers to clients behind the mux are serialized, and the MUX needs to be
stable during all i2c traffic (otherwise individual mux slave segments
might see garbage).

This series accomplishes this by adding code to i2c-mux-gpio and
i2c-mux-pinctrl that determines if all involved devices used to update the
mux are controlled by the same root i2c adapter that is muxed. When this
is the case, the select-transfer-deselect operations should be locked
individually to avoid the deadlock. The i2c bus *is* still locked
during muxing, since the muxing happens as part of i2c transfers. This
is true even if the MUX is updated with several transfers to the GPIO (at
least as long as *all* MUX changes are using the i2c master bus). A lock
is added to i2c adapters that muxes on that adapter grab, so that transfers
through the muxes are serialized.

Concerns:
- The locking is perhaps too complex?
- I worry about the priority inheritance aspect of the adapter lock. When
  the transfers behind the mux are divided into select-transfer-deselect all
  locked individually, low priority transfers get more chances to interfere
  with high priority transfers.
- When doing an i2c_transfer() in_atomic() context or with irqs_disabled(),
  there is a higher possibility that the mux is not returned to its idle
  state after a failed (-EAGAIN) transfer due to trylock.
- Is the detection of i2c-controlled gpios and pinctrls sane (i.e. the
  usage of the new i2c_root_adapter() function in 18/24)?

To summarize the series, there's some i2c-mux infrastructure cleanup work
first (I think that part stands by itself as desireable regardless), the
locking changes are in 16/24 and after with the real meat in 18/24. There
is some documentation added in 19/24 while 20/24 and after are cleanups to
existing drivers utilizing the new stuff.

PS. needs a bunch of testing, I do not have access to all the involved hw.

Thanks to those who have ested this series so far. At this point, only
patches 01 through 15 are planned for 4.6, and the rest will hopefully
follow later, so lets focus of the cleanup work that enables the real
work later in the series.

Antti, you reviewed 09 through 12 for v5, and even though they changed
slightly due to the changes in v7 I have kept your reviewed tags, since
I classified the changes as mechanical. I hope this is ok.

Similarly, Jonathan and Rob acked patch 08 and 14 respectively, and these
patches have the same kind of mechanical changes so I have kept the acks.
I hope this is also ok.

I have also kept the acks and review tags on patches 20 and forward since
the fixups to adjust to the changes earlier in the series were completely
trivial.

This series can also be pulled from github, if that is preferred:

-
The following changes since commit f55532a0c0b8bb6148f4e07853b876ef73bc69ca:

  Linux 4.6-rc1 (2016-03-26 16:03:24 -0700)

are available in the git repository at:

  https://github.com/peda-r/i2c-mux.git mux-core-and-locking-7

for you to fetch changes up to f725ef789ff0eb2663f1cff2b29d8196a7f0fd0b:

  [media] rtl2832: regmap is aware of lockdep, drop local locking hack 
(2016-04-20 14:49:00 +0200)
-

v7 compared to v6:
- Removed i2c_mux_reserve_adapters, and all realloc attempts in
  i2c_mux_add_adapter. Supply a maximum number of adapters in i2c_mux_alloc
  instead.
- Removed i2c_mux_one_adapter since it is was hard to use correctly, which
  was evident from the crash in the mpu6050 driver (on a mpu9150 chip) reported
  by Crestez Dan Leonard. Also, it didn't make things all that much simpler
  anyway (even if used correctly).
- Rename i2c_mux_core:adapters into i2c_mux_core:num_adapters.
- Some grammar and spelling fixes.

v6 compared to v5:
- Rebase on top of v4.6-rc1
- Adjust to gpio subsystem 

Re: [PATCH V5 0/4] Introduce CoreSight STM support

2016-04-20 Thread Mathieu Poirier
On 6 April 2016 at 20:51, Chunyan Zhang  wrote:
> This patchset adds support for the CoreSight STM IP block.

This has been out there long enough - I'm picking this up.

Alex, I'll have 1/4 go through my tree.  Get back to me if you want to
proceed differently.

Thanks,
Mathieu

>
> Changes from V4:
>  - Rebased the whole patch set onto [4] (v4.6-rc1).
>  - Made a few minor modifications according to the code changes since v4.5.
>  - Replaced the original 1/4 with a new patch the Alex provided.
>  - Another new patch 2/4 in this set is for storing path from CS-STM to sink.
>  - Addressed comments from V4.
>  - Removed coresight_simple_func() from CS-STM driver, used the common 
> definition instead.
>  - Modified STM tracer-id from an arbitrary value 0x20 to 0x1.
>  - Replaced module_amba_driver() with builtin_amba_driver() according to [5].
>  - Used driver->suppress_bind_attr to prevent CS-STM being unbound from the 
> driver.
>  - Updated the kernel version (4.7) and month in 
> sysfs-bus-coresight-devices-stm.
>  - Replaced 'mshared' with 'hw_override' in CS-STM driver.
>  - Initialized sw_start and sw_end with 1.
>  - Returned a size of '1' after processing FLAG packets.
>  - Removed pre-compile option 'CONFIG_64BIT' for the packet size of 8.
>  - Added Michael Williams's Reviewed-by in 4/4.
>
> Changes from V3:
>  - Removed ioctl get_options interface from the generic STM code and 
> CoreSight STM driver.
>  - Removed 'write_max' from the structure 'stm_drvdata', and changed 
> 'write_64bit' to 'write_bytes'.
>  - Revised stm_fundamental_data_size() to return the fundamental data size 
> instead of 0/1.
>  - Removed stm_remove() from the driver.
>  - Revised the return value of ::packet() callback function according to [2].
>  - Modified stm_send() to send one STP packet at a time.
>  - Added comments to invariant/guaranteed CoreSight STM transaction mode.
>
> Changes from V2:
>  - Changed to return -EFAULT if failed on the command STP_GET_OPTIONS.
>  - Used Alex's patch [1] instead of the last 2/6.
>  - Removed the while loop from stm_send(), since the packet size passed
>to it isn't larger than 4 bytes on 32-bit system and 8 bytes on
>64-bit system.
>  - Removed stm_send_64bit(), since the process of packets on 64-bit
>CS-STM should be basically the same with on 32-bit system, except the
>maximum length of writing STM at a time.
>  - Removed the support of writing 64-bit to CoreSight STM buffer at a time
>on 32-bit ARM architecture according to an ARM engineer suggestion.  As
>he said that the STM might receive a 64-bit write, or might receive a
>pair of 32-bit writes to the two addressed words in either order.
>So 64-bit write isn't guaranteed to work on the ARM 32-bit architecture.
>
> Changes from v1:
>  - Added a definition of coresight_simple_func() in CS-STM driver to
>avoid the kbuild test robot error for the time being.  This
>modification will be removed when merging the code in which the
>coresight_simple_func() has been moved to the header file.
>  - Calculate the channel number according to the channel memory space size.
>
>
> Thanks,
> Chunyan
>
> [1] https://lkml.org/lkml/2016/2/4/652
> [2] https://lkml.org/lkml/2016/2/12/397
> [3] https://lkml.org/lkml/2015/12/22/348
> [4] https://git.linaro.org/kernel/coresight.git/shortlog/refs/heads/next
> [5] http://www.spinics.net/lists/kernel/msg2187320.html
>
> Alexander Shishkin (1):
>   stm class: Support devices that override software assigned masters
>
> Mathieu Poirier (2):
>   coresight: adding path for STM device
>   coresight-stm: Bindings for System Trace Macrocell
>
> Pratik Patel (1):
>   coresight-stm: adding driver for CoreSight STM component
>
>  .../ABI/testing/sysfs-bus-coresight-devices-stm|  53 ++
>  Documentation/ABI/testing/sysfs-class-stm  |  10 +
>  .../devicetree/bindings/arm/coresight.txt  |  28 +
>  Documentation/trace/coresight.txt  |  37 +-
>  drivers/hwtracing/coresight/Kconfig|  11 +
>  drivers/hwtracing/coresight/Makefile   |   1 +
>  drivers/hwtracing/coresight/coresight-stm.c| 918 
> +
>  drivers/hwtracing/coresight/coresight.c| 106 ++-
>  drivers/hwtracing/stm/core.c   |  15 +
>  include/linux/coresight-stm.h  |   6 +
>  include/linux/stm.h|   3 +
>  include/uapi/linux/coresight-stm.h |  21 +
>  12 files changed, 1183 insertions(+), 26 deletions(-)
>  create mode 100644 Documentation/ABI/testing/sysfs-bus-coresight-devices-stm
>  create mode 100644 drivers/hwtracing/coresight/coresight-stm.c
>  create mode 100644 include/linux/coresight-stm.h
>  create mode 100644 include/uapi/linux/coresight-stm.h
>
> --
> 1.9.1
>
--
To unsubscribe from this list: send the line "unsubscribe linux-doc" in
the body of a message to majord...@vger.kernel.org
More majordomo