Index: flash.h
===================================================================
--- flash.h	(Revision 1256)
+++ flash.h	(Arbeitskopie)
@@ -136,6 +136,7 @@
 
 	int (*printlock) (struct flashchip *flash);
 	int (*unlock) (struct flashchip *flash);
+	int (*lock) (struct flashchip *flash);
 	int (*write) (struct flashchip *flash, uint8_t *buf, int start, int len);
 	int (*read) (struct flashchip *flash, uint8_t *buf, int start, int len);
 
@@ -207,7 +208,7 @@
 void print_banner(void);
 void list_programmers_linebreak(int startcol, int cols, int paren);
 int selfcheck(void);
-int doit(struct flashchip *flash, int force, char *filename, int read_it, int write_it, int erase_it, int verify_it);
+int doit(struct flashchip *flash, int force, char *filename, int read_it, int write_it, int erase_it, int verify_it, int lock_it);
 int read_buf_from_file(unsigned char *buf, unsigned long size, char *filename);
 int write_buf_to_file(unsigned char *buf, unsigned long size, char *filename);
 
Index: cli_classic.c
===================================================================
--- cli_classic.c	(Revision 1256)
+++ cli_classic.c	(Arbeitskopie)
@@ -37,7 +37,7 @@
 #if CONFIG_PRINT_WIKI == 1
 	         "-z|"
 #endif
-	         "-E|-r <file>|-w <file>|-v <file>]\n"
+	         "-E|-K|-r <file>|-w <file>|-v <file>]\n"
 	       "       [-c <chipname>] [-m [<vendor>:]<part>] [-l <file>]\n"
 	       "       [-i <image>] [-p <programmername>[:<parameters>]]\n\n");
 
@@ -57,6 +57,7 @@
 	       "   -v | --verify <file>              verify flash against "
 	         "<file>\n"
 	       "   -E | --erase                      erase flash device\n"
+	       "   -K | --lock                       lock flash device\n"
 	       "   -V | --verbose                    more verbose output\n"
 	       "   -c | --chip <chipname>            probe only for specified "
 	         "flash chip\n"
@@ -85,7 +86,7 @@
 #if CONFIG_PRINT_WIKI == 1
 	         "-z, "
 #endif
-	         "-E, -r, -w, -v or no operation.\n"
+	         "-E, -K, -r, -w, -v or no operation.\n"
 	       "If no operation is specified, flashrom will only probe for "
 	         "flash chips.\n\n");
 }
@@ -106,7 +107,7 @@
 	int opt;
 	int option_index = 0;
 	int force = 0;
-	int read_it = 0, write_it = 0, erase_it = 0, verify_it = 0;
+	int read_it = 0, write_it = 0, erase_it = 0, verify_it = 0, lock_it = 0;
 	int dont_verify_it = 0, list_supported = 0;
 #if CONFIG_PRINT_WIKI == 1
 	int list_supported_wiki = 0;
@@ -114,11 +115,12 @@
 	int operation_specified = 0;
 	int i;
 
-	static const char optstring[] = "r:Rw:v:nVEfc:m:l:i:p:Lzh";
+	static const char optstring[] = "r:Rw:v:nVEKfc:m:l:i:p:Lzh";
 	static const struct option long_options[] = {
 		{"read", 1, NULL, 'r'},
 		{"write", 1, NULL, 'w'},
 		{"erase", 0, NULL, 'E'},
+		{"lock", 0, NULL, 'K'},
 		{"verify", 1, NULL, 'v'},
 		{"noverify", 0, NULL, 'n'},
 		{"chip", 1, NULL, 'c'},
@@ -208,6 +210,14 @@
 			}
 			erase_it = 1;
 			break;
+		case 'K':
+			if (++operation_specified > 1) {
+				fprintf(stderr, "More than one operation "
+					"specified. Aborting.\n");
+				cli_classic_abort_usage();
+			}
+			lock_it = 1;
+			break;
 		case 'm':
 #if CONFIG_INTERNAL == 1
 			tempstr = strdup(optarg);
@@ -409,14 +419,14 @@
 		return 1;
 	}
 
