Index: config_gram.y
===================================================================
--- config_gram.y	(revision 953)
+++ config_gram.y	(working copy)
@@ -214,6 +214,7 @@
 %token K_HAS_TPI                /* MCU has TPI i/f rather than ISP (ATtiny4/5/9/10). */
 %token K_IDR			/* address of OCD register in IO space */
 %token K_IS_AVR32               /* chip is in the avr32 family */
+%token K_IS_AT89S               /* chip is in the avr32 family */
 %token K_RAMPZ			/* address of RAMPZ reg. in IO space */
 %token K_SPMCR			/* address of SPMC[S]R in memory space */
 %token K_EECR    		/* address of EECR in memory space */
@@ -1089,12 +1090,22 @@
       free_token($3);
     } |
 
+  K_IS_AT89S TKN_EQUAL yesno
+    {
+      if ($3->primary == K_YES)
+        current_part->flags |= AVRPART_AT89S;
+      else if ($3->primary == K_NO)
+        current_part->flags &= ~AVRPART_AT89S;
+
+      free_token($3);
+    } |
+
   K_IS_AVR32 TKN_EQUAL yesno
     {
       if ($3->primary == K_YES)
         current_part->flags |= AVRPART_AVR32;
       else if ($3->primary == K_NO)
-        current_part->flags &= AVRPART_AVR32;
+        current_part->flags &= ~AVRPART_AVR32;
 
       free_token($3);
     } |
Index: avrdude.conf.in
===================================================================
--- avrdude.conf.in	(revision 953)
+++ avrdude.conf.in	(working copy)
@@ -15855,4 +15855,143 @@
     ;
 ;
 
+#------------------------------------------------------------
+# AT89S51
+#------------------------------------------------------------
 
+part
+    id               = "89S51";
+    is_at89s         = yes;
+    desc             = "AT89S51";
+    stk500_devcode   = 0xE0;
+    signature        = 0x1e 0x51 0x06;
+    pgm_enable       = "1 0 1 0  1 1 0 0    0 1 0 1  0 0 1 1",
+                       "x x x x  x x x x    x x x x  x x x x";
+
+    chip_erase_delay = 250000;
+    chip_erase       = "1 0 1 0  1 1 0 0    1 0 0 x  x x x x",
+                       "x x x x  x x x x    x x x x  x x x x";
+
+    timeout		    = 200;
+    stabdelay		= 100;
+    cmdexedelay		= 25;
+    synchloops		= 32;
+    bytedelay		= 0;
+    pollindex		= 4;
+    pollvalue		= 0x69;
+    predelay		= 1;
+    postdelay		= 1;
+    pollmethod		= 0;
+
+    progmodedelay       = 0;
+    latchcycles         = 0;
+    togglevtg           = 0;
+    poweroffdelay       = 0;
+    resetdelayms        = 0;
+    resetdelayus        = 0;
+    chiperasepulsewidth = 15;
+    chiperasepolltimeout = 0;
+    programfusepulsewidth = 2;
+    programfusepolltimeout = 0;
+    programlockpulsewidth = 0;
+    programlockpolltimeout = 1;
+
+    memory "flash"
+        size        = 4096;
+	    mode		= 0x02;
+	    delay		= 10;
+	    blocksize	= 256;
+        min_write_delay = 4500;
+        max_write_delay = 4500;
+        readback_p1     = 0xff;
+        readback_p2     = 0xff;
+
+        read            = "  0   0   1   0    0   0   0   0",
+                          "  x   x   x  a12  a11 a10  a9  a8",
+                          " a7  a6  a5  a4   a3  a2  a1  a0",
+                          "  o   o   o   o    o   o   o   o";
+        write           = "  0   1   0   0    0   0   0   0",
+                          "  x   x   x  a12  a11 a10  a9  a8",
+                          " a7  a6  a5  a4   a3  a2  a1  a0",
+                          "  i   i   i   i    i   i   i   i";
+        # Page mode is available in the device, but not implemented here.
+      ;
+    memory "signature"
+        size            = 3;
+        read            = "0  0  1  0   1  0  0  0   x  x  x  x   x  x  a1 a0",
+                          "x x  x  x   x  x  x  0   o  o  o  o   o  o  o  o";
+      ;
+  # Some lock bits are available in the device, but not implemented here.
+  ;
+
+#------------------------------------------------------------
+# AT89S52
+#------------------------------------------------------------
+  
+part
+    id               = "89S52";
+    is_at89s         = yes;
+    desc             = "AT89S52";
+    stk500_devcode   = 0xE1;
+    signature        = 0x1e 0x52 0x06;
+    pgm_enable       = "1 0 1 0  1 1 0 0    0 1 0 1  0 0 1 1",
+                       "x x x x  x x x x    x x x x  x x x x";
+
+    chip_erase_delay = 250000;
+    chip_erase       = "1 0 1 0  1 1 0 0    1 0 0 x  x x x x",
+                       "x x x x  x x x x    x x x x  x x x x";
+
+    timeout		    = 200;
+    stabdelay		= 100;
+    cmdexedelay		= 25;
+    synchloops		= 32;
+    bytedelay		= 0;
+    pollindex		= 4;
+    pollvalue		= 0x69;
+    predelay		= 1;
+    postdelay		= 1;
+    pollmethod		= 0;
+
+    progmodedelay       = 0;
+    latchcycles         = 0;
+    togglevtg           = 0;
+    poweroffdelay       = 0;
+    resetdelayms        = 0;
+    resetdelayus        = 0;
+    chiperasepulsewidth = 15;
+    chiperasepolltimeout = 0;
+    programfusepulsewidth = 2;
+    programfusepolltimeout = 0;
+    programlockpulsewidth = 0;
+    programlockpolltimeout = 1;
+
+    memory "flash"
+        size        = 8192;
+	    mode		= 0x02;
+	    delay		= 10;
+	    blocksize	= 256;
+        min_write_delay = 4500;
+        max_write_delay = 4500;
+        readback_p1     = 0xff;
+        readback_p2     = 0xff;
+
+        read            = "  0   0   1   0    0   0   0   0",
+                          "  x   x   x  a12  a11 a10  a9  a8",
+                          " a7  a6  a5  a4   a3  a2  a1  a0",
+                          "  o   o   o   o    o   o   o   o";
+        write           = "  0   1   0   0    0   0   0   0",
+                          "  x   x   x  a12  a11 a10  a9  a8",
+                          " a7  a6  a5  a4   a3  a2  a1  a0",
+                          "  i   i   i   i    i   i   i   i";
+        # Page mode is available in the device, but not implemented here.
+      ;
+    memory "signature"
+        size            = 3;
+        read            = "0  0  1  0   1  0  0  0   x  x  x  x   x  x  a1 a0",
+                          "x x  x  x   x  x  x  0   o  o  o  o   o  o  o  o";
+      ;
+  # Some lock bits are available in the device, but not implemented here.
+  ;
+
+default_programmer = "avrisp2";
+default_serial = "usb";
Index: avrpart.h
===================================================================
--- avrpart.h	(revision 953)
+++ avrpart.h	(working copy)
@@ -93,6 +93,7 @@
 #define AVRPART_INIT_SMC       0x0200  /* part will undergo chip erase */
 #define AVRPART_WRITE          0x0400  /* at least one write operation specified */
 #define AVRPART_HAS_TPI        0x0800  /* part has TPI i/f rather than ISP (ATtiny4/5/9/10) */
