aboutsummaryrefslogtreecommitdiffstats
path: root/target/linux/oxnas/files/arch/arm/mach-oxnas/platsmp.c
diff options
context:
space:
mode:
authorDaniel Golle <daniel@makrotopia.org>2018-05-31 17:28:38 +0200
committerDaniel Golle <daniel@makrotopia.org>2018-06-18 18:44:14 +0200
commit6f398aa76248dfdbd1ea31b8ef32431be0f762ee (patch)
treee9c8f6380fdabb0a5e00b6bdd335c9397e93b6ad /target/linux/oxnas/files/arch/arm/mach-oxnas/platsmp.c
parentd6ee5e462c34a337a1b53994df5581a507e2c342 (diff)
downloadupstream-6f398aa76248dfdbd1ea31b8ef32431be0f762ee.tar.gz
upstream-6f398aa76248dfdbd1ea31b8ef32431be0f762ee.tar.bz2
upstream-6f398aa76248dfdbd1ea31b8ef32431be0f762ee.zip
oxnas: reboot target
Reboot the oxnas target based on Linux 4.14 by rebasing our support on top of the now-existing upstream kernel support. This commit brings oxnas support to the level of v4.17 having upstream drivers for Ethernet, Serial and NAND flash. Botch up OpenWrt's local drivers for EHCI, SATA and PCIe based on the new platform code and device-tree. Re-introduce base-files from old oxnas target which works for now but needs further clean-up towards generic board support. Functional issues: * PCIe won't come up (hence no USB3 on Shuttle KD20) * I2C bus of Akitio myCloud device is likely not to work (missing debounce support in new pinctrl driver) Code-style issues: * plla/pllb needs further cleanup -- currently their users are writing into the syscon regmap after acquireling the clk instead of using defined clk_*_*() functions to setup multipliers and dividors. * PCIe phy needs its own little driver. * SATA driver is a monster and should be split into an mfd having a raidctrl regmap, sata controller, sata ports and sata phy. Tested on MitraStar STG-212 aka. Medion Akoya MD86xxx and Shuttle KD20. Signed-off-by: Daniel Golle <daniel@makrotopia.org> (squash-picked commit 17511a7ea8 and commit dcc34574ef from master)
Diffstat (limited to 'target/linux/oxnas/files/arch/arm/mach-oxnas/platsmp.c')
-rw-r--r--target/linux/oxnas/files/arch/arm/mach-oxnas/platsmp.c315
1 files changed, 0 insertions, 315 deletions
diff --git a/target/linux/oxnas/files/arch/arm/mach-oxnas/platsmp.c b/target/linux/oxnas/files/arch/arm/mach-oxnas/platsmp.c
deleted file mode 100644
index 8e4e2d8273..0000000000
--- a/target/linux/oxnas/files/arch/arm/mach-oxnas/platsmp.c
+++ /dev/null
@@ -1,315 +0,0 @@
-/*
- * arch/arm/mach-ox820/platsmp.c
- *
- * Copyright (C) 2002 ARM Ltd.
- * All Rights Reserved
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- */
-#include <linux/init.h>
-#include <linux/device.h>
-#include <linux/jiffies.h>
-#include <linux/smp.h>
-#include <linux/io.h>
-#include <linux/dma-mapping.h>
-#include <linux/cache.h>
-#include <asm/cacheflush.h>
-#include <asm/smp_scu.h>
-#include <asm/tlbflush.h>
-#include <asm/cputype.h>
-#include <linux/delay.h>
-#include <asm/fiq.h>
-
-#include <linux/irqchip/arm-gic.h>
-#include <mach/iomap.h>
-#include <mach/smp.h>
-#include <mach/hardware.h>
-#include <mach/irqs.h>
-
-#ifdef CONFIG_DMA_CACHE_FIQ_BROADCAST
-
-#define FIQ_GENERATE 0x00000002
-#define OXNAS_MAP_AREA 0x01000000
-#define OXNAS_UNMAP_AREA 0x02000000
-#define OXNAS_FLUSH_RANGE 0x03000000
-
-struct fiq_req {
- union {
- struct {
- const void *addr;
- size_t size;
- } map;
- struct {
- const void *addr;
- size_t size;
- } unmap;
- struct {
- const void *start;
- const void *end;
- } flush;
- };
- volatile uint flags;
- void __iomem *reg;
-} ____cacheline_aligned;
-
-static struct fiq_handler fh = {
- .name = "oxnas-fiq"
-};
-
-DEFINE_PER_CPU(struct fiq_req, fiq_data);
-
-static inline void ox820_set_fiq_regs(unsigned int cpu)
-{
- struct pt_regs FIQ_regs;
- struct fiq_req *fiq_req = &per_cpu(fiq_data, !cpu);
-
- FIQ_regs.ARM_r8 = 0;
- FIQ_regs.ARM_ip = (unsigned int)fiq_req;
- FIQ_regs.ARM_sp = (int)(cpu ? RPSC_IRQ_SOFT : RPSA_IRQ_SOFT);
- fiq_req->reg = cpu ? RPSC_IRQ_SOFT : RPSA_IRQ_SOFT;
-
- set_fiq_regs(&FIQ_regs);
-}
-
-static void __init ox820_init_fiq(void)
-{
- void *fiqhandler_start;
- unsigned int fiqhandler_length;
- int ret;
-
- fiqhandler_start = &ox820_fiq_start;
- fiqhandler_length = &ox820_fiq_end - &ox820_fiq_start;
-
- ret = claim_fiq(&fh);
-
- if (ret)
- return;
-
- set_fiq_handler(fiqhandler_start, fiqhandler_length);
-
- writel(IRQ_SOFT, RPSA_FIQ_IRQ_TO_FIQ);
- writel(1, RPSA_FIQ_ENABLE);
- writel(IRQ_SOFT, RPSC_FIQ_IRQ_TO_FIQ);
- writel(1, RPSC_FIQ_ENABLE);
-}
-
-void fiq_dma_map_area(const void *addr, size_t size, int dir)
-{
- unsigned long flags;
- struct fiq_req *req;
-
- raw_local_irq_save(flags);
- /* currently, not possible to take cpu0 down, so only check cpu1 */
- if (!cpu_online(1)) {
- raw_local_irq_restore(flags);
- v6_dma_map_area(addr, size, dir);
- return;
- }
-
- req = this_cpu_ptr(&fiq_data);
- req->map.addr = addr;
- req->map.size = size;
- req->flags = dir | OXNAS_MAP_AREA;
- smp_mb();
-
- writel_relaxed(FIQ_GENERATE, req->reg);
-
- v6_dma_map_area(addr, size, dir);
- while (req->flags)
- barrier();
-
- raw_local_irq_restore(flags);
-}
-
-void fiq_dma_unmap_area(const void *addr, size_t size, int dir)
-{
- unsigned long flags;
- struct fiq_req *req;
-
- raw_local_irq_save(flags);
- /* currently, not possible to take cpu0 down, so only check cpu1 */
- if (!cpu_online(1)) {
- raw_local_irq_restore(flags);
- v6_dma_unmap_area(addr, size, dir);
- return;
- }
-
- req = this_cpu_ptr(&fiq_data);
- req->unmap.addr = addr;
- req->unmap.size = size;
- req->flags = dir | OXNAS_UNMAP_AREA;
- smp_mb();
-
- writel_relaxed(FIQ_GENERATE, req->reg);
-
- v6_dma_unmap_area(addr, size, dir);
- while (req->flags)
- barrier();
-
- raw_local_irq_restore(flags);
-}
-
-void fiq_dma_flush_range(const void *start, const void *end)
-{
- unsigned long flags;
- struct fiq_req *req;
-
- raw_local_irq_save(flags);
- /* currently, not possible to take cpu0 down, so only check cpu1 */
- if (!cpu_online(1)) {
- raw_local_irq_restore(flags);
- v6_dma_flush_range(start, end);
- return;
- }
-
- req = this_cpu_ptr(&fiq_data);
-
- req->flush.start = start;
- req->flush.end = end;
- req->flags = OXNAS_FLUSH_RANGE;
- smp_mb();
-
- writel_relaxed(FIQ_GENERATE, req->reg);
-
- v6_dma_flush_range(start, end);
-
- while (req->flags)
- barrier();
-
- raw_local_irq_restore(flags);
-}
-
-void fiq_flush_kern_dcache_area(void *addr, size_t size)
-{
- fiq_dma_flush_range(addr, addr + size);
-}
-#else
-
-#define ox820_set_fiq_regs(cpu) do {} while (0) /* nothing */
-#define ox820_init_fiq() do {} while (0) /* nothing */
-
-#endif /* DMA_CACHE_FIQ_BROADCAST */
-
-static DEFINE_SPINLOCK(boot_lock);
-
-void ox820_secondary_init(unsigned int cpu)
-{
- /*
- * Setup Secondary Core FIQ regs
- */
- ox820_set_fiq_regs(1);
-
- /*
- * let the primary processor know we're out of the
- * pen, then head off into the C entry point
- */
- write_pen_release(-1);
-
- /*
- * Synchronise with the boot thread.
- */
- spin_lock(&boot_lock);
- spin_unlock(&boot_lock);
-}
-
-int ox820_boot_secondary(unsigned int cpu, struct task_struct *idle)
-{
- unsigned long timeout;
-
- /*
- * Set synchronisation state between this boot processor
- * and the secondary one
- */
- spin_lock(&boot_lock);
-
- /*
- * This is really belt and braces; we hold unintended secondary
- * CPUs in the holding pen until we're ready for them. However,
- * since we haven't sent them a soft interrupt, they shouldn't
- * be there.
- */
- write_pen_release(cpu);
-
- writel(1, IOMEM(OXNAS_GICN_BASE_VA(cpu) + GIC_CPU_CTRL));
-
- /*
- * Send the secondary CPU a soft interrupt, thereby causing
- * the boot monitor to read the system wide flags register,
- * and branch to the address found there.
- */
-
- arch_send_wakeup_ipi_mask(cpumask_of(cpu));
- timeout = jiffies + (1 * HZ);
- while (time_before(jiffies, timeout)) {
- smp_rmb();
- if (read_pen_release() == -1)
- break;
-
- udelay(10);
- }
-
- /*
- * now the secondary core is starting up let it run its
- * calibrations, then wait for it to finish
- */
- spin_unlock(&boot_lock);
-
- return read_pen_release() != -1 ? -ENOSYS : 0;
-}
-
-void *scu_base_addr(void)
-{
- return IOMEM(OXNAS_SCU_BASE_VA);
-}
-
-/*
- * Initialise the CPU possible map early - this describes the CPUs
- * which may be present or become present in the system.
- */
-static void __init ox820_smp_init_cpus(void)
-{
- void __iomem *scu_base = scu_base_addr();
- unsigned int i, ncores;
-
- ncores = scu_base ? scu_get_core_count(scu_base) : 1;
-
- /* sanity check */
- if (ncores > nr_cpu_ids) {
- pr_warn("SMP: %u cores greater than maximum (%u), clipping\n",
- ncores, nr_cpu_ids);
- ncores = nr_cpu_ids;
- }
-
- for (i = 0; i < ncores; i++)
- set_cpu_possible(i, true);
-}
-
-static void __init ox820_smp_prepare_cpus(unsigned int max_cpus)
-{
-
- scu_enable(scu_base_addr());
-
- /*
- * Write the address of secondary startup into the
- * system-wide flags register. The BootMonitor waits
- * until it receives a soft interrupt, and then the
- * secondary CPU branches to this address.
- */
- writel(virt_to_phys(ox820_secondary_startup),
- HOLDINGPEN_LOCATION);
- ox820_init_fiq();
-
- ox820_set_fiq_regs(0);
-}
-
-struct smp_operations ox820_smp_ops __initdata = {
- .smp_init_cpus = ox820_smp_init_cpus,
- .smp_prepare_cpus = ox820_smp_prepare_cpus,
- .smp_secondary_init = ox820_secondary_init,
- .smp_boot_secondary = ox820_boot_secondary,
-#ifdef CONFIG_HOTPLUG_CPU
- .cpu_die = ox820_cpu_die,
-#endif
-};