prepare for the transition to linux 2.6.22 - make it possible to override the kernel...
[openwrt.git] / target / linux / generic-2.6 / patches-2.6.22 / 009-revert_intel_flash_breakage.patch
1 diff -urN linux-2.6.21.1.old/drivers/mtd/chips/cfi_cmdset_0001.c linux-2.6.21.1.dev/drivers/mtd/chips/cfi_cmdset_0001.c
2 --- linux-2.6.21.1.old/drivers/mtd/chips/cfi_cmdset_0001.c      2007-04-27 23:49:26.000000000 +0200
3 +++ linux-2.6.21.1.dev/drivers/mtd/chips/cfi_cmdset_0001.c      2007-05-26 19:40:46.809023552 +0200
4 @@ -933,7 +933,7 @@
5  
6  static int __xipram xip_wait_for_operation(
7                 struct map_info *map, struct flchip *chip,
8 -               unsigned long adr, unsigned int chip_op_time )
9 +               unsigned long adr, int *chip_op_time )
10  {
11         struct cfi_private *cfi = map->fldrv_priv;
12         struct cfi_pri_intelext *cfip = cfi->cmdset_priv;
13 @@ -942,7 +942,7 @@
14         flstate_t oldstate, newstate;
15  
16                 start = xip_currtime();
17 -       usec = chip_op_time * 8;
18 +       usec = *chip_op_time * 8;
19         if (usec == 0)
20                 usec = 500000;
21         done = 0;
22 @@ -1052,8 +1052,8 @@
23  #define XIP_INVAL_CACHED_RANGE(map, from, size)  \
24         INVALIDATE_CACHED_RANGE(map, from, size)
25  
26 -#define INVAL_CACHE_AND_WAIT(map, chip, cmd_adr, inval_adr, inval_len, usec) \
27 -       xip_wait_for_operation(map, chip, cmd_adr, usec)
28 +#define INVAL_CACHE_AND_WAIT(map, chip, cmd_adr, inval_adr, inval_len, p_usec) \
29 +       xip_wait_for_operation(map, chip, cmd_adr, p_usec)
30  
31  #else
32  
33 @@ -1065,65 +1065,65 @@
34  static int inval_cache_and_wait_for_operation(
35                 struct map_info *map, struct flchip *chip,
36                 unsigned long cmd_adr, unsigned long inval_adr, int inval_len,
37 -               unsigned int chip_op_time)
38 +               int *chip_op_time )
39  {
40         struct cfi_private *cfi = map->fldrv_priv;
41         map_word status, status_OK = CMD(0x80);
42 -       int chip_state = chip->state;
43 -       unsigned int timeo, sleep_time;
44 +       int z, chip_state = chip->state;
45 +       unsigned long timeo;
46  
47         spin_unlock(chip->mutex);
48         if (inval_len)
49                 INVALIDATE_CACHED_RANGE(map, inval_adr, inval_len);
50 +       if (*chip_op_time)
51 +               cfi_udelay(*chip_op_time);
52         spin_lock(chip->mutex);
53  
54 -       /* set our timeout to 8 times the expected delay */
55 -       timeo = chip_op_time * 8;
56 -       if (!timeo)
57 -               timeo = 500000;
58 -       sleep_time = chip_op_time / 2;
59 +       timeo = *chip_op_time * 8 * HZ / 1000000;
60 +       if (timeo < HZ/2)
61 +               timeo = HZ/2;
62 +       timeo += jiffies;
63  
64 +       z = 0;
65         for (;;) {
66 +               if (chip->state != chip_state) {
67 +                       /* Someone's suspended the operation: sleep */
68 +                       DECLARE_WAITQUEUE(wait, current);
69 +
70 +                       set_current_state(TASK_UNINTERRUPTIBLE);
71 +                       add_wait_queue(&chip->wq, &wait);
72 +                       spin_unlock(chip->mutex);
73 +                       schedule();
74 +                       remove_wait_queue(&chip->wq, &wait);
75 +                       timeo = jiffies + (HZ / 2); /* FIXME */
76 +                       spin_lock(chip->mutex);
77 +                       continue;
78 +               }
79 +
80                 status = map_read(map, cmd_adr);
81                 if (map_word_andequal(map, status, status_OK, status_OK))
82                         break;
83  
84 -               if (!timeo) {
85 +               /* OK Still waiting */
86 +               if (time_after(jiffies, timeo)) {
87                         map_write(map, CMD(0x70), cmd_adr);
88                         chip->state = FL_STATUS;
89                         return -ETIME;
90                 }
91  
92 -               /* OK Still waiting. Drop the lock, wait a while and retry. */
93 +               /* Latency issues. Drop the lock, wait a while and retry */
94 +               z++;
95                 spin_unlock(chip->mutex);
96 -               if (sleep_time >= 1000000/HZ) {
97 -                       /*
98 -                        * Half of the normal delay still remaining
99 -                        * can be performed with a sleeping delay instead
100 -                        * of busy waiting.
101 -                        */
102 -                       msleep(sleep_time/1000);
103 -                       timeo -= sleep_time;
104 -                       sleep_time = 1000000/HZ;
105 -               } else {
106 -                       udelay(1);
107 -                       cond_resched();
108 -                       timeo--;
109 -               }
110 +               cfi_udelay(1);
111                 spin_lock(chip->mutex);
112 -
113 -               while (chip->state != chip_state) {
114 -                       /* Someone's suspended the operation: sleep */
115 -                       DECLARE_WAITQUEUE(wait, current);
116 -                       set_current_state(TASK_UNINTERRUPTIBLE);
117 -                       add_wait_queue(&chip->wq, &wait);
118 -                       spin_unlock(chip->mutex);
119 -                       schedule();
120 -                       remove_wait_queue(&chip->wq, &wait);
121 -                       spin_lock(chip->mutex);
122 -               }
123         }
124  
125 +       if (!z) {
126 +               if (!--(*chip_op_time))
127 +                       *chip_op_time = 1;
128 +       } else if (z > 1)
129 +               ++(*chip_op_time);
130 +
131         /* Done and happy. */
132         chip->state = FL_STATUS;
133         return 0;
134 @@ -1132,7 +1132,8 @@
135  #endif
136  
137  #define WAIT_TIMEOUT(map, chip, adr, udelay) \
138 -       INVAL_CACHE_AND_WAIT(map, chip, adr, 0, 0, udelay);
139 +       ({ int __udelay = (udelay); \
140 +          INVAL_CACHE_AND_WAIT(map, chip, adr, 0, 0, &__udelay); })
141  
142  
143  static int do_point_onechip (struct map_info *map, struct flchip *chip, loff_t adr, size_t len)
144 @@ -1356,7 +1357,7 @@
145  
146         ret = INVAL_CACHE_AND_WAIT(map, chip, adr,
147                                    adr, map_bankwidth(map),
148 -                                  chip->word_write_time);
149 +                                  &chip->word_write_time);
150         if (ret) {
151                 xip_enable(map, chip, adr);
152                 printk(KERN_ERR "%s: word write error (status timeout)\n", map->name);
153 @@ -1593,7 +1594,7 @@
154  
155         ret = INVAL_CACHE_AND_WAIT(map, chip, cmd_adr,
156                                    adr, len,
157 -                                  chip->buffer_write_time);
158 +                                  &chip->buffer_write_time);
159         if (ret) {
160                 map_write(map, CMD(0x70), cmd_adr);
161                 chip->state = FL_STATUS;
162 @@ -1728,7 +1729,7 @@
163  
164         ret = INVAL_CACHE_AND_WAIT(map, chip, adr,
165                                    adr, len,
166 -                                  chip->erase_time);
167 +                                  &chip->erase_time);
168         if (ret) {
169                 map_write(map, CMD(0x70), adr);
170                 chip->state = FL_STATUS;