aboutsummaryrefslogtreecommitdiffstats
path: root/arch/arm/mach-mvebu
diff options
context:
space:
mode:
authorThomas Petazzoni <thomas.petazzoni@free-electrons.com>2014-11-13 04:38:57 -0500
committerJason Cooper <jason@lakedaemon.net>2014-11-21 20:49:33 -0500
commite55355453600a33bb5ca4f71f2d7214875f3b061 (patch)
tree6155d933799315d876054ab5db481c1577807fc4 /arch/arm/mach-mvebu
parent30cdef97107370a7f63ab5d80fd2de30540750c8 (diff)
ARM: mvebu: disable I/O coherency on non-SMP situations on Armada 370/375/38x/XP
Enabling the hardware I/O coherency on Armada 370, Armada 375, Armada 38x and Armada XP requires a certain number of conditions: - On Armada 370, the cache policy must be set to write-allocate. - On Armada 375, 38x and XP, the cache policy must be set to write-allocate, the pages must be mapped with the shareable attribute, and the SMP bit must be set Currently, on Armada XP, when CONFIG_SMP is enabled, those conditions are met. However, when Armada XP is used in a !CONFIG_SMP kernel, none of these conditions are met. With Armada 370, the situation is worse: since the processor is single core, regardless of whether CONFIG_SMP or !CONFIG_SMP is used, the cache policy will be set to write-back by the kernel and not write-allocate. Since solving this problem turns out to be quite complicated, and we don't want to let users with a mainline kernel known to have infrequent but existing data corruptions, this commit proposes to simply disable hardware I/O coherency in situations where it is known not to work. And basically, the is_smp() function of the kernel tells us whether it is OK to enable hardware I/O coherency or not, so this commit slightly refactors the coherency_type() function to return COHERENCY_FABRIC_TYPE_NONE when is_smp() is false, or the appropriate type of the coherency fabric in the other case. Thanks to this, the I/O coherency fabric will no longer be used at all in !CONFIG_SMP configurations. It will continue to be used in CONFIG_SMP configurations on Armada XP, Armada 375 and Armada 38x (which are multiple cores processors), but will no longer be used on Armada 370 (which is a single core processor). In the process, it simplifies the implementation of the coherency_type() function, and adds a missing call to of_node_put(). Signed-off-by: Thomas Petazzoni <thomas.petazzoni@free-electrons.com> Fixes: e60304f8cb7bb545e79fe62d9b9762460c254ec2 ("arm: mvebu: Add hardware I/O Coherency support") Cc: <stable@vger.kernel.org> # v3.8+ Acked-by: Gregory CLEMENT <gregory.clement@free-electrons.com> Link: https://lkml.kernel.org/r/1415871540-20302-3-git-send-email-thomas.petazzoni@free-electrons.com Signed-off-by: Jason Cooper <jason@lakedaemon.net>
Diffstat (limited to 'arch/arm/mach-mvebu')
-rw-r--r--arch/arm/mach-mvebu/coherency.c44
1 files changed, 30 insertions, 14 deletions
diff --git a/arch/arm/mach-mvebu/coherency.c b/arch/arm/mach-mvebu/coherency.c
index 044b51185fcc..c31f4c00b1fc 100644
--- a/arch/arm/mach-mvebu/coherency.c
+++ b/arch/arm/mach-mvebu/coherency.c
@@ -361,25 +361,41 @@ static int coherency_type(void)
361{ 361{
362 struct device_node *np; 362 struct device_node *np;
363 const struct of_device_id *match; 363 const struct of_device_id *match;
364 int type;
364 365
365 np = of_find_matching_node_and_match(NULL, of_coherency_table, &match); 366 /*
366 if (np) { 367 * The coherency fabric is needed:
367 int type = (int) match->data; 368 * - For coherency between processors on Armada XP, so only
369 * when SMP is enabled.
370 * - For coherency between the processor and I/O devices, but
371 * this coherency requires many pre-requisites (write
372 * allocate cache policy, shareable pages, SMP bit set) that
373 * are only meant in SMP situations.
374 *
375 * Note that this means that on Armada 370, there is currently
376 * no way to use hardware I/O coherency, because even when
377 * CONFIG_SMP is enabled, is_smp() returns false due to the
378 * Armada 370 being a single-core processor. To lift this
379 * limitation, we would have to find a way to make the cache
380 * policy set to write-allocate (on all Armada SoCs), and to
381 * set the shareable attribute in page tables (on all Armada
382 * SoCs except the Armada 370). Unfortunately, such decisions
383 * are taken very early in the kernel boot process, at a point
384 * where we don't know yet on which SoC we are running.
368 385
369 /* Armada 370/XP coherency works in both UP and SMP */ 386 */
370 if (type == COHERENCY_FABRIC_TYPE_ARMADA_370_XP) 387 if (!is_smp())
371 return type; 388 return COHERENCY_FABRIC_TYPE_NONE;
372 389
373 /* Armada 375 coherency works only on SMP */ 390 np = of_find_matching_node_and_match(NULL, of_coherency_table, &match);
374 else if (type == COHERENCY_FABRIC_TYPE_ARMADA_375 && is_smp()) 391 if (!np)
375 return type; 392 return COHERENCY_FABRIC_TYPE_NONE;
376 393
377 /* Armada 380 coherency works only on SMP */ 394 type = (int) match->data;
378 else if (type == COHERENCY_FABRIC_TYPE_ARMADA_380 && is_smp()) 395
379 return type; 396 of_node_put(np);
380 }
381 397
382 return COHERENCY_FABRIC_TYPE_NONE; 398 return type;
383} 399}
384 400
385int coherency_available(void) 401int coherency_available(void)