oxnas: add testing support for Linux 5.15

Rebase patches and port SATA driver to work with Linux > 5.13.
Tested on Shuttle KD-20.

Signed-off-by: Daniel Golle <daniel@makrotopia.org>
This commit is contained in:
Daniel Golle 2022-09-11 02:31:21 +01:00
parent ef59da8669
commit a9dda40fe2
15 changed files with 1295 additions and 0 deletions

View File

@ -8,6 +8,7 @@ FEATURES:=gpio ramdisk rtc squashfs
DEVICE_TYPE:=nas
KERNEL_PATCHVER:=5.10
KERNEL_TESTING_PATCHVER:=5.15
include $(INCLUDE_DIR)/target.mk

View File

@ -0,0 +1,289 @@
CONFIG_ALIGNMENT_TRAP=y
CONFIG_ARCH_32BIT_OFF_T=y
CONFIG_ARCH_HIBERNATION_POSSIBLE=y
CONFIG_ARCH_KEEP_MEMBLOCK=y
CONFIG_ARCH_MIGHT_HAVE_PC_PARPORT=y
CONFIG_ARCH_MULTIPLATFORM=y
CONFIG_ARCH_MULTI_CPU_AUTO=y
# CONFIG_ARCH_MULTI_V4 is not set
# CONFIG_ARCH_MULTI_V4T is not set
CONFIG_ARCH_MULTI_V4_V5=y
CONFIG_ARCH_MULTI_V5=y
CONFIG_ARCH_NR_GPIO=0
CONFIG_ARCH_OPTIONAL_KERNEL_RWX=y
CONFIG_ARCH_OXNAS=y
CONFIG_ARCH_SELECT_MEMORY_MODEL=y
CONFIG_ARCH_SPARSEMEM_ENABLE=y
CONFIG_ARCH_SUSPEND_POSSIBLE=y
CONFIG_ARCH_WANT_LIBATA_LEDS=y
CONFIG_ARM=y
CONFIG_ARM_APPENDED_DTB=y
CONFIG_ARM_ATAG_DTB_COMPAT=y
# CONFIG_ARM_ATAG_DTB_COMPAT_CMDLINE_FROM_BOOTLOADER is not set
CONFIG_ARM_ATAG_DTB_COMPAT_CMDLINE_MANGLE=y
CONFIG_ARM_CPU_SUSPEND=y
CONFIG_ARM_HAS_SG_CHAIN=y
CONFIG_ARM_L1_CACHE_SHIFT=5
CONFIG_ARM_PATCH_PHYS_VIRT=y
# CONFIG_ARM_SMMU is not set
CONFIG_ARM_THUMB=y
CONFIG_ARM_UNWIND=y
CONFIG_ATAGS=y
CONFIG_AUTO_ZRELADDR=y
CONFIG_BINFMT_FLAT_ARGVP_ENVP_ON_STACK=y
CONFIG_BLK_DEBUG_FS=y
CONFIG_BLK_DEV_LOOP=y
CONFIG_BLK_DEV_RAM=y
CONFIG_BLK_DEV_RAM_COUNT=16
CONFIG_BLK_DEV_RAM_SIZE=65536
CONFIG_BLK_PM=y
CONFIG_CLKSRC_MMIO=y
CONFIG_CLONE_BACKWARDS=y
CONFIG_CMA=y
CONFIG_CMA_ALIGNMENT=8
CONFIG_CMA_AREAS=7
# CONFIG_CMA_DEBUG is not set
# CONFIG_CMA_DEBUGFS is not set
CONFIG_CMA_SIZE_MBYTES=64
# CONFIG_CMA_SIZE_SEL_MAX is not set
CONFIG_CMA_SIZE_SEL_MBYTES=y
# CONFIG_CMA_SIZE_SEL_MIN is not set
# CONFIG_CMA_SIZE_SEL_PERCENTAGE is not set
# CONFIG_CMA_SYSFS is not set
CONFIG_CMDLINE_PARTITION=y
CONFIG_COMMON_CLK=y
CONFIG_COMMON_CLK_OXNAS=y
CONFIG_COMPAT_32BIT_TIME=y
CONFIG_CONTIG_ALLOC=y
CONFIG_COREDUMP=y
CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS=y
CONFIG_CPU_32v5=y
CONFIG_CPU_ABRT_EV5TJ=y
CONFIG_CPU_ARM926T=y
# CONFIG_CPU_CACHE_ROUND_ROBIN is not set
CONFIG_CPU_CACHE_VIVT=y
CONFIG_CPU_COPY_V4WB=y
CONFIG_CPU_CP15=y
CONFIG_CPU_CP15_MMU=y
# CONFIG_CPU_DCACHE_WRITETHROUGH is not set
CONFIG_CPU_PABRT_LEGACY=y
CONFIG_CPU_PM=y
CONFIG_CPU_THUMB_CAPABLE=y
CONFIG_CPU_TLB_V4WBI=y
CONFIG_CPU_USE_DOMAINS=y
CONFIG_CRASH_CORE=y
CONFIG_CRC16=y
# CONFIG_CRC32_SARWATE is not set
CONFIG_CRC32_SLICEBY8=y
CONFIG_CROSS_MEMORY_ATTACH=y
CONFIG_CRYPTO_LIB_BLAKE2S_GENERIC=y
CONFIG_CRYPTO_RNG2=y
CONFIG_DEBUG_ALIGN_RODATA=y
CONFIG_DEBUG_BUGVERBOSE=y
CONFIG_DEBUG_LL_INCLUDE="mach/debug-macro.S"
CONFIG_DECOMPRESS_BZIP2=y
CONFIG_DECOMPRESS_GZIP=y
CONFIG_DECOMPRESS_LZ4=y
CONFIG_DECOMPRESS_LZMA=y
CONFIG_DECOMPRESS_LZO=y
CONFIG_DECOMPRESS_XZ=y
CONFIG_DMA_CMA=y
CONFIG_DMA_OPS=y
CONFIG_DMA_REMAP=y
CONFIG_DNOTIFY=y
CONFIG_DTC=y
CONFIG_DWMAC_GENERIC=y
CONFIG_DWMAC_OXNAS=y
CONFIG_EDAC_ATOMIC_SCRUB=y
CONFIG_EDAC_SUPPORT=y
CONFIG_ELF_CORE=y
CONFIG_FAT_FS=y
CONFIG_FIXED_PHY=y
CONFIG_FIX_EARLYCON_MEM=y
CONFIG_FREEZER=y
CONFIG_FWNODE_MDIO=y
# CONFIG_FW_CACHE is not set
CONFIG_FW_LOADER_PAGED_BUF=y
CONFIG_GENERIC_ALLOCATOR=y
CONFIG_GENERIC_ATOMIC64=y
CONFIG_GENERIC_BUG=y
CONFIG_GENERIC_CLOCKEVENTS=y
CONFIG_GENERIC_CPU_AUTOPROBE=y
CONFIG_GENERIC_EARLY_IOREMAP=y
CONFIG_GENERIC_IDLE_POLL_SETUP=y
CONFIG_GENERIC_IRQ_MULTI_HANDLER=y
CONFIG_GENERIC_IRQ_SHOW=y
CONFIG_GENERIC_IRQ_SHOW_LEVEL=y
CONFIG_GENERIC_LIB_DEVMEM_IS_ALLOWED=y
CONFIG_GENERIC_PCI_IOMAP=y
CONFIG_GENERIC_PHY=y
CONFIG_GENERIC_PINCONF=y
CONFIG_GENERIC_SCHED_CLOCK=y
CONFIG_GENERIC_SMP_IDLE_THREAD=y
CONFIG_GENERIC_STRNCPY_FROM_USER=y
CONFIG_GENERIC_STRNLEN_USER=y
CONFIG_GPIOLIB_IRQCHIP=y
CONFIG_GPIO_CDEV=y
CONFIG_GPIO_GENERIC=y
CONFIG_GPIO_GENERIC_PLATFORM=y
CONFIG_HANDLE_DOMAIN_IRQ=y
CONFIG_HARDIRQS_SW_RESEND=y
CONFIG_HAS_DMA=y
CONFIG_HAS_IOMEM=y
CONFIG_HAS_IOPORT_MAP=y
CONFIG_HID=y
CONFIG_HID_GENERIC=y
CONFIG_HWMON=y
CONFIG_HZ_FIXED=0
CONFIG_ICPLUS_PHY=y
CONFIG_INET_DIAG=y
# CONFIG_INET_DIAG_DESTROY is not set
# CONFIG_INET_RAW_DIAG is not set
CONFIG_INET_TCP_DIAG=y
CONFIG_INITRAMFS_SOURCE=""
CONFIG_INPUT=y
# CONFIG_IOMMU_DEBUGFS is not set
# CONFIG_IOMMU_IO_PGTABLE_ARMV7S is not set
# CONFIG_IOMMU_IO_PGTABLE_LPAE is not set
CONFIG_IOMMU_SUPPORT=y
CONFIG_IRQCHIP=y
CONFIG_IRQ_DOMAIN=y
CONFIG_IRQ_FORCED_THREADING=y
CONFIG_IRQ_WORK=y
# CONFIG_ISDN is not set
# CONFIG_JFFS2_FS is not set
CONFIG_KALLSYMS=y
CONFIG_KERNEL_GZIP=y
# CONFIG_KERNEL_XZ is not set
CONFIG_KEXEC=y
CONFIG_KEXEC_CORE=y
# CONFIG_LEDS_BRIGHTNESS_HW_CHANGED is not set
CONFIG_LEDS_GPIO=y
CONFIG_LEDS_TRIGGER_CPU=y
CONFIG_LEDS_TRIGGER_GPIO=y
CONFIG_LEDS_TRIGGER_ONESHOT=y
CONFIG_LIBFDT=y
CONFIG_LOCALVERSION_AUTO=y
CONFIG_LOCK_DEBUGGING_SUPPORT=y
CONFIG_LZ4_DECOMPRESS=y
CONFIG_LZO_DECOMPRESS=y
# CONFIG_MACH_OX810SE is not set
CONFIG_MDIO_BUS=y
CONFIG_MDIO_DEVICE=y
CONFIG_MDIO_DEVRES=y
CONFIG_MEMFD_CREATE=y
CONFIG_MEMORY_ISOLATION=y
CONFIG_MFD_SYSCON=y
CONFIG_MIGRATION=y
CONFIG_MODULES_USE_ELF_REL=y
CONFIG_NEED_DMA_MAP_STATE=y
CONFIG_NEED_KUSER_HELPERS=y
CONFIG_NEED_PER_CPU_KM=y
CONFIG_NET_PTP_CLASSIFY=y
CONFIG_NET_SELFTESTS=y
CONFIG_NLS=y
CONFIG_NO_HZ=y
CONFIG_NO_HZ_COMMON=y
CONFIG_NO_HZ_IDLE=y
CONFIG_OF=y
CONFIG_OF_ADDRESS=y
CONFIG_OF_EARLY_FLATTREE=y
CONFIG_OF_FLATTREE=y
CONFIG_OF_GPIO=y
CONFIG_OF_IRQ=y
CONFIG_OF_KOBJ=y
CONFIG_OF_MDIO=y
CONFIG_OLD_SIGACTION=y
CONFIG_OLD_SIGSUSPEND3=y
CONFIG_OXNAS_RPS_TIMER=y
CONFIG_PAGE_OFFSET=0xC0000000
CONFIG_PAGE_POOL=y
# CONFIG_PANIC_ON_OOPS is not set
CONFIG_PANIC_ON_OOPS_VALUE=0
CONFIG_PANIC_TIMEOUT=0
CONFIG_PCS_XPCS=y
CONFIG_PERF_USE_VMALLOC=y
CONFIG_PGTABLE_LEVELS=2
CONFIG_PHYLIB=y
CONFIG_PHYLINK=y
CONFIG_PHY_OXNAS=y
CONFIG_PINCTRL=y
CONFIG_PINCTRL_OXNAS=y
# CONFIG_PINCTRL_SINGLE is not set
CONFIG_PM=y
CONFIG_PM_CLK=y
CONFIG_PM_SLEEP=y
CONFIG_POWER_RESET=y
CONFIG_POWER_RESET_OXNAS=y
CONFIG_PPS=y
CONFIG_PTP_1588_CLOCK=y
CONFIG_PTP_1588_CLOCK_OPTIONAL=y
CONFIG_RAS=y
CONFIG_RATIONAL=y
CONFIG_RCU_TRACE=y
CONFIG_RD_BZIP2=y
CONFIG_RD_GZIP=y
CONFIG_RD_LZ4=y
CONFIG_RD_LZMA=y
CONFIG_RD_LZO=y
CONFIG_RD_XZ=y
CONFIG_REALTEK_PHY=y
CONFIG_REGMAP=y
CONFIG_REGMAP_MMIO=y
CONFIG_RESET_CONTROLLER=y
CONFIG_RESET_OXNAS=y
CONFIG_SCHED_DEBUG=y
CONFIG_SERIAL_8250_DEPRECATED_OPTIONS=y
CONFIG_SERIAL_8250_FSL=y
CONFIG_SERIAL_8250_NR_UARTS=4
CONFIG_SERIAL_8250_RUNTIME_UARTS=4
CONFIG_SERIAL_MCTRL_GPIO=y
CONFIG_SERIAL_OF_PLATFORM=y
CONFIG_SERIO=y
CONFIG_SERIO_LIBPS2=y
CONFIG_SERIO_SERPORT=y
CONFIG_SLUB_DEBUG=y
CONFIG_SOCK_DIAG=y
CONFIG_SPARSE_IRQ=y
CONFIG_SPLIT_PTLOCK_CPUS=999999
CONFIG_SRCU=y
CONFIG_STACKTRACE=y
CONFIG_STMMAC_ETH=y
CONFIG_STMMAC_PLATFORM=y
# CONFIG_STRIP_ASM_SYMS is not set
CONFIG_SUSPEND=y
CONFIG_SUSPEND_FREEZER=y
CONFIG_SWPHY=y
CONFIG_SYS_SUPPORTS_APM_EMULATION=y
CONFIG_THERMAL=y
CONFIG_THERMAL_DEFAULT_GOV_STEP_WISE=y
CONFIG_THERMAL_EMERGENCY_POWEROFF_DELAY_MS=0
CONFIG_THERMAL_GOV_STEP_WISE=y
CONFIG_THERMAL_HWMON=y
CONFIG_THERMAL_OF=y
CONFIG_TICK_CPU_ACCOUNTING=y
CONFIG_TIMER_OF=y
CONFIG_TIMER_PROBE=y
CONFIG_TINY_SRCU=y
CONFIG_TRACE_CLOCK=y
CONFIG_UEVENT_HELPER_PATH=""
CONFIG_UNCOMPRESS_INCLUDE="debug/uncompress.h"
CONFIG_UNWINDER_ARM=y
CONFIG_USB_SUPPORT=y
CONFIG_USE_OF=y
CONFIG_VERSATILE_FPGA_IRQ=y
CONFIG_VERSATILE_FPGA_IRQ_NR=4
CONFIG_VFAT_FS=y
# CONFIG_VFP is not set
CONFIG_VM_EVENT_COUNTERS=y
# CONFIG_WATCHDOG is not set
# CONFIG_WQ_POWER_EFFICIENT_DEFAULT is not set
CONFIG_XZ_DEC_ARM=y
CONFIG_XZ_DEC_BCJ=y
CONFIG_XZ_DEC_IA64=y
CONFIG_XZ_DEC_POWERPC=y
CONFIG_XZ_DEC_SPARC=y
CONFIG_XZ_DEC_X86=y
CONFIG_ZBOOT_ROM_BSS=0
CONFIG_ZBOOT_ROM_TEXT=0
CONFIG_ZLIB_INFLATE=y

