* [PATCH 6/8] hwmon: da9055: Remove use of platform_get_irq_byname()
From: Adam Thomson @ 2014-02-05 17:48 UTC (permalink / raw)
To: Mark Brown, Lee Jones
Cc: devicetree, alsa-devel, Alessandro Zummo, Linus Walleij,
Dmitry Torokhov, linux-kernel, Rob Herring, Guenter Roeck
In-Reply-To: <cover.1391614923.git.Adam.Thomson.Opensource@diasemi.com>
Signed-off-by: Adam Thomson <Adam.Thomson.Opensource@diasemi.com>
---
drivers/hwmon/da9055-hwmon.c | 7 ++-----
1 files changed, 2 insertions(+), 5 deletions(-)
diff --git a/drivers/hwmon/da9055-hwmon.c b/drivers/hwmon/da9055-hwmon.c
index 029ecab..1867682 100644
--- a/drivers/hwmon/da9055-hwmon.c
+++ b/drivers/hwmon/da9055-hwmon.c
@@ -274,11 +274,8 @@ static int da9055_hwmon_probe(struct platform_device *pdev)
platform_set_drvdata(pdev, hwmon);
- hwmon_irq = platform_get_irq_byname(pdev, "HWMON");
- if (hwmon_irq < 0)
- return hwmon_irq;
-
- hwmon_irq = regmap_irq_get_virq(hwmon->da9055->irq_data, hwmon_irq);
+ hwmon_irq = regmap_irq_get_virq(hwmon->da9055->irq_data,
+ DA9055_IRQ_HWMON);
if (hwmon_irq < 0)
return hwmon_irq;
--
1.7.0.4
^ permalink raw reply related
* [PATCH 5/8] onkey: da9055: Remove use of platform_get_irq_byname()
From: Adam Thomson @ 2014-02-05 17:48 UTC (permalink / raw)
To: Mark Brown, Lee Jones
Cc: devicetree, alsa-devel, Alessandro Zummo, Linus Walleij,
Dmitry Torokhov, linux-kernel, Guenter Roeck, Rob Herring
In-Reply-To: <cover.1391614923.git.Adam.Thomson.Opensource@diasemi.com>
Using platform_get_irq_byname() to retrieve the IRQ number
returns the VIRQ number rather than the local IRQ number for
the device. Passing that value then into regmap_irq_get_virq()
causes a failure because the function is expecting the local
IRQ number (e.g. 0, 1, 2, 3, etc). This patch removes use of
platform_get_irq_byname() and uses the local IRQ number instead.
Signed-off-by: Adam Thomson <Adam.Thomson.Opensource@diasemi.com>
---
drivers/input/misc/da9055_onkey.c | 9 +--------
1 files changed, 1 insertions(+), 8 deletions(-)
diff --git a/drivers/input/misc/da9055_onkey.c b/drivers/input/misc/da9055_onkey.c
index 4b11ede..4842c6c 100644
--- a/drivers/input/misc/da9055_onkey.c
+++ b/drivers/input/misc/da9055_onkey.c
@@ -79,13 +79,6 @@ static int da9055_onkey_probe(struct platform_device *pdev)
struct input_dev *input_dev;
int irq, err;
- irq = platform_get_irq_byname(pdev, "ONKEY");
- if (irq < 0) {
- dev_err(&pdev->dev,
- "Failed to get an IRQ for input device, %d\n", irq);
- return -EINVAL;
- }
-
onkey = devm_kzalloc(&pdev->dev, sizeof(*onkey), GFP_KERNEL);
if (!onkey) {
dev_err(&pdev->dev, "Failed to allocate memory\n");
@@ -109,7 +102,7 @@ static int da9055_onkey_probe(struct platform_device *pdev)
INIT_DELAYED_WORK(&onkey->work, da9055_onkey_work);
- irq = regmap_irq_get_virq(da9055->irq_data, irq);
+ irq = regmap_irq_get_virq(da9055->irq_data, DA9055_IRQ_NONKEY);
err = request_threaded_irq(irq, NULL, da9055_onkey_irq,
IRQF_TRIGGER_HIGH | IRQF_ONESHOT,
"ONKEY", onkey);
--
1.7.0.4
^ permalink raw reply related
* [PATCH 7/8] rtc: da9055: Remove use of platform_get_irq_byname()
From: Adam Thomson @ 2014-02-05 17:48 UTC (permalink / raw)
To: Mark Brown, Lee Jones
Cc: devicetree, alsa-devel, Alessandro Zummo, Linus Walleij,
Dmitry Torokhov, linux-kernel, Rob Herring, Guenter Roeck
In-Reply-To: <cover.1391614923.git.Adam.Thomson.Opensource@diasemi.com>
Signed-off-by: Adam Thomson <Adam.Thomson.Opensource@diasemi.com>
---
drivers/rtc/rtc-da9055.c | 3 +--
1 files changed, 1 insertions(+), 2 deletions(-)
diff --git a/drivers/rtc/rtc-da9055.c b/drivers/rtc/rtc-da9055.c
index 48cb2ac..6e06840 100644
--- a/drivers/rtc/rtc-da9055.c
+++ b/drivers/rtc/rtc-da9055.c
@@ -301,8 +301,7 @@ static int da9055_rtc_probe(struct platform_device *pdev)
goto err_rtc;
}
- alm_irq = platform_get_irq_byname(pdev, "ALM");
- alm_irq = regmap_irq_get_virq(rtc->da9055->irq_data, alm_irq);
+ alm_irq = regmap_irq_get_virq(rtc->da9055->irq_data, DA9055_IRQ_ALARM);
ret = devm_request_threaded_irq(&pdev->dev, alm_irq, NULL,
da9055_rtc_alm_irq,
IRQF_TRIGGER_HIGH | IRQF_ONESHOT,
--
1.7.0.4
^ permalink raw reply related
* [PATCH 8/8] mfd: da9055: Remove unused resource structures for mfd cells.
From: Adam Thomson @ 2014-02-05 17:48 UTC (permalink / raw)
To: Mark Brown, Lee Jones
Cc: devicetree, alsa-devel, Alessandro Zummo, Linus Walleij,
Dmitry Torokhov, linux-kernel, Rob Herring, Guenter Roeck
In-Reply-To: <cover.1391614923.git.Adam.Thomson.Opensource@diasemi.com>
Signed-off-by: Adam Thomson <Adam.Thomson.Opensource@diasemi.com>
---
drivers/mfd/da9055-core.c | 46 ---------------------------------------------
1 files changed, 0 insertions(+), 46 deletions(-)
diff --git a/drivers/mfd/da9055-core.c b/drivers/mfd/da9055-core.c
index caf8dcf..5cf8ca6 100644
--- a/drivers/mfd/da9055-core.c
+++ b/drivers/mfd/da9055-core.c
@@ -258,42 +258,6 @@ struct regmap_config da9055_regmap_config = {
};
EXPORT_SYMBOL_GPL(da9055_regmap_config);
-static struct resource da9055_onkey_resource = {
- .name = "ONKEY",
- .start = DA9055_IRQ_NONKEY,
- .end = DA9055_IRQ_NONKEY,
- .flags = IORESOURCE_IRQ,
-};
-
-static struct resource da9055_rtc_resource[] = {
- {
- .name = "ALM",
- .start = DA9055_IRQ_ALARM,
- .end = DA9055_IRQ_ALARM,
- .flags = IORESOURCE_IRQ,
- },
- {
- .name = "TICK",
- .start = DA9055_IRQ_TICK,
- .end = DA9055_IRQ_TICK,
- .flags = IORESOURCE_IRQ,
- },
-};
-
-static struct resource da9055_hwmon_resource = {
- .name = "HWMON",
- .start = DA9055_IRQ_HWMON,
- .end = DA9055_IRQ_HWMON,
- .flags = IORESOURCE_IRQ,
-};
-
-static struct resource da9055_ld05_6_resource = {
- .name = "REGULATOR",
- .start = DA9055_IRQ_REGULATOR,
- .end = DA9055_IRQ_REGULATOR,
- .flags = IORESOURCE_IRQ,
-};
-
static const struct mfd_cell da9055_devs[] = {
{
.of_compatible = "dialog,da9055-gpio",
@@ -333,33 +297,23 @@ static const struct mfd_cell da9055_devs[] = {
.of_compatible = "dialog,da9055-regulator",
.name = "da9055-regulator",
.id = 7,
- .resources = &da9055_ld05_6_resource,
- .num_resources = 1,
},
{
.of_compatible = "dialog,da9055-regulator",
.name = "da9055-regulator",
- .resources = &da9055_ld05_6_resource,
- .num_resources = 1,
.id = 8,
},
{
.of_compatible = "dialog,da9055-onkey",
.name = "da9055-onkey",
- .resources = &da9055_onkey_resource,
- .num_resources = 1,
},
{
.of_compatible = "dialog,da9055-rtc",
.name = "da9055-rtc",
- .resources = da9055_rtc_resource,
- .num_resources = ARRAY_SIZE(da9055_rtc_resource),
},
{
.of_compatible = "dialog,da9055-hwmon",
.name = "da9055-hwmon",
- .resources = &da9055_hwmon_resource,
- .num_resources = 1,
},
{
.of_compatible = "dialog,da9055-watchdog",
--
1.7.0.4
^ permalink raw reply related
* Re: [PATCH 4/8] regulator: da9055: Add DT support
From: Mark Brown @ 2014-02-05 18:36 UTC (permalink / raw)
To: Adam Thomson
Cc: Lee Jones, alsa-devel-K7yf7f+aM1XWsZ/bQMPhNw,
linux-kernel-u79uwXL29TY76Z2rM5mHXA,
devicetree-u79uwXL29TY76Z2rM5mHXA, Rob Herring, Linus Walleij,
Dmitry Torokhov, Alessandro Zummo, Guenter Roeck
In-Reply-To: <6d76ae40cd435eaae0323f3e806515130b06a376.1391614923.git.Adam.Thomson.Opensource-WBD+wuPFNBhBDgjK7y7TUQ@public.gmane.org>
[-- Attachment #1: Type: text/plain, Size: 1277 bytes --]
On Wed, Feb 05, 2014 at 05:48:35PM +0000, Adam Thomson wrote:
> +#ifdef CONFIG_OF
> +#include <linux/of.h>
> +#include <linux/regulator/of_regulator.h>
> +#endif /* CONFIG_OF */
Don't do ifdefs for includes like this, it's not worth it.
> + for_each_child_of_node(nproot, np) {
> + if (!of_node_cmp(np->name,
> + regulator->info->reg_desc.name)) {
> + config->init_data = of_get_regulator_init_data(
> + &pdev->dev, np);
> + config->of_node = np;
> + break;
> + }
> + }
I think you're looking for of_regulator_match() here.
> if (pdata && pdata->regulators)
> config.init_data = pdata->regulators[pdev->id];
> + else {
> + ret = da9055_regulator_dt_init(pdev, regulator, &config);
> + if (ret < 0)
> + return ret;
> + }
Coding style, both sides of the if should have braces if one does.
> /* Only LDO 5 and 6 has got the over current interrupt */
> if (pdev->id == DA9055_ID_LDO5 || pdev->id == DA9055_ID_LDO6) {
> - irq = platform_get_irq_byname(pdev, "REGULATOR");
> - irq = regmap_irq_get_virq(da9055->irq_data, irq);
> + irq = regmap_irq_get_virq(da9055->irq_data,
> + DA9055_IRQ_REGULATOR);
This seems like a bit of a step backwards - what happened in the MFD
(and why didn't it update the users to avoid breaking bisection)?
[-- Attachment #2: Digital signature --]
[-- Type: application/pgp-signature, Size: 836 bytes --]
^ permalink raw reply
* Re: [PATCH 1/8] ASoC: da9055: Fix device registration of PMIC and CODEC devices
From: Mark Brown @ 2014-02-05 18:38 UTC (permalink / raw)
To: Adam Thomson
Cc: Lee Jones, alsa-devel-K7yf7f+aM1XWsZ/bQMPhNw,
linux-kernel-u79uwXL29TY76Z2rM5mHXA,
devicetree-u79uwXL29TY76Z2rM5mHXA, Rob Herring, Linus Walleij,
Dmitry Torokhov, Alessandro Zummo, Guenter Roeck
In-Reply-To: <6a398d176b0b2bf8792d27bd5e2995fd96afb32d.1391614923.git.Adam.Thomson.Opensource-WBD+wuPFNBhBDgjK7y7TUQ@public.gmane.org>
[-- Attachment #1: Type: text/plain, Size: 322 bytes --]
On Wed, Feb 05, 2014 at 05:48:32PM +0000, Adam Thomson wrote:
> Currently the I2C device Ids conflict for the MFD and CODEC so
> cannot be both instantiated on one platform. This patch updates
> the Ids and names to make them unique from each other.
Acked-by: Mark Brown <broonie-QSEj5FYQhm4dnm+yROfE0A@public.gmane.org>
[-- Attachment #2: Digital signature --]
[-- Type: application/pgp-signature, Size: 836 bytes --]
^ permalink raw reply
* Re: [PATCH v3 4/6] ARM: tegra: Add efuse bindings
From: Stephen Warren @ 2014-02-05 18:42 UTC (permalink / raw)
To: Peter De Schrijver
Cc: linux-arm-kernel, linux-tegra, linux-kernel, Rob Herring,
Pawel Moll, Mark Rutland, Ian Campbell, Kumar Gala, Rob Landley,
Thierry Reding, Russell King, devicetree, linux-doc
In-Reply-To: <1390952176-30402-5-git-send-email-pdeschrijver@nvidia.com>
On 01/28/2014 04:36 PM, Peter De Schrijver wrote:
> Add efuse bindings for Tegra20, Tegra30, Tegra114 and Tegra124.
> diff --git a/Documentation/devicetree/bindings/fuse/fuse-tegra.txt b/Documentation/devicetree/bindings/fuse/fuse-tegra.txt
> +- clocks: Should contain a pointer to the fuse clock.
I would prefer to use clock-names, and to follow the same text as all
the other Tegra bindings that are clock clients. In other words:
- clocks: Must contain an entry for each entry in clock-names.
See ../clocks/clock-bindings.txt for details.
- clock-names: Must include the following entries:
- fuse
(this will allow easy future changes to the binding if required)
^ permalink raw reply
* Re: [PATCH v5 2/3] clocksource: keystone: add bindings for keystone timer
From: Ivan Khoronzhuk @ 2014-02-05 18:52 UTC (permalink / raw)
To: Rob Herring
Cc: Santosh Shilimkar, Rob Landley, Russell King - ARM Linux,
Kumar Gala, Rob Herring, Pawel Moll, Mark Rutland, Ian Campbell,
Daniel Lezcano, Thomas Gleixner, devicetree@vger.kernel.org,
linux-doc@vger.kernel.org, linux-arm-kernel@lists.infradead.org,
linux-kernel@vger.kernel.org, Grygorii Strashko
In-Reply-To: <CAL_JsqL6YDcZJa5xziR7dP-bEt1CO4BtL1vsO8Qm+hFwgCiQ1w@mail.gmail.com>
On 02/05/2014 07:41 PM, Rob Herring wrote:
> On Wed, Feb 5, 2014 at 10:18 AM, Ivan Khoronzhuk <ivan.khoronzhuk@ti.com> wrote:
>> On 02/05/2014 04:39 PM, Rob Herring wrote:
>>> On Wed, Feb 5, 2014 at 7:47 AM, Ivan Khoronzhuk <ivan.khoronzhuk@ti.com>
>>> wrote:
>>>> This patch provides bindings for the 64-bit timer in the KeyStone
>>>> architecture devices. The timer can be configured as a general-purpose
>>>> 64-bit
>>>> timer, dual general-purpose 32-bit timers. When configured as dual 32-bit
>>>> timers, each half can operate in conjunction (chain mode) or
>>>> independently
>>>> (unchained mode) of each other.
>>> This is software configurable or h/w design time configurations?
>>>
>>> Rob
>>>
>> This is h/w design time configurations
> Then it seems like the binding should provide for describing those
> differences either with a property or different compatible strings.
>
> Rob
Oh..sorry, seems I didn't catch, this is configurable by software.
These configurations are like modes in which timer can work
and they are not different hardware IPs. It depends on driver in
which mode it should work.
--
Regards,
Ivan Khoronzhuk
^ permalink raw reply
* [PATCH v3 0/6] IIO pulse capture support for TI ECAP
From: Matt Porter @ 2014-02-05 19:01 UTC (permalink / raw)
To: Jonathan Cameron, Grant Likely, Rob Herring, Benoît Cousson,
Tony Lindgren, Pawel Moll, Mark Rutland, Ian Campbell, Kumar Gala,
Thierry Reding
Cc: Linux IIO List, Linux Kernel Mailing List, Devicetree List,
Linux PWM List, Linux OMAP List, Linux ARM Kernel List
Changes since v2:
- Remove various unneeded field initialization
- Call iio_triggered_buffer_cleanup() on remove
Changes since v1:
- Rebased to 3.14-rc1
- Renamed in_pulse_polarity to pulse_polarity
- Added ABI entries for pulse devices and TI ECAP
This series adds support for PWM capture devices within IIO and
adds a TI ECAP IIO driver.
PWM capture devices are supported using a new IIO "pulse" channel type.
The IIO ECAP driver implements interrupt driven triggered buffer capture
only as raw sample reads are not applicable to this hardware.
Initially, the driver supports a single pulse width measurement with
configurable polarity. The ECAP hardware can support measurement of a
complete period and duty cycle but this is not yet implemented.
Matt Porter (6):
iio: add support for pulse width capture devices
iio: pulse: add TI ECAP driver
iio: enable selection and build of pulse drivers
iio: Add ABI docs for pulse capture devices
pwm: enable TI PWMSS if the IIO tiecap driver is selected
ARM: dts: AM33XX: Add ecap interrupt properties
Documentation/ABI/testing/sysfs-bus-iio | 18 +
.../ABI/testing/sysfs-bus-iio-pulse-tiecap | 9 +
arch/arm/boot/dts/am33xx.dtsi | 6 +
drivers/iio/Kconfig | 1 +
drivers/iio/Makefile | 1 +
drivers/iio/industrialio-core.c | 1 +
drivers/iio/pulse/Kconfig | 20 +
drivers/iio/pulse/Makefile | 6 +
drivers/iio/pulse/tiecap.c | 491 +++++++++++++++++++++
drivers/pwm/Kconfig | 2 +-
include/linux/iio/types.h | 1 +
11 files changed, 555 insertions(+), 1 deletion(-)
create mode 100644 Documentation/ABI/testing/sysfs-bus-iio-pulse-tiecap
create mode 100644 drivers/iio/pulse/Kconfig
create mode 100644 drivers/iio/pulse/Makefile
create mode 100644 drivers/iio/pulse/tiecap.c
--
1.8.4
^ permalink raw reply
* [PATCH v3 1/6] iio: add support for pulse width capture devices
From: Matt Porter @ 2014-02-05 19:01 UTC (permalink / raw)
To: Jonathan Cameron, Grant Likely, Rob Herring, Benoît Cousson,
Tony Lindgren, Pawel Moll, Mark Rutland, Ian Campbell, Kumar Gala,
Thierry Reding
Cc: Devicetree List, Linux PWM List, Linux IIO List,
Linux Kernel Mailing List, Linux OMAP List, Linux ARM Kernel List
In-Reply-To: <1391626901-31684-1-git-send-email-mporter@linaro.org>
Add a channel type to support pulse width capture devices.
These devices capture the timing of a PWM signal based on a
configurable trigger
Signed-off-by: Matt Porter <mporter@linaro.org>
---
drivers/iio/industrialio-core.c | 1 +
include/linux/iio/types.h | 1 +
2 files changed, 2 insertions(+)
diff --git a/drivers/iio/industrialio-core.c b/drivers/iio/industrialio-core.c
index acc911a..6ea0cf8 100644
--- a/drivers/iio/industrialio-core.c
+++ b/drivers/iio/industrialio-core.c
@@ -70,6 +70,7 @@ static const char * const iio_chan_type_name_spec[] = {
[IIO_CCT] = "cct",
[IIO_PRESSURE] = "pressure",
[IIO_HUMIDITYRELATIVE] = "humidityrelative",
+ [IIO_PULSE] = "pulse",
};
static const char * const iio_modifier_names[] = {
diff --git a/include/linux/iio/types.h b/include/linux/iio/types.h
index 084d882..4fa8840 100644
--- a/include/linux/iio/types.h
+++ b/include/linux/iio/types.h
@@ -30,6 +30,7 @@ enum iio_chan_type {
IIO_CCT,
IIO_PRESSURE,
IIO_HUMIDITYRELATIVE,
+ IIO_PULSE,
};
enum iio_modifier {
--
1.8.4
^ permalink raw reply related
* [PATCH v3 2/6] iio: pulse: add TI ECAP driver
From: Matt Porter @ 2014-02-05 19:01 UTC (permalink / raw)
To: Jonathan Cameron, Grant Likely, Rob Herring, Benoît Cousson,
Tony Lindgren, Pawel Moll, Mark Rutland, Ian Campbell, Kumar Gala,
Thierry Reding
Cc: Linux IIO List, Linux Kernel Mailing List, Devicetree List,
Linux PWM List, Linux OMAP List, Linux ARM Kernel List
In-Reply-To: <1391626901-31684-1-git-send-email-mporter@linaro.org>
Adds support for capturing PWM signals using the TI ECAP peripheral.
This driver supports triggered buffer capture of pulses on multiple
ECAP instances. In addition, the driver supports configurable polarity
of the signal to be captured.
Signed-off-by: Matt Porter <mporter@linaro.org>
---
drivers/iio/pulse/Kconfig | 20 ++
drivers/iio/pulse/Makefile | 6 +
drivers/iio/pulse/tiecap.c | 491 +++++++++++++++++++++++++++++++++++++++++++++
3 files changed, 517 insertions(+)
create mode 100644 drivers/iio/pulse/Kconfig
create mode 100644 drivers/iio/pulse/Makefile
create mode 100644 drivers/iio/pulse/tiecap.c
diff --git a/drivers/iio/pulse/Kconfig b/drivers/iio/pulse/Kconfig
new file mode 100644
index 0000000..9864d4b
--- /dev/null
+++ b/drivers/iio/pulse/Kconfig
@@ -0,0 +1,20 @@
+#
+# Pulse Capture Devices
+#
+# When adding new entries keep the list in alphabetical order
+
+menu "Pulse Capture Devices"
+
+config IIO_TIECAP
+ tristate "TI ECAP Pulse Capture"
+ depends on SOC_AM33XX
+ select IIO_BUFFER
+ select IIO_TRIGGERED_BUFFER
+ help
+ If you say yes here you get support for the TI ECAP peripheral
+ in pulse capture mode.
+
+ This driver can also be built as a module. If so, the module
+ will be called tiecap
+
+endmenu
diff --git a/drivers/iio/pulse/Makefile b/drivers/iio/pulse/Makefile
new file mode 100644
index 0000000..94d4b00
--- /dev/null
+++ b/drivers/iio/pulse/Makefile
@@ -0,0 +1,6 @@
+#
+# Makefile for IIO PWM Capture Devices
+#
+
+# When adding new entries keep the list in alphabetical order
+obj-$(CONFIG_IIO_TIECAP) += tiecap.o
diff --git a/drivers/iio/pulse/tiecap.c b/drivers/iio/pulse/tiecap.c
new file mode 100644
index 0000000..fd96745
--- /dev/null
+++ b/drivers/iio/pulse/tiecap.c
@@ -0,0 +1,491 @@
+/*
+ * ECAP IIO pulse capture driver
+ *
+ * Copyright (C) 2014 Linaro Limited
+ * Author: Matt Porter <mporter@linaro.org>
+ *
+ * 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.
+ */
+
+#include <linux/clk.h>
+#include <linux/err.h>
+#include <linux/iio/buffer.h>
+#include <linux/iio/iio.h>
+#include <linux/iio/sysfs.h>
+#include <linux/iio/trigger.h>
+#include <linux/iio/trigger_consumer.h>
+#include <linux/iio/triggered_buffer.h>
+#include <linux/io.h>
+#include <linux/interrupt.h>
+#include <linux/irq.h>
+#include <linux/module.h>
+#include <linux/of_device.h>
+#include <linux/platform_device.h>
+#include <linux/pm_runtime.h>
+
+#include "../../pwm/pwm-tipwmss.h"
+
+/* ECAP regs and bits */
+#define CAP1 0x08
+#define CAP2 0x0c
+#define ECCTL1 0x28
+#define ECCTL1_RUN_FREE BIT(15)
+#define ECCTL1_CAPLDEN BIT(8)
+#define ECCTL1_CAP2POL BIT(2)
+#define ECCTL1_CTRRST1 BIT(1)
+#define ECCTL1_CAP1POL BIT(0)
+#define ECCTL2 0x2a
+#define ECCTL2_SYNCO_SEL_DIS BIT(7)
+#define ECCTL2_TSCTR_FREERUN BIT(4)
+#define ECCTL2_REARM BIT(3)
+#define ECCTL2_STOP_WRAP_2 BIT(1)
+#define ECEINT 0x2c
+#define ECFLG 0x2e
+#define ECCLR 0x30
+#define ECINT_CTRCMP BIT(7)
+#define ECINT_CTRPRD BIT(6)
+#define ECINT_CTROVF BIT(5)
+#define ECINT_CEVT4 BIT(4)
+#define ECINT_CEVT3 BIT(3)
+#define ECINT_CEVT2 BIT(2)
+#define ECINT_CEVT1 BIT(1)
+#define ECINT_ALL (ECINT_CTRCMP | \
+ ECINT_CTRPRD | \
+ ECINT_CTROVF | \
+ ECINT_CEVT4 | \
+ ECINT_CEVT3 | \
+ ECINT_CEVT2 | \
+ ECINT_CEVT1)
+
+/* ECAP driver flags */
+#define ECAP_POLARITY_HIGH BIT(1)
+#define ECAP_ENABLED BIT(0)
+
+struct ecap_context {
+ u32 cap1;
+ u32 cap2;
+ u16 ecctl1;
+ u16 ecctl2;
+ u16 eceint;
+};
+
+struct ecap_state {
+ unsigned long flags;
+ unsigned int clk_rate;
+ void __iomem *regs;
+ u32 *buf;
+ struct ecap_context ctx;
+};
+
+#define dev_to_ecap_state(d) iio_priv(dev_to_iio_dev(d))
+
+static const struct iio_chan_spec ecap_channels[] = {
+ {
+ .type = IIO_PULSE,
+ .info_mask_separate =
+ BIT(IIO_CHAN_INFO_RAW) | BIT(IIO_CHAN_INFO_SCALE),
+ .scan_index = 0,
+ .scan_type = {
+ .sign = 'u',
+ .realbits = 32,
+ .storagebits = 32,
+ .endianness = IIO_LE,
+ },
+ },
+ IIO_CHAN_SOFT_TIMESTAMP(1)
+};
+
+static ssize_t ecap_attr_show(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ struct ecap_state *state = dev_to_ecap_state(dev);
+
+ return sprintf(buf, "%d\n",
+ test_bit(ECAP_POLARITY_HIGH, &state->flags));
+}
+
+static ssize_t ecap_attr_store(struct device *dev,
+ struct device_attribute *attr,
+ const char *buf,
+ size_t len)
+{
+ int ret;
+ bool val;
+ struct ecap_state *state = dev_to_ecap_state(dev);
+
+ if (test_bit(ECAP_ENABLED, &state->flags))
+ return -EINVAL;
+
+ ret = strtobool(buf, &val);
+ if (ret)
+ return ret;
+
+ if (val)
+ set_bit(ECAP_POLARITY_HIGH, &state->flags);
+ else
+ clear_bit(ECAP_POLARITY_HIGH, &state->flags);
+
+ return len;
+}
+
+static IIO_DEVICE_ATTR(pulse_polarity, S_IRUGO | S_IWUSR,
+ ecap_attr_show, ecap_attr_store, 0);
+
+static struct attribute *ecap_attributes[] = {
+ &iio_dev_attr_pulse_polarity.dev_attr.attr,
+ NULL,
+};
+
+static struct attribute_group ecap_attribute_group = {
+ .attrs = ecap_attributes,
+};
+
+static int ecap_read_raw(struct iio_dev *idev,
+ struct iio_chan_spec const *ch, int *val,
+ int *val2, long mask)
+{
+ struct ecap_state *state = iio_priv(idev);
+
+ switch (mask) {
+ case IIO_CHAN_INFO_RAW:
+ /*
+ * Always return 0 as a pulse width sample
+ * is only valid in a triggered condition
+ */
+ *val = 0;
+ return IIO_VAL_INT;
+ case IIO_CHAN_INFO_SCALE:
+ *val = 0;
+ *val2 = NSEC_PER_SEC / state->clk_rate;
+ return IIO_VAL_INT_PLUS_NANO;
+ default:
+ return -EINVAL;
+ }
+}
+
+static const struct iio_info ecap_info = {
+ .driver_module = THIS_MODULE,
+ .attrs = &ecap_attribute_group,
+ .read_raw = &ecap_read_raw,
+};
+
+static irqreturn_t ecap_trigger_handler(int irq, void *private)
+{
+ struct iio_poll_func *pf = private;
+ struct iio_dev *idev = pf->indio_dev;
+ struct ecap_state *state = iio_priv(idev);
+
+ /* Read pulse counter value */
+ *state->buf = readl(state->regs + CAP2);
+
+ iio_push_to_buffers_with_timestamp(idev, state->buf, iio_get_time_ns());
+
+ iio_trigger_notify_done(idev->trig);
+
+ return IRQ_HANDLED;
+};
+
+
+static const struct iio_trigger_ops iio_interrupt_trigger_ops = {
+ .owner = THIS_MODULE,
+};
+
+static irqreturn_t ecap_interrupt_handler(int irq, void *private)
+{
+ struct iio_dev *idev = private;
+ struct ecap_state *state = iio_priv(idev);
+ u16 ints;
+
+ iio_trigger_poll(idev->trig, 0);
+
+ /* Clear CAP2 interrupt */
+ ints = readw(state->regs + ECFLG);
+ if (ints & ECINT_CEVT2)
+ writew(ECINT_CEVT2, state->regs + ECCLR);
+ else
+ dev_warn(&idev->dev, "unhandled interrupt flagged: %04x\n",
+ ints);
+
+ return IRQ_HANDLED;
+}
+
+static int ecap_buffer_predisable(struct iio_dev *idev)
+{
+ struct ecap_state *state = iio_priv(idev);
+ int ret = 0;
+ u16 ecctl2;
+
+ /* Stop capture */
+ clear_bit(ECAP_ENABLED, &state->flags);
+ ecctl2 = readw(state->regs + ECCTL2) & ~ECCTL2_TSCTR_FREERUN;
+ writew(ecctl2, state->regs + ECCTL2);
+
+ /* Disable and clear all interrupts */
+ writew(0, state->regs + ECEINT);
+ writew(ECINT_ALL, state->regs + ECCLR);
+
+ ret = iio_triggered_buffer_predisable(idev);
+
+ pm_runtime_put_sync(idev->dev.parent);
+
+ return ret;
+}
+
+static int ecap_buffer_postenable(struct iio_dev *idev)
+{
+ struct ecap_state *state = iio_priv(idev);
+ int ret = 0;
+ u16 ecctl1, ecctl2;
+
+ pm_runtime_get_sync(idev->dev.parent);
+
+ /* Configure pulse polarity */
+ ecctl1 = readw(state->regs + ECCTL1);
+ if (test_bit(ECAP_POLARITY_HIGH, &state->flags)) {
+ /* CAP1 rising, CAP2 falling */
+ ecctl1 |= ECCTL1_CAP2POL;
+ ecctl1 &= ~ECCTL1_CAP1POL;
+ } else {
+ /* CAP1 falling, CAP2 rising */
+ ecctl1 &= ~ECCTL1_CAP2POL;
+ ecctl1 |= ECCTL1_CAP1POL;
+ }
+ writew(ecctl1, state->regs + ECCTL1);
+
+ /* Enable CAP2 interrupt */
+ writew(ECINT_CEVT2, state->regs + ECEINT);
+
+ /* Enable capture */
+ ecctl2 = readw(state->regs + ECCTL2);
+ ecctl2 |= ECCTL2_TSCTR_FREERUN | ECCTL2_REARM;
+ writew(ecctl2, state->regs + ECCTL2);
+ set_bit(ECAP_ENABLED, &state->flags);
+
+ ret = iio_triggered_buffer_postenable(idev);
+
+ return ret;
+}
+
+static const struct iio_buffer_setup_ops ecap_buffer_setup_ops = {
+ .postenable = &ecap_buffer_postenable,
+ .predisable = &ecap_buffer_predisable,
+};
+
+static void ecap_init_hw(struct iio_dev *idev)
+{
+ struct ecap_state *state = iio_priv(idev);
+
+ clear_bit(ECAP_ENABLED, &state->flags);
+ set_bit(ECAP_POLARITY_HIGH, &state->flags);
+
+ writew(ECCTL1_RUN_FREE | ECCTL1_CAPLDEN |
+ ECCTL1_CAP2POL | ECCTL1_CTRRST1,
+ state->regs + ECCTL1);
+
+ writew(ECCTL2_SYNCO_SEL_DIS | ECCTL2_STOP_WRAP_2,
+ state->regs + ECCTL2);
+}
+
+static const struct of_device_id ecap_of_ids[] = {
+ { .compatible = "ti,am33xx-ecap" },
+ { /* sentinel */ },
+};
+MODULE_DEVICE_TABLE(of, ecap_of_ids);
+
+static int ecap_probe(struct platform_device *pdev)
+{
+ int irq, ret;
+ struct iio_dev *idev;
+ struct ecap_state *state;
+ struct resource *r;
+ struct clk *clk;
+ struct iio_trigger *trig;
+ u16 status;
+
+ idev = devm_iio_device_alloc(&pdev->dev, sizeof(struct ecap_state));
+ if (!idev)
+ return -ENOMEM;
+
+ state = iio_priv(idev);
+
+ clk = devm_clk_get(&pdev->dev, "fck");
+ if (IS_ERR(clk)) {
+ dev_err(&pdev->dev, "failed to get clock\n");
+ return PTR_ERR(clk);
+ }
+
+ state->clk_rate = clk_get_rate(clk);
+ if (!state->clk_rate) {
+ dev_err(&pdev->dev, "failed to get clock rate\n");
+ return -EINVAL;
+ }
+
+ platform_set_drvdata(pdev, idev);
+
+ idev->dev.parent = &pdev->dev;
+ idev->name = dev_name(&pdev->dev);
+ idev->modes = INDIO_DIRECT_MODE;
+ idev->info = &ecap_info;
+ idev->channels = ecap_channels;
+ /* One h/w capture and one s/w timestamp channel per instance */
+ idev->num_channels = ARRAY_SIZE(ecap_channels);
+
+ trig = devm_iio_trigger_alloc(&pdev->dev, "%s-dev%d",
+ idev->name, idev->id);
+ if (!trig)
+ return -ENOMEM;
+ trig->dev.parent = idev->dev.parent;
+ iio_trigger_set_drvdata(trig, idev);
+ trig->ops = &iio_interrupt_trigger_ops;
+
+ ret = iio_trigger_register(trig);
+ if (ret) {
+ dev_err(&pdev->dev, "failed to register trigger\n");
+ return ret;
+ }
+
+ ret = iio_triggered_buffer_setup(idev, NULL,
+ &ecap_trigger_handler,
+ &ecap_buffer_setup_ops);
+ if (ret)
+ return ret;
+
+ irq = platform_get_irq(pdev, 0);
+ if (irq < 0) {
+ dev_err(&pdev->dev, "no irq is specified\n");
+ return irq;
+ }
+ ret = devm_request_irq(&pdev->dev, irq,
+ &ecap_interrupt_handler,
+ 0, dev_name(&pdev->dev), idev);
+ if (ret) {
+ dev_err(&pdev->dev, "unable to request irq\n");
+ goto uninit_buffer;
+ }
+
+ r = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+ state->regs = devm_ioremap_resource(&pdev->dev, r);
+ if (IS_ERR(state->regs)) {
+ dev_err(&pdev->dev, "unable to remap registers\n");
+ ret = PTR_ERR(state->regs);
+ goto uninit_buffer;
+ };
+
+ ret = iio_device_register(idev);
+ if (ret < 0) {
+ dev_err(&pdev->dev, "unable to register device\n");
+ goto uninit_buffer;
+ }
+
+ state->buf = devm_kzalloc(&idev->dev, idev->scan_bytes, GFP_KERNEL);
+ if (!state->buf) {
+ ret = -ENOMEM;
+ goto uninit_buffer;
+ }
+
+ pm_runtime_enable(&pdev->dev);
+ pm_runtime_get_sync(&pdev->dev);
+
+ status = pwmss_submodule_state_change(pdev->dev.parent,
+ PWMSS_ECAPCLK_EN);
+ if (!(status & PWMSS_ECAPCLK_EN_ACK)) {
+ dev_err(&pdev->dev, "failed to enable PWMSS config space clock\n");
+ ret = -EINVAL;
+ goto pwmss_clk_failure;
+ }
+
+ ecap_init_hw(idev);
+
+ pm_runtime_put_sync(&pdev->dev);
+
+ return 0;
+
+pwmss_clk_failure:
+ pm_runtime_put_sync(&pdev->dev);
+ pm_runtime_disable(&pdev->dev);
+ iio_device_unregister(idev);
+
+uninit_buffer:
+ iio_triggered_buffer_cleanup(idev);
+
+ return ret;
+}
+
+static int ecap_remove(struct platform_device *pdev)
+{
+ struct iio_dev *idev = platform_get_drvdata(pdev);
+
+ pm_runtime_get_sync(&pdev->dev);
+
+ pwmss_submodule_state_change(pdev->dev.parent, PWMSS_ECAPCLK_STOP_REQ);
+
+ pm_runtime_put_sync(&pdev->dev);
+ pm_runtime_disable(&pdev->dev);
+
+ iio_device_unregister(idev);
+ iio_triggered_buffer_cleanup(idev);
+
+ return 0;
+}
+
+#ifdef CONFIG_PM_SLEEP
+static int ecap_suspend(struct device *dev)
+{
+ struct ecap_state *state = dev_to_ecap_state(dev);
+
+ pm_runtime_get_sync(dev);
+ state->ctx.cap1 = readl(state->regs + CAP1);
+ state->ctx.cap2 = readl(state->regs + CAP2);
+ state->ctx.eceint = readw(state->regs + ECEINT);
+ state->ctx.ecctl1 = readw(state->regs + ECCTL1);
+ state->ctx.ecctl2 = readw(state->regs + ECCTL2);
+ pm_runtime_put_sync(dev);
+
+ /* If capture was active, disable ECAP */
+ if (test_bit(ECAP_ENABLED, &state->flags))
+ pm_runtime_put_sync(dev);
+
+ return 0;
+}
+
+static int ecap_resume(struct device *dev)
+{
+ struct ecap_state *state = dev_to_ecap_state(dev);
+
+ /* If capture was active, enable ECAP */
+ if (test_bit(ECAP_ENABLED, &state->flags))
+ pm_runtime_get_sync(dev);
+
+ pm_runtime_get_sync(dev);
+ writel(state->ctx.cap1, state->regs + CAP1);
+ writel(state->ctx.cap2, state->regs + CAP2);
+ writew(state->ctx.eceint, state->regs + ECEINT);
+ writew(state->ctx.ecctl1, state->regs + ECCTL1);
+ writew(state->ctx.ecctl2, state->regs + ECCTL2);
+ pm_runtime_put_sync(dev);
+
+ return 0;
+}
+#endif
+
+static SIMPLE_DEV_PM_OPS(ecap_pm_ops, ecap_suspend, ecap_resume);
+
+static struct platform_driver ecap_iio_driver = {
+ .driver = {
+ .name = "ecap",
+ .owner = THIS_MODULE,
+ .of_match_table = of_match_ptr(ecap_of_ids),
+ .pm = &ecap_pm_ops,
+ },
+ .probe = ecap_probe,
+ .remove = ecap_remove,
+};
+
+module_platform_driver(ecap_iio_driver);
+
+MODULE_DESCRIPTION("ECAP IIO pulse capture driver");
+MODULE_AUTHOR("Matt Porter <mporter@linaro.org>");
+MODULE_LICENSE("GPL");
--
1.8.4
^ permalink raw reply related
* [PATCH v3 3/6] iio: enable selection and build of pulse drivers
From: Matt Porter @ 2014-02-05 19:01 UTC (permalink / raw)
To: Jonathan Cameron, Grant Likely, Rob Herring, Benoît Cousson,
Tony Lindgren, Pawel Moll, Mark Rutland, Ian Campbell, Kumar Gala,
Thierry Reding
Cc: Linux IIO List, Linux Kernel Mailing List, Devicetree List,
Linux PWM List, Linux OMAP List, Linux ARM Kernel List
In-Reply-To: <1391626901-31684-1-git-send-email-mporter@linaro.org>
Add the pulse driver subdirectory when configuring and building
IIO.
Signed-off-by: Matt Porter <mporter@linaro.org>
---
drivers/iio/Kconfig | 1 +
drivers/iio/Makefile | 1 +
2 files changed, 2 insertions(+)
diff --git a/drivers/iio/Kconfig b/drivers/iio/Kconfig
index 5dd0e12..286acc3 100644
--- a/drivers/iio/Kconfig
+++ b/drivers/iio/Kconfig
@@ -74,6 +74,7 @@ if IIO_TRIGGER
source "drivers/iio/trigger/Kconfig"
endif #IIO_TRIGGER
source "drivers/iio/pressure/Kconfig"
+source "drivers/iio/pulse/Kconfig"
source "drivers/iio/temperature/Kconfig"
endif # IIO
diff --git a/drivers/iio/Makefile b/drivers/iio/Makefile
index 887d390..9a953c9 100644
--- a/drivers/iio/Makefile
+++ b/drivers/iio/Makefile
@@ -24,5 +24,6 @@ obj-y += light/
obj-y += magnetometer/
obj-y += orientation/
obj-y += pressure/
+obj-y += pulse/
obj-y += temperature/
obj-y += trigger/
--
1.8.4
^ permalink raw reply related
* [PATCH v3 4/6] iio: Add ABI docs for pulse capture devices
From: Matt Porter @ 2014-02-05 19:01 UTC (permalink / raw)
To: Jonathan Cameron, Grant Likely, Rob Herring, Benoît Cousson,
Tony Lindgren, Pawel Moll, Mark Rutland, Ian Campbell, Kumar Gala,
Thierry Reding
Cc: Linux IIO List, Linux Kernel Mailing List, Devicetree List,
Linux PWM List, Linux OMAP List, Linux ARM Kernel List
In-Reply-To: <1391626901-31684-1-git-send-email-mporter@linaro.org>
Add standard ABI entries for pulse capture devices. Also add
a separate ABI entry for the TI ECAP driver polarity option.
Signed-off-by: Matt Porter <mporter@linaro.org>
---
Documentation/ABI/testing/sysfs-bus-iio | 18 ++++++++++++++++++
Documentation/ABI/testing/sysfs-bus-iio-pulse-tiecap | 9 +++++++++
2 files changed, 27 insertions(+)
create mode 100644 Documentation/ABI/testing/sysfs-bus-iio-pulse-tiecap
diff --git a/Documentation/ABI/testing/sysfs-bus-iio b/Documentation/ABI/testing/sysfs-bus-iio
index 6e02c50..918a201 100644
--- a/Documentation/ABI/testing/sysfs-bus-iio
+++ b/Documentation/ABI/testing/sysfs-bus-iio
@@ -210,6 +210,14 @@ Contact: linux-iio@vger.kernel.org
Description:
Scaled humidity measurement in milli percent.
+What: /sys/bus/iio/devices/iio:deviceX/in_pulseY_raw
+What: /sys/bus/iio/devices/iio:deviceX/in_pulse_raw
+KernelVersion: 3.15
+Contact: linux-iio@vger.kernel.org
+Description:
+ Raw pulse measurement from channel Y. Units after
+ application of scale and offset are nanoseconds.
+
What: /sys/bus/iio/devices/iio:deviceX/in_accel_offset
What: /sys/bus/iio/devices/iio:deviceX/in_accel_x_offset
What: /sys/bus/iio/devices/iio:deviceX/in_accel_y_offset
@@ -220,6 +228,8 @@ What: /sys/bus/iio/devices/iio:deviceX/in_tempY_offset
What: /sys/bus/iio/devices/iio:deviceX/in_temp_offset
What: /sys/bus/iio/devices/iio:deviceX/in_pressureY_offset
What: /sys/bus/iio/devices/iio:deviceX/in_pressure_offset
+What: /sys/bus/iio/devices/iio:deviceX/in_pulseY_offset
+What: /sys/bus/iio/devices/iio:deviceX/in_pulse_offset
KernelVersion: 2.6.35
Contact: linux-iio@vger.kernel.org
Description:
@@ -251,6 +261,8 @@ What: /sys/bus/iio/devices/iio:deviceX/in_magn_y_scale
What: /sys/bus/iio/devices/iio:deviceX/in_magn_z_scale
What: /sys/bus/iio/devices/iio:deviceX/in_pressureY_scale
What: /sys/bus/iio/devices/iio:deviceX/in_pressure_scale
+What: /sys/bus/iio/devices/iio:deviceX/in_pulseY_scale
+What: /sys/bus/iio/devices/iio:deviceX/in_pulse_scale
KernelVersion: 2.6.35
Contact: linux-iio@vger.kernel.org
Description:
@@ -784,6 +796,8 @@ What: /sys/.../iio:deviceX/scan_elements/in_incli_x_en
What: /sys/.../iio:deviceX/scan_elements/in_incli_y_en
What: /sys/.../iio:deviceX/scan_elements/in_pressureY_en
What: /sys/.../iio:deviceX/scan_elements/in_pressure_en
+What: /sys/.../iio:deviceX/scan_elements/in_pulseY_en
+What: /sys/.../iio:deviceX/scan_elements/in_pulse_en
KernelVersion: 2.6.37
Contact: linux-iio@vger.kernel.org
Description:
@@ -799,6 +813,8 @@ What: /sys/.../iio:deviceX/scan_elements/in_voltageY_supply_type
What: /sys/.../iio:deviceX/scan_elements/in_timestamp_type
What: /sys/.../iio:deviceX/scan_elements/in_pressureY_type
What: /sys/.../iio:deviceX/scan_elements/in_pressure_type
+What: /sys/.../iio:deviceX/scan_elements/in_pulseY_type
+What: /sys/.../iio:deviceX/scan_elements/in_pulse_type
KernelVersion: 2.6.37
Contact: linux-iio@vger.kernel.org
Description:
@@ -845,6 +861,8 @@ What: /sys/.../iio:deviceX/scan_elements/in_incli_y_index
What: /sys/.../iio:deviceX/scan_elements/in_timestamp_index
What: /sys/.../iio:deviceX/scan_elements/in_pressureY_index
What: /sys/.../iio:deviceX/scan_elements/in_pressure_index
+What: /sys/.../iio:deviceX/scan_elements/in_pulseY_index
+What: /sys/.../iio:deviceX/scan_elements/in_pulse_index
KernelVersion: 2.6.37
Contact: linux-iio@vger.kernel.org
Description:
diff --git a/Documentation/ABI/testing/sysfs-bus-iio-pulse-tiecap b/Documentation/ABI/testing/sysfs-bus-iio-pulse-tiecap
new file mode 100644
index 0000000..a9e4a9f
--- /dev/null
+++ b/Documentation/ABI/testing/sysfs-bus-iio-pulse-tiecap
@@ -0,0 +1,9 @@
+What: /sys/bus/iio/devices/iio:deviceX/pulse_polarityY
+What: /sys/bus/iio/devices/iio:deviceX/pulse_polarity
+Date: January 2014
+KernelVersion: 3.15
+Contact: Matt Porter <mporter@linaro.org>
+Description:
+ Get and set the polarity of the pulse signal to be captured
+ for channel Y. 1 indicates a high pulse signal and 0
+ indicates a low pulse signal.
--
1.8.4
^ permalink raw reply related
* [PATCH v3 5/6] pwm: enable TI PWMSS if the IIO tiecap driver is selected
From: Matt Porter @ 2014-02-05 19:01 UTC (permalink / raw)
To: Jonathan Cameron, Grant Likely, Rob Herring, Benoît Cousson,
Tony Lindgren, Pawel Moll, Mark Rutland, Ian Campbell, Kumar Gala,
Thierry Reding
Cc: Linux IIO List, Linux Kernel Mailing List, Devicetree List,
Linux PWM List, Linux OMAP List, Linux ARM Kernel List
In-Reply-To: <1391626901-31684-1-git-send-email-mporter@linaro.org>
The IIO TI ECAP driver depends on the TI PWMSS management
driver in this subsystem. Enable PWMSS when the IIO TI ECAP
driver is selected.
Signed-off-by: Matt Porter <mporter@linaro.org>
---
drivers/pwm/Kconfig | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/pwm/Kconfig b/drivers/pwm/Kconfig
index 22f2f28..bd3cc65 100644
--- a/drivers/pwm/Kconfig
+++ b/drivers/pwm/Kconfig
@@ -219,7 +219,7 @@ config PWM_TIEHRPWM
config PWM_TIPWMSS
bool
- default y if SOC_AM33XX && (PWM_TIECAP || PWM_TIEHRPWM)
+ default y if SOC_AM33XX && (IIO_TIECAP || PWM_TIECAP || PWM_TIEHRPWM)
help
PWM Subsystem driver support for AM33xx SOC.
--
1.8.4
^ permalink raw reply related
* [PATCH v3 6/6] ARM: dts: AM33XX: Add ecap interrupt properties
From: Matt Porter @ 2014-02-05 19:01 UTC (permalink / raw)
To: Jonathan Cameron, Grant Likely, Rob Herring, Benoît Cousson,
Tony Lindgren, Pawel Moll, Mark Rutland, Ian Campbell, Kumar Gala,
Thierry Reding
Cc: Linux IIO List, Linux Kernel Mailing List, Devicetree List,
Linux PWM List, Linux OMAP List, Linux ARM Kernel List
In-Reply-To: <1391626901-31684-1-git-send-email-mporter@linaro.org>
Add missing interrupt properties to the ecap0, ecap1, and ecap2
nodes.
Signed-off-by: Matt Porter <mporter@linaro.org>
---
arch/arm/boot/dts/am33xx.dtsi | 6 ++++++
1 file changed, 6 insertions(+)
diff --git a/arch/arm/boot/dts/am33xx.dtsi b/arch/arm/boot/dts/am33xx.dtsi
index 6d95d3d..b4139ba 100644
--- a/arch/arm/boot/dts/am33xx.dtsi
+++ b/arch/arm/boot/dts/am33xx.dtsi
@@ -582,6 +582,8 @@
compatible = "ti,am33xx-ecap";
#pwm-cells = <3>;
reg = <0x48300100 0x80>;
+ interrupts = <31>;
+ interrupt-names = "ecap0";
ti,hwmods = "ecap0";
status = "disabled";
};
@@ -610,6 +612,8 @@
compatible = "ti,am33xx-ecap";
#pwm-cells = <3>;
reg = <0x48302100 0x80>;
+ interrupts = <47>;
+ interrupt-names = "ecap1";
ti,hwmods = "ecap1";
status = "disabled";
};
@@ -638,6 +642,8 @@
compatible = "ti,am33xx-ecap";
#pwm-cells = <3>;
reg = <0x48304100 0x80>;
+ interrupts = <61>;
+ interrupt-names = "ecap2";
ti,hwmods = "ecap2";
status = "disabled";
};
--
1.8.4
^ permalink raw reply related
* Re: [PATCH v5 00/20] Armada 370/XP watchdog support
From: Jason Cooper @ 2014-02-05 19:06 UTC (permalink / raw)
To: Ezequiel Garcia
Cc: linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
devicetree-u79uwXL29TY76Z2rM5mHXA,
linux-watchdog-u79uwXL29TY76Z2rM5mHXA, Lior Amsalem, Andrew Lunn,
Tawfik Bayouk, Daniel Lezcano, Wim Van Sebroeck, Arnd Bergmann,
Gregory Clement, Guenter Roeck, Sebastian Hesselbarth
In-Reply-To: <1390836440-12744-1-git-send-email-ezequiel.garcia-wi1+55ScJUtKEb57/3fJTNBPR1lH4CV8@public.gmane.org>
Wim,
On Mon, Jan 27, 2014 at 12:27:00PM -0300, Ezequiel Garcia wrote:
> A new round, mostly fixing some minor nitpicks.
>
> This entire series depends on latest irqchip-orion fixes by Sebastian.
> Namely, this one: https://lkml.org/lkml/2014/1/23/594.
>
> How should we handle this dependency?
As this series depends on another branch we are handling (currently
mvebu-next/irqchip-fixes, destined for tglx's tree), would you mind if
we took this series through arm-soc with your Ack?
thx,
Jason.
>
> Changes from v4 are:
>
> * Provided better commit subject and commit log for patch 7:
> "watchdog: orion: Handle the interrupt so it's properly acked".
>
> * Corrected the misnamed fuction try_rstout_ioremap().
>
> * A bunch of s/interruption/interrupt fixes
>
> * Dropped the '0' as a valid IRQ in the platform_get_irq() check, given
> it should return a positive virq-space number.
>
> Changes from v3 are:
>
> * It wasn't nice to break DT compatibility by adding a second resource
> requirement, so we provided a fallback to use the RSTOUT address.
> All in all, the solution doesn't look too bad.
>
> * Added a full watchdog stop at driver probe time, *before* the call
> to request_irq().
>
> Notice that currently the request_irq() doesn't seem to clear the
> pending interrupt. This means the BRIDGE_CAUSE clear removal is
> still not safe.
>
> This should be fixed sooner than later and, of course, before this
> gets merged.
>
> * Rework the interrupt request, to use devm_request_irq() and
> avoid dealing with IRQ releasing.
>
> * Added proper clock error handling and fixed the probe() error path.
>
> * Typos and minor issues got fixed
>
> Changes from v2:
>
> * Add proper error checking on clk_prepare_enable() and return
> PTR_ERR instead of ENODEV. Suggested by Fabio Estevam.
>
> * After the usage of the atomic I/O and considering the watchdog core
> does its own serialization, the driver's spinlock was completely
> redundant and was removed. Also suggested by Fabio.
>
> * Instead of making the driver dependent on PLAT_ORION, added a dependency
> to ARCH_MVEBU. This was proposed by Sebastian and Andrew, given
> we're working on PLAT_ORION removal.
>
> Changes from v1:
>
> * Watchdog RSTOUT enable.
> While v1 enabled the RSTOUT at each machine initialization, Jason Gunthorpe
> later pointed out [2] that such enabling might lead to a spurious watchdog
> trigger, in the event of the watchdog expired event not being cleared.
>
> Therefore, the current patchset adds RSTOUT as a second address resource
> (or 'reg' entry in devicetree words) to allow different platforms specify
> the corresponding address of the register. This change allows to build the
> driver on multiplatforms builds as helps remove a mach-specific header.
>
> The drawback of this is that the DT backwards compatibility gets broken;
> this was timely discussed but no better solution was achieved or proposed.
>
> * BRIDGE CAUSE clear removal
> The watchdog cause clear should be done by the bridge irqchip driver, so
> it's fine to remove it from the watchdog driver and instead request the
> interrupt.
>
> However, there are still a few platforms (orion5x, and legacy
> kirkwood/dove) that doesn't have this bridge irqchip support enabled.
> On these platforms the bridge cause clear is simply *not* done.
>
> If we are paranoid about this, maybe we can simply add the clear on each
> mach-xxx/irq.c, together with the other irq is initialization.
>
> Once again, thanks to everyone who helped reviewing this.
>
> Ezequiel Garcia (20):
> ARM: Introduce atomic MMIO modify
> clocksource: orion: Use atomic access for shared registers
> watchdog: orion: Add clock error handling
> watchdog: orion: Use atomic access for shared registers
> watchdog: orion: Remove unused macros
> watchdog: orion: Make sure the watchdog is initially stopped
> watchdog: orion: Handle the interrupt so it's properly acked
> watchdog: orion: Make RSTOUT register a separate resource
> watchdog: orion: Remove unneeded BRIDGE_CAUSE clear
> watchdog: orion: Introduce an orion_watchdog device structure
> watchdog: orion: Introduce per-compatible of_device_id data
> watchdog: orion: Add per-compatible clock initialization
> watchdog: orion: Add per-compatible watchdog start implementation
> watchdog: orion: Add support for Armada 370 and Armada XP SoC
> ARM: mvebu: Enable Armada 370/XP watchdog in the devicetree
> ARM: kirkwood: Add RSTOUT 'reg' entry to devicetree
> ARM: dove: Enable Dove watchdog in the devicetree
> watchdog: orion: Enable the build on ARCH_MVEBU
> ARM: mvebu: Enable watchdog support in defconfig
> ARM: dove: Enable watchdog support in the defconfig
>
> .../devicetree/bindings/watchdog/marvel.txt | 8 +-
> arch/arm/boot/dts/armada-370-xp.dtsi | 4 +
> arch/arm/boot/dts/armada-370.dtsi | 5 +
> arch/arm/boot/dts/armada-xp.dtsi | 6 +
> arch/arm/boot/dts/dove.dtsi | 8 +
> arch/arm/boot/dts/kirkwood.dtsi | 2 +-
> arch/arm/configs/dove_defconfig | 2 +
> arch/arm/configs/mvebu_defconfig | 2 +
> arch/arm/include/asm/io.h | 6 +
> arch/arm/kernel/io.c | 35 ++
> arch/arm/mach-dove/include/mach/bridge-regs.h | 1 +
> arch/arm/mach-kirkwood/include/mach/bridge-regs.h | 1 +
> arch/arm/mach-mv78xx0/include/mach/bridge-regs.h | 1 +
> arch/arm/mach-orion5x/include/mach/bridge-regs.h | 1 +
> arch/arm/plat-orion/common.c | 10 +-
> drivers/clocksource/time-orion.c | 28 +-
> drivers/watchdog/Kconfig | 2 +-
> drivers/watchdog/orion_wdt.c | 369 ++++++++++++++++-----
> 18 files changed, 383 insertions(+), 108 deletions(-)
>
> --
> 1.8.1.5
>
>
> _______________________________________________
> linux-arm-kernel mailing list
> linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r@public.gmane.org
> http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
--
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
* Re: [PATCH v5 02/20] clocksource: orion: Use atomic access for shared registers
From: Jason Cooper @ 2014-02-05 19:10 UTC (permalink / raw)
To: Ezequiel Garcia, Daniel Lezcano
Cc: linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
devicetree-u79uwXL29TY76Z2rM5mHXA,
linux-watchdog-u79uwXL29TY76Z2rM5mHXA, Lior Amsalem, Andrew Lunn,
Tawfik Bayouk, Wim Van Sebroeck, Arnd Bergmann, Gregory Clement,
Guenter Roeck, Sebastian Hesselbarth
In-Reply-To: <1390836440-12744-3-git-send-email-ezequiel.garcia-wi1+55ScJUtKEb57/3fJTNBPR1lH4CV8@public.gmane.org>
Daniel,
On Mon, Jan 27, 2014 at 12:27:02PM -0300, Ezequiel Garcia wrote:
> Replace the driver-specific thread-safe shared register API
> by the recently introduced atomic_io_clear_set().
>
> Cc: Daniel Lezcano <daniel.lezcano-QSEj5FYQhm4dnm+yROfE0A@public.gmane.org>
> Tested-by: Sebastian Hesselbarth <sebastian.hesselbarth-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
> Signed-off-by: Ezequiel Garcia <ezequiel.garcia-wi1+55ScJUtKEb57/3fJTNBPR1lH4CV8@public.gmane.org>
> ---
> drivers/clocksource/time-orion.c | 28 ++++++++++------------------
> 1 file changed, 10 insertions(+), 18 deletions(-)
The MMIO patch this depends on:
c5ca95b507c8 ARM: 7930/1: Introduce atomic MMIO modify
made it in to v3.14-rc1. It looks like this change is independent of
the rest of the watchdog series, so:
Acked-by: Jason Cooper <jason-NLaQJdtUoK4Be96aLqz0jA@public.gmane.org>
thx,
Jason.
> diff --git a/drivers/clocksource/time-orion.c b/drivers/clocksource/time-orion.c
> index 9c7f018..3f14e56 100644
> --- a/drivers/clocksource/time-orion.c
> +++ b/drivers/clocksource/time-orion.c
> @@ -35,20 +35,6 @@
> #define ORION_ONESHOT_MAX 0xfffffffe
>
> static void __iomem *timer_base;
> -static DEFINE_SPINLOCK(timer_ctrl_lock);
> -
> -/*
> - * Thread-safe access to TIMER_CTRL register
> - * (shared with watchdog timer)
> - */
> -void orion_timer_ctrl_clrset(u32 clr, u32 set)
> -{
> - spin_lock(&timer_ctrl_lock);
> - writel((readl(timer_base + TIMER_CTRL) & ~clr) | set,
> - timer_base + TIMER_CTRL);
> - spin_unlock(&timer_ctrl_lock);
> -}
> -EXPORT_SYMBOL(orion_timer_ctrl_clrset);
>
> /*
> * Free-running clocksource handling.
> @@ -68,7 +54,8 @@ static int orion_clkevt_next_event(unsigned long delta,
> {
> /* setup and enable one-shot timer */
> writel(delta, timer_base + TIMER1_VAL);
> - orion_timer_ctrl_clrset(TIMER1_RELOAD_EN, TIMER1_EN);
> + atomic_io_modify(timer_base + TIMER_CTRL,
> + TIMER1_RELOAD_EN | TIMER1_EN, TIMER1_EN);
>
> return 0;
> }
> @@ -80,10 +67,13 @@ static void orion_clkevt_mode(enum clock_event_mode mode,
> /* setup and enable periodic timer at 1/HZ intervals */
> writel(ticks_per_jiffy - 1, timer_base + TIMER1_RELOAD);
> writel(ticks_per_jiffy - 1, timer_base + TIMER1_VAL);
> - orion_timer_ctrl_clrset(0, TIMER1_RELOAD_EN | TIMER1_EN);
> + atomic_io_modify(timer_base + TIMER_CTRL,
> + TIMER1_RELOAD_EN | TIMER1_EN,
> + TIMER1_RELOAD_EN | TIMER1_EN);
> } else {
> /* disable timer */
> - orion_timer_ctrl_clrset(TIMER1_RELOAD_EN | TIMER1_EN, 0);
> + atomic_io_modify(timer_base + TIMER_CTRL,
> + TIMER1_RELOAD_EN | TIMER1_EN, 0);
> }
> }
>
> @@ -131,7 +121,9 @@ static void __init orion_timer_init(struct device_node *np)
> /* setup timer0 as free-running clocksource */
> writel(~0, timer_base + TIMER0_VAL);
> writel(~0, timer_base + TIMER0_RELOAD);
> - orion_timer_ctrl_clrset(0, TIMER0_RELOAD_EN | TIMER0_EN);
> + atomic_io_modify(timer_base + TIMER_CTRL,
> + TIMER0_RELOAD_EN | TIMER0_EN,
> + TIMER0_RELOAD_EN | TIMER0_EN);
> clocksource_mmio_init(timer_base + TIMER0_VAL, "orion_clocksource",
> clk_get_rate(clk), 300, 32,
> clocksource_mmio_readl_down);
> --
> 1.8.1.5
>
>
> _______________________________________________
> linux-arm-kernel mailing list
> linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r@public.gmane.org
> http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
--
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
* Re: [PATCH v3 3/6] misc: fuse: Add efuse driver for Tegra
From: Stephen Warren @ 2014-02-05 19:15 UTC (permalink / raw)
To: Peter De Schrijver
Cc: linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
linux-tegra-u79uwXL29TY76Z2rM5mHXA,
linux-kernel-u79uwXL29TY76Z2rM5mHXA, Rob Landley, Thierry Reding,
Grant Likely, Rob Herring, Danny Huang,
linux-doc-u79uwXL29TY76Z2rM5mHXA,
devicetree-u79uwXL29TY76Z2rM5mHXA
In-Reply-To: <1390952176-30402-4-git-send-email-pdeschrijver-DDmLM1+adcrQT0dZR+AlfA@public.gmane.org>
On 01/28/2014 04:36 PM, Peter De Schrijver wrote:
> Implement fuse driver for Tegra20, Tegra30, Tegra114 and Tegra124.
I assume most of this code is simply cut/paste from the existing code in
arch/arm/mach-tegra/? If so, "git format-patch -C" would have been
useful to highlight what changed when duplicating the files.
> diff --git a/Documentation/ABI/testing/sysfs-driver-tegra-fuse b/Documentation/ABI/testing/sysfs-driver-tegra-fuse
> +What: /sys/devices/*/<our-device>/fuse
> +Date: December 2013
> +Contact: Peter De Schrijver <pdeschrijver-DDmLM1+adcrQT0dZR+AlfA@public.gmane.org>
> +Description: read-only access to the efuses on Tegra20, Tegra30, Tegra114
> + and Tegra124 SoC's from NVIDIA. The efuses contain write once
> + data programmed at the factory.
> +Users: any user space application which wants to read the efuses on
> + Tegra SoC's
Surely this file should describe the format of the file, since that's
part of the ABI too, right?
> diff --git a/drivers/misc/fuse/tegra/fuse-tegra20.c b/drivers/misc/fuse/tegra/fuse-tegra20.c
> +static int tegra20_fuse_probe(struct platform_device *pdev)
...
> + sku_info.revision = tegra_revision;
> + tegra20_init_speedo_data(&sku_info, &pdev->dev);
...
> +}
> +
> +static struct platform_driver tegra20_fuse_driver = {
> + .probe = tegra20_fuse_probe,
> + .driver = {
> + .name = "tegra20_fuse",
> + .owner = THIS_MODULE,
> + .of_match_table = tegra20_fuse_of_match,
> + }
> +};
> +
> +static int __init tegra20_fuse_init(void)
> +{
> + return platform_driver_register(&tegra20_fuse_driver);
> +}
> +postcore_initcall(tegra20_fuse_init);
That call to tegra20_init_speedo_data() now happens much later in boot.
Are you sure there's nothing that relies on data it sets up between when
tegra_fuse_init() is called (which is where it happens before this
series), and the somewhat arbitrary later time when this driver probes?
> diff --git a/drivers/misc/fuse/tegra/fuse-tegra30.c b/drivers/misc/fuse/tegra/fuse-tegra30.c
> +postcore_initcall(tegra30_fuse_init);
> +
There's a blank line at the end of the file. I thought checkpatch warned
about this? But actually it doesn't seem to at least in -f mode.
> diff --git a/drivers/misc/fuse/tegra/fuse.h b/drivers/misc/fuse/tegra/fuse.h
> +struct tegra_sku_info {
> + int sku_id;
> + int cpu_process_id;
> + int cpu_speedo_id;
> + int cpu_speedo_value;
> + int cpu_iddq_value;
> + int core_process_id;
> + int soc_speedo_id;
> + int gpu_speedo_id;
> + int gpu_process_id;
> + int gpu_speedo_value;
> + enum tegra_revision revision;
> +};
The only use of this appears to be to pass to tegra_fuse_create_sysfs()
which prints out the fields. Will there be more users in the future?
Otherwise, I'd be tempted to just print it out outside/before-calling
tegra_fuse_create_sysfs().
That said, I wonder if these values could/should be exposed in the sysfs
file to make it easier to interpret the fuses?
> diff --git a/drivers/misc/fuse/tegra/tegra114_speedo.c b/drivers/misc/fuse/tegra/tegra114_speedo.c
It might be nice to make these filenames consistent with the others,
e.g. fuse-speedo-tegraNNN.c/speedo-tegraNNN.c, or wrap them into
fuse-tegraNNN.c?
> diff --git a/drivers/misc/fuse/tegra/tegra30_speedo.c b/drivers/misc/fuse/tegra/tegra30_speedo.c
> +#define FUSE_SPEEDO_CALIB_0 0x14
> +#define FUSE_PACKAGE_INFO 0XFC
> +#define FUSE_TEST_PROG_VER 0X28
In arch/arm/mach-tegra/tegra30_speedo.c, those values are different:
#define FUSE_SPEEDO_CALIB_0 0x114
#define FUSE_PACKAGE_INFO 0X1FC
#define FUSE_TEST_PROG_VER 0X128
Was this change intentional? Perhaps it should be in a separate patch to
highlight the change, if it's an intentional bug-fix?
^ permalink raw reply
* Re: [PATCH v2 5/5] of: document bindings for reserved-memory nodes
From: Josh Cartwright @ 2014-02-05 19:25 UTC (permalink / raw)
To: Grant Likely
Cc: Marek Szyprowski, linux-kernel, linux-arm-kernel, linaro-mm-sig,
devicetree, linux-doc, Kyungmin Park, Benjamin Herrenschmidt,
Arnd Bergmann, Michal Nazarewicz, Tomasz Figa, Sascha Hauer,
Laura Abbott, Rob Herring, Olof Johansson, Pawel Moll,
Mark Rutland, Stephen Warren, Ian Campbell, Tomasz Figa,
Kumar Gala, Nishanth Peethambaran, Marc
In-Reply-To: <20140205100750.58EFAC40A89@trevor.secretlab.ca>
On Wed, Feb 05, 2014 at 10:07:50AM +0000, Grant Likely wrote:
> On Tue, 04 Feb 2014 13:09:33 +0100, Marek Szyprowski <m.szyprowski@samsung.com> wrote:
> > From: Grant Likely <grant.likely@linaro.org>
> > +/reserved-memory node
> > +---------------------
> > +#address-cells, #size-cells (required) - standard definition
> > + - Should use the same values as the root node
> > +#memory-region-cells (required) - dictates number of cells used in the child
> > + nodes memory-region specifier
>
> I don't think this isn't defined well enough. These reserved regions may
> not have a driver attached to them, so there is no central agent to
> decide what the specifier means. That leaves the interpretation of
> the memory region in the hands of the client drivers. How do you see the
> specifier getting parsed and used?
I had a specific usecase in mind when I added it, although admittedly I
haven't yet worked through all of the details.
On MSM chips, there is a region of memory accessible from the various
processors on the SoC. This region is used for (among other things)
inter-processor communication. Inside this region, a heap allocation
protocol is implemented by software on all interested processors.
Consumers of this shared memory heap specify a 32-bit identifier and a
size, and are either given a matching preexisting chunk (for example,
another processor has already allocated a chunk with the corresponding
identifier), or are allocated a new chunk for that identifier out of the
region.
Given it's shared nature, this region has some specific requirements
about how it may be accessed by the kernel (specifically regarding
cacheability/how it's mapped), which means it at least needs _some_
representation in a reserved-memory node.
I had envisioned expressing the shared memory/consumer relationship in
the device tree:
reserved-memory {
smem : smem {
compatible = "qcom,shared-memory";
reg = <...>;
#memory-region-cells = <2>;
no-map;
};
};
consumer {
/* ... */;
memory-region = <&smem 0xDEADBEEF 0x1000>;
};
That is, the heap protocol implementation exists as a "driver" for the
smem reserved-memory node, and the consumer's 2-cell specifier is a
32-bit identifier and a size.
If your concern is for the case where a "qcom,shared-memory" node is
specified in a device tree, but the "driver" hasn't been built into the
kernel, then the appropriate behavior would be the same as the DMA/CMA
case: fallback to a default case of memblock_reserve/memblock_remove'ing
the region.
Would using reserved-memory in this way be outside the scope of what was
originally intended?
Thanks,
Josh
--
Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum,
hosted by The Linux Foundation
^ permalink raw reply
* [PATCH v4 0/2] Introduce AEMIF driver for Davinci/Keystone archs
From: Ivan Khoronzhuk @ 2014-02-05 19:46 UTC (permalink / raw)
To: santosh.shilimkar-l0cyMroinI0, rob-VoJi6FS/r0vR7s880joybQ,
linux-lFZ/pmaqli7XmaaqVzeoHQ,
galak-XVmvHMARGAS8U2dJNN8I7kB+6BGkLq7r
Cc: devicetree-u79uwXL29TY76Z2rM5mHXA, pawel.moll-5wv7dgnIgG8,
mark.rutland-5wv7dgnIgG8, rob.herring-bsGFqQB8/DxBDgjK7y7TUQ,
swarren-3lzwWm7+Weoh9ZMKESR00Q,
ijc+devicetree-KcIKpvwj1kUDXYZnReoRVg,
linux-kernel-u79uwXL29TY76Z2rM5mHXA,
linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
linux-mtd-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
grygorii.strashko-l0cyMroinI0,
gregkh-hQyY1W1yCW8ekmWlsbkhG0B+6BGkLq7r,
dwmw2-wEGCiKHe2LqWVfeAwA7xHQ, nsekhar-l0cyMroinI0,
Ivan Khoronzhuk
These patches introduce Async External Memory Interface (EMIF16/AEMIF)
controller driver for Davinci/Keystone archs.
For more informations see documentation:
Davinci DM646x - http://www.ti.com/lit/ug/sprueq7c/sprueq7c.pdf
OMAP-L138 - http://www.ti.com/lit/ug/spruh77a/spruh77a.pdf
Kestone - http://www.ti.com/lit/ug/sprugz3a/sprugz3a.pdf
Based on
git://git.kernel.org/pub/scm/linux/kernel/git/ssantosh/linux-keystone.git
keystone/master
v3..v4:
rebased on latest of linux-keystone.git keystone/master
v2..v3 (https://lkml.org/lkml/2013/12/11/148):
- memory: ti-aemif: introduce AEMIF driver
changed to work with multiple AEMIF controllers
corrected "copyright" to "authors" in header
changed compatible "ti,omap-L138-aemif" to "ti,da850-aeimf"
used NULL in clk_get() instead of "aemif" name
driver can be build as loadable module
treat all child nodes as cs nodes, it makes code simpler
- memory: ti-aemif: add bindings for AEMIF driver
deleted direct link driver/memory/ti-aemif.c
clarified description of controller ranges property
changed compatible "ti,omap-L138-aemif" to "ti,da850-aeimf"
added cs number information in commit log
removed compatible property from cs node, it makes code simpler
v1..v2 (https://lkml.org/lkml/2013/11/21/170):
- memory: ti-aemif: introduce AEMIF driver
- memory: ti-aemif: add bindings for AEMIF driver
added ti.cs-chipselect property instead of representing chipselect
number in cs node name.
Ivan Khoronzhuk (2):
memory: ti-aemif: introduce AEMIF driver
memory: ti-aemif: add bindings for AEMIF driver
.../bindings/memory-controllers/ti-aemif.txt | 210 ++++++++++
drivers/memory/Kconfig | 11 +
drivers/memory/Makefile | 1 +
drivers/memory/ti-aemif.c | 429 +++++++++++++++++++++
4 files changed, 651 insertions(+)
create mode 100644 Documentation/devicetree/bindings/memory-controllers/ti-aemif.txt
create mode 100644 drivers/memory/ti-aemif.c
--
1.8.3.2
--
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
* [PATCH v4 1/2] memory: ti-aemif: introduce AEMIF driver
From: Ivan Khoronzhuk @ 2014-02-05 19:46 UTC (permalink / raw)
To: santosh.shilimkar-l0cyMroinI0, rob-VoJi6FS/r0vR7s880joybQ,
linux-lFZ/pmaqli7XmaaqVzeoHQ,
galak-XVmvHMARGAS8U2dJNN8I7kB+6BGkLq7r
Cc: devicetree-u79uwXL29TY76Z2rM5mHXA, pawel.moll-5wv7dgnIgG8,
mark.rutland-5wv7dgnIgG8, rob.herring-bsGFqQB8/DxBDgjK7y7TUQ,
swarren-3lzwWm7+Weoh9ZMKESR00Q,
ijc+devicetree-KcIKpvwj1kUDXYZnReoRVg,
linux-kernel-u79uwXL29TY76Z2rM5mHXA,
linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
linux-mtd-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
grygorii.strashko-l0cyMroinI0,
gregkh-hQyY1W1yCW8ekmWlsbkhG0B+6BGkLq7r,
dwmw2-wEGCiKHe2LqWVfeAwA7xHQ, nsekhar-l0cyMroinI0,
Ivan Khoronzhuk, [initial author] Murali Karicheri
In-Reply-To: <1391629574-18955-1-git-send-email-ivan.khoronzhuk-l0cyMroinI0@public.gmane.org>
Add new AEMIF driver for EMIF16 Texas Instruments controller.
The EMIF16 module is intended to provide a glue-less interface to
a variety of asynchronous memory devices like ASRA M, NOR and NAND
memory. A total of 256M bytes of any of these memories can be
accessed at any given time via 4 chip selects with 64M byte access
per chip select.
Synchronous memories such as DDR1 SD RAM, SDR SDRAM and Mobile SDR
are not supported.
This controller is used on SoCs like Davinci, Keysone2
Acked-by: Santosh Shilimkar <santosh.shilimkar-l0cyMroinI0@public.gmane.org
Signed-off-by: [initial author] Murali Karicheri <m-karicheri2-l0cyMroinI0@public.gmane.org>
Signed-off-by: Ivan Khoronzhuk <ivan.khoronzhuk-l0cyMroinI0@public.gmane.org>
---
drivers/memory/Kconfig | 11 ++
drivers/memory/Makefile | 1 +
drivers/memory/ti-aemif.c | 429 ++++++++++++++++++++++++++++++++++++++++++++++
3 files changed, 441 insertions(+)
create mode 100644 drivers/memory/ti-aemif.c
diff --git a/drivers/memory/Kconfig b/drivers/memory/Kconfig
index 29a11db..7bc3982 100644
--- a/drivers/memory/Kconfig
+++ b/drivers/memory/Kconfig
@@ -7,6 +7,17 @@ menuconfig MEMORY
if MEMORY
+config TI_AEMIF
+ tristate "Texas Instruments AEMIF driver"
+ depends on (ARCH_DAVINCI || ARCH_KEYSTONE) && OF
+ help
+ This driver is for the AEMIF module available in Texas Instruments
+ SoCs. AEMIF stands for Asynchronous External Memory Interface and
+ is intended to provide a glue-less interface to a variety of
+ asynchronuous memory devices like ASRAM, NOR and NAND memory. A total
+ of 256M bytes of any of these memories can be accessed at a given
+ time via four chip selects with 64M byte access per chip select.
+
config TI_EMIF
tristate "Texas Instruments EMIF driver"
depends on ARCH_OMAP2PLUS
diff --git a/drivers/memory/Makefile b/drivers/memory/Makefile
index 969d923..d4e150c 100644
--- a/drivers/memory/Makefile
+++ b/drivers/memory/Makefile
@@ -5,6 +5,7 @@
ifeq ($(CONFIG_DDR),y)
obj-$(CONFIG_OF) += of_memory.o
endif
+obj-$(CONFIG_TI_AEMIF) += ti-aemif.o
obj-$(CONFIG_TI_EMIF) += emif.o
obj-$(CONFIG_MVEBU_DEVBUS) += mvebu-devbus.o
obj-$(CONFIG_TEGRA20_MC) += tegra20-mc.o
diff --git a/drivers/memory/ti-aemif.c b/drivers/memory/ti-aemif.c
new file mode 100644
index 0000000..8d15d87
--- /dev/null
+++ b/drivers/memory/ti-aemif.c
@@ -0,0 +1,429 @@
+/*
+ * TI AEMIF driver
+ *
+ * Copyright (C) 2010 - 2013 Texas Instruments Incorporated. http://www.ti.com/
+ *
+ * Authors:
+ * Murali Karicheri <m-karicheri2-l0cyMroinI0@public.gmane.org>
+ * Ivan Khoronzhuk <ivan.khoronzhuk-l0cyMroinI0@public.gmane.org>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/clk.h>
+#include <linux/err.h>
+#include <linux/io.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/of.h>
+#include <linux/of_platform.h>
+#include <linux/platform_device.h>
+
+#define TA_SHIFT 2
+#define RHOLD_SHIFT 4
+#define RSTROBE_SHIFT 7
+#define RSETUP_SHIFT 13
+#define WHOLD_SHIFT 17
+#define WSTROBE_SHIFT 20
+#define WSETUP_SHIFT 26
+#define EW_SHIFT 30
+#define SS_SHIFT 31
+
+#define TA(x) ((x) << TA_SHIFT)
+#define RHOLD(x) ((x) << RHOLD_SHIFT)
+#define RSTROBE(x) ((x) << RSTROBE_SHIFT)
+#define RSETUP(x) ((x) << RSETUP_SHIFT)
+#define WHOLD(x) ((x) << WHOLD_SHIFT)
+#define WSTROBE(x) ((x) << WSTROBE_SHIFT)
+#define WSETUP(x) ((x) << WSETUP_SHIFT)
+#define EW(x) ((x) << EW_SHIFT)
+#define SS(x) ((x) << SS_SHIFT)
+
+#define ASIZE_MAX 0x1
+#define TA_MAX 0x3
+#define RHOLD_MAX 0x7
+#define RSTROBE_MAX 0x3f
+#define RSETUP_MAX 0xf
+#define WHOLD_MAX 0x7
+#define WSTROBE_MAX 0x3f
+#define WSETUP_MAX 0xf
+#define EW_MAX 0x1
+#define SS_MAX 0x1
+#define NUM_CS 4
+
+#define TA_VAL(x) (((x) & TA(TA_MAX)) >> TA_SHIFT)
+#define RHOLD_VAL(x) (((x) & RHOLD(RHOLD_MAX)) >> RHOLD_SHIFT)
+#define RSTROBE_VAL(x) (((x) & RSTROBE(RSTROBE_MAX)) >> RSTROBE_SHIFT)
+#define RSETUP_VAL(x) (((x) & RSETUP(RSETUP_MAX)) >> RSETUP_SHIFT)
+#define WHOLD_VAL(x) (((x) & WHOLD(WHOLD_MAX)) >> WHOLD_SHIFT)
+#define WSTROBE_VAL(x) (((x) & WSTROBE(WSTROBE_MAX)) >> WSTROBE_SHIFT)
+#define WSETUP_VAL(x) (((x) & WSETUP(WSETUP_MAX)) >> WSETUP_SHIFT)
+#define EW_VAL(x) (((x) & EW(EW_MAX)) >> EW_SHIFT)
+#define SS_VAL(x) (((x) & SS(SS_MAX)) >> SS_SHIFT)
+
+#define NRCSR_OFFSET 0x00
+#define AWCCR_OFFSET 0x04
+#define A1CR_OFFSET 0x10
+
+#define ACR_ASIZE_MASK 0x3
+#define ACR_EW_MASK BIT(30)
+#define ACR_SS_MASK BIT(31)
+#define ASIZE_16BIT 1
+
+#define CONFIG_MASK (TA(TA_MAX) | \
+ RHOLD(RHOLD_MAX) | \
+ RSTROBE(RSTROBE_MAX) | \
+ RSETUP(RSETUP_MAX) | \
+ WHOLD(WHOLD_MAX) | \
+ WSTROBE(WSTROBE_MAX) | \
+ WSETUP(WSETUP_MAX) | \
+ EW(EW_MAX) | SS(SS_MAX) | \
+ ASIZE_MAX)
+
+#define DRV_NAME "ti-aemif"
+
+/**
+ * struct aemif_cs_data: structure to hold cs parameters
+ * @cs: chip-select number
+ * @wstrobe: write strobe width, ns
+ * @rstrobe: read strobe width, ns
+ * @wsetup: write setup width, ns
+ * @whold: write hold width, ns
+ * @rsetup: read setup width, ns
+ * @rhold: read hold width, ns
+ * @ta: minimum turn around time, ns
+ * @enable_ss: enable/disable select strobe mode
+ * @enable_ew: enable/disable extended wait mode
+ * @asize: width of the asynchronous device's data bus
+ */
+struct aemif_cs_data {
+ u8 cs;
+ u16 wstrobe;
+ u16 rstrobe;
+ u8 wsetup;
+ u8 whold;
+ u8 rsetup;
+ u8 rhold;
+ u8 ta;
+ u8 enable_ss;
+ u8 enable_ew;
+ u8 asize;
+};
+
+/**
+ * struct aemif_device: structure to hold device data
+ * @base: base address of AEMIF registers
+ * @clk: source clock
+ * @clk_rate: clock's rate in kHz
+ * @num_cs: number of assigned chip-selects
+ * @cs_offset: start number of cs nodes
+ * @cs_data: array of chip-select settings
+ */
+struct aemif_device {
+ void __iomem *base;
+ struct clk *clk;
+ unsigned long clk_rate;
+ u8 num_cs;
+ int cs_offset;
+ struct aemif_cs_data cs_data[NUM_CS];
+};
+
+/**
+ * aemif_calc_rate - calculate timing data.
+ * @pdev: platform device to calculate for
+ * @wanted: The cycle time needed in nanoseconds.
+ * @clk: The input clock rate in kHz.
+ * @max: The maximum divider value that can be programmed.
+ *
+ * On success, returns the calculated timing value minus 1 for easy
+ * programming into AEMIF timing registers, else negative errno.
+ */
+static int aemif_calc_rate(struct platform_device *pdev, int wanted,
+ unsigned long clk, int max)
+{
+ int result;
+
+ result = DIV_ROUND_UP((wanted * clk), NSEC_PER_MSEC) - 1;
+
+ dev_dbg(&pdev->dev, "%s: result %d from %ld, %d\n", __func__, result,
+ clk, wanted);
+
+ /* It is generally OK to have a more relaxed timing than requested... */
+ if (result < 0)
+ result = 0;
+
+ /* ... But configuring tighter timings is not an option. */
+ else if (result > max)
+ result = -EINVAL;
+
+ return result;
+}
+
+/**
+ * aemif_config_abus - configure async bus parameters
+ * @pdev: platform device to configure for
+ * @csnum: aemif chip select number
+ *
+ * This function programs the given timing values (in real clock) into the
+ * AEMIF registers taking the AEMIF clock into account.
+ *
+ * This function does not use any locking while programming the AEMIF
+ * because it is expected that there is only one user of a given
+ * chip-select.
+ *
+ * Returns 0 on success, else negative errno.
+ */
+static int aemif_config_abus(struct platform_device *pdev, int csnum)
+{
+ struct aemif_device *aemif = platform_get_drvdata(pdev);
+ struct aemif_cs_data *data = &aemif->cs_data[csnum];
+ int ta, rhold, rstrobe, rsetup, whold, wstrobe, wsetup;
+ unsigned long clk_rate = aemif->clk_rate;
+ unsigned offset;
+ u32 set, val;
+
+ offset = A1CR_OFFSET + (data->cs - aemif->cs_offset) * 4;
+
+ ta = aemif_calc_rate(pdev, data->ta, clk_rate, TA_MAX);
+ rhold = aemif_calc_rate(pdev, data->rhold, clk_rate, RHOLD_MAX);
+ rstrobe = aemif_calc_rate(pdev, data->rstrobe, clk_rate, RSTROBE_MAX);
+ rsetup = aemif_calc_rate(pdev, data->rsetup, clk_rate, RSETUP_MAX);
+ whold = aemif_calc_rate(pdev, data->whold, clk_rate, WHOLD_MAX);
+ wstrobe = aemif_calc_rate(pdev, data->wstrobe, clk_rate, WSTROBE_MAX);
+ wsetup = aemif_calc_rate(pdev, data->wsetup, clk_rate, WSETUP_MAX);
+
+ if (ta < 0 || rhold < 0 || rstrobe < 0 || rsetup < 0 ||
+ whold < 0 || wstrobe < 0 || wsetup < 0) {
+ dev_err(&pdev->dev, "%s: cannot get suitable timings\n",
+ __func__);
+ return -EINVAL;
+ }
+
+ set = TA(ta) | RHOLD(rhold) | RSTROBE(rstrobe) | RSETUP(rsetup) |
+ WHOLD(whold) | WSTROBE(wstrobe) | WSETUP(wsetup);
+
+ set |= (data->asize & ACR_ASIZE_MASK);
+ if (data->enable_ew)
+ set |= ACR_EW_MASK;
+ if (data->enable_ss)
+ set |= ACR_SS_MASK;
+
+ val = readl(aemif->base + offset);
+ val &= ~CONFIG_MASK;
+ val |= set;
+ writel(val, aemif->base + offset);
+
+ return 0;
+}
+
+static inline int aemif_cycles_to_nsec(int val, unsigned long clk_rate)
+{
+ return ((val + 1) * NSEC_PER_MSEC) / clk_rate;
+}
+
+/**
+ * aemif_get_hw_params - function to read hw register values
+ * @pdev: platform device to read for
+ * @csnum: aemif chip select number
+ *
+ * This function reads the defaults from the registers and update
+ * the timing values. Required for get/set commands and also for
+ * the case when driver needs to use defaults in hardware.
+ */
+static void aemif_get_hw_params(struct platform_device *pdev, int csnum)
+{
+ struct aemif_device *aemif = platform_get_drvdata(pdev);
+ struct aemif_cs_data *data = &aemif->cs_data[csnum];
+ unsigned long clk_rate = aemif->clk_rate;
+ u32 val, offset;
+
+ offset = A1CR_OFFSET + (data->cs - aemif->cs_offset) * 4;
+ val = readl(aemif->base + offset);
+
+ data->ta = aemif_cycles_to_nsec(TA_VAL(val), clk_rate);
+ data->rhold = aemif_cycles_to_nsec(RHOLD_VAL(val), clk_rate);
+ data->rstrobe = aemif_cycles_to_nsec(RSTROBE_VAL(val), clk_rate);
+ data->rsetup = aemif_cycles_to_nsec(RSETUP_VAL(val), clk_rate);
+ data->whold = aemif_cycles_to_nsec(WHOLD_VAL(val), clk_rate);
+ data->wstrobe = aemif_cycles_to_nsec(WSTROBE_VAL(val), clk_rate);
+ data->wsetup = aemif_cycles_to_nsec(WSETUP_VAL(val), clk_rate);
+ data->enable_ew = EW_VAL(val);
+ data->enable_ss = SS_VAL(val);
+ data->asize = val & ASIZE_MAX;
+}
+
+/**
+ * of_aemif_parse_abus_config - parse CS configuration from DT
+ * @pdev: platform device to parse for
+ * @np: device node ptr
+ *
+ * This function update the emif async bus configuration based on the values
+ * configured in a cs device binding node.
+ */
+static int of_aemif_parse_abus_config(struct platform_device *pdev,
+ struct device_node *np)
+{
+ struct aemif_device *aemif = platform_get_drvdata(pdev);
+ struct aemif_cs_data *data;
+ u32 cs;
+ u32 val;
+
+ if (of_property_read_u32(np, "ti,cs-chipselect", &cs)) {
+ dev_dbg(&pdev->dev, "cs property is required");
+ return -EINVAL;
+ }
+
+ if (cs - aemif->cs_offset >= NUM_CS || cs < aemif->cs_offset) {
+ dev_dbg(&pdev->dev, "cs number is incorrect %d", cs);
+ return -EINVAL;
+ }
+
+ if (aemif->num_cs >= NUM_CS) {
+ dev_dbg(&pdev->dev, "cs count is more than %d", NUM_CS);
+ return -EINVAL;
+ }
+
+ data = &aemif->cs_data[aemif->num_cs];
+ data->cs = cs;
+
+ /* read the current value in the hw register */
+ aemif_get_hw_params(pdev, aemif->num_cs++);
+
+ /* override the values from device node */
+ if (!of_property_read_u32(np, "ti,cs-ta", &val))
+ data->ta = val;
+
+ if (!of_property_read_u32(np, "ti,cs-rhold", &val))
+ data->rhold = val;
+
+ if (!of_property_read_u32(np, "ti,cs-rstrobe", &val))
+ data->rstrobe = val;
+
+ if (!of_property_read_u32(np, "ti,cs-rsetup", &val))
+ data->rsetup = val;
+
+ if (!of_property_read_u32(np, "ti,cs-whold", &val))
+ data->whold = val;
+
+ if (!of_property_read_u32(np, "ti,cs-wstrobe", &val))
+ data->wstrobe = val;
+
+ if (!of_property_read_u32(np, "ti,cs-wsetup", &val))
+ data->wsetup = val;
+
+ if (!of_property_read_u32(np, "ti,bus-width", &val))
+ if (val == 16)
+ data->asize = 1;
+ data->enable_ew = of_property_read_bool(np, "ti,cs-ew");
+ data->enable_ss = of_property_read_bool(np, "ti,cs-ss");
+ return 0;
+}
+
+static const struct of_device_id aemif_of_match[] = {
+ { .compatible = "ti,davinci-aemif", },
+ { .compatible = "ti,da850-aemif", },
+ {},
+};
+
+static int aemif_probe(struct platform_device *pdev)
+{
+ int ret = -ENODEV, i;
+ struct resource *res;
+ struct device *dev = &pdev->dev;
+ struct device_node *np = dev->of_node;
+ struct device_node *child_np;
+ struct aemif_device *aemif;
+
+ if (np == NULL)
+ return 0;
+
+ aemif = devm_kzalloc(dev, sizeof(*aemif), GFP_KERNEL);
+ if (!aemif) {
+ dev_err(dev, "cannot allocate memory for aemif\n");
+ return -ENOMEM;
+ }
+
+ platform_set_drvdata(pdev, aemif);
+
+ aemif->clk = devm_clk_get(dev, NULL);
+ if (IS_ERR(aemif->clk)) {
+ dev_err(dev, "cannot get clock 'aemif'\n");
+ return PTR_ERR(aemif->clk);
+ }
+
+ clk_prepare_enable(aemif->clk);
+ aemif->clk_rate = clk_get_rate(aemif->clk) / MSEC_PER_SEC;
+
+ if (of_device_is_compatible(np, "ti,da850-aemif"))
+ aemif->cs_offset = 2;
+
+ res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+ aemif->base = devm_ioremap_resource(dev, res);
+ if (IS_ERR(aemif->base)) {
+ ret = PTR_ERR(aemif->base);
+ goto error;
+ }
+
+ /*
+ * For every controller device node, there is a cs device node that
+ * describe the bus configuration parameters. This functions iterate
+ * over these nodes and update the cs data array.
+ */
+ for_each_available_child_of_node(np, child_np) {
+ ret = of_aemif_parse_abus_config(pdev, child_np);
+ if (ret < 0)
+ goto error;
+ }
+
+ for (i = 0; i < aemif->num_cs; i++) {
+ ret = aemif_config_abus(pdev, i);
+ if (ret < 0) {
+ dev_err(dev, "Error configuring chip select %d\n",
+ aemif->cs_data[i].cs);
+ goto error;
+ }
+ }
+
+ /*
+ * Create a child devices explicitly from here to
+ * guarantee that the child will be probed after the AEMIF timing
+ * parameters are set.
+ */
+ for_each_available_child_of_node(np, child_np) {
+ ret = of_platform_populate(child_np, NULL, NULL, dev);
+ if (ret < 0)
+ goto error;
+ }
+
+ return 0;
+error:
+ clk_disable_unprepare(aemif->clk);
+ return ret;
+}
+
+static int aemif_remove(struct platform_device *pdev)
+{
+ struct aemif_device *aemif = platform_get_drvdata(pdev);
+ clk_disable_unprepare(aemif->clk);
+ return 0;
+}
+
+static struct platform_driver aemif_driver = {
+ .probe = aemif_probe,
+ .remove = aemif_remove,
+ .driver = {
+ .name = DRV_NAME,
+ .owner = THIS_MODULE,
+ .of_match_table = of_match_ptr(aemif_of_match),
+ },
+};
+
+module_platform_driver(aemif_driver);
+
+MODULE_AUTHOR("Murali Karicheri <m-karicheri2-l0cyMroinI0@public.gmane.org>");
+MODULE_AUTHOR("Ivan Khoronzhuk <ivan.khoronzhuk-l0cyMroinI0@public.gmane.org>");
+MODULE_DESCRIPTION("Texas Instruments AEMIF driver");
+MODULE_LICENSE("GPL v2");
+MODULE_ALIAS("platform:" DRV_NAME);
--
1.8.3.2
--
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 v4 2/2] memory: ti-aemif: add bindings for AEMIF driver
From: Ivan Khoronzhuk @ 2014-02-05 19:46 UTC (permalink / raw)
To: santosh.shilimkar, rob, linux, galak
Cc: devicetree, pawel.moll, mark.rutland, rob.herring, swarren,
ijc+devicetree, linux-kernel, linux-arm-kernel, linux-mtd,
grygorii.strashko, gregkh, dwmw2, nsekhar, Ivan Khoronzhuk
In-Reply-To: <1391629574-18955-1-git-send-email-ivan.khoronzhuk@ti.com>
Add bindings for TI Async External Memory Interface (AEMIF) controller.
The Async External Memory Interface (EMIF16/AEMIF) controller is intended to
provide a glue-less interface to a variety of asynchronous memory devices like
ASRA M, NOR and NAND memory. A total of 256M bytes of any of these memories
can be accessed via 4 chip selects with 64M byte access per chip select.
We are not encoding CS number in reg property, it's memory partition number.
The CS number is encoded for Davinci NAND node using standalone property
"ti,davinci-chipselect" and we need to provide two memory ranges to it,
as result we can't encode CS number in "reg" for AEMIF child devices
(NAND/NOR/etc), as it will break bindings compatibility.
In this patch, NAND node is used just as an example of child node.
Signed-off-by: Ivan Khoronzhuk <ivan.khoronzhuk@ti.com>
---
.../bindings/memory-controllers/ti-aemif.txt | 210 +++++++++++++++++++++
1 file changed, 210 insertions(+)
create mode 100644 Documentation/devicetree/bindings/memory-controllers/ti-aemif.txt
diff --git a/Documentation/devicetree/bindings/memory-controllers/ti-aemif.txt b/Documentation/devicetree/bindings/memory-controllers/ti-aemif.txt
new file mode 100644
index 0000000..d1466dc
--- /dev/null
+++ b/Documentation/devicetree/bindings/memory-controllers/ti-aemif.txt
@@ -0,0 +1,210 @@
+* Device tree bindings for Texas instruments AEMIF controller
+
+The Async External Memory Interface (EMIF16/AEMIF) controller is intended to
+provide a glue-less interface to a variety of asynchronous memory devices like
+ASRA M, NOR and NAND memory. A total of 256M bytes of any of these memories
+can be accessed at any given time via four chip selects with 64M byte access
+per chip select. Synchronous memories such as DDR1 SD RAM, SDR SDRAM
+and Mobile SDR are not supported.
+
+Documentation:
+Davinci DM646x - http://www.ti.com/lit/ug/sprueq7c/sprueq7c.pdf
+OMAP-L138 (DA850) - http://www.ti.com/lit/ug/spruh77a/spruh77a.pdf
+Kestone - http://www.ti.com/lit/ug/sprugz3a/sprugz3a.pdf
+
+Required properties:
+
+- compatible: "ti,davinci-aemif"
+ "ti,keystone-aemif"
+ "ti,da850-aemif"
+
+- reg: contains offset/length value for AEMIF control registers
+ space.
+
+- #address-cells: Must be 2. The partition number has to be encoded in the
+ first address cell and it may accept values 0..N-1
+ (N - total number of partitions). It's recommended to
+ assign N-1 number for the control partition. The second
+ cell is the offset into the partition.
+
+- #size-cells: Must be set to 1.
+
+- ranges: Contains memory regions. There are two types of
+ ranges/partitions:
+ - CS-specific partition/range. If continuous, must be
+ set up to reflect the memory layout for 4 chipselects,
+ if not then additional range/partition can be added and
+ child device can select the proper one.
+ - control partition which is common for all CS
+ interfaces.
+
+- clocks: the clock feeding the controller clock. Required only
+ if clock tree data present in device tree.
+ See clock-bindings.txt
+
+- clock-names: clock name. It has to be "aemif". Required only if clock
+ tree data present in device tree, in another case don't
+ use it.
+ See clock-bindings.txt
+
+- clock-ranges: Empty property indicating that child nodes can inherit
+ named clocks. Required only if clock tree data present
+ in device tree.
+ See clock-bindings.txt
+
+
+Child chip-select (cs) nodes contain the memory devices nodes connected to
+such as NOR (e.g. cfi-flash) and NAND (ti,davinci-nand, see davinci-nand.txt).
+There might be board specific devices like FPGAs.
+
+Required child cs node properties:
+
+- #address-cells: Must be 2.
+
+- #size-cells: Must be 1.
+
+- ranges: Empty property indicating that child nodes can inherit
+ memory layout.
+
+- clock-ranges: Empty property indicating that child nodes can inherit
+ named clocks. Required only if clock tree data present
+ in device tree.
+
+- ti,cs-chipselect: number of chipselect. Indicates on the aemif driver
+ which chipselect is used for accessing the memory. For
+ compatibles "ti,davinci-aemif" and "ti,keystone-aemif"
+ it can be in range [0-3]. For compatible
+ "ti,da850-aemif" range is [2-5].
+
+Optional child cs node properties:
+
+- ti,bus-width: width of the asynchronous device's data bus
+ 8 or 16 if not preset 8
+
+- ti,cs-ss: enable/disable select strobe mode
+ In select strobe mode chip select behaves as
+ the strobe and is active only during the strobe
+ period. If present then enable.
+
+- ti,cs-ew: enable/disable extended wait mode
+ if set, the controller monitors the EMIFWAIT pin
+ mapped to that chip select to determine if the
+ device wants to extend the strobe period. If
+ present then enable.
+
+- ti,cs-ta: minimum turn around time, ns
+ Time between the end of one asynchronous memory
+ access and the start of another asynchronous
+ memory access. This delay is not incurred
+ between a read followed by read or a write
+ followed by a write to same chip select.
+
+- ti,cs-rsetup: read setup width, ns
+ Time between the beginning of a memory cycle
+ and the activation of read strobe.
+ Minimum value is 1 (0 treated as 1).
+
+- ti,cs-rstobe: read strobe width, ns
+ Time between the activation and deactivation of
+ the read strobe.
+ Minimum value is 1 (0 treated as 1).
+
+- ti,cs-rhold: read hold width, ns
+ Time between the deactivation of the read
+ strobe and the end of the cycle (which may be
+ either an address change or the deactivation of
+ the chip select signal.
+ Minimum value is 1 (0 treated as 1).
+
+- ti,cs-wsetup: write setup width, ns
+ Time between the beginning of a memory cycle
+ and the activation of write strobe.
+ Minimum value is 1 (0 treated as 1).
+
+- ti,cs-wstrobe: write strobe width, ns
+ Time between the activation and deactivation of
+ the write strobe.
+ Minimum value is 1 (0 treated as 1).
+
+- ti,cs-whold: write hold width, ns
+ Time between the deactivation of the write
+ strobe and the end of the cycle (which may be
+ either an address change or the deactivation of
+ the chip select signal.
+ Minimum value is 1 (0 treated as 1).
+
+If any of the above parameters are absent, current parameter value will be taken
+from the corresponding HW reg.
+
+Example for aemif, davinci nand and nor flash chip select shown below.
+
+memory-controller@21000A00 {
+ compatible = "ti,davinci-aemif";
+ #address-cells = <2>;
+ #size-cells = <1>;
+ clocks = <&clkaemif 0>;
+ clock-names = "aemif";
+ clock-ranges;
+ reg = <0x2100A00 0x00000100>;
+ ranges = <0 0 0x70000000 0x10000000
+ 1 0 0x21000A00 0x0000100>;
+ /*
+ * Partition0: CS-specific memory range which is
+ * implemented as continuous physical memory region
+ * Partition1: control memory range
+ */
+
+ nand:cs2 {
+ #address-cells = <2>;
+ #size-cells = <1>;
+ clock-ranges;
+ ranges;
+
+ ti,cs-chipselect = <2>;
+ /* all timings in nanoseconds */
+ ti,cs-ta = <0>;
+ ti,cs-rhold = <7>;
+ ti,cs-rstrobe = <42>;
+ ti,cs-rsetup = <14>;
+ ti,cs-whold = <7>;
+ ti,cs-wstrobe = <42>;
+ ti,cs-wsetup = <14>;
+
+ nand@0,0x8000000 {
+ compatible = "ti,davinci-nand";
+ reg = <0 0x8000000 0x4000000
+ 1 0x0000000 0x0000100>;
+ /*
+ * Partition0, offset 0x8000000, size 0x4000000
+ * Partition1, offset 0x0000000, size 0x0000100
+ */
+
+ .. see davinci-nand.txt
+ };
+ };
+
+ nor:cs0 {
+ #address-cells = <2>;
+ #size-cells = <1>;
+ clock-ranges;
+ ranges;
+
+ ti,cs-chipselect = <0>;
+ /* all timings in nanoseconds */
+ ti,cs-ta = <0>;
+ ti,cs-rhold = <8>;
+ ti,cs-rstrobe = <40>;
+ ti,cs-rsetup = <14>;
+ ti,cs-whold = <7>;
+ ti,cs-wstrobe = <40>;
+ ti,cs-wsetup = <14>;
+ ti,cs-asize = <1>;
+
+ flash@0,0x0000000 {
+ compatible = "cfi-flash";
+ reg = <0 0x0000000 0x4000000>;
+
+ ...
+ };
+ };
+};
--
1.8.3.2
^ permalink raw reply related
* RE: [PATCH v6 8/8] usb: ehci-exynos: Change to use phy provided by the generic phy framework
From: Alan Stern @ 2014-02-05 19:55 UTC (permalink / raw)
To: Kamil Debski
Cc: linux-kernel-u79uwXL29TY76Z2rM5mHXA,
linux-samsung-soc-u79uwXL29TY76Z2rM5mHXA,
linux-usb-u79uwXL29TY76Z2rM5mHXA,
devicetree-u79uwXL29TY76Z2rM5mHXA,
kyungmin.park-Sze3O3UU22JBDgjK7y7TUQ, kishon-l0cyMroinI0,
Tomasz Figa, Sylwester Nawrocki, Marek Szyprowski,
gautam.vivek-Sze3O3UU22JBDgjK7y7TUQ,
mat.krawczuk-Re5JQEeQqe8AvxtiuMwx3w,
yulgon.kim-Sze3O3UU22JBDgjK7y7TUQ,
p.paneri-Sze3O3UU22JBDgjK7y7TUQ,
av.tikhomirov-Sze3O3UU22JBDgjK7y7TUQ,
jg1.han-Sze3O3UU22JBDgjK7y7TUQ, galak-sgV2jX0FEOL9JmXXK+q4OQ,
matt.porter-QSEj5FYQhm4dnm+yROfE0A,
tjakobi-o02PS0xoJP9W0yFyLvAVXMxlOr/tl8fh
In-Reply-To: <054301cf228a$eb58a480$c209ed80$%debski-Sze3O3UU22JBDgjK7y7TUQ@public.gmane.org>
On Wed, 5 Feb 2014, Kamil Debski wrote:
> Hi Alan,
>
> Thank you for your review.
You're welcome.
> >
> > > Change the phy provider used from the old one using the USB phy
> > You have removed all the OTG stuff from the driver. This wasn't
> > mentioned in the patch description, and it has no connection with the
> > PHY work.
>
> Maybe I'll explain more about what are we trying to achieve. The goal
> is to replace the old phy driver with the new one. In the old driver it was
> difficult to add support to new SoC. It also had issues with having device
> and
> host working together.
>
> You're right that until the old phy driver is removed support for the it
> should
> remain. To be able to remove the old driver both new USB2 and new USB3 phy
> drivers
> have to be ready. The USB3 driver is written by Vivek Gautam and as I see
> it, he
> is also close to completion.
>
> Regarding the otg part. The old phy driver is the only provider of the otg
> structure. It sets the host field of the structure. It is then used by
> samsung_usb2phy_init (drivers/usb/phy/phy-samsung-usb2.c) to check which
> driver is requesting the phy (is it host or device). In the new driver this
> is determined by the entry in device tree. So no need to check the otg
> struct
> and strstr (!) to check if dev_name is ehci, ohci or other, like the old
> driver.
Okay, that's fine. But please explain this in the patch description
next time. Otherwise the connection between the phy driver and the otg
structure is not at all clear; they look like two unrelated things.
Alan Stern
--
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
* Re: [PATCH v3 0/6] IIO pulse capture support for TI ECAP
From: Sergei Shtylyov @ 2014-02-05 20:23 UTC (permalink / raw)
To: Matt Porter, Jonathan Cameron, Grant Likely, Rob Herring,
Benoît Cousson, Tony Lindgren, Pawel Moll, Mark Rutland,
Ian Campbell, Kumar Gala, Thierry Reding
Cc: Devicetree List, Linux PWM List, Linux IIO List,
Linux Kernel Mailing List, Linux OMAP List, Linux ARM Kernel List
In-Reply-To: <1391626901-31684-1-git-send-email-mporter@linaro.org>
Hello.
On 02/05/2014 10:01 PM, Matt Porter wrote:
[...]
> This series adds support for PWM capture devices within IIO and
> adds a TI ECAP IIO driver.
> PWM capture devices are supported using a new IIO "pulse" channel type.
> The IIO ECAP driver implements interrupt driven triggered buffer capture
> only as raw sample reads are not applicable to this hardware.
> Initially, the driver supports a single pulse width measurement with
> configurable polarity. The ECAP hardware can support measurement of a
> complete period and duty cycle but this is not yet implemented.
How about pulse counting? I have the hardware that can also count pulses
in addition to measuring the periods, so I'm interested in this work
(initially I supported it in driver/misc/ but it got turned down for iio).
WBR, Sergei
^ permalink raw reply
* Re: [PATCH v5 1/3] clocksource: timer-keystone: introduce clocksource driver for Keystone
From: Thomas Gleixner @ 2014-02-05 20:27 UTC (permalink / raw)
To: Ivan Khoronzhuk
Cc: santosh.shilimkar, rob, linux, galak, robh+dt, pawel.moll,
mark.rutland, ijc+devicetree, daniel.lezcano, devicetree,
linux-doc, linux-arm-kernel, linux-kernel, grygorii.strashko
In-Reply-To: <1391608060-10760-2-git-send-email-ivan.khoronzhuk@ti.com>
On Wed, 5 Feb 2014, Ivan Khoronzhuk wrote:
> + /* here we have to be sure the timer has been disabled */
Sigh. This is not a proper explanation for a barrier, really. You want
to explain what it serializes against what. i.e. you want to explain
why you are using the relaxed functions and avoid a separate non
relaxed variant in favour of an explicit barrier.
> + __iowmb();
The proper thing is to have an inline function key_stone_barrier() and
a full explanation of the issue in exactly that place instead of
handwaving comments here and there.
Thanks,
tglx
^ permalink raw reply
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox