brcm47xx: Add support for Huawei E970
[openwrt/svn-archive/archive.git] / target / linux / brcm47xx / patches-3.10 / 051-mtd_bcm47xxsflash_implement_polling_chip_status.patch
1 commit 7026e9844112fa33e5ffcd562daf0c919b16a9d1
2 Author: Rafał Miłecki <zajec5@gmail.com>
3 Date: Sun Mar 24 21:51:31 2013 +0100
4
5 mtd: bcm47xxsflash: implement polling chip status
6
7 Signed-off-by: Rafał Miłecki <zajec5@gmail.com>
8 Signed-off-by: Artem Bityutskiy <artem.bityutskiy@linux.intel.com>
9
10 --- a/drivers/mtd/devices/bcm47xxsflash.c
11 +++ b/drivers/mtd/devices/bcm47xxsflash.c
12 @@ -1,6 +1,7 @@
13 #include <linux/kernel.h>
14 #include <linux/module.h>
15 #include <linux/slab.h>
16 +#include <linux/delay.h>
17 #include <linux/mtd/mtd.h>
18 #include <linux/platform_device.h>
19 #include <linux/bcma/bcma.h>
20 @@ -12,6 +13,57 @@ MODULE_DESCRIPTION("Serial flash driver
21
22 static const char * const probes[] = { "bcm47xxpart", NULL };
23
24 +/**************************************************
25 + * Various helpers
26 + **************************************************/
27 +
28 +static void bcm47xxsflash_cmd(struct bcm47xxsflash *b47s, u32 opcode)
29 +{
30 + int i;
31 +
32 + b47s->cc_write(b47s, BCMA_CC_FLASHCTL, BCMA_CC_FLASHCTL_START | opcode);
33 + for (i = 0; i < 1000; i++) {
34 + if (!(b47s->cc_read(b47s, BCMA_CC_FLASHCTL) &
35 + BCMA_CC_FLASHCTL_BUSY))
36 + return;
37 + cpu_relax();
38 + }
39 + pr_err("Control command failed (timeout)!\n");
40 +}
41 +
42 +static int bcm47xxsflash_poll(struct bcm47xxsflash *b47s, int timeout)
43 +{
44 + unsigned long deadline = jiffies + timeout;
45 +
46 + do {
47 + switch (b47s->type) {
48 + case BCM47XXSFLASH_TYPE_ST:
49 + bcm47xxsflash_cmd(b47s, OPCODE_ST_RDSR);
50 + if (!(b47s->cc_read(b47s, BCMA_CC_FLASHDATA) &
51 + SR_ST_WIP))
52 + return 0;
53 + break;
54 + case BCM47XXSFLASH_TYPE_ATMEL:
55 + bcm47xxsflash_cmd(b47s, OPCODE_AT_STATUS);
56 + if (b47s->cc_read(b47s, BCMA_CC_FLASHDATA) &
57 + SR_AT_READY)
58 + return 0;
59 + break;
60 + }
61 +
62 + cpu_relax();
63 + udelay(1);
64 + } while (!time_after_eq(jiffies, deadline));
65 +
66 + pr_err("Timeout waiting for flash to be ready!\n");
67 +
68 + return -EBUSY;
69 +}
70 +
71 +/**************************************************
72 + * MTD ops
73 + **************************************************/
74 +
75 static int bcm47xxsflash_read(struct mtd_info *mtd, loff_t from, size_t len,
76 size_t *retlen, u_char *buf)
77 {
78 @@ -97,6 +149,9 @@ static int bcm47xxsflash_bcma_probe(stru
79 goto err_dev_reg;
80 }
81
82 + if (bcm47xxsflash_poll(b47s, HZ / 10))
83 + pr_warn("Serial flash busy\n");
84 +
85 return 0;
86
87 err_dev_reg: