2014-12-23 12:29:35

by Aleksey Makarov

[permalink] [raw]
Subject: [PATCH 0/3] MIPS: OCTEON: flash: syncronize bootbus access

- Use semaphore to protect access to bootbus.
- Use device tree to probe for flash chips.

David Daney (3):
MIPS: OCTEON: Add semaphore to serialize bootbus accesses.
MIPS: OCTEON: Protect accesses to bootbus flash with
octeon_bootbus_sem.
MIPS: OCTEON: Use device tree to probe for flash chips.

arch/mips/Kconfig | 1 +
arch/mips/cavium-octeon/flash_setup.c | 84 ++++++++++++++++++++++++++++++++---
arch/mips/cavium-octeon/setup.c | 3 ++
arch/mips/include/asm/octeon/octeon.h | 2 +
4 files changed, 84 insertions(+), 6 deletions(-)

--
2.1.3


2014-12-23 12:29:42

by Aleksey Makarov

[permalink] [raw]
Subject: [PATCH 1/3] MIPS: OCTEON: Add semaphore to serialize bootbus accesses.

From: David Daney <[email protected]>

Some hardware blocks attached to the OCTEON bootbus run asynchronously
to accesses from the CPUs. These include MMC/SD host, CF(when using
DMA), and NAND controller. A bus error, or corrupt data may occur if
a CPU is trying to access a bootbus connected device at the same time
the bus is running asynchronous operations.

To work around these problems we add this semaphore that must be
acquired before initiating bootbus activity. Subsequent patches will
add users for this.

Signed-off-by: David Daney <[email protected]>
[[email protected]: combine the patches]
Signed-off-by: Aleksey Makarov <[email protected]>
Signed-off-by: Chandrakala Chavva <[email protected]>
---
arch/mips/cavium-octeon/setup.c | 3 +++
arch/mips/include/asm/octeon/octeon.h | 2 ++
2 files changed, 5 insertions(+)

diff --git a/arch/mips/cavium-octeon/setup.c b/arch/mips/cavium-octeon/setup.c
index 94f888d..7311338 100644
--- a/arch/mips/cavium-octeon/setup.c
+++ b/arch/mips/cavium-octeon/setup.c
@@ -50,6 +50,9 @@ extern void pci_console_init(const char *arg);

static unsigned long long MAX_MEMORY = 512ull << 20;

+DEFINE_SEMAPHORE(octeon_bootbus_sem);
+EXPORT_SYMBOL(octeon_bootbus_sem);
+
struct octeon_boot_descriptor *octeon_boot_desc_ptr;

struct cvmx_bootinfo *octeon_bootinfo;
diff --git a/arch/mips/include/asm/octeon/octeon.h b/arch/mips/include/asm/octeon/octeon.h
index d781f9e..8e4e4db 100644
--- a/arch/mips/include/asm/octeon/octeon.h
+++ b/arch/mips/include/asm/octeon/octeon.h
@@ -252,4 +252,6 @@ void octeon_irq_set_ip4_handler(octeon_irq_ip4_handler_t);

extern void octeon_fixup_irqs(void);

+extern struct semaphore octeon_bootbus_sem;
+
#endif /* __ASM_OCTEON_OCTEON_H */
--
2.1.3

2014-12-23 12:30:07

by Aleksey Makarov

[permalink] [raw]
Subject: [PATCH 2/3] MIPS: OCTEON: Protect accesses to bootbus flash with octeon_bootbus_sem.

From: David Daney <[email protected]>

Without this, we get bus errors.

Signed-off-by: David Daney <[email protected]>
Signed-off-by: Aleksey Makarov <[email protected]>
---
arch/mips/Kconfig | 1 +
arch/mips/cavium-octeon/flash_setup.c | 42 ++++++++++++++++++++++++++++++++++-
2 files changed, 42 insertions(+), 1 deletion(-)

diff --git a/arch/mips/Kconfig b/arch/mips/Kconfig
index 3289969..94f6012 100644
--- a/arch/mips/Kconfig
+++ b/arch/mips/Kconfig
@@ -790,6 +790,7 @@ config CAVIUM_OCTEON_SOC
select SYS_SUPPORTS_SMP
select NR_CPUS_DEFAULT_16
select BUILTIN_DTB
+ select MTD_COMPLEX_MAPPINGS
help
This option supports all of the Octeon reference boards from Cavium
Networks. It builds a kernel that dynamically determines the Octeon
diff --git a/arch/mips/cavium-octeon/flash_setup.c b/arch/mips/cavium-octeon/flash_setup.c
index 237e5b1..39e26df 100644
--- a/arch/mips/cavium-octeon/flash_setup.c
+++ b/arch/mips/cavium-octeon/flash_setup.c
@@ -9,6 +9,7 @@
*/
#include <linux/kernel.h>
#include <linux/export.h>
+#include <linux/semaphore.h>
#include <linux/mtd/mtd.h>
#include <linux/mtd/map.h>
#include <linux/mtd/partitions.h>
@@ -25,6 +26,41 @@ static const char *part_probe_types[] = {
NULL
};