View File

@ -31,6 +31,7 @@
#include <linux/io.h>
#include <linux/sizes.h>
#include <linux/version.h>
static inline void oxnas_register_clear_mask(void __iomem *p, unsigned mask)
{
@ -2231,7 +2232,9 @@ static struct scsi_host_template sata_oxnas_sht = {
.can_queue = SATA_OXNAS_QUEUE_DEPTH,
.sg_tablesize = SATA_OXNAS_MAX_PRD,
.dma_boundary = ATA_DMA_BOUNDARY,
#if LINUX_VERSION_CODE < KERNEL_VERSION(5, 13, 0)
.unchecked_isa_dma = 0,
#endif
};

View File

@ -52,7 +52,11 @@ CONFIG_MIGHT_HAVE_PCI=y
CONFIG_MTD_CMDLINE_PARTS=y
# CONFIG_MTD_COMPLEX_MAPPINGS is not set
CONFIG_MTD_NAND=y
CONFIG_MTD_NAND_CORE=y
CONFIG_MTD_NAND_ECC=y
# CONFIG_MTD_NAND_ECC_SW_BCH is not set
CONFIG_MTD_NAND_ECC_SW_HAMMING=y
# CONFIG_MTD_NAND_ECC_SW_HAMMING_SMC is not set
CONFIG_MTD_NAND_OXNAS=y
CONFIG_MTD_RAW_NAND=y
CONFIG_MTD_UBI=y

View File

@ -0,0 +1,82 @@
- add compatible string
- add console to bootargs
- add led aliases
- adjust nand partition table
---
--- a/arch/arm/boot/dts/ox820-cloudengines-pogoplug-series-3.dts
+++ b/arch/arm/boot/dts/ox820-cloudengines-pogoplug-series-3.dts
@@ -11,10 +11,10 @@
/ {
model = "Cloud Engines PogoPlug Series 3";
- compatible = "cloudengines,pogoplugv3", "oxsemi,ox820";
+ compatible = "cloudengines,pogoplug-series-3", "cloudengines,pogoplugv3", "oxsemi,ox820";
chosen {
- bootargs = "earlyprintk";
+ bootargs = "earlyprintk console=ttyS0,115200";
stdout-path = "serial0:115200n8";
};
@@ -27,24 +27,28 @@
serial0 = &uart0;
gpio0 = &gpio0;
gpio1 = &gpio1;
+ led-boot = &led_status;
+ led-failsafe = &led_warn;
+ led-running = &led_act;
+ led-upgrade = &led_warn;
};
leds {
compatible = "gpio-leds";
- blue {
+ led_status: blue {
label = "pogoplug:blue";
gpios = <&gpio0 2 0>;
default-state = "keep";
};
- orange {
+ led_warn: orange {
label = "pogoplug:orange";
gpios = <&gpio1 16 1>;
default-state = "keep";
};
- green {
+ led_act: green {
label = "pogoplug:green";
gpios = <&gpio1 17 1>;
default-state = "keep";
@@ -73,11 +77,27 @@
nand-ecc-algo = "hamming";
partition@0 {
- label = "boot";
- reg = <0x00000000 0x00e00000>;
+ label = "stage1";
+ reg = <0x00000000 0x00040000>;
read-only;
};
+ partition@40000 {
+ label = "u-boot";
+ reg = <0x00040000 0x00380000>;
+ read-only;
+ };
+
+ partition@3c0000 {
+ label = "u-boot-env";
+ reg = <0x003c0000 0x00080000>;
+ };
+
+ partition@440000 {
+ label = "kernel";
+ reg = <0x00440000 0x009c0000>;
+ };
+
partition@e00000 {
label = "ubi";
reg = <0x00e00000 0x07200000>;

View File

@ -0,0 +1,63 @@
From 552ed4955c1fee1109bf5ba137dc35a411a1448c Mon Sep 17 00:00:00 2001
From: Daniel Golle <daniel@makrotopia.org>
Date: Fri, 1 Jun 2018 02:41:15 +0200
Subject: [PATCH] arm: ox820: remove left-overs
Signed-off-by: Daniel Golle <daniel@makrotopia.org>
---
drivers/clk/clk-oxnas.c | 2 --
include/dt-bindings/clock/oxsemi,ox820.h | 32 +++++++++++-------------
2 files changed, 14 insertions(+), 20 deletions(-)
--- a/drivers/clk/clk-oxnas.c
+++ b/drivers/clk/clk-oxnas.c
@@ -29,8 +29,6 @@ struct oxnas_stdclk_data {
struct clk_hw_onecell_data *onecell_data;
struct clk_oxnas_gate **gates;
unsigned int ngates;
- struct clk_oxnas_pll **plls;
- unsigned int nplls;
};
/* Regmap offsets */
--- a/include/dt-bindings/clock/oxsemi,ox820.h
+++ b/include/dt-bindings/clock/oxsemi,ox820.h
@@ -6,24 +6,20 @@
#ifndef DT_CLOCK_OXSEMI_OX820_H
#define DT_CLOCK_OXSEMI_OX820_H
-/* PLLs */
-#define CLK_820_PLLA 0
-#define CLK_820_PLLB 1
-
/* Gate Clocks */
-#define CLK_820_LEON 2
-#define CLK_820_DMA_SGDMA 3
-#define CLK_820_CIPHER 4
-#define CLK_820_SD 5
-#define CLK_820_SATA 6
-#define CLK_820_AUDIO 7
-#define CLK_820_USBMPH 8
-#define CLK_820_ETHA 9
-#define CLK_820_PCIEA 10
-#define CLK_820_NAND 11
-#define CLK_820_PCIEB 12
-#define CLK_820_ETHB 13
-#define CLK_820_REF600 14
-#define CLK_820_USBDEV 15
+#define CLK_820_LEON 0
+#define CLK_820_DMA_SGDMA 1
+#define CLK_820_CIPHER 2
+#define CLK_820_SD 3
+#define CLK_820_SATA 4
+#define CLK_820_AUDIO 5
+#define CLK_820_USBMPH 6
+#define CLK_820_ETHA 7
+#define CLK_820_PCIEA 8
+#define CLK_820_NAND 9
+#define CLK_820_PCIEB 10
+#define CLK_820_ETHB 11
+#define CLK_820_REF600 12
+#define CLK_820_USBDEV 13
#endif /* DT_CLOCK_OXSEMI_OX820_H */

View File

@ -0,0 +1,273 @@
--- a/drivers/clk/clk-oxnas.c
+++ b/drivers/clk/clk-oxnas.c
@@ -5,19 +5,42 @@
* Copyright (C) 2016 Neil Armstrong <narmstrong@baylibre.com>
*/
+#include <linux/clk.h>
+#include <linux/clkdev.h>
#include <linux/clk-provider.h>
#include <linux/kernel.h>
#include <linux/init.h>
+#include <linux/delay.h>
#include <linux/of.h>
#include <linux/of_device.h>
#include <linux/platform_device.h>
#include <linux/stringify.h>
#include <linux/regmap.h>
#include <linux/mfd/syscon.h>
+#include <linux/reset.h>
#include <dt-bindings/clock/oxsemi,ox810se.h>
#include <dt-bindings/clock/oxsemi,ox820.h>
+#define REF300_DIV_INT_SHIFT 8
+#define REF300_DIV_FRAC_SHIFT 0
+#define REF300_DIV_INT(val) ((val) << REF300_DIV_INT_SHIFT)
+#define REF300_DIV_FRAC(val) ((val) << REF300_DIV_FRAC_SHIFT)
+
+#define PLLB_BYPASS 1
+#define PLLB_ENSAT 3
+#define PLLB_OUTDIV 4
+#define PLLB_REFDIV 8
+#define PLLB_DIV_INT_SHIFT 8
+#define PLLB_DIV_FRAC_SHIFT 0
+#define PLLB_DIV_INT(val) ((val) << PLLB_DIV_INT_SHIFT)
+#define PLLB_DIV_FRAC(val) ((val) << PLLB_DIV_FRAC_SHIFT)
+
+#define PLLA_REFDIV_MASK 0x3F
+#define PLLA_REFDIV_SHIFT 8
+#define PLLA_OUTDIV_MASK 0x7
+#define PLLA_OUTDIV_SHIFT 4
+
/* Standard regmap gate clocks */
struct clk_oxnas_gate {
struct clk_hw hw;
@@ -36,6 +59,135 @@ struct oxnas_stdclk_data {
#define CLK_SET_REGOFFSET 0x2c
#define CLK_CLR_REGOFFSET 0x30
+#define PLLA_CTRL0_REGOFFSET 0x1f0
+#define PLLA_CTRL1_REGOFFSET 0x1f4
+#define PLLB_CTRL0_REGOFFSET 0x1001f0
+#define MHZ (1000 * 1000)
+
+struct clk_oxnas_pll {
+ struct clk_hw hw;
+ struct device_node *devnode;
+ struct reset_control *rstc;
+ struct regmap *syscon;
+};
+
+#define to_clk_oxnas_pll(_hw) container_of(_hw, struct clk_oxnas_pll, hw)
+
+static unsigned long plla_clk_recalc_rate(struct clk_hw *hw,
+ unsigned long parent_rate)
+{
+ struct clk_oxnas_pll *plla = to_clk_oxnas_pll(hw);
+ unsigned long fin = parent_rate;
+ unsigned long refdiv, outdiv;
+ unsigned int pll0, fbdiv;
+
+ BUG_ON(regmap_read(plla->syscon, PLLA_CTRL0_REGOFFSET, &pll0));
+
+ refdiv = (pll0 >> PLLA_REFDIV_SHIFT) & PLLA_REFDIV_MASK;
+ refdiv += 1;
+ outdiv = (pll0 >> PLLA_OUTDIV_SHIFT) & PLLA_OUTDIV_MASK;
+ outdiv += 1;
+
+ BUG_ON(regmap_read(plla->syscon, PLLA_CTRL1_REGOFFSET, &fbdiv));
+ /* seems we will not be here when pll is bypassed, so ignore this
+ * case */
+
+ return fin / MHZ * fbdiv / (refdiv * outdiv) / 32768 * MHZ;
+}
+
+static const char *pll_clk_parents[] = {
+ "oscillator",
+};
+
+static struct clk_ops plla_ops = {
+ .recalc_rate = plla_clk_recalc_rate,
+};
+
+static struct clk_init_data clk_plla_init = {
+ .name = "plla",
+ .ops = &plla_ops,
+ .parent_names = pll_clk_parents,
+ .num_parents = ARRAY_SIZE(pll_clk_parents),
+};
+
+static int pllb_clk_is_prepared(struct clk_hw *hw)
+{
+ struct clk_oxnas_pll *pllb = to_clk_oxnas_pll(hw);
+
+ return !!pllb->rstc;
+}
+
+static int pllb_clk_prepare(struct clk_hw *hw)
+{
+ struct clk_oxnas_pll *pllb = to_clk_oxnas_pll(hw);
+
+ pllb->rstc = of_reset_control_get(pllb->devnode, NULL);
+
+ return IS_ERR(pllb->rstc) ? PTR_ERR(pllb->rstc) : 0;
+}
+
+static void pllb_clk_unprepare(struct clk_hw *hw)
+{
+ struct clk_oxnas_pll *pllb = to_clk_oxnas_pll(hw);
+
+ BUG_ON(IS_ERR(pllb->rstc));
+
+ reset_control_put(pllb->rstc);
+ pllb->rstc = NULL;
+}
+
+static int pllb_clk_enable(struct clk_hw *hw)
+{
+ struct clk_oxnas_pll *pllb = to_clk_oxnas_pll(hw);
+
+ BUG_ON(IS_ERR(pllb->rstc));
+
+ /* put PLL into bypass */
+ regmap_update_bits(pllb->syscon, PLLB_CTRL0_REGOFFSET, BIT(PLLB_BYPASS), BIT(PLLB_BYPASS));
+ wmb();
+ udelay(10);
+ reset_control_assert(pllb->rstc);
+ udelay(10);
+ /* set PLL B control information */
+ regmap_write_bits(pllb->syscon, PLLB_CTRL0_REGOFFSET, 0xffff,
+ (1 << PLLB_ENSAT) | (1 << PLLB_OUTDIV) | (2 << PLLB_REFDIV));
+ reset_control_deassert(pllb->rstc);
+ udelay(100);
+ regmap_update_bits(pllb->syscon, PLLB_CTRL0_REGOFFSET, BIT(PLLB_BYPASS), 0);
+
+ return 0;
+}
+
+static void pllb_clk_disable(struct clk_hw *hw)
+{
+ struct clk_oxnas_pll *pllb = to_clk_oxnas_pll(hw);
+
+ BUG_ON(IS_ERR(pllb->rstc));
+
+ /* put PLL into bypass */
+ regmap_update_bits(pllb->syscon, PLLB_CTRL0_REGOFFSET, BIT(PLLB_BYPASS), BIT(PLLB_BYPASS));
+
+ wmb();
+ udelay(10);
+
+ reset_control_assert(pllb->rstc);
+}
+
+static struct clk_ops pllb_ops = {
+ .prepare = pllb_clk_prepare,
+ .unprepare = pllb_clk_unprepare,
+ .is_prepared = pllb_clk_is_prepared,
+ .enable = pllb_clk_enable,
+ .disable = pllb_clk_disable,
+};
+
+static struct clk_init_data clk_pllb_init = {
+ .name = "pllb",
+ .ops = &pllb_ops,
+ .parent_names = pll_clk_parents,
+ .num_parents = ARRAY_SIZE(pll_clk_parents),
+};
+
static inline struct clk_oxnas_gate *to_clk_oxnas_gate(struct clk_hw *hw)
{
return container_of(hw, struct clk_oxnas_gate, hw);
@@ -249,3 +401,42 @@ static struct platform_driver oxnas_stdc
},
};
builtin_platform_driver(oxnas_stdclk_driver);
+
+void __init oxnas_init_plla(struct device_node *np)
+{
+ struct clk *clk;
+ struct clk_oxnas_pll *plla;
+
+ plla = kmalloc(sizeof(*plla), GFP_KERNEL);
+ BUG_ON(!plla);
+
+ plla->syscon = syscon_node_to_regmap(of_get_parent(np));
+ plla->hw.init = &clk_plla_init;
+ plla->devnode = np;
+ plla->rstc = NULL;
+ clk = clk_register(NULL, &plla->hw);
+ BUG_ON(IS_ERR(clk));
+ /* mark it as enabled */
+ clk_prepare_enable(clk);
+ of_clk_add_provider(np, of_clk_src_simple_get, clk);
+}
+CLK_OF_DECLARE(oxnas_plla, "plxtech,nas782x-plla", oxnas_init_plla);
+
+void __init oxnas_init_pllb(struct device_node *np)
+{
+ struct clk *clk;
+ struct clk_oxnas_pll *pllb;
+
+ pllb = kmalloc(sizeof(*pllb), GFP_KERNEL);
+ BUG_ON(!pllb);
+
+ pllb->syscon = syscon_node_to_regmap(of_get_parent(np));
+ pllb->hw.init = &clk_pllb_init;
+ pllb->devnode = np;
+ pllb->rstc = NULL;
+
+ clk = clk_register(NULL, &pllb->hw);
+ BUG_ON(IS_ERR(clk));
+ of_clk_add_provider(np, of_clk_src_simple_get, clk);
+}
+CLK_OF_DECLARE(oxnas_pllb, "plxtech,nas782x-pllb", oxnas_init_pllb);
--- a/arch/arm/boot/dts/ox820.dtsi
+++ b/arch/arm/boot/dts/ox820.dtsi
@@ -61,12 +61,6 @@
clocks = <&osc>;
};
- plla: plla {
- compatible = "fixed-clock";
- #clock-cells = <0>;
- clock-frequency = <850000000>;
- };
-
armclk: armclk {
compatible = "fixed-factor-clock";
#clock-cells = <0>;
@@ -266,6 +260,19 @@
compatible = "oxsemi,ox820-stdclk", "oxsemi,ox810se-stdclk";
#clock-cells = <1>;
};
+
+ plla: plla {
+ compatible = "plxtech,nas782x-plla";
+ #clock-cells = <0>;
+ clocks = <&osc>;
+ };
+
+ pllb: pllb {
+ compatible = "plxtech,nas782x-pllb";
+ #clock-cells = <0>;
+ clocks = <&osc>;
+ resets = <&reset RESET_PLLB>;
+ };
};
};
@@ -287,6 +294,13 @@
clocks = <&armclk>;
};
+ watchdog@620 {
+ compatible = "mpcore_wdt";
+ reg = <0x620 0x20>;
+ interrupts = <GIC_PPI 14 (GIC_CPU_MASK_RAW(3)|IRQ_TYPE_LEVEL_HIGH)>;
+ clocks = <&armclk>;
+ };
+
gic: interrupt-controller@1000 {
compatible = "arm,arm11mp-gic";
interrupt-controller;

View File

@ -0,0 +1,25 @@
--- a/drivers/power/reset/Kconfig
+++ b/drivers/power/reset/Kconfig
@@ -148,6 +148,12 @@ config POWER_RESET_OXNAS
help
Restart support for OXNAS/PLXTECH OX820 SoC.
+config POWER_RESET_OXNAS
+ bool "OXNAS SoC restart driver"
+ depends on ARCH_OXNAS
+ help
+ Restart support for OXNAS boards.
+
config POWER_RESET_PIIX4_POWEROFF
tristate "Intel PIIX4 power-off driver"
depends on PCI
--- a/drivers/power/reset/Makefile
+++ b/drivers/power/reset/Makefile
@@ -19,6 +19,7 @@ obj-$(CONFIG_POWER_RESET_QCOM_PON) += qc
obj-$(CONFIG_POWER_RESET_OCELOT_RESET) += ocelot-reset.o
obj-$(CONFIG_POWER_RESET_PIIX4_POWEROFF) += piix4-poweroff.o
obj-$(CONFIG_POWER_RESET_LTC2952) += ltc2952-poweroff.o
+obj-$(CONFIG_POWER_RESET_OXNAS) += oxnas-restart.o
obj-$(CONFIG_POWER_RESET_QNAP) += qnap-poweroff.o
obj-$(CONFIG_POWER_RESET_REGULATOR) += regulator-poweroff.o
obj-$(CONFIG_POWER_RESET_RESTART) += restart-poweroff.o

View File

@ -0,0 +1,44 @@
--- a/arch/arm/boot/dts/ox820.dtsi
+++ b/arch/arm/boot/dts/ox820.dtsi
@@ -247,6 +247,15 @@
};
};
+ pcie_phy: pcie-phy@a00000 {
+ compatible = "oxsemi,ox820-pcie-phy";
+ reg = <0xa00000 0x10>;
+ #phy-cells = <0>;
+ resets = <&reset RESET_PCIEPHY>;
+ reset-names = "phy";
+ status = "disabled";
+ };
+
sys: sys-ctrl@e00000 {
compatible = "oxsemi,ox820-sys-ctrl", "syscon", "simple-mfd";
reg = <0xe00000 0x200000>;
--- a/drivers/phy/Kconfig
+++ b/drivers/phy/Kconfig
@@ -35,6 +35,13 @@ config PHY_LPC18XX_USB_OTG
This driver is need for USB0 support on LPC18xx/43xx and takes
care of enabling and clock setup.
+config PHY_OXNAS
+ tristate "Oxford Semi. OX820 PCI-E PHY support"
+ depends on HAS_IOMEM && OF && (ARM || COMPILE_TEST)
+ select GENERIC_PHY
+ help
+ This option enables support for OXNAS OX820 SoC PCIE PHY.
+
config PHY_PISTACHIO_USB
tristate "IMG Pistachio USB2.0 PHY driver"
depends on MIPS || COMPILE_TEST
--- a/drivers/phy/Makefile
+++ b/drivers/phy/Makefile
@@ -7,6 +7,7 @@ obj-$(CONFIG_GENERIC_PHY) += phy-core.o
obj-$(CONFIG_GENERIC_PHY_MIPI_DPHY) += phy-core-mipi-dphy.o
obj-$(CONFIG_PHY_CAN_TRANSCEIVER) += phy-can-transceiver.o
obj-$(CONFIG_PHY_LPC18XX_USB_OTG) += phy-lpc18xx-usb-otg.o
+obj-$(CONFIG_PHY_OXNAS) += phy-oxnas-pcie.o
obj-$(CONFIG_PHY_XGENE) += phy-xgene.o
obj-$(CONFIG_PHY_PISTACHIO_USB) += phy-pistachio-usb.o
obj-$(CONFIG_USB_LGM_PHY) += phy-lgm-usb.o

View File

@ -0,0 +1,122 @@
--- a/drivers/pci/controller/Kconfig
+++ b/drivers/pci/controller/Kconfig
@@ -312,6 +312,11 @@ config PCIE_HISI_ERR
Say Y here if you want error handling support
for the PCIe controller's errors on HiSilicon HIP SoCs
+config PCIE_OXNAS
+ bool "PLX Oxnas PCIe controller"
+ depends on ARCH_OXNAS
+ select PCIEPORTBUS
+
source "drivers/pci/controller/dwc/Kconfig"
source "drivers/pci/controller/mobiveil/Kconfig"
source "drivers/pci/controller/cadence/Kconfig"
--- a/drivers/pci/controller/Makefile
+++ b/drivers/pci/controller/Makefile
@@ -33,6 +33,7 @@ obj-$(CONFIG_PCIE_ROCKCHIP_HOST) += pcie
obj-$(CONFIG_PCIE_MEDIATEK) += pcie-mediatek.o
obj-$(CONFIG_PCIE_MEDIATEK_GEN3) += pcie-mediatek-gen3.o
obj-$(CONFIG_PCIE_MICROCHIP_HOST) += pcie-microchip-host.o
+obj-$(CONFIG_PCIE_OXNAS) += pcie-oxnas.o
obj-$(CONFIG_VMD) += vmd.o
obj-$(CONFIG_PCIE_BRCMSTB) += pcie-brcmstb.o
obj-$(CONFIG_PCI_LOONGSON) += pci-loongson.o
--- a/arch/arm/boot/dts/ox820.dtsi
+++ b/arch/arm/boot/dts/ox820.dtsi
@@ -289,7 +289,7 @@
#address-cells = <1>;
#size-cells = <1>;
compatible = "simple-bus";
- ranges = <0 0x47000000 0x1000000>;
+ ranges = <0 0x47000000 0x2000>;
scu: scu@0 {
compatible = "arm,arm11mp-scu";
@@ -318,5 +318,86 @@
<0x100 0x500>;
};
};
+
+ pcie0: pcie-controller@47c00000 {
+ compatible = "plxtech,nas782x-pcie";
+ device_type = "pci";
+ #address-cells = <3>;
+ #size-cells = <2>;
+
+ /* flag & space bus address host address size */
+ ranges = < 0x82000000 0 0x48000000 0x48000000 0 0x2000000
+ 0xC2000000 0 0x4A000000 0x4A000000 0 0x1E00000
+ 0x81000000 0 0x4BE00000 0x4BE00000 0 0x0100000
+ 0x80000000 0 0x4BF00000 0x4BF00000 0 0x0100000>;
+
+ bus-range = <0x00 0x7f>;
+
+ /* cfg inbound translator */
+ reg = <0x47c00000 0x1000>, <0x47d00000 0x100>;
+
+ phys = <&pcie_phy>;
+ phy-names = "pcie-phy";
+
+ #interrupt-cells = <1>;
+ /* wild card mask, match all bus address & interrupt specifier */
+ /* format: bus address mask, interrupt specifier mask */
+ /* each bit 1 means need match, 0 means ignored when match */
+ interrupt-map-mask = <0 0 0 0>;
+ /* format: a list of: bus address, interrupt specifier,
+ * parent interrupt controller & specifier */
+ interrupt-map = <0 0 0 0 &gic 0 19 0x304>;
+ gpios = <&gpio1 12 0>;
+ clocks = <&stdclk CLK_820_PCIEA>, <&pllb>;
+ clock-names = "pcie", "busclk";
+ resets = <&reset RESET_PCIEA>;
+ reset-names = "pcie";
+
+ plxtech,pcie-hcsl-bit = <2>;
+ plxtech,pcie-ctrl-offset = <0x120>;
+ plxtech,pcie-outbound-offset = <0x138>;
+ status = "disabled";
+ };
+
+ pcie1: pcie-controller@47e00000 {
+ compatible = "plxtech,nas782x-pcie";
+ device_type = "pci";
+ #address-cells = <3>;
+ #size-cells = <2>;
+
+ /* flag & space bus address host address size */
+ ranges = < 0x82000000 0 0x4C000000 0x4C000000 0 0x2000000
+ 0xC2000000 0 0x4E000000 0x4E000000 0 0x1E00000
+ 0x81000000 0 0x4FE00000 0x4FE00000 0 0x0100000
+ 0x80000000 0 0x4FF00000 0x4FF00000 0 0x0100000>;
+
+ bus-range = <0x80 0xff>;
+
+ /* cfg inbound translator */
+ reg = <0x47e00000 0x1000>, <0x47f00000 0x100>;
+
+ phys = <&pcie_phy>;
+ phy-names = "pcie-phy";
+
+ #interrupt-cells = <1>;
+ /* wild card mask, match all bus address & interrupt specifier */
+ /* format: bus address mask, interrupt specifier mask */
+ /* each bit 1 means need match, 0 means ignored when match */
+ interrupt-map-mask = <0 0 0 0>;
+ /* format: a list of: bus address, interrupt specifier,
+ * parent interrupt controller & specifier */
+ interrupt-map = <0 0 0 0 &gic 0 20 0x304>;
+
+ /* gpios = <&gpio1 12 0>; */
+ clocks = <&stdclk CLK_820_PCIEB>, <&pllb>;
+ clock-names = "pcie", "busclk";
+ resets = <&reset RESET_PCIEB>;
+ reset-names = "pcie";
+
+ plxtech,pcie-hcsl-bit = <3>;
+ plxtech,pcie-ctrl-offset = <0x124>;
+ plxtech,pcie-outbound-offset = <0x174>;
+ status = "disabled";
+ };
};
};

View File

@ -0,0 +1,60 @@
--- a/drivers/ata/Kconfig
+++ b/drivers/ata/Kconfig
@@ -568,6 +568,14 @@ config SATA_VITESSE
If unsure, say N.
+config SATA_OXNAS
+ tristate "PLXTECH NAS782X SATA support"
+ select SATA_HOST
+ help
+ This option enables support for Nas782x Serial ATA controller.
+
+ If unsure, say N.
+
comment "PATA SFF controllers with BMDMA"
config PATA_ALI
--- a/drivers/ata/Makefile
+++ b/drivers/ata/Makefile
@@ -46,6 +46,7 @@ obj-$(CONFIG_SATA_SVW) += sata_svw.o
obj-$(CONFIG_SATA_ULI) += sata_uli.o
obj-$(CONFIG_SATA_VIA) += sata_via.o
obj-$(CONFIG_SATA_VITESSE) += sata_vsc.o
+obj-$(CONFIG_SATA_OXNAS) += sata_oxnas.o
# SFF PATA w/ BMDMA
obj-$(CONFIG_PATA_ALI) += pata_ali.o
--- a/arch/arm/boot/dts/ox820.dtsi
+++ b/arch/arm/boot/dts/ox820.dtsi
@@ -399,5 +399,20 @@
plxtech,pcie-outbound-offset = <0x174>;
status = "disabled";
};
+
+ sata: sata@45900000 {
+ compatible = "plxtech,nas782x-sata";
+ /* ports dmactl sgdma */
+ reg = <0x45900000 0x20000>, <0x459A0000 0x40>, <0x459B0000 0x20>,
+ /* core phy descriptors (optional) */
+ <0x459E0000 0x2000>, <0x44900000 0x0C>, <0x50000000 0x1000>;
+ interrupts = <GIC_SPI 18 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&stdclk CLK_820_SATA>;
+ resets = <&reset RESET_SATA>, <&reset RESET_SATA_LINK>, <&reset RESET_SATA_PHY>;
+ reset-names = "sata", "link", "phy";
+ nr-ports = <1>;
+ status = "disabled";
+ };
+
};
};
--- a/arch/arm/boot/dts/ox820-cloudengines-pogoplug-series-3.dts
+++ b/arch/arm/boot/dts/ox820-cloudengines-pogoplug-series-3.dts
@@ -111,3 +111,7 @@
pinctrl-names = "default";
pinctrl-0 = <&pinctrl_etha_mdio>;
};
+
+&sata {
+ status = "okay";
+};

