Title: [7415] trunk/drivers/mtd/chips: stm_flash: punt now that we can use the common mtd drivers
Revision
7415
Author
vapier
Date
2009-09-22 23:55:12 -0400 (Tue, 22 Sep 2009)

Log Message

stm_flash: punt now that we can use the common mtd drivers

Modified Paths


Removed Paths

Diff

Modified: trunk/drivers/mtd/chips/Kconfig (7414 => 7415)


--- trunk/drivers/mtd/chips/Kconfig	2009-09-23 03:23:48 UTC (rev 7414)
+++ trunk/drivers/mtd/chips/Kconfig	2009-09-23 03:55:12 UTC (rev 7415)
@@ -207,14 +207,6 @@
 	  sets which a CFI-compliant chip may claim to implement. This code
 	  provides support for one of those command sets.
 
-config MTD_PSD4256G
-	tristate "ST PSD4256G compatible flash chip support"
-	help
-	  Driver for flashes compatible with ST PSD4256G.  This is a non-CFI
-	  and non-JEDEC compliant flash and you really shouldn't buy this.
-
-	  If unsure, say N here.
-
 config MTD_CFI_UTIL
 	tristate
 

Modified: trunk/drivers/mtd/chips/Makefile (7414 => 7415)


--- trunk/drivers/mtd/chips/Makefile	2009-09-23 03:23:48 UTC (rev 7414)
+++ trunk/drivers/mtd/chips/Makefile	2009-09-23 03:55:12 UTC (rev 7415)
@@ -13,4 +13,3 @@
 obj-$(CONFIG_MTD_RAM)		+= map_ram.o
 obj-$(CONFIG_MTD_ROM)		+= map_rom.o
 obj-$(CONFIG_MTD_ABSENT)	+= map_absent.o
-obj-$(CONFIG_MTD_PSD4256G)	+= stm_flash.o

Deleted: trunk/drivers/mtd/chips/stm_flash.c (7414 => 7415)


