diff --git a/config/kernel/linux-sun50i-dev.config b/config/kernel/linux-sun50i-dev.config index f854136f3..3817be67e 100644 --- a/config/kernel/linux-sun50i-dev.config +++ b/config/kernel/linux-sun50i-dev.config @@ -1,6 +1,6 @@ # # Automatically generated file; DO NOT EDIT. -# Linux/arm64 4.10.0 Kernel Configuration +# Linux/arm64 4.11.0 Kernel Configuration # CONFIG_ARM64=y CONFIG_64BIT=y @@ -231,6 +231,7 @@ CONFIG_HAVE_ARCH_TRACEHOOK=y CONFIG_HAVE_DMA_CONTIGUOUS=y CONFIG_GENERIC_SMP_IDLE_THREAD=y CONFIG_GENERIC_IDLE_POLL_SETUP=y +CONFIG_ARCH_HAS_SET_MEMORY=y CONFIG_HAVE_REGS_AND_STACK_ACCESS_API=y CONFIG_HAVE_CLK=y CONFIG_HAVE_DMA_API_DEBUG=y @@ -315,6 +316,7 @@ CONFIG_BLK_DEV_THROTTLING=y CONFIG_MSDOS_PARTITION=y CONFIG_EFI_PARTITION=y CONFIG_BLOCK_COMPAT=y +CONFIG_BLK_MQ_VIRTIO=y # # IO Schedulers @@ -328,13 +330,6 @@ CONFIG_DEFAULT_CFQ=y # CONFIG_DEFAULT_NOOP is not set CONFIG_DEFAULT_IOSCHED="cfq" CONFIG_MQ_IOSCHED_DEADLINE=y -CONFIG_MQ_IOSCHED_NONE=y -# CONFIG_DEFAULT_SQ_DEADLINE is not set -CONFIG_DEFAULT_SQ_NONE=y -CONFIG_DEFAULT_SQ_IOSCHED="none" -# CONFIG_DEFAULT_MQ_DEADLINE is not set -CONFIG_DEFAULT_MQ_NONE=y -CONFIG_DEFAULT_MQ_IOSCHED="none" CONFIG_PADATA=y CONFIG_ASN1=y CONFIG_INLINE_SPIN_UNLOCK_IRQ=y @@ -388,6 +383,10 @@ CONFIG_ARCH_SUNXI=y # CONFIG_PCI_DOMAINS_GENERIC is not set # CONFIG_PCI_SYSCALL is not set +# +# DesignWare PCI Core Support +# + # # Kernel Features # @@ -407,6 +406,7 @@ CONFIG_ARM64_ERRATUM_843419=y # CONFIG_CAVIUM_ERRATUM_27456 is not set # CONFIG_QCOM_FALKOR_ERRATUM_1003 is not set # CONFIG_QCOM_FALKOR_ERRATUM_1009 is not set +# CONFIG_QCOM_QDF2400_ERRATUM_0065 is not set CONFIG_ARM64_4K_PAGES=y # CONFIG_ARM64_16K_PAGES is not set # CONFIG_ARM64_64K_PAGES is not set @@ -519,6 +519,7 @@ CONFIG_BINFMT_MISC=y CONFIG_COREDUMP=y CONFIG_COMPAT=y CONFIG_SYSVIPC_COMPAT=y +CONFIG_KEYS_COMPAT=y # # Power management options @@ -2160,7 +2161,6 @@ CONFIG_PINCTRL_SUNXI=y # CONFIG_PINCTRL_SUN4I_A10 is not set # CONFIG_PINCTRL_SUN5I is not set # CONFIG_PINCTRL_SUN6I_A31 is not set -# CONFIG_PINCTRL_SUN6I_A31S is not set # CONFIG_PINCTRL_SUN6I_A31_R is not set # CONFIG_PINCTRL_SUN7I_A20 is not set # CONFIG_PINCTRL_SUN8I_A23 is not set @@ -2175,7 +2175,6 @@ CONFIG_PINCTRL_SUN8I_H3_R=y CONFIG_PINCTRL_SUN50I_A64=y CONFIG_PINCTRL_SUN50I_A64_R=y CONFIG_PINCTRL_SUN50I_H5=y -# CONFIG_PINCTRL_TI_IODELAY is not set CONFIG_GPIOLIB=y CONFIG_OF_GPIO=y # CONFIG_DEBUG_GPIO is not set @@ -2443,7 +2442,6 @@ CONFIG_THERMAL_EMULATION=y # # ACPI INT340X thermal drivers # -CONFIG_SUN8I_THS=y CONFIG_WATCHDOG=y CONFIG_WATCHDOG_CORE=y # CONFIG_WATCHDOG_NOWAYOUT is not set @@ -2625,13 +2623,77 @@ CONFIG_REGULATOR_QCOM_SPMI=y # CONFIG_REGULATOR_S2MPA01 is not set CONFIG_REGULATOR_S2MPS11=y # CONFIG_REGULATOR_S5M8767 is not set -CONFIG_REGULATOR_SY8106A=y # CONFIG_REGULATOR_TPS51632 is not set # CONFIG_REGULATOR_TPS62360 is not set # CONFIG_REGULATOR_TPS65023 is not set # CONFIG_REGULATOR_TPS6507X is not set # CONFIG_REGULATOR_TPS6524X is not set -# CONFIG_MEDIA_SUPPORT is not set +CONFIG_MEDIA_SUPPORT=m + +# +# Multimedia core support +# +# CONFIG_MEDIA_CAMERA_SUPPORT is not set +# CONFIG_MEDIA_ANALOG_TV_SUPPORT is not set +# CONFIG_MEDIA_DIGITAL_TV_SUPPORT is not set +# CONFIG_MEDIA_RADIO_SUPPORT is not set +# CONFIG_MEDIA_SDR_SUPPORT is not set +CONFIG_MEDIA_RC_SUPPORT=y +# CONFIG_MEDIA_CEC_SUPPORT is not set +# CONFIG_VIDEO_ADV_DEBUG is not set +# CONFIG_VIDEO_FIXED_MINOR_RANGES is not set +# CONFIG_TTPCI_EEPROM is not set + +# +# Media drivers +# +CONFIG_RC_CORE=m +CONFIG_RC_MAP=m +CONFIG_RC_DECODERS=y +CONFIG_LIRC=m +CONFIG_IR_LIRC_CODEC=m +CONFIG_IR_NEC_DECODER=m +CONFIG_IR_RC5_DECODER=m +CONFIG_IR_RC6_DECODER=m +CONFIG_IR_JVC_DECODER=m +CONFIG_IR_SONY_DECODER=m +CONFIG_IR_SANYO_DECODER=m +CONFIG_IR_SHARP_DECODER=m +CONFIG_IR_MCE_KBD_DECODER=m +CONFIG_IR_XMP_DECODER=m +CONFIG_RC_DEVICES=y +# CONFIG_RC_ATI_REMOTE is not set +# CONFIG_IR_HIX5HD2 is not set +# CONFIG_IR_IMON is not set +# CONFIG_IR_MCEUSB is not set +# CONFIG_IR_REDRAT3 is not set +# CONFIG_IR_SPI is not set +# CONFIG_IR_STREAMZAP is not set +# CONFIG_IR_IGORPLUGUSB is not set +# CONFIG_IR_IGUANA is not set +# CONFIG_IR_TTUSBIR is not set +# CONFIG_RC_LOOPBACK is not set +# CONFIG_IR_GPIO_CIR is not set +CONFIG_IR_SUNXI=m +# CONFIG_IR_SERIAL is not set +# CONFIG_MEDIA_USB_SUPPORT is not set + +# +# Supported MMC/SDIO adapters +# +# CONFIG_CYPRESS_FIRMWARE is not set + +# +# Media ancillary drivers (tuners, sensors, i2c, spi, frontends) +# + +# +# Customise DVB Frontends +# + +# +# Tools to develop new frontends +# # # Graphics support @@ -2830,7 +2892,8 @@ CONFIG_SND_SOC_I2C_AND_SPI=m # CONFIG_SND_SOC_CS42XX8_I2C is not set # CONFIG_SND_SOC_CS4349 is not set # CONFIG_SND_SOC_CS53L30 is not set -# CONFIG_SND_SOC_ES8328 is not set +# CONFIG_SND_SOC_ES8328_I2C is not set +# CONFIG_SND_SOC_ES8328_SPI is not set # CONFIG_SND_SOC_GTM601 is not set # CONFIG_SND_SOC_INNO_RK3036 is not set # CONFIG_SND_SOC_MAX98504 is not set @@ -3549,7 +3612,7 @@ CONFIG_SUN50I_A64_CCU=y # CONFIG_SUN6I_A31_CCU is not set # CONFIG_SUN8I_A23_CCU is not set # CONFIG_SUN8I_A33_CCU is not set -CONFIG_SUNXI_H3_H5_CCU=y +CONFIG_SUN8I_H3_CCU=y # CONFIG_SUN8I_V3S_CCU is not set # CONFIG_SUN9I_A80_CCU is not set CONFIG_SUN8I_R_CCU=y @@ -3566,7 +3629,9 @@ CONFIG_CLKSRC_PROBE=y CONFIG_CLKSRC_MMIO=y CONFIG_ARM_ARCH_TIMER=y CONFIG_ARM_ARCH_TIMER_EVTSTREAM=y +CONFIG_ARM_ARCH_TIMER_OOL_WORKAROUND=y CONFIG_FSL_ERRATUM_A008585=y +# CONFIG_HISILICON_ERRATUM_161010101 is not set CONFIG_ARM_TIMER_SP804=y # CONFIG_ATMEL_PIT is not set # CONFIG_SH_TIMER_CMT is not set @@ -4028,6 +4093,7 @@ CONFIG_DEBUG_KERNEL=y # CONFIG_PAGE_EXTENSION is not set # CONFIG_DEBUG_PAGEALLOC is not set # CONFIG_PAGE_POISONING is not set +# CONFIG_DEBUG_RODATA_TEST is not set # CONFIG_DEBUG_OBJECTS is not set # CONFIG_SLUB_DEBUG_ON is not set # CONFIG_SLUB_STATS is not set @@ -4064,7 +4130,6 @@ CONFIG_SCHED_INFO=y # CONFIG_SCHEDSTATS is not set # CONFIG_SCHED_STACK_END_CHECK is not set # CONFIG_DEBUG_TIMEKEEPING is not set -# CONFIG_TIMER_STATS is not set # # Lock Debugging (spinlocks, mutexes, etc...) @@ -4348,7 +4413,6 @@ CONFIG_CRYPTO_USER_API_AEAD=y # # Certificates for signature checking # -# CONFIG_SYSTEM_BLACKLIST_KEYRING is not set CONFIG_ARM64_CRYPTO=y CONFIG_CRYPTO_SHA256_ARM64=y CONFIG_CRYPTO_SHA512_ARM64=y @@ -4426,6 +4490,8 @@ CONFIG_RADIX_TREE_MULTIORDER=y CONFIG_ASSOCIATIVE_ARRAY=y CONFIG_HAS_IOMEM=y CONFIG_HAS_DMA=y +# CONFIG_DMA_NOOP_OPS is not set +# CONFIG_DMA_VIRT_OPS is not set CONFIG_CPU_RMAP=y CONFIG_DQL=y CONFIG_GLOB=y @@ -4446,5 +4512,3 @@ CONFIG_FONT_8x16=y CONFIG_SG_POOL=y CONFIG_ARCH_HAS_SG_CHAIN=y CONFIG_SBITMAP=y -# CONFIG_PARMAN is not set -CONFIG_PRIME_NUMBERS=m diff --git a/config/sources/sunxi64_common.inc b/config/sources/sunxi64_common.inc index 66a8bef97..951feba57 100644 --- a/config/sources/sunxi64_common.inc +++ b/config/sources/sunxi64_common.inc @@ -13,9 +13,10 @@ case $BRANCH in BOOTSCRIPT='boot-sun50i-next.cmd:boot.cmd' KERNELSOURCE='https://github.com/Icenowy/linux/' - KERNELBRANCH='branch:sunxi64-next-20170216' + KERNELBRANCH='branch:sunxi64-4.11.y' KERNELDIR='linux-sun50i-dev' KERNEL_USE_GCC='> 6.1' LINUXCONFIG='linux-sun50i-dev' + KERNELPATCHDIR='sun50i-dev' ;; esac diff --git a/patch/kernel/sun50iw1-dev/add-mtd-spi-nor-dts.patch.disabled b/patch/kernel/sun50i-dev/add-mtd-spi-nor-dts.patch.disabled similarity index 100% rename from patch/kernel/sun50iw1-dev/add-mtd-spi-nor-dts.patch.disabled rename to patch/kernel/sun50i-dev/add-mtd-spi-nor-dts.patch.disabled diff --git a/patch/kernel/sun50iw1-dev/add-overlay-compilation-support.patch b/patch/kernel/sun50i-dev/add-overlay-compilation-support.patch similarity index 100% rename from patch/kernel/sun50iw1-dev/add-overlay-compilation-support.patch rename to patch/kernel/sun50i-dev/add-overlay-compilation-support.patch diff --git a/patch/kernel/sun50iw2-dev/add-spi-flash-pc2.patch b/patch/kernel/sun50i-dev/add-spi-flash-pc2.patch similarity index 100% rename from patch/kernel/sun50iw2-dev/add-spi-flash-pc2.patch rename to patch/kernel/sun50i-dev/add-spi-flash-pc2.patch diff --git a/patch/kernel/sun50iw1-dev/add_BergMicro_flashes_to_SPI-NOR.patch b/patch/kernel/sun50i-dev/add_BergMicro_flashes_to_SPI-NOR.patch similarity index 100% rename from patch/kernel/sun50iw1-dev/add_BergMicro_flashes_to_SPI-NOR.patch rename to patch/kernel/sun50i-dev/add_BergMicro_flashes_to_SPI-NOR.patch diff --git a/patch/kernel/sun50iw1-dev/add_configfs_overlay_for_v4.10.x.patch b/patch/kernel/sun50i-dev/add_configfs_overlay_for_v4.10.x.patch similarity index 100% rename from patch/kernel/sun50iw1-dev/add_configfs_overlay_for_v4.10.x.patch rename to patch/kernel/sun50i-dev/add_configfs_overlay_for_v4.10.x.patch diff --git a/patch/kernel/sun50iw1-dev/add_proc_cpuinfo_entries_for_v4.10.x.patch b/patch/kernel/sun50i-dev/add_proc_cpuinfo_entries_for_v4.10.x.patch similarity index 100% rename from patch/kernel/sun50iw1-dev/add_proc_cpuinfo_entries_for_v4.10.x.patch rename to patch/kernel/sun50i-dev/add_proc_cpuinfo_entries_for_v4.10.x.patch diff --git a/patch/kernel/sun50iw2-dev/add_sun50i_a64_spi.patch b/patch/kernel/sun50i-dev/add_sun50i_a64_spi.patch similarity index 100% rename from patch/kernel/sun50iw2-dev/add_sun50i_a64_spi.patch rename to patch/kernel/sun50i-dev/add_sun50i_a64_spi.patch diff --git a/patch/kernel/sun50iw1-dev/enable-fsl-timer-errata.patch b/patch/kernel/sun50i-dev/enable-fsl-timer-errata.patch similarity index 100% rename from patch/kernel/sun50iw1-dev/enable-fsl-timer-errata.patch rename to patch/kernel/sun50i-dev/enable-fsl-timer-errata.patch diff --git a/patch/kernel/sun50iw2-dev/packaging-4.x-DEV-with-postinstall-scripts.patch b/patch/kernel/sun50i-dev/packaging-4.x-DEV-with-postinstall-scripts.patch similarity index 100% rename from patch/kernel/sun50iw2-dev/packaging-4.x-DEV-with-postinstall-scripts.patch rename to patch/kernel/sun50i-dev/packaging-4.x-DEV-with-postinstall-scripts.patch diff --git a/patch/kernel/sun50i-dev/scripts-dtc-import-updates.patch b/patch/kernel/sun50i-dev/scripts-dtc-import-updates.patch new file mode 100644 index 000000000..89d2a2adc --- /dev/null +++ b/patch/kernel/sun50i-dev/scripts-dtc-import-updates.patch @@ -0,0 +1,3046 @@ +diff --git a/scripts/dtc/checks.c b/scripts/dtc/checks.c +index 3d18e453..5adfc8f5 100644 +--- a/scripts/dtc/checks.c ++++ b/scripts/dtc/checks.c +@@ -72,17 +72,16 @@ struct check { + #define CHECK(_nm, _fn, _d, ...) \ + CHECK_ENTRY(_nm, _fn, _d, false, false, __VA_ARGS__) + +-#ifdef __GNUC__ +-static inline void check_msg(struct check *c, const char *fmt, ...) __attribute__((format (printf, 2, 3))); +-#endif +-static inline void check_msg(struct check *c, const char *fmt, ...) ++static inline void PRINTF(3, 4) check_msg(struct check *c, struct dt_info *dti, ++ const char *fmt, ...) + { + va_list ap; + va_start(ap, fmt); + + if ((c->warn && (quiet < 1)) + || (c->error && (quiet < 2))) { +- fprintf(stderr, "%s (%s): ", ++ fprintf(stderr, "%s: %s (%s): ", ++ strcmp(dti->outname, "-") ? dti->outname : "<stdout>", + (c->error) ? "ERROR" : "Warning", c->name); + vfprintf(stderr, fmt, ap); + fprintf(stderr, "\n"); +@@ -90,11 +89,11 @@ static inline void check_msg(struct check *c, const char *fmt, ...) + va_end(ap); + } + +-#define FAIL(c, ...) \ +- do { \ +- TRACE((c), "\t\tFAILED at %s:%d", __FILE__, __LINE__); \ +- (c)->status = FAILED; \ +- check_msg((c), __VA_ARGS__); \ ++#define FAIL(c, dti, ...) \ ++ do { \ ++ TRACE((c), "\t\tFAILED at %s:%d", __FILE__, __LINE__); \ ++ (c)->status = FAILED; \ ++ check_msg((c), dti, __VA_ARGS__); \ + } while (0) + + static void check_nodes_props(struct check *c, struct dt_info *dti, struct node *node) +@@ -127,7 +126,7 @@ static bool run_check(struct check *c, struct dt_info *dti) + error = error || run_check(prq, dti); + if (prq->status != PASSED) { + c->status = PREREQ; +- check_msg(c, "Failed prerequisite '%s'", ++ check_msg(c, dti, "Failed prerequisite '%s'", + c->prereq[i]->name); + } + } +@@ -157,7 +156,7 @@ static bool run_check(struct check *c, struct dt_info *dti) + static inline void check_always_fail(struct check *c, struct dt_info *dti, + struct node *node) + { +- FAIL(c, "always_fail check"); ++ FAIL(c, dti, "always_fail check"); + } + CHECK(always_fail, check_always_fail, NULL); + +@@ -172,7 +171,7 @@ static void check_is_string(struct check *c, struct dt_info *dti, + return; /* Not present, assumed ok */ + + if (!data_is_one_string(prop->val)) +- FAIL(c, "\"%s\" property in %s is not a string", ++ FAIL(c, dti, "\"%s\" property in %s is not a string", + propname, node->fullpath); + } + #define WARNING_IF_NOT_STRING(nm, propname) \ +@@ -191,7 +190,7 @@ static void check_is_cell(struct check *c, struct dt_info *dti, + return; /* Not present, assumed ok */ + + if (prop->val.len != sizeof(cell_t)) +- FAIL(c, "\"%s\" property in %s is not a single cell", ++ FAIL(c, dti, "\"%s\" property in %s is not a single cell", + propname, node->fullpath); + } + #define WARNING_IF_NOT_CELL(nm, propname) \ +@@ -213,7 +212,7 @@ static void check_duplicate_node_names(struct check *c, struct dt_info *dti, + child2; + child2 = child2->next_sibling) + if (streq(child->name, child2->name)) +- FAIL(c, "Duplicate node name %s", ++ FAIL(c, dti, "Duplicate node name %s", + child->fullpath); + } + ERROR(duplicate_node_names, check_duplicate_node_names, NULL); +@@ -228,7 +227,7 @@ static void check_duplicate_property_names(struct check *c, struct dt_info *dti, + if (prop2->deleted) + continue; + if (streq(prop->name, prop2->name)) +- FAIL(c, "Duplicate property name %s in %s", ++ FAIL(c, dti, "Duplicate property name %s in %s", + prop->name, node->fullpath); + } + } +@@ -239,6 +238,7 @@ ERROR(duplicate_property_names, check_duplicate_property_names, NULL); + #define UPPERCASE "ABCDEFGHIJKLMNOPQRSTUVWXYZ" + #define DIGITS "0123456789" + #define PROPNODECHARS LOWERCASE UPPERCASE DIGITS ",._+*#?-" ++#define PROPNODECHARSSTRICT LOWERCASE UPPERCASE DIGITS ",-" + + static void check_node_name_chars(struct check *c, struct dt_info *dti, + struct node *node) +@@ -246,16 +246,27 @@ static void check_node_name_chars(struct check *c, struct dt_info *dti, + int n = strspn(node->name, c->data); + + if (n < strlen(node->name)) +- FAIL(c, "Bad character '%c' in node %s", ++ FAIL(c, dti, "Bad character '%c' in node %s", + node->name[n], node->fullpath); + } + ERROR(node_name_chars, check_node_name_chars, PROPNODECHARS "@"); + ++static void check_node_name_chars_strict(struct check *c, struct dt_info *dti, ++ struct node *node) ++{ ++ int n = strspn(node->name, c->data); ++ ++ if (n < node->basenamelen) ++ FAIL(c, dti, "Character '%c' not recommended in node %s", ++ node->name[n], node->fullpath); ++} ++CHECK(node_name_chars_strict, check_node_name_chars_strict, PROPNODECHARSSTRICT); ++ + static void check_node_name_format(struct check *c, struct dt_info *dti, + struct node *node) + { + if (strchr(get_unitname(node), '@')) +- FAIL(c, "Node %s has multiple '@' characters in name", ++ FAIL(c, dti, "Node %s has multiple '@' characters in name", + node->fullpath); + } + ERROR(node_name_format, check_node_name_format, NULL, &node_name_chars); +@@ -274,11 +285,11 @@ static void check_unit_address_vs_reg(struct check *c, struct dt_info *dti, + + if (prop) { + if (!unitname[0]) +- FAIL(c, "Node %s has a reg or ranges property, but no unit name", ++ FAIL(c, dti, "Node %s has a reg or ranges property, but no unit name", + node->fullpath); + } else { + if (unitname[0]) +- FAIL(c, "Node %s has a unit name, but no reg property", ++ FAIL(c, dti, "Node %s has a unit name, but no reg property", + node->fullpath); + } + } +@@ -293,12 +304,44 @@ static void check_property_name_chars(struct check *c, struct dt_info *dti, + int n = strspn(prop->name, c->data); + + if (n < strlen(prop->name)) +- FAIL(c, "Bad character '%c' in property name \"%s\", node %s", ++ FAIL(c, dti, "Bad character '%c' in property name \"%s\", node %s", + prop->name[n], prop->name, node->fullpath); + } + } + ERROR(property_name_chars, check_property_name_chars, PROPNODECHARS); + ++static void check_property_name_chars_strict(struct check *c, ++ struct dt_info *dti, ++ struct node *node) ++{ ++ struct property *prop; ++ ++ for_each_property(node, prop) { ++ const char *name = prop->name; ++ int n = strspn(name, c->data); ++ ++ if (n == strlen(prop->name)) ++ continue; ++ ++ /* Certain names are whitelisted */ ++ if (streq(name, "device_type")) ++ continue; ++ ++ /* ++ * # is only allowed at the beginning of property names not counting ++ * the vendor prefix. ++ */ ++ if (name[n] == '#' && ((n == 0) || (name[n-1] == ','))) { ++ name += n + 1; ++ n = strspn(name, c->data); ++ } ++ if (n < strlen(name)) ++ FAIL(c, dti, "Character '%c' not recommended in property name \"%s\", node %s", ++ name[n], prop->name, node->fullpath); ++ } ++} ++CHECK(property_name_chars_strict, check_property_name_chars_strict, PROPNODECHARSSTRICT); ++ + #define DESCLABEL_FMT "%s%s%s%s%s" + #define DESCLABEL_ARGS(node,prop,mark) \ + ((mark) ? "value of " : ""), \ +@@ -327,7 +370,7 @@ static void check_duplicate_label(struct check *c, struct dt_info *dti, + return; + + if ((othernode != node) || (otherprop != prop) || (othermark != mark)) +- FAIL(c, "Duplicate label '%s' on " DESCLABEL_FMT ++ FAIL(c, dti, "Duplicate label '%s' on " DESCLABEL_FMT + " and " DESCLABEL_FMT, + label, DESCLABEL_ARGS(node, prop, mark), + DESCLABEL_ARGS(othernode, otherprop, othermark)); +@@ -367,7 +410,7 @@ static cell_t check_phandle_prop(struct check *c, struct dt_info *dti, + return 0; + + if (prop->val.len != sizeof(cell_t)) { +- FAIL(c, "%s has bad length (%d) %s property", ++ FAIL(c, dti, "%s has bad length (%d) %s property", + node->fullpath, prop->val.len, prop->name); + return 0; + } +@@ -379,7 +422,7 @@ static cell_t check_phandle_prop(struct check *c, struct dt_info *dti, + /* "Set this node's phandle equal to some + * other node's phandle". That's nonsensical + * by construction. */ { +- FAIL(c, "%s in %s is a reference to another node", ++ FAIL(c, dti, "%s in %s is a reference to another node", + prop->name, node->fullpath); + } + /* But setting this node's phandle equal to its own +@@ -393,7 +436,7 @@ static cell_t check_phandle_prop(struct check *c, struct dt_info *dti, + phandle = propval_cell(prop); + + if ((phandle == 0) || (phandle == -1)) { +- FAIL(c, "%s has bad value (0x%x) in %s property", ++ FAIL(c, dti, "%s has bad value (0x%x) in %s property", + node->fullpath, phandle, prop->name); + return 0; + } +@@ -420,7 +463,7 @@ static void check_explicit_phandles(struct check *c, struct dt_info *dti, + return; + + if (linux_phandle && phandle && (phandle != linux_phandle)) +- FAIL(c, "%s has mismatching 'phandle' and 'linux,phandle'" ++ FAIL(c, dti, "%s has mismatching 'phandle' and 'linux,phandle'" + " properties", node->fullpath); + + if (linux_phandle && !phandle) +@@ -428,7 +471,7 @@ static void check_explicit_phandles(struct check *c, struct dt_info *dti, + + other = get_node_by_phandle(root, phandle); + if (other && (other != node)) { +- FAIL(c, "%s has duplicated phandle 0x%x (seen before at %s)", ++ FAIL(c, dti, "%s has duplicated phandle 0x%x (seen before at %s)", + node->fullpath, phandle, other->fullpath); + return; + } +@@ -453,7 +496,7 @@ static void check_name_properties(struct check *c, struct dt_info *dti, + + if ((prop->val.len != node->basenamelen+1) + || (memcmp(prop->val.val, node->name, node->basenamelen) != 0)) { +- FAIL(c, "\"name\" property in %s is incorrect (\"%s\" instead" ++ FAIL(c, dti, "\"name\" property in %s is incorrect (\"%s\" instead" + " of base node name)", node->fullpath, prop->val.val); + } else { + /* The name property is correct, and therefore redundant. +@@ -488,16 +531,16 @@ static void fixup_phandle_references(struct check *c, struct dt_info *dti, + refnode = get_node_by_ref(dt, m->ref); + if (! refnode) { + if (!(dti->dtsflags & DTSF_PLUGIN)) +- FAIL(c, "Reference to non-existent node or " ++ FAIL(c, dti, "Reference to non-existent node or " + "label \"%s\"\n", m->ref); + else /* mark the entry as unresolved */ +- *((cell_t *)(prop->val.val + m->offset)) = ++ *((fdt32_t *)(prop->val.val + m->offset)) = + cpu_to_fdt32(0xffffffff); + continue; + } + + phandle = get_node_phandle(dt, refnode); +- *((cell_t *)(prop->val.val + m->offset)) = cpu_to_fdt32(phandle); ++ *((fdt32_t *)(prop->val.val + m->offset)) = cpu_to_fdt32(phandle); + } + } + } +@@ -520,7 +563,7 @@ static void fixup_path_references(struct check *c, struct dt_info *dti, + + refnode = get_node_by_ref(dt, m->ref); + if (!refnode) { +- FAIL(c, "Reference to non-existent node or label \"%s\"\n", ++ FAIL(c, dti, "Reference to non-existent node or label \"%s\"\n", + m->ref); + continue; + } +@@ -579,19 +622,19 @@ static void check_reg_format(struct check *c, struct dt_info *dti, + return; /* No "reg", that's fine */ + + if (!node->parent) { +- FAIL(c, "Root node has a \"reg\" property"); ++ FAIL(c, dti, "Root node has a \"reg\" property"); + return; + } + + if (prop->val.len == 0) +- FAIL(c, "\"reg\" property in %s is empty", node->fullpath); ++ FAIL(c, dti, "\"reg\" property in %s is empty", node->fullpath); + + addr_cells = node_addr_cells(node->parent); + size_cells = node_size_cells(node->parent); + entrylen = (addr_cells + size_cells) * sizeof(cell_t); + + if (!entrylen || (prop->val.len % entrylen) != 0) +- FAIL(c, "\"reg\" property in %s has invalid length (%d bytes) " ++ FAIL(c, dti, "\"reg\" property in %s has invalid length (%d bytes) " + "(#address-cells == %d, #size-cells == %d)", + node->fullpath, prop->val.len, addr_cells, size_cells); + } +@@ -608,7 +651,7 @@ static void check_ranges_format(struct check *c, struct dt_info *dti, + return; + + if (!node->parent) { +- FAIL(c, "Root node has a \"ranges\" property"); ++ FAIL(c, dti, "Root node has a \"ranges\" property"); + return; + } + +@@ -620,17 +663,17 @@ static void check_ranges_format(struct check *c, struct dt_info *dti, + + if (prop->val.len == 0) { + if (p_addr_cells != c_addr_cells) +- FAIL(c, "%s has empty \"ranges\" property but its " ++ FAIL(c, dti, "%s has empty \"ranges\" property but its " + "#address-cells (%d) differs from %s (%d)", + node->fullpath, c_addr_cells, node->parent->fullpath, + p_addr_cells); + if (p_size_cells != c_size_cells) +- FAIL(c, "%s has empty \"ranges\" property but its " ++ FAIL(c, dti, "%s has empty \"ranges\" property but its " + "#size-cells (%d) differs from %s (%d)", + node->fullpath, c_size_cells, node->parent->fullpath, + p_size_cells); + } else if ((prop->val.len % entrylen) != 0) { +- FAIL(c, "\"ranges\" property in %s has invalid length (%d bytes) " ++ FAIL(c, dti, "\"ranges\" property in %s has invalid length (%d bytes) " + "(parent #address-cells == %d, child #address-cells == %d, " + "#size-cells == %d)", node->fullpath, prop->val.len, + p_addr_cells, c_addr_cells, c_size_cells); +@@ -638,6 +681,229 @@ static void check_ranges_format(struct check *c, struct dt_info *dti, + } + WARNING(ranges_format, check_ranges_format, NULL, &addr_size_cells); + ++static const struct bus_type pci_bus = { ++ .name = "PCI", ++}; ++ ++static void check_pci_bridge(struct check *c, struct dt_info *dti, struct node *node) ++{ ++ struct property *prop; ++ cell_t *cells; ++ ++ prop = get_property(node, "device_type"); ++ if (!prop || !streq(prop->val.val, "pci")) ++ return; ++ ++ node->bus = &pci_bus; ++ ++ if (!strneq(node->name, "pci", node->basenamelen) && ++ !strneq(node->name, "pcie", node->basenamelen)) ++ FAIL(c, dti, "Node %s node name is not \"pci\" or \"pcie\"", ++ node->fullpath); ++ ++ prop = get_property(node, "ranges"); ++ if (!prop) ++ FAIL(c, dti, "Node %s missing ranges for PCI bridge (or not a bridge)", ++ node->fullpath); ++ ++ if (node_addr_cells(node) != 3) ++ FAIL(c, dti, "Node %s incorrect #address-cells for PCI bridge", ++ node->fullpath); ++ if (node_size_cells(node) != 2) ++ FAIL(c, dti, "Node %s incorrect #size-cells for PCI bridge", ++ node->fullpath); ++ ++ prop = get_property(node, "bus-range"); ++ if (!prop) { ++ FAIL(c, dti, "Node %s missing bus-range for PCI bridge", ++ node->fullpath); ++ return; ++ } ++ if (prop->val.len != (sizeof(cell_t) * 2)) { ++ FAIL(c, dti, "Node %s bus-range must be 2 cells", ++ node->fullpath); ++ return; ++ } ++ cells = (cell_t *)prop->val.val; ++ if (fdt32_to_cpu(cells[0]) > fdt32_to_cpu(cells[1])) ++ FAIL(c, dti, "Node %s bus-range 1st cell must be less than or equal to 2nd cell", ++ node->fullpath); ++ if (fdt32_to_cpu(cells[1]) > 0xff) ++ FAIL(c, dti, "Node %s bus-range maximum bus number must be less than 256", ++ node->fullpath); ++} ++WARNING(pci_bridge, check_pci_bridge, NULL, ++ &device_type_is_string, &addr_size_cells); ++ ++static void check_pci_device_bus_num(struct check *c, struct dt_info *dti, struct node *node) ++{ ++ struct property *prop; ++ unsigned int bus_num, min_bus, max_bus; ++ cell_t *cells; ++ ++ if (!node->parent || (node->parent->bus != &pci_bus)) ++ return; ++ ++ prop = get_property(node, "reg"); ++ if (!prop) ++ return; ++ ++ cells = (cell_t *)prop->val.val; ++ bus_num = (fdt32_to_cpu(cells[0]) & 0x00ff0000) >> 16; ++ ++ prop = get_property(node->parent, "bus-range"); ++ if (!prop) { ++ min_bus = max_bus = 0; ++ } else { ++ cells = (cell_t *)prop->val.val; ++ min_bus = fdt32_to_cpu(cells[0]); ++ max_bus = fdt32_to_cpu(cells[0]); ++ } ++ if ((bus_num < min_bus) || (bus_num > max_bus)) ++ FAIL(c, dti, "Node %s PCI bus number %d out of range, expected (%d - %d)", ++ node->fullpath, bus_num, min_bus, max_bus); ++} ++WARNING(pci_device_bus_num, check_pci_device_bus_num, NULL, ®_format, &pci_bridge); ++ ++static void check_pci_device_reg(struct check *c, struct dt_info *dti, struct node *node) ++{ ++ struct property *prop; ++ const char *unitname = get_unitname(node); ++ char unit_addr[5]; ++ unsigned int dev, func, reg; ++ cell_t *cells; ++ ++ if (!node->parent || (node->parent->bus != &pci_bus)) ++ return; ++ ++ prop = get_property(node, "reg"); ++ if (!prop) { ++ FAIL(c, dti, "Node %s missing PCI reg property", node->fullpath); ++ return; ++ } ++ ++ cells = (cell_t *)prop->val.val; ++ if (cells[1] || cells[2]) ++ FAIL(c, dti, "Node %s PCI reg config space address cells 2 and 3 must be 0", ++ node->fullpath); ++ ++ reg = fdt32_to_cpu(cells[0]); ++ dev = (reg & 0xf800) >> 11; ++ func = (reg & 0x700) >> 8; ++ ++ if (reg & 0xff000000) ++ FAIL(c, dti, "Node %s PCI reg address is not configuration space", ++ node->fullpath); ++ if (reg & 0x000000ff) ++ FAIL(c, dti, "Node %s PCI reg config space address register number must be 0", ++ node->fullpath); ++ ++ if (func == 0) { ++ snprintf(unit_addr, sizeof(unit_addr), "%x", dev); ++ if (streq(unitname, unit_addr)) ++ return; ++ } ++ ++ snprintf(unit_addr, sizeof(unit_addr), "%x,%x", dev, func); ++ if (streq(unitname, unit_addr)) ++ return; ++ ++ FAIL(c, dti, "Node %s PCI unit address format error, expected \"%s\"", ++ node->fullpath, unit_addr); ++} ++WARNING(pci_device_reg, check_pci_device_reg, NULL, ®_format, &pci_bridge); ++ ++static const struct bus_type simple_bus = { ++ .name = "simple-bus", ++}; ++ ++static bool node_is_compatible(struct node *node, const char *compat) ++{ ++ struct property *prop; ++ const char *str, *end; ++ ++ prop = get_property(node, "compatible"); ++ if (!prop) ++ return false; ++ ++ for (str = prop->val.val, end = str + prop->val.len; str < end; ++ str += strnlen(str, end - str) + 1) { ++ if (strneq(str, compat, end - str)) ++ return true; ++ } ++ return false; ++} ++ ++static void check_simple_bus_bridge(struct check *c, struct dt_info *dti, struct node *node) ++{ ++ if (node_is_compatible(node, "simple-bus")) ++ node->bus = &simple_bus; ++} ++WARNING(simple_bus_bridge, check_simple_bus_bridge, NULL, &addr_size_cells); ++ ++static void check_simple_bus_reg(struct check *c, struct dt_info *dti, struct node *node) ++{ ++ struct property *prop; ++ const char *unitname = get_unitname(node); ++ char unit_addr[17]; ++ unsigned int size; ++ uint64_t reg = 0; ++ cell_t *cells = NULL; ++ ++ if (!node->parent || (node->parent->bus != &simple_bus)) ++ return; ++ ++ prop = get_property(node, "reg"); ++ if (prop) ++ cells = (cell_t *)prop->val.val; ++ else { ++ prop = get_property(node, "ranges"); ++ if (prop && prop->val.len) ++ /* skip of child address */ ++ cells = ((cell_t *)prop->val.val) + node_addr_cells(node); ++ } ++ ++ if (!cells) { ++ if (node->parent->parent && !(node->bus == &simple_bus)) ++ FAIL(c, dti, "Node %s missing or empty reg/ranges property", node->fullpath); ++ return; ++ } ++ ++ size = node_addr_cells(node->parent); ++ while (size--) ++ reg = (reg << 32) | fdt32_to_cpu(*(cells++)); ++ ++ snprintf(unit_addr, sizeof(unit_addr), "%lx", reg); ++ if (!streq(unitname, unit_addr)) ++ FAIL(c, dti, "Node %s simple-bus unit address format error, expected \"%s\"", ++ node->fullpath, unit_addr); ++} ++WARNING(simple_bus_reg, check_simple_bus_reg, NULL, ®_format, &simple_bus_bridge); ++ ++static void check_unit_address_format(struct check *c, struct dt_info *dti, ++ struct node *node) ++{ ++ const char *unitname = get_unitname(node); ++ ++ if (node->parent && node->parent->bus) ++ return; ++ ++ if (!unitname[0]) ++ return; ++ ++ if (!strncmp(unitname, "0x", 2)) { ++ FAIL(c, dti, "Node %s unit name should not have leading \"0x\"", ++ node->fullpath); ++ /* skip over 0x for next test */ ++ unitname += 2; ++ } ++ if (unitname[0] == '0' && isxdigit(unitname[1])) ++ FAIL(c, dti, "Node %s unit name should not have leading 0s", ++ node->fullpath); ++} ++WARNING(unit_address_format, check_unit_address_format, NULL, ++ &node_name_format, &pci_bridge, &simple_bus_bridge); ++ + /* + * Style checks + */ +@@ -656,11 +922,11 @@ static void check_avoid_default_addr_size(struct check *c, struct dt_info *dti, + return; + + if (node->parent->addr_cells == -1) +- FAIL(c, "Relying on default #address-cells value for %s", ++ FAIL(c, dti, "Relying on default #address-cells value for %s", + node->fullpath); + + if (node->parent->size_cells == -1) +- FAIL(c, "Relying on default #size-cells value for %s", ++ FAIL(c, dti, "Relying on default #size-cells value for %s", + node->fullpath); + } + WARNING(avoid_default_addr_size, check_avoid_default_addr_size, NULL, +@@ -684,7 +950,7 @@ static void check_obsolete_chosen_interrupt_controller(struct check *c, + + prop = get_property(chosen, "interrupt-controller"); + if (prop) +- FAIL(c, "/chosen has obsolete \"interrupt-controller\" " ++ FAIL(c, dti, "/chosen has obsolete \"interrupt-controller\" " + "property"); + } + WARNING(obsolete_chosen_interrupt_controller, +@@ -703,9 +969,20 @@ static struct check *check_table[] = { + &address_cells_is_cell, &size_cells_is_cell, &interrupt_cells_is_cell, + &device_type_is_string, &model_is_string, &status_is_string, + ++ &property_name_chars_strict, ++ &node_name_chars_strict, ++ + &addr_size_cells, ®_format, &ranges_format, + + &unit_address_vs_reg, ++ &unit_address_format, ++ ++ &pci_bridge, ++ &pci_device_reg, ++ &pci_device_bus_num, ++ ++ &simple_bus_bridge, ++ &simple_bus_reg, + + &avoid_default_addr_size, + &obsolete_chosen_interrupt_controller, +diff --git a/scripts/dtc/data.c b/scripts/dtc/data.c +index 8cae2374..aa37a16c 100644 +--- a/scripts/dtc/data.c ++++ b/scripts/dtc/data.c +@@ -171,9 +171,9 @@ struct data data_merge(struct data d1, struct data d2) + struct data data_append_integer(struct data d, uint64_t value, int bits) + { + uint8_t value_8; +- uint16_t value_16; +- uint32_t value_32; +- uint64_t value_64; ++ fdt16_t value_16; ++ fdt32_t value_32; ++ fdt64_t value_64; + + switch (bits) { + case 8: +@@ -197,14 +197,14 @@ struct data data_append_integer(struct data d, uint64_t value, int bits) + } + } + +-struct data data_append_re(struct data d, const struct fdt_reserve_entry *re) ++struct data data_append_re(struct data d, uint64_t address, uint64_t size) + { +- struct fdt_reserve_entry bere; ++ struct fdt_reserve_entry re; + +- bere.address = cpu_to_fdt64(re->address); +- bere.size = cpu_to_fdt64(re->size); ++ re.address = cpu_to_fdt64(address); ++ re.size = cpu_to_fdt64(size); + +- return data_append_data(d, &bere, sizeof(bere)); ++ return data_append_data(d, &re, sizeof(re)); + } + + struct data data_append_cell(struct data d, cell_t word) +diff --git a/scripts/dtc/dtc-lexer.l b/scripts/dtc/dtc-lexer.l +index c6006030..fd825ebb 100644 +--- a/scripts/dtc/dtc-lexer.l ++++ b/scripts/dtc/dtc-lexer.l +@@ -62,7 +62,8 @@ static int dts_version = 1; + + static void push_input_file(const char *filename); + static bool pop_input_file(void); +-static void lexical_error(const char *fmt, ...); ++static void PRINTF(1, 2) lexical_error(const char *fmt, ...); ++ + %} + + %% +diff --git a/scripts/dtc/dtc-lexer.lex.c_shipped b/scripts/dtc/dtc-lexer.lex.c_shipped +index 2c862bc8..6b016dba 100644 +--- a/scripts/dtc/dtc-lexer.lex.c_shipped ++++ b/scripts/dtc/dtc-lexer.lex.c_shipped +@@ -9,7 +9,7 @@ + #define FLEX_SCANNER + #define YY_FLEX_MAJOR_VERSION 2 + #define YY_FLEX_MINOR_VERSION 6 +-#define YY_FLEX_SUBMINOR_VERSION 1 ++#define YY_FLEX_SUBMINOR_VERSION 0 + #if YY_FLEX_SUBMINOR_VERSION > 0 + #define FLEX_BETA + #endif +@@ -88,13 +88,25 @@ typedef unsigned int flex_uint32_t; + + #endif /* ! FLEXINT_H */ + +-/* TODO: this is always defined, so inline it */ +-#define yyconst const ++#ifdef __cplusplus + +-#if defined(__GNUC__) && __GNUC__ >= 3 +-#define yynoreturn __attribute__((__noreturn__)) ++/* The "const" storage-class-modifier is valid. */ ++#define YY_USE_CONST ++ ++#else /* ! __cplusplus */ ++ ++/* C99 requires __STDC__ to be defined as 1. */ ++#if defined (__STDC__) ++ ++#define YY_USE_CONST ++ ++#endif /* defined (__STDC__) */ ++#endif /* ! __cplusplus */ ++ ++#ifdef YY_USE_CONST ++#define yyconst const + #else +-#define yynoreturn ++#define yyconst + #endif + + /* Returned upon end-of-file. */ +@@ -155,7 +167,7 @@ typedef struct yy_buffer_state *YY_BUFFER_STATE; + typedef size_t yy_size_t; + #endif + +-extern int yyleng; ++extern yy_size_t yyleng; + + extern FILE *yyin, *yyout; + +@@ -194,7 +206,7 @@ struct yy_buffer_state + /* Size of input buffer in bytes, not including room for EOB + * characters. + */ +- int yy_buf_size; ++ yy_size_t yy_buf_size; + + /* Number of characters read into yy_ch_buf, not including EOB + * characters. +@@ -222,7 +234,7 @@ struct yy_buffer_state + + int yy_bs_lineno; /**< The line count. */ + int yy_bs_column; /**< The column count. */ +- ++ + /* Whether to try to fill the input buffer when we reach the + * end of it. + */ +@@ -250,7 +262,7 @@ struct yy_buffer_state + /* Stack of input buffers. */ + static size_t yy_buffer_stack_top = 0; /**< index of top of stack. */ + static size_t yy_buffer_stack_max = 0; /**< capacity of stack. */ +-static YY_BUFFER_STATE * yy_buffer_stack = NULL; /**< Stack as an array. */ ++static YY_BUFFER_STATE * yy_buffer_stack = 0; /**< Stack as an array. */ + + /* We provide macros for accessing buffer states in case in the + * future we want to put the buffer states in a more general +@@ -270,10 +282,10 @@ static YY_BUFFER_STATE * yy_buffer_stack = NULL; /**< Stack as an array. */ + /* yy_hold_char holds the character lost when yytext is formed. */ + static char yy_hold_char; + static int yy_n_chars; /* number of characters read into yy_ch_buf */ +-int yyleng; ++yy_size_t yyleng; + + /* Points to current character in buffer. */ +-static char *yy_c_buf_p = NULL; ++static char *yy_c_buf_p = (char *) 0; + static int yy_init = 0; /* whether we need to initialize */ + static int yy_start = 0; /* start state number */ + +@@ -298,7 +310,7 @@ static void yy_init_buffer (YY_BUFFER_STATE b,FILE *file ); + + YY_BUFFER_STATE yy_scan_buffer (char *base,yy_size_t size ); + YY_BUFFER_STATE yy_scan_string (yyconst char *yy_str ); +-YY_BUFFER_STATE yy_scan_bytes (yyconst char *bytes,int len ); ++YY_BUFFER_STATE yy_scan_bytes (yyconst char *bytes,yy_size_t len ); + + void *yyalloc (yy_size_t ); + void *yyrealloc (void *,yy_size_t ); +@@ -335,7 +347,7 @@ void yyfree (void * ); + + typedef unsigned char YY_CHAR; + +-FILE *yyin = NULL, *yyout = NULL; ++FILE *yyin = (FILE *) 0, *yyout = (FILE *) 0; + + typedef int yy_state_type; + +@@ -352,14 +364,17 @@ extern char *yytext; + static yy_state_type yy_get_previous_state (void ); + static yy_state_type yy_try_NUL_trans (yy_state_type current_state ); + static int yy_get_next_buffer (void ); +-static void yynoreturn yy_fatal_error (yyconst char* msg ); ++#if defined(__GNUC__) && __GNUC__ >= 3 ++__attribute__((__noreturn__)) ++#endif ++static void yy_fatal_error (yyconst char msg[] ); + + /* Done after the current pattern has been matched and before the + * corresponding action - sets up yytext. + */ + #define YY_DO_BEFORE_ACTION \ + (yytext_ptr) = yy_bp; \ +- yyleng = (int) (yy_cp - yy_bp); \ ++ yyleng = (size_t) (yy_cp - yy_bp); \ + (yy_hold_char) = *yy_cp; \ + *yy_cp = '\0'; \ + (yy_c_buf_p) = yy_cp; +@@ -655,8 +670,9 @@ static int dts_version = 1; + + static void push_input_file(const char *filename); + static bool pop_input_file(void); +-static void lexical_error(const char *fmt, ...); +-#line 660 "dtc-lexer.lex.c" ++static void PRINTF(1, 2) lexical_error(const char *fmt, ...); ++ ++#line 676 "dtc-lexer.lex.c" + + #define INITIAL 0 + #define BYTESTRING 1 +@@ -698,7 +714,7 @@ FILE *yyget_out (void ); + + void yyset_out (FILE * _out_str ); + +- int yyget_leng (void ); ++yy_size_t yyget_leng (void ); + + char *yyget_text (void ); + +@@ -755,7 +771,7 @@ static int input (void ); + /* This used to be an fputs(), but since the string might contain NUL's, + * we now use fwrite(). + */ +-#define ECHO do { if (fwrite( yytext, (size_t) yyleng, 1, yyout )) {} } while (0) ++#define ECHO do { if (fwrite( yytext, yyleng, 1, yyout )) {} } while (0) + #endif + + /* Gets input and stuffs it into "buf". number of characters read, or YY_NULL, +@@ -779,7 +795,7 @@ static int input (void ); + else \ + { \ + errno=0; \ +- while ( (result = (int) fread(buf, 1, max_size, yyin))==0 && ferror(yyin)) \ ++ while ( (result = fread(buf, 1, max_size, yyin))==0 && ferror(yyin)) \ + { \ + if( errno != EINTR) \ + { \ +@@ -878,9 +894,9 @@ YY_DECL + } + + { +-#line 68 "dtc-lexer.l" ++#line 69 "dtc-lexer.l" + +-#line 884 "dtc-lexer.lex.c" ++#line 900 "dtc-lexer.lex.c" + + while ( /*CONSTCOND*/1 ) /* loops until end-of-file is reached */ + { +@@ -911,7 +927,7 @@ yy_match: + if ( yy_current_state >= 166 ) + yy_c = yy_meta[(unsigned int) yy_c]; + } +- yy_current_state = yy_nxt[yy_base[yy_current_state] + (flex_int16_t) yy_c]; ++ yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c]; + ++yy_cp; + } + while ( yy_current_state != 165 ); +@@ -937,7 +953,7 @@ do_action: /* This label is used only to access EOF actions. */ + case 1: + /* rule 1 can match eol */ + YY_RULE_SETUP +-#line 69 "dtc-lexer.l" ++#line 70 "dtc-lexer.l" + { + char *name = strchr(yytext, '\"') + 1; + yytext[yyleng-1] = '\0'; +@@ -947,7 +963,7 @@ YY_RULE_SETUP + case 2: + /* rule 2 can match eol */ + YY_RULE_SETUP +-#line 75 "dtc-lexer.l" ++#line 76 "dtc-lexer.l" + { + char *line, *fnstart, *fnend; + struct data fn; +@@ -981,7 +997,7 @@ case YY_STATE_EOF(INITIAL): + case YY_STATE_EOF(BYTESTRING): + case YY_STATE_EOF(PROPNODENAME): + case YY_STATE_EOF(V1): +-#line 104 "dtc-lexer.l" ++#line 105 "dtc-lexer.l" + { + if (!pop_input_file()) { + yyterminate(); +@@ -991,7 +1007,7 @@ case YY_STATE_EOF(V1): + case 3: + /* rule 3 can match eol */ + YY_RULE_SETUP +-#line 110 "dtc-lexer.l" ++#line 111 "dtc-lexer.l" + { + DPRINT("String: %s\n", yytext); + yylval.data = data_copy_escape_string(yytext+1, +@@ -1001,7 +1017,7 @@ YY_RULE_SETUP + YY_BREAK + case 4: + YY_RULE_SETUP +-#line 117 "dtc-lexer.l" ++#line 118 "dtc-lexer.l" + { + DPRINT("Keyword: /dts-v1/\n"); + dts_version = 1; +@@ -1011,7 +1027,7 @@ YY_RULE_SETUP + YY_BREAK + case 5: + YY_RULE_SETUP +-#line 124 "dtc-lexer.l" ++#line 125 "dtc-lexer.l" + { + DPRINT("Keyword: /plugin/\n"); + return DT_PLUGIN; +@@ -1019,7 +1035,7 @@ YY_RULE_SETUP + YY_BREAK + case 6: + YY_RULE_SETUP +-#line 129 "dtc-lexer.l" ++#line 130 "dtc-lexer.l" + { + DPRINT("Keyword: /memreserve/\n"); + BEGIN_DEFAULT(); +@@ -1028,7 +1044,7 @@ YY_RULE_SETUP + YY_BREAK + case 7: + YY_RULE_SETUP +-#line 135 "dtc-lexer.l" ++#line 136 "dtc-lexer.l" + { + DPRINT("Keyword: /bits/\n"); + BEGIN_DEFAULT(); +@@ -1037,7 +1053,7 @@ YY_RULE_SETUP + YY_BREAK + case 8: + YY_RULE_SETUP +-#line 141 "dtc-lexer.l" ++#line 142 "dtc-lexer.l" + { + DPRINT("Keyword: /delete-property/\n"); + DPRINT("<PROPNODENAME>\n"); +@@ -1047,7 +1063,7 @@ YY_RULE_SETUP + YY_BREAK + case 9: + YY_RULE_SETUP +-#line 148 "dtc-lexer.l" ++#line 149 "dtc-lexer.l" + { + DPRINT("Keyword: /delete-node/\n"); + DPRINT("<PROPNODENAME>\n"); +@@ -1057,7 +1073,7 @@ YY_RULE_SETUP + YY_BREAK + case 10: + YY_RULE_SETUP +-#line 155 "dtc-lexer.l" ++#line 156 "dtc-lexer.l" + { + DPRINT("Label: %s\n", yytext); + yylval.labelref = xstrdup(yytext); +@@ -1067,7 +1083,7 @@ YY_RULE_SETUP + YY_BREAK + case 11: + YY_RULE_SETUP +-#line 162 "dtc-lexer.l" ++#line 163 "dtc-lexer.l" + { + char *e; + DPRINT("Integer Literal: '%s'\n", yytext); +@@ -1093,7 +1109,7 @@ YY_RULE_SETUP + case 12: + /* rule 12 can match eol */ + YY_RULE_SETUP +-#line 184 "dtc-lexer.l" ++#line 185 "dtc-lexer.l" + { + struct data d; + DPRINT("Character literal: %s\n", yytext); +@@ -1117,7 +1133,7 @@ YY_RULE_SETUP + YY_BREAK + case 13: + YY_RULE_SETUP +-#line 205 "dtc-lexer.l" ++#line 206 "dtc-lexer.l" + { /* label reference */ + DPRINT("Ref: %s\n", yytext+1); + yylval.labelref = xstrdup(yytext+1); +@@ -1126,7 +1142,7 @@ YY_RULE_SETUP + YY_BREAK + case 14: + YY_RULE_SETUP +-#line 211 "dtc-lexer.l" ++#line 212 "dtc-lexer.l" + { /* new-style path reference */ + yytext[yyleng-1] = '\0'; + DPRINT("Ref: %s\n", yytext+2); +@@ -1136,7 +1152,7 @@ YY_RULE_SETUP + YY_BREAK + case 15: + YY_RULE_SETUP +-#line 218 "dtc-lexer.l" ++#line 219 "dtc-lexer.l" + { + yylval.byte = strtol(yytext, NULL, 16); + DPRINT("Byte: %02x\n", (int)yylval.byte); +@@ -1145,7 +1161,7 @@ YY_RULE_SETUP + YY_BREAK + case 16: + YY_RULE_SETUP +-#line 224 "dtc-lexer.l" ++#line 225 "dtc-lexer.l" + { + DPRINT("/BYTESTRING\n"); + BEGIN_DEFAULT(); +@@ -1154,7 +1170,7 @@ YY_RULE_SETUP + YY_BREAK + case 17: + YY_RULE_SETUP +-#line 230 "dtc-lexer.l" ++#line 231 "dtc-lexer.l" + { + DPRINT("PropNodeName: %s\n", yytext); + yylval.propnodename = xstrdup((yytext[0] == '\\') ? +@@ -1165,7 +1181,7 @@ YY_RULE_SETUP + YY_BREAK + case 18: + YY_RULE_SETUP +-#line 238 "dtc-lexer.l" ++#line 239 "dtc-lexer.l" + { + DPRINT("Binary Include\n"); + return DT_INCBIN; +@@ -1174,64 +1190,64 @@ YY_RULE_SETUP + case 19: + /* rule 19 can match eol */ + YY_RULE_SETUP +-#line 243 "dtc-lexer.l" ++#line 244 "dtc-lexer.l" + /* eat whitespace */ + YY_BREAK + case 20: + /* rule 20 can match eol */ + YY_RULE_SETUP +-#line 244 "dtc-lexer.l" ++#line 245 "dtc-lexer.l" + /* eat C-style comments */ + YY_BREAK + case 21: + /* rule 21 can match eol */ + YY_RULE_SETUP +-#line 245 "dtc-lexer.l" ++#line 246 "dtc-lexer.l" + /* eat C++-style comments */ + YY_BREAK + case 22: + YY_RULE_SETUP +-#line 247 "dtc-lexer.l" ++#line 248 "dtc-lexer.l" + { return DT_LSHIFT; }; + YY_BREAK + case 23: + YY_RULE_SETUP +-#line 248 "dtc-lexer.l" ++#line 249 "dtc-lexer.l" + { return DT_RSHIFT; }; + YY_BREAK + case 24: + YY_RULE_SETUP +-#line 249 "dtc-lexer.l" ++#line 250 "dtc-lexer.l" + { return DT_LE; }; + YY_BREAK + case 25: + YY_RULE_SETUP +-#line 250 "dtc-lexer.l" ++#line 251 "dtc-lexer.l" + { return DT_GE; }; + YY_BREAK + case 26: + YY_RULE_SETUP +-#line 251 "dtc-lexer.l" ++#line 252 "dtc-lexer.l" + { return DT_EQ; }; + YY_BREAK + case 27: + YY_RULE_SETUP +-#line 252 "dtc-lexer.l" ++#line 253 "dtc-lexer.l" + { return DT_NE; }; + YY_BREAK + case 28: + YY_RULE_SETUP +-#line 253 "dtc-lexer.l" ++#line 254 "dtc-lexer.l" + { return DT_AND; }; + YY_BREAK + case 29: + YY_RULE_SETUP +-#line 254 "dtc-lexer.l" ++#line 255 "dtc-lexer.l" + { return DT_OR; }; + YY_BREAK + case 30: + YY_RULE_SETUP +-#line 256 "dtc-lexer.l" ++#line 257 "dtc-lexer.l" + { + DPRINT("Char: %c (\\x%02x)\n", yytext[0], + (unsigned)yytext[0]); +@@ -1249,10 +1265,10 @@ YY_RULE_SETUP + YY_BREAK + case 31: + YY_RULE_SETUP +-#line 271 "dtc-lexer.l" ++#line 272 "dtc-lexer.l" + ECHO; + YY_BREAK +-#line 1256 "dtc-lexer.lex.c" ++#line 1272 "dtc-lexer.lex.c" + + case YY_END_OF_BUFFER: + { +@@ -1438,7 +1454,7 @@ static int yy_get_next_buffer (void) + + else + { +- int num_to_read = ++ yy_size_t num_to_read = + YY_CURRENT_BUFFER_LVALUE->yy_buf_size - number_to_move - 1; + + while ( num_to_read <= 0 ) +@@ -1452,7 +1468,7 @@ static int yy_get_next_buffer (void) + + if ( b->yy_is_our_buffer ) + { +- int new_size = b->yy_buf_size * 2; ++ yy_size_t new_size = b->yy_buf_size * 2; + + if ( new_size <= 0 ) + b->yy_buf_size += b->yy_buf_size / 8; +@@ -1465,7 +1481,7 @@ static int yy_get_next_buffer (void) + } + else + /* Can't grow it, we don't own it. */ +- b->yy_ch_buf = NULL; ++ b->yy_ch_buf = 0; + + if ( ! b->yy_ch_buf ) + YY_FATAL_ERROR( +@@ -1548,7 +1564,7 @@ static int yy_get_next_buffer (void) + if ( yy_current_state >= 166 ) + yy_c = yy_meta[(unsigned int) yy_c]; + } +- yy_current_state = yy_nxt[yy_base[yy_current_state] + (flex_int16_t) yy_c]; ++ yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c]; + } + + return yy_current_state; +@@ -1576,7 +1592,7 @@ static int yy_get_next_buffer (void) + if ( yy_current_state >= 166 ) + yy_c = yy_meta[(unsigned int) yy_c]; + } +- yy_current_state = yy_nxt[yy_base[yy_current_state] + (flex_int16_t) yy_c]; ++ yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c]; + yy_is_jam = (yy_current_state == 165); + + return yy_is_jam ? 0 : yy_current_state; +@@ -1610,7 +1626,7 @@ static int yy_get_next_buffer (void) + + else + { /* need more input */ +- int offset = (yy_c_buf_p) - (yytext_ptr); ++ yy_size_t offset = (yy_c_buf_p) - (yytext_ptr); + ++(yy_c_buf_p); + + switch ( yy_get_next_buffer( ) ) +@@ -1634,7 +1650,7 @@ static int yy_get_next_buffer (void) + case EOB_ACT_END_OF_FILE: + { + if ( yywrap( ) ) +- return 0; ++ return EOF; + + if ( ! (yy_did_buffer_switch_on_eof) ) + YY_NEW_FILE; +@@ -1884,7 +1900,7 @@ void yypop_buffer_state (void) + */ + static void yyensure_buffer_stack (void) + { +- int num_to_alloc; ++ yy_size_t num_to_alloc; + + if (!(yy_buffer_stack)) { + +@@ -1892,15 +1908,15 @@ static void yyensure_buffer_stack (void) + * scanner will even need a stack. We use 2 instead of 1 to avoid an + * immediate realloc on the next call. + */ +- num_to_alloc = 1; /* After all that talk, this was set to 1 anyways... */ ++ num_to_alloc = 1; /* After all that talk, this was set to 1 anyways... */ + (yy_buffer_stack) = (struct yy_buffer_state**)yyalloc + (num_to_alloc * sizeof(struct yy_buffer_state*) + ); + if ( ! (yy_buffer_stack) ) + YY_FATAL_ERROR( "out of dynamic memory in yyensure_buffer_stack()" ); +- ++ + memset((yy_buffer_stack), 0, num_to_alloc * sizeof(struct yy_buffer_state*)); +- ++ + (yy_buffer_stack_max) = num_to_alloc; + (yy_buffer_stack_top) = 0; + return; +@@ -1929,7 +1945,7 @@ static void yyensure_buffer_stack (void) + * @param base the character buffer + * @param size the size in bytes of the character buffer + * +- * @return the newly allocated buffer state object. ++ * @return the newly allocated buffer state object. + */ + YY_BUFFER_STATE yy_scan_buffer (char * base, yy_size_t size ) + { +@@ -1939,7 +1955,7 @@ YY_BUFFER_STATE yy_scan_buffer (char * base, yy_size_t size ) + base[size-2] != YY_END_OF_BUFFER_CHAR || + base[size-1] != YY_END_OF_BUFFER_CHAR ) + /* They forgot to leave room for the EOB's. */ +- return NULL; ++ return 0; + + b = (YY_BUFFER_STATE) yyalloc(sizeof( struct yy_buffer_state ) ); + if ( ! b ) +@@ -1948,7 +1964,7 @@ YY_BUFFER_STATE yy_scan_buffer (char * base, yy_size_t size ) + b->yy_buf_size = size - 2; /* "- 2" to take care of EOB's */ + b->yy_buf_pos = b->yy_ch_buf = base; + b->yy_is_our_buffer = 0; +- b->yy_input_file = NULL; ++ b->yy_input_file = 0; + b->yy_n_chars = b->yy_buf_size; + b->yy_is_interactive = 0; + b->yy_at_bol = 1; +@@ -1971,7 +1987,7 @@ YY_BUFFER_STATE yy_scan_buffer (char * base, yy_size_t size ) + YY_BUFFER_STATE yy_scan_string (yyconst char * yystr ) + { + +- return yy_scan_bytes(yystr,(int) strlen(yystr) ); ++ return yy_scan_bytes(yystr,strlen(yystr) ); + } + + /** Setup the input buffer state to scan the given bytes. The next call to yylex() will +@@ -1981,7 +1997,7 @@ YY_BUFFER_STATE yy_scan_string (yyconst char * yystr ) + * + * @return the newly allocated buffer state object. + */ +-YY_BUFFER_STATE yy_scan_bytes (yyconst char * yybytes, int _yybytes_len ) ++YY_BUFFER_STATE yy_scan_bytes (yyconst char * yybytes, yy_size_t _yybytes_len ) + { + YY_BUFFER_STATE b; + char *buf; +@@ -1989,7 +2005,7 @@ YY_BUFFER_STATE yy_scan_bytes (yyconst char * yybytes, int _yybytes_len ) + yy_size_t i; + + /* Get memory for full buffer, including space for trailing EOB's. */ +- n = (yy_size_t) _yybytes_len + 2; ++ n = _yybytes_len + 2; + buf = (char *) yyalloc(n ); + if ( ! buf ) + YY_FATAL_ERROR( "out of dynamic memory in yy_scan_bytes()" ); +@@ -2015,7 +2031,7 @@ YY_BUFFER_STATE yy_scan_bytes (yyconst char * yybytes, int _yybytes_len ) + #define YY_EXIT_FAILURE 2 + #endif + +-static void yynoreturn yy_fatal_error (yyconst char* msg ) ++static void yy_fatal_error (yyconst char* msg ) + { + (void) fprintf( stderr, "%s\n", msg ); + exit( YY_EXIT_FAILURE ); +@@ -2045,7 +2061,7 @@ static void yynoreturn yy_fatal_error (yyconst char* msg ) + */ + int yyget_lineno (void) + { +- ++ + return yylineno; + } + +@@ -2068,7 +2084,7 @@ FILE *yyget_out (void) + /** Get the length of the current token. + * + */ +-int yyget_leng (void) ++yy_size_t yyget_leng (void) + { + return yyleng; + } +@@ -2124,10 +2140,10 @@ static int yy_init_globals (void) + * This function is called from yylex_destroy(), so don't allocate here. + */ + +- (yy_buffer_stack) = NULL; ++ (yy_buffer_stack) = 0; + (yy_buffer_stack_top) = 0; + (yy_buffer_stack_max) = 0; +- (yy_c_buf_p) = NULL; ++ (yy_c_buf_p) = (char *) 0; + (yy_init) = 0; + (yy_start) = 0; + +@@ -2136,8 +2152,8 @@ static int yy_init_globals (void) + yyin = stdin; + yyout = stdout; + #else +- yyin = NULL; +- yyout = NULL; ++ yyin = (FILE *) 0; ++ yyout = (FILE *) 0; + #endif + + /* For future reference: Set errno on error, since we are called by +@@ -2195,7 +2211,7 @@ static int yy_flex_strlen (yyconst char * s ) + + void *yyalloc (yy_size_t size ) + { +- return malloc(size); ++ return (void *) malloc( size ); + } + + void *yyrealloc (void * ptr, yy_size_t size ) +@@ -2208,7 +2224,7 @@ void *yyrealloc (void * ptr, yy_size_t size ) + * any pointer type to void*, and deal with argument conversions + * as though doing an assignment. + */ +- return realloc(ptr, size); ++ return (void *) realloc( (char *) ptr, size ); + } + + void yyfree (void * ptr ) +@@ -2218,7 +2234,7 @@ void yyfree (void * ptr ) + + #define YYTABLES_NAME "yytables" + +-#line 271 "dtc-lexer.l" ++#line 272 "dtc-lexer.l" + + + +diff --git a/scripts/dtc/dtc-parser.tab.c_shipped b/scripts/dtc/dtc-parser.tab.c_shipped +index 2965227a..0a7a5ed8 100644 +--- a/scripts/dtc/dtc-parser.tab.c_shipped ++++ b/scripts/dtc/dtc-parser.tab.c_shipped +@@ -1557,10 +1557,10 @@ yyreduce: + { + struct node *target = get_node_by_ref((yyvsp[-3].node), (yyvsp[-1].labelref)); + +- add_label(&target->labels, (yyvsp[-2].labelref)); +- if (target) ++ if (target) { ++ add_label(&target->labels, (yyvsp[-2].labelref)); + merge_nodes(target, (yyvsp[0].node)); +- else ++ } else + ERROR(&(yylsp[-1]), "Label or path %s not found", (yyvsp[-1].labelref)); + (yyval.node) = (yyvsp[-3].node); + } +diff --git a/scripts/dtc/dtc-parser.y b/scripts/dtc/dtc-parser.y +index b2fd4d15..ca3f5003 100644 +--- a/scripts/dtc/dtc-parser.y ++++ b/scripts/dtc/dtc-parser.y +@@ -171,10 +171,10 @@ devicetree: + { + struct node *target = get_node_by_ref($1, $3); + +- add_label(&target->labels, $2); +- if (target) ++ if (target) { ++ add_label(&target->labels, $2); + merge_nodes(target, $4); +- else ++ } else + ERROR(&@3, "Label or path %s not found", $3); + $$ = $1; + } +diff --git a/scripts/dtc/dtc.c b/scripts/dtc/dtc.c +index a4edf4c7..f5eed9d7 100644 +--- a/scripts/dtc/dtc.c ++++ b/scripts/dtc/dtc.c +@@ -138,7 +138,7 @@ static const char *guess_type_by_name(const char *fname, const char *fallback) + static const char *guess_input_format(const char *fname, const char *fallback) + { + struct stat statbuf; +- uint32_t magic; ++ fdt32_t magic; + FILE *f; + + if (stat(fname, &statbuf) != 0) +@@ -159,8 +159,7 @@ static const char *guess_input_format(const char *fname, const char *fallback) + } + fclose(f); + +- magic = fdt32_to_cpu(magic); +- if (magic == FDT_MAGIC) ++ if (fdt32_to_cpu(magic) == FDT_MAGIC) + return "dtb"; + + return guess_type_by_name(fname, fallback); +@@ -216,7 +215,7 @@ int main(int argc, char *argv[]) + alignsize = strtol(optarg, NULL, 0); + if (!is_power_of_2(alignsize)) + die("Invalid argument \"%d\" to -a option\n", +- optarg); ++ alignsize); + break; + case 'f': + force = true; +@@ -309,6 +308,8 @@ int main(int argc, char *argv[]) + else + die("Unknown input format \"%s\"\n", inform); + ++ dti->outname = outname; ++ + if (depfile) { + fputc('\n', depfile); + fclose(depfile); +diff --git a/scripts/dtc/dtc.h b/scripts/dtc/dtc.h +index c6f125c6..fc24e175 100644 +--- a/scripts/dtc/dtc.h ++++ b/scripts/dtc/dtc.h +@@ -43,7 +43,6 @@ + #define debug(...) + #endif + +- + #define DEFAULT_FDT_VERSION 17 + + /* +@@ -114,7 +113,7 @@ struct data data_insert_at_marker(struct data d, struct marker *m, + struct data data_merge(struct data d1, struct data d2); + struct data data_append_cell(struct data d, cell_t word); + struct data data_append_integer(struct data d, uint64_t word, int bits); +-struct data data_append_re(struct data d, const struct fdt_reserve_entry *re); ++struct data data_append_re(struct data d, uint64_t address, uint64_t size); + struct data data_append_addr(struct data d, uint64_t addr); + struct data data_append_byte(struct data d, uint8_t byte); + struct data data_append_zeroes(struct data d, int len); +@@ -136,6 +135,10 @@ struct label { + struct label *next; + }; + ++struct bus_type { ++ const char *name; ++}; ++ + struct property { + bool deleted; + char *name; +@@ -162,6 +165,7 @@ struct node { + int addr_cells, size_cells; + + struct label *labels; ++ const struct bus_type *bus; + }; + + #define for_each_label_withdel(l0, l) \ +@@ -227,7 +231,7 @@ uint32_t guess_boot_cpuid(struct node *tree); + /* Boot info (tree plus memreserve information */ + + struct reserve_info { +- struct fdt_reserve_entry re; ++ uint64_t address, size; + + struct reserve_info *next; + +@@ -246,6 +250,7 @@ struct dt_info { + struct reserve_info *reservelist; + uint32_t boot_cpuid_phys; + struct node *dt; /* the device tree */ ++ const char *outname; /* filename being written to, "-" for stdout */ + }; + + /* DTS version flags definitions */ +diff --git a/scripts/dtc/flattree.c b/scripts/dtc/flattree.c +index ebac548b..fcf71541 100644 +--- a/scripts/dtc/flattree.c ++++ b/scripts/dtc/flattree.c +@@ -49,7 +49,7 @@ static struct version_info { + + struct emitter { + void (*cell)(void *, cell_t); +- void (*string)(void *, char *, int); ++ void (*string)(void *, const char *, int); + void (*align)(void *, int); + void (*data)(void *, struct data); + void (*beginnode)(void *, struct label *labels); +@@ -64,7 +64,7 @@ static void bin_emit_cell(void *e, cell_t val) + *dtbuf = data_append_cell(*dtbuf, val); + } + +-static void bin_emit_string(void *e, char *str, int len) ++static void bin_emit_string(void *e, const char *str, int len) + { + struct data *dtbuf = e; + +@@ -144,22 +144,14 @@ static void asm_emit_cell(void *e, cell_t val) + (val >> 8) & 0xff, val & 0xff); + } + +-static void asm_emit_string(void *e, char *str, int len) ++static void asm_emit_string(void *e, const char *str, int len) + { + FILE *f = e; +- char c = 0; + +- if (len != 0) { +- /* XXX: ewww */ +- c = str[len]; +- str[len] = '\0'; +- } +- +- fprintf(f, "\t.string\t\"%s\"\n", str); +- +- if (len != 0) { +- str[len] = c; +- } ++ if (len != 0) ++ fprintf(f, "\t.string\t\"%.*s\"\n", len, str); ++ else ++ fprintf(f, "\t.string\t\"%s\"\n", str); + } + + static void asm_emit_align(void *e, int a) +@@ -179,7 +171,7 @@ static void asm_emit_data(void *e, struct data d) + emit_offset_label(f, m->ref, m->offset); + + while ((d.len - off) >= sizeof(uint32_t)) { +- asm_emit_cell(e, fdt32_to_cpu(*((uint32_t *)(d.val+off)))); ++ asm_emit_cell(e, fdt32_to_cpu(*((fdt32_t *)(d.val+off)))); + off += sizeof(uint32_t); + } + +@@ -318,17 +310,16 @@ static struct data flatten_reserve_list(struct reserve_info *reservelist, + { + struct reserve_info *re; + struct data d = empty_data; +- static struct fdt_reserve_entry null_re = {0,0}; + int j; + + for (re = reservelist; re; re = re->next) { +- d = data_append_re(d, &re->re); ++ d = data_append_re(d, re->address, re->size); + } + /* + * Add additional reserved slots if the user asked for them. + */ + for (j = 0; j < reservenum; j++) { +- d = data_append_re(d, &null_re); ++ d = data_append_re(d, 0, 0); + } + + return d; +@@ -544,11 +535,11 @@ void dt_to_asm(FILE *f, struct dt_info *dti, int version) + fprintf(f, "\t.globl\t%s\n", l->label); + fprintf(f, "%s:\n", l->label); + } +- ASM_EMIT_BELONG(f, "0x%08x", (unsigned int)(re->re.address >> 32)); ++ ASM_EMIT_BELONG(f, "0x%08x", (unsigned int)(re->address >> 32)); + ASM_EMIT_BELONG(f, "0x%08x", +- (unsigned int)(re->re.address & 0xffffffff)); +- ASM_EMIT_BELONG(f, "0x%08x", (unsigned int)(re->re.size >> 32)); +- ASM_EMIT_BELONG(f, "0x%08x", (unsigned int)(re->re.size & 0xffffffff)); ++ (unsigned int)(re->address & 0xffffffff)); ++ ASM_EMIT_BELONG(f, "0x%08x", (unsigned int)(re->size >> 32)); ++ ASM_EMIT_BELONG(f, "0x%08x", (unsigned int)(re->size & 0xffffffff)); + } + for (i = 0; i < reservenum; i++) { + fprintf(f, "\t.long\t0, 0\n\t.long\t0, 0\n"); +@@ -609,7 +600,7 @@ static void flat_read_chunk(struct inbuf *inb, void *p, int len) + + static uint32_t flat_read_word(struct inbuf *inb) + { +- uint32_t val; ++ fdt32_t val; + + assert(((inb->ptr - inb->base) % sizeof(val)) == 0); + +@@ -718,13 +709,15 @@ static struct reserve_info *flat_read_mem_reserve(struct inbuf *inb) + * First pass, count entries. + */ + while (1) { ++ uint64_t address, size; ++ + flat_read_chunk(inb, &re, sizeof(re)); +- re.address = fdt64_to_cpu(re.address); +- re.size = fdt64_to_cpu(re.size); +- if (re.size == 0) ++ address = fdt64_to_cpu(re.address); ++ size = fdt64_to_cpu(re.size); ++ if (size == 0) + break; + +- new = build_reserve_entry(re.address, re.size); ++ new = build_reserve_entry(address, size); + reservelist = add_reserve_entry(reservelist, new); + } + +@@ -817,6 +810,7 @@ static struct node *unflatten_tree(struct inbuf *dtbuf, + struct dt_info *dt_from_blob(const char *fname) + { + FILE *f; ++ fdt32_t magic_buf, totalsize_buf; + uint32_t magic, totalsize, version, size_dt, boot_cpuid_phys; + uint32_t off_dt, off_str, off_mem_rsvmap; + int rc; +@@ -833,7 +827,7 @@ struct dt_info *dt_from_blob(const char *fname) + + f = srcfile_relative_open(fname, NULL); + +- rc = fread(&magic, sizeof(magic), 1, f); ++ rc = fread(&magic_buf, sizeof(magic_buf), 1, f); + if (ferror(f)) + die("Error reading DT blob magic number: %s\n", + strerror(errno)); +@@ -844,11 +838,11 @@ struct dt_info *dt_from_blob(const char *fname) + die("Mysterious short read reading magic number\n"); + } + +- magic = fdt32_to_cpu(magic); ++ magic = fdt32_to_cpu(magic_buf); + if (magic != FDT_MAGIC) + die("Blob has incorrect magic number\n"); + +- rc = fread(&totalsize, sizeof(totalsize), 1, f); ++ rc = fread(&totalsize_buf, sizeof(totalsize_buf), 1, f); + if (ferror(f)) + die("Error reading DT blob size: %s\n", strerror(errno)); + if (rc < 1) { +@@ -858,7 +852,7 @@ struct dt_info *dt_from_blob(const char *fname) + die("Mysterious short read reading blob size\n"); + } + +- totalsize = fdt32_to_cpu(totalsize); ++ totalsize = fdt32_to_cpu(totalsize_buf); + if (totalsize < FDT_V1_SIZE) + die("DT blob size (%d) is too small\n", totalsize); + +diff --git a/scripts/dtc/libfdt/fdt_addresses.c b/scripts/dtc/libfdt/fdt_addresses.c +new file mode 100644 +index 00000000..eff4dbcc +--- /dev/null ++++ b/scripts/dtc/libfdt/fdt_addresses.c +@@ -0,0 +1,96 @@ ++/* ++ * libfdt - Flat Device Tree manipulation ++ * Copyright (C) 2014 David Gibson <david@gibson.dropbear.id.au> ++ * ++ * libfdt is dual licensed: you can use it either under the terms of ++ * the GPL, or the BSD license, at your option. ++ * ++ * a) This library is free software; you can redistribute it and/or ++ * modify it under the terms of the GNU General Public License as ++ * published by the Free Software Foundation; either version 2 of the ++ * License, or (at your option) any later version. ++ * ++ * This library is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ * GNU General Public License for more details. ++ * ++ * You should have received a copy of the GNU General Public ++ * License along with this library; if not, write to the Free ++ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, ++ * MA 02110-1301 USA ++ * ++ * Alternatively, ++ * ++ * b) Redistribution and use in source and binary forms, with or ++ * without modification, are permitted provided that the following ++ * conditions are met: ++ * ++ * 1. Redistributions of source code must retain the above ++ * copyright notice, this list of conditions and the following ++ * disclaimer. ++ * 2. Redistributions in binary form must reproduce the above ++ * copyright notice, this list of conditions and the following ++ * disclaimer in the documentation and/or other materials ++ * provided with the distribution. ++ * ++ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND ++ * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, ++ * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF ++ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE ++ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR ++ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, ++ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT ++ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; ++ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) ++ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN ++ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR ++ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, ++ * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ++ */ ++#include "libfdt_env.h" ++ ++#include <fdt.h> ++#include <libfdt.h> ++ ++#include "libfdt_internal.h" ++ ++int fdt_address_cells(const void *fdt, int nodeoffset) ++{ ++ const fdt32_t *ac; ++ int val; ++ int len; ++ ++ ac = fdt_getprop(fdt, nodeoffset, "#address-cells", &len); ++ if (!ac) ++ return 2; ++ ++ if (len != sizeof(*ac)) ++ return -FDT_ERR_BADNCELLS; ++ ++ val = fdt32_to_cpu(*ac); ++ if ((val <= 0) || (val > FDT_MAX_NCELLS)) ++ return -FDT_ERR_BADNCELLS; ++ ++ return val; ++} ++ ++int fdt_size_cells(const void *fdt, int nodeoffset) ++{ ++ const fdt32_t *sc; ++ int val; ++ int len; ++ ++ sc = fdt_getprop(fdt, nodeoffset, "#size-cells", &len); ++ if (!sc) ++ return 2; ++ ++ if (len != sizeof(*sc)) ++ return -FDT_ERR_BADNCELLS; ++ ++ val = fdt32_to_cpu(*sc); ++ if ((val < 0) || (val > FDT_MAX_NCELLS)) ++ return -FDT_ERR_BADNCELLS; ++ ++ return val; ++} +diff --git a/scripts/dtc/libfdt/fdt_empty_tree.c b/scripts/dtc/libfdt/fdt_empty_tree.c +index f72d13b1..f2ae9b77 100644 +--- a/scripts/dtc/libfdt/fdt_empty_tree.c ++++ b/scripts/dtc/libfdt/fdt_empty_tree.c +@@ -81,4 +81,3 @@ int fdt_create_empty_tree(void *buf, int bufsize) + + return fdt_open_into(buf, buf, bufsize); + } +- +diff --git a/scripts/dtc/libfdt/fdt_overlay.c b/scripts/dtc/libfdt/fdt_overlay.c +new file mode 100644 +index 00000000..ceb96878 +--- /dev/null ++++ b/scripts/dtc/libfdt/fdt_overlay.c +@@ -0,0 +1,677 @@ ++#include "libfdt_env.h" ++ ++#include <fdt.h> ++#include <libfdt.h> ++ ++#include "libfdt_internal.h" ++ ++/** ++ * overlay_get_target_phandle - retrieves the target phandle of a fragment ++ * @fdto: pointer to the device tree overlay blob ++ * @fragment: node offset of the fragment in the overlay ++ * ++ * overlay_get_target_phandle() retrieves the target phandle of an ++ * overlay fragment when that fragment uses a phandle (target ++ * property) instead of a path (target-path property). ++ * ++ * returns: ++ * the phandle pointed by the target property ++ * 0, if the phandle was not found ++ * -1, if the phandle was malformed ++ */ ++static uint32_t overlay_get_target_phandle(const void *fdto, int fragment) ++{ ++ const fdt32_t *val; ++ int len; ++ ++ val = fdt_getprop(fdto, fragment, "target", &len); ++ if (!val) ++ return 0; ++ ++ if ((len != sizeof(*val)) || (fdt32_to_cpu(*val) == (uint32_t)-1)) ++ return (uint32_t)-1; ++ ++ return fdt32_to_cpu(*val); ++} ++ ++/** ++ * overlay_get_target - retrieves the offset of a fragment's target ++ * @fdt: Base device tree blob ++ * @fdto: Device tree overlay blob ++ * @fragment: node offset of the fragment in the overlay ++ * ++ * overlay_get_target() retrieves the target offset in the base ++ * device tree of a fragment, no matter how the actual targetting is ++ * done (through a phandle or a path) ++ * ++ * returns: ++ * the targetted node offset in the base device tree ++ * Negative error code on error ++ */ ++static int overlay_get_target(const void *fdt, const void *fdto, ++ int fragment) ++{ ++ uint32_t phandle; ++ const char *path; ++ int path_len; ++ ++ /* Try first to do a phandle based lookup */ ++ phandle = overlay_get_target_phandle(fdto, fragment); ++ if (phandle == (uint32_t)-1) ++ return -FDT_ERR_BADPHANDLE; ++ ++ if (phandle) ++ return fdt_node_offset_by_phandle(fdt, phandle); ++ ++ /* And then a path based lookup */ ++ path = fdt_getprop(fdto, fragment, "target-path", &path_len); ++ if (!path) { ++ /* ++ * If we haven't found either a target or a ++ * target-path property in a node that contains a ++ * __overlay__ subnode (we wouldn't be called ++ * otherwise), consider it a improperly written ++ * overlay ++ */ ++ if (path_len == -FDT_ERR_NOTFOUND) ++ return -FDT_ERR_BADOVERLAY; ++ ++ return path_len; ++ } ++ ++ return fdt_path_offset(fdt, path); ++} ++ ++/** ++ * overlay_phandle_add_offset - Increases a phandle by an offset ++ * @fdt: Base device tree blob ++ * @node: Device tree overlay blob ++ * @name: Name of the property to modify (phandle or linux,phandle) ++ * @delta: offset to apply ++ * ++ * overlay_phandle_add_offset() increments a node phandle by a given ++ * offset. ++ * ++ * returns: ++ * 0 on success. ++ * Negative error code on error ++ */ ++static int overlay_phandle_add_offset(void *fdt, int node, ++ const char *name, uint32_t delta) ++{ ++ const fdt32_t *val; ++ uint32_t adj_val; ++ int len; ++ ++ val = fdt_getprop(fdt, node, name, &len); ++ if (!val) ++ return len; ++ ++ if (len != sizeof(*val)) ++ return -FDT_ERR_BADPHANDLE; ++ ++ adj_val = fdt32_to_cpu(*val); ++ if ((adj_val + delta) < adj_val) ++ return -FDT_ERR_NOPHANDLES; ++ ++ adj_val += delta; ++ if (adj_val == (uint32_t)-1) ++ return -FDT_ERR_NOPHANDLES; ++ ++ return fdt_setprop_inplace_u32(fdt, node, name, adj_val); ++} ++ ++/** ++ * overlay_adjust_node_phandles - Offsets the phandles of a node ++ * @fdto: Device tree overlay blob ++ * @node: Offset of the node we want to adjust ++ * @delta: Offset to shift the phandles of ++ * ++ * overlay_adjust_node_phandles() adds a constant to all the phandles ++ * of a given node. This is mainly use as part of the overlay ++ * application process, when we want to update all the overlay ++ * phandles to not conflict with the overlays of the base device tree. ++ * ++ * returns: ++ * 0 on success ++ * Negative error code on failure ++ */ ++static int overlay_adjust_node_phandles(void *fdto, int node, ++ uint32_t delta) ++{ ++ int child; ++ int ret; ++ ++ ret = overlay_phandle_add_offset(fdto, node, "phandle", delta); ++ if (ret && ret != -FDT_ERR_NOTFOUND) ++ return ret; ++ ++ ret = overlay_phandle_add_offset(fdto, node, "linux,phandle", delta); ++ if (ret && ret != -FDT_ERR_NOTFOUND) ++ return ret; ++ ++ fdt_for_each_subnode(child, fdto, node) { ++ ret = overlay_adjust_node_phandles(fdto, child, delta); ++ if (ret) ++ return ret; ++ } ++ ++ return 0; ++} ++ ++/** ++ * overlay_adjust_local_phandles - Adjust the phandles of a whole overlay ++ * @fdto: Device tree overlay blob ++ * @delta: Offset to shift the phandles of ++ * ++ * overlay_adjust_local_phandles() adds a constant to all the ++ * phandles of an overlay. This is mainly use as part of the overlay ++ * application process, when we want to update all the overlay ++ * phandles to not conflict with the overlays of the base device tree. ++ * ++ * returns: ++ * 0 on success ++ * Negative error code on failure ++ */ ++static int overlay_adjust_local_phandles(void *fdto, uint32_t delta) ++{ ++ /* ++ * Start adjusting the phandles from the overlay root ++ */ ++ return overlay_adjust_node_phandles(fdto, 0, delta); ++} ++ ++/** ++ * overlay_update_local_node_references - Adjust the overlay references ++ * @fdto: Device tree overlay blob ++ * @tree_node: Node offset of the node to operate on ++ * @fixup_node: Node offset of the matching local fixups node ++ * @delta: Offset to shift the phandles of ++ * ++ * overlay_update_local_nodes_references() update the phandles ++ * pointing to a node within the device tree overlay by adding a ++ * constant delta. ++ * ++ * This is mainly used as part of a device tree application process, ++ * where you want the device tree overlays phandles to not conflict ++ * with the ones from the base device tree before merging them. ++ * ++ * returns: ++ * 0 on success ++ * Negative error code on failure ++ */ ++static int overlay_update_local_node_references(void *fdto, ++ int tree_node, ++ int fixup_node, ++ uint32_t delta) ++{ ++ int fixup_prop; ++ int fixup_child; ++ int ret; ++ ++ fdt_for_each_property_offset(fixup_prop, fdto, fixup_node) { ++ const fdt32_t *fixup_val; ++ const char *tree_val; ++ const char *name; ++ int fixup_len; ++ int tree_len; ++ int i; ++ ++ fixup_val = fdt_getprop_by_offset(fdto, fixup_prop, ++ &name, &fixup_len); ++ if (!fixup_val) ++ return fixup_len; ++ ++ if (fixup_len % sizeof(uint32_t)) ++ return -FDT_ERR_BADOVERLAY; ++ ++ tree_val = fdt_getprop(fdto, tree_node, name, &tree_len); ++ if (!tree_val) { ++ if (tree_len == -FDT_ERR_NOTFOUND) ++ return -FDT_ERR_BADOVERLAY; ++ ++ return tree_len; ++ } ++ ++ for (i = 0; i < (fixup_len / sizeof(uint32_t)); i++) { ++ fdt32_t adj_val; ++ uint32_t poffset; ++ ++ poffset = fdt32_to_cpu(fixup_val[i]); ++ ++ /* ++ * phandles to fixup can be unaligned. ++ * ++ * Use a memcpy for the architectures that do ++ * not support unaligned accesses. ++ */ ++ memcpy(&adj_val, tree_val + poffset, sizeof(adj_val)); ++ ++ adj_val = cpu_to_fdt32(fdt32_to_cpu(adj_val) + delta); ++ ++ ret = fdt_setprop_inplace_namelen_partial(fdto, ++ tree_node, ++ name, ++ strlen(name), ++ poffset, ++ &adj_val, ++ sizeof(adj_val)); ++ if (ret == -FDT_ERR_NOSPACE) ++ return -FDT_ERR_BADOVERLAY; ++ ++ if (ret) ++ return ret; ++ } ++ } ++ ++ fdt_for_each_subnode(fixup_child, fdto, fixup_node) { ++ const char *fixup_child_name = fdt_get_name(fdto, fixup_child, ++ NULL); ++ int tree_child; ++ ++ tree_child = fdt_subnode_offset(fdto, tree_node, ++ fixup_child_name); ++ if (tree_child == -FDT_ERR_NOTFOUND) ++ return -FDT_ERR_BADOVERLAY; ++ if (tree_child < 0) ++ return tree_child; ++ ++ ret = overlay_update_local_node_references(fdto, ++ tree_child, ++ fixup_child, ++ delta); ++ if (ret) ++ return ret; ++ } ++ ++ return 0; ++} ++ ++/** ++ * overlay_update_local_references - Adjust the overlay references ++ * @fdto: Device tree overlay blob ++ * @delta: Offset to shift the phandles of ++ * ++ * overlay_update_local_references() update all the phandles pointing ++ * to a node within the device tree overlay by adding a constant ++ * delta to not conflict with the base overlay. ++ * ++ * This is mainly used as part of a device tree application process, ++ * where you want the device tree overlays phandles to not conflict ++ * with the ones from the base device tree before merging them. ++ * ++ * returns: ++ * 0 on success ++ * Negative error code on failure ++ */ ++static int overlay_update_local_references(void *fdto, uint32_t delta) ++{ ++ int fixups; ++ ++ fixups = fdt_path_offset(fdto, "/__local_fixups__"); ++ if (fixups < 0) { ++ /* There's no local phandles to adjust, bail out */ ++ if (fixups == -FDT_ERR_NOTFOUND) ++ return 0; ++ ++ return fixups; ++ } ++ ++ /* ++ * Update our local references from the root of the tree ++ */ ++ return overlay_update_local_node_references(fdto, 0, fixups, ++ delta); ++} ++ ++/** ++ * overlay_fixup_one_phandle - Set an overlay phandle to the base one ++ * @fdt: Base Device Tree blob ++ * @fdto: Device tree overlay blob ++ * @symbols_off: Node offset of the symbols node in the base device tree ++ * @path: Path to a node holding a phandle in the overlay ++ * @path_len: number of path characters to consider ++ * @name: Name of the property holding the phandle reference in the overlay ++ * @name_len: number of name characters to consider ++ * @poffset: Offset within the overlay property where the phandle is stored ++ * @label: Label of the node referenced by the phandle ++ * ++ * overlay_fixup_one_phandle() resolves an overlay phandle pointing to ++ * a node in the base device tree. ++ * ++ * This is part of the device tree overlay application process, when ++ * you want all the phandles in the overlay to point to the actual ++ * base dt nodes. ++ * ++ * returns: ++ * 0 on success ++ * Negative error code on failure ++ */ ++static int overlay_fixup_one_phandle(void *fdt, void *fdto, ++ int symbols_off, ++ const char *path, uint32_t path_len, ++ const char *name, uint32_t name_len, ++ int poffset, const char *label) ++{ ++ const char *symbol_path; ++ uint32_t phandle; ++ fdt32_t phandle_prop; ++ int symbol_off, fixup_off; ++ int prop_len; ++ ++ if (symbols_off < 0) ++ return symbols_off; ++ ++ symbol_path = fdt_getprop(fdt, symbols_off, label, ++ &prop_len); ++ if (!symbol_path) ++ return prop_len; ++ ++ symbol_off = fdt_path_offset(fdt, symbol_path); ++ if (symbol_off < 0) ++ return symbol_off; ++ ++ phandle = fdt_get_phandle(fdt, symbol_off); ++ if (!phandle) ++ return -FDT_ERR_NOTFOUND; ++ ++ fixup_off = fdt_path_offset_namelen(fdto, path, path_len); ++ if (fixup_off == -FDT_ERR_NOTFOUND) ++ return -FDT_ERR_BADOVERLAY; ++ if (fixup_off < 0) ++ return fixup_off; ++ ++ phandle_prop = cpu_to_fdt32(phandle); ++ return fdt_setprop_inplace_namelen_partial(fdto, fixup_off, ++ name, name_len, poffset, ++ &phandle_prop, ++ sizeof(phandle_prop)); ++}; ++ ++/** ++ * overlay_fixup_phandle - Set an overlay phandle to the base one ++ * @fdt: Base Device Tree blob ++ * @fdto: Device tree overlay blob ++ * @symbols_off: Node offset of the symbols node in the base device tree ++ * @property: Property offset in the overlay holding the list of fixups ++ * ++ * overlay_fixup_phandle() resolves all the overlay phandles pointed ++ * to in a __fixups__ property, and updates them to match the phandles ++ * in use in the base device tree. ++ * ++ * This is part of the device tree overlay application process, when ++ * you want all the phandles in the overlay to point to the actual ++ * base dt nodes. ++ * ++ * returns: ++ * 0 on success ++ * Negative error code on failure ++ */ ++static int overlay_fixup_phandle(void *fdt, void *fdto, int symbols_off, ++ int property) ++{ ++ const char *value; ++ const char *label; ++ int len; ++ ++ value = fdt_getprop_by_offset(fdto, property, ++ &label, &len); ++ if (!value) { ++ if (len == -FDT_ERR_NOTFOUND) ++ return -FDT_ERR_INTERNAL; ++ ++ return len; ++ } ++ ++ do { ++ const char *path, *name, *fixup_end; ++ const char *fixup_str = value; ++ uint32_t path_len, name_len; ++ uint32_t fixup_len; ++ char *sep, *endptr; ++ int poffset, ret; ++ ++ fixup_end = memchr(value, '\0', len); ++ if (!fixup_end) ++ return -FDT_ERR_BADOVERLAY; ++ fixup_len = fixup_end - fixup_str; ++ ++ len -= fixup_len + 1; ++ value += fixup_len + 1; ++ ++ path = fixup_str; ++ sep = memchr(fixup_str, ':', fixup_len); ++ if (!sep || *sep != ':') ++ return -FDT_ERR_BADOVERLAY; ++ ++ path_len = sep - path; ++ if (path_len == (fixup_len - 1)) ++ return -FDT_ERR_BADOVERLAY; ++ ++ fixup_len -= path_len + 1; ++ name = sep + 1; ++ sep = memchr(name, ':', fixup_len); ++ if (!sep || *sep != ':') ++ return -FDT_ERR_BADOVERLAY; ++ ++ name_len = sep - name; ++ if (!name_len) ++ return -FDT_ERR_BADOVERLAY; ++ ++ poffset = strtoul(sep + 1, &endptr, 10); ++ if ((*endptr != '\0') || (endptr <= (sep + 1))) ++ return -FDT_ERR_BADOVERLAY; ++ ++ ret = overlay_fixup_one_phandle(fdt, fdto, symbols_off, ++ path, path_len, name, name_len, ++ poffset, label); ++ if (ret) ++ return ret; ++ } while (len > 0); ++ ++ return 0; ++} ++ ++/** ++ * overlay_fixup_phandles - Resolve the overlay phandles to the base ++ * device tree ++ * @fdt: Base Device Tree blob ++ * @fdto: Device tree overlay blob ++ * ++ * overlay_fixup_phandles() resolves all the overlay phandles pointing ++ * to nodes in the base device tree. ++ * ++ * This is one of the steps of the device tree overlay application ++ * process, when you want all the phandles in the overlay to point to ++ * the actual base dt nodes. ++ * ++ * returns: ++ * 0 on success ++ * Negative error code on failure ++ */ ++static int overlay_fixup_phandles(void *fdt, void *fdto) ++{ ++ int fixups_off, symbols_off; ++ int property; ++ ++ /* We can have overlays without any fixups */ ++ fixups_off = fdt_path_offset(fdto, "/__fixups__"); ++ if (fixups_off == -FDT_ERR_NOTFOUND) ++ return 0; /* nothing to do */ ++ if (fixups_off < 0) ++ return fixups_off; ++ ++ /* And base DTs without symbols */ ++ symbols_off = fdt_path_offset(fdt, "/__symbols__"); ++ if ((symbols_off < 0 && (symbols_off != -FDT_ERR_NOTFOUND))) ++ return symbols_off; ++ ++ fdt_for_each_property_offset(property, fdto, fixups_off) { ++ int ret; ++ ++ ret = overlay_fixup_phandle(fdt, fdto, symbols_off, property); ++ if (ret) ++ return ret; ++ } ++ ++ return 0; ++} ++ ++/** ++ * overlay_apply_node - Merges a node into the base device tree ++ * @fdt: Base Device Tree blob ++ * @target: Node offset in the base device tree to apply the fragment to ++ * @fdto: Device tree overlay blob ++ * @node: Node offset in the overlay holding the changes to merge ++ * ++ * overlay_apply_node() merges a node into a target base device tree ++ * node pointed. ++ * ++ * This is part of the final step in the device tree overlay ++ * application process, when all the phandles have been adjusted and ++ * resolved and you just have to merge overlay into the base device ++ * tree. ++ * ++ * returns: ++ * 0 on success ++ * Negative error code on failure ++ */ ++static int overlay_apply_node(void *fdt, int target, ++ void *fdto, int node) ++{ ++ int property; ++ int subnode; ++ ++ fdt_for_each_property_offset(property, fdto, node) { ++ const char *name; ++ const void *prop; ++ int prop_len; ++ int ret; ++ ++ prop = fdt_getprop_by_offset(fdto, property, &name, ++ &prop_len); ++ if (prop_len == -FDT_ERR_NOTFOUND) ++ return -FDT_ERR_INTERNAL; ++ if (prop_len < 0) ++ return prop_len; ++ ++ ret = fdt_setprop(fdt, target, name, prop, prop_len); ++ if (ret) ++ return ret; ++ } ++ ++ fdt_for_each_subnode(subnode, fdto, node) { ++ const char *name = fdt_get_name(fdto, subnode, NULL); ++ int nnode; ++ int ret; ++ ++ nnode = fdt_add_subnode(fdt, target, name); ++ if (nnode == -FDT_ERR_EXISTS) { ++ nnode = fdt_subnode_offset(fdt, target, name); ++ if (nnode == -FDT_ERR_NOTFOUND) ++ return -FDT_ERR_INTERNAL; ++ } ++ ++ if (nnode < 0) ++ return nnode; ++ ++ ret = overlay_apply_node(fdt, nnode, fdto, subnode); ++ if (ret) ++ return ret; ++ } ++ ++ return 0; ++} ++ ++/** ++ * overlay_merge - Merge an overlay into its base device tree ++ * @fdt: Base Device Tree blob ++ * @fdto: Device tree overlay blob ++ * ++ * overlay_merge() merges an overlay into its base device tree. ++ * ++ * This is the final step in the device tree overlay application ++ * process, when all the phandles have been adjusted and resolved and ++ * you just have to merge overlay into the base device tree. ++ * ++ * returns: ++ * 0 on success ++ * Negative error code on failure ++ */ ++static int overlay_merge(void *fdt, void *fdto) ++{ ++ int fragment; ++ ++ fdt_for_each_subnode(fragment, fdto, 0) { ++ int overlay; ++ int target; ++ int ret; ++ ++ /* ++ * Each fragments will have an __overlay__ node. If ++ * they don't, it's not supposed to be merged ++ */ ++ overlay = fdt_subnode_offset(fdto, fragment, "__overlay__"); ++ if (overlay == -FDT_ERR_NOTFOUND) ++ continue; ++ ++ if (overlay < 0) ++ return overlay; ++ ++ target = overlay_get_target(fdt, fdto, fragment); ++ if (target < 0) ++ return target; ++ ++ ret = overlay_apply_node(fdt, target, fdto, overlay); ++ if (ret) ++ return ret; ++ } ++ ++ return 0; ++} ++ ++int fdt_overlay_apply(void *fdt, void *fdto) ++{ ++ uint32_t delta = fdt_get_max_phandle(fdt); ++ int ret; ++ ++ FDT_CHECK_HEADER(fdt); ++ FDT_CHECK_HEADER(fdto); ++ ++ ret = overlay_adjust_local_phandles(fdto, delta); ++ if (ret) ++ goto err; ++ ++ ret = overlay_update_local_references(fdto, delta); ++ if (ret) ++ goto err; ++ ++ ret = overlay_fixup_phandles(fdt, fdto); ++ if (ret) ++ goto err; ++ ++ ret = overlay_merge(fdt, fdto); ++ if (ret) ++ goto err; ++ ++ /* ++ * The overlay has been damaged, erase its magic. ++ */ ++ fdt_set_magic(fdto, ~0); ++ ++ return 0; ++ ++err: ++ /* ++ * The overlay might have been damaged, erase its magic. ++ */ ++ fdt_set_magic(fdto, ~0); ++ ++ /* ++ * The base device tree might have been damaged, erase its ++ * magic. ++ */ ++ fdt_set_magic(fdt, ~0); ++ ++ return ret; ++} +diff --git a/scripts/dtc/libfdt/fdt_ro.c b/scripts/dtc/libfdt/fdt_ro.c +index 3d00d2ee..08de2cce 100644 +--- a/scripts/dtc/libfdt/fdt_ro.c ++++ b/scripts/dtc/libfdt/fdt_ro.c +@@ -60,7 +60,7 @@ static int _fdt_nodename_eq(const void *fdt, int offset, + { + const char *p = fdt_offset_ptr(fdt, offset + FDT_TAGSIZE, len+1); + +- if (! p) ++ if (!p) + /* short match */ + return 0; + +@@ -327,7 +327,7 @@ const void *fdt_getprop_namelen(const void *fdt, int nodeoffset, + const struct fdt_property *prop; + + prop = fdt_get_property_namelen(fdt, nodeoffset, name, namelen, lenp); +- if (! prop) ++ if (!prop) + return NULL; + + return prop->data; +diff --git a/scripts/dtc/libfdt/fdt_rw.c b/scripts/dtc/libfdt/fdt_rw.c +index 2eed4f58..8b487f6c 100644 +--- a/scripts/dtc/libfdt/fdt_rw.c ++++ b/scripts/dtc/libfdt/fdt_rw.c +@@ -207,7 +207,7 @@ static int _fdt_resize_property(void *fdt, int nodeoffset, const char *name, + int err; + + *prop = fdt_get_property_w(fdt, nodeoffset, name, &oldlen); +- if (! (*prop)) ++ if (!*prop) + return oldlen; + + if ((err = _fdt_splice_struct(fdt, (*prop)->data, FDT_TAGALIGN(oldlen), +@@ -283,7 +283,8 @@ int fdt_setprop(void *fdt, int nodeoffset, const char *name, + if (err) + return err; + +- memcpy(prop->data, val, len); ++ if (len) ++ memcpy(prop->data, val, len); + return 0; + } + +@@ -322,7 +323,7 @@ int fdt_delprop(void *fdt, int nodeoffset, const char *name) + FDT_RW_CHECK_HEADER(fdt); + + prop = fdt_get_property_w(fdt, nodeoffset, name, &len); +- if (! prop) ++ if (!prop) + return len; + + proplen = sizeof(*prop) + FDT_TAGALIGN(len); +diff --git a/scripts/dtc/libfdt/fdt_sw.c b/scripts/dtc/libfdt/fdt_sw.c +index 6a804859..2bd15e7a 100644 +--- a/scripts/dtc/libfdt/fdt_sw.c ++++ b/scripts/dtc/libfdt/fdt_sw.c +@@ -220,7 +220,7 @@ static int _fdt_find_add_string(void *fdt, const char *s) + return offset; + } + +-int fdt_property(void *fdt, const char *name, const void *val, int len) ++int fdt_property_placeholder(void *fdt, const char *name, int len, void **valp) + { + struct fdt_property *prop; + int nameoff; +@@ -238,7 +238,19 @@ int fdt_property(void *fdt, const char *name, const void *val, int len) + prop->tag = cpu_to_fdt32(FDT_PROP); + prop->nameoff = cpu_to_fdt32(nameoff); + prop->len = cpu_to_fdt32(len); +- memcpy(prop->data, val, len); ++ *valp = prop->data; ++ return 0; ++} ++ ++int fdt_property(void *fdt, const char *name, const void *val, int len) ++{ ++ void *ptr; ++ int ret; ++ ++ ret = fdt_property_placeholder(fdt, name, len, &ptr); ++ if (ret) ++ return ret; ++ memcpy(ptr, val, len); + return 0; + } + +diff --git a/scripts/dtc/libfdt/fdt_wip.c b/scripts/dtc/libfdt/fdt_wip.c +index 6aaab399..5e859198 100644 +--- a/scripts/dtc/libfdt/fdt_wip.c ++++ b/scripts/dtc/libfdt/fdt_wip.c +@@ -82,7 +82,7 @@ int fdt_setprop_inplace(void *fdt, int nodeoffset, const char *name, + int proplen; + + propval = fdt_getprop(fdt, nodeoffset, name, &proplen); +- if (! propval) ++ if (!propval) + return proplen; + + if (proplen != len) +@@ -107,7 +107,7 @@ int fdt_nop_property(void *fdt, int nodeoffset, const char *name) + int len; + + prop = fdt_get_property_w(fdt, nodeoffset, name, &len); +- if (! prop) ++ if (!prop) + return len; + + _fdt_nop_region(prop, len + sizeof(*prop)); +diff --git a/scripts/dtc/libfdt/libfdt.h b/scripts/dtc/libfdt/libfdt.h +index b842b156..707b5069 100644 +--- a/scripts/dtc/libfdt/libfdt.h ++++ b/scripts/dtc/libfdt/libfdt.h +@@ -143,7 +143,9 @@ + /* Low-level functions (you probably don't need these) */ + /**********************************************************************/ + ++#ifndef SWIG /* This function is not useful in Python */ + const void *fdt_offset_ptr(const void *fdt, int offset, unsigned int checklen); ++#endif + static inline void *fdt_offset_ptr_w(void *fdt, int offset, int checklen) + { + return (void *)(uintptr_t)fdt_offset_ptr(fdt, offset, checklen); +@@ -210,7 +212,6 @@ int fdt_next_subnode(const void *fdt, int offset); + /**********************************************************************/ + /* General functions */ + /**********************************************************************/ +- + #define fdt_get_header(fdt, field) \ + (fdt32_to_cpu(((const struct fdt_header *)(fdt))->field)) + #define fdt_magic(fdt) (fdt_get_header(fdt, magic)) +@@ -354,8 +355,10 @@ int fdt_get_mem_rsv(const void *fdt, int n, uint64_t *address, uint64_t *size); + * useful for finding subnodes based on a portion of a larger string, + * such as a full path. + */ ++#ifndef SWIG /* Not available in Python */ + int fdt_subnode_offset_namelen(const void *fdt, int parentoffset, + const char *name, int namelen); ++#endif + /** + * fdt_subnode_offset - find a subnode of a given node + * @fdt: pointer to the device tree blob +@@ -391,7 +394,9 @@ int fdt_subnode_offset(const void *fdt, int parentoffset, const char *name); + * Identical to fdt_path_offset(), but only consider the first namelen + * characters of path as the path name. + */ ++#ifndef SWIG /* Not available in Python */ + int fdt_path_offset_namelen(const void *fdt, const char *path, int namelen); ++#endif + + /** + * fdt_path_offset - find a tree node by its full path +@@ -550,10 +555,12 @@ const struct fdt_property *fdt_get_property_by_offset(const void *fdt, + * Identical to fdt_get_property(), but only examine the first namelen + * characters of name for matching the property name. + */ ++#ifndef SWIG /* Not available in Python */ + const struct fdt_property *fdt_get_property_namelen(const void *fdt, + int nodeoffset, + const char *name, + int namelen, int *lenp); ++#endif + + /** + * fdt_get_property - find a given property in a given node +@@ -624,8 +631,10 @@ static inline struct fdt_property *fdt_get_property_w(void *fdt, int nodeoffset, + * -FDT_ERR_BADSTRUCTURE, + * -FDT_ERR_TRUNCATED, standard meanings + */ ++#ifndef SWIG /* This function is not useful in Python */ + const void *fdt_getprop_by_offset(const void *fdt, int offset, + const char **namep, int *lenp); ++#endif + + /** + * fdt_getprop_namelen - get property value based on substring +@@ -638,6 +647,7 @@ const void *fdt_getprop_by_offset(const void *fdt, int offset, + * Identical to fdt_getprop(), but only examine the first namelen + * characters of name for matching the property name. + */ ++#ifndef SWIG /* Not available in Python */ + const void *fdt_getprop_namelen(const void *fdt, int nodeoffset, + const char *name, int namelen, int *lenp); + static inline void *fdt_getprop_namelen_w(void *fdt, int nodeoffset, +@@ -647,6 +657,7 @@ static inline void *fdt_getprop_namelen_w(void *fdt, int nodeoffset, + return (void *)(uintptr_t)fdt_getprop_namelen(fdt, nodeoffset, name, + namelen, lenp); + } ++#endif + + /** + * fdt_getprop - retrieve the value of a given property +@@ -707,8 +718,10 @@ uint32_t fdt_get_phandle(const void *fdt, int nodeoffset); + * Identical to fdt_get_alias(), but only examine the first namelen + * characters of name for matching the alias name. + */ ++#ifndef SWIG /* Not available in Python */ + const char *fdt_get_alias_namelen(const void *fdt, + const char *name, int namelen); ++#endif + + /** + * fdt_get_alias - retrieve the path referenced by a given alias +@@ -1106,10 +1119,12 @@ int fdt_size_cells(const void *fdt, int nodeoffset); + * of the name. It is useful when you want to manipulate only one value of + * an array and you have a string that doesn't end with \0. + */ ++#ifndef SWIG /* Not available in Python */ + int fdt_setprop_inplace_namelen_partial(void *fdt, int nodeoffset, + const char *name, int namelen, + uint32_t idx, const void *val, + int len); ++#endif + + /** + * fdt_setprop_inplace - change a property's value, but not its size +@@ -1139,8 +1154,10 @@ int fdt_setprop_inplace_namelen_partial(void *fdt, int nodeoffset, + * -FDT_ERR_BADSTRUCTURE, + * -FDT_ERR_TRUNCATED, standard meanings + */ ++#ifndef SWIG /* Not available in Python */ + int fdt_setprop_inplace(void *fdt, int nodeoffset, const char *name, + const void *val, int len); ++#endif + + /** + * fdt_setprop_inplace_u32 - change the value of a 32-bit integer property +@@ -1297,6 +1314,22 @@ static inline int fdt_property_cell(void *fdt, const char *name, uint32_t val) + { + return fdt_property_u32(fdt, name, val); + } ++ ++/** ++ * fdt_property_placeholder - add a new property and return a ptr to its value ++ * ++ * @fdt: pointer to the device tree blob ++ * @name: name of property to add ++ * @len: length of property value in bytes ++ * @valp: returns a pointer to where where the value should be placed ++ * ++ * returns: ++ * 0, on success ++ * -FDT_ERR_BADMAGIC, ++ * -FDT_ERR_NOSPACE, standard meanings ++ */ ++int fdt_property_placeholder(void *fdt, const char *name, int len, void **valp); ++ + #define fdt_property_string(fdt, name, str) \ + fdt_property(fdt, name, str, strlen(str)+1) + int fdt_end_node(void *fdt); +@@ -1527,6 +1560,36 @@ static inline int fdt_setprop_cell(void *fdt, int nodeoffset, const char *name, + #define fdt_setprop_string(fdt, nodeoffset, name, str) \ + fdt_setprop((fdt), (nodeoffset), (name), (str), strlen(str)+1) + ++ ++/** ++ * fdt_setprop_empty - set a property to an empty value ++ * @fdt: pointer to the device tree blob ++ * @nodeoffset: offset of the node whose property to change ++ * @name: name of the property to change ++ * ++ * fdt_setprop_empty() sets the value of the named property in the ++ * given node to an empty (zero length) value, or creates a new empty ++ * property if it does not already exist. ++ * ++ * This function may insert or delete data from the blob, and will ++ * therefore change the offsets of some existing nodes. ++ * ++ * returns: ++ * 0, on success ++ * -FDT_ERR_NOSPACE, there is insufficient free space in the blob to ++ * contain the new property value ++ * -FDT_ERR_BADOFFSET, nodeoffset did not point to FDT_BEGIN_NODE tag ++ * -FDT_ERR_BADLAYOUT, ++ * -FDT_ERR_BADMAGIC, ++ * -FDT_ERR_BADVERSION, ++ * -FDT_ERR_BADSTATE, ++ * -FDT_ERR_BADSTRUCTURE, ++ * -FDT_ERR_BADLAYOUT, ++ * -FDT_ERR_TRUNCATED, standard meanings ++ */ ++#define fdt_setprop_empty(fdt, nodeoffset, name) \ ++ fdt_setprop((fdt), (nodeoffset), (name), NULL, 0) ++ + /** + * fdt_appendprop - append to or create a property + * @fdt: pointer to the device tree blob +@@ -1704,8 +1767,10 @@ int fdt_delprop(void *fdt, int nodeoffset, const char *name); + * creating subnodes based on a portion of a larger string, such as a + * full path. + */ ++#ifndef SWIG /* Not available in Python */ + int fdt_add_subnode_namelen(void *fdt, int parentoffset, + const char *name, int namelen); ++#endif + + /** + * fdt_add_subnode - creates a new node +diff --git a/scripts/dtc/libfdt/libfdt_env.h b/scripts/dtc/libfdt/libfdt_env.h +index 99f936da..952056cd 100644 +--- a/scripts/dtc/libfdt/libfdt_env.h ++++ b/scripts/dtc/libfdt/libfdt_env.h +@@ -58,16 +58,16 @@ + #include <string.h> + + #ifdef __CHECKER__ +-#define __force __attribute__((force)) +-#define __bitwise __attribute__((bitwise)) ++#define FDT_FORCE __attribute__((force)) ++#define FDT_BITWISE __attribute__((bitwise)) + #else +-#define __force +-#define __bitwise ++#define FDT_FORCE ++#define FDT_BITWISE + #endif + +-typedef uint16_t __bitwise fdt16_t; +-typedef uint32_t __bitwise fdt32_t; +-typedef uint64_t __bitwise fdt64_t; ++typedef uint16_t FDT_BITWISE fdt16_t; ++typedef uint32_t FDT_BITWISE fdt32_t; ++typedef uint64_t FDT_BITWISE fdt64_t; + + #define EXTRACT_BYTE(x, n) ((unsigned long long)((uint8_t *)&x)[n]) + #define CPU_TO_FDT16(x) ((EXTRACT_BYTE(x, 0) << 8) | EXTRACT_BYTE(x, 1)) +@@ -80,29 +80,29 @@ typedef uint64_t __bitwise fdt64_t; + + static inline uint16_t fdt16_to_cpu(fdt16_t x) + { +- return (__force uint16_t)CPU_TO_FDT16(x); ++ return (FDT_FORCE uint16_t)CPU_TO_FDT16(x); + } + static inline fdt16_t cpu_to_fdt16(uint16_t x) + { +- return (__force fdt16_t)CPU_TO_FDT16(x); ++ return (FDT_FORCE fdt16_t)CPU_TO_FDT16(x); + } + + static inline uint32_t fdt32_to_cpu(fdt32_t x) + { +- return (__force uint32_t)CPU_TO_FDT32(x); ++ return (FDT_FORCE uint32_t)CPU_TO_FDT32(x); + } + static inline fdt32_t cpu_to_fdt32(uint32_t x) + { +- return (__force fdt32_t)CPU_TO_FDT32(x); ++ return (FDT_FORCE fdt32_t)CPU_TO_FDT32(x); + } + + static inline uint64_t fdt64_to_cpu(fdt64_t x) + { +- return (__force uint64_t)CPU_TO_FDT64(x); ++ return (FDT_FORCE uint64_t)CPU_TO_FDT64(x); + } + static inline fdt64_t cpu_to_fdt64(uint64_t x) + { +- return (__force fdt64_t)CPU_TO_FDT64(x); ++ return (FDT_FORCE fdt64_t)CPU_TO_FDT64(x); + } + #undef CPU_TO_FDT64 + #undef CPU_TO_FDT32 +diff --git a/scripts/dtc/livetree.c b/scripts/dtc/livetree.c +index afa2f67b..aecd2787 100644 +--- a/scripts/dtc/livetree.c ++++ b/scripts/dtc/livetree.c +@@ -242,7 +242,7 @@ void delete_property_by_name(struct node *node, char *name) + struct property *prop = node->proplist; + + while (prop) { +- if (!strcmp(prop->name, name)) { ++ if (streq(prop->name, name)) { + delete_property(prop); + return; + } +@@ -275,7 +275,7 @@ void delete_node_by_name(struct node *parent, char *name) + struct node *node = parent->children; + + while (node) { +- if (!strcmp(node->name, name)) { ++ if (streq(node->name, name)) { + delete_node(node); + return; + } +@@ -319,8 +319,8 @@ struct reserve_info *build_reserve_entry(uint64_t address, uint64_t size) + + memset(new, 0, sizeof(*new)); + +- new->re.address = address; +- new->re.size = size; ++ new->address = address; ++ new->size = size; + + return new; + } +@@ -393,7 +393,7 @@ struct property *get_property(struct node *node, const char *propname) + cell_t propval_cell(struct property *prop) + { + assert(prop->val.len == sizeof(cell_t)); +- return fdt32_to_cpu(*((cell_t *)prop->val.val)); ++ return fdt32_to_cpu(*((fdt32_t *)prop->val.val)); + } + + struct property *get_property_by_label(struct node *tree, const char *label, +@@ -478,7 +478,8 @@ struct node *get_node_by_path(struct node *tree, const char *path) + p = strchr(path, '/'); + + for_each_child(tree, child) { +- if (p && strneq(path, child->name, p-path)) ++ if (p && (strlen(child->name) == p-path) && ++ strneq(path, child->name, p-path)) + return get_node_by_path(child, p+1); + else if (!p && streq(path, child->name)) + return child; +@@ -599,13 +600,13 @@ static int cmp_reserve_info(const void *ax, const void *bx) + a = *((const struct reserve_info * const *)ax); + b = *((const struct reserve_info * const *)bx); + +- if (a->re.address < b->re.address) ++ if (a->address < b->address) + return -1; +- else if (a->re.address > b->re.address) ++ else if (a->address > b->address) + return 1; +- else if (a->re.size < b->re.size) ++ else if (a->size < b->size) + return -1; +- else if (a->re.size > b->re.size) ++ else if (a->size > b->size) + return 1; + else + return 0; +@@ -847,6 +848,8 @@ static void add_fixup_entry(struct dt_info *dti, struct node *fn, + xasprintf(&entry, "%s:%s:%u", + node->fullpath, prop->name, m->offset); + append_to_property(fn, m->ref, entry, strlen(entry) + 1); ++ ++ free(entry); + } + + static void generate_fixups_tree_internal(struct dt_info *dti, +@@ -900,7 +903,7 @@ static void add_local_fixup_entry(struct dt_info *dti, + struct node *refnode) + { + struct node *wn, *nwn; /* local fixup node, walk node, new */ +- uint32_t value_32; ++ fdt32_t value_32; + char **compp; + int i, depth; + +diff --git a/scripts/dtc/srcpos.c b/scripts/dtc/srcpos.c +index aa3aad04..9d384599 100644 +--- a/scripts/dtc/srcpos.c ++++ b/scripts/dtc/srcpos.c +@@ -252,7 +252,7 @@ srcpos_string(struct srcpos *pos) + const char *fname = "<no-file>"; + char *pos_str; + +- if (pos) ++ if (pos->file && pos->file->name) + fname = pos->file->name; + + +diff --git a/scripts/dtc/srcpos.h b/scripts/dtc/srcpos.h +index 2cdfcd82..7caca825 100644 +--- a/scripts/dtc/srcpos.h ++++ b/scripts/dtc/srcpos.h +@@ -22,6 +22,7 @@ + + #include <stdio.h> + #include <stdbool.h> ++#include "util.h" + + struct srcfile_state { + FILE *f; +@@ -106,12 +107,10 @@ extern void srcpos_update(struct srcpos *pos, const char *text, int len); + extern struct srcpos *srcpos_copy(struct srcpos *pos); + extern char *srcpos_string(struct srcpos *pos); + +-extern void srcpos_verror(struct srcpos *pos, const char *prefix, +- const char *fmt, va_list va) +- __attribute__((format(printf, 3, 0))); +-extern void srcpos_error(struct srcpos *pos, const char *prefix, +- const char *fmt, ...) +- __attribute__((format(printf, 3, 4))); ++extern void PRINTF(3, 0) srcpos_verror(struct srcpos *pos, const char *prefix, ++ const char *fmt, va_list va); ++extern void PRINTF(3, 4) srcpos_error(struct srcpos *pos, const char *prefix, ++ const char *fmt, ...); + + extern void srcpos_set_line(char *f, int l); + +diff --git a/scripts/dtc/treesource.c b/scripts/dtc/treesource.c +index c9d89679..2461a3d0 100644 +--- a/scripts/dtc/treesource.c ++++ b/scripts/dtc/treesource.c +@@ -137,7 +137,7 @@ static void write_propval_string(FILE *f, struct data val) + static void write_propval_cells(FILE *f, struct data val) + { + void *propend = val.val + val.len; +- cell_t *cp = (cell_t *)val.val; ++ fdt32_t *cp = (fdt32_t *)val.val; + struct marker *m = val.markers; + + fprintf(f, "<"); +@@ -275,8 +275,8 @@ void dt_to_source(FILE *f, struct dt_info *dti) + for_each_label(re->labels, l) + fprintf(f, "%s: ", l->label); + fprintf(f, "/memreserve/\t0x%016llx 0x%016llx;\n", +- (unsigned long long)re->re.address, +- (unsigned long long)re->re.size); ++ (unsigned long long)re->address, ++ (unsigned long long)re->size); + } + + write_tree_source_node(f, dti->dt, 0); +diff --git a/scripts/dtc/util.c b/scripts/dtc/util.c +index 3550f86b..9953c32a 100644 +--- a/scripts/dtc/util.c ++++ b/scripts/dtc/util.c +@@ -396,7 +396,7 @@ void utilfdt_print_data(const char *data, int len) + } while (s < data + len); + + } else if ((len % 4) == 0) { +- const uint32_t *cell = (const uint32_t *)data; ++ const fdt32_t *cell = (const fdt32_t *)data; + + printf(" = <"); + for (i = 0, len /= 4; i < len; i++) +@@ -412,15 +412,16 @@ void utilfdt_print_data(const char *data, int len) + } + } + +-void util_version(void) ++void NORETURN util_version(void) + { + printf("Version: %s\n", DTC_VERSION); + exit(0); + } + +-void util_usage(const char *errmsg, const char *synopsis, +- const char *short_opts, struct option const long_opts[], +- const char * const opts_help[]) ++void NORETURN util_usage(const char *errmsg, const char *synopsis, ++ const char *short_opts, ++ struct option const long_opts[], ++ const char * const opts_help[]) + { + FILE *fp = errmsg ? stderr : stdout; + const char a_arg[] = "<arg>"; +diff --git a/scripts/dtc/util.h b/scripts/dtc/util.h +index f5c4f1b5..ad5f4119 100644 +--- a/scripts/dtc/util.h ++++ b/scripts/dtc/util.h +@@ -25,9 +25,17 @@ + * USA + */ + ++#ifdef __GNUC__ ++#define PRINTF(i, j) __attribute__((format (printf, i, j))) ++#define NORETURN __attribute__((noreturn)) ++#else ++#define PRINTF(i, j) ++#define NORETURN ++#endif ++ + #define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0])) + +-static inline void __attribute__((noreturn)) die(const char *str, ...) ++static inline void NORETURN PRINTF(1, 2) die(const char *str, ...) + { + va_list ap; + +@@ -53,13 +61,14 @@ static inline void *xrealloc(void *p, size_t len) + void *new = realloc(p, len); + + if (!new) +- die("realloc() failed (len=%d)\n", len); ++ die("realloc() failed (len=%zd)\n", len); + + return new; + } + + extern char *xstrdup(const char *s); +-extern int xasprintf(char **strp, const char *fmt, ...); ++ ++extern int PRINTF(2, 3) xasprintf(char **strp, const char *fmt, ...); + extern char *join_path(const char *path, const char *name); + + /** +@@ -188,7 +197,7 @@ void utilfdt_print_data(const char *data, int len); + /** + * Show source version and exit + */ +-void util_version(void) __attribute__((noreturn)); ++void NORETURN util_version(void); + + /** + * Show usage and exit +@@ -202,9 +211,10 @@ void util_version(void) __attribute__((noreturn)); + * @param long_opts The structure of long options + * @param opts_help An array of help strings (should align with long_opts) + */ +-void util_usage(const char *errmsg, const char *synopsis, +- const char *short_opts, struct option const long_opts[], +- const char * const opts_help[]) __attribute__((noreturn)); ++void NORETURN util_usage(const char *errmsg, const char *synopsis, ++ const char *short_opts, ++ struct option const long_opts[], ++ const char * const opts_help[]); + + /** + * Show usage and exit diff --git a/patch/kernel/sun50iw1-dev/spi-sun6i-allow-large-transfers.patch b/patch/kernel/sun50i-dev/spi-sun6i-allow-large-transfers.patch similarity index 100% rename from patch/kernel/sun50iw1-dev/spi-sun6i-allow-large-transfers.patch rename to patch/kernel/sun50i-dev/spi-sun6i-allow-large-transfers.patch diff --git a/patch/kernel/sun50iw1-dev/spidev-remove-warnings.patch b/patch/kernel/sun50i-dev/spidev-remove-warnings.patch similarity index 100% rename from patch/kernel/sun50iw1-dev/spidev-remove-warnings.patch rename to patch/kernel/sun50i-dev/spidev-remove-warnings.patch diff --git a/patch/kernel/sun50iw2-dev/add-DVFS-and-THS-DT-H5.patch b/patch/kernel/sun50i-dev/unresolved/add-DVFS-and-THS-DT-H5.patch similarity index 100% rename from patch/kernel/sun50iw2-dev/add-DVFS-and-THS-DT-H5.patch rename to patch/kernel/sun50i-dev/unresolved/add-DVFS-and-THS-DT-H5.patch diff --git a/patch/kernel/sun50iw2-dev/add-DVFS-and-THS-drivers-H5.patch b/patch/kernel/sun50i-dev/unresolved/add-DVFS-and-THS-drivers-H5.patch similarity index 100% rename from patch/kernel/sun50iw2-dev/add-DVFS-and-THS-drivers-H5.patch rename to patch/kernel/sun50i-dev/unresolved/add-DVFS-and-THS-drivers-H5.patch diff --git a/patch/kernel/sun50iw1-dev/add-h5-a64-simplefb.patch b/patch/kernel/sun50i-dev/unresolved/add-h5-a64-simplefb.patch similarity index 100% rename from patch/kernel/sun50iw1-dev/add-h5-a64-simplefb.patch rename to patch/kernel/sun50i-dev/unresolved/add-h5-a64-simplefb.patch diff --git a/patch/kernel/sun50iw1-dev/add-sun50i-a64-overlays.patch b/patch/kernel/sun50i-dev/unresolved/add-sun50i-a64-overlays.patch similarity index 100% rename from patch/kernel/sun50iw1-dev/add-sun50i-a64-overlays.patch rename to patch/kernel/sun50i-dev/unresolved/add-sun50i-a64-overlays.patch diff --git a/patch/kernel/sun50iw2-dev/add-sun50i-h5-overlays.patch b/patch/kernel/sun50i-dev/unresolved/add-sun50i-h5-overlays.patch similarity index 100% rename from patch/kernel/sun50iw2-dev/add-sun50i-h5-overlays.patch rename to patch/kernel/sun50i-dev/unresolved/add-sun50i-h5-overlays.patch diff --git a/patch/kernel/sun50iw2-dev/add_nanopim1plus2_dts.patch b/patch/kernel/sun50i-dev/unresolved/add_nanopim1plus2_dts.patch similarity index 100% rename from patch/kernel/sun50iw2-dev/add_nanopim1plus2_dts.patch rename to patch/kernel/sun50i-dev/unresolved/add_nanopim1plus2_dts.patch diff --git a/patch/kernel/sun50iw2-dev/add_nanopineo2.patch b/patch/kernel/sun50i-dev/unresolved/add_nanopineo2.patch similarity index 100% rename from patch/kernel/sun50iw2-dev/add_nanopineo2.patch rename to patch/kernel/sun50i-dev/unresolved/add_nanopineo2.patch diff --git a/patch/kernel/sun50iw2-dev/add_orangepi-zero-plus-h5.patch b/patch/kernel/sun50i-dev/unresolved/add_orangepi-zero-plus-h5.patch similarity index 100% rename from patch/kernel/sun50iw2-dev/add_orangepi-zero-plus-h5.patch rename to patch/kernel/sun50i-dev/unresolved/add_orangepi-zero-plus-h5.patch diff --git a/patch/kernel/sun50iw2-dev/add_orangepiprime_dts.patch b/patch/kernel/sun50i-dev/unresolved/add_orangepiprime_dts.patch similarity index 100% rename from patch/kernel/sun50iw2-dev/add_orangepiprime_dts.patch rename to patch/kernel/sun50i-dev/unresolved/add_orangepiprime_dts.patch diff --git a/patch/kernel/sun50iw2-dev/add_orangepiwin_dts.patch b/patch/kernel/sun50i-dev/unresolved/add_orangepiwin_dts.patch similarity index 100% rename from patch/kernel/sun50iw2-dev/add_orangepiwin_dts.patch rename to patch/kernel/sun50i-dev/unresolved/add_orangepiwin_dts.patch diff --git a/patch/kernel/sun50iw1-dev/spi-patch-for-A64-4.10.x.patch b/patch/kernel/sun50i-dev/unresolved/spi-patch-for-A64-4.10.x.patch similarity index 100% rename from patch/kernel/sun50iw1-dev/spi-patch-for-A64-4.10.x.patch rename to patch/kernel/sun50i-dev/unresolved/spi-patch-for-A64-4.10.x.patch diff --git a/patch/kernel/sun50iw1-dev/add_sun50i_a64_rccu.patch b/patch/kernel/sun50iw1-dev/add_sun50i_a64_rccu.patch deleted file mode 100644 index 1ad041f64..000000000 --- a/patch/kernel/sun50iw1-dev/add_sun50i_a64_rccu.patch +++ /dev/null @@ -1,404 +0,0 @@ -diff --git a/drivers/clk/sunxi-ng/Kconfig b/drivers/clk/sunxi-ng/Kconfig -index 8af8f4be8e3b..fbd3f8cd5c22 100644 ---- a/drivers/clk/sunxi-ng/Kconfig -+++ b/drivers/clk/sunxi-ng/Kconfig -@@ -151,4 +151,10 @@ config SUN9I_A80_CCU - default MACH_SUN9I - depends on MACH_SUN9I || COMPILE_TEST - -+config SUN8I_R_CCU -+ bool "Support for Allwinner SoCs' PRCM CCUs" -+ select SUNXI_CCU_DIV -+ select SUNXI_CCU_GATE -+ default MACH_SUN8I || (ARCH_SUNXI && ARM64) -+ - endif -diff --git a/drivers/clk/sunxi-ng/Makefile b/drivers/clk/sunxi-ng/Makefile -index 6feaac0c5600..0ec02fe14c50 100644 ---- a/drivers/clk/sunxi-ng/Makefile -+++ b/drivers/clk/sunxi-ng/Makefile -@@ -25,6 +25,7 @@ obj-$(CONFIG_SUN8I_A23_CCU) += ccu-sun8i-a23.o - obj-$(CONFIG_SUN8I_A33_CCU) += ccu-sun8i-a33.o - obj-$(CONFIG_SUN8I_H3_CCU) += ccu-sun8i-h3.o - obj-$(CONFIG_SUN8I_V3S_CCU) += ccu-sun8i-v3s.o -+obj-$(CONFIG_SUN8I_R_CCU) += ccu-sun8i-r.o - obj-$(CONFIG_SUN9I_A80_CCU) += ccu-sun9i-a80.o - obj-$(CONFIG_SUN9I_A80_CCU) += ccu-sun9i-a80-de.o - obj-$(CONFIG_SUN9I_A80_CCU) += ccu-sun9i-a80-usb.o -diff --git a/drivers/clk/sunxi-ng/ccu-sun8i-r.c b/drivers/clk/sunxi-ng/ccu-sun8i-r.c -new file mode 100644 -index 000000000000..0d027d53dbdf ---- /dev/null -+++ b/drivers/clk/sunxi-ng/ccu-sun8i-r.c -@@ -0,0 +1,213 @@ -+/* -+ * Copyright (c) 2016 Icenowy Zheng <icenowy@aosc.xyz> -+ * -+ * This software is licensed under the terms of the GNU General Public -+ * License version 2, as published by the Free Software Foundation, and -+ * may be copied, distributed, and modified under those terms. -+ * -+ * This program is distributed in the hope that it will be useful, -+ * but WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+ * GNU General Public License for more details. -+ */ -+ -+#include <linux/clk-provider.h> -+#include <linux/of_address.h> -+#include <linux/platform_device.h> -+ -+#include "ccu_common.h" -+#include "ccu_reset.h" -+ -+#include "ccu_div.h" -+#include "ccu_gate.h" -+#include "ccu_mp.h" -+#include "ccu_nm.h" -+ -+#include "ccu-sun8i-r.h" -+ -+static const char * const ar100_parents[] = { "osc32k", "osc24M", -+ "pll-periph0", "iosc" }; -+ -+static struct ccu_div ar100_clk = { -+ .div = _SUNXI_CCU_DIV_FLAGS(4, 2, CLK_DIVIDER_POWER_OF_TWO), -+ -+ .mux = { -+ .shift = 16, -+ .width = 2, -+ -+ .variable_prediv = { -+ .index = 2, -+ .shift = 8, -+ .width = 5, -+ }, -+ }, -+ -+ .common = { -+ .reg = 0x00, -+ .features = CCU_FEATURE_VARIABLE_PREDIV, -+ .hw.init = CLK_HW_INIT_PARENTS("ar100", -+ ar100_parents, -+ &ccu_div_ops, -+ 0), -+ }, -+}; -+ -+static CLK_FIXED_FACTOR(ahb0_clk, "ahb0", "ar100", 1, 1, 0); -+ -+static struct ccu_div apb0_clk = { -+ .div = _SUNXI_CCU_DIV_FLAGS(0, 2, CLK_DIVIDER_POWER_OF_TWO), -+ -+ .common = { -+ .reg = 0x0c, -+ .hw.init = CLK_HW_INIT("apb0", -+ "ahb0", -+ &ccu_div_ops, -+ 0), -+ }, -+}; -+ -+static SUNXI_CCU_GATE(apb0_pio_clk, "apb0-pio", "apb0", -+ 0x28, BIT(0), 0); -+static SUNXI_CCU_GATE(apb0_ir_clk, "apb0-ir", "apb0", -+ 0x28, BIT(1), 0); -+static SUNXI_CCU_GATE(apb0_timer_clk, "apb0-timer", "apb0", -+ 0x28, BIT(2), 0); -+static SUNXI_CCU_GATE(apb0_rsb_clk, "apb0-rsb", "apb0", -+ 0x28, BIT(3), 0); -+static SUNXI_CCU_GATE(apb0_uart_clk, "apb0-uart", "apb0", -+ 0x28, BIT(4), 0); -+static SUNXI_CCU_GATE(apb0_i2c_clk, "apb0-i2c", "apb0", -+ 0x28, BIT(6), 0); -+static SUNXI_CCU_GATE(apb0_twd_clk, "apb0-twd", "apb0", -+ 0x28, BIT(7), 0); -+ -+static const char * const r_mod0_default_parents[] = { "osc32K", "osc24M" }; -+static SUNXI_CCU_MP_WITH_MUX_GATE(ir_clk, "ir", -+ r_mod0_default_parents, 0x54, -+ 0, 4, /* M */ -+ 16, 2, /* P */ -+ 24, 2, /* mux */ -+ BIT(31), /* gate */ -+ 0); -+ -+static struct ccu_common *sun8i_h3_r_ccu_clks[] = { -+ &ar100_clk.common, -+ &apb0_clk.common, -+ &apb0_pio_clk.common, -+ &apb0_ir_clk.common, -+ &apb0_timer_clk.common, -+ &apb0_uart_clk.common, -+ &apb0_i2c_clk.common, -+ &apb0_twd_clk.common, -+ &ir_clk.common, -+}; -+ -+static struct ccu_common *sun50i_a64_r_ccu_clks[] = { -+ &ar100_clk.common, -+ &apb0_clk.common, -+ &apb0_pio_clk.common, -+ &apb0_ir_clk.common, -+ &apb0_timer_clk.common, -+ &apb0_rsb_clk.common, -+ &apb0_uart_clk.common, -+ &apb0_i2c_clk.common, -+ &apb0_twd_clk.common, -+ &ir_clk.common, -+}; -+ -+static struct clk_hw_onecell_data sun8i_h3_r_hw_clks = { -+ .hws = { -+ [CLK_AR100] = &ar100_clk.common.hw, -+ [CLK_AHB0] = &ahb0_clk.hw, -+ [CLK_APB0] = &apb0_clk.common.hw, -+ [CLK_APB0_PIO] = &apb0_pio_clk.common.hw, -+ [CLK_APB0_IR] = &apb0_ir_clk.common.hw, -+ [CLK_APB0_TIMER] = &apb0_timer_clk.common.hw, -+ [CLK_APB0_UART] = &apb0_uart_clk.common.hw, -+ [CLK_APB0_I2C] = &apb0_i2c_clk.common.hw, -+ [CLK_APB0_TWD] = &apb0_twd_clk.common.hw, -+ [CLK_IR] = &ir_clk.common.hw, -+ }, -+ .num = CLK_NUMBER, -+}; -+ -+static struct clk_hw_onecell_data sun50i_a64_r_hw_clks = { -+ .hws = { -+ [CLK_AR100] = &ar100_clk.common.hw, -+ [CLK_AHB0] = &ahb0_clk.hw, -+ [CLK_APB0] = &apb0_clk.common.hw, -+ [CLK_APB0_PIO] = &apb0_pio_clk.common.hw, -+ [CLK_APB0_IR] = &apb0_ir_clk.common.hw, -+ [CLK_APB0_TIMER] = &apb0_timer_clk.common.hw, -+ [CLK_APB0_RSB] = &apb0_rsb_clk.common.hw, -+ [CLK_APB0_UART] = &apb0_uart_clk.common.hw, -+ [CLK_APB0_I2C] = &apb0_i2c_clk.common.hw, -+ [CLK_APB0_TWD] = &apb0_twd_clk.common.hw, -+ [CLK_IR] = &ir_clk.common.hw, -+ }, -+ .num = CLK_NUMBER, -+}; -+ -+static struct ccu_reset_map sun8i_h3_r_ccu_resets[] = { -+ [RST_APB0_IR] = { 0xb0, BIT(1) }, -+ [RST_APB0_TIMER] = { 0xb0, BIT(2) }, -+ [RST_APB0_UART] = { 0xb0, BIT(4) }, -+ [RST_APB0_I2C] = { 0xb0, BIT(6) }, -+}; -+ -+static struct ccu_reset_map sun50i_a64_r_ccu_resets[] = { -+ [RST_APB0_IR] = { 0xb0, BIT(1) }, -+ [RST_APB0_TIMER] = { 0xb0, BIT(2) }, -+ [RST_APB0_RSB] = { 0xb0, BIT(3) }, -+ [RST_APB0_UART] = { 0xb0, BIT(4) }, -+ [RST_APB0_I2C] = { 0xb0, BIT(6) }, -+}; -+ -+static const struct sunxi_ccu_desc sun8i_h3_r_ccu_desc = { -+ .ccu_clks = sun8i_h3_r_ccu_clks, -+ .num_ccu_clks = ARRAY_SIZE(sun8i_h3_r_ccu_clks), -+ -+ .hw_clks = &sun8i_h3_r_hw_clks, -+ -+ .resets = sun8i_h3_r_ccu_resets, -+ .num_resets = ARRAY_SIZE(sun8i_h3_r_ccu_resets), -+}; -+ -+static const struct sunxi_ccu_desc sun50i_a64_r_ccu_desc = { -+ .ccu_clks = sun50i_a64_r_ccu_clks, -+ .num_ccu_clks = ARRAY_SIZE(sun50i_a64_r_ccu_clks), -+ -+ .hw_clks = &sun50i_a64_r_hw_clks, -+ -+ .resets = sun50i_a64_r_ccu_resets, -+ .num_resets = ARRAY_SIZE(sun50i_a64_r_ccu_resets), -+}; -+ -+static void __init sunxi_r_ccu_init(struct device_node *node, -+ const struct sunxi_ccu_desc *desc) -+{ -+ void __iomem *reg; -+ -+ reg = of_io_request_and_map(node, 0, of_node_full_name(node)); -+ if (IS_ERR(reg)) { -+ pr_err("%s: Could not map the clock registers\n", -+ of_node_full_name(node)); -+ return; -+ } -+ -+ sunxi_ccu_probe(node, reg, desc); -+} -+ -+static void __init sun8i_h3_r_ccu_setup(struct device_node *node) -+{ -+ sunxi_r_ccu_init(node, &sun8i_h3_r_ccu_desc); -+} -+CLK_OF_DECLARE(sun8i_h3_r_ccu, "allwinner,sun8i-h3-r-ccu", -+ sun8i_h3_r_ccu_setup); -+ -+static void __init sun50i_a64_r_ccu_setup(struct device_node *node) -+{ -+ sunxi_r_ccu_init(node, &sun50i_a64_r_ccu_desc); -+} -+CLK_OF_DECLARE(sun50i_a64_r_ccu, "allwinner,sun50i-a64-r-ccu", -+ sun50i_a64_r_ccu_setup); -diff --git a/drivers/clk/sunxi-ng/ccu-sun8i-r.h b/drivers/clk/sunxi-ng/ccu-sun8i-r.h -new file mode 100644 -index 000000000000..eaa431fd1d8f ---- /dev/null -+++ b/drivers/clk/sunxi-ng/ccu-sun8i-r.h -@@ -0,0 +1,27 @@ -+/* -+ * Copyright 2016 Icenowy <icenowy@aosc.xyz> -+ * -+ * This program is free software; you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License as published by -+ * the Free Software Foundation; either version 2 of the License, or -+ * (at your option) any later version. -+ * -+ * This program is distributed in the hope that it will be useful, -+ * but WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+ * GNU General Public License for more details. -+ */ -+ -+#ifndef _CCU_SUN8I_R_H -+#define _CCU_SUN8I_R_H_ -+ -+#include <dt-bindings/clock/sun8i-r-ccu.h> -+#include <dt-bindings/reset/sun8i-r-ccu.h> -+ -+/* AHB/APB bus clocks are not exported */ -+#define CLK_AHB0 1 -+#define CLK_APB0 2 -+ -+#define CLK_NUMBER (CLK_APB0_TWD + 1) -+ -+#endif /* _CCU_SUN8I_R_H */ -diff --git a/include/dt-bindings/clock/sun8i-r-ccu.h b/include/dt-bindings/clock/sun8i-r-ccu.h -new file mode 100644 -index 000000000000..779d20aa0d05 ---- /dev/null -+++ b/include/dt-bindings/clock/sun8i-r-ccu.h -@@ -0,0 +1,59 @@ -+/* -+ * Copyright (c) 2016 Icenowy Zheng <icenowy@aosc.xyz> -+ * -+ * This file is dual-licensed: you can use it either under the terms -+ * of the GPL or the X11 license, at your option. Note that this dual -+ * licensing only applies to this file, and not this project as a -+ * whole. -+ * -+ * a) This file is free software; you can redistribute it and/or -+ * modify it under the terms of the GNU General Public License as -+ * published by the Free Software Foundation; either version 2 of the -+ * License, or (at your option) any later version. -+ * -+ * This file is distributed in the hope that it will be useful, -+ * but WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+ * GNU General Public License for more details. -+ * -+ * Or, alternatively, -+ * -+ * b) Permission is hereby granted, free of charge, to any person -+ * obtaining a copy of this software and associated documentation -+ * files (the "Software"), to deal in the Software without -+ * restriction, including without limitation the rights to use, -+ * copy, modify, merge, publish, distribute, sublicense, and/or -+ * sell copies of the Software, and to permit persons to whom the -+ * Software is furnished to do so, subject to the following -+ * conditions: -+ * -+ * The above copyright notice and this permission notice shall be -+ * included in all copies or substantial portions of the Software. -+ * -+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES -+ * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT -+ * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, -+ * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING -+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR -+ * OTHER DEALINGS IN THE SOFTWARE. -+ */ -+ -+#ifndef _DT_BINDINGS_CLK_SUN8I_R_CCU_H_ -+#define _DT_BINDINGS_CLK_SUN8I_R_CCU_H_ -+ -+#define CLK_AR100 0 -+ -+#define CLK_APB0_PIO 3 -+#define CLK_APB0_IR 4 -+#define CLK_APB0_TIMER 5 -+#define CLK_APB0_RSB 6 -+#define CLK_APB0_UART 7 -+/* 8 is reserved for CLK_APB0_W1 on A31 */ -+#define CLK_APB0_I2C 9 -+#define CLK_APB0_TWD 10 -+ -+#define CLK_IR 11 -+ -+#endif /* _DT_BINDINGS_CLK_SUN8I_R_CCU_H_ */ -diff --git a/include/dt-bindings/reset/sun8i-r-ccu.h b/include/dt-bindings/reset/sun8i-r-ccu.h -new file mode 100644 -index 000000000000..4ba64f3d6fc9 ---- /dev/null -+++ b/include/dt-bindings/reset/sun8i-r-ccu.h -@@ -0,0 +1,53 @@ -+/* -+ * Copyright (C) 2016 Icenowy Zheng <icenowy@aosc.xyz> -+ * -+ * This file is dual-licensed: you can use it either under the terms -+ * of the GPL or the X11 license, at your option. Note that this dual -+ * licensing only applies to this file, and not this project as a -+ * whole. -+ * -+ * a) This file is free software; you can redistribute it and/or -+ * modify it under the terms of the GNU General Public License as -+ * published by the Free Software Foundation; either version 2 of the -+ * License, or (at your option) any later version. -+ * -+ * This file is distributed in the hope that it will be useful, -+ * but WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+ * GNU General Public License for more details. -+ * -+ * Or, alternatively, -+ * -+ * b) Permission is hereby granted, free of charge, to any person -+ * obtaining a copy of this software and associated documentation -+ * files (the "Software"), to deal in the Software without -+ * restriction, including without limitation the rights to use, -+ * copy, modify, merge, publish, distribute, sublicense, and/or -+ * sell copies of the Software, and to permit persons to whom the -+ * Software is furnished to do so, subject to the following -+ * conditions: -+ * -+ * The above copyright notice and this permission notice shall be -+ * included in all copies or substantial portions of the Software. -+ * -+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES -+ * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT -+ * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, -+ * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING -+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR -+ * OTHER DEALINGS IN THE SOFTWARE. -+ */ -+ -+#ifndef _DT_BINDINGS_RST_SUN8I_R_CCU_H_ -+#define _DT_BINDINGS_RST_SUN8I_R_CCU_H_ -+ -+#define RST_APB0_IR 0 -+#define RST_APB0_TIMER 1 -+#define RST_APB0_RSB 2 -+#define RST_APB0_UART 3 -+/* 4 is reserved for RST_APB0_W1 on A31 */ -+#define RST_APB0_I2C 5 -+ -+#endif /* _DT_BINDINGS_RST_SUN8I_R_CCU_H_ */ - diff --git a/patch/kernel/sun50iw1-dev/add_sun50i_a64_rpio.patch b/patch/kernel/sun50iw1-dev/add_sun50i_a64_rpio.patch deleted file mode 100644 index 428807bd8..000000000 --- a/patch/kernel/sun50iw1-dev/add_sun50i_a64_rpio.patch +++ /dev/null @@ -1,227 +0,0 @@ -diff --git a/arch/arm64/Kconfig.platforms b/arch/arm64/Kconfig.platforms -index 81f0d61..18ff031 100644 ---- a/arch/arm64/Kconfig.platforms -+++ b/arch/arm64/Kconfig.platforms -@@ -5,6 +5,7 @@ config ARCH_SUNXI - select GENERIC_IRQ_CHIP - select PINCTRL - select PINCTRL_SUN50I_A64 -+ select PINCTRL_SUN50I_A64_R - select PINCTRL_SUN50I_H5 - select PINCTRL_SUN8I_H3_R - help -diff --git a/drivers/pinctrl/sunxi/Kconfig b/drivers/pinctrl/sunxi/Kconfig -index a84bfa7f3c05..a0c419ac2a3b 100644 ---- a/drivers/pinctrl/sunxi/Kconfig -+++ b/drivers/pinctrl/sunxi/Kconfig -@@ -68,6 +68,10 @@ config PINCTRL_SUN50I_A64 - def_bool ARM64 && ARCH_SUNXI - select PINCTRL_SUNXI - -+config PINCTRL_SUN50I_A64_R -+ def_bool ARM64 && ARCH_SUNXI -+ select PINCTRL_SUNXI -+ - config PINCTRL_SUN50I_H5 - def_bool ARM64 && ARCH_SUNXI - select PINCTRL_SUNXI -diff --git a/drivers/pinctrl/sunxi/Makefile b/drivers/pinctrl/sunxi/Makefile -index 04ccb88ebd5f..df4ccd6cd44c 100644 ---- a/drivers/pinctrl/sunxi/Makefile -+++ b/drivers/pinctrl/sunxi/Makefile -@@ -11,6 +11,7 @@ obj-$(CONFIG_PINCTRL_SUN8I_A23) += pinctrl-sun8i-a23.o - obj-$(CONFIG_PINCTRL_SUN8I_A23_R) += pinctrl-sun8i-a23-r.o - obj-$(CONFIG_PINCTRL_SUN8I_A33) += pinctrl-sun8i-a33.o - obj-$(CONFIG_PINCTRL_SUN50I_A64) += pinctrl-sun50i-a64.o -+obj-$(CONFIG_PINCTRL_SUN50I_A64_R) += pinctrl-sun50i-a64-r.o - obj-$(CONFIG_PINCTRL_SUN8I_A83T) += pinctrl-sun8i-a83t.o - obj-$(CONFIG_PINCTRL_SUN8I_H3) += pinctrl-sun8i-h3.o - obj-$(CONFIG_PINCTRL_SUN8I_H3_R) += pinctrl-sun8i-h3-r.o -diff --git a/drivers/pinctrl/sunxi/pinctrl-sun50i-a64-r.c b/drivers/pinctrl/sunxi/pinctrl-sun50i-a64-r.c -new file mode 100644 -index 000000000000..415870e82cbf ---- /dev/null -+++ b/drivers/pinctrl/sunxi/pinctrl-sun50i-a64-r.c -@@ -0,0 +1,125 @@ -+/* -+ * Allwinner A64 SoCs special pins pinctrl driver. -+ * -+ * Based on pinctrl-sun8i-a23-r.c -+ * -+ * Copyright (C) 2016 Icenowy Zheng -+ * Icenowy Zheng <icenowy@aosc.xyz> -+ * -+ * Copyright (C) 2014 Chen-Yu Tsai -+ * Chen-Yu Tsai <wens@csie.org> -+ * -+ * Copyright (C) 2014 Boris Brezillon -+ * Boris Brezillon <boris.brezillon@free-electrons.com> -+ * -+ * Copyright (C) 2014 Maxime Ripard -+ * Maxime Ripard <maxime.ripard@free-electrons.com> -+ * -+ * This file is licensed under the terms of the GNU General Public -+ * License version 2. This program is licensed "as is" without any -+ * warranty of any kind, whether express or implied. -+ */ -+ -+#include <linux/of.h> -+#include <linux/of_device.h> -+#include <linux/pinctrl/pinctrl.h> -+#include <linux/platform_device.h> -+#include <linux/reset.h> -+ -+#include "pinctrl-sunxi.h" -+ -+static const struct sunxi_desc_pin sun50i_a64_r_pins[] = { -+ SUNXI_PIN(SUNXI_PINCTRL_PIN(L, 0), -+ SUNXI_FUNCTION(0x0, "gpio_in"), -+ SUNXI_FUNCTION(0x1, "gpio_out"), -+ SUNXI_FUNCTION(0x2, "s_rsb"), /* SCK */ -+ SUNXI_FUNCTION(0x3, "s_i2c"), /* SCK */ -+ SUNXI_FUNCTION_IRQ_BANK(0x6, 0, 0)), /* PL_EINT0 */ -+ SUNXI_PIN(SUNXI_PINCTRL_PIN(L, 1), -+ SUNXI_FUNCTION(0x0, "gpio_in"), -+ SUNXI_FUNCTION(0x1, "gpio_out"), -+ SUNXI_FUNCTION(0x2, "s_rsb"), /* SDA */ -+ SUNXI_FUNCTION(0x3, "s_i2c"), /* SDA */ -+ SUNXI_FUNCTION_IRQ_BANK(0x6, 0, 1)), /* PL_EINT1 */ -+ SUNXI_PIN(SUNXI_PINCTRL_PIN(L, 2), -+ SUNXI_FUNCTION(0x0, "gpio_in"), -+ SUNXI_FUNCTION(0x1, "gpio_out"), -+ SUNXI_FUNCTION(0x2, "s_uart"), /* TX */ -+ SUNXI_FUNCTION_IRQ_BANK(0x6, 0, 2)), /* PL_EINT2 */ -+ SUNXI_PIN(SUNXI_PINCTRL_PIN(L, 3), -+ SUNXI_FUNCTION(0x0, "gpio_in"), -+ SUNXI_FUNCTION(0x1, "gpio_out"), -+ SUNXI_FUNCTION(0x2, "s_uart"), /* RX */ -+ SUNXI_FUNCTION_IRQ_BANK(0x6, 0, 3)), /* PL_EINT3 */ -+ SUNXI_PIN(SUNXI_PINCTRL_PIN(L, 4), -+ SUNXI_FUNCTION(0x0, "gpio_in"), -+ SUNXI_FUNCTION(0x1, "gpio_out"), -+ SUNXI_FUNCTION(0x2, "s_jtag"), /* MS */ -+ SUNXI_FUNCTION_IRQ_BANK(0x6, 0, 4)), /* PL_EINT4 */ -+ SUNXI_PIN(SUNXI_PINCTRL_PIN(L, 5), -+ SUNXI_FUNCTION(0x0, "gpio_in"), -+ SUNXI_FUNCTION(0x1, "gpio_out"), -+ SUNXI_FUNCTION(0x2, "s_jtag"), /* CK */ -+ SUNXI_FUNCTION_IRQ_BANK(0x6, 0, 5)), /* PL_EINT5 */ -+ SUNXI_PIN(SUNXI_PINCTRL_PIN(L, 6), -+ SUNXI_FUNCTION(0x0, "gpio_in"), -+ SUNXI_FUNCTION(0x1, "gpio_out"), -+ SUNXI_FUNCTION(0x2, "s_jtag"), /* DO */ -+ SUNXI_FUNCTION_IRQ_BANK(0x6, 0, 6)), /* PL_EINT6 */ -+ SUNXI_PIN(SUNXI_PINCTRL_PIN(L, 7), -+ SUNXI_FUNCTION(0x0, "gpio_in"), -+ SUNXI_FUNCTION(0x1, "gpio_out"), -+ SUNXI_FUNCTION(0x2, "s_jtag"), /* DI */ -+ SUNXI_FUNCTION_IRQ_BANK(0x6, 0, 7)), /* PL_EINT7 */ -+ SUNXI_PIN(SUNXI_PINCTRL_PIN(L, 8), -+ SUNXI_FUNCTION(0x0, "gpio_in"), -+ SUNXI_FUNCTION(0x1, "gpio_out"), -+ SUNXI_FUNCTION(0x2, "s_i2c"), /* SCK */ -+ SUNXI_FUNCTION_IRQ_BANK(0x6, 0, 8)), /* PL_EINT8 */ -+ SUNXI_PIN(SUNXI_PINCTRL_PIN(L, 9), -+ SUNXI_FUNCTION(0x0, "gpio_in"), -+ SUNXI_FUNCTION(0x1, "gpio_out"), -+ SUNXI_FUNCTION(0x2, "s_i2c"), /* SDA */ -+ SUNXI_FUNCTION_IRQ_BANK(0x6, 0, 9)), /* PL_EINT9 */ -+ SUNXI_PIN(SUNXI_PINCTRL_PIN(L, 10), -+ SUNXI_FUNCTION(0x0, "gpio_in"), -+ SUNXI_FUNCTION(0x1, "gpio_out"), -+ SUNXI_FUNCTION(0x2, "s_pwm"), -+ SUNXI_FUNCTION_IRQ_BANK(0x6, 0, 10)), /* PL_EINT10 */ -+ SUNXI_PIN(SUNXI_PINCTRL_PIN(L, 11), -+ SUNXI_FUNCTION(0x0, "gpio_in"), -+ SUNXI_FUNCTION(0x1, "gpio_out"), -+ SUNXI_FUNCTION(0x2, "s_cir_rx"), -+ SUNXI_FUNCTION_IRQ_BANK(0x6, 0, 11)), /* PL_EINT11 */ -+ SUNXI_PIN(SUNXI_PINCTRL_PIN(L, 12), -+ SUNXI_FUNCTION(0x0, "gpio_in"), -+ SUNXI_FUNCTION(0x1, "gpio_out"), -+ SUNXI_FUNCTION_IRQ_BANK(0x6, 0, 12)), /* PL_EINT12 */ -+}; -+ -+static const struct sunxi_pinctrl_desc sun50i_a64_r_pinctrl_data = { -+ .pins = sun50i_a64_r_pins, -+ .npins = ARRAY_SIZE(sun50i_a64_r_pins), -+ .pin_base = PL_BASE, -+ .irq_banks = 1, -+}; -+ -+static int sun50i_a64_r_pinctrl_probe(struct platform_device *pdev) -+{ -+ return sunxi_pinctrl_init(pdev, -+ &sun50i_a64_r_pinctrl_data); -+} -+ -+static const struct of_device_id sun50i_a64_r_pinctrl_match[] = { -+ { .compatible = "allwinner,sun50i-a64-r-pinctrl", }, -+ {} -+}; -+ -+static struct platform_driver sun50i_a64_r_pinctrl_driver = { -+ .probe = sun50i_a64_r_pinctrl_probe, -+ .driver = { -+ .name = "sun50i-a64-r-pinctrl", -+ .of_match_table = sun50i_a64_r_pinctrl_match, -+ }, -+}; -+builtin_platform_driver(sun50i_a64_r_pinctrl_driver); -diff --git a/arch/arm64/boot/dts/allwinner/sun50i-a64.dtsi b/arch/arm64/boot/dts/allwinner/sun50i-a64.dtsi -index 02c0385..c0773d8 100644 ---- a/arch/arm64/boot/dts/allwinner/sun50i-a64.dtsi -+++ b/arch/arm64/boot/dts/allwinner/sun50i-a64.dtsi -@@ -43,8 +43,10 @@ - */ - - #include <dt-bindings/clock/sun50i-a64-ccu.h> -+#include <dt-bindings/clock/sun8i-r-ccu.h> - #include <dt-bindings/interrupt-controller/arm-gic.h> - #include <dt-bindings/reset/sun50i-a64-ccu.h> -+#include <dt-bindings/reset/sun8i-r-ccu.h> - - / { - interrupt-parent = <&gic>; -@@ -98,6 +100,13 @@ - clock-output-names = "osc32k"; - }; - -+ osc32000: osc32000_clk { -+ #clock-cells = <0>; -+ compatible = "fixed-clock"; -+ clock-frequency = <32000>; -+ clock-output-names = "osc32000"; -+ }; -+ - psci { - compatible = "arm,psci-0.2"; - method = "smc"; -@@ -306,6 +315,27 @@ - }; - }; - -+ r_ccu: clock@1f01400 { -+ compatible = "allwinner,sun50i-a64-r-ccu"; -+ reg = <0x01f01400 0x100>; -+ clocks = <&osc24M>, <&osc32k>, <&osc32000>; -+ clock-names = "hosc", "losc", "iosc"; -+ #clock-cells = <1>; -+ #reset-cells = <1>; -+ }; -+ -+ r_pio: pinctrl@1f02c00 { -+ compatible = "allwinner,sun50i-a64-r-pinctrl"; -+ reg = <0x01f02c00 0x400>; -+ interrupts = <GIC_SPI 45 IRQ_TYPE_LEVEL_HIGH>; -+ clocks = <&r_ccu CLK_APB0_PIO>, <&osc24M>, <&osc32k>; -+ clock-names = "apb", "hosc", "losc"; -+ gpio-controller; -+ #gpio-cells = <3>; -+ interrupt-controller; -+ #interrupt-cells = <3>; -+ }; -+ - uart0: serial@1c28000 { - compatible = "snps,dw-apb-uart"; - reg = <0x01c28000 0x400>; diff --git a/patch/kernel/sun50iw1-dev/packaging-4.x-DEV-with-postinstall-scripts.patch b/patch/kernel/sun50iw1-dev/packaging-4.x-DEV-with-postinstall-scripts.patch deleted file mode 100644 index 68c734bab..000000000 --- a/patch/kernel/sun50iw1-dev/packaging-4.x-DEV-with-postinstall-scripts.patch +++ /dev/null @@ -1,180 +0,0 @@ -diff --git a/scripts/package/builddeb b/scripts/package/builddeb -index 8ea9fd2b..9f17b825 100755 ---- a/scripts/package/builddeb -+++ b/scripts/package/builddeb -@@ -29,6 +29,28 @@ create_package() { - # in case we are in a restrictive umask environment like 0077 - chmod -R a+rX "$pdir" - -+ # Create preinstall and post install script to remove dtb -+ if [[ "$1" == *dtb* ]]; then -+ echo "if [ -d /boot/dtb-$version ]; then mv /boot/dtb-$version /boot/dtb-$version.old; fi" >> $pdir/DEBIAN/preinst -+ echo "if [ -d /boot/dtb.old ]; then rm -rf /boot/dtb.old; fi" >> $pdir/DEBIAN/preinst -+ echo "if [ -d /dtb ]; then mv /dtb /dtb.old; fi" >> $pdir/DEBIAN/preinst -+ echo "if [ -d /boot/dtb ]; then mv /boot/dtb /boot/dtb.old; fi" >> $pdir/DEBIAN/preinst -+ echo "exit 0" >> $pdir/DEBIAN/preinst -+ chmod 775 $pdir/DEBIAN/preinst -+ # -+ echo "if [ -d /boot/dtb-$version.old ]; then rm -rf /boot/dtb-$version.old; fi" >> $pdir/DEBIAN/postinst -+ echo "ln -sf dtb-$version /boot/dtb > /dev/null 2>&1 || mv /boot/dtb-$version /boot/dtb" >> $pdir/DEBIAN/postinst -+ echo "exit 0" >> $pdir/DEBIAN/postinst -+ chmod 775 $pdir/DEBIAN/postinst -+ fi -+ -+ # Create postinstall script for headers -+ if [[ "$1" == *headers* ]]; then -+ echo "cd /usr/src/linux-headers-$version; echo \"Compiling headers - please wait ...\"; make -s scripts >/dev/null 2>&1" >> $pdir/DEBIAN/postinst -+ echo "exit 0" >> $pdir/DEBIAN/postinst -+ chmod 775 $pdir/DEBIAN/postinst -+ fi -+ - # Create the package - dpkg-gencontrol $forcearch -Vkernel:debarch="${debarch}" -p$pname -P"$pdir" - dpkg --build "$pdir" .. -@@ -95,11 +117,13 @@ tmpdir="$objtree/debian/tmp" - fwdir="$objtree/debian/fwtmp" - kernel_headers_dir="$objtree/debian/hdrtmp" - libc_headers_dir="$objtree/debian/headertmp" -+dtb_dir="$objtree/debian/dtbtmp" - dbg_dir="$objtree/debian/dbgtmp" --packagename=linux-image-$version --fwpackagename=linux-firmware-image-$version --kernel_headers_packagename=linux-headers-$version --libc_headers_packagename=linux-libc-dev -+packagename=linux-image-dev"$LOCALVERSION" -+fwpackagename=linux-firmware-image-dev"$LOCALVERSION" -+kernel_headers_packagename=linux-headers-dev"$LOCALVERSION" -+dtb_packagename=linux-dtb-dev"$LOCALVERSION" -+libc_headers_packagename=linux-libc-dev-dev"$LOCALVERSION" - dbg_packagename=$packagename-dbg - debarch= - forcearch= -@@ -119,6 +143,9 @@ um) - parisc|mips|powerpc) - installed_image_path="boot/vmlinux-$version" - ;; -+arm64) -+ installed_image_path="boot/Image-$version" -+ ;; - *) - installed_image_path="boot/vmlinuz-$version" - esac -@@ -126,7 +153,9 @@ esac - BUILD_DEBUG="$(grep -s '^CONFIG_DEBUG_INFO=y' $KCONFIG_CONFIG || true)" - - # Setup the directory structure --rm -rf "$tmpdir" "$fwdir" "$kernel_headers_dir" "$libc_headers_dir" "$dbg_dir" $objtree/debian/files -+rm -rf "$tmpdir" "$fwdir" "$kernel_headers_dir" "$libc_headers_dir" "$dbg_dir" "$dtb_dir" $objtree/debian/files -+mkdir -m 755 -p "$dtb_dir/DEBIAN" -+mkdir -p "$dtb_dir/boot/dtb-$version" "$dtb_dir/usr/share/doc/$dtb_packagename" - mkdir -m 755 -p "$tmpdir/DEBIAN" - mkdir -p "$tmpdir/lib" "$tmpdir/boot" - mkdir -p "$fwdir/lib/firmware/$version/" -@@ -143,12 +172,7 @@ else - cp System.map "$tmpdir/boot/System.map-$version" - cp $KCONFIG_CONFIG "$tmpdir/boot/config-$version" - fi --# Not all arches include the boot path in KBUILD_IMAGE --if [ -e $KBUILD_IMAGE ]; then -- cp $KBUILD_IMAGE "$tmpdir/$installed_image_path" --else -- cp arch/$ARCH/boot/$KBUILD_IMAGE "$tmpdir/$installed_image_path" --fi -+cp arch/$ARCH/boot/Image "$tmpdir/$installed_image_path" - - if grep -q "^CONFIG_OF=y" $KCONFIG_CONFIG ; then - # Only some architectures with OF support have this target -@@ -185,6 +209,11 @@ if grep -q '^CONFIG_MODULES=y' $KCONFIG_CONFIG ; then - fi - fi - -+if grep -q '^CONFIG_OF=y' $KCONFIG_CONFIG ; then -+ #mkdir -p "$tmpdir/boot/dtb" -+ INSTALL_DTBS_PATH="$dtb_dir/boot/dtb-$version" $MAKE KBUILD_SRC= dtbs_install -+fi -+ - if [ "$ARCH" != "um" ]; then - $MAKE headers_check KBUILD_SRC= - $MAKE headers_install KBUILD_SRC= INSTALL_HDR_PATH="$libc_headers_dir/usr" -@@ -209,9 +238,11 @@ for script in postinst postrm preinst prerm ; do - set -e - - # Pass maintainer script parameters to hook scripts -+ - export DEB_MAINT_PARAMS="\$*" - - # Tell initramfs builder whether it's wanted -+ - export INITRD=$want_initrd - - test -d $debhookdir/$script.d && run-parts --arg="$version" --arg="/$installed_image_path" $debhookdir/$script.d -@@ -220,6 +251,17 @@ EOF - chmod 755 "$tmpdir/DEBIAN/$script" - done - -+## -+## Create sym link to kernel image -+## -+sed -e "s/set -e//g" -i $tmpdir/DEBIAN/postinst -+sed -e "s/exit 0//g" -i $tmpdir/DEBIAN/postinst -+cat >> $tmpdir/DEBIAN/postinst <<EOT -+ln -sf $(basename $installed_image_path) /boot/Image > /dev/null 2>&1 || mv /$installed_image_path /boot/Image -+touch /boot/.next -+exit 0 -+EOT -+ - # Try to determine maintainer and email values - if [ -n "$DEBEMAIL" ]; then - email=$DEBEMAIL -@@ -337,16 +379,24 @@ if grep -q '^CONFIG_GCC_PLUGINS=y' $KCONFIG_CONFIG ; then - fi - destdir=$kernel_headers_dir/usr/src/linux-headers-$version - mkdir -p "$destdir" -+######################## headers patch -+ZACNI=$(pwd) -+cd $destdir -+patch -p1 < /tmp/headers-debian-byteshift.patch -+cd $ZACNI -+######################## headers patch - (cd $srctree; tar -c -f - -T -) < "$objtree/debian/hdrsrcfiles" | (cd $destdir; tar -xf -) - (cd $objtree; tar -c -f - -T -) < "$objtree/debian/hdrobjfiles" | (cd $destdir; tar -xf -) - (cd $objtree; cp $KCONFIG_CONFIG $destdir/.config) # copy .config manually to be where it's expected to be - ln -sf "/usr/src/linux-headers-$version" "$kernel_headers_dir/lib/modules/$version/build" - rm -f "$objtree/debian/hdrsrcfiles" "$objtree/debian/hdrobjfiles" - -+(cd "$destdir"; make M=scripts clean) -+ - cat <<EOF >> debian/control - - Package: $kernel_headers_packagename --Provides: linux-headers, linux-headers-2.6 -+Provides: linux-headers - Architecture: any - Description: Linux kernel headers for $KERNELRELEASE on \${kernel:debarch} - This package provides kernel header files for $KERNELRELEASE on \${kernel:debarch} -@@ -372,6 +422,16 @@ fi - - cat <<EOF >> debian/control - -+Package: $dtb_packagename -+Architecture: any -+Description: Linux DTB, version $version -+ This package contains device blobs from the Linux kernel, version $version. -+EOF -+ -+create_package "$dtb_packagename" "$dtb_dir" -+ -+cat <<EOF >> debian/control -+ - Package: $libc_headers_packagename - Section: devel - Provides: linux-kernel-headers -@@ -383,7 +443,7 @@ EOF - - if [ "$ARCH" != "um" ]; then - create_package "$kernel_headers_packagename" "$kernel_headers_dir" -- create_package "$libc_headers_packagename" "$libc_headers_dir" -+# create_package "$libc_headers_packagename" "$libc_headers_dir" - fi - - create_package "$packagename" "$tmpdir" diff --git a/patch/kernel/sun50iw1-dev/remove-localversion.patch b/patch/kernel/sun50iw1-dev/remove-localversion.patch deleted file mode 100644 index 8083ac142..000000000 --- a/patch/kernel/sun50iw1-dev/remove-localversion.patch +++ /dev/null @@ -1,7 +0,0 @@ -diff --git a/localversion-next b/localversion-next -deleted file mode 100644 -index 299f8119..00000000 ---- a/localversion-next -+++ /dev/null -@@ -1 +0,0 @@ ---next-20170216 diff --git a/patch/kernel/sun50iw1-dev/scripts-dtc-Update-to-version-with-overlays.patch b/patch/kernel/sun50iw1-dev/scripts-dtc-Update-to-version-with-overlays.patch deleted file mode 100644 index bc3f71600..000000000 --- a/patch/kernel/sun50iw1-dev/scripts-dtc-Update-to-version-with-overlays.patch +++ /dev/null @@ -1,16 +0,0 @@ -diff --git a/scripts/Makefile.lib b/scripts/Makefile.lib -index ddf83d0..a0fb9e3 100644 ---- a/scripts/Makefile.lib -+++ b/scripts/Makefile.lib -@@ -275,7 +275,11 @@ cmd_gzip = (cat $(filter-out FORCE,$^) | gzip -n -f -9 > $@) || \ - - # DTC - # --------------------------------------------------------------------------- -+ifeq ($(CONFIG_OF_CONFIGFS),y) -+DTC ?= $(objtree)/scripts/dtc/dtc -@ -+else - DTC ?= $(objtree)/scripts/dtc/dtc -+endif - - # Generate an assembly file to wrap the output of the device tree compiler - quiet_cmd_dt_S_dtb= DTB $@ diff --git a/patch/kernel/sun50iw2-dev/add-h5-a64-simplefb.patch b/patch/kernel/sun50iw2-dev/add-h5-a64-simplefb.patch deleted file mode 100644 index 0e1eb6837..000000000 --- a/patch/kernel/sun50iw2-dev/add-h5-a64-simplefb.patch +++ /dev/null @@ -1,54 +0,0 @@ -diff --git a/arch/arm64/boot/dts/allwinner/sun50i-h5.dtsi b/arch/arm64/boot/dts/allwinner/sun50i-h5.dtsi -index 495edf5f..c0edd5c2 100644 ---- a/arch/arm64/boot/dts/allwinner/sun50i-h5.dtsi -+++ b/arch/arm64/boot/dts/allwinner/sun50i-h5.dtsi -@@ -45,6 +45,22 @@ - / { - interrupt-parent = <&gic>; - -+ chosen { -+ #address-cells = <1>; -+ #size-cells = <1>; -+ ranges; -+ -+ simplefb_hdmi: framebuffer@0 { -+ compatible = "allwinner,simple-framebuffer", -+ "simple-framebuffer"; -+ allwinner,pipeline = "de0-lcd0-hdmi"; -+ clocks = <&ccu CLK_BUS_TCON0>, <&ccu CLK_BUS_DE>, -+ <&ccu CLK_BUS_HDMI>, <&ccu CLK_DE>, -+ <&ccu CLK_TCON0>, <&ccu CLK_HDMI>; -+ status = "disabled"; -+ }; -+ }; -+ - cpus { - #address-cells = <1>; - #size-cells = <0>; -diff --git a/arch/arm64/boot/dts/allwinner/sun50i-a64.dtsi b/arch/arm64/boot/dts/allwinner/sun50i-a64.dtsi -index 100e9b49..e208e005 100644 ---- a/arch/arm64/boot/dts/allwinner/sun50i-a64.dtsi -+++ b/arch/arm64/boot/dts/allwinner/sun50i-a64.dtsi -@@ -52,6 +52,22 @@ - #address-cells = <1>; - #size-cells = <1>; - -+ chosen { -+ #address-cells = <1>; -+ #size-cells = <1>; -+ ranges; -+ -+ simplefb_hdmi: framebuffer@0 { -+ compatible = "allwinner,simple-framebuffer", -+ "simple-framebuffer"; -+ allwinner,pipeline = "de0-lcd0-hdmi"; -+ clocks = <&ccu CLK_BUS_TCON1>, <&ccu CLK_BUS_DE>, -+ <&ccu CLK_BUS_HDMI>, <&ccu CLK_DE>, -+ <&ccu CLK_TCON1>, <&ccu CLK_HDMI>; -+ status = "disabled"; -+ }; -+ }; -+ - cpus { - #address-cells = <1>; - #size-cells = <0>; diff --git a/patch/kernel/sun50iw2-dev/add-overlay-compilation-support.patch b/patch/kernel/sun50iw2-dev/add-overlay-compilation-support.patch deleted file mode 100644 index 361e9f86a..000000000 --- a/patch/kernel/sun50iw2-dev/add-overlay-compilation-support.patch +++ /dev/null @@ -1,123 +0,0 @@ -diff --git a/arch/arm/Makefile b/arch/arm/Makefile -index ab30cc63..cc176797 100644 ---- a/arch/arm/Makefile -+++ b/arch/arm/Makefile -@@ -339,6 +339,12 @@ $(INSTALL_TARGETS): - %.dtb: | scripts - $(Q)$(MAKE) $(build)=$(boot)/dts MACHINE=$(MACHINE) $(boot)/dts/$@ - -+%.dtbo: | scripts -+ $(Q)$(MAKE) $(build)=$(boot)/dts MACHINE=$(MACHINE) $(boot)/dts/$@ -+ -+%.scr: | scripts -+ $(Q)$(MAKE) $(build)=$(boot)/dts ARCH=$(ARCH) $(boot)/dts/$@ -+ - PHONY += dtbs dtbs_install - - dtbs: prepare scripts -diff --git a/arch/arm/boot/.gitignore b/arch/arm/boot/.gitignore -index 3c79f859..eaaeb17e 100644 ---- a/arch/arm/boot/.gitignore -+++ b/arch/arm/boot/.gitignore -@@ -3,4 +3,5 @@ zImage - xipImage - bootpImage - uImage --*.dtb -+*.dtb* -+*.scr -diff --git a/arch/arm64/Makefile b/arch/arm64/Makefile -index b9a4a934..54e3c38d 100644 ---- a/arch/arm64/Makefile -+++ b/arch/arm64/Makefile -@@ -119,6 +119,12 @@ zinstall install: - %.dtb: scripts - $(Q)$(MAKE) $(build)=$(boot)/dts $(boot)/dts/$@ - -+%.dtbo: | scripts -+ $(Q)$(MAKE) $(build)=$(boot)/dts MACHINE=$(MACHINE) $(boot)/dts/$@ -+ -+%.scr: | scripts -+ $(Q)$(MAKE) $(build)=$(boot)/dts ARCH=$(ARCH) $(boot)/dts/$@ -+ - PHONY += dtbs dtbs_install - - dtbs: prepare scripts -diff --git a/arch/arm64/boot/dts/.gitignore b/arch/arm64/boot/dts/.gitignore -index b60ed208..5d65b54b 100644 ---- a/arch/arm64/boot/dts/.gitignore -+++ b/arch/arm64/boot/dts/.gitignore -@@ -1 +1,2 @@ --*.dtb -+*.dtb* -+*.scr -diff --git a/scripts/Makefile.dtbinst b/scripts/Makefile.dtbinst -index a1be75d0..ad8dc1c9 100644 ---- a/scripts/Makefile.dtbinst -+++ b/scripts/Makefile.dtbinst -@@ -27,6 +27,9 @@ ifeq ("$(dtbinst-root)", "$(obj)") - endif - - dtbinst-files := $(dtb-y) -+dtboinst-files := $(dtbo-y) -+script-files := $(scr-y) -+readme-files := $(dtbotxt-y) - dtbinst-dirs := $(dts-dirs) - - # Helper targets for Installing DTBs into the boot directory -@@ -35,15 +38,24 @@ quiet_cmd_dtb_install = INSTALL $< - - install-dir = $(patsubst $(dtbinst-root)%,$(INSTALL_DTBS_PATH)%,$(obj)) - --$(dtbinst-files) $(dtbinst-dirs): | __dtbs_install_prep -+$(dtbinst-files) $(dtboinst-files) $(readme-files) $(script-files) $(dtbinst-dirs): | __dtbs_install_prep - - $(dtbinst-files): %.dtb: $(obj)/%.dtb - $(call cmd,dtb_install,$(install-dir)) - -+$(dtboinst-files): %.dtbo: $(obj)/%.dtbo -+ $(call cmd,dtb_install,$(install-dir)) -+ -+$(script-files): %.scr: $(obj)/%.scr -+ $(call cmd,dtb_install,$(install-dir)) -+ -+$(readme-files): %: $(src)/% -+ $(call cmd,dtb_install,$(install-dir)) -+ - $(dtbinst-dirs): - $(Q)$(MAKE) $(dtbinst)=$(obj)/$@ - --PHONY += $(dtbinst-files) $(dtbinst-dirs) --__dtbs_install: $(dtbinst-files) $(dtbinst-dirs) -+PHONY += $(dtbinst-files) $(dtboinst-files) $(script-files) $(readme-files) $(dtbinst-dirs) -+__dtbs_install: $(dtbinst-files) $(dtboinst-files) $(script-files) $(readme-files) $(dtbinst-dirs) - - .PHONY: $(PHONY) -diff --git a/scripts/Makefile.lib b/scripts/Makefile.lib -index 0a07f901..5ccd3490 100644 ---- a/scripts/Makefile.lib -+++ b/scripts/Makefile.lib -@@ -312,6 +312,23 @@ cmd_dtc = mkdir -p $(dir ${dtc-tmp}) ; \ - $(obj)/%.dtb: $(src)/%.dts FORCE - $(call if_changed_dep,dtc) - -+quiet_cmd_dtco = DTCO $@ -+cmd_dtco = mkdir -p $(dir ${dtc-tmp}) ; \ -+ $(CPP) $(dtc_cpp_flags) -x assembler-with-cpp -o $(dtc-tmp) $< ; \ -+ $(DTC) -O dtb -o $@ -b 0 \ -+ -i $(dir $<) $(DTC_FLAGS) \ -+ -d $(depfile).dtc.tmp $(dtc-tmp) ; \ -+ cat $(depfile).pre.tmp $(depfile).dtc.tmp > $(depfile) -+ -+$(obj)/%.dtbo: $(src)/%.dts FORCE -+ $(call if_changed_dep,dtco) -+ -+quiet_cmd_scr = MKIMAGE $@ -+cmd_scr = mkimage -C none -A $(ARCH) -T script -d $< $@ -+ -+$(obj)/%.scr: $(src)/%.scr-cmd FORCE -+ $(call if_changed,scr) -+ - dtc-tmp = $(subst $(comma),_,$(dot-target).dts.tmp) - - # Bzip2 diff --git a/patch/kernel/sun50iw2-dev/add_BergMicro_flashes_to_SPI-NOR.patch b/patch/kernel/sun50iw2-dev/add_BergMicro_flashes_to_SPI-NOR.patch deleted file mode 100644 index 87d97f508..000000000 --- a/patch/kernel/sun50iw2-dev/add_BergMicro_flashes_to_SPI-NOR.patch +++ /dev/null @@ -1,18 +0,0 @@ -diff --git a/drivers/mtd/spi-nor/spi-nor.c b/drivers/mtd/spi-nor/spi-nor.c -index d0fc165..4510c2d 100644 ---- a/drivers/mtd/spi-nor/spi-nor.c -+++ b/drivers/mtd/spi-nor/spi-nor.c -@@ -809,6 +809,13 @@ static const struct flash_info spi_nor_ids[] = { - - { "at45db081d", INFO(0x1f2500, 0, 64 * 1024, 16, SECT_4K) }, - -+ /* BergMicro Flashes */ -+ { "bg25q80", INFO(0xe04014, 0, 64 * 1024, 16, SECT_4K) }, -+ { "bg25q16", INFO(0xe04015, 0, 64 * 1024, 32, SECT_4K) }, -+ { "bg25q32", INFO(0xe04016, 0, 64 * 1024, 64, SECT_4K) }, -+ { "bg25q64", INFO(0xe04017, 0, 64 * 1024, 128, SECT_4K) }, -+ { "bg25q128", INFO(0xe04018, 0, 64 * 1024, 256, SECT_4K) }, -+ - /* EON -- en25xxx */ - { "en25f32", INFO(0x1c3116, 0, 64 * 1024, 64, SECT_4K) }, - { "en25p32", INFO(0x1c2016, 0, 64 * 1024, 64, 0) }, diff --git a/patch/kernel/sun50iw2-dev/add_configfs_overlay_for_v4.10.x.patch b/patch/kernel/sun50iw2-dev/add_configfs_overlay_for_v4.10.x.patch deleted file mode 100644 index 006766a22..000000000 --- a/patch/kernel/sun50iw2-dev/add_configfs_overlay_for_v4.10.x.patch +++ /dev/null @@ -1,360 +0,0 @@ -diff --git a/drivers/of/Kconfig b/drivers/of/Kconfig -index bc07ad3..e9da9cf 100644 ---- a/drivers/of/Kconfig -+++ b/drivers/of/Kconfig -@@ -113,6 +113,13 @@ config OF_OVERLAY - While this option is selected automatically when needed, you can - enable it manually to improve device tree unit test coverage. - -+config OF_CONFIGFS -+ bool "Device Tree Overlay ConfigFS interface" -+ select CONFIGFS_FS -+ depends on OF_OVERLAY -+ help -+ Enable a simple user-space driven DT overlay interface. -+ - config OF_NUMA - bool - -diff --git a/drivers/of/Makefile b/drivers/of/Makefile -index d7efd9d..a06cc35 100644 ---- a/drivers/of/Makefile -+++ b/drivers/of/Makefile -@@ -13,6 +13,7 @@ obj-$(CONFIG_OF_PCI_IRQ) += of_pci_irq.o - obj-$(CONFIG_OF_RESERVED_MEM) += of_reserved_mem.o - obj-$(CONFIG_OF_RESOLVE) += resolver.o - obj-$(CONFIG_OF_OVERLAY) += overlay.o -+obj-$(CONFIG_OF_CONFIGFS) += configfs.o - obj-$(CONFIG_OF_NUMA) += of_numa.o - - obj-$(CONFIG_OF_UNITTEST) += unittest-data/ -diff --git a/drivers/of/configfs.c b/drivers/of/configfs.c -new file mode 100644 -index 0000000..68f889d ---- /dev/null -+++ b/drivers/of/configfs.c -@@ -0,0 +1,311 @@ -+/* -+ * Configfs entries for device-tree -+ * -+ * Copyright (C) 2013 - Pantelis Antoniou <panto@antoniou-consulting.com> -+ * -+ * This program is free software; you can redistribute it and/or -+ * modify it under the terms of the GNU General Public License -+ * as published by the Free Software Foundation; either version -+ * 2 of the License, or (at your option) any later version. -+ */ -+#include <linux/ctype.h> -+#include <linux/cpu.h> -+#include <linux/module.h> -+#include <linux/of.h> -+#include <linux/of_fdt.h> -+#include <linux/spinlock.h> -+#include <linux/slab.h> -+#include <linux/proc_fs.h> -+#include <linux/configfs.h> -+#include <linux/types.h> -+#include <linux/stat.h> -+#include <linux/limits.h> -+#include <linux/file.h> -+#include <linux/vmalloc.h> -+#include <linux/firmware.h> -+#include <linux/sizes.h> -+ -+#include "of_private.h" -+ -+struct cfs_overlay_item { -+ struct config_item item; -+ -+ char path[PATH_MAX]; -+ -+ const struct firmware *fw; -+ struct device_node *overlay; -+ int ov_id; -+ -+ void *dtbo; -+ int dtbo_size; -+}; -+ -+static int create_overlay(struct cfs_overlay_item *overlay, void *blob) -+{ -+ int err; -+ -+ /* unflatten the tree */ -+ of_fdt_unflatten_tree(blob, NULL, &overlay->overlay); -+ if (overlay->overlay == NULL) { -+ pr_err("%s: failed to unflatten tree\n", __func__); -+ err = -EINVAL; -+ goto out_err; -+ } -+ pr_debug("%s: unflattened OK\n", __func__); -+ -+ /* mark it as detached */ -+ of_node_set_flag(overlay->overlay, OF_DETACHED); -+ -+ /* perform resolution */ -+ err = of_resolve_phandles(overlay->overlay); -+ if (err != 0) { -+ pr_err("%s: Failed to resolve tree\n", __func__); -+ goto out_err; -+ } -+ pr_debug("%s: resolved OK\n", __func__); -+ -+ err = of_overlay_create(overlay->overlay); -+ if (err < 0) { -+ pr_err("%s: Failed to create overlay (err=%d)\n", -+ __func__, err); -+ goto out_err; -+ } -+ overlay->ov_id = err; -+ -+out_err: -+ return err; -+} -+ -+static inline struct cfs_overlay_item *to_cfs_overlay_item( -+ struct config_item *item) -+{ -+ return item ? container_of(item, struct cfs_overlay_item, item) : NULL; -+} -+ -+static ssize_t cfs_overlay_item_path_show(struct config_item *item, -+ char *page) -+{ -+ struct cfs_overlay_item *overlay = to_cfs_overlay_item(item); -+ return sprintf(page, "%s\n", overlay->path); -+} -+ -+static ssize_t cfs_overlay_item_path_store(struct config_item *item, -+ const char *page, size_t count) -+{ -+ struct cfs_overlay_item *overlay = to_cfs_overlay_item(item); -+ const char *p = page; -+ char *s; -+ int err; -+ -+ /* if it's set do not allow changes */ -+ if (overlay->path[0] != '\0' || overlay->dtbo_size > 0) -+ return -EPERM; -+ -+ /* copy to path buffer (and make sure it's always zero terminated */ -+ count = snprintf(overlay->path, sizeof(overlay->path) - 1, "%s", p); -+ overlay->path[sizeof(overlay->path) - 1] = '\0'; -+ -+ /* strip trailing newlines */ -+ s = overlay->path + strlen(overlay->path); -+ while (s > overlay->path && *--s == '\n') -+ *s = '\0'; -+ -+ pr_debug("%s: path is '%s'\n", __func__, overlay->path); -+ -+ err = request_firmware(&overlay->fw, overlay->path, NULL); -+ if (err != 0) -+ goto out_err; -+ -+ err = create_overlay(overlay, (void *)overlay->fw->data); -+ if (err != 0) -+ goto out_err; -+ -+ return count; -+ -+out_err: -+ -+ release_firmware(overlay->fw); -+ overlay->fw = NULL; -+ -+ overlay->path[0] = '\0'; -+ return err; -+} -+ -+static ssize_t cfs_overlay_item_status_show(struct config_item *item, -+ char *page) -+{ -+ struct cfs_overlay_item *overlay = to_cfs_overlay_item(item); -+ -+ return sprintf(page, "%s\n", -+ overlay->ov_id >= 0 ? "applied" : "unapplied"); -+} -+ -+CONFIGFS_ATTR(cfs_overlay_item_, path); -+CONFIGFS_ATTR_RO(cfs_overlay_item_, status); -+ -+static struct configfs_attribute *cfs_overlay_attrs[] = { -+ &cfs_overlay_item_attr_path, -+ &cfs_overlay_item_attr_status, -+ NULL, -+}; -+ -+ssize_t cfs_overlay_item_dtbo_read(struct config_item *item, -+ void *buf, size_t max_count) -+{ -+ struct cfs_overlay_item *overlay = to_cfs_overlay_item(item); -+ -+ pr_debug("%s: buf=%p max_count=%zu\n", __func__, -+ buf, max_count); -+ -+ if (overlay->dtbo == NULL) -+ return 0; -+ -+ /* copy if buffer provided */ -+ if (buf != NULL) { -+ /* the buffer must be large enough */ -+ if (overlay->dtbo_size > max_count) -+ return -ENOSPC; -+ -+ memcpy(buf, overlay->dtbo, overlay->dtbo_size); -+ } -+ -+ return overlay->dtbo_size; -+} -+ -+ssize_t cfs_overlay_item_dtbo_write(struct config_item *item, -+ const void *buf, size_t count) -+{ -+ struct cfs_overlay_item *overlay = to_cfs_overlay_item(item); -+ int err; -+ -+ /* if it's set do not allow changes */ -+ if (overlay->path[0] != '\0' || overlay->dtbo_size > 0) -+ return -EPERM; -+ -+ /* copy the contents */ -+ overlay->dtbo = kmemdup(buf, count, GFP_KERNEL); -+ if (overlay->dtbo == NULL) -+ return -ENOMEM; -+ -+ overlay->dtbo_size = count; -+ -+ err = create_overlay(overlay, overlay->dtbo); -+ if (err != 0) -+ goto out_err; -+ -+ return count; -+ -+out_err: -+ kfree(overlay->dtbo); -+ overlay->dtbo = NULL; -+ overlay->dtbo_size = 0; -+ -+ return err; -+} -+ -+CONFIGFS_BIN_ATTR(cfs_overlay_item_, dtbo, NULL, SZ_1M); -+ -+static struct configfs_bin_attribute *cfs_overlay_bin_attrs[] = { -+ &cfs_overlay_item_attr_dtbo, -+ NULL, -+}; -+ -+static void cfs_overlay_release(struct config_item *item) -+{ -+ struct cfs_overlay_item *overlay = to_cfs_overlay_item(item); -+ -+ if (overlay->ov_id >= 0) -+ of_overlay_destroy(overlay->ov_id); -+ if (overlay->fw) -+ release_firmware(overlay->fw); -+ /* kfree with NULL is safe */ -+ kfree(overlay->dtbo); -+ kfree(overlay); -+} -+ -+static struct configfs_item_operations cfs_overlay_item_ops = { -+ .release = cfs_overlay_release, -+}; -+ -+static struct config_item_type cfs_overlay_type = { -+ .ct_item_ops = &cfs_overlay_item_ops, -+ .ct_attrs = cfs_overlay_attrs, -+ .ct_bin_attrs = cfs_overlay_bin_attrs, -+ .ct_owner = THIS_MODULE, -+}; -+ -+static struct config_item *cfs_overlay_group_make_item( -+ struct config_group *group, const char *name) -+{ -+ struct cfs_overlay_item *overlay; -+ -+ overlay = kzalloc(sizeof(*overlay), GFP_KERNEL); -+ if (!overlay) -+ return ERR_PTR(-ENOMEM); -+ overlay->ov_id = -1; -+ -+ config_item_init_type_name(&overlay->item, name, &cfs_overlay_type); -+ return &overlay->item; -+} -+ -+static void cfs_overlay_group_drop_item(struct config_group *group, -+ struct config_item *item) -+{ -+ struct cfs_overlay_item *overlay = to_cfs_overlay_item(item); -+ -+ config_item_put(&overlay->item); -+} -+ -+static struct configfs_group_operations overlays_ops = { -+ .make_item = cfs_overlay_group_make_item, -+ .drop_item = cfs_overlay_group_drop_item, -+}; -+ -+static struct config_item_type overlays_type = { -+ .ct_group_ops = &overlays_ops, -+ .ct_owner = THIS_MODULE, -+}; -+ -+static struct configfs_group_operations of_cfs_ops = { -+ /* empty - we don't allow anything to be created */ -+}; -+ -+static struct config_item_type of_cfs_type = { -+ .ct_group_ops = &of_cfs_ops, -+ .ct_owner = THIS_MODULE, -+}; -+ -+struct config_group of_cfs_overlay_group; -+ -+static struct configfs_subsystem of_cfs_subsys = { -+ .su_group = { -+ .cg_item = { -+ .ci_namebuf = "device-tree", -+ .ci_type = &of_cfs_type, -+ }, -+ }, -+ .su_mutex = __MUTEX_INITIALIZER(of_cfs_subsys.su_mutex), -+}; -+ -+static int __init of_cfs_init(void) -+{ -+ int ret; -+ -+ pr_info("%s\n", __func__); -+ -+ config_group_init(&of_cfs_subsys.su_group); -+ config_group_init_type_name(&of_cfs_overlay_group, "overlays", -+ &overlays_type); -+ configfs_add_default_group(&of_cfs_overlay_group, -+ &of_cfs_subsys.su_group); -+ -+ ret = configfs_register_subsystem(&of_cfs_subsys); -+ if (ret != 0) { -+ pr_err("%s: failed to register subsys\n", __func__); -+ goto out; -+ } -+ pr_info("%s: OK\n", __func__); -+out: -+ return ret; -+} -+late_initcall(of_cfs_init); -diff --git a/drivers/of/fdt_address.c b/drivers/of/fdt_address.c -index dca8f9b..ec7e167 100644 ---- a/drivers/of/fdt_address.c -+++ b/drivers/of/fdt_address.c -@@ -161,7 +161,7 @@ static int __init fdt_translate_one(const void *blob, int parent, - * that can be mapped to a cpu physical address). This is not really specified - * that way, but this is traditionally the way IBM at least do things - */ --static u64 __init fdt_translate_address(const void *blob, int node_offset) -+u64 __init fdt_translate_address(const void *blob, int node_offset) - { - int parent, len; - const struct of_bus *bus, *pbus; diff --git a/patch/kernel/sun50iw2-dev/add_proc_cpuinfo_entries_for_v4.9.x.patch b/patch/kernel/sun50iw2-dev/add_proc_cpuinfo_entries_for_v4.9.x.patch deleted file mode 100644 index 49338fb4b..000000000 --- a/patch/kernel/sun50iw2-dev/add_proc_cpuinfo_entries_for_v4.9.x.patch +++ /dev/null @@ -1,13 +0,0 @@ -diff --git a/arch/arm64/kernel/cpuinfo.c b/arch/arm64/kernel/cpuinfo.c -index b3d5b3e..9520280 100644 ---- a/arch/arm64/kernel/cpuinfo.c -+++ b/arch/arm64/kernel/cpuinfo.c -@@ -118,6 +118,8 @@ static int c_show(struct seq_file *m, void *v) - * "processor". Give glibc what it expects. - */ - seq_printf(m, "processor\t: %d\n", i); -+ seq_printf(m, "Processor\t: AArch64 Processor rev %d (aarch64)\n", MIDR_REVISION(midr)); -+ seq_printf(m, "Hardware\t: sun50iw1p1\n"); - if (compat) - seq_printf(m, "model name\t: ARMv8 Processor rev %d (%s)\n", - MIDR_REVISION(midr), COMPAT_ELF_PLATFORM); diff --git a/patch/kernel/sun50iw2-dev/add_sun50i_a64_rccu.patch b/patch/kernel/sun50iw2-dev/add_sun50i_a64_rccu.patch deleted file mode 100644 index afbf6308b..000000000 --- a/patch/kernel/sun50iw2-dev/add_sun50i_a64_rccu.patch +++ /dev/null @@ -1,404 +0,0 @@ -diff --git a/drivers/clk/sunxi-ng/Kconfig b/drivers/clk/sunxi-ng/Kconfig -index 8af8f4be8e3b..fbd3f8cd5c22 100644 ---- a/drivers/clk/sunxi-ng/Kconfig -+++ b/drivers/clk/sunxi-ng/Kconfig -@@ -151,4 +151,10 @@ config SUN9I_A80_CCU - default MACH_SUN9I - depends on MACH_SUN9I || COMPILE_TEST - -+config SUN8I_R_CCU -+ bool "Support for Allwinner SoCs' PRCM CCUs" -+ select SUNXI_CCU_DIV -+ select SUNXI_CCU_GATE -+ default MACH_SUN8I || (ARCH_SUNXI && ARM64) -+ - endif -diff --git a/drivers/clk/sunxi-ng/Makefile b/drivers/clk/sunxi-ng/Makefile -index 6feaac0c5600..0ec02fe14c50 100644 ---- a/drivers/clk/sunxi-ng/Makefile -+++ b/drivers/clk/sunxi-ng/Makefile -@@ -25,6 +25,7 @@ obj-$(CONFIG_SUN8I_A23_CCU) += ccu-sun8i-a23.o - obj-$(CONFIG_SUN8I_A33_CCU) += ccu-sun8i-a33.o - obj-$(CONFIG_SUN8I_H3_CCU) += ccu-sun8i-h3.o - obj-$(CONFIG_SUN8I_V3S_CCU) += ccu-sun8i-v3s.o -+obj-$(CONFIG_SUN8I_R_CCU) += ccu-sun8i-r.o - obj-$(CONFIG_SUN9I_A80_CCU) += ccu-sun9i-a80.o - obj-$(CONFIG_SUN9I_A80_CCU) += ccu-sun9i-a80-de.o - obj-$(CONFIG_SUN9I_A80_CCU) += ccu-sun9i-a80-usb.o -diff --git a/drivers/clk/sunxi-ng/ccu-sun8i-r.c b/drivers/clk/sunxi-ng/ccu-sun8i-r.c -new file mode 100644 -index 000000000000..0d027d53dbdf ---- /dev/null -+++ b/drivers/clk/sunxi-ng/ccu-sun8i-r.c -@@ -0,0 +1,213 @@ -+/* -+ * Copyright (c) 2016 Icenowy Zheng <icenowy@aosc.xyz> -+ * -+ * This software is licensed under the terms of the GNU General Public -+ * License version 2, as published by the Free Software Foundation, and -+ * may be copied, distributed, and modified under those terms. -+ * -+ * This program is distributed in the hope that it will be useful, -+ * but WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+ * GNU General Public License for more details. -+ */ -+ -+#include <linux/clk-provider.h> -+#include <linux/of_address.h> -+#include <linux/platform_device.h> -+ -+#include "ccu_common.h" -+#include "ccu_reset.h" -+ -+#include "ccu_div.h" -+#include "ccu_gate.h" -+#include "ccu_mp.h" -+#include "ccu_nm.h" -+ -+#include "ccu-sun8i-r.h" -+ -+static const char * const ar100_parents[] = { "osc32K", "osc24M", -+ "pll-periph0", "iosc" }; -+ -+static struct ccu_div ar100_clk = { -+ .div = _SUNXI_CCU_DIV_FLAGS(4, 2, CLK_DIVIDER_POWER_OF_TWO), -+ -+ .mux = { -+ .shift = 16, -+ .width = 2, -+ -+ .variable_prediv = { -+ .index = 2, -+ .shift = 8, -+ .width = 5, -+ }, -+ }, -+ -+ .common = { -+ .reg = 0x00, -+ .features = CCU_FEATURE_VARIABLE_PREDIV, -+ .hw.init = CLK_HW_INIT_PARENTS("ar100", -+ ar100_parents, -+ &ccu_div_ops, -+ 0), -+ }, -+}; -+ -+static CLK_FIXED_FACTOR(ahb0_clk, "ahb0", "ar100", 1, 1, 0); -+ -+static struct ccu_div apb0_clk = { -+ .div = _SUNXI_CCU_DIV_FLAGS(0, 2, CLK_DIVIDER_POWER_OF_TWO), -+ -+ .common = { -+ .reg = 0x0c, -+ .hw.init = CLK_HW_INIT("apb0", -+ "ahb0", -+ &ccu_div_ops, -+ 0), -+ }, -+}; -+ -+static SUNXI_CCU_GATE(apb0_pio_clk, "apb0-pio", "apb0", -+ 0x28, BIT(0), 0); -+static SUNXI_CCU_GATE(apb0_ir_clk, "apb0-ir", "apb0", -+ 0x28, BIT(1), 0); -+static SUNXI_CCU_GATE(apb0_timer_clk, "apb0-timer", "apb0", -+ 0x28, BIT(2), 0); -+static SUNXI_CCU_GATE(apb0_rsb_clk, "apb0-rsb", "apb0", -+ 0x28, BIT(3), 0); -+static SUNXI_CCU_GATE(apb0_uart_clk, "apb0-uart", "apb0", -+ 0x28, BIT(4), 0); -+static SUNXI_CCU_GATE(apb0_i2c_clk, "apb0-i2c", "apb0", -+ 0x28, BIT(6), 0); -+static SUNXI_CCU_GATE(apb0_twd_clk, "apb0-twd", "apb0", -+ 0x28, BIT(7), 0); -+ -+static const char * const r_mod0_default_parents[] = { "osc32K", "osc24M" }; -+static SUNXI_CCU_MP_WITH_MUX_GATE(ir_clk, "ir", -+ r_mod0_default_parents, 0x54, -+ 0, 4, /* M */ -+ 16, 2, /* P */ -+ 24, 2, /* mux */ -+ BIT(31), /* gate */ -+ 0); -+ -+static struct ccu_common *sun8i_h3_r_ccu_clks[] = { -+ &ar100_clk.common, -+ &apb0_clk.common, -+ &apb0_pio_clk.common, -+ &apb0_ir_clk.common, -+ &apb0_timer_clk.common, -+ &apb0_uart_clk.common, -+ &apb0_i2c_clk.common, -+ &apb0_twd_clk.common, -+ &ir_clk.common, -+}; -+ -+static struct ccu_common *sun50i_a64_r_ccu_clks[] = { -+ &ar100_clk.common, -+ &apb0_clk.common, -+ &apb0_pio_clk.common, -+ &apb0_ir_clk.common, -+ &apb0_timer_clk.common, -+ &apb0_rsb_clk.common, -+ &apb0_uart_clk.common, -+ &apb0_i2c_clk.common, -+ &apb0_twd_clk.common, -+ &ir_clk.common, -+}; -+ -+static struct clk_hw_onecell_data sun8i_h3_r_hw_clks = { -+ .hws = { -+ [CLK_AR100] = &ar100_clk.common.hw, -+ [CLK_AHB0] = &ahb0_clk.hw, -+ [CLK_APB0] = &apb0_clk.common.hw, -+ [CLK_APB0_PIO] = &apb0_pio_clk.common.hw, -+ [CLK_APB0_IR] = &apb0_ir_clk.common.hw, -+ [CLK_APB0_TIMER] = &apb0_timer_clk.common.hw, -+ [CLK_APB0_UART] = &apb0_uart_clk.common.hw, -+ [CLK_APB0_I2C] = &apb0_i2c_clk.common.hw, -+ [CLK_APB0_TWD] = &apb0_twd_clk.common.hw, -+ [CLK_IR] = &ir_clk.common.hw, -+ }, -+ .num = CLK_NUMBER, -+}; -+ -+static struct clk_hw_onecell_data sun50i_a64_r_hw_clks = { -+ .hws = { -+ [CLK_AR100] = &ar100_clk.common.hw, -+ [CLK_AHB0] = &ahb0_clk.hw, -+ [CLK_APB0] = &apb0_clk.common.hw, -+ [CLK_APB0_PIO] = &apb0_pio_clk.common.hw, -+ [CLK_APB0_IR] = &apb0_ir_clk.common.hw, -+ [CLK_APB0_TIMER] = &apb0_timer_clk.common.hw, -+ [CLK_APB0_RSB] = &apb0_rsb_clk.common.hw, -+ [CLK_APB0_UART] = &apb0_uart_clk.common.hw, -+ [CLK_APB0_I2C] = &apb0_i2c_clk.common.hw, -+ [CLK_APB0_TWD] = &apb0_twd_clk.common.hw, -+ [CLK_IR] = &ir_clk.common.hw, -+ }, -+ .num = CLK_NUMBER, -+}; -+ -+static struct ccu_reset_map sun8i_h3_r_ccu_resets[] = { -+ [RST_APB0_IR] = { 0xb0, BIT(1) }, -+ [RST_APB0_TIMER] = { 0xb0, BIT(2) }, -+ [RST_APB0_UART] = { 0xb0, BIT(4) }, -+ [RST_APB0_I2C] = { 0xb0, BIT(6) }, -+}; -+ -+static struct ccu_reset_map sun50i_a64_r_ccu_resets[] = { -+ [RST_APB0_IR] = { 0xb0, BIT(1) }, -+ [RST_APB0_TIMER] = { 0xb0, BIT(2) }, -+ [RST_APB0_RSB] = { 0xb0, BIT(3) }, -+ [RST_APB0_UART] = { 0xb0, BIT(4) }, -+ [RST_APB0_I2C] = { 0xb0, BIT(6) }, -+}; -+ -+static const struct sunxi_ccu_desc sun8i_h3_r_ccu_desc = { -+ .ccu_clks = sun8i_h3_r_ccu_clks, -+ .num_ccu_clks = ARRAY_SIZE(sun8i_h3_r_ccu_clks), -+ -+ .hw_clks = &sun8i_h3_r_hw_clks, -+ -+ .resets = sun8i_h3_r_ccu_resets, -+ .num_resets = ARRAY_SIZE(sun8i_h3_r_ccu_resets), -+}; -+ -+static const struct sunxi_ccu_desc sun50i_a64_r_ccu_desc = { -+ .ccu_clks = sun50i_a64_r_ccu_clks, -+ .num_ccu_clks = ARRAY_SIZE(sun50i_a64_r_ccu_clks), -+ -+ .hw_clks = &sun50i_a64_r_hw_clks, -+ -+ .resets = sun50i_a64_r_ccu_resets, -+ .num_resets = ARRAY_SIZE(sun50i_a64_r_ccu_resets), -+}; -+ -+static void __init sunxi_r_ccu_init(struct device_node *node, -+ const struct sunxi_ccu_desc *desc) -+{ -+ void __iomem *reg; -+ -+ reg = of_io_request_and_map(node, 0, of_node_full_name(node)); -+ if (IS_ERR(reg)) { -+ pr_err("%s: Could not map the clock registers\n", -+ of_node_full_name(node)); -+ return; -+ } -+ -+ sunxi_ccu_probe(node, reg, desc); -+} -+ -+static void __init sun8i_h3_r_ccu_setup(struct device_node *node) -+{ -+ sunxi_r_ccu_init(node, &sun8i_h3_r_ccu_desc); -+} -+CLK_OF_DECLARE(sun8i_h3_r_ccu, "allwinner,sun8i-h3-r-ccu", -+ sun8i_h3_r_ccu_setup); -+ -+static void __init sun50i_a64_r_ccu_setup(struct device_node *node) -+{ -+ sunxi_r_ccu_init(node, &sun50i_a64_r_ccu_desc); -+} -+CLK_OF_DECLARE(sun50i_a64_r_ccu, "allwinner,sun50i-a64-r-ccu", -+ sun50i_a64_r_ccu_setup); -diff --git a/drivers/clk/sunxi-ng/ccu-sun8i-r.h b/drivers/clk/sunxi-ng/ccu-sun8i-r.h -new file mode 100644 -index 000000000000..eaa431fd1d8f ---- /dev/null -+++ b/drivers/clk/sunxi-ng/ccu-sun8i-r.h -@@ -0,0 +1,27 @@ -+/* -+ * Copyright 2016 Icenowy <icenowy@aosc.xyz> -+ * -+ * This program is free software; you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License as published by -+ * the Free Software Foundation; either version 2 of the License, or -+ * (at your option) any later version. -+ * -+ * This program is distributed in the hope that it will be useful, -+ * but WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+ * GNU General Public License for more details. -+ */ -+ -+#ifndef _CCU_SUN8I_R_H -+#define _CCU_SUN8I_R_H_ -+ -+#include <dt-bindings/clock/sun8i-r-ccu.h> -+#include <dt-bindings/reset/sun8i-r-ccu.h> -+ -+/* AHB/APB bus clocks are not exported */ -+#define CLK_AHB0 1 -+#define CLK_APB0 2 -+ -+#define CLK_NUMBER (CLK_IR + 1) -+ -+#endif /* _CCU_SUN8I_R_H */ -diff --git a/include/dt-bindings/clock/sun8i-r-ccu.h b/include/dt-bindings/clock/sun8i-r-ccu.h -new file mode 100644 -index 000000000000..779d20aa0d05 ---- /dev/null -+++ b/include/dt-bindings/clock/sun8i-r-ccu.h -@@ -0,0 +1,59 @@ -+/* -+ * Copyright (c) 2016 Icenowy Zheng <icenowy@aosc.xyz> -+ * -+ * This file is dual-licensed: you can use it either under the terms -+ * of the GPL or the X11 license, at your option. Note that this dual -+ * licensing only applies to this file, and not this project as a -+ * whole. -+ * -+ * a) This file is free software; you can redistribute it and/or -+ * modify it under the terms of the GNU General Public License as -+ * published by the Free Software Foundation; either version 2 of the -+ * License, or (at your option) any later version. -+ * -+ * This file is distributed in the hope that it will be useful, -+ * but WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+ * GNU General Public License for more details. -+ * -+ * Or, alternatively, -+ * -+ * b) Permission is hereby granted, free of charge, to any person -+ * obtaining a copy of this software and associated documentation -+ * files (the "Software"), to deal in the Software without -+ * restriction, including without limitation the rights to use, -+ * copy, modify, merge, publish, distribute, sublicense, and/or -+ * sell copies of the Software, and to permit persons to whom the -+ * Software is furnished to do so, subject to the following -+ * conditions: -+ * -+ * The above copyright notice and this permission notice shall be -+ * included in all copies or substantial portions of the Software. -+ * -+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES -+ * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT -+ * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, -+ * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING -+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR -+ * OTHER DEALINGS IN THE SOFTWARE. -+ */ -+ -+#ifndef _DT_BINDINGS_CLK_SUN8I_R_CCU_H_ -+#define _DT_BINDINGS_CLK_SUN8I_R_CCU_H_ -+ -+#define CLK_AR100 0 -+ -+#define CLK_APB0_PIO 3 -+#define CLK_APB0_IR 4 -+#define CLK_APB0_TIMER 5 -+#define CLK_APB0_RSB 6 -+#define CLK_APB0_UART 7 -+/* 8 is reserved for CLK_APB0_W1 on A31 */ -+#define CLK_APB0_I2C 9 -+#define CLK_APB0_TWD 10 -+ -+#define CLK_IR 11 -+ -+#endif /* _DT_BINDINGS_CLK_SUN8I_R_CCU_H_ */ -diff --git a/include/dt-bindings/reset/sun8i-r-ccu.h b/include/dt-bindings/reset/sun8i-r-ccu.h -new file mode 100644 -index 000000000000..4ba64f3d6fc9 ---- /dev/null -+++ b/include/dt-bindings/reset/sun8i-r-ccu.h -@@ -0,0 +1,53 @@ -+/* -+ * Copyright (C) 2016 Icenowy Zheng <icenowy@aosc.xyz> -+ * -+ * This file is dual-licensed: you can use it either under the terms -+ * of the GPL or the X11 license, at your option. Note that this dual -+ * licensing only applies to this file, and not this project as a -+ * whole. -+ * -+ * a) This file is free software; you can redistribute it and/or -+ * modify it under the terms of the GNU General Public License as -+ * published by the Free Software Foundation; either version 2 of the -+ * License, or (at your option) any later version. -+ * -+ * This file is distributed in the hope that it will be useful, -+ * but WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+ * GNU General Public License for more details. -+ * -+ * Or, alternatively, -+ * -+ * b) Permission is hereby granted, free of charge, to any person -+ * obtaining a copy of this software and associated documentation -+ * files (the "Software"), to deal in the Software without -+ * restriction, including without limitation the rights to use, -+ * copy, modify, merge, publish, distribute, sublicense, and/or -+ * sell copies of the Software, and to permit persons to whom the -+ * Software is furnished to do so, subject to the following -+ * conditions: -+ * -+ * The above copyright notice and this permission notice shall be -+ * included in all copies or substantial portions of the Software. -+ * -+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES -+ * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT -+ * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, -+ * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING -+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR -+ * OTHER DEALINGS IN THE SOFTWARE. -+ */ -+ -+#ifndef _DT_BINDINGS_RST_SUN8I_R_CCU_H_ -+#define _DT_BINDINGS_RST_SUN8I_R_CCU_H_ -+ -+#define RST_APB0_IR 0 -+#define RST_APB0_TIMER 1 -+#define RST_APB0_RSB 2 -+#define RST_APB0_UART 3 -+/* 4 is reserved for RST_APB0_W1 on A31 */ -+#define RST_APB0_I2C 5 -+ -+#endif /* _DT_BINDINGS_RST_SUN8I_R_CCU_H_ */ - diff --git a/patch/kernel/sun50iw2-dev/add_sun50i_a64_rpio.patch b/patch/kernel/sun50iw2-dev/add_sun50i_a64_rpio.patch deleted file mode 100644 index 428807bd8..000000000 --- a/patch/kernel/sun50iw2-dev/add_sun50i_a64_rpio.patch +++ /dev/null @@ -1,227 +0,0 @@ -diff --git a/arch/arm64/Kconfig.platforms b/arch/arm64/Kconfig.platforms -index 81f0d61..18ff031 100644 ---- a/arch/arm64/Kconfig.platforms -+++ b/arch/arm64/Kconfig.platforms -@@ -5,6 +5,7 @@ config ARCH_SUNXI - select GENERIC_IRQ_CHIP - select PINCTRL - select PINCTRL_SUN50I_A64 -+ select PINCTRL_SUN50I_A64_R - select PINCTRL_SUN50I_H5 - select PINCTRL_SUN8I_H3_R - help -diff --git a/drivers/pinctrl/sunxi/Kconfig b/drivers/pinctrl/sunxi/Kconfig -index a84bfa7f3c05..a0c419ac2a3b 100644 ---- a/drivers/pinctrl/sunxi/Kconfig -+++ b/drivers/pinctrl/sunxi/Kconfig -@@ -68,6 +68,10 @@ config PINCTRL_SUN50I_A64 - def_bool ARM64 && ARCH_SUNXI - select PINCTRL_SUNXI - -+config PINCTRL_SUN50I_A64_R -+ def_bool ARM64 && ARCH_SUNXI -+ select PINCTRL_SUNXI -+ - config PINCTRL_SUN50I_H5 - def_bool ARM64 && ARCH_SUNXI - select PINCTRL_SUNXI -diff --git a/drivers/pinctrl/sunxi/Makefile b/drivers/pinctrl/sunxi/Makefile -index 04ccb88ebd5f..df4ccd6cd44c 100644 ---- a/drivers/pinctrl/sunxi/Makefile -+++ b/drivers/pinctrl/sunxi/Makefile -@@ -11,6 +11,7 @@ obj-$(CONFIG_PINCTRL_SUN8I_A23) += pinctrl-sun8i-a23.o - obj-$(CONFIG_PINCTRL_SUN8I_A23_R) += pinctrl-sun8i-a23-r.o - obj-$(CONFIG_PINCTRL_SUN8I_A33) += pinctrl-sun8i-a33.o - obj-$(CONFIG_PINCTRL_SUN50I_A64) += pinctrl-sun50i-a64.o -+obj-$(CONFIG_PINCTRL_SUN50I_A64_R) += pinctrl-sun50i-a64-r.o - obj-$(CONFIG_PINCTRL_SUN8I_A83T) += pinctrl-sun8i-a83t.o - obj-$(CONFIG_PINCTRL_SUN8I_H3) += pinctrl-sun8i-h3.o - obj-$(CONFIG_PINCTRL_SUN8I_H3_R) += pinctrl-sun8i-h3-r.o -diff --git a/drivers/pinctrl/sunxi/pinctrl-sun50i-a64-r.c b/drivers/pinctrl/sunxi/pinctrl-sun50i-a64-r.c -new file mode 100644 -index 000000000000..415870e82cbf ---- /dev/null -+++ b/drivers/pinctrl/sunxi/pinctrl-sun50i-a64-r.c -@@ -0,0 +1,125 @@ -+/* -+ * Allwinner A64 SoCs special pins pinctrl driver. -+ * -+ * Based on pinctrl-sun8i-a23-r.c -+ * -+ * Copyright (C) 2016 Icenowy Zheng -+ * Icenowy Zheng <icenowy@aosc.xyz> -+ * -+ * Copyright (C) 2014 Chen-Yu Tsai -+ * Chen-Yu Tsai <wens@csie.org> -+ * -+ * Copyright (C) 2014 Boris Brezillon -+ * Boris Brezillon <boris.brezillon@free-electrons.com> -+ * -+ * Copyright (C) 2014 Maxime Ripard -+ * Maxime Ripard <maxime.ripard@free-electrons.com> -+ * -+ * This file is licensed under the terms of the GNU General Public -+ * License version 2. This program is licensed "as is" without any -+ * warranty of any kind, whether express or implied. -+ */ -+ -+#include <linux/of.h> -+#include <linux/of_device.h> -+#include <linux/pinctrl/pinctrl.h> -+#include <linux/platform_device.h> -+#include <linux/reset.h> -+ -+#include "pinctrl-sunxi.h" -+ -+static const struct sunxi_desc_pin sun50i_a64_r_pins[] = { -+ SUNXI_PIN(SUNXI_PINCTRL_PIN(L, 0), -+ SUNXI_FUNCTION(0x0, "gpio_in"), -+ SUNXI_FUNCTION(0x1, "gpio_out"), -+ SUNXI_FUNCTION(0x2, "s_rsb"), /* SCK */ -+ SUNXI_FUNCTION(0x3, "s_i2c"), /* SCK */ -+ SUNXI_FUNCTION_IRQ_BANK(0x6, 0, 0)), /* PL_EINT0 */ -+ SUNXI_PIN(SUNXI_PINCTRL_PIN(L, 1), -+ SUNXI_FUNCTION(0x0, "gpio_in"), -+ SUNXI_FUNCTION(0x1, "gpio_out"), -+ SUNXI_FUNCTION(0x2, "s_rsb"), /* SDA */ -+ SUNXI_FUNCTION(0x3, "s_i2c"), /* SDA */ -+ SUNXI_FUNCTION_IRQ_BANK(0x6, 0, 1)), /* PL_EINT1 */ -+ SUNXI_PIN(SUNXI_PINCTRL_PIN(L, 2), -+ SUNXI_FUNCTION(0x0, "gpio_in"), -+ SUNXI_FUNCTION(0x1, "gpio_out"), -+ SUNXI_FUNCTION(0x2, "s_uart"), /* TX */ -+ SUNXI_FUNCTION_IRQ_BANK(0x6, 0, 2)), /* PL_EINT2 */ -+ SUNXI_PIN(SUNXI_PINCTRL_PIN(L, 3), -+ SUNXI_FUNCTION(0x0, "gpio_in"), -+ SUNXI_FUNCTION(0x1, "gpio_out"), -+ SUNXI_FUNCTION(0x2, "s_uart"), /* RX */ -+ SUNXI_FUNCTION_IRQ_BANK(0x6, 0, 3)), /* PL_EINT3 */ -+ SUNXI_PIN(SUNXI_PINCTRL_PIN(L, 4), -+ SUNXI_FUNCTION(0x0, "gpio_in"), -+ SUNXI_FUNCTION(0x1, "gpio_out"), -+ SUNXI_FUNCTION(0x2, "s_jtag"), /* MS */ -+ SUNXI_FUNCTION_IRQ_BANK(0x6, 0, 4)), /* PL_EINT4 */ -+ SUNXI_PIN(SUNXI_PINCTRL_PIN(L, 5), -+ SUNXI_FUNCTION(0x0, "gpio_in"), -+ SUNXI_FUNCTION(0x1, "gpio_out"), -+ SUNXI_FUNCTION(0x2, "s_jtag"), /* CK */ -+ SUNXI_FUNCTION_IRQ_BANK(0x6, 0, 5)), /* PL_EINT5 */ -+ SUNXI_PIN(SUNXI_PINCTRL_PIN(L, 6), -+ SUNXI_FUNCTION(0x0, "gpio_in"), -+ SUNXI_FUNCTION(0x1, "gpio_out"), -+ SUNXI_FUNCTION(0x2, "s_jtag"), /* DO */ -+ SUNXI_FUNCTION_IRQ_BANK(0x6, 0, 6)), /* PL_EINT6 */ -+ SUNXI_PIN(SUNXI_PINCTRL_PIN(L, 7), -+ SUNXI_FUNCTION(0x0, "gpio_in"), -+ SUNXI_FUNCTION(0x1, "gpio_out"), -+ SUNXI_FUNCTION(0x2, "s_jtag"), /* DI */ -+ SUNXI_FUNCTION_IRQ_BANK(0x6, 0, 7)), /* PL_EINT7 */ -+ SUNXI_PIN(SUNXI_PINCTRL_PIN(L, 8), -+ SUNXI_FUNCTION(0x0, "gpio_in"), -+ SUNXI_FUNCTION(0x1, "gpio_out"), -+ SUNXI_FUNCTION(0x2, "s_i2c"), /* SCK */ -+ SUNXI_FUNCTION_IRQ_BANK(0x6, 0, 8)), /* PL_EINT8 */ -+ SUNXI_PIN(SUNXI_PINCTRL_PIN(L, 9), -+ SUNXI_FUNCTION(0x0, "gpio_in"), -+ SUNXI_FUNCTION(0x1, "gpio_out"), -+ SUNXI_FUNCTION(0x2, "s_i2c"), /* SDA */ -+ SUNXI_FUNCTION_IRQ_BANK(0x6, 0, 9)), /* PL_EINT9 */ -+ SUNXI_PIN(SUNXI_PINCTRL_PIN(L, 10), -+ SUNXI_FUNCTION(0x0, "gpio_in"), -+ SUNXI_FUNCTION(0x1, "gpio_out"), -+ SUNXI_FUNCTION(0x2, "s_pwm"), -+ SUNXI_FUNCTION_IRQ_BANK(0x6, 0, 10)), /* PL_EINT10 */ -+ SUNXI_PIN(SUNXI_PINCTRL_PIN(L, 11), -+ SUNXI_FUNCTION(0x0, "gpio_in"), -+ SUNXI_FUNCTION(0x1, "gpio_out"), -+ SUNXI_FUNCTION(0x2, "s_cir_rx"), -+ SUNXI_FUNCTION_IRQ_BANK(0x6, 0, 11)), /* PL_EINT11 */ -+ SUNXI_PIN(SUNXI_PINCTRL_PIN(L, 12), -+ SUNXI_FUNCTION(0x0, "gpio_in"), -+ SUNXI_FUNCTION(0x1, "gpio_out"), -+ SUNXI_FUNCTION_IRQ_BANK(0x6, 0, 12)), /* PL_EINT12 */ -+}; -+ -+static const struct sunxi_pinctrl_desc sun50i_a64_r_pinctrl_data = { -+ .pins = sun50i_a64_r_pins, -+ .npins = ARRAY_SIZE(sun50i_a64_r_pins), -+ .pin_base = PL_BASE, -+ .irq_banks = 1, -+}; -+ -+static int sun50i_a64_r_pinctrl_probe(struct platform_device *pdev) -+{ -+ return sunxi_pinctrl_init(pdev, -+ &sun50i_a64_r_pinctrl_data); -+} -+ -+static const struct of_device_id sun50i_a64_r_pinctrl_match[] = { -+ { .compatible = "allwinner,sun50i-a64-r-pinctrl", }, -+ {} -+}; -+ -+static struct platform_driver sun50i_a64_r_pinctrl_driver = { -+ .probe = sun50i_a64_r_pinctrl_probe, -+ .driver = { -+ .name = "sun50i-a64-r-pinctrl", -+ .of_match_table = sun50i_a64_r_pinctrl_match, -+ }, -+}; -+builtin_platform_driver(sun50i_a64_r_pinctrl_driver); -diff --git a/arch/arm64/boot/dts/allwinner/sun50i-a64.dtsi b/arch/arm64/boot/dts/allwinner/sun50i-a64.dtsi -index 02c0385..c0773d8 100644 ---- a/arch/arm64/boot/dts/allwinner/sun50i-a64.dtsi -+++ b/arch/arm64/boot/dts/allwinner/sun50i-a64.dtsi -@@ -43,8 +43,10 @@ - */ - - #include <dt-bindings/clock/sun50i-a64-ccu.h> -+#include <dt-bindings/clock/sun8i-r-ccu.h> - #include <dt-bindings/interrupt-controller/arm-gic.h> - #include <dt-bindings/reset/sun50i-a64-ccu.h> -+#include <dt-bindings/reset/sun8i-r-ccu.h> - - / { - interrupt-parent = <&gic>; -@@ -98,6 +100,13 @@ - clock-output-names = "osc32k"; - }; - -+ osc32000: osc32000_clk { -+ #clock-cells = <0>; -+ compatible = "fixed-clock"; -+ clock-frequency = <32000>; -+ clock-output-names = "osc32000"; -+ }; -+ - psci { - compatible = "arm,psci-0.2"; - method = "smc"; -@@ -306,6 +315,27 @@ - }; - }; - -+ r_ccu: clock@1f01400 { -+ compatible = "allwinner,sun50i-a64-r-ccu"; -+ reg = <0x01f01400 0x100>; -+ clocks = <&osc24M>, <&osc32k>, <&osc32000>; -+ clock-names = "hosc", "losc", "iosc"; -+ #clock-cells = <1>; -+ #reset-cells = <1>; -+ }; -+ -+ r_pio: pinctrl@1f02c00 { -+ compatible = "allwinner,sun50i-a64-r-pinctrl"; -+ reg = <0x01f02c00 0x400>; -+ interrupts = <GIC_SPI 45 IRQ_TYPE_LEVEL_HIGH>; -+ clocks = <&r_ccu CLK_APB0_PIO>, <&osc24M>, <&osc32k>; -+ clock-names = "apb", "hosc", "losc"; -+ gpio-controller; -+ #gpio-cells = <3>; -+ interrupt-controller; -+ #interrupt-cells = <3>; -+ }; -+ - uart0: serial@1c28000 { - compatible = "snps,dw-apb-uart"; - reg = <0x01c28000 0x400>; diff --git a/patch/kernel/sun50iw2-dev/remove-localversion.patch b/patch/kernel/sun50iw2-dev/remove-localversion.patch deleted file mode 100644 index 8083ac142..000000000 --- a/patch/kernel/sun50iw2-dev/remove-localversion.patch +++ /dev/null @@ -1,7 +0,0 @@ -diff --git a/localversion-next b/localversion-next -deleted file mode 100644 -index 299f8119..00000000 ---- a/localversion-next -+++ /dev/null -@@ -1 +0,0 @@ ---next-20170216 diff --git a/patch/kernel/sun50iw2-dev/scripts-dtc-Update-to-version-with-overlays.patch b/patch/kernel/sun50iw2-dev/scripts-dtc-Update-to-version-with-overlays.patch deleted file mode 100644 index bc3f71600..000000000 --- a/patch/kernel/sun50iw2-dev/scripts-dtc-Update-to-version-with-overlays.patch +++ /dev/null @@ -1,16 +0,0 @@ -diff --git a/scripts/Makefile.lib b/scripts/Makefile.lib -index ddf83d0..a0fb9e3 100644 ---- a/scripts/Makefile.lib -+++ b/scripts/Makefile.lib -@@ -275,7 +275,11 @@ cmd_gzip = (cat $(filter-out FORCE,$^) | gzip -n -f -9 > $@) || \ - - # DTC - # --------------------------------------------------------------------------- -+ifeq ($(CONFIG_OF_CONFIGFS),y) -+DTC ?= $(objtree)/scripts/dtc/dtc -@ -+else - DTC ?= $(objtree)/scripts/dtc/dtc -+endif - - # Generate an assembly file to wrap the output of the device tree compiler - quiet_cmd_dt_S_dtb= DTB $@ diff --git a/patch/kernel/sun50iw2-dev/spi-sun6i-allow-large-transfers.patch b/patch/kernel/sun50iw2-dev/spi-sun6i-allow-large-transfers.patch deleted file mode 100644 index 4dbf46ad8..000000000 --- a/patch/kernel/sun50iw2-dev/spi-sun6i-allow-large-transfers.patch +++ /dev/null @@ -1,190 +0,0 @@ -diff --git a/drivers/spi/spi-sun6i.c b/drivers/spi/spi-sun6i.c -index e3114832..03a773a9 100644 ---- a/drivers/spi/spi-sun6i.c -+++ b/drivers/spi/spi-sun6i.c -@@ -46,13 +46,19 @@ - #define SUN6I_TFR_CTL_XCH BIT(31) - - #define SUN6I_INT_CTL_REG 0x10 -+#define SUN6I_INT_CTL_RF_RDY BIT(0) -+#define SUN6I_INT_CTL_TF_ERQ BIT(4) - #define SUN6I_INT_CTL_RF_OVF BIT(8) - #define SUN6I_INT_CTL_TC BIT(12) - - #define SUN6I_INT_STA_REG 0x14 - - #define SUN6I_FIFO_CTL_REG 0x18 -+#define SUN6I_FIFO_CTL_RF_RDY_TRIG_LEVEL_MASK 0xff -+#define SUN6I_FIFO_CTL_RF_RDY_TRIG_LEVEL_BITS 0 - #define SUN6I_FIFO_CTL_RF_RST BIT(15) -+#define SUN6I_FIFO_CTL_TF_ERQ_TRIG_LEVEL_MASK 0xff -+#define SUN6I_FIFO_CTL_TF_ERQ_TRIG_LEVEL_BITS 16 - #define SUN6I_FIFO_CTL_TF_RST BIT(31) - - #define SUN6I_FIFO_STA_REG 0x1c -@@ -68,14 +74,16 @@ - #define SUN6I_CLK_CTL_CDR1(div) (((div) & SUN6I_CLK_CTL_CDR1_MASK) << 8) - #define SUN6I_CLK_CTL_DRS BIT(12) - -+#define SUN6I_MAX_XFER_SIZE 0xffffff -+ - #define SUN6I_BURST_CNT_REG 0x30 --#define SUN6I_BURST_CNT(cnt) ((cnt) & 0xffffff) -+#define SUN6I_BURST_CNT(cnt) ((cnt) & SUN6I_MAX_XFER_SIZE) - - #define SUN6I_XMIT_CNT_REG 0x34 --#define SUN6I_XMIT_CNT(cnt) ((cnt) & 0xffffff) -+#define SUN6I_XMIT_CNT(cnt) ((cnt) & SUN6I_MAX_XFER_SIZE) - - #define SUN6I_BURST_CTL_CNT_REG 0x38 --#define SUN6I_BURST_CTL_CNT_STC(cnt) ((cnt) & 0xffffff) -+#define SUN6I_BURST_CTL_CNT_STC(cnt) ((cnt) & SUN6I_MAX_XFER_SIZE) - - #define SUN6I_TXDATA_REG 0x200 - #define SUN6I_RXDATA_REG 0x300 -@@ -105,6 +113,31 @@ static inline void sun6i_spi_write(struct sun6i_spi *sspi, u32 reg, u32 value) - writel(value, sspi->base_addr + reg); - } - -+static inline u32 sun6i_spi_get_tx_fifo_count(struct sun6i_spi *sspi) -+{ -+ u32 reg = sun6i_spi_read(sspi, SUN6I_FIFO_STA_REG); -+ -+ reg >>= SUN6I_FIFO_STA_TF_CNT_BITS; -+ -+ return reg & SUN6I_FIFO_STA_TF_CNT_MASK; -+} -+ -+static inline void sun6i_spi_enable_interrupt(struct sun6i_spi *sspi, u32 mask) -+{ -+ u32 reg = sun6i_spi_read(sspi, SUN6I_INT_CTL_REG); -+ -+ reg |= mask; -+ sun6i_spi_write(sspi, SUN6I_INT_CTL_REG, reg); -+} -+ -+static inline void sun6i_spi_disable_interrupt(struct sun6i_spi *sspi, u32 mask) -+{ -+ u32 reg = sun6i_spi_read(sspi, SUN6I_INT_CTL_REG); -+ -+ reg &= ~mask; -+ sun6i_spi_write(sspi, SUN6I_INT_CTL_REG, reg); -+} -+ - static inline void sun6i_spi_drain_fifo(struct sun6i_spi *sspi, int len) - { - u32 reg, cnt; -@@ -127,10 +160,13 @@ static inline void sun6i_spi_drain_fifo(struct sun6i_spi *sspi, int len) - - static inline void sun6i_spi_fill_fifo(struct sun6i_spi *sspi, int len) - { -+ u32 cnt; - u8 byte; - -- if (len > sspi->len) -- len = sspi->len; -+ /* See how much data we can fit */ -+ cnt = sspi->fifo_depth - sun6i_spi_get_tx_fifo_count(sspi); -+ -+ len = min3(len, (int)cnt, sspi->len); - - while (len--) { - byte = sspi->tx_buf ? *sspi->tx_buf++ : 0; -@@ -158,9 +194,7 @@ static void sun6i_spi_set_cs(struct spi_device *spi, bool enable) - - static size_t sun6i_spi_max_transfer_size(struct spi_device *spi) - { -- struct sun6i_spi *sspi = spi_master_get_devdata(spi->master); -- -- return sspi->fifo_depth - 1; -+ return SUN6I_MAX_XFER_SIZE - 1; - } - - static int sun6i_spi_transfer_one(struct spi_master *master, -@@ -170,12 +204,12 @@ static int sun6i_spi_transfer_one(struct spi_master *master, - struct sun6i_spi *sspi = spi_master_get_devdata(master); - unsigned int mclk_rate, div, timeout; - unsigned int start, end, tx_time; -+ unsigned int trig_level; - unsigned int tx_len = 0; - int ret = 0; - u32 reg; - -- /* We don't support transfer larger than the FIFO */ -- if (tfr->len > sspi->fifo_depth) -+ if (tfr->len > SUN6I_MAX_XFER_SIZE) - return -EINVAL; - - reinit_completion(&sspi->done); -@@ -191,6 +225,17 @@ static int sun6i_spi_transfer_one(struct spi_master *master, - SUN6I_FIFO_CTL_RF_RST | SUN6I_FIFO_CTL_TF_RST); - - /* -+ * Setup FIFO interrupt trigger level -+ * Here we choose 3/4 of the full fifo depth, as it's the hardcoded -+ * value used in old generation of Allwinner SPI controller. -+ * (See spi-sun4i.c) -+ */ -+ trig_level = sspi->fifo_depth / 4 * 3; -+ sun6i_spi_write(sspi, SUN6I_FIFO_CTL_REG, -+ (trig_level << SUN6I_FIFO_CTL_RF_RDY_TRIG_LEVEL_BITS) | -+ (trig_level << SUN6I_FIFO_CTL_TF_ERQ_TRIG_LEVEL_BITS)); -+ -+ /* - * Setup the transfer control register: Chip Select, - * polarities, etc. - */ -@@ -274,6 +319,10 @@ static int sun6i_spi_transfer_one(struct spi_master *master, - - /* Enable the interrupts */ - sun6i_spi_write(sspi, SUN6I_INT_CTL_REG, SUN6I_INT_CTL_TC); -+ sun6i_spi_enable_interrupt(sspi, SUN6I_INT_CTL_TC | -+ SUN6I_INT_CTL_RF_RDY); -+ if (tx_len > sspi->fifo_depth) -+ sun6i_spi_enable_interrupt(sspi, SUN6I_INT_CTL_TF_ERQ); - - /* Start the transfer */ - reg = sun6i_spi_read(sspi, SUN6I_TFR_CTL_REG); -@@ -293,8 +342,6 @@ static int sun6i_spi_transfer_one(struct spi_master *master, - goto out; - } - -- sun6i_spi_drain_fifo(sspi, sspi->fifo_depth); -- - out: - sun6i_spi_write(sspi, SUN6I_INT_CTL_REG, 0); - -@@ -309,10 +356,33 @@ static irqreturn_t sun6i_spi_handler(int irq, void *dev_id) - /* Transfer complete */ - if (status & SUN6I_INT_CTL_TC) { - sun6i_spi_write(sspi, SUN6I_INT_STA_REG, SUN6I_INT_CTL_TC); -+ sun6i_spi_drain_fifo(sspi, sspi->fifo_depth); - complete(&sspi->done); - return IRQ_HANDLED; - } - -+ /* Receive FIFO 3/4 full */ -+ if (status & SUN6I_INT_CTL_RF_RDY) { -+ sun6i_spi_drain_fifo(sspi, SUN6I_FIFO_DEPTH); -+ /* Only clear the interrupt _after_ draining the FIFO */ -+ sun6i_spi_write(sspi, SUN6I_INT_STA_REG, SUN6I_INT_CTL_RF_RDY); -+ return IRQ_HANDLED; -+ } -+ -+ /* Transmit FIFO 3/4 empty */ -+ if (status & SUN6I_INT_CTL_TF_ERQ) { -+ sun6i_spi_fill_fifo(sspi, SUN6I_FIFO_DEPTH); -+ -+ if (!sspi->len) -+ /* nothing left to transmit */ -+ sun6i_spi_disable_interrupt(sspi, SUN6I_INT_CTL_TF_ERQ); -+ -+ /* Only clear the interrupt _after_ re-seeding the FIFO */ -+ sun6i_spi_write(sspi, SUN6I_INT_STA_REG, SUN6I_INT_CTL_TF_ERQ); -+ -+ return IRQ_HANDLED; -+ } -+ - return IRQ_NONE; - } - diff --git a/patch/kernel/sun50iw2-dev/spidev-remove-warnings.patch b/patch/kernel/sun50iw2-dev/spidev-remove-warnings.patch deleted file mode 100644 index 25648e844..000000000 --- a/patch/kernel/sun50iw2-dev/spidev-remove-warnings.patch +++ /dev/null @@ -1,21 +0,0 @@ -diff --git a/drivers/spi/spidev.c b/drivers/spi/spidev.c -index 9e2e099b..a065943d 100644 ---- a/drivers/spi/spidev.c -+++ b/drivers/spi/spidev.c -@@ -749,13 +749,11 @@ static int spidev_probe(struct spi_device *spi) - - /* - * spidev should never be referenced in DT without a specific -- * compatible string, it is a Linux implementation thing -- * rather than a description of the hardware. -+ * compatible string, but people don't care and use DT overlays -+ * to activate SPIdev on demand - */ - if (spi->dev.of_node && !of_match_device(spidev_dt_ids, &spi->dev)) { -- dev_err(&spi->dev, "buggy DT: spidev listed directly in DT\n"); -- WARN_ON(spi->dev.of_node && -- !of_match_device(spidev_dt_ids, &spi->dev)); -+ dev_info(&spi->dev, "probing from DT"); - } - - spidev_probe_acpi(spi);