From 626d9efa74685720020e816f3a917b7591d3cf7a Mon Sep 17 00:00:00 2001 From: James <> Date: Sat, 26 Sep 2015 12:29:31 +0100 Subject: trunk-47048 --- target/linux/ar7/Makefile | 26 ++ target/linux/ar7/ac49x/config-default | 4 + target/linux/ar7/ac49x/profiles/210-None.mk | 17 ++ target/linux/ar7/ac49x/target.mk | 10 + target/linux/ar7/base-files.mk | 11 + target/linux/ar7/base-files/etc/config/network | 50 ++++ target/linux/ar7/base-files/etc/diag.sh | 45 ++++ target/linux/ar7/base-files/etc/init.d/adam2 | 13 + .../ar7/base-files/etc/uci-defaults/02_network | 30 +++ target/linux/ar7/config-3.18 | 130 +++++++++ target/linux/ar7/config-4.1 | 147 ++++++++++ target/linux/ar7/files/drivers/char/ar7_gpio.c | 158 +++++++++++ target/linux/ar7/files/drivers/mtd/ac49xpart.c | 221 +++++++++++++++ target/linux/ar7/files/drivers/mtd/titanpart.c | 234 ++++++++++++++++ target/linux/ar7/generic/config-default | 5 + target/linux/ar7/generic/profiles/100-Annex-A.mk | 18 ++ target/linux/ar7/generic/profiles/110-Annex-B.mk | 18 ++ target/linux/ar7/generic/profiles/200-Texas.mk | 18 ++ target/linux/ar7/generic/profiles/210-None.mk | 17 ++ target/linux/ar7/generic/target.mk | 12 + target/linux/ar7/image/Makefile | 137 ++++++++++ .../ar7/patches-3.18/001-mips-ar7-fix-serial.patch | 23 ++ .../ar7/patches-3.18/100-fix-highmem-offset.patch | 11 + target/linux/ar7/patches-3.18/110-flash.patch | 22 ++ .../linux/ar7/patches-3.18/120-gpio_chrdev.patch | 28 ++ .../patches-3.18/160-vlynq_try_remote_first.patch | 300 +++++++++++++++++++++ .../200-free-mem-below-kernel-offset.patch | 15 ++ .../ar7/patches-3.18/300-add-ac49x-platform.patch | 85 ++++++ .../ar7/patches-3.18/310-ac49x-prom-support.patch | 20 ++ .../patches-3.18/320-ac49x-mtd-partitions.patch | 35 +++ .../linux/ar7/patches-3.18/500-serial_kludge.patch | 28 ++ target/linux/ar7/patches-3.18/920-ar7part.patch | 118 ++++++++ .../ar7/patches-3.18/925-actiontec_leds.patch | 95 +++++++ .../linux/ar7/patches-3.18/950-cpmac_titan.patch | 52 ++++ .../ar7/patches-4.1/001-mips-ar7-fix-serial.patch | 23 ++ .../ar7/patches-4.1/100-fix-highmem-offset.patch | 11 + target/linux/ar7/patches-4.1/110-flash.patch | 22 ++ target/linux/ar7/patches-4.1/120-gpio_chrdev.patch | 28 ++ .../patches-4.1/160-vlynq_try_remote_first.patch | 300 +++++++++++++++++++++ .../200-free-mem-below-kernel-offset.patch | 15 ++ .../ar7/patches-4.1/300-add-ac49x-platform.patch | 85 ++++++ .../ar7/patches-4.1/310-ac49x-prom-support.patch | 20 ++ .../ar7/patches-4.1/320-ac49x-mtd-partitions.patch | 35 +++ .../linux/ar7/patches-4.1/500-serial_kludge.patch | 28 ++ target/linux/ar7/patches-4.1/920-ar7part.patch | 118 ++++++++ .../linux/ar7/patches-4.1/925-actiontec_leds.patch | 95 +++++++ target/linux/ar7/patches-4.1/950-cpmac_titan.patch | 52 ++++ target/linux/ar7/src/adam2patcher.c | 59 ++++ 48 files changed, 3044 insertions(+) create mode 100644 target/linux/ar7/Makefile create mode 100644 target/linux/ar7/ac49x/config-default create mode 100644 target/linux/ar7/ac49x/profiles/210-None.mk create mode 100644 target/linux/ar7/ac49x/target.mk create mode 100644 target/linux/ar7/base-files.mk create mode 100644 target/linux/ar7/base-files/etc/config/network create mode 100644 target/linux/ar7/base-files/etc/diag.sh create mode 100755 target/linux/ar7/base-files/etc/init.d/adam2 create mode 100644 target/linux/ar7/base-files/etc/uci-defaults/02_network create mode 100644 target/linux/ar7/config-3.18 create mode 100644 target/linux/ar7/config-4.1 create mode 100644 target/linux/ar7/files/drivers/char/ar7_gpio.c create mode 100644 target/linux/ar7/files/drivers/mtd/ac49xpart.c create mode 100644 target/linux/ar7/files/drivers/mtd/titanpart.c create mode 100644 target/linux/ar7/generic/config-default create mode 100644 target/linux/ar7/generic/profiles/100-Annex-A.mk create mode 100644 target/linux/ar7/generic/profiles/110-Annex-B.mk create mode 100644 target/linux/ar7/generic/profiles/200-Texas.mk create mode 100644 target/linux/ar7/generic/profiles/210-None.mk create mode 100644 target/linux/ar7/generic/target.mk create mode 100644 target/linux/ar7/image/Makefile create mode 100644 target/linux/ar7/patches-3.18/001-mips-ar7-fix-serial.patch create mode 100644 target/linux/ar7/patches-3.18/100-fix-highmem-offset.patch create mode 100644 target/linux/ar7/patches-3.18/110-flash.patch create mode 100644 target/linux/ar7/patches-3.18/120-gpio_chrdev.patch create mode 100644 target/linux/ar7/patches-3.18/160-vlynq_try_remote_first.patch create mode 100644 target/linux/ar7/patches-3.18/200-free-mem-below-kernel-offset.patch create mode 100644 target/linux/ar7/patches-3.18/300-add-ac49x-platform.patch create mode 100644 target/linux/ar7/patches-3.18/310-ac49x-prom-support.patch create mode 100644 target/linux/ar7/patches-3.18/320-ac49x-mtd-partitions.patch create mode 100644 target/linux/ar7/patches-3.18/500-serial_kludge.patch create mode 100644 target/linux/ar7/patches-3.18/920-ar7part.patch create mode 100644 target/linux/ar7/patches-3.18/925-actiontec_leds.patch create mode 100644 target/linux/ar7/patches-3.18/950-cpmac_titan.patch create mode 100644 target/linux/ar7/patches-4.1/001-mips-ar7-fix-serial.patch create mode 100644 target/linux/ar7/patches-4.1/100-fix-highmem-offset.patch create mode 100644 target/linux/ar7/patches-4.1/110-flash.patch create mode 100644 target/linux/ar7/patches-4.1/120-gpio_chrdev.patch create mode 100644 target/linux/ar7/patches-4.1/160-vlynq_try_remote_first.patch create mode 100644 target/linux/ar7/patches-4.1/200-free-mem-below-kernel-offset.patch create mode 100644 target/linux/ar7/patches-4.1/300-add-ac49x-platform.patch create mode 100644 target/linux/ar7/patches-4.1/310-ac49x-prom-support.patch create mode 100644 target/linux/ar7/patches-4.1/320-ac49x-mtd-partitions.patch create mode 100644 target/linux/ar7/patches-4.1/500-serial_kludge.patch create mode 100644 target/linux/ar7/patches-4.1/920-ar7part.patch create mode 100644 target/linux/ar7/patches-4.1/925-actiontec_leds.patch create mode 100644 target/linux/ar7/patches-4.1/950-cpmac_titan.patch create mode 100644 target/linux/ar7/src/adam2patcher.c (limited to 'target/linux/ar7') diff --git a/target/linux/ar7/Makefile b/target/linux/ar7/Makefile new file mode 100644 index 0000000..1832e7b --- /dev/null +++ b/target/linux/ar7/Makefile @@ -0,0 +1,26 @@ +# +# Copyright (C) 2006-2011 OpenWrt.org +# +# This is free software, licensed under the GNU General Public License v2. +# See /LICENSE for more information. +# +include $(TOPDIR)/rules.mk + +ARCH:=mipsel +BOARD:=ar7 +BOARDNAME:=TI AR7 +FEATURES:=squashfs atm low_mem +MAINTAINER:=Florian Fainelli +SUBTARGETS:=generic ac49x + +KERNEL_PATCHVER:=3.18 + +include $(INCLUDE_DIR)/target.mk + +DEFAULT_PACKAGES+= swconfig + +define Target/Description + Build firmware images for TI AR7 based routers. +endef + +$(eval $(call BuildTarget)) diff --git a/target/linux/ar7/ac49x/config-default b/target/linux/ar7/ac49x/config-default new file mode 100644 index 0000000..d56df86 --- /dev/null +++ b/target/linux/ar7/ac49x/config-default @@ -0,0 +1,4 @@ +CONFIG_AR7_AC49X=y +CONFIG_AR7_TYPE_AC49X=y +# CONFIG_AR7_TYPE_TI is not set +CONFIG_MTD_AC49X_PARTS=y diff --git a/target/linux/ar7/ac49x/profiles/210-None.mk b/target/linux/ar7/ac49x/profiles/210-None.mk new file mode 100644 index 0000000..2fcfacd --- /dev/null +++ b/target/linux/ar7/ac49x/profiles/210-None.mk @@ -0,0 +1,17 @@ +# +# Copyright (C) 2006 OpenWrt.org +# +# This is free software, licensed under the GNU General Public License v2. +# See /LICENSE for more information. +# + +define Profile/None + NAME:=No WiFi + PACKAGES:= +endef + +define Profile/None/Description + Package set without WiFi support +endef +$(eval $(call Profile,None)) + diff --git a/target/linux/ar7/ac49x/target.mk b/target/linux/ar7/ac49x/target.mk new file mode 100644 index 0000000..47f3ab2 --- /dev/null +++ b/target/linux/ar7/ac49x/target.mk @@ -0,0 +1,10 @@ +# +# Copyright (C) 2012 OpenWrt.org +# + +SUBTARGET:=ac49x +BOARDNAME:=AudioCodes AC49x + +define Target/Description + Build firmware images for AudioCodes AC49x based routers. +endef diff --git a/target/linux/ar7/base-files.mk b/target/linux/ar7/base-files.mk new file mode 100644 index 0000000..f21a604 --- /dev/null +++ b/target/linux/ar7/base-files.mk @@ -0,0 +1,11 @@ +define Build/Compile + $(call Build/Compile/Default) + $(TARGET_CC) -o $(PKG_BUILD_DIR)/adam2patcher $(PLATFORM_DIR)/src/adam2patcher.c +endef + +define Package/base-files/install-target + mkdir -p $(1)/sbin + $(CP) $(PKG_BUILD_DIR)/adam2patcher $(1)/sbin +endef + + diff --git a/target/linux/ar7/base-files/etc/config/network b/target/linux/ar7/base-files/etc/config/network new file mode 100644 index 0000000..968d955 --- /dev/null +++ b/target/linux/ar7/base-files/etc/config/network @@ -0,0 +1,50 @@ +# Copyright (C) 2006 OpenWrt.org + +config interface loopback + option ifname lo + option proto static + option ipaddr 127.0.0.1 + option netmask 255.0.0.0 + +config interface lan + option type bridge + option ifname "eth0 eth1 eth0.1 eth0.2" + option proto static + option ipaddr 192.168.1.1 + option netmask 255.255.255.0 + option nat 1 + option ip6assign 60 + +config interface wan6 + option ifname @wan + option proto dhcpv6 + +config globals globals + option ula_prefix auto + +## Example for ATM bridging. +## Useful for PPPoE or IP over ATM. Will create 'nas${unit}' +# +# config atm-bridge +# option unit 0 +# option encaps llc +# option vpi 8 +# option vci 35 +# option payload bridged # some ISPs need this set to 'routed' + + +# config interface wan +## PPPoE: +# option ifname nas0 +# option proto pppoe + +## PPPoA: +# option ifname atm0 +# option proto pppoa +# option encaps llc +# option vpi 8 +# option vci 35 + +## Both: +# option username "my_username" +# option password "my_password" diff --git a/target/linux/ar7/base-files/etc/diag.sh b/target/linux/ar7/base-files/etc/diag.sh new file mode 100644 index 0000000..f6548e8 --- /dev/null +++ b/target/linux/ar7/base-files/etc/diag.sh @@ -0,0 +1,45 @@ +#!/bin/sh +# Copyright (C) 2007-2013 OpenWrt.org + +# This setup gives us 4.5 distinguishable states: +# +# (1-LED) Solid OFF: Bootloader running, or kernel hung (timer task stalled) +# (1-LED) Solid ON: Kernel hung (timer task stalled) +# (2-LED) Solid RED: Bootloader running, or kernel hung (timer task stalled) +# (2-LED) Solid YELLOW: Kernel hung (timer task stalled) +# 5Hz blink: preinit +# 10Hz blink: failsafe +# (1-LED) Heartbeat: normal operation +# (2-LED) Solid GREEN: normal operation + +. /lib/functions/leds.sh + +get_status_led() { + [ -d "/sys/class/leds/status" ] && status_led="status" + [ -d "/sys/class/leds/power:green" ] && status_led="power:green" +} + +set_state() { + get_status_led + + case "$1" in + preinit) + status_led_set_timer 100 100 + ;; + failsafe) + status_led_set_timer 50 50 + ;; + preinit_regular) + status_led_blink_preinit_regular + ;; + done) + [ "$status_led" = "status" ] && { + status_led_set_heartbeat + } + [ "$status_led" = "power:green" ] && { + status_led_set_on + led_off "power:red" + } + ;; + esac +} diff --git a/target/linux/ar7/base-files/etc/init.d/adam2 b/target/linux/ar7/base-files/etc/init.d/adam2 new file mode 100755 index 0000000..6b78627 --- /dev/null +++ b/target/linux/ar7/base-files/etc/init.d/adam2 @@ -0,0 +1,13 @@ +#!/bin/sh /etc/rc.common +# ADAM2 patcher for Netgear DG834 and compatible +# Copyright (C) 2006 OpenWrt.org + +START=00 +start() { + MD5="$(md5sum /dev/mtdblock0 | awk '{print $1}')" + [ "$MD5" = "0530bfdf00ec155f4182afd70da028c1" ] && { + mtd unlock adam2 + /sbin/adam2patcher /dev/mtdblock0 + } + rm -f /etc/rc.d/S${START}adam2 /etc/init.d/adam2 /sbin/adam2patcher >&- 2>&- +} diff --git a/target/linux/ar7/base-files/etc/uci-defaults/02_network b/target/linux/ar7/base-files/etc/uci-defaults/02_network new file mode 100644 index 0000000..2d35c56 --- /dev/null +++ b/target/linux/ar7/base-files/etc/uci-defaults/02_network @@ -0,0 +1,30 @@ +#!/bin/sh +if [ -e "/sys/bus/mdio_bus/drivers/IC+ IP175A/1:00" -o \ + -e "/sys/bus/mdio_bus/drivers/IC+ IP17xx/1:00" ] && \ + [ -x /sbin/swconfig ]; +then + uci batch < + * + * 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. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define DRVNAME "ar7_gpio" +#define LONGNAME "TI AR7 GPIOs Driver" + +MODULE_AUTHOR("Nicolas Thill "); +MODULE_DESCRIPTION(LONGNAME); +MODULE_LICENSE("GPL"); + +static int ar7_gpio_major; + +static ssize_t ar7_gpio_write(struct file *file, const char __user *buf, + size_t len, loff_t *ppos) +{ + int pin = iminor(file->f_path.dentry->d_inode); + size_t i; + + for (i = 0; i < len; ++i) { + char c; + if (get_user(c, buf + i)) + return -EFAULT; + switch (c) { + case '0': + gpio_set_value(pin, 0); + break; + case '1': + gpio_set_value(pin, 1); + break; + case 'd': + case 'D': + ar7_gpio_disable(pin); + break; + case 'e': + case 'E': + ar7_gpio_enable(pin); + break; + case 'i': + case 'I': + case '<': + gpio_direction_input(pin); + break; + case 'o': + case 'O': + case '>': + gpio_direction_output(pin, 0); + break; + default: + return -EINVAL; + } + } + + return len; +} + +static ssize_t ar7_gpio_read(struct file *file, char __user *buf, + size_t len, loff_t *ppos) +{ + int pin = iminor(file->f_path.dentry->d_inode); + int value; + + value = gpio_get_value(pin); + if (put_user(value ? '1' : '0', buf)) + return -EFAULT; + + return 1; +} + +static int ar7_gpio_open(struct inode *inode, struct file *file) +{ + int m = iminor(inode); + + if (m >= (ar7_is_titan() ? TITAN_GPIO_MAX : AR7_GPIO_MAX)) + return -EINVAL; + + return nonseekable_open(inode, file); +} + +static int ar7_gpio_release(struct inode *inode, struct file *file) +{ + return 0; +} + +static const struct file_operations ar7_gpio_fops = { + .owner = THIS_MODULE, + .write = ar7_gpio_write, + .read = ar7_gpio_read, + .open = ar7_gpio_open, + .release = ar7_gpio_release, + .llseek = no_llseek, +}; + +static struct platform_device *ar7_gpio_device; + +static int __init ar7_gpio_char_init(void) +{ + int rc; + + ar7_gpio_device = platform_device_alloc(DRVNAME, -1); + if (!ar7_gpio_device) + return -ENOMEM; + + rc = platform_device_add(ar7_gpio_device); + if (rc < 0) + goto out_put; + + rc = register_chrdev(ar7_gpio_major, DRVNAME, &ar7_gpio_fops); + if (rc < 0) + goto out_put; + + ar7_gpio_major = rc; + + rc = 0; + + goto out; + +out_put: + platform_device_put(ar7_gpio_device); +out: + return rc; +} + +static void __exit ar7_gpio_char_exit(void) +{ + unregister_chrdev(ar7_gpio_major, DRVNAME); + platform_device_unregister(ar7_gpio_device); +} + +module_init(ar7_gpio_char_init); +module_exit(ar7_gpio_char_exit); diff --git a/target/linux/ar7/files/drivers/mtd/ac49xpart.c b/target/linux/ar7/files/drivers/mtd/ac49xpart.c new file mode 100644 index 0000000..7ac4a81 --- /dev/null +++ b/target/linux/ar7/files/drivers/mtd/ac49xpart.c @@ -0,0 +1,221 @@ +/* + * AudioCodes AC49x PSPBoot-based flash partition table + * Copyright 2012 Daniel Golle + * + * 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. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + * + */ + +#include +#include + +#include +#include +#include +#include +#include + +#include + +#define AC49X_MAXENVPARTS 8 + +#define AC49X_PARTTYPE_LOADER 0 +#define AC49X_PARTTYPE_BOOTENV 1 +#define AC49X_PARTTYPE_LINUX 2 +#define AC49X_PARTTYPE_ROOTFS 3 +#define AC49X_PARTTYPE_UNKNOWN 4 +#define AC49X_NUM_PARTTYPES 5 + +#define AC49X_FLASH_ADDRMASK 0x00FFFFFF + +#define AC49X_LOADER_MAGIC 0x40809000 +#define AC49X_LINUX_MAGIC 0x464c457f /* ELF */ +#define AC49X_BOOTENV_MAGIC 0x4578614d /* MaxE */ + +#define ROOTFS_MIN_OFFSET 0xC0000 + +int parse_partvar(const unsigned char *partvar, struct mtd_partition *part) +{ + unsigned int partstart, partend; + unsigned int pnum; + + pnum = sscanf(partvar, "0x%x,0x%x", &partstart, &partend); + if (pnum != 2) + return 1; + + part->offset = partstart & AC49X_FLASH_ADDRMASK; + part->size = partend - partstart; + + return 0; +} + +int detect_parttype(struct mtd_info *master, struct mtd_partition part) +{ + unsigned int magic; + size_t len; + + if (part.size < 4) + return -1; + + mtd_read(master, part.offset, sizeof(magic), &len, + (uint8_t *)&magic); + + if (len != sizeof(magic)) + return -1; + + switch (magic) { + case AC49X_LOADER_MAGIC: + return AC49X_PARTTYPE_LOADER; + case AC49X_LINUX_MAGIC: + return AC49X_PARTTYPE_LINUX; + case SQUASHFS_MAGIC: + case CRAMFS_MAGIC: + case CRAMFS_MAGIC_WEND: + return AC49X_PARTTYPE_ROOTFS; + case AC49X_BOOTENV_MAGIC: + return AC49X_PARTTYPE_BOOTENV; + default: + switch (magic & 0xFF) { + case JFFS2_SUPER_MAGIC: + return AC49X_PARTTYPE_ROOTFS; + } + switch (magic >> 8) { + case JFFS2_SUPER_MAGIC: + return AC49X_PARTTYPE_ROOTFS; + } + return AC49X_PARTTYPE_UNKNOWN; + } +} + +const char *partnames[] = { + "loader", + "config", + "linux", + "rootfs", + "data" +}; + +void gen_partname(unsigned int type, + unsigned int *typenumeration, + struct mtd_partition *part) +{ + char *s = kzalloc(sizeof(char) * 8, GFP_KERNEL); + + (typenumeration[type])++; + if (typenumeration[type] == 1) + sprintf(s, "%s", partnames[type]); + else + sprintf(s, "%s%d", partnames[type], typenumeration[type]); + + part->name = s; +} + +static int create_mtd_partitions(struct mtd_info *master, + struct mtd_partition **pparts, + struct mtd_part_parser_data *data) +{ + unsigned int envpartnum = 0, linuxpartnum = 0; + unsigned int typenumeration[5] = { 0, 0, 0, 0, 0 }; + unsigned char evn[5]; + const unsigned char *partvar = NULL; + + struct mtd_partition *ac49x_parts; + + ac49x_parts = kzalloc(sizeof(*ac49x_parts) * AC49X_MAXENVPARTS, + GFP_KERNEL); + + if (!ac49x_parts) + return -ENOMEM; + + linuxpartnum = 0; + for (envpartnum = 0; envpartnum < AC49X_MAXENVPARTS; envpartnum++) { + struct mtd_partition parsepart; + unsigned int offset, size, type; + int err; + sprintf(evn, "mtd%d", envpartnum); + partvar = prom_getenv(evn); + if (!partvar) + continue; + err = parse_partvar(partvar, &parsepart); + if (err) + continue; + offset = parsepart.offset; + size = parsepart.size; + type = detect_parttype(master, parsepart); + gen_partname(type, typenumeration, &parsepart); + /* protect loader */ + if (type == AC49X_PARTTYPE_LOADER) + parsepart.mask_flags = MTD_WRITEABLE; + else + parsepart.mask_flags = 0; + + memcpy(&(ac49x_parts[linuxpartnum]), &parsepart, + sizeof(struct mtd_partition)); + + /* scan for contained rootfs */ + if (type == AC49X_PARTTYPE_LINUX) { + parsepart.offset += ROOTFS_MIN_OFFSET & + ~(master->erasesize - 1); + parsepart.size -= ROOTFS_MIN_OFFSET & + ~(master->erasesize - 1); + do { + unsigned int size, offset; + size = parsepart.size; + offset = parsepart.offset; + + type = detect_parttype(master, parsepart); + if (type == AC49X_PARTTYPE_ROOTFS) { + gen_partname(type, typenumeration, + &parsepart); + printk(KERN_INFO + "%s %s: 0x%08x@0x%08x\n", + "detected sub-partition", + parsepart.name, + (unsigned int)parsepart.size, + (unsigned int)parsepart.offset); + linuxpartnum++; + memcpy(&(ac49x_parts[linuxpartnum]), + &parsepart, + sizeof(struct mtd_partition)); + break; + } + parsepart.offset += master->erasesize; + parsepart.size -= master->erasesize; + } while (parsepart.size >= master->erasesize); + } + linuxpartnum++; + } + + *pparts = ac49x_parts; + return linuxpartnum; +} + +static struct mtd_part_parser ac49x_parser = { + .owner = THIS_MODULE, + .parse_fn = create_mtd_partitions, + .name = "ac49xpart", +}; + +static int __init ac49x_parser_init(void) +{ + register_mtd_parser(&ac49x_parser); + return 0; +} + +module_init(ac49x_parser_init); + +MODULE_LICENSE("GPL"); +MODULE_AUTHOR("Daniel Golle "); +MODULE_DESCRIPTION("MTD partitioning for AudioCodes AC49x"); diff --git a/target/linux/ar7/files/drivers/mtd/titanpart.c b/target/linux/ar7/files/drivers/mtd/titanpart.c new file mode 100644 index 0000000..a6403f6 --- /dev/null +++ b/target/linux/ar7/files/drivers/mtd/titanpart.c @@ -0,0 +1,234 @@ +#include +#include + +#include +#include +#include +#include +#include + +#define IMAGE_A_SIZE 0X3c0000 +#define WRTP_PARTS 14 +#define NSP_IMG_MAGIC_NUMBER le32_to_cpu(0x4D544443) +#define NSP_IMG_SECTION_TYPE_KERNEL (0x01) +#define NSP_IMG_SECTION_TYPE_FILESYSTEM_ROOT (0x02) +#define NSP_IMG_SECTION_TYPE_FILESYSTEM (0x03) +#define MAX_NUM_PARTITIONS 14 + +static int part_count=0; +static struct mtd_partition titan_parts[WRTP_PARTS]; + + +struct nsp_img_hdr_head +{ + unsigned int magic; /* Magic number to identify this image header */ + unsigned int boot_offset; /* Offset from start of header to kernel code. */ + unsigned int flags; /* Image flags. */ + unsigned int hdr_version; /* Version of this header. */ + unsigned int hdr_size; /* The complete size of all portions of the header */ + unsigned int prod_id; /* This product id */ + unsigned int rel_id; /* Which release this is */ + unsigned int version; /* name-MMM.nnn.ooo-rxx => 0xMMnnooxx. See comment + below */ + unsigned int image_size; /* Image size (including header) */ + unsigned int info_offset; /* Offset from start of header to info block */ + unsigned int sect_info_offset; /* Offset from start of header to section desc */ + unsigned int chksum_offset; /* Offset from start of header to chksum block */ + unsigned int pad1; +}; + +struct nsp_img_hdr_section_info +{ + unsigned int num_sects; /* Number of section (and section desc blocks) in this image */ + unsigned int sect_size; /* Size of a SINGLE section_desc block */ + unsigned int sections_offset; /* Offset to from start of header to the start of the section blocks */ +}; + +/* There will be one of more of the following stuctures in the image header. Each + section will have one of these blocks. */ +struct nsp_img_hdr_sections +{ + unsigned int offset; /* Offset of section from start of NSP_IMG_HDR_HEAD */ + unsigned int total_size; /* Size of section (including pad size.) */ + unsigned int raw_size; /* Size of section only */ + unsigned int flags; /* Section flags */ + unsigned int chksum; /* Section checksum */ + unsigned int type; /* Section type. What kind of info does this section describe */ + char name[16]; /* Reference name for this section. */ +}; + + + + + +static int titan_parse_env_address(char *env_name, unsigned int *flash_base, + unsigned int *flash_end) +{ + char image_name[30]; + char *env_ptr; + char *base_ptr; + char *end_ptr; + char * string_ptr; + /* Get the image variable */ + env_ptr = prom_getenv(env_name); + if(!env_ptr){ + printk("titan: invalid env name, %s.\n", env_name); + return -1; /* Error, no image variable */ + } + strncpy(image_name, env_ptr, 30); + image_name[29]=0; + string_ptr = image_name; + /* Extract the start and stop addresses of the partition */ + base_ptr = strsep(&string_ptr, ","); + end_ptr = strsep(&string_ptr, ","); + if ((base_ptr == NULL) || (end_ptr == NULL)) { + printk("titan: Couldn't tokenize %s start,end.\n", image_name); + return -1; + } + + *flash_base = (unsigned int) simple_strtol(base_ptr, NULL, 0); + *flash_end = (unsigned int) simple_strtol(end_ptr, NULL, 0); + if((!*flash_base) || (!*flash_end)) { + printk("titan: Unable to convert :%s: :%s: into start,end values.\n", + env_name, image_name); + return -1; + } + *flash_base &= 0x0fffffff; + *flash_end &= 0x0fffffff; + return 0; +} + + + +static int titan_get_single_image(char *bootcfg_name, unsigned int *flash_base, + unsigned int *flash_end) +{ + char *env_ptr; + char *base_ptr; + char *end_ptr; + char image_name[30]; + char * string_ptr; + + if(!bootcfg_name || !flash_base || !flash_end) + return -1; + + env_ptr = prom_getenv(bootcfg_name); + if(!env_ptr){ + printk("titan: %s variable not found.\n", bootcfg_name); + return -1; /* Error, no bootcfg variable */ + } + + string_ptr = image_name; + /* Save off the image name */ + strncpy(image_name, env_ptr, 30); + image_name[29]=0; + + end_ptr=strsep(&string_ptr, "\""); + base_ptr=strsep(&string_ptr, "\""); /* Loose the last " */ + if(!end_ptr || !base_ptr){ + printk("titan: invalid bootcfg format, %s.\n", image_name); + return -1; /* Error, invalid bootcfg variable */ + } + + /* Now, parse the addresses */ + return titan_parse_env_address(base_ptr, flash_base, flash_end); +} + + + +static void titan_add_partition(char * env_name, unsigned int flash_base, unsigned int flash_end) +{ + titan_parts[part_count].name = env_name; + titan_parts[part_count].offset = flash_base; + titan_parts[part_count].size = flash_end-flash_base; + titan_parts[part_count].mask_flags = (strcmp(env_name, "bootloader")==0|| + strcmp(env_name, "boot_env")==0 || + strcmp(env_name, "full_image")==0 )?MTD_WRITEABLE:0; + part_count++; + +} +int create_titan_partitions(struct mtd_info *master, + struct mtd_partition **pparts, + unsigned long origin) +{ + struct nsp_img_hdr_head hdr; + struct nsp_img_hdr_section_info sect_info; + struct nsp_img_hdr_sections section; + unsigned int flash_base, flash_end; + unsigned int start, end; + char *name; + int i; + int total_sects=0; + size_t len; + + /* Get the bootcfg env variable first */ + if(titan_get_single_image("BOOTCFG", &flash_base, &flash_end)) { + /* Error, fallback */ + return -1; + } + + /* Get access to the header, and do some validation checks */ + //hdr=(struct nsp_img_hdr_head*)flash_base; + mtd_read(master, flash_base, sizeof(struct nsp_img_hdr_head), &len, (uint8_t *)&hdr); + if(hdr.magic != NSP_IMG_MAGIC_NUMBER) + return -1; /* Not a single image */ + + mtd_read(master, flash_base + hdr.sect_info_offset, sizeof(struct nsp_img_hdr_section_info), &len, (uint8_t *)§_info); + + /* Look for the root fs, and add it first. This way we KNOW where the rootfs is */ + for(i=0; i< sect_info.num_sects && isize); + total_sects++; + + if (!titan_parse_env_address("BOOTLOADER", &start, &end)){ + titan_add_partition("bootloader", start, end); + total_sects++; + } + if (!titan_parse_env_address("boot_env", &start, &end)){ + titan_add_partition("boot_env", start, end); + total_sects++; + } + *pparts = titan_parts; + return total_sects; +} diff --git a/target/linux/ar7/generic/config-default b/target/linux/ar7/generic/config-default new file mode 100644 index 0000000..10d46e9 --- /dev/null +++ b/target/linux/ar7/generic/config-default @@ -0,0 +1,5 @@ +CONFIG_AR7_TI=y +# CONFIG_AR7_TYPE_AC49X is not set +CONFIG_AR7_TYPE_TI=y +# CONFIG_MTD_AC49X_PARTS is not set +CONFIG_MTD_AR7_PARTS=y diff --git a/target/linux/ar7/generic/profiles/100-Annex-A.mk b/target/linux/ar7/generic/profiles/100-Annex-A.mk new file mode 100644 index 0000000..d8e549e --- /dev/null +++ b/target/linux/ar7/generic/profiles/100-Annex-A.mk @@ -0,0 +1,18 @@ +# +# Copyright (C) 2009 OpenWrt.org +# +# This is free software, licensed under the GNU General Public License v2. +# See /LICENSE for more information. +# + +define Profile/Annex-A + NAME:=Annex-A DSL firmware (default) + PACKAGES:=kmod-pppoa ppp-mod-pppoa linux-atm atm-tools br2684ctl \ + kmod-sangam-atm-annex-a +endef + +define Profile/Annex-A/Description + Package set compatible with Annex-A DSL lines (most countries). +endef +$(eval $(call Profile,Annex-A)) + diff --git a/target/linux/ar7/generic/profiles/110-Annex-B.mk b/target/linux/ar7/generic/profiles/110-Annex-B.mk new file mode 100644 index 0000000..55de1fc --- /dev/null +++ b/target/linux/ar7/generic/profiles/110-Annex-B.mk @@ -0,0 +1,18 @@ +# +# Copyright (C) 2009 OpenWrt.org +# +# This is free software, licensed under the GNU General Public License v2. +# See /LICENSE for more information. +# + +define Profile/Annex-B + NAME:=Annex-B DSL firmware + PACKAGES:=kmod-pppoa ppp-mod-pppoa linux-atm atm-tools br2684ctl \ + kmod-sangam-atm-annex-b +endef + +define Profile/Annex-B/Description + Package set compatible with Annex-B DSL lines (Germany). +endef +$(eval $(call Profile,Annex-B)) + diff --git a/target/linux/ar7/generic/profiles/200-Texas.mk b/target/linux/ar7/generic/profiles/200-Texas.mk new file mode 100644 index 0000000..7d868bd --- /dev/null +++ b/target/linux/ar7/generic/profiles/200-Texas.mk @@ -0,0 +1,18 @@ +# +# Copyright (C) 2006-2009 OpenWrt.org +# +# This is free software, licensed under the GNU General Public License v2. +# See /LICENSE for more information. +# + +define Profile/Texas + NAME:=Texas Instruments WiFi (mac80211) + PACKAGES:=kmod-acx-mac80211 +endef + +define Profile/Texas/Description + Package set compatible with hardware using Texas Instruments WiFi cards + using the mac80211 driver. +endef +$(eval $(call Profile,Texas)) + diff --git a/target/linux/ar7/generic/profiles/210-None.mk b/target/linux/ar7/generic/profiles/210-None.mk new file mode 100644 index 0000000..2fcfacd --- /dev/null +++ b/target/linux/ar7/generic/profiles/210-None.mk @@ -0,0 +1,17 @@ +# +# Copyright (C) 2006 OpenWrt.org +# +# This is free software, licensed under the GNU General Public License v2. +# See /LICENSE for more information. +# + +define Profile/None + NAME:=No WiFi + PACKAGES:= +endef + +define Profile/None/Description + Package set without WiFi support +endef +$(eval $(call Profile,None)) + diff --git a/target/linux/ar7/generic/target.mk b/target/linux/ar7/generic/target.mk new file mode 100644 index 0000000..8b5350e --- /dev/null +++ b/target/linux/ar7/generic/target.mk @@ -0,0 +1,12 @@ +# +# Copyright (C) 2012 OpenWrt.org +# + +SUBTARGET:=generic +BOARDNAME:=Texas Instruments AR7 boards + +DEFAULT_PACKAGES+= kmod-mac80211 kmod-acx-mac80211 wpad-mini + +define Target/Description + Build firmware images for TI AR7 based routers. +endef diff --git a/target/linux/ar7/image/Makefile b/target/linux/ar7/image/Makefile new file mode 100644 index 0000000..d20de27 --- /dev/null +++ b/target/linux/ar7/image/Makefile @@ -0,0 +1,137 @@ +# +# Copyright (C) 2006-2015 OpenWrt.org +# +# This is free software, licensed under the GNU General Public License v2. +# See /LICENSE for more information. +# +include $(TOPDIR)/rules.mk +include $(INCLUDE_DIR)/image.mk + +DROP_SECTIONS:=.reginfo .mdebug .comment .note .pdr .options .MIPS.options +OBJCOPY_SREC:=$(TARGET_CROSS)objcopy -S -O srec $(addprefix --remove-section=,$(DROP_SECTIONS)) + +LOADADDR:=0x94600000 +KERNEL_ENTRY:=0x94100000 +RAMSTART:=0x94000000 +RAMSIZE:=0x00100000 + +EVA_LOADADDR := 0x94100000 + +LOADER_MAKEOPTS= \ + KDIR=$(KDIR) \ + LOADADDR=$(LOADADDR) \ + KERNEL_ENTRY=$(KERNEL_ENTRY) \ + RAMSTART=$(RAMSTART) \ + RAMSIZE=$(RAMSIZE) + +CFLAGS := -D__KERNEL__ -Wall -Wstrict-prototypes -Wno-trigraphs -Os \ + -fno-strict-aliasing -fno-common -fomit-frame-pointer -G 0 -mno-abicalls -fno-pic \ + -pipe -mlong-calls -fno-common \ + -mabi=32 -march=mips32 -Wa,-32 -Wa,-march=mips32 -Wa,-mips32 -Wa,--trap \ + -DLOADADDR=$(LOADADDR) + +define Build/Clean + $(MAKE) -C $(GENERIC_PLATFORM_DIR)/image/lzma-loader $(LOADER_MAKEOPTS) clean +endef + +define Image/Prepare + cat $(KDIR)/vmlinux | $(STAGING_DIR_HOST)/bin/lzma e -si -so -eos -lc1 -lp2 -pb2 > $(KDIR)/vmlinux.lzma + $(STAGING_DIR_HOST)/bin/lzma2eva $(EVA_LOADADDR) 0x$${shell $(TARGET_CROSS)nm $(KDIR)/vmlinux | grep -w kernel_entry | cut -d' ' -f1} $(KDIR)/vmlinux.lzma $(KDIR)/loader.eva + + $(MAKE) -C $(GENERIC_PLATFORM_DIR)/image/lzma-loader \ + $(LOADER_MAKEOPTS) \ + clean compile + $(OBJCOPY_SREC) $(KDIR)/loader.elf $(KDIR)/loader.srec + $(OBJCOPY_SREC) $(KDIR)/vmlinux.elf $(KDIR)/vmlinux.srec + srec2bin $(KDIR)/loader.srec $(KDIR)/loader.bin + srec2bin $(KDIR)/vmlinux.srec $(KDIR)/vmlinux.bin +ifneq ($(CONFIG_TARGET_ROOTFS_INITRAMFS),) + $(OBJCOPY_SREC) $(KDIR)/vmlinux-initramfs.elf \ + $(KDIR)/vmlinux-initramfs.srec + srec2bin $(KDIR)/vmlinux-initramfs.srec $(KDIR)/vmlinux-initramfs.bin +endif +endef + +define align/jffs2-64k +bs=65536 conv=sync +endef + +define align/jffs2-128k +bs=131072 conv=sync +endef + +define align/squashfs +endef + +define Image/Build/CyberTAN + (dd if=/dev/zero bs=16 count=1; cat $(BIN_DIR)/$(IMG_PREFIX)-$(1).bin) | \ + $(STAGING_DIR_HOST)/bin/addpattern -p $(3) -o $(BIN_DIR)/$(IMG_PREFIX)-$(2)-$(4)-code.bin +endef + +define Image/Build/Titan + $(STAGING_DIR_HOST)/bin/mktitanimg -o $(BIN_DIR)/$(IMG_PREFIX)-$(2)-$(4)-code.bin -i $(KDIR)/loader.bin $(KDIR)/root.$(1) -a 0x10000 0x10000 -h 2 -p 0x4C575943 -s 0x0b010000 + $(STAGING_DIR_HOST)/bin/mktitanimg -o $(BIN_DIR)/$(IMG_PREFIX)-$(2)-na-$(4)-code.bin -i $(KDIR)/loader.bin $(KDIR)/root.$(1) -a 0x10000 0x10000 -h 2 -p 0x4D575943 -s 0x0b010000 +endef + +define Image/Build/AudioCodes + ( dd if=$(KDIR)/vmlinux.elf bs=64k conv=sync ; dd if=$(KDIR)/root.$(1) ) > $(BIN_DIR)/$(IMG_PREFIX)-$(2)-$(1).bin +endef + +#define Image/Build/sErCoMm +# cat sercomm/adam2.bin "$(BIN_DIR)/$(IMG_PREFIX)-$(1).bin" > "$(KDIR)/dgfw.tmp" +# dd if=sercomm/$(2) of="$(KDIR)/dgfw.tmp" bs=$$$$((0x3e0000 - 80)) seek=1 conv=notrunc +# $(STAGING_DIR_HOST)/bin/dgfirmware -f -w "$(BIN_DIR)/$(IMG_PREFIX)-$(2)-$(3).img" "$(KDIR)/dgfw.tmp" +# rm -f "$(KDIR)/dgfw.tmp" +#endef + +define Image/Build/EVA + dd if=$(KDIR)/loader.eva $(call align/$(1)) > $(BIN_DIR)/$(IMG_PREFIX)-$(2)-$(KERNEL)-$(1).bin + cat $(KDIR)/root.$(1) >> $(BIN_DIR)/$(IMG_PREFIX)-$(2)-$(KERNEL)-$(1).bin + $(call prepare_generic_squashfs,$(BIN_DIR)/$(IMG_PREFIX)-$(2)-$(KERNEL)-$(1).bin) +endef + +define Image/Build/Initramfs + $(CP) $(KDIR)/vmlinux-initramfs.bin $(BIN_DIR)/$(IMG_PREFIX)-initramfs.bin +endef + +ifeq ($(CONFIG_AR7_TI),y) +define Image/Build + dd if=$(KDIR)/loader.bin $(call align/$(1)) > $(BIN_DIR)/$(IMG_PREFIX)-$(1).bin + cat $(KDIR)/root.$(1) >> $(BIN_DIR)/$(IMG_PREFIX)-$(1).bin + $(call prepare_generic_squashfs,$(BIN_DIR)/$(IMG_PREFIX)-$(1).bin) + $(call Image/Build/CyberTAN,$(1),AG1B,AG1B,$(1)) + $(call Image/Build/CyberTAN,$(1),AG1A,AG1A,$(1)) + $(call Image/Build/CyberTAN,$(1),WA21,WA21,$(1)) + $(call Image/Build/CyberTAN,$(1),WA22,WA22,$(1)) + $(call Image/Build/CyberTAN,$(1),WAG2,WAG2,$(1)) + $(call Image/Build/CyberTAN,$(1),AG310,AV2A -b -r 1.0,$(1)) + $(call Image/Build/CyberTAN,$(1),AG241v2,AG3A -b -r 2.0,$(1)) + $(call Image/Build/CyberTAN,$(1),AG241v2b,AG3B -b -r 2.0,$(1)) + $(call Image/Build/CyberTAN,$(1),AG241v1,AG3A -b,$(1)) + $(call Image/Build/CyberTAN,$(1),WAG54GP2v1,ATWL -b,$(1)) + $(call Image/Build/CyberTAN,$(1),WAG54GP2v2,CTWL -b,$(1)) + $(call Image/Build/CyberTAN,$(1),WA31,WA31 -b,$(1)) + $(call Image/Build/CyberTAN,$(1),WA32,WA32 -b,$(1)) + $(call Image/Build/CyberTAN,$(1),WA7A,WA7A -b,$(1)) + $(call Image/Build/CyberTAN,$(1),WA7B,WA7B -b,$(1)) +# $(call Image/Build/sErCoMm,$(1),dg834,$(1)) +# $(call Image/Build/sErCoMm,$(1),jdr454wb,$(1)) + $(call Image/Build/EVA,$(1),EVA) + $(call Image/Build/Titan,$(1),Titan,Titan,$(1)) +ifeq ($(CONFIG_TARGET_ROOTFS_INITRAMFS),y) + $(call Image/Build/Initramfs) +endif +endef +endif + +ifeq ($(CONFIG_AR7_AC49X),y) +define Image/Build +# $(call prepare_generic_squashfs,$(BIN_DIR)/$(IMG_PREFIX)-$(1).bin) + $(call Image/Build/AudioCodes,$(1),mp202,$(1)) +ifeq ($(CONFIG_TARGET_ROOTFS_INITRAMFS),y) + $(call Image/Build/Initramfs) +endif +endef +endif + +$(eval $(call BuildImage)) diff --git a/target/linux/ar7/patches-3.18/001-mips-ar7-fix-serial.patch b/target/linux/ar7/patches-3.18/001-mips-ar7-fix-serial.patch new file mode 100644 index 0000000..6896352 --- /dev/null +++ b/target/linux/ar7/patches-3.18/001-mips-ar7-fix-serial.patch @@ -0,0 +1,23 @@ +From 443ab715a40881d6c9ba11b027ba154bac904cb0 Mon Sep 17 00:00:00 2001 +From: Oswald Buddenhagen +Date: Sat, 10 May 2014 23:19:08 +0200 +Subject: [PATCH] MIPS/AR7: ensure that serial ports are properly set up + +without UPF_FIXED_TYPE, the data from the PORT_AR7 uart_config entry is +never copied, resulting in a dead port. + +Signed-off-by: Oswald Buddenhagen +--- + arch/mips/ar7/platform.c | 1 + + 1 file changed, 1 insertion(+) + +--- a/arch/mips/ar7/platform.c ++++ b/arch/mips/ar7/platform.c +@@ -581,6 +581,7 @@ static int __init ar7_register_uarts(voi + uart_port.type = PORT_AR7; + uart_port.uartclk = clk_get_rate(bus_clk) / 2; + uart_port.iotype = UPIO_MEM32; ++ uart_port.flags = UPF_FIXED_TYPE; + uart_port.regshift = 2; + + uart_port.line = 0; diff --git a/target/linux/ar7/patches-3.18/100-fix-highmem-offset.patch b/target/linux/ar7/patches-3.18/100-fix-highmem-offset.patch new file mode 100644 index 0000000..f1a7549 --- /dev/null +++ b/target/linux/ar7/patches-3.18/100-fix-highmem-offset.patch @@ -0,0 +1,11 @@ +--- a/arch/mips/include/asm/mach-ar7/spaces.h ++++ b/arch/mips/include/asm/mach-ar7/spaces.h +@@ -20,6 +20,8 @@ + #define UNCAC_BASE _AC(0xb4000000, UL) /* 0xa0000000 + PHYS_OFFSET */ + #define IO_BASE UNCAC_BASE + ++#define HIGHMEM_START _AC(0x20000000, UL) ++ + #include + + #endif /* __ASM_AR7_SPACES_H */ diff --git a/target/linux/ar7/patches-3.18/110-flash.patch b/target/linux/ar7/patches-3.18/110-flash.patch new file mode 100644 index 0000000..e4aeffd --- /dev/null +++ b/target/linux/ar7/patches-3.18/110-flash.patch @@ -0,0 +1,22 @@ +--- a/drivers/mtd/Makefile ++++ b/drivers/mtd/Makefile +@@ -12,7 +12,7 @@ obj-$(CONFIG_MTD_OF_PARTS) += ofpart.o + obj-$(CONFIG_MTD_REDBOOT_PARTS) += redboot.o + obj-$(CONFIG_MTD_CMDLINE_PARTS) += cmdlinepart.o + obj-$(CONFIG_MTD_AFS_PARTS) += afs.o +-obj-$(CONFIG_MTD_AR7_PARTS) += ar7part.o ++obj-$(CONFIG_MTD_AR7_PARTS) += ar7part.o titanpart.o + obj-$(CONFIG_MTD_BCM63XX_PARTS) += bcm63xxpart.o + obj-$(CONFIG_MTD_BCM47XX_PARTS) += bcm47xxpart.o + obj-$(CONFIG_MTD_MYLOADER_PARTS) += myloader.o +--- a/arch/mips/ar7/platform.c ++++ b/arch/mips/ar7/platform.c +@@ -199,7 +199,7 @@ static struct resource physmap_flash_res + .name = "mem", + .flags = IORESOURCE_MEM, + .start = 0x10000000, +- .end = 0x107fffff, ++ .end = 0x11ffffff, + }; + + static const char *ar7_probe_types[] = { "ar7part", NULL }; diff --git a/target/linux/ar7/patches-3.18/120-gpio_chrdev.patch b/target/linux/ar7/patches-3.18/120-gpio_chrdev.patch new file mode 100644 index 0000000..beb0052 --- /dev/null +++ b/target/linux/ar7/patches-3.18/120-gpio_chrdev.patch @@ -0,0 +1,28 @@ +--- a/drivers/char/Kconfig ++++ b/drivers/char/Kconfig +@@ -452,6 +452,15 @@ config MWAVE + To compile this driver as a module, choose M here: the + module will be called mwave. + ++config AR7_GPIO ++ tristate "TI AR7 GPIO Support" ++ depends on AR7 ++ help ++ Give userspace access to the GPIO pins on the Texas Instruments AR7 ++ processors. ++ ++ If compiled as a module, it will be called ar7_gpio. ++ + config SCx200_GPIO + tristate "NatSemi SCx200 GPIO Support" + depends on SCx200 +--- a/drivers/char/Makefile ++++ b/drivers/char/Makefile +@@ -42,6 +42,7 @@ obj-$(CONFIG_HW_RANDOM) += hw_random/ + obj-$(CONFIG_PPDEV) += ppdev.o + obj-$(CONFIG_NWBUTTON) += nwbutton.o + obj-$(CONFIG_NWFLASH) += nwflash.o ++obj-$(CONFIG_AR7_GPIO) += ar7_gpio.o + obj-$(CONFIG_SCx200_GPIO) += scx200_gpio.o + obj-$(CONFIG_PC8736x_GPIO) += pc8736x_gpio.o + obj-$(CONFIG_NSC_GPIO) += nsc_gpio.o diff --git a/target/linux/ar7/patches-3.18/160-vlynq_try_remote_first.patch b/target/linux/ar7/patches-3.18/160-vlynq_try_remote_first.patch new file mode 100644 index 0000000..1d1310d --- /dev/null +++ b/target/linux/ar7/patches-3.18/160-vlynq_try_remote_first.patch @@ -0,0 +1,300 @@ +--- a/drivers/vlynq/vlynq.c ++++ b/drivers/vlynq/vlynq.c +@@ -119,20 +119,40 @@ static int vlynq_linked(struct vlynq_dev + return 0; + } + ++static volatile int vlynq_delay_value_new = 0; ++ ++static void vlynq_delay_wait(u32 count) ++{ ++ /* Code adopted from original vlynq driver */ ++ int i = 0; ++ volatile int *ptr = &vlynq_delay_value_new; ++ *ptr = 0; ++ ++ /* We are assuming that the each cycle takes about ++ * 23 assembly instructions. */ ++ for(i = 0; i < (count + 23)/23; i++) ++ *ptr = *ptr + 1; ++} ++ + static void vlynq_reset(struct vlynq_device *dev) + { ++ u32 rtm = readl(&dev->local->revision); ++ ++ rtm = rtm < 0x00010205 || readl(&dev->local->status) & 0x800 == 0 ? ++ 0 : 0x600000; ++ + writel(readl(&dev->local->control) | VLYNQ_CTRL_RESET, + &dev->local->control); + + /* Wait for the devices to finish resetting */ +- msleep(5); ++ vlynq_delay_wait(0xffffff); + + /* Remove reset bit */ +- writel(readl(&dev->local->control) & ~VLYNQ_CTRL_RESET, ++ writel(readl(&dev->local->control) & ~VLYNQ_CTRL_RESET | rtm, + &dev->local->control); + + /* Give some time for the devices to settle */ +- msleep(5); ++ vlynq_delay_wait(0xffffff); + } + + static void vlynq_irq_unmask(struct irq_data *d) +@@ -379,6 +399,61 @@ void vlynq_unregister_driver(struct vlyn + } + EXPORT_SYMBOL(vlynq_unregister_driver); + ++enum vlynq_clk_src { ++ vlynq_clk_external, ++ vlynq_clk_local, ++ vlynq_clk_remote, ++ vlynq_clk_invalid, ++}; ++ ++static int __vlynq_set_clocks(struct vlynq_device *dev, ++ enum vlynq_clk_src clk_dir, ++ int lclk_div, int rclk_div) ++{ ++ u32 reg; ++ ++ if (clk_dir == vlynq_clk_invalid) { ++ printk(KERN_ERR "%s: attempt to set invalid clocking\n", ++ dev_name(&dev->dev)); ++ return -EINVAL; ++ } ++ ++ reg = readl(&dev->local->control); ++ if (readl(&dev->local->revision) < 0x00010205) { ++ if (clk_dir & vlynq_clk_local) ++ reg |= VLYNQ_CTRL_CLOCK_INT; ++ else ++ reg &= ~VLYNQ_CTRL_CLOCK_INT; ++ } ++ reg &= ~VLYNQ_CTRL_CLOCK_MASK; ++ reg |= VLYNQ_CTRL_CLOCK_DIV(lclk_div); ++ writel(reg, &dev->local->control); ++ ++ if (!vlynq_linked(dev)) ++ return -ENODEV; ++ ++ printk(KERN_INFO "%s: local VLYNQ protocol rev. is 0x%08x\n", ++ dev_name(&dev->dev), readl(&dev->local->revision)); ++ printk(KERN_INFO "%s: remote VLYNQ protocol rev. is 0x%08x\n", ++ dev_name(&dev->dev), readl(&dev->remote->revision)); ++ ++ reg = readl(&dev->remote->control); ++ if (readl(&dev->remote->revision) < 0x00010205) { ++ if (clk_dir & vlynq_clk_remote) ++ reg |= VLYNQ_CTRL_CLOCK_INT; ++ else ++ reg &= ~VLYNQ_CTRL_CLOCK_INT; ++ } ++ reg &= ~VLYNQ_CTRL_CLOCK_MASK; ++ reg |= VLYNQ_CTRL_CLOCK_DIV(rclk_div); ++ writel(reg, &dev->remote->control); ++ ++ if (!vlynq_linked(dev)) ++ return -ENODEV; ++ ++ return 0; ++} ++ + /* + * A VLYNQ remote device can clock the VLYNQ bus master + * using a dedicated clock line. In that case, both the +@@ -392,29 +467,16 @@ static int __vlynq_try_remote(struct vly + int i; + + vlynq_reset(dev); +- for (i = dev->dev_id ? vlynq_rdiv2 : vlynq_rdiv8; dev->dev_id ? +- i <= vlynq_rdiv8 : i >= vlynq_rdiv2; +- dev->dev_id ? i++ : i--) { ++ for (i = 0; i <= 7; i++) { + + if (!vlynq_linked(dev)) + break; + +- writel((readl(&dev->remote->control) & +- ~VLYNQ_CTRL_CLOCK_MASK) | +- VLYNQ_CTRL_CLOCK_INT | +- VLYNQ_CTRL_CLOCK_DIV(i - vlynq_rdiv1), +- &dev->remote->control); +- writel((readl(&dev->local->control) +- & ~(VLYNQ_CTRL_CLOCK_INT | +- VLYNQ_CTRL_CLOCK_MASK)) | +- VLYNQ_CTRL_CLOCK_DIV(i - vlynq_rdiv1), +- &dev->local->control); +- +- if (vlynq_linked(dev)) { +- printk(KERN_DEBUG +- "%s: using remote clock divisor %d\n", +- dev_name(&dev->dev), i - vlynq_rdiv1 + 1); +- dev->divisor = i; ++ if (!__vlynq_set_clocks(dev, vlynq_clk_remote, i, i)) { ++ printk(KERN_INFO ++ "%s: using remote clock divisor %d\n", ++ dev_name(&dev->dev), i + 1); ++ dev->divisor = i + vlynq_rdiv1; + return 0; + } else { + vlynq_reset(dev); +@@ -433,25 +495,17 @@ static int __vlynq_try_remote(struct vly + */ + static int __vlynq_try_local(struct vlynq_device *dev) + { +- int i; ++ int i, dir = !dev->dev_id; + + vlynq_reset(dev); + +- for (i = dev->dev_id ? vlynq_ldiv2 : vlynq_ldiv8; dev->dev_id ? +- i <= vlynq_ldiv8 : i >= vlynq_ldiv2; +- dev->dev_id ? i++ : i--) { +- +- writel((readl(&dev->local->control) & +- ~VLYNQ_CTRL_CLOCK_MASK) | +- VLYNQ_CTRL_CLOCK_INT | +- VLYNQ_CTRL_CLOCK_DIV(i - vlynq_ldiv1), +- &dev->local->control); +- +- if (vlynq_linked(dev)) { +- printk(KERN_DEBUG +- "%s: using local clock divisor %d\n", +- dev_name(&dev->dev), i - vlynq_ldiv1 + 1); +- dev->divisor = i; ++ for (i = dir ? 7 : 0; dir ? i >= 0 : i <= 7; dir ? i-- : i++) { ++ ++ if (!__vlynq_set_clocks(dev, vlynq_clk_local, i, 0)) { ++ printk(KERN_INFO ++ "%s: using local clock divisor %d\n", ++ dev_name(&dev->dev), i + 1); ++ dev->divisor = i + vlynq_ldiv1; + return 0; + } else { + vlynq_reset(dev); +@@ -473,18 +527,10 @@ static int __vlynq_try_external(struct v + if (!vlynq_linked(dev)) + return -ENODEV; + +- writel((readl(&dev->remote->control) & +- ~VLYNQ_CTRL_CLOCK_INT), +- &dev->remote->control); +- +- writel((readl(&dev->local->control) & +- ~VLYNQ_CTRL_CLOCK_INT), +- &dev->local->control); +- +- if (vlynq_linked(dev)) { +- printk(KERN_DEBUG "%s: using external clock\n", +- dev_name(&dev->dev)); +- dev->divisor = vlynq_div_external; ++ if (!__vlynq_set_clocks(dev, vlynq_clk_external, 0, 0)) { ++ printk(KERN_INFO "%s: using external clock\n", ++ dev_name(&dev->dev)); ++ dev->divisor = vlynq_div_external; + return 0; + } + +@@ -501,24 +547,16 @@ static int __vlynq_enable_device(struct + return result; + + switch (dev->divisor) { +- case vlynq_div_external: + case vlynq_div_auto: + /* When the device is brought from reset it should have clock + * generation negotiated by hardware. + * Check which device is generating clocks and perform setup + * accordingly */ +- if (vlynq_linked(dev) && readl(&dev->remote->control) & +- VLYNQ_CTRL_CLOCK_INT) { +- if (!__vlynq_try_remote(dev) || +- !__vlynq_try_local(dev) || +- !__vlynq_try_external(dev)) +- return 0; +- } else { +- if (!__vlynq_try_external(dev) || +- !__vlynq_try_local(dev) || +- !__vlynq_try_remote(dev)) +- return 0; +- } ++ if (!__vlynq_try_remote(dev) || !__vlynq_try_local(dev)) ++ return 0; ++ case vlynq_div_external: ++ if (!__vlynq_try_external(dev)) ++ return 0; + break; + case vlynq_ldiv1: + case vlynq_ldiv2: +@@ -528,15 +566,12 @@ static int __vlynq_enable_device(struct + case vlynq_ldiv6: + case vlynq_ldiv7: + case vlynq_ldiv8: +- writel(VLYNQ_CTRL_CLOCK_INT | +- VLYNQ_CTRL_CLOCK_DIV(dev->divisor - +- vlynq_ldiv1), &dev->local->control); +- writel(0, &dev->remote->control); +- if (vlynq_linked(dev)) { +- printk(KERN_DEBUG +- "%s: using local clock divisor %d\n", +- dev_name(&dev->dev), +- dev->divisor - vlynq_ldiv1 + 1); ++ if (!__vlynq_set_clocks(dev, vlynq_clk_local, dev->divisor - ++ vlynq_ldiv1, 0)) { ++ printk(KERN_INFO ++ "%s: using local clock divisor %d\n", ++ dev_name(&dev->dev), ++ dev->divisor - vlynq_ldiv1 + 1); + return 0; + } + break; +@@ -548,20 +583,17 @@ static int __vlynq_enable_device(struct + case vlynq_rdiv6: + case vlynq_rdiv7: + case vlynq_rdiv8: +- writel(0, &dev->local->control); +- writel(VLYNQ_CTRL_CLOCK_INT | +- VLYNQ_CTRL_CLOCK_DIV(dev->divisor - +- vlynq_rdiv1), &dev->remote->control); +- if (vlynq_linked(dev)) { +- printk(KERN_DEBUG +- "%s: using remote clock divisor %d\n", +- dev_name(&dev->dev), +- dev->divisor - vlynq_rdiv1 + 1); ++ if (!__vlynq_set_clocks(dev, vlynq_clk_remote, 0, ++ dev->divisor - vlynq_rdiv1)) { ++ printk(KERN_INFO ++ "%s: using remote clock divisor %d\n", ++ dev_name(&dev->dev), ++ dev->divisor - vlynq_rdiv1 + 1); + return 0; + } + break; + } +- ++ vlynq_reset(dev); + ops->off(dev); + return -ENODEV; + } +@@ -732,14 +764,14 @@ static int vlynq_probe(struct platform_d + platform_set_drvdata(pdev, dev); + + printk(KERN_INFO "%s: regs 0x%p, irq %d, mem 0x%p\n", +- dev_name(&dev->dev), (void *)dev->regs_start, dev->irq, +- (void *)dev->mem_start); ++ dev_name(&dev->dev), (void *)dev->regs_start, ++ dev->irq, (void *)dev->mem_start); + + dev->dev_id = 0; + dev->divisor = vlynq_div_auto; +- result = __vlynq_enable_device(dev); +- if (result == 0) { ++ if (!__vlynq_enable_device(dev)) { + dev->dev_id = readl(&dev->remote->chip); ++ vlynq_reset(dev); + ((struct plat_vlynq_ops *)(dev->dev.platform_data))->off(dev); + } + if (dev->dev_id) diff --git a/target/linux/ar7/patches-3.18/200-free-mem-below-kernel-offset.patch b/target/linux/ar7/patches-3.18/200-free-mem-below-kernel-offset.patch new file mode 100644 index 0000000..4011942 --- /dev/null +++ b/target/linux/ar7/patches-3.18/200-free-mem-below-kernel-offset.patch @@ -0,0 +1,15 @@ +--- a/arch/mips/ar7/memory.c ++++ b/arch/mips/ar7/memory.c +@@ -66,5 +66,11 @@ void __init prom_meminit(void) + + void __init prom_free_prom_memory(void) + { +- /* Nothing to free */ ++ /* adapted from arch/mips/txx9/generic/setup.c */ ++ unsigned long saddr = PHYS_OFFSET + PAGE_SIZE; ++ unsigned long eaddr = __pa_symbol(&_text); ++ ++ /* free memory between prom-record and kernel _text base */ ++ if (saddr < eaddr) ++ free_init_pages("prom memory", saddr, eaddr); + } diff --git a/target/linux/ar7/patches-3.18/300-add-ac49x-platform.patch b/target/linux/ar7/patches-3.18/300-add-ac49x-platform.patch new file mode 100644 index 0000000..ccdc84d --- /dev/null +++ b/target/linux/ar7/patches-3.18/300-add-ac49x-platform.patch @@ -0,0 +1,85 @@ +--- a/arch/mips/ar7/Platform ++++ b/arch/mips/ar7/Platform +@@ -3,4 +3,9 @@ + # + platform-$(CONFIG_AR7) += ar7/ + cflags-$(CONFIG_AR7) += -I$(srctree)/arch/mips/include/asm/mach-ar7 +-load-$(CONFIG_AR7) += 0xffffffff94100000 ++load-$(CONFIG_AR7_TI) += 0xffffffff94100000 ++ ++# ++# AudioCodes AC49x ++# ++load-$(CONFIG_AR7_AC49X) += 0xffffffff945ca000 +--- a/arch/mips/ar7/setup.c ++++ b/arch/mips/ar7/setup.c +@@ -69,6 +69,10 @@ const char *get_system_type(void) + return "TI AR7 (TNETV1056)"; + case TITAN_CHIP_1060: + return "TI AR7 (TNETV1060)"; ++ case TITAN_CHIP_AC495: ++ return "AudioCodes AC495"; ++ case TITAN_CHIP_AC496: ++ return "AudioCodes AC496"; + } + default: + return "TI AR7 (unknown)"; +--- a/arch/mips/include/asm/mach-ar7/ar7.h ++++ b/arch/mips/include/asm/mach-ar7/ar7.h +@@ -92,6 +92,8 @@ + #define TITAN_CHIP_1055 0x0e + #define TITAN_CHIP_1056 0x0d + #define TITAN_CHIP_1060 0x07 ++#define TITAN_CHIP_AC495 0x00 ++#define TITAN_CHIP_AC496 0x02 + + /* Interrupts */ + #define AR7_IRQ_UART0 15 +--- a/arch/mips/Kconfig ++++ b/arch/mips/Kconfig +@@ -94,7 +94,7 @@ config AR7 + select HAVE_CLK + help + Support for the Texas Instruments AR7 System-on-a-Chip +- family: TNETD7100, 7200 and 7300. ++ family: TI TNETD7100, 7200, 7300 and AudioCodes AC49x. + + config ATH79 + bool "Atheros AR71XX/AR724X/AR913X based boards" +@@ -835,6 +835,7 @@ config MIPS_PARAVIRT + endchoice + + source "arch/mips/alchemy/Kconfig" ++source "arch/mips/ar7/Kconfig" + source "arch/mips/ath79/Kconfig" + source "arch/mips/bcm47xx/Kconfig" + source "arch/mips/bcm63xx/Kconfig" +--- /dev/null ++++ b/arch/mips/ar7/Kconfig +@@ -0,0 +1,26 @@ ++if AR7 ++ ++config AR7_TI ++ bool ++ ++config AR7_AC49X ++ bool ++ ++choice ++ prompt "AR7 SoC family selection" ++ default AR7_TYPE_TI ++ depends on AR7 ++ help ++ Select AR7 MIPS SoC implementation. ++ ++ config AR7_TYPE_TI ++ bool "Texas Instruments AR7" ++ select AR7_TI ++ ++ config AR7_TYPE_AC49X ++ bool "AudioCodes AC49X" ++ select AR7_AC49X ++ ++endchoice ++ ++endif diff --git a/target/linux/ar7/patches-3.18/310-ac49x-prom-support.patch b/target/linux/ar7/patches-3.18/310-ac49x-prom-support.patch new file mode 100644 index 0000000..dddf221 --- /dev/null +++ b/target/linux/ar7/patches-3.18/310-ac49x-prom-support.patch @@ -0,0 +1,20 @@ +--- a/arch/mips/ar7/prom.c ++++ b/arch/mips/ar7/prom.c +@@ -70,6 +70,7 @@ struct psbl_rec { + }; + + static const char psp_env_version[] __initconst = "TIENV0.8"; ++static const char psp_env_version_ac49x[] __initconst = "MaxENV0.2"; + + struct psp_env_chunk { + u8 num; +@@ -186,7 +187,8 @@ static void __init ar7_init_env(struct e + struct psbl_rec *psbl = (struct psbl_rec *)(KSEG1ADDR(0x14000300)); + void *psp_env = (void *)KSEG1ADDR(psbl->env_base); + +- if (strcmp(psp_env, psp_env_version) == 0) { ++ if (strcmp(psp_env, psp_env_version) == 0 || ++ strcmp(psp_env, psp_env_version_ac49x) == 0) { + parse_psp_env(psp_env); + } else { + for (i = 0; i < MAX_ENTRY; i++, env++) diff --git a/target/linux/ar7/patches-3.18/320-ac49x-mtd-partitions.patch b/target/linux/ar7/patches-3.18/320-ac49x-mtd-partitions.patch new file mode 100644 index 0000000..53ac072 --- /dev/null +++ b/target/linux/ar7/patches-3.18/320-ac49x-mtd-partitions.patch @@ -0,0 +1,35 @@ +--- a/drivers/mtd/Kconfig ++++ b/drivers/mtd/Kconfig +@@ -164,6 +164,11 @@ config MTD_OF_PARTS + the partition map from the children of the flash node, + as described in Documentation/devicetree/booting-without-of.txt. + ++config MTD_AC49X_PARTS ++ tristate "AudioCodes AC49X partitioning support" ++ ---help--- ++ AudioCodes AC49X partitioning support ++ + config MTD_AR7_PARTS + tristate "TI AR7 partitioning support" + ---help--- +--- a/drivers/mtd/Makefile ++++ b/drivers/mtd/Makefile +@@ -11,6 +11,7 @@ obj-$(CONFIG_MTD_SPLIT) += mtdsplit/ + obj-$(CONFIG_MTD_OF_PARTS) += ofpart.o + obj-$(CONFIG_MTD_REDBOOT_PARTS) += redboot.o + obj-$(CONFIG_MTD_CMDLINE_PARTS) += cmdlinepart.o ++obj-$(CONFIG_MTD_AC49X_PARTS) += ac49xpart.o + obj-$(CONFIG_MTD_AFS_PARTS) += afs.o + obj-$(CONFIG_MTD_AR7_PARTS) += ar7part.o titanpart.o + obj-$(CONFIG_MTD_BCM63XX_PARTS) += bcm63xxpart.o +--- a/arch/mips/ar7/platform.c ++++ b/arch/mips/ar7/platform.c +@@ -202,7 +202,7 @@ static struct resource physmap_flash_res + .end = 0x11ffffff, + }; + +-static const char *ar7_probe_types[] = { "ar7part", NULL }; ++static const char *ar7_probe_types[] = { "ac49xpart", "ar7part", NULL }; + + static struct physmap_flash_data physmap_flash_data = { + .width = 2, diff --git a/target/linux/ar7/patches-3.18/500-serial_kludge.patch b/target/linux/ar7/patches-3.18/500-serial_kludge.patch new file mode 100644 index 0000000..08bd6a6 --- /dev/null +++ b/target/linux/ar7/patches-3.18/500-serial_kludge.patch @@ -0,0 +1,28 @@ +--- a/drivers/tty/serial/8250/8250_core.c ++++ b/drivers/tty/serial/8250/8250_core.c +@@ -329,6 +329,13 @@ static const struct serial8250_config ua + .fcr = UART_FCR_ENABLE_FIFO | UART_FCR_R_TRIG_10, + .flags = UART_CAP_FIFO | UART_CAP_AFE, + }, ++ [PORT_AR7] = { ++ .name = "TI-AR7", ++ .fifo_size = 16, ++ .tx_loadsz = 16, ++ .fcr = UART_FCR_ENABLE_FIFO | UART_FCR_R_TRIG_00, ++ .flags = UART_CAP_FIFO | UART_CAP_AFE, ++ }, + }; + + /* Uart divisor latch read */ +@@ -3174,7 +3181,11 @@ static void serial8250_console_putchar(s + { + struct uart_8250_port *up = up_to_u8250p(port); + ++#ifdef CONFIG_AR7 ++ wait_for_xmitr(up, BOTH_EMPTY); ++#else + wait_for_xmitr(up, UART_LSR_THRE); ++#endif + serial_port_out(port, UART_TX, ch); + } + diff --git a/target/linux/ar7/patches-3.18/920-ar7part.patch b/target/linux/ar7/patches-3.18/920-ar7part.patch new file mode 100644 index 0000000..9948858 --- /dev/null +++ b/target/linux/ar7/patches-3.18/920-ar7part.patch @@ -0,0 +1,118 @@ +--- a/drivers/mtd/ar7part.c ++++ b/drivers/mtd/ar7part.c +@@ -30,11 +30,14 @@ + + #include + ++#include ++ + #define AR7_PARTS 4 + #define ROOT_OFFSET 0xe0000 + + #define LOADER_MAGIC1 le32_to_cpu(0xfeedfa42) + #define LOADER_MAGIC2 le32_to_cpu(0xfeed1281) ++#define LOADER_MAGIC3 le32_to_cpu(0x434d4d4c) + + struct ar7_bin_rec { + unsigned int checksum; +@@ -42,12 +45,16 @@ struct ar7_bin_rec { + unsigned int address; + }; + ++int create_titan_partitions(struct mtd_info *master, ++ struct mtd_partition **pparts, ++ struct mtd_part_parser_data *data); ++ + static int create_mtd_partitions(struct mtd_info *master, + struct mtd_partition **pparts, + struct mtd_part_parser_data *data) + { + struct ar7_bin_rec header; +- unsigned int offset; ++ unsigned int offset, mtd_start, mtd_end; + size_t len; + unsigned int pre_size = master->erasesize, post_size = 0; + unsigned int root_offset = ROOT_OFFSET; +@@ -55,6 +62,16 @@ static int create_mtd_partitions(struct + int retries = 10; + struct mtd_partition *ar7_parts; + ++ const char *prom_str = prom_getenv("ProductID"); ++ char mtd_name[] = "mtd1"; ++ if(prom_str && ++ (strcmp(prom_str, "CYWL")==0 || ++ strcmp(prom_str, "CYWM")==0 || ++ strcmp(prom_str, "CYLM")==0 || ++ strcmp(prom_str, "CYLL")==0)){ ++ return create_titan_partitions(master, pparts, data); ++ } ++ + ar7_parts = kzalloc(sizeof(*ar7_parts) * AR7_PARTS, GFP_KERNEL); + if (!ar7_parts) + return -ENOMEM; +@@ -83,34 +100,39 @@ static int create_mtd_partitions(struct + + pre_size = offset; + +- if (!ar7_parts[1].offset) { +- ar7_parts[1].offset = master->size - master->erasesize; +- post_size = master->erasesize; +- } +- + switch (header.checksum) { +- case LOADER_MAGIC1: +- while (header.length) { +- offset += sizeof(header) + header.length; +- mtd_read(master, offset, sizeof(header), &len, +- (uint8_t *)&header); +- } +- root_offset = offset + sizeof(header) + 4; +- break; + case LOADER_MAGIC2: ++ for (retries = 0; retries <= 9; retries++) { ++ mtd_name[3] = '0' + retries; ++ prom_str = prom_getenv(mtd_name); ++ if (prom_str == NULL) ++ continue; ++ sscanf(prom_str, "%i,%i", &mtd_start, &mtd_end); ++ if (pre_size == (mtd_start & 0x1ffffff)) { ++ ar7_parts[1].offset = mtd_end &= 0x1ffffff; ++ ar7_parts[1].size = post_size = master->size - mtd_end; ++ break; ++ } ++ } ++ case LOADER_MAGIC1: ++ root_offset = (header.checksum == LOADER_MAGIC1) ? 4 : 0; + while (header.length) { + offset += sizeof(header) + header.length; + mtd_read(master, offset, sizeof(header), &len, + (uint8_t *)&header); + } +- root_offset = offset + sizeof(header) + 4 + 0xff; +- root_offset &= ~(uint32_t)0xff; ++ root_offset += offset + sizeof(header); + break; + default: + printk(KERN_WARNING "Unknown magic: %08x\n", header.checksum); + break; + } + ++ if (!ar7_parts[1].offset) { ++ post_size = master->erasesize; ++ ar7_parts[1].offset = master->size - post_size; ++ } ++ + mtd_read(master, root_offset, sizeof(header), &len, (u8 *)&header); + if (header.checksum != SQUASHFS_MAGIC) { + root_offset += master->erasesize - 1; +--- a/drivers/mtd/titanpart.c ++++ b/drivers/mtd/titanpart.c +@@ -149,7 +149,7 @@ static void titan_add_partition(char * e + } + int create_titan_partitions(struct mtd_info *master, + struct mtd_partition **pparts, +- unsigned long origin) ++ struct mtd_part_parser_data *data) + { + struct nsp_img_hdr_head hdr; + struct nsp_img_hdr_section_info sect_info; diff --git a/target/linux/ar7/patches-3.18/925-actiontec_leds.patch b/target/linux/ar7/patches-3.18/925-actiontec_leds.patch new file mode 100644 index 0000000..41af2cb --- /dev/null +++ b/target/linux/ar7/patches-3.18/925-actiontec_leds.patch @@ -0,0 +1,95 @@ +--- a/arch/mips/ar7/platform.c ++++ b/arch/mips/ar7/platform.c +@@ -465,31 +465,22 @@ static struct gpio_led fb_fon_leds[] = { + }, + }; + +-static struct gpio_led gt701_leds[] = { ++static struct gpio_led actiontec_leds[] = { + { + .name = "inet:green", + .gpio = 13, +- .active_low = 1, +- }, +- { +- .name = "usb", +- .gpio = 12, +- .active_low = 1, + }, + { + .name = "inet:red", + .gpio = 9, +- .active_low = 1, + }, + { +- .name = "power:red", ++ .name = "power:green", + .gpio = 7, +- .active_low = 1, + }, + { +- .name = "power:green", ++ .name = "power:red", + .gpio = 8, +- .active_low = 1, + .default_trigger = "default-on", + }, + { +@@ -497,6 +488,44 @@ static struct gpio_led gt701_leds[] = { + .gpio = 10, + .active_low = 1, + }, ++ { ++ .name = "wifi", ++ .gpio = 6, ++ .active_low = 1, ++ }, ++ { ++ .name = "wifi:red", ++ .gpio = 3, ++ }, ++ { ++ .name = "standby", ++ .gpio = 4, ++ }, ++ { ++ .name = "wps", ++ .gpio = 16, ++ .active_low = 1, ++ }, ++ { ++ .name = "usb", ++ .gpio = 12, ++ .active_low = 1, ++ }, ++ { ++ .name = "voip", ++ .gpio = 15, ++ .active_low = 1, ++ }, ++ { ++ .name = "line1", ++ .gpio = 23, ++ .active_low = 1, ++ }, ++ { ++ .name = "line2", ++ .gpio = 25, ++ .active_low = 1, ++ }, + }; + + static struct gpio_led_platform_data ar7_led_data; +@@ -540,9 +569,9 @@ static void __init detect_leds(void) + } else if (strstr(prid, "CYWM") || strstr(prid, "CYWL")) { + ar7_led_data.num_leds = ARRAY_SIZE(titan_leds); + ar7_led_data.leds = titan_leds; +- } else if (strstr(prid, "GT701")) { +- ar7_led_data.num_leds = ARRAY_SIZE(gt701_leds); +- ar7_led_data.leds = gt701_leds; ++ } else if (strstr(prid, "GT7") || strstr(prid, "PK5000")) { ++ ar7_led_data.num_leds = ARRAY_SIZE(actiontec_leds); ++ ar7_led_data.leds = actiontec_leds; + } + } + diff --git a/target/linux/ar7/patches-3.18/950-cpmac_titan.patch b/target/linux/ar7/patches-3.18/950-cpmac_titan.patch new file mode 100644 index 0000000..f1d432c --- /dev/null +++ b/target/linux/ar7/patches-3.18/950-cpmac_titan.patch @@ -0,0 +1,52 @@ +--- a/drivers/net/ethernet/ti/cpmac.c ++++ b/drivers/net/ethernet/ti/cpmac.c +@@ -1146,6 +1146,8 @@ static int cpmac_probe(struct platform_d + goto out; + } + ++ ar7_device_reset(pdata->reset_bit); ++ + dev->irq = platform_get_irq_byname(pdev, "irq"); + + dev->netdev_ops = &cpmac_netdev_ops; +@@ -1227,7 +1229,7 @@ int cpmac_init(void) + cpmac_mii->reset = cpmac_mdio_reset; + cpmac_mii->irq = mii_irqs; + +- cpmac_mii->priv = ioremap(AR7_REGS_MDIO, 256); ++ cpmac_mii->priv = ioremap(ar7_is_titan() ? TITAN_REGS_MDIO : AR7_REGS_MDIO, 256); + + if (!cpmac_mii->priv) { + pr_err("Can't ioremap mdio registers\n"); +@@ -1238,10 +1240,16 @@ int cpmac_init(void) + #warning FIXME: unhardcode gpio&reset bits + ar7_gpio_disable(26); + ar7_gpio_disable(27); +- ar7_device_reset(AR7_RESET_BIT_CPMAC_LO); +- ar7_device_reset(AR7_RESET_BIT_CPMAC_HI); ++ ++ if (!ar7_is_titan()) { ++ ar7_device_reset(AR7_RESET_BIT_CPMAC_LO); ++ ar7_device_reset(AR7_RESET_BIT_CPMAC_HI); ++ } + ar7_device_reset(AR7_RESET_BIT_EPHY); + ++ if (ar7_is_titan()) ++ ar7_device_reset(TITAN_RESET_BIT_EPHY1); ++ + cpmac_mii->reset(cpmac_mii); + + for (i = 0; i < 300; i++) { +@@ -1258,7 +1266,11 @@ int cpmac_init(void) + mask = 0; + } + +- cpmac_mii->phy_mask = ~(mask | 0x80000000); ++ if (ar7_is_titan()) ++ cpmac_mii->phy_mask = ~(mask | 0x80000000 | 0x40000000); ++ else ++ cpmac_mii->phy_mask = ~(mask | 0x80000000); ++ + snprintf(cpmac_mii->id, MII_BUS_ID_SIZE, "cpmac-1"); + + res = mdiobus_register(cpmac_mii); diff --git a/target/linux/ar7/patches-4.1/001-mips-ar7-fix-serial.patch b/target/linux/ar7/patches-4.1/001-mips-ar7-fix-serial.patch new file mode 100644 index 0000000..1aded92 --- /dev/null +++ b/target/linux/ar7/patches-4.1/001-mips-ar7-fix-serial.patch @@ -0,0 +1,23 @@ +From 443ab715a40881d6c9ba11b027ba154bac904cb0 Mon Sep 17 00:00:00 2001 +From: Oswald Buddenhagen +Date: Sat, 10 May 2014 23:19:08 +0200 +Subject: [PATCH] MIPS/AR7: ensure that serial ports are properly set up + +without UPF_FIXED_TYPE, the data from the PORT_AR7 uart_config entry is +never copied, resulting in a dead port. + +Signed-off-by: Oswald Buddenhagen +--- + arch/mips/ar7/platform.c | 1 + + 1 file changed, 1 insertion(+) + +--- a/arch/mips/ar7/platform.c ++++ b/arch/mips/ar7/platform.c +@@ -577,6 +577,7 @@ static int __init ar7_register_uarts(voi + uart_port.type = PORT_AR7; + uart_port.uartclk = clk_get_rate(bus_clk) / 2; + uart_port.iotype = UPIO_MEM32; ++ uart_port.flags = UPF_FIXED_TYPE; + uart_port.regshift = 2; + + uart_port.line = 0; diff --git a/target/linux/ar7/patches-4.1/100-fix-highmem-offset.patch b/target/linux/ar7/patches-4.1/100-fix-highmem-offset.patch new file mode 100644 index 0000000..f1a7549 --- /dev/null +++ b/target/linux/ar7/patches-4.1/100-fix-highmem-offset.patch @@ -0,0 +1,11 @@ +--- a/arch/mips/include/asm/mach-ar7/spaces.h ++++ b/arch/mips/include/asm/mach-ar7/spaces.h +@@ -20,6 +20,8 @@ + #define UNCAC_BASE _AC(0xb4000000, UL) /* 0xa0000000 + PHYS_OFFSET */ + #define IO_BASE UNCAC_BASE + ++#define HIGHMEM_START _AC(0x20000000, UL) ++ + #include + + #endif /* __ASM_AR7_SPACES_H */ diff --git a/target/linux/ar7/patches-4.1/110-flash.patch b/target/linux/ar7/patches-4.1/110-flash.patch new file mode 100644 index 0000000..e4aeffd --- /dev/null +++ b/target/linux/ar7/patches-4.1/110-flash.patch @@ -0,0 +1,22 @@ +--- a/drivers/mtd/Makefile ++++ b/drivers/mtd/Makefile +@@ -12,7 +12,7 @@ obj-$(CONFIG_MTD_OF_PARTS) += ofpart.o + obj-$(CONFIG_MTD_REDBOOT_PARTS) += redboot.o + obj-$(CONFIG_MTD_CMDLINE_PARTS) += cmdlinepart.o + obj-$(CONFIG_MTD_AFS_PARTS) += afs.o +-obj-$(CONFIG_MTD_AR7_PARTS) += ar7part.o ++obj-$(CONFIG_MTD_AR7_PARTS) += ar7part.o titanpart.o + obj-$(CONFIG_MTD_BCM63XX_PARTS) += bcm63xxpart.o + obj-$(CONFIG_MTD_BCM47XX_PARTS) += bcm47xxpart.o + obj-$(CONFIG_MTD_MYLOADER_PARTS) += myloader.o +--- a/arch/mips/ar7/platform.c ++++ b/arch/mips/ar7/platform.c +@@ -199,7 +199,7 @@ static struct resource physmap_flash_res + .name = "mem", + .flags = IORESOURCE_MEM, + .start = 0x10000000, +- .end = 0x107fffff, ++ .end = 0x11ffffff, + }; + + static const char *ar7_probe_types[] = { "ar7part", NULL }; diff --git a/target/linux/ar7/patches-4.1/120-gpio_chrdev.patch b/target/linux/ar7/patches-4.1/120-gpio_chrdev.patch new file mode 100644 index 0000000..1468ca3 --- /dev/null +++ b/target/linux/ar7/patches-4.1/120-gpio_chrdev.patch @@ -0,0 +1,28 @@ +--- a/drivers/char/Kconfig ++++ b/drivers/char/Kconfig +@@ -461,6 +461,15 @@ config MWAVE + To compile this driver as a module, choose M here: the + module will be called mwave. + ++config AR7_GPIO ++ tristate "TI AR7 GPIO Support" ++ depends on AR7 ++ help ++ Give userspace access to the GPIO pins on the Texas Instruments AR7 ++ processors. ++ ++ If compiled as a module, it will be called ar7_gpio. ++ + config SCx200_GPIO + tristate "NatSemi SCx200 GPIO Support" + depends on SCx200 +--- a/drivers/char/Makefile ++++ b/drivers/char/Makefile +@@ -42,6 +42,7 @@ obj-$(CONFIG_HW_RANDOM) += hw_random/ + obj-$(CONFIG_PPDEV) += ppdev.o + obj-$(CONFIG_NWBUTTON) += nwbutton.o + obj-$(CONFIG_NWFLASH) += nwflash.o ++obj-$(CONFIG_AR7_GPIO) += ar7_gpio.o + obj-$(CONFIG_SCx200_GPIO) += scx200_gpio.o + obj-$(CONFIG_PC8736x_GPIO) += pc8736x_gpio.o + obj-$(CONFIG_NSC_GPIO) += nsc_gpio.o diff --git a/target/linux/ar7/patches-4.1/160-vlynq_try_remote_first.patch b/target/linux/ar7/patches-4.1/160-vlynq_try_remote_first.patch new file mode 100644 index 0000000..1d1310d --- /dev/null +++ b/target/linux/ar7/patches-4.1/160-vlynq_try_remote_first.patch @@ -0,0 +1,300 @@ +--- a/drivers/vlynq/vlynq.c ++++ b/drivers/vlynq/vlynq.c +@@ -119,20 +119,40 @@ static int vlynq_linked(struct vlynq_dev + return 0; + } + ++static volatile int vlynq_delay_value_new = 0; ++ ++static void vlynq_delay_wait(u32 count) ++{ ++ /* Code adopted from original vlynq driver */ ++ int i = 0; ++ volatile int *ptr = &vlynq_delay_value_new; ++ *ptr = 0; ++ ++ /* We are assuming that the each cycle takes about ++ * 23 assembly instructions. */ ++ for(i = 0; i < (count + 23)/23; i++) ++ *ptr = *ptr + 1; ++} ++ + static void vlynq_reset(struct vlynq_device *dev) + { ++ u32 rtm = readl(&dev->local->revision); ++ ++ rtm = rtm < 0x00010205 || readl(&dev->local->status) & 0x800 == 0 ? ++ 0 : 0x600000; ++ + writel(readl(&dev->local->control) | VLYNQ_CTRL_RESET, + &dev->local->control); + + /* Wait for the devices to finish resetting */ +- msleep(5); ++ vlynq_delay_wait(0xffffff); + + /* Remove reset bit */ +- writel(readl(&dev->local->control) & ~VLYNQ_CTRL_RESET, ++ writel(readl(&dev->local->control) & ~VLYNQ_CTRL_RESET | rtm, + &dev->local->control); + + /* Give some time for the devices to settle */ +- msleep(5); ++ vlynq_delay_wait(0xffffff); + } + + static void vlynq_irq_unmask(struct irq_data *d) +@@ -379,6 +399,61 @@ void vlynq_unregister_driver(struct vlyn + } + EXPORT_SYMBOL(vlynq_unregister_driver); + ++enum vlynq_clk_src { ++ vlynq_clk_external, ++ vlynq_clk_local, ++ vlynq_clk_remote, ++ vlynq_clk_invalid, ++}; ++ ++static int __vlynq_set_clocks(struct vlynq_device *dev, ++ enum vlynq_clk_src clk_dir, ++ int lclk_div, int rclk_div) ++{ ++ u32 reg; ++ ++ if (clk_dir == vlynq_clk_invalid) { ++ printk(KERN_ERR "%s: attempt to set invalid clocking\n", ++ dev_name(&dev->dev)); ++ return -EINVAL; ++ } ++ ++ reg = readl(&dev->local->control); ++ if (readl(&dev->local->revision) < 0x00010205) { ++ if (clk_dir & vlynq_clk_local) ++ reg |= VLYNQ_CTRL_CLOCK_INT; ++ else ++ reg &= ~VLYNQ_CTRL_CLOCK_INT; ++ } ++ reg &= ~VLYNQ_CTRL_CLOCK_MASK; ++ reg |= VLYNQ_CTRL_CLOCK_DIV(lclk_div); ++ writel(reg, &dev->local->control); ++ ++ if (!vlynq_linked(dev)) ++ return -ENODEV; ++ ++ printk(KERN_INFO "%s: local VLYNQ protocol rev. is 0x%08x\n", ++ dev_name(&dev->dev), readl(&dev->local->revision)); ++ printk(KERN_INFO "%s: remote VLYNQ protocol rev. is 0x%08x\n", ++ dev_name(&dev->dev), readl(&dev->remote->revision)); ++ ++ reg = readl(&dev->remote->control); ++ if (readl(&dev->remote->revision) < 0x00010205) { ++ if (clk_dir & vlynq_clk_remote) ++ reg |= VLYNQ_CTRL_CLOCK_INT; ++ else ++ reg &= ~VLYNQ_CTRL_CLOCK_INT; ++ } ++ reg &= ~VLYNQ_CTRL_CLOCK_MASK; ++ reg |= VLYNQ_CTRL_CLOCK_DIV(rclk_div); ++ writel(reg, &dev->remote->control); ++ ++ if (!vlynq_linked(dev)) ++ return -ENODEV; ++ ++ return 0; ++} ++ + /* + * A VLYNQ remote device can clock the VLYNQ bus master + * using a dedicated clock line. In that case, both the +@@ -392,29 +467,16 @@ static int __vlynq_try_remote(struct vly + int i; + + vlynq_reset(dev); +- for (i = dev->dev_id ? vlynq_rdiv2 : vlynq_rdiv8; dev->dev_id ? +- i <= vlynq_rdiv8 : i >= vlynq_rdiv2; +- dev->dev_id ? i++ : i--) { ++ for (i = 0; i <= 7; i++) { + + if (!vlynq_linked(dev)) + break; + +- writel((readl(&dev->remote->control) & +- ~VLYNQ_CTRL_CLOCK_MASK) | +- VLYNQ_CTRL_CLOCK_INT | +- VLYNQ_CTRL_CLOCK_DIV(i - vlynq_rdiv1), +- &dev->remote->control); +- writel((readl(&dev->local->control) +- & ~(VLYNQ_CTRL_CLOCK_INT | +- VLYNQ_CTRL_CLOCK_MASK)) | +- VLYNQ_CTRL_CLOCK_DIV(i - vlynq_rdiv1), +- &dev->local->control); +- +- if (vlynq_linked(dev)) { +- printk(KERN_DEBUG +- "%s: using remote clock divisor %d\n", +- dev_name(&dev->dev), i - vlynq_rdiv1 + 1); +- dev->divisor = i; ++ if (!__vlynq_set_clocks(dev, vlynq_clk_remote, i, i)) { ++ printk(KERN_INFO ++ "%s: using remote clock divisor %d\n", ++ dev_name(&dev->dev), i + 1); ++ dev->divisor = i + vlynq_rdiv1; + return 0; + } else { + vlynq_reset(dev); +@@ -433,25 +495,17 @@ static int __vlynq_try_remote(struct vly + */ + static int __vlynq_try_local(struct vlynq_device *dev) + { +- int i; ++ int i, dir = !dev->dev_id; + + vlynq_reset(dev); + +- for (i = dev->dev_id ? vlynq_ldiv2 : vlynq_ldiv8; dev->dev_id ? +- i <= vlynq_ldiv8 : i >= vlynq_ldiv2; +- dev->dev_id ? i++ : i--) { +- +- writel((readl(&dev->local->control) & +- ~VLYNQ_CTRL_CLOCK_MASK) | +- VLYNQ_CTRL_CLOCK_INT | +- VLYNQ_CTRL_CLOCK_DIV(i - vlynq_ldiv1), +- &dev->local->control); +- +- if (vlynq_linked(dev)) { +- printk(KERN_DEBUG +- "%s: using local clock divisor %d\n", +- dev_name(&dev->dev), i - vlynq_ldiv1 + 1); +- dev->divisor = i; ++ for (i = dir ? 7 : 0; dir ? i >= 0 : i <= 7; dir ? i-- : i++) { ++ ++ if (!__vlynq_set_clocks(dev, vlynq_clk_local, i, 0)) { ++ printk(KERN_INFO ++ "%s: using local clock divisor %d\n", ++ dev_name(&dev->dev), i + 1); ++ dev->divisor = i + vlynq_ldiv1; + return 0; + } else { + vlynq_reset(dev); +@@ -473,18 +527,10 @@ static int __vlynq_try_external(struct v + if (!vlynq_linked(dev)) + return -ENODEV; + +- writel((readl(&dev->remote->control) & +- ~VLYNQ_CTRL_CLOCK_INT), +- &dev->remote->control); +- +- writel((readl(&dev->local->control) & +- ~VLYNQ_CTRL_CLOCK_INT), +- &dev->local->control); +- +- if (vlynq_linked(dev)) { +- printk(KERN_DEBUG "%s: using external clock\n", +- dev_name(&dev->dev)); +- dev->divisor = vlynq_div_external; ++ if (!__vlynq_set_clocks(dev, vlynq_clk_external, 0, 0)) { ++ printk(KERN_INFO "%s: using external clock\n", ++ dev_name(&dev->dev)); ++ dev->divisor = vlynq_div_external; + return 0; + } + +@@ -501,24 +547,16 @@ static int __vlynq_enable_device(struct + return result; + + switch (dev->divisor) { +- case vlynq_div_external: + case vlynq_div_auto: + /* When the device is brought from reset it should have clock + * generation negotiated by hardware. + * Check which device is generating clocks and perform setup + * accordingly */ +- if (vlynq_linked(dev) && readl(&dev->remote->control) & +- VLYNQ_CTRL_CLOCK_INT) { +- if (!__vlynq_try_remote(dev) || +- !__vlynq_try_local(dev) || +- !__vlynq_try_external(dev)) +- return 0; +- } else { +- if (!__vlynq_try_external(dev) || +- !__vlynq_try_local(dev) || +- !__vlynq_try_remote(dev)) +- return 0; +- } ++ if (!__vlynq_try_remote(dev) || !__vlynq_try_local(dev)) ++ return 0; ++ case vlynq_div_external: ++ if (!__vlynq_try_external(dev)) ++ return 0; + break; + case vlynq_ldiv1: + case vlynq_ldiv2: +@@ -528,15 +566,12 @@ static int __vlynq_enable_device(struct + case vlynq_ldiv6: + case vlynq_ldiv7: + case vlynq_ldiv8: +- writel(VLYNQ_CTRL_CLOCK_INT | +- VLYNQ_CTRL_CLOCK_DIV(dev->divisor - +- vlynq_ldiv1), &dev->local->control); +- writel(0, &dev->remote->control); +- if (vlynq_linked(dev)) { +- printk(KERN_DEBUG +- "%s: using local clock divisor %d\n", +- dev_name(&dev->dev), +- dev->divisor - vlynq_ldiv1 + 1); ++ if (!__vlynq_set_clocks(dev, vlynq_clk_local, dev->divisor - ++ vlynq_ldiv1, 0)) { ++ printk(KERN_INFO ++ "%s: using local clock divisor %d\n", ++ dev_name(&dev->dev), ++ dev->divisor - vlynq_ldiv1 + 1); + return 0; + } + break; +@@ -548,20 +583,17 @@ static int __vlynq_enable_device(struct + case vlynq_rdiv6: + case vlynq_rdiv7: + case vlynq_rdiv8: +- writel(0, &dev->local->control); +- writel(VLYNQ_CTRL_CLOCK_INT | +- VLYNQ_CTRL_CLOCK_DIV(dev->divisor - +- vlynq_rdiv1), &dev->remote->control); +- if (vlynq_linked(dev)) { +- printk(KERN_DEBUG +- "%s: using remote clock divisor %d\n", +- dev_name(&dev->dev), +- dev->divisor - vlynq_rdiv1 + 1); ++ if (!__vlynq_set_clocks(dev, vlynq_clk_remote, 0, ++ dev->divisor - vlynq_rdiv1)) { ++ printk(KERN_INFO ++ "%s: using remote clock divisor %d\n", ++ dev_name(&dev->dev), ++ dev->divisor - vlynq_rdiv1 + 1); + return 0; + } + break; + } +- ++ vlynq_reset(dev); + ops->off(dev); + return -ENODEV; + } +@@ -732,14 +764,14 @@ static int vlynq_probe(struct platform_d + platform_set_drvdata(pdev, dev); + + printk(KERN_INFO "%s: regs 0x%p, irq %d, mem 0x%p\n", +- dev_name(&dev->dev), (void *)dev->regs_start, dev->irq, +- (void *)dev->mem_start); ++ dev_name(&dev->dev), (void *)dev->regs_start, ++ dev->irq, (void *)dev->mem_start); + + dev->dev_id = 0; + dev->divisor = vlynq_div_auto; +- result = __vlynq_enable_device(dev); +- if (result == 0) { ++ if (!__vlynq_enable_device(dev)) { + dev->dev_id = readl(&dev->remote->chip); ++ vlynq_reset(dev); + ((struct plat_vlynq_ops *)(dev->dev.platform_data))->off(dev); + } + if (dev->dev_id) diff --git a/target/linux/ar7/patches-4.1/200-free-mem-below-kernel-offset.patch b/target/linux/ar7/patches-4.1/200-free-mem-below-kernel-offset.patch new file mode 100644 index 0000000..4011942 --- /dev/null +++ b/target/linux/ar7/patches-4.1/200-free-mem-below-kernel-offset.patch @@ -0,0 +1,15 @@ +--- a/arch/mips/ar7/memory.c ++++ b/arch/mips/ar7/memory.c +@@ -66,5 +66,11 @@ void __init prom_meminit(void) + + void __init prom_free_prom_memory(void) + { +- /* Nothing to free */ ++ /* adapted from arch/mips/txx9/generic/setup.c */ ++ unsigned long saddr = PHYS_OFFSET + PAGE_SIZE; ++ unsigned long eaddr = __pa_symbol(&_text); ++ ++ /* free memory between prom-record and kernel _text base */ ++ if (saddr < eaddr) ++ free_init_pages("prom memory", saddr, eaddr); + } diff --git a/target/linux/ar7/patches-4.1/300-add-ac49x-platform.patch b/target/linux/ar7/patches-4.1/300-add-ac49x-platform.patch new file mode 100644 index 0000000..2e5528e --- /dev/null +++ b/target/linux/ar7/patches-4.1/300-add-ac49x-platform.patch @@ -0,0 +1,85 @@ +--- a/arch/mips/ar7/Platform ++++ b/arch/mips/ar7/Platform +@@ -3,4 +3,9 @@ + # + platform-$(CONFIG_AR7) += ar7/ + cflags-$(CONFIG_AR7) += -I$(srctree)/arch/mips/include/asm/mach-ar7 +-load-$(CONFIG_AR7) += 0xffffffff94100000 ++load-$(CONFIG_AR7_TI) += 0xffffffff94100000 ++ ++# ++# AudioCodes AC49x ++# ++load-$(CONFIG_AR7_AC49X) += 0xffffffff945ca000 +--- a/arch/mips/ar7/setup.c ++++ b/arch/mips/ar7/setup.c +@@ -69,6 +69,10 @@ const char *get_system_type(void) + return "TI AR7 (TNETV1056)"; + case TITAN_CHIP_1060: + return "TI AR7 (TNETV1060)"; ++ case TITAN_CHIP_AC495: ++ return "AudioCodes AC495"; ++ case TITAN_CHIP_AC496: ++ return "AudioCodes AC496"; + } + default: + return "TI AR7 (unknown)"; +--- a/arch/mips/include/asm/mach-ar7/ar7.h ++++ b/arch/mips/include/asm/mach-ar7/ar7.h +@@ -92,6 +92,8 @@ + #define TITAN_CHIP_1055 0x0e + #define TITAN_CHIP_1056 0x0d + #define TITAN_CHIP_1060 0x07 ++#define TITAN_CHIP_AC495 0x00 ++#define TITAN_CHIP_AC496 0x02 + + /* Interrupts */ + #define AR7_IRQ_UART0 15 +--- a/arch/mips/Kconfig ++++ b/arch/mips/Kconfig +@@ -99,7 +99,7 @@ config AR7 + select HAVE_CLK + help + Support for the Texas Instruments AR7 System-on-a-Chip +- family: TNETD7100, 7200 and 7300. ++ family: TI TNETD7100, 7200, 7300 and AudioCodes AC49x. + + config ATH25 + bool "Atheros AR231x/AR531x SoC support" +@@ -925,6 +925,7 @@ config MIPS_PARAVIRT + endchoice + + source "arch/mips/alchemy/Kconfig" ++source "arch/mips/ar7/Kconfig" + source "arch/mips/ath25/Kconfig" + source "arch/mips/ath79/Kconfig" + source "arch/mips/bcm47xx/Kconfig" +--- /dev/null ++++ b/arch/mips/ar7/Kconfig +@@ -0,0 +1,26 @@ ++if AR7 ++ ++config AR7_TI ++ bool ++ ++config AR7_AC49X ++ bool ++ ++choice ++ prompt "AR7 SoC family selection" ++ default AR7_TYPE_TI ++ depends on AR7 ++ help ++ Select AR7 MIPS SoC implementation. ++ ++ config AR7_TYPE_TI ++ bool "Texas Instruments AR7" ++ select AR7_TI ++ ++ config AR7_TYPE_AC49X ++ bool "AudioCodes AC49X" ++ select AR7_AC49X ++ ++endchoice ++ ++endif diff --git a/target/linux/ar7/patches-4.1/310-ac49x-prom-support.patch b/target/linux/ar7/patches-4.1/310-ac49x-prom-support.patch new file mode 100644 index 0000000..dddf221 --- /dev/null +++ b/target/linux/ar7/patches-4.1/310-ac49x-prom-support.patch @@ -0,0 +1,20 @@ +--- a/arch/mips/ar7/prom.c ++++ b/arch/mips/ar7/prom.c +@@ -70,6 +70,7 @@ struct psbl_rec { + }; + + static const char psp_env_version[] __initconst = "TIENV0.8"; ++static const char psp_env_version_ac49x[] __initconst = "MaxENV0.2"; + + struct psp_env_chunk { + u8 num; +@@ -186,7 +187,8 @@ static void __init ar7_init_env(struct e + struct psbl_rec *psbl = (struct psbl_rec *)(KSEG1ADDR(0x14000300)); + void *psp_env = (void *)KSEG1ADDR(psbl->env_base); + +- if (strcmp(psp_env, psp_env_version) == 0) { ++ if (strcmp(psp_env, psp_env_version) == 0 || ++ strcmp(psp_env, psp_env_version_ac49x) == 0) { + parse_psp_env(psp_env); + } else { + for (i = 0; i < MAX_ENTRY; i++, env++) diff --git a/target/linux/ar7/patches-4.1/320-ac49x-mtd-partitions.patch b/target/linux/ar7/patches-4.1/320-ac49x-mtd-partitions.patch new file mode 100644 index 0000000..475104e --- /dev/null +++ b/target/linux/ar7/patches-4.1/320-ac49x-mtd-partitions.patch @@ -0,0 +1,35 @@ +--- a/drivers/mtd/Kconfig ++++ b/drivers/mtd/Kconfig +@@ -164,6 +164,11 @@ config MTD_OF_PARTS + the partition map from the children of the flash node, + as described in Documentation/devicetree/bindings/mtd/partition.txt. + ++config MTD_AC49X_PARTS ++ tristate "AudioCodes AC49X partitioning support" ++ ---help--- ++ AudioCodes AC49X partitioning support ++ + config MTD_AR7_PARTS + tristate "TI AR7 partitioning support" + ---help--- +--- a/drivers/mtd/Makefile ++++ b/drivers/mtd/Makefile +@@ -11,6 +11,7 @@ obj-$(CONFIG_MTD_SPLIT) += mtdsplit/ + obj-$(CONFIG_MTD_OF_PARTS) += ofpart.o + obj-$(CONFIG_MTD_REDBOOT_PARTS) += redboot.o + obj-$(CONFIG_MTD_CMDLINE_PARTS) += cmdlinepart.o ++obj-$(CONFIG_MTD_AC49X_PARTS) += ac49xpart.o + obj-$(CONFIG_MTD_AFS_PARTS) += afs.o + obj-$(CONFIG_MTD_AR7_PARTS) += ar7part.o titanpart.o + obj-$(CONFIG_MTD_BCM63XX_PARTS) += bcm63xxpart.o +--- a/arch/mips/ar7/platform.c ++++ b/arch/mips/ar7/platform.c +@@ -202,7 +202,7 @@ static struct resource physmap_flash_res + .end = 0x11ffffff, + }; + +-static const char *ar7_probe_types[] = { "ar7part", NULL }; ++static const char *ar7_probe_types[] = { "ac49xpart", "ar7part", NULL }; + + static struct physmap_flash_data physmap_flash_data = { + .width = 2, diff --git a/target/linux/ar7/patches-4.1/500-serial_kludge.patch b/target/linux/ar7/patches-4.1/500-serial_kludge.patch new file mode 100644 index 0000000..4baf4aa --- /dev/null +++ b/target/linux/ar7/patches-4.1/500-serial_kludge.patch @@ -0,0 +1,28 @@ +--- a/drivers/tty/serial/8250/8250_core.c ++++ b/drivers/tty/serial/8250/8250_core.c +@@ -339,6 +339,13 @@ configured less than Maximum supported f + UART_FCR7_64BYTE, + .flags = UART_CAP_FIFO, + }, ++ [PORT_AR7] = { ++ .name = "TI-AR7", ++ .fifo_size = 16, ++ .tx_loadsz = 16, ++ .fcr = UART_FCR_ENABLE_FIFO | UART_FCR_R_TRIG_00, ++ .flags = UART_CAP_FIFO | UART_CAP_AFE, ++ }, + }; + + /* Uart divisor latch read */ +@@ -3340,7 +3347,11 @@ static void serial8250_console_putchar(s + { + struct uart_8250_port *up = up_to_u8250p(port); + ++#ifdef CONFIG_AR7 ++ wait_for_xmitr(up, BOTH_EMPTY); ++#else + wait_for_xmitr(up, UART_LSR_THRE); ++#endif + serial_port_out(port, UART_TX, ch); + } + diff --git a/target/linux/ar7/patches-4.1/920-ar7part.patch b/target/linux/ar7/patches-4.1/920-ar7part.patch new file mode 100644 index 0000000..9948858 --- /dev/null +++ b/target/linux/ar7/patches-4.1/920-ar7part.patch @@ -0,0 +1,118 @@ +--- a/drivers/mtd/ar7part.c ++++ b/drivers/mtd/ar7part.c +@@ -30,11 +30,14 @@ + + #include + ++#include ++ + #define AR7_PARTS 4 + #define ROOT_OFFSET 0xe0000 + + #define LOADER_MAGIC1 le32_to_cpu(0xfeedfa42) + #define LOADER_MAGIC2 le32_to_cpu(0xfeed1281) ++#define LOADER_MAGIC3 le32_to_cpu(0x434d4d4c) + + struct ar7_bin_rec { + unsigned int checksum; +@@ -42,12 +45,16 @@ struct ar7_bin_rec { + unsigned int address; + }; + ++int create_titan_partitions(struct mtd_info *master, ++ struct mtd_partition **pparts, ++ struct mtd_part_parser_data *data); ++ + static int create_mtd_partitions(struct mtd_info *master, + struct mtd_partition **pparts, + struct mtd_part_parser_data *data) + { + struct ar7_bin_rec header; +- unsigned int offset; ++ unsigned int offset, mtd_start, mtd_end; + size_t len; + unsigned int pre_size = master->erasesize, post_size = 0; + unsigned int root_offset = ROOT_OFFSET; +@@ -55,6 +62,16 @@ static int create_mtd_partitions(struct + int retries = 10; + struct mtd_partition *ar7_parts; + ++ const char *prom_str = prom_getenv("ProductID"); ++ char mtd_name[] = "mtd1"; ++ if(prom_str && ++ (strcmp(prom_str, "CYWL")==0 || ++ strcmp(prom_str, "CYWM")==0 || ++ strcmp(prom_str, "CYLM")==0 || ++ strcmp(prom_str, "CYLL")==0)){ ++ return create_titan_partitions(master, pparts, data); ++ } ++ + ar7_parts = kzalloc(sizeof(*ar7_parts) * AR7_PARTS, GFP_KERNEL); + if (!ar7_parts) + return -ENOMEM; +@@ -83,34 +100,39 @@ static int create_mtd_partitions(struct + + pre_size = offset; + +- if (!ar7_parts[1].offset) { +- ar7_parts[1].offset = master->size - master->erasesize; +- post_size = master->erasesize; +- } +- + switch (header.checksum) { +- case LOADER_MAGIC1: +- while (header.length) { +- offset += sizeof(header) + header.length; +- mtd_read(master, offset, sizeof(header), &len, +- (uint8_t *)&header); +- } +- root_offset = offset + sizeof(header) + 4; +- break; + case LOADER_MAGIC2: ++ for (retries = 0; retries <= 9; retries++) { ++ mtd_name[3] = '0' + retries; ++ prom_str = prom_getenv(mtd_name); ++ if (prom_str == NULL) ++ continue; ++ sscanf(prom_str, "%i,%i", &mtd_start, &mtd_end); ++ if (pre_size == (mtd_start & 0x1ffffff)) { ++ ar7_parts[1].offset = mtd_end &= 0x1ffffff; ++ ar7_parts[1].size = post_size = master->size - mtd_end; ++ break; ++ } ++ } ++ case LOADER_MAGIC1: ++ root_offset = (header.checksum == LOADER_MAGIC1) ? 4 : 0; + while (header.length) { + offset += sizeof(header) + header.length; + mtd_read(master, offset, sizeof(header), &len, + (uint8_t *)&header); + } +- root_offset = offset + sizeof(header) + 4 + 0xff; +- root_offset &= ~(uint32_t)0xff; ++ root_offset += offset + sizeof(header); + break; + default: + printk(KERN_WARNING "Unknown magic: %08x\n", header.checksum); + break; + } + ++ if (!ar7_parts[1].offset) { ++ post_size = master->erasesize; ++ ar7_parts[1].offset = master->size - post_size; ++ } ++ + mtd_read(master, root_offset, sizeof(header), &len, (u8 *)&header); + if (header.checksum != SQUASHFS_MAGIC) { + root_offset += master->erasesize - 1; +--- a/drivers/mtd/titanpart.c ++++ b/drivers/mtd/titanpart.c +@@ -149,7 +149,7 @@ static void titan_add_partition(char * e + } + int create_titan_partitions(struct mtd_info *master, + struct mtd_partition **pparts, +- unsigned long origin) ++ struct mtd_part_parser_data *data) + { + struct nsp_img_hdr_head hdr; + struct nsp_img_hdr_section_info sect_info; diff --git a/target/linux/ar7/patches-4.1/925-actiontec_leds.patch b/target/linux/ar7/patches-4.1/925-actiontec_leds.patch new file mode 100644 index 0000000..1346a21 --- /dev/null +++ b/target/linux/ar7/patches-4.1/925-actiontec_leds.patch @@ -0,0 +1,95 @@ +--- a/arch/mips/ar7/platform.c ++++ b/arch/mips/ar7/platform.c +@@ -461,31 +461,22 @@ static struct gpio_led fb_fon_leds[] = { + }, + }; + +-static struct gpio_led gt701_leds[] = { ++static struct gpio_led actiontec_leds[] = { + { + .name = "inet:green", + .gpio = 13, +- .active_low = 1, +- }, +- { +- .name = "usb", +- .gpio = 12, +- .active_low = 1, + }, + { + .name = "inet:red", + .gpio = 9, +- .active_low = 1, + }, + { +- .name = "power:red", ++ .name = "power:green", + .gpio = 7, +- .active_low = 1, + }, + { +- .name = "power:green", ++ .name = "power:red", + .gpio = 8, +- .active_low = 1, + .default_trigger = "default-on", + }, + { +@@ -493,6 +484,44 @@ static struct gpio_led gt701_leds[] = { + .gpio = 10, + .active_low = 1, + }, ++ { ++ .name = "wifi", ++ .gpio = 6, ++ .active_low = 1, ++ }, ++ { ++ .name = "wifi:red", ++ .gpio = 3, ++ }, ++ { ++ .name = "standby", ++ .gpio = 4, ++ }, ++ { ++ .name = "wps", ++ .gpio = 16, ++ .active_low = 1, ++ }, ++ { ++ .name = "usb", ++ .gpio = 12, ++ .active_low = 1, ++ }, ++ { ++ .name = "voip", ++ .gpio = 15, ++ .active_low = 1, ++ }, ++ { ++ .name = "line1", ++ .gpio = 23, ++ .active_low = 1, ++ }, ++ { ++ .name = "line2", ++ .gpio = 25, ++ .active_low = 1, ++ }, + }; + + static struct gpio_led_platform_data ar7_led_data; +@@ -536,9 +565,9 @@ static void __init detect_leds(void) + } else if (strstr(prid, "CYWM") || strstr(prid, "CYWL")) { + ar7_led_data.num_leds = ARRAY_SIZE(titan_leds); + ar7_led_data.leds = titan_leds; +- } else if (strstr(prid, "GT701")) { +- ar7_led_data.num_leds = ARRAY_SIZE(gt701_leds); +- ar7_led_data.leds = gt701_leds; ++ } else if (strstr(prid, "GT7") || strstr(prid, "PK5000")) { ++ ar7_led_data.num_leds = ARRAY_SIZE(actiontec_leds); ++ ar7_led_data.leds = actiontec_leds; + } + } + diff --git a/target/linux/ar7/patches-4.1/950-cpmac_titan.patch b/target/linux/ar7/patches-4.1/950-cpmac_titan.patch new file mode 100644 index 0000000..f1d432c --- /dev/null +++ b/target/linux/ar7/patches-4.1/950-cpmac_titan.patch @@ -0,0 +1,52 @@ +--- a/drivers/net/ethernet/ti/cpmac.c ++++ b/drivers/net/ethernet/ti/cpmac.c +@@ -1146,6 +1146,8 @@ static int cpmac_probe(struct platform_d + goto out; + } + ++ ar7_device_reset(pdata->reset_bit); ++ + dev->irq = platform_get_irq_byname(pdev, "irq"); + + dev->netdev_ops = &cpmac_netdev_ops; +@@ -1227,7 +1229,7 @@ int cpmac_init(void) + cpmac_mii->reset = cpmac_mdio_reset; + cpmac_mii->irq = mii_irqs; + +- cpmac_mii->priv = ioremap(AR7_REGS_MDIO, 256); ++ cpmac_mii->priv = ioremap(ar7_is_titan() ? TITAN_REGS_MDIO : AR7_REGS_MDIO, 256); + + if (!cpmac_mii->priv) { + pr_err("Can't ioremap mdio registers\n"); +@@ -1238,10 +1240,16 @@ int cpmac_init(void) + #warning FIXME: unhardcode gpio&reset bits + ar7_gpio_disable(26); + ar7_gpio_disable(27); +- ar7_device_reset(AR7_RESET_BIT_CPMAC_LO); +- ar7_device_reset(AR7_RESET_BIT_CPMAC_HI); ++ ++ if (!ar7_is_titan()) { ++ ar7_device_reset(AR7_RESET_BIT_CPMAC_LO); ++ ar7_device_reset(AR7_RESET_BIT_CPMAC_HI); ++ } + ar7_device_reset(AR7_RESET_BIT_EPHY); + ++ if (ar7_is_titan()) ++ ar7_device_reset(TITAN_RESET_BIT_EPHY1); ++ + cpmac_mii->reset(cpmac_mii); + + for (i = 0; i < 300; i++) { +@@ -1258,7 +1266,11 @@ int cpmac_init(void) + mask = 0; + } + +- cpmac_mii->phy_mask = ~(mask | 0x80000000); ++ if (ar7_is_titan()) ++ cpmac_mii->phy_mask = ~(mask | 0x80000000 | 0x40000000); ++ else ++ cpmac_mii->phy_mask = ~(mask | 0x80000000); ++ + snprintf(cpmac_mii->id, MII_BUS_ID_SIZE, "cpmac-1"); + + res = mdiobus_register(cpmac_mii); diff --git a/target/linux/ar7/src/adam2patcher.c b/target/linux/ar7/src/adam2patcher.c new file mode 100644 index 0000000..25a7807 --- /dev/null +++ b/target/linux/ar7/src/adam2patcher.c @@ -0,0 +1,59 @@ +/* + * patcher.c - ADAM2 patcher for Netgear DG834 (and compatible) + * + * Copyright (C) 2006 Felix Fietkau + * + * 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. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +int main(int argc, char **argv) +{ + int fd; + char *ptr; + uint32_t *i; + + if (argc != 2) { + fprintf(stderr, "Usage: %s \n", argv[0]); + exit(1); + } + + if (((fd = open(argv[1], O_RDWR)) < 0) + || ((ptr = mmap(0, 128 * 1024, PROT_READ|PROT_WRITE, MAP_SHARED, fd, 0)) == (void *) (-1))) { + fprintf(stderr, "Can't open file\n"); + exit(1); + } + + i = (uint32_t *) &ptr[0x3944]; + if (*i == 0x0c000944) { + fprintf(stderr, "Unpatched ADAM2 detected. Patching... "); + *i = 0x00000000; + msync(i, sizeof(*i), MS_SYNC|MS_INVALIDATE); + fprintf(stderr, "done!\n"); + } else if (*i == 0x00000000) { + fprintf(stderr, "Patched ADAM2 detected.\n"); + } else { + fprintf(stderr, "Unknown ADAM2 detected. Can't patch!\n"); + } + + close(fd); +} -- cgit v1.2.3