From 854c5047814d6eb446cc26b6b742cd6abe10e183 Mon Sep 17 00:00:00 2001
From: Florian Fainelli <florian@openwrt.org>
Date: Sun, 11 Nov 2012 18:40:48 +0000
Subject: move files directory to files-3.3

SVN-Revision: 34153
---
 target/linux/ar7/files-3.3/drivers/char/ar7_gpio.c | 158 ++++++++++++++
 target/linux/ar7/files-3.3/drivers/mtd/ac49xpart.c | 220 +++++++++++++++++++
 target/linux/ar7/files-3.3/drivers/mtd/titanpart.c | 234 +++++++++++++++++++++
 3 files changed, 612 insertions(+)
 create mode 100644 target/linux/ar7/files-3.3/drivers/char/ar7_gpio.c
 create mode 100644 target/linux/ar7/files-3.3/drivers/mtd/ac49xpart.c
 create mode 100644 target/linux/ar7/files-3.3/drivers/mtd/titanpart.c

(limited to 'target/linux/ar7/files-3.3/drivers')

diff --git a/target/linux/ar7/files-3.3/drivers/char/ar7_gpio.c b/target/linux/ar7/files-3.3/drivers/char/ar7_gpio.c
new file mode 100644
index 0000000..a7d0a55
--- /dev/null
+++ b/target/linux/ar7/files-3.3/drivers/char/ar7_gpio.c
@@ -0,0 +1,158 @@
+/*
+ * Copyright (C) 2007 Nicolas Thill <nico@openwrt.org>
+ *
+ * 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 <linux/device.h>
+#include <linux/fs.h>
+#include <linux/module.h>
+#include <linux/errno.h>
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/platform_device.h>
+#include <linux/uaccess.h>
+#include <linux/io.h>
+#include <linux/types.h>
+#include <linux/cdev.h>
+#include <gpio.h>
+
+#define DRVNAME "ar7_gpio"
+#define LONGNAME "TI AR7 GPIOs Driver"
+
+MODULE_AUTHOR("Nicolas Thill <nico@openwrt.org>");
+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_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_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-3.3/drivers/mtd/ac49xpart.c b/target/linux/ar7/files-3.3/drivers/mtd/ac49xpart.c
new file mode 100644
index 0000000..1f937f0
--- /dev/null
+++ b/target/linux/ar7/files-3.3/drivers/mtd/ac49xpart.c
@@ -0,0 +1,220 @@
+/*
+ * AudioCodes AC49x PSPBoot-based flash partition table
+ * Copyright 2012 Daniel Golle <daniel.golle@gmail.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.
+ *
+ * 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 <linux/kernel.h>
+#include <linux/slab.h>
+
+#include <linux/mtd/mtd.h>
+#include <linux/mtd/partitions.h>
+#include <linux/bootmem.h>
+#include <linux/magic.h>
+#include <linux/module.h>
+
+#include <asm/mach-ar7/prom.h>
+
+#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)
+{
+	return register_mtd_parser(&ac49x_parser);
+}
+
+module_init(ac49x_parser_init);
+
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("Daniel Golle <daniel.golle@gmail.com>");
+MODULE_DESCRIPTION("MTD partitioning for AudioCodes AC49x");
diff --git a/target/linux/ar7/files-3.3/drivers/mtd/titanpart.c b/target/linux/ar7/files-3.3/drivers/mtd/titanpart.c
new file mode 100644
index 0000000..74f8251
--- /dev/null
+++ b/target/linux/ar7/files-3.3/drivers/mtd/titanpart.c
@@ -0,0 +1,234 @@
+#include <linux/kernel.h>
+#include <linux/slab.h>
+
+#include <linux/mtd/mtd.h>
+#include <linux/mtd/partitions.h>
+#include <linux/bootmem.h>
+#include <linux/magic.h>
+#include <asm/mach-ar7/prom.h>
+
+#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;
+	master->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 */
+
+	master->read(master, flash_base + hdr.sect_info_offset, sizeof(struct nsp_img_hdr_section_info), &len, (uint8_t *)&sect_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 && i<MAX_NUM_PARTITIONS; i++){
+		master->read(master, flash_base + sect_info.sections_offset + (i * sect_info.sect_size) , sizeof(struct nsp_img_hdr_sections), &len, (uint8_t *)&section);
+		/* Add only the root partition */
+		if(section.type != NSP_IMG_SECTION_TYPE_FILESYSTEM_ROOT){
+			continue;
+		}
+		start=flash_base + section.offset;
+		end=start + section.total_size;
+		titan_add_partition("root", start, end);
+		total_sects++;
+		
+	}
+
+	for(i=0; i< sect_info.num_sects && i<MAX_NUM_PARTITIONS; i++){
+
+		master->read(master, flash_base + sect_info.sections_offset + (i * sect_info.sect_size) , sizeof(struct nsp_img_hdr_sections), &len, (uint8_t *)&section);
+
+		name=section.name;
+		if(section.type == NSP_IMG_SECTION_TYPE_FILESYSTEM_ROOT)
+		{
+			name = "rootfs";
+			start=flash_base + section.offset;
+			end=flash_end;
+			titan_add_partition(name, start, end);
+			total_sects++;
+		}
+		else if(section.type == NSP_IMG_SECTION_TYPE_KERNEL)
+		{
+			name = "kernel";
+			start=flash_base + section.offset;
+			end=start + section.total_size;
+			titan_add_partition(name, start, end);
+			total_sects++;
+		}
+
+	}
+
+	/* Next, lets add the single image */
+	titan_add_partition("primary_image", flash_base, flash_end);
+	total_sects++;
+
+
+	titan_add_partition("full_image", 0,  master->size);
+	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;
+}
-- 
cgit v1.1