Linux userland API discussions
 help / color / mirror / Atom feed
* [PATCH 1/5] of: unittest: overlay: Keep track of created overlays
From: Pantelis Antoniou @ 2015-03-17 20:30 UTC (permalink / raw)
  To: Grant Likely
  Cc: Andrew Morton, Matt Porter, Koen Kooi, Guenter Roeck, Rob Herring,
	devicetree-u79uwXL29TY76Z2rM5mHXA,
	linux-kernel-u79uwXL29TY76Z2rM5mHXA,
	linux-api-u79uwXL29TY76Z2rM5mHXA, Pantelis Antoniou,
	Pantelis Antoniou
In-Reply-To: <1426624257-23003-1-git-send-email-pantelis.antoniou-OWPKS81ov/FWk0Htik3J/w@public.gmane.org>

During the course of the overlay selftests some of them remain
applied. While this does not pose a real problem, make sure you track
them and destroy them at the end of the test.

Signed-off-by: Pantelis Antoniou <pantelis.antoniou-OWPKS81ov/FWk0Htik3J/w@public.gmane.org>
---
 drivers/of/unittest.c | 62 +++++++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 62 insertions(+)

diff --git a/drivers/of/unittest.c b/drivers/of/unittest.c
index 4e60682..c711534 100644
--- a/drivers/of/unittest.c
+++ b/drivers/of/unittest.c
@@ -23,6 +23,8 @@
 #include <linux/i2c.h>
 #include <linux/i2c-mux.h>
 
+#include <linux/bitops.h>
+
 #include "of_private.h"
 
 static struct selftest_results {
@@ -1115,6 +1117,59 @@ static const char *overlay_path(int nr)
 
 static const char *bus_path = "/testcase-data/overlay-node/test-bus";
 
+/* it is guaranteed that overlay ids are assigned in sequence */
+#define MAX_SELFTEST_OVERLAYS	256
+static unsigned long overlay_id_bits[BITS_TO_LONGS(MAX_SELFTEST_OVERLAYS)];
+static int overlay_first_id = -1;
+
+static void of_selftest_track_overlay(int id)
+{
+	if (overlay_first_id < 0)
+		overlay_first_id = id;
+	id -= overlay_first_id;
+
+	/* we shouldn't need that many */
+	BUG_ON(id >= MAX_SELFTEST_OVERLAYS);
+	overlay_id_bits[BIT_WORD(id)] |= BIT_MASK(id);
+}
+
+static void of_selftest_untrack_overlay(int id)
+{
+	if (overlay_first_id < 0)
+		return;
+	id -= overlay_first_id;
+	BUG_ON(id >= MAX_SELFTEST_OVERLAYS);
+	overlay_id_bits[BIT_WORD(id)] &= ~BIT_MASK(id);
+}
+
+static void of_selftest_destroy_tracked_overlays(void)
+{
+	int id, ret, defers;
+
+	if (overlay_first_id < 0)
+		return;
+
+	/* try until no defers */
+	do {
+		defers = 0;
+		/* remove in reverse order */
+		for (id = MAX_SELFTEST_OVERLAYS - 1; id >= 0; id--) {
+			if (!(overlay_id_bits[BIT_WORD(id)] & BIT_MASK(id)))
+				continue;
+
+			ret = of_overlay_destroy(id + overlay_first_id);
+			if (ret != 0) {
+				defers++;
+				pr_warn("%s: overlay destroy failed for #%d\n",
+					__func__, id + overlay_first_id);
+				continue;
+			}
+
+			overlay_id_bits[BIT_WORD(id)] &= ~BIT_MASK(id);
+		}
+	} while (defers > 0);
+}
+
 static int of_selftest_apply_overlay(int selftest_nr, int overlay_nr,
 		int *overlay_id)
 {
@@ -1136,6 +1191,7 @@ static int of_selftest_apply_overlay(int selftest_nr, int overlay_nr,
 		goto out;
 	}
 	id = ret;
+	of_selftest_track_overlay(id);
 
 	ret = 0;
 
@@ -1349,6 +1405,7 @@ static void of_selftest_overlay_6(void)
 			return;
 		}
 		ov_id[i] = ret;
+		of_selftest_track_overlay(ov_id[i]);
 	}
 
 	for (i = 0; i < 2; i++) {
@@ -1373,6 +1430,7 @@ static void of_selftest_overlay_6(void)
 						PDEV_OVERLAY));
 			return;
 		}
+		of_selftest_untrack_overlay(ov_id[i]);
 	}
 
 	for (i = 0; i < 2; i++) {
@@ -1417,6 +1475,7 @@ static void of_selftest_overlay_8(void)
 			return;
 		}
 		ov_id[i] = ret;
+		of_selftest_track_overlay(ov_id[i]);
 	}
 
 	/* now try to remove first overlay (it should fail) */
@@ -1439,6 +1498,7 @@ static void of_selftest_overlay_8(void)
 						PDEV_OVERLAY));
 			return;
 		}
+		of_selftest_untrack_overlay(ov_id[i]);
 	}
 
 	selftest(1, "overlay test %d passed\n", 8);
@@ -1861,6 +1921,8 @@ static void __init of_selftest_overlay(void)
 	of_selftest_overlay_i2c_cleanup();
 #endif
 
+	of_selftest_destroy_tracked_overlays();
+
 out:
 	of_node_put(bus_np);
 }
-- 
1.7.12

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

^ permalink raw reply related

* [PATCH 2/5] of: overlay: kobjectify overlay objects
From: Pantelis Antoniou @ 2015-03-17 20:30 UTC (permalink / raw)
  To: Grant Likely
  Cc: Andrew Morton, Matt Porter, Koen Kooi, Guenter Roeck, Rob Herring,
	devicetree, linux-kernel, linux-api, Pantelis Antoniou,
	Pantelis Antoniou
In-Reply-To: <1426624257-23003-1-git-send-email-pantelis.antoniou@konsulko.com>

We are going to need the overlays to appear on sysfs with runtime
global properties (like master enable) so turn them into kobjects.

Signed-off-by: Pantelis Antoniou <pantelis.antoniou@konsulko.com>
---
 drivers/of/base.c       |  5 +++++
 drivers/of/of_private.h |  9 +++++++++
 drivers/of/overlay.c    | 52 +++++++++++++++++++++++++++++++++++++++++++++++--
 3 files changed, 64 insertions(+), 2 deletions(-)

diff --git a/drivers/of/base.c b/drivers/of/base.c
index adb8764..9b4d6f9 100644
--- a/drivers/of/base.c
+++ b/drivers/of/base.c
@@ -192,6 +192,7 @@ int __of_attach_node_sysfs(struct device_node *np)
 static int __init of_init(void)
 {
 	struct device_node *np;
+	int ret;
 
 	/* Create the kset, and register existing nodes */
 	mutex_lock(&of_mutex);
@@ -208,6 +209,10 @@ static int __init of_init(void)
 	if (of_root)
 		proc_symlink("device-tree", NULL, "/sys/firmware/devicetree/base");
 
+	ret = of_overlay_init();
+	if (ret != 0)
+		pr_warn("of_init: of_overlay_init failed!\n");
+
 	return 0;
 }
 core_initcall(of_init);
diff --git a/drivers/of/of_private.h b/drivers/of/of_private.h
index 8e882e7..120eb44 100644
--- a/drivers/of/of_private.h
+++ b/drivers/of/of_private.h
@@ -90,4 +90,13 @@ extern void __of_detach_node_sysfs(struct device_node *np);
 #define for_each_transaction_entry_reverse(_oft, _te) \
 	list_for_each_entry_reverse(_te, &(_oft)->te_list, node)
 
+#if defined(CONFIG_OF_OVERLAY)
+extern int of_overlay_init(void);
+#else
+static inline int of_overlay_init(void)
+{
+	return 0;
+}
+#endif
+
 #endif /* _LINUX_OF_PRIVATE_H */
diff --git a/drivers/of/overlay.c b/drivers/of/overlay.c
index dee9270..f17f5ef 100644
--- a/drivers/of/overlay.c
+++ b/drivers/of/overlay.c
@@ -20,6 +20,7 @@
 #include <linux/slab.h>
 #include <linux/err.h>
 #include <linux/idr.h>
+#include <linux/sysfs.h>
 
 #include "of_private.h"
 
@@ -51,6 +52,7 @@ struct of_overlay {
 	int count;
 	struct of_overlay_info *ovinfo_tab;
 	struct of_changeset cset;
+	struct kobject kobj;
 };
 
 static int of_overlay_apply_one(struct of_overlay *ov,
@@ -325,6 +327,24 @@ static int of_free_overlay_info(struct of_overlay *ov)
 static LIST_HEAD(ov_list);
 static DEFINE_IDR(ov_idr);
 
+static inline struct of_overlay *kobj_to_overlay(struct kobject *kobj)
+{
+	return container_of(kobj, struct of_overlay, kobj);
+}
+
+void of_overlay_release(struct kobject *kobj)
+{
+	struct of_overlay *ov = kobj_to_overlay(kobj);
+
+	kfree(ov);
+}
+
+static struct kobj_type of_overlay_ktype = {
+	.release = of_overlay_release,
+};
+
+static struct kset *ov_kset;
+
 /**
  * of_overlay_create() - Create and apply an overlay
  * @tree:	Device node containing all the overlays
@@ -350,6 +370,9 @@ int of_overlay_create(struct device_node *tree)
 
 	of_changeset_init(&ov->cset);
 
+	/* initialize kobject */
+	kobject_init(&ov->kobj, &of_overlay_ktype);
+
 	mutex_lock(&of_mutex);
 
 	id = idr_alloc(&ov_idr, ov, 0, 0, GFP_KERNEL);
@@ -385,6 +408,14 @@ int of_overlay_create(struct device_node *tree)
 		goto err_revert_overlay;
 	}
 
+	ov->kobj.kset = ov_kset;
+	err = kobject_add(&ov->kobj, NULL, "%d", id);
+	if (err != 0) {
+		pr_err("%s: kobject_add() failed for tree@%s\n",
+				__func__, tree->full_name);
+		goto err_cancel_overlay;
+	}
+
 	/* add to the tail of the overlay list */
 	list_add_tail(&ov->node, &ov_list);
 
@@ -392,6 +423,8 @@ int of_overlay_create(struct device_node *tree)
 
 	return id;
 
+err_cancel_overlay:
+	of_changeset_revert(&ov->cset);
 err_revert_overlay:
 err_abort_trans:
 	of_free_overlay_info(ov);
@@ -512,7 +545,9 @@ int of_overlay_destroy(int id)
 	of_free_overlay_info(ov);
 	idr_remove(&ov_idr, id);
 	of_changeset_destroy(&ov->cset);
-	kfree(ov);
+
+	kobject_del(&ov->kobj);
+	kobject_put(&ov->kobj);
 
 	err = 0;
 
@@ -542,7 +577,8 @@ int of_overlay_destroy_all(void)
 		of_changeset_revert(&ov->cset);
 		of_free_overlay_info(ov);
 		idr_remove(&ov_idr, ov->id);
-		kfree(ov);
+		kobject_del(&ov->kobj);
+		kobject_put(&ov->kobj);
 	}
 
 	mutex_unlock(&of_mutex);
@@ -550,3 +586,15 @@ int of_overlay_destroy_all(void)
 	return 0;
 }
 EXPORT_SYMBOL_GPL(of_overlay_destroy_all);
+
+/* called from of_init() */
+int of_overlay_init(void)
+{
+	int rc;
+
+	ov_kset = kset_create_and_add("overlays", NULL, &of_kset->kobj);
+	if (!ov_kset)
+		return -ENOMEM;
+
+	return 0;
+}
-- 
1.7.12

^ permalink raw reply related

* [PATCH 3/5] of: overlay: Master enable switch
From: Pantelis Antoniou @ 2015-03-17 20:30 UTC (permalink / raw)
  To: Grant Likely
  Cc: Andrew Morton, Matt Porter, Koen Kooi, Guenter Roeck, Rob Herring,
	devicetree, linux-kernel, linux-api, Pantelis Antoniou,
	Pantelis Antoniou
In-Reply-To: <1426624257-23003-1-git-send-email-pantelis.antoniou@konsulko.com>

Implement a throw once master enable switch to protect against any
further overlay applications if the administrator desires so.

Signed-off-by: Pantelis Antoniou <pantelis.antoniou@konsulko.com>
---
 drivers/of/overlay.c | 66 +++++++++++++++++++++++++++++++++++++++++++++++++++-
 1 file changed, 65 insertions(+), 1 deletion(-)

diff --git a/drivers/of/overlay.c b/drivers/of/overlay.c
index f17f5ef..6688797 100644
--- a/drivers/of/overlay.c
+++ b/drivers/of/overlay.c
@@ -21,6 +21,7 @@
 #include <linux/err.h>
 #include <linux/idr.h>
 #include <linux/sysfs.h>
+#include <linux/atomic.h>
 
 #include "of_private.h"
 
@@ -55,6 +56,9 @@ struct of_overlay {
 	struct kobject kobj;
 };
 
+/* master enable switch; once set to 0 can't be re-enabled */
+static atomic_t ov_enable = ATOMIC_INIT(1);
+
 static int of_overlay_apply_one(struct of_overlay *ov,
 		struct device_node *target, const struct device_node *overlay);
 
@@ -345,6 +349,60 @@ static struct kobj_type of_overlay_ktype = {
 
 static struct kset *ov_kset;
 
+static ssize_t enable_read(struct file *filp, struct kobject *kobj,
+		struct bin_attribute *bin_attr, char *buf,
+		loff_t offset, size_t count)
+{
+	char tbuf[3];
+
+	if (offset < 0)
+		return -EINVAL;
+
+	if (offset >= sizeof(tbuf))
+		return 0;
+
+	if (count > sizeof(tbuf) - offset)
+		count = sizeof(tbuf) - offset;
+
+	/* fill in temp */
+	tbuf[0] = '0' + atomic_read(&ov_enable);
+	tbuf[1] = '\n';
+	tbuf[2] = '\0';
+
+	/* copy to buffer */
+	memcpy(buf, tbuf + offset, count);
+
+	return count;
+}
+
+static ssize_t enable_write(struct file *filp, struct kobject *kobj,
+		struct bin_attribute *bin_attr, char *buf,
+		loff_t off, size_t count)
+{
+	int new_enable;
+
+	if (off != 0 || (buf[0] != '0' && buf[1] != '1'))
+		return -EINVAL;
+
+	new_enable = buf[0] - '0';
+	if (new_enable != 0 && new_enable != 1)
+		return -EINVAL;
+
+	/* NOP for same value */
+	if (new_enable == atomic_read(&ov_enable))
+		return count;
+
+	/* if we've disabled it, no going back */
+	if (atomic_read(&ov_enable) == 0)
+		return -EPERM;
+
+	atomic_set(&ov_enable, new_enable);
+	return count;
+}
+
+/* just a single char + '\n' + '\0' */
+static BIN_ATTR_RW(enable, 3);
+
 /**
  * of_overlay_create() - Create and apply an overlay
  * @tree:	Device node containing all the overlays
@@ -360,6 +418,10 @@ int of_overlay_create(struct device_node *tree)
 	struct of_overlay *ov;
 	int err, id;
 
+	/* administratively disabled */
+	if (!atomic_read(&ov_enable))
+		return -EPERM;
+
 	/* allocate the overlay structure */
 	ov = kzalloc(sizeof(*ov), GFP_KERNEL);
 	if (ov == NULL)
@@ -596,5 +658,7 @@ int of_overlay_init(void)
 	if (!ov_kset)
 		return -ENOMEM;
 
-	return 0;
+	rc = sysfs_create_bin_file(&ov_kset->kobj, &bin_attr_enable);
+	WARN(rc, "%s: error adding enable attribute\n", __func__);
+	return rc;
 }
-- 
1.7.12

^ permalink raw reply related

* [PATCH 4/5] Documentation: ABI: /sys/firmware/devicetree/overlays
From: Pantelis Antoniou @ 2015-03-17 20:30 UTC (permalink / raw)
  To: Grant Likely
  Cc: Andrew Morton, Matt Porter, Koen Kooi, Guenter Roeck, Rob Herring,
	devicetree-u79uwXL29TY76Z2rM5mHXA,
	linux-kernel-u79uwXL29TY76Z2rM5mHXA,
	linux-api-u79uwXL29TY76Z2rM5mHXA, Pantelis Antoniou,
	Pantelis Antoniou
In-Reply-To: <1426624257-23003-1-git-send-email-pantelis.antoniou-OWPKS81ov/FWk0Htik3J/w@public.gmane.org>

Documentation ABI entry for overlays sysfs entries.

Signed-off-by: Pantelis Antoniou <pantelis.antoniou-OWPKS81ov/FWk0Htik3J/w@public.gmane.org>
---
 Documentation/ABI/testing/sysfs-firmware-devicetree-overlays | 9 +++++++++
 1 file changed, 9 insertions(+)
 create mode 100644 Documentation/ABI/testing/sysfs-firmware-devicetree-overlays

diff --git a/Documentation/ABI/testing/sysfs-firmware-devicetree-overlays b/Documentation/ABI/testing/sysfs-firmware-devicetree-overlays
new file mode 100644
index 0000000..5a07499
--- /dev/null
+++ b/Documentation/ABI/testing/sysfs-firmware-devicetree-overlays
@@ -0,0 +1,9 @@
+What:		/sys/firmware/devicetree/overlays/
+Date:		March 2015
+Contact:	Pantelis Antoniou <pantelis.antoniou-OWPKS81ov/FWk0Htik3J/w@public.gmane.org>
+Description:
+		This directory contains the applied device tree overlays of
+		the running system, as directories of the overlay id.
+
+		enable: The master enable switch, by default is 1, and when
+		        set to 0 it cannot be re-enabled for security reasons.
-- 
1.7.12

^ permalink raw reply related

* [PATCH 5/5] MAINTAINERS: Pantelis Antoniou device tree overlay maintainer
From: Pantelis Antoniou @ 2015-03-17 20:30 UTC (permalink / raw)
  To: Grant Likely
  Cc: Andrew Morton, Matt Porter, Koen Kooi, Guenter Roeck, Rob Herring,
	devicetree, linux-kernel, linux-api, Pantelis Antoniou,
	Pantelis Antoniou
