Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save pdp7/16a2731b9fc571943f026f4b72a93f41 to your computer and use it in GitHub Desktop.
Save pdp7/16a2731b9fc571943f026f4b72a93f41 to your computer and use it in GitHub Desktop.
BeagleBone Linux 4.9.x eQEP driver
From 4242860c4fc7ce2f17b7a90411c1f2712ccef03c Mon Sep 17 00:00:00 2001
From: Robert Nelson <robertcnelson@gmail.com>
Date: Wed, 2 Nov 2016 11:11:27 -0500
Subject: [PATCH] tieqep: forward port of Nathaniel Lewis eQEP driver
Signed-off-by: Robert Nelson <robertcnelson@gmail.com>
---
arch/arm/boot/dts/am33xx.dtsi | 31 ++
drivers/misc/Kconfig | 11 +
drivers/misc/Makefile | 1 +
drivers/misc/tieqep.c | 738 ++++++++++++++++++++++++++++++++++++++++++
4 files changed, 781 insertions(+)
create mode 100644 drivers/misc/tieqep.c
diff --git a/arch/arm/boot/dts/am33xx.dtsi b/arch/arm/boot/dts/am33xx.dtsi
index 771fc0a..20ccf52 100644
--- a/arch/arm/boot/dts/am33xx.dtsi
+++ b/arch/arm/boot/dts/am33xx.dtsi
@@ -701,6 +701,16 @@
status = "disabled";
};
+ eqep0: eqep@0x48300180 {
+ compatible = "ti,am33xx-eqep";
+ reg = <0x48300180 0x80>;
+ clocks = <&l4ls_gclk>;
+ clock-names = "fck";
+ interrupt-parent = <&intc>;
+ interrupts = <79>;
+ status = "disabled";
+ };
+
ehrpwm0: pwm@48300200 {
compatible = "ti,am3352-ehrpwm",
"ti,am33xx-ehrpwm";
@@ -735,6 +745,17 @@
status = "disabled";
};
+
+ eqep1: eqep@0x48302180 {
+ compatible = "ti,am33xx-eqep";
+ reg = <0x48302180 0x80>;
+ clocks = <&l4ls_gclk>;
+ clock-names = "fck";
+ interrupt-parent = <&intc>;
+ interrupts = <88>;
+ status = "disabled";
+ };
+
ehrpwm1: pwm@48302200 {
compatible = "ti,am3352-ehrpwm",
"ti,am33xx-ehrpwm";
@@ -769,6 +790,16 @@
status = "disabled";
};
+ eqep2: eqep@0x48304180 {
+ compatible = "ti,am33xx-eqep";
+ reg = <0x48304180 0x80>;
+ clocks = <&l4ls_gclk>;
+ clock-names = "fck";
+ interrupt-parent = <&intc>;
+ interrupts = <89>;
+ status = "disabled";
+ };
+
ehrpwm2: pwm@48304200 {
compatible = "ti,am3352-ehrpwm",
"ti,am33xx-ehrpwm";
diff --git a/drivers/misc/Kconfig b/drivers/misc/Kconfig
index e3c6a92..b444d1db 100644
--- a/drivers/misc/Kconfig
+++ b/drivers/misc/Kconfig
@@ -785,6 +785,17 @@ config DEV_OVERLAYMGR
Say Y here to include support for the automagical dev
overlay manager.
+config TIEQEP
+ tristate "EQEP Hardware quadrature encoder controller"
+ depends on SOC_AM33XX
+ select PWM_TIPWMSS
+ help
+ Driver support for the EQEP quadrature encoder controller AM33XX
+ TI SOC
+
+ To compile this driver as a module, choose M here: the module
+ will be called tieqep.
+
source "drivers/misc/c2port/Kconfig"
source "drivers/misc/eeprom/Kconfig"
source "drivers/misc/cb710/Kconfig"
diff --git a/drivers/misc/Makefile b/drivers/misc/Makefile
index 9df0a01..a84dde4 100644
--- a/drivers/misc/Makefile
+++ b/drivers/misc/Makefile
@@ -53,6 +53,7 @@ obj-$(CONFIG_ECHO) += echo/
obj-$(CONFIG_VEXPRESS_SYSCFG) += vexpress-syscfg.o
obj-$(CONFIG_CXL_BASE) += cxl/
obj-$(CONFIG_PANEL) += panel.o
+obj-$(CONFIG_TIEQEP) += tieqep.o
obj-$(CONFIG_BONE_CAPEMGR) += bone_capemgr.o
obj-$(CONFIG_DEV_OVERLAYMGR) += devovmgr.o
diff --git a/drivers/misc/tieqep.c b/drivers/misc/tieqep.c
new file mode 100644
index 0000000..d2628847
--- /dev/null
+++ b/drivers/misc/tieqep.c
@@ -0,0 +1,738 @@
+/*
+ * TI eQEP driver for AM33xx devices
+ *
+ * Copyright (C) 2013 Nathaniel R. Lewis - http://teknoman117.wordpress.com/
+ * Copyright (C) 2015 SoftPLC Corporation, Dick Hollenbeck <dick@softplc.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * 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.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ *
+ * sysfs entries
+ * - position = absolute - current position; relative - last latched value
+ * - mode => 0 - absolute; 1 - relative
+ * - period => sampling period for the hardware
+ * - enable => 0 - eQEP disabled, 1 - eQEP enabled
+ */
+
+#include <linux/module.h>
+#include <linux/platform_device.h>
+#include <linux/interrupt.h>
+#include <linux/io.h>
+#include <linux/err.h>
+#include <linux/clk.h>
+#include <linux/pm_runtime.h>
+#include <linux/of_device.h>
+#include <linux/pinctrl/consumer.h>
+#include <linux/input.h>
+
+/* eQEP register offsets from its base IO address */
+#define QPOSCNT 0x0000
+#define QPOSINIT 0x0004
+#define QPOSMAX 0x0008
+#define QPOSCMP 0x000C
+#define QPOSILAT 0x0010
+#define QPOSSLAT 0x0014
+#define QPOSLAT 0x0018
+#define QUTMR 0x001C
+#define QUPRD 0x0020
+#define QWDTMR 0x0024
+#define QWDPRD 0x0026
+#define QDECCTL 0x0028
+#define QEPCTL 0x002A
+#define QCAPCTL 0x002C
+#define QPOSCTL 0x002E
+#define QEINT 0x0030
+#define QFLG 0x0032
+#define QCLR 0x0034
+#define QFRC 0x0036
+#define QEPSTS 0x0038
+#define QCTMR 0x003A
+#define QCPRD 0x003C
+#define QCTMRLAT 0x003E
+#define QCPRDLAT 0x0040
+#define QREVID 0x005C
+
+#if 0 /* if you wanted another way to modify IP registers... */
+typedef volatile u32 REG32;
+typedef volatile u16 REG16;
+struct EQEP_REGS {
+ REG32 q_poscnt; /* 0x00 position counter */
+ REG32 q_posinit; /* 0x04 position counter initialization */
+ REG32 q_posmax; /* 0x08 maximum position count */
+ REG32 q_poscmp; /* 0x0C position compare */
+ REG32 q_posilat; /* 0x10 index position latch */
+ REG32 q_posslat; /* 0x14 strobe position latch */
+ REG32 q_poslat; /* 0x18 position counter latch */
+ REG32 q_utmr; /* 0x1C unit timer */
+ REG32 q_uprd; /* 0x20 unit period */
+ REG16 q_wdtmr; /* 0x24 watchdog timer */
+ REG16 q_wdprd; /* 0x26 watchdog period */
+ REG16 q_decctl; /* 0x28 decoder control */
+ REG16 q_epctl; /* 0x2A control register */
+ REG16 q_capctl; /* 0x2C capture control */
+ REG16 q_posctl; /* 0x2E position compare control */
+ REG16 q_eint; /* 0x30 interrupt enable */
+ REG16 q_flg; /* 0x32 interrupt flag */
+ REG16 q_clr; /* 0x34 interrupt clear */
+ REG16 q_frc; /* 0x36 interrupt force */
+ REG16 q_epsts; /* 0x38 status */
+ REG16 q_ctmr; /* 0x3A capture timer */
+ REG16 q_cprd; /* 0x3C capture period */
+ REG16 q_ctmrlat; /* 0x3E capture timer latch */
+ REG16 q_prdlat; /* 0x40 capture period latch */
+ char q_fill1[0x5c-0x40];
+ REG32 q_revid; /* 0x5C revision id */
+};
+#endif
+
+
+/* Bits for the QDECTL register */
+#define QSRC1 (1 << 15)
+#define QSRC0 (1 << 14)
+#define SOEN (1 << 13)
+#define SPSEL (1 << 12)
+#define XCR (1 << 11)
+#define SWAP (1 << 10)
+#define IGATE (1 << 9)
+#define QAP (1 << 8)
+#define QBP (1 << 7)
+#define QIP (1 << 6)
+#define QSP (1 << 5)
+
+/* Bits for the QEPCTL register */
+#define FREESOFT1 (1 << 15)
+#define FREESOFT0 (1 << 14)
+#define PCRM1 (1 << 13)
+#define PCRM0 (1 << 12)
+#define SEI1 (1 << 11)
+#define SEI0 (1 << 10)
+#define IEI1 (1 << 9)
+#define IEI0 (1 << 8)
+#define SWI (1 << 7)
+#define SEL (1 << 6)
+#define IEL1 (1 << 5)
+#define IEL0 (1 << 4)
+#define PHEN (1 << 3)
+#define QCLM (1 << 2)
+#define UTE (1 << 1)
+#define WDE (1 << 0)
+
+/* Bits for the QCAPCTL register */
+#define CEN (1 << 15)
+#define CCPS2 (1 << 6)
+#define CCPS0 (1 << 5)
+#define CCPS1 (1 << 4)
+#define UPPS3 (1 << 3)
+#define UPPS2 (1 << 2)
+#define UPPS1 (1 << 1)
+#define UPPS0 (1 << 0)
+
+/* Bits for the QPOSCTL register */
+#define PCSHDW (1 << 15)
+#define PCLOAD (1 << 14)
+#define PCPOL (1 << 13)
+#define PCE (1 << 12)
+#define PCSPW11 (1 << 11)
+#define PCSPW10 (1 << 10)
+#define PCSPW9 (1 << 9)
+#define PCSPW8 (1 << 8)
+#define PCSPW7 (1 << 7)
+#define PCSPW6 (1 << 6)
+#define PCSPW5 (1 << 5)
+#define PCSPW4 (1 << 4)
+#define PCSPW3 (1 << 3)
+#define PCSPW2 (1 << 2)
+#define PCSPW1 (1 << 1)
+#define PCSPW0 (1 << 0)
+
+/* Bits for the interrupt registers */
+#define EQEP_INTERRUPT_MASK 0x0FFF
+#define UTOF (1 << 11)
+
+/* Bits to control the clock in the PWMSS subsystem */
+#define PWMSS_EQEPCLK_EN BIT(4)
+#define PWMSS_EQEPCLK_STOP_REQ BIT(5)
+#define PWMSS_EQEPCLK_EN_ACK BIT(4)
+
+/*
+ * Modes for the eQEP unit
+ * Absolute - the position entry represents the current position of the encoder.
+ * Poll this value and it will be notified every period nanoseconds
+ * Relative - the position entry represents the last latched position of the encoder
+ * This value is latched every period nanoseconds and the internal counter
+ * is subsequenty reset
+ */
+#define TIEQEP_MODE_ABSOLUTE 0
+#define TIEQEP_MODE_RELATIVE 1
+
+/* Structure defining the characteristics of the eQEP unit */
+struct eqep_chip
+{
+ /* Platform device for this eQEP unit */
+ struct platform_device *pdev;
+
+ /* Pointer to the base of the memory of the eQEP unit */
+ void __iomem *mmio_base;
+
+ /* SYSCLKOUT to the eQEP unit */
+ u32 clk_rate;
+
+ /* IRQ for the eQEP unit */
+ u16 irq;
+
+ /* Mode of the eQEP unit */
+ u8 op_mode;
+
+ /* work stuct for the notify userspace work */
+ struct work_struct notify_work;
+
+ /* Backup for driver suspension */
+ u16 prior_qepctl;
+ u16 prior_qeint;
+};
+
+/* Notify userspace work */
+static void notify_handler(struct work_struct *work)
+{
+ /* Get a reference to the eQEP driver */
+ struct eqep_chip *eqep = container_of(work, struct eqep_chip, notify_work);
+
+ /* Notify the userspace */
+ sysfs_notify(&eqep->pdev->dev.kobj, NULL, "position");
+}
+
+/* eQEP Interrupt handler */
+static irqreturn_t eqep_irq_handler(int irq, void *dev_id)
+{
+ /* Get the instance information */
+ struct platform_device *pdev = dev_id;
+ struct eqep_chip *eqep = platform_get_drvdata(pdev);
+
+ /* Get the interrupt flags */
+ u16 iflags = readw(eqep->mmio_base + QFLG) & EQEP_INTERRUPT_MASK;
+
+ /* Check the interrupt source(s) */
+ if (iflags & UTOF) {
+ /* Handle the unit timer overflow interrupt by notifying any potential pollers */
+ schedule_work(&eqep->notify_work);
+ }
+
+ /* Clear interrupt flags (write back triggered flags to the clear register) */
+ writew(iflags, eqep->mmio_base + QCLR);
+
+ /* Return that the IRQ was handled successfully */
+ return IRQ_HANDLED;
+}
+
+/* Function to read whether the eQEP unit is enabled or disabled */
+static ssize_t eqep_get_enabled(struct device *dev, struct device_attribute *attr, char *buf)
+{
+ /* Get the instance structure */
+ struct eqep_chip *eqep = dev_get_drvdata(dev);
+
+ /* Read the qep control register and mask all but the enabled bit */
+ u16 enabled = readw(eqep->mmio_base + QEPCTL) & PHEN;
+
+ /* Return the target in string format */
+ return sprintf(buf, "%u\n", (enabled) ? 1 : 0);
+}
+
+/* Function to set if the eQEP is enabled */
+static ssize_t eqep_set_enabled(struct device *dev, struct device_attribute *attr, const char *buf, size_t count)
+{
+ /* Get the instance structure */
+ int rc;
+ u16 val;
+ u8 enabled;
+ struct eqep_chip *eqep = dev_get_drvdata(dev);
+
+ /* Convert the input string to an 8 bit uint */
+ if ((rc = kstrtou8(buf, 0, &enabled)))
+ return rc;
+
+ /* Get the existing state of QEPCTL */
+ val = readw(eqep->mmio_base + QEPCTL);
+
+ /* If we passed a number that is not 0, enable the eQEP */
+ if (enabled)
+ /* Enable the eQEP (Set PHEN in QEPCTL) */
+ val |= PHEN;
+ else
+ /* Disable the eQEP (Clear PHEN in QEPCTL) */
+ val &= ~PHEN;
+
+ /* Write flags back to control register */
+ writew(val, eqep->mmio_base + QEPCTL);
+
+ /* Return buffer length consumed (all) */
+ return count;
+}
+
+/* Function to read the current position of the eQEP */
+static ssize_t eqep_get_position(struct device *dev, struct device_attribute *attr, char *buf)
+{
+ struct eqep_chip *eqep = dev_get_drvdata(dev);
+
+ s32 position = 0;
+
+ if (eqep->op_mode == TIEQEP_MODE_ABSOLUTE) {
+ position = readl(eqep->mmio_base + QPOSCNT);
+ } else if (eqep->op_mode == TIEQEP_MODE_RELATIVE) {
+ /* in relative mode, use the last latched value of the eQEP hardware */
+ position = readl(eqep->mmio_base + QPOSLAT);
+ dev_dbg(dev, "get_position:0x%08x\n", position);
+ }
+
+ return sprintf(buf, "%d\n", position);
+}
+
+/* Function to set the position of the eQEP hardware */
+static ssize_t eqep_set_position(struct device *dev, struct device_attribute *attr, const char *buf, size_t count)
+{
+ int rc;
+ s32 position;
+ struct eqep_chip *eqep = dev_get_drvdata(dev);
+
+ if ((rc = kstrtos32(buf, 0, &position)))
+ return rc;
+
+ /*
+ * If we are in absolute mode, set the position of the encoder,
+ * discard relative mode because thats pointless
+ */
+ if (eqep->op_mode == TIEQEP_MODE_ABSOLUTE) {
+ /* If absolute mode, set the current value of the eQEP hardware */
+ writel(position, eqep->mmio_base + QPOSCNT);
+ }
+
+ /* Return buffer length consumed (all) */
+ return count;
+}
+
+/* Function to read the period of the unit time event timer */
+static ssize_t eqep_get_timer_period(struct device *dev, struct device_attribute *attr, char *buf)
+{
+ struct eqep_chip *eqep = dev_get_drvdata(dev);
+ u64 period;
+
+ /* Convert from counts per interrupt back into period_ns */
+ period = readl(eqep->mmio_base + QUPRD);
+ period = period * NSEC_PER_SEC;
+ do_div(period, eqep->clk_rate);
+
+ /* Otherwise write out the data */
+ return sprintf(buf, "%llu\n", period);
+}
+
+/* Function to set the unit timer period. 0 = off, greater than zero sets the period */
+static ssize_t eqep_set_timer_period(struct device *dev, struct device_attribute *attr, const char *buf, size_t count)
+{
+ int rc;
+ u16 tmp;
+ u64 period;
+
+ struct eqep_chip *eqep = dev_get_drvdata(dev);
+
+ if ((rc = kstrtou64(buf, 0, &period)))
+ return rc;
+
+ /* Disable the unit timer before modifying its period register */
+ tmp = readw(eqep->mmio_base + QEPCTL);
+ tmp &= ~(UTE | QCLM);
+ writew(tmp, eqep->mmio_base + QEPCTL);
+
+ /* Zero the unit timer counter register */
+ writel(0, eqep->mmio_base + QUTMR);
+
+ /* If the timer is enabled (a non-zero period has been passed) */
+ if (period) {
+ /* update the period */
+ period = period * eqep->clk_rate;
+ do_div(period, NSEC_PER_SEC);
+
+ dev_dbg(dev, "eqep_set_timer_period:%llu\n", period);
+
+ writel(period, eqep->mmio_base + QUPRD);
+
+ /* Enable unit timer, and latch QPOSLAT to QPOSCNT on timer expiration */
+ tmp |= UTE | QCLM;
+ writew(tmp, eqep->mmio_base + QEPCTL);
+ }
+
+ return count;
+}
+
+/* Function to read the mode of the eQEP hardware */
+static ssize_t eqep_get_mode(struct device *dev, struct device_attribute *attr, char *buf)
+{
+ struct eqep_chip *eqep = dev_get_drvdata(dev);
+
+ return sprintf(buf, "%u\n", eqep->op_mode);
+}
+
+/* Function to set the mode of the eQEP hardware */
+static ssize_t eqep_set_mode(struct device *dev, struct device_attribute *attr, const char *buf, size_t count)
+{
+ int rc;
+ u16 val;
+ u8 tmp_mode;
+ struct eqep_chip *eqep = dev_get_drvdata(dev);
+
+ if ((rc = kstrtou8(buf, 0, &tmp_mode)))
+ return rc;
+
+ dev_dbg(dev, "eqep_set_mode:%d\n", tmp_mode);
+
+ val = readw(eqep->mmio_base + QEPCTL);
+
+ if (tmp_mode == TIEQEP_MODE_ABSOLUTE) {
+ /*
+ * In absolute mode, don't reset the hardware based on time,
+ * so disable the unit timer position reset (Set PCRM[1:0] = 0)
+ */
+ val &= ~(PCRM1 | PCRM0);
+
+ eqep->op_mode = TIEQEP_MODE_ABSOLUTE;
+ } else if (tmp_mode == TIEQEP_MODE_RELATIVE) {
+ /*
+ * In relative mode, latch the value of the eQEP hardware on the
+ * overflow of the unit timer. So enable the unit timer position reset
+ * (Set PCRM[1:0] = 3)
+ */
+ val |= PCRM1 | PCRM0;
+
+ eqep->op_mode = TIEQEP_MODE_RELATIVE;
+ }
+
+ writew(val, eqep->mmio_base + QEPCTL);
+
+ return count;
+}
+
+/* Bind read/write functions to sysfs entries */
+static DEVICE_ATTR(enabled, 0644, eqep_get_enabled, eqep_set_enabled);
+static DEVICE_ATTR(position, 0644, eqep_get_position, eqep_set_position);
+static DEVICE_ATTR(period, 0644, eqep_get_timer_period, eqep_set_timer_period);
+static DEVICE_ATTR(mode, 0644, eqep_get_mode, eqep_set_mode);
+
+/* Array holding all of the sysfs entries */
+static const struct attribute *eqep_attrs[] = {
+ &dev_attr_enabled.attr,
+ &dev_attr_position.attr,
+ &dev_attr_period.attr,
+ &dev_attr_mode.attr,
+ NULL,
+};
+
+/* Driver function group */
+static const struct attribute_group eqep_device_attr_group = {
+ .attrs = (struct attribute **) eqep_attrs,
+};
+
+/* Driver compatibility list */
+static struct of_device_id eqep_of_match[] =
+{
+ { .compatible = "ti,am33xx-eqep" },
+ { }
+};
+
+/* Register our compatibilities for device trees */
+MODULE_DEVICE_TABLE(of, eqep_of_match);
+
+/* Create an instance of the eQEP driver */
+static int eqep_probe(struct platform_device *pdev)
+{
+ struct resource *r;
+ struct clk *clk;
+ struct eqep_chip *eqep;
+ struct pinctrl *pinctrl;
+
+ u64 period;
+ u16 status;
+ u32 value;
+
+ dev_info(&pdev->dev, "ver. 1.0\n");
+
+ /* Select pins provided through the device tree */
+ pinctrl = devm_pinctrl_get_select_default(&pdev->dev);
+ if (IS_ERR(pinctrl))
+ {
+ dev_warn(&pdev->dev, "unable to select pin group\n");
+ }
+
+ /* Allocate a eqep_driver object */
+ eqep = devm_kzalloc(&pdev->dev, sizeof(struct eqep_chip), GFP_KERNEL);
+ if (!eqep) {
+ dev_err(&pdev->dev, "failed to allocate memory\n");
+ return -ENOMEM;
+ }
+
+ /* Get a handle to the system clock object */
+ clk = devm_clk_get(pdev->dev.parent, "fck");
+ if (IS_ERR(clk)) {
+ dev_err(&pdev->dev, "failed to get clock\n");
+ return PTR_ERR(clk);
+ }
+
+ /* Get the frequency of the system clock */
+ eqep->clk_rate = clk_get_rate(clk);
+ if (!eqep->clk_rate) {
+ dev_err(&pdev->dev, "failed to get clock rate\n");
+ return -EINVAL;
+ }
+
+ /* Get a resource containing the IRQ for this eQEP controller */
+ r = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
+ if (unlikely(!r)) {
+ dev_err(&pdev->dev, "Invalid IRQ resource\n");
+ return -ENODEV;
+ }
+
+ /* Store the irq */
+ eqep->irq = r->start;
+
+ /* Get a resource containing the requested (from DT) memory address and range of eQEP controller */
+ r = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+ if (!r) {
+ dev_err(&pdev->dev, "no memory resource defined\n");
+ return -ENODEV;
+ }
+
+ /* Remap the eQEP controller memory into our own memory space */
+ eqep->mmio_base = devm_ioremap_resource(&pdev->dev, r);
+ if (IS_ERR(eqep->mmio_base))
+ return PTR_ERR(eqep->mmio_base);
+
+ /* Store the platform device in our eQEP data structure for later usage */
+ eqep->pdev = pdev;
+
+ /* Subscribe to the eQEP interrupt */
+ if (request_irq(eqep->irq, eqep_irq_handler, IRQF_IRQPOLL, "eqep_interrupt", pdev))
+ {
+ dev_err(&pdev->dev, "unable to request irq for eQEP\n");
+ return -ENODEV;
+ }
+
+ /* Register controls to sysfs */
+ if (sysfs_create_group(&pdev->dev.kobj, &eqep_device_attr_group))
+ {
+ dev_err(&pdev->dev, "sysfs creation failed\n");
+ return -EINVAL;
+ }
+
+ /* set QDECCTL */
+ status = 0; /* default to Quadrature count mode, QSRC1 & QSRC0 = 0 */
+
+ /* set QSRC1 & QSRC0 bits, one of 4 count_modes. */
+ if (!of_property_read_u32(pdev->dev.of_node, "count_mode", &value) && value <= 3) {
+ status |= value << 14;
+
+ /*
+ * in count up or count down mode, count on rising edge only
+ * not on both edges.
+ */
+ if (value >= 2)
+ status |= XCR;
+ }
+ dev_info(&pdev->dev, "count_mode:%d\n", value);
+
+ /* Should we invert the qa input */
+ if (!of_property_read_u32(pdev->dev.of_node, "invert_qa", &value))
+ status = value ? status | QAP : status & ~QAP;
+ dev_info(&pdev->dev, "invert_qa:%d\n", value);
+
+ /* Should we invert the qb input */
+ if (!of_property_read_u32(pdev->dev.of_node, "invert_qb", &value))
+ status = value ? status | QBP : status & ~QBP;
+ dev_info(&pdev->dev, "invert_qb:%d\n", value);
+
+ /* Should we invert the index input */
+ if (!of_property_read_u32(pdev->dev.of_node, "invert_qi", &value))
+ status = value ? status | QIP : status & ~QIP;
+ dev_info(&pdev->dev, "invert_qi:%d\n", value);
+
+ /* Should we invert the strobe input */
+ if (!of_property_read_u32(pdev->dev.of_node, "invert_qs", &value))
+ status = value ? status | QSP : status & ~QSP;
+ dev_info(&pdev->dev, "invert_qs:%d\n", value);
+
+ /* Should we swap the cha and chb inputs */
+ if (!of_property_read_u32(pdev->dev.of_node, "swap_inputs", &value))
+ status = value ? status | SWAP : status & ~SWAP;
+ dev_info(&pdev->dev, "swap_inputs:%d\n", value);
+
+ dev_info(&pdev->dev, "QDECCTL:0x%04x\n", status);
+
+ /* Write the decoder control settings back to the control register */
+ writew(status, eqep->mmio_base + QDECCTL);
+
+ writel( 0, eqep->mmio_base + QPOSINIT);
+ writel(~0, eqep->mmio_base + QPOSMAX);
+ writel( 0, eqep->mmio_base + QPOSCNT);
+
+ dev_info(&pdev->dev, "QPOSINIT:0x%08x\n", readl(eqep->mmio_base + QPOSINIT));
+ dev_info(&pdev->dev, "QPOSMAX:0x%08x\n", readl(eqep->mmio_base + QPOSMAX));
+ dev_info(&pdev->dev, "QPOSCNT:0x%08x\n", readl(eqep->mmio_base + QPOSCNT));
+
+ status = UTOF; /* Enable Unit Time Period interrupt. */
+ if (!of_property_read_u32(pdev->dev.of_node, "omit_interrupt", &value) && value) {
+ status = 0; /* no interrupt */
+ }
+ writew(status, eqep->mmio_base + QEINT);
+ dev_info(&pdev->dev, "omit_interrupt:%d\n", value);
+ dev_info(&pdev->dev, "QEINT:0x%04x\n", status);
+
+ /* Calculate the timer ticks per second */
+ period = 1000000000;
+ period = period * eqep->clk_rate;
+ do_div(period, NSEC_PER_SEC);
+
+ /* Set this period into the unit timer period register */
+ writel(period, eqep->mmio_base + QUPRD);
+ dev_info(&pdev->dev, "QUPRD:0x%08x\n", (u32) period);
+
+ /*
+ * Enable the eQEP with basic position counting turned on
+ * PHEN - Quadrature position counter enable bit
+ * UTE - unit timer enable
+ * QCLM - latch QPOSLAT to QPOSCNT upon unit timer overflow
+ * IEL0 - Latch QPOSILAT on index signal. Rising or falling, IEL[1:0] = 0 is reserved
+ * SWI - Software initialization of position count register, i.e. set QPOSCNT <= QPOSINIT,
+ * but this bit was not being reset by hardware as advertised in TRM,
+ * (so omit & clear QPOSCNT manually elsewhere?)
+ */
+ status = PHEN | UTE | QCLM | IEL0 | SWI;
+ writew(status, eqep->mmio_base + QEPCTL);
+ dev_info(&pdev->dev, "QEPCTL:0x%04x write\n", status);
+ dev_info(&pdev->dev, "QEPCTL:0x%04x read\n", readw(eqep->mmio_base + QEPCTL));
+
+ /* We default to absolute mode */
+ eqep->op_mode = TIEQEP_MODE_ABSOLUTE;
+
+ /* Enable the power management runtime */
+ pm_runtime_enable(&pdev->dev);
+
+ /* Increment the device usage count and run pm_runtime_resume() */
+ pm_runtime_get_sync(&pdev->dev);
+
+ /* Initialize the notify work struture */
+ INIT_WORK(&eqep->notify_work, notify_handler);
+
+ /* Decrement the device usage count (twice) and run pm_runtime_idle() if zero */
+ pm_runtime_put_sync(&pdev->dev);
+
+ /* Set the platform driver data to the data object we've been creating for the eQEP unit */
+ platform_set_drvdata(pdev, eqep);
+
+ /* Success! */
+ dev_info(&pdev->dev, "irq:%d, clk_rate:%u\n", eqep->irq, eqep->clk_rate);
+ return 0;
+}
+
+/* Remove an instance of the eQEP driver */
+static int eqep_remove(struct platform_device *pdev)
+{
+ /* Get the eQEP driver data from the platform device structure */
+ struct eqep_chip *eqep = platform_get_drvdata(pdev);
+
+ /* Cancel work */
+ cancel_work_sync(&eqep->notify_work);
+
+ /* Unmap from sysfs */
+ sysfs_remove_group(&pdev->dev.kobj, &eqep_device_attr_group);
+
+ /* Release important assets */
+ free_irq(eqep->irq, pdev);
+
+ /* Increment the device usage count and run pm_runtime_resume() */
+ pm_runtime_get_sync(&pdev->dev);
+
+ /* Decrement the device usage count (twice) and run pm_runtime_idle() if zero */
+ pm_runtime_put_sync(&pdev->dev);
+ pm_runtime_put_sync(&pdev->dev);
+
+ /* Disable the runtime power management of this device */
+ pm_runtime_disable(&pdev->dev);
+
+ /* Return success */
+ return 0;
+}
+
+/* Power management suspend device */
+static int eqep_suspend(struct device *dev)
+{
+ /* Get the eqep driver information */
+ struct eqep_chip *eqep = dev_get_drvdata(dev);
+ u16 tmp;
+
+ /* Shut down interrupts */
+ eqep->prior_qeint = readw(eqep->mmio_base + QEINT);
+ tmp = eqep->prior_qeint & ~UTOF;
+ writew(tmp, eqep->mmio_base + QEINT);
+
+ /* Get the existing state of QEPCTL */
+ eqep->prior_qepctl = readw(eqep->mmio_base + QEPCTL);
+
+ /* Disable eQEP controller */
+ writew(eqep->prior_qepctl & ~PHEN, eqep->mmio_base + QEPCTL);
+
+ /* Decrement the device usage count and run pm_runtime_idle() if zero */
+ pm_runtime_put_sync(dev);
+
+ /* Return success */
+ return 0;
+}
+
+/* Power management wake device back up */
+static int eqep_resume(struct device *dev)
+{
+ /* Get the eqep driver information */
+ struct eqep_chip *eqep = dev_get_drvdata(dev);
+
+ /* Restore interrupt enabled register */
+ writew(eqep->prior_qeint, eqep->mmio_base + QEINT);
+
+ /* Restore prior qep control register */
+ writew(eqep->prior_qepctl, eqep->mmio_base + QEPCTL);
+
+ /* Increment the device usage count and run pm_runtime_resume() */
+ pm_runtime_get_sync(dev);
+
+ /* Success */
+ return 0;
+}
+
+/* create pm functions object */
+static SIMPLE_DEV_PM_OPS(eqep_pm_ops, eqep_suspend, eqep_resume);
+
+/* Platform driver information */
+static struct platform_driver eqep_driver = {
+ .driver = {
+ .name = "eqep",
+ .owner = THIS_MODULE,
+ .pm = &eqep_pm_ops,
+ .of_match_table = eqep_of_match,
+ },
+ .probe = eqep_probe,
+ .remove = eqep_remove,
+};
+
+/* Register this platform driver */
+module_platform_driver(eqep_driver);
+
+/* Module information */
+MODULE_DESCRIPTION("TI eQEP driver");
+MODULE_AUTHOR("Nathaniel R. Lewis");
+MODULE_LICENSE("GPL");
--
2.10.1
/*
* Device Tree Source for AM33XX SoC
*
* Copyright (C) 2012 Texas Instruments Incorporated - http://www.ti.com/
*
* This file is licensed under the terms of the GNU General Public License
* version 2. This program is licensed "as is" without any warranty of any
* kind, whether express or implied.
*/
#include <dt-bindings/gpio/gpio.h>
#include <dt-bindings/pinctrl/am33xx.h>
/ {
compatible = "ti,am33xx";
interrupt-parent = <&intc>;
#address-cells = <1>;
#size-cells = <1>;
chosen { };
aliases {
i2c0 = &i2c0;
i2c1 = &i2c1;
i2c2 = &i2c2;
serial0 = &uart0;
serial1 = &uart1;
serial2 = &uart2;
serial3 = &uart3;
serial4 = &uart4;
serial5 = &uart5;
d_can0 = &dcan0;
d_can1 = &dcan1;
usb0 = &usb0;
usb1 = &usb1;
phy0 = &usb0_phy;
phy1 = &usb1_phy;
ethernet0 = &cpsw_emac0;
ethernet1 = &cpsw_emac1;
mmc0 = &mmc1;
mmc1 = &mmc2;
mmc2 = &mmc3;
spi0 = &spi0;
spi1 = &spi1;
};
cpus {
#address-cells = <1>;
#size-cells = <0>;
cpu@0 {
compatible = "arm,cortex-a8";
enable-method = "ti,am3352";
device_type = "cpu";
reg = <0>;
operating-points-v2 = <&cpu0_opp_table>;
clocks = <&dpll_mpu_ck>;
clock-names = "cpu";
clock-latency = <300000>; /* From omap-cpufreq driver */
cpu-idle-states = <&mpu_gate>;
};
idle-states {
mpu_gate: mpu_gate {
compatible = "arm,idle-state";
entry-latency-us = <40>;
exit-latency-us = <90>;
min-residency-us = <300>;
ti,idle-wkup-m3;
};
};
};
cpu0_opp_table: opp_table0 {
compatible = "operating-points-v2-ti-cpu";
ti,syscon-efuse = <&scm_conf 0x7fc 0x1fff 0>;
ti,syscon-rev = <&scm_conf 0x600>;
/*
* The three following nodes are marked with opp-suspend
* because the can not be enabled simultaneously on a
* single SoC.
*/
opp50@300000000 {
opp-hz = /bits/ 64 <300000000>;
opp-microvolt = <950000 931000 969000>;
opp-supported-hw = <0x06 0x0010>;
opp-suspend;
};
opp100@275000000 {
opp-hz = /bits/ 64 <275000000>;
opp-microvolt = <1100000 1078000 1122000>;
opp-supported-hw = <0x01 0x00FF>;
opp-suspend;
};
opp100@300000000 {
opp-hz = /bits/ 64 <300000000>;
opp-microvolt = <1100000 1078000 1122000>;
opp-supported-hw = <0x06 0x0020>;
opp-suspend;
};
opp100@500000000 {
opp-hz = /bits/ 64 <500000000>;
opp-microvolt = <1100000 1078000 1122000>;
opp-supported-hw = <0x01 0xFFFF>;
};
opp100@600000000 {
opp-hz = /bits/ 64 <600000000>;
opp-microvolt = <1100000 1078000 1122000>;
opp-supported-hw = <0x06 0x0040>;
};
opp120@600000000 {
opp-hz = /bits/ 64 <600000000>;
opp-microvolt = <1200000 1176000 1224000>;
opp-supported-hw = <0x01 0xFFFF>;
};
opp120@720000000 {
opp-hz = /bits/ 64 <720000000>;
opp-microvolt = <1200000 1176000 1224000>;
opp-supported-hw = <0x06 0x0080>;
};
oppturbo@720000000 {
opp-hz = /bits/ 64 <720000000>;
opp-microvolt = <1260000 1234800 1285200>;
opp-supported-hw = <0x01 0xFFFF>;
};
oppturbo@800000000 {
opp-hz = /bits/ 64 <800000000>;
opp-microvolt = <1260000 1234800 1285200>;
opp-supported-hw = <0x06 0x0100>;
};
oppnitro@1000000000 {
opp-hz = /bits/ 64 <1000000000>;
opp-microvolt = <1325000 1298500 1351500>;
opp-supported-hw = <0x04 0x0200>;
};
};
pmu {
compatible = "arm,cortex-a8-pmu";
interrupts = <3>;
};
/*
* The soc node represents the soc top level view. It is used for IPs
* that are not memory mapped in the MPU view or for the MPU itself.
*/
soc {
compatible = "ti,omap-infra";
mpu {
compatible = "ti,omap3-mpu";
ti,hwmods = "mpu";
pm-sram = <&pm_sram_code
&pm_sram_data>;
};
};
/*
* XXX: Use a flat representation of the AM33XX interconnect.
* The real AM33XX interconnect network is quite complex. Since
* it will not bring real advantage to represent that in DT
* for the moment, just use a fake OCP bus entry to represent
* the whole bus hierarchy.
*/
ocp: ocp {
compatible = "simple-bus";
#address-cells = <1>;
#size-cells = <1>;
ranges;
ti,hwmods = "l3_main";
l4_wkup: l4_wkup@44c00000 {
compatible = "ti,am3-l4-wkup", "simple-bus";
#address-cells = <1>;
#size-cells = <1>;
ranges = <0 0x44c00000 0x280000>;
wkup_m3: wkup_m3@100000 {
compatible = "ti,am3352-wkup-m3";
reg = <0x100000 0x4000>,
<0x180000 0x2000>;
reg-names = "umem", "dmem";
ti,hwmods = "wkup_m3";
ti,pm-firmware = "am335x-pm-firmware.elf";
};
prcm: prcm@200000 {
compatible = "ti,am3-prcm";
reg = <0x200000 0x4000>;
prcm_clocks: clocks {
#address-cells = <1>;
#size-cells = <0>;
};
prcm_clockdomains: clockdomains {
};
};
scm: scm@210000 {
compatible = "ti,am3-scm", "simple-bus";
reg = <0x210000 0x2000>;
#address-cells = <1>;
#size-cells = <1>;
ranges = <0 0x210000 0x2000>;
am33xx_pinmux: pinmux@800 {
compatible = "pinctrl-single";
reg = <0x800 0x238>;
#address-cells = <1>;
#size-cells = <0>;
pinctrl-single,register-width = <32>;
pinctrl-single,function-mask = <0x7f>;
};
scm_conf: scm_conf@0 {
compatible = "syscon";
reg = <0x0 0x800>;
#address-cells = <1>;
#size-cells = <1>;
scm_clocks: clocks {
#address-cells = <1>;
#size-cells = <0>;
};
};
wkup_m3_ipc: wkup_m3_ipc@1324 {
compatible = "ti,am3352-wkup-m3-ipc";
reg = <0x1324 0x24>;
interrupts = <78>;
ti,rproc = <&wkup_m3>;
mboxes = <&mailbox &mbox_wkupm3>;
};
edma_xbar: dma-router@f90 {
compatible = "ti,am335x-edma-crossbar";
reg = <0xf90 0x40>;
#dma-cells = <3>;
dma-requests = <32>;
dma-masters = <&edma>;
};
scm_clockdomains: clockdomains {
};
};
};
intc: interrupt-controller@48200000 {
compatible = "ti,am33xx-intc";
interrupt-controller;
#interrupt-cells = <1>;
reg = <0x48200000 0x1000>;
};
edma: edma@49000000 {
compatible = "ti,edma3-tpcc";
ti,hwmods = "tpcc";
reg = <0x49000000 0x10000>;
reg-names = "edma3_cc";
interrupts = <12 13 14>;
interrupt-names = "edma3_ccint", "edma3_mperr",
"edma3_ccerrint";
dma-requests = <64>;
#dma-cells = <2>;
ti,tptcs = <&edma_tptc0 7>, <&edma_tptc1 5>,
<&edma_tptc2 0>;
ti,edma-memcpy-channels = <20 21>;
};
edma_tptc0: tptc@49800000 {
compatible = "ti,edma3-tptc";
ti,hwmods = "tptc0";
reg = <0x49800000 0x100000>;
interrupts = <112>;
interrupt-names = "edma3_tcerrint";
};
edma_tptc1: tptc@49900000 {
compatible = "ti,edma3-tptc";
ti,hwmods = "tptc1";
reg = <0x49900000 0x100000>;
interrupts = <113>;
interrupt-names = "edma3_tcerrint";
};
edma_tptc2: tptc@49a00000 {
compatible = "ti,edma3-tptc";
ti,hwmods = "tptc2";
reg = <0x49a00000 0x100000>;
interrupts = <114>;
interrupt-names = "edma3_tcerrint";
};
emif: emif@4c000000 {
compatible = "ti,emif-am3352";
reg = <0x4C000000 0x1000>;
sram = <&pm_sram_code
&pm_sram_data>;
};
gpio0: gpio@44e07000 {
compatible = "ti,omap4-gpio";
ti,hwmods = "gpio1";
gpio-controller;
#gpio-cells = <2>;
interrupt-controller;
#interrupt-cells = <2>;
reg = <0x44e07000 0x1000>;
interrupts = <96>;
};
gpio1: gpio@4804c000 {
compatible = "ti,omap4-gpio";
ti,hwmods = "gpio2";
gpio-controller;
#gpio-cells = <2>;
interrupt-controller;
#interrupt-cells = <2>;
reg = <0x4804c000 0x1000>;
interrupts = <98>;
};
gpio2: gpio@481ac000 {
compatible = "ti,omap4-gpio";
ti,hwmods = "gpio3";
gpio-controller;
#gpio-cells = <2>;
interrupt-controller;
#interrupt-cells = <2>;
reg = <0x481ac000 0x1000>;
interrupts = <32>;
};
gpio3: gpio@481ae000 {
compatible = "ti,omap4-gpio";
ti,hwmods = "gpio4";
gpio-controller;
#gpio-cells = <2>;
interrupt-controller;
#interrupt-cells = <2>;
reg = <0x481ae000 0x1000>;
interrupts = <62>;
};
uart0: serial@44e09000 {
compatible = "ti,am3352-uart", "ti,omap3-uart";
ti,hwmods = "uart1";
clock-frequency = <48000000>;
reg = <0x44e09000 0x2000>;
interrupts = <72>;
status = "disabled";
dmas = <&edma 26 0>, <&edma 27 0>;
dma-names = "tx", "rx";
};
uart1: serial@48022000 {
compatible = "ti,am3352-uart", "ti,omap3-uart";
ti,hwmods = "uart2";
clock-frequency = <48000000>;
reg = <0x48022000 0x2000>;
interrupts = <73>;
status = "disabled";
dmas = <&edma 28 0>, <&edma 29 0>;
dma-names = "tx", "rx";
};
uart2: serial@48024000 {
compatible = "ti,am3352-uart", "ti,omap3-uart";
ti,hwmods = "uart3";
clock-frequency = <48000000>;
reg = <0x48024000 0x2000>;
interrupts = <74>;
status = "disabled";
dmas = <&edma 30 0>, <&edma 31 0>;
dma-names = "tx", "rx";
};
uart3: serial@481a6000 {
compatible = "ti,am3352-uart", "ti,omap3-uart";
ti,hwmods = "uart4";
clock-frequency = <48000000>;
reg = <0x481a6000 0x2000>;
interrupts = <44>;
status = "disabled";
};
uart4: serial@481a8000 {
compatible = "ti,am3352-uart", "ti,omap3-uart";
ti,hwmods = "uart5";
clock-frequency = <48000000>;
reg = <0x481a8000 0x2000>;
interrupts = <45>;
status = "disabled";
};
uart5: serial@481aa000 {
compatible = "ti,am3352-uart", "ti,omap3-uart";
ti,hwmods = "uart6";
clock-frequency = <48000000>;
reg = <0x481aa000 0x2000>;
interrupts = <46>;
status = "disabled";
};
i2c0: i2c@44e0b000 {
compatible = "ti,omap4-i2c";
#address-cells = <1>;
#size-cells = <0>;
ti,hwmods = "i2c1";
reg = <0x44e0b000 0x1000>;
interrupts = <70>;
status = "disabled";
};
i2c1: i2c@4802a000 {
compatible = "ti,omap4-i2c";
#address-cells = <1>;
#size-cells = <0>;
ti,hwmods = "i2c2";
reg = <0x4802a000 0x1000>;
interrupts = <71>;
status = "disabled";
};
i2c2: i2c@4819c000 {
compatible = "ti,omap4-i2c";
#address-cells = <1>;
#size-cells = <0>;
ti,hwmods = "i2c3";
reg = <0x4819c000 0x1000>;
interrupts = <30>;
status = "disabled";
};
mmc1: mmc@48060000 {
compatible = "ti,omap4-hsmmc";
ti,hwmods = "mmc1";
ti,dual-volt;
ti,needs-special-reset;
ti,needs-special-hs-handling;
dmas = <&edma_xbar 24 0 0
&edma_xbar 25 0 0>;
dma-names = "tx", "rx";
interrupts = <64>;
interrupt-parent = <&intc>;
reg = <0x48060000 0x1000>;
status = "disabled";
};
mmc2: mmc@481d8000 {
compatible = "ti,omap4-hsmmc";
ti,hwmods = "mmc2";
ti,needs-special-reset;
dmas = <&edma 2 0
&edma 3 0>;
dma-names = "tx", "rx";
interrupts = <28>;
interrupt-parent = <&intc>;
reg = <0x481d8000 0x1000>;
status = "disabled";
};
mmc3: mmc@47810000 {
compatible = "ti,omap4-hsmmc";
ti,hwmods = "mmc3";
ti,needs-special-reset;
interrupts = <29>;
interrupt-parent = <&intc>;
reg = <0x47810000 0x1000>;
status = "disabled";
};
hwspinlock: spinlock@480ca000 {
compatible = "ti,omap4-hwspinlock";
reg = <0x480ca000 0x1000>;
ti,hwmods = "spinlock";
#hwlock-cells = <1>;
};
wdt2: wdt@44e35000 {
compatible = "ti,omap3-wdt";
ti,hwmods = "wd_timer2";
reg = <0x44e35000 0x1000>;
interrupts = <91>;
};
dcan0: can@481cc000 {
compatible = "ti,am3352-d_can";
ti,hwmods = "d_can0";
reg = <0x481cc000 0x2000>;
clocks = <&dcan0_fck>;
clock-names = "fck";
syscon-raminit = <&scm_conf 0x644 0>;
interrupts = <52>;
status = "disabled";
};
dcan1: can@481d0000 {
compatible = "ti,am3352-d_can";
ti,hwmods = "d_can1";
reg = <0x481d0000 0x2000>;
clocks = <&dcan1_fck>;
clock-names = "fck";
syscon-raminit = <&scm_conf 0x644 1>;
interrupts = <55>;
status = "disabled";
};
mailbox: mailbox@480C8000 {
compatible = "ti,omap4-mailbox";
reg = <0x480C8000 0x200>;
interrupts = <77>;
ti,hwmods = "mailbox";
#mbox-cells = <1>;
ti,mbox-num-users = <4>;
ti,mbox-num-fifos = <8>;
mbox_wkupm3: wkup_m3 {
ti,mbox-send-noirq;
ti,mbox-tx = <0 0 0>;
ti,mbox-rx = <0 0 3>;
};
};
timer1: timer@44e31000 {
compatible = "ti,am335x-timer-1ms";
reg = <0x44e31000 0x400>;
interrupts = <67>;
ti,hwmods = "timer1";
ti,timer-alwon;
};
timer2: timer@48040000 {
compatible = "ti,am335x-timer";
reg = <0x48040000 0x400>;
interrupts = <68>;
ti,hwmods = "timer2";
};
timer3: timer@48042000 {
compatible = "ti,am335x-timer";
reg = <0x48042000 0x400>;
interrupts = <69>;
ti,hwmods = "timer3";
};
timer4: timer@48044000 {
compatible = "ti,am335x-timer";
reg = <0x48044000 0x400>;
interrupts = <92>;
ti,hwmods = "timer4";
ti,timer-pwm;
};
timer5: timer@48046000 {
compatible = "ti,am335x-timer";
reg = <0x48046000 0x400>;
interrupts = <93>;
ti,hwmods = "timer5";
ti,timer-pwm;
};
timer6: timer@48048000 {
compatible = "ti,am335x-timer";
reg = <0x48048000 0x400>;
interrupts = <94>;
ti,hwmods = "timer6";
ti,timer-pwm;
};
timer7: timer@4804a000 {
compatible = "ti,am335x-timer";
reg = <0x4804a000 0x400>;
interrupts = <95>;
ti,hwmods = "timer7";
ti,timer-pwm;
};
pruss: pruss@4a300000 {
compatible = "ti,pruss-v2";
ti,hwmods = "pruss";
ti,deassert-hard-reset = "pruss", "pruss";
reg = <0x4a300000 0x080000>;
ti,pintc-offset = <0x20000>;
interrupt-parent = <&intc>;
status = "disabled";
interrupts = <20 21 22 23 24 25 26 27>;
};
rtc: rtc@44e3e000 {
compatible = "ti,am3352-rtc", "ti,da830-rtc";
reg = <0x44e3e000 0x1000>;
interrupts = <75
76>;
ti,hwmods = "rtc";
clocks = <&clkdiv32k_ick>;
clock-names = "int-clk";
ti,no-reset-on-init;
ti,no-idle-on-init;
};
spi0: spi@48030000 {
compatible = "ti,omap4-mcspi";
#address-cells = <1>;
#size-cells = <0>;
reg = <0x48030000 0x400>;
interrupts = <65>;
ti,spi-num-cs = <2>;
ti,hwmods = "spi0";
dmas = <&edma 16 0
&edma 17 0
&edma 18 0
&edma 19 0>;
dma-names = "tx0", "rx0", "tx1", "rx1";
status = "disabled";
};
spi1: spi@481a0000 {
compatible = "ti,omap4-mcspi";
#address-cells = <1>;
#size-cells = <0>;
reg = <0x481a0000 0x400>;
interrupts = <125>;
ti,spi-num-cs = <2>;
ti,hwmods = "spi1";
dmas = <&edma 42 0
&edma 43 0
&edma 44 0
&edma 45 0>;
dma-names = "tx0", "rx0", "tx1", "rx1";
status = "disabled";
};
usb: usb@47400000 {
compatible = "ti,am33xx-usb";
reg = <0x47400000 0x1000>;
ranges;
#address-cells = <1>;
#size-cells = <1>;
ti,hwmods = "usb_otg_hs";
status = "disabled";
usb_ctrl_mod: control@44e10620 {
compatible = "ti,am335x-usb-ctrl-module";
reg = <0x44e10620 0x10
0x44e10648 0x4>;
reg-names = "phy_ctrl", "wakeup";
status = "disabled";
};
usb0_phy: usb-phy@47401300 {
compatible = "ti,am335x-usb-phy";
reg = <0x47401300 0x100>;
reg-names = "phy";
status = "disabled";
ti,ctrl_mod = <&usb_ctrl_mod>;
};
usb0: usb@47401000 {
compatible = "ti,musb-am33xx";
status = "disabled";
reg = <0x47401400 0x400
0x47401000 0x200>;
reg-names = "mc", "control";
interrupts = <18>;
interrupt-names = "mc";
dr_mode = "otg";
mentor,multipoint = <1>;
mentor,num-eps = <16>;
mentor,ram-bits = <12>;
mentor,power = <500>;
phys = <&usb0_phy>;
dmas = <&cppi41dma 0 0 &cppi41dma 1 0
&cppi41dma 2 0 &cppi41dma 3 0
&cppi41dma 4 0 &cppi41dma 5 0
&cppi41dma 6 0 &cppi41dma 7 0
&cppi41dma 8 0 &cppi41dma 9 0
&cppi41dma 10 0 &cppi41dma 11 0
&cppi41dma 12 0 &cppi41dma 13 0
&cppi41dma 14 0 &cppi41dma 0 1
&cppi41dma 1 1 &cppi41dma 2 1
&cppi41dma 3 1 &cppi41dma 4 1
&cppi41dma 5 1 &cppi41dma 6 1
&cppi41dma 7 1 &cppi41dma 8 1
&cppi41dma 9 1 &cppi41dma 10 1
&cppi41dma 11 1 &cppi41dma 12 1
&cppi41dma 13 1 &cppi41dma 14 1>;
dma-names =
"rx1", "rx2", "rx3", "rx4", "rx5", "rx6", "rx7",
"rx8", "rx9", "rx10", "rx11", "rx12", "rx13",
"rx14", "rx15",
"tx1", "tx2", "tx3", "tx4", "tx5", "tx6", "tx7",
"tx8", "tx9", "tx10", "tx11", "tx12", "tx13",
"tx14", "tx15";
};
usb1_phy: usb-phy@47401b00 {
compatible = "ti,am335x-usb-phy";
reg = <0x47401b00 0x100>;
reg-names = "phy";
status = "disabled";
ti,ctrl_mod = <&usb_ctrl_mod>;
};
usb1: usb@47401800 {
compatible = "ti,musb-am33xx";
status = "disabled";
reg = <0x47401c00 0x400
0x47401800 0x200>;
reg-names = "mc", "control";
interrupts = <19>;
interrupt-names = "mc";
dr_mode = "otg";
mentor,multipoint = <1>;
mentor,num-eps = <16>;
mentor,ram-bits = <12>;
mentor,power = <500>;
phys = <&usb1_phy>;
dmas = <&cppi41dma 15 0 &cppi41dma 16 0
&cppi41dma 17 0 &cppi41dma 18 0
&cppi41dma 19 0 &cppi41dma 20 0
&cppi41dma 21 0 &cppi41dma 22 0
&cppi41dma 23 0 &cppi41dma 24 0
&cppi41dma 25 0 &cppi41dma 26 0
&cppi41dma 27 0 &cppi41dma 28 0
&cppi41dma 29 0 &cppi41dma 15 1
&cppi41dma 16 1 &cppi41dma 17 1
&cppi41dma 18 1 &cppi41dma 19 1
&cppi41dma 20 1 &cppi41dma 21 1
&cppi41dma 22 1 &cppi41dma 23 1
&cppi41dma 24 1 &cppi41dma 25 1
&cppi41dma 26 1 &cppi41dma 27 1
&cppi41dma 28 1 &cppi41dma 29 1>;
dma-names =
"rx1", "rx2", "rx3", "rx4", "rx5", "rx6", "rx7",
"rx8", "rx9", "rx10", "rx11", "rx12", "rx13",
"rx14", "rx15",
"tx1", "tx2", "tx3", "tx4", "tx5", "tx6", "tx7",
"tx8", "tx9", "tx10", "tx11", "tx12", "tx13",
"tx14", "tx15";
};
cppi41dma: dma-controller@47402000 {
compatible = "ti,am3359-cppi41";
reg = <0x47400000 0x1000
0x47402000 0x1000
0x47403000 0x1000
0x47404000 0x4000>;
reg-names = "glue", "controller", "scheduler", "queuemgr";
interrupts = <17>;
interrupt-names = "glue";
#dma-cells = <2>;
#dma-channels = <30>;
#dma-requests = <256>;
status = "disabled";
};
};
epwmss0: epwmss@48300000 {
compatible = "ti,am33xx-pwmss";
reg = <0x48300000 0x10>;
ti,hwmods = "epwmss0";
#address-cells = <1>;
#size-cells = <1>;
status = "disabled";
ranges = <0x48300100 0x48300100 0x80 /* ECAP */
0x48300180 0x48300180 0x80 /* EQEP */
0x48300200 0x48300200 0x80>; /* EHRPWM */
ecap0: ecap@48300100 {
compatible = "ti,am3352-ecap",
"ti,am33xx-ecap";
#pwm-cells = <3>;
reg = <0x48300100 0x80>;
clocks = <&l4ls_gclk>;
clock-names = "fck";
interrupts = <31>;
interrupt-names = "ecap0";
status = "disabled";
};
eqep0: eqep@0x48300180 {
compatible = "ti,am33xx-eqep";
reg = <0x48300180 0x80>;
clocks = <&l4ls_gclk>;
clock-names = "fck";
interrupt-parent = <&intc>;
interrupts = <79>;
status = "disabled";
};
ehrpwm0: pwm@48300200 {
compatible = "ti,am3352-ehrpwm",
"ti,am33xx-ehrpwm";
#pwm-cells = <3>;
reg = <0x48300200 0x80>;
clocks = <&ehrpwm0_tbclk>, <&l4ls_gclk>;
clock-names = "tbclk", "fck";
status = "disabled";
};
};
epwmss1: epwmss@48302000 {
compatible = "ti,am33xx-pwmss";
reg = <0x48302000 0x10>;
ti,hwmods = "epwmss1";
#address-cells = <1>;
#size-cells = <1>;
status = "disabled";
ranges = <0x48302100 0x48302100 0x80 /* ECAP */
0x48302180 0x48302180 0x80 /* EQEP */
0x48302200 0x48302200 0x80>; /* EHRPWM */
ecap1: ecap@48302100 {
compatible = "ti,am3352-ecap",
"ti,am33xx-ecap";
#pwm-cells = <3>;
reg = <0x48302100 0x80>;
clocks = <&l4ls_gclk>;
clock-names = "fck";
interrupts = <47>;
interrupt-names = "ecap1";
status = "disabled";
};
eqep1: eqep@0x48302180 {
compatible = "ti,am33xx-eqep";
reg = <0x48302180 0x80>;
clocks = <&l4ls_gclk>;
clock-names = "fck";
interrupt-parent = <&intc>;
interrupts = <88>;
status = "disabled";
};
ehrpwm1: pwm@48302200 {
compatible = "ti,am3352-ehrpwm",
"ti,am33xx-ehrpwm";
#pwm-cells = <3>;
reg = <0x48302200 0x80>;
clocks = <&ehrpwm1_tbclk>, <&l4ls_gclk>;
clock-names = "tbclk", "fck";
status = "disabled";
};
};
epwmss2: epwmss@48304000 {
compatible = "ti,am33xx-pwmss";
reg = <0x48304000 0x10>;
ti,hwmods = "epwmss2";
#address-cells = <1>;
#size-cells = <1>;
status = "disabled";
ranges = <0x48304100 0x48304100 0x80 /* ECAP */
0x48304180 0x48304180 0x80 /* EQEP */
0x48304200 0x48304200 0x80>; /* EHRPWM */
ecap2: ecap@48304100 {
compatible = "ti,am3352-ecap",
"ti,am33xx-ecap";
#pwm-cells = <3>;
reg = <0x48304100 0x80>;
clocks = <&l4ls_gclk>;
clock-names = "fck";
interrupts = <61>;
interrupt-names = "ecap2";
status = "disabled";
};
eqep2: eqep@0x48304180 {
compatible = "ti,am33xx-eqep";
reg = <0x48304180 0x80>;
clocks = <&l4ls_gclk>;
clock-names = "fck";
interrupt-parent = <&intc>;
interrupts = <89>;
status = "disabled";
};
ehrpwm2: pwm@48304200 {
compatible = "ti,am3352-ehrpwm",
"ti,am33xx-ehrpwm";
#pwm-cells = <3>;
reg = <0x48304200 0x80>;
clocks = <&ehrpwm2_tbclk>, <&l4ls_gclk>;
clock-names = "tbclk", "fck";
status = "disabled";
};
};
mac: ethernet@4a100000 {
compatible = "ti,am335x-cpsw","ti,cpsw";
ti,hwmods = "cpgmac0";
clocks = <&cpsw_125mhz_gclk>, <&cpsw_cpts_rft_clk>;
clock-names = "fck", "cpts";
cpdma_channels = <8>;
ale_entries = <1024>;
bd_ram_size = <0x2000>;
mac_control = <0x20>;
slaves = <2>;
active_slave = <0>;
cpts_clock_mult = <0x80000000>;
cpts_clock_shift = <29>;
reg = <0x4a100000 0x800
0x4a101200 0x100>;
#address-cells = <1>;
#size-cells = <1>;
interrupt-parent = <&intc>;
/*
* c0_rx_thresh_pend
* c0_rx_pend
* c0_tx_pend
* c0_misc_pend
*/
interrupts = <40 41 42 43>;
ranges;
syscon = <&scm_conf>;
status = "disabled";
davinci_mdio: mdio@4a101000 {
compatible = "ti,cpsw-mdio","ti,davinci_mdio";
#address-cells = <1>;
#size-cells = <0>;
ti,hwmods = "davinci_mdio";
bus_freq = <1000000>;
reg = <0x4a101000 0x100>;
status = "disabled";
};
cpsw_emac0: slave@4a100200 {
/* Filled in by U-Boot */
mac-address = [ 00 00 00 00 00 00 ];
};
cpsw_emac1: slave@4a100300 {
/* Filled in by U-Boot */
mac-address = [ 00 00 00 00 00 00 ];
};
phy_sel: cpsw-phy-sel@44e10650 {
compatible = "ti,am3352-cpsw-phy-sel";
reg= <0x44e10650 0x4>;
reg-names = "gmii-sel";
};
};
ocmcram: ocmcram@40300000 {
compatible = "mmio-sram";
reg = <0x40300000 0x10000>; /* 64k */
ranges = <0x0 0x40300000 0x10000>;
#address-cells = <1>;
#size-cells = <1>;
pm_sram_code: pm-sram-code@0 {
compatible = "ti,sram";
reg = <0x0 0x1000>;
protect-exec;
};
pm_sram_data: pm-sram-data@1000 {
compatible = "ti,sram";
reg = <0x1000 0x1000>;
pool;
};
};
elm: elm@48080000 {
compatible = "ti,am3352-elm";
reg = <0x48080000 0x2000>;
interrupts = <4>;
ti,hwmods = "elm";
status = "disabled";
};
lcdc: lcdc@4830e000 {
compatible = "ti,am33xx-tilcdc";
reg = <0x4830e000 0x1000>;
interrupt-parent = <&intc>;
interrupts = <36>;
ti,hwmods = "lcdc";
status = "disabled";
};
tscadc: tscadc@44e0d000 {
compatible = "ti,am3359-tscadc";
reg = <0x44e0d000 0x1000>;
interrupt-parent = <&intc>;
interrupts = <16>;
ti,hwmods = "adc_tsc";
status = "disabled";
tsc {
compatible = "ti,am3359-tsc";
};
am335x_adc: adc {
#io-channel-cells = <1>;
compatible = "ti,am3359-adc";
};
};
gpmc: gpmc@50000000 {
compatible = "ti,am3352-gpmc";
ti,hwmods = "gpmc";
ti,no-idle-on-init;
reg = <0x50000000 0x2000>;
interrupts = <100>;
dmas = <&edma 52 0>;
dma-names = "rxtx";
gpmc,num-cs = <7>;
gpmc,num-waitpins = <2>;
#address-cells = <2>;
#size-cells = <1>;
interrupt-controller;
#interrupt-cells = <2>;
gpio-controller;
#gpio-cells = <2>;
status = "disabled";
};
sham: sham@53100000 {
compatible = "ti,omap4-sham";
ti,hwmods = "sham";
reg = <0x53100000 0x200>;
interrupts = <109>;
dmas = <&edma 36 0>;
dma-names = "rx";
};
aes: aes@53500000 {
compatible = "ti,omap4-aes";
ti,hwmods = "aes";
reg = <0x53500000 0xa0>;
interrupts = <103>;
dmas = <&edma 6 0>,
<&edma 5 0>;
dma-names = "tx", "rx";
};
mcasp0: mcasp@48038000 {
compatible = "ti,am33xx-mcasp-audio";
ti,hwmods = "mcasp0";
reg = <0x48038000 0x2000>,
<0x46000000 0x400000>;
reg-names = "mpu", "dat";
interrupts = <80>, <81>;
interrupt-names = "tx", "rx";
status = "disabled";
dmas = <&edma 8 2>,
<&edma 9 2>;
dma-names = "tx", "rx";
};
mcasp1: mcasp@4803C000 {
compatible = "ti,am33xx-mcasp-audio";
ti,hwmods = "mcasp1";
reg = <0x4803C000 0x2000>,
<0x46400000 0x400000>;
reg-names = "mpu", "dat";
interrupts = <82>, <83>;
interrupt-names = "tx", "rx";
status = "disabled";
dmas = <&edma 10 2>,
<&edma 11 2>;
dma-names = "tx", "rx";
};
rng: rng@48310000 {
compatible = "ti,omap4-rng";
ti,hwmods = "rng";
reg = <0x48310000 0x2000>;
interrupts = <111>;
};
};
};
/include/ "am33xx-clocks.dtsi"
[ 0.000000] Booting Linux on physical CPU 0x0
[ 0.000000] Linux version 4.9.6-ti-r17 (root@a6-imx6q-wandboard-2gb) (gcc version 4.9.2 (Debian 4.9.2-10) ) #1 SMP PREEMPT Sat Jan 28 11:37:11 UTC 2017
[ 0.000000] CPU: ARMv7 Processor [413fc082] revision 2 (ARMv7), cr=10c5387d
[ 0.000000] CPU: PIPT / VIPT nonaliasing data cache, VIPT aliasing instruction cache
[ 0.000000] OF: fdt:Machine model: TI AM335x BeagleBone Black
[ 0.000000] cma: Reserved 48 MiB at 0x9c800000
[ 0.000000] Memory policy: Data cache writeback
[ 0.000000] On node 0 totalpages: 130560
[ 0.000000] free_area_init_node: node 0, pgdat c13dd080, node_mem_map df961000
[ 0.000000] Normal zone: 1152 pages used for memmap
[ 0.000000] Normal zone: 0 pages reserved
[ 0.000000] Normal zone: 130560 pages, LIFO batch:31
[ 0.000000] CPU: All CPU(s) started in SVC mode.
[ 0.000000] AM335X ES2.1 (sgx neon)
[ 0.000000] percpu: Embedded 15 pages/cpu @df92d000 s31936 r8192 d21312 u61440
[ 0.000000] pcpu-alloc: s31936 r8192 d21312 u61440 alloc=15*4096
[ 0.000000] pcpu-alloc: [0] 0
[ 0.000000] Built 1 zonelists in Zone order, mobility grouping on. Total pages: 129408
[ 0.000000] Kernel command line: console=tty0 console=ttyO0,115200n8 root=/dev/mmcblk0p2 rootfstype=ext4 rootwait coherent_pool=1M quiet cape_universal=enable
[ 0.000000] PID hash table entries: 2048 (order: 1, 8192 bytes)
[ 0.000000] Dentry cache hash table entries: 65536 (order: 6, 262144 bytes)
[ 0.000000] Inode-cache hash table entries: 32768 (order: 5, 131072 bytes)
[ 0.000000] Memory: 443920K/522240K available (12288K kernel code, 1086K rwdata, 4092K rodata, 1024K init, 736K bss, 29168K reserved, 49152K cma-reserved, 0K highmem)
[ 0.000000] Virtual kernel memory layout:
vector : 0xffff0000 - 0xffff1000 ( 4 kB)
fixmap : 0xffc00000 - 0xfff00000 (3072 kB)
vmalloc : 0xe0800000 - 0xff800000 ( 496 MB)
lowmem : 0xc0000000 - 0xe0000000 ( 512 MB)
pkmap : 0xbfe00000 - 0xc0000000 ( 2 MB)
modules : 0xbf000000 - 0xbfe00000 ( 14 MB)
.text : 0xc0008000 - 0xc0d00000 (13280 kB)
.init : 0xc1200000 - 0xc1300000 (1024 kB)
.data : 0xc1300000 - 0xc140fa80 (1087 kB)
.bss : 0xc1411000 - 0xc14c9138 ( 737 kB)
[ 0.000000] Preemptible hierarchical RCU implementation.
[ 0.000000] Build-time adjustment of leaf fanout to 32.
[ 0.000000] RCU restricting CPUs from NR_CPUS=2 to nr_cpu_ids=1.
[ 0.000000] RCU: Adjusting geometry for rcu_fanout_leaf=32, nr_cpu_ids=1
[ 0.000000] NR_IRQS:16 nr_irqs:16 16
[ 0.000000] IRQ: Found an INTC at 0xfa200000 (revision 5.0) with 128 interrupts
[ 0.000000] OMAP clockevent source: timer2 at 24000000 Hz
[ 0.000016] sched_clock: 32 bits at 24MHz, resolution 41ns, wraps every 89478484971ns
[ 0.000032] clocksource: timer1: mask: 0xffffffff max_cycles: 0xffffffff, max_idle_ns: 79635851949 ns
[ 0.000042] OMAP clocksource: timer1 at 24000000 Hz
[ 0.001186] clocksource_probe: no matching clocksources found
[ 0.001673] Console: colour dummy device 80x30
[ 0.001728] console [tty0] enabled
[ 0.001751] WARNING: Your 'console=ttyO0' has been replaced by 'ttyS0'
[ 0.001756] This ensures that you still see kernel messages. Please
[ 0.001760] update your kernel commandline.
[ 0.001781] Calibrating delay loop... 995.32 BogoMIPS (lpj=1990656)
[ 0.046785] pid_max: default: 32768 minimum: 301
[ 0.047081] Security Framework initialized
[ 0.047092] Yama: becoming mindful.
[ 0.047131] AppArmor: AppArmor disabled by boot time parameter
[ 0.047346] Mount-cache hash table entries: 1024 (order: 0, 4096 bytes)
[ 0.047356] Mountpoint-cache hash table entries: 1024 (order: 0, 4096 bytes)
[ 0.048556] CPU: Testing write buffer coherency: ok
[ 0.048627] ftrace: allocating 37044 entries in 109 pages
[ 0.153760] CPU0: thread -1, cpu 0, socket -1, mpidr 0
[ 0.153824] Setting up static identity map for 0x80100000 - 0x80100060
[ 0.198808] Brought up 1 CPUs
[ 0.198826] SMP: Total of 1 processors activated (995.32 BogoMIPS).
[ 0.198832] CPU: All CPU(s) started in SVC mode.
[ 0.200443] devtmpfs: initialized
[ 0.219185] VFP support v0.3: implementor 41 architecture 3 part 30 variant c rev 3
[ 0.219725] clocksource: jiffies: mask: 0xffffffff max_cycles: 0xffffffff, max_idle_ns: 7645041785100000 ns
[ 0.223527] xor: measuring software checksum speed
[ 0.262839] arm4regs : 1217.000 MB/sec
[ 0.302771] 8regs : 1090.000 MB/sec
[ 0.342773] 32regs : 1088.000 MB/sec
[ 0.382773] neon : 1666.000 MB/sec
[ 0.382780] xor: using function: neon (1666.000 MB/sec)
[ 0.382798] pinctrl core: initialized pinctrl subsystem
[ 0.384832] NET: Registered protocol family 16
[ 0.388617] DMA: preallocated 1024 KiB pool for atomic coherent allocations
[ 0.413968] omap_hwmod: debugss: _wait_target_disable failed
[ 0.466822] cpuidle: using governor ladder
[ 0.478800] cpuidle: using governor menu
[ 0.487237] OMAP GPIO hardware version 0.1
[ 0.488074] GPIO line 52 (EMMC ResetN) hogged as output/high
[ 0.505213] No ATAGs?
[ 0.505236] hw-breakpoint: debug architecture 0x4 unsupported.
[ 0.505496] omap4_sram_init:Unable to allocate sram needed to handle errata I688
[ 0.505506] omap4_sram_init:Unable to get sram pool needed to handle errata I688
[ 0.614981] raid6: int32x1 gen() 233 MB/s
[ 0.682837] raid6: int32x1 xor() 176 MB/s
[ 0.750850] raid6: int32x2 gen() 303 MB/s
[ 0.818795] raid6: int32x2 xor() 198 MB/s
[ 0.886950] raid6: int32x4 gen() 283 MB/s
[ 0.954850] raid6: int32x4 xor() 202 MB/s
[ 1.022908] raid6: int32x8 gen() 286 MB/s
[ 1.090769] random: fast init done
[ 1.090802] raid6: int32x8 xor() 186 MB/s
[ 1.158798] raid6: neonx1 gen() 1460 MB/s
[ 1.226785] raid6: neonx1 xor() 843 MB/s
[ 1.294777] raid6: neonx2 gen() 1887 MB/s
[ 1.362770] raid6: neonx2 xor() 1169 MB/s
[ 1.430779] raid6: neonx4 gen() 1919 MB/s
[ 1.498772] raid6: neonx4 xor() 1198 MB/s
[ 1.566801] raid6: neonx8 gen() 1185 MB/s
[ 1.634778] raid6: neonx8 xor() 836 MB/s
[ 1.634785] raid6: using algorithm neonx4 gen() 1919 MB/s
[ 1.634790] raid6: .... xor() 1198 MB/s, rmw enabled
[ 1.634796] raid6: using intx1 recovery algorithm
[ 1.644709] edma 49000000.edma: TI EDMA DMA engine driver
[ 1.648892] SCSI subsystem initialized
[ 1.650957] libata version 3.00 loaded.
[ 1.651337] usbcore: registered new interface driver usbfs
[ 1.651411] usbcore: registered new interface driver hub
[ 1.651531] usbcore: registered new device driver usb
[ 1.652111] omap_i2c 44e0b000.i2c: could not find pctldev for node /ocp/l4_wkup@44c00000/scm@210000/pinmux@800/pinmux_i2c0_pins, deferring probe
[ 1.652162] omap_i2c 4819c000.i2c: could not find pctldev for node /ocp/l4_wkup@44c00000/scm@210000/pinmux@800/pinmux_i2c2_pins, deferring probe
[ 1.652263] media: Linux media interface: v0.10
[ 1.652334] Linux video capture interface: v2.00
[ 1.652419] pps_core: LinuxPPS API ver. 1 registered
[ 1.652424] pps_core: Software ver. 5.3.6 - Copyright 2005-2007 Rodolfo Giometti <giometti@linux.it>
[ 1.652447] PTP clock support registered
[ 1.653032] omap-mailbox 480c8000.mailbox: omap mailbox rev 0x400
[ 1.654507] NetLabel: Initializing
[ 1.654519] NetLabel: domain hash size = 128
[ 1.654523] NetLabel: protocols = UNLABELED CIPSOv4
[ 1.654613] NetLabel: unlabeled traffic allowed by default
[ 1.655391] clocksource: Switched to clocksource timer1
[ 1.782966] VFS: Disk quotas dquot_6.6.0
[ 1.783075] VFS: Dquot-cache hash table entries: 1024 (order 0, 4096 bytes)
[ 1.798173] NET: Registered protocol family 2
[ 1.799220] TCP established hash table entries: 4096 (order: 2, 16384 bytes)
[ 1.799264] TCP bind hash table entries: 4096 (order: 3, 32768 bytes)
[ 1.799322] TCP: Hash tables configured (established 4096 bind 4096)
[ 1.799518] UDP hash table entries: 256 (order: 1, 8192 bytes)
[ 1.799538] UDP-Lite hash table entries: 256 (order: 1, 8192 bytes)
[ 1.799770] NET: Registered protocol family 1
[ 1.808703] RPC: Registered named UNIX socket transport module.
[ 1.808711] RPC: Registered udp transport module.
[ 1.808716] RPC: Registered tcp transport module.
[ 1.808720] RPC: Registered tcp NFSv4.1 backchannel transport module.
[ 1.809395] Unpacking initramfs...
[ 2.085255] Freeing initrd memory: 3504K (c8080000 - c83ec000)
[ 2.085817] hw perfevents: enabled with armv7_cortex_a8 PMU driver, 5 counters available
[ 2.088708] futex hash table entries: 256 (order: 2, 16384 bytes)
[ 2.088827] audit: initializing netlink subsys (disabled)
[ 2.088923] audit: type=2000 audit(2.020:1): initialized
[ 2.094439] workingset: timestamp_bits=14 max_order=17 bucket_order=3
[ 2.094632] zbud: loaded
[ 2.099951] NFS: Registering the id_resolver key type
[ 2.099993] Key type id_resolver registered
[ 2.099999] Key type id_legacy registered
[ 2.100016] nfs4filelayout_init: NFSv4 File Layout Driver Registering...
[ 2.100437] fuse init (API version 7.26)
[ 2.100869] orangefs_debugfs_init: called with debug mask: :none: :0:
[ 2.101145] orangefs_init: module version upstream loaded
[ 2.101152] SGI XFS with ACLs, security attributes, realtime, no debug enabled
[ 2.121115] Key type asymmetric registered
[ 2.121129] Asymmetric key parser 'x509' registered
[ 2.121265] Block layer SCSI generic (bsg) driver version 0.4 loaded (major 247)
[ 2.125591] io scheduler noop registered
[ 2.125601] io scheduler deadline registered
[ 2.125701] io scheduler cfq registered (default)
[ 2.126800] pinctrl-single 44e10800.pinmux: please update dts to use #pinctrl-cells = <1>
[ 2.127272] pinctrl-single 44e10800.pinmux: 142 pins at pa f9e10800 size 568
[ 2.130181] wkup_m3_ipc 44e11324.wkup_m3_ipc: could not get rproc handle
[ 2.131560] Serial: 8250/16550 driver, 6 ports, IRQ sharing disabled
[ 2.134898] 44e09000.serial: ttyS0 at MMIO 0x44e09000 (irq = 158, base_baud = 3000000) is a 8250
[ 2.147902] console [ttyS0] enabled
[ 2.149412] [drm] Initialized
[ 2.153429] libphy: Fixed MDIO Bus: probed
[ 2.207413] davinci_mdio 4a101000.mdio: davinci mdio revision 1.6
[ 2.207428] davinci_mdio 4a101000.mdio: detected phy mask fffffffe
[ 2.207802] davinci_mdio: dt: updated phy_id[0] from phy_mask[fffffffe]
[ 2.219630] libphy: 4a101000.mdio: probed
[ 2.219658] davinci_mdio 4a101000.mdio: phy[0]: device 4a101000.mdio:00, driver SMSC LAN8710/LAN8720
[ 2.220581] cpsw 4a100000.ethernet: Detected MACID = 1c:ba:8c:9b:be:b4
[ 2.220755] cpsw 4a100000.ethernet: cpts: overflow check period 1250 (jiffies)
[ 2.223274] ehci_hcd: USB 2.0 'Enhanced' Host Controller (EHCI) Driver
[ 2.223334] ehci-platform: EHCI generic platform driver
[ 2.223818] ehci-omap: OMAP-EHCI Host Controller driver
[ 2.224310] usbcore: registered new interface driver usb-storage
[ 2.226682] 47401300.usb-phy supply vcc not found, using dummy regulator
[ 2.241010] 47401b00.usb-phy supply vcc not found, using dummy regulator
[ 2.255014] musb-hdrc musb-hdrc.1.auto: MUSB HDRC host driver
[ 2.255056] musb-hdrc musb-hdrc.1.auto: new USB bus registered, assigned bus number 1
[ 2.255509] usb usb1: New USB device found, idVendor=1d6b, idProduct=0002
[ 2.255521] usb usb1: New USB device strings: Mfr=3, Product=2, SerialNumber=1
[ 2.255529] usb usb1: Product: MUSB HDRC host driver
[ 2.255537] usb usb1: Manufacturer: Linux 4.9.6-ti-r17 musb-hcd
[ 2.255544] usb usb1: SerialNumber: musb-hdrc.1.auto
[ 2.256567] hub 1-0:1.0: USB hub found
[ 2.256638] hub 1-0:1.0: 1 port detected
[ 2.277597] mousedev: PS/2 mouse device common for all mice
[ 2.279135] omap_rtc 44e3e000.rtc: already running
[ 2.279792] omap_rtc 44e3e000.rtc: rtc core: registered 44e3e000.rtc as rtc0
[ 2.280783] i2c /dev entries driver
[ 2.282463] omap_wdt: OMAP Watchdog Timer Rev 0x01: initial timeout 60 sec
[ 2.283977] cpuidle: enable-method property 'ti,am3352' found operations
[ 2.284939] omap_hsmmc 48060000.mmc: Got CD GPIO
[ 2.328687] ledtrig-cpu: registered to indicate activity on CPUs
[ 2.328808] hidraw: raw HID events driver (C) Jiri Kosina
[ 2.329522] usbcore: registered new interface driver usbhid
[ 2.329528] usbhid: USB HID core driver
[ 2.329852] ashmem: initialized
[ 2.330694] remoteproc remoteproc0: wkup_m3 is available
[ 2.333292] NET: Registered protocol family 10
[ 2.342101] mip6: Mobile IPv6
[ 2.342124] NET: Registered protocol family 17
[ 2.342252] Key type dns_resolver registered
[ 2.342259] mpls_gso: MPLS GSO support
[ 2.342558] omap_voltage_late_init: Voltage driver support not added
[ 2.349694] PM: Cannot get wkup_m3_ipc handle
[ 2.354340] ThumbEE CPU extension supported.
[ 2.354366] Registering SWP/SWPB emulation handler
[ 2.355577] registered taskstats version 1
[ 2.355707] zswap: loaded using pool lzo/zbud
[ 2.361860] Btrfs loaded, crc32c=crc32c-generic
[ 2.387901] Key type encrypted registered
[ 2.406847] mmc0: host does not support reading read-only switch, assuming write-enable
[ 2.410579] mmc0: new high speed SDHC card at address aaaa
[ 2.415806] mmcblk0: mmc0:aaaa SU16G 14.8 GiB
[ 2.417753] mmcblk0: p1 p2
[ 2.432807] input: tps65217_pwr_but as /devices/platform/ocp/44e0b000.i2c/i2c-0/0-0024/tps65217-pwrbutton/input/input0
[ 2.433376] tps65217 0-0024: TPS65217 ID 0xe version 1.2
[ 2.433909] at24 0-0050: 32768 byte 24c256 EEPROM, writable, 1 bytes/write
[ 2.433963] omap_i2c 44e0b000.i2c: bus 0 rev0.11 at 400 kHz
[ 2.435940] at24 2-0054: 32768 byte 24c256 EEPROM, writable, 1 bytes/write
[ 2.436352] at24 2-0055: 32768 byte 24c256 EEPROM, writable, 1 bytes/write
[ 2.436718] at24 2-0056: 32768 byte 24c256 EEPROM, writable, 1 bytes/write
[ 2.437079] at24 2-0057: 32768 byte 24c256 EEPROM, writable, 1 bytes/write
[ 2.437121] omap_i2c 4819c000.i2c: bus 2 rev0.11 at 100 kHz
[ 2.438528] remoteproc remoteproc0: powering up wkup_m3
[ 2.438552] remoteproc remoteproc0: Booting fw image am335x-pm-firmware.elf, size 217148
[ 2.438803] remoteproc remoteproc0: remote processor wkup_m3 is now up
[ 2.438824] wkup_m3_ipc 44e11324.wkup_m3_ipc: CM3 Firmware Version = 0x192
[ 2.444530] bone_capemgr bone_capemgr: Baseboard: 'A335BNLT,000C,3014BBBK1316'
[ 2.444560] bone_capemgr bone_capemgr: compatible-baseboard=ti,beaglebone-black - #slots=4
[ 2.472449] bone_capemgr bone_capemgr: slot #0: No cape found
[ 2.503510] bone_capemgr bone_capemgr: slot #1: No cape found
[ 2.536190] bone_capemgr bone_capemgr: slot #2: No cape found
[ 2.568917] bone_capemgr bone_capemgr: slot #3: No cape found
[ 2.574810] bone_capemgr bone_capemgr: initialized OK.
[ 2.577315] PM: bootloader does not support rtc-only!
[ 2.578324] omap_rtc 44e3e000.rtc: setting system clock to 2017-01-30 18:48:39 UTC (1485802119)
[ 2.578336] of_cfs_init
[ 2.578488] of_cfs_init: OK
[ 2.579006] PM: Hibernation image not present or could not be loaded.
[ 2.581252] Freeing unused kernel memory: 1024K (c1200000 - c1300000)
[ 2.656384] systemd-udevd[104]: starting version 215
[ 3.677268] EXT4-fs (mmcblk0p2): mounted filesystem with ordered data mode. Opts: (null)
[ 4.491131] systemd[1]: Configuration file /lib/systemd/system/bonescript.socket is marked world-inaccessible. This has no effect as configuration data is accessible via APIs without restrictions. Proceeding anyway.
[ 4.493114] systemd[1]: Configuration file /lib/systemd/system/bonescript.service is marked world-inaccessible. This has no effect as configuration data is accessible via APIs without restrictions. Proceeding anyway.
[ 4.544538] systemd[1]: Configuration file /etc/systemd/system/serial-getty@ttyGS0.service is marked world-inaccessible. This has no effect as configuration data is accessible via APIs without restrictions. Proceeding anyway.
[ 4.554156] systemd[1]: Configuration file /lib/systemd/system/capemgr.service is marked world-inaccessible. This has no effect as configuration data is accessible via APIs without restrictions. Proceeding anyway.
[ 4.555988] systemd[1]: Configuration file /lib/systemd/system/bonescript-autorun.service is marked world-inaccessible. This has no effect as configuration data is accessible via APIs without restrictions. Proceeding anyway.
[ 4.560815] systemd[1]: Configuration file /lib/systemd/system/jekyll-autorun.service is marked world-inaccessible. This has no effect as configuration data is accessible via APIs without restrictions. Proceeding anyway.
[ 4.588142] systemd[1]: Cannot add dependency job for unit display-manager.service, ignoring: Unit display-manager.service failed to load: No such file or directory.
[ 5.438064] EXT4-fs (mmcblk0p2): re-mounted. Opts: errors=remount-ro
[ 5.667092] systemd-udevd[186]: starting version 215
[ 10.228836] net eth0: initializing cpsw version 1.12 (0)
[ 10.228858] net eth0: initialized cpsw ale version 1.4
[ 10.228867] net eth0: ALE Table size 1024
[ 10.290226] systemd-journald[179]: Received request to flush runtime journal from PID 1
[ 10.316196] SMSC LAN8710/LAN8720 4a101000.mdio:00: attached PHY driver [SMSC LAN8710/LAN8720] (mii_bus:phy_addr=4a101000.mdio:00, irq=-1)
[ 10.342260] IPv6: ADDRCONF(NETDEV_UP): eth0: link is not ready
[ 10.936806] omap_rng 48310000.rng: OMAP Random Number Generator ver. 20
[ 12.061958] using random self ethernet address
[ 12.061978] using random host ethernet address
[ 12.356328] cpsw 4a100000.ethernet eth0: Link is Up - 100Mbps/Full - flow control rx/tx
[ 12.357109] IPv6: ADDRCONF(NETDEV_CHANGE): eth0: link becomes ready
[ 12.363335] usb0: HOST MAC 1c:ba:8c:9b:be:b5
[ 12.365172] usb0: MAC 1c:ba:8c:9b:be:b6
[ 12.508392] 8021q: 802.1Q VLAN Support v1.8
[ 12.508465] 8021q: adding VLAN 0 to HW filter on device eth0
[ 13.046752] omap-sham 53100000.sham: hw accel on OMAP rev 4.3
[ 13.491645] omap-aes 53500000.aes: OMAP AES hw accel rev: 3.2
[ 13.503678] omap-aes 53500000.aes: will run requests pump with realtime priority
[ 13.655754] IPv6: ADDRCONF(NETDEV_UP): usb0: link is not ready
[ 16.701296] bone_capemgr bone_capemgr: part_number 'univ-all', version 'N/A'
[ 16.701328] bone_capemgr bone_capemgr: slot #4: override
[ 16.723615] bone_capemgr bone_capemgr: Using override eeprom data at slot 4
[ 16.723635] bone_capemgr bone_capemgr: slot #4: 'Override Board Name,00A0,Override Manuf,univ-all'
[ 17.918093] gpio-of-helper ocp:cape-universal: ready
[ 17.939822] 48022000.serial: ttyS1 at MMIO 0x48022000 (irq = 185, base_baud = 3000000) is a 8250
[ 17.953959] 48024000.serial: ttyS2 at MMIO 0x48024000 (irq = 186, base_baud = 3000000) is a 8250
[ 17.966126] 481a8000.serial: ttyS4 at MMIO 0x481a8000 (irq = 187, base_baud = 3000000) is a 8250
[ 17.981689] 481aa000.serial: ttyS5 at MMIO 0x481aa000 (irq = 188, base_baud = 3000000) is a 8250
[ 18.047749] omap_i2c 4802a000.i2c: bus 1 rev0.11 at 100 kHz
[ 18.073872] bone_capemgr bone_capemgr: slot #4: dtbo 'univ-all-00A0.dtbo' loaded; overlay id #0
[ 19.797690] eqep 48300180.eqep: ver. 1.0
[ 19.797902] eqep 48300180.eqep: count_mode:0
[ 19.797913] eqep 48300180.eqep: invert_qa:1
[ 19.797922] eqep 48300180.eqep: invert_qb:1
[ 19.797931] eqep 48300180.eqep: invert_qi:0
[ 19.797940] eqep 48300180.eqep: invert_qs:0
[ 19.797948] eqep 48300180.eqep: swap_inputs:0
[ 19.797958] eqep 48300180.eqep: QDECCTL:0x0180
[ 19.797965] eqep 48300180.eqep: QPOSINIT:0x00000000
[ 19.797973] eqep 48300180.eqep: QPOSMAX:0xffffffff
[ 19.797980] eqep 48300180.eqep: QPOSCNT:0x00000000
[ 19.797988] eqep 48300180.eqep: omit_interrupt:0
[ 19.797996] eqep 48300180.eqep: QEINT:0x0800
[ 19.798003] eqep 48300180.eqep: QUPRD:0x05f5e100
[ 19.798011] eqep 48300180.eqep: QEPCTL:0x009e write
[ 19.798018] eqep 48300180.eqep: QEPCTL:0x009e read
[ 19.798045] eqep 48300180.eqep: irq:190, clk_rate:100000000
[ 19.860142] eqep 48302180.eqep: ver. 1.0
[ 19.860397] eqep 48302180.eqep: count_mode:0
[ 19.860409] eqep 48302180.eqep: invert_qa:1
[ 19.860418] eqep 48302180.eqep: invert_qb:1
[ 19.860427] eqep 48302180.eqep: invert_qi:0
[ 19.860436] eqep 48302180.eqep: invert_qs:0
[ 19.860444] eqep 48302180.eqep: swap_inputs:0
[ 19.860454] eqep 48302180.eqep: QDECCTL:0x0180
[ 19.860462] eqep 48302180.eqep: QPOSINIT:0x00000000
[ 19.860470] eqep 48302180.eqep: QPOSMAX:0xffffffff
[ 19.860477] eqep 48302180.eqep: QPOSCNT:0x00000000
[ 19.860485] eqep 48302180.eqep: omit_interrupt:0
[ 19.860492] eqep 48302180.eqep: QEINT:0x0800
[ 19.860500] eqep 48302180.eqep: QUPRD:0x05f5e100
[ 19.860507] eqep 48302180.eqep: QEPCTL:0x009e write
[ 19.860514] eqep 48302180.eqep: QEPCTL:0x009e read
[ 19.860540] eqep 48302180.eqep: irq:191, clk_rate:100000000
[ 19.920051] eqep 48304180.eqep: ver. 1.0
[ 19.920277] eqep 48304180.eqep: count_mode:0
[ 19.920288] eqep 48304180.eqep: invert_qa:1
[ 19.920297] eqep 48304180.eqep: invert_qb:1
[ 19.920306] eqep 48304180.eqep: invert_qi:0
[ 19.920315] eqep 48304180.eqep: invert_qs:0
[ 19.920324] eqep 48304180.eqep: swap_inputs:0
[ 19.920333] eqep 48304180.eqep: QDECCTL:0x0180
[ 19.920341] eqep 48304180.eqep: QPOSINIT:0x00000000
[ 19.920348] eqep 48304180.eqep: QPOSMAX:0xffffffff
[ 19.920356] eqep 48304180.eqep: QPOSCNT:0x00000000
[ 19.920364] eqep 48304180.eqep: omit_interrupt:0
[ 19.920371] eqep 48304180.eqep: QEINT:0x0800
[ 19.920379] eqep 48304180.eqep: QUPRD:0x05f5e100
[ 19.920386] eqep 48304180.eqep: QEPCTL:0x009e write
[ 19.920394] eqep 48304180.eqep: QEPCTL:0x009e read
[ 19.920420] eqep 48304180.eqep: irq:193, clk_rate:100000000
[ 20.102532] CAN device driver interface
[ 20.232192] c_can_platform 481cc000.can: c_can_platform device registered (regs=fa1cc000, irq=197)
[ 20.232538] pruss_uio 4a300000.pruss: pins are not configured from the driver
[ 20.294368] c_can_platform 481d0000.can: c_can_platform device registered (regs=fa1d0000, irq=198)
[ 40.880784] random: crng init done
root@beaglebone:~# cat /sys/devices/platform/ocp/48304000.epwmss/48304180.eqep/position
[ 615.400669] Unhandled fault: external abort on non-linefetch (0x1028) at 0xfa304180
[ 615.408497] pgd = dc470000
[ 615.411260] [fa304180] *pgd=48211452(bad)
[ 615.415402] Internal error: : 1028 [#1] PREEMPT SMP ARM
[ 615.420707] Modules linked in: spidev uio_pruss c_can_platform c_can can_dev spi_omap2_mcspi pwm_tiecap tieqep pwm_tiehrpwm omap_aes_driver crypto_engine omap_sham 8021q garp mrp stp llc usb_f_acm u_serial usb_f_rndis u_ether libcomposite cpufreq_powersave cpufreq_userspace omap_rng cpufreq_conservative rng_core cpufreq_ondemand evdev tps65217_charger uio_pdrv_genirq uio
[ 615.454633] CPU: 0 PID: 734 Comm: cat Not tainted 4.9.6-ti-r17 #1
[ 615.460813] Hardware name: Generic AM33XX (Flattened Device Tree)
[ 615.466995] task: dc17a700 task.stack: dc192000
[ 615.471643] PC is at eqep_get_position+0x68/0x90 [tieqep]
[ 615.477147] LR is at dev_attr_show+0x2c/0x58
[ 615.481493] pc : [<bf0e3310>] lr : [<c0893f1c>] psr: 600f0013
sp : dc193e30 ip : 00000000 fp : dc193e44
[ 615.493113] r10: 00000001 r9 : dc776f80 r8 : da8d5c18
[ 615.498470] r7 : dc77f000 r6 : c0d855b4 r5 : dc77f000 r4 : dc430900
[ 615.505122] r3 : fa304180 r2 : dc77f000 r1 : bf0e452c r0 : da8d5c10
[ 615.511777] Flags: nZCv IRQs on FIQs on Mode SVC_32 ISA ARM Segment none
[ 615.519045] Control: 10c5387d Table: 9c470019 DAC: 00000051
[ 615.524907] Process cat (pid: 734, stack limit = 0xdc192218)
[ 615.530682] Stack: (0xdc193e30 to 0xdc194000)
[ 615.535151] 3e20: dc430900 bf0e452c dc193e5c dc193e48
[ 615.543520] 3e40: c0893f1c bf0e32b4 dc430900 00001000 dc193e84 dc193e60 c035ffa4 c0893efc
[ 615.551886] 3e60: dc430900 00000000 da814540 c130414c dc193f70 00000001 dc193e94 dc193e88
[ 615.560252] 3e80: c035e954 c035ff18 dc193ef4 dc193e98 c03013dc c035e92c da6f22e0 dc193f70
[ 615.568618] 3ea0: dc430930 b6ea1000 dc193eb0 00020000 00000000 00000000 00020000 da814548
[ 615.576984] 3ec0: 00000004 00040906 00000000 00020000 da814540 b6ea1000 dc193f70 b6ea1000
[ 615.585350] 3ee0: dc776f80 00000000 dc193f2c dc193ef8 c035f724 c0301200 dc193f3c dc193f08
[ 615.593715] 3f00: c02d8fac 00020000 da814540 b6ea1000 dc193f70 b6ea1000 dc192000 00000000
[ 615.602081] 3f20: dc193f3c dc193f30 c02d8290 c035f5fc dc193f6c dc193f40 c02d90ec c02d8274
[ 615.610448] 3f40: 000b6ea0 c02fae4c dc193f6c da814540 c130414c da814540 00020000 b6ea1000
[ 615.618815] 3f60: dc193fa4 dc193f70 c02da388 c02d905c 00000000 00000000 00000022 00040906
[ 615.627180] 3f80: 00000000 00020000 00020000 b6ea1000 00000003 c01092c4 00000000 dc193fa8
[ 615.635546] 3fa0: c0109100 c02da330 00020000 00020000 00000003 b6ea1000 00020000 000271c4
[ 615.643912] 3fc0: 00020000 00020000 b6ea1000 00000003 7fffe000 00000000 00000000 00020000
[ 615.652279] 3fe0: 00000000 bea5caa4 00013835 b6f4ac76 400f0030 00000003 7b7b33da 9e96bd2f
[ 615.660717] [<bf0e3310>] (eqep_get_position [tieqep]) from [<c0893f1c>] (dev_attr_show+0x2c/0x58)
[ 615.669821] [<c0893f1c>] (dev_attr_show) from [<c035ffa4>] (sysfs_kf_seq_show+0x98/0x108)
[ 615.678205] [<c035ffa4>] (sysfs_kf_seq_show) from [<c035e954>] (kernfs_seq_show+0x34/0x38)
[ 615.686666] [<c035e954>] (kernfs_seq_show) from [<c03013dc>] (seq_read+0x1e8/0x538)
[ 615.694512] [<c03013dc>] (seq_read) from [<c035f724>] (kernfs_fop_read+0x134/0x1c0)
[ 615.702358] [<c035f724>] (kernfs_fop_read) from [<c02d8290>] (__vfs_read+0x28/0x48)
[ 615.710202] [<c02d8290>] (__vfs_read) from [<c02d90ec>] (vfs_read+0x9c/0x168)
[ 615.717483] [<c02d90ec>] (vfs_read) from [<c02da388>] (SyS_read+0x64/0xcc)
[ 615.724516] [<c02da388>] (SyS_read) from [<c0109100>] (ret_fast_syscall+0x0/0x3c)
[ 615.732188] Code: e1a04003 e320f000 eafffff3 e5933004 (e5934000)
[ 615.738437] ---[ end trace 7936ced3381948b2 ]---
@pdp7
Copy link
Author

pdp7 commented Feb 2, 2017

UPDATE:
Fix merged by Robert C. Nelson:
tieqep: add patch to fix unhandled fault on 4.9 kernel
RobertCNelson/ti-linux-kernel-dev@f89418b

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment