disable some mediatekl custom warnings
[GitHub/mt8127/android_kernel_alcatel_ttab.git] / drivers / mtd / mtdpart.c
index 70fa70a8318f4584c473a7fabd35a7bc4fad6027..e504187ae093f863843d6d939ff9ad952ae3ead1 100644 (file)
 
 #include "mtdcore.h"
 
+#define DYNAMIC_CHANGE_MTD_WRITEABLE
+#ifdef DYNAMIC_CHANGE_MTD_WRITEABLE //wschen 2011-01-05
+#include <linux/proc_fs.h>
+#include <asm/uaccess.h>
+static struct mtd_info *my_mtd = NULL;
+int mtd_writeable_proc_write(struct file *file, const char *buffer, unsigned long count, void *data);
+
+struct mtd_change {
+    uint64_t size;
+    uint64_t offset;
+};
+int mtd_change_proc_write(struct file *file, const char *buffer, unsigned long count, void *data);
+#endif
+
+
 /* Our partition linked list */
 static LIST_HEAD(mtd_partitions);
 static DEFINE_MUTEX(mtd_partitions_mutex);
@@ -326,6 +341,10 @@ int del_mtd_partitions(struct mtd_info *master)
        mutex_lock(&mtd_partitions_mutex);
        list_for_each_entry_safe(slave, next, &mtd_partitions, list)
                if (slave->master == master) {
+#ifdef DYNAMIC_CHANGE_MTD_WRITEABLE //wschen 2011-01-05
+                        my_mtd = NULL;
+#endif
+
                        ret = del_mtd_device(&slave->mtd);
                        if (ret < 0) {
                                err = ret;
@@ -645,7 +664,9 @@ int add_mtd_partitions(struct mtd_info *master,
 
                cur_offset = slave->offset + slave->mtd.size;
        }
-
+#ifdef DYNAMIC_CHANGE_MTD_WRITEABLE //wschen 2011-01-05
+        my_mtd = master;
+#endif
        return 0;
 }
 
@@ -694,7 +715,7 @@ EXPORT_SYMBOL_GPL(deregister_mtd_parser);
  * Do not forget to update 'parse_mtd_partitions()' kerneldoc comment if you
  * are changing this array!
  */
-static const char *default_mtd_part_types[] = {
+static const char * const default_mtd_part_types[] = {
        "cmdlinepart",
        "ofpart",
        NULL
@@ -720,7 +741,7 @@ static const char *default_mtd_part_types[] = {
  * o a positive number of found partitions, in which case on exit @pparts will
  *   point to an array containing this number of &struct mtd_info objects.
  */
-int parse_mtd_partitions(struct mtd_info *master, const char **types,
+int parse_mtd_partitions(struct mtd_info *master, const char *const *types,
                         struct mtd_partition **pparts,
                         struct mtd_part_parser_data *data)
 {
@@ -764,6 +785,15 @@ int mtd_is_partition(const struct mtd_info *mtd)
 }
 EXPORT_SYMBOL_GPL(mtd_is_partition);
 
+#ifdef CONFIG_MTK_MTD_NAND
+u64 mtd_partition_start_address(struct mtd_info *mtd)
+{
+       struct mtd_part *part = PART(mtd);
+       return part->offset;
+}
+EXPORT_SYMBOL_GPL(mtd_partition_start_address);
+#endif
+
 /* Returns the size of the entire flash chip */
 uint64_t mtd_get_device_size(const struct mtd_info *mtd)
 {
@@ -773,3 +803,88 @@ uint64_t mtd_get_device_size(const struct mtd_info *mtd)
        return PART(mtd)->master->size;
 }
 EXPORT_SYMBOL_GPL(mtd_get_device_size);
+
+#ifdef DYNAMIC_CHANGE_MTD_WRITEABLE //wschen 2011-01-05
+int mtd_writeable_proc_write(struct file *file, const char *buffer, unsigned long count, void *data)
+{
+    char buf[3];
+
+    if (count != 3) {
+        return -EFAULT;
+    }
+
+    if (copy_from_user(buf, buffer, 3)) {
+        return -EFAULT;
+    }
+
+    if ((buf[0] != 0) || (buf[1] != 0) || (buf[2] != 0)) {
+        return -EFAULT;
+    }
+
+    if (my_mtd) {
+
+        struct mtd_part *slave, *next;
+
+        list_for_each_entry_safe(slave, next, &mtd_partitions, list)
+            if (slave->master == my_mtd) {
+                slave->mtd.flags |= MTD_WRITEABLE;
+            }
+    }
+
+    return count;
+}
+
+#define MTD_CHANGE_NUM 4
+int mtd_change_proc_write(struct file *file, const char *buffer, unsigned long count, void *data)
+{
+    struct mtd_change mtd_change[MTD_CHANGE_NUM];
+    int write_3 = 0;
+
+    if (count == (sizeof(struct mtd_change) * (MTD_CHANGE_NUM - 1))) {
+        write_3 = 1;
+    } else if (count != (sizeof(struct mtd_change) * MTD_CHANGE_NUM)) {
+        return -EFAULT;
+    }
+
+    if (copy_from_user(mtd_change, buffer, count)) {
+        return -EFAULT;
+    }
+
+    if (my_mtd) {
+        struct mtd_part *slave, *next;
+        
+        list_for_each_entry_safe(slave, next, &mtd_partitions, list)
+            if (slave->master == my_mtd) {
+                if (write_3 == 1) {
+                    if (strncmp(slave->mtd.name, "system", strlen(slave->mtd.name)) == 0) {
+                        slave->mtd.size = mtd_change[0].size;
+                        slave->offset = mtd_change[0].offset;
+                    } else if (strncmp(slave->mtd.name, "cache", strlen(slave->mtd.name)) == 0) {
+                        slave->mtd.size = mtd_change[1].size;
+                        slave->offset = mtd_change[1].offset;
+                    } else if (strncmp(slave->mtd.name, "userdata", strlen(slave->mtd.name)) == 0) {
+                        slave->mtd.size = mtd_change[2].size;
+                        slave->offset = mtd_change[2].offset;
+                    }
+                } else {
+                    //4 arguments
+                    if (strncmp(slave->mtd.name, "expdb", strlen(slave->mtd.name)) == 0) {
+                        slave->mtd.size = mtd_change[0].size;
+                        slave->offset = mtd_change[0].offset;
+                    } else if (strncmp(slave->mtd.name, "system", strlen(slave->mtd.name)) == 0) {
+                        slave->mtd.size = mtd_change[1].size;
+                        slave->offset = mtd_change[1].offset;
+                    } else if (strncmp(slave->mtd.name, "cache", strlen(slave->mtd.name)) == 0) {
+                        slave->mtd.size = mtd_change[2].size;
+                        slave->offset = mtd_change[2].offset;
+                    } else if (strncmp(slave->mtd.name, "userdata", strlen(slave->mtd.name)) == 0) {
+                        slave->mtd.size = mtd_change[3].size;
+                        slave->offset = mtd_change[3].offset;
+                    }
+                }
+            }
+    }
+
+    return count;
+}
+#endif