diff options
-rw-r--r-- | drivers/mtd/devices/Kconfig | 2 | ||||
-rw-r--r-- | drivers/mtd/devices/lart.c | 10 | ||||
-rw-r--r-- | drivers/mtd/devices/spear_smi.c | 4 | ||||
-rw-r--r-- | drivers/mtd/lpddr/lpddr2_nvm.c | 35 | ||||
-rw-r--r-- | drivers/mtd/lpddr/lpddr_cmds.c | 28 | ||||
-rw-r--r-- | drivers/mtd/maps/Kconfig | 11 | ||||
-rw-r--r-- | drivers/mtd/maps/Makefile | 1 | ||||
-rw-r--r-- | drivers/mtd/maps/physmap-bt1-rom.c | 126 | ||||
-rw-r--r-- | drivers/mtd/maps/physmap-bt1-rom.h | 17 | ||||
-rw-r--r-- | drivers/mtd/maps/physmap-core.c | 8 | ||||
-rw-r--r-- | drivers/mtd/maps/vmu-flash.c | 11 | ||||
-rw-r--r-- | drivers/mtd/mtdconcat.c | 43 | ||||
-rw-r--r-- | drivers/mtd/mtdcore.c | 28 | ||||
-rw-r--r-- | drivers/mtd/mtdoops.c | 11 | ||||
-rw-r--r-- | drivers/mtd/parsers/Kconfig | 2 | ||||
-rw-r--r-- | include/linux/mtd/pfow.h | 33 |
16 files changed, 277 insertions, 93 deletions
diff --git a/drivers/mtd/devices/Kconfig b/drivers/mtd/devices/Kconfig index f96287c4b789..0f4c2d823de8 100644 --- a/drivers/mtd/devices/Kconfig +++ b/drivers/mtd/devices/Kconfig @@ -91,7 +91,7 @@ config MTD_MCHP23K256 config MTD_SPEAR_SMI tristate "SPEAR MTD NOR Support through SMI controller" - depends on PLAT_SPEAR + depends on PLAT_SPEAR || COMPILE_TEST default y help This enable SNOR support on SPEAR platforms using SMI controller diff --git a/drivers/mtd/devices/lart.c b/drivers/mtd/devices/lart.c index 56f50d27b7fd..aecd441e4183 100644 --- a/drivers/mtd/devices/lart.c +++ b/drivers/mtd/devices/lart.c @@ -436,7 +436,10 @@ static int flash_read (struct mtd_info *mtd,loff_t from,size_t len,size_t *retle { int gap = BUSWIDTH - (from & (BUSWIDTH - 1)); - while (len && gap--) *buf++ = read8 (from++), len--; + while (len && gap--) { + *buf++ = read8 (from++); + len--; + } } /* now we read dwords until we reach a non-dword boundary */ @@ -518,7 +521,10 @@ static int flash_write (struct mtd_info *mtd,loff_t to,size_t len,size_t *retlen i = n = 0; while (gap--) tmp[i++] = 0xFF; - while (len && i < BUSWIDTH) tmp[i++] = buf[n++], len--; + while (len && i < BUSWIDTH) { + tmp[i++] = buf[n++]; + len--; + } while (i < BUSWIDTH) tmp[i++] = 0xFF; if (!write_dword (aligned,*((__u32 *) tmp))) return (-EIO); diff --git a/drivers/mtd/devices/spear_smi.c b/drivers/mtd/devices/spear_smi.c index 79dcca16481d..2e00862389dd 100644 --- a/drivers/mtd/devices/spear_smi.c +++ b/drivers/mtd/devices/spear_smi.c @@ -793,7 +793,7 @@ static int spear_smi_probe_config_dt(struct platform_device *pdev, struct device_node *np) { struct spear_smi_plat_data *pdata = dev_get_platdata(&pdev->dev); - struct device_node *pp = NULL; + struct device_node *pp; const __be32 *addr; u32 val; int len; @@ -812,7 +812,7 @@ static int spear_smi_probe_config_dt(struct platform_device *pdev, return -ENOMEM; /* Fill structs for each subnode (flash device) */ - while ((pp = of_get_next_child(np, pp))) { + for_each_child_of_node(np, pp) { pdata->np[i] = pp; /* Read base-addr and size from DT */ diff --git a/drivers/mtd/lpddr/lpddr2_nvm.c b/drivers/mtd/lpddr/lpddr2_nvm.c index 0f1547f09d08..72f5c7b30079 100644 --- a/drivers/mtd/lpddr/lpddr2_nvm.c +++ b/drivers/mtd/lpddr/lpddr2_nvm.c @@ -393,6 +393,17 @@ static int lpddr2_nvm_lock(struct mtd_info *mtd, loff_t start_add, return lpddr2_nvm_do_block_op(mtd, start_add, len, LPDDR2_NVM_LOCK); } +static const struct mtd_info lpddr2_nvm_mtd_info = { + .type = MTD_RAM, + .writesize = 1, + .flags = (MTD_CAP_NVRAM | MTD_POWERUP_LOCK), + ._read = lpddr2_nvm_read, + ._write = lpddr2_nvm_write, + ._erase = lpddr2_nvm_erase, + ._unlock = lpddr2_nvm_unlock, + ._lock = lpddr2_nvm_lock, +}; + /* * lpddr2_nvm driver probe method */ @@ -433,6 +444,7 @@ static int lpddr2_nvm_probe(struct platform_device *pdev) .pfow_base = OW_BASE_ADDRESS, .fldrv_priv = pcm_data, }; + if (IS_ERR(map->virt)) return PTR_ERR(map->virt); @@ -444,22 +456,13 @@ static int lpddr2_nvm_probe(struct platform_device *pdev) return PTR_ERR(pcm_data->ctl_regs); /* Populate mtd_info data structure */ - *mtd = (struct mtd_info) { - .dev = { .parent = &pdev->dev }, - .name = pdev->dev.init_name, - .type = MTD_RAM, - .priv = map, - .size = resource_size(add_range), - .erasesize = ERASE_BLOCKSIZE * pcm_data->bus_width, - .writesize = 1, - .writebufsize = WRITE_BUFFSIZE * pcm_data->bus_width, - .flags = (MTD_CAP_NVRAM | MTD_POWERUP_LOCK), - ._read = lpddr2_nvm_read, - ._write = lpddr2_nvm_write, - ._erase = lpddr2_nvm_erase, - ._unlock = lpddr2_nvm_unlock, - ._lock = lpddr2_nvm_lock, - }; + *mtd = lpddr2_nvm_mtd_info; + mtd->dev.parent = &pdev->dev; + mtd->name = pdev->dev.init_name; + mtd->priv = map; + mtd->size = resource_size(add_range); + mtd->erasesize = ERASE_BLOCKSIZE * pcm_data->bus_width; + mtd->writebufsize = WRITE_BUFFSIZE * pcm_data->bus_width; /* Verify the presence of the device looking for PFOW string */ if (!lpddr2_nvm_pfow_present(map)) { diff --git a/drivers/mtd/lpddr/lpddr_cmds.c b/drivers/mtd/lpddr/lpddr_cmds.c index fb1cbc9a2870..ee063baed136 100644 --- a/drivers/mtd/lpddr/lpddr_cmds.c +++ b/drivers/mtd/lpddr/lpddr_cmds.c @@ -94,6 +94,34 @@ struct mtd_info *lpddr_cmdset(struct map_info *map) } EXPORT_SYMBOL(lpddr_cmdset); +static void print_drs_error(unsigned int dsr) +{ + int prog_status = (dsr & DSR_RPS) >> 8; + + if (!(dsr & DSR_AVAILABLE)) + pr_notice("DSR.15: (0) Device not Available\n"); + if ((prog_status & 0x03) == 0x03) + pr_notice("DSR.9,8: (11) Attempt to program invalid half with 41h command\n"); + else if (prog_status & 0x02) + pr_notice("DSR.9,8: (10) Object Mode Program attempt in region with Control Mode data\n"); + else if (prog_status & 0x01) + pr_notice("DSR.9,8: (01) Program attempt in region with Object Mode data\n"); + if (!(dsr & DSR_READY_STATUS)) + pr_notice("DSR.7: (0) Device is Busy\n"); + if (dsr & DSR_ESS) + pr_notice("DSR.6: (1) Erase Suspended\n"); + if (dsr & DSR_ERASE_STATUS) + pr_notice("DSR.5: (1) Erase/Blank check error\n"); + if (dsr & DSR_PROGRAM_STATUS) + pr_notice("DSR.4: (1) Program Error\n"); + if (dsr & DSR_VPPS) + pr_notice("DSR.3: (1) Vpp low detect, operation aborted\n"); + if (dsr & DSR_PSS) + pr_notice("DSR.2: (1) Program suspended\n"); + if (dsr & DSR_DPS) + pr_notice("DSR.1: (1) Aborted Erase/Program attempt on locked block\n"); +} + static int wait_for_ready(struct map_info *map, struct flchip *chip, unsigned int chip_op_time) { diff --git a/drivers/mtd/maps/Kconfig b/drivers/mtd/maps/Kconfig index fd37553f1b07..6650acbc961e 100644 --- a/drivers/mtd/maps/Kconfig +++ b/drivers/mtd/maps/Kconfig @@ -75,6 +75,17 @@ config MTD_PHYSMAP_OF physically into the CPU's memory. The mapping description here is taken from OF device tree. +config MTD_PHYSMAP_BT1_ROM + bool "Baikal-T1 Boot ROMs OF-based physical memory map handling" + depends on MTD_PHYSMAP_OF + depends on MIPS_BAIKAL_T1 || COMPILE_TEST + select MTD_COMPLEX_MAPPINGS + select MULTIPLEXER + select MUX_MMIO + help + This provides some extra DT physmap parsing for the Baikal-T1 + platforms, some detection and setting up ROMs-specific accessors. + config MTD_PHYSMAP_VERSATILE bool "ARM Versatile OF-based physical memory map handling" depends on MTD_PHYSMAP_OF diff --git a/drivers/mtd/maps/Makefile b/drivers/mtd/maps/Makefile index c0da86a5d26f..79f018cf412f 100644 --- a/drivers/mtd/maps/Makefile +++ b/drivers/mtd/maps/Makefile @@ -18,6 +18,7 @@ obj-$(CONFIG_MTD_CK804XROM) += ck804xrom.o obj-$(CONFIG_MTD_TSUNAMI) += tsunami_flash.o obj-$(CONFIG_MTD_PXA2XX) += pxa2xx-flash.o physmap-objs-y += physmap-core.o +physmap-objs-$(CONFIG_MTD_PHYSMAP_BT1_ROM) += physmap-bt1-rom.o physmap-objs-$(CONFIG_MTD_PHYSMAP_VERSATILE) += physmap-versatile.o physmap-objs-$(CONFIG_MTD_PHYSMAP_GEMINI) += physmap-gemini.o physmap-objs-$(CONFIG_MTD_PHYSMAP_IXP4XX) += physmap-ixp4xx.o diff --git a/drivers/mtd/maps/physmap-bt1-rom.c b/drivers/mtd/maps/physmap-bt1-rom.c new file mode 100644 index 000000000000..27cfe1c63a2e --- /dev/null +++ b/drivers/mtd/maps/physmap-bt1-rom.c @@ -0,0 +1,126 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * Copyright (C) 2020 BAIKAL ELECTRONICS, JSC + * + * Authors: + * Serge Semin <Sergey.Semin@baikalelectronics.ru> + * + * Baikal-T1 Physically Mapped Internal ROM driver + */ +#include <linux/bits.h> +#include <linux/device.h> +#include <linux/kernel.h> +#include <linux/mtd/map.h> +#include <linux/mtd/xip.h> +#include <linux/mux/consumer.h> +#include <linux/of.h> +#include <linux/of_device.h> +#include <linux/platform_device.h> +#include <linux/string.h> +#include <linux/types.h> + +#include "physmap-bt1-rom.h" + +/* + * Baikal-T1 SoC ROMs are only accessible by the dword-aligned instructions. + * We have to take this into account when implementing the data read-methods. + * Note there is no need in bothering with endianness, since both Baikal-T1 + * CPU and MMIO are LE. + */ +static map_word __xipram bt1_rom_map_read(struct map_info *map, + unsigned long ofs) +{ + void __iomem *src = map->virt + ofs; + unsigned long shift; + map_word ret; + u32 data; + + /* Read data within offset dword. */ + shift = (unsigned long)src & 0x3; + data = readl_relaxed(src - shift); + if (!shift) { + ret.x[0] = data; + return ret; + } + ret.x[0] = data >> (shift * BITS_PER_BYTE); + + /* Read data from the next dword. */ + shift = 4 - shift; + if (ofs + shift >= map->size) + return ret; + + data = readl_relaxed(src + shift); + ret.x[0] |= data << (shift * BITS_PER_BYTE); + + return ret; +} + +static void __xipram bt1_rom_map_copy_from(struct map_info *map, + void *to, unsigned long from, + ssize_t len) +{ + void __iomem *src = map->virt + from; + ssize_t shift, chunk; + u32 data; + + if (len <= 0 || from >= map->size) + return; + + /* Make sure we don't go over the map limit. */ + len = min_t(ssize_t, map->size - from, len); + + /* + * Since requested data size can be pretty big we have to implement + * the copy procedure as optimal as possible. That's why it's split + * up into the next three stages: unaligned head, aligned body, + * unaligned tail. + */ + shift = (ssize_t)src & 0x3; + if (shift) { + chunk = min_t(ssize_t, 4 - shift, len); + data = readl_relaxed(src - shift); + memcpy(to, &data + shift, chunk); + src += chunk; + to += chunk; + len -= chunk; + } + + while (len >= 4) { + data = readl_relaxed(src); + memcpy(to, &data, 4); + src += 4; + to += 4; + len -= 4; + } + + if (len) { + data = readl_relaxed(src); + memcpy(to, &data, len); + } +} + +int of_flash_probe_bt1_rom(struct platform_device *pdev, + struct device_node *np, + struct map_info *map) +{ + struct device *dev = &pdev->dev; + + /* It's supposed to be read-only MTD. */ + if (!of_device_is_compatible(np, "mtd-rom")) { + dev_info(dev, "No mtd-rom compatible string\n"); + return 0; + } + + /* Multiplatform guard. */ + if (!of_device_is_compatible(np, "baikal,bt1-int-rom")) + return 0; + + /* Sanity check the device parameters retrieved from DTB. */ + if (map->bankwidth != 4) + dev_warn(dev, "Bank width is supposed to be 32 bits wide\n"); + + map->read = bt1_rom_map_read; + map->copy_from = bt1_rom_map_copy_from; + + return 0; +} diff --git a/drivers/mtd/maps/physmap-bt1-rom.h b/drivers/mtd/maps/physmap-bt1-rom.h new file mode 100644 index 000000000000..6782899598a4 --- /dev/null +++ b/drivers/mtd/maps/physmap-bt1-rom.h @@ -0,0 +1,17 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ +#include <linux/mtd/map.h> +#include <linux/of.h> + +#ifdef CONFIG_MTD_PHYSMAP_BT1_ROM +int of_flash_probe_bt1_rom(struct platform_device *pdev, + struct device_node *np, + struct map_info *map); +#else +static inline +int of_flash_probe_bt1_rom(struct platform_device *pdev, + struct device_node *np, + struct map_info *map) +{ + return 0; +} +#endif diff --git a/drivers/mtd/maps/physmap-core.c b/drivers/mtd/maps/physmap-core.c index 8f7f966fa9a7..001ed5deb622 100644 --- a/drivers/mtd/maps/physmap-core.c +++ b/drivers/mtd/maps/physmap-core.c @@ -41,6 +41,7 @@ #include <linux/pm_runtime.h> #include <linux/gpio/consumer.h> +#include "physmap-bt1-rom.h" #include "physmap-gemini.h" #include "physmap-ixp4xx.h" #include "physmap-versatile.h" @@ -371,6 +372,10 @@ static int physmap_flash_of_init(struct platform_device *dev) info->maps[i].bankwidth = bankwidth; info->maps[i].device_node = dp; + err = of_flash_probe_bt1_rom(dev, dp, &info->maps[i]); + if (err) + return err; + err = of_flash_probe_gemini(dev, dp, &info->maps[i]); if (err) return err; @@ -515,7 +520,8 @@ static int physmap_flash_probe(struct platform_device *dev) dev_notice(&dev->dev, "physmap platform flash device: %pR\n", res); - info->maps[i].name = dev_name(&dev->dev); + if (!info->maps[i].name) + info->maps[i].name = dev_name(&dev->dev); if (!info->maps[i].phys) info->maps[i].phys = res->start; diff --git a/drivers/mtd/maps/vmu-flash.c b/drivers/mtd/maps/vmu-flash.c index 177bf134e189..a7ec947a3ebb 100644 --- a/drivers/mtd/maps/vmu-flash.c +++ b/drivers/mtd/maps/vmu-flash.c @@ -40,7 +40,7 @@ struct memcard { u32 blocklen; u32 writecnt; u32 readcnt; - u32 removeable; + u32 removable; int partition; int read; unsigned char *blockread; @@ -619,7 +619,7 @@ static int vmu_connect(struct maple_device *mdev) card->blocklen = ((basic_flash_data >> 16 & 0xFF) + 1) << 5; card->writecnt = basic_flash_data >> 12 & 0xF; card->readcnt = basic_flash_data >> 8 & 0xF; - card->removeable = basic_flash_data >> 7 & 1; + card->removable = basic_flash_data >> 7 & 1; card->partition = 0; @@ -772,7 +772,6 @@ static void vmu_file_error(struct maple_device *mdev, void *recvbuf) static int probe_maple_vmu(struct device *dev) { - int error; struct maple_device *mdev = to_maple_dev(dev); struct maple_driver *mdrv = to_maple_driver(dev->driver); @@ -780,11 +779,7 @@ static int probe_maple_vmu(struct device *dev) mdev->fileerr_handler = vmu_file_error; mdev->driver = mdrv; - error = vmu_connect(mdev); - if (error) - return error; - - return 0; + return vmu_connect(mdev); } static int remove_maple_vmu(struct device *dev) diff --git a/drivers/mtd/mtdconcat.c b/drivers/mtd/mtdconcat.c index 1d6c9e7e7b7d..6e4d0017c0bd 100644 --- a/drivers/mtd/mtdconcat.c +++ b/drivers/mtd/mtdconcat.c @@ -103,6 +103,47 @@ concat_read(struct mtd_info *mtd, loff_t from, size_t len, } static int +concat_panic_write(struct mtd_info *mtd, loff_t to, size_t len, + size_t * retlen, const u_char * buf) +{ + struct mtd_concat *concat = CONCAT(mtd); + int err = -EINVAL; + int i; + for (i = 0; i < concat->num_subdev; i++) { + struct mtd_info *subdev = concat->subdev[i]; + size_t size, retsize; + + if (to >= subdev->size) { + to -= subdev->size; + continue; + } + if (to + len > subdev->size) + size = subdev->size - to; + else + size = len; + + err = mtd_panic_write(subdev, to, size, &retsize, buf); + if (err == -EOPNOTSUPP) { + printk(KERN_ERR "mtdconcat: Cannot write from panic without panic_write\n"); + return err; + } + if (err) + break; + + *retlen += retsize; + len -= size; + if (len == 0) + break; + + err = -EINVAL; + buf += size; + to = 0; + } + return err; +} + + +static int concat_write(struct mtd_info *mtd, loff_t to, size_t len, size_t * retlen, const u_char * buf) { @@ -648,6 +689,8 @@ struct mtd_info *mtd_concat_create(struct mtd_info *subdev[], /* subdevices to c concat->mtd._block_isbad = concat_block_isbad; if (subdev[0]->_block_markbad) concat->mtd._block_markbad = concat_block_markbad; + if (subdev[0]->_panic_write) + concat->mtd._panic_write = concat_panic_write; concat->mtd.ecc_stats.badblocks = subdev[0]->ecc_stats.badblocks; diff --git a/drivers/mtd/mtdcore.c b/drivers/mtd/mtdcore.c index 7d930569a7df..a88fe9fc09fa 100644 --- a/drivers/mtd/mtdcore.c +++ b/drivers/mtd/mtdcore.c @@ -335,7 +335,7 @@ static const struct device_type mtd_devtype = { .release = mtd_release, }; -static int mtd_partid_show(struct seq_file *s, void *p) +static int mtd_partid_debug_show(struct seq_file *s, void *p) { struct mtd_info *mtd = s->private; @@ -344,19 +344,9 @@ static int mtd_partid_show(struct seq_file *s, void *p) return 0; } -static int mtd_partid_debugfs_open(struct inode *inode, struct file *file) -{ - return single_open(file, mtd_partid_show, inode->i_private); -} - -static const struct file_operations mtd_partid_debug_fops = { - .open = mtd_partid_debugfs_open, - .read = seq_read, - .llseek = seq_lseek, - .release = single_release, -}; +DEFINE_SHOW_ATTRIBUTE(mtd_partid_debug); -static int mtd_partname_show(struct seq_file *s, void *p) +static int mtd_partname_debug_show(struct seq_file *s, void *p) { struct mtd_info *mtd = s->private; @@ -365,17 +355,7 @@ static int mtd_partname_show(struct seq_file *s, void *p) return 0; } -static int mtd_partname_debugfs_open(struct inode *inode, struct file *file) -{ - return single_open(file, mtd_partname_show, inode->i_private); -} - -static const struct file_operations mtd_partname_debug_fops = { - .open = mtd_partname_debugfs_open, - .read = seq_read, - .llseek = seq_lseek, - .release = single_release, -}; +DEFINE_SHOW_ATTRIBUTE(mtd_partname_debug); static struct dentry *dfs_dir_mtd; diff --git a/drivers/mtd/mtdoops.c b/drivers/mtd/mtdoops.c index 4ced68be7ed7..774970bfcf85 100644 --- a/drivers/mtd/mtdoops.c +++ b/drivers/mtd/mtdoops.c @@ -279,12 +279,13 @@ static void mtdoops_do_dump(struct kmsg_dumper *dumper, kmsg_dump_get_buffer(dumper, true, cxt->oops_buf + MTDOOPS_HEADER_SIZE, record_size - MTDOOPS_HEADER_SIZE, NULL); - /* Panics must be written immediately */ - if (reason != KMSG_DUMP_OOPS) + if (reason != KMSG_DUMP_OOPS) { + /* Panics must be written immediately */ mtdoops_write(cxt, 1); - - /* For other cases, schedule work to write it "nicely" */ - schedule_work(&cxt->work_write); + } else { + /* For other cases, schedule work to write it "nicely" */ + schedule_work(&cxt->work_write); + } } static void mtdoops_notify_add(struct mtd_info *mtd) diff --git a/drivers/mtd/parsers/Kconfig b/drivers/mtd/parsers/Kconfig index f98363c9b363..e72354322f62 100644 --- a/drivers/mtd/parsers/Kconfig +++ b/drivers/mtd/parsers/Kconfig @@ -12,7 +12,7 @@ config MTD_BCM47XX_PARTS boards. config MTD_BCM63XX_PARTS - tristate "BCM63XX CFE partitioning parser" + bool "BCM63XX CFE partitioning parser" depends on BCM63XX || BMIPS_GENERIC || COMPILE_TEST select CRC32 select MTD_PARSER_IMAGETAG diff --git a/include/linux/mtd/pfow.h b/include/linux/mtd/pfow.h index 6166e7c60869..146413d4bdb7 100644 --- a/include/linux/mtd/pfow.h +++ b/include/linux/mtd/pfow.h @@ -121,37 +121,4 @@ static inline void send_pfow_command(struct map_info *map, map_write(map, CMD(LPDDR_START_EXECUTION), map->pfow_base + PFOW_COMMAND_EXECUTE); } - -static inline void print_drs_error(unsigned dsr) -{ - int prog_status = (dsr & DSR_RPS) >> 8; - - if (!(dsr & DSR_AVAILABLE)) - printk(KERN_NOTICE"DSR.15: (0) Device not Available\n"); - if (prog_status & 0x03) - printk(KERN_NOTICE"DSR.9,8: (11) Attempt to program invalid " - "half with 41h command\n"); - else if (prog_status & 0x02) - printk(KERN_NOTICE"DSR.9,8: (10) Object Mode Program attempt " - "in region with Control Mode data\n"); - else if (prog_status & 0x01) - printk(KERN_NOTICE"DSR.9,8: (01) Program attempt in region " - "with Object Mode data\n"); - if (!(dsr & DSR_READY_STATUS)) - printk(KERN_NOTICE"DSR.7: (0) Device is Busy\n"); - if (dsr & DSR_ESS) - printk(KERN_NOTICE"DSR.6: (1) Erase Suspended\n"); - if (dsr & DSR_ERASE_STATUS) - printk(KERN_NOTICE"DSR.5: (1) Erase/Blank check error\n"); - if (dsr & DSR_PROGRAM_STATUS) - printk(KERN_NOTICE"DSR.4: (1) Program Error\n"); - if (dsr & DSR_VPPS) - printk(KERN_NOTICE"DSR.3: (1) Vpp low detect, operation " - "aborted\n"); - if (dsr & DSR_PSS) - printk(KERN_NOTICE"DSR.2: (1) Program suspended\n"); - if (dsr & DSR_DPS) - printk(KERN_NOTICE"DSR.1: (1) Aborted Erase/Program attempt " - "on locked block\n"); -} #endif /* __LINUX_MTD_PFOW_H */ |