* [PATCH v2 0/5] BCM59056 PMU regulator support
From: Matt Porter @ 2014-02-18 23:17 UTC (permalink / raw)
To: Rob Herring, Pawel Moll, Mark Rutland, Ian Campbell, Kumar Gala,
Samuel Ortiz, Lee Jones, Liam Girdwood, Mark Brown,
Christian Daudt
Cc: Devicetree List, Linux ARM Kernel List, Linux Kernel Mailing List
The BCM59056 is a multi-function power management unit used with the
BCM281xx family of SoCs. This series adds an MFD and voltage regulator
driver to support the BCM59056. The bcm28155-ap DT support is updated
to enable use of regulators on the otg and sdhci peripherals.
Changes since v1:
- renamed to bcm590xx to accomodate future family parts
- remove use of subsys_initcall
- fix BCM590XX_MAX_REGISTER value
- remove unused chip id in mfd of/i2c matching
- switch to of_platform_populate() in mfd
- update binding to single document with regulators as optional
properties in the regulator subdevice IP description
- remove unused regulator get/set mode ops
- remove unneeded regulator NULL constraint check
- regulators property is optional, allow the driver to probe
when it is missing
- move of_node presence check into bcm590xx_parse_dt_reg_data()
Matt Porter (5):
mfd: add bcm590xx pmu DT binding
mfd: add bcm590xx pmu driver
regulator: add bcm590xx regulator driver
ARM: configs: bcm_defconfig: enable bcm590xx regulator support
ARM: dts: add bcm590xx pmu support and enable for bcm28155-ap
Documentation/devicetree/bindings/mfd/bcm590xx.txt | 49 +++
arch/arm/boot/dts/bcm28155-ap.dts | 43 ++-
arch/arm/boot/dts/bcm59056.dtsi | 162 ++++++++
arch/arm/configs/bcm_defconfig | 7 +
drivers/mfd/Kconfig | 8 +
drivers/mfd/Makefile | 1 +
drivers/mfd/bcm590xx.c | 86 +++++
drivers/regulator/Kconfig | 8 +
drivers/regulator/Makefile | 1 +
drivers/regulator/bcm590xx-regulator.c | 419 +++++++++++++++++++++
include/linux/mfd/bcm590xx.h | 31 ++
11 files changed, 814 insertions(+), 1 deletion(-)
create mode 100644 Documentation/devicetree/bindings/mfd/bcm590xx.txt
create mode 100644 arch/arm/boot/dts/bcm59056.dtsi
create mode 100644 drivers/mfd/bcm590xx.c
create mode 100644 drivers/regulator/bcm590xx-regulator.c
create mode 100644 include/linux/mfd/bcm590xx.h
--
1.8.4
^ permalink raw reply
* Re: [PATCH v2] of_mdio: fix phy interrupt passing
From: David Miller @ 2014-02-18 23:13 UTC (permalink / raw)
To: grant.likely
Cc: ben.dooks, linux-kernel, devicetree, linux-kernel, netdev,
linux-sh, sergei.shtylyov
In-Reply-To: <20140218161551.44A52C40517@trevor.secretlab.ca>
From: Grant Likely <grant.likely@linaro.org>
Date: Tue, 18 Feb 2014 16:15:51 +0000
> On Tue, 18 Feb 2014 12:16:58 +0000, Ben Dooks <ben.dooks@codethink.co.uk> wrote:
>> The of_mdiobus_register_phy() is not setting phy->irq thus causing
>> some drivers to incorrectly assume that the PHY does not have an
>> IRQ associated with it. Not only do some drivers report no IRQ
>> they do not install an interrupt handler for the PHY.
>>
>> Simplify the code setting irq and set the phy->irq at the same
>> time so that we cover the following issues, which should cover
>> all the cases the code will find:
>>
>> - Set phy->irq if node has irq property and mdio->irq is NULL
>> - Set phy->irq if node has no irq and mdio->irq is not NULL
>> - Leave phy->irq as PHY_POLL default if none of the above
>>
>> This fixes the issue:
>> net eth0: attached PHY 1 (IRQ -1) to driver Micrel KSZ8041RNLI
>>
>> to the correct:
>> net eth0: attached PHY 1 (IRQ 416) to driver Micrel KSZ8041RNLI
>>
>> Signed-off-by: Ben Dooks <ben.dooks@codethink.co.uk>
>
> Looks okay to me
>
> Reviewed-by: Grant Likely <grant.likely@linaro.org>
Applied, thanks.
^ permalink raw reply
* [PATCH v2] net: ethoc: document OF bindings
From: Max Filippov @ 2014-02-18 22:46 UTC (permalink / raw)
To: netdev-u79uwXL29TY76Z2rM5mHXA, devicetree-u79uwXL29TY76Z2rM5mHXA,
linux-kernel-u79uwXL29TY76Z2rM5mHXA
Cc: David S. Miller, Grant Likely, Rob Herring, Sergei Shtylyov,
Florian Fainelli, Max Filippov
Signed-off-by: Max Filippov <jcmvbkbc-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
---
Changes v1->v2:
- drop local-mac-address optional property description
(described in the common ethernet.txt);
- drop optional properties for MDIO bus frequency and MAC frequency
(removed from the implementation);
- add clocks property.
.../devicetree/bindings/net/opencores-ethoc.txt | 22 ++++++++++++++++++++++
1 file changed, 22 insertions(+)
create mode 100644 Documentation/devicetree/bindings/net/opencores-ethoc.txt
diff --git a/Documentation/devicetree/bindings/net/opencores-ethoc.txt b/Documentation/devicetree/bindings/net/opencores-ethoc.txt
new file mode 100644
index 0000000..41e2675
--- /dev/null
+++ b/Documentation/devicetree/bindings/net/opencores-ethoc.txt
@@ -0,0 +1,22 @@
+* OpenCores MAC 10/100 Mbps
+
+Required properties:
+- compatible: Should be "opencores,ethoc".
+- reg: two memory regions (address and length),
+ first region is for the device registers and descriptor rings,
+ second is for the device packet memory.
+- interrupts: interrupt for the device.
+
+Optional properties:
+- clocks: phandle to refer to the clk used as per
+ Documentation/devicetree/bindings/clock/clock-bindings.txt
+
+Examples:
+
+ enet0: ethoc@fd030000 {
+ compatible = "opencores,ethoc";
+ reg = <0xfd030000 0x4000 0xfd800000 0x4000>;
+ interrupts = <1>;
+ local-mac-address = [00 50 c2 13 6f 00];
+ clocks = <&osc>;
+ };
--
1.8.1.4
--
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
* Re: devicetree repository separation/migration
From: Tim Bird @ 2014-02-18 22:44 UTC (permalink / raw)
To: Olof Johansson
Cc: Jason Cooper, Sascha Hauer, Grant Likely, Rob Herring,
Ian Campbell, Pawel Moll, Mark Rutland, Kumar Gala, Rob Landley,
devicetree-u79uwXL29TY76Z2rM5mHXA@public.gmane.org,
devicetree-spec-u79uwXL29TY76Z2rM5mHXA,
devicetree-compiler-u79uwXL29TY76Z2rM5mHXA
In-Reply-To: <CAOesGMi8zJXhfj46CLB-_Kk2s4MY9da46DhMoCtRj=zSUiuOGA-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org>
I'm not in favor of separating the device tree information from the kernel.
If we switch, then whatever synchronization issues other projects
are having now with synching with the device tree info from the kernel will
just then become the problem of the kernel developers, who will then
have to sync with the device tree info from another repository. If the
sync issues can't be solved now for them, why or how would it be solved
post-separation for us? (It sounds like a zero-sum game of pain transfer
to me.)
I'm relatively unfamiliar with the arguments. Can someone provide
a brief list of reasons this is needed, and how the inconvenience to Linux
kernel developers will be minimized, should it proceed?
Thanks,
-- Tim
On Tue, Feb 18, 2014 at 2:21 PM, Olof Johansson <olof-nZhT3qVonbNeoWH0uzbU5w@public.gmane.org> wrote:
> On Tue, Feb 18, 2014 at 11:47 AM, Olof Johansson <olof-nZhT3qVonbNeoWH0uzbU5w@public.gmane.org> wrote:
>> Breakage due to the move is something we should have to put up
>> with, etc.
>
> Typo. We absolutely must not have breakage due to this move.
>
>
> -Olof
> --
> 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
--
-- Tim Bird
Senior Software Engineer, Sony Mobile
Architecture Group Chair, CE Workgroup, Linux Foundation
--
To unsubscribe from this list: send the line "unsubscribe devicetree-spec" 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] dt: platform driver: Fill the resources before probe and defer if needed
From: Grant Likely @ 2014-02-18 22:34 UTC (permalink / raw)
To: Greg KH, Jean-Jacques Hiblot
Cc: robh+dt, linux-kernel, devicetree, gregory.clement,
linux-arm-kernel
In-Reply-To: <20140218202205.GA13835@kroah.com>
On Tue, 18 Feb 2014 12:22:05 -0800, Greg KH <gregkh@linuxfoundation.org> wrote:
> On Thu, Feb 13, 2014 at 10:57:09AM +0100, Jean-Jacques Hiblot wrote:
> > The goal of this patch is to allow drivers to be probed even if at the time of
> > the DT parsing some of their ressources are not available yet.
> >
> > In the current situation, the resource of a platform device are filled from the
> > DT at the time the device is created (of_device_alloc()). The drawbackof this
> > is that a device sitting close to the top of the DT (ahb for example) but
> > depending on ressources that are initialized later (IRQ domain dynamically
> > created for example) will fail to probe because the ressources don't exist
> > at this time.
> >
> > This patch fills the resource structure only before the device is probed and
> > will defer the probe if the resource are not available yet.
> >
> > Signed-off-by: Jean-Jacques Hiblot <jjhiblot@traphandler.com>
> > Reviewed-by: Gregory CLEMENT <gregory.clement@free-electrons.com>
> > ---
> > drivers/base/platform.c | 6 ++++
> > drivers/of/platform.c | 71 +++++++++++++++++++++++++++++----------------
> > include/linux/of_platform.h | 10 +++++++
> > 3 files changed, 62 insertions(+), 25 deletions(-)
>
> I need some others to ack this before I can take it...
Yes, please let me review it first, and I'll probably want to take it
through the devicetree branch.
g.
^ permalink raw reply
* [PATCH 4/4] of: Add self test for of_match_node()
From: Grant Likely @ 2014-02-18 22:31 UTC (permalink / raw)
To: devicetree, linux-kernel
Cc: Kevin Hao, Rob Herring, Sebastian Hesselbarth, Grant Likely
In-Reply-To: <1392762680-1498-1-git-send-email-grant.likely@linaro.org>
Adds a selftest function for the of_match_node function. of_match_node
is supposed to handle precedence for the compatible property as well as
the name and device_type values. This patch adds some test case data and
a function that makes sure each test node matches against the correct
entry of an of_device_id table.
This code was written to verify the new of_match_node() implementation
that is an earlier part of this series.
Currently all but one test passes. There is one scenario where the empty
"b/name2" node is getting matched against an entry without any
device_type property at all. It is unknown why this is, but it needs to
be solved before this patch can be committed. (However, this is testing
the new of_match_table implementation, which still does far better than
the old implementation which gets the precedence completely wrong.)
Signed-off-by: Grant Likely <grant.likely@linaro.org>
Cc: Kevin Hau <haokexin@gmail.com>
---
drivers/of/selftest.c | 67 +++++++++++++++++++++++++++++++
drivers/of/testcase-data/testcases.dtsi | 1 +
drivers/of/testcase-data/tests-match.dtsi | 19 +++++++++
3 files changed, 87 insertions(+)
create mode 100644 drivers/of/testcase-data/tests-match.dtsi
diff --git a/drivers/of/selftest.c b/drivers/of/selftest.c
index e21012bde639..6643d1920985 100644
--- a/drivers/of/selftest.c
+++ b/drivers/of/selftest.c
@@ -300,6 +300,72 @@ static void __init of_selftest_parse_interrupts_extended(void)
of_node_put(np);
}
+static struct of_device_id match_node_table[] = {
+ { .data = "A", .name = "name0", }, /* Name alone is lowest priority */
+ { .data = "B", .type = "type1", }, /* followed by type alone */
+
+ { .data = "Ca", .name = "name2", .type = "type1", }, /* followed by both together */
+ { .data = "Cb", .name = "name2", }, /* Only match when type doesn't match */
+ { .data = "Cc", .name = "name2", .type = "type2", },
+
+ { .data = "E", .compatible = "compat3" },
+ { .data = "G", .compatible = "compat2", },
+ { .data = "H", .compatible = "compat2", .name = "name5", },
+ { .data = "I", .compatible = "compat2", .type = "type1", },
+ { .data = "J", .compatible = "compat2", .type = "type1", .name = "name8", },
+ { .data = "K", .compatible = "compat2", .name = "name9", },
+ {}
+};
+
+static struct {
+ const char *path;
+ const char *data;
+} match_node_tests[] = {
+ { .path = "/testcase-data/match-node/name0", .data = "A", },
+ { .path = "/testcase-data/match-node/name1", .data = "B", },
+ { .path = "/testcase-data/match-node/a/name2", .data = "Ca", },
+ { .path = "/testcase-data/match-node/b/name2", .data = "Cb", },
+ { .path = "/testcase-data/match-node/c/name2", .data = "Cc", },
+ { .path = "/testcase-data/match-node/name3", .data = "E", },
+ { .path = "/testcase-data/match-node/name4", .data = "G", },
+ { .path = "/testcase-data/match-node/name5", .data = "H", },
+ { .path = "/testcase-data/match-node/name6", .data = "G", },
+ { .path = "/testcase-data/match-node/name7", .data = "I", },
+ { .path = "/testcase-data/match-node/name8", .data = "J", },
+ { .path = "/testcase-data/match-node/name9", .data = "K", },
+};
+
+static void __init of_selftest_match_node(void)
+{
+ struct device_node *np;
+ const struct of_device_id *match;
+ int i;
+
+ for (i = 0; i < ARRAY_SIZE(match_node_tests); i++) {
+ np = of_find_node_by_path(match_node_tests[i].path);
+ if (!np) {
+ selftest(0, "missing testcase node %s\n",
+ match_node_tests[i].path);
+ continue;
+ }
+
+ match = of_match_node(match_node_table, np);
+ if (!match) {
+ selftest(0, "%s didn't match anything\n",
+ match_node_tests[i].path);
+ continue;
+ }
+
+ if (strcmp(match->data, match_node_tests[i].data) != 0) {
+ selftest(0, "%s got wrong match. expected %s, got %s\n",
+ match_node_tests[i].path, match_node_tests[i].data,
+ (const char *)match->data);
+ continue;
+ }
+ selftest(1, "passed");
+ }
+}
+
static int __init of_selftest(void)
{
struct device_node *np;
@@ -316,6 +382,7 @@ static int __init of_selftest(void)
of_selftest_property_match_string();
of_selftest_parse_interrupts();
of_selftest_parse_interrupts_extended();
+ of_selftest_match_node();
pr_info("end of selftest - %i passed, %i failed\n",
selftest_results.passed, selftest_results.failed);
return 0;
diff --git a/drivers/of/testcase-data/testcases.dtsi b/drivers/of/testcase-data/testcases.dtsi
index 3cc2f55534ac..3a5b75a8e4d7 100644
--- a/drivers/of/testcase-data/testcases.dtsi
+++ b/drivers/of/testcase-data/testcases.dtsi
@@ -1,2 +1,3 @@
#include "tests-phandle.dtsi"
#include "tests-interrupts.dtsi"
+#include "tests-match.dtsi"
diff --git a/drivers/of/testcase-data/tests-match.dtsi b/drivers/of/testcase-data/tests-match.dtsi
new file mode 100644
index 000000000000..c9e541129534
--- /dev/null
+++ b/drivers/of/testcase-data/tests-match.dtsi
@@ -0,0 +1,19 @@
+
+/ {
+ testcase-data {
+ match-node {
+ name0 { };
+ name1 { device_type = "type1"; };
+ a { name2 { device_type = "type1"; }; };
+ b { name2 { }; };
+ c { name2 { device_type = "type2"; }; };
+ name3 { compatible = "compat3"; };
+ name4 { compatible = "compat2", "compat3"; };
+ name5 { compatible = "compat2", "compat3"; };
+ name6 { compatible = "compat1", "compat2", "compat3"; };
+ name7 { compatible = "compat2"; device_type = "type1"; };
+ name8 { compatible = "compat2"; device_type = "type1"; };
+ name9 { compatible = "compat2"; };
+ };
+ };
+};
--
1.8.3.2
^ permalink raw reply related
* [PATCH 3/4] of: Move testcase FDT data into drivers/of
From: Grant Likely @ 2014-02-18 22:31 UTC (permalink / raw)
To: devicetree, linux-kernel
Cc: Kevin Hao, Rob Herring, Sebastian Hesselbarth, Grant Likely
In-Reply-To: <1392762680-1498-1-git-send-email-grant.likely@linaro.org>
The testcase data is usable by any platform. This patch moves it into
the drivers/of directory so it can be included by any architecture.
Using the test cases requires manually adding #include <testcases.dtsi>
to the end of the boards .dtsi file and enabling CONFIG_OF_SELFTEST. Not
pretty though. A useful project would be to make the testcase code
easier to execute.
Signed-off-by: Grant Likely <grant.likely@linaro.org>
---
arch/arm/boot/dts/testcases/tests-interrupts.dtsi | 58 -----------------------
arch/arm/boot/dts/testcases/tests-phandle.dtsi | 39 ---------------
arch/arm/boot/dts/testcases/tests.dtsi | 2 -
arch/arm/boot/dts/versatile-pb.dts | 4 +-
drivers/of/testcase-data/testcases.dtsi | 2 +
drivers/of/testcase-data/tests-interrupts.dtsi | 58 +++++++++++++++++++++++
drivers/of/testcase-data/tests-phandle.dtsi | 39 +++++++++++++++
scripts/Makefile.lib | 1 +
8 files changed, 102 insertions(+), 101 deletions(-)
delete mode 100644 arch/arm/boot/dts/testcases/tests-interrupts.dtsi
delete mode 100644 arch/arm/boot/dts/testcases/tests-phandle.dtsi
delete mode 100644 arch/arm/boot/dts/testcases/tests.dtsi
create mode 100644 drivers/of/testcase-data/testcases.dtsi
create mode 100644 drivers/of/testcase-data/tests-interrupts.dtsi
create mode 100644 drivers/of/testcase-data/tests-phandle.dtsi
diff --git a/arch/arm/boot/dts/testcases/tests-interrupts.dtsi b/arch/arm/boot/dts/testcases/tests-interrupts.dtsi
deleted file mode 100644
index c843720bd3e5..000000000000
--- a/arch/arm/boot/dts/testcases/tests-interrupts.dtsi
+++ /dev/null
@@ -1,58 +0,0 @@
-
-/ {
- testcase-data {
- interrupts {
- #address-cells = <1>;
- #size-cells = <1>;
- test_intc0: intc0 {
- interrupt-controller;
- #interrupt-cells = <1>;
- };
-
- test_intc1: intc1 {
- interrupt-controller;
- #interrupt-cells = <3>;
- };
-
- test_intc2: intc2 {
- interrupt-controller;
- #interrupt-cells = <2>;
- };
-
- test_intmap0: intmap0 {
- #interrupt-cells = <1>;
- #address-cells = <0>;
- interrupt-map = <1 &test_intc0 9>,
- <2 &test_intc1 10 11 12>,
- <3 &test_intc2 13 14>,
- <4 &test_intc2 15 16>;
- };
-
- test_intmap1: intmap1 {
- #interrupt-cells = <2>;
- interrupt-map = <0x5000 1 2 &test_intc0 15>;
- };
-
- interrupts0 {
- interrupt-parent = <&test_intc0>;
- interrupts = <1>, <2>, <3>, <4>;
- };
-
- interrupts1 {
- interrupt-parent = <&test_intmap0>;
- interrupts = <1>, <2>, <3>, <4>;
- };
-
- interrupts-extended0 {
- reg = <0x5000 0x100>;
- interrupts-extended = <&test_intc0 1>,
- <&test_intc1 2 3 4>,
- <&test_intc2 5 6>,
- <&test_intmap0 1>,
- <&test_intmap0 2>,
- <&test_intmap0 3>,
- <&test_intmap1 1 2>;
- };
- };
- };
-};
diff --git a/arch/arm/boot/dts/testcases/tests-phandle.dtsi b/arch/arm/boot/dts/testcases/tests-phandle.dtsi
deleted file mode 100644
index 0007d3cd7dc2..000000000000
--- a/arch/arm/boot/dts/testcases/tests-phandle.dtsi
+++ /dev/null
@@ -1,39 +0,0 @@
-
-/ {
- testcase-data {
- phandle-tests {
- provider0: provider0 {
- #phandle-cells = <0>;
- };
-
- provider1: provider1 {
- #phandle-cells = <1>;
- };
-
- provider2: provider2 {
- #phandle-cells = <2>;
- };
-
- provider3: provider3 {
- #phandle-cells = <3>;
- };
-
- consumer-a {
- phandle-list = <&provider1 1>,
- <&provider2 2 0>,
- <0>,
- <&provider3 4 4 3>,
- <&provider2 5 100>,
- <&provider0>,
- <&provider1 7>;
- phandle-list-names = "first", "second", "third";
-
- phandle-list-bad-phandle = <12345678 0 0>;
- phandle-list-bad-args = <&provider2 1 0>,
- <&provider3 0>;
- empty-property;
- unterminated-string = [40 41 42 43];
- };
- };
- };
-};
diff --git a/arch/arm/boot/dts/testcases/tests.dtsi b/arch/arm/boot/dts/testcases/tests.dtsi
deleted file mode 100644
index 3f123ecc9dd7..000000000000
--- a/arch/arm/boot/dts/testcases/tests.dtsi
+++ /dev/null
@@ -1,2 +0,0 @@
-/include/ "tests-phandle.dtsi"
-/include/ "tests-interrupts.dtsi"
diff --git a/arch/arm/boot/dts/versatile-pb.dts b/arch/arm/boot/dts/versatile-pb.dts
index f43907c40c93..65f657711323 100644
--- a/arch/arm/boot/dts/versatile-pb.dts
+++ b/arch/arm/boot/dts/versatile-pb.dts
@@ -1,4 +1,4 @@
-/include/ "versatile-ab.dts"
+#include <versatile-ab.dts>
/ {
model = "ARM Versatile PB";
@@ -47,4 +47,4 @@
};
};
-/include/ "testcases/tests.dtsi"
+#include <testcases.dtsi>
diff --git a/drivers/of/testcase-data/testcases.dtsi b/drivers/of/testcase-data/testcases.dtsi
new file mode 100644
index 000000000000..3cc2f55534ac
--- /dev/null
+++ b/drivers/of/testcase-data/testcases.dtsi
@@ -0,0 +1,2 @@
+#include "tests-phandle.dtsi"
+#include "tests-interrupts.dtsi"
diff --git a/drivers/of/testcase-data/tests-interrupts.dtsi b/drivers/of/testcase-data/tests-interrupts.dtsi
new file mode 100644
index 000000000000..c843720bd3e5
--- /dev/null
+++ b/drivers/of/testcase-data/tests-interrupts.dtsi
@@ -0,0 +1,58 @@
+
+/ {
+ testcase-data {
+ interrupts {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ test_intc0: intc0 {
+ interrupt-controller;
+ #interrupt-cells = <1>;
+ };
+
+ test_intc1: intc1 {
+ interrupt-controller;
+ #interrupt-cells = <3>;
+ };
+
+ test_intc2: intc2 {
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ };
+
+ test_intmap0: intmap0 {
+ #interrupt-cells = <1>;
+ #address-cells = <0>;
+ interrupt-map = <1 &test_intc0 9>,
+ <2 &test_intc1 10 11 12>,
+ <3 &test_intc2 13 14>,
+ <4 &test_intc2 15 16>;
+ };
+
+ test_intmap1: intmap1 {
+ #interrupt-cells = <2>;
+ interrupt-map = <0x5000 1 2 &test_intc0 15>;
+ };
+
+ interrupts0 {
+ interrupt-parent = <&test_intc0>;
+ interrupts = <1>, <2>, <3>, <4>;
+ };
+
+ interrupts1 {
+ interrupt-parent = <&test_intmap0>;
+ interrupts = <1>, <2>, <3>, <4>;
+ };
+
+ interrupts-extended0 {
+ reg = <0x5000 0x100>;
+ interrupts-extended = <&test_intc0 1>,
+ <&test_intc1 2 3 4>,
+ <&test_intc2 5 6>,
+ <&test_intmap0 1>,
+ <&test_intmap0 2>,
+ <&test_intmap0 3>,
+ <&test_intmap1 1 2>;
+ };
+ };
+ };
+};
diff --git a/drivers/of/testcase-data/tests-phandle.dtsi b/drivers/of/testcase-data/tests-phandle.dtsi
new file mode 100644
index 000000000000..0007d3cd7dc2
--- /dev/null
+++ b/drivers/of/testcase-data/tests-phandle.dtsi
@@ -0,0 +1,39 @@
+
+/ {
+ testcase-data {
+ phandle-tests {
+ provider0: provider0 {
+ #phandle-cells = <0>;
+ };
+
+ provider1: provider1 {
+ #phandle-cells = <1>;
+ };
+
+ provider2: provider2 {
+ #phandle-cells = <2>;
+ };
+
+ provider3: provider3 {
+ #phandle-cells = <3>;
+ };
+
+ consumer-a {
+ phandle-list = <&provider1 1>,
+ <&provider2 2 0>,
+ <0>,
+ <&provider3 4 4 3>,
+ <&provider2 5 100>,
+ <&provider0>,
+ <&provider1 7>;
+ phandle-list-names = "first", "second", "third";
+
+ phandle-list-bad-phandle = <12345678 0 0>;
+ phandle-list-bad-args = <&provider2 1 0>,
+ <&provider3 0>;
+ empty-property;
+ unterminated-string = [40 41 42 43];
+ };
+ };
+ };
+};
diff --git a/scripts/Makefile.lib b/scripts/Makefile.lib
index 49392ecbef17..79c059e70860 100644
--- a/scripts/Makefile.lib
+++ b/scripts/Makefile.lib
@@ -152,6 +152,7 @@ ld_flags = $(LDFLAGS) $(ldflags-y)
dtc_cpp_flags = -Wp,-MD,$(depfile).pre.tmp -nostdinc \
-I$(srctree)/arch/$(SRCARCH)/boot/dts \
-I$(srctree)/arch/$(SRCARCH)/boot/dts/include \
+ -I$(srctree)/drivers/of/testcase-data \
-undef -D__DTS__
# Finds the multi-part object the current object will be linked into
--
1.8.3.2
^ permalink raw reply related
* [PATCH 2/4] of: reimplement the matching method for __of_match_node()
From: Grant Likely @ 2014-02-18 22:31 UTC (permalink / raw)
To: devicetree-u79uwXL29TY76Z2rM5mHXA,
linux-kernel-u79uwXL29TY76Z2rM5mHXA
Cc: Kevin Hao, Rob Herring, Sebastian Hesselbarth, Grant Likely
In-Reply-To: <1392762680-1498-1-git-send-email-grant.likely-QSEj5FYQhm4dnm+yROfE0A@public.gmane.org>
From: Kevin Hao <haokexin-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
In the current implementation of __of_match_node(), it will compare
each given match entry against all the node's compatible strings
with of_device_is_compatible().
To achieve multiple compatible strings per node with ordering from
specific to generic, this requires given matches to be ordered from
specific to generic. For most of the drivers this is not true and
also an alphabetical ordering is more sane there.
Therefore, we define a following priority order for the match, and
then scan all the entries to find the best match.
1. specific compatible && type && name
2. specific compatible && type
3. specific compatible && name
4. specific compatible
5. general compatible && type && name
6. general compatible && type
7. general compatible && name
8. general compatible
9. type && name
10. type
11. name
This is based on some pseudo-codes provided by Grant Likely.
Signed-off-by: Kevin Hao <haokexin-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org
[grant.likely: Changed multiplier to 4 which makes more sense]
Signed-off-by: Grant Likely <grant.likely-QSEj5FYQhm4dnm+yROfE0A@public.gmane.org>
---
drivers/of/base.c | 87 +++++++++++++++++++++++++++++++++++++++++++------------
1 file changed, 68 insertions(+), 19 deletions(-)
diff --git a/drivers/of/base.c b/drivers/of/base.c
index ba195fbce4c6..6e893f6f19a9 100644
--- a/drivers/of/base.c
+++ b/drivers/of/base.c
@@ -342,21 +342,28 @@ struct device_node *of_get_cpu_node(int cpu, unsigned int *thread)
}
EXPORT_SYMBOL(of_get_cpu_node);
-/** Checks if the given "compat" string matches one of the strings in
- * the device's "compatible" property
+/*
+ * Compare with the __of_device_is_compatible, this will return a score for the
+ * matching strings. The smaller value indicates the match for the more specific
+ * compatible string.
*/
-static int __of_device_is_compatible(const struct device_node *device,
- const char *compat)
+static int __of_device_is_compatible_score(const struct device_node *device,
+ const char *compat, unsigned int *pscore)
{
const char* cp;
int cplen, l;
+ unsigned int score = 0;
cp = __of_get_property(device, "compatible", &cplen);
if (cp == NULL)
return 0;
while (cplen > 0) {
- if (of_compat_cmp(cp, compat, strlen(compat)) == 0)
+ score++;
+ if (of_compat_cmp(cp, compat, strlen(compat)) == 0) {
+ if (pscore)
+ *pscore = score;
return 1;
+ }
l = strlen(cp) + 1;
cp += l;
cplen -= l;
@@ -368,6 +375,15 @@ static int __of_device_is_compatible(const struct device_node *device,
/** Checks if the given "compat" string matches one of the strings in
* the device's "compatible" property
*/
+static int __of_device_is_compatible(const struct device_node *device,
+ const char *compat)
+{
+ return __of_device_is_compatible_score(device, compat, NULL);
+}
+
+/** Checks if the given "compat" string matches one of the strings in
+ * the device's "compatible" property
+ */
int of_device_is_compatible(const struct device_node *device,
const char *compat)
{
@@ -734,25 +750,46 @@ static
const struct of_device_id *__of_match_node(const struct of_device_id *matches,
const struct device_node *node)
{
+ const struct of_device_id *best_match = NULL;
+ unsigned int best_score = ~0;
+
if (!matches)
return NULL;
while (matches->name[0] || matches->type[0] || matches->compatible[0]) {
- int match = 1;
- if (matches->name[0])
- match &= node->name
- && !strcmp(matches->name, node->name);
- if (matches->type[0])
- match &= node->type
- && !strcmp(matches->type, node->type);
- if (matches->compatible[0])
- match &= __of_device_is_compatible(node,
- matches->compatible);
- if (match)
- return matches;
+ unsigned int score = ~0;
+
+ /*
+ * Matching compatible is better than matching type and name,
+ * and the specific compatible is better than the general.
+ */
+ if (matches->compatible[0] &&
+ __of_device_is_compatible_score(node,
+ matches->compatible, &score))
+ score *= 4;
+
+ /*
+ * Matching type is better than matching name, but matching
+ * both is even better than that.
+ */
+ if (matches->type[0] && node->type &&
+ !strcmp(matches->type, node->type))
+ score -= 2;
+
+ /* Matching name is a bit better than not */
+ if (matches->name[0] && node->name &&
+ !strcmp(matches->name, node->name))
+ score--;
+
+ if (score < best_score) {
+ best_match = matches;
+ best_score = score;
+ }
+
matches++;
}
- return NULL;
+
+ return best_match;
}
/**
@@ -760,7 +797,19 @@ const struct of_device_id *__of_match_node(const struct of_device_id *matches,
* @matches: array of of device match structures to search in
* @node: the of device structure to match against
*
- * Low level utility function used by device matching.
+ * Low level utility function used by device matching. The priority order
+ * for the matching is:
+ * 1. specific compatible && type && name
+ * 2. specific compatible && type
+ * 3. specific compatible && name
+ * 4. specific compatible
+ * 5. general compatible && type && name
+ * 6. general compatible && type
+ * 7. general compatible && name
+ * 8. general compatible
+ * 9. type && name
+ * 10. type
+ * 11. name
*/
const struct of_device_id *of_match_node(const struct of_device_id *matches,
const struct device_node *node)
--
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 1/4] Revert "of: search the best compatible match first in __of_match_node()"
From: Grant Likely @ 2014-02-18 22:31 UTC (permalink / raw)
To: devicetree, linux-kernel
Cc: Kevin Hao, Rob Herring, Sebastian Hesselbarth, Grant Likely
In-Reply-To: <1392762680-1498-1-git-send-email-grant.likely@linaro.org>
From: Kevin Hao <haokexin@gmail.com>
This reverts commit 06b29e76a74b2373e6f8b5a7938b3630b9ae98b2.
As pointed out by Grant Likely, we should also take the type and name
into account when searching the best compatible match. That means the
match with compatible, type and name should be better than the match
just with the same compatible string. So revert this and we will
implement another method to find the best match entry.
Signed-off-by: Kevin Hao <haokexin@gmail.com>
Signed-off-by: Grant Likely <grant.likely@linaro.org>
---
drivers/of/base.c | 43 +------------------------------------------
1 file changed, 1 insertion(+), 42 deletions(-)
diff --git a/drivers/of/base.c b/drivers/of/base.c
index 10b51106c854..ba195fbce4c6 100644
--- a/drivers/of/base.c
+++ b/drivers/of/base.c
@@ -730,49 +730,13 @@ out:
}
EXPORT_SYMBOL(of_find_node_with_property);
-static const struct of_device_id *
-of_match_compatible(const struct of_device_id *matches,
- const struct device_node *node)
-{
- const char *cp;
- int cplen, l;
- const struct of_device_id *m;
-
- cp = __of_get_property(node, "compatible", &cplen);
- while (cp && (cplen > 0)) {
- m = matches;
- while (m->name[0] || m->type[0] || m->compatible[0]) {
- /* Only match for the entries without type and name */
- if (m->name[0] || m->type[0] ||
- of_compat_cmp(m->compatible, cp,
- strlen(m->compatible)))
- m++;
- else
- return m;
- }
-
- /* Get node's next compatible string */
- l = strlen(cp) + 1;
- cp += l;
- cplen -= l;
- }
-
- return NULL;
-}
-
static
const struct of_device_id *__of_match_node(const struct of_device_id *matches,
const struct device_node *node)
{
- const struct of_device_id *m;
-
if (!matches)
return NULL;
- m = of_match_compatible(matches, node);
- if (m)
- return m;
-
while (matches->name[0] || matches->type[0] || matches->compatible[0]) {
int match = 1;
if (matches->name[0])
@@ -796,12 +760,7 @@ const struct of_device_id *__of_match_node(const struct of_device_id *matches,
* @matches: array of of device match structures to search in
* @node: the of device structure to match against
*
- * Low level utility function used by device matching. We have two ways
- * of matching:
- * - Try to find the best compatible match by comparing each compatible
- * string of device node with all the given matches respectively.
- * - If the above method failed, then try to match the compatible by using
- * __of_device_is_compatible() besides the match in type and name.
+ * Low level utility function used by device matching.
*/
const struct of_device_id *of_match_node(const struct of_device_id *matches,
const struct device_node *node)
--
1.8.3.2
^ permalink raw reply related
* Bug fix and test matching method for of_match_node()
From: Grant Likely @ 2014-02-18 22:31 UTC (permalink / raw)
To: devicetree, linux-kernel; +Cc: Kevin Hao, Rob Herring, Sebastian Hesselbarth
This series fixes the matching order in of_match_node() and adds some
test cases to make sure the ordering is working correctly. It mostly
works, but there is one test case that fails. I haven't debugged yet
whether the problem is of_match_node() or the testcase itself.
^ permalink raw reply
* Re: [PATCH 2/2] of: reimplement the matching method for __of_match_node()
From: Grant Likely @ 2014-02-18 22:29 UTC (permalink / raw)
To: devicetree-u79uwXL29TY76Z2rM5mHXA
Cc: Kevin Hao, Sebastian Hesselbarth, Stephen N Chivers, Rob Herring
In-Reply-To: <1392710250-29913-3-git-send-email-haokexin-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
On Tue, 18 Feb 2014 15:57:30 +0800, Kevin Hao <haokexin-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org> wrote:
> In the current implementation of __of_match_node(), it will compare
> each given match entry against all the node's compatible strings
> with of_device_is_compatible().
>
> To achieve multiple compatible strings per node with ordering from
> specific to generic, this requires given matches to be ordered from
> specific to generic. For most of the drivers this is not true and
> also an alphabetical ordering is more sane there.
>
> Therefore, we define a following priority order for the match, and
> then scan all the entries to find the best match.
> 1. specific compatible && type && name
> 2. specific compatible && type
> 3. specific compatible && name
> 4. specific compatible
> 5. general compatible && type && name
> 6. general compatible && type
> 7. general compatible && name
> 8. general compatible
> 9. type && name
> 10. type
> 11. name
>
> This is based on some pseudo-codes provided by Grant Likely.
The patch looks good, but I wasn't confident applying it directly
without some validation, so I've written a test case for this function.
I'll resend the series to the list and cc you. Unfortunately I've found
one case that is failing on the test cases, but I'm too tired to debug
it now. Maybe you'd like to take a look. The test case may very well be
wrong.
g.
>
> Signed-off-by: Kevin Hao <haokexin-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
> ---
> drivers/of/base.c | 87 +++++++++++++++++++++++++++++++++++++++++++------------
> 1 file changed, 68 insertions(+), 19 deletions(-)
>
> diff --git a/drivers/of/base.c b/drivers/of/base.c
> index ba195fbce4c6..378091f8460c 100644
> --- a/drivers/of/base.c
> +++ b/drivers/of/base.c
> @@ -342,21 +342,28 @@ struct device_node *of_get_cpu_node(int cpu, unsigned int *thread)
> }
> EXPORT_SYMBOL(of_get_cpu_node);
>
> -/** Checks if the given "compat" string matches one of the strings in
> - * the device's "compatible" property
> +/*
> + * Compare with the __of_device_is_compatible, this will return a score for the
> + * matching strings. The smaller value indicates the match for the more specific
> + * compatible string.
> */
> -static int __of_device_is_compatible(const struct device_node *device,
> - const char *compat)
> +static int __of_device_is_compatible_score(const struct device_node *device,
> + const char *compat, unsigned int *pscore)
> {
> const char* cp;
> int cplen, l;
> + unsigned int score = 0;
>
> cp = __of_get_property(device, "compatible", &cplen);
> if (cp == NULL)
> return 0;
> while (cplen > 0) {
> - if (of_compat_cmp(cp, compat, strlen(compat)) == 0)
> + score++;
> + if (of_compat_cmp(cp, compat, strlen(compat)) == 0) {
> + if (pscore)
> + *pscore = score;
> return 1;
> + }
> l = strlen(cp) + 1;
> cp += l;
> cplen -= l;
> @@ -368,6 +375,15 @@ static int __of_device_is_compatible(const struct device_node *device,
> /** Checks if the given "compat" string matches one of the strings in
> * the device's "compatible" property
> */
> +static int __of_device_is_compatible(const struct device_node *device,
> + const char *compat)
> +{
> + return __of_device_is_compatible_score(device, compat, NULL);
> +}
> +
> +/** Checks if the given "compat" string matches one of the strings in
> + * the device's "compatible" property
> + */
> int of_device_is_compatible(const struct device_node *device,
> const char *compat)
> {
> @@ -734,25 +750,46 @@ static
> const struct of_device_id *__of_match_node(const struct of_device_id *matches,
> const struct device_node *node)
> {
> + const struct of_device_id *best_match = NULL;
> + unsigned int best_score = ~0;
> +
> if (!matches)
> return NULL;
>
> while (matches->name[0] || matches->type[0] || matches->compatible[0]) {
> - int match = 1;
> - if (matches->name[0])
> - match &= node->name
> - && !strcmp(matches->name, node->name);
> - if (matches->type[0])
> - match &= node->type
> - && !strcmp(matches->type, node->type);
> - if (matches->compatible[0])
> - match &= __of_device_is_compatible(node,
> - matches->compatible);
> - if (match)
> - return matches;
> + unsigned int score = ~0;
> +
> + /*
> + * Matching compatible is better than matching type and name,
> + * and the specific compatible is better than the general.
> + */
> + if (matches->compatible[0] &&
> + __of_device_is_compatible_score(node,
> + matches->compatible, &score))
> + score *= 10;
> +
> + /*
> + * Matching type is better than matching name, but matching
> + * both is even better than that.
> + */
> + if (matches->type[0] && node->type &&
> + !strcmp(matches->type, node->type))
> + score -= 2;
> +
> + /* Matching name is a bit better than not */
> + if (matches->name[0] && node->name &&
> + !strcmp(matches->name, node->name))
> + score--;
> +
> + if (score < best_score) {
> + best_match = matches;
> + best_score = score;
> + }
> +
> matches++;
> }
> - return NULL;
> +
> + return best_match;
> }
>
> /**
> @@ -760,7 +797,19 @@ const struct of_device_id *__of_match_node(const struct of_device_id *matches,
> * @matches: array of of device match structures to search in
> * @node: the of device structure to match against
> *
> - * Low level utility function used by device matching.
> + * Low level utility function used by device matching. The priority order
> + * for the matching is:
> + * 1. specific compatible && type && name
> + * 2. specific compatible && type
> + * 3. specific compatible && name
> + * 4. specific compatible
> + * 5. general compatible && type && name
> + * 6. general compatible && type
> + * 7. general compatible && name
> + * 8. general compatible
> + * 9. type && name
> + * 10. type
> + * 11. name
> */
> const struct of_device_id *of_match_node(const struct of_device_id *matches,
> const struct device_node *node)
> --
> 1.8.5.3
>
--
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 v4] sh_eth: add device tree support
From: David Miller @ 2014-02-18 22:21 UTC (permalink / raw)
To: sergei.shtylyov
Cc: robh+dt, pawel.moll, mark.rutland, grant.likely, devicetree,
linux-sh, ijc+devicetree, galak, netdev, nobuhiro.iwamatsu.yj,
rob, linux-doc
In-Reply-To: <201402180312.44775.sergei.shtylyov@cogentembedded.com>
From: Sergei Shtylyov <sergei.shtylyov@cogentembedded.com>
Date: Tue, 18 Feb 2014 03:12:43 +0300
> Add support of the device tree probing for the Renesas SH-Mobile SoCs
> documenting the device tree binding as necessary.
>
> This work is loosely based on the original patch by Nobuhiro Iwamatsu
> <nobuhiro.iwamatsu.yj@renesas.com>.
>
> Signed-off-by: Sergei Shtylyov <sergei.shtylyov@cogentembedded.com>
Also applied, thanks.
^ permalink raw reply
* Re: devicetree repository separation/migration
From: Olof Johansson @ 2014-02-18 22:21 UTC (permalink / raw)
To: Jason Cooper
Cc: Sascha Hauer, Grant Likely, Rob Herring, Ian Campbell, Pawel Moll,
Mark Rutland, Kumar Gala, Rob Landley,
devicetree-u79uwXL29TY76Z2rM5mHXA@public.gmane.org,
devicetree-spec-u79uwXL29TY76Z2rM5mHXA,
devicetree-compiler-u79uwXL29TY76Z2rM5mHXA
In-Reply-To: <CAOesGMhvoB7vRf3H1kMaL5+MgZ2gJy=ZVNU0gsXVye9S4YGBOg-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org>
On Tue, Feb 18, 2014 at 11:47 AM, Olof Johansson <olof-nZhT3qVonbNeoWH0uzbU5w@public.gmane.org> wrote:
> Breakage due to the move is something we should have to put up
> with, etc.
Typo. We absolutely must not have breakage due to this move.
-Olof
--
To unsubscribe from this list: send the line "unsubscribe devicetree-compiler" 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: devicetree repository separation/migration
From: Frank Rowand @ 2014-02-18 22:14 UTC (permalink / raw)
To: Jason Cooper
Cc: Sascha Hauer, Grant Likely, Rob Herring, Ian Campbell,
pawel.moll-5wv7dgnIgG8, mark.rutland-5wv7dgnIgG8,
galak-sgV2jX0FEOL9JmXXK+q4OQ, rob-VoJi6FS/r0vR7s880joybQ,
devicetree-u79uwXL29TY76Z2rM5mHXA,
devicetree-spec-u79uwXL29TY76Z2rM5mHXA,
devicetree-compiler-u79uwXL29TY76Z2rM5mHXA
In-Reply-To: <20140218181854.GB7862-u4khhh1J0LxI1Ri9qeTfzeTW4wlIGRCZ@public.gmane.org>
On 2/18/2014 10:18 AM, Jason Cooper wrote:
> On Tue, Feb 18, 2014 at 04:57:50PM +0100, Sascha Hauer wrote:
>> On Mon, Feb 17, 2014 at 01:05:44PM -0500, Jason Cooper wrote:
> ...
>>> - Is the Linux development workflow ready for devicetree to move out
>>> of the Linux Kernel?
>>
>> I hope so since keeping the devicetrees in sync with the kernel is a
>> pain for all external users.
>
> Well, I haven't heard any screams yet. I suspect people are waiting for
> details on the exact form it would take before complaining...
< snip >
Let me join the chorus of screams.
I would venture that the number of linux kernel developers actively
touching device tree source files (and impacted by changes to them)
is vastly larger than any other set of developers.
My experience in the kernel is already that finding working device
tree fragments that match current under development code is difficult.
(I am not trying to generalize for all systems, just the ones I use.)
Moving the device tree source files out of the kernel git tree will
only make things worse.
-Frank
--
To unsubscribe from this list: send the line "unsubscribe devicetree-compiler" 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] ARM: dts: qcom: Add RNG device tree node
From: Stephen Boyd @ 2014-02-18 22:13 UTC (permalink / raw)
To: Stanimir Varbanov
Cc: devicetree, linux-arm-kernel, linux-arm-msm, Kumar Gala,
Mark Rutland, Rob Herring, Pawel Moll, Ian Campbell, David Brown
In-Reply-To: <52FB3EB5.4020207@mm-sol.com>
On 02/12, Stanimir Varbanov wrote:
> Hi, Stephen
>
> On 02/08/2014 05:37 AM, Stephen Boyd wrote:
> > On 02/07, Stanimir Varbanov wrote:
> >> Add the necessary DT node to probe the rng driver on
> >> msm8974 platforms.
> >>
> >
> > Looks good. We should add it to msm8960-cdp and enable the driver
> > in the defconfig as well.
>
> Sure, I can prepare a patch. Unfortunately I haven't msm8960 CDP to test it.
>
No problem. I have one on my desk and can run a test if you like.
--
Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum,
hosted by The Linux Foundation
^ permalink raw reply
* Re: [PATCH v5] DT: net: document Ethernet bindings in one place
From: David Miller @ 2014-02-18 22:05 UTC (permalink / raw)
To: sergei.shtylyov
Cc: robh+dt, pawel.moll, mark.rutland, ijc+devicetree, galak,
devicetree, netdev, rob, linux-doc, jcmvbkbc, linux-sh
In-Reply-To: <201402180242.00796.sergei.shtylyov@cogentembedded.com>
From: Sergei Shtylyov <sergei.shtylyov@cogentembedded.com>
Date: Tue, 18 Feb 2014 02:41:59 +0300
> This patch is an attempt to gather the Ethernet related bindings in one file,
> like it's done in the MMC and some other subsystems. It should save some of
> the trouble of documenting several properties over and over in each binding
> document, instead only making reference to the main file.
>
> I have used the Embedded Power Architecture(TM) Platform Requirements (ePAPR)
> standard as a base for the properties description, also documenting some ad-hoc
> properties that have been introduced over time despite having direct analogs in
> ePAPR.
>
> Signed-off-by: Sergei Shtylyov <sergei.shtylyov@cogentembedded.com>
Applied, thanks Sergei.
^ permalink raw reply
* Re: [PATCH v2 2/3] usb: chipidea: msm: Add device tree support
From: Courtney Cavin @ 2014-02-18 21:34 UTC (permalink / raw)
To: Sergei Shtylyov
Cc: Ivan T. Ivanov, Peter Chen, Grant Likely, Rob Herring,
Greg Kroah-Hartman,
linux-usb-u79uwXL29TY76Z2rM5mHXA@public.gmane.org,
linux-kernel-u79uwXL29TY76Z2rM5mHXA@public.gmane.org,
devicetree-u79uwXL29TY76Z2rM5mHXA@public.gmane.org,
linux-arm-msm-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
In-Reply-To: <5303A71B.7060208-M4DtvfQ/ZS1MRgGoP+s0PdBPR1lH4CV8@public.gmane.org>
On Tue, Feb 18, 2014 at 07:31:55PM +0100, Sergei Shtylyov wrote:
> On 02/18/2014 08:14 PM, Ivan T. Ivanov wrote:
>
> >>> From: "Ivan T. Ivanov" <iivanov-NEYub+7Iv8PQT0dZR+AlfA@public.gmane.org>
>
> >>> Allows controller to be specified via device tree.
> >>> Pass PHY phandle specified in DT to core driver.
>
> >>> Signed-off-by: Ivan T. Ivanov <iivanov-NEYub+7Iv8PQT0dZR+AlfA@public.gmane.org>
> >>> ---
> >>> drivers/usb/chipidea/ci_hdrc_msm.c | 23 ++++++++++++++++++++++-
> >>> 1 file changed, 22 insertions(+), 1 deletion(-)
>
> >> You also need to describe the binding you're creating in
> >> Documentation/devicetree/bindings/usb/<file>.txt.
>
> > Did you check "[PATCH v2 1/3]"?
>
> Did you send it to 'linux-usb'? I just didn't get the patch.
> (Typically, the bindings are described in the same patch the DT support is
> added to the driver bu YMMV, of course.)
Although I would personally agree that this is the most logical method,
it would appear that the DT guys disagree with us [1]. Lately, they
seem to have either given up or are otherwise preoccupied, so perhaps
you can still slip a few patches by them. ;)
-Courtney
[1] https://git.kernel.org/cgit/linux/kernel/git/torvalds/linux.git/tree/Documentation/devicetree/bindings/submitting-patches.txt
--
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 v2 1/3] usb: chipidea: msm: Add device tree binding information
From: Courtney Cavin @ 2014-02-18 21:26 UTC (permalink / raw)
To: Ivan T. Ivanov
Cc: Rob Herring, Pawel Moll, Mark Rutland, Ian Campbell, Kumar Gala,
Rob Landley, Greg Kroah-Hartman, David Brown,
devicetree@vger.kernel.org, linux-doc@vger.kernel.org,
linux-kernel@vger.kernel.org, linux-arm-msm@vger.kernel.org
In-Reply-To: <1392729681-21022-2-git-send-email-iivanov@mm-sol.com>
On Tue, Feb 18, 2014 at 02:21:19PM +0100, Ivan T. Ivanov wrote:
> From: "Ivan T. Ivanov" <iivanov@mm-sol.com>
>
> Document device tree binding information as required by
> the Qualcomm USB controller.
>
> Signed-off-by: Ivan T. Ivanov <iivanov@mm-sol.com>
> ---
> .../devicetree/bindings/usb/msm-hsusb.txt | 17 +++++++++++++++++
Although you mentioned to Josh that this is intended for "non-standard"
Chipidea properties, I don't see any other than requiring that 'dr_mode'
must be "peripheral". It would seem that this should all be integrated
into a ci3xxx.txt.
> 1 file changed, 17 insertions(+)
>
> diff --git a/Documentation/devicetree/bindings/usb/msm-hsusb.txt b/Documentation/devicetree/bindings/usb/msm-hsusb.txt
> index 5ea26c6..d4e7e41 100644
> --- a/Documentation/devicetree/bindings/usb/msm-hsusb.txt
> +++ b/Documentation/devicetree/bindings/usb/msm-hsusb.txt
> @@ -15,3 +15,20 @@ Example EHCI controller device node:
> usb-phy = <&usb_otg>;
> };
>
> +CI13xxx (Chipidea) USB controllers
> +
> +Required properties:
> +- compatible: should contain "qcom,ci-hdrc"
Is there nothing more specific you could put here? Maybe a hardware
revision, or something?
> +- reg: offset and length of the register set in the memory map
> +- interrupts: interrupt-specifier for the controller interrupt.
> +- usb-phy: phandle for the PHY device
> +- dr_mode: Sould be "peripheral"
s/Sould/should/
-Courtney
^ permalink raw reply
* Re: [PATCH v7 4/8] ARM: sunxi: Add driver for SD/MMC hosts found on Allwinner sunxi SoCs
From: Hans de Goede @ 2014-02-18 20:49 UTC (permalink / raw)
To: Maxime Ripard, David Lanzendörfer
Cc: devicetree-u79uwXL29TY76Z2rM5mHXA, Ulf Hansson, Laurent Pinchart,
Mike Turquette, Simon Baatz, Emilio López,
linux-mmc-u79uwXL29TY76Z2rM5mHXA, Chris Ball,
linux-kernel-u79uwXL29TY76Z2rM5mHXA, H Hartley Sweeten,
linux-sunxi-/JYPxA39Uh5TLH3MbocFFw, Tejun Heo,
Guennadi Liakhovetski,
linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r
In-Reply-To: <20140218153731.GK3142@lukather>
Hi,
On 02/18/2014 04:37 PM, Maxime Ripard wrote:
<snip>
>> +
>> + for (i = 0; i < data->sg_len; i++) {
>> + pdes[i].config = SDXC_IDMAC_DES0_CH | SDXC_IDMAC_DES0_OWN |
>> + SDXC_IDMAC_DES0_DIC;
>> +
>> + if (data->sg[i].length == max_len)
>> + pdes[i].buf_size = 0; /* 0 == max_len */
>> + else
>> + pdes[i].buf_size = data->sg[i].length;
>> +
>> + pdes[i].buf_addr_ptr1 = sg_dma_address(&data->sg[i]);
>> + pdes[i].buf_addr_ptr2 = (u32)&pdes_pa[i + 1];
>> + }
>> +
>> + pdes[0].config |= SDXC_IDMAC_DES0_FD;
>> + pdes[i - 1].config = SDXC_IDMAC_DES0_OWN | SDXC_IDMAC_DES0_LD;
>> +
>> + wmb(); /* Ensure idma_des hit main mem before we start the idmac */
>
> wmb ensure the proper ordering of the instructions, not flushing the
> caches like what your comment implies.
Since I put that comment there, allow me to explain. A modern ARM
cpu core has 2 or more units handling stores. One for regular
memory stores, and one for io-mem stores. Regular mem stores can
be re-ordered, io stores cannot. Normally there is no "syncing"
between the 2 store units. Cache flushing is not an issue here
since the memory holding the descriptors for the idma controller
is allocated cache coherent, which on arm means it is not cached.
What is an issue here is the io-store starting the idmac hitting
the io-mem before the descriptors hit the main-mem, the wmb()
ensures this does not happen.
>> +static int sunxi_mmc_prepare_dma(struct sunxi_mmc_host *smc_host,
>> + struct mmc_data *data)
>> +{
>> + u32 dma_len;
>> + u32 i;
>> + u32 temp;
>> + struct scatterlist *sg;
>> +
>> + dma_len = dma_map_sg(mmc_dev(smc_host->mmc), data->sg, data->sg_len,
>> + sunxi_mmc_get_dma_dir(data));
>> + if (dma_len == 0) {
>> + dev_err(mmc_dev(smc_host->mmc), "dma_map_sg failed\n");
>> + return -ENOMEM;
>> + }
>> +
>> + for_each_sg(data->sg, sg, data->sg_len, i) {
>> + if (sg->offset & 3 || sg->length & 3) {
>> + dev_err(mmc_dev(smc_host->mmc),
>> + "unaligned scatterlist: os %x length %d\n",
>> + sg->offset, sg->length);
>> + return -EINVAL;
>> + }
>> + }
>> +
>> + sunxi_mmc_init_idma_des(smc_host, data);
>> +
>> + temp = mci_readl(smc_host, REG_GCTRL);
>> + temp |= SDXC_DMA_ENABLE_BIT;
>> + mci_writel(smc_host, REG_GCTRL, temp);
>> + temp |= SDXC_DMA_RESET;
>> + mci_writel(smc_host, REG_GCTRL, temp);
>
> Does it really need to be done in two steps?
We don't know, so this is probably best left as is.
>
> (Newline)
>
>> + mci_writel(smc_host, REG_DMAC, SDXC_IDMAC_SOFT_RESET);
>> +
>> + if (!(data->flags & MMC_DATA_WRITE))
>> + mci_writel(smc_host, REG_IDIE, SDXC_IDMAC_RECEIVE_INTERRUPT);
>> +
>> + mci_writel(smc_host, REG_DMAC, SDXC_IDMAC_FIX_BURST | SDXC_IDMAC_IDMA_ON);
>> +
>> + return 0;
>> +}
>> +
>> +static void sunxi_mmc_send_manual_stop(struct sunxi_mmc_host *host,
>> + struct mmc_request *req)
>> +{
>> + u32 cmd_val = SDXC_START | SDXC_RESP_EXPIRE | SDXC_STOP_ABORT_CMD
>> + | SDXC_CHECK_RESPONSE_CRC | MMC_STOP_TRANSMISSION;
>> + u32 ri = 0;
>> + unsigned long expire = jiffies + msecs_to_jiffies(1000);
>> +
>> + mci_writel(host, REG_CARG, 0);
>> + mci_writel(host, REG_CMDR, cmd_val);
>> +
>> + do {
>> + ri = mci_readl(host, REG_RINTR);
>> + } while (!(ri & (SDXC_COMMAND_DONE | SDXC_INTERRUPT_ERROR_BIT)) &&
>> + time_before(jiffies, expire));
>> +
>> + if (ri & SDXC_INTERRUPT_ERROR_BIT) {
>> + dev_err(mmc_dev(host->mmc), "send stop command failed\n");
>> + if (req->stop)
>> + req->stop->resp[0] = -ETIMEDOUT;
>> + } else {
>> + if (req->stop)
>> + req->stop->resp[0] = mci_readl(host, REG_RESP0);
>> + }
>> +
>> + mci_writel(host, REG_RINTR, 0xffff);
>> +}
>> +
>> +static void sunxi_mmc_dump_errinfo(struct sunxi_mmc_host *smc_host)
>> +{
>> + struct mmc_command *cmd = smc_host->mrq->cmd;
>> + struct mmc_data *data = smc_host->mrq->data;
>> +
>> + /* For some cmds timeout is normal with sd/mmc cards */
>> + if ((smc_host->int_sum & SDXC_INTERRUPT_ERROR_BIT) == SDXC_RESP_TIMEOUT &&
>> + (cmd->opcode == SD_IO_SEND_OP_COND || cmd->opcode == SD_IO_RW_DIRECT))
>> + return;
>> +
>> + dev_err(mmc_dev(smc_host->mmc),
>
> I'd rather put it at a debug loglevel.
Erm, this only happens if something is seriously wrong.
>> + /* Make sure the controller is in a sane state before enabling irqs */
>> + ret = sunxi_mmc_init_host(host->mmc);
>> + if (ret)
>> + return ret;
>> +
>> + host->irq = platform_get_irq(pdev, 0);
>> + ret = devm_request_irq(&pdev->dev, host->irq, sunxi_mmc_irq, 0,
>> + "sunxi-mmc", host);
>> + if (ret == 0)
>> + disable_irq(host->irq);
>
> The disable_irq is useless here. Just exit.
No it is not note the ret == 0, this is not an error handling path!
This is done under an if because we want to do the sunxi_mmc_exit_host
regardless of the request_irq succeeding or not.
>
>> +
>> + /* And put it back in reset */
>> + sunxi_mmc_exit_host(host);
>
> Hu? If it's in reset, how can it generate some IRQs?
Yes, that is why we do the whole dance of init controller, get irq,
disable irq, drop it back in reset (until the mmc subsys does a power on
of the mmc card / sdio dev).
Sometime the controller asserts the irq in reset for some reason, so
without the dance as soon as we do the devm_request_irq we get an irq,
and worse, not only do we get an irq, we cannot clear it since writing to
the interrupt status register does not work when the controller is in reset,
so we get stuck re-entering the irq handler.
>
>> + return ret;
>> +}
>> +
>> +static int sunxi_mmc_probe(struct platform_device *pdev)
>> +{
>> + struct sunxi_mmc_host *host;
>> + struct mmc_host *mmc;
>> + int ret;
>> +
>> + mmc = mmc_alloc_host(sizeof(struct sunxi_mmc_host), &pdev->dev);
>> + if (!mmc) {
>> + dev_err(&pdev->dev, "mmc alloc host failed\n");
>> + return -ENOMEM;
>> + }
>> +
>> + ret = mmc_of_parse(mmc);
>> + if (ret)
>> + goto error_free_host;
>> +
>> + host = mmc_priv(mmc);
>> + host->mmc = mmc;
>> + spin_lock_init(&host->lock);
>> + tasklet_init(&host->tasklet, sunxi_mmc_tasklet, (unsigned long)host);
>> +
>> + ret = sunxi_mmc_resource_request(host, pdev);
>> + if (ret)
>> + goto error_free_host;
>> +
>> + host->sg_cpu = dma_alloc_coherent(&pdev->dev, PAGE_SIZE,
>> + &host->sg_dma, GFP_KERNEL);
>> + if (!host->sg_cpu) {
>> + dev_err(&pdev->dev, "Failed to allocate DMA descriptor mem\n");
>> + ret = -ENOMEM;
>> + goto error_free_host;
>> + }
>> +
>> + mmc->ops = &sunxi_mmc_ops;
>> + mmc->max_blk_count = 8192;
>> + mmc->max_blk_size = 4096;
>> + mmc->max_segs = PAGE_SIZE / sizeof(struct sunxi_idma_des);
>> + mmc->max_seg_size = (1 << host->idma_des_size_bits);
>> + mmc->max_req_size = mmc->max_seg_size * mmc->max_segs;
>> + /* 400kHz ~ 50MHz */
>> + mmc->f_min = 400000;
>> + mmc->f_max = 50000000;
>> + /* available voltages */
>> + if (!IS_ERR(host->vmmc))
>> + mmc->ocr_avail = mmc_regulator_get_ocrmask(host->vmmc);
>> + else
>> + mmc->ocr_avail = MMC_VDD_32_33 | MMC_VDD_33_34;
>> +
>> + mmc->caps = MMC_CAP_MMC_HIGHSPEED | MMC_CAP_SD_HIGHSPEED |
>> + MMC_CAP_UHS_SDR12 | MMC_CAP_UHS_SDR25 | MMC_CAP_UHS_SDR50 |
>> + MMC_CAP_UHS_DDR50 | MMC_CAP_SDIO_IRQ | MMC_CAP_DRIVER_TYPE_A;
>> + mmc->caps2 = MMC_CAP2_NO_PRESCAN_POWERUP;
>> +
>> + ret = mmc_add_host(mmc);
>> +
>> + if (ret)
>> + goto error_free_dma;
>> +
>> + dev_info(&pdev->dev, "base:0x%p irq:%u\n", host->reg_base, host->irq);
>> + platform_set_drvdata(pdev, mmc);
>
> This should be before the registration. Otherwise, you're racy.
Nope, we only need this to get the data on sunxi_mmc_remove, everywhere
else the data is found through the mmc-host struct.
>
>> + return 0;
>> +
>> +error_free_dma:
>> + dma_free_coherent(&pdev->dev, PAGE_SIZE, host->sg_cpu, host->sg_dma);
>> +error_free_host:
>> + mmc_free_host(mmc);
>> + return ret;
>> +}
>> +
>> +static int sunxi_mmc_remove(struct platform_device *pdev)
>> +{
>> + struct mmc_host *mmc = platform_get_drvdata(pdev);
>> + struct sunxi_mmc_host *host = mmc_priv(mmc);
>> +
>> + mmc_remove_host(mmc);
>> + sunxi_mmc_exit_host(host);
>> + tasklet_disable(&host->tasklet);
>> + dma_free_coherent(&pdev->dev, PAGE_SIZE, host->sg_cpu, host->sg_dma);
>> + mmc_free_host(mmc);
>> +
>> + return 0;
>> +}
>> +
>> +static struct platform_driver sunxi_mmc_driver = {
>> + .driver = {
>> + .name = "sunxi-mmc",
>> + .owner = THIS_MODULE,
>> + .of_match_table = of_match_ptr(sunxi_mmc_of_match),
>> + },
>> + .probe = sunxi_mmc_probe,
>> + .remove = sunxi_mmc_remove,
>> +};
>> +module_platform_driver(sunxi_mmc_driver);
>> +
>> +MODULE_DESCRIPTION("Allwinner's SD/MMC Card Controller Driver");
>> +MODULE_LICENSE("GPL v2");
>> +MODULE_AUTHOR("David Lanzend?rfer <david.lanzendoerfer-Z7Kmv9EsliU@public.gmane.org>");
>> +MODULE_ALIAS("platform:sunxi-mmc");
>> diff --git a/drivers/mmc/host/sunxi-mmc.h b/drivers/mmc/host/sunxi-mmc.h
>> new file mode 100644
>> index 0000000..75eaa02
>> --- /dev/null
>> +++ b/drivers/mmc/host/sunxi-mmc.h
>> @@ -0,0 +1,239 @@
>> +/*
>> + * Driver for sunxi SD/MMC host controllers
>> + * (C) Copyright 2007-2011 Reuuimlla Technology Co., Ltd.
>> + * (C) Copyright 2007-2011 Aaron Maoye <leafy.myeh-jFKXxz0WcGyYHARAtoI1EgC/G2K4zDHf@public.gmane.org>
>> + * (C) Copyright 2013-2014 O2S GmbH <www.o2s.ch>
>> + * (C) Copyright 2013-2014 David Lanzend?rfer <david.lanzendoerfer-Z7Kmv9EsliU@public.gmane.org>
>> + * (C) Copyright 2013-2014 Hans de Goede <hdegoede-H+wXaHxf7aLQT0dZR+AlfA@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 as
>> + * published by the Free Software Foundation; either version 2 of
>> + * the License, or (at your option) any later version.
>> + */
>> +
>> +#ifndef __SUNXI_MMC_H__
>> +#define __SUNXI_MMC_H__
>> +
>> +/* register offset definitions */
>> +#define SDXC_REG_GCTRL (0x00) /* SMC Global Control Register */
>> +#define SDXC_REG_CLKCR (0x04) /* SMC Clock Control Register */
>> +#define SDXC_REG_TMOUT (0x08) /* SMC Time Out Register */
>> +#define SDXC_REG_WIDTH (0x0C) /* SMC Bus Width Register */
>> +#define SDXC_REG_BLKSZ (0x10) /* SMC Block Size Register */
>> +#define SDXC_REG_BCNTR (0x14) /* SMC Byte Count Register */
>> +#define SDXC_REG_CMDR (0x18) /* SMC Command Register */
>> +#define SDXC_REG_CARG (0x1C) /* SMC Argument Register */
>> +#define SDXC_REG_RESP0 (0x20) /* SMC Response Register 0 */
>> +#define SDXC_REG_RESP1 (0x24) /* SMC Response Register 1 */
>> +#define SDXC_REG_RESP2 (0x28) /* SMC Response Register 2 */
>> +#define SDXC_REG_RESP3 (0x2C) /* SMC Response Register 3 */
>> +#define SDXC_REG_IMASK (0x30) /* SMC Interrupt Mask Register */
>> +#define SDXC_REG_MISTA (0x34) /* SMC Masked Interrupt Status Register */
>> +#define SDXC_REG_RINTR (0x38) /* SMC Raw Interrupt Status Register */
>> +#define SDXC_REG_STAS (0x3C) /* SMC Status Register */
>> +#define SDXC_REG_FTRGL (0x40) /* SMC FIFO Threshold Watermark Registe */
>> +#define SDXC_REG_FUNS (0x44) /* SMC Function Select Register */
>> +#define SDXC_REG_CBCR (0x48) /* SMC CIU Byte Count Register */
>> +#define SDXC_REG_BBCR (0x4C) /* SMC BIU Byte Count Register */
>> +#define SDXC_REG_DBGC (0x50) /* SMC Debug Enable Register */
>> +#define SDXC_REG_HWRST (0x78) /* SMC Card Hardware Reset for Register */
>> +#define SDXC_REG_DMAC (0x80) /* SMC IDMAC Control Register */
>> +#define SDXC_REG_DLBA (0x84) /* SMC IDMAC Descriptor List Base Addre */
>> +#define SDXC_REG_IDST (0x88) /* SMC IDMAC Status Register */
>> +#define SDXC_REG_IDIE (0x8C) /* SMC IDMAC Interrupt Enable Register */
>> +#define SDXC_REG_CHDA (0x90)
>> +#define SDXC_REG_CBDA (0x94)
>> +
>> +#define mci_readl(host, reg) \
>> + readl((host)->reg_base + SDXC_##reg)
>> +#define mci_writel(host, reg, value) \
>> + writel((value), (host)->reg_base + SDXC_##reg)
>
> Please use some inline functions here.
>
>> +/* global control register bits */
>> +#define SDXC_SOFT_RESET BIT(0)
>> +#define SDXC_FIFO_RESET BIT(1)
>> +#define SDXC_DMA_RESET BIT(2)
>> +#define SDXC_HARDWARE_RESET (SDXC_SOFT_RESET|SDXC_FIFO_RESET|SDXC_DMA_RESET)
>> +#define SDXC_INTERRUPT_ENABLE_BIT BIT(4)
>> +#define SDXC_DMA_ENABLE_BIT BIT(5)
>> +#define SDXC_DEBOUNCE_ENABLE_BIT BIT(8)
>> +#define SDXC_POSEDGE_LATCH_DATA BIT(9)
>> +#define SDXC_DDR_MODE BIT(10)
>> +#define SDXC_MEMORY_ACCESS_DONE BIT(29)
>> +#define SDXC_ACCESS_DONE_DIRECT BIT(30)
>> +#define SDXC_ACCESS_BY_AHB BIT(31)
>> +#define SDXC_ACCESS_BY_DMA (0U << 31)
>
> Isn't it 0?
Yes, but is is the inverse of ACCESS_BY_DMA, which
this makes much clearer then just 0 does.
>
>> +/* clock control bits */
>> +#define SDXC_CARD_CLOCK_ON BIT(16)
>> +#define SDXC_LOW_POWER_ON BIT(17)
>> +/* bus width */
>> +#define SDXC_WIDTH1 (0)
>> +#define SDXC_WIDTH4 (1)
>> +#define SDXC_WIDTH8 (2)
>> +/* smc command bits */
>> +#define SDXC_RESP_EXPIRE BIT(6)
>> +#define SDXC_LONG_RESPONSE BIT(7)
>> +#define SDXC_CHECK_RESPONSE_CRC BIT(8)
>> +#define SDXC_DATA_EXPIRE BIT(9)
>> +#define SDXC_WRITE BIT(10)
>> +#define SDXC_SEQUENCE_MODE BIT(11)
>> +#define SDXC_SEND_AUTO_STOP BIT(12)
>> +#define SDXC_WAIT_PRE_OVER BIT(13)
>> +#define SDXC_STOP_ABORT_CMD BIT(14)
>> +#define SDXC_SEND_INIT_SEQUENCE BIT(15)
>> +#define SDXC_UPCLK_ONLY BIT(21)
>> +#define SDXC_READ_CEATA_DEV BIT(22)
>> +#define SDXC_CCS_EXPIRE BIT(23)
>> +#define SDXC_ENABLE_BIT_BOOT BIT(24)
>> +#define SDXC_ALT_BOOT_OPTIONS BIT(25)
>> +#define SDXC_BOOT_ACK_EXPIRE BIT(26)
>> +#define SDXC_BOOT_ABORT BIT(27)
>> +#define SDXC_VOLTAGE_SWITCH BIT(28)
>> +#define SDXC_USE_HOLD_REGISTER BIT(29)
>> +#define SDXC_START BIT(31)
>> +/* interrupt bits */
>> +#define SDXC_RESP_ERROR BIT(1)
>> +#define SDXC_COMMAND_DONE BIT(2)
>> +#define SDXC_DATA_OVER BIT(3)
>> +#define SDXC_TX_DATA_REQUEST BIT(4)
>> +#define SDXC_RX_DATA_REQUEST BIT(5)
>> +#define SDXC_RESP_CRC_ERROR BIT(6)
>> +#define SDXC_DATA_CRC_ERROR BIT(7)
>> +#define SDXC_RESP_TIMEOUT BIT(8)
>> +#define SDXC_DATA_TIMEOUT BIT(9)
>> +#define SDXC_VOLTAGE_CHANGE_DONE BIT(10)
>> +#define SDXC_FIFO_RUN_ERROR BIT(11)
>> +#define SDXC_HARD_WARE_LOCKED BIT(12)
>> +#define SDXC_START_BIT_ERROR BIT(13)
>> +#define SDXC_AUTO_COMMAND_DONE BIT(14)
>> +#define SDXC_END_BIT_ERROR BIT(15)
>> +#define SDXC_SDIO_INTERRUPT BIT(16)
>> +#define SDXC_CARD_INSERT BIT(30)
>> +#define SDXC_CARD_REMOVE BIT(31)
>> +#define SDXC_INTERRUPT_ERROR_BIT (SDXC_RESP_ERROR | SDXC_RESP_CRC_ERROR | \
>> + SDXC_DATA_CRC_ERROR | SDXC_RESP_TIMEOUT | \
>> + SDXC_DATA_TIMEOUT | SDXC_FIFO_RUN_ERROR | \
>> + SDXC_HARD_WARE_LOCKED | SDXC_START_BIT_ERROR | \
>> + SDXC_END_BIT_ERROR) /* 0xbbc2 */
>> +#define SDXC_INTERRUPT_DONE_BIT (SDXC_AUTO_COMMAND_DONE | SDXC_DATA_OVER | \
>> + SDXC_COMMAND_DONE | SDXC_VOLTAGE_CHANGE_DONE)
>> +/* status */
>> +#define SDXC_RXWL_FLAG BIT(0)
>> +#define SDXC_TXWL_FLAG BIT(1)
>> +#define SDXC_FIFO_EMPTY BIT(2)
>> +#define SDXC_FIFO_FULL BIT(3)
>> +#define SDXC_CARD_PRESENT BIT(8)
>> +#define SDXC_CARD_DATA_BUSY BIT(9)
>> +#define SDXC_DATA_FSM_BUSY BIT(10)
>> +#define SDXC_DMA_REQUEST BIT(31)
>> +#define SDXC_FIFO_SIZE (16)
>> +/* Function select */
>> +#define SDXC_CEATA_ON (0xceaaU << 16)
>> +#define SDXC_SEND_IRQ_RESPONSE BIT(0)
>> +#define SDXC_SDIO_READ_WAIT BIT(1)
>> +#define SDXC_ABORT_READ_DATA BIT(2)
>> +#define SDXC_SEND_CCSD BIT(8)
>> +#define SDXC_SEND_AUTO_STOPCCSD BIT(9)
>> +#define SDXC_CEATA_DEV_INTERRUPT_ENABLE_BIT BIT(10)
>> +/* IDMA controller bus mod bit field */
>> +#define SDXC_IDMAC_SOFT_RESET BIT(0)
>> +#define SDXC_IDMAC_FIX_BURST BIT(1)
>> +#define SDXC_IDMAC_IDMA_ON BIT(7)
>> +#define SDXC_IDMAC_REFETCH_DES BIT(31)
>> +/* IDMA status bit field */
>> +#define SDXC_IDMAC_TRANSMIT_INTERRUPT BIT(0)
>> +#define SDXC_IDMAC_RECEIVE_INTERRUPT BIT(1)
>> +#define SDXC_IDMAC_FATAL_BUS_ERROR BIT(2)
>> +#define SDXC_IDMAC_DESTINATION_INVALID BIT(4)
>> +#define SDXC_IDMAC_CARD_ERROR_SUM BIT(5)
>> +#define SDXC_IDMAC_NORMAL_INTERRUPT_SUM BIT(8)
>> +#define SDXC_IDMAC_ABNORMAL_INTERRUPT_SUM BIT(9)
>> +#define SDXC_IDMAC_HOST_ABORT_INTERRUPT_TX BIT(10)
>> +#define SDXC_IDMAC_HOST_ABORT_INTERRUPT_RX BIT(10)
>> +#define SDXC_IDMAC_IDLE (0U << 13)
>
> Ditto
>
>> +#define SDXC_IDMAC_SUSPEND (1U << 13)
>> +#define SDXC_IDMAC_DESC_READ (2U << 13)
>> +#define SDXC_IDMAC_DESC_CHECK (3U << 13)
>> +#define SDXC_IDMAC_READ_REQUEST_WAIT (4U << 13)
>> +#define SDXC_IDMAC_WRITE_REQUEST_WAIT (5U << 13)
>> +#define SDXC_IDMAC_READ (6U << 13)
>> +#define SDXC_IDMAC_WRITE (7U << 13)
>> +#define SDXC_IDMAC_DESC_CLOSE (8U << 13)
>
> Please use BIT as much as possible here.
Erm lets not do that, nor remove the 0 << 13, this are all
values to store in a multi-bit field which lives in bits 13-xx,
changing the values which happen to be power of 2 into BIT
macros is not helpful.
>
>
>> +
>> +/*
>> +* If the idma-des-size-bits of property is ie 13, bufsize bits are:
>> +* Bits 0-12: buf1 size
>> +* Bits 13-25: buf2 size
>> +* Bits 26-31: not used
>> +* Since we only ever set buf1 size, we can simply store it directly.
>> +*/
>> +#define SDXC_IDMAC_DES0_DIC BIT(1) /* disable interrupt on completion */
>> +#define SDXC_IDMAC_DES0_LD BIT(2) /* last descriptor */
>> +#define SDXC_IDMAC_DES0_FD BIT(3) /* first descriptor */
>> +#define SDXC_IDMAC_DES0_CH BIT(4) /* chain mode */
>> +#define SDXC_IDMAC_DES0_ER BIT(5) /* end of ring */
>> +#define SDXC_IDMAC_DES0_CES BIT(30) /* card error summary */
>> +#define SDXC_IDMAC_DES0_OWN BIT(31) /* 1-idma owns it, 0-host owns it */
>
> Overall, I prefer to have the registers right beneath the register
> declaration. It's easier to spot what bits belong to what registers
> that way.
>
>> +struct sunxi_idma_des {
>> + u32 config;
>> + u32 buf_size;
>> + u32 buf_addr_ptr1;
>> + u32 buf_addr_ptr2;
>> +};
>
> Some comments on top of this structure would be great.
>
>> +struct sunxi_mmc_host {
>> + struct mmc_host *mmc;
>> + struct regulator *vmmc;
>> +
>> + /* IO mapping base */
>> + void __iomem *reg_base;
>> +
>> + spinlock_t lock;
>> + struct tasklet_struct tasklet;
>> +
>> + /* clock management */
>> + struct clk *clk_ahb;
>> + struct clk *clk_mod;
>> +
>> + /* ios information */
>> + u32 clk_mod_rate;
>> + u32 bus_width;
>> + u32 idma_des_size_bits;
>> + u32 ddr;
>> + u32 voltage_switching;
>> +
>> + /* irq */
>> + int irq;
>> + u32 int_sum;
>> + u32 sdio_imask;
>> +
>> + /* flags */
>> + u32 power_on:1;
>> + u32 io_flag:1;
>> + u32 wait_dma:1;
>
> bool?
>
>> + dma_addr_t sg_dma;
>> + void *sg_cpu;
>> +
>> + struct mmc_request *mrq;
>> + u32 ferror;
>> +};
>
> Please be consistent in your spacing, either align the variable names,
> or don't, but make a decision :)
>
>> +#define MMC_CLK_400K 0
>> +#define MMC_CLK_25M 1
>> +#define MMC_CLK_50M 2
>> +#define MMC_CLK_50MDDR 3
>> +#define MMC_CLK_50MDDR_8BIT 4
>> +#define MMC_CLK_100M 5
>> +#define MMC_CLK_200M 6
>> +#define MMC_CLK_MOD_NUM 7
>
> Wouldn't an enum be better here?
>
>> +
>> +struct sunxi_mmc_clk_dly {
>> + u32 mode;
>> + u32 oclk_dly;
>> + u32 sclk_dly;
>> +};
>
> Comments here would be great too.
>
> Thanks for working on this!
> Maxime
>
Regards,
Hans
^ permalink raw reply
* Re: [PATCH v5 1/4] ASoC: tlv320aic32x4: Support for master clock
From: Markus Pargmann @ 2014-02-18 20:46 UTC (permalink / raw)
To: Mark Brown
Cc: Mark Rutland, devicetree, alsa-devel, Lars-Peter Clausen,
Pawel Moll, Ian Campbell, Liam Girdwood, Rob Herring, kernel,
Kumar Gala
In-Reply-To: <20140218012329.GR2669@sirena.org.uk>
[-- Attachment #1.1: Type: text/plain, Size: 1582 bytes --]
Hi,
On Tue, Feb 18, 2014 at 10:23:29AM +0900, Mark Brown wrote:
> On Mon, Feb 17, 2014 at 11:04:17AM +0100, Markus Pargmann wrote:
>
> > Optional properties:
> > - reset-gpios: Reset-GPIO phandle with args as described in gpio/gpio.txt
> > + - clocks/clock-names: Clock named 'mclk' for the master clock of the codec.
> > + See clock/clock-bindings.txt for information about the detailed format.
>
> Looking at the code the clock isn't physically optional, why not make it
> mandatory? There's only one mainline user, it looks like it should be
> straightforward to update with a fixed clock.
The masterclock is physically optional. There are several modes to use
this codec without master clock. The PLL can use different clock inputs,
BCLK, MCLK, etc. and even the PLL is not necessary. Instead BCLK and so
on can be used as direct codec clock input. However, most of this is not
supported by the driver yet and I can't test these cases.
>
> > + aic32x4->mclk = devm_clk_get(&i2c->dev, "mclk");
> > + if (IS_ERR(aic32x4->mclk))
> > + dev_info(&i2c->dev, "No mclk found, continuing without clock\n");
>
> This is going to break with deferred probe, we need to handle that at
> least.
Yes, I fixed this.
Thanks,
Markus
--
Pengutronix e.K. | |
Industrial Linux Solutions | http://www.pengutronix.de/ |
Peiner Str. 6-8, 31137 Hildesheim, Germany | Phone: +49-5121-206917-0 |
Amtsgericht Hildesheim, HRA 2686 | Fax: +49-5121-206917-5555 |
[-- Attachment #1.2: Digital signature --]
[-- Type: application/pgp-signature, Size: 836 bytes --]
[-- Attachment #2: Type: text/plain, Size: 0 bytes --]
^ permalink raw reply
* Re: [PATCH 1/2] staging: iio: hmc5843: Add all available models to device tree id table.
From: Belisko Marek @ 2014-02-18 20:35 UTC (permalink / raw)
To: Jonathan Cameron
Cc: Mark Rutland, devicetree@vger.kernel.org, devel, Peter Meerwald,
Pawel Moll, ijc+devicetree@hellion.org.uk, linux-iio,
Dr. H. Nikolaus Schaller, linux-doc@vger.kernel.org, LKML,
Rob Herring, Rob Landley, Kumar Gala
In-Reply-To: <530338B2.603@kernel.org>
Hi Jonathan,
On Tue, Feb 18, 2014 at 11:40 AM, Jonathan Cameron <jic23@kernel.org> wrote:
> On 14/02/14 14:25, Marek Belisko wrote:
>>
>> Signed-off-by: Marek Belisko <marek@goldelico.com>
>
> I wonder how this got missed. However, for those data elements to be
> useful, you will
> need to read them somewhere in the driver I think.... (if there is any magic
> that puts this in the relevant i2c locations then point it out to me!)
There is a table called hmc5843_chip_info_tbl which contains entries
for all models
which this driver can handle. And magic is that correct model variant
is set probe function:
line: idata->variant = &hmc5843_chip_info_tbl[id->driver_data];
(id->driver_data contains model value).
>
>> ---
>> drivers/staging/iio/magnetometer/hmc5843.c | 4 +++-
>> 1 file changed, 3 insertions(+), 1 deletion(-)
>>
>> diff --git a/drivers/staging/iio/magnetometer/hmc5843.c
>> b/drivers/staging/iio/magnetometer/hmc5843.c
>> index d4f4dd9..f595fdc 100644
>> --- a/drivers/staging/iio/magnetometer/hmc5843.c
>> +++ b/drivers/staging/iio/magnetometer/hmc5843.c
>> @@ -630,7 +630,9 @@ static const struct i2c_device_id hmc5843_id[] = {
>> MODULE_DEVICE_TABLE(i2c, hmc5843_id);
>>
>> static const struct of_device_id hmc5843_of_match[] = {
>> - { .compatible = "honeywell,hmc5843" },
>> + { .compatible = "honeywell,hmc5843", .data = (void *)HMC5843_ID },
>> + { .compatible = "honeywell,hmc5883", .data = (void *)HMC5883_ID },
>> + { .compatible = "honeywell,hmc5883l", .data = (void *)HMC5883L_ID
>> },
>> {}
>> };
>> MODULE_DEVICE_TABLE(of, hmc5843_of_match);
>>
>
BR,
marek
--
as simple and primitive as possible
-------------------------------------------------
Marek Belisko - OPEN-NANDRA
Freelance Developer
Ruska Nova Ves 219 | Presov, 08005 Slovak Republic
Tel: +421 915 052 184
skype: marekwhite
twitter: #opennandra
web: http://open-nandra.com
^ permalink raw reply
* Re: [PATCH v4 0/2] Introduce AEMIF driver for Davinci/Keystone archs
From: Santosh Shilimkar @ 2014-02-18 20:34 UTC (permalink / raw)
To: Greg KH
Cc: Ivan Khoronzhuk, rob, linux, galak, devicetree, pawel.moll,
mark.rutland, rob.herring, swarren, ijc+devicetree, linux-kernel,
linux-arm-kernel, linux-mtd, grygorii.strashko, dwmw2, nsekhar
In-Reply-To: <20140218202702.GA18642@kroah.com>
On Tuesday 18 February 2014 03:27 PM, Greg KH wrote:
> On Tue, Feb 18, 2014 at 09:41:23AM -0500, Santosh Shilimkar wrote:
>> Greg,
>>
>> On Wednesday 05 February 2014 02:46 PM, Ivan Khoronzhuk wrote:
>>> 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
>>>
>> Can you please have a look at the series ? It has been on the list for
>> sometime and all the outstanding comments are addressed so far. If
>> you are ok with it, I would like to get these queued up for 3.15
>> via your tree.
>
> Why my tree? Am I the drivers/memory/ maintainer?
>
> /me digs in git...
>
> Ah, it looks like I might be...
>
yes :-)
> Ok, let me go review this.
>
Thanks a lot.
Regards,
Santosh
^ permalink raw reply
* [RFC PATCH 6/6] devicetree: bindings: voltagedomain: add bindings for OMAP compatible SoCs
From: Nishanth Menon @ 2014-02-18 20:32 UTC (permalink / raw)
To: Rafael J. Wysocki, Viresh Kumar, MyungJoo Ham, Mark Brown,
Mike Turquette
Cc: devicetree, linux-doc, linux-kernel, cpufreq, linux-pm,
linux-arm-kernel, linux-omap, Nishanth Menon
In-Reply-To: <1392755543-28335-1-git-send-email-nm@ti.com>
Add documentation for device tree description for basic voltage domain
for Texas Instruments OMAP compatible SoC family of processors which
controls both bias and supply voltage planes.
Signed-off-by: Nishanth Menon <nm@ti.com>
---
.../bindings/power/voltdm/voltdm_omap.txt | 24 ++++++++++++++++++++
1 file changed, 24 insertions(+)
create mode 100644 Documentation/devicetree/bindings/power/voltdm/voltdm_omap.txt
diff --git a/Documentation/devicetree/bindings/power/voltdm/voltdm_omap.txt b/Documentation/devicetree/bindings/power/voltdm/voltdm_omap.txt
new file mode 100644
index 0000000..30cd3d2
--- /dev/null
+++ b/Documentation/devicetree/bindings/power/voltdm/voltdm_omap.txt
@@ -0,0 +1,24 @@
+Texas Instruments OMAP compatible voltage domain description
+
+This binding uses [1] and describes the voltage domain devices
+typically used on Texas Instruments OMAP compatible SoC family of
+processors.
+
+[1] Documentation/devicetree/bindings/power/voltdm/voltage_domain.txt
+
+Required Properties:
+- compatible: Should be one of:
+ "ti,omap-voltdm" - basic voltage domain controlling VDD and VBB
+- vdd-supply: phandle to regulator controlling VDD supply
+- vbb-supply: phandle to regulator controlling Body Bias supply
+ (Usually Adaptive Body Bias regulator)
+- #voltdm-cells: shall be <0>
+
+Example:
+voltage_domain_mpu: voltdm@1 {
+ compatible = "ti,omap-voltdm";
+ #voltdm-cells = <0>;
+
+ vdd-supply = <&vcc>;
+ vbb-supply = <&abb_mpu>;
+};
--
1.7.9.5
^ permalink raw reply related
* [RFC PATCH 5/6] PM / Voltagedomain: introduce basic voltage domain support for OMAP
From: Nishanth Menon @ 2014-02-18 20:32 UTC (permalink / raw)
To: Rafael J. Wysocki, Viresh Kumar, MyungJoo Ham, Mark Brown,
Mike Turquette
Cc: devicetree, linux-doc, linux-kernel, cpufreq, linux-pm,
linux-arm-kernel, linux-omap, Nishanth Menon
In-Reply-To: <1392755543-28335-1-git-send-email-nm@ti.com>
OMAP platforms have multiple voltage domains, but each with consistent
behavior of controlling the VDD (supply) and VBB(ABB/Bias voltage).
These need to be sequenced in a specific order for functionality.
Further optimization such as AVS(Adaptive Voltage Scaling), optimized
voltages from efuse(Class0) can also be introduced based on this basic
framework.
This now allows reuse by voltage domain devices which may share the same
voltage domain by allowing the regulator framework to maintain per
consumer usage information.
Signed-off-by: Nishanth Menon <nm@ti.com>
---
drivers/power/voltdm/Kconfig | 7 +
drivers/power/voltdm/Makefile | 1 +
drivers/power/voltdm/voltdm_omap.c | 287 ++++++++++++++++++++++++++++++++++++
3 files changed, 295 insertions(+)
create mode 100644 drivers/power/voltdm/voltdm_omap.c
diff --git a/drivers/power/voltdm/Kconfig b/drivers/power/voltdm/Kconfig
index 270fdab..41bfbc3 100644
--- a/drivers/power/voltdm/Kconfig
+++ b/drivers/power/voltdm/Kconfig
@@ -9,4 +9,11 @@ config VOLTAGE_DOMAIN
menu "Voltage Domain Framework Drivers"
depends on VOLTAGE_DOMAIN
+config VOLTAGE_DOMAIN_OMAP
+ tristate "TI OMAP Voltage domain driver"
+ ---help---
+ Voltage domain support for OMAP platforms which need
+ vdd regulator and Adaptive Body Bias(ABB) regulator
+ support
+
endmenu
diff --git a/drivers/power/voltdm/Makefile b/drivers/power/voltdm/Makefile
index fd32040..e1cb50d 100644
--- a/drivers/power/voltdm/Makefile
+++ b/drivers/power/voltdm/Makefile
@@ -3,3 +3,4 @@ obj-$(CONFIG_VOLTAGE_DOMAIN) += core.o
# Hardware specific voltage domain
# please keep this section sorted lexicographically by file/directory path name
+obj-$(CONFIG_VOLTAGE_DOMAIN_OMAP) += voltdm_omap.o
diff --git a/drivers/power/voltdm/voltdm_omap.c b/drivers/power/voltdm/voltdm_omap.c
new file mode 100644
index 0000000..aacbdde
--- /dev/null
+++ b/drivers/power/voltdm/voltdm_omap.c
@@ -0,0 +1,287 @@
+/*
+ * Copyright (C) 2014 Texas Instruments Incorporated - http://www.ti.com/
+ *
+ * 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.
+ *
+ * Helper functions for registering clock rate-change notifier handlers
+ * that scale voltage when a clock changes its output frequency.
+ */
+#include <linux/clk.h>
+#include <linux/cpufreq.h>
+#include <linux/device.h>
+#include <linux/module.h>
+#include <linux/notifier.h>
+#include <linux/of_device.h>
+#include <linux/of.h>
+#include <linux/platform_device.h>
+#include <linux/pm_opp.h>
+#include <linux/regulator/consumer.h>
+#include <linux/slab.h>
+#include "voltage_domain_private.h"
+
+/**
+ * struct omap_voltdm_data - OMAP specific voltage domain data
+ * @vdd_reg: VDD regulator
+ * @vbb_reg: Body Bias regulator
+ */
+struct omap_voltdm_data {
+ struct regulator *vdd_reg;
+ struct regulator *vbb_reg;
+};
+
+/**
+ * omap_voltdm_do_transition() - do the voltage domain transition
+ * @dev: voltage domain device for which we are doing the transition
+ * @voltdm_data: data specific to the device
+ * @clk_notifier_flags: clk notifier flags for direction of transition
+ * @uv: what voltage to transition to
+ * @tol_uv: voltage tolerance to use
+ */
+static int omap_voltdm_do_transition(struct device *dev,
+ void *voltdm_data,
+ unsigned long clk_notifier_flags, int uv,
+ int tol_uv)
+{
+ struct omap_voltdm_data *data = (struct omap_voltdm_data *)voltdm_data;
+ int ret;
+ bool do_abb_first;
+
+ /* We dont expect voltdm layer to make mistakes.. but still */
+ BUG_ON(!data);
+
+ do_abb_first = clk_notifier_flags == ABORT_RATE_CHANGE ||
+ clk_notifier_flags == POST_RATE_CHANGE;
+
+ if (do_abb_first) {
+ dev_dbg(dev, "vbb pre %duV[tol %duV]\n", uv, tol_uv);
+ ret = regulator_set_voltage_tol(data->vbb_reg, uv, tol_uv);
+ if (ret) {
+ dev_err(dev,
+ "vbb failed for voltage %duV[tol %duV]:%d\n",
+ uv, tol_uv, ret);
+ return ret;
+ }
+ }
+
+ dev_dbg(dev, "vdd for voltage %duV[tol %duV]\n", uv, tol_uv);
+ ret = regulator_set_voltage_tol(data->vdd_reg, uv, tol_uv);
+ if (ret) {
+ dev_err(dev,
+ "vdd failed for voltage %duV[tol %duV]:%d\n",
+ uv, tol_uv, ret);
+ return ret;
+ }
+
+ if (!do_abb_first) {
+ dev_dbg(dev, "vbb post %duV[tol %duV]\n", uv, tol_uv);
+ ret = regulator_set_voltage_tol(data->vbb_reg, uv, tol_uv);
+ if (ret) {
+ dev_err(dev,
+ "vbb failed for voltage %duV[tol %duV]:%d\n",
+ uv, tol_uv, ret);
+ return ret;
+ }
+ }
+
+ return 0;
+}
+
+/**
+ * omap_voltdm_latency() - provide the transition latency for the voltage domain
+ * @dev: voltage domain device for which we are doing the transition
+ * @voltdm_data: data specific to the device
+ * @min: minimum voltage in uV
+ * @max: maximum voltage in uV
+ *
+ * Return: If successful, the combined transition latency from min to max, else
+ * returns error value
+ */
+static int omap_voltdm_latency(struct device *dev, void *voltdm_data,
+ unsigned long min, unsigned long max)
+{
+ struct omap_voltdm_data *data = (struct omap_voltdm_data *)voltdm_data;
+ int ret, tot_latency = 0;
+
+ /* We dont expect voltdm layer to make mistakes.. but still */
+ BUG_ON(!data);
+
+ ret = regulator_set_voltage_time(data->vdd_reg, min, max);
+ if (ret < 0) {
+ dev_warn(dev, "vdd failed voltage latency: %d\n", ret);
+ return ret;
+ }
+ tot_latency += ret;
+
+ ret = regulator_set_voltage_time(data->vbb_reg, min, max);
+ if (ret < 0) {
+ dev_warn(dev, "vbb failed voltage latency: %d\n", ret);
+ return ret;
+ }
+ tot_latency += ret;
+
+ return tot_latency;
+}
+
+static inline void omap_voltdm_cleanup(struct omap_voltdm_data *data)
+{
+ if (!IS_ERR(data->vbb_reg))
+ regulator_put(data->vbb_reg);
+ if (!IS_ERR(data->vdd_reg))
+ regulator_put(data->vdd_reg);
+ kfree(data);
+}
+
+/**
+ * omap_voltdm_get() - get the voltage domain resources specific to request
+ * @voltdm_dev: voltage domain device
+ * @request_dev: device for which we have been requested to get
+ * @np: unused
+ * @np_args: unused
+ * @supply: unused
+ * @*voltdm_data: returns data for the current request (freed in put)
+ *
+ * Return: 0 if everything went OK, else return appropriate error value.
+ */
+static int omap_voltdm_get(struct device *voltdm_dev,
+ struct device *request_dev,
+ struct device_node *np,
+ struct of_phandle_args *np_args,
+ const char *supply,
+ void **voltdm_data)
+{
+ struct omap_voltdm_data *data;
+ int ret = 0;
+
+ BUG_ON(!voltdm_dev || !request_dev || !voltdm_data);
+
+ data = kzalloc(sizeof(*data), GFP_KERNEL);
+ if (!data)
+ return -ENOMEM;
+ /* Intialize for use in generic cleanup routine */
+ data->vdd_reg = ERR_PTR(-ENODEV);
+ data->vbb_reg = ERR_PTR(-ENODEV);
+
+ /*
+ * Setup aliases for request device supply to let regulator framework
+ * do multi-consumer scenario
+ */
+ ret = regulator_register_supply_alias(request_dev, "vdd", voltdm_dev, "vdd");
+ if (ret)
+ goto out_free;
+ ret = regulator_register_supply_alias(request_dev, "vbb", voltdm_dev, "vbb");
+ if (ret)
+ goto out_unreg_vdd;
+
+ data->vdd_reg = regulator_get(request_dev, "vdd");
+ if (IS_ERR(data->vdd_reg)) {
+ ret = PTR_ERR(data->vdd_reg);
+ dev_err(voltdm_dev, "Unable to get vdd regulator:%d\n", ret);
+ goto out_unreg;
+ }
+
+ data->vbb_reg = regulator_get(request_dev, "vbb");
+ if (IS_ERR(data->vbb_reg)) {
+ ret = PTR_ERR(data->vbb_reg);
+ dev_err(voltdm_dev, "Unable to get vbb regulator:%d\n", ret);
+ goto out_vdd_reg;
+ }
+
+ *voltdm_data = data;
+ return 0;
+
+out_vdd_reg:
+ regulator_put(data->vdd_reg);
+out_unreg:
+ regulator_unregister_supply_alias(request_dev, "vbb");
+out_unreg_vdd:
+ regulator_unregister_supply_alias(request_dev, "vdd");
+out_free:
+ kfree(data);
+
+ return ret;
+}
+
+/**
+ * omap_voltdm_put() - release the resources reserved by omap_voltdm_get()
+ * @voltdm_dev: voltage domain device for which we reserved resources
+ * @request_dev: device for which we have been requested to put
+ * @voltdm_data: data for the request provided by omap_voltdm_get()
+ */
+static void omap_voltdm_put(struct device *voltdm_dev, struct device *request_dev,
+ void *voltdm_data)
+{
+ struct omap_voltdm_data *data = (struct omap_voltdm_data *)voltdm_data;
+
+ /* We dont expect voltdm layer to make mistakes.. but still */
+ BUG_ON(!data || !voltdm_dev || !request_dev);
+
+ regulator_put(data->vbb_reg);
+ regulator_put(data->vdd_reg);
+ regulator_unregister_supply_alias(request_dev, "vbb");
+ regulator_unregister_supply_alias(request_dev, "vdd");
+ kfree(data);
+
+ return;
+}
+
+static const struct pm_voltdm_ops omap_voltdm_ops = {
+ .voltdm_get = omap_voltdm_get,
+ .voltdm_put = omap_voltdm_put,
+ .voltdm_latency = omap_voltdm_latency,
+ .voltdm_do_transition = omap_voltdm_do_transition,
+};
+
+static const struct pm_voltdm_desc omap_voltdm_desc = {
+ .ops = &omap_voltdm_ops,
+};
+
+static const struct of_device_id omap_voltdm_of_match[] = {
+ {.compatible = "ti,omap-voltdm", .data = &omap_voltdm_desc},
+ {},
+};
+
+static int omap_voltdm_probe(struct platform_device *pdev)
+{
+ struct device *dev = &pdev->dev;
+ const struct of_device_id *match;
+ struct pm_voltdm_dev *vdev;
+ int ret = 0;
+
+ match = of_match_device(omap_voltdm_of_match, dev);
+ if (!match) {
+ /* We do not expect this to happen */
+ dev_err(dev, "%s: Unable to match device\n", __func__);
+ return -ENODEV;
+ }
+ if (!match->data) {
+ /* Again, unlikely.. but mistakes do happen */
+ dev_err(dev, "%s: Bad data in match\n", __func__);
+ return -EINVAL;
+ }
+
+ vdev = devm_voltdm_register(dev, match->data);
+ if (IS_ERR(vdev)) {
+ ret = PTR_ERR(vdev);
+ dev_err(dev, "Failed to register voltage domain %d\n", ret);
+ }
+
+ return ret;
+}
+
+MODULE_ALIAS("platform:omap_voltdm");
+
+static struct platform_driver omap_voltdm_driver = {
+ .probe = omap_voltdm_probe,
+ .driver = {
+ .name = "omap_voltdm",
+ .owner = THIS_MODULE,
+ .of_match_table = of_match_ptr(omap_voltdm_of_match),
+ },
+};
+module_platform_driver(omap_voltdm_driver);
+
+MODULE_DESCRIPTION("Texas Instruments OMAP Voltage Domain driver");
+MODULE_AUTHOR("Texas Instruments Inc.");
+MODULE_LICENSE("GPL v2");
--
1.7.9.5
^ permalink raw reply related
* [RFC PATCH 4/6] devicetree: bindings: add documentation for voltagedomain
From: Nishanth Menon @ 2014-02-18 20:32 UTC (permalink / raw)
To: Rafael J. Wysocki, Viresh Kumar, MyungJoo Ham, Mark Brown,
Mike Turquette
Cc: Nishanth Menon, devicetree, linux-pm, linux-doc, linux-kernel,
cpufreq, linux-omap, linux-arm-kernel
In-Reply-To: <1392755543-28335-1-git-send-email-nm@ti.com>
Add documentation for voltage domain binding format. Specific
voltage domains will have bindings corresponding to them.
Signed-off-by: Nishanth Menon <nm@ti.com>
---
.../bindings/power/voltdm/voltage_domain.txt | 65 ++++++++++++++++++++
1 file changed, 65 insertions(+)
create mode 100644 Documentation/devicetree/bindings/power/voltdm/voltage_domain.txt
diff --git a/Documentation/devicetree/bindings/power/voltdm/voltage_domain.txt b/Documentation/devicetree/bindings/power/voltdm/voltage_domain.txt
new file mode 100644
index 0000000..da48a19
--- /dev/null
+++ b/Documentation/devicetree/bindings/power/voltdm/voltage_domain.txt
@@ -0,0 +1,65 @@
+Specifying Voltage Domain information for devices
+=================================================
+
+1. Specifying a voltage domain.
+
+SoCs may have multiple voltage domains under which various clocks operate.
+
+Mandatory Properties:
+- #voltdm-cells - indicates if there are specifiers needed to reference the
+ voltage domain
+
+Optional Properties:
+- voltage-tolerance: Specify the voltage tolerance in percentage
+
+2. Voltage domain consumer
+consumer nodes can be reference using the below binding:
+- <name>-voltdm: phandle to the voltage domain node.
+
+Examples:
+
+A. Voltage Domain controlling multiple regulator
+voltage_domain_mpu: voltdm@1 {
+ compatible = "xyz";
+ #voltdm-cells = <0>;
+ vdd-supply = <&vcc>;
+ vbb-supply = <&abb_mpu>;
+ ...
+};
+
+voltage_domain_gpu: voltdm@2 {
+ compatible = "xyz";
+ #voltdm-cells = <0>;
+ vdd-supply = <&dcdc2>;
+ vbb-supply = <&abb_gpu>;
+ ...
+};
+...
+&cpu0 {
+ cpu0-voltdm = <&voltage_domain_mpu>;
+ voltage-tolerance = <1>;
+};
+
+&gpu {
+ gpu-voltdm = <&voltage_domain_gpu>;
+};
+
+B. Indexed voltage domain device
+
+#define SOC_XYZ_VOLTAGE_DOMAIN_MPU 0
+#define SOC_XYZ_VOLTAGE_DOMAIN_GFX 1
+
+voltage_domain_socx: voltdm@1 {
+ compatible = "abc";
+ #voltdm-cells = <1>;
+ ...
+};
+...
+&cpu0 {
+ cpu0-voltdm = <&voltage_domain_socx SOC_XYZ_VOLTAGE_DOMAIN_MPU>;
+ voltage-tolerance = <1>;
+};
+
+&gpu {
+ gpu-voltdm = <&voltage_domain_socx SOC_XYZ_VOLTAGE_DOMAIN_GFX>;
+};
--
1.7.9.5
^ permalink raw reply related
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