Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
gsplhtlxg
clone-Linux
提交
f0250fd7
C
clone-Linux
项目概览
gsplhtlxg
/
clone-Linux
通知
2
Star
0
Fork
1
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
0
列表
看板
标记
里程碑
合并请求
0
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
C
clone-Linux
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
0
Issue
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
DevOps
DevOps
流水线
流水线任务
计划
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
流水线任务
提交
Issue看板
体验新版 GitCode,发现更多精彩内容 >>
提交
f0250fd7
编写于
11月 07, 2005
作者:
T
Thomas Gleixner
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
Revert "[PATCH] OneNAND: Add simulator"
This reverts
405c829f
commit.
上级
01ac742d
变更
3
隐藏空白更改
内联
并排
Showing
3 changed file
with
0 addition
and
474 deletion
+0
-474
drivers/mtd/onenand/Kconfig
drivers/mtd/onenand/Kconfig
+0
-7
drivers/mtd/onenand/Makefile
drivers/mtd/onenand/Makefile
+0
-3
drivers/mtd/onenand/onenand_sim.c
drivers/mtd/onenand/onenand_sim.c
+0
-464
未找到文件。
drivers/mtd/onenand/Kconfig
浏览文件 @
f0250fd7
...
...
@@ -36,11 +36,4 @@ config MTD_ONENAND_SYNC_READ
help
This enables support for Sync. Burst Read.
config MTD_ONENAND_SIM
tristate "Support for OneNAND flash simulator"
depends on MTD_ONENAND
help
The simulator may simulate verious OneNAND flash chips for the
MTD onenand layer.
endmenu
drivers/mtd/onenand/Makefile
浏览文件 @
f0250fd7
...
...
@@ -8,7 +8,4 @@ obj-$(CONFIG_MTD_ONENAND) += onenand.o
# Board specific.
obj-$(CONFIG_MTD_ONENAND_GENERIC)
+=
generic.o
# Simulator
obj-$(CONFIG_MTD_ONENAND_SIM)
+=
onenand_sim.o
onenand-objs
=
onenand_base.o onenand_bbt.o
drivers/mtd/onenand/onenand_sim.c
已删除
100644 → 0
浏览文件 @
01ac742d
/*
* linux/drivers/mtd/onenand/simulator.c
*
* The OneNAND simulator
*
* Copyright(c) 2005 Samsung Electronics
* Kyungmin Park <kyungmin.park@samsung.com>
*/
#include <linux/config.h>
#include <linux/module.h>
#include <linux/init.h>
#include <linux/vmalloc.h>
#include <linux/mtd/mtd.h>
#include <linux/mtd/onenand.h>
#include <asm/io.h>
#include <asm/sizes.h>
#ifndef CONFIG_ONENAND_SIM_MANUFACTURER
#define CONFIG_ONENAND_SIM_MANUFACTURER 0xec
#endif
#ifndef CONFIG_ONENAND_SIM_DEVICE_ID
#define CONFIG_ONENAND_SIM_DEVICE_ID 0x04
#endif
#ifndef CONFIG_ONENAND_SIM_VERSION_ID
#define CONFIG_ONENAND_SIM_VERSION_ID 0x1e
#endif
static
int
manuf_id
=
CONFIG_ONENAND_SIM_MANUFACTURER
;
static
int
device_id
=
CONFIG_ONENAND_SIM_DEVICE_ID
;
static
int
version_id
=
CONFIG_ONENAND_SIM_VERSION_ID
;
struct
onenand_flash
{
void
__iomem
*
base
;
void
__iomem
*
data
;
};
#define ONENAND_CORE(flash) (flash->data)
#define ONENAND_MAIN_AREA(this, offset) \
(this->base + ONENAND_DATARAM + offset)
#define ONENAND_SPARE_AREA(this, offset) \
(this->base + ONENAND_SPARERAM + offset)
#define ONENAND_GET_WP_STATUS(this) \
(readw(this->base + ONENAND_REG_WP_STATUS))
#define ONENAND_SET_WP_STATUS(v, this) \
(writew(v, this->base + ONENAND_REG_WP_STATUS))
/* It has all 0xff chars */
static
unsigned
char
*
ffchars
;
/*
* OneNAND simulator mtd
*/
struct
mtd_info
*
onenand_sim
;
/**
* onenand_lock_handle - Handle Lock scheme
* @param this OneNAND device structure
* @param cmd The command to be sent
*
* Send lock command to OneNAND device.
* The lock scheme is depends on chip type.
*/
static
void
onenand_lock_handle
(
struct
onenand_chip
*
this
,
int
cmd
)
{
int
block_lock_scheme
;
int
status
;
status
=
ONENAND_GET_WP_STATUS
(
this
);
block_lock_scheme
=
!
(
this
->
options
&
ONENAND_CONT_LOCK
);
switch
(
cmd
)
{
case
ONENAND_CMD_UNLOCK
:
if
(
block_lock_scheme
)
ONENAND_SET_WP_STATUS
(
ONENAND_WP_US
,
this
);
else
ONENAND_SET_WP_STATUS
(
status
|
ONENAND_WP_US
,
this
);
break
;
case
ONENAND_CMD_LOCK
:
if
(
block_lock_scheme
)
ONENAND_SET_WP_STATUS
(
ONENAND_WP_LS
,
this
);
else
ONENAND_SET_WP_STATUS
(
status
|
ONENAND_WP_LS
,
this
);
break
;
case
ONENAND_CMD_LOCK_TIGHT
:
if
(
block_lock_scheme
)
ONENAND_SET_WP_STATUS
(
ONENAND_WP_LTS
,
this
);
else
ONENAND_SET_WP_STATUS
(
status
|
ONENAND_WP_LTS
,
this
);
break
;
default:
break
;
}
}
/**
* onenand_bootram_handle - Handle BootRAM area
* @param this OneNAND device structure
* @param cmd The command to be sent
*
* Emulate BootRAM area. It is possible to do basic operation using BootRAM.
*/
static
void
onenand_bootram_handle
(
struct
onenand_chip
*
this
,
int
cmd
)
{
switch
(
cmd
)
{
case
ONENAND_CMD_READID
:
writew
(
manuf_id
,
this
->
base
);
writew
(
device_id
,
this
->
base
+
2
);
writew
(
version_id
,
this
->
base
+
4
);
break
;
default:
/* REVIST: Handle other commands */
break
;
}
}
/**
* onenand_update_interrupt - Set interrupt register
* @param this OneNAND device structure
* @param cmd The command to be sent
*
* Update interrupt register. The status is depends on command.
*/
static
void
onenand_update_interrupt
(
struct
onenand_chip
*
this
,
int
cmd
)
{
int
interrupt
=
ONENAND_INT_MASTER
;
switch
(
cmd
)
{
case
ONENAND_CMD_READ
:
case
ONENAND_CMD_READOOB
:
interrupt
|=
ONENAND_INT_READ
;
break
;
case
ONENAND_CMD_PROG
:
case
ONENAND_CMD_PROGOOB
:
interrupt
|=
ONENAND_INT_WRITE
;
break
;
case
ONENAND_CMD_ERASE
:
interrupt
|=
ONENAND_INT_ERASE
;
break
;
case
ONENAND_CMD_RESET
:
interrupt
|=
ONENAND_INT_RESET
;
break
;
default:
break
;
}
writew
(
interrupt
,
this
->
base
+
ONENAND_REG_INTERRUPT
);
}
/**
* onenand_check_overwrite - Check over-write if happend
* @param dest The destination pointer
* @param src The source pointer
* @param count The length to be check
* @return 0 on same, otherwise 1
*
* Compare the source with destination
*/
static
int
onenand_check_overwrite
(
void
*
dest
,
void
*
src
,
size_t
count
)
{
unsigned
int
*
s
=
(
unsigned
int
*
)
src
;
unsigned
int
*
d
=
(
unsigned
int
*
)
dest
;
int
i
;
count
>>=
2
;
for
(
i
=
0
;
i
<
count
;
i
++
)
if
((
*
s
++
^
*
d
++
)
!=
0
)
return
1
;
return
0
;
}
/**
* onenand_data_handle - Handle OneNAND Core and DataRAM
* @param this OneNAND device structure
* @param cmd The command to be sent
* @param dataram Which dataram used
* @param offset The offset to OneNAND Core
*
* Copy data from OneNAND Core to DataRAM (read)
* Copy data from DataRAM to OneNAND Core (write)
* Erase the OneNAND Core (erase)
*/
static
void
onenand_data_handle
(
struct
onenand_chip
*
this
,
int
cmd
,
int
dataram
,
unsigned
int
offset
)
{
struct
onenand_flash
*
flash
=
this
->
priv
;
int
main_offset
,
spare_offset
;
void
__iomem
*
src
;
void
__iomem
*
dest
;
if
(
dataram
)
{
main_offset
=
onenand_sim
->
oobblock
;
spare_offset
=
onenand_sim
->
oobsize
;
}
else
{
main_offset
=
0
;
spare_offset
=
0
;
}
switch
(
cmd
)
{
case
ONENAND_CMD_READ
:
src
=
ONENAND_CORE
(
flash
)
+
offset
;
dest
=
ONENAND_MAIN_AREA
(
this
,
main_offset
);
memcpy
(
dest
,
src
,
onenand_sim
->
oobblock
);
/* Fall through */
case
ONENAND_CMD_READOOB
:
src
=
ONENAND_CORE
(
flash
)
+
this
->
chipsize
+
(
offset
>>
5
);
dest
=
ONENAND_SPARE_AREA
(
this
,
spare_offset
);
memcpy
(
dest
,
src
,
onenand_sim
->
oobsize
);
break
;
case
ONENAND_CMD_PROG
:
src
=
ONENAND_MAIN_AREA
(
this
,
main_offset
);
dest
=
ONENAND_CORE
(
flash
)
+
offset
;
if
(
memcmp
(
dest
,
ffchars
,
onenand_sim
->
oobblock
)
&&
onenand_check_overwrite
(
dest
,
src
,
onenand_sim
->
oobblock
))
printk
(
KERN_ERR
"over-write happend at 0x%08x
\n
"
,
offset
);
memcpy
(
dest
,
src
,
onenand_sim
->
oobblock
);
/* Fall through */
case
ONENAND_CMD_PROGOOB
:
src
=
ONENAND_SPARE_AREA
(
this
,
spare_offset
);
/* Check all data is 0xff chars */
if
(
!
memcmp
(
src
,
ffchars
,
onenand_sim
->
oobsize
))
break
;
dest
=
ONENAND_CORE
(
flash
)
+
this
->
chipsize
+
(
offset
>>
5
);
if
(
memcmp
(
dest
,
ffchars
,
onenand_sim
->
oobsize
)
&&
onenand_check_overwrite
(
dest
,
src
,
onenand_sim
->
oobsize
))
printk
(
KERN_ERR
"OOB: over-write happend at 0x%08x
\n
"
,
offset
);
memcpy
(
dest
,
src
,
onenand_sim
->
oobsize
);
break
;
case
ONENAND_CMD_ERASE
:
memset
(
ONENAND_CORE
(
flash
)
+
offset
,
0xff
,
(
1
<<
this
->
erase_shift
));
break
;
default:
break
;
}
}
/**
* onenand_command_handle - Handle command
* @param this OneNAND device structure
* @param cmd The command to be sent
*
* Emulate OneNAND command.
*/
static
void
onenand_command_handle
(
struct
onenand_chip
*
this
,
int
cmd
)
{
unsigned
long
offset
=
0
;
int
block
=
-
1
,
page
=
-
1
,
bufferram
=
-
1
;
int
dataram
=
0
;
switch
(
cmd
)
{
case
ONENAND_CMD_UNLOCK
:
case
ONENAND_CMD_LOCK
:
case
ONENAND_CMD_LOCK_TIGHT
:
onenand_lock_handle
(
this
,
cmd
);
break
;
case
ONENAND_CMD_BUFFERRAM
:
/* Do nothing */
return
;
default:
block
=
(
int
)
readw
(
this
->
base
+
ONENAND_REG_START_ADDRESS1
);
if
(
block
&
(
1
<<
ONENAND_DDP_SHIFT
))
{
block
&=
~
(
1
<<
ONENAND_DDP_SHIFT
);
/* The half of chip block */
block
+=
this
->
chipsize
>>
(
this
->
erase_shift
+
1
);
}
if
(
cmd
==
ONENAND_CMD_ERASE
)
break
;
page
=
(
int
)
readw
(
this
->
base
+
ONENAND_REG_START_ADDRESS8
);
page
=
(
page
>>
ONENAND_FPA_SHIFT
);
bufferram
=
(
int
)
readw
(
this
->
base
+
ONENAND_REG_START_BUFFER
);
bufferram
>>=
ONENAND_BSA_SHIFT
;
bufferram
&=
ONENAND_BSA_DATARAM1
;
dataram
=
(
bufferram
==
ONENAND_BSA_DATARAM1
)
?
1
:
0
;
break
;
}
if
(
block
!=
-
1
)
offset
+=
block
<<
this
->
erase_shift
;
if
(
page
!=
-
1
)
offset
+=
page
<<
this
->
page_shift
;
onenand_data_handle
(
this
,
cmd
,
dataram
,
offset
);
onenand_update_interrupt
(
this
,
cmd
);
}
/**
* onenand_writew - [OneNAND Interface] Emulate write operation
* @param value value to write
* @param addr address to write
*
* Write OneNAND reigser with value
*/
static
void
onenand_writew
(
unsigned
short
value
,
void
__iomem
*
addr
)
{
struct
onenand_chip
*
this
=
onenand_sim
->
priv
;
/* BootRAM handling */
if
(
addr
<
this
->
base
+
ONENAND_DATARAM
)
{
onenand_bootram_handle
(
this
,
value
);
return
;
}
/* Command handling */
if
(
addr
==
this
->
base
+
ONENAND_REG_COMMAND
)
onenand_command_handle
(
this
,
value
);
writew
(
value
,
addr
);
}
/**
* flash_init - Initialize OneNAND simulator
* @param flash OneNAND simulaotr data strucutres
*
* Initialize OneNAND simulator.
*/
static
int
__init
flash_init
(
struct
onenand_flash
*
flash
)
{
int
density
,
size
;
int
buffer_size
;
flash
->
base
=
kmalloc
(
SZ_128K
,
GFP_KERNEL
);
if
(
!
flash
->
base
)
{
printk
(
KERN_ERR
"Unalbe to allocate base address.
\n
"
);
return
-
ENOMEM
;
}
memset
(
flash
->
base
,
0
,
SZ_128K
);
density
=
device_id
>>
ONENAND_DEVICE_DENSITY_SHIFT
;
size
=
((
16
<<
20
)
<<
density
);
ONENAND_CORE
(
flash
)
=
vmalloc
(
size
+
(
size
>>
5
));
if
(
!
ONENAND_CORE
(
flash
))
{
printk
(
KERN_ERR
"Unalbe to allocate nand core address.
\n
"
);
kfree
(
flash
->
base
);
return
-
ENOMEM
;
}
memset
(
ONENAND_CORE
(
flash
),
0xff
,
size
+
(
size
>>
5
));
/* Setup registers */
writew
(
manuf_id
,
flash
->
base
+
ONENAND_REG_MANUFACTURER_ID
);
writew
(
device_id
,
flash
->
base
+
ONENAND_REG_DEVICE_ID
);
writew
(
version_id
,
flash
->
base
+
ONENAND_REG_VERSION_ID
);
if
(
density
<
2
)
buffer_size
=
0x0400
;
/* 1KB page */
else
buffer_size
=
0x0800
;
/* 2KB page */
writew
(
buffer_size
,
flash
->
base
+
ONENAND_REG_DATA_BUFFER_SIZE
);
return
0
;
}
/**
* flash_exit - Clean up OneNAND simulator
* @param flash OneNAND simulaotr data strucutres
*
* Clean up OneNAND simulator.
*/
static
void
flash_exit
(
struct
onenand_flash
*
flash
)
{
vfree
(
ONENAND_CORE
(
flash
));
kfree
(
flash
->
base
);
kfree
(
flash
);
}
static
int
__init
onenand_sim_init
(
void
)
{
struct
onenand_chip
*
this
;
struct
onenand_flash
*
flash
;
int
len
;
/* Allocate all 0xff chars pointer */
ffchars
=
kmalloc
(
MAX_ONENAND_PAGESIZE
,
GFP_KERNEL
);
if
(
!
ffchars
)
{
printk
(
KERN_ERR
"Unable to allocate ff chars.
\n
"
);
return
-
ENOMEM
;
}
memset
(
ffchars
,
0xff
,
MAX_ONENAND_PAGESIZE
);
len
=
sizeof
(
struct
mtd_info
)
+
sizeof
(
struct
onenand_chip
)
+
sizeof
(
struct
onenand_flash
);
/* Allocate OneNAND simulator mtd pointer */
onenand_sim
=
kmalloc
(
len
,
GFP_KERNEL
);
if
(
!
onenand_sim
)
{
printk
(
KERN_ERR
"Unable to allocate core structures.
\n
"
);
kfree
(
ffchars
);
return
-
ENOMEM
;
}
memset
(
onenand_sim
,
0
,
len
);
this
=
(
struct
onenand_chip
*
)
(
onenand_sim
+
1
);
/* Override write_word function */
this
->
write_word
=
onenand_writew
;
flash
=
(
struct
onenand_flash
*
)
(
this
+
1
);
if
(
flash_init
(
flash
))
{
printk
(
KERN_ERR
"Unable to allocat flash.
\n
"
);
kfree
(
ffchars
);
kfree
(
onenand_sim
);
return
-
ENOMEM
;
}
this
->
base
=
flash
->
base
;
this
->
priv
=
flash
;
onenand_sim
->
priv
=
this
;
if
(
onenand_scan
(
onenand_sim
,
1
))
{
kfree
(
ffchars
);
kfree
(
onenand_sim
);
flash_exit
(
flash
);
return
-
ENXIO
;
}
add_mtd_device
(
onenand_sim
);
return
0
;
}
static
void
__exit
onenand_sim_exit
(
void
)
{
struct
onenand_chip
*
this
=
onenand_sim
->
priv
;
struct
onenand_flash
*
flash
=
this
->
priv
;
kfree
(
ffchars
);
onenand_release
(
onenand_sim
);
flash_exit
(
flash
);
kfree
(
onenand_sim
);
}
module_init
(
onenand_sim_init
);
module_exit
(
onenand_sim_exit
);
MODULE_LICENSE
(
"GPL"
);
MODULE_AUTHOR
(
"Kyungmin Park <kyungmin.park@samsung.com>"
);
MODULE_DESCRIPTION
(
"The OneNAND flash simulator"
);
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录