prepare for the transition to linux 2.6.22 - make it possible to override the kernel...
[openwrt/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;