Lines Matching +full:flash +full:- +full:timeout +full:- +full:us
1 // SPDX-License-Identifier: GPL-2.0-only
14 MODULE_DESCRIPTION("Serial flash driver for BCMA bus");
26 b47s->cc_write(b47s, BCMA_CC_FLASHCTL, BCMA_CC_FLASHCTL_START | opcode); in bcm47xxsflash_cmd()
28 if (!(b47s->cc_read(b47s, BCMA_CC_FLASHCTL) & in bcm47xxsflash_cmd()
33 pr_err("Control command failed (timeout)!\n"); in bcm47xxsflash_cmd()
36 static int bcm47xxsflash_poll(struct bcm47xxsflash *b47s, int timeout) in bcm47xxsflash_poll() argument
38 unsigned long deadline = jiffies + timeout; in bcm47xxsflash_poll()
41 switch (b47s->type) { in bcm47xxsflash_poll()
44 if (!(b47s->cc_read(b47s, BCMA_CC_FLASHDATA) & in bcm47xxsflash_poll()
50 if (b47s->cc_read(b47s, BCMA_CC_FLASHDATA) & in bcm47xxsflash_poll()
60 pr_err("Timeout waiting for flash to be ready!\n"); in bcm47xxsflash_poll()
62 return -EBUSY; in bcm47xxsflash_poll()
71 struct bcm47xxsflash *b47s = mtd->priv; in bcm47xxsflash_erase()
73 switch (b47s->type) { in bcm47xxsflash_erase()
76 b47s->cc_write(b47s, BCMA_CC_FLASHADDR, erase->addr); in bcm47xxsflash_erase()
77 /* Newer flashes have "sub-sectors" which can be erased in bcm47xxsflash_erase()
81 if (b47s->blocksize < (64 * 1024)) in bcm47xxsflash_erase()
87 b47s->cc_write(b47s, BCMA_CC_FLASHADDR, erase->addr << 1); in bcm47xxsflash_erase()
98 struct bcm47xxsflash *b47s = mtd->priv; in bcm47xxsflash_read()
102 if ((from + len) > mtd->size) in bcm47xxsflash_read()
103 return -EINVAL; in bcm47xxsflash_read()
109 memcpy_len = min(len, (size_t)(BCM47XXSFLASH_WINDOW_SZ - from)); in bcm47xxsflash_read()
110 memcpy_fromio(buf, b47s->window + from, memcpy_len); in bcm47xxsflash_read()
112 len -= memcpy_len; in bcm47xxsflash_read()
117 for (; len; len--) { in bcm47xxsflash_read()
118 b47s->cc_write(b47s, BCMA_CC_FLASHADDR, from++); in bcm47xxsflash_read()
120 *buf++ = b47s->cc_read(b47s, BCMA_CC_FLASHDATA); in bcm47xxsflash_read()
131 struct bcm47xxsflash *b47s = mtd->priv; in bcm47xxsflash_write_st()
138 b47s->cc_write(b47s, BCMA_CC_FLASHADDR, offset); in bcm47xxsflash_write_st()
139 b47s->cc_write(b47s, BCMA_CC_FLASHDATA, *buf++); in bcm47xxsflash_write_st()
142 if (b47s->bcma_cc->core->id.rev < 20) { in bcm47xxsflash_write_st()
150 len--; in bcm47xxsflash_write_st()
160 len--; in bcm47xxsflash_write_st()
165 b47s->cc_write(b47s, BCMA_CC_FLASHCTL, 0); in bcm47xxsflash_write_st()
168 pr_err("Flash rejected dropping CSA\n"); in bcm47xxsflash_write_st()
176 struct bcm47xxsflash *b47s = mtd->priv; in bcm47xxsflash_write_at()
177 u32 mask = b47s->blocksize - 1; in bcm47xxsflash_write_at()
183 if (byte || (len < b47s->blocksize)) { in bcm47xxsflash_write_at()
186 b47s->cc_write(b47s, BCMA_CC_FLASHADDR, page); in bcm47xxsflash_write_at()
188 /* 250 us for AT45DB321B */ in bcm47xxsflash_write_at()
191 pr_err("Timeout reading page 0x%X info buffer\n", page); in bcm47xxsflash_write_at()
199 if (byte == b47s->blocksize) in bcm47xxsflash_write_at()
202 b47s->cc_write(b47s, BCMA_CC_FLASHADDR, byte++); in bcm47xxsflash_write_at()
203 b47s->cc_write(b47s, BCMA_CC_FLASHDATA, *buf++); in bcm47xxsflash_write_at()
205 len--; in bcm47xxsflash_write_at()
210 b47s->cc_write(b47s, BCMA_CC_FLASHADDR, page); in bcm47xxsflash_write_at()
219 struct bcm47xxsflash *b47s = mtd->priv; in bcm47xxsflash_write()
226 switch (b47s->type) { in bcm47xxsflash_write()
241 len -= written; in bcm47xxsflash_write()
252 struct mtd_info *mtd = &b47s->mtd; in bcm47xxsflash_fill_mtd()
254 mtd->priv = b47s; in bcm47xxsflash_fill_mtd()
255 mtd->dev.parent = dev; in bcm47xxsflash_fill_mtd()
256 mtd->name = "bcm47xxsflash"; in bcm47xxsflash_fill_mtd()
258 mtd->type = MTD_NORFLASH; in bcm47xxsflash_fill_mtd()
259 mtd->flags = MTD_CAP_NORFLASH; in bcm47xxsflash_fill_mtd()
260 mtd->size = b47s->size; in bcm47xxsflash_fill_mtd()
261 mtd->erasesize = b47s->blocksize; in bcm47xxsflash_fill_mtd()
262 mtd->writesize = 1; in bcm47xxsflash_fill_mtd()
263 mtd->writebufsize = 1; in bcm47xxsflash_fill_mtd()
265 mtd->_erase = bcm47xxsflash_erase; in bcm47xxsflash_fill_mtd()
266 mtd->_read = bcm47xxsflash_read; in bcm47xxsflash_fill_mtd()
267 mtd->_write = bcm47xxsflash_write; in bcm47xxsflash_fill_mtd()
276 return bcma_cc_read32(b47s->bcma_cc, offset); in bcm47xxsflash_bcma_cc_read()
282 bcma_cc_write32(b47s->bcma_cc, offset, value); in bcm47xxsflash_bcma_cc_write()
287 struct device *dev = &pdev->dev; in bcm47xxsflash_bcma_probe()
295 return -ENOMEM; in bcm47xxsflash_bcma_probe()
300 return -EINVAL; in bcm47xxsflash_bcma_probe()
302 if (!devm_request_mem_region(dev, res->start, resource_size(res), in bcm47xxsflash_bcma_probe()
303 res->name)) { in bcm47xxsflash_bcma_probe()
305 return -EBUSY; in bcm47xxsflash_bcma_probe()
308 b47s->bcma_cc = container_of(sflash, struct bcma_drv_cc, sflash); in bcm47xxsflash_bcma_probe()
309 b47s->cc_read = bcm47xxsflash_bcma_cc_read; in bcm47xxsflash_bcma_probe()
310 b47s->cc_write = bcm47xxsflash_bcma_cc_write; in bcm47xxsflash_bcma_probe()
314 * allowing us to use cached access and gain some performance. Trying in bcm47xxsflash_bcma_probe()
315 * the same on ARM based BCM53573 results in flash corruptions, we need in bcm47xxsflash_bcma_probe()
322 if (b47s->bcma_cc->core->id.rev == 54) in bcm47xxsflash_bcma_probe()
323 b47s->window = ioremap(res->start, resource_size(res)); in bcm47xxsflash_bcma_probe()
325 b47s->window = ioremap_cache(res->start, resource_size(res)); in bcm47xxsflash_bcma_probe()
326 if (!b47s->window) { in bcm47xxsflash_bcma_probe()
328 return -ENOMEM; in bcm47xxsflash_bcma_probe()
331 switch (b47s->bcma_cc->capabilities & BCMA_CC_CAP_FLASHT) { in bcm47xxsflash_bcma_probe()
333 b47s->type = BCM47XXSFLASH_TYPE_ST; in bcm47xxsflash_bcma_probe()
336 b47s->type = BCM47XXSFLASH_TYPE_ATMEL; in bcm47xxsflash_bcma_probe()
340 b47s->blocksize = sflash->blocksize; in bcm47xxsflash_bcma_probe()
341 b47s->numblocks = sflash->numblocks; in bcm47xxsflash_bcma_probe()
342 b47s->size = sflash->size; in bcm47xxsflash_bcma_probe()
343 bcm47xxsflash_fill_mtd(b47s, &pdev->dev); in bcm47xxsflash_bcma_probe()
347 err = mtd_device_parse_register(&b47s->mtd, probes, NULL, NULL, 0); in bcm47xxsflash_bcma_probe()
350 iounmap(b47s->window); in bcm47xxsflash_bcma_probe()
355 pr_warn("Serial flash busy\n"); in bcm47xxsflash_bcma_probe()
364 mtd_device_unregister(&b47s->mtd); in bcm47xxsflash_bcma_remove()
365 iounmap(b47s->window); in bcm47xxsflash_bcma_remove()