--- trunk/drivers/mtd/chips/stm_flash.c	2009-09-23 03:23:48 UTC (rev 7414)
+++ trunk/drivers/mtd/chips/stm_flash.c	2009-09-23 03:55:12 UTC (rev 7415)
@@ -1,747 +0,0 @@
-/*
- * Driver for ST PSD4256G flash
- *
- * Copyright 2004-2009 Analog Devices Inc.
- * Licensed under the GPL-2 or later.
- */
-
-#define pr_fmt(fmt) "stm_flash: " fmt
-
-#include <linux/delay.h>
-#include <linux/errno.h>
-#include <linux/init.h>
-#include <linux/interrupt.h>
-#include <linux/kernel.h>
-#include <linux/module.h>
-#include <linux/mtd/map.h>
-#include <linux/mtd/mtd.h>
-#include <linux/mtd/flashchip.h>
-#include <linux/sched.h>
-#include <linux/types.h>
-
-/* Addresses */
-#define ADDR_MANUFACTURER		0x0000
-#define ADDR_DEVICE_ID			0x0002
-#define ADDR_UNLOCK_1			0x0AAA
-#define ADDR_UNLOCK_2			0x0554
-
-/* Commands */
-#define CMD_UNLOCK_DATA_1		0x00aa
-#define CMD_UNLOCK_DATA_2		0x0055
-#define CMD_MANUFACTURER_UNLOCK_DATA	0x0090
-#define CMD_PROGRAM_UNLOCK_DATA		0x00A0
-#define CMD_RESET_DATA			0x00F0
-#define CMD_SECTOR_ERASE_UNLOCK_DATA	0x0080
-#define CMD_SECTOR_ERASE_UNLOCK_DATA_2	0x0030
-
-#define D6_MASK 0x40
-
-struct stm_flash_private {
-	unsigned long chipshift;
-	struct flchip chip;
-};
-
-static void send_unlock(struct map_info *map, unsigned long base)
-{
-	map_word test;
-	test.x[0] = 0x00aa;
-	map_write(map, test, base + ADDR_UNLOCK_1);
-	test.x[0] = 0x0055;
-	map_write(map, test, base + ADDR_UNLOCK_2);
-}
-
-static void send_cmd(struct map_info *map, unsigned long base,
-		     unsigned long cmd)
-{
-	map_word test;
-	test.x[0] = cmd;
-	send_unlock(map, base);
-	map_write(map, test, base + ADDR_UNLOCK_1);
-}
-
-static void send_cmd_to_addr(struct map_info *map, unsigned long base,
-			     unsigned long cmd, unsigned long addr)
-{
-	map_word test;
-	test.x[0] = cmd;
-	send_unlock(map, base);
-	map_write(map, test, addr);
-}
-
-static void stm_flash_sync(struct mtd_info *mtd)
-{
-	struct map_info *map = mtd->priv;
-	struct stm_flash_private *private = map->fldrv_priv;
-	struct flchip *chip;
-	DECLARE_WAITQUEUE(wait, current);
-
-	chip = &private->chip;
-
- retry:
-		spin_lock_bh(chip->mutex);
-
-		switch (chip->state) {
-		case FL_READY:
-		case FL_STATUS:
-		case FL_CFI_QUERY:
-		case FL_JEDEC_QUERY:
-			chip->oldstate = chip->state;
-			chip->state = FL_SYNCING;
-		case FL_SYNCING:
-			spin_unlock_bh(chip->mutex);
-			break;
-		default:
-			/* Not an idle state */
-			add_wait_queue(&chip->wq, &wait);
-
-			spin_unlock_bh(chip->mutex);
-			schedule();
-			remove_wait_queue(&chip->wq, &wait);
-
-			goto retry;
-		}
-
-	chip = &private->chip;
-
-	spin_lock_bh(chip->mutex);
-
-	if (chip->state == FL_SYNCING) {
-		chip->state = chip->oldstate;
-		wake_up(&chip->wq);
-	}
-	spin_unlock_bh(chip->mutex);
-}
-
-static int read_one_chip(struct map_info *map, struct flchip *chip,
-			loff_t addr, size_t len, unsigned char *buf)
-{
-	DECLARE_WAITQUEUE(wait, current);
-	unsigned long timeo = jiffies + HZ;
-
- retry:
-	spin_lock_bh(chip->mutex);
-
-	if (chip->state != FL_READY) {
-		pr_info("waiting for chip to read, state = %d\n",
-			chip->state);
-		set_current_state(TASK_UNINTERRUPTIBLE);
-		add_wait_queue(&chip->wq, &wait);
-
-		spin_unlock_bh(chip->mutex);
-
-		schedule();
-		remove_wait_queue(&chip->wq, &wait);
-
-		if (signal_pending(current))
-			return -EINTR;
-
-		timeo = jiffies + HZ;
-
-		goto retry;
-	}
-
-	addr += chip->start;
-
-	chip->state = FL_READY;
-
-	map_copy_from(map, buf, addr, len);
-
-	wake_up(&chip->wq);
-	spin_unlock_bh(chip->mutex);
-
-	return 0;
-}
-
-static int stm_flash_read(struct mtd_info *mtd, loff_t from, size_t len,
-			  size_t *retlen, unsigned char *buf)
-{
-	struct map_info *map = mtd->priv;
-	struct stm_flash_private *private = map->fldrv_priv;
-	unsigned long offset;
-	int chipnum, ret = 0;
-
-	if ((from + len) > mtd->size) {
-		pr_warning("read request past end of device (0x%lx)\n",
-			   (unsigned long)from + len);
-		return -EINVAL;
-	}
-
-	/* Offset within the first chip that the first read should start. */
-	chipnum = (from >> private->chipshift);
-	offset = from - (chipnum << private->chipshift);
-
-	*retlen = 0;
-
-	while (len) {
-		unsigned long this_len;
-
-		if ((len + offset - 1) >> private->chipshift)
-			this_len = (1 << private->chipshift) - offset;
-		else
-			this_len = len;
-
-		ret = read_one_chip(map, &private->chip, offset,
-				this_len, buf);
-
-		if (ret)
-			break;
-
-		*retlen += this_len;
-		len -= this_len;
-		buf += this_len;
-
-		offset = 0;
-		chipnum++;
-	}
-
-	return ret;
-}
-
-static int flash_is_busy(struct map_info *map, unsigned long addr)
-{
-	unsigned short toggled;
-	map_word read11, read21;
-
-	read11 = map_read(map, addr);
-	read21 = map_read(map, addr);
-
-	toggled = (unsigned short)read11.x[0] ^ (unsigned short)read21.x[0];
-
-	toggled &= (((unsigned short)1) << 6);
-	return toggled;
-}
-
-static int write_one_word(struct map_info *map, struct flchip *chip,
-		unsigned long addr, unsigned long datum)
-{
-	unsigned long timeo = jiffies + HZ;
-	DECLARE_WAITQUEUE(wait, current);
-	int ret = 0;
-	int times_left;
-	map_word test;
-
- retry:
-	spin_lock_bh(chip->mutex);
-
-	if (chip->state != FL_READY) {
-		pr_info("%s: waiting for chip to write, state = %d\n",
-			map->name, chip->state);
-		set_current_state(TASK_UNINTERRUPTIBLE);
-		add_wait_queue(&chip->wq, &wait);
-
-		spin_unlock_bh(chip->mutex);
-
-		schedule();
-		remove_wait_queue(&chip->wq, &wait);
-		pr_info("%s: woke up to write\n", map->name);
-		if (signal_pending(current))
-			return -EINTR;
-
-		timeo = jiffies + HZ;
-
-		goto retry;
-	}
-
-	chip->state = FL_WRITING;
-
-	addr += chip->start;
-
-	send_cmd(map, chip->start, CMD_PROGRAM_UNLOCK_DATA);
-
-	test.x[0] = datum;
-	map_write(map, test, addr);
-
-	times_left = 50000;
-	while (times_left-- && flash_is_busy(map, addr)) {
-		if (need_resched()) {
-			spin_unlock_bh(chip->mutex);
-			schedule();
-			spin_lock_bh(chip->mutex);
-		}
-	}
-
-	if (!times_left) {
-		pr_warning("write to 0x%lx timed out!\n", addr);
-		ret = -EIO;
-	} else {
-		unsigned long verify;
-		map_word test;
-
-		test = map_read(map, addr);
-		verify = test.x[0];
-		if (verify != datum) {
-			pr_warning("write to 0x%lx failed "
-				   "datum = %lx, verify = %lx\n",
-				   addr, datum, verify);
-			ret = -EIO;
-		}
-	}
-	chip->state = FL_READY;
-	wake_up(&chip->wq);
-	spin_unlock_bh(chip->mutex);
-
-	return ret;
-}
-
-static int stm_flash_write(struct mtd_info *mtd, loff_t to, size_t len,
-			   size_t *retlen, const unsigned char *buf)
-{
-	struct map_info *map = mtd->priv;
-	struct stm_flash_private *private = map->fldrv_priv;
-	int ret = 0;
-	int chipnum;
-	unsigned long offset;
-
-	*retlen = 0;
-	if (!len)
-		return 0;
-
-	chipnum = to >> private->chipshift;
-	offset = to - (chipnum << private->chipshift);
-
-	/* If it's not bus-aligned, do the first byte write. */
-	if (offset & (map->bankwidth - 1)) {
-		unsigned long bus_offset = offset & ~(map->bankwidth - 1);
-		int i = offset - bus_offset;
-		int n = 0;
-		unsigned char tmp_buf[4];
-		unsigned long datum;
-
-		map_copy_from(map, tmp_buf,
-			       bus_offset + private->chip.start,
-			       map->bankwidth);
-		while (len && i < map->bankwidth)
-			tmp_buf[i++] = buf[n++], len--;
-
-		if (map->bankwidth == 2)
-			datum = *(__u16 *)tmp_buf;
-		else if (map->bankwidth == 4)
-			datum = *(__u32 *)tmp_buf;
-		else
-			return -EINVAL;
-
-		ret = write_one_word(map, &private->chip, bus_offset,
-				datum);
-
-		if (ret)
-			return ret;
-
-		offset += n;
-		buf += n;
-		(*retlen) += n;
-
-		if (offset >> private->chipshift)
-			return 0;
-	}
-
-	/* We are now aligned, write as much as possible. */
-	while (len >= map->bankwidth) {
-		unsigned long datum;
-
-		if (map->bankwidth == 1)
-			datum = *(unsigned char *)buf;
-		else if (map->bankwidth == 2)
-			datum = *(unsigned short *)buf;
-		else if (map->bankwidth == 4)
-			datum = *(unsigned long *)buf;
-		else
-			return -EINVAL;
-
-		ret = write_one_word(map, &private->chip, offset,
-				datum);
-
-		if (ret)
-			return ret;
-
-		offset += map->bankwidth;
-		buf += map->bankwidth;
-		(*retlen) += map->bankwidth;
-		len -= map->bankwidth;
-
-		if (offset >> private->chipshift)
-			return 0;
-	}
-
-	if (len & (map->bankwidth - 1)) {
-		int i = 0, n = 0;
-		unsigned char tmp_buf[2];
-		unsigned long datum;
-
-		map_copy_from(map, tmp_buf,
-				offset + private->chip.start,
-				map->bankwidth);
-
-		while (len--)
-			tmp_buf[i++] = buf[n++];
-
-		if (map->bankwidth == 2)
-			datum = *(unsigned short *)tmp_buf;
-		else if (map->bankwidth == 4)
-			datum = *(unsigned long *)tmp_buf;
-		else
-			return -EINVAL;
-
-		ret = write_one_word(map, &private->chip, offset,
-				datum);
-
-		if (ret)
-			return ret;
-
-		(*retlen) += n;
-	}
-
-	return 0;
-}
-
-static int erase_one_block(struct map_info *map, struct flchip *chip,
-			   unsigned long addr, unsigned long size)
-{
-	unsigned long timeo = jiffies + HZ;
-	DECLARE_WAITQUEUE(wait, current);
-
- retry:
-	spin_lock_bh(chip->mutex);
-
-	if (chip->state != FL_READY) {
-		set_current_state(TASK_UNINTERRUPTIBLE);
-		add_wait_queue(&chip->wq, &wait);
-
-		spin_unlock_bh(chip->mutex);
-
-		schedule();
-		remove_wait_queue(&chip->wq, &wait);
-
-		if (signal_pending(current))
-			return -EINTR;
-
-		timeo = jiffies + HZ;
-
-		goto retry;
-	}
-
-	chip->state = FL_ERASING;
-
-	addr += chip->start;
-
-	send_cmd(map, chip->start, CMD_SECTOR_ERASE_UNLOCK_DATA);
-	send_cmd_to_addr(map, chip->start, CMD_SECTOR_ERASE_UNLOCK_DATA_2, addr);
-
-	timeo = jiffies + (HZ * 20);
-
-	spin_unlock_bh(chip->mutex);
-	schedule_timeout(HZ);
-	spin_lock_bh(chip->mutex);
-
-	while (flash_is_busy(map, chip->start)) {
-		if (chip->state != FL_ERASING) {
-			/* Someone's suspended the erase. Sleep. */
-			set_current_state(TASK_UNINTERRUPTIBLE);
-			add_wait_queue(&chip->wq, &wait);
-
-			spin_unlock_bh(chip->mutex);
-			pr_info("erase suspended, sleeping\n");
-			schedule();
-			remove_wait_queue(&chip->wq, &wait);
-
-			if (signal_pending(current))
-				return -EINTR;
-
-			timeo = jiffies + (HZ*2);
-			spin_lock_bh(chip->mutex);
-			continue;
-		}
-
-		/* OK Still waiting */
-		if (time_after(jiffies, timeo)) {
-			chip->state = FL_READY;
-			spin_unlock_bh(chip->mutex);
-			pr_warning("waiting for erase to complete timed out\n");
-			return -EIO;
-		}
-
-		/* Latency issues. Drop the lock, wait a while, and retry. */
-		spin_unlock_bh(chip->mutex);
-
-		if (need_resched())
-			schedule();
-		else
-			udelay(1);
-
-		spin_lock_bh(chip->mutex);
-	}
-
-	{
-		/* Verify every single word */
-		int address;
-		int error = 0;
-		int verify;
-		map_word test;
-
-		for (address = addr; address < (addr + size); address += 2) {
-			test = map_read(map, address);
-			verify = test.x[0];
-			if (verify != 0xFFFF) {
-				error = 1;
-				break;
-			}
-		}
-
-		if (error) {
-			chip->state = FL_READY;
-			spin_unlock_bh(chip->mutex);
-			pr_warning("verify error at 0x%x, size %ld\n",
-				   address, size);
-			return -EIO;
-		}
-	}
-
-	chip->state = FL_READY;
-	wake_up(&chip->wq);
-	spin_unlock_bh(chip->mutex);
-
-	return 0;
-}
-
-static int stm_flash_erase(struct mtd_info *mtd, struct erase_info *instr)
-{
-	struct map_info *map = mtd->priv;
-	struct stm_flash_private *private = map->fldrv_priv;
-	unsigned long addr, len, shift;
-	int chipnum;
-	int ret = 0;
-	int i, first;
-	struct mtd_erase_region_info *regions = mtd->eraseregions;
-
-	if (instr->addr > mtd->size)
-		return -EINVAL;
-
-	if ((instr->len + instr->addr) > mtd->size)
-		return -EINVAL;
-
-	/*
-	 * Check that both start and end of the requested erase are aligned
-	 * with the erasesize at the appropriate addresses.
-	 */
-	i = 0;
-
-	/*
-	 * Skip all erase regions which are ended before the start of the
-	 * requested erase. Actually, to save on the calculations, we skip
-	 * to the first erase region which starts after the start of the
-	 * requested erase, and then go back one.
-	 */
-	while ((i < mtd->numeraseregions) &&
-	       (instr->addr >= regions[i].offset))
-		++i;
-	--i;
-
-	/*
-	 * OK. Now i is pointing at the erase region in which this erase
-	 * request starts. Check the start of the requested erase range
-	 * is aligned with the erase size which is in effect here.
-	 */
-	if (instr->addr & (regions[i].erasesize - 1))
-		return -EINVAL;
-
-	/*
-	 * Remember the erase region we start on.
-	 */
-	first = i;
-
-	/*
-	 * Next, theck that the end of the requested erase is aligned with
-	 * the erase region at that address.
-	 */
-	while ((i < mtd->numeraseregions) &&
-	       ((instr->addr + instr->len) >= regions[i].offset))
-		++i;
-	--i;
-
-	if ((instr->addr + instr->len) & (regions[i].erasesize - 1))
-		return -EINVAL;
-
-	chipnum = instr->addr >> private->chipshift;
-	addr = instr->addr - (chipnum << private->chipshift);
-	len = instr->len;
-
-	i = first;
-	shift = (1 << private->chipshift) - 1;
-	while (len) {
-		ret = erase_one_block(map, &private->chip, addr,
-				regions[i].erasesize);
-
-		if (ret)
-			return ret;
-
-		addr += regions[i].erasesize;
-		len -= regions[i].erasesize;
-
-		if ((addr & shift) ==
-		    ((regions[i].offset +
-		      (regions[i].erasesize * regions[i].numblocks))
-		     & shift))
-			++i;
-
-		if (addr & ~shift)
-			break;
-	}
-
-	instr->state = MTD_ERASE_DONE;
-	if (instr->callback)
-		instr->callback(instr);
-
-	return 0;
-}
-
-static void stm_flash_destroy(struct mtd_info *mtd)
-{
-	struct map_info *map = mtd->priv;
-	struct stm_flash_private *private = map->fldrv_priv;
-	kfree(private);
-}
-
-struct stm_flash_info {
-	u8 mfr_id, dev_id;
-	char *name;
-	unsigned long size;
-	int numeraseregions;
-	struct mtd_erase_region_info regions[1];
-};
-
-const struct stm_flash_info stm_data[] = {
-	{
-		.mfr_id = 0x20,
-		.dev_id = 0xe9,
-		.name   = "STM PSD4256G6V",
-		.size   = 0x100000,
-		.numeraseregions = 1,
-		.regions = {
-			{
-				.offset    = 0x000000,
-				.erasesize = 0x10000,
-				.numblocks = 16
-			},
-		},
-	},
-};
-
-static int stm_probe_new_chip(struct mtd_info *mtd)
-{
-	const struct stm_flash_info *std;
-	struct map_info *map = mtd->priv;
-	int i;
-	u8 mfr_id, dev_id;
-	map_word mfr_word, dev_word;
-
-	/* Enter autoselect mode */
-	send_cmd(map, 0, CMD_RESET_DATA);
-	send_cmd(map, 0, CMD_MANUFACTURER_UNLOCK_DATA);
-
-	mfr_word = map_read(map, ADDR_MANUFACTURER);
-	dev_word = map_read(map, ADDR_DEVICE_ID);
-	mfr_id = mfr_word.x[0] & 0xFF;
-	dev_id = dev_word.x[0] & 0xFF;
-
-	/* Exit autoselect mode */
-	send_cmd(map, 0, CMD_RESET_DATA);
-
-	for (i = 0; i < ARRAY_SIZE(stm_data); ++i) {
-		std = &stm_data[i];
-		if (mfr_id == std->mfr_id && dev_id == std->dev_id)
-			break;
-	}
-	if (i == ARRAY_SIZE(stm_data)) {
-		pr_warning("unknown mfr/dev id: 0x%02x 0x%02x\n", mfr_id, dev_id);
-		return 1;
-	}
-
-	mtd->size += std->size;
-	mtd->numeraseregions += std->numeraseregions;
-
-	mtd->eraseregions = kmalloc(sizeof(*mtd->eraseregions) *
-				    mtd->numeraseregions, GFP_KERNEL);
-	if (!mtd->eraseregions) {
-		pr_warning("failed to allocate memory for MTD erase region\n");
-		return 1;
-	}
-
-	for (i = 0; i < std->numeraseregions; ++i) {
-		mtd->eraseregions[i].offset    = std->regions[i].offset;
-		mtd->eraseregions[i].erasesize = std->regions[i].erasesize;
-		mtd->eraseregions[i].numblocks = std->regions[i].numblocks;
-		if (mtd->erasesize < mtd->eraseregions[i].erasesize)
-			mtd->erasesize = mtd->eraseregions[i].erasesize;
-	}
-
-	pr_info("found %s device at %p in %d-bit bank\n",
-	        std->name, map->virt, map->bankwidth * 8);
-
-	return 0;
-}
-
-static struct mtd_info *stm_flash_probe(struct map_info *map);
-
-static struct mtd_chip_driver stm_flash_chipdrv = {
-	.probe   = stm_flash_probe,
-	.destroy = stm_flash_destroy,
-	.name    = "stm_flash",
-	.module  = THIS_MODULE
-};
-
-static struct mtd_info *stm_flash_probe(struct map_info *map)
-{
-	struct mtd_info *mtd;
-	struct flchip *chip;
-	struct stm_flash_private *private;
-	unsigned long size;
-
-	mtd = kzalloc(sizeof(*mtd) + sizeof(*private), GFP_KERNEL);
-	if (!mtd) {
-		pr_warning("kmalloc failed for info structure\n");
-		return NULL;
-	}
-	mtd->priv = map;
-	map->fldrv_priv = private = (void *)&mtd[1];
-	map->fldrv = &stm_flash_chipdrv;
-
-	if (stm_probe_new_chip(mtd)) {
-		kfree(mtd);
-		return NULL;
-	}
-
-	chip = &private->chip;
-	init_waitqueue_head(&chip->wq);
-	spin_lock_init(&chip->_spinlock);
-	chip->start = 0;
-	chip->state = FL_READY;
-	chip->mutex = &chip->_spinlock;
-	for (size = mtd->size; size > 1; size >>= 1)
-		++private->chipshift;
-
-	mtd->type  = MTD_NORFLASH;
-	mtd->flags = MTD_CAP_NORFLASH;
-	mtd->name  = map->name;
-	mtd->erase = stm_flash_erase;
-	mtd->read  = stm_flash_read;
-	mtd->write = stm_flash_write;
-	mtd->sync  = stm_flash_sync;
-	mtd->writesize = 1;
-
-	return mtd;
-}
-
-static int __init stm_flash_init(void)
-{
-	register_mtd_chip_driver(&stm_flash_chipdrv);
-	return 0;
-}
-module_init(stm_flash_init);
-
-static void __exit stm_flash_exit(void)
-{
-	unregister_mtd_chip_driver(&stm_flash_chipdrv);
-}
-module_exit(stm_flash_exit);
-
-MODULE_DESCRIPTION("MTD chip driver for ST PSD4256G flashes");
-MODULE_LICENSE("GPL");
_______________________________________________
Linux-kernel-commits mailing list
[email protected]
https://blackfin.uclinux.org/mailman/listinfo/linux-kernel-commits

Reply via email to