View File

@ -0,0 +1,10 @@
--- a/arch/arm/mach-oxnas/Kconfig
+++ b/arch/arm/mach-oxnas/Kconfig
@@ -2,6 +2,7 @@
menuconfig ARCH_OXNAS
bool "Oxford Semiconductor OXNAS Family SoCs"
select ARCH_HAS_RESET_CONTROLLER
+ select ARCH_WANT_LIBATA_LEDS
select COMMON_CLK_OXNAS
select GPIOLIB
select MFD_SYSCON

View File

@ -0,0 +1,73 @@
--- a/drivers/usb/host/Kconfig
+++ b/drivers/usb/host/Kconfig
@@ -339,6 +339,13 @@ config USB_OCTEON_EHCI
USB 2.0 device support. All CN6XXX based chips with USB are
supported.
+config USB_EHCI_OXNAS
+ tristate "OXNAS EHCI Module"
+ depends on USB_EHCI_HCD && ARCH_OXNAS
+ select USB_EHCI_ROOT_HUB_TT
+ help
+ Enable support for the OX820 SOC's on-chip EHCI controller.
+
endif # USB_EHCI_HCD
config USB_OXU210HP_HCD
--- a/drivers/usb/host/Makefile
+++ b/drivers/usb/host/Makefile
@@ -46,6 +46,7 @@ obj-$(CONFIG_USB_EHCI_HCD_STI) += ehci-s
obj-$(CONFIG_USB_EHCI_EXYNOS) += ehci-exynos.o
obj-$(CONFIG_USB_EHCI_HCD_AT91) += ehci-atmel.o
obj-$(CONFIG_USB_EHCI_BRCMSTB) += ehci-brcm.o
+obj-$(CONFIG_USB_EHCI_OXNAS) += ehci-oxnas.o
obj-$(CONFIG_USB_OXU210HP_HCD) += oxu210hp-hcd.o
obj-$(CONFIG_USB_ISP116X_HCD) += isp116x-hcd.o
--- a/arch/arm/boot/dts/ox820.dtsi
+++ b/arch/arm/boot/dts/ox820.dtsi
@@ -106,6 +106,31 @@
status = "disabled";
};
+ ehci: ehci@40200100 {
+ compatible = "plxtech,nas782x-ehci";
+ reg = <0x40200100 0xf00>;
+ interrupts = <GIC_SPI 7 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&stdclk CLK_820_USBMPH>, <&pllb>, <&stdclk CLK_820_REF600>;
+ clock-names = "usb", "refsrc", "phyref";
+ resets = <&reset RESET_USBHS>, <&reset RESET_USBPHYA>, <&reset RESET_USBPHYB>;
+ reset-names = "host", "phya", "phyb";
+ oxsemi,sys-ctrl = <&sys>;
+ /* Otherwise ref300 is used, which is derived from sata phy
+ * in that case, usb depends on sata initialization */
+ /* FIXME: how to make this dependency explicit ? */
+ oxsemi,ehci_use_pllb;
+ status = "disabled";
+
+ ehci_port1: port@1 {
+ reg = <1>;
+ #trigger-source-cells = <0>;
+ };
+ ehci_port2: port@2 {
+ reg = <2>;
+ #trigger-source-cells = <0>;
+ };
+ };
+
apb-bridge@44000000 {
#address-cells = <1>;
#size-cells = <1>;
--- a/arch/arm/boot/dts/ox820-cloudengines-pogoplug-series-3.dts
+++ b/arch/arm/boot/dts/ox820-cloudengines-pogoplug-series-3.dts
@@ -105,6 +105,10 @@
};
};
+&ehci {
+ status = "okay";
+};
+
&etha {
status = "okay";

View File

@ -0,0 +1,189 @@
From 71270226b14733a4b1f2cde58ea9265caa50b38d Mon Sep 17 00:00:00 2001
From: Adrian Panella <ianchi74@outlook.com>
Date: Thu, 9 Mar 2017 09:37:17 +0100
Subject: [PATCH 67/69] generic: Mangle bootloader's kernel arguments
The command-line arguments provided by the boot loader will be
appended to a new device tree property: bootloader-args.
If there is a property "append-rootblock" in DT under /chosen
and a root= option in bootloaders command line it will be parsed
and added to DT bootargs with the form: <append-rootblock>XX.
Only command line ATAG will be processed, the rest of the ATAGs
sent by bootloader will be ignored.
This is usefull in dual boot systems, to get the current root partition
without afecting the rest of the system.
Signed-off-by: Adrian Panella <ianchi74@outlook.com>
---
arch/arm/Kconfig | 11 +++++
arch/arm/boot/compressed/atags_to_fdt.c | 72 ++++++++++++++++++++++++++++++++-
init/main.c | 16 ++++++++
3 files changed, 98 insertions(+), 1 deletion(-)
--- a/arch/arm/Kconfig
+++ b/arch/arm/Kconfig
@@ -1727,6 +1727,17 @@ config ARM_ATAG_DTB_COMPAT_CMDLINE_EXTEN
The command-line arguments provided by the boot loader will be
appended to the the device tree bootargs property.
+config ARM_ATAG_DTB_COMPAT_CMDLINE_MANGLE
+ bool "Append rootblock parsing bootloader's kernel arguments"
+ help
+ The command-line arguments provided by the boot loader will be
+ appended to a new device tree property: bootloader-args.
+ If there is a property "append-rootblock" in DT under /chosen
+ and a root= option in bootloaders command line it will be parsed
+ and added to DT bootargs with the form: <append-rootblock>XX.
+ Only command line ATAG will be processed, the rest of the ATAGs
+ sent by bootloader will be ignored.
+
endchoice
config CMDLINE
--- a/arch/arm/boot/compressed/atags_to_fdt.c
+++ b/arch/arm/boot/compressed/atags_to_fdt.c
@@ -5,6 +5,8 @@
#if defined(CONFIG_ARM_ATAG_DTB_COMPAT_CMDLINE_EXTEND)
#define do_extend_cmdline 1
+#elif defined(CONFIG_ARM_ATAG_DTB_COMPAT_CMDLINE_MANGLE)
+#define do_extend_cmdline 1
#else
#define do_extend_cmdline 0
#endif
@@ -69,6 +71,59 @@ static uint32_t get_cell_size(const void
return cell_size;
}
+#if defined(CONFIG_ARM_ATAG_DTB_COMPAT_CMDLINE_MANGLE)
+
+static char *append_rootblock(char *dest, const char *str, int len, void *fdt)
+{
+ char *ptr, *end;
+ char *root="root=";
+ int i, l;
+ const char *rootblock;
+
+ //ARM doesn't have __HAVE_ARCH_STRSTR, so search manually
+ ptr = str - 1;
+
+ do {
+ //first find an 'r' at the begining or after a space
+ do {
+ ptr++;
+ ptr = strchr(ptr, 'r');
+ if(!ptr) return dest;
+
+ } while (ptr != str && *(ptr-1) != ' ');
+
+ //then check for the rest
+ for(i = 1; i <= 4; i++)
+ if(*(ptr+i) != *(root+i)) break;
+
+ } while (i != 5);
+
+ end = strchr(ptr, ' ');
+ end = end ? (end - 1) : (strchr(ptr, 0) - 1);
+
+ //find partition number (assumes format root=/dev/mtdXX | /dev/mtdblockXX | yy:XX )
+ for( i = 0; end >= ptr && *end >= '0' && *end <= '9'; end--, i++);
+ ptr = end + 1;
+
+ /* if append-rootblock property is set use it to append to command line */
+ rootblock = getprop(fdt, "/chosen", "append-rootblock", &l);
+ if(rootblock != NULL) {
+ if(*dest != ' ') {
+ *dest = ' ';
+ dest++;
+ len++;
+ }
+ if (len + l + i <= COMMAND_LINE_SIZE) {
+ memcpy(dest, rootblock, l);
+ dest += l - 1;
+ memcpy(dest, ptr, i);
+ dest += i;
+ }
+ }
+ return dest;
+}
+#endif
+
static void merge_fdt_bootargs(void *fdt, const char *fdt_cmdline)
{
char cmdline[COMMAND_LINE_SIZE];
@@ -88,12 +143,21 @@ static void merge_fdt_bootargs(void *fdt
/* and append the ATAG_CMDLINE */
if (fdt_cmdline) {
+
+#if defined(CONFIG_ARM_ATAG_DTB_COMPAT_CMDLINE_MANGLE)
+ //save original bootloader args
+ //and append ubi.mtd with root partition number to current cmdline
+ setprop_string(fdt, "/chosen", "bootloader-args", fdt_cmdline);
+ ptr = append_rootblock(ptr, fdt_cmdline, len, fdt);
+
+#else
len = strlen(fdt_cmdline);
if (ptr - cmdline + len + 2 < COMMAND_LINE_SIZE) {
*ptr++ = ' ';
memcpy(ptr, fdt_cmdline, len);
ptr += len;
}
+#endif
}
*ptr = '\0';
@@ -168,7 +232,9 @@ int atags_to_fdt(void *atag_list, void *
else
setprop_string(fdt, "/chosen", "bootargs",
atag->u.cmdline.cmdline);
- } else if (atag->hdr.tag == ATAG_MEM) {
+ }
+#ifndef CONFIG_ARM_ATAG_DTB_COMPAT_CMDLINE_MANGLE
+ else if (atag->hdr.tag == ATAG_MEM) {
if (memcount >= sizeof(mem_reg_property)/4)
continue;
if (!atag->u.mem.size)
@@ -212,6 +278,10 @@ int atags_to_fdt(void *atag_list, void *
setprop(fdt, "/memory", "reg", mem_reg_property,
4 * memcount * memsize);
}
+#else
+
+ }
+#endif
return fdt_pack(fdt);
}
--- a/init/main.c
+++ b/init/main.c
@@ -114,6 +114,10 @@
#include <kunit/test.h>
+#if defined(CONFIG_ARM_ATAG_DTB_COMPAT_CMDLINE_MANGLE)
+#include <linux/of.h>
+#endif
+
static int kernel_init(void *);
extern void init_IRQ(void);
@@ -991,6 +995,18 @@ asmlinkage __visible void __init __no_sa
page_alloc_init();
pr_notice("Kernel command line: %s\n", saved_command_line);
+
+#if defined(CONFIG_ARM_ATAG_DTB_COMPAT_CMDLINE_MANGLE)
+ //Show bootloader's original command line for reference
+ if(of_chosen) {
+ const char *prop = of_get_property(of_chosen, "bootloader-args", NULL);
+ if(prop)
+ pr_notice("Bootloader command line (ignored): %s\n", prop);
+ else
+ pr_notice("Bootloader command line not present\n");
+ }
+#endif
+
/* parameters may set static keys */
jump_label_init();
parse_early_param();

View File

@ -0,0 +1,57 @@
--- a/drivers/ata/libata-core.c
+++ b/drivers/ata/libata-core.c
@@ -1531,6 +1531,14 @@ unsigned ata_exec_internal_sg(struct ata
return AC_ERR_SYSTEM;
}
+ if (ap->ops->acquire_hw && !ap->ops->acquire_hw(ap, 0, 0)) {
+ spin_unlock_irqrestore(ap->lock, flags);
+ if (!ap->ops->acquire_hw(ap, 1, (2*HZ))) {
+ return AC_ERR_TIMEOUT;
+ }
+ spin_lock_irqsave(ap->lock, flags);
+ }
+
/* initialize internal qc */
qc = __ata_qc_from_tag(ap, ATA_TAG_INTERNAL);
@@ -4583,6 +4591,9 @@ struct ata_queued_cmd *ata_qc_new_init(s
if (unlikely(ap->pflags & ATA_PFLAG_FROZEN))
return NULL;
+ if (ap->ops->qc_new && ap->ops->qc_new(ap))
+ return NULL;
+
/* libsas case */
if (ap->flags & ATA_FLAG_SAS_HOST) {
tag = ata_sas_allocate_tag(ap);
@@ -4628,6 +4639,8 @@ void ata_qc_free(struct ata_queued_cmd *
qc->tag = ATA_TAG_POISON;
if (ap->flags & ATA_FLAG_SAS_HOST)
ata_sas_free_tag(tag, ap);
+ if (ap->ops->qc_free)
+ ap->ops->qc_free(qc);
}
}
--- a/include/linux/libata.h
+++ b/include/linux/libata.h
@@ -917,6 +917,8 @@ struct ata_port_operations {
enum ata_completion_errors (*qc_prep)(struct ata_queued_cmd *qc);
unsigned int (*qc_issue)(struct ata_queued_cmd *qc);
bool (*qc_fill_rtf)(struct ata_queued_cmd *qc);
+ int (*qc_new)(struct ata_port *ap);
+ void (*qc_free)(struct ata_queued_cmd *qc);
/*
* Configuration and exception handling
@@ -1007,6 +1009,9 @@ struct ata_port_operations {
void (*phy_reset)(struct ata_port *ap);
void (*eng_timeout)(struct ata_port *ap);
+ int (*acquire_hw)(struct ata_port *ap, int may_sleep,
+ int timeout_jiffies);
+
/*
* ->inherits must be the last field and all the preceding
* fields must be pointers.