On Tue, Jan 31, 2017 at 5:47 AM, Drew Fustini <[email protected]> wrote:
> On Mon, Jan 30, 2017 at 8:40 PM, Robert Nelson <[email protected]> 
> wrote:
>> Once you enable the power control, it's it acting the same as v4.4.x was?
>
> Yes, it does read position ok.

I've created this patch which seems to have done the trick without
messing with sysfs.  It adds pm_runtime_get_sync() before read or
write to eQEP memory mapped registers:
patches/drivers/ti/eqep/0002-Avoid-unhandled-fault-when-reading-eQEP-registers.patch

Here is the gist of the patch (also attached):
https://gist.github.com/pdp7/5fddaab028630dd06ace8e5012cf6798

Here's the results (no need to mess with files in sysfs anymore):

root@beaglebone:~# uname -r
4.9.6-ti-r18
root@beaglebone:~# config-pin p8.11 qep && config-pin p8.12 qep
root@beaglebone:~# cat
/sys/devices/platform/ocp/48304000.epwmss/48304180.eqep/position
0
<turn the rotary encoder>
root@beaglebone:~# cat
/sys/devices/platform/ocp/48304000.epwmss/48304180.eqep/position
66


thanks,
drew

-- 
For more options, visit http://beagleboard.org/discuss
--- 
You received this message because you are subscribed to the Google Groups 
"BeagleBoard" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to [email protected].
To view this discussion on the web visit 
https://groups.google.com/d/msgid/beagleboard/CAEf4M_DzOLDs6v5r%3DT%2BqR7vNLZEZvibFS93mjDJqR7zkX%2BKCjQ%40mail.gmail.com.
For more options, visit https://groups.google.com/d/optout.
From 692114189bf8635c0be02f7136227b7f7207d2e8 Mon Sep 17 00:00:00 2001
From: Drew Fustini <[email protected]>
Date: Thu, 2 Feb 2017 03:19:08 -0600
Subject: [PATCH] Avoid unhandled fault when reading eQEP registers

Add pm_runtime_get_sync() before any read or write to the eQEP
memory mapped registers.
---
 drivers/misc/tieqep.c | 19 ++++++++++++++++++-
 1 file changed, 18 insertions(+), 1 deletion(-)

diff --git a/drivers/misc/tieqep.c b/drivers/misc/tieqep.c
index d2628847..c2bbc33 100644
--- a/drivers/misc/tieqep.c
+++ b/drivers/misc/tieqep.c
@@ -242,8 +242,13 @@ static ssize_t eqep_get_enabled(struct device *dev, struct device_attribute *att
 	/* Get the instance structure */
 	struct eqep_chip *eqep = dev_get_drvdata(dev);
 
+	u16 enabled = 0;
+
 	/* Read the qep control register and mask all but the enabled bit */
-	u16 enabled = readw(eqep->mmio_base + QEPCTL) & PHEN;
+	enabled = readw(eqep->mmio_base + QEPCTL) & PHEN;
+
+	/* Increment the device usage count and run pm_runtime_resume() */
+	pm_runtime_get_sync(dev);
 
 	/* Return the target in string format */
 	return sprintf(buf, "%u\n", (enabled) ? 1 : 0);
@@ -262,6 +267,8 @@ static ssize_t eqep_set_enabled(struct device *dev, struct device_attribute *att
 	if ((rc = kstrtou8(buf, 0, &enabled)))
 		return rc;
 
+	/* Increment the device usage count and run pm_runtime_resume() */
+	pm_runtime_get_sync(dev);
 	/* Get the existing state of QEPCTL */
 	val = readw(eqep->mmio_base + QEPCTL);
 
@@ -286,6 +293,8 @@ static ssize_t eqep_get_position(struct device *dev, struct device_attribute *at
 	struct eqep_chip *eqep = dev_get_drvdata(dev);
 
 	s32 position = 0;
+	/* Increment the device usage count and run pm_runtime_resume() */
+	pm_runtime_get_sync(dev);
 
 	if (eqep->op_mode == TIEQEP_MODE_ABSOLUTE) {
 		position = readl(eqep->mmio_base + QPOSCNT);
@@ -308,6 +317,8 @@ static ssize_t eqep_set_position(struct device *dev, struct device_attribute *at
 	if ((rc = kstrtos32(buf, 0, &position)))
 		return rc;
 
+	/* Increment the device usage count and run pm_runtime_resume() */
+	pm_runtime_get_sync(dev);
 	/*
 	 * If we are in absolute mode, set the position of the encoder,
 	 * discard relative mode because thats pointless
@@ -327,6 +338,8 @@ static ssize_t eqep_get_timer_period(struct device *dev, struct device_attribute
 	struct eqep_chip *eqep = dev_get_drvdata(dev);
 	u64 period;
 
+	/* Increment the device usage count and run pm_runtime_resume() */
+	pm_runtime_get_sync(dev);
 	/* Convert from counts per interrupt back into period_ns */
 	period = readl(eqep->mmio_base + QUPRD);
 	period = period * NSEC_PER_SEC;
@@ -348,6 +361,8 @@ static ssize_t eqep_set_timer_period(struct device *dev, struct device_attribute
 	if ((rc = kstrtou64(buf, 0, &period)))
 		return rc;
 
+	/* Increment the device usage count and run pm_runtime_resume() */
+	pm_runtime_get_sync(dev);
 	/* Disable the unit timer before modifying its period register */
 	tmp = readw(eqep->mmio_base + QEPCTL);
 	tmp &= ~(UTE | QCLM);
@@ -395,6 +410,8 @@ static ssize_t eqep_set_mode(struct device *dev, struct device_attribute *attr,
 
 	dev_dbg(dev, "eqep_set_mode:%d\n", tmp_mode);
 
+	/* Increment the device usage count and run pm_runtime_resume() */
+	pm_runtime_get_sync(dev);
 	val = readw(eqep->mmio_base + QEPCTL);
 
 	if (tmp_mode == TIEQEP_MODE_ABSOLUTE) {
-- 
2.9.3

Reply via email to