Commit 621c2559c16fc703e24fc0e3ffad28d5477b49c7
Exists in
master
and in
4 other branches
Merge git://git.infradead.org/mtd-2.6
* git://git.infradead.org/mtd-2.6: mtd: fix timeout in M25P80 driver mtd: Bug in m25p80.c during whole-chip erase mtd: expose subpage size via sysfs mtd: mtd in mtd_release is unused without CONFIG_MTD_CHAR
Showing 2 changed files Side-by-side Diff
drivers/mtd/devices/m25p80.c
... | ... | @@ -54,7 +54,7 @@ |
54 | 54 | #define SR_SRWD 0x80 /* SR write protect */ |
55 | 55 | |
56 | 56 | /* Define max times to check status register before we give up. */ |
57 | -#define MAX_READY_WAIT_COUNT 100000 | |
57 | +#define MAX_READY_WAIT_JIFFIES (10 * HZ) /* eg. M25P128 specs 6s max sector erase */ | |
58 | 58 | #define CMD_SIZE 4 |
59 | 59 | |
60 | 60 | #ifdef CONFIG_M25PXX_USE_FAST_READ |
61 | 61 | |
62 | 62 | |
63 | 63 | |
... | ... | @@ -139,21 +139,21 @@ |
139 | 139 | */ |
140 | 140 | static int wait_till_ready(struct m25p *flash) |
141 | 141 | { |
142 | - int count; | |
142 | + unsigned long deadline; | |
143 | 143 | int sr; |
144 | 144 | |
145 | - /* one chip guarantees max 5 msec wait here after page writes, | |
146 | - * but potentially three seconds (!) after page erase. | |
147 | - */ | |
148 | - for (count = 0; count < MAX_READY_WAIT_COUNT; count++) { | |
145 | + deadline = jiffies + MAX_READY_WAIT_JIFFIES; | |
146 | + | |
147 | + do { | |
149 | 148 | if ((sr = read_sr(flash)) < 0) |
150 | 149 | break; |
151 | 150 | else if (!(sr & SR_WIP)) |
152 | 151 | return 0; |
153 | 152 | |
154 | - /* REVISIT sometimes sleeping would be best */ | |
155 | - } | |
153 | + cond_resched(); | |
156 | 154 | |
155 | + } while (!time_after_eq(jiffies, deadline)); | |
156 | + | |
157 | 157 | return 1; |
158 | 158 | } |
159 | 159 | |
... | ... | @@ -246,10 +246,12 @@ |
246 | 246 | mutex_lock(&flash->lock); |
247 | 247 | |
248 | 248 | /* whole-chip erase? */ |
249 | - if (len == flash->mtd.size && erase_chip(flash)) { | |
250 | - instr->state = MTD_ERASE_FAILED; | |
251 | - mutex_unlock(&flash->lock); | |
252 | - return -EIO; | |
249 | + if (len == flash->mtd.size) { | |
250 | + if (erase_chip(flash)) { | |
251 | + instr->state = MTD_ERASE_FAILED; | |
252 | + mutex_unlock(&flash->lock); | |
253 | + return -EIO; | |
254 | + } | |
253 | 255 | |
254 | 256 | /* REVISIT in some cases we could speed up erasing large regions |
255 | 257 | * by using OPCODE_SE instead of OPCODE_BE_4K. We may have set up |
drivers/mtd/mtdcore.c
... | ... | @@ -48,11 +48,11 @@ |
48 | 48 | */ |
49 | 49 | static void mtd_release(struct device *dev) |
50 | 50 | { |
51 | - struct mtd_info *mtd = dev_to_mtd(dev); | |
51 | + dev_t index = MTD_DEVT(dev_to_mtd(dev)->index); | |
52 | 52 | |
53 | 53 | /* remove /dev/mtdXro node if needed */ |
54 | - if (MTD_DEVT(mtd->index)) | |
55 | - device_destroy(mtd_class, MTD_DEVT(mtd->index) + 1); | |
54 | + if (index) | |
55 | + device_destroy(mtd_class, index + 1); | |
56 | 56 | } |
57 | 57 | |
58 | 58 | static ssize_t mtd_type_show(struct device *dev, |
... | ... | @@ -132,6 +132,17 @@ |
132 | 132 | } |
133 | 133 | static DEVICE_ATTR(writesize, S_IRUGO, mtd_writesize_show, NULL); |
134 | 134 | |
135 | +static ssize_t mtd_subpagesize_show(struct device *dev, | |
136 | + struct device_attribute *attr, char *buf) | |
137 | +{ | |
138 | + struct mtd_info *mtd = dev_to_mtd(dev); | |
139 | + unsigned int subpagesize = mtd->writesize >> mtd->subpage_sft; | |
140 | + | |
141 | + return snprintf(buf, PAGE_SIZE, "%u\n", subpagesize); | |
142 | + | |
143 | +} | |
144 | +static DEVICE_ATTR(subpagesize, S_IRUGO, mtd_subpagesize_show, NULL); | |
145 | + | |
135 | 146 | static ssize_t mtd_oobsize_show(struct device *dev, |
136 | 147 | struct device_attribute *attr, char *buf) |
137 | 148 | { |
... | ... | @@ -169,6 +180,7 @@ |
169 | 180 | &dev_attr_size.attr, |
170 | 181 | &dev_attr_erasesize.attr, |
171 | 182 | &dev_attr_writesize.attr, |
183 | + &dev_attr_subpagesize.attr, | |
172 | 184 | &dev_attr_oobsize.attr, |
173 | 185 | &dev_attr_numeraseregions.attr, |
174 | 186 | &dev_attr_name.attr, |