Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 195935
b: refs/heads/master
c: eafe131
h: refs/heads/master
i:
  195933: b8072dd
  195931: b4932b1
  195927: c077697
  195919: dc935e8
  195903: b7d89f3
v: v3
  • Loading branch information
Kevin Cernekee authored and David Woodhouse committed May 10, 2010
1 parent 2225773 commit c166d67
Show file tree
Hide file tree
Showing 2 changed files with 57 additions and 1 deletion.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: bff3c10d369440bc87ba612b45ba2777d2bf017f
refs/heads/master: eafe1311aa3cdb13efa25c60251bce12e60ae38a
56 changes: 56 additions & 0 deletions trunk/drivers/mtd/chips/cfi_cmdset_0002.c
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@
#include <linux/slab.h>
#include <linux/delay.h>
#include <linux/interrupt.h>
#include <linux/reboot.h>
#include <linux/mtd/compatmac.h>
#include <linux/mtd/map.h>
#include <linux/mtd/mtd.h>
Expand All @@ -56,6 +57,7 @@ static int cfi_amdstd_erase_varsize(struct mtd_info *, struct erase_info *);
static void cfi_amdstd_sync (struct mtd_info *);
static int cfi_amdstd_suspend (struct mtd_info *);
static void cfi_amdstd_resume (struct mtd_info *);
static int cfi_amdstd_reboot(struct notifier_block *, unsigned long, void *);
static int cfi_amdstd_secsi_read (struct mtd_info *, loff_t, size_t, size_t *, u_char *);

static void cfi_amdstd_destroy(struct mtd_info *);
Expand Down Expand Up @@ -351,6 +353,8 @@ struct mtd_info *cfi_cmdset_0002(struct map_info *map, int primary)
mtd->name = map->name;
mtd->writesize = 1;

mtd->reboot_notifier.notifier_call = cfi_amdstd_reboot;

if (cfi->cfi_mode==CFI_MODE_CFI){
unsigned char bootloc;
/*
Expand Down Expand Up @@ -487,6 +491,7 @@ static struct mtd_info *cfi_amdstd_setup(struct mtd_info *mtd)
#endif

__module_get(THIS_MODULE);
register_reboot_notifier(&mtd->reboot_notifier);
return mtd;

setup_err:
Expand Down Expand Up @@ -628,6 +633,10 @@ static int get_chip(struct map_info *map, struct flchip *chip, unsigned long adr
chip->state = FL_READY;
return 0;

case FL_SHUTDOWN:
/* The machine is rebooting */
return -EIO;

case FL_POINT:
/* Only if there's no operation suspended... */
if (mode == FL_READY && chip->oldstate == FL_READY)
Expand Down Expand Up @@ -1918,11 +1927,58 @@ static void cfi_amdstd_resume(struct mtd_info *mtd)
}
}


/*
* Ensure that the flash device is put back into read array mode before
* unloading the driver or rebooting. On some systems, rebooting while
* the flash is in query/program/erase mode will prevent the CPU from
* fetching the bootloader code, requiring a hard reset or power cycle.
*/
static int cfi_amdstd_reset(struct mtd_info *mtd)
{
struct map_info *map = mtd->priv;
struct cfi_private *cfi = map->fldrv_priv;
int i, ret;
struct flchip *chip;

for (i = 0; i < cfi->numchips; i++) {

chip = &cfi->chips[i];

mutex_lock(&chip->mutex);

ret = get_chip(map, chip, chip->start, FL_SHUTDOWN);
if (!ret) {
map_write(map, CMD(0xF0), chip->start);
chip->state = FL_SHUTDOWN;
put_chip(map, chip, chip->start);
}

mutex_unlock(&chip->mutex);
}

return 0;
}


static int cfi_amdstd_reboot(struct notifier_block *nb, unsigned long val,
void *v)
{
struct mtd_info *mtd;

mtd = container_of(nb, struct mtd_info, reboot_notifier);
cfi_amdstd_reset(mtd);
return NOTIFY_DONE;
}


static void cfi_amdstd_destroy(struct mtd_info *mtd)
{
struct map_info *map = mtd->priv;
struct cfi_private *cfi = map->fldrv_priv;

cfi_amdstd_reset(mtd);
unregister_reboot_notifier(&mtd->reboot_notifier);
kfree(cfi->cmdset_priv);
kfree(cfi->cfiq);
kfree(cfi);
Expand Down

0 comments on commit c166d67

Please sign in to comment.