-	if (!(read_it | write_it | verify_it | erase_it)) {
+	if (!(read_it | write_it | verify_it | erase_it | lock_it)) {
 		printf("No operations were specified.\n");
 		// FIXME: flash writes stay enabled!
 		programmer_shutdown();
 		exit(0);
 	}
 
-	if (!filename && !erase_it) {
+	if (!filename && !(erase_it || lock_it)) {
 		printf("Error: No filename specified.\n");
 		// FIXME: flash writes stay enabled!
 		programmer_shutdown();
@@ -432,5 +442,5 @@
 	 * Give the chip time to settle.
 	 */
 	programmer_delay(100000);
-	return doit(flash, force, filename, read_it, write_it, erase_it, verify_it);
+	return doit(flash, force, filename, read_it, write_it, erase_it, verify_it, lock_it);
 }
Index: spi25.c
===================================================================
--- spi25.c	(Revision 1256)
+++ spi25.c	(Arbeitskopie)
@@ -1197,6 +1197,44 @@
 	return 0;
 }
 
+int spi_enable_blockprotect_at25df(struct flashchip *flash)
+{
+	uint8_t status;
+	int result;
+
+	/* Reset SPRL when needed to be able to modify status register */
+	status = spi_read_status_register();
+	if (status & (1 << 7)) {
+		msg_cdbg("Need to disable Sector Protection Register Lock\n");
+		if ((status & (1 << 4)) == 0) {
+			msg_cerr("WP# pin is active, disabling "
+				 "write protection is impossible.\n");
+			return 1;
+		}
+		/* All bits except bit 7 (SPRL) are readonly. */
+		result = spi_write_status_register(flash, status & ~(1 << 7));
+		if (result) {
+			msg_cerr("spi_write_status_register failed\n");
+			return result;
+		}
+		
+	}
+	/* Global protect. Make sure to set SPRL as well. */
+	result = spi_write_status_register(flash, status | 0xbc);
+	if (result) {
+		msg_cerr("spi_write_status_register failed\n");
+		return result;
+	}
+	status = spi_read_status_register();
+	if ((status & (3 << 2)) != (3 << 2)) {
+		msg_cerr("Block protection could not be enabled!\n");
+		return 1;
+	}
+	msg_cinfo("Block protection enabled, %s locked!\n",
+		  (status & (1 << 4)) ? "software" : "hardware");
+	return 0;
+}
+
 int spi_nbyte_read(int address, uint8_t *bytes, int len)
 {
 	const unsigned char cmd[JEDEC_READ_OUTSIZE] = {
Index: flashchips.c
===================================================================
--- flashchips.c	(Revision 1256)
+++ flashchips.c	(Arbeitskopie)
@@ -1501,6 +1501,7 @@
 			}
 		},
 		.unlock		= spi_disable_blockprotect_at25df,
+		.lock		= spi_enable_blockprotect_at25df,
 		.write		= spi_chip_write_256,
 		.read		= spi_chip_read,
 	},
Index: flashrom.c
===================================================================
--- flashrom.c	(Revision 1256)
+++ flashrom.c	(Arbeitskopie)
@@ -1759,7 +1759,7 @@
 /* FIXME: This function signature needs to be improved once doit() has a better
  * function signature.
  */
-int chip_safety_check(struct flashchip *flash, int force, char *filename, int read_it, int write_it, int erase_it, int verify_it)
+int chip_safety_check(struct flashchip *flash, int force, char *filename, int read_it, int write_it, int erase_it, int verify_it, int lock_it)
 {
 	if (!programmer_may_write && (write_it || erase_it)) {
 		msg_perr("Write/erase is not working yet on your programmer in "
@@ -1809,6 +1809,13 @@
 			return 1;
 		}
 	}
+	if (lock_it) {
+		if (!flash->lock) {
+			msg_cerr("flashrom has no lock function for this "
+				 "flash chip.\n");
+			return 1;
+		}
+	}
 	return 0;
 }
 
@@ -1816,14 +1823,14 @@
  * but right now it allows us to split off the CLI code.
  * Besides that, the function itself is a textbook example of abysmal code flow.
  */
-int doit(struct flashchip *flash, int force, char *filename, int read_it, int write_it, int erase_it, int verify_it)
+int doit(struct flashchip *flash, int force, char *filename, int read_it, int write_it, int erase_it, int verify_it, int lock_it)
 {
 	uint8_t *oldcontents;
 	uint8_t *newcontents;
 	int ret = 0;
 	unsigned long size = flash->total_size * 1024;
 
-	if (chip_safety_check(flash, force, filename, read_it, write_it, erase_it, verify_it)) {
+	if (chip_safety_check(flash, force, filename, read_it, write_it, erase_it, verify_it, lock_it)) {
 		msg_cerr("Aborting.\n");
 		ret = 1;
 		goto out_nofree;
@@ -1835,6 +1842,11 @@
 	if (flash->unlock)
 		flash->unlock(flash);
 
+	if (lock_it) {
+		ret = flash->lock(flash);
+		goto out_nofree;
+	}
+
 	if (read_it) {
 		ret = read_flash_to_file(flash, filename);
 		goto out_nofree;
Index: chipdrivers.h
===================================================================
--- chipdrivers.h	(Revision 1256)
+++ chipdrivers.h	(Arbeitskopie)
@@ -54,6 +54,7 @@
 int spi_disable_blockprotect_at25f(struct flashchip *flash);
 int spi_disable_blockprotect_at25fs010(struct flashchip *flash);
 int spi_disable_blockprotect_at25fs040(struct flashchip *flash);
+int spi_enable_blockprotect_at25df(struct flashchip *flash);
 int spi_byte_program(int addr, uint8_t databyte);
 int spi_nbyte_program(int addr, uint8_t *bytes, int len);
 int spi_nbyte_read(int addr, uint8_t *bytes, int len);