In-Reply-To: <1426624257-23003-1-git-send-email-pantelis.antoniou@konsulko.com>

Add me as the device tree overlays maintainer.

Signed-off-by: Pantelis Antoniou <pantelis.antoniou@konsulko.com>
---
 MAINTAINERS | 9 +++++++++
 1 file changed, 9 insertions(+)

diff --git a/MAINTAINERS b/MAINTAINERS
index 0e1abe8..24aa339 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -7187,6 +7187,15 @@ F:	Documentation/devicetree/
 F:	arch/*/boot/dts/
 F:	include/dt-bindings/
 
+OPEN FIRMWARE AND DEVICE TREE OVERLAYS
+M:	Pantelis Antoniou <pantelis.antoniou@konsulko.com>
+L:	devicetree@vger.kernel.org
+S:	Maintained
+F:	Documentation/devicetree/dynamic-resolution-notes.txt
+F:	Documentation/devicetree/overlay-notes.txt
+F:	drivers/of/overlay.c
+F:	drivers/of/resolver.c
+
 OPENRISC ARCHITECTURE
 M:	Jonas Bonn <jonas@southpole.se>
 W:	http://openrisc.net
-- 
1.7.12

^ permalink raw reply related

* Re: [PATCH 0/5] of: overlay: Assorted fixes
From: Rob Herring @ 2015-03-17 20:37 UTC (permalink / raw)
  To: Pantelis Antoniou
  Cc: Grant Likely, Andrew Morton, Matt Porter, Koen Kooi,
	Guenter Roeck, devicetree-u79uwXL29TY76Z2rM5mHXA@public.gmane.org,
	linux-kernel-u79uwXL29TY76Z2rM5mHXA@public.gmane.org,
	linux-api-u79uwXL29TY76Z2rM5mHXA@public.gmane.org,
	Pantelis Antoniou
In-Reply-To: <1426624257-23003-1-git-send-email-pantelis.antoniou-OWPKS81ov/FWk0Htik3J/w@public.gmane.org>

On Tue, Mar 17, 2015 at 3:30 PM, Pantelis Antoniou
<pantelis.antoniou-OWPKS81ov/FWk0Htik3J/w@public.gmane.org> wrote:
> The first patch makes sure that no overlays are being left over from
> the unit tests.
>
> The second puts the overlays as objects in the sysfs in
> /sys/firmware/devicetree/overlays while the next one adds a master
> overlay enable switch (that once is set to disabled can't be re-enabled)
>
> The next updates the ABI docs and the final one adds me as the
> maintainer for device tree overlays.

You call this fixes, but it looks like new functionality to me. So
this looks like 4.1 material.

Rob

>
> Pantelis Antoniou (5):
>   of: unittest: overlay: Keep track of created overlays
>   of: overlay: kobjectify overlay objects
>   of: overlay: Master enable switch
>   Documentation: ABI: /sys/firmware/devicetree/overlays
>   MAINTAINERS: Pantelis Antoniou device tree overlay maintainer
>
>  .../ABI/testing/sysfs-firmware-devicetree-overlays |   9 ++
>  MAINTAINERS                                        |   9 ++
>  drivers/of/base.c                                  |   5 +
>  drivers/of/of_private.h                            |   9 ++
>  drivers/of/overlay.c                               | 116 ++++++++++++++++++++-
>  drivers/of/unittest.c                              |  62 +++++++++++
>  6 files changed, 208 insertions(+), 2 deletions(-)
>  create mode 100644 Documentation/ABI/testing/sysfs-firmware-devicetree-overlays
>
> --
> 1.7.12
>

^ permalink raw reply

* Re: [PATCH 0/5] of: overlay: Assorted fixes
From: Pantelis Antoniou @ 2015-03-17 20:39 UTC (permalink / raw)
  To: Rob Herring
  Cc: Grant Likely, Andrew Morton, Matt Porter, Koen Kooi,
	Guenter Roeck, devicetree@vger.kernel.org,
	linux-kernel@vger.kernel.org, linux-api@vger.kernel.org
In-Reply-To: <CAL_Jsq+ingowTc_Seun2yHPfHYXQ0Lb+6Bewr9=8HG2teG7hdg@mail.gmail.com>


> On Mar 17, 2015, at 22:37 , Rob Herring <robherring2@gmail.com> wrote:
> 
> On Tue, Mar 17, 2015 at 3:30 PM, Pantelis Antoniou
> <pantelis.antoniou@konsulko.com> wrote:
>> The first patch makes sure that no overlays are being left over from
>> the unit tests.
>> 
>> The second puts the overlays as objects in the sysfs in
>> /sys/firmware/devicetree/overlays while the next one adds a master
>> overlay enable switch (that once is set to disabled can't be re-enabled)
>> 
>> The next updates the ABI docs and the final one adds me as the
>> maintainer for device tree overlays.
> 
> You call this fixes, but it looks like new functionality to me. So
> this looks like 4.1 material.
> 

Yep, they are not 4.0 material. They are not major functional changes though.

> Rob
> 

Regards

— Pantelis

>> 
>> Pantelis Antoniou (5):
>>  of: unittest: overlay: Keep track of created overlays
>>  of: overlay: kobjectify overlay objects
>>  of: overlay: Master enable switch
>>  Documentation: ABI: /sys/firmware/devicetree/overlays
>>  MAINTAINERS: Pantelis Antoniou device tree overlay maintainer
>> 
>> .../ABI/testing/sysfs-firmware-devicetree-overlays |   9 ++
>> MAINTAINERS                                        |   9 ++
>> drivers/of/base.c                                  |   5 +
>> drivers/of/of_private.h                            |   9 ++
>> drivers/of/overlay.c                               | 116 ++++++++++++++++++++-
>> drivers/of/unittest.c                              |  62 +++++++++++
>> 6 files changed, 208 insertions(+), 2 deletions(-)
>> create mode 100644 Documentation/ABI/testing/sysfs-firmware-devicetree-overlays
>> 
>> --
>> 1.7.12
>> 

^ permalink raw reply

* [PATCH] mremap: add MREMAP_NOHOLE flag --resend
From: Shaohua Li @ 2015-03-17 21:09 UTC (permalink / raw)
  To: linux-mm-Bw31MaZKKs3YtjvyW6yDsg
  Cc: danielmicay-Re5JQEeQqe8AvxtiuMwx3w,
	linux-api-u79uwXL29TY76Z2rM5mHXA, Rik van Riel, Andrew Morton,
	Hugh Dickins, Mel Gorman, Johannes Weiner, Michal Hocko,
	Andy Lutomirski

There was a similar patch posted before, but it doesn't get merged. I'd like
to try again if there are more discussions.
http://marc.info/?l=linux-mm&m=141230769431688&w=2

mremap can be used to accelerate realloc. The problem is mremap will
punch a hole in original VMA, which makes specific memory allocator
unable to utilize it. Jemalloc is an example. It manages memory in 4M
chunks. mremap a range of the chunk will punch a hole, which other
mmap() syscall can fill into. The 4M chunk is then fragmented, jemalloc
can't handle it.

This patch adds a new flag for mremap. With it, mremap will not punch the
hole. page tables of original vma will be zapped in the same way, but
vma is still there. That is original vma will look like a vma without
pagefault. Behavior of new vma isn't changed.

For private vma, accessing original vma will cause
page fault and just like the address of the vma has never been accessed.
So for anonymous, new page/zero page will be fault in. For file mapping,
new page will be allocated with file reading for cow, or pagefault will
use existing page cache.

For shared vma, original and new vma will map to the same file. We can
optimize this without zaping original vma's page table in this case, but
this patch doesn't do it yet.

Since with MREMAP_NOHOLE, original vma still exists. pagefault handler
for special vma might not able to handle pagefault for mremap'd area.
The patch doesn't allow vmas with VM_PFNMAP|VM_MIXEDMAP flags do NOHOLE
mremap.

Cc: Rik van Riel <riel-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org>
Cc: Andrew Morton <akpm-de/tnXTf+JLsfHDXvbKv3WD2FQJk+8+b@public.gmane.org>
Cc: Hugh Dickins <hughd-hpIqsD4AKlfQT0dZR+AlfA@public.gmane.org>
Cc: Mel Gorman <mel-wPRd99KPJ+uzQB+pC5nmwQ@public.gmane.org>
Cc: Johannes Weiner <hannes-druUgvl0LCNAfugRpC6u6w@public.gmane.org>
Cc: Michal Hocko <mhocko-AlSwsSmVLrQ@public.gmane.org>
Cc: Andy Lutomirski <luto-kltTT9wpgjJwATOyAt5JVQ@public.gmane.org>
Signed-off-by: Shaohua Li <shli-b10kYP2dOMg@public.gmane.org>
---
 include/uapi/linux/mman.h |  1 +
 mm/mremap.c               | 97 ++++++++++++++++++++++++++++++++---------------
 2 files changed, 67 insertions(+), 31 deletions(-)

diff --git a/include/uapi/linux/mman.h b/include/uapi/linux/mman.h
index ade4acd..9ee9a15 100644
--- a/include/uapi/linux/mman.h
+++ b/include/uapi/linux/mman.h
@@ -5,6 +5,7 @@
 
 #define MREMAP_MAYMOVE	1
 #define MREMAP_FIXED	2
+#define MREMAP_NOHOLE	4
 
 #define OVERCOMMIT_GUESS		0
 #define OVERCOMMIT_ALWAYS		1
diff --git a/mm/mremap.c b/mm/mremap.c
index 38df67b..4771fd1 100644
--- a/mm/mremap.c
+++ b/mm/mremap.c
@@ -234,7 +234,8 @@ unsigned long move_page_tables(struct vm_area_struct *vma,
 
 static unsigned long move_vma(struct vm_area_struct *vma,
 		unsigned long old_addr, unsigned long old_len,
-		unsigned long new_len, unsigned long new_addr, bool *locked)
+		unsigned long new_len, unsigned long new_addr, bool *locked,
+		bool nohole)
 {
 	struct mm_struct *mm = vma->vm_mm;
 	struct vm_area_struct *new_vma;
@@ -290,7 +291,7 @@ static unsigned long move_vma(struct vm_area_struct *vma,
 		vma->vm_file->f_op->mremap(vma->vm_file, new_vma);
 
 	/* Conceal VM_ACCOUNT so old reservation is not undone */