+static map_word octeon_flash_map_read(struct map_info *map, unsigned long ofs)
+{
+ map_word r;
+
+ down(&octeon_bootbus_sem);
+ r = inline_map_read(map, ofs);
+ up(&octeon_bootbus_sem);
+
+ return r;
+}
+
+static void octeon_flash_map_write(struct map_info *map, const map_word datum,
+ unsigned long ofs)
+{
+ down(&octeon_bootbus_sem);
+ inline_map_write(map, datum, ofs);
+ up(&octeon_bootbus_sem);
+}
+
+static void octeon_flash_map_copy_from(struct map_info *map, void *to,
+ unsigned long from, ssize_t len)
+{
+ down(&octeon_bootbus_sem);
+ inline_map_copy_from(map, to, from, len);
+ up(&octeon_bootbus_sem);
+}
+
+static void octeon_flash_map_copy_to(struct map_info *map, unsigned long to,
+ const void *from, ssize_t len)
+{
+ down(&octeon_bootbus_sem);
+ inline_map_copy_to(map, to, from, len);
+ up(&octeon_bootbus_sem);
+}
+
/**
* Module/ driver initialization.
*
@@ -56,7 +92,11 @@ static int __init flash_init(void)
flash_map.virt = ioremap(flash_map.phys, flash_map.size);
pr_notice("Bootbus flash: Setting flash for %luMB flash at "
"0x%08llx\n", flash_map.size >> 20, flash_map.phys);
- simple_map_init(&flash_map);
+ WARN_ON(!map_bankwidth_supported(flash_map.bankwidth));
+ flash_map.read = octeon_flash_map_read;
+ flash_map.write = octeon_flash_map_write;
+ flash_map.copy_from = octeon_flash_map_copy_from;
+ flash_map.copy_to = octeon_flash_map_copy_to;
mymtd = do_map_probe("cfi_probe", &flash_map);
if (mymtd) {
mymtd->owner = THIS_MODULE;
--
2.1.3

2014-12-23 12:30:16

by Aleksey Makarov

[permalink] [raw]
Subject: [PATCH 3/3] MIPS: OCTEON: Use device tree to probe for flash chips.

From: David Daney <[email protected]>

Don't assume they are there, the device tree will tell us.

Signed-off-by: David Daney <[email protected]>
Signed-off-by: Aleksey Makarov <[email protected]>
---
arch/mips/cavium-octeon/flash_setup.c | 42 ++++++++++++++++++++++++++++++-----
1 file changed, 37 insertions(+), 5 deletions(-)

diff --git a/arch/mips/cavium-octeon/flash_setup.c b/arch/mips/cavium-octeon/flash_setup.c
index 39e26df..8eb81e2 100644
--- a/arch/mips/cavium-octeon/flash_setup.c
+++ b/arch/mips/cavium-octeon/flash_setup.c
@@ -8,10 +8,11 @@
* Copyright (C) 2007, 2008 Cavium Networks
*/
#include <linux/kernel.h>
-#include <linux/export.h>
+#include <linux/module.h>
#include <linux/semaphore.h>
#include <linux/mtd/mtd.h>
#include <linux/mtd/map.h>
+#include <linux/of_platform.h>
#include <linux/mtd/partitions.h>

#include <asm/octeon/octeon.h>
@@ -66,14 +67,22 @@ static void octeon_flash_map_copy_to(struct map_info *map, unsigned long to,
*
* Returns Zero on success
*/
-static int __init flash_init(void)
+static int octeon_flash_probe(struct platform_device *pdev)
{
+ union cvmx_mio_boot_reg_cfgx region_cfg;
+ u32 cs;
+ int r;
+ struct device_node *np = pdev->dev.of_node;
+
+ r = of_property_read_u32(np, "reg", &cs);
+ if (r)
+ return r;
+
/*
* Read the bootbus region 0 setup to determine the base
* address of the flash.
*/
- union cvmx_mio_boot_reg_cfgx region_cfg;
- region_cfg.u64 = cvmx_read_csr(CVMX_MIO_BOOT_REG_CFGX(0));
+ region_cfg.u64 = cvmx_read_csr(CVMX_MIO_BOOT_REG_CFGX(cs));
if (region_cfg.s.en) {
/*
* The bootloader always takes the flash and sets its
@@ -109,4 +118,27 @@ static int __init flash_init(void)
return 0;
}

-late_initcall(flash_init);
+static struct of_device_id of_flash_match[] = {
+ {
+ .compatible = "cfi-flash",
+ },
+ { },
+};
+MODULE_DEVICE_TABLE(of, of_flash_match);
+
+static struct platform_driver of_flash_driver = {
+ .driver = {
+ .name = "octeon-of-flash",
+ .owner = THIS_MODULE,
+ .of_match_table = of_flash_match,
+ },
+ .probe = octeon_flash_probe,
+};
+
+static int octeon_flash_init(void)
+{
+ return platform_driver_register(&of_flash_driver);
+}
+late_initcall(octeon_flash_init);
+
+MODULE_LICENSE("GPL");
--
2.1.3