kernel: update bcma and ssb to version from wireless-testing/master tag master-2013...
[openwrt.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: