aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/mtd
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/mtd')
-rw-r--r--drivers/mtd/chips/gen_probe.c8
-rw-r--r--drivers/mtd/maps/Kconfig2
-rw-r--r--drivers/mtd/mtd_blkdevs.c9
-rw-r--r--drivers/mtd/mtdblock.c4
-rw-r--r--drivers/mtd/mtdchar.c59
-rw-r--r--drivers/mtd/mtdcore.c1
-rw-r--r--drivers/mtd/nand/Kconfig2
-rw-r--r--drivers/mtd/nand/gpmi-nand/gpmi-nand.c51
-rw-r--r--drivers/mtd/nand/gpmi-nand/gpmi-nand.h3
-rw-r--r--drivers/mtd/onenand/samsung.c4
-rw-r--r--drivers/mtd/onenand/samsung.h61
-rw-r--r--drivers/mtd/sm_ftl.c3
12 files changed, 81 insertions, 126 deletions
diff --git a/drivers/mtd/chips/gen_probe.c b/drivers/mtd/chips/gen_probe.c
index 3b9a2843c5f8..74dbb6bcf488 100644
--- a/drivers/mtd/chips/gen_probe.c
+++ b/drivers/mtd/chips/gen_probe.c
@@ -204,14 +204,16 @@ static inline struct mtd_info *cfi_cmdset_unknown(struct map_info *map,
204 struct cfi_private *cfi = map->fldrv_priv; 204 struct cfi_private *cfi = map->fldrv_priv;
205 __u16 type = primary?cfi->cfiq->P_ID:cfi->cfiq->A_ID; 205 __u16 type = primary?cfi->cfiq->P_ID:cfi->cfiq->A_ID;
206#ifdef CONFIG_MODULES 206#ifdef CONFIG_MODULES
207 char probename[16+sizeof(MODULE_SYMBOL_PREFIX)]; 207 char probename[sizeof(VMLINUX_SYMBOL_STR(cfi_cmdset_%4.4X))];
208 cfi_cmdset_fn_t *probe_function; 208 cfi_cmdset_fn_t *probe_function;
209 209
210 sprintf(probename, MODULE_SYMBOL_PREFIX "cfi_cmdset_%4.4X", type); 210 sprintf(probename, VMLINUX_SYMBOL_STR(cfi_cmdset_%4.4X), type);
211 211
212 probe_function = __symbol_get(probename); 212 probe_function = __symbol_get(probename);
213 if (!probe_function) { 213 if (!probe_function) {
214 request_module(probename + sizeof(MODULE_SYMBOL_PREFIX) - 1); 214 char modname[sizeof("cfi_cmdset_%4.4X")];
215 sprintf(modname, "cfi_cmdset_%4.4X", type);
216 request_module(modname);
215 probe_function = __symbol_get(probename); 217 probe_function = __symbol_get(probename);
216 } 218 }
217 219
diff --git a/drivers/mtd/maps/Kconfig b/drivers/mtd/maps/Kconfig
index bed9634026ce..bed9d58d5741 100644
--- a/drivers/mtd/maps/Kconfig
+++ b/drivers/mtd/maps/Kconfig
@@ -351,7 +351,7 @@ config MTD_BFIN_ASYNC
351 351
352config MTD_GPIO_ADDR 352config MTD_GPIO_ADDR
353 tristate "GPIO-assisted Flash Chip Support" 353 tristate "GPIO-assisted Flash Chip Support"
354 depends on GENERIC_GPIO || GPIOLIB 354 depends on GPIOLIB
355 depends on MTD_COMPLEX_MAPPINGS 355 depends on MTD_COMPLEX_MAPPINGS
356 help 356 help
357 Map driver which allows flashes to be partially physically addressed 357 Map driver which allows flashes to be partially physically addressed
diff --git a/drivers/mtd/mtd_blkdevs.c b/drivers/mtd/mtd_blkdevs.c
index 5ad39bb5ab4c..5073cbc796d8 100644
--- a/drivers/mtd/mtd_blkdevs.c
+++ b/drivers/mtd/mtd_blkdevs.c
@@ -237,13 +237,12 @@ error_put:
237 return ret; 237 return ret;
238} 238}
239 239
240static int blktrans_release(struct gendisk *disk, fmode_t mode) 240static void blktrans_release(struct gendisk *disk, fmode_t mode)
241{ 241{
242 struct mtd_blktrans_dev *dev = blktrans_dev_get(disk); 242 struct mtd_blktrans_dev *dev = blktrans_dev_get(disk);
243 int ret = 0;
244 243
245 if (!dev) 244 if (!dev)
246 return ret; 245 return;
247 246
248 mutex_lock(&dev->lock); 247 mutex_lock(&dev->lock);
249 248
@@ -254,13 +253,13 @@ static int blktrans_release(struct gendisk *disk, fmode_t mode)
254 module_put(dev->tr->owner); 253 module_put(dev->tr->owner);
255 254
256 if (dev->mtd) { 255 if (dev->mtd) {
257 ret = dev->tr->release ? dev->tr->release(dev) : 0; 256 if (dev->tr->release)
257 dev->tr->release(dev);
258 __put_mtd_device(dev->mtd); 258 __put_mtd_device(dev->mtd);
259 } 259 }
260unlock: 260unlock:
261 mutex_unlock(&dev->lock); 261 mutex_unlock(&dev->lock);
262 blktrans_dev_put(dev); 262 blktrans_dev_put(dev);
263 return ret;
264} 263}
265 264
266static int blktrans_getgeo(struct block_device *bdev, struct hd_geometry *geo) 265static int blktrans_getgeo(struct block_device *bdev, struct hd_geometry *geo)
diff --git a/drivers/mtd/mtdblock.c b/drivers/mtd/mtdblock.c
index 6c6d80736fad..2aef5dda522b 100644
--- a/drivers/mtd/mtdblock.c
+++ b/drivers/mtd/mtdblock.c
@@ -308,7 +308,7 @@ static int mtdblock_open(struct mtd_blktrans_dev *mbd)
308 return 0; 308 return 0;
309} 309}
310 310
311static int mtdblock_release(struct mtd_blktrans_dev *mbd) 311static void mtdblock_release(struct mtd_blktrans_dev *mbd)
312{ 312{
313 struct mtdblk_dev *mtdblk = container_of(mbd, struct mtdblk_dev, mbd); 313 struct mtdblk_dev *mtdblk = container_of(mbd, struct mtdblk_dev, mbd);
314 314
@@ -333,8 +333,6 @@ static int mtdblock_release(struct mtd_blktrans_dev *mbd)
333 mutex_unlock(&mtdblks_lock); 333 mutex_unlock(&mtdblks_lock);
334 334
335 pr_debug("ok\n"); 335 pr_debug("ok\n");
336
337 return 0;
338} 336}
339 337
340static int mtdblock_flush(struct mtd_blktrans_dev *dev) 338static int mtdblock_flush(struct mtd_blktrans_dev *dev)
diff --git a/drivers/mtd/mtdchar.c b/drivers/mtd/mtdchar.c
index e0e59bf9b915..c719879284bd 100644
--- a/drivers/mtd/mtdchar.c
+++ b/drivers/mtd/mtdchar.c
@@ -1121,33 +1121,6 @@ static unsigned long mtdchar_get_unmapped_area(struct file *file,
1121} 1121}
1122#endif 1122#endif
1123 1123
1124static inline unsigned long get_vm_size(struct vm_area_struct *vma)
1125{
1126 return vma->vm_end - vma->vm_start;
1127}
1128
1129static inline resource_size_t get_vm_offset(struct vm_area_struct *vma)
1130{
1131 return (resource_size_t) vma->vm_pgoff << PAGE_SHIFT;
1132}
1133
1134/*
1135 * Set a new vm offset.
1136 *
1137 * Verify that the incoming offset really works as a page offset,
1138 * and that the offset and size fit in a resource_size_t.
1139 */
1140static inline int set_vm_offset(struct vm_area_struct *vma, resource_size_t off)
1141{
1142 pgoff_t pgoff = off >> PAGE_SHIFT;
1143 if (off != (resource_size_t) pgoff << PAGE_SHIFT)
1144 return -EINVAL;
1145 if (off + get_vm_size(vma) - 1 < off)
1146 return -EINVAL;
1147 vma->vm_pgoff = pgoff;
1148 return 0;
1149}
1150
1151/* 1124/*
1152 * set up a mapping for shared memory segments 1125 * set up a mapping for shared memory segments
1153 */ 1126 */
@@ -1157,45 +1130,17 @@ static int mtdchar_mmap(struct file *file, struct vm_area_struct *vma)
1157 struct mtd_file_info *mfi = file->private_data; 1130 struct mtd_file_info *mfi = file->private_data;
1158 struct mtd_info *mtd = mfi->mtd; 1131 struct mtd_info *mtd = mfi->mtd;
1159 struct map_info *map = mtd->priv; 1132 struct map_info *map = mtd->priv;
1160 resource_size_t start, off;
1161 unsigned long len, vma_len;
1162 1133
1163 /* This is broken because it assumes the MTD device is map-based 1134 /* This is broken because it assumes the MTD device is map-based
1164 and that mtd->priv is a valid struct map_info. It should be 1135 and that mtd->priv is a valid struct map_info. It should be
1165 replaced with something that uses the mtd_get_unmapped_area() 1136 replaced with something that uses the mtd_get_unmapped_area()
1166 operation properly. */ 1137 operation properly. */
1167 if (0 /*mtd->type == MTD_RAM || mtd->type == MTD_ROM*/) { 1138 if (0 /*mtd->type == MTD_RAM || mtd->type == MTD_ROM*/) {
1168 off = get_vm_offset(vma);
1169 start = map->phys;
1170 len = PAGE_ALIGN((start & ~PAGE_MASK) + map->size);
1171 start &= PAGE_MASK;
1172 vma_len = get_vm_size(vma);
1173
1174 /* Overflow in off+len? */
1175 if (vma_len + off < off)
1176 return -EINVAL;
1177 /* Does it fit in the mapping? */
1178 if (vma_len + off > len)
1179 return -EINVAL;
1180
1181 off += start;
1182 /* Did that overflow? */
1183 if (off < start)
1184 return -EINVAL;
1185 if (set_vm_offset(vma, off) < 0)
1186 return -EINVAL;
1187 vma->vm_flags |= VM_IO | VM_DONTEXPAND | VM_DONTDUMP;
1188
1189#ifdef pgprot_noncached 1139#ifdef pgprot_noncached
1190 if (file->f_flags & O_DSYNC || off >= __pa(high_memory)) 1140 if (file->f_flags & O_DSYNC || map->phys >= __pa(high_memory))
1191 vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot); 1141 vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot);
1192#endif 1142#endif
1193 if (io_remap_pfn_range(vma, vma->vm_start, off >> PAGE_SHIFT, 1143 return vm_iomap_memory(vma, map->phys, map->size);
1194 vma->vm_end - vma->vm_start,
1195 vma->vm_page_prot))
1196 return -EAGAIN;
1197
1198 return 0;
1199 } 1144 }
1200 return -ENOSYS; 1145 return -ENOSYS;
1201#else 1146#else
diff --git a/drivers/mtd/mtdcore.c b/drivers/mtd/mtdcore.c
index 71877ff77cbf..c400c57c394a 100644
--- a/drivers/mtd/mtdcore.c
+++ b/drivers/mtd/mtdcore.c
@@ -36,6 +36,7 @@
36#include <linux/idr.h> 36#include <linux/idr.h>
37#include <linux/backing-dev.h> 37#include <linux/backing-dev.h>
38#include <linux/gfp.h> 38#include <linux/gfp.h>
39#include <linux/slab.h>
39 40
40#include <linux/mtd/mtd.h> 41#include <linux/mtd/mtd.h>
41#include <linux/mtd/partitions.h> 42#include <linux/mtd/partitions.h>
diff --git a/drivers/mtd/nand/Kconfig b/drivers/mtd/nand/Kconfig
index 1cca71208340..a60f6c17f57b 100644
--- a/drivers/mtd/nand/Kconfig
+++ b/drivers/mtd/nand/Kconfig
@@ -75,7 +75,7 @@ config MTD_NAND_DENALI_SCRATCH_REG_ADDR
75 75
76config MTD_NAND_GPIO 76config MTD_NAND_GPIO
77 tristate "GPIO NAND Flash driver" 77 tristate "GPIO NAND Flash driver"
78 depends on GENERIC_GPIO && ARM 78 depends on GPIOLIB && ARM
79 help 79 help
80 This enables a GPIO based NAND flash driver. 80 This enables a GPIO based NAND flash driver.
81 81
diff --git a/drivers/mtd/nand/gpmi-nand/gpmi-nand.c b/drivers/mtd/nand/gpmi-nand/gpmi-nand.c
index 717881a3d1b8..25ecfa1822a8 100644
--- a/drivers/mtd/nand/gpmi-nand/gpmi-nand.c
+++ b/drivers/mtd/nand/gpmi-nand/gpmi-nand.c
@@ -36,7 +36,6 @@
36#define GPMI_NAND_GPMI_REGS_ADDR_RES_NAME "gpmi-nand" 36#define GPMI_NAND_GPMI_REGS_ADDR_RES_NAME "gpmi-nand"
37#define GPMI_NAND_BCH_REGS_ADDR_RES_NAME "bch" 37#define GPMI_NAND_BCH_REGS_ADDR_RES_NAME "bch"
38#define GPMI_NAND_BCH_INTERRUPT_RES_NAME "bch" 38#define GPMI_NAND_BCH_INTERRUPT_RES_NAME "bch"
39#define GPMI_NAND_DMA_INTERRUPT_RES_NAME "gpmi-dma"
40 39
41/* add our owner bbt descriptor */ 40/* add our owner bbt descriptor */
42static uint8_t scan_ff_pattern[] = { 0xff }; 41static uint8_t scan_ff_pattern[] = { 0xff };
@@ -420,28 +419,6 @@ static void release_bch_irq(struct gpmi_nand_data *this)
420 free_irq(i, this); 419 free_irq(i, this);
421} 420}
422 421
423static bool gpmi_dma_filter(struct dma_chan *chan, void *param)
424{
425 struct gpmi_nand_data *this = param;
426 int dma_channel = (int)this->private;
427
428 if (!mxs_dma_is_apbh(chan))
429 return false;
430 /*
431 * only catch the GPMI dma channels :
432 * for mx23 : MX23_DMA_GPMI0 ~ MX23_DMA_GPMI3
433 * (These four channels share the same IRQ!)
434 *
435 * for mx28 : MX28_DMA_GPMI0 ~ MX28_DMA_GPMI7
436 * (These eight channels share the same IRQ!)
437 */
438 if (dma_channel == chan->chan_id) {
439 chan->private = &this->dma_data;
440 return true;
441 }
442 return false;
443}
444
445static void release_dma_channels(struct gpmi_nand_data *this) 422static void release_dma_channels(struct gpmi_nand_data *this)
446{ 423{
447 unsigned int i; 424 unsigned int i;
@@ -455,36 +432,10 @@ static void release_dma_channels(struct gpmi_nand_data *this)
455static int acquire_dma_channels(struct gpmi_nand_data *this) 432static int acquire_dma_channels(struct gpmi_nand_data *this)
456{ 433{
457 struct platform_device *pdev = this->pdev; 434 struct platform_device *pdev = this->pdev;
458 struct resource *r_dma;
459 struct device_node *dn;
460 u32 dma_channel;
461 int ret;
462 struct dma_chan *dma_chan; 435 struct dma_chan *dma_chan;
463 dma_cap_mask_t mask;
464
465 /* dma channel, we only use the first one. */
466 dn = pdev->dev.of_node;
467 ret = of_property_read_u32(dn, "fsl,gpmi-dma-channel", &dma_channel);
468 if (ret) {
469 pr_err("unable to get DMA channel from dt.\n");
470 goto acquire_err;
471 }
472 this->private = (void *)dma_channel;
473
474 /* gpmi dma interrupt */
475 r_dma = platform_get_resource_byname(pdev, IORESOURCE_IRQ,
476 GPMI_NAND_DMA_INTERRUPT_RES_NAME);
477 if (!r_dma) {
478 pr_err("Can't get resource for DMA\n");
479 goto acquire_err;
480 }
481 this->dma_data.chan_irq = r_dma->start;
482 436
483 /* request dma channel */ 437 /* request dma channel */
484 dma_cap_zero(mask); 438 dma_chan = dma_request_slave_channel(&pdev->dev, "rx-tx");
485 dma_cap_set(DMA_SLAVE, mask);
486
487 dma_chan = dma_request_channel(mask, gpmi_dma_filter, this);
488 if (!dma_chan) { 439 if (!dma_chan) {
489 pr_err("Failed to request DMA channel.\n"); 440 pr_err("Failed to request DMA channel.\n");
490 goto acquire_err; 441 goto acquire_err;
diff --git a/drivers/mtd/nand/gpmi-nand/gpmi-nand.h b/drivers/mtd/nand/gpmi-nand/gpmi-nand.h
index 072947731277..a7685e3a8748 100644
--- a/drivers/mtd/nand/gpmi-nand/gpmi-nand.h
+++ b/drivers/mtd/nand/gpmi-nand/gpmi-nand.h
@@ -20,7 +20,7 @@
20#include <linux/mtd/nand.h> 20#include <linux/mtd/nand.h>
21#include <linux/platform_device.h> 21#include <linux/platform_device.h>
22#include <linux/dma-mapping.h> 22#include <linux/dma-mapping.h>
23#include <linux/fsl/mxs-dma.h> 23#include <linux/dmaengine.h>
24 24
25#define GPMI_CLK_MAX 5 /* MX6Q needs five clocks */ 25#define GPMI_CLK_MAX 5 /* MX6Q needs five clocks */
26struct resources { 26struct resources {
@@ -180,7 +180,6 @@ struct gpmi_nand_data {
180 /* DMA channels */ 180 /* DMA channels */
181#define DMA_CHANS 8 181#define DMA_CHANS 8
182 struct dma_chan *dma_chans[DMA_CHANS]; 182 struct dma_chan *dma_chans[DMA_CHANS];
183 struct mxs_dma_data dma_data;
184 enum dma_ops_type last_dma_type; 183 enum dma_ops_type last_dma_type;
185 enum dma_ops_type dma_type; 184 enum dma_ops_type dma_type;
186 struct completion dma_done; 185 struct completion dma_done;
diff --git a/drivers/mtd/onenand/samsung.c b/drivers/mtd/onenand/samsung.c
index 33f2a8fb8df9..2cf74085f935 100644
--- a/drivers/mtd/onenand/samsung.c
+++ b/drivers/mtd/onenand/samsung.c
@@ -23,11 +23,11 @@
23#include <linux/mtd/partitions.h> 23#include <linux/mtd/partitions.h>
24#include <linux/dma-mapping.h> 24#include <linux/dma-mapping.h>
25#include <linux/interrupt.h> 25#include <linux/interrupt.h>
26#include <linux/io.h>
26 27
27#include <asm/mach/flash.h> 28#include <asm/mach/flash.h>
28#include <plat/regs-onenand.h>
29 29
30#include <linux/io.h> 30#include "samsung.h"
31 31
32enum soc_type { 32enum soc_type {
33 TYPE_S3C6400, 33 TYPE_S3C6400,
diff --git a/drivers/mtd/onenand/samsung.h b/drivers/mtd/onenand/samsung.h
new file mode 100644
index 000000000000..c4a80e67e438
--- /dev/null
+++ b/drivers/mtd/onenand/samsung.h
@@ -0,0 +1,61 @@
1/*
2 * linux/arch/arm/plat-s3c/include/plat/regs-onenand.h
3 *
4 * Copyright (C) 2008-2010 Samsung Electronics
5 * Kyungmin Park <kyungmin.park@samsung.com>
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License version 2 as
9 * published by the Free Software Foundation.
10 */
11#ifndef __SAMSUNG_ONENAND_H__
12#define __SAMSUNG_ONENAND_H__
13
14/*
15 * OneNAND Controller
16 */
17#define MEM_CFG_OFFSET 0x0000
18#define BURST_LEN_OFFSET 0x0010
19#define MEM_RESET_OFFSET 0x0020
20#define INT_ERR_STAT_OFFSET 0x0030
21#define INT_ERR_MASK_OFFSET 0x0040
22#define INT_ERR_ACK_OFFSET 0x0050
23#define ECC_ERR_STAT_OFFSET 0x0060
24#define MANUFACT_ID_OFFSET 0x0070
25#define DEVICE_ID_OFFSET 0x0080
26#define DATA_BUF_SIZE_OFFSET 0x0090
27#define BOOT_BUF_SIZE_OFFSET 0x00A0
28#define BUF_AMOUNT_OFFSET 0x00B0
29#define TECH_OFFSET 0x00C0
30#define FBA_WIDTH_OFFSET 0x00D0
31#define FPA_WIDTH_OFFSET 0x00E0
32#define FSA_WIDTH_OFFSET 0x00F0
33#define TRANS_SPARE_OFFSET 0x0140
34#define DBS_DFS_WIDTH_OFFSET 0x0160
35#define INT_PIN_ENABLE_OFFSET 0x01A0
36#define ACC_CLOCK_OFFSET 0x01C0
37#define FLASH_VER_ID_OFFSET 0x01F0
38#define FLASH_AUX_CNTRL_OFFSET 0x0300 /* s3c64xx only */
39
40#define ONENAND_MEM_RESET_HOT 0x3
41#define ONENAND_MEM_RESET_COLD 0x2
42#define ONENAND_MEM_RESET_WARM 0x1
43
44#define CACHE_OP_ERR (1 << 13)
45#define RST_CMP (1 << 12)
46#define RDY_ACT (1 << 11)
47#define INT_ACT (1 << 10)
48#define UNSUP_CMD (1 << 9)
49#define LOCKED_BLK (1 << 8)
50#define BLK_RW_CMP (1 << 7)
51#define ERS_CMP (1 << 6)
52#define PGM_CMP (1 << 5)
53#define LOAD_CMP (1 << 4)
54#define ERS_FAIL (1 << 3)
55#define PGM_FAIL (1 << 2)
56#define INT_TO (1 << 1)
57#define LD_FAIL_ECC_ERR (1 << 0)
58
59#define TSRF (1 << 0)
60
61#endif
diff --git a/drivers/mtd/sm_ftl.c b/drivers/mtd/sm_ftl.c
index 8dd6ba52404a..f9d5615c5727 100644
--- a/drivers/mtd/sm_ftl.c
+++ b/drivers/mtd/sm_ftl.c
@@ -1107,7 +1107,7 @@ static int sm_flush(struct mtd_blktrans_dev *dev)
1107} 1107}
1108 1108
1109/* outside interface: device is released */ 1109/* outside interface: device is released */
1110static int sm_release(struct mtd_blktrans_dev *dev) 1110static void sm_release(struct mtd_blktrans_dev *dev)
1111{ 1111{
1112 struct sm_ftl *ftl = dev->priv; 1112 struct sm_ftl *ftl = dev->priv;
1113 1113
@@ -1116,7 +1116,6 @@ static int sm_release(struct mtd_blktrans_dev *dev)
1116 cancel_work_sync(&ftl->flush_work); 1116 cancel_work_sync(&ftl->flush_work);
1117 sm_cache_flush(ftl); 1117 sm_cache_flush(ftl);
1118 mutex_unlock(&ftl->mutex); 1118 mutex_unlock(&ftl->mutex);
1119 return 0;
1120} 1119}
1121 1120
1122/* outside interface: get geometry */ 1121/* outside interface: get geometry */