--- /dev/null
+diff -Naurp include/avr/pgmspace.h include/avr/pgmspace.h
+--- include/avr/pgmspace.h 2011-12-29 14:21:50.000000000 +0530
++++ include/avr/pgmspace.h 2012-06-04 15:08:29.000000000 +0530
+@@ -419,6 +419,19 @@ typedef uint64_t prog_uint64_t __attrib
+ __result; \
+ }))
+
++#define __LPM_tiny__(addr) \
++(__extension__({ \
++ uint16_t __addr16 = (uint16_t)(addr) + __AVR_TINY_PM_BASE_ADDRESS__; \
++ uint8_t __result; \
++ __asm__ \
++ ( \
++ "ld %0, z" "\n\t" \
++ : "=r" (__result) \
++ : "z" (__addr16) \
++ ); \
++ __result; \
++}))
++
+ #define __LPM_enhanced__(addr) \
+ (__extension__({ \
+ uint16_t __addr16 = (uint16_t)(addr); \
+@@ -450,6 +463,20 @@ typedef uint64_t prog_uint64_t __attrib
+ __result; \
+ }))
+
++#define __LPM_word_tiny__(addr) \
++(__extension__({ \
++ uint16_t __addr16 = (uint16_t)(addr) + __AVR_TINY_PM_BASE_ADDRESS__; \
++ uint16_t __result; \
++ __asm__ \
++ ( \
++ "ld %A0, z+" "\n\t" \
++ "ld %B0, z" "\n\t" \
++ : "=r" (__result), "=z" (__addr16) \
++ : "1" (__addr16) \
++ ); \
++ __result; \
++}))
++
+ #define __LPM_word_enhanced__(addr) \
+ (__extension__({ \
+ uint16_t __addr16 = (uint16_t)(addr); \
+@@ -488,6 +515,22 @@ typedef uint64_t prog_uint64_t __attrib
+ __result; \
+ }))
+
++#define __LPM_dword_tiny__(addr) \
++(__extension__({ \
++ uint16_t __addr16 = (uint16_t)(addr) + __AVR_TINY_PM_BASE_ADDRESS__; \
++ uint32_t __result; \
++ __asm__ \
++ ( \
++ "ld %A0, z+" "\n\t" \
++ "ld %B0, z+" "\n\t" \
++ "ld %C0, z+" "\n\t" \
++ "ld %D0, z" "\n\t" \
++ : "=r" (__result), "=z" (__addr16) \
++ : "1" (__addr16) \
++ ); \
++ __result; \
++}))
++
+ #define __LPM_dword_enhanced__(addr) \
+ (__extension__({ \
+ uint16_t __addr16 = (uint16_t)(addr); \
+@@ -528,6 +571,22 @@ typedef uint64_t prog_uint64_t __attrib
+ __result; \
+ }))
+
++#define __LPM_float_tiny__(addr) \
++(__extension__({ \
++ uint16_t __addr16 = (uint16_t)(addr) + __AVR_TINY_PM_BASE_ADDRESS__; \
++ float __result; \
++ __asm__ \
++ ( \
++ "ld %A0, z+" "\n\t" \
++ "ld %B0, z+" "\n\t" \
++ "ld %C0, z+" "\n\t" \
++ "ld %D0, z" "\n\t" \
++ : "=r" (__result), "=z" (__addr16) \
++ : "1" (__addr16) \
++ ); \
++ __result; \
++}))
++
+ #define __LPM_float_enhanced__(addr) \
+ (__extension__({ \
+ uint16_t __addr16 = (uint16_t)(addr); \
+@@ -549,6 +608,20 @@ typedef uint64_t prog_uint64_t __attrib
+ #define __LPM_word(addr) __LPM_word_enhanced__(addr)
+ #define __LPM_dword(addr) __LPM_dword_enhanced__(addr)
+ #define __LPM_float(addr) __LPM_float_enhanced__(addr)
++/*
++Macro to read data from program memory for avr tiny parts(tiny 4/5/9/10/20/40).
++why:
++- LPM instruction is not available in AVR_TINY instruction set.
++- Programs are executed starting from address 0x0000 in program memory.
++But it must be addressed starting from 0x4000 when accessed via data memory.
++Reference: TINY device (ATTiny 4,5,9,10,20 and 40) datasheets
++Bug: avrtc-536
++*/
++#elif defined (__AVR_TINY__)
++#define __LPM(addr) __LPM_tiny__(addr)
++#define __LPM_word(addr) __LPM_word_tiny__(addr)
++#define __LPM_dword(addr) __LPM_dword_tiny__(addr)
++#define __LPM_float(addr) __LPM_float_tiny__(addr)
+ #else
+ #define __LPM(addr) __LPM_classic__(addr)
+ #define __LPM_word(addr) __LPM_word_classic__(addr)