+#define AVRPART_AT89S          0x1000  /* AT89S51/AT89S52 parts */
 
 #define AVR_DESCLEN 64
 #define AVR_IDLEN   32
Index: stk500v2.c
===================================================================
--- stk500v2.c	(revision 953)
+++ stk500v2.c	(working copy)
@@ -911,7 +911,9 @@
   avr_set_bits(p->op[AVR_OP_CHIP_ERASE], buf+3);
   result = stk500v2_command(pgm, buf, 7, sizeof(buf));
   usleep(p->chip_erase_delay);
-  pgm->initialize(pgm, p);
+  
+  /* Issuing a second CMD_ENTER_PROGMODE_ISP fails with AT89S */
+  if (!(p->flags&AVRPART_AT89S)) pgm->initialize(pgm, p);
 
   pgm->pgm_led(pgm, OFF);
 
@@ -1001,10 +1003,13 @@
     return -1;
   }
 
-  if (PDATA(pgm)->pgmtype == PGMTYPE_STK500 ||
-      PDATA(pgm)->pgmtype == PGMTYPE_STK600)
-      /* Activate AVR-style (low active) RESET */
-      stk500v2_setparm_real(pgm, PARAM_RESET_POLARITY, 0x01);
+  if (p->flags&AVRPART_AT89S) {
+    /* Activate AT89S-style (high active) RESET */
+    stk500v2_setparm_real(pgm, PARAM_RESET_POLARITY, 0x00);
+  } else {
+    /* Activate AVR-style (low active) RESET */
+    stk500v2_setparm_real(pgm, PARAM_RESET_POLARITY, 0x01);
+  }
 
   if (PDATA(pgm)->pgmtype == PGMTYPE_STK600) {
     buf[0] = CMD_CHECK_TARGET_CONNECTION;
Index: lexer.l
===================================================================
--- lexer.l	(revision 953)
+++ lexer.l	(working copy)
@@ -153,6 +153,7 @@
 id               { yylval=NULL; return K_ID; }
 idr              { yylval=NULL; return K_IDR; }
 is_avr32         { yylval=NULL; return K_IS_AVR32; }
+is_at89s         { yylval=NULL; return K_IS_AT89S; }
 jtagmki          { yylval=NULL; return K_JTAG_MKI; }
 jtagmkii         { yylval=NULL; return K_JTAG_MKII; }
 jtagmkii_avr32   { yylval=NULL; return K_JTAG_MKII_AVR32; }