-	if (vm_flags & VM_ACCOUNT) {
+	if ((vm_flags & VM_ACCOUNT) && !nohole) {
 		vma->vm_flags &= ~VM_ACCOUNT;
 		excess = vma->vm_end - vma->vm_start - old_len;
 		if (old_addr > vma->vm_start &&
@@ -310,11 +311,18 @@ static unsigned long move_vma(struct vm_area_struct *vma,
 	hiwater_vm = mm->hiwater_vm;
 	vm_stat_account(mm, vma->vm_flags, vma->vm_file, new_len>>PAGE_SHIFT);
 
-	if (do_munmap(mm, old_addr, old_len) < 0) {
+	if (!nohole && do_munmap(mm, old_addr, old_len) < 0) {
 		/* OOM: unable to split vma, just get accounts right */
 		vm_unacct_memory(excess >> PAGE_SHIFT);
 		excess = 0;
 	}
+
+	if (nohole && (new_addr & ~PAGE_MASK)) {
+		/* caller will unaccount */
+		vma->vm_flags &= ~VM_ACCOUNT;
+		do_munmap(mm, old_addr, old_len);
+	}
+
 	mm->hiwater_vm = hiwater_vm;
 
 	/* Restore VM_ACCOUNT if one or two pieces of vma left */
@@ -332,14 +340,13 @@ static unsigned long move_vma(struct vm_area_struct *vma,
 	return new_addr;
 }
 
-static struct vm_area_struct *vma_to_resize(unsigned long addr,
-	unsigned long old_len, unsigned long new_len, unsigned long *p)
+static unsigned long validate_vma_and_charge(struct vm_area_struct *vma,
+	unsigned long addr,
+	unsigned long old_len, unsigned long new_len, unsigned long *p,
+	bool nohole)
 {
 	struct mm_struct *mm = current->mm;
-	struct vm_area_struct *vma = find_vma(mm, addr);
-
-	if (!vma || vma->vm_start > addr)
-		goto Efault;
+	unsigned long diff;
 
 	if (is_vm_hugetlb_page(vma))
 		goto Einval;
@@ -348,6 +355,9 @@ static struct vm_area_struct *vma_to_resize(unsigned long addr,
 	if (old_len > vma->vm_end - addr)
 		goto Efault;
 
+	if (nohole && (vma->vm_flags & (VM_PFNMAP | VM_MIXEDMAP)))
+		goto Einval;
+
 	/* Need to be careful about a growing mapping */
 	if (new_len > old_len) {
 		unsigned long pgoff;
@@ -360,39 +370,45 @@ static struct vm_area_struct *vma_to_resize(unsigned long addr,
 			goto Einval;
 	}
 
+	if (nohole)
+		diff = new_len;
+	else
+		diff = new_len - old_len;
+
 	if (vma->vm_flags & VM_LOCKED) {
 		unsigned long locked, lock_limit;
 		locked = mm->locked_vm << PAGE_SHIFT;
 		lock_limit = rlimit(RLIMIT_MEMLOCK);
-		locked += new_len - old_len;
+		locked += diff;
 		if (locked > lock_limit && !capable(CAP_IPC_LOCK))
 			goto Eagain;
 	}
 
-	if (!may_expand_vm(mm, (new_len - old_len) >> PAGE_SHIFT))
+	if (!may_expand_vm(mm, diff >> PAGE_SHIFT))
 		goto Enomem;
 
 	if (vma->vm_flags & VM_ACCOUNT) {
-		unsigned long charged = (new_len - old_len) >> PAGE_SHIFT;
+		unsigned long charged = diff >> PAGE_SHIFT;
 		if (security_vm_enough_memory_mm(mm, charged))
 			goto Efault;
 		*p = charged;
 	}
 
-	return vma;
+	return 0;
 
 Efault:	/* very odd choice for most of the cases, but... */
-	return ERR_PTR(-EFAULT);
+	return -EFAULT;
 Einval:
-	return ERR_PTR(-EINVAL);
+	return -EINVAL;
 Enomem:
-	return ERR_PTR(-ENOMEM);
+	return -ENOMEM;
 Eagain:
-	return ERR_PTR(-EAGAIN);
+	return -EAGAIN;
 }
 
 static unsigned long mremap_to(unsigned long addr, unsigned long old_len,
-		unsigned long new_addr, unsigned long new_len, bool *locked)
+		unsigned long new_addr, unsigned long new_len, bool *locked,
+		bool nohole)
 {
 	struct mm_struct *mm = current->mm;
 	struct vm_area_struct *vma;
@@ -420,17 +436,23 @@ static unsigned long mremap_to(unsigned long addr, unsigned long old_len,
 		goto out;
 
 	if (old_len >= new_len) {
-		ret = do_munmap(mm, addr+new_len, old_len - new_len);
-		if (ret && old_len != new_len)
-			goto out;
+		if (!nohole) {
+			ret = do_munmap(mm, addr+new_len, old_len - new_len);
+			if (ret && old_len != new_len)
+				goto out;
+		}
 		old_len = new_len;
 	}
 
-	vma = vma_to_resize(addr, old_len, new_len, &charged);
-	if (IS_ERR(vma)) {
-		ret = PTR_ERR(vma);
+	vma = find_vma(mm, addr);
+	if (!vma || vma->vm_start > addr) {
+		ret = -EFAULT;
 		goto out;
 	}
+	ret = validate_vma_and_charge(vma, addr, old_len, new_len, &charged,
+		nohole);
+	if (ret)
+		goto out;
 
 	map_flags = MAP_FIXED;
 	if (vma->vm_flags & VM_MAYSHARE)
@@ -442,7 +464,7 @@ static unsigned long mremap_to(unsigned long addr, unsigned long old_len,
 	if (ret & ~PAGE_MASK)
 		goto out1;
 
-	ret = move_vma(vma, addr, old_len, new_len, new_addr, locked);
+	ret = move_vma(vma, addr, old_len, new_len, new_addr, locked, nohole);
 	if (!(ret & ~PAGE_MASK))
 		goto out;
 out1:
@@ -481,8 +503,9 @@ SYSCALL_DEFINE5(mremap, unsigned long, addr, unsigned long, old_len,
 	unsigned long ret = -EINVAL;
 	unsigned long charged = 0;
 	bool locked = false;
+	bool nohole = flags & MREMAP_NOHOLE;
 
-	if (flags & ~(MREMAP_FIXED | MREMAP_MAYMOVE))
+	if (flags & ~(MREMAP_FIXED | MREMAP_MAYMOVE | MREMAP_NOHOLE))
 		return ret;
 
 	if (flags & MREMAP_FIXED && !(flags & MREMAP_MAYMOVE))
@@ -506,7 +529,7 @@ SYSCALL_DEFINE5(mremap, unsigned long, addr, unsigned long, old_len,
 
 	if (flags & MREMAP_FIXED) {
 		ret = mremap_to(addr, old_len, new_addr, new_len,
-				&locked);
+				&locked, nohole);
 		goto out;
 	}
 
@@ -526,9 +549,9 @@ SYSCALL_DEFINE5(mremap, unsigned long, addr, unsigned long, old_len,
 	/*
 	 * Ok, we need to grow..
 	 */
-	vma = vma_to_resize(addr, old_len, new_len, &charged);
-	if (IS_ERR(vma)) {
-		ret = PTR_ERR(vma);
+	vma = find_vma(mm, addr);
+	if (!vma || vma->vm_start > addr) {
+		ret = -EFAULT;
 		goto out;
 	}
 
@@ -539,6 +562,12 @@ SYSCALL_DEFINE5(mremap, unsigned long, addr, unsigned long, old_len,
 		if (vma_expandable(vma, new_len - old_len)) {
 			int pages = (new_len - old_len) >> PAGE_SHIFT;
 
+			ret = validate_vma_and_charge(vma, addr, old_len, new_len,
+				&charged, false);
+			if (ret) {
+				BUG_ON(charged != 0);
+				goto out;
+			}
 			if (vma_adjust(vma, vma->vm_start, addr + new_len,
 				       vma->vm_pgoff, NULL)) {
 				ret = -ENOMEM;
@@ -556,6 +585,11 @@ SYSCALL_DEFINE5(mremap, unsigned long, addr, unsigned long, old_len,
 		}
 	}
 
+	ret = validate_vma_and_charge(vma, addr, old_len, new_len,
+		&charged, nohole);
+	if (ret)
+		goto out;
+
 	/*
 	 * We weren't able to just expand or shrink the area,
 	 * we need to create a new one and move it..
@@ -575,7 +609,8 @@ SYSCALL_DEFINE5(mremap, unsigned long, addr, unsigned long, old_len,
 			goto out;
 		}
 
-		ret = move_vma(vma, addr, old_len, new_len, new_addr, &locked);
+		ret = move_vma(vma, addr, old_len, new_len, new_addr, &locked,
+			nohole);
 	}
 out:
 	if (ret & ~PAGE_MASK)
-- 
1.8.1

^ permalink raw reply related

* Re: [PATCH v2 11/18] pinctrl: Add pinctrl driver for STM32 MCUs
From: Linus Walleij @ 2015-03-18  1:08 UTC (permalink / raw)
  To: Arnd Bergmann
  Cc: linux-arm-kernel@lists.infradead.org, Maxime Coquelin,
	Uwe Kleine-König, Andreas Färber, Geert Uytterhoeven,
	Rob Herring, Philipp Zabel, Jonathan Corbet, Pawel Moll,
	Mark Rutland, Ian Campbell, Kumar Gala, Russell King,
	Daniel Lezcano, Thomas Gleixner, Greg Kroah-Hartman, Jiri Slaby,
	Andrew Morton, David S. Miller, Mauro Carvalho Chehab
In-Reply-To: <2464742.YZIRrHto62@wuerfel>

On Tue, Mar 10, 2015 at 4:08 PM, Arnd Bergmann <arnd@arndb.de> wrote:
> On Friday 20 February 2015 19:01:10 Maxime Coquelin wrote:

>> +/* Pull-Up/Down */
>> +#define NO_PULL                0
>> +#define PULL_UP                1
>> +#define PULL_DOWN      2
>> +
>> +/* Type */
>> +#define PUSH_PULL      (0 << 2)
>> +#define OPEN_DRAIN     (1 << 2)
>> +
>
> These should probably not be stm32 specific at all, they sound
> rather generic, so maybe put the definitions into a common file.

It's part of what GENERIC_PINCONF does and it has bindings
in Documentation/devicetree/bindings/pinctrl/pinctrl-bindings.txt

Yours,
Linus Walleij

^ permalink raw reply

* Re: [PATCHv3 xfstests 2/3] generic: test openat and new O_BENEATH flag
From: Dave Chinner @ 2015-03-18  2:52 UTC (permalink / raw)
  To: Kees Cook
  Cc: David Drysdale, LKML, Alexander Viro, Eric W. Biederman,
	Greg Kroah-Hartman, Meredydd Luff, Will Drewry,
	Jorge Lucangeli Obes, Ricky Zhou, Lee Campbell, Julien Tinnes,
	Mike Depinet, James Morris, Andy Lutomirski, Paolo Bonzini,
	Paul Moore, Christoph Hellwig, Michael Kerrisk, Linux API,
	linux-security-module, fstests-u79uwXL29TY76Z2rM5mHXA
In-Reply-To: <CAGXu5jLfrGrVO=9sF6=TK0QQHq4SWRjL0urGu-e+e1H8gk9Y3Q-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org>

On Tue, Mar 17, 2015 at 08:33:27AM -0700, Kees Cook wrote:
> On Mon, Mar 16, 2015 at 4:24 PM, Dave Chinner
> <david-FqsqvQoI3Ljby3iVrkZq2A@public.gmane.org> wrote:
> > On Mon, Mar 09, 2015 at 02:00:11PM +0000, David Drysdale wrote:
> >> Test basic openat(2) behaviour.
> >>
> >> Test that if O_BENEATH flag is set, openat() will only open
> >> paths that have no .. component and do not start with /.
> >> Symlinks are also checked for the same restrictions.
> >>
> >> Signed-off-by: David Drysdale <drysdale-hpIqsD4AKlfQT0dZR+AlfA@public.gmane.org> ---
> >> .gitignore            |   1 + common/openat         |  61
> >> ++++++++++++++++++++++++++++++ src/Makefile          |   3 +-
> >> src/openat.c          | 100
> >> +++++++++++++++++++++++++++++++++++++++++++++++++
> >
> > This strikes me as something that shoul dbe added to xfs_io for
> > testing, as it already supports a heap of other open flags and
> > xfstests is already dependent on it.
> 
> While I don't see a problem adding this to xfs_io, I'd still like
> to see this test live in the kernel tree too.

You can do whatever you want with the kernel tree - it doesn't
concern me at all.

> Having it in the
> same source means more testing, IMO.

That's complete bunk, though.  This helper binary is a limited use,
one shot test that can't be combined with anything else.  "sharing"
the source code across multiple different test suites doesn't change
that. However, putting support into xfs_io means it will get more
testing because we can *easily* use the functionality in many, many
different ways.

Cheers,

Dave.
-- 
Dave Chinner
david-FqsqvQoI3Ljby3iVrkZq2A@public.gmane.org

^ permalink raw reply

* Re: [PATCHv3 xfstests 2/3] generic: test openat and new O_BENEATH flag
From: David Drysdale @ 2015-03-18 10:17 UTC (permalink / raw)
  To: Dave Chinner
  Cc: Kees Cook, LKML, Alexander Viro, Eric W. Biederman,
	Greg Kroah-Hartman, Meredydd Luff, Will Drewry,
	Jorge Lucangeli Obes, Ricky Zhou, Lee Campbell, Julien Tinnes,
	Mike Depinet, James Morris, Andy Lutomirski, Paolo Bonzini,
	Paul Moore, Christoph Hellwig, Michael Kerrisk, Linux API,
	linux-security-module, fstests
In-Reply-To: <20150318025238.GC10105@dastard>

[resend, remembering to tick the Plaintext button this time -- sorry]

On Wed, Mar 18, 2015 at 2:52 AM, Dave Chinner <david@fromorbit.com> wrote:
> On Tue, Mar 17, 2015 at 08:33:27AM -0700, Kees Cook wrote:
>> On Mon, Mar 16, 2015 at 4:24 PM, Dave Chinner
>> <david@fromorbit.com> wrote:
>> > On Mon, Mar 09, 2015 at 02:00:11PM +0000, David Drysdale wrote:
>> >> Test basic openat(2) behaviour.
>> >>
>> >> Test that if O_BENEATH flag is set, openat() will only open
>> >> paths that have no .. component and do not start with /.
>> >> Symlinks are also checked for the same restrictions.
>> >>
>> >> Signed-off-by: David Drysdale <drysdale@google.com> ---
>> >> .gitignore            |   1 + common/openat         |  61
>> >> ++++++++++++++++++++++++++++++ src/Makefile          |   3 +-
>> >> src/openat.c          | 100
>> >> +++++++++++++++++++++++++++++++++++++++++++++++++
>> >
>> > This strikes me as something that shoul dbe added to xfs_io for
>> > testing, as it already supports a heap of other open flags and
>> > xfstests is already dependent on it.
>>
>> While I don't see a problem adding this to xfs_io, I'd still like
>> to see this test live in the kernel tree too.
>
> You can do whatever you want with the kernel tree - it doesn't
> concern me at all.
>
>> Having it in the
>> same source means more testing, IMO.
>
> That's complete bunk, though.  This helper binary is a limited use,
> one shot test that can't be combined with anything else.  "sharing"
> the source code across multiple different test suites doesn't change
> that. However, putting support into xfs_io means it will get more
> testing because we can *easily* use the functionality in many, many
> different ways.

It's useful to have a simple self-test in the kernel tree, so
that kernel developers (and their buildbots) can catch any
obvious regressions that might arise when working in related
areas, without requiring any other dependencies.

(Personally, I also think it's good that new kernel APIs
come with demonstrations of their use in userspace in a
nearby commit.)

OTOH, testing openat() behaviour should clearly be a part of
the xfstests suite (as a general/comprehensive filesystem
test repository), and Dave makes a good point that putting
the openat() functionality into xfs_io allows for more flexible
test combinations.

So I guess ideally we should end up with:
 a) Reinstate the kernel-tree selftests from the earlier iteration.
 b) Add openat test functionality into xfs_io
 c) Migrate the new xfstests cases to use xfs_io rather than
   a local openat utility program

However, given that I've already moved the test code once,
and that a)-c) involve three different source trees, I'd like
to de-couple things:
- Concentrate on kernel changes and a) on the LKML.
 - If & when the kernel changes make progress, return to
   b) and c).

Sound sensible?

Thanks,
David.

> Cheers,
>
> Dave.
> --
> Dave Chinner
> david@fromorbit.com

^ permalink raw reply

* Re: [PATCH v7 1/3] scsi: ufs: add ioctl interface for query request
From: Dov Levenglick @ 2015-03-18 13:17 UTC (permalink / raw)
  To: Gilad Broner
  Cc: james.bottomley, linux-kernel, linux-scsi, linux-arm-msm,
	santoshsy, linux-scsi-owner, subhashj, ygardi, draviv, Noa Rubens,
	Raviv Shvili, Vinayak Holikatti, James E.J. Bottomley,
	open list:ABI/API
In-Reply-To: <1426175700-23152-2-git-send-email-gbroner@codeaurora.org>

> From: Dolev Raviv <draviv@codeaurora.org>
>
> This patch exposes the ioctl interface for UFS driver via SCSI device
> ioctl interface. As of now UFS driver would provide the ioctl for query
> interface to connected UFS device.
>
> Signed-off-by: Dolev Raviv <draviv@codeaurora.org>
> Signed-off-by: Noa Rubens <noag@codeaurora.org>
> Signed-off-by: Raviv Shvili <rshvili@codeaurora.org>
> Signed-off-by: Yaniv Gardi <ygardi@codeaurora.org>
> ---
>  drivers/scsi/ufs/ufs.h        |  53 ++--------
>  drivers/scsi/ufs/ufshcd.c     | 226
> +++++++++++++++++++++++++++++++++++++++++-
>  include/scsi/scsi.h           |   1 +
>  include/uapi/scsi/Kbuild      |   1 +
>  include/uapi/scsi/ufs/Kbuild  |   3 +
>  include/uapi/scsi/ufs/ioctl.h |  57 +++++++++++
>  include/uapi/scsi/ufs/ufs.h   |  66 ++++++++++++
>  7 files changed, 363 insertions(+), 44 deletions(-)
>  create mode 100644 include/uapi/scsi/ufs/Kbuild
>  create mode 100644 include/uapi/scsi/ufs/ioctl.h
>  create mode 100644 include/uapi/scsi/ufs/ufs.h
>

[ removed ~530 lines of code]
Reviewed-by: Dov Levenglick <dovl@codeaurora.org>

> --
> Qualcomm Israel, on behalf of Qualcomm Innovation Center, Inc.
> The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,
> a Linux Foundation Collaborative Project
>
> --
> To unsubscribe from this list: send the line "unsubscribe linux-scsi" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html
>


QUALCOMM ISRAEL, on behalf of Qualcomm Innovation Center, Inc.
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,
a Linux Foundation Collaborative Project

^ permalink raw reply

* Re: [PATCH v4 00/14] Add kdbus implementation
From: David Herrmann @ 2015-03-18 13:54 UTC (permalink / raw)
  To: Andy Lutomirski
  Cc: Greg Kroah-Hartman, Arnd Bergmann, Eric W. Biederman,
	One Thousand Gnomes, Tom Gundersen, Jiri Kosina, Linux API,
	linux-kernel-u79uwXL29TY76Z2rM5mHXA@public.gmane.org, Daniel Mack,
	Djalal Harouni
In-Reply-To: <CALCETrUjqTH14fZCeqU_OBoKX_6x4B=712WTeSqSAztpgXGiDw-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org>

Hi

On Tue, Mar 17, 2015 at 8:24 PM, Andy Lutomirski <luto-kltTT9wpgjJwATOyAt5JVQ@public.gmane.org> wrote:
[...]
> Can anyone comment on how fast it actually is.  I'm curious
> about:
>
>  - The time it takes to do the ioctl to send a message
>
>  - The time it takes to receive a message (poll + whatever ioctls)

I'm not sure I can gather useful absolute data here. This highly
depends on how you call it, how often you call it, what payloads you
pass, what machine you're on.. you know all that.

So here's a flamegraph for you (which I use for comparisons to UDS):
  http://people.freedesktop.org/~dvdhrm/kdbus_8kb.svg

This program sends unicast messages on kdbus and UDS, exactly the same
number of times with the same 8kb payload. No parsing, no marshaling
is done, just plain message passing. The interesting spikes are
sys_read(), sys_write() and the 3 kdbus sys_ioctl(). Everything else
should be ignored.

sys_read() and sys_ioctl(KDBUS_CMD_RECV) are about the same. But note
that we don't copy any payload in RECV, so it scales O(1) compared to
message-size.

sys_write() is about 3x faster than sys_ioctl(KDBUS_CMD_WRITE).

I see lots of room for improvement in both RECV and SEND. Caching the
namespaces on a connection, would get rid of
kdbus_queue_entry_install() in RECV, thus speeding it up by ~30%. In
SEND, we could merge the kvec and iovec copying, to avoid calling
shmem_begin_write() twice. We should also stop allocating management
structures that are not used (like for metadata, if no metadata is
transmitted). We should use stack-space for small ioctl objects,
instead of memdup_user(). And so on.. Oh, and locking can be reduced.
We haven't even looked at rcu, yet (though that's mostly interesting
for policy and broadcasts, not unicasts).

>  - The time it takes to transfer a memfd (I don't care about how long
> it takes to create or map a memfd -- that's exactly the same between
> kdbus and any other memfds user, I imagine)

The time to transmit a memfd is the same as to transmit a 64-byte
payload. Ok, you also get to install the fd into the fd-table, but
that's true regardless of the transport.
Here's a graph for 64byte transfers (otherwise, same as above):
  http://people.freedesktop.org/~dvdhrm/kdbus_64b.svg

>  - The time it takes to connect

No idea, never measured it. Why is it of interest?

> I'm also interested in whether the current design is actually amenable
> to good performance.  I'm told that it is, but ISTM there's a lot of
> heavyweight stuff going on with each send operation that will be hard
> to remove.

I disagree. What heavyweight stuff is going on?

Thanks
David

^ permalink raw reply

* Re: [PATCH v4 4/9] selftests: Add install target
From: Shuah Khan @ 2015-03-18 14:30 UTC (permalink / raw)
  To: Michael Ellerman
  Cc: linux-kernel-u79uwXL29TY76Z2rM5mHXA,
	davej-rdkfGonbjUTCLXcRTR1eJlpr/1R2p/CL, mmarek-AlSwsSmVLrQ,
	linux-api-u79uwXL29TY76Z2rM5mHXA
In-Reply-To: <1426475092.20210.4.camel-Gsx/Oe8HsFggBc27wqDAHg@public.gmane.org>

On 03/15/2015 09:04 PM, Michael Ellerman wrote:
> On Fri, 2015-03-13 at 15:32 -0600, Shuah Khan wrote:
>> On 03/13/2015 11:20 AM, Shuah Khan wrote:
>>> On 03/10/2015 10:06 PM, Michael Ellerman wrote:
>>>> This adds make install support to selftests. The basic usage is:
>>>>
>>>> $ cd tools/testing/selftests
>>>> $ make install
>>>>
>>>> That installs into tools/testing/selftests/install, which can then be
>>>> copied where ever necessary.
>>>>
>>>> The install destination is also configurable using eg:
>>>>
>>>> $ INSTALL_PATH=/mnt/selftests make install
>>>>
>>>> The implementation uses two targets in the child makefiles. The first
>>>> "install" is expected to install all files into $(INSTALL_PATH).
>>>>
>>>> The second, "emit_tests", is expected to emit the test instructions (ie.
>>>> bash script) on stdout. Separating this from install means the child
>>>> makefiles need no knowledge of the location of the test script.
>>>>
>>>> Signed-off-by: Michael Ellerman <mpe-Gsx/Oe8HsFggBc27wqDAHg@public.gmane.org>
>>>
>>> Thanks for doing the work. This patch will be applied to next and will
>>> be queued for 4.1
>>>
>>
>> ok. linux-kselftest next has both shared logic and install patches
>> now.
> 
> Thanks, looks good to me.
> 
> Can you also apply the patch to install the powerpc tests, or was there a
> problem with it? It seems to apply cleanly for me.
> 
> https://lkml.org/lkml/2015/3/11/9
> 
> cheers

It is on my todo after the install patches are squared away.
It will be applied to next.

-- Shuah

-- 
Shuah Khan
Sr. Linux Kernel Developer
Open Source Innovation Group
Samsung Research America (Silicon Valley)
shuahkh-JPH+aEBZ4P+UEJcrhfAQsw@public.gmane.org | (970) 217-8978

^ permalink raw reply

* Re: [PATCH V5] Allow compaction of unevictable pages
From: Vlastimil Babka @ 2015-03-18 14:40 UTC (permalink / raw)
  To: Eric B Munson
  Cc: Michal Hocko, Rik van Riel, Andrew Morton, Thomas Gleixner,
	Christoph Lameter, Peter Zijlstra, Mel Gorman, David Rientjes,
	linux-mm-Bw31MaZKKs3YtjvyW6yDsg,
	linux-kernel-u79uwXL29TY76Z2rM5mHXA, Linux API
In-Reply-To: <20150316134956.GA15324-JqFfY2XvxFXQT0dZR+AlfA@public.gmane.org>

On 03/16/2015 02:49 PM, Eric B Munson wrote:
> On Mon, 16 Mar 2015, Vlastimil Babka wrote:
>
>> [CC += linux-api@]
>>
>> Since this is a kernel-user-space API change, please CC linux-api@.
>> The kernel source file Documentation/SubmitChecklist notes that all
>> Linux kernel patches that change userspace interfaces should be CCed
>> to linux-api-u79uwXL29TY76Z2rM5mHXA@public.gmane.org, so that the various parties who are
>> interested in API changes are informed. For further information, see
>> https://urldefense.proofpoint.com/v2/url?u=https-3A__www.kernel.org_doc_man-2Dpages_linux-2Dapi-2Dml.html&d=AwIC-g&c=96ZbZZcaMF4w0F4jpN6LZg&r=aUmMDRRT0nx4IfILbQLv8xzE0wB9sQxTHI3QrQ2lkBU&m=GUotTNnv26L0HxtXrBgiHqu6kwW3ufx2_TQpXIA216c&s=IFFYQ7Zr-4SIaF3slOZqiSP_noyva42kCwVRxxDm5wo&e=
>
> Added to the Cc list, thanks.
>
>>
>>
>> On 03/13/2015 09:19 PM, Michal Hocko wrote:
>>> On Fri 13-03-15 15:09:15, Eric B Munson wrote:
>>>> On Fri, 13 Mar 2015, Rik van Riel wrote:
>>>>
>>>>> On 03/13/2015 01:26 PM, Eric B Munson wrote:
>>>>>
>>>>>> --- a/mm/compaction.c
>>>>>> +++ b/mm/compaction.c
>>>>>> @@ -1046,6 +1046,8 @@ typedef enum {
>>>>>>   	ISOLATE_SUCCESS,	/* Pages isolated, migrate */
>>>>>>   } isolate_migrate_t;
>>>>>>
>>>>>> +int sysctl_compact_unevictable;
>>
>> A comment here would be useful I think, as well as explicit default
>> value. Maybe also __read_mostly although I don't know how much that
>> matters.
>
> I am going to sit on V6 for a couple of days incase anyone from rt wants
> to chime in.  But these will be in V6.
>
>>
>> I also wonder if it might be confusing that "compact_memory" is a
>> write-only trigger that doesn't even show under "sysctl -a", while
>> "compact_unevictable" is a read/write setting. But I don't have a
>> better suggestion right now.
>
> Does allow_unevictable_compaction sound better?  It feels too much like

For sorting purposes, maybe compact_unevictable_allowed?

> variable naming conventions from other languages which seems to
> encourage verbosity to me, but does indicate a difference from
> compact_memory.

If it sounds too awkward/long and nobody else has better suggestion, 
then just keep it as "compact_unevictable".

^ permalink raw reply

* Re: [PATCH] selftests: Fix kcmp build to not require headers install
From: Shuah Khan @ 2015-03-18 15:04 UTC (permalink / raw)
  To: Michael Ellerman
  Cc: gorcunov-GEFAQzZX7r8dnm+yROfE0A,
	tranmanphong-Re5JQEeQqe8AvxtiuMwx3w,
	akpm-de/tnXTf+JLsfHDXvbKv3WD2FQJk+8+b,
	linux-api-u79uwXL29TY76Z2rM5mHXA,
	linux-kernel-u79uwXL29TY76Z2rM5mHXA
In-Reply-To: <1426503639.4716.7.camel-Gsx/Oe8HsFggBc27wqDAHg@public.gmane.org>

On 03/16/2015 05:00 AM, Michael Ellerman wrote:
> On Fri, 2015-03-13 at 19:45 -0600, Shuah Khan wrote:
>> Change CFLAGS to look in uapi to allow kcmp to be built without
>> requiring headers install. This will make it easier to run tests
>> without going through the headers install step.
>>
>> Signed-off-by: Shuah Khan <shuahkh-JPH+aEBZ4P+UEJcrhfAQsw@public.gmane.org>
>> ---
>>  tools/testing/selftests/kcmp/Makefile | 2 +-
>>  1 file changed, 1 insertion(+), 1 deletion(-)
>>
>> diff --git a/tools/testing/selftests/kcmp/Makefile b/tools/testing/selftests/kcmp/Makefile
>> index ff0eefd..d405ad4 100644
>> --- a/tools/testing/selftests/kcmp/Makefile
>> +++ b/tools/testing/selftests/kcmp/Makefile
>> @@ -1,5 +1,5 @@
>>  CC := $(CROSS_COMPILE)$(CC)
>> -CFLAGS += -I../../../../usr/include/
>> +CFLAGS += -I../../../../include/uapi -I../../../../usr/include/
> 
> Hi Shuah,
> 
> Sorry but this is wrong. The contents of include/uapi are not the same as the
> exported kernel headers.
> 
> Mixing the unprocessed kernel headers with user headers leads to all sorts of
> mess, eg:
> 
> $ cc -I../../../../include/uapi -I../../../../usr/include/ kcmp_test.c   -o kcmp_test

Do you see this error when you run the compile using kcmp Makefile
or using make ksefltest target?

Do you consider running cc directly isn't a valid use-case for
this test?

I see your point that kernel headers shouldn't be included from user
space. But kcmp_test isn't really a regular use space app. It is
intended for testing kernel. There are other tests that do include
uapi headers.

> In file included from /usr/include/powerpc64le-linux-gnu/asm/ptrace.h:27:0,
>                  from /usr/include/powerpc64le-linux-gnu/asm/sigcontext.h:11,
>                  from /usr/include/powerpc64le-linux-gnu/bits/sigcontext.h:27,
>                  from /usr/include/signal.h:332,
>                  from kcmp_test.c:5:
> ../../../../include/uapi/linux/types.h:9:2: warning: #warning "Attempt to use kernel headers from user space, see http://kernelnewbies.org/KernelHeaders" [-Wcpp]
>  #warning "Attempt to use kernel headers from user space, see http://kernelnewbies.org/KernelHeaders"
>   ^
> In file included from ../../../../include/uapi/linux/posix_types.h:4:0,
>                  from ../../../../include/uapi/linux/types.h:13,
>                  from /usr/include/powerpc64le-linux-gnu/asm/ptrace.h:27,
>                  from /usr/include/powerpc64le-linux-gnu/asm/sigcontext.h:11,
>                  from /usr/include/powerpc64le-linux-gnu/bits/sigcontext.h:27,
>                  from /usr/include/signal.h:332,
>                  from kcmp_test.c:5:
> ../../../../include/uapi/linux/stddef.h:1:28: fatal error: linux/compiler.h: No such file or directory
>  #include <linux/compiler.h>
>                             ^
> compilation terminated.
> <builtin>: recipe for target 'kcmp_test' failed
> make: *** [kcmp_test] Error 1
> 
> 
> If you want to make it easier to build tests that need the kernel headers then
> maybe kselftest should depend on headers_install?
> 

Requiring header install is a big hammer. Thinking about a developer
use-case, if a developer is building and testing several kernels, it
is tedious install headers each time and remembering to cleanup headers.

thanks,
-- Shuah


-- 
Shuah Khan
Sr. Linux Kernel Developer
Open Source Innovation Group
Samsung Research America (Silicon Valley)
shuahkh-JPH+aEBZ4P+UEJcrhfAQsw@public.gmane.org | (970) 217-8978

^ permalink raw reply

* Re: [PATCH v0 01/11] stm class: Introduce an abstraction for System Trace Module devices
From: Mathieu Poirier @ 2015-03-18 15:07 UTC (permalink / raw)
  To: Alexander Shishkin
  Cc: Greg Kroah-Hartman, linux-kernel@vger.kernel.org, Pratik Patel,
	peter.lachner, norbert.schulz, keven.boell, yann.fouassier,
	laurent.fert, linux-api
In-Reply-To: <87mw3bewq8.fsf@ashishki-desk.ger.corp.intel.com>

On 17 March 2015 at 04:37, Alexander Shishkin
<alexander.shishkin@linux.intel.com> wrote:
> Mathieu Poirier <mathieu.poirier@linaro.org> writes:
>
>> On 7 March 2015 at 04:35, Alexander Shishkin
>> <alexander.shishkin@linux.intel.com> wrote:
>>> A System Trace Module (STM) is a device exporting data in System Trace
>>> Protocol (STP) format as defined by MIPI STP standards. Examples of such
>>> devices are Intel Trace Hub and Coresight STM.
>>>
>>> This abstraction provides a unified interface for software trace sources
>>> to send their data over an STM device to a debug host. In order to do
>>> that, such a trace source needs to be assigned a pair of master/channel
>>> identifiers that all the data from this source will be tagged with. The
>>> STP decoder on the debug host side will use these master/channel tags to
>>> distinguish different trace streams from one another inside one STP
>>> stream.
>>>
>>> This abstraction provides a configfs-based policy management mechanism
>>> for dynamic allocation of these master/channel pairs based on trace
>>> source-supplied string identifier. It has the flexibility of being
>>> defined at runtime and at the same time (provided that the policy
>>> definition is aligned with the decoding end) consistency.
>>>
>>> For userspace trace sources, this abstraction provides write()-based and
>>> mmap()-based (if the underlying stm device allows this) output mechanism.
>>>
>>> For kernel-side trace sources, we provide "stm_source" device class that
>>> can be connected to an stm device at run time.
>>>
>>> Cc: linux-api@vger.kernel.org
>>> Cc: Pratik Patel <pratikp@codeaurora.org>
>>> Cc: Mathieu Poirier <mathieu.poirier@linaro.org>
>>> Signed-off-by: Alexander Shishkin <alexander.shishkin@linux.intel.com>
>>> ---
>>>  Documentation/ABI/testing/configfs-stp-policy    |  44 ++
>>>  Documentation/ABI/testing/sysfs-class-stm        |  14 +
>>>  Documentation/ABI/testing/sysfs-class-stm_source |  11 +
>>>  Documentation/trace/stm.txt                      |  77 +++
>>>  drivers/Kconfig                                  |   2 +
>>>  drivers/Makefile                                 |   1 +
>>>  drivers/stm/Kconfig                              |   8 +
>>>  drivers/stm/Makefile                             |   3 +
>>>  drivers/stm/core.c                               | 839 +++++++++++++++++++++++
>>>  drivers/stm/policy.c                             | 470 +++++++++++++
>>>  drivers/stm/stm.h                                |  77 +++
>>>  include/linux/stm.h                              |  87 +++
>>>  include/uapi/linux/stm.h                         |  47 ++
>>>  13 files changed, 1680 insertions(+)
>>>  create mode 100644 Documentation/ABI/testing/configfs-stp-policy
>>>  create mode 100644 Documentation/ABI/testing/sysfs-class-stm
>>>  create mode 100644 Documentation/ABI/testing/sysfs-class-stm_source
>>>  create mode 100644 Documentation/trace/stm.txt
>>>  create mode 100644 drivers/stm/Kconfig
>>>  create mode 100644 drivers/stm/Makefile
>>>  create mode 100644 drivers/stm/core.c
>>>  create mode 100644 drivers/stm/policy.c
>>>  create mode 100644 drivers/stm/stm.h
>>>  create mode 100644 include/linux/stm.h
>>>  create mode 100644 include/uapi/linux/stm.h
>>>
>>
>> [Snip...]
>>
>>> +
>>> +static int stm_output_assign(struct stm_device *stm, unsigned int width,
>>> +                            struct stp_policy_node *policy_node,
>>> +                            struct stm_output *output)
>>> +{
>>> +       unsigned int midx, cidx, mend, cend;
>>> +       int ret = -EBUSY;
>>> +
>>> +       if (width > stm->data->sw_nchannels)
>>> +               return -EINVAL;
>>> +
>>> +       if (policy_node) {
>>
>> Where does this get set?  All I found is code that is switching on it.
>
> It comes from stp_policy_node_lookup() in stm_file_assign() or
> stm_source_link_add().
>
>>> +               stp_policy_node_get_ranges(policy_node,
>>> +                                          &midx, &mend, &cidx, &cend);
>>> +       } else {
>>> +               midx = stm->data->sw_start;
>>> +               cidx = 0;
>>> +               mend = stm->data->sw_end;
>>> +               cend = stm->data->sw_nchannels - 1;
>>> +       }
>>> +
>>> +       spin_lock(&stm->mc_lock);
>>> +       if (output->nr_chans)
>>> +               goto unlock;
>>> +
>>> +       ret = stm_find_master_chan(stm, width, &midx, mend, &cidx, cend);
>>> +       if (ret)
>>> +               goto unlock;
>>> +
>>> +       output->master = midx;
>>> +       output->channel = cidx;
>>> +       output->nr_chans = width;
>>> +       stm_output_claim(stm, output);
>>> +       dev_dbg(stm->dev, "assigned %u:%u (+%u)\n", midx, cidx, width);
>>> +
>>> +       ret = 0;
>>> +unlock:
>>> +       spin_unlock(&stm->mc_lock);
>>> +
>>> +       return ret;
>>> +}
>>> +
>>
>> [Snip...]
>>
>>> +
>>> +/**
>>> + * stm_source_register_device() - register an stm_source device
>>> + * @parent:    parent device
>>> + * @data:      device description structure
>>> + *
>>> + * This will create a device of stm_source class that can write
>>> + * data to an stm device once linked.
>>> + *
>>> + * Return:     0 on success, -errno otherwise.
>>> + */
>>> +int stm_source_register_device(struct device *parent,
>>> +                              struct stm_source_data *data)
>>> +{
>>> +       struct stm_source_device *src;
>>> +       struct device *dev;
>>> +
>>> +       if (!stm_core_up)
>>> +               return -EPROBE_DEFER;
>>> +
>>> +       src = kzalloc(sizeof(*src), GFP_KERNEL);
>>> +       if (!src)
>>> +               return -ENOMEM;
>>> +
>>> +       dev = device_create(&stm_source_class, parent, MKDEV(0, 0), NULL, "%s",
>>> +                           data->name);
>>> +       if (IS_ERR(dev)) {
>>> +               kfree(src);
>>> +               return PTR_ERR(dev);
>>> +       }
>>> +
>>> +       spin_lock_init(&src->link_lock);
>>> +       INIT_LIST_HEAD(&src->link_entry);
>>> +       src->dev = dev;
>>> +       src->data = data;
>>> +       data->src = src;
>>> +       dev_set_drvdata(dev, src);
>>> +
>>> +       return 0;
>>> +}
>>> +EXPORT_SYMBOL_GPL(stm_source_register_device);
>>> +
>>
>> [Snip...]
>>
>> It's really not clear (at least to me) how stm_source_device works.
>> They make a bridge between the kernel and the STM devices but the
>> "link" between them is not obvious.  More documentation perhaps?
>
> Sure, I need to elaborate on this a bit. The idea the stm_source device
> gets "linked" to an stm device by way of writing that stm device name to
> its stm_source_link attribute and if everything's fine, stm_sounrce's
> .link callback is called, after which it can start sending data out with
> stm_sounce_write().
>
>>> +/**
>>> + * struct stm_data - STM device description and callbacks
>>> + * @name:              device name
>>> + * @stm:               internal structure, only used by stm class code
>>> + * @sw_start:          first STP master
>>> + * @sw_end:            last STP master
>>> + * @sw_nchannels:      number of STP channels per master
>>> + * @sw_mmiosz:         size of one channel's IO space, for mmap, optional
>>> + * @write:             write callback
>>> + * @mmio_addr:         mmap callback, optional
>>> + *
>>> + * Fill out this structure before calling stm_register_device() to create
>>> + * an STM device and stm_unregister_device() to destroy it. It will also be
>>> + * passed back to write() and mmio_addr() callbacks.
>>> + */
>>> +struct stm_data {
>>> +       const char              *name;
>>> +       struct stm_device       *stm;
>>> +       unsigned int            sw_start;
>>> +       unsigned int            sw_end;
>>
>> The above kernel doc is the only place where "sw_start" and "sw_end"
>> are described as first and last STP masters.  Other than that it takes
>> a really long time to figure out what they really are.  I think a
>> better naming convention can be chosen here.
>
> The idea is that only a certain subset of masters is available for
> software (others being statically assigned to different hw blocks or
> otherwise unavailable to software). These two mark start and end of this
> subset.
>
>>
>>> +       unsigned int            sw_nchannels;
>>> +       unsigned int            sw_mmiosz;
>>> +       ssize_t                 (*write)(struct stm_data *, unsigned int,
>>> +                                        unsigned int, const char *, size_t);
>>> +       phys_addr_t             (*mmio_addr)(struct stm_data *, unsigned int,
>>> +                                            unsigned int, unsigned int);
>>> +       void                    (*link)(struct stm_data *, unsigned int,
>>> +                                       unsigned int);
>>> +       void                    (*unlink)(struct stm_data *, unsigned int,
>>> +                                         unsigned int);
>>
>> It is really not clear to me what the "link" and "unlink" functions do
>> - documenting what they're for and explain when to use them and (not
>> use them) would be appreciated.
>
> Will do.
>
>> I think we should also add two things to this structure:  1) a private
>> field and 2) a (*stm_drv_ioctl) stub.
>> The private field would be filled by the registrant and left alone by
>> the generic-stm core.  When parsing the commands in
>> "stm_char_ioctl()", data->stm_drv_ioctl(private, cmd, arg) could be
>> called to let architecture specific drivers deal with it.  That way
>> applications can deal with a single configuration file descriptor.
>
> Indeed, good idea.
>
>>
>>> +};
>>> +
>>> +int stm_register_device(struct device *parent, struct stm_data *stm_data,
>>> +                       struct module *owner);
>>> +void stm_unregister_device(struct stm_data *stm_data);
>>> +
>>> +struct stm_source_device;
>>> +
>>> +/**
>>> + * struct stm_source_data - STM source device description and callbacks
>>> + * @name:      device name, will be used for policy lookup
>>> + * @src:       internal structure, only used by stm class code
>>> + * @nr_chans:  number of channels to allocate
>>> + * @link:      called when STM device gets linked to this source
>>> + * @unlink:    called when STH device is about to be unlinked
>>> + *
>>> + * Fill in this structure before calling stm_source_register_device() to
>>> + * register a source device. Also pass it to unregister and write calls.
>>> + */
>>> +struct stm_source_data {
>>> +       const char              *name;
>>> +       struct stm_source_device *src;
>>> +       unsigned int            percpu;
>>> +       unsigned int            nr_chans;
>>> +       int                     (*link)(struct stm_source_data *data);
>>> +       void                    (*unlink)(struct stm_source_data *data);
>>> +};
>>> +
>>
>> I didn't get the linking/unlinking process - it is also not clear as
>> to why we need struct stm_data and struct stm_source_data.  More
>> explanation on this would be good.
>
> My idea is that connecting stm to stm_source device is done via sysfs
> attribute write like so:
>
> $ echo dummy_stm > /sys/class/stm_source/stm_console/stm_source_link
>
> This will result in stm_source's .link getting called, at which point
> stm_console, for example, will do a register_console().
>
> stm_data is there for stm devices to pass their parameters and callbacks
> to stm_register_device(); stm_source data is that for stm_source
> devices. I'll try to be more elaborate about these in my followup.
>
>>> +int stm_source_register_device(struct device *parent,
>>> +                              struct stm_source_data *data);
>>> +void stm_source_unregister_device(struct stm_source_data *data);
>>> +
>>> +int stm_source_write(struct stm_source_data *data, unsigned int chan,
>>> +                    const char *buf, size_t count);
>>> +
>>> +#endif /* _STM_H_ */
>>> diff --git a/include/uapi/linux/stm.h b/include/uapi/linux/stm.h
>>> new file mode 100644
>>> index 0000000000..042b58b53b
>>> --- /dev/null
>>> +++ b/include/uapi/linux/stm.h
>>> @@ -0,0 +1,47 @@
>>> +/*
>>> + * System Trace Module (STM) userspace interfaces
>>> + * Copyright (c) 2014, Intel Corporation.
>>> + *
>>> + * This program is free software; you can redistribute it and/or modify it
>>> + * under the terms and conditions of the GNU General Public License,
>>> + * version 2, as published by the Free Software Foundation.
>>> + *
>>> + * This program is distributed in the hope it will be useful, but WITHOUT
>>> + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
>>> + * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
>>> + * more details.
>>> + *
>>> + * STM class implements generic infrastructure for  System Trace Module devices
>>> + * as defined in MIPI STPv2 specification.
>>> + */
>>> +
>>> +#ifndef _UAPI_LINUX_STM_H
>>> +#define _UAPI_LINUX_STM_H
>>> +
>>> +/**
>>> + * struct stp_policy_id - identification for the STP policy
>>> + * @size:      size of the structure including real id[] length
>>> + * @master:    assigned master
>>> + * @channel:   first assigned channel
>>> + * @width:     number of requested channels
>>> + * @id:                identification string
>>> + *
>>> + * User must calculate the total size of the structure and put it into
>>> + * @size field, fill out the @id and desired @width. In return, kernel
>>> + * fills out @master, @channel and @width.
>>> + */
>>> +struct stp_policy_id {
>>> +       __u32           size;
>>> +       __u16           master;
>>> +       __u16           channel;
>>> +       __u16           width;
>>> +       /* padding */
>>> +       __u16           __reserved_0;
>>> +       __u32           __reserved_1;
>>> +       char            id[0];
>>> +};
>>> +
>>> +#define STP_POLICY_ID_SET      _IOWR('%', 0, struct stp_policy_id)
>>> +#define STP_POLICY_ID_GET      _IOR('%', 1, struct stp_policy_id)
>>> +
>>> +#endif /* _UAPI_LINUX_STM_H */
>>> --
>>> 2.1.4
>>>
>>
>> Aside from the above points I think this is all very good work.  The
>> patchset should likely be broken up in two sets, one for the generic
>> STM architecture wrapper and another for the Intel TH part.  That way
>> things can be worked on independently.
>
> The Intel TH part is very much dependent on the STM part; I could split
> out the stm-dependant patch from Intel TH, but that just seems to make
> it more complex for me and reviewers. I'd prefer to keep them together
> unless there are strong objections.
>
>> On my side I will get a prototype going that folds the current
>> coresight-stm driver in this new mindset - I'll let you know how
>> things go.
>
> Thanks a lot!
>
> Regards,

I forgot to mention in my previous email...  I think the hierarchy of
our respective tracing module along with the generic-stm probably
needs a review.

Currently we have drivers/coresight, drivers/intel_th and drivers/stm.

To me it doesn't scale - what happens when other architectures come
out with their own hw tracing technologies?

I suggest we move everything under drivers/hwtracing and as such have:

drivers/hwtracing
drivers/hwtracing/intel_ht
drivers/hwtracing/coresight
drivers/hwtracing/stm

That way other architectures can add drivers for their own hw tracing
technology without further polluting the drivers/ directory and
concentrating everything in the same area.  What's your view on that?

> --
> Alex

^ permalink raw reply

* Re: [PATCH V5] Allow compaction of unevictable pages
From: Steven Rostedt @ 2015-03-18 15:40 UTC (permalink / raw)
  To: Eric B Munson
  Cc: Vlastimil Babka, Michal Hocko, Rik van Riel, Andrew Morton,
	Thomas Gleixner, Christoph Lameter, Peter Zijlstra, Mel Gorman,
	David Rientjes, linux-mm, linux-kernel, Linux API, linux-rt-users
In-Reply-To: <20150316134956.GA15324@akamai.com>

On Mon, Mar 16, 2015 at 09:49:56AM -0400, Eric B Munson wrote:
> On Mon, 16 Mar 2015, Vlastimil Babka wrote:
> 
> > [CC += linux-api@]
> > 
> > Since this is a kernel-user-space API change, please CC linux-api@.
> > The kernel source file Documentation/SubmitChecklist notes that all
> > Linux kernel patches that change userspace interfaces should be CCed
> > to linux-api@vger.kernel.org, so that the various parties who are
> > interested in API changes are informed. For further information, see
> > https://urldefense.proofpoint.com/v2/url?u=https-3A__www.kernel.org_doc_man-2Dpages_linux-2Dapi-2Dml.html&d=AwIC-g&c=96ZbZZcaMF4w0F4jpN6LZg&r=aUmMDRRT0nx4IfILbQLv8xzE0wB9sQxTHI3QrQ2lkBU&m=GUotTNnv26L0HxtXrBgiHqu6kwW3ufx2_TQpXIA216c&s=IFFYQ7Zr-4SIaF3slOZqiSP_noyva42kCwVRxxDm5wo&e=
> 
> Added to the Cc list, thanks.
> 
> > 
> > 
> > On 03/13/2015 09:19 PM, Michal Hocko wrote:
> > >On Fri 13-03-15 15:09:15, Eric B Munson wrote:
> > >>On Fri, 13 Mar 2015, Rik van Riel wrote:
> > >>
> > >>>On 03/13/2015 01:26 PM, Eric B Munson wrote:
> > >>>
> > >>>>--- a/mm/compaction.c
> > >>>>+++ b/mm/compaction.c
> > >>>>@@ -1046,6 +1046,8 @@ typedef enum {
> > >>>>  	ISOLATE_SUCCESS,	/* Pages isolated, migrate */
> > >>>>  } isolate_migrate_t;
> > >>>>
> > >>>>+int sysctl_compact_unevictable;
> > 
> > A comment here would be useful I think, as well as explicit default
> > value. Maybe also __read_mostly although I don't know how much that
> > matters.
> 
> I am going to sit on V6 for a couple of days incase anyone from rt wants
> to chime in.  But these will be in V6.
> 
> > 
> > I also wonder if it might be confusing that "compact_memory" is a
> > write-only trigger that doesn't even show under "sysctl -a", while
> > "compact_unevictable" is a read/write setting. But I don't have a
> > better suggestion right now.
> 
> Does allow_unevictable_compaction sound better?  It feels too much like
> variable naming conventions from other languages which seems to
> encourage verbosity to me, but does indicate a difference from
> compact_memory.
> 
> > 
> > >>>>+
> > >>>>  /*
> > >>>>   * Isolate all pages that can be migrated from the first suitable block,
> > >>>>   * starting at the block pointed to by the migrate scanner pfn within
> > >>>
> > >>>I suspect that the use cases where users absolutely do not want
> > >>>unevictable pages migrated are special cases, and it may make
> > >>>sense to enable sysctl_compact_unevictable by default.
> > >>
> > >>Given that sysctl_compact_unevictable=0 is the way the kernel behaves
> > >>now and the push back against always enabling compaction on unevictable
> > >>pages, I left the default to be the behavior as it is today.
> > >
> > >The question is _why_ we have this behavior now. Is it intentional?
> > 
> > It's there since 748446bb6 ("mm: compaction: memory compaction
> > core"). Commit c53919adc0 ("mm: vmscan: remove lumpy reclaim")
> > changes the comment in __isolate_lru_page() handling of unevictable
> > pages to mention compaction explicitly. It could have been
> > accidental in 748446bb6 though, maybe it just reused
> > __isolate_lru_page() for compaction - it seems that the skipping of
> > unevictable was initially meant to optimize lumpy reclaim.
> > 
> > >e46a28790e59 (CMA: migrate mlocked pages) is a precedence in that
> > 
> > Well, CMA and realtime kernels are probably mutually exclusive enough.
> > 
> > >direction. Vlastimil has then changed that by edc2ca612496 (mm,
> > >compaction: move pageblock checks up from isolate_migratepages_range()).
> > >There is no mention about mlock pages so I guess it was more an
> > >unintentional side effect of the patch. At least that is my current
> > >understanding. I might be wrong here.
> > 
> > Although that commit did change unintentionally more details that I
> > would have liked (unfortunately), I think you are wrong on this one.
> > ISOLATE_UNEVICTABLE is still passed from
> > isolate_migratepages_range() which is used by CMA, while the
> > compaction variant isolate_migratepages() does not pass it. So it's
> > kept CMA-specific as before.
> > 
> > >The thing about RT is that it is not usable with the upstream kernel
> > >without the RT patchset AFAIU. So the default should be reflect what is
> > >better for the standard kernel. RT loads have to tune the system anyway
> > >so it is not so surprising they would disable this option as well. We
> > >should help those guys and do not require them to touch the code but the
> > >knob is reasonable IMHO.
> > >
> > >Especially when your changelog suggests that having this enabled by
> > >default is beneficial for the standard kernel.
> > 
> > I agree, but if there's a danger of becoming too of a bikeshed
> > topic, I'm fine with keeping the default same as current behavior
> > and changing it later. Or maybe we should ask some -rt mailing list
> > instead of just Peter and Thomas?
> 
> According to the rt wiki, there is no -rt development list so lkml is
> it.  I will change the default to 1 for V6 if I don't hear otherwise by
> the time I get back around to spinning V6.
> 

For kernel development, yes. But this change affects users. Cc'ing the
linux-rt-users mailing list (which I did) is appropriate in this case.

-- Steve


--
To unsubscribe, send a message with 'unsubscribe linux-mm' in
the body to majordomo@kvack.org.  For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"dont@kvack.org"> email@kvack.org </a>

^ permalink raw reply

* Re: [PATCH 2/2] selftests/timers: change to use shared logic to run and install tests
From: Shuah Khan @ 2015-03-18 15:43 UTC (permalink / raw)
  To: John Stultz; +Cc: Thomas Gleixner, mpe, Linux API, lkml, Shuah Khan
In-Reply-To: <CALAqxLXApErmHgCzgoo9xkBCZaP59yu=f9WEmmYwTH29ZrDadQ@mail.gmail.com>

On 03/13/2015 09:14 PM, John Stultz wrote:
> On Fri, Mar 13, 2015 at 3:57 PM, Shuah Khan <shuahkh@osg.samsung.com> wrote:
>> Change the timers Makefile to make use of shared run and install
>> logic in lib.mk. Destructive tests are installed. Regular tests
>> are emited to run_kselftest script to match the run_tests behavior.
>>
>> Signed-off-by: Shuah Khan <shuahkh@osg.samsung.com>
>> ---
>>  tools/testing/selftests/timers/Makefile | 20 +++++++++++---------
>>  1 file changed, 11 insertions(+), 9 deletions(-)
>>
>> diff --git a/tools/testing/selftests/timers/Makefile b/tools/testing/selftests/timers/Makefile
>> index 9da3498..61e7284 100644
>> --- a/tools/testing/selftests/timers/Makefile
>> +++ b/tools/testing/selftests/timers/Makefile
>> @@ -7,19 +7,21 @@ bins = posix_timers nanosleep inconsistency-check nsleep-lat raw_skew \
>>         alarmtimer-suspend change_skew skew_consistency clocksource-switch \
>>         leap-a-day leapcrash set-tai set-2038
>>
>> +TEST_PROGS = posix_timers nanosleep nsleep-lat set-timer-lat mqueue-lat \
>> +               inconsistency-check raw_skew
>> +TEST_FILES = threadtest alarmtimer-suspend valid-adjtimex change_skew \
>> +               skew_consistency clocksource-switch leap-a-day leapcrash \
>> +               set-tai set-2038
>> +
>> +RUN_TESTS_WITH_ARGS := ./threadtest -t 30 -n 8 || echo "selftests: threadtest [FAIL]"
>> +
>> +EMIT_TESTS_WITH_ARGS := echo "$(RUN_TESTS_WITH_ARGS)"
>> +
> 
> So my make-foo isn't very strong, but no objections from me.
> 
> My only thoughts:
> 1) Would it be better if threadtest can be made to have better
> defaults for kselftest so you don't need that extra logic?

Yes. If you can change the threadset to run with -t 30 -n 8
in default case, that would make the logic simpler. Can you
send me a patch to do this?


> 2) While I get that TEST_FILES is likely going to be used to copy the
> destructive tests over, It feels a little like its being bundled in
> with something like data files that tests might need, which seems sort
> of hackish. Would TEST_PROGS_EXTENDED or something be more clear and
> make more sense?

I agree with you on this. TEST_FILES usage is an overload.

-- Shuah


-- 
Shuah Khan
Sr. Linux Kernel Developer
Open Source Innovation Group
Samsung Research America (Silicon Valley)
shuahkh@osg.samsung.com | (970) 217-8978

^ permalink raw reply

* Re: [PATCH 2/2] selftests/timers: change to use shared logic to run and install tests
From: Shuah Khan @ 2015-03-18 15:55 UTC (permalink / raw)
  To: Michael Ellerman, John Stultz
  Cc: Thomas Gleixner, Linux API, lkml, Shuah Khan
In-Reply-To: <1426474128.20210.2.camel-Gsx/Oe8HsFggBc27wqDAHg@public.gmane.org>

On 03/15/2015 08:48 PM, Michael Ellerman wrote:
> On Fri, 2015-03-13 at 20:14 -0700, John Stultz wrote:
>> On Fri, Mar 13, 2015 at 3:57 PM, Shuah Khan <shuahkh-JPH+aEBZ4P+UEJcrhfAQsw@public.gmane.org> wrote:
>>> Change the timers Makefile to make use of shared run and install
>>> logic in lib.mk. Destructive tests are installed. Regular tests
>>> are emited to run_kselftest script to match the run_tests behavior.
>>>
>>> Signed-off-by: Shuah Khan <shuahkh-JPH+aEBZ4P+UEJcrhfAQsw@public.gmane.org>
>>> ---
>>>  tools/testing/selftests/timers/Makefile | 20 +++++++++++---------
>>>  1 file changed, 11 insertions(+), 9 deletions(-)
>>>
>>> diff --git a/tools/testing/selftests/timers/Makefile b/tools/testing/selftests/timers/Makefile
>>> index 9da3498..61e7284 100644
>>> --- a/tools/testing/selftests/timers/Makefile
>>> +++ b/tools/testing/selftests/timers/Makefile
>>> @@ -7,19 +7,21 @@ bins = posix_timers nanosleep inconsistency-check nsleep-lat raw_skew \
>>>         alarmtimer-suspend change_skew skew_consistency clocksource-switch \
>>>         leap-a-day leapcrash set-tai set-2038
>>>
>>> +TEST_PROGS = posix_timers nanosleep nsleep-lat set-timer-lat mqueue-lat \
>>> +               inconsistency-check raw_skew
>>> +TEST_FILES = threadtest alarmtimer-suspend valid-adjtimex change_skew \
>>> +               skew_consistency clocksource-switch leap-a-day leapcrash \
>>> +               set-tai set-2038
>>> +
>>> +RUN_TESTS_WITH_ARGS := ./threadtest -t 30 -n 8 || echo "selftests: threadtest [FAIL]"
>>> +
>>> +EMIT_TESTS_WITH_ARGS := echo "$(RUN_TESTS_WITH_ARGS)"
>>> +
>>
>> So my make-foo isn't very strong, but no objections from me.
>>
>> My only thoughts:
>> 1) Would it be better if threadtest can be made to have better
>> defaults for kselftest so you don't need that extra logic?
> 
> That would help. But with the patch I just sent I think it's no bother, it's
> only a little extra logic and it's only in the timers Makefile.

Let's go with a threadtest patch with better defaults. It will emit
scripts logic as well. Awesome. I just saw John's new patch in my
Inbox. Thanks.

> 
>> 2) While I get that TEST_FILES is likely going to be used to copy the
>> destructive tests over, It feels a little like its being bundled in
>> with something like data files that tests might need, which seems sort
>> of hackish. Would TEST_PROGS_EXTENDED or something be more clear and
>> make more sense?
> 
> That doesn't really bother me. You're right that TEST_FILES is originally
> intended for data files etc. but I don't think it's a big hack to use it for
> other tests that shouldn't be run by default. Still if it bothers you I'm happy
> to add a separate variable for it, they are cheap :)
> 

Michael,

Could you please make the change from TEST_FILES to TEST_PROGS_EXTENDED
which is definitely better than overloading TEST_FILES?

I think this would probably only change Add Install target patch. You
can send me patch v5 with that change and I will override the next with
your new one. Thanks for doing this.

thanks,
-- Shuah

-- 
Shuah Khan
Sr. Linux Kernel Developer
Open Source Innovation Group
Samsung Research America (Silicon Valley)
shuahkh-JPH+aEBZ4P+UEJcrhfAQsw@public.gmane.org | (970) 217-8978

^ permalink raw reply

* [PATCH v2] add support for Freescale's MMA8653FC 10 bit accelerometer
From: Martin Kepplinger @ 2015-03-18 15:55 UTC (permalink / raw)
  To: robh+dt, pawel.moll, mark.rutland, ijc+devicetree, galak,
	dmitry.torokhov
  Cc: akpm, gregkh, linux-api, devicetree, linux-input, linux-kernel,
	Martin Kepplinger, Christoph Muellner

From: Martin Kepplinger <martin.kepplinger@theobroma-systems.com>

The MMA8653FC is a low-power, three-axis, capacitive micromachined
accelerometer with 10 bits of resolution with flexible user-programmable
options.

Embedded interrupt functions enable overall power savings, by relieving the
host processor from continuously polling data, for example using the poll()
system call.

The device can be configured to generate wake-up interrupt signals from any
combination of the configurable embedded functions, enabling the MMA8653FC
to monitor events while remaining in a low-power mode during periods of
inactivity.

This driver provides devicetree properties to program the device's behaviour
and a simple, tested and documented sysfs interface. The data sheet and more
information is available on Freescale's website.

Signed-off-by: Martin Kepplinger <martin.kepplinger@theobroma-systems.com>
Signed-off-by: Christoph Muellner <christoph.muellner@theobroma-systems.com>
---
applies to v4.0-rc4 and the current -next.

patch revision history
......................
v2 corrects licensing and commit messages and adds appropriate recipients

 .../testing/sysfs-bus-i2c-devices-fsl-mma8653fc    |  39 +
 .../devicetree/bindings/misc/fsl,mma8653fc.txt     |  96 +++
 MAINTAINERS                                        |   5 +
 drivers/input/misc/Kconfig                         |  11 +
 drivers/input/misc/Makefile                        |   1 +
 drivers/input/misc/mma8653fc.c                     | 913 +++++++++++++++++++++
 6 files changed, 1065 insertions(+)
 create mode 100644 Documentation/ABI/testing/sysfs-bus-i2c-devices-fsl-mma8653fc
 create mode 100644 Documentation/devicetree/bindings/misc/fsl,mma8653fc.txt
 create mode 100644 drivers/input/misc/mma8653fc.c

diff --git a/Documentation/ABI/testing/sysfs-bus-i2c-devices-fsl-mma8653fc b/Documentation/ABI/testing/sysfs-bus-i2c-devices-fsl-mma8653fc
new file mode 100644
index 0000000..8172c27
--- /dev/null
+++ b/Documentation/ABI/testing/sysfs-bus-i2c-devices-fsl-mma8653fc
@@ -0,0 +1,39 @@
+What:		/sys/bus/i2c/drivers/mma8653fc/*/standby
+Date:		March 2015
+Contact:	Martin Kepplinger <martin.kepplinger@theobroma-systems.com>
+Description:
+		Write 0 to this in order to turn on the device, and 1 to turn
+		it off. Read to see if it is turned on or off.
+
+
+What:		/sys/bus/i2c/drivers/mma8653fc/*/currentmode
+Date:		March 2015
+Contact:	Martin Kepplinger <martin.kepplinger@theobroma-systems.com>
+Description:
+		Reading this provides the current state of the device, read
+		directly from a register. This can be "standby", "wake" or
+		"sleep".
+
+
+What:		/sys/bus/i2c/drivers/mma8653fc/*/position
+Date:		March 2015
+Contact:	Martin Kepplinger <martin.kepplinger@theobroma-systems.com>
+Description:
+		Read only. Without interrupts enabled gets current position
+		values by reading. Poll "position" with interrupt conditions
+		set, to get notified; see Documentation/.../fsl,mma8653fc.txt
+
+		position file format:
+		"x y z [landscape/portrait status] [front/back status]"
+
+		x y z values:
+			in mg
+		landscape/portrait status char:
+			r	landscape right
+			d	portrait down
+			u	portrait up
+			l	landscape left
+		front/back status char:
+			f	front facing
+			b	back facing
+
diff --git a/Documentation/devicetree/bindings/misc/fsl,mma8653fc.txt b/Documentation/devicetree/bindings/misc/fsl,mma8653fc.txt
new file mode 100644
index 0000000..3921acb
--- /dev/null
+++ b/Documentation/devicetree/bindings/misc/fsl,mma8653fc.txt
@@ -0,0 +1,96 @@
+Freescale MMA8653FC 3-axis Accelerometer
+
+Required properties:
+- compatible
+	"fsl,mma8653fc"
+- reg
+	I2C address
+
+Optional properties:
+
+- interrupt-parent
+	a phandle for the interrupt controller (see
+	Documentation/devicetree/bindings/interrupt-controller/interrupts.txt)
+- interrupts
+	interrupt line to which the chip is connected
+- int1
+	set to use interrupt line 1 instead of 2
+- int_active_high
+	set interrupt line active high
+- ir_freefall_motion_x
+	activate freefall/motion interrupts on x axis
+- ir_freefall_motion_y
+	activate freefall/motion interrupts on y axis
+- ir_freefall_motion_z
+	activate freefall/motion interrupts on z axis
+- irq_threshold
+	0 < value < 8000: threshold for motion interrupts in mg
+- ir_landscape_portrait
+	activate landscape/portrait interrupts
+- ir_data_ready:
+	activate data-ready interrupts
+	Interrupt events can be activated in any combination.
+- range
+	2, 4, or 8: range in g, default: 2
+- auto_wake_sleep
+	auto sleep mode (lower frequency)
+- motion_mode
+	use motion mode instead of freefall mode (trigger if >threshold).
+	per default an interrupt occurs if motion values fall below the
+	value set in "threshold" and therefore can detect free fall on the
+	vertical axis (depending on the position of the device).
+	Setting this values inverts the behaviour and an interrupt occurs
+	above the threshold value, so usually activate horizontal axis in
+	this case.
+
+- x-offset
+	0 < value < 500: calibration offset in mg
+	this value has an offset of 250 itself:
+	0 is -250mg, 250 is 0 mg, 500 is 250mg
+- y-offset
+	see x-offset
+- z-offset
+	see x-offset
+
+Example 1:
+for a device laying on flat ground to recognize acceleration over 100mg.
+x-axis is calibrated to +10mg. Adapt interrupt line to your device.
+
+mma8653fc@1d {
+		compatible = "fsl,mma8653fc";
+		interrupt-parent = <&gpio1>;
+		interrupts = <5 0>;
+		reg = <0x1d>;
+
+		range = <2>;
+		motion_mode;
+		ir_freefall_motion_x;
+		ir_freefall_motion_y;
+		irq_threshold = <100>;
+		x-offset = <160>;
+};
+
+Example 2:
+for a device mounted on a wall with y being the vertical axis. This recognizes
+y-acceleration below 800mg, so free fall or changing the orientation of the
+device (y not being the vertical axis and having ~1000mg anymore).
+
+mma8653fc@1d {
+		compatible = "fsl,mma8653fc";
+		interrupt-parent = <&gpio1>;
+		interrupts = <5 0>;
+		reg = <0x1d>;
+
+		range = <2>;
+		ir_freefall_motion_y;
+		irq_threshold = <800>;
+};
+
+Example 3:
+minimal example. lets users read current acceleration values. No polling
+is available.
+
+mma8653fc@1d {
+		compatible = "fsl,mma8653fc";
+		reg = <0x1d>;
+};
diff --git a/MAINTAINERS b/MAINTAINERS
index 0e1abe8..04c080d 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -4104,6 +4104,11 @@ S:	Maintained
 F:	include/linux/platform_data/video-imxfb.h
 F:	drivers/video/fbdev/imxfb.c
 
+FREESCALE MMA8653FC ACCELEROMETER I2C DRIVER
+M:	Martin Kepplinger <martin.kepplinger@theobroma-systems.com>
+S:	Maintained
+F:	drivers/input/misc/mma8653fc.c
+
 FREESCALE QUAD SPI DRIVER
 M:	Han Xu <han.xu@freescale.com>
 L:	linux-mtd@lists.infradead.org
diff --git a/drivers/input/misc/Kconfig b/drivers/input/misc/Kconfig
index 6deb8da..70d9bf5 100644
--- a/drivers/input/misc/Kconfig
+++ b/drivers/input/misc/Kconfig
@@ -208,6 +208,17 @@ config INPUT_MMA8450
 	  To compile this driver as a module, choose M here: the
 	  module will be called mma8450.
 
+config INPUT_MMA8653FC
+	tristate "MMA8653FC - Freescale's 3-Axis, 10-bit Digital Accelerometer"
+	depends on I2C
+	default n
+	help
+	  Say Y here if you want to support Freescale's MMA8653FC Accelerometer
+	  through I2C interface.
+
+	  To compile this driver as a module, choose M here: the
+	  module will be called mma8653fc.
+
 config INPUT_MPU3050
 	tristate "MPU3050 Triaxial gyroscope sensor"
 	depends on I2C
diff --git a/drivers/input/misc/Makefile b/drivers/input/misc/Makefile
index 403a1a5..0bcd878 100644
--- a/drivers/input/misc/Makefile
+++ b/drivers/input/misc/Makefile
@@ -43,6 +43,7 @@ obj-$(CONFIG_INPUT_MAX8925_ONKEY)	+= max8925_onkey.o
 obj-$(CONFIG_INPUT_MAX8997_HAPTIC)	+= max8997_haptic.o
 obj-$(CONFIG_INPUT_MC13783_PWRBUTTON)	+= mc13783-pwrbutton.o
 obj-$(CONFIG_INPUT_MMA8450)		+= mma8450.o
+obj-$(CONFIG_INPUT_MMA8653FC)		+= mma8653fc.o
 obj-$(CONFIG_INPUT_MPU3050)		+= mpu3050.o
 obj-$(CONFIG_INPUT_PALMAS_PWRBUTTON)	+= palmas-pwrbutton.o
 obj-$(CONFIG_INPUT_PCAP)		+= pcap_keys.o
diff --git a/drivers/input/misc/mma8653fc.c b/drivers/input/misc/mma8653fc.c
new file mode 100644
index 0000000..aba1e5a
--- /dev/null
+++ b/drivers/input/misc/mma8653fc.c
@@ -0,0 +1,913 @@
+/*
+ * mma8653fc.c - Support for Freescale MMA8653FC 3-axis 10-bit accelerometer
+ *
+ * Copyright (c) 2014 Theobroma Systems Design and Consulting GmbH
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ */
+
+#include <linux/device.h>
+#include <linux/delay.h>
+#include <linux/interrupt.h>
+#include <linux/irq.h>
+#include <linux/slab.h>
+#include <linux/module.h>
+#include <linux/i2c.h>
+#include <linux/types.h>
+#include <linux/of_device.h>
+#include <linux/of_irq.h>
+
+#define DRV_NAME	"mma8653fc"
+#define MMA8653FC_DEVICE_ID	0x5a
+
+#define MMA8653FC_STATUS	0x00
+
+#define ZYXOW_MASK	0x80
+#define ZYXDR		0x08
+
+#define MMA8653FC_WHO_AM_I	0x0d
+
+#define MMA8653FC_SYSMOD	0x0b
+#define STATE_STANDBY	0x00
+#define STATE_WAKE	0x01
+#define STATE_SLEEP	0x02
+
+#define MMA8450_STATUS_ZXYDR	0x08
+
+/*
+ * 10 bit output data registers
+ * MSB: 7:0 bits 9:2 of data word
+ * LSB: 7:6 bits 1:0 of data word
+ */
+#define MMA8653FC_OUT_X_MSB	0x01
+#define MMA8653FC_OUT_X_LSB	0x02
+#define MMA8653FC_OUT_Y_MSB	0x03
+#define MMA8653FC_OUT_Y_LSB	0x04
+#define MMA8653FC_OUT_Z_MSB	0x05
+#define MMA8653FC_OUT_Z_LSB	0x06
+
+/*
+ * Portrait/Landscape Status
+ */
+#define MMA8653FC_PL_STATUS	0x10
+
+#define NEWLP		0x80
+#define LAPO_HIGH	0x04
+#define LAPO_LOW	0x02
+#define BAFRO		0x01
+
+/*
+ * Portrait/Landscape Configuration
+ */
+#define MMA8653FC_PL_CFG	0x11
+
+#define PL_EN		(1 << 6)
+
+/*
+ * Data calibration registers
+ */
+#define MMA8653FC_OFF_X		0x2f
+#define MMA8653FC_OFF_Y		0x30
+#define MMA8653FC_OFF_Z		0x31
+
+/* 0 to 500 for dts, but -250 to 250 in mg */
+#define DEFAULT_OFF	250
+
+/*
+ * bits 1:0 dynamic range
+ * 00 +/- 2g
+ * 01 +/- 4g
+ * 10 +/- 8g
+ *
+ * HPF_Out bit 4 - data high pass or low pass filtered
+ */
+#define MMA8653FC_XYZ_DATA_CFG	0x0e
+
+#define RANGE_MASK	0x03
+#define RANGE2G		0x00
+#define RANGE4G		0x01
+#define RANGE8G		0x02
+/* values for calculation */
+#define SHIFT_2G	8
+#define INCR_2G		128
+#define SHIFT_4G	7
+#define INCR_4G		64
+#define SHIFT_8G	6
+#define INCR_8G		32
+#define DYN_RANGE_2G	2
+#define DYN_RANGE_4G	4
+#define DYN_RANGE_8G	8
+
+/*
+ * System Control Reg 1
+ */
+#define MMA8653FC_CTRL_REG1	0x2a
+
+#define ACTIVE_BIT	(1 << 0)
+#define ODR_MASK	0x38
+#define ODR_DEFAULT	0x20 /* 50 Hz */
+#define ASLP_RATE_MASK	0xc0
+#define ASLP_RATE_DEFAULT 0x80 /* 6.25 Hz */
+
+/*
+ * Sys Control Reg 2
+ *
+ * auto-sleep enable, software reset
+ */
+#define MMA8653FC_CTRL_REG2	0x2b
+
+#define SLPE		(1 << 2)
+#define SELFTEST	(1 << 7)
+#define SOFT_RESET	(1 << 6)
+
+/*
+ * Interrupt Source
+ */
+#define MMA8653FC_INT_SOURCE	0x0c
+
+#define SRC_ASLP	(1 << 7)
+#define SRC_LNDPRT	(1 << 4)
+#define SRC_FF_MT	(1 << 2)
+#define SRC_DRDY	(1 << 0)
+
+/*
+ * Interrupt Control Register
+ *
+ * default: active low
+ * default push-pull, not open-drain
+ */
+#define MMA8653FC_CTRL_REG3	0x2c
+
+#define WAKE_LNDPRT	(1 << 5)
+#define WAKE_FF_MT	(1 << 3)
+#define IPOL		(1 << 1)
+#define PP_OD		(1 << 0)
+
+/*
+ * Interrupt Enable Register
+ */
+#define MMA8653FC_CTRL_REG4	0x2d
+
+#define INT_EN_ASLP	(1 << 7)
+#define INT_EN_LNDPRT	(1 << 4)
+#define INT_EN_FF_MT	(1 << 2)
+#define INT_EN_DRDY	(1 << 0)
+
+/*
+ * Interrupt Configuration Register
+ * bit value 0 ... INT2 (default)
+ * bit value 1 ... INT1
+ */
+#define MMA8653FC_CTRL_REG5	0x2e
+
+#define INT_CFG_ASLP	(1 << 7)
+#define INT_CFG_LNDPRT	(1 << 4)
+#define INT_CFG_FF_MT	(1 << 2)
+#define INT_CFG_DRDY	(1 << 0)
+
+/*
+ * Freefall / Motion Configuration Register
+ *
+ * Event Latch enable/disable, motion or freefall mode
+ * and event flag enable per axis
+ */
+#define MMA8653FC_FF_MT_CFG	0x15
+
+#define FF_MT_CFG_ELE	(1 << 7)
+#define FF_MT_CFG_OAE	(1 << 6)
+#define FF_MT_CFG_ZEFE	(1 << 5)
+#define FF_MT_CFG_YEFE	(1 << 4)
+#define FF_MT_CFG_XEFE	(1 << 3)
+
+/*
+ * Freefall / Motion Source Register
+ */
+#define MMA8653FC_FF_MT_SRC	0x16
+
+/*
+ * Freefall / Motion Threshold Register
+ *
+ * define motion threshold
+ * 0.063 g/LSB, 127 counts(0x7f) (7 bit from LSB)
+ * range: 0.063g - 8g
+ */
+#define MMA8653FC_FF_MT_THS	0x17
+
+struct axis_triple {
+	s16 x;
+	s16 y;
+	s16 z;
+};
+
+struct mma8653fc_pdata {
+	s8 x_axis_offset;
+	s8 y_axis_offset;
+	s8 z_axis_offset;
+	bool auto_wake_sleep;
+	u32 range;
+	bool int1;
+	bool int_active_high;
+	bool motion_mode;
+	u8 freefall_motion_thr;
+	bool int_src_data_ready;
+	bool int_src_ff_mt_x;
+	bool int_src_ff_mt_y;
+	bool int_src_ff_mt_z;
+	bool int_src_lndprt;
+	bool int_src_aslp;
+};
+
+struct mma8653fc {
+	struct i2c_client *client;
+	struct mutex mutex;
+	struct mma8653fc_pdata pdata;
+	struct axis_triple saved;
+	char orientation;
+	char bafro;
+	bool standby;
+	int irq;
+	unsigned int_mask;
+	u8 (*read)(struct mma8653fc *, unsigned char);
+	int (*write)(struct mma8653fc *, unsigned char, unsigned char);
+};
+
+/* defaults */
+static const struct mma8653fc_pdata mma8653fc_default_init = {
+	.range = 2,
+	.x_axis_offset = DEFAULT_OFF,
+	.y_axis_offset = DEFAULT_OFF,
+	.z_axis_offset = DEFAULT_OFF,
+	.auto_wake_sleep = false,
+	.int1 = false,
+	.int_active_high = false,
+	.motion_mode = false,
+	.freefall_motion_thr = 5,
+	.int_src_data_ready = false,
+	.int_src_ff_mt_x = false,
+	.int_src_ff_mt_y = false,
+	.int_src_ff_mt_z = false,
+	.int_src_lndprt = false,
+	.int_src_aslp = false,
+};
+
+static void mma8653fc_get_triple(struct mma8653fc *mma)
+{
+	u8 buf[6];
+	u8 status;
+
+	buf[0] = 0;
+
+	status = mma->read(mma, MMA8653FC_STATUS);
+	if (status & ZYXOW_MASK)
+		dev_dbg(&mma->client->dev, "previous read not completed\n");
+
+	buf[0] = mma->read(mma, MMA8653FC_OUT_X_MSB);
+	buf[1] = mma->read(mma, MMA8653FC_OUT_X_LSB);
+	buf[2] = mma->read(mma, MMA8653FC_OUT_Y_MSB);
+	buf[3] = mma->read(mma, MMA8653FC_OUT_Y_LSB);
+	buf[4] = mma->read(mma, MMA8653FC_OUT_Z_MSB);
+	buf[5] = mma->read(mma, MMA8653FC_OUT_Z_LSB);
+
+	mutex_lock(&mma->mutex);
+	/* move from registers to s16 */
+	mma->saved.x = (buf[1] | (buf[0] << 8)) >> 6;
+	mma->saved.y = (buf[3] | (buf[2] << 8)) >> 6;
+	mma->saved.z = (buf[5] | (buf[4] << 8)) >> 6;
+	mma->saved.x = sign_extend32(mma->saved.x, 9);
+	mma->saved.y = sign_extend32(mma->saved.y, 9);
+	mma->saved.z = sign_extend32(mma->saved.z, 9);
+
+	/* calc g, see data sheet and application note */
+	switch (mma->pdata.range) {
+	case DYN_RANGE_2G:
+		mma->saved.x = le16_to_cpu((1000 * mma->saved.x +
+					    INCR_2G) >> SHIFT_2G);
+		mma->saved.y = le16_to_cpu((1000 * mma->saved.y +
+					   INCR_2G) >> SHIFT_2G);
+		mma->saved.z = le16_to_cpu((1000 * mma->saved.z +
+					   INCR_2G) >> SHIFT_2G);
+		break;
+	case DYN_RANGE_4G:
+		mma->saved.x = le16_to_cpu((1000 * mma->saved.x +
+					   INCR_4G) >> SHIFT_4G);
+		mma->saved.y = le16_to_cpu((1000 * mma->saved.y +
+					   INCR_4G) >> SHIFT_4G);
+		mma->saved.z = le16_to_cpu((1000 * mma->saved.z +
+					   INCR_4G) >> SHIFT_4G);
+		break;
+	case DYN_RANGE_8G:
+		mma->saved.x = le16_to_cpu((1000 * mma->saved.x +
+					   INCR_8G) >> SHIFT_8G);
+		mma->saved.y = le16_to_cpu((1000 * mma->saved.y +
+					   INCR_8G) >> SHIFT_8G);
+		mma->saved.z = le16_to_cpu((1000 * mma->saved.z +
+					   INCR_8G) >> SHIFT_8G);
+		break;
+	default:
+		dev_err(&mma->client->dev, "internal data corrupt\n");
+	}
+	mutex_unlock(&mma->mutex);
+}
+
+static void mma8653fc_get_orientation(struct mma8653fc *mma, u8 byte)
+{
+	if ((byte & LAPO_HIGH) && !(LAPO_LOW))
+		mma->orientation = 'r'; /* landscape right */
+	if (!(byte & LAPO_HIGH) && (byte & LAPO_LOW))
+		mma->orientation = 'd'; /* portrait down */
+	if (!(byte & LAPO_HIGH) && !(byte & LAPO_LOW))
+		mma->orientation = 'u'; /* portrait up */
+	if ((byte & LAPO_HIGH) && (byte & LAPO_LOW))
+		mma->orientation = 'l'; /* landscape left */
+
+	if (byte & BAFRO)
+		mma->bafro = 'b'; /* back facing */
+	else
+		mma->bafro = 'f'; /* front facing */
+}
+
+static irqreturn_t mma8653fc_irq(int irq, void *handle)
+{
+	struct mma8653fc *mma = handle;
+	u8 int_src;
+	u8 byte;
+
+	int_src = mma->read(mma, MMA8653FC_INT_SOURCE);
+	if (int_src & SRC_DRDY)
+		/* data ready handle */
+	if (int_src & SRC_FF_MT) {
+		/* freefall/motion change handle */
+		dev_dbg(&mma->client->dev,
+			"freefall or motion change\n");
+		byte = mma->read(mma, MMA8653FC_FF_MT_SRC);
+	}
+	if (int_src & SRC_LNDPRT) {
+		/* landscape/portrait change handle */
+		dev_dbg(&mma->client->dev,
+			"landscape / portrait change\n");
+		byte = mma->read(mma, MMA8653FC_PL_STATUS);
+		mma8653fc_get_orientation(mma, byte);
+	}
+	if (int_src & SRC_ASLP)
+		/* autosleep change handle */
+	mma8653fc_get_triple(mma);
+
+	sysfs_notify(&mma->client->dev.kobj, NULL, "position");
+
+	return IRQ_HANDLED;
+}
+
+static void __mma8653fc_enable(struct mma8653fc *mma)
+{
+	u8 byte;
+
+	byte = mma->read(mma, MMA8653FC_CTRL_REG1);
+	mma->write(mma, MMA8653FC_CTRL_REG1, byte | ACTIVE_BIT);
+}
+
+static void __mma8653fc_disable(struct mma8653fc *mma)
+{
+	u8 byte;
+
+	byte = mma->read(mma, MMA8653FC_CTRL_REG1);
+	mma->write(mma, MMA8653FC_CTRL_REG1, byte & ~ACTIVE_BIT);
+}
+
+static ssize_t mma8653fc_standby_show(struct device *dev,
+				    struct device_attribute *attr, char *buf)
+{
+	struct i2c_client *client = to_i2c_client(dev);
+	struct mma8653fc *mma = i2c_get_clientdata(client);
+
+	return scnprintf(buf, PAGE_SIZE, "%u\n", mma->standby);
+}
+
+static ssize_t mma8653fc_standby_store(struct device *dev,
+				     struct device_attribute *attr,
+				     const char *buf, size_t count)
+{
+	struct i2c_client *client = to_i2c_client(dev);
+	struct mma8653fc *mma = i2c_get_clientdata(client);
+	unsigned int val;
+	int error;
+
+	error = kstrtouint(buf, 10, &val);
+	if (error)
+		return error;
+
+	mutex_lock(&mma->mutex);
+
+	if (val) {
+		if (!mma->standby)
+			__mma8653fc_disable(mma);
+	} else {
+		if (mma->standby)
+			__mma8653fc_enable(mma);
+	}
+
+	mma->standby = !!val;
+
+	mutex_unlock(&mma->mutex);
+
+	return count;
+}
+
+static DEVICE_ATTR(standby, 0664, mma8653fc_standby_show,
+				  mma8653fc_standby_store);
+
+static ssize_t mma8653fc_currentmode_show(struct device *dev,
+				 struct device_attribute *attr, char *buf)
+{
+	struct i2c_client *client = to_i2c_client(dev);
+	struct mma8653fc *mma = i2c_get_clientdata(client);
+	ssize_t count;
+	u8 byte;
+
+	byte = mma->read(mma, MMA8653FC_SYSMOD);
+	if (byte < 0)
+		return byte;
+
+	switch (byte) {
+	case STATE_STANDBY:
+		count = scnprintf(buf, PAGE_SIZE, "standby\n");
+		break;
+	case STATE_WAKE:
+		count = scnprintf(buf, PAGE_SIZE, "wake\n");
+		break;
+	case STATE_SLEEP:
+		count = scnprintf(buf, PAGE_SIZE, "sleep\n");
+		break;
+	default:
+		count = scnprintf(buf, PAGE_SIZE, "unknown\n");
+	}
+	return count;
+}
+static DEVICE_ATTR(currentmode, S_IRUGO, mma8653fc_currentmode_show, NULL);
+
+static ssize_t mma8653fc_position_show(struct device *dev,
+				 struct device_attribute *attr, char *buf)
+{
+	struct i2c_client *client = to_i2c_client(dev);
+	struct mma8653fc *mma = i2c_get_clientdata(client);
+	ssize_t count;
+	u8 byte;
+
+	if (!mma->irq) {
+		byte = mma->read(mma, MMA8653FC_PL_STATUS);
+		if (byte & NEWLP)
+			mma8653fc_get_orientation(mma, byte);
+
+		byte = mma->read(mma, MMA8653FC_STATUS);
+		if (byte & ZYXDR)
+			mma8653fc_get_triple(mma);
+
+		msleep(20);
+		dev_dbg(&client->dev, "data polled\n");
+	}
+	mutex_lock(&mma->mutex);
+	count = scnprintf(buf, PAGE_SIZE, "%d %d %d %c %c\n",
+			mma->saved.x, mma->saved.y, mma->saved.z,
+			mma->orientation, mma->bafro);
+	mutex_unlock(&mma->mutex);
+
+	return count;
+}
+static DEVICE_ATTR(position, S_IRUGO, mma8653fc_position_show, NULL);
+
+static struct attribute *mma8653fc_attributes[] = {
+	&dev_attr_position.attr,
+	&dev_attr_standby.attr,
+	&dev_attr_currentmode.attr,
+	NULL,
+};
+
+static const struct attribute_group mma8653fc_attr_group = {
+	.attrs = mma8653fc_attributes,
+};
+
+static u8 mma8653fc_read(struct mma8653fc *mma, unsigned char reg)
+{
+	u8 val;
+
+	val = i2c_smbus_read_byte_data(mma->client, reg);
+	if (val < 0) {
+		dev_err(&mma->client->dev,
+			"failed to read %x register\n", reg);
+	}
+	return val;
+}
+
+static int mma8653fc_write(struct mma8653fc *mma, unsigned char reg,
+			   unsigned char val)
+{
+	int ret;
+
+	ret = i2c_smbus_write_byte_data(mma->client, reg, val);
+	if (ret) {
+		dev_err(&mma->client->dev,
+			"failed to write %x register\n", reg);
+	}
+	return ret;
+}
+
+static const struct of_device_id mma8653fc_dt_ids[] = {
+	{ .compatible = "fsl,mma8653fc", },
+	{ }
+};
+MODULE_DEVICE_TABLE(of, mma8653fc_dt_ids);
+
+static const struct mma8653fc_pdata *mma8653fc_probe_dt(struct device *dev)
+{
+	struct mma8653fc_pdata *pdata;
+	struct device_node *node = dev->of_node;
+	const struct of_device_id *match;
+	u32 testu32;
+	s32 tests32;
+
+	if (!node) {
+		dev_err(dev, "no associated DT data\n");
+		return ERR_PTR(-EINVAL);
+	}
+
+	match = of_match_device(mma8653fc_dt_ids, dev);
+	if (!match) {
+		dev_err(dev, "unknown device model\n");
+		return ERR_PTR(-EINVAL);
+	}
+
+	pdata = devm_kzalloc(dev, sizeof(*pdata), GFP_KERNEL);
+	if (!pdata)
+		return ERR_PTR(-ENOMEM);
+
+	*pdata = mma8653fc_default_init;
+
+	/* overwrite from dts */
+	testu32 = pdata->x_axis_offset;
+	tests32 = 0;
+	of_property_read_u32(node, "x-offset", &testu32);
+	tests32 = testu32 - DEFAULT_OFF;
+	if ((tests32) && (tests32 <= DEFAULT_OFF) &&
+	    (tests32 >= -DEFAULT_OFF)) {
+		dev_info(dev, "use %dmg offset on X axis\n", tests32);
+		/* calc register value, resolution: 1.96mg */
+		pdata->x_axis_offset = (s8) (tests32 / 2);
+	}
+	testu32 = pdata->y_axis_offset;
+	tests32 = 0;
+	of_property_read_u32(node, "y-offset", &testu32);
+	tests32 = testu32 - DEFAULT_OFF;
+	if ((tests32) && (tests32 <= DEFAULT_OFF) &&
+	    (tests32 >= -DEFAULT_OFF)) {
+		dev_info(dev, "use %dmg offset on Y axis\n", tests32);
+		pdata->y_axis_offset = (s8) (tests32 / 2);
+	}
+	testu32 = pdata->z_axis_offset;
+	tests32 = 0;
+	of_property_read_u32(node, "z-offset", &testu32);
+	tests32 = testu32 - DEFAULT_OFF;
+	if ((tests32) && (tests32 <= DEFAULT_OFF) &&
+	    (tests32 >= -DEFAULT_OFF)) {
+		dev_info(dev, "use %dmg offset on Z axis\n", tests32);
+		pdata->z_axis_offset = (s8) (tests32 / 2);
+	}
+
+	testu32 = 0;
+	of_property_read_u32(node, "range", &testu32);
+	if ((testu32) && (testu32 != 2) && (testu32 != 4) && (testu32 != 8)) {
+		dev_warn(dev, "wrong value for full scale range in dtb\n");
+	} else {
+		if (testu32)
+			pdata->range = testu32;
+	}
+
+	if (of_property_read_bool(node, "auto_wake_sleep"))
+		pdata->auto_wake_sleep = true;
+
+	if (of_property_read_bool(node, "int1"))
+		pdata->int1 = true;
+
+	if (of_property_read_bool(node, "int_active_high"))
+		pdata->int_active_high = true;
+
+	if (of_property_read_bool(node, "motion_mode"))
+		pdata->motion_mode = true;
+
+	if (of_property_read_bool(node, "ir_data_ready"))
+		pdata->int_src_data_ready = true;
+
+	if (of_property_read_bool(node, "ir_freefall_motion_x"))
+		pdata->int_src_ff_mt_x = true;
+
+	if (of_property_read_bool(node, "ir_freefall_motion_y"))
+		pdata->int_src_ff_mt_y = true;
+
+	if (of_property_read_bool(node, "ir_freefall_motion_z"))
+		pdata->int_src_ff_mt_z = true;
+
+	if (of_property_read_bool(node, "ir_auto_wake"))
+		pdata->int_src_aslp = true;
+
+	if (of_property_read_bool(node, "ir_landscape_portrait"))
+		pdata->int_src_lndprt = true;
+
+	testu32 = 0;
+	of_property_read_u32(node, "irq_threshold", &testu32);
+	/* always uses maximum range +/- 8000g, resolution 63mg */
+	if ((testu32 <= 8000) && (testu32 > 0)) {
+		dev_dbg(dev, "use freefall / motion threshold %dmg\n",
+			 testu32);
+		/* calculate register value from mg */
+		pdata->freefall_motion_thr = (testu32 / 63) + 1;
+	}
+
+	return pdata;
+}
+static int mma8653fc_i2c_probe(struct i2c_client *client,
+				       const struct i2c_device_id *id)
+{
+	struct mma8653fc *mma;
+	const struct mma8653fc_pdata *pdata;
+	int err;
+	u8 byte;
+
+	err = i2c_check_functionality(client->adapter,
+			I2C_FUNC_SMBUS_BYTE_DATA);
+	if (!err) {
+		dev_err(&client->dev, "SMBUS Byte Data not Supported\n");
+		return -EIO;
+	}
+
+	mma = kzalloc(sizeof(*mma), GFP_KERNEL);
+	if (!mma) {
+		err = -ENOMEM;
+		goto err_out;
+	}
+
+	pdata = dev_get_platdata(&client->dev);
+	if (!pdata) {
+		pdata = mma8653fc_probe_dt(&client->dev);
+		if (IS_ERR(pdata)) {
+			err = PTR_ERR(pdata);
+			pr_err("pdata from DT failed\n");
+			goto err_free_mem;
+		}
+	}
+	mma->pdata = *pdata;
+	pdata = &mma->pdata;
+	mma->client = client;
+	mma->read = &mma8653fc_read;
+	mma->write = &mma8653fc_write;
+
+	mutex_init(&mma->mutex);
+
+	i2c_set_clientdata(client, mma);
+
+	err = sysfs_create_group(&client->dev.kobj, &mma8653fc_attr_group);
+	if (err)
+		goto err_free_mem;
+
+	mma->irq = irq_of_parse_and_map(client->dev.of_node, 0);
+	if (!mma->irq) {
+		dev_err(&client->dev, "Unable to parse or map IRQ\n");
+		goto no_irq;
+	}
+
+	err = irq_set_irq_type(mma->irq, IRQ_TYPE_EDGE_FALLING);
+	if (err) {
+		dev_err(&client->dev, "set_irq_type failed\n");
+		goto err_free_mem;
+	}
+
+	err = request_threaded_irq(mma->irq, NULL, mma8653fc_irq, IRQF_ONESHOT,
+				   dev_name(&mma->client->dev), mma);
+	if (err) {
+		dev_err(&client->dev, "irq %d busy?\n", mma->irq);
+		goto err_free_mem;
+	}
+
+	if (mma->write(mma, MMA8653FC_CTRL_REG2, SOFT_RESET))
+		goto err_free_irq;
+
+	__mma8653fc_disable(mma);
+	mma->standby = true;
+
+	/* enable desired interrupts */
+	mma->orientation = '\0';
+	mma->bafro = '\0';
+	byte = 0;
+	if (pdata->int_src_data_ready) {
+		byte |= INT_EN_DRDY;
+		dev_dbg(&client->dev, "DATA READY interrupt source enabled\n");
+	}
+	if (pdata->int_src_ff_mt_x || pdata->int_src_ff_mt_y ||
+	    pdata->int_src_ff_mt_z) {
+		byte |= INT_EN_FF_MT;
+		dev_dbg(&client->dev, "FF MT interrupt source enabled\n");
+	}
+	if (pdata->int_src_lndprt) {
+		if (mma->write(mma, MMA8653FC_PL_CFG, PL_EN))
+			goto err_free_irq;
+		byte |= INT_EN_LNDPRT;
+		dev_dbg(&client->dev, "LNDPRT interrupt source enabled\n");
+	}
+	if (pdata->int_src_aslp) {
+		byte |= INT_EN_ASLP;
+		dev_dbg(&client->dev, "ASLP interrupt source enabled\n");
+	}
+	if (mma->write(mma, MMA8653FC_CTRL_REG4, byte))
+		goto err_free_irq;
+
+	/* force everything to line 1 */
+	if (pdata->int1) {
+		if (mma->write(mma, MMA8653FC_CTRL_REG5,
+				 (INT_CFG_ASLP | INT_CFG_LNDPRT |
+				 INT_CFG_FF_MT | INT_CFG_DRDY)))
+			goto err_free_irq;
+		dev_dbg(&client->dev, "using interrupt line 1\n");
+	}
+
+	/* force active high */
+	if (pdata->int_active_high) {
+		byte = mma->read(mma, MMA8653FC_CTRL_REG3);
+		if (byte < 0)
+			goto err_free_irq;
+		byte |= IPOL;
+		if (mma->write(mma, MMA8653FC_CTRL_REG3, byte))
+			goto err_free_irq;
+		dev_dbg(&client->dev, "using active high on interrupt line\n");
+	}
+no_irq:
+	/* range mode */
+	byte = mma->read(mma, MMA8653FC_XYZ_DATA_CFG);
+	byte &= ~RANGE_MASK;
+	switch (pdata->range) {
+	case DYN_RANGE_2G:
+		byte |= RANGE2G;
+		dev_dbg(&client->dev, "use 2g range\n");
+		break;
+	case DYN_RANGE_4G:
+		byte |= RANGE4G;
+		dev_dbg(&client->dev, "use 4g range\n");
+		break;
+	case DYN_RANGE_8G:
+		byte |= RANGE8G;
+		dev_dbg(&client->dev, "use 8g range\n");
+		break;
+	default:
+		dev_err(&client->dev, "wrong range mode value\n");
+		goto err_free_irq;
+	}
+	if (mma->write(mma, MMA8653FC_XYZ_DATA_CFG, byte))
+		goto err_free_irq;
+
+	/* data calibration offsets */
+	if (pdata->x_axis_offset) {
+		if (mma->write(mma, MMA8653FC_OFF_X, pdata->x_axis_offset))
+			goto err_free_irq;
+	}
+	if (pdata->y_axis_offset) {
+		if (mma->write(mma, MMA8653FC_OFF_Y, pdata->y_axis_offset))
+			goto err_free_irq;
+	}
+	if (pdata->z_axis_offset) {
+		if (mma->write(mma, MMA8653FC_OFF_Z, pdata->z_axis_offset))
+			goto err_free_irq;
+	}
+
+	/* if autosleep, wake on both landscape and motion changes */
+	if (pdata->auto_wake_sleep) {
+		byte = 0;
+		byte |= WAKE_LNDPRT;
+		byte |= WAKE_FF_MT;
+		if (mma->write(mma, MMA8653FC_CTRL_REG3, byte))
+			goto err_free_irq;
+		if (mma->write(mma, MMA8653FC_CTRL_REG2, SLPE))
+			goto err_free_irq;
+		dev_dbg(&client->dev, "auto sleep enabled\n");
+	}
+
+	/* data rates */
+	byte = 0;
+	byte = mma->read(mma, MMA8653FC_CTRL_REG1);
+	if (byte < 0)
+		goto err_free_irq;
+	byte &= ~ODR_MASK;
+	byte |= ODR_DEFAULT;
+	byte &= ~ASLP_RATE_MASK;
+	byte |= ASLP_RATE_DEFAULT;
+	if (mma->write(mma, MMA8653FC_CTRL_REG1, byte))
+		goto err_free_irq;
+
+	/* freefall / motion config */
+	byte = 0;
+	if (pdata->motion_mode) {
+		byte |= FF_MT_CFG_OAE;
+		dev_dbg(&client->dev, "detect motion instead of freefall\n");
+	}
+	byte |= FF_MT_CFG_ELE;
+	if (pdata->int_src_ff_mt_x)
+		byte |= FF_MT_CFG_XEFE;
+	if (pdata->int_src_ff_mt_y)
+		byte |= FF_MT_CFG_YEFE;
+	if (pdata->int_src_ff_mt_z)
+		byte |= FF_MT_CFG_ZEFE;
+	if (mma->write(mma, MMA8653FC_FF_MT_CFG, byte))
+		goto err_free_irq;
+
+	if (pdata->freefall_motion_thr) {
+		if (mma->write(mma, MMA8653FC_FF_MT_THS,
+				 pdata->freefall_motion_thr))
+			goto err_free_irq;
+		/* calculate back to mg */
+		dev_dbg(&client->dev, "threshold set to %dmg\n",
+			 (63 * pdata->freefall_motion_thr) - 1);
+	}
+
+	byte = mma->read(mma, MMA8653FC_WHO_AM_I);
+	if (byte != MMA8653FC_DEVICE_ID) {
+		dev_err(&client->dev, "wrong device for driver\n");
+		goto err_free_irq;
+	}
+	dev_info(&client->dev,
+		 "accelerometer driver loaded. device id %x\n", byte);
+
+	return 0;
+
+ err_free_irq:
+	if (mma->irq)
+		free_irq(mma->irq, mma);
+ err_free_mem:
+	kfree(mma);
+ err_out:
+	return err;
+}
+
+static int mma8653fc_remove(struct i2c_client *client)
+{
+	struct mma8653fc *mma = i2c_get_clientdata(client);
+
+	free_irq(mma->irq, mma);
+	dev_dbg(&client->dev, "unregistered accelerometer\n");
+	kfree(mma);
+
+	return 0;
+}
+
+#ifdef CONFIG_PM_SLEEP
+static int mma8653fc_suspend(struct device *dev)
+{
+	struct i2c_client *client = to_i2c_client(dev);
+	struct mma8653fc *mma = i2c_get_clientdata(client);
+
+	__mma8653fc_disable(mma);
+
+	return 0;
+}
+
+static int mma8653fc_resume(struct device *dev)
+{
+	struct i2c_client *client = to_i2c_client(dev);
+	struct mma8653fc *mma = i2c_get_clientdata(client);
+
+	__mma8653fc_enable(mma);
+
+	return 0;
+}
+
+static SIMPLE_DEV_PM_OPS(mma8653fc_pm_ops, mma8653fc_suspend, mma8653fc_resume);
+#define MMA8653FC_PM_OPS (&mma8653fc_pm_ops)
+#else
+#define MMA8653FC_PM_OPS NULL
+#endif
+
+static const struct i2c_device_id mma8653fc_id[] = {
+	{ DRV_NAME, 0 },
+	{ }
+};
+MODULE_DEVICE_TABLE(i2c, mma8653fc_id);
+
+static struct i2c_driver mma8653fc_driver = {
+	.driver = {
+		.name = DRV_NAME,
+		.owner = THIS_MODULE,
+		.of_match_table = mma8653fc_dt_ids,
+		.pm = MMA8653FC_PM_OPS,
+	},
+	.probe    = mma8653fc_i2c_probe,
+	.remove   = mma8653fc_remove,
+	.id_table = mma8653fc_id,
+};
+
+module_i2c_driver(mma8653fc_driver);
+
+MODULE_AUTHOR("Martin Kepplinger <martin.kepplinger@theobroma-systems.com");
+MODULE_DESCRIPTION("Freescale's MMA8653FC Three-Axis Accelerometer I2C Driver");
+MODULE_LICENSE("GPL");
-- 
2.1.4


^ permalink raw reply related

* Re: [PATCH v2] add support for Freescale's MMA8653FC 10 bit accelerometer
From: Alexander Stein @ 2015-03-18 16:21 UTC (permalink / raw)
  To: Martin Kepplinger
  Cc: robh+dt, pawel.moll, mark.rutland, ijc+devicetree, galak,
	dmitry.torokhov, akpm, gregkh, linux-api, devicetree, linux-input,
	linux-kernel, Martin Kepplinger, Christoph Muellner
In-Reply-To: <1426694157-10866-1-git-send-email-martink@posteo.de>

On Wednesday 18 March 2015 16:55:57, Martin Kepplinger wrote:
> From: Martin Kepplinger <martin.kepplinger@theobroma-systems.com>
> 
> The MMA8653FC is a low-power, three-axis, capacitive micromachined
> accelerometer with 10 bits of resolution with flexible user-programmable
> options.
> 
> Embedded interrupt functions enable overall power savings, by relieving the
> host processor from continuously polling data, for example using the poll()
> system call.
> 
> The device can be configured to generate wake-up interrupt signals from any
> combination of the configurable embedded functions, enabling the MMA8653FC
> to monitor events while remaining in a low-power mode during periods of
> inactivity.
> 
> This driver provides devicetree properties to program the device's behaviour
> and a simple, tested and documented sysfs interface. The data sheet and more
> information is available on Freescale's website.
> 
> Signed-off-by: Martin Kepplinger <martin.kepplinger@theobroma-systems.com>
> Signed-off-by: Christoph Muellner <christoph.muellner@theobroma-systems.com>
> ---
> applies to v4.0-rc4 and the current -next.
> 
> patch revision history
> ......................
> v2 corrects licensing and commit messages and adds appropriate recipients
> 
>  .../testing/sysfs-bus-i2c-devices-fsl-mma8653fc    |  39 +
>  .../devicetree/bindings/misc/fsl,mma8653fc.txt     |  96 +++
>  MAINTAINERS                                        |   5 +
>  drivers/input/misc/Kconfig                         |  11 +
>  drivers/input/misc/Makefile                        |   1 +
>  drivers/input/misc/mma8653fc.c                     | 913 +++++++++++++++++++++
>  6 files changed, 1065 insertions(+)
>  create mode 100644 Documentation/ABI/testing/sysfs-bus-i2c-devices-fsl-mma8653fc
>  create mode 100644 Documentation/devicetree/bindings/misc/fsl,mma8653fc.txt
>  create mode 100644 drivers/input/misc/mma8653fc.c

Shouldn't this go to drivers/iio/magnetometer instead of defining a new sysfs ABI?

Best regards,
Alexander
-- 
Dipl.-Inf. Alexander Stein

SYS TEC electronic GmbH
Am Windrad 2
08468 Heinsdorfergrund
Tel.: 03765 38600-1156
Fax: 03765 38600-4100
Email: alexander.stein@systec-electronic.com
Website: www.systec-electronic.com
 
Managing Director: Dipl.-Phys. Siegmar Schmidt
Commercial registry: Amtsgericht Chemnitz, HRB 28082

^ permalink raw reply

* Re: [PATCH v2] add support for Freescale's MMA8653FC 10 bit accelerometer
From: Martin Kepplinger @ 2015-03-18 16:42 UTC (permalink / raw)
  To: Alexander Stein
  Cc: robh+dt, pawel.moll, mark.rutland, ijc+devicetree, galak,
	dmitry.torokhov, akpm, gregkh, linux-api, devicetree, linux-input,
	linux-kernel, Martin Kepplinger, Christoph Muellner
In-Reply-To: <2231139.ojeyer6qnI@ws-stein>

Am 2015-03-18 um 17:21 schrieb Alexander Stein:
> On Wednesday 18 March 2015 16:55:57, Martin Kepplinger wrote:
>> From: Martin Kepplinger <martin.kepplinger@theobroma-systems.com>
>>
>> The MMA8653FC is a low-power, three-axis, capacitive micromachined
>> accelerometer with 10 bits of resolution with flexible user-programmable
>> options.
>>
>> Embedded interrupt functions enable overall power savings, by relieving the
>> host processor from continuously polling data, for example using the poll()
>> system call.
>>
>> The device can be configured to generate wake-up interrupt signals from any
>> combination of the configurable embedded functions, enabling the MMA8653FC
>> to monitor events while remaining in a low-power mode during periods of
>> inactivity.
>>
>> This driver provides devicetree properties to program the device's behaviour
>> and a simple, tested and documented sysfs interface. The data sheet and more
>> information is available on Freescale's website.
>>
>> Signed-off-by: Martin Kepplinger <martin.kepplinger@theobroma-systems.com>
>> Signed-off-by: Christoph Muellner <christoph.muellner@theobroma-systems.com>
>> ---
>> applies to v4.0-rc4 and the current -next.
>>
>> patch revision history
>> ......................
>> v2 corrects licensing and commit messages and adds appropriate recipients
>>
>>  .../testing/sysfs-bus-i2c-devices-fsl-mma8653fc    |  39 +
>>  .../devicetree/bindings/misc/fsl,mma8653fc.txt     |  96 +++
>>  MAINTAINERS                                        |   5 +
>>  drivers/input/misc/Kconfig                         |  11 +
>>  drivers/input/misc/Makefile                        |   1 +
>>  drivers/input/misc/mma8653fc.c                     | 913 +++++++++++++++++++++
>>  6 files changed, 1065 insertions(+)
>>  create mode 100644 Documentation/ABI/testing/sysfs-bus-i2c-devices-fsl-mma8653fc
>>  create mode 100644 Documentation/devicetree/bindings/misc/fsl,mma8653fc.txt
>>  create mode 100644 drivers/input/misc/mma8653fc.c
> 
> Shouldn't this go to drivers/iio/magnetometer instead of defining a new sysfs ABI?
> 

It could have gone to drivers/iio/accel if it would use an iio
interface, which would make more sense, you are right, but I simply
don't have the time to merge it in to iio.

It doesn't use an input interface either but I don't see a good place
for an accelerometer that uses sysfs only.

It works well, is a relatively recent chip and a clean dirver. But this
is all I can provide.

> Best regards,
> Alexander
> 


^ permalink raw reply

* Re: [PATCH v2] add support for Freescale's MMA8653FC 10 bit accelerometer
From: Dmitry Torokhov @ 2015-03-18 16:44 UTC (permalink / raw)
  To: Martin Kepplinger
  Cc: Alexander Stein, robh+dt, pawel.moll, mark.rutland,
	ijc+devicetree, galak, akpm, gregkh, linux-api, devicetree,
	linux-input, linux-kernel, Martin Kepplinger, Christoph Muellner
In-Reply-To: <5509AAE5.1000503@posteo.de>

On Wed, Mar 18, 2015 at 05:42:13PM +0100, Martin Kepplinger wrote:
> Am 2015-03-18 um 17:21 schrieb Alexander Stein:
> > On Wednesday 18 March 2015 16:55:57, Martin Kepplinger wrote:
> >> From: Martin Kepplinger <martin.kepplinger@theobroma-systems.com>
> >>
> >> The MMA8653FC is a low-power, three-axis, capacitive micromachined
> >> accelerometer with 10 bits of resolution with flexible user-programmable
> >> options.
> >>
> >> Embedded interrupt functions enable overall power savings, by relieving the
> >> host processor from continuously polling data, for example using the poll()
> >> system call.
> >>
> >> The device can be configured to generate wake-up interrupt signals from any
> >> combination of the configurable embedded functions, enabling the MMA8653FC
> >> to monitor events while remaining in a low-power mode during periods of
> >> inactivity.
> >>
> >> This driver provides devicetree properties to program the device's behaviour
> >> and a simple, tested and documented sysfs interface. The data sheet and more
> >> information is available on Freescale's website.
> >>
> >> Signed-off-by: Martin Kepplinger <martin.kepplinger@theobroma-systems.com>
> >> Signed-off-by: Christoph Muellner <christoph.muellner@theobroma-systems.com>
> >> ---
> >> applies to v4.0-rc4 and the current -next.
> >>
> >> patch revision history
> >> ......................
> >> v2 corrects licensing and commit messages and adds appropriate recipients
> >>
> >>  .../testing/sysfs-bus-i2c-devices-fsl-mma8653fc    |  39 +
> >>  .../devicetree/bindings/misc/fsl,mma8653fc.txt     |  96 +++
> >>  MAINTAINERS                                        |   5 +
> >>  drivers/input/misc/Kconfig                         |  11 +
> >>  drivers/input/misc/Makefile                        |   1 +
> >>  drivers/input/misc/mma8653fc.c                     | 913 +++++++++++++++++++++
> >>  6 files changed, 1065 insertions(+)
> >>  create mode 100644 Documentation/ABI/testing/sysfs-bus-i2c-devices-fsl-mma8653fc
> >>  create mode 100644 Documentation/devicetree/bindings/misc/fsl,mma8653fc.txt
> >>  create mode 100644 drivers/input/misc/mma8653fc.c
> > 
> > Shouldn't this go to drivers/iio/magnetometer instead of defining a new sysfs ABI?
> > 
> 
> It could have gone to drivers/iio/accel if it would use an iio
> interface, which would make more sense, you are right, but I simply
> don't have the time to merge it in to iio.
> 
> It doesn't use an input interface either but I don't see a good place
> for an accelerometer that uses sysfs only.

drivers/misc? Since it is not using input infrastructure (nor should
it), it does not belong in drivers/input.

Thanks.

-- 
Dmitry

^ permalink raw reply

* Re: [PATCH] selftests: Fix build failures when invoked from kselftest target
From: Shuah Khan @ 2015-03-18 16:46 UTC (permalink / raw)
  To: Michael Ellerman
  Cc: linux-api-u79uwXL29TY76Z2rM5mHXA,
	linux-kernel-u79uwXL29TY76Z2rM5mHXA, Shuah Khan
In-Reply-To: <1426466329.21900.2.camel-Gsx/Oe8HsFggBc27wqDAHg@public.gmane.org>

On 03/15/2015 06:38 PM, Michael Ellerman wrote:
> On Fri, 2015-03-13 at 19:45 -0600, Shuah Khan wrote:
>> Several tests that rely on implicit build rules fail to build,
>> when invoked from the main Makefile kselftest target. These
>> failures are due to --no-builtin-rules and --no-builtin-variables
>> options set in the inherited MAKEFLAGS.
>>
>> --no-builtin-rules eliminates the use of built-in implicit rules
>> and --no-builtin-variables is for not defining built-in variables.
>> These two options override the use of implicit rules resulting in
>> build failures. In addition, inherited LDFLAGS result in build
>> failures and there is no need to define LDFLAGS.  Clear LDFLAGS
>> and MAKEFLAG when make is invoked from the main Makefile kselftest
>> target. Fixing this at selftests Makefile avoids changing the main
>> Makefile and keeps this change self contained at selftests level.
>>
>> Signed-off-by: Shuah Khan <shuahkh-JPH+aEBZ4P+UEJcrhfAQsw@public.gmane.org>
>> ---
>>  tools/testing/selftests/Makefile | 9 +++++++++
>>  1 file changed, 9 insertions(+)
>>
>> diff --git a/tools/testing/selftests/Makefile b/tools/testing/selftests/Makefile
>> index 4e51122..8e09db7 100644
>> --- a/tools/testing/selftests/Makefile
>> +++ b/tools/testing/selftests/Makefile
>> @@ -22,6 +22,15 @@ TARGETS += vm
>>  TARGETS_HOTPLUG = cpu-hotplug
>>  TARGETS_HOTPLUG += memory-hotplug
>>  
>> +# Clear LDFLAGS and MAKEFLAGS if called from main
>> +# Makefile to avoid test build failures when test
>> +# Makefile doesn't have explicit build rules.
>> +ifeq (1,$(MAKELEVEL))
>> +undefine LDFLAGS
>> +override define MAKEFLAGS =
>> +endef
>> +endif
> 
> You shouldn't need to use define/endef here, that is just for multi-line
> variables.
> 
> This should be equivalent:
> 
>   ifeq (1,$(MAKELEVEL))
>   undefine LDFLAGS
>   override MAKEFLAGS =
>   endif
> 

ok. Will send a patch v2 with that change.

-- Shuah

-- 
Shuah Khan
Sr. Linux Kernel Developer
Open Source Innovation Group
Samsung Research America (Silicon Valley)
shuahkh-JPH+aEBZ4P+UEJcrhfAQsw@public.gmane.org | (970) 217-8978

^ permalink raw reply


This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox