diff options
author | Ezequiel Garcia <ezequiel.garcia@free-electrons.com> | 2014-04-24 16:23:22 -0400 |
---|---|---|
committer | Jason Cooper <jason@lakedaemon.net> | 2014-05-08 12:23:10 -0400 |
commit | 5fd62066d2900b25a4fb3295ad13e3ee31474a51 (patch) | |
tree | aeded9f89285307855972019dd83866f78a87da8 | |
parent | e9d3c849a8dc92e1019a6c7ced98f6ac231a2703 (diff) |
ARM: mvebu: Add thermal quirk for the Armada 375 DB board
The initial release of the Armada 375 DB board has an Armada 375
Z1 stepping silicon. This commit introduces a quirk that allows
to workaround a series of issues with the thermal sensor in this
stepping, but updating the devicetree:
* Updates the compatible string for the thermal, so the driver
can perform a specific initialization of the sensor.
* Moves the offset of the thermal control register. This quirk
allows to specifiy the correct (A0 stepping) offset in the
devicetree.
Signed-off-by: Ezequiel Garcia <ezequiel.garcia@free-electrons.com>
Link: https://lkml.kernel.org/r/1398371004-15807-9-git-send-email-ezequiel.garcia@free-electrons.com
Signed-off-by: Jason Cooper <jason@lakedaemon.net>
-rw-r--r-- | arch/arm/mach-mvebu/board-v7.c | 57 | ||||
-rw-r--r-- | arch/arm/mach-mvebu/mvebu-soc-id.h | 3 |
2 files changed, 60 insertions, 0 deletions
diff --git a/arch/arm/mach-mvebu/board-v7.c b/arch/arm/mach-mvebu/board-v7.c index c8a90d992be2..bc0283f0dd88 100644 --- a/arch/arm/mach-mvebu/board-v7.c +++ b/arch/arm/mach-mvebu/board-v7.c | |||
@@ -113,10 +113,66 @@ static void __init i2c_quirk(void) | |||
113 | return; | 113 | return; |
114 | } | 114 | } |
115 | 115 | ||
116 | #define A375_Z1_THERMAL_FIXUP_OFFSET 0xc | ||
117 | |||
118 | static void __init thermal_quirk(void) | ||
119 | { | ||
120 | struct device_node *np; | ||
121 | u32 dev, rev; | ||
122 | |||
123 | if (mvebu_get_soc_id(&dev, &rev) && rev > ARMADA_375_Z1_REV) | ||
124 | return; | ||
125 | |||
126 | for_each_compatible_node(np, NULL, "marvell,armada375-thermal") { | ||
127 | struct property *prop; | ||
128 | __be32 newval, *newprop, *oldprop; | ||
129 | int len; | ||
130 | |||
131 | /* | ||
132 | * The register offset is at a wrong location. This quirk | ||
133 | * creates a new reg property as a clone of the previous | ||
134 | * one and corrects the offset. | ||
135 | */ | ||
136 | oldprop = (__be32 *)of_get_property(np, "reg", &len); | ||
137 | if (!oldprop) | ||
138 | continue; | ||
139 | |||
140 | /* Create a duplicate of the 'reg' property */ | ||
141 | prop = kzalloc(sizeof(*prop), GFP_KERNEL); | ||
142 | prop->length = len; | ||
143 | prop->name = kstrdup("reg", GFP_KERNEL); | ||
144 | prop->value = kzalloc(len, GFP_KERNEL); | ||
145 | memcpy(prop->value, oldprop, len); | ||
146 | |||
147 | /* Fixup the register offset of the second entry */ | ||
148 | oldprop += 2; | ||
149 | newprop = (__be32 *)prop->value + 2; | ||
150 | newval = cpu_to_be32(be32_to_cpu(*oldprop) - | ||
151 | A375_Z1_THERMAL_FIXUP_OFFSET); | ||
152 | *newprop = newval; | ||
153 | of_update_property(np, prop); | ||
154 | |||
155 | /* | ||
156 | * The thermal controller needs some quirk too, so let's change | ||
157 | * the compatible string to reflect this. | ||
158 | */ | ||
159 | prop = kzalloc(sizeof(*prop), GFP_KERNEL); | ||
160 | prop->name = kstrdup("compatible", GFP_KERNEL); | ||
161 | prop->length = sizeof("marvell,armada375-z1-thermal"); | ||
162 | prop->value = kstrdup("marvell,armada375-z1-thermal", | ||
163 | GFP_KERNEL); | ||
164 | of_update_property(np, prop); | ||
165 | } | ||
166 | return; | ||
167 | } | ||
168 | |||
116 | static void __init mvebu_dt_init(void) | 169 | static void __init mvebu_dt_init(void) |
117 | { | 170 | { |
118 | if (of_machine_is_compatible("plathome,openblocks-ax3-4")) | 171 | if (of_machine_is_compatible("plathome,openblocks-ax3-4")) |
119 | i2c_quirk(); | 172 | i2c_quirk(); |
173 | if (of_machine_is_compatible("marvell,a375-db")) | ||
174 | thermal_quirk(); | ||
175 | |||
120 | of_platform_populate(NULL, of_default_bus_match_table, NULL, NULL); | 176 | of_platform_populate(NULL, of_default_bus_match_table, NULL, NULL); |
121 | } | 177 | } |
122 | 178 | ||
@@ -140,6 +196,7 @@ static const char * const armada_375_dt_compat[] = { | |||
140 | 196 | ||
141 | DT_MACHINE_START(ARMADA_375_DT, "Marvell Armada 375 (Device Tree)") | 197 | DT_MACHINE_START(ARMADA_375_DT, "Marvell Armada 375 (Device Tree)") |
142 | .init_time = mvebu_timer_and_clk_init, | 198 | .init_time = mvebu_timer_and_clk_init, |
199 | .init_machine = mvebu_dt_init, | ||
143 | .restart = mvebu_restart, | 200 | .restart = mvebu_restart, |
144 | .dt_compat = armada_375_dt_compat, | 201 | .dt_compat = armada_375_dt_compat, |
145 | MACHINE_END | 202 | MACHINE_END |
diff --git a/arch/arm/mach-mvebu/mvebu-soc-id.h b/arch/arm/mach-mvebu/mvebu-soc-id.h index 31654252fe35..294a443f56fc 100644 --- a/arch/arm/mach-mvebu/mvebu-soc-id.h +++ b/arch/arm/mach-mvebu/mvebu-soc-id.h | |||
@@ -20,6 +20,9 @@ | |||
20 | #define MV78XX0_A0_REV 0x1 | 20 | #define MV78XX0_A0_REV 0x1 |
21 | #define MV78XX0_B0_REV 0x2 | 21 | #define MV78XX0_B0_REV 0x2 |
22 | 22 | ||
23 | /* Armada 375 */ | ||
24 | #define ARMADA_375_Z1_REV 0x0 | ||
25 | |||
23 | #ifdef CONFIG_ARCH_MVEBU | 26 | #ifdef CONFIG_ARCH_MVEBU |
24 | int mvebu_get_soc_id(u32 *dev, u32 *rev); | 27 | int mvebu_get_soc_id(u32 *dev, u32 *rev); |
25 | #else | 28 | #else |