感谢楼上几位大侠, 终于搞定:
添加一个fixcode.asm到工程, 内容是:
CSEG AT 03780h
CFG_BYTE_0: DB 'A'
CFG_BYTE_1: DB 'B'
END
重新编译生成bin即可。
链接: https://pan.baidu.com/s/1iRQZL2CC6PoQbfyAosRQVQ
提取码:f5va
AD16.2
https://blog.csdn.net/zxjohnson/article/details/106621457
从Qt5.15.0起,对于开源用户,Qt官方不再提供独立安装文件,且不再有bug修复版本(比如Qt5.15.1)
如果想体验Qt5.15及之后的版本,就要培养一个新技能——编译Qt源码
从编译到发布大概需要这么几个步骤:
1. 从Qt官网下载源码;
2. 编译源码;
3. 将编译后的qmake.exe导入QtCreator或者Visual Studio;
4. 使用QtCreator或者Visual Studio编译Qt项目;
5. 项目发布可仍然使用windeployqt.exe。
拉轰的脚踏车 说:请问下我编写了一个Qt应用程序, 如何添加到buildroot的package里面去,如果自动拷贝到根文件系统?
Building a Linux system for the STM32MP1: setting up a Qt5 application development environment
https://github.com/tpetazzoni/buildroot/commit/a0bdf09634961a84f2d801da08e906eae8d7ebf3
https://github.com/tpetazzoni/buildroot/commits/2019.02/stm32mp157-dk-blog-4
学到了! 简直完美解答我心中的疑虑,这个老外耐心足够好。
smartcar 说:hanzixi_angel 说:晕哥 如何使用de功能 在Linux设备树中更改lcd屏幕的参数 现在都是更改linux/drivers/gpu/drm/panel/panel-simple.c源码 然后编译镜像之后烧写 以后会有多种屏幕 这样不太方便 最好只修改设备树 在设备树配置参数 只更换设备树即可 这样最好
你的de功能正常了吗?
de功能正常啊 修改了linux/drivers/gpu/drm/panel/panel-simple.c源码 适配了屏幕 但是这样修改不太好 想只修改设备树 在设备树增加屏幕参数
drm的话如果找不到现成的LCD配置估计就一定要修改那部分的代码吧,
https://github.com/ccrisan/motionpie/blob/master/board/common/overlay/etc/init.d/S40network
#!/bin/sh
mkdir -p /var/lib/dhcp
dh_conf="/var/cache/dhclient.conf"
sys_static_conf="/etc/static_ip.conf"
static_conf="/data/etc/static_ip.conf"
watch_conf="/data/etc/watch.conf"
link_watch=yes
link_watch_timeout=20
ip_watch=yes
ip_watch_timeout=40
link_nego_timeout=10
eth=eth0
wlan=wlan0
if [ -f $watch_conf ]; then
source $watch_conf
fi
if [ -f $sys_static_conf ] && ! [ -f $static_conf ]; then
mkdir -p $(dirname $static_conf)
cp $sys_static_conf $static_conf
fi
test -r $static_conf && source $static_conf
watch_eth() {
count=0
while true; do
sleep 5
if mii-tool $eth 2>&1 | grep "link ok" > /dev/null; then
count=0
else
if [ $count -lt $link_watch_timeout ]; then
count=$(($count + 5))
logger -t ethernet -s "disconnected"
else
logger -t ethernet -s "disconnected for $link_watch_timeout seconds, rebooting"
reboot
fi
fi
done
}
watch_ip() {
iface=$1
count=0
while true; do
sleep 5
if ip addr show dev $iface | grep inet &>/dev/null; then
count=0
else
if [ $count -lt $ip_watch_timeout ]; then
count=$(($count + 5))
logger -t network -s "$iface has no IP address"
else
logger -t network -s "$iface had no IP address for $ip_watch_timeout seconds, rebooting"
reboot
fi
fi
done
}
start_lo() {
ifconfig lo up
}
start_wlan() {
if ! ifconfig $wlan >/dev/null 2>&1; then
echo "$wlan: no device"
return
fi
if [ "$(cat /sys/class/net/$wlan/carrier 2>/dev/null)" != "1" ]; then
echo "$wlan: no link"
return
fi
if [ -n "$static_ip" ]; then
echo "$wlan: setting static IP to $static_ip"
ifconfig $wlan $static_ip up
static_ip="" # won't be used again
else
echo "$wlan: starting dhclient"
dhclient -cf "$dh_conf" $wlan
fi
if [ "$ip_watch" == "yes" ]; then
watch_ip $wlan &
fi
}
start_eth() {
# wait up to 3 seconds for driver
count=0
while ! ifconfig $eth >/dev/null 2>&1; do
sleep 1
count=$(($count + 1))
if [ $count -ge 3 ]; then
echo "$eth: no device"
return
fi
done
# bring it up
ifconfig $eth up
# wait up to 3 seconds for operstate
count=0
while [ "$(cat /sys/class/net/$eth/operstate 2>&1)" == "unknown" ]; do
sleep 1
count=$(($count + 1))
if [ $count -ge 3 ]; then
echo "$eth: no link"
return
fi
done
# wait up to link_nego_timeout seconds for link
count=0
while [ "$(cat /sys/class/net/$eth/carrier 2>&1)" != "1" ]; do
sleep 1
count=$(($count + 1))
if [ $count -ge $link_nego_timeout ]; then
echo "$eth: no link"
return
fi
done
if [ -n "$static_ip" ]; then
echo "$eth: setting static IP to $static_ip"
ifconfig $eth $static_ip up
static_ip="" # won't be used again
else
echo "$eth: starting dhclient"
dhclient -cf "$dh_conf" $eth
fi
if [ "$link_watch" == "yes" ]; then
watch_eth &
fi
if [ "$ip_watch" == "yes" ]; then
watch_ip $eth &
fi
}
start() {
hostname=$(hostname)
echo "send host-name = \"$hostname\";" > /var/cache/dhclient.conf
start_lo
start_wlan
# if wifi or ppp connection configured, start eth in background
ssid=$(cat /data/etc/wpa_supplicant.conf 2>&1 | grep ssid | grep -v scan_ssid | cut -d '"' -f 2)
if [ -n "$ssid" ] || [ -r /data/etc/ppp/modem ]; then
start_eth &>/dev/null &
else
start_eth
fi
if [ -n "$static_gw" ]; then
echo "setting static gateway to $static_gw"
ip route add default via $static_gw
fi
if [ -n "$static_dns" ]; then
echo "setting static DNS server to $static_dns"
echo "nameserver $static_dns" > /etc/resolv.conf
fi
# print the current network configuration
ifconfig -a
}
case "$1" in
start)
echo -n "Starting network: "
start
echo "done"
;;
stop)
echo -n "Stopping network: "
killall dhclient
ps | grep S40network | grep -v $$ | grep -v grep | tr -s ' ' | sed -e 's/^\s//' | cut -d ' ' -f 1 | xargs -r kill
echo "done"
;;
restart|reload)
"$0" stop
"$0" start
;;
*)
echo "Usage: $0 {start|stop|restart}"
exit 1
esac
exit $?
这个脚本不错,可以试一试
晕哥 说:这个问题我以前也纳闷过,
后来发现 u-boot的 common/fdt_support.c 里面有 fdt_setup_simplefb_node()这个函数,
他居然会自己创建设备树, 然后传递给Linux用,赶脚好神奇!晕哥 如何使用de功能 在Linux设备树中更改lcd屏幕的参数 现在都是更改linux/drivers/gpu/drm/panel/panel-simple.c源码 然后编译镜像之后烧写 以后会有多种屏幕 这样不太方便 最好只修改设备树 在设备树配置参数 只更换设备树即可 这样最好
你的de功能正常了吗?
https://whycan.com/files/members/1116/_20200924151151.png
就这样的 不知道在那里修改那个编译的版本
这个貌似就是C99支持不全,官方都用VS2017了,你何必折腾自己?
https://whycan.cn/files/members/2006/tu1_20191121-1739.jpg
c9这个100n的电容脱了,这个滤波没有不影响吧。
R1,R2没有焊接,RFC脚是悬空的,看手册这个脚是设置上或下降沿读数据的。
https://whycan.cn/files/members/2006/tu2.jpg
https://whycan.cn/files/members/2006/tu0.jpg
https://whycan.cn/files/members/2006/tu3.jpg
https://whycan.cn/files/members/2006/tu4.jpg
怎么感觉显示有点不正常呢,最后解决了吗?
没那么麻烦拉,再给大家推荐一个傻瓜方法kpartx,一句命令搞定。
https://blog.csdn.net/qq_28693567/article/details/80324846
这个好,学到一招。
https://whycan.cn/files/members/3311/QQ图片20200722172134.jpg
第二版已经下单,很快就要与大家见面了,修复了不少第一版的问题
干得漂亮
目测BGA封装,劝退劝退
有关于荔枝派制作文件系统的标准操作么,我就是解压到主分区,可能是我操作有问题
1. 添加虚拟can网络, 参考can.html:
ip link add type vcan
指定名称的can网络:
ip link add dev vcan42 type vcan
2. 使能 can 网络:
https://www.technexion.com/support/knowledgebase/using-the-can-bus-from-linux-shell/
http://codingadventures.org/2018/10/01/setting-and-testing-a-can-bus-connection-in-linux/
ip link set vcan0 type can bitrate 125000
ifconfig vcan0 up
3. 测试
先抓包:
candump can0 &
再发送:
cansend can1 123#CAFEBABE
买了块F1C200S的板子 需要手册
0.949797] SCSI Media Changer driver v0.25
[ 0.957610] m25p80 spi0.0: w25q128 (16384 Kbytes)
[ 0.962464] 5 ofpart partitions found on MTD device spi0.0
[ 0.968096] Creating 5 MTD partitions on "spi0.0":
[ 0.972946] 0x000000000000-0x000000070000 : "u-boot"
[ 0.980506] rfd_ftl: no RFD magic found in 'u-boot'
[ 0.986556] ftl_cs: FTL header not found.
[ 0.992325] 0x000000070000-0x000000080000 : "dtb"
[ 0.998475] ftl_cs: FTL header not found.
[ 1.004100] 0x000000080000-0x000000480000 : "kernel"
[ 1.019930] rfd_ftl: no RFD magic found in 'kernel'
[ 1.027130] ftl_cs: FTL header not found.
[ 1.032752] 0x000000480000-0x000000c00000 : "rootfs"
[ 1.056702] rfd_ftl: no RFD magic found in 'rootfs'
[ 1.063882] ftl_cs: FTL header not found.
[ 1.069612] 0x000000c00000-0x000001000000 : "overlayfs"
[ 1.085693] rfd_ftl: no RFD magic found in 'overlayfs'
[ 1.093115] ftl_cs: FTL header not found.分区信息多了一些 ftl 异常,大家有踩过坑吗?
从来没有遇到这种问题,得跟踪一下代码
建议先用红白机大佬的这种lvds转换方案,后面再costdown: https://whycan.cn/t_3472.html#p32696
https://item.taobao.com/item.htm?id=45502231519
高仿汉仁HanRun网络隔离变压器RJ45插座滤波器HR911105A RJ45带灯
价格 ¥3.00
这么看来, 高仿石锤了!
https://s.taobao.com/search?q=HY951180A
https://item.szlcsc.com/35646.html
都是 HY951180A, 淘宝卖4块, LC卖13.5块?
直连也会出现,但是网卡接收数据和内存减少的速度要慢很多
有没有可能是这个问题: https://whycan.cn/t_3887.html
https://item.taobao.com/item.htm?spm=a1z09.2.0.0.76262e8dzsKKpW&id=524754285200&_u=gef23h147f
这家还行,买过几次,是很粗线芯的硅胶线。可以少买点试试。
感谢推荐,我这就去买。
不错哦,求插座链接和w600模块链接。
汇报下,今天完成了CPU部分原理图的绘制,顺便想问下,怎么上传截图呀 下次汇报工作就可以上传图片了哈哈 明天计划做SD卡部分和以太网部分,到时候看看吧~
下个Process Explorer,微软官方的免费系统诊断工具,可以当成是任务管理器的高阶版。里面会写进程的资源占用。
https://docs.microsoft.com/en-us/sysinternals/downloads/process-explorer
软件是下载到了, 但是只能右击任务,点属性,然后TCP/IP选项卡看端口吗?
V10的硬件,boot里把v10的字符串改成v11,然后就会升v11的固件了。
见
https://www.cnblogs.com/emwork/p/11297416.html
也就是说v10与v11硬件相同?
相关链接: 闲鱼捡漏,拆解一台收银机【多图警告,流量党劝退】
收到海南网友寄过来的 4.3寸高分辨率LCD(800*480), 上电测试, 完美!
4.3寸TFT液晶横屏IPS,超宽温LCD彩色显示屏800*480 RGB通用接口, 108元两片,相当于 54元一片:
https://item.taobao.com/item.htm?id=574813477169 (上图就是用这片液晶)
第一个链接涨价了?
我的配置文件已经开源了哦,看帖不认真
哈哈,上面有个压缩包,里面镜像和配置文件都有,改了XZ压缩方式,还可以缩到1.7M
奇怪,昨天明明放上去的呀,咋不见了,我再发一次
感谢分享, 只是下载有点慢, 一会再仔细研究.
嗯,接一个常见的A4988模块就可以了
好, 多谢, 我手里有一个 Raspberry Pi 2 Model B V1.1 2014, 不知道能不能跑,
正在下载 https://www.nanodlp.com/nanodlp.img.gz
等会烧到 TF 试一试.
树莓派上有一路硬件PWM,LCD打印机只需要一个控制Z轴的电机就可以了,所以可以用树莓派直接驱动打印,不需要额外的电机控制板。
是加这个吗:
1. 看你的log,可以屏蔽uboot的emmc,在.config里面可以删除,估计能提高0.0x秒
2. /etc/init.d/S90app 改成 /etc/init.d/S01app,可以最先执行lvgl app
这里还浪费了一点点时间,
Trying to boot from MMC1
MMC Device 0 not found
spl: could not find mmc device. error: -19
还有你的 lvgl app有没有 strip ?体积多大?
mount: mounting tmpfs on /dev/shm failed: Invalid argument
mount: mounting tmpfs on /tmp failed: Invalid argument
mount: mounting tmpfs on /run failed: Invalid argument
根文件系统还缺这几个目录, 最好手动建立一下.
https://www.nanodlp.com/download
https://www.nanodlp.com/download/nanodlp.win64.zip
下载了一个 windows 版本的模拟软件跑起来了, 看看会不会用.
这是他们的主页: https://www.nanodlp.com/
不错。 推荐一个: https://github.com/xtoolbox/qtlua
这是 lua 绑定 Qt吗?
这个屏是什么型号,哪里有卖?
感觉各位大佬的分享,虽然还无法通过sunxi-fel直接写入spi nand但可以通过内存写入,目前W25N01G 128MB spi nandflash uboot启动成功
源码及记录分享链接: https://github.com/hcly/f1c100s
这个更吊,围观
libdrm是一个开源库,这里可以下载: http://www.linuxfromscratch.org/blfs/view/stable/x/libdrm.html ,
下载到的库里面就有测试程序,其实也可以在buildroot里面勾选libdrm,会自动帮你下载和编译。另外libdrm只是将linux的drm驱动包装一下,使接口更加友好而已,实际功能实现还是在内核驱动里面,我觉得它是硬件实现的。
我可能有点知道为什么上次f1c100s debian 跑桌面出不来的原因了,报一堆 drm 错误,然后桌面就挂了。
1. 看到这位兄弟 https://whycan.cn/t_2386.html#p25634 修改 c 文件,才想起要改 awtk-port/main_loop_linux.c
#define FB_DEVICE_FILENAME "/dev/fb0"
#define TS_DEVICE_FILENAME "/dev/input/event1"
#define KB_DEVICE_FILENAME "/dev/input/event0"
2. 改完后界面也不抖了.
3. 现在最后一个问题: 如何隐藏界面的光标(cursor)呢?
TSLIB_TSDEVICE=/dev/input/event1 ts_calibrate
TSLIB_TSDEVICE=/dev/input/event1 ts_test
# TSLIB_TSDEVICE=/dev/input/event1 /awtk/bin/demoui
app_root_is_valid:43 app_root != NULL
try /root
try /awtk/bin
app_root=/awtk
fb_info_t: /dev/fb0
fb_info_t: xres=800 yres=480 bits_per_pixel=32 mem_size=1536000
fb_info_t: red(16 8) green(8 8) blue(0 8)
line_length=3200 mem_size=1536000 smem_len=1536000
xres_virtual =800 yres_virtual=480 xpanstep=1 ywrapstep=0
ratio=1.000000 800 480
Build at: Oct 22 2019 16:41:20
window preload open
tslib: Selected device is not a touchscreen (must support ABS event type)
tslib_dispatch_one_event:61 tslib read failed(ret=0, errno=0, filename=/dev/input/event0)
Print tslib: : Success
keyboard pointer down:3198 982
input_dispatch_one_event:71 mouse read failed(ret=-1, errno=0, fd=-1, filename=/dev/input/mice)
Print mouse: : Success
window system_bar open
main
ignore_user_input
window main open
window preload close
main
main
input_dispatch_one_event:71 mouse read failed(ret=-1, errno=2, fd=-1, filename=/dev/input/mice)
Print mouse: : No such file or directory
tslib: Selected device is not a touchscreen (must support ABS event type)
tslib_dispatch_one_event:61 tslib read failed(ret=0, errno=0, filename=/dev/input/event0)
Print tslib: : Success
input_dispatch_one_event:71 mouse read failed(ret=-1, errno=2, fd=-1, filename=/dev/input/mice)
Print mouse: : No such file or directory
tslib: Selected device is not a touchscreen (must support ABS event type)
tslib_dispatch_one_event:61 tslib read failed(ret=0, errno=0, filename=/dev/input/event0)
Print tslib: : Success
input_dispatch_one_event:71 mouse read failed(ret=-1, errno=2, fd=-1, filename=/dev/input/mice)
Print mouse: : No such file or directory
tslib: Selected device is not a touchscreen (must support ABS event type)
tslib_dispatch_one_event:61 tslib read failed(ret=0, errno=0, filename=/dev/input/event0)
Print tslib: : Success
input_dispatch_one_event:71 mouse read failed(ret=-1, errno=2, fd=-1, filename=/dev/input/mice)
Print mouse: : No such file or directory
tslib: Selected device is not a touchscreen (must support ABS event type)
tslib_dispatch_one_event:61 tslib read failed(ret=0, errno=0, filename=/dev/input/event0)
Print tslib: : Success
input_dispatch_one_event:71 mouse read failed(ret=-1, errno=2, fd=-1, filename=/dev/input/mice)
Print mouse: : No such file or directory
tslib: Selected device is not a touchscreen (must support ABS event type)
tslib_dispatch_one_event:61 tslib read failed(ret=0, errno=0, filename=/dev/input/event0)
Print tslib: : Success
input_dispatch_one_event:71 mouse read failed(ret=-1, errno=2, fd=-1, filename=/dev/input/mice)
Print mouse: : No such file or directory
tslib: Selected device is not a touchscreen (must support ABS event type)
tslib_dispatch_one_event:61 tslib read failed(ret=0, errno=0, filename=/dev/input/event0)
Print tslib: : Success
input_dispatch_one_event:71 mouse read failed(ret=-1, errno=2, fd=-1, filename=/dev/input/mice)
Print mouse: : No such file or directory
tslib: Selected device is not a touchscreen (must support ABS event type)
tslib_dispatch_one_event:61 tslib read failed(ret=0, errno=0, filename=/dev/input/event0)
Print tslib: : Success
keyboard pointer up:1148 641
keyboard pointer down:1439 531
keyboard pointer up:1441 530
keyboard pointer down:1488 468
keyboard pointer up:1488 477
keyboard pointer down:1452 523
input_dispatch_one_event:71 mouse read failed(ret=-1, errno=2, fd=-1, filename=/dev/input/mice)
Print mouse: : No such file or directory
tslib: Selected device is not a touchscreen (must support ABS event type)
tslib_dispatch_one_event:61 tslib read failed(ret=0, errno=0, filename=/dev/input/event0)
Print tslib: : Success
keyboard pointer up:1458 525
keyboard pointer down:1435 424
keyboard pointer up:1428 422
input_dispatch_one_event:71 mouse read failed(ret=-1, errno=2, fd=-1, filename=/dev/input/mice)
Print mouse: : No such file or directory
keyboard pointer down:1904 750
tslib: Selected device is not a touchscreen (must support ABS event type)
tslib_dispatch_one_event:61 tslib read failed(ret=0, errno=0, filename=/dev/input/event0)
Print tslib: : Success
keyboard pointer up:1908 734
input_dispatch_one_event:71 mouse read failed(ret=-1, errno=2, fd=-1, filename=/dev/input/mice)
Print mouse: : No such file or directory
tslib: Selected device is not a touchscreen (must support ABS event type)
tslib_dispatch_one_event:61 tslib read failed(ret=0, errno=0, filename=/dev/input/event0)
Print tslib: : Success
input_dispatch_one_event:71 mouse read failed(ret=-1, errno=2, fd=-1, filename=/dev/input/mice)
Print mouse: : No such file or directory
tslib: Selected device is not a touchscreen (must support ABS event type)
tslib_dispatch_one_event:61 tslib read failed(ret=0, errno=0, filename=/dev/input/event0)
Print tslib: : Success
input_dispatch_one_event:71 mouse read failed(ret=-1, errno=2, fd=-1, filename=/dev/input/mice)
Print mouse: : No such file or directory
tslib: Selected device is not a touchscreen (must support ABS event type)
tslib_dispatch_one_event:61 tslib read failed(ret=0, errno=0, filename=/dev/input/event0)
Print tslib: : Success
这里是按压触摸屏的输出:
Print tslib: : Success
keyboard pointer up:1148 641
keyboard pointer down:1439 531
keyboard pointer up:1441 530
keyboard pointer down:1488 468
keyboard pointer up:1488 477
keyboard pointer down:1452 523
但是实际上触摸是没有反应的.
请问这是为什么呢?
--------------------------------------------------------
--------------------------------------------------------
--------------------------------------------------------
--------------------------------------------------------
--------------------------------------------------------
以下是网友仿制:
以下是网友仿制:
以下是网友仿制:
以下是网友仿制:
以下是网友仿制:
--------------------------------------------------------
--------------------------------------------------------
--------------------------------------------------------
--------------------------------------------------------
--------------------------------------------------------
可能外网速度不行,或者文件没有下载完全,用豆瓣的仓库试一试:
pip install PyQt5 --trusted-host http://pypi.douban.com/simple/
pip install PyInstaller --trusted-host http://pypi.douban.com/simple/
https://github.com/rxi/microui
看到 xboot qq群推荐的,没有用过哈
# GitHub Start
192.30.253.112 github.com
192.30.253.118 gist.github.com
151.101.112.133 assets-cdn.github.com
151.101.184.133 raw.githubusercontent.com
151.101.112.133 gist.githubusercontent.com
151.101.184.133 cloud.githubusercontent.com
151.101.112.133 camo.githubusercontent.com
151.101.112.133 avatars0.githubusercontent.com
151.101.112.133 avatars1.githubusercontent.com
151.101.184.133 avatars2.githubusercontent.com
151.101.12.133 avatars3.githubusercontent.com
151.101.12.133 avatars4.githubusercontent.com
151.101.184.133 avatars5.githubusercontent.com
151.101.184.133 avatars6.githubusercontent.com
151.101.184.133 avatars7.githubusercontent.com
151.101.12.133 avatars8.githubusercontent.com
# GitHub End
以上添加到本地 hosts 文件
diff -Naur a/include/ieee80211.h b/include/ieee80211.h
--- a/include/ieee80211.h 2016-10-20 12:20:19.000000000 -0700
+++ b/include/ieee80211.h 2016-11-15 17:00:32.239848199 -0800
@@ -1388,18 +1388,18 @@
(((Addr[2]) & 0xff) == 0xff) && (((Addr[3]) & 0xff) == 0xff) && (((Addr[4]) & 0xff) == 0xff) && \
(((Addr[5]) & 0xff) == 0xff))
#else
-extern __inline int is_multicast_mac_addr(const u8 *addr)
+static __inline int is_multicast_mac_addr(const u8 *addr)
{
return ((addr[0] != 0xff) && (0x01 & addr[0]));
}
-extern __inline int is_broadcast_mac_addr(const u8 *addr)
+static __inline int is_broadcast_mac_addr(const u8 *addr)
{
return ((addr[0] == 0xff) && (addr[1] == 0xff) && (addr[2] == 0xff) && \
(addr[3] == 0xff) && (addr[4] == 0xff) && (addr[5] == 0xff));
}
-extern __inline int is_zero_mac_addr(const u8 *addr)
+static __inline int is_zero_mac_addr(const u8 *addr)
{
return ((addr[0] == 0x00) && (addr[1] == 0x00) && (addr[2] == 0x00) && \
(addr[3] == 0x00) && (addr[4] == 0x00) && (addr[5] == 0x00));
找到解决方案, 更新 drivers/net/wireless/rtl8723bs/include/ieee80211.h 一下试一试.
CC [M] drivers/net/wireless/rtl8723bs/hal/OUTSRC/rtl8723b/odm_RTL8723B.o
CC [M] drivers/net/wireless/rtl8723bs/platform/platform_ops.o
CC [M] drivers/net/wireless/rtl8723bs/platform/platform_ARM_SUNnI_sdio.o
CC [M] drivers/net/wireless/rtl8723bs/core/rtw_mp.o
CC [M] drivers/net/wireless/rtl8723bs/core/rtw_mp_ioctl.o
CC [M] drivers/net/wireless/rtl8723bs/core/rtw_bt_mp.o
LD [M] drivers/net/wireless/rtl8723bs/8723bs.o
drivers/net/wireless/rtl8723bs/core/rtw_security.o: In function `is_multicast_mac_addr':
rtw_security.c:(.text+0x20b8): multiple definition of `is_multicast_mac_addr'
drivers/net/wireless/rtl8723bs/core/rtw_cmd.o:rtw_cmd.c:(.text+0x44): first defined here
drivers/net/wireless/rtl8723bs/core/rtw_security.o: In function `is_broadcast_mac_addr':
rtw_security.c:(.text+0x20d8): multiple definition of `is_broadcast_mac_addr'
drivers/net/wireless/rtl8723bs/core/rtw_cmd.o:rtw_cmd.c:(.text+0x64): first defined here
drivers/net/wireless/rtl8723bs/core/rtw_security.o: In function `is_zero_mac_addr':
rtw_security.c:(.text+0x215c): multiple definition of `is_zero_mac_addr'
drivers/net/wireless/rtl8723bs/core/rtw_cmd.o:rtw_cmd.c:(.text+0xe8): first defined here
drivers/net/wireless/rtl8723bs/core/rtw_debug.o: In function `is_multicast_mac_addr':
rtw_debug.c:(.text+0x0): multiple definition of `is_multicast_mac_addr'
drivers/net/wireless/rtl8723bs/core/rtw_cmd.o:rtw_cmd.c:(.text+0x44): first defined here
drivers/net/wireless/rtl8723bs/core/rtw_debug.o: In function `is_broadcast_mac_addr':
rtw_debug.c:(.text+0x20): multiple definition of `is_broadcast_mac_addr'
drivers/net/wireless/rtl8723bs/core/rtw_cmd.o:rtw_cmd.c:(.text+0x64): first defined here
drivers/net/wireless/rtl8723bs/core/rtw_debug.o: In function `is_zero_mac_addr':
rtw_debug.c:(.text+0xa4): multiple definition of `is_zero_mac_addr'
drivers/net/wireless/rtl8723bs/core/rtw_cmd.o:rtw_cmd.c:(.text+0xe8): first defined here
drivers/net/wireless/rtl8723bs/core/rtw_io.o: In function `is_multicast_mac_addr':
rtw_io.c:(.text+0x0): multiple definition of `is_multicast_mac_addr'
drivers/net/wireless/rtl8723bs/core/rtw_cmd.o:rtw_cmd.c:(.text+0x44): first defined here
drivers/net/wireless/rtl8723bs/core/rtw_io.o: In function `is_broadcast_mac_addr':
rtw_io.c:(.text+0x20): multiple definition of `is_broadcast_mac_addr'
drivers/net/wireless/rtl8723bs/core/rtw_cmd.o:rtw_cmd.c:(.text+0x64): first defined here
drivers/net/wireless/rtl8723bs/core/rtw_io.o: In function `is_zero_mac_addr':
rtw_io.c:(.text+0xa4): multiple definition of `is_zero_mac_addr'
drivers/net/wireless/rtl8723bs/core/rtw_cmd.o:rtw_cmd.c:(.text+0xe8): first defined here
drivers/net/wireless/rtl8723bs/core/rtw_ioctl_query.o: In function `is_multicast_mac_addr':
rtw_ioctl_query.c:(.text+0x0): multiple definition of `is_multicast_mac_addr'
drivers/net/wireless/rtl8723bs/core/rtw_cmd.o:rtw_cmd.c:(.text+0x44): first defined here
drivers/net/wireless/rtl8723bs/core/rtw_ioctl_query.o: In function `is_broadcast_mac_addr':
rtw_ioctl_query.c:(.text+0x20): multiple definition of `is_broadcast_mac_addr'
drivers/net/wireless/rtl8723bs/core/rtw_cmd.o:rtw_cmd.c:(.text+0x64): first defined here
drivers/net/wireless/rtl8723bs/core/rtw_ioctl_query.o: In function `is_zero_mac_addr':
rtw_ioctl_query.c:(.text+0xa4): multiple definition of `is_zero_mac_addr'
drivers/net/wireless/rtl8723bs/core/rtw_cmd.o:rtw_cmd.c:(.text+0xe8): first defined here
drivers/net/wireless/rtl8723bs/core/rtw_ioctl_set.o: In function `is_multicast_mac_addr':
rtw_ioctl_set.c:(.text+0x0): multiple definition of `is_multicast_mac_addr'
drivers/net/wireless/rtl8723bs/core/rtw_cmd.o:rtw_cmd.c:(.text+0x44): first defined here
drivers/net/wireless/rtl8723bs/core/rtw_ioctl_set.o: In function `is_broadcast_mac_addr':
rtw_ioctl_set.c:(.text+0x20): multiple definition of `is_broadcast_mac_addr'
drivers/net/wireless/rtl8723bs/core/rtw_cmd.o:rtw_cmd.c:(.text+0x64): first defined here
drivers/net/wireless/rtl8723bs/core/rtw_ioctl_set.o: In function `is_zero_mac_addr':
rtw_ioctl_set.c:(.text+0xa4): multiple definition of `is_zero_mac_addr'
drivers/net/wireless/rtl8723bs/core/rtw_cmd.o:rtw_cmd.c:(.text+0xe8): first defined here
drivers/net/wireless/rtl8723bs/core/rtw_ieee80211.o: In function `is_multicast_mac_addr':
rtw_ieee80211.c:(.text+0x58): multiple definition of `is_multicast_mac_addr'
drivers/net/wireless/rtl8723bs/core/rtw_cmd.o:rtw_cmd.c:(.text+0x44): first defined here
drivers/net/wireless/rtl8723bs/core/rtw_ieee80211.o: In function `is_broadcast_mac_addr':
rtw_ieee80211.c:(.text+0x78): multiple definition of `is_broadcast_mac_addr'
drivers/net/wireless/rtl8723bs/core/rtw_cmd.o:rtw_cmd.c:(.text+0x64): first defined here
drivers/net/wireless/rtl8723bs/core/rtw_ieee80211.o: In function `is_zero_mac_addr':
rtw_ieee80211.c:(.text+0xfc): multiple definition of `is_zero_mac_addr'
drivers/net/wireless/rtl8723bs/core/rtw_cmd.o:rtw_cmd.c:(.text+0xe8): first defined here
drivers/net/wireless/rtl8723bs/core/rtw_mlme.o: In function `is_multicast_mac_addr':
rtw_mlme.c:(.text+0x38): multiple definition of `is_multicast_mac_addr'
drivers/net/wireless/rtl8723bs/core/rtw_cmd.o:rtw_cmd.c:(.text+0x44): first defined here
drivers/net/wireless/rtl8723bs/core/rtw_mlme.o: In function `is_broadcast_mac_addr':
rtw_mlme.c:(.text+0x58): multiple definition of `is_broadcast_mac_addr'
drivers/net/wireless/rtl8723bs/core/rtw_cmd.o:rtw_cmd.c:(.text+0x64): first defined here
drivers/net/wireless/rtl8723bs/core/rtw_mlme.o: In function `is_zero_mac_addr':
rtw_mlme.c:(.text+0xdc): multiple definition of `is_zero_mac_addr'
drivers/net/wireless/rtl8723bs/core/rtw_cmd.o:rtw_cmd.c:(.text+0xe8): first defined here
drivers/net/wireless/rtl8723bs/core/rtw_mlme_ext.o: In function `is_multicast_mac_addr':
rtw_mlme_ext.c:(.text+0x6bc): multiple definition of `is_multicast_mac_addr'
drivers/net/wireless/rtl8723bs/core/rtw_cmd.o:rtw_cmd.c:(.text+0x44): first defined here
drivers/net/wireless/rtl8723bs/core/rtw_mlme_ext.o: In function `is_broadcast_mac_addr':
rtw_mlme_ext.c:(.text+0x6dc): multiple definition of `is_broadcast_mac_addr'
drivers/net/wireless/rtl8723bs/core/rtw_cmd.o:rtw_cmd.c:(.text+0x64): first defined here
drivers/net/wireless/rtl8723bs/core/rtw_mlme_ext.o: In function `is_zero_mac_addr':
rtw_mlme_ext.c:(.text+0x760): multiple definition of `is_zero_mac_addr'
drivers/net/wireless/rtl8723bs/core/rtw_cmd.o:rtw_cmd.c:(.text+0xe8): first defined here
drivers/net/wireless/rtl8723bs/core/rtw_wlan_util.o: In function `is_multicast_mac_addr':
rtw_wlan_util.c:(.text+0x0): multiple definition of `is_multicast_mac_addr'
drivers/net/wireless/rtl8723bs/core/rtw_cmd.o:rtw_cmd.c:(.text+0x44): first defined here
drivers/net/wireless/rtl8723bs/core/rtw_wlan_util.o: In function `is_broadcast_mac_addr':
rtw_wlan_util.c:(.text+0x20): multiple definition of `is_broadcast_mac_addr'
drivers/net/wireless/rtl8723bs/core/rtw_cmd.o:rtw_cmd.c:(.text+0x64): first defined here
drivers/net/wireless/rtl8723bs/core/rtw_wlan_util.o: In function `is_zero_mac_addr':
rtw_wlan_util.c:(.text+0xa4): multiple definition of `is_zero_mac_addr'
drivers/net/wireless/rtl8723bs/core/rtw_cmd.o:rtw_cmd.c:(.text+0xe8): first defined here
drivers/net/wireless/rtl8723bs/core/rtw_vht.o: In function `is_multicast_mac_addr':
rtw_vht.c:(.text+0x0): multiple definition of `is_multicast_mac_addr'
drivers/net/wireless/rtl8723bs/core/rtw_cmd.o:rtw_cmd.c:(.text+0x44): first defined here
drivers/net/wireless/rtl8723bs/core/rtw_vht.o: In function `is_broadcast_mac_addr':
rtw_vht.c:(.text+0x20): multiple definition of `is_broadcast_mac_addr'
drivers/net/wireless/rtl8723bs/core/rtw_cmd.o:rtw_cmd.c:(.text+0x64): first defined here
drivers/net/wireless/rtl8723bs/core/rtw_vht.o: In function `is_zero_mac_addr':
rtw_vht.c:(.text+0xa4): multiple definition of `is_zero_mac_addr'
drivers/net/wireless/rtl8723bs/core/rtw_cmd.o:rtw_cmd.c:(.text+0xe8): first defined here
drivers/net/wireless/rtl8723bs/core/rtw_pwrctrl.o: In function `is_multicast_mac_addr':
rtw_pwrctrl.c:(.text+0x90): multiple definition of `is_multicast_mac_addr'
drivers/net/wireless/rtl8723bs/core/rtw_cmd.o:rtw_cmd.c:(.text+0x44): first defined here
drivers/net/wireless/rtl8723bs/core/rtw_pwrctrl.o: In function `is_broadcast_mac_addr':
rtw_pwrctrl.c:(.text+0xb0): multiple definition of `is_broadcast_mac_addr'
drivers/net/wireless/rtl8723bs/core/rtw_cmd.o:rtw_cmd.c:(.text+0x64): first defined here
drivers/net/wireless/rtl8723bs/core/rtw_pwrctrl.o: In function `is_zero_mac_addr':
rtw_pwrctrl.c:(.text+0x134): multiple definition of `is_zero_mac_addr'
drivers/net/wireless/rtl8723bs/core/rtw_cmd.o:rtw_cmd.c:(.text+0xe8): first defined here
drivers/net/wireless/rtl8723bs/core/rtw_rf.o: In function `is_multicast_mac_addr':
rtw_rf.c:(.text+0x0): multiple definition of `is_multicast_mac_addr'
drivers/net/wireless/rtl8723bs/core/rtw_cmd.o:rtw_cmd.c:(.text+0x44): first defined here
drivers/net/wireless/rtl8723bs/core/rtw_rf.o: In function `is_broadcast_mac_addr':
rtw_rf.c:(.text+0x20): multiple definition of `is_broadcast_mac_addr'
drivers/net/wireless/rtl8723bs/core/rtw_cmd.o:rtw_cmd.c:(.text+0x64): first defined here
drivers/net/wireless/rtl8723bs/core/rtw_rf.o: In function `is_zero_mac_addr':
rtw_rf.c:(.text+0xa4): multiple definition of `is_zero_mac_addr'
drivers/net/wireless/rtl8723bs/core/rtw_cmd.o:rtw_cmd.c:(.text+0xe8): first defined here
drivers/net/wireless/rtl8723bs/core/rtw_recv.o: In function `is_multicast_mac_addr':
rtw_recv.c:(.text+0x1d8): multiple definition of `is_multicast_mac_addr'
drivers/net/wireless/rtl8723bs/core/rtw_cmd.o:rtw_cmd.c:(.text+0x44): first defined here
drivers/net/wireless/rtl8723bs/core/rtw_recv.o: In function `is_broadcast_mac_addr':
rtw_recv.c:(.text+0x1f8): multiple definition of `is_broadcast_mac_addr'
drivers/net/wireless/rtl8723bs/core/rtw_cmd.o:rtw_cmd.c:(.text+0x64): first defined here
drivers/net/wireless/rtl8723bs/core/rtw_recv.o: In function `is_zero_mac_addr':
rtw_recv.c:(.text+0x27c): multiple definition of `is_zero_mac_addr'
drivers/net/wireless/rtl8723bs/core/rtw_cmd.o:rtw_cmd.c:(.text+0xe8): first defined here
drivers/net/wireless/rtl8723bs/core/rtw_sta_mgt.o: In function `is_multicast_mac_addr':
rtw_sta_mgt.c:(.text+0x0): multiple definition of `is_multicast_mac_addr'
drivers/net/wireless/rtl8723bs/core/rtw_cmd.o:rtw_cmd.c:(.text+0x44): first defined here
drivers/net/wireless/rtl8723bs/core/rtw_sta_mgt.o: In function `is_broadcast_mac_addr':
rtw_sta_mgt.c:(.text+0x20): multiple definition of `is_broadcast_mac_addr'
drivers/net/wireless/rtl8723bs/core/rtw_cmd.o:rtw_cmd.c:(.text+0x64): first defined here
drivers/net/wireless/rtl8723bs/core/rtw_sta_mgt.o: In function `is_zero_mac_addr':
rtw_sta_mgt.c:(.text+0xa4): multiple definition of `is_zero_mac_addr'
drivers/net/wireless/rtl8723bs/core/rtw_cmd.o:rtw_cmd.c:(.text+0xe8): first defined here
drivers/net/wireless/rtl8723bs/core/rtw_ap.o: In function `is_multicast_mac_addr':
rtw_ap.c:(.text+0x27c): multiple definition of `is_multicast_mac_addr'
drivers/net/wireless/rtl8723bs/core/rtw_cmd.o:rtw_cmd.c:(.text+0x44): first defined here
drivers/net/wireless/rtl8723bs/core/rtw_ap.o: In function `is_broadcast_mac_addr':
rtw_ap.c:(.text+0x29c): multiple definition of `is_broadcast_mac_addr'
drivers/net/wireless/rtl8723bs/core/rtw_cmd.o:rtw_cmd.c:(.text+0x64): first defined here
drivers/net/wireless/rtl8723bs/core/rtw_ap.o: In function `is_zero_mac_addr':
rtw_ap.c:(.text+0x320): multiple definition of `is_zero_mac_addr'
drivers/net/wireless/rtl8723bs/core/rtw_cmd.o:rtw_cmd.c:(.text+0xe8): first defined here
drivers/net/wireless/rtl8723bs/core/rtw_xmit.o: In function `is_multicast_mac_addr':
rtw_xmit.c:(.text+0xa4): multiple definition of `is_multicast_mac_addr'
drivers/net/wireless/rtl8723bs/core/rtw_cmd.o:rtw_cmd.c:(.text+0x44): first defined here
drivers/net/wireless/rtl8723bs/core/rtw_xmit.o: In function `is_broadcast_mac_addr':
rtw_xmit.c:(.text+0xc4): multiple definition of `is_broadcast_mac_addr'
drivers/net/wireless/rtl8723bs/core/rtw_cmd.o:rtw_cmd.c:(.text+0x64): first defined here
drivers/net/wireless/rtl8723bs/core/rtw_xmit.o: In function `is_zero_mac_addr':
rtw_xmit.c:(.text+0x148): multiple definition of `is_zero_mac_addr'
drivers/net/wireless/rtl8723bs/core/rtw_cmd.o:rtw_cmd.c:(.text+0xe8): first defined here
drivers/net/wireless/rtl8723bs/core/rtw_p2p.o: In function `is_multicast_mac_addr':
rtw_p2p.c:(.text+0x7dc): multiple definition of `is_multicast_mac_addr'
drivers/net/wireless/rtl8723bs/core/rtw_cmd.o:rtw_cmd.c:(.text+0x44): first defined here
drivers/net/wireless/rtl8723bs/core/rtw_p2p.o: In function `is_broadcast_mac_addr':
rtw_p2p.c:(.text+0x7fc): multiple definition of `is_broadcast_mac_addr'
drivers/net/wireless/rtl8723bs/core/rtw_cmd.o:rtw_cmd.c:(.text+0x64): first defined here
drivers/net/wireless/rtl8723bs/core/rtw_p2p.o: In function `is_zero_mac_addr':
rtw_p2p.c:(.text+0x880): multiple definition of `is_zero_mac_addr'
drivers/net/wireless/rtl8723bs/core/rtw_cmd.o:rtw_cmd.c:(.text+0xe8): first defined here
drivers/net/wireless/rtl8723bs/core/rtw_tdls.o: In function `is_multicast_mac_addr':
rtw_tdls.c:(.text+0x0): multiple definition of `is_multicast_mac_addr'
drivers/net/wireless/rtl8723bs/core/rtw_cmd.o:rtw_cmd.c:(.text+0x44): first defined here
drivers/net/wireless/rtl8723bs/core/rtw_tdls.o: In function `is_broadcast_mac_addr':
rtw_tdls.c:(.text+0x20): multiple definition of `is_broadcast_mac_addr'
drivers/net/wireless/rtl8723bs/core/rtw_cmd.o:rtw_cmd.c:(.text+0x64): first defined here
drivers/net/wireless/rtl8723bs/core/rtw_tdls.o: In function `is_zero_mac_addr':
rtw_tdls.c:(.text+0xa4): multiple definition of `is_zero_mac_addr'
drivers/net/wireless/rtl8723bs/core/rtw_cmd.o:rtw_cmd.c:(.text+0xe8): first defined here
drivers/net/wireless/rtl8723bs/core/rtw_br_ext.o: In function `is_multicast_mac_addr':
rtw_br_ext.c:(.text+0x0): multiple definition of `is_multicast_mac_addr'
drivers/net/wireless/rtl8723bs/core/rtw_cmd.o:rtw_cmd.c:(.text+0x44): first defined here
drivers/net/wireless/rtl8723bs/core/rtw_br_ext.o: In function `is_broadcast_mac_addr':
rtw_br_ext.c:(.text+0x20): multiple definition of `is_broadcast_mac_addr'
drivers/net/wireless/rtl8723bs/core/rtw_cmd.o:rtw_cmd.c:(.text+0x64): first defined here
drivers/net/wireless/rtl8723bs/core/rtw_br_ext.o: In function `is_zero_mac_addr':
rtw_br_ext.c:(.text+0xa4): multiple definition of `is_zero_mac_addr'
drivers/net/wireless/rtl8723bs/core/rtw_cmd.o:rtw_cmd.c:(.text+0xe8): first defined here
drivers/net/wireless/rtl8723bs/core/rtw_iol.o: In function `is_multicast_mac_addr':
rtw_iol.c:(.text+0x0): multiple definition of `is_multicast_mac_addr'
drivers/net/wireless/rtl8723bs/core/rtw_cmd.o:rtw_cmd.c:(.text+0x44): first defined here
drivers/net/wireless/rtl8723bs/core/rtw_iol.o: In function `is_broadcast_mac_addr':
rtw_iol.c:(.text+0x20): multiple definition of `is_broadcast_mac_addr'
drivers/net/wireless/rtl8723bs/core/rtw_cmd.o:rtw_cmd.c:(.text+0x64): first defined here
drivers/net/wireless/rtl8723bs/core/rtw_iol.o: In function `is_zero_mac_addr':
rtw_iol.c:(.text+0xa4): multiple definition of `is_zero_mac_addr'
drivers/net/wireless/rtl8723bs/core/rtw_cmd.o:rtw_cmd.c:(.text+0xe8): first defined here
drivers/net/wireless/rtl8723bs/core/rtw_sreset.o: In function `is_multicast_mac_addr':
rtw_sreset.c:(.text+0x0): multiple definition of `is_multicast_mac_addr'
drivers/net/wireless/rtl8723bs/core/rtw_cmd.o:rtw_cmd.c:(.text+0x44): first defined here
drivers/net/wireless/rtl8723bs/core/rtw_sreset.o: In function `is_broadcast_mac_addr':
rtw_sreset.c:(.text+0x20): multiple definition of `is_broadcast_mac_addr'
drivers/net/wireless/rtl8723bs/core/rtw_cmd.o:rtw_cmd.c:(.text+0x64): first defined here
drivers/net/wireless/rtl8723bs/core/rtw_sreset.o: In function `is_zero_mac_addr':
rtw_sreset.c:(.text+0xa4): multiple definition of `is_zero_mac_addr'
drivers/net/wireless/rtl8723bs/core/rtw_cmd.o:rtw_cmd.c:(.text+0xe8): first defined here
drivers/net/wireless/rtl8723bs/core/rtw_btcoex.o: In function `is_multicast_mac_addr':
rtw_btcoex.c:(.text+0x0): multiple definition of `is_multicast_mac_addr'
drivers/net/wireless/rtl8723bs/core/rtw_cmd.o:rtw_cmd.c:(.text+0x44): first defined here
drivers/net/wireless/rtl8723bs/core/rtw_btcoex.o: In function `is_broadcast_mac_addr':
rtw_btcoex.c:(.text+0x20): multiple definition of `is_broadcast_mac_addr'
drivers/net/wireless/rtl8723bs/core/rtw_cmd.o:rtw_cmd.c:(.text+0x64): first defined here
drivers/net/wireless/rtl8723bs/core/rtw_btcoex.o: In function `is_zero_mac_addr':
rtw_btcoex.c:(.text+0xa4): multiple definition of `is_zero_mac_addr'
drivers/net/wireless/rtl8723bs/core/rtw_cmd.o:rtw_cmd.c:(.text+0xe8): first defined here
drivers/net/wireless/rtl8723bs/core/rtw_beamforming.o: In function `is_multicast_mac_addr':
rtw_beamforming.c:(.text+0x0): multiple definition of `is_multicast_mac_addr'
drivers/net/wireless/rtl8723bs/core/rtw_cmd.o:rtw_cmd.c:(.text+0x44): first defined here
drivers/net/wireless/rtl8723bs/core/rtw_beamforming.o: In function `is_broadcast_mac_addr':
rtw_beamforming.c:(.text+0x20): multiple definition of `is_broadcast_mac_addr'
drivers/net/wireless/rtl8723bs/core/rtw_cmd.o:rtw_cmd.c:(.text+0x64): first defined here
drivers/net/wireless/rtl8723bs/core/rtw_beamforming.o: In function `is_zero_mac_addr':
rtw_beamforming.c:(.text+0xa4): multiple definition of `is_zero_mac_addr'
drivers/net/wireless/rtl8723bs/core/rtw_cmd.o:rtw_cmd.c:(.text+0xe8): first defined here
drivers/net/wireless/rtl8723bs/core/rtw_odm.o: In function `is_multicast_mac_addr':
rtw_odm.c:(.text+0x0): multiple definition of `is_multicast_mac_addr'
drivers/net/wireless/rtl8723bs/core/rtw_cmd.o:rtw_cmd.c:(.text+0x44): first defined here
drivers/net/wireless/rtl8723bs/core/rtw_odm.o: In function `is_broadcast_mac_addr':
rtw_odm.c:(.text+0x20): multiple definition of `is_broadcast_mac_addr'
drivers/net/wireless/rtl8723bs/core/rtw_cmd.o:rtw_cmd.c:(.text+0x64): first defined here
drivers/net/wireless/rtl8723bs/core/rtw_odm.o: In function `is_zero_mac_addr':
rtw_odm.c:(.text+0xa4): multiple definition of `is_zero_mac_addr'
drivers/net/wireless/rtl8723bs/core/rtw_cmd.o:rtw_cmd.c:(.text+0xe8): first defined here
drivers/net/wireless/rtl8723bs/core/efuse/rtw_efuse.o: In function `is_multicast_mac_addr':
rtw_efuse.c:(.text+0x0): multiple definition of `is_multicast_mac_addr'
drivers/net/wireless/rtl8723bs/core/rtw_cmd.o:rtw_cmd.c:(.text+0x44): first defined here
drivers/net/wireless/rtl8723bs/core/efuse/rtw_efuse.o: In function `is_broadcast_mac_addr':
rtw_efuse.c:(.text+0x20): multiple definition of `is_broadcast_mac_addr'
drivers/net/wireless/rtl8723bs/core/rtw_cmd.o:rtw_cmd.c:(.text+0x64): first defined here
drivers/net/wireless/rtl8723bs/core/efuse/rtw_efuse.o: In function `is_zero_mac_addr':
rtw_efuse.c:(.text+0xa4): multiple definition of `is_zero_mac_addr'
drivers/net/wireless/rtl8723bs/core/rtw_cmd.o:rtw_cmd.c:(.text+0xe8): first defined here
drivers/net/wireless/rtl8723bs/os_dep/osdep_service.o: In function `is_multicast_mac_addr':
osdep_service.c:(.text+0x98): multiple definition of `is_multicast_mac_addr'
drivers/net/wireless/rtl8723bs/core/rtw_cmd.o:rtw_cmd.c:(.text+0x44): first defined here
drivers/net/wireless/rtl8723bs/os_dep/osdep_service.o: In function `is_broadcast_mac_addr':
osdep_service.c:(.text+0xb8): multiple definition of `is_broadcast_mac_addr'
drivers/net/wireless/rtl8723bs/core/rtw_cmd.o:rtw_cmd.c:(.text+0x64): first defined here
drivers/net/wireless/rtl8723bs/os_dep/osdep_service.o: In function `is_zero_mac_addr':
osdep_service.c:(.text+0x13c): multiple definition of `is_zero_mac_addr'
drivers/net/wireless/rtl8723bs/core/rtw_cmd.o:rtw_cmd.c:(.text+0xe8): first defined here
drivers/net/wireless/rtl8723bs/os_dep/linux/os_intfs.o: In function `is_multicast_mac_addr':
os_intfs.c:(.text+0x42c): multiple definition of `is_multicast_mac_addr'
drivers/net/wireless/rtl8723bs/core/rtw_cmd.o:rtw_cmd.c:(.text+0x44): first defined here
drivers/net/wireless/rtl8723bs/os_dep/linux/os_intfs.o: In function `is_broadcast_mac_addr':
os_intfs.c:(.text+0x44c): multiple definition of `is_broadcast_mac_addr'
drivers/net/wireless/rtl8723bs/core/rtw_cmd.o:rtw_cmd.c:(.text+0x64): first defined here
drivers/net/wireless/rtl8723bs/os_dep/linux/os_intfs.o: In function `is_zero_mac_addr':
os_intfs.c:(.text+0x4d0): multiple definition of `is_zero_mac_addr'
drivers/net/wireless/rtl8723bs/core/rtw_cmd.o:rtw_cmd.c:(.text+0xe8): first defined here
drivers/net/wireless/rtl8723bs/os_dep/linux/sdio_intf.o: In function `is_multicast_mac_addr':
sdio_intf.c:(.text+0x608): multiple definition of `is_multicast_mac_addr'
drivers/net/wireless/rtl8723bs/core/rtw_cmd.o:rtw_cmd.c:(.text+0x44): first defined here
drivers/net/wireless/rtl8723bs/os_dep/linux/sdio_intf.o: In function `is_broadcast_mac_addr':
sdio_intf.c:(.text+0x628): multiple definition of `is_broadcast_mac_addr'
drivers/net/wireless/rtl8723bs/core/rtw_cmd.o:rtw_cmd.c:(.text+0x64): first defined here
drivers/net/wireless/rtl8723bs/os_dep/linux/sdio_intf.o: In function `is_zero_mac_addr':
sdio_intf.c:(.text+0x6ac): multiple definition of `is_zero_mac_addr'
drivers/net/wireless/rtl8723bs/core/rtw_cmd.o:rtw_cmd.c:(.text+0xe8): first defined here
drivers/net/wireless/rtl8723bs/os_dep/linux/sdio_ops_linux.o: In function `is_multicast_mac_addr':
sdio_ops_linux.c:(.text+0x44): multiple definition of `is_multicast_mac_addr'
drivers/net/wireless/rtl8723bs/core/rtw_cmd.o:rtw_cmd.c:(.text+0x44): first defined here
drivers/net/wireless/rtl8723bs/os_dep/linux/sdio_ops_linux.o: In function `is_broadcast_mac_addr':
sdio_ops_linux.c:(.text+0x64): multiple definition of `is_broadcast_mac_addr'
drivers/net/wireless/rtl8723bs/core/rtw_cmd.o:rtw_cmd.c:(.text+0x64): first defined here
drivers/net/wireless/rtl8723bs/os_dep/linux/sdio_ops_linux.o: In function `is_zero_mac_addr':
sdio_ops_linux.c:(.text+0xe8): multiple definition of `is_zero_mac_addr'
drivers/net/wireless/rtl8723bs/core/rtw_cmd.o:rtw_cmd.c:(.text+0xe8): first defined here
drivers/net/wireless/rtl8723bs/os_dep/linux/ioctl_linux.o: In function `is_multicast_mac_addr':
ioctl_linux.c:(.text+0xae14): multiple definition of `is_multicast_mac_addr'
drivers/net/wireless/rtl8723bs/core/rtw_cmd.o:rtw_cmd.c:(.text+0x44): first defined here
drivers/net/wireless/rtl8723bs/os_dep/linux/ioctl_linux.o: In function `is_broadcast_mac_addr':
ioctl_linux.c:(.text+0xae34): multiple definition of `is_broadcast_mac_addr'
drivers/net/wireless/rtl8723bs/core/rtw_cmd.o:rtw_cmd.c:(.text+0x64): first defined here
drivers/net/wireless/rtl8723bs/os_dep/linux/ioctl_linux.o: In function `is_zero_mac_addr':
ioctl_linux.c:(.text+0xaeb8): multiple definition of `is_zero_mac_addr'
drivers/net/wireless/rtl8723bs/core/rtw_cmd.o:rtw_cmd.c:(.text+0xe8): first defined here
drivers/net/wireless/rtl8723bs/os_dep/linux/xmit_linux.o: In function `is_multicast_mac_addr':
xmit_linux.c:(.text+0x0): multiple definition of `is_multicast_mac_addr'
drivers/net/wireless/rtl8723bs/core/rtw_cmd.o:rtw_cmd.c:(.text+0x44): first defined here
drivers/net/wireless/rtl8723bs/os_dep/linux/xmit_linux.o: In function `is_broadcast_mac_addr':
xmit_linux.c:(.text+0x20): multiple definition of `is_broadcast_mac_addr'
drivers/net/wireless/rtl8723bs/core/rtw_cmd.o:rtw_cmd.c:(.text+0x64): first defined here
drivers/net/wireless/rtl8723bs/os_dep/linux/xmit_linux.o: In function `is_zero_mac_addr':
xmit_linux.c:(.text+0xa4): multiple definition of `is_zero_mac_addr'
drivers/net/wireless/rtl8723bs/core/rtw_cmd.o:rtw_cmd.c:(.text+0xe8): first defined here
drivers/net/wireless/rtl8723bs/os_dep/linux/mlme_linux.o: In function `is_multicast_mac_addr':
mlme_linux.c:(.text+0x104): multiple definition of `is_multicast_mac_addr'
drivers/net/wireless/rtl8723bs/core/rtw_cmd.o:rtw_cmd.c:(.text+0x44): first defined here
drivers/net/wireless/rtl8723bs/os_dep/linux/mlme_linux.o: In function `is_broadcast_mac_addr':
mlme_linux.c:(.text+0x124): multiple definition of `is_broadcast_mac_addr'
drivers/net/wireless/rtl8723bs/core/rtw_cmd.o:rtw_cmd.c:(.text+0x64): first defined here
drivers/net/wireless/rtl8723bs/os_dep/linux/mlme_linux.o: In function `is_zero_mac_addr':
mlme_linux.c:(.text+0x1a8): multiple definition of `is_zero_mac_addr'
drivers/net/wireless/rtl8723bs/core/rtw_cmd.o:rtw_cmd.c:(.text+0xe8): first defined here
drivers/net/wireless/rtl8723bs/os_dep/linux/recv_linux.o: In function `is_multicast_mac_addr':
recv_linux.c:(.text+0x14): multiple definition of `is_multicast_mac_addr'
drivers/net/wireless/rtl8723bs/core/rtw_cmd.o:rtw_cmd.c:(.text+0x44): first defined here
drivers/net/wireless/rtl8723bs/os_dep/linux/recv_linux.o: In function `is_broadcast_mac_addr':
recv_linux.c:(.text+0x34): multiple definition of `is_broadcast_mac_addr'
drivers/net/wireless/rtl8723bs/core/rtw_cmd.o:rtw_cmd.c:(.text+0x64): first defined here
drivers/net/wireless/rtl8723bs/os_dep/linux/recv_linux.o: In function `is_zero_mac_addr':
recv_linux.c:(.text+0xb8): multiple definition of `is_zero_mac_addr'
drivers/net/wireless/rtl8723bs/core/rtw_cmd.o:rtw_cmd.c:(.text+0xe8): first defined here
drivers/net/wireless/rtl8723bs/os_dep/linux/ioctl_cfg80211.o: In function `is_multicast_mac_addr':
ioctl_cfg80211.c:(.text+0x3f8c): multiple definition of `is_multicast_mac_addr'
drivers/net/wireless/rtl8723bs/core/rtw_cmd.o:rtw_cmd.c:(.text+0x44): first defined here
drivers/net/wireless/rtl8723bs/os_dep/linux/ioctl_cfg80211.o: In function `is_broadcast_mac_addr':
ioctl_cfg80211.c:(.text+0x3fac): multiple definition of `is_broadcast_mac_addr'
drivers/net/wireless/rtl8723bs/core/rtw_cmd.o:rtw_cmd.c:(.text+0x64): first defined here
drivers/net/wireless/rtl8723bs/os_dep/linux/ioctl_cfg80211.o: In function `is_zero_mac_addr':
ioctl_cfg80211.c:(.text+0x4030): multiple definition of `is_zero_mac_addr'
drivers/net/wireless/rtl8723bs/core/rtw_cmd.o:rtw_cmd.c:(.text+0xe8): first defined here
drivers/net/wireless/rtl8723bs/os_dep/linux/wifi_regd.o: In function `is_multicast_mac_addr':
wifi_regd.c:(.text+0x154): multiple definition of `is_multicast_mac_addr'
drivers/net/wireless/rtl8723bs/core/rtw_cmd.o:rtw_cmd.c:(.text+0x44): first defined here
drivers/net/wireless/rtl8723bs/os_dep/linux/wifi_regd.o: In function `is_broadcast_mac_addr':
wifi_regd.c:(.text+0x174): multiple definition of `is_broadcast_mac_addr'
drivers/net/wireless/rtl8723bs/core/rtw_cmd.o:rtw_cmd.c:(.text+0x64): first defined here
drivers/net/wireless/rtl8723bs/os_dep/linux/wifi_regd.o: In function `is_zero_mac_addr':
wifi_regd.c:(.text+0x1f8): multiple definition of `is_zero_mac_addr'
drivers/net/wireless/rtl8723bs/core/rtw_cmd.o:rtw_cmd.c:(.text+0xe8): first defined here
drivers/net/wireless/rtl8723bs/os_dep/linux/rtw_android.o: In function `is_multicast_mac_addr':
rtw_android.c:(.text+0x0): multiple definition of `is_multicast_mac_addr'
drivers/net/wireless/rtl8723bs/core/rtw_cmd.o:rtw_cmd.c:(.text+0x44): first defined here
drivers/net/wireless/rtl8723bs/os_dep/linux/rtw_android.o: In function `is_broadcast_mac_addr':
rtw_android.c:(.text+0x20): multiple definition of `is_broadcast_mac_addr'
drivers/net/wireless/rtl8723bs/core/rtw_cmd.o:rtw_cmd.c:(.text+0x64): first defined here
drivers/net/wireless/rtl8723bs/os_dep/linux/rtw_android.o: In function `is_zero_mac_addr':
rtw_android.c:(.text+0xa4): multiple definition of `is_zero_mac_addr'
drivers/net/wireless/rtl8723bs/core/rtw_cmd.o:rtw_cmd.c:(.text+0xe8): first defined here
drivers/net/wireless/rtl8723bs/os_dep/linux/rtw_proc.o: In function `is_multicast_mac_addr':
rtw_proc.c:(.text+0xee8): multiple definition of `is_multicast_mac_addr'
drivers/net/wireless/rtl8723bs/core/rtw_cmd.o:rtw_cmd.c:(.text+0x44): first defined here
drivers/net/wireless/rtl8723bs/os_dep/linux/rtw_proc.o: In function `is_broadcast_mac_addr':
rtw_proc.c:(.text+0xf08): multiple definition of `is_broadcast_mac_addr'
drivers/net/wireless/rtl8723bs/core/rtw_cmd.o:rtw_cmd.c:(.text+0x64): first defined here
drivers/net/wireless/rtl8723bs/os_dep/linux/rtw_proc.o: In function `is_zero_mac_addr':
rtw_proc.c:(.text+0xf8c): multiple definition of `is_zero_mac_addr'
drivers/net/wireless/rtl8723bs/core/rtw_cmd.o:rtw_cmd.c:(.text+0xe8): first defined here
drivers/net/wireless/rtl8723bs/os_dep/linux/custom_gpio_linux.o: In function `is_multicast_mac_addr':
custom_gpio_linux.c:(.text+0x0): multiple definition of `is_multicast_mac_addr'
drivers/net/wireless/rtl8723bs/core/rtw_cmd.o:rtw_cmd.c:(.text+0x44): first defined here
drivers/net/wireless/rtl8723bs/os_dep/linux/custom_gpio_linux.o: In function `is_broadcast_mac_addr':
custom_gpio_linux.c:(.text+0x20): multiple definition of `is_broadcast_mac_addr'
drivers/net/wireless/rtl8723bs/core/rtw_cmd.o:rtw_cmd.c:(.text+0x64): first defined here
drivers/net/wireless/rtl8723bs/os_dep/linux/custom_gpio_linux.o: In function `is_zero_mac_addr':
custom_gpio_linux.c:(.text+0xa4): multiple definition of `is_zero_mac_addr'
drivers/net/wireless/rtl8723bs/core/rtw_cmd.o:rtw_cmd.c:(.text+0xe8): first defined here
drivers/net/wireless/rtl8723bs/hal/hal_intf.o: In function `is_multicast_mac_addr':
hal_intf.c:(.text+0x0): multiple definition of `is_multicast_mac_addr'
drivers/net/wireless/rtl8723bs/core/rtw_cmd.o:rtw_cmd.c:(.text+0x44): first defined here
drivers/net/wireless/rtl8723bs/hal/hal_intf.o: In function `is_broadcast_mac_addr':
hal_intf.c:(.text+0x20): multiple definition of `is_broadcast_mac_addr'
drivers/net/wireless/rtl8723bs/core/rtw_cmd.o:rtw_cmd.c:(.text+0x64): first defined here
drivers/net/wireless/rtl8723bs/hal/hal_intf.o: In function `is_zero_mac_addr':
hal_intf.c:(.text+0xa4): multiple definition of `is_zero_mac_addr'
drivers/net/wireless/rtl8723bs/core/rtw_cmd.o:rtw_cmd.c:(.text+0xe8): first defined here
drivers/net/wireless/rtl8723bs/hal/hal_com.o: In function `is_multicast_mac_addr':
hal_com.c:(.text+0x0): multiple definition of `is_multicast_mac_addr'
drivers/net/wireless/rtl8723bs/core/rtw_cmd.o:rtw_cmd.c:(.text+0x44): first defined here
drivers/net/wireless/rtl8723bs/hal/hal_com.o: In function `is_broadcast_mac_addr':
hal_com.c:(.text+0x20): multiple definition of `is_broadcast_mac_addr'
drivers/net/wireless/rtl8723bs/core/rtw_cmd.o:rtw_cmd.c:(.text+0x64): first defined here
drivers/net/wireless/rtl8723bs/hal/hal_com.o: In function `is_zero_mac_addr':
hal_com.c:(.text+0xa4): multiple definition of `is_zero_mac_addr'
drivers/net/wireless/rtl8723bs/core/rtw_cmd.o:rtw_cmd.c:(.text+0xe8): first defined here
drivers/net/wireless/rtl8723bs/hal/hal_com_phycfg.o: In function `is_multicast_mac_addr':
hal_com_phycfg.c:(.text+0x0): multiple definition of `is_multicast_mac_addr'
drivers/net/wireless/rtl8723bs/core/rtw_cmd.o:rtw_cmd.c:(.text+0x44): first defined here
drivers/net/wireless/rtl8723bs/hal/hal_com_phycfg.o: In function `is_broadcast_mac_addr':
hal_com_phycfg.c:(.text+0x20): multiple definition of `is_broadcast_mac_addr'
drivers/net/wireless/rtl8723bs/core/rtw_cmd.o:rtw_cmd.c:(.text+0x64): first defined here
drivers/net/wireless/rtl8723bs/hal/hal_com_phycfg.o: In function `is_zero_mac_addr':
hal_com_phycfg.c:(.text+0xa4): multiple definition of `is_zero_mac_addr'
drivers/net/wireless/rtl8723bs/core/rtw_cmd.o:rtw_cmd.c:(.text+0xe8): first defined here
drivers/net/wireless/rtl8723bs/hal/hal_phy.o: In function `is_multicast_mac_addr':
hal_phy.c:(.text+0x0): multiple definition of `is_multicast_mac_addr'
drivers/net/wireless/rtl8723bs/core/rtw_cmd.o:rtw_cmd.c:(.text+0x44): first defined here
drivers/net/wireless/rtl8723bs/hal/hal_phy.o: In function `is_broadcast_mac_addr':
hal_phy.c:(.text+0x20): multiple definition of `is_broadcast_mac_addr'
drivers/net/wireless/rtl8723bs/core/rtw_cmd.o:rtw_cmd.c:(.text+0x64): first defined here
drivers/net/wireless/rtl8723bs/hal/hal_phy.o: In function `is_zero_mac_addr':
hal_phy.c:(.text+0xa4): multiple definition of `is_zero_mac_addr'
drivers/net/wireless/rtl8723bs/core/rtw_cmd.o:rtw_cmd.c:(.text+0xe8): first defined here
drivers/net/wireless/rtl8723bs/hal/hal_btcoex.o: In function `is_multicast_mac_addr':
hal_btcoex.c:(.text+0x2c0): multiple definition of `is_multicast_mac_addr'
drivers/net/wireless/rtl8723bs/core/rtw_cmd.o:rtw_cmd.c:(.text+0x44): first defined here
drivers/net/wireless/rtl8723bs/hal/hal_btcoex.o: In function `is_broadcast_mac_addr':
hal_btcoex.c:(.text+0x2e0): multiple definition of `is_broadcast_mac_addr'
drivers/net/wireless/rtl8723bs/core/rtw_cmd.o:rtw_cmd.c:(.text+0x64): first defined here
drivers/net/wireless/rtl8723bs/hal/hal_btcoex.o: In function `is_zero_mac_addr':
hal_btcoex.c:(.text+0x364): multiple definition of `is_zero_mac_addr'
drivers/net/wireless/rtl8723bs/core/rtw_cmd.o:rtw_cmd.c:(.text+0xe8): first defined here
drivers/net/wireless/rtl8723bs/hal/hal_hci/hal_sdio.o: In function `is_multicast_mac_addr':
hal_sdio.c:(.text+0x0): multiple definition of `is_multicast_mac_addr'
drivers/net/wireless/rtl8723bs/core/rtw_cmd.o:rtw_cmd.c:(.text+0x44): first defined here
drivers/net/wireless/rtl8723bs/hal/hal_hci/hal_sdio.o: In function `is_broadcast_mac_addr':
hal_sdio.c:(.text+0x20): multiple definition of `is_broadcast_mac_addr'
drivers/net/wireless/rtl8723bs/core/rtw_cmd.o:rtw_cmd.c:(.text+0x64): first defined here
drivers/net/wireless/rtl8723bs/hal/hal_hci/hal_sdio.o: In function `is_zero_mac_addr':
hal_sdio.c:(.text+0xa4): multiple definition of `is_zero_mac_addr'
drivers/net/wireless/rtl8723bs/core/rtw_cmd.o:rtw_cmd.c:(.text+0xe8): first defined here
drivers/net/wireless/rtl8723bs/hal/led/hal_sdio_led.o: In function `is_multicast_mac_addr':
hal_sdio_led.c:(.text+0x3c): multiple definition of `is_multicast_mac_addr'
drivers/net/wireless/rtl8723bs/core/rtw_cmd.o:rtw_cmd.c:(.text+0x44): first defined here
drivers/net/wireless/rtl8723bs/hal/led/hal_sdio_led.o: In function `is_broadcast_mac_addr':
hal_sdio_led.c:(.text+0x5c): multiple definition of `is_broadcast_mac_addr'
drivers/net/wireless/rtl8723bs/core/rtw_cmd.o:rtw_cmd.c:(.text+0x64): first defined here
drivers/net/wireless/rtl8723bs/hal/led/hal_sdio_led.o: In function `is_zero_mac_addr':
hal_sdio_led.c:(.text+0xe0): multiple definition of `is_zero_mac_addr'
drivers/net/wireless/rtl8723bs/core/rtw_cmd.o:rtw_cmd.c:(.text+0xe8): first defined here
drivers/net/wireless/rtl8723bs/hal/HalPwrSeqCmd.o: In function `is_multicast_mac_addr':
HalPwrSeqCmd.c:(.text+0x0): multiple definition of `is_multicast_mac_addr'
drivers/net/wireless/rtl8723bs/core/rtw_cmd.o:rtw_cmd.c:(.text+0x44): first defined here
drivers/net/wireless/rtl8723bs/hal/HalPwrSeqCmd.o: In function `is_broadcast_mac_addr':
HalPwrSeqCmd.c:(.text+0x20): multiple definition of `is_broadcast_mac_addr'
drivers/net/wireless/rtl8723bs/core/rtw_cmd.o:rtw_cmd.c:(.text+0x64): first defined here
drivers/net/wireless/rtl8723bs/hal/HalPwrSeqCmd.o: In function `is_zero_mac_addr':
HalPwrSeqCmd.c:(.text+0xa4): multiple definition of `is_zero_mac_addr'
drivers/net/wireless/rtl8723bs/core/rtw_cmd.o:rtw_cmd.c:(.text+0xe8): first defined here
drivers/net/wireless/rtl8723bs/hal/rtl8723b/Hal8723BPwrSeq.o: In function `is_multicast_mac_addr':
Hal8723BPwrSeq.c:(.text+0x0): multiple definition of `is_multicast_mac_addr'
drivers/net/wireless/rtl8723bs/core/rtw_cmd.o:rtw_cmd.c:(.text+0x44): first defined here
drivers/net/wireless/rtl8723bs/hal/rtl8723b/Hal8723BPwrSeq.o: In function `is_broadcast_mac_addr':
Hal8723BPwrSeq.c:(.text+0x20): multiple definition of `is_broadcast_mac_addr'
drivers/net/wireless/rtl8723bs/core/rtw_cmd.o:rtw_cmd.c:(.text+0x64): first defined here
drivers/net/wireless/rtl8723bs/hal/rtl8723b/Hal8723BPwrSeq.o: In function `is_zero_mac_addr':
Hal8723BPwrSeq.c:(.text+0xa4): multiple definition of `is_zero_mac_addr'
drivers/net/wireless/rtl8723bs/core/rtw_cmd.o:rtw_cmd.c:(.text+0xe8): first defined here
drivers/net/wireless/rtl8723bs/hal/rtl8723b/rtl8723b_sreset.o: In function `is_multicast_mac_addr':
rtl8723b_sreset.c:(.text+0x0): multiple definition of `is_multicast_mac_addr'
drivers/net/wireless/rtl8723bs/core/rtw_cmd.o:rtw_cmd.c:(.text+0x44): first defined here
drivers/net/wireless/rtl8723bs/hal/rtl8723b/rtl8723b_sreset.o: In function `is_broadcast_mac_addr':
rtl8723b_sreset.c:(.text+0x20): multiple definition of `is_broadcast_mac_addr'
drivers/net/wireless/rtl8723bs/core/rtw_cmd.o:rtw_cmd.c:(.text+0x64): first defined here
drivers/net/wireless/rtl8723bs/hal/rtl8723b/rtl8723b_sreset.o: In function `is_zero_mac_addr':
rtl8723b_sreset.c:(.text+0xa4): multiple definition of `is_zero_mac_addr'
drivers/net/wireless/rtl8723bs/core/rtw_cmd.o:rtw_cmd.c:(.text+0xe8): first defined here
drivers/net/wireless/rtl8723bs/hal/rtl8723b/rtl8723b_hal_init.o: In function `is_multicast_mac_addr':
rtl8723b_hal_init.c:(.text+0x21ec): multiple definition of `is_multicast_mac_addr'
drivers/net/wireless/rtl8723bs/core/rtw_cmd.o:rtw_cmd.c:(.text+0x44): first defined here
drivers/net/wireless/rtl8723bs/hal/rtl8723b/rtl8723b_hal_init.o: In function `is_broadcast_mac_addr':
rtl8723b_hal_init.c:(.text+0x220c): multiple definition of `is_broadcast_mac_addr'
drivers/net/wireless/rtl8723bs/core/rtw_cmd.o:rtw_cmd.c:(.text+0x64): first defined here
drivers/net/wireless/rtl8723bs/hal/rtl8723b/rtl8723b_hal_init.o: In function `is_zero_mac_addr':
rtl8723b_hal_init.c:(.text+0x2290): multiple definition of `is_zero_mac_addr'
drivers/net/wireless/rtl8723bs/core/rtw_cmd.o:rtw_cmd.c:(.text+0xe8): first defined here
drivers/net/wireless/rtl8723bs/hal/rtl8723b/rtl8723b_phycfg.o: In function `is_multicast_mac_addr':
rtl8723b_phycfg.c:(.text+0x558): multiple definition of `is_multicast_mac_addr'
drivers/net/wireless/rtl8723bs/core/rtw_cmd.o:rtw_cmd.c:(.text+0x44): first defined here
drivers/net/wireless/rtl8723bs/hal/rtl8723b/rtl8723b_phycfg.o: In function `is_broadcast_mac_addr':
rtl8723b_phycfg.c:(.text+0x578): multiple definition of `is_broadcast_mac_addr'
drivers/net/wireless/rtl8723bs/core/rtw_cmd.o:rtw_cmd.c:(.text+0x64): first defined here
drivers/net/wireless/rtl8723bs/hal/rtl8723b/rtl8723b_phycfg.o: In function `is_zero_mac_addr':
rtl8723b_phycfg.c:(.text+0x5fc): multiple definition of `is_zero_mac_addr'
drivers/net/wireless/rtl8723bs/core/rtw_cmd.o:rtw_cmd.c:(.text+0xe8): first defined here
drivers/net/wireless/rtl8723bs/hal/rtl8723b/rtl8723b_rf6052.o: In function `is_multicast_mac_addr':
rtl8723b_rf6052.c:(.text+0x0): multiple definition of `is_multicast_mac_addr'
drivers/net/wireless/rtl8723bs/core/rtw_cmd.o:rtw_cmd.c:(.text+0x44): first defined here
drivers/net/wireless/rtl8723bs/hal/rtl8723b/rtl8723b_rf6052.o: In function `is_broadcast_mac_addr':
rtl8723b_rf6052.c:(.text+0x20): multiple definition of `is_broadcast_mac_addr'
drivers/net/wireless/rtl8723bs/core/rtw_cmd.o:rtw_cmd.c:(.text+0x64): first defined here
drivers/net/wireless/rtl8723bs/hal/rtl8723b/rtl8723b_rf6052.o: In function `is_zero_mac_addr':
rtl8723b_rf6052.c:(.text+0xa4): multiple definition of `is_zero_mac_addr'
drivers/net/wireless/rtl8723bs/core/rtw_cmd.o:rtw_cmd.c:(.text+0xe8): first defined here
drivers/net/wireless/rtl8723bs/hal/rtl8723b/rtl8723b_dm.o: In function `is_multicast_mac_addr':
rtl8723b_dm.c:(.text+0x0): multiple definition of `is_multicast_mac_addr'
drivers/net/wireless/rtl8723bs/core/rtw_cmd.o:rtw_cmd.c:(.text+0x44): first defined here
drivers/net/wireless/rtl8723bs/hal/rtl8723b/rtl8723b_dm.o: In function `is_broadcast_mac_addr':
rtl8723b_dm.c:(.text+0x20): multiple definition of `is_broadcast_mac_addr'
drivers/net/wireless/rtl8723bs/core/rtw_cmd.o:rtw_cmd.c:(.text+0x64): first defined here
drivers/net/wireless/rtl8723bs/hal/rtl8723b/rtl8723b_dm.o: In function `is_zero_mac_addr':
rtl8723b_dm.c:(.text+0xa4): multiple definition of `is_zero_mac_addr'
drivers/net/wireless/rtl8723bs/core/rtw_cmd.o:rtw_cmd.c:(.text+0xe8): first defined here
drivers/net/wireless/rtl8723bs/hal/rtl8723b/rtl8723b_rxdesc.o: In function `is_multicast_mac_addr':
rtl8723b_rxdesc.c:(.text+0x0): multiple definition of `is_multicast_mac_addr'
drivers/net/wireless/rtl8723bs/core/rtw_cmd.o:rtw_cmd.c:(.text+0x44): first defined here
drivers/net/wireless/rtl8723bs/hal/rtl8723b/rtl8723b_rxdesc.o: In function `is_broadcast_mac_addr':
rtl8723b_rxdesc.c:(.text+0x20): multiple definition of `is_broadcast_mac_addr'
drivers/net/wireless/rtl8723bs/core/rtw_cmd.o:rtw_cmd.c:(.text+0x64): first defined here
drivers/net/wireless/rtl8723bs/hal/rtl8723b/rtl8723b_rxdesc.o: In function `is_zero_mac_addr':
rtl8723b_rxdesc.c:(.text+0xa4): multiple definition of `is_zero_mac_addr'
drivers/net/wireless/rtl8723bs/core/rtw_cmd.o:rtw_cmd.c:(.text+0xe8): first defined here
drivers/net/wireless/rtl8723bs/hal/rtl8723b/rtl8723b_cmd.o: In function `is_multicast_mac_addr':
rtl8723b_cmd.c:(.text+0x3b4): multiple definition of `is_multicast_mac_addr'
drivers/net/wireless/rtl8723bs/core/rtw_cmd.o:rtw_cmd.c:(.text+0x44): first defined here
drivers/net/wireless/rtl8723bs/hal/rtl8723b/rtl8723b_cmd.o: In function `is_broadcast_mac_addr':
rtl8723b_cmd.c:(.text+0x3d4): multiple definition of `is_broadcast_mac_addr'
drivers/net/wireless/rtl8723bs/core/rtw_cmd.o:rtw_cmd.c:(.text+0x64): first defined here
drivers/net/wireless/rtl8723bs/hal/rtl8723b/rtl8723b_cmd.o: In function `is_zero_mac_addr':
rtl8723b_cmd.c:(.text+0x458): multiple definition of `is_zero_mac_addr'
drivers/net/wireless/rtl8723bs/core/rtw_cmd.o:rtw_cmd.c:(.text+0xe8): first defined here
drivers/net/wireless/rtl8723bs/hal/rtl8723b/sdio/sdio_halinit.o: In function `is_multicast_mac_addr':
sdio_halinit.c:(.text+0x914): multiple definition of `is_multicast_mac_addr'
drivers/net/wireless/rtl8723bs/core/rtw_cmd.o:rtw_cmd.c:(.text+0x44): first defined here
drivers/net/wireless/rtl8723bs/hal/rtl8723b/sdio/sdio_halinit.o: In function `is_broadcast_mac_addr':
sdio_halinit.c:(.text+0x934): multiple definition of `is_broadcast_mac_addr'
drivers/net/wireless/rtl8723bs/core/rtw_cmd.o:rtw_cmd.c:(.text+0x64): first defined here
drivers/net/wireless/rtl8723bs/hal/rtl8723b/sdio/sdio_halinit.o: In function `is_zero_mac_addr':
sdio_halinit.c:(.text+0x9b8): multiple definition of `is_zero_mac_addr'
drivers/net/wireless/rtl8723bs/core/rtw_cmd.o:rtw_cmd.c:(.text+0xe8): first defined here
drivers/net/wireless/rtl8723bs/hal/rtl8723b/sdio/rtl8723bs_led.o: In function `is_multicast_mac_addr':
rtl8723bs_led.c:(.text+0x0): multiple definition of `is_multicast_mac_addr'
drivers/net/wireless/rtl8723bs/core/rtw_cmd.o:rtw_cmd.c:(.text+0x44): first defined here
drivers/net/wireless/rtl8723bs/hal/rtl8723b/sdio/rtl8723bs_led.o: In function `is_broadcast_mac_addr':
rtl8723bs_led.c:(.text+0x20): multiple definition of `is_broadcast_mac_addr'
drivers/net/wireless/rtl8723bs/core/rtw_cmd.o:rtw_cmd.c:(.text+0x64): first defined here
drivers/net/wireless/rtl8723bs/hal/rtl8723b/sdio/rtl8723bs_led.o: In function `is_zero_mac_addr':
rtl8723bs_led.c:(.text+0xa4): multiple definition of `is_zero_mac_addr'
drivers/net/wireless/rtl8723bs/core/rtw_cmd.o:rtw_cmd.c:(.text+0xe8): first defined here
drivers/net/wireless/rtl8723bs/hal/rtl8723b/sdio/rtl8723bs_xmit.o: In function `is_multicast_mac_addr':
rtl8723bs_xmit.c:(.text+0x2ec): multiple definition of `is_multicast_mac_addr'
drivers/net/wireless/rtl8723bs/core/rtw_cmd.o:rtw_cmd.c:(.text+0x44): first defined here
drivers/net/wireless/rtl8723bs/hal/rtl8723b/sdio/rtl8723bs_xmit.o: In function `is_broadcast_mac_addr':
rtl8723bs_xmit.c:(.text+0x30c): multiple definition of `is_broadcast_mac_addr'
drivers/net/wireless/rtl8723bs/core/rtw_cmd.o:rtw_cmd.c:(.text+0x64): first defined here
drivers/net/wireless/rtl8723bs/hal/rtl8723b/sdio/rtl8723bs_xmit.o: In function `is_zero_mac_addr':
rtl8723bs_xmit.c:(.text+0x390): multiple definition of `is_zero_mac_addr'
drivers/net/wireless/rtl8723bs/core/rtw_cmd.o:rtw_cmd.c:(.text+0xe8): first defined here
drivers/net/wireless/rtl8723bs/hal/rtl8723b/sdio/rtl8723bs_recv.o: In function `is_multicast_mac_addr':
rtl8723bs_recv.c:(.text+0x0): multiple definition of `is_multicast_mac_addr'
drivers/net/wireless/rtl8723bs/core/rtw_cmd.o:rtw_cmd.c:(.text+0x44): first defined here
drivers/net/wireless/rtl8723bs/hal/rtl8723b/sdio/rtl8723bs_recv.o: In function `is_broadcast_mac_addr':
rtl8723bs_recv.c:(.text+0x20): multiple definition of `is_broadcast_mac_addr'
drivers/net/wireless/rtl8723bs/core/rtw_cmd.o:rtw_cmd.c:(.text+0x64): first defined here
drivers/net/wireless/rtl8723bs/hal/rtl8723b/sdio/rtl8723bs_recv.o: In function `is_zero_mac_addr':
rtl8723bs_recv.c:(.text+0xa4): multiple definition of `is_zero_mac_addr'
drivers/net/wireless/rtl8723bs/core/rtw_cmd.o:rtw_cmd.c:(.text+0xe8): first defined here
drivers/net/wireless/rtl8723bs/hal/rtl8723b/sdio/sdio_ops.o: In function `is_multicast_mac_addr':
sdio_ops.c:(.text+0x728): multiple definition of `is_multicast_mac_addr'
drivers/net/wireless/rtl8723bs/core/rtw_cmd.o:rtw_cmd.c:(.text+0x44): first defined here
drivers/net/wireless/rtl8723bs/hal/rtl8723b/sdio/sdio_ops.o: In function `is_broadcast_mac_addr':
sdio_ops.c:(.text+0x748): multiple definition of `is_broadcast_mac_addr'
drivers/net/wireless/rtl8723bs/core/rtw_cmd.o:rtw_cmd.c:(.text+0x64): first defined here
drivers/net/wireless/rtl8723bs/hal/rtl8723b/sdio/sdio_ops.o: In function `is_zero_mac_addr':
sdio_ops.c:(.text+0x7cc): multiple definition of `is_zero_mac_addr'
drivers/net/wireless/rtl8723bs/core/rtw_cmd.o:rtw_cmd.c:(.text+0xe8): first defined here
drivers/net/wireless/rtl8723bs/hal/rtl8723b/rtl8723b_mp.o: In function `is_multicast_mac_addr':
rtl8723b_mp.c:(.text+0x0): multiple definition of `is_multicast_mac_addr'
drivers/net/wireless/rtl8723bs/core/rtw_cmd.o:rtw_cmd.c:(.text+0x44): first defined here
drivers/net/wireless/rtl8723bs/hal/rtl8723b/rtl8723b_mp.o: In function `is_broadcast_mac_addr':
rtl8723b_mp.c:(.text+0x20): multiple definition of `is_broadcast_mac_addr'
drivers/net/wireless/rtl8723bs/core/rtw_cmd.o:rtw_cmd.c:(.text+0x64): first defined here
drivers/net/wireless/rtl8723bs/hal/rtl8723b/rtl8723b_mp.o: In function `is_zero_mac_addr':
rtl8723b_mp.c:(.text+0xa4): multiple definition of `is_zero_mac_addr'
drivers/net/wireless/rtl8723bs/core/rtw_cmd.o:rtw_cmd.c:(.text+0xe8): first defined here
drivers/net/wireless/rtl8723bs/hal/OUTSRC/odm_debug.o: In function `is_multicast_mac_addr':
odm_debug.c:(.text+0x0): multiple definition of `is_multicast_mac_addr'
drivers/net/wireless/rtl8723bs/core/rtw_cmd.o:rtw_cmd.c:(.text+0x44): first defined here
drivers/net/wireless/rtl8723bs/hal/OUTSRC/odm_debug.o: In function `is_broadcast_mac_addr':
odm_debug.c:(.text+0x20): multiple definition of `is_broadcast_mac_addr'
drivers/net/wireless/rtl8723bs/core/rtw_cmd.o:rtw_cmd.c:(.text+0x64): first defined here
drivers/net/wireless/rtl8723bs/hal/OUTSRC/odm_debug.o: In function `is_zero_mac_addr':
odm_debug.c:(.text+0xa4): multiple definition of `is_zero_mac_addr'
drivers/net/wireless/rtl8723bs/core/rtw_cmd.o:rtw_cmd.c:(.text+0xe8): first defined here
drivers/net/wireless/rtl8723bs/hal/OUTSRC/odm_AntDiv.o: In function `is_multicast_mac_addr':
odm_AntDiv.c:(.text+0x0): multiple definition of `is_multicast_mac_addr'
drivers/net/wireless/rtl8723bs/core/rtw_cmd.o:rtw_cmd.c:(.text+0x44): first defined here
drivers/net/wireless/rtl8723bs/hal/OUTSRC/odm_AntDiv.o: In function `is_broadcast_mac_addr':
odm_AntDiv.c:(.text+0x20): multiple definition of `is_broadcast_mac_addr'
drivers/net/wireless/rtl8723bs/core/rtw_cmd.o:rtw_cmd.c:(.text+0x64): first defined here
drivers/net/wireless/rtl8723bs/hal/OUTSRC/odm_AntDiv.o: In function `is_zero_mac_addr':
odm_AntDiv.c:(.text+0xa4): multiple definition of `is_zero_mac_addr'
drivers/net/wireless/rtl8723bs/core/rtw_cmd.o:rtw_cmd.c:(.text+0xe8): first defined here
drivers/net/wireless/rtl8723bs/hal/OUTSRC/odm_interface.o: In function `is_multicast_mac_addr':
odm_interface.c:(.text+0x0): multiple definition of `is_multicast_mac_addr'
drivers/net/wireless/rtl8723bs/core/rtw_cmd.o:rtw_cmd.c:(.text+0x44): first defined here
drivers/net/wireless/rtl8723bs/hal/OUTSRC/odm_interface.o: In function `is_broadcast_mac_addr':
odm_interface.c:(.text+0x20): multiple definition of `is_broadcast_mac_addr'
drivers/net/wireless/rtl8723bs/core/rtw_cmd.o:rtw_cmd.c:(.text+0x64): first defined here
drivers/net/wireless/rtl8723bs/hal/OUTSRC/odm_interface.o: In function `is_zero_mac_addr':
odm_interface.c:(.text+0xa4): multiple definition of `is_zero_mac_addr'
drivers/net/wireless/rtl8723bs/core/rtw_cmd.o:rtw_cmd.c:(.text+0xe8): first defined here
drivers/net/wireless/rtl8723bs/hal/OUTSRC/odm_HWConfig.o: In function `is_multicast_mac_addr':
odm_HWConfig.c:(.text+0x38): multiple definition of `is_multicast_mac_addr'
drivers/net/wireless/rtl8723bs/core/rtw_cmd.o:rtw_cmd.c:(.text+0x44): first defined here
drivers/net/wireless/rtl8723bs/hal/OUTSRC/odm_HWConfig.o: In function `is_broadcast_mac_addr':
odm_HWConfig.c:(.text+0x58): multiple definition of `is_broadcast_mac_addr'
drivers/net/wireless/rtl8723bs/core/rtw_cmd.o:rtw_cmd.c:(.text+0x64): first defined here
drivers/net/wireless/rtl8723bs/hal/OUTSRC/odm_HWConfig.o: In function `is_zero_mac_addr':
odm_HWConfig.c:(.text+0xdc): multiple definition of `is_zero_mac_addr'
drivers/net/wireless/rtl8723bs/core/rtw_cmd.o:rtw_cmd.c:(.text+0xe8): first defined here
drivers/net/wireless/rtl8723bs/hal/OUTSRC/odm.o: In function `is_multicast_mac_addr':
odm.c:(.text+0x0): multiple definition of `is_multicast_mac_addr'
drivers/net/wireless/rtl8723bs/core/rtw_cmd.o:rtw_cmd.c:(.text+0x44): first defined here
drivers/net/wireless/rtl8723bs/hal/OUTSRC/odm.o: In function `is_broadcast_mac_addr':
odm.c:(.text+0x20): multiple definition of `is_broadcast_mac_addr'
drivers/net/wireless/rtl8723bs/core/rtw_cmd.o:rtw_cmd.c:(.text+0x64): first defined here
drivers/net/wireless/rtl8723bs/hal/OUTSRC/odm.o: In function `is_zero_mac_addr':
odm.c:(.text+0xa4): multiple definition of `is_zero_mac_addr'
drivers/net/wireless/rtl8723bs/core/rtw_cmd.o:rtw_cmd.c:(.text+0xe8): first defined here
drivers/net/wireless/rtl8723bs/hal/OUTSRC/HalPhyRf.o: In function `is_multicast_mac_addr':
HalPhyRf.c:(.text+0x0): multiple definition of `is_multicast_mac_addr'
drivers/net/wireless/rtl8723bs/core/rtw_cmd.o:rtw_cmd.c:(.text+0x44): first defined here
drivers/net/wireless/rtl8723bs/hal/OUTSRC/HalPhyRf.o: In function `is_broadcast_mac_addr':
HalPhyRf.c:(.text+0x20): multiple definition of `is_broadcast_mac_addr'
drivers/net/wireless/rtl8723bs/core/rtw_cmd.o:rtw_cmd.c:(.text+0x64): first defined here
drivers/net/wireless/rtl8723bs/hal/OUTSRC/HalPhyRf.o: In function `is_zero_mac_addr':
HalPhyRf.c:(.text+0xa4): multiple definition of `is_zero_mac_addr'
drivers/net/wireless/rtl8723bs/core/rtw_cmd.o:rtw_cmd.c:(.text+0xe8): first defined here
drivers/net/wireless/rtl8723bs/hal/OUTSRC-BTCoexist/HalBtc8188c2Ant.o: In function `is_multicast_mac_addr':
HalBtc8188c2Ant.c:(.text+0x0): multiple definition of `is_multicast_mac_addr'
drivers/net/wireless/rtl8723bs/core/rtw_cmd.o:rtw_cmd.c:(.text+0x44): first defined here
drivers/net/wireless/rtl8723bs/hal/OUTSRC-BTCoexist/HalBtc8188c2Ant.o: In function `is_broadcast_mac_addr':
HalBtc8188c2Ant.c:(.text+0x20): multiple definition of `is_broadcast_mac_addr'
drivers/net/wireless/rtl8723bs/core/rtw_cmd.o:rtw_cmd.c:(.text+0x64): first defined here
drivers/net/wireless/rtl8723bs/hal/OUTSRC-BTCoexist/HalBtc8188c2Ant.o: In function `is_zero_mac_addr':
HalBtc8188c2Ant.c:(.text+0xa4): multiple definition of `is_zero_mac_addr'
drivers/net/wireless/rtl8723bs/core/rtw_cmd.o:rtw_cmd.c:(.text+0xe8): first defined here
drivers/net/wireless/rtl8723bs/hal/OUTSRC-BTCoexist/HalBtc8192d2Ant.o: In function `is_multicast_mac_addr':
HalBtc8192d2Ant.c:(.text+0x0): multiple definition of `is_multicast_mac_addr'
drivers/net/wireless/rtl8723bs/core/rtw_cmd.o:rtw_cmd.c:(.text+0x44): first defined here
drivers/net/wireless/rtl8723bs/hal/OUTSRC-BTCoexist/HalBtc8192d2Ant.o: In function `is_broadcast_mac_addr':
HalBtc8192d2Ant.c:(.text+0x20): multiple definition of `is_broadcast_mac_addr'
drivers/net/wireless/rtl8723bs/core/rtw_cmd.o:rtw_cmd.c:(.text+0x64): first defined here
drivers/net/wireless/rtl8723bs/hal/OUTSRC-BTCoexist/HalBtc8192d2Ant.o: In function `is_zero_mac_addr':
HalBtc8192d2Ant.c:(.text+0xa4): multiple definition of `is_zero_mac_addr'
drivers/net/wireless/rtl8723bs/core/rtw_cmd.o:rtw_cmd.c:(.text+0xe8): first defined here
drivers/net/wireless/rtl8723bs/hal/OUTSRC-BTCoexist/HalBtc8192e1Ant.o: In function `is_multicast_mac_addr':
HalBtc8192e1Ant.c:(.text+0x0): multiple definition of `is_multicast_mac_addr'
drivers/net/wireless/rtl8723bs/core/rtw_cmd.o:rtw_cmd.c:(.text+0x44): first defined here
drivers/net/wireless/rtl8723bs/hal/OUTSRC-BTCoexist/HalBtc8192e1Ant.o: In function `is_broadcast_mac_addr':
HalBtc8192e1Ant.c:(.text+0x20): multiple definition of `is_broadcast_mac_addr'
drivers/net/wireless/rtl8723bs/core/rtw_cmd.o:rtw_cmd.c:(.text+0x64): first defined here
drivers/net/wireless/rtl8723bs/hal/OUTSRC-BTCoexist/HalBtc8192e1Ant.o: In function `is_zero_mac_addr':
HalBtc8192e1Ant.c:(.text+0xa4): multiple definition of `is_zero_mac_addr'
drivers/net/wireless/rtl8723bs/core/rtw_cmd.o:rtw_cmd.c:(.text+0xe8): first defined here
drivers/net/wireless/rtl8723bs/hal/OUTSRC-BTCoexist/HalBtc8192e2Ant.o: In function `is_multicast_mac_addr':
HalBtc8192e2Ant.c:(.text+0x0): multiple definition of `is_multicast_mac_addr'
drivers/net/wireless/rtl8723bs/core/rtw_cmd.o:rtw_cmd.c:(.text+0x44): first defined here
drivers/net/wireless/rtl8723bs/hal/OUTSRC-BTCoexist/HalBtc8192e2Ant.o: In function `is_broadcast_mac_addr':
HalBtc8192e2Ant.c:(.text+0x20): multiple definition of `is_broadcast_mac_addr'
drivers/net/wireless/rtl8723bs/core/rtw_cmd.o:rtw_cmd.c:(.text+0x64): first defined here
drivers/net/wireless/rtl8723bs/hal/OUTSRC-BTCoexist/HalBtc8192e2Ant.o: In function `is_zero_mac_addr':
HalBtc8192e2Ant.c:(.text+0xa4): multiple definition of `is_zero_mac_addr'
drivers/net/wireless/rtl8723bs/core/rtw_cmd.o:rtw_cmd.c:(.text+0xe8): first defined here
drivers/net/wireless/rtl8723bs/hal/OUTSRC-BTCoexist/HalBtc8723a1Ant.o: In function `is_multicast_mac_addr':
HalBtc8723a1Ant.c:(.text+0x0): multiple definition of `is_multicast_mac_addr'
drivers/net/wireless/rtl8723bs/core/rtw_cmd.o:rtw_cmd.c:(.text+0x44): first defined here
drivers/net/wireless/rtl8723bs/hal/OUTSRC-BTCoexist/HalBtc8723a1Ant.o: In function `is_broadcast_mac_addr':
HalBtc8723a1Ant.c:(.text+0x20): multiple definition of `is_broadcast_mac_addr'
drivers/net/wireless/rtl8723bs/core/rtw_cmd.o:rtw_cmd.c:(.text+0x64): first defined here
drivers/net/wireless/rtl8723bs/hal/OUTSRC-BTCoexist/HalBtc8723a1Ant.o: In function `is_zero_mac_addr':
HalBtc8723a1Ant.c:(.text+0xa4): multiple definition of `is_zero_mac_addr'
drivers/net/wireless/rtl8723bs/core/rtw_cmd.o:rtw_cmd.c:(.text+0xe8): first defined here
drivers/net/wireless/rtl8723bs/hal/OUTSRC-BTCoexist/HalBtc8723a2Ant.o: In function `is_multicast_mac_addr':
HalBtc8723a2Ant.c:(.text+0x0): multiple definition of `is_multicast_mac_addr'
drivers/net/wireless/rtl8723bs/core/rtw_cmd.o:rtw_cmd.c:(.text+0x44): first defined here
drivers/net/wireless/rtl8723bs/hal/OUTSRC-BTCoexist/HalBtc8723a2Ant.o: In function `is_broadcast_mac_addr':
HalBtc8723a2Ant.c:(.text+0x20): multiple definition of `is_broadcast_mac_addr'
drivers/net/wireless/rtl8723bs/core/rtw_cmd.o:rtw_cmd.c:(.text+0x64): first defined here
drivers/net/wireless/rtl8723bs/hal/OUTSRC-BTCoexist/HalBtc8723a2Ant.o: In function `is_zero_mac_addr':
HalBtc8723a2Ant.c:(.text+0xa4): multiple definition of `is_zero_mac_addr'
drivers/net/wireless/rtl8723bs/core/rtw_cmd.o:rtw_cmd.c:(.text+0xe8): first defined here
drivers/net/wireless/rtl8723bs/hal/OUTSRC-BTCoexist/HalBtc8723b1Ant.o: In function `is_multicast_mac_addr':
HalBtc8723b1Ant.c:(.text+0x0): multiple definition of `is_multicast_mac_addr'
drivers/net/wireless/rtl8723bs/core/rtw_cmd.o:rtw_cmd.c:(.text+0x44): first defined here
drivers/net/wireless/rtl8723bs/hal/OUTSRC-BTCoexist/HalBtc8723b1Ant.o: In function `is_broadcast_mac_addr':
HalBtc8723b1Ant.c:(.text+0x20): multiple definition of `is_broadcast_mac_addr'
drivers/net/wireless/rtl8723bs/core/rtw_cmd.o:rtw_cmd.c:(.text+0x64): first defined here
drivers/net/wireless/rtl8723bs/hal/OUTSRC-BTCoexist/HalBtc8723b1Ant.o: In function `is_zero_mac_addr':
HalBtc8723b1Ant.c:(.text+0xa4): multiple definition of `is_zero_mac_addr'
drivers/net/wireless/rtl8723bs/core/rtw_cmd.o:rtw_cmd.c:(.text+0xe8): first defined here
drivers/net/wireless/rtl8723bs/hal/OUTSRC-BTCoexist/HalBtc8723b2Ant.o: In function `is_multicast_mac_addr':
HalBtc8723b2Ant.c:(.text+0x0): multiple definition of `is_multicast_mac_addr'
drivers/net/wireless/rtl8723bs/core/rtw_cmd.o:rtw_cmd.c:(.text+0x44): first defined here
drivers/net/wireless/rtl8723bs/hal/OUTSRC-BTCoexist/HalBtc8723b2Ant.o: In function `is_broadcast_mac_addr':
HalBtc8723b2Ant.c:(.text+0x20): multiple definition of `is_broadcast_mac_addr'
drivers/net/wireless/rtl8723bs/core/rtw_cmd.o:rtw_cmd.c:(.text+0x64): first defined here
drivers/net/wireless/rtl8723bs/hal/OUTSRC-BTCoexist/HalBtc8723b2Ant.o: In function `is_zero_mac_addr':
HalBtc8723b2Ant.c:(.text+0xa4): multiple definition of `is_zero_mac_addr'
drivers/net/wireless/rtl8723bs/core/rtw_cmd.o:rtw_cmd.c:(.text+0xe8): first defined here
drivers/net/wireless/rtl8723bs/hal/OUTSRC-BTCoexist/HalBtc8812a1Ant.o: In function `is_multicast_mac_addr':
HalBtc8812a1Ant.c:(.text+0x0): multiple definition of `is_multicast_mac_addr'
drivers/net/wireless/rtl8723bs/core/rtw_cmd.o:rtw_cmd.c:(.text+0x44): first defined here
drivers/net/wireless/rtl8723bs/hal/OUTSRC-BTCoexist/HalBtc8812a1Ant.o: In function `is_broadcast_mac_addr':
HalBtc8812a1Ant.c:(.text+0x20): multiple definition of `is_broadcast_mac_addr'
drivers/net/wireless/rtl8723bs/core/rtw_cmd.o:rtw_cmd.c:(.text+0x64): first defined here
drivers/net/wireless/rtl8723bs/hal/OUTSRC-BTCoexist/HalBtc8812a1Ant.o: In function `is_zero_mac_addr':
HalBtc8812a1Ant.c:(.text+0xa4): multiple definition of `is_zero_mac_addr'
drivers/net/wireless/rtl8723bs/core/rtw_cmd.o:rtw_cmd.c:(.text+0xe8): first defined here
drivers/net/wireless/rtl8723bs/hal/OUTSRC-BTCoexist/HalBtc8812a2Ant.o: In function `is_multicast_mac_addr':
HalBtc8812a2Ant.c:(.text+0x0): multiple definition of `is_multicast_mac_addr'
drivers/net/wireless/rtl8723bs/core/rtw_cmd.o:rtw_cmd.c:(.text+0x44): first defined here
drivers/net/wireless/rtl8723bs/hal/OUTSRC-BTCoexist/HalBtc8812a2Ant.o: In function `is_broadcast_mac_addr':
HalBtc8812a2Ant.c:(.text+0x20): multiple definition of `is_broadcast_mac_addr'
drivers/net/wireless/rtl8723bs/core/rtw_cmd.o:rtw_cmd.c:(.text+0x64): first defined here
drivers/net/wireless/rtl8723bs/hal/OUTSRC-BTCoexist/HalBtc8812a2Ant.o: In function `is_zero_mac_addr':
HalBtc8812a2Ant.c:(.text+0xa4): multiple definition of `is_zero_mac_addr'
drivers/net/wireless/rtl8723bs/core/rtw_cmd.o:rtw_cmd.c:(.text+0xe8): first defined here
drivers/net/wireless/rtl8723bs/hal/OUTSRC-BTCoexist/HalBtc8821a1Ant.o: In function `is_multicast_mac_addr':
HalBtc8821a1Ant.c:(.text+0x0): multiple definition of `is_multicast_mac_addr'
drivers/net/wireless/rtl8723bs/core/rtw_cmd.o:rtw_cmd.c:(.text+0x44): first defined here
drivers/net/wireless/rtl8723bs/hal/OUTSRC-BTCoexist/HalBtc8821a1Ant.o: In function `is_broadcast_mac_addr':
HalBtc8821a1Ant.c:(.text+0x20): multiple definition of `is_broadcast_mac_addr'
drivers/net/wireless/rtl8723bs/core/rtw_cmd.o:rtw_cmd.c:(.text+0x64): first defined here
drivers/net/wireless/rtl8723bs/hal/OUTSRC-BTCoexist/HalBtc8821a1Ant.o: In function `is_zero_mac_addr':
HalBtc8821a1Ant.c:(.text+0xa4): multiple definition of `is_zero_mac_addr'
drivers/net/wireless/rtl8723bs/core/rtw_cmd.o:rtw_cmd.c:(.text+0xe8): first defined here
drivers/net/wireless/rtl8723bs/hal/OUTSRC-BTCoexist/HalBtc8821a2Ant.o: In function `is_multicast_mac_addr':
HalBtc8821a2Ant.c:(.text+0x0): multiple definition of `is_multicast_mac_addr'
drivers/net/wireless/rtl8723bs/core/rtw_cmd.o:rtw_cmd.c:(.text+0x44): first defined here
drivers/net/wireless/rtl8723bs/hal/OUTSRC-BTCoexist/HalBtc8821a2Ant.o: In function `is_broadcast_mac_addr':
HalBtc8821a2Ant.c:(.text+0x20): multiple definition of `is_broadcast_mac_addr'
drivers/net/wireless/rtl8723bs/core/rtw_cmd.o:rtw_cmd.c:(.text+0x64): first defined here
drivers/net/wireless/rtl8723bs/hal/OUTSRC-BTCoexist/HalBtc8821a2Ant.o: In function `is_zero_mac_addr':
HalBtc8821a2Ant.c:(.text+0xa4): multiple definition of `is_zero_mac_addr'
drivers/net/wireless/rtl8723bs/core/rtw_cmd.o:rtw_cmd.c:(.text+0xe8): first defined here
drivers/net/wireless/rtl8723bs/hal/OUTSRC/rtl8723b/HalHWImg8723B_BB.o: In function `is_multicast_mac_addr':
HalHWImg8723B_BB.c:(.text+0x88): multiple definition of `is_multicast_mac_addr'
drivers/net/wireless/rtl8723bs/core/rtw_cmd.o:rtw_cmd.c:(.text+0x44): first defined here
drivers/net/wireless/rtl8723bs/hal/OUTSRC/rtl8723b/HalHWImg8723B_BB.o: In function `is_broadcast_mac_addr':
HalHWImg8723B_BB.c:(.text+0xa8): multiple definition of `is_broadcast_mac_addr'
drivers/net/wireless/rtl8723bs/core/rtw_cmd.o:rtw_cmd.c:(.text+0x64): first defined here
drivers/net/wireless/rtl8723bs/hal/OUTSRC/rtl8723b/HalHWImg8723B_BB.o: In function `is_zero_mac_addr':
HalHWImg8723B_BB.c:(.text+0x12c): multiple definition of `is_zero_mac_addr'
drivers/net/wireless/rtl8723bs/core/rtw_cmd.o:rtw_cmd.c:(.text+0xe8): first defined here
drivers/net/wireless/rtl8723bs/hal/OUTSRC/rtl8723b/HalHWImg8723B_MAC.o: In function `is_multicast_mac_addr':
HalHWImg8723B_MAC.c:(.text+0x0): multiple definition of `is_multicast_mac_addr'
drivers/net/wireless/rtl8723bs/core/rtw_cmd.o:rtw_cmd.c:(.text+0x44): first defined here
drivers/net/wireless/rtl8723bs/hal/OUTSRC/rtl8723b/HalHWImg8723B_MAC.o: In function `is_broadcast_mac_addr':
HalHWImg8723B_MAC.c:(.text+0x20): multiple definition of `is_broadcast_mac_addr'
drivers/net/wireless/rtl8723bs/core/rtw_cmd.o:rtw_cmd.c:(.text+0x64): first defined here
drivers/net/wireless/rtl8723bs/hal/OUTSRC/rtl8723b/HalHWImg8723B_MAC.o: In function `is_zero_mac_addr':
HalHWImg8723B_MAC.c:(.text+0xa4): multiple definition of `is_zero_mac_addr'
drivers/net/wireless/rtl8723bs/core/rtw_cmd.o:rtw_cmd.c:(.text+0xe8): first defined here
drivers/net/wireless/rtl8723bs/hal/OUTSRC/rtl8723b/HalHWImg8723B_RF.o: In function `is_multicast_mac_addr':
HalHWImg8723B_RF.c:(.text+0x0): multiple definition of `is_multicast_mac_addr'
drivers/net/wireless/rtl8723bs/core/rtw_cmd.o:rtw_cmd.c:(.text+0x44): first defined here
drivers/net/wireless/rtl8723bs/hal/OUTSRC/rtl8723b/HalHWImg8723B_RF.o: In function `is_broadcast_mac_addr':
HalHWImg8723B_RF.c:(.text+0x20): multiple definition of `is_broadcast_mac_addr'
drivers/net/wireless/rtl8723bs/core/rtw_cmd.o:rtw_cmd.c:(.text+0x64): first defined here
drivers/net/wireless/rtl8723bs/hal/OUTSRC/rtl8723b/HalHWImg8723B_RF.o: In function `is_zero_mac_addr':
HalHWImg8723B_RF.c:(.text+0xa4): multiple definition of `is_zero_mac_addr'
drivers/net/wireless/rtl8723bs/core/rtw_cmd.o:rtw_cmd.c:(.text+0xe8): first defined here
drivers/net/wireless/rtl8723bs/hal/OUTSRC/rtl8723b/HalHWImg8723B_FW.o: In function `is_multicast_mac_addr':
HalHWImg8723B_FW.c:(.text+0x0): multiple definition of `is_multicast_mac_addr'
drivers/net/wireless/rtl8723bs/core/rtw_cmd.o:rtw_cmd.c:(.text+0x44): first defined here
drivers/net/wireless/rtl8723bs/hal/OUTSRC/rtl8723b/HalHWImg8723B_FW.o: In function `is_broadcast_mac_addr':
HalHWImg8723B_FW.c:(.text+0x20): multiple definition of `is_broadcast_mac_addr'
drivers/net/wireless/rtl8723bs/core/rtw_cmd.o:rtw_cmd.c:(.text+0x64): first defined here
drivers/net/wireless/rtl8723bs/hal/OUTSRC/rtl8723b/HalHWImg8723B_FW.o: In function `is_zero_mac_addr':
HalHWImg8723B_FW.c:(.text+0xa4): multiple definition of `is_zero_mac_addr'
drivers/net/wireless/rtl8723bs/core/rtw_cmd.o:rtw_cmd.c:(.text+0xe8): first defined here
....
MK(米客方德) SD NAND:
https://item.szlcsc.com/351535.html 4Gb(512MB) SD NAND, -40°C to +85°C 10+: ¥13.92
https://item.szlcsc.com/351534.html 2Gb(256MB) SD NAND, -25°C to +85°C 10+: ¥8.53
https://item.szlcsc.com/351533.html 1Gb(128MB) SD NAND, -25°C to +85°C 10+: ¥6.63
上次618促销用 立创商城发的100羊毛券撸了不少 SD NAND, 效果还不错, 特此分享.
https://github.com/steward-fu/miyoo
请问大神, 这个 miyoo链接 怎么玩?
972的bsp里的根文件系统的/etc/profile,里面原来只有两行,后面的都是我加的。
原来的两行是:
1 export LD_LIBRARY_PATH=/lib:/mnt/mmcblk0p2
2 /mnt/mmcblk0p1/scan_zbar
很好奇,这两行是不是应该合成一行? 第二行没有命令语句吧?
第1行是设置全局环境变量,
如果合并到一行就是这样:
LD_LIBRARY_PATH=/lib:/mnt/mmcblk0p2 /mnt/mmcblk0p1/scan_zbar
估计第2行的 scan_zbar 动态加载了 so 文件,
而 so 文件在 /mnt/mmcblk0p1/ 目录
关闭恼人的屏保: https://askubuntu.com/questions/1048774/disabling-lock-screen-18-04
关闭屏保:
gsettings set org.gnome.desktop.lockdown disable-lock-screen 'true'
读取 是否关闭屏保:
gsettings get org.gnome.desktop.lockdown disable-lock-screen
左边是 软件浮点数工具链 CROSS_COMPILE=arm-linux-gnueabi-
右边是 硬件浮点数工具链 CROSS_COMPILE=arm-linux-gnueabihf-
右边居然会检测 TF 卡分区没有消息了。
U-Boot SPL 2017.01-rc2-00073-gdd6e874 (Jul 11 2018 - 16:05:42)
DRAM: 64 MiB
Trying to boot from MMC1
U-Boot 2017.01-rc2-00073-gdd6e874 (Jul 11 2018 - 16:05:42 +0800) Allwinner Technology
CPU: Allwinner V3s (SUN8I 1681)
Model: Lichee Pi Zero
DRAM: 64 MiB
MMC: SUNXI SD/MMC: 0
SF: unrecognized JEDEC id bytes: c2, 20, 19
*** Warning - spi_flash_probe() failed, using default environment
Setting up a 800x480 lcd console (overscan 0x0)
dotclock: 33000kHz = 33000kHz: (1 * 3MHz * 66) / 6
In: serial@01c28000
Out: serial@01c28000
Err: serial@01c28000
U-Boot 2017.01-rc2-00073-gdd6e874 (Jul 11 2018 - 16:05:42 +0800) Allwinner Technology
CPU: Allwinner V3s (SUN8I 1681)
Model: Lichee Pi Zero
DRAM: 64 MiB
MMC: SUNXI SD/MMC: 0
SF: unrecognized JEDEC id bytes: c2, 20, 19
*** Warning - spi_flash_probe() failed, using default environment
Setting up a 800x480 lcd console (overscan 0x0)
dotclock: 33000kHz = 33000kHz: (1 * 3MHz * 66) / 6
In: serial@01c28000
Out: serial@01c28000
Err: serial@01c28000
Net: No ethernet found.
starting USB...
No controllers found
Hit any key to stop autoboot: 0
switch to partitions #0, OK
mmc0 is current device
Scanning mmc 0:1...
Found U-Boot script /boot.scr
reading /boot.scr
290 bytes read in 15 ms (18.6 KiB/s)
## Executing script at 41900000
reading uImage
2440600 bytes read in 140 ms (16.6 MiB/s)
reading script.bin
35240 bytes read in 25 ms (1.3 MiB/s)
## Booting kernel from Legacy Image at 41000000 ...
Image Name: Linux-3.4.39+
Image Type: ARM Linux Kernel Image (uncompressed)
Data Size: 2440536 Bytes = 2.3 MiB
Load Address: 40008000
Entry Point: 40008000
Verifying Checksum ... OK
Loading Kernel Image ... OK
Using machid 0x1029 from environment
Starting kernel ...
[ 0.000000] Booting Linux on physical CPU 0
[ 0.000000] Linux version 3.4.39+ (smartcar@ubuntu) (gcc version 7.4.0 (Ubuntu/Linaro 7.4.0-1ubuntu1~18.04.1) ) #2 Tue Jun 25 14:14:24 CST 2019
[ 0.000000] Initialized persistent memory from 41d20800-41d307ff
[ 0.000000] Kernel command line: console=ttyS0,115200 panic=5 rootwait root=/dev/mmcblk0p2 earlyprintk rw
[ 0.000000] PID hash table entries: 256 (order: -2, 1024 bytes)
[ 0.000000] Dentry cache hash table entries: 8192 (order: 3, 32768 bytes)
[ 0.000000] Inode-cache hash table entries: 4096 (order: 2, 16384 bytes)
[ 0.000000] Memory: 64MB = 64MB total
[ 0.000000] Memory: 30428k/30428k available, 35108k reserved, 0K highmem
[ 0.000000] Virtual kernel memory layout:
[ 0.000000] vector : 0xffff0000 - 0xffff1000 ( 4 kB)
[ 0.000000] fixmap : 0xfff00000 - 0xfffe0000 ( 896 kB)
[ 0.000000] vmalloc : 0xc4800000 - 0xff000000 ( 936 MB)
[ 0.000000] lowmem : 0xc0000000 - 0xc4000000 ( 64 MB)
[ 0.000000] modules : 0xbf000000 - 0xc0000000 ( 16 MB)
[ 0.000000] .text : 0xc0008000 - 0xc0470000 (4512 kB)
[ 0.000000] .init : 0xc0470000 - 0xc0493000 ( 140 kB)
[ 0.000000] .data : 0xc0494000 - 0xc04d8750 ( 274 kB)
[ 0.000000] .bss : 0xc04d8774 - 0xc057320d ( 619 kB)
[ 0.000000] NR_IRQS:544
[ 0.000000] Architected local timer running at 24.00MHz.
[ 0.000000] Switching to timer-based delay loop
[ 0.000000] sched_clock: 32 bits at 24MHz, resolution 41ns, wraps every 178956ms
[ 0.000000] Console: colour dummy device 80x30
[ 0.000161] Calibrating delay loop (skipped), value calculated using timer frequency.. 4800.00 BogoMIPS (lpj=24000000)
[ 0.000180] pid_max: default: 32768 minimum: 301
[ 0.000321] Mount-cache hash table entries: 512
[ 0.000879] CPU: Testing write buffer coherency: ok
[ 0.001144] Setting up static identity map for 0x4034b9e0 - 0x4034ba38
[ 0.001813] devtmpfs: initialized
[ 0.003519] pinctrl core: initialized pinctrl subsystem
[ 0.003994] NET: Registered protocol family 16
[ 0.004307] DMA: preallocated 128 KiB pool for atomic coherent allocations
[ 0.004363] script_sysfs_init success
[ 0.005100] gpiochip_add: registered GPIOs 0 to 223 on device: sunxi-pinctrl
[ 0.005998] sunxi-pinctrl sunxi-pinctrl: initialized sunXi PIO driver
[ 0.006367] gpiochip_add: registered GPIOs 1024 to 1031 on device: axp-pinctrl
[ 0.007164] persistent_ram: uncorrectable error in header
[ 0.007179] persistent_ram: no valid data in buffer (sig = 0x75175517)
[ 0.013834] console [ram-1] enabled
[ 0.014631] Not Found clk pll_isp in script
[ 0.014757] Not Found clk pll_video in script
[ 0.014975] Not Found clk pll_ve in script
[ 0.015094] Not Found clk pll_periph0 in script
[ 0.015311] Not Found clk pll_de in script
[ 0.019022] bio: create slab <bio-0> at 0
[ 0.019403] pwm module init!
[ 0.021734] SCSI subsystem initialized
[ 0.022080] usbcore: registered new interface driver usbfs
[ 0.022259] usbcore: registered new interface driver hub
[ 0.022617] usbcore: registered new device driver usb
[ 0.022877] twi_chan_cfg()340 - [twi0] has no twi_regulator.
[ 0.023100] twi_chan_cfg()340 - [twi1] has no twi_regulator.
[ 0.023905] sunxi_i2c_do_xfer()985 - [i2c0] incomplete xfer (status: 0x20, dev addr: 0x34)
[ 0.024142] axp20_board 0-0034: failed reading at 0x03
[ 0.024390] axp20_board: probe of 0-0034 failed with error -70
[ 0.024556] Linux video capture interface: v2.00
[ 0.024761] gpiochip_add: gpios 1024..1028 (axp_pin) failed to register
[ 0.025307] Advanced Linux Sound Architecture Driver Version 1.0.25.
[ 0.026186] Switching to clocksource arch_sys_counter
[ 0.030000] NET: Registered protocol family 2
[ 0.030000] IP route cache hash table entries: 1024 (order: 0, 4096 bytes)
[ 0.030000] TCP established hash table entries: 2048 (order: 2, 16384 bytes)
[ 0.030319] TCP bind hash table entries: 2048 (order: 1, 8192 bytes)
[ 0.030465] TCP: Hash tables configured (established 2048 bind 2048)
[ 0.030688] TCP: reno registered
[ 0.030813] UDP hash table entries: 256 (order: 0, 4096 bytes)
[ 0.031044] UDP-Lite hash table entries: 256 (order: 0, 4096 bytes)
[ 0.031437] NET: Registered protocol family 1
[ 0.031991] standby_mode = 1.
[ 0.032116] wakeup src cnt is : 3.
[ 0.032254] pmu1_enable = 0x1.
[ 0.032374] pmux_id = 0x1.
[ 0.032603] config_pmux_para: script_parser_fetch err.
[ 0.032724] pmu2_enable = 0x0.
[ 0.032847] add_sys_pwr_dm: get ldo name failed
[ 0.033067] add_sys_pwr_dm: get ldo name failed
[ 0.033187] add_sys_pwr_dm: get ldo name failed
[ 0.033408] add_sys_pwr_dm: get ldo name failed
[ 0.033527] add_sys_pwr_dm: get ldo name failed
[ 0.033645] add_sys_pwr_dm: get ldo name failed
[ 0.033864] add_sys_pwr_dm: get ldo name failed
[ 0.033984] add_sys_pwr_dm: get ldo name failed
[ 0.034203] add_sys_pwr_dm: get ldo name failed
[ 0.034321] add_sys_pwr_dm: get ldo name failed
[ 0.034439] after inited: sys_mask config = 0x0.
[ 0.034659] dynamic_standby enalbe = 0x0.
[ 0.034825] sunxi_reg_init enter
[ 0.036868] squashfs: version 4.0 (2009/01/31) Phillip Lougher
[ 0.037143] jffs2: version 2.2. (NAND) (SUMMARY) © 2001-2006 Red Hat, Inc.
[ 0.037552] msgmni has been set to 59
[ 0.038595] io scheduler noop registered
[ 0.038726] io scheduler deadline registered
[ 0.039015] io scheduler cfq registered (default)
[ 0.039514] [DISP]disp_module_init
[ 0.040088] cmdline,disp=
[ 0.040766] [DISP] disp_get_rotation_sw,line:68:disp 0 out of range? g_rot_sw=0
[ 0.041102] [DISP] disp_init_connections,line:288:NULL pointer: 0, 0
[ 0.043741] [DISP] Fb_map_kernel_logo,line:924:Fb_map_kernel_logo failed!
[ 0.046334] [DISP] disp_sys_power_enable,line:387:some error happen, fail to get regulator
[ 0.047417] [DISP]disp_module_init finish
[ 0.047806] sw_uart_get_devinfo()1503 - uart0 has no uart_regulator.
[ 0.048389] uart0: ttyS0 at MMIO 0x1c28000 (irq = 32) is a SUNXI
[ 0.048521] sw_uart_pm()890 - uart0 clk is already enable
[ 0.048753] sw_console_setup()1233 - console setup baud 115200 parity n bits 8, flow n
[ 0.162221] console [ttyS0] enabled
[ 0.685792] sunxi_spi_chan_cfg()1376 - [spi-0] has no spi_regulator.
[ 0.693772] spi spi0: master is unqueued, this is deprecated
[ 0.700344] m25p_probe()982 - Use the Dual Mode Read.
[ 0.706286] m25p80 spi0.0: found mx25l25635e, expected w25q128
[ 0.712925] m25p80 spi0.0: mx25l25635e (32768 Kbytes)
[ 0.720232] partitions_register()869 - Invalid partitions count: -499109887
[ 0.728521] Creating 4 MTD partitions on "spi0.0":
[ 0.734114] 0x000000000000-0x000000080000 : "u-boot"
[ 0.740765] 0x000000080000-0x000000100000 : "sys_config"
[ 0.747689] 0x000000100000-0x000000400000 : "kernel"
[ 0.754251] 0x000000400000-0x000001000000 : "rootfs"
[ 0.762223] Failed to alloc md5
[ 0.765969] eth0: Use random mac address
[ 0.770572] ehci_hcd: USB 2.0 'Enhanced' Host Controller (EHCI) Driver
[ 0.798215] sunxi-ehci sunxi-ehci.1: SW USB2.0 'Enhanced' Host Controller (EHCI) Driver
[ 0.807267] sunxi-ehci sunxi-ehci.1: new USB bus registered, assigned bus number 1
[ 0.816008] sunxi-ehci sunxi-ehci.1: irq 104, io mem 0xf1c1a000
[ 0.840032] sunxi-ehci sunxi-ehci.1: USB 0.0 started, EHCI 1.00
[ 0.847530] hub 1-0:1.0: USB hub found
[ 0.851864] hub 1-0:1.0: 1 port detected
[ 0.856887] sunxi-ehci sunxi-ehci.1: remove, state 1
[ 0.862555] usb usb1: USB disconnect, device number 1
[ 0.869858] sunxi-ehci sunxi-ehci.1: USB bus 1 deregistered
[ 0.886299] ohci_hcd: USB 1.1 'Open' Host Controller (OHCI) Driver
[ 0.913493] sunxi-ohci sunxi-ohci.1: SW USB2.0 'Open' Host Controller (OHCI) Driver
[ 0.922141] sunxi-ohci sunxi-ohci.1: new USB bus registered, assigned bus number 1
[ 0.930801] sunxi-ohci sunxi-ohci.1: irq 105, io mem 0xf1c1a400
[ 0.994661] hub 1-0:1.0: USB hub found
[ 0.999055] hub 1-0:1.0: 1 port detected
[ 1.004028] sunxi-ohci sunxi-ohci.1: remove, state 1
[ 1.009762] usb usb1: USB disconnect, device number 1
[ 1.016063] sunxi-ohci sunxi-ohci.1: USB bus 1 deregistered
[ 1.032610] Initializing USB Mass Storage driver...
[ 1.038218] usbcore: registered new interface driver usb-storage
[ 1.045019] USB Mass Storage support registered.
[ 1.050820] file system registered
[ 1.056277] android_usb gadget: Mass Storage Function, version: 2009/09/11
[ 1.064180] android_usb gadget: Number of LUNs=1
[ 1.069414] lun0: LUN: removable file: (no medium)
[ 1.075540] android_usb gadget: android_usb ready
[ 1.081034] sunxikbd_script_init: key para not found, used default para.
[ 1.089715] sunxi-rtc sunxi-rtc: rtc core: registered sunxi-rtc as rtc0
[ 1.098066] platform reg-20-cs-dcdc2: Driver reg-20-cs-dcdc2 requests probe deferral
[ 1.107076] platform reg-20-cs-dcdc3: Driver reg-20-cs-dcdc3 requests probe deferral
[ 1.116010] platform reg-20-cs-ldo1: Driver reg-20-cs-ldo1 requests probe deferral
[ 1.124645] platform reg-20-cs-ldo2: Driver reg-20-cs-ldo2 requests probe deferral
[ 1.133379] platform reg-20-cs-ldo3: Driver reg-20-cs-ldo3 requests probe deferral
[ 1.142116] platform reg-20-cs-ldo4: Driver reg-20-cs-ldo4 requests probe deferral
[ 1.150735] platform reg-20-cs-ldoio0: Driver reg-20-cs-ldoio0 requests probe deferral
[ 1.159748] sunxi_wdt_init_module: sunxi WatchDog Timer Driver v1.0
[ 1.167108] sunxi_wdt_probe: devm_ioremap return wdt_reg 0xf1c20ca0, res->start 0x01c20ca0, res->end 0x01c20cbf
[ 1.178441] sunxi_wdt_probe: initialized (g_timeout=16s, g_nowayout=0)
[ 1.186233] wdt_enable, write reg 0xf1c20cb8 val 0x00000000
[ 1.192647] wdt_set_tmout, write 0x000000b0 to mode reg 0xf1c20cb8, actual timeout 16 sec
[ 1.204497] no led_3, ignore it!
[ 1.208350] no led_4, ignore it!
[ 1.212074] no led_5, ignore it!
[ 1.215763] no led_6, ignore it!
[ 1.219450] no led_7, ignore it!
[ 1.225188] usbcore: registered new interface driver usbhid
[ 1.231538] usbhid: USB HID core driver
[ 1.236548] ashmem: initialized
[ 1.240672] logger: created 256K log 'log_main'
[ 1.245930] logger: created 32K log 'log_events'
[ 1.251420] logger: created 32K log 'log_radio'
[ 1.256703] logger: created 32K log 'log_system'
[ 1.263541] script_get_item return type err, consider it no ldo
[ 1.274558] *******************Try sdio*******************
[ 1.281140] asoc: sndcodec <-> sunxi-codec mapping ok
[ 1.289197] TCP: cubic registered
[ 1.293104] NET: Registered protocol family 17
[ 1.298170] *******************Try sd *******************
[ 1.304433] VFP support v0.3: implementor 41 architecture 2 part 30 variant 7 rev 5
[ 1.313307] ThumbEE CPU extension supported.
[ 1.318191] Registering SWP/SWPB emulation handler
[ 1.328185] platform reg-20-cs-ldoio0: Driver reg-20-cs-ldoio0 requests probe deferral
[ 1.337353] platform reg-20-cs-ldo4: Driver reg-20-cs-ldo4 requests probe deferral
[ 1.346074] platform reg-20-cs-ldo3: Driver reg-20-cs-ldo3 requests probe deferral
[ 1.354647] platform reg-20-cs-ldo2: Driver reg-20-cs-ldo2 requests probe deferral
[ 1.363228] platform reg-20-cs-ldo1: Driver reg-20-cs-ldo1 requests probe deferral
[ 1.371907] platform reg-20-cs-dcdc3: Driver reg-20-cs-dcdc3 requests probe deferral
[ 1.380783] platform reg-20-cs-dcdc2: Driver reg-20-cs-dcdc2 requests probe deferral
[ 1.389652] sunxi-rtc sunxi-rtc: setting system clock to 1970-01-01 00:00:05 UTC (5)
[ 1.400211] ALSA device list:
[ 1.403639] #0: audiocodec
[ 1.407369] Waiting for root device /dev/mmcblk0p2...
[ 1.414264] mmc0: new high speed SD card at address 0001
[ 1.420737] mmcblk0: mmc0:0001 00000 1.83 GiB
[ 1.427334] mmcblk0: p1 p2
[ 1.431310] mmcblk mmc0:0001: Card claimed for testing.
[ 1.437235] mmc0:0001: 00000 1.83 GiB
[ 1.441785] platform reg-20-cs-dcdc2: Driver reg-20-cs-dcdc2 requests probe deferral
[ 1.450552] *******************sd init ok*******************
[ 1.457173] platform reg-20-cs-dcdc3: Driver reg-20-cs-dcdc3 requests probe deferral
[ 1.466035] platform reg-20-cs-ldo1: Driver reg-20-cs-ldo1 requests probe deferral
[ 1.474602] platform reg-20-cs-ldo2: Driver reg-20-cs-ldo2 requests probe deferral
[ 1.483262] platform reg-20-cs-ldo3: Driver reg-20-cs-ldo3 requests probe deferral
[ 1.491922] platform reg-20-cs-ldo4: Driver reg-20-cs-ldo4 requests probe deferral
[ 1.500474] platform reg-20-cs-ldoio0: Driver reg-20-cs-ldoio0 requests probe deferral
[ 1.520980] EXT4-fs (mmcblk0p2): couldn't mount as ext3 due to feature incompatibilities
[ 1.531014] EXT4-fs (mmcblk0p2): couldn't mount as ext2 due to feature incompatibilities
[ 1.632188] EXT4-fs (mmcblk0p2): recovery complete
[ 1.644073] EXT4-fs (mmcblk0p2): mounted filesystem with ordered data mode. Opts: (null)
[ 1.653353] VFS: Mounted root (ext4 filesystem) on device 179:2.
[ 1.662223] devtmpfs: mounted
[ 1.665918] Freeing init memory: 140K
[ 1.796753] EXT4-fs (mmcblk0p2): re-mounted. Opts: data=ordered
Starting logging: OK
Initializing random number generator... done.
Starting network: OK
Welcome to Buildroot
buildroot login:
U-Boot SPL 2017.01-rc2-00073-gdd6e874 (Jul 11 2018 - 16:05:42)
DRAM: 64 MiB
Trying to boot from MMC1
U-Boot 2017.01-rc2-00073-gdd6e874 (Jul 11 2018 - 16:05:42 +0800) Allwinner Technology
CPU: Allwinner V3s (SUN8I 1681)
Model: Lichee Pi Zero
DRAM: 64 MiB
MMC: SUNXI SD/MMC: 0
SF: unrecognized JEDEC id bytes: c2, 20, 19
*** Warning - spi_flash_probe() failed, using default environment
Setting up a 800x480 lcd console (overscan 0x0)
dotclock: 33000kHz = 33000kHz: (1 * 3MHz * 66) / 6
In: serial@01c28000
Out: serial@01c28000
Err: serial@01c28000
U-Boot 2017.01-rc2-00073-gdd6e874 (Jul 11 2018 - 16:05:42 +0800) Allwinner Technology
CPU: Allwinner V3s (SUN8I 1681)
Model: Lichee Pi Zero
DRAM: 64 MiB
MMC: SUNXI SD/MMC: 0
SF: unrecognized JEDEC id bytes: c2, 20, 19
*** Warning - spi_flash_probe() failed, using default environment
Setting up a 800x480 lcd console (overscan 0x0)
dotclock: 33000kHz = 33000kHz: (1 * 3MHz * 66) / 6
In: serial@01c28000
Out: serial@01c28000
Err: serial@01c28000
Net: No ethernet found.
starting USB...
No controllers found
Hit any key to stop autoboot: 0
switch to partitions #0, OK
mmc0 is current device
Scanning mmc 0:1...
Found U-Boot script /boot.scr
reading /boot.scr
290 bytes read in 17 ms (16.6 KiB/s)
## Executing script at 41900000
reading uImage
2572800 bytes read in 151 ms (16.2 MiB/s)
reading script.bin
35240 bytes read in 29 ms (1.2 MiB/s)
## Booting kernel from Legacy Image at 41000000 ...
Image Name: Linux-3.4.39+
Image Type: ARM Linux Kernel Image (uncompressed)
Data Size: 2572736 Bytes = 2.5 MiB
Load Address: 40008000
Entry Point: 40008000
Verifying Checksum ... OK
Loading Kernel Image ... OK
Using machid 0x1029 from environment
Starting kernel ...
[ 0.000000] Booting Linux on physical CPU 0
[ 0.000000] Linux version 3.4.39+ (smartcar@ubuntu) (gcc version 7.4.0 (Ubuntu/Linaro 7.4.0-1ubuntu1~18.04.1) ) #1 Tue Jun 25 11:22:20 CST 2019
[ 0.000000] Initialized persistent memory from 41d20800-41d307ff
[ 0.000000] Kernel command line: console=ttyS0,115200 panic=5 rootwait root=/dev/mmcblk0p2 earlyprintk rw
[ 0.000000] PID hash table entries: 256 (order: -2, 1024 bytes)
[ 0.000000] Dentry cache hash table entries: 8192 (order: 3, 32768 bytes)
[ 0.000000] Inode-cache hash table entries: 4096 (order: 2, 16384 bytes)
[ 0.000000] Memory: 64MB = 64MB total
[ 0.000000] Memory: 30196k/30196k available, 35340k reserved, 0K highmem
[ 0.000000] Virtual kernel memory layout:
[ 0.000000] vector : 0xffff0000 - 0xffff1000 ( 4 kB)
[ 0.000000] fixmap : 0xfff00000 - 0xfffe0000 ( 896 kB)
[ 0.000000] vmalloc : 0xc4800000 - 0xff000000 ( 936 MB)
[ 0.000000] lowmem : 0xc0000000 - 0xc4000000 ( 64 MB)
[ 0.000000] modules : 0xbf000000 - 0xc0000000 ( 16 MB)
[ 0.000000] .text : 0xc0008000 - 0xc0492000 (4648 kB)
[ 0.000000] .init : 0xc0492000 - 0xc04b9000 ( 156 kB)
[ 0.000000] .data : 0xc04ba000 - 0xc04d4920 ( 107 kB)
[ 0.000000] .bss : 0xc0513174 - 0xc05adc05 ( 619 kB)
[ 0.000000] NR_IRQS:544
[ 0.000000] Architected local timer running at 24.00MHz.
[ 0.000000] Switching to timer-based delay loop
[ 0.000000] sched_clock: 32 bits at 24MHz, resolution 41ns, wraps every 178956ms
[ 0.000000] Console: colour dummy device 80x30
[ 0.000167] Calibrating delay loop (skipped), value calculated using timer frequency.. 4800.00 BogoMIPS (lpj=24000000)
[ 0.000192] pid_max: default: 32768 minimum: 301
[ 0.000328] Mount-cache hash table entries: 512
[ 0.000895] CPU: Testing write buffer coherency: ok
[ 0.001180] Setting up static identity map for 0x40382b50 - 0x40382ba8
[ 0.001867] devtmpfs: initialized
[ 0.003566] pinctrl core: initialized pinctrl subsystem
[ 0.004068] NET: Registered protocol family 16
[ 0.004391] DMA: preallocated 128 KiB pool for atomic coherent allocations
[ 0.004452] script_sysfs_init success
[ 0.005211] gpiochip_add: registered GPIOs 0 to 223 on device: sunxi-pinctrl
[ 0.006125] sunxi-pinctrl sunxi-pinctrl: initialized sunXi PIO driver
[ 0.006521] gpiochip_add: registered GPIOs 1024 to 1031 on device: axp-pinctrl
[ 0.007365] persistent_ram: error in header, 8
[ 0.007381] persistent_ram: found existing buffer, size 16618, start 16618
[ 0.088049] console [ram-1] enabled
[ 0.088922] Not Found clk pll_isp in script
[ 0.089054] Not Found clk pll_video in script
[ 0.089276] Not Found clk pll_ve in script
[ 0.089397] Not Found clk pll_periph0 in script
[ 0.089617] Not Found clk pll_de in script
[ 0.093547] bio: create slab <bio-0> at 0
[ 0.093950] pwm module init!
[ 0.096335] SCSI subsystem initialized
[ 0.096704] usbcore: registered new interface driver usbfs
[ 0.096892] usbcore: registered new interface driver hub
[ 0.097264] usbcore: registered new device driver usb
[ 0.097534] twi_chan_cfg()340 - [twi0] has no twi_regulator.
[ 0.097760] twi_chan_cfg()340 - [twi1] has no twi_regulator.
[ 0.098581] sunxi_i2c_do_xfer()985 - [i2c0] incomplete xfer (status: 0x20, dev addr: 0x34)
[ 0.098827] axp20_board 0-0034: failed reading at 0x03
[ 0.098979] axp20_board: probe of 0-0034 failed with error -70
[ 0.099254] Linux video capture interface: v2.00
[ 0.099465] gpiochip_add: gpios 1024..1028 (axp_pin) failed to register
[ 0.100040] Advanced Linux Sound Architecture Driver Version 1.0.25.
[ 0.100956] Switching to clocksource arch_sys_counter
[ 0.109838] NET: Registered protocol family 2
[ 0.109838] IP route cache hash table entries: 1024 (order: 0, 4096 bytes)
[ 0.110314] TCP established hash table entries: 2048 (order: 2, 16384 bytes)
[ 0.110578] TCP bind hash table entries: 2048 (order: 1, 8192 bytes)
[ 0.110725] TCP: Hash tables configured (established 2048 bind 2048)
[ 0.110952] TCP: reno registered
[ 0.111076] UDP hash table entries: 256 (order: 0, 4096 bytes)
[ 0.111307] UDP-Lite hash table entries: 256 (order: 0, 4096 bytes)
[ 0.111691] NET: Registered protocol family 1
[ 0.112156] standby_mode = 1.
[ 0.112382] wakeup src cnt is : 3.
[ 0.112524] pmu1_enable = 0x1.
[ 0.112645] pmux_id = 0x1.
[ 0.112874] config_pmux_para: script_parser_fetch err.
[ 0.112996] pmu2_enable = 0x0.
[ 0.113119] add_sys_pwr_dm: get ldo name failed
[ 0.113341] add_sys_pwr_dm: get ldo name failed
[ 0.113462] add_sys_pwr_dm: get ldo name failed
[ 0.113583] add_sys_pwr_dm: get ldo name failed
[ 0.113804] add_sys_pwr_dm: get ldo name failed
[ 0.113925] add_sys_pwr_dm: get ldo name failed
[ 0.114146] add_sys_pwr_dm: get ldo name failed
[ 0.114266] add_sys_pwr_dm: get ldo name failed
[ 0.114386] add_sys_pwr_dm: get ldo name failed
[ 0.114604] add_sys_pwr_dm: get ldo name failed
[ 0.114724] after inited: sys_mask config = 0x0.
[ 0.114944] dynamic_standby enalbe = 0x0.
[ 0.115117] sunxi_reg_init enter
[ 0.117245] squashfs: version 4.0 (2009/01/31) Phillip Lougher
[ 0.117522] jffs2: version 2.2. (NAND) (SUMMARY) © 2001-2006 Red Hat, Inc.
[ 0.117837] msgmni has been set to 58
[ 0.119061] io scheduler noop registered
[ 0.119195] io scheduler deadline registered
[ 0.119387] io scheduler cfq registered (default)
[ 0.120067] [DISP]disp_module_init
[ 0.120621] cmdline,disp=
[ 0.121326] [DISP] disp_get_rotation_sw,line:68:disp 0 out of range? g_rot_sw=0
[ 0.121672] [DISP] disp_init_connections,line:288:NULL pointer: 0, 0
[ 0.124334] [DISP] Fb_map_kernel_logo,line:924:Fb_map_kernel_logo failed!
[ 0.127007] [DISP] disp_sys_power_enable,line:387:some error happen, fail to get regulator
[ 0.128105] [DISP]disp_module_init finish
[ 0.128510] sw_uart_get_devinfo()1503 - uart0 has no uart_regulator.
[ 0.129096] uart0: ttyS0 at MMIO 0x1c28000 (irq = 32) is a SUNXI
[ 0.129230] sw_uart_pm()890 - uart0 clk is already enable
[ 0.129463] sw_console_setup()1233 - console setup baud 115200 parity n bits 8, flow n
[ 0.242938] console [ttyS0] enabled
[ 0.765567] sunxi_spi_chan_cfg()1376 - [spi-0] has no spi_regulator.
[ 0.773582] spi spi0: master is unqueued, this is deprecated
[ 0.780175] m25p_probe()982 - Use the Dual Mode Read.
[ 0.786030] m25p80 spi0.0: found mx25l25635e, expected w25q128
[ 0.792774] m25p80 spi0.0: mx25l25635e (32768 Kbytes)
[ 0.799996] partitions_register()869 - Invalid partitions count: -499109887
[ 0.808429] Creating 4 MTD partitions on "spi0.0":
[ 0.813917] 0x000000000000-0x000000080000 : "u-boot"
[ 0.820712] 0x000000080000-0x000000100000 : "sys_config"
[ 0.827563] 0x000000100000-0x000000400000 : "kernel"
[ 0.834259] 0x000000400000-0x000001000000 : "rootfs"
[ 0.842357] Failed to alloc md5
[ 0.846109] eth0: Use random mac address
[ 0.850724] ehci_hcd: USB 2.0 'Enhanced' Host Controller (EHCI) Driver
[ 0.878285] sunxi-ehci sunxi-ehci.1: SW USB2.0 'Enhanced' Host Controller (EHCI) Driver
[ 0.887443] sunxi-ehci sunxi-ehci.1: new USB bus registered, assigned bus number 1
[ 0.896189] sunxi-ehci sunxi-ehci.1: irq 104, io mem 0xf1c1a000
[ 0.920032] sunxi-ehci sunxi-ehci.1: USB 0.0 started, EHCI 1.00
[ 0.927539] hub 1-0:1.0: USB hub found
[ 0.931928] hub 1-0:1.0: 1 port detected
[ 0.936974] sunxi-ehci sunxi-ehci.1: remove, state 1
[ 0.942649] usb usb1: USB disconnect, device number 1
[ 0.949969] sunxi-ehci sunxi-ehci.1: USB bus 1 deregistered
[ 0.966537] ohci_hcd: USB 1.1 'Open' Host Controller (OHCI) Driver
[ 0.993639] sunxi-ohci sunxi-ohci.1: SW USB2.0 'Open' Host Controller (OHCI) Driver
[ 1.002406] sunxi-ohci sunxi-ohci.1: new USB bus registered, assigned bus number 1
[ 1.011074] sunxi-ohci sunxi-ohci.1: irq 105, io mem 0xf1c1a400
[ 1.074805] hub 1-0:1.0: USB hub found
[ 1.079200] hub 1-0:1.0: 1 port detected
[ 1.084216] sunxi-ohci sunxi-ohci.1: remove, state 1
[ 1.089858] usb usb1: USB disconnect, device number 1
[ 1.096292] sunxi-ohci sunxi-ohci.1: USB bus 1 deregistered
[ 1.112749] Initializing USB Mass Storage driver...
[ 1.118472] usbcore: registered new interface driver usb-storage
[ 1.125268] USB Mass Storage support registered.
[ 1.130939] file system registered
[ 1.136471] android_usb gadget: Mass Storage Function, version: 2009/09/11
[ 1.144384] android_usb gadget: Number of LUNs=1
[ 1.149622] lun0: LUN: removable file: (no medium)
[ 1.155773] android_usb gadget: android_usb ready
[ 1.161285] sunxikbd_script_init: key para not found, used default para.
[ 1.169684] [RTC] WARNING: Rtc time will be wrong!!
[ 1.175555] sunxi-rtc sunxi-rtc: rtc core: registered sunxi-rtc as rtc0
[ 1.184159] platform reg-20-cs-dcdc2: Driver reg-20-cs-dcdc2 requests probe deferral
[ 1.193057] platform reg-20-cs-dcdc3: Driver reg-20-cs-dcdc3 requests probe deferral
[ 1.202014] platform reg-20-cs-ldo1: Driver reg-20-cs-ldo1 requests probe deferral
[ 1.210751] platform reg-20-cs-ldo2: Driver reg-20-cs-ldo2 requests probe deferral
[ 1.219393] platform reg-20-cs-ldo3: Driver reg-20-cs-ldo3 requests probe deferral
[ 1.228127] platform reg-20-cs-ldo4: Driver reg-20-cs-ldo4 requests probe deferral
[ 1.236864] platform reg-20-cs-ldoio0: Driver reg-20-cs-ldoio0 requests probe deferral
[ 1.245789] sunxi_wdt_init_module: sunxi WatchDog Timer Driver v1.0
[ 1.253163] sunxi_wdt_probe: devm_ioremap return wdt_reg 0xf1c20ca0, res->start 0x01c20ca0, res->end 0x01c20cbf
[ 1.264593] sunxi_wdt_probe: initialized (g_timeout=16s, g_nowayout=0)
[ 1.272307] wdt_enable, write reg 0xf1c20cb8 val 0x00000000
[ 1.278706] wdt_set_tmout, write 0x000000b0 to mode reg 0xf1c20cb8, actual timeout 16 sec
[ 1.290742] no led_3, ignore it!
[ 1.294459] no led_4, ignore it!
[ 1.298149] no led_5, ignore it!
[ 1.301920] no led_6, ignore it!
[ 1.305712] no led_7, ignore it!
[ 1.311383] usbcore: registered new interface driver usbhid
[ 1.317704] usbhid: USB HID core driver
[ 1.322886] ashmem: initialized
[ 1.326727] logger: created 256K log 'log_main'
[ 1.332069] logger: created 32K log 'log_events'
[ 1.337577] logger: created 32K log 'log_radio'
[ 1.343084] logger: created 32K log 'log_system'
[ 1.349926] script_get_item return type err, consider it no ldo
[ 1.357712] asoc: sndcodec <-> sunxi-codec mapping ok
[ 1.369329] TCP: cubic registered
[ 1.373195] *******************Try sdio*******************
[ 1.379411] NET: Registered protocol family 17
[ 1.384737] VFP support v0.3: [mmc]: *** sunxi_mci_dump_errinfo(L826): smc 0 err, cmd 5, RTO !!
[ 1.394997] ThumbEE CPU extension supported.
[ 1.399874] Registering SWP/SWPB emulation handler
[ 1.406222] *******************Try sd *******************
[ 1.412720] platform reg-20-cs-ldoio0: Driver reg-20-cs-ldoio0 requests probe deferral
[ 1.421884] platform reg-20-cs-ldo4: Driver reg-20-cs-ldo4 requests probe deferral
[ 1.431802] platform reg-20-cs-ldo3: Driver reg-20-cs-ldo3 requests probe deferral
[ 1.442673] platform reg-20-cs-ldo2: Driver reg-20-cs-ldo2 requests probe deferral
[ 1.451375] platform reg-20-cs-ldo1: Driver reg-20-cs-ldo1 requests probe deferral
[ 1.459955] platform reg-20-cs-dcdc3: Driver reg-20-cs-dcdc3 requests probe deferral
[ 1.468831] platform reg-20-cs-dcdc2: Driver reg-20-cs-dcdc2 requests probe deferral
[ 1.477724] sunxi-rtc sunxi-rtc: hctosys: unable to read the hardware clock
[ 1.487168] ALSA device list:
[ 1.490759] #0: audiocodec
[ 1.494460] Waiting for root device /dev/mmcblk0p2...
复制一份,骗一骗编译器搞定:
cp include/linux/compiler-gcc4.h include/linux/compiler-gcc7.h
'make CONFIG_DEBUG_SECTION_MISMATCH=y'
GEN .version
CHK include/generated/compile.h
UPD include/generated/compile.h
CC init/version.o
LD init/built-in.o
LD .tmp_vmlinux1
KSYM .tmp_kallsyms1.S
AS .tmp_kallsyms1.o
LD .tmp_vmlinux2
KSYM .tmp_kallsyms2.S
AS .tmp_kallsyms2.o
LD vmlinux
SYSMAP System.map
SYSMAP .tmp_System.map
OBJCOPY arch/arm/boot/Image
Kernel: arch/arm/boot/Image is ready
AS arch/arm/boot/compressed/head.o
GZIP arch/arm/boot/compressed/piggy.gzip
AS arch/arm/boot/compressed/piggy.gzip.o
CC arch/arm/boot/compressed/misc.o
CC arch/arm/boot/compressed/decompress.o
CC arch/arm/boot/compressed/string.o
SHIPPED arch/arm/boot/compressed/lib1funcs.S
AS arch/arm/boot/compressed/lib1funcs.o
SHIPPED arch/arm/boot/compressed/ashldi3.S
AS arch/arm/boot/compressed/ashldi3.o
LD arch/arm/boot/compressed/vmlinux
OBJCOPY arch/arm/boot/zImage
Kernel: arch/arm/boot/zImage is ready
UIMAGE arch/arm/boot/uImage
Image Name: Linux-3.4.39+
Created: Tue Jun 25 11:22:27 2019
Image Type: ARM Linux Kernel Image (uncompressed)
Data Size: 2572736 Bytes = 2512.44 KiB = 2.45 MiB
Load Address: 40008000
Entry Point: 40008000
Image arch/arm/boot/uImage is ready
我是参考 @qianhao 大神这个帖子: https://whycan.cn/t_682.html
6.编译内核
使用我提供的 lichee_BSP_config 说明一下 这里修改了内核支持网口 支持ext4文件系统 就直接给出我配置好的。
cd linux-3.4cp lichee_BSP_config .config
make ARCH=arm CROSS_COMPILE=arm-linux-gnueabi- uImage -j16
make ARCH=arm CROSS_COMPILE=arm-linux-gnueabi- -j16 INSTALL_MOD_PATH=out modules
make ARCH=arm CROSS_COMPILE=arm-linux-gnueabi- -j16 INSTALL_MOD_PATH=out modules_install
这时 我们要用的 uImage 在 arch/arm/boot/uImage
smartcar@ubuntu:/opt/v3s_linux3.4$ make ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- uImage
HOSTCC scripts/kconfig/conf.o
SHIPPED scripts/kconfig/zconf.tab.c
SHIPPED scripts/kconfig/zconf.lex.c
SHIPPED scripts/kconfig/zconf.hash.c
HOSTCC scripts/kconfig/zconf.tab.o
HOSTLD scripts/kconfig/conf
scripts/kconfig/conf --silentoldconfig Kconfig
WRAP arch/arm/include/generated/asm/auxvec.h
WRAP arch/arm/include/generated/asm/bitsperlong.h
WRAP arch/arm/include/generated/asm/cputime.h
WRAP arch/arm/include/generated/asm/emergency-restart.h
WRAP arch/arm/include/generated/asm/errno.h
WRAP arch/arm/include/generated/asm/ioctl.h
WRAP arch/arm/include/generated/asm/irq_regs.h
WRAP arch/arm/include/generated/asm/kdebug.h
WRAP arch/arm/include/generated/asm/local.h
WRAP arch/arm/include/generated/asm/local64.h
WRAP arch/arm/include/generated/asm/percpu.h
WRAP arch/arm/include/generated/asm/poll.h
WRAP arch/arm/include/generated/asm/resource.h
WRAP arch/arm/include/generated/asm/sections.h
WRAP arch/arm/include/generated/asm/siginfo.h
WRAP arch/arm/include/generated/asm/sizes.h
CHK include/linux/version.h
UPD include/linux/version.h
CHK include/generated/utsrelease.h
UPD include/generated/utsrelease.h
Generating include/generated/mach-types.h
CC kernel/bounds.s
In file included from include/linux/compiler.h:48:0,
from include/linux/stddef.h:4,
from include/linux/posix_types.h:4,
from include/linux/types.h:17,
from include/linux/page-flags.h:8,
from kernel/bounds.c:9:
include/linux/compiler-gcc.h:100:1: fatal error: linux/compiler-gcc7.h: No such file or directory
#include gcc_header(__GNUC__)
^~~~
compilation terminated.
/opt/v3s_linux3.4/./Kbuild:35: recipe for target 'kernel/bounds.s' failed
make[1]: *** [kernel/bounds.s] Error 1
Makefile:985: recipe for target 'prepare0' failed
make: *** [prepare0] Error 2
smartcar:/$ gcc -v
Using built-in specs.
COLLECT_GCC=gcc
COLLECT_LTO_WRAPPER=/usr/lib/gcc/x86_64-linux-gnu/7/lto-wrapper
OFFLOAD_TARGET_NAMES=nvptx-none
OFFLOAD_TARGET_DEFAULT=1
Target: x86_64-linux-gnu
Configured with: ../src/configure -v --with-pkgversion='Ubuntu 7.4.0-1ubuntu1~18.04.1' --with-bugurl=file:///usr/share/doc/gcc-7/README.Bugs --enable-languages=c,ada,c++,go,brig,d,fortran,objc,obj-c++ --prefix=/usr --with-gcc-major-version-only --program-suffix=-7 --program-prefix=x86_64-linux-gnu- --enable-shared --enable-linker-build-id --libexecdir=/usr/lib --without-included-gettext --enable-threads=posix --libdir=/usr/lib --enable-nls --with-sysroot=/ --enable-clocale=gnu --enable-libstdcxx-debug --enable-libstdcxx-time=yes --with-default-libstdcxx-abi=new --enable-gnu-unique-object --disable-vtable-verify --enable-libmpx --enable-plugin --enable-default-pie --with-system-zlib --with-target-system-zlib --enable-objc-gc=auto --enable-multiarch --disable-werror --with-arch-32=i686 --with-abi=m64 --with-multilib-list=m32,m64,mx32 --enable-multilib --with-tune=generic --enable-offload-targets=nvptx-none --without-cuda-driver --enable-checking=release --build=x86_64-linux-gnu --host=x86_64-linux-gnu --target=x86_64-linux-gnu
Thread model: posix
gcc version 7.4.0 (Ubuntu 7.4.0-1ubuntu1~18.04.1)
smartcar:/$ arm-linux-gnueabihf-gcc -v
Using built-in specs.
COLLECT_GCC=arm-linux-gnueabihf-gcc
COLLECT_LTO_WRAPPER=/usr/lib/gcc-cross/arm-linux-gnueabihf/7/lto-wrapper
Target: arm-linux-gnueabihf
Configured with: ../src/configure -v --with-pkgversion='Ubuntu/Linaro 7.4.0-1ubuntu1~18.04.1' --with-bugurl=file:///usr/share/doc/gcc-7/README.Bugs --enable-languages=c,ada,c++,go,d,fortran,objc,obj-c++ --prefix=/usr --with-gcc-major-version-only --program-suffix=-7 --enable-shared --enable-linker-build-id --libexecdir=/usr/lib --without-included-gettext --enable-threads=posix --libdir=/usr/lib --enable-nls --with-sysroot=/ --enable-clocale=gnu --enable-libstdcxx-debug --enable-libstdcxx-time=yes --with-default-libstdcxx-abi=new --enable-gnu-unique-object --disable-libitm --disable-libquadmath --disable-libquadmath-support --enable-plugin --enable-default-pie --with-system-zlib --with-target-system-zlib --enable-multiarch --enable-multilib --disable-sjlj-exceptions --with-arch=armv7-a --with-fpu=vfpv3-d16 --with-float=hard --with-mode=thumb --disable-werror --enable-multilib --enable-checking=release --build=x86_64-linux-gnu --host=x86_64-linux-gnu --target=arm-linux-gnueabihf --program-prefix=arm-linux-gnueabihf- --includedir=/usr/arm-linux-gnueabihf/include
Thread model: posix
gcc version 7.4.0 (Ubuntu/Linaro 7.4.0-1ubuntu1~18.04.1)
gcc 默认都是 7.4 了, 这很好,不需要再手动安装其他工具链
i2c pcf8563 RTC 芯片: https://item.szlcsc.com/7917.html
Performance:
- Still capture resolution up to 5M with parallel interface
- Video capture resolution up to 1080p@30fps with parallel interface
- Still capture resolution up to 5M with MIPI-CSI2 interface
- Video capture resolution up to 1080p@30fps with MIPI-CSI2 interface
- MIPI-DPHY maximum data rate up to 1Gbps per lane
性能:
- 使用并行接口仍可捕获高达5M的分辨率
- 具有并行接口的视频捕获分辨率高达1080p @ 30fps
- 使用MIPI-CSI2接口仍可捕获高达5M的分辨率
- 使用MIPI-CSI2接口,视频捕获分辨率高达1080p @ 30fps
- MIPI-DPHY每通道最高数据速率高达1Gbps
1.上电初始化 spi 控制器,
2. 初始化ddr,
3. 把代码从flash拷贝到ddr上
4 .跳转运行。
AREA WB_INIT, CODE, READONLY
USR_MODE EQU 0x10
FIQ_MODE EQU 0x11
IRQ_MODE EQU 0x12
SVC_MODE EQU 0x13
ABT_MODE EQU 0x17
UDF_MODE EQU 0x1B
SYS_MODE EQU 0x1F
I_BIT EQU 0x80
F_BIT EQU 0x40
IRQ_RAMStack EQU 0x81FA0000
DRAM_Limit EQU 0x81F00000 ;DDR栈顶
RAM_Limit EQU 0x4000 ;内存大小 32k
UND_Stack EQU RAM_Limit - 128
Abort_Stack EQU RAM_Limit - 256
IRQ_Stack EQU RAM_Limit - 512
FIQ_Stack EQU RAM_Limit - 768
SVC_Stack EQU RAM_Limit - 1024
USR_Stack EQU RAM_Limit - 2048
ENTRY
; EXPORT Reset_Go
; EXPORT Vector_Table
IMPORT ||Load$$ER_IROM1$$Length||
IMPORT ||Image$$RW_RAM1$$RW$$Length||
; 链接器产生代码链接运行位置
_start
; /* Boot head information for BROM */
DCD 0xea000016
DCB 'e', 'G', 'O', 'N', '.', 'B', 'T', '0'
DCD 0, ||Load$$ER_IROM1$$Length||
; DCD 0, __bootloader_size
DCB 'S', 'P', 'L', 2
DCD 0, 0
DCD 0, 0, 0, 0, 0, 0, 0, 0
DCD 0, 0, 0, 0, 0, 0, 0, 0 ;/* 0x40 - boot params, 0x58 - fel boot type, 0x5c - dram size */
Vector_Table
B Reset_Go
LDR PC, Undefined_Addr
LDR PC, SWI_Addr
LDR PC, Prefetch_Addr
LDR PC, Abort_Addr
DCD 0x0
LDR PC, IRQ_Addr
LDR PC, FIQ_Addr
Reset_Addr DCD Reset_Go
Undefined_Addr DCD Undefined_Handler
SWI_Addr DCD SWI_Handler1
Prefetch_Addr DCD Prefetch_Handler
Abort_Addr DCD Abort_Handler
DCD 0
IRQ_Addr DCD IRQ_Handler
FIQ_Addr DCD FIQ_Handler
Undefined_Handler
B Undefined_Handler
SWI_Handler1
B SWI_Handler1
Prefetch_Handler
B Prefetch_Handler
Abort_Handler
B Abort_Handler
IMPORT arm32_do_irq
PRESERVE8
IRQ_Handler
ldr sp,=IRQ_RAMStack
sub sp, sp, #72
stmia sp, {r0 - r12}
add r8, sp, #60
stmdb r8, {sp, lr}^
str lr, [r8, #0]
mrs r6, spsr
str r6, [r8, #4]
str r0, [r8, #8]
mov r0, sp
bl arm32_do_irq
ldmia sp, {r0 - lr}^
mov r0, r0
ldr lr, [sp, #60]
add sp, sp, #72
subs pc, lr, #4
FIQ_Handler
B FIQ_Handler
EXPORT __CodeAddr__
; 引入链接器产生符号,以确定代码运行位置,编译生成的大小
IMPORT ||Load$$ER_IROM1$$Base||
IMPORT ||Load$$RW_RAM1$$RW$$Length||
IMPORT ||Load$$ER_IROM2$$Length||
; IMPORT ||Image$$ER_IROM2$$Length||
; 链接器产生代码链接运行位置
__CodeAddr__ DCD ||Load$$ER_IROM1$$Base||
__CodeSize__ DCD ||Load$$ER_IROM1$$Length|| + ||Load$$ER_IROM2$$Length|| + ||Load$$RW_RAM1$$RW$$Length||
Reset_Go
;/* Save boot params to 0x00000040 */
ldr r0, =0x01c20890
ldr r1, = 0x11111111
str r1,[r0]
ldr r0, =0x01c20894
ldr r1, = 0x11111111
str r1,[r0]
;ldr r0, =0x01c208a0
;ldr r1, = 0xffffffff
;str r1,[r0]
ldr r0, =0x00000040
str sp, [r0, #0]
str lr, [r0, #4]
mrs lr, cpsr
str lr, [r0, #8]
mrc p15, 0, lr, c1, c0, 0
str lr, [r0, #12]
mrc p15, 0, lr, c1, c0, 0
str lr, [r0, #16]
; /* Check boot type just for fel */
mov r0, #0x0
ldr r1, [r0, #8]
ldr r2, =0x4c45462e
cmp r1, r2
bne lab1
; ldr r1, =0x1
; str r1, [r0, #0x58]
lab1 nop
; /* Enter svc mode and mask interrupts */
mrs r0, cpsr
bic r0, r0, #0x1f
orr r0, r0, #0xd3
msr CPSR_cxsf, r0
; /* Set vector to the low address */
mrc p15, 0, r0, c1, c0, 0
bic r0, #(1<<13)
mcr p15, 0, r0, c1, c0, 0
; /* Copy vector to the correct address */
adr r0, Vector_Table
mrc p15, 0, r2, c1, c0, 0
ands r2, r2, #(1 << 13)
ldreq r1, =0x00000000
ldrne r1, =0xffff0000
; mcr p15, 0, r2, c1, c0, 0
ldmia r0!, {r2-r8, r10}
stmia r1!, {r2-r8, r10}
ldmia r0!, {r2-r8, r10}
stmia r1!, {r2-r8, r10}
IMPORT sys_clock_init
IMPORT sys_dram_init
IMPORT sys_spi_flash_init
IMPORT sys_spi_flash_read
IMPORT sys_spi_flash_exit
IMPORT memcpy
IMPORT memset
IMPORT MMU_Init
PRESERVE8
; /* Boot speed up, leave slower sram */
adr r0, _start
ldr r1, =_start
cmp r0, r1
beq _speedup
bl sys_dram_init
bl sys_clock_init
bl sys_spi_flash_init
bl MMU_Init
ldr r0,=0x00
ldr r1,__CodeAddr__
ldr r2,__CodeSize__
bl sys_spi_flash_read
; bl sys_spi_flash_exit
_speedup
nop
MSR CPSR_c, #UDF_MODE :OR: I_BIT :OR: F_BIT
LDR SP, =UND_Stack + DRAM_Limit
MSR CPSR_c, #ABT_MODE :OR: I_BIT :OR: F_BIT
LDR SP, =Abort_Stack + DRAM_Limit
MSR CPSR_c, #IRQ_MODE :OR: I_BIT :OR: F_BIT
LDR SP, =IRQ_Stack + DRAM_Limit
MSR CPSR_c, #FIQ_MODE :OR: I_BIT :OR: F_BIT
LDR SP, =FIQ_Stack + DRAM_Limit
MSR CPSR_c, #SYS_MODE :OR: I_BIT :OR: F_BIT
LDR SP, =USR_Stack + DRAM_Limit
MSR CPSR_c, #SVC_MODE :OR: I_BIT :OR: F_BIT
LDR SP, =SVC_Stack + DRAM_Limit
MRS r1, CPSR
; BIC r1, #0x1f
; ORR r1, #0x7f;进入IRQ模式
AND r1, #0x7f;允许IRQ中断
MSR CPSR_c,r1
; MRC p15, 0, r0 , c1, c0 ; r0 := cp15 register 1
; BIC r0, r0, #0x2000 ; Clear bit13 in r1
; MCR p15, 0, r0 , c1, c0 ; cp15 register 1 := r0
IMPORT __main
adr r0, _start
ldr r1, =_start
cmp r0, r1
bne _NoDdr
bl sys_clock_init
bl sys_spi_flash_init
bl MMU_Init
_NoDdr
LDR R0, =__main
BX R0
; B __main
end
100颗 f1c100s 100颗f1c200s芯片到了晒晒,PCB在华强pcb做的,四层板,邮票孔嘉立创说不能做4边的,比较郁闷,华强贵了150块钱
https://whycan.cn/files/members/428/f1c200s.png
不错, 强势围观, f1c200s 比 f1c100s 贵多少钱?
jiangming1399 说:小王子&木头人 说:你们用16Mflash可以成功reboot吗
不行……
主线linux spiflash能不能重启
确实不能重启, 不过和 flash 根文件系统没有关系。
我用 initramfs 根文件系统也一样:
# reboot
# Stopping network: OK
Stopping klogd: OK
Stopping syslogd: OK
umount: can't unmount /: Invalid argument
The system is going down NOW!
Sent SIGTERM to all processesSent SIGKILL to all processes
[ 894.514832] reboot: Restarting system
[ 895.514598] Reboot failed -- System halted
arch/arm/kernel/reboot.c
/*
* Restart requires that the secondary CPUs stop performing any activity
* while the primary CPU resets the system. Systems with a single CPU can
* use soft_restart() as their machine descriptor's .restart hook, since that
* will cause the only available CPU to reset. Systems with multiple CPUs must
* provide a HW restart implementation, to ensure that all CPUs reset at once.
* This is required so that any code running after reset on the primary CPU
* doesn't have to co-ordinate with other CPUs to ensure they aren't still
* executing pre-reset code, and using RAM that the primary CPU's code wishes
* to use. Implementing such co-ordination would be essentially impossible.
*/
void machine_restart(char *cmd)
{
local_irq_disable();
smp_send_stop();
if (arm_pm_restart)
arm_pm_restart(reboot_mode, cmd);
else
do_kernel_restart(cmd);
/* Give a grace period for failure to restart of 1s */
mdelay(1000);
/* Whoops - the platform was unable to reboot. Tell the user! */
printk("Reboot failed -- System halted\n");
while (1);
}
发现主线上面并没有 W25M512 的补丁, 代码里面并没有适配这个芯片。
哪怕 最新的 linux 5.1 也没有关于 die 切换的代码
https://github.com/torvalds/linux/blob/v5.1/include/linux/mtd/spi-nor.h
https://github.com/torvalds/linux/blob/v5.1/drivers/mtd/spi-nor/spi-nor.c
From c7025568f83800de384c457557169e44740dc8f7 Mon Sep 17 00:00:00 2001
From: "Anton D. Kachalov" <mouse@yandex-team.ru>
Date: Tue, 24 May 2016 19:36:35 +0300
Subject: [PATCH 06/14] Add various MTD SPI chips
Signed-off-by: Anton D. Kachalov <mouse@yandex-team.ru>
---
drivers/mtd/spichips/Kconfig | 94 ++++
drivers/mtd/spichips/Makefile | 18 +
drivers/mtd/spichips/astspi.c | 367 +++++++++++++
drivers/mtd/spichips/atmel.c | 133 +++++
drivers/mtd/spichips/default.c | 106 ++++
drivers/mtd/spichips/generic.c | 1052 ++++++++++++++++++++++++++++++++++++++
drivers/mtd/spichips/intels33.c | 96 ++++
drivers/mtd/spichips/m25pxx.c | 121 +++++
drivers/mtd/spichips/macronix.c | 208 ++++++++
drivers/mtd/spichips/micron.c | 104 ++++
drivers/mtd/spichips/spansion.c | 103 ++++
drivers/mtd/spichips/spiaccess.c | 433 ++++++++++++++++
drivers/mtd/spichips/spiflash.h | 178 +++++++
drivers/mtd/spichips/spimtd.c | 241 +++++++++
drivers/mtd/spichips/spireg.c | 180 +++++++
drivers/mtd/spichips/winbond.c | 98 ++++
16 files changed, 3532 insertions(+)
create mode 100644 drivers/mtd/spichips/Kconfig
create mode 100644 drivers/mtd/spichips/Makefile
create mode 100644 drivers/mtd/spichips/astspi.c
create mode 100644 drivers/mtd/spichips/atmel.c
create mode 100644 drivers/mtd/spichips/default.c
create mode 100644 drivers/mtd/spichips/generic.c
create mode 100644 drivers/mtd/spichips/intels33.c
create mode 100644 drivers/mtd/spichips/m25pxx.c
create mode 100644 drivers/mtd/spichips/macronix.c
create mode 100644 drivers/mtd/spichips/micron.c
create mode 100644 drivers/mtd/spichips/spansion.c
create mode 100644 drivers/mtd/spichips/spiaccess.c
create mode 100644 drivers/mtd/spichips/spiflash.h
create mode 100644 drivers/mtd/spichips/spimtd.c
create mode 100644 drivers/mtd/spichips/spireg.c
create mode 100644 drivers/mtd/spichips/winbond.c
diff --git a/drivers/mtd/spichips/Kconfig b/drivers/mtd/spichips/Kconfig
new file mode 100644
index 0000000..c5e5a4c
--- /dev/null
+++ b/drivers/mtd/spichips/Kconfig
@@ -0,0 +1,94 @@
+# drivers/mtd/chips/Kconfig
+# $Id: Kconfig,v 1.18 2005/11/07 11:14:22 gleixner Exp $
+
+menu "SPI Flash chip drivers"
+ depends on MTD!=n
+
+config MTD_SPI
+ bool "Enable MTD support on SPI devices"
+ depends on MTD
+ help
+ Select this if you want to access SPI flash devices via MTD
+
+config MTD_SPI_SPANSION
+ bool "Spansion SPI devices Support"
+ depends on MTD_SPI
+ help
+ Select this if you want to use Spansion SPI devices
+
+config MTD_SPI_MACRONIX
+ bool "Macronix SPI devices Support"
+ depends on MTD_SPI
+ help
+ Select this if you want to use Macronix SPI devices
+
+config MTD_SPI_INTEL_S33
+ bool "Intel S33 SPI devices Support"
+ depends on MTD_SPI
+ help
+ Select this if you want to use Intel S33 SPI devices
+
+config MTD_SPI_WINBOND
+ bool "Winbond SPI devices Support"
+ depends on MTD_SPI
+ help
+ Select this if you want to use Winbond SPI devices
+
+config MTD_SPI_AT
+ bool "Atmel SPI devices Support"
+ depends on MTD_SPI
+ help
+ Select this if you want to use Atmel SPI devices
+
+config MTD_SPI_ST
+ bool "ST Micro SPI devices Support"
+ depends on MTD_SPI
+ help
+ Select this if you want to use ST Microelectronics SPI devices
+
+config MTD_SPI_NUMONYX
+ bool "Numonyx SPI devices Support"
+ depends on MTD_SPI
+ help
+ Select this if you want to use Numonyx SPI devices
+
+config MTD_SPI_MICRON
+ bool "Numonyx SPI devices Support"
+ depends on MTD_SPI
+ help
+ Select this if you want to use Micron SPI devices
+
+config MTD_SPI_DEFAULT
+ bool "Support for SPI Devices not supporting ReadID"
+ depends on MTD_SPI
+ help
+ Select this if the SPI device on your board does not SPI ReadID Command
+
+config DEFAULT_SPI_NAME
+ string "Default SPI Name"
+ depends on MTD_SPI && MTD_SPI_DEFAULT
+ default "default"
+ help
+ Name of the SPI Device that does not support ReadID
+
+config DEFAULT_SPI_SIZE
+ int "Default SPI Size in Bytes"
+ depends on MTD_SPI && MTD_SPI_DEFAULT
+ default "65536"
+ help
+ Chip Size of the SPI Device that does not support ReadID
+
+config DEFAULT_SPI_ERASE_SIZE
+ int "Default SPI Erase Block Size in Bytes"
+ depends on MTD_SPI && MTD_SPI_DEFAULT
+ default "65536"
+ help
+ Erase Block Size of the SPI Device that does not support ReadID
+
+config MTD_AST_SPI
+ bool "AST SOC SPI Flash Controller"
+ depends on MTD_SPI
+ help
+ If you are using SPI device on AST SOC, select Y
+
+endmenu
diff --git a/drivers/mtd/spichips/Makefile b/drivers/mtd/spichips/Makefile
new file mode 100644
index 0000000..b30a452
--- /dev/null
+++ b/drivers/mtd/spichips/Makefile
@@ -0,0 +1,18 @@
+#
+# linux/drivers/spichips/Makefile
+#
+obj-$(CONFIG_MTD_SPI) += spimtd.o spiaccess.o spireg.o generic.o
+
+obj-$(CONFIG_MTD_SPI_ST) += m25pxx.o
+obj-$(CONFIG_MTD_SPI_SPANSION) += spansion.o
+obj-$(CONFIG_MTD_SPI_MACRONIX) += macronix.o
+obj-$(CONFIG_MTD_SPI_AT) += atmel.o
+obj-$(CONFIG_MTD_SPI_INTEL_S33) += intels33.o
+obj-$(CONFIG_MTD_SPI_WINBOND) += winbond.o
+obj-$(CONFIG_MTD_SPI_MICRON) += micron.o
+obj-$(CONFIG_MTD_SPI_NUMONYX) += micron.o
+
+# The default driver should be the last in the list of suppported devices
+obj-$(CONFIG_MTD_SPI_DEFAULT) += default.o
+
+obj-$(CONFIG_MTD_AST_SPI) += astspi.o
diff --git a/drivers/mtd/spichips/astspi.c b/drivers/mtd/spichips/astspi.c
new file mode 100644
index 0000000..a0dc9d4
--- /dev/null
+++ b/drivers/mtd/spichips/astspi.c
@@ -0,0 +1,367 @@
+/*
+ * (C) Copyright 2009
+ * American Megatrends Inc.
+ *
+ * SPI flash controller driver for the AST SoC
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+#include "spiflash.h"
+
+#define AST_FMC_REG_BASE AST_FMC_VA_BASE /* 0x1E620000 */
+#define AST_FMC_FLASH_CTRL_REG 0x00
+
+#define AST_FMC_CE0_CTRL_REG 0x10
+#define AST_FMC_CTRL_REG_SIZE 0x04
+
+#define AST_SPI_CMD_MASK 0x00FF0000 /* bit[23:16] */
+#define AST_SPI_CMD_SHIFT 16
+
+#define AST_SPI_CLOCK_MASK 0x00000F00 /* bit[11:8] */
+#define AST_SPI_CLOCK_SHIFT 8
+
+#define AST_SPI_DUMMY_MASK 0x000000C0 /* bit[7:6] */
+#define AST_SPI_DUMMY_0 0x00000000
+#define AST_SPI_DUMMY_1 0x00000040
+#define AST_SPI_DUMMY_2 0x00000080
+#define AST_SPI_DUMMY_3 0x000000C0
+
+#define AST_SPI_DATA_SINGLE 0x00000000
+#define AST_SPI_DATA_DUAL 0x00000008
+#define AST_SPI_DUAL_IO 0x00000002
+#define AST_SPI_FULL_DUAL_IO 0x00000003
+#define AST_SPI_DATA_MASK 7
+#define AST_SPI_DUAL_IO_SHIFT 28
+
+#define AST_SPI_CE_LOW 0x00000000
+#define AST_SPI_CE_HI 0x00000004
+
+#define AST_SPI_CMD_MODE_MASK 0x00000007 /* bit[2:0] */
+#define AST_SPI_CMD_MODE_NORMAL 0x00000000
+#define AST_SPI_CMD_MODE_FAST 0x00000001
+#define AST_SPI_CMD_MODE_WRITE 0x00000002
+#define AST_SPI_CMD_MODE_USER 0x00000003
+
+#define SPI_FAST_READ_CMD 0x0B
+#define SPI_DREAD_CMD 0x3B
+#define SPI_2READ_CMD 0xBB
+
+extern unsigned long ractrends_spiflash_flash_size[MAX_SPI_BANKS];
+static int *g_fast_read = 0;
+
+static void reset_flash(int bank)
+{
+ uint32_t reg;
+ uint32_t ctrl_reg;
+
+ // bank = 0,CE0 (0x10) ; bank = 1,CE1 (0x14) ; bank = 2,CE2 (0x18)
+ ctrl_reg = AST_FMC_CE0_CTRL_REG + (bank * AST_FMC_CTRL_REG_SIZE);
+
+ reg = ioread32((void __iomem *)AST_FMC_REG_BASE + ctrl_reg);
+ if (*g_fast_read == 3)//2xI/O Read
+ {
+ reg &= ~(AST_SPI_CMD_MASK | AST_SPI_DUMMY_MASK | AST_SPI_CMD_MODE_MASK);
+ reg |= (SPI_2READ_CMD << AST_SPI_CMD_SHIFT) | AST_SPI_DUMMY_1 | AST_SPI_CE_LOW | AST_SPI_CMD_MODE_FAST | (AST_SPI_FULL_DUAL_IO << AST_SPI_DUAL_IO_SHIFT);
+ }
+ else if (*g_fast_read == 2)//Dual Read
+ {
+ reg &= ~(AST_SPI_CMD_MASK | AST_SPI_DUMMY_MASK | AST_SPI_CMD_MODE_MASK);
+ reg |= (SPI_DREAD_CMD << AST_SPI_CMD_SHIFT) | AST_SPI_DUMMY_1 | AST_SPI_CE_LOW | AST_SPI_CMD_MODE_FAST | (AST_SPI_DUAL_IO << AST_SPI_DUAL_IO_SHIFT);
+ }
+ else if (*g_fast_read == 1)//Fast Read
+ {
+ reg &= ~(AST_SPI_CMD_MASK | AST_SPI_DUMMY_MASK | AST_SPI_CMD_MODE_MASK);
+ reg |= (SPI_FAST_READ_CMD << AST_SPI_CMD_SHIFT) | AST_SPI_DUMMY_1 | AST_SPI_CE_LOW | AST_SPI_CMD_MODE_FAST;
+ }
+ else
+ {
+ reg &= (~AST_SPI_CMD_MODE_MASK);
+ reg |= (AST_SPI_CE_LOW | AST_SPI_CMD_MODE_NORMAL);
+ }
+ iowrite32(reg, (void __iomem *)AST_FMC_REG_BASE + ctrl_reg);
+
+}
+
+static void reset_iomode (int bank)
+{
+ uint32_t reg;
+ uint32_t ctrl_reg;
+
+ // bank = 0,CE0 (0x10) ; bank = 1,CE1 (0x14) ; bank = 2,CE2 (0x18)
+ ctrl_reg = AST_FMC_CE0_CTRL_REG + (bank * AST_FMC_CTRL_REG_SIZE);
+
+ reg = ioread32((void __iomem *)AST_FMC_REG_BASE + ctrl_reg);
+ reg &= ~(AST_SPI_CMD_MASK | AST_SPI_DUMMY_MASK | (AST_SPI_DATA_MASK << AST_SPI_DUAL_IO_SHIFT));
+
+ if (*g_fast_read == 2)//Dual Read
+ reg |= (AST_SPI_DUAL_IO << AST_SPI_DUAL_IO_SHIFT);
+ else if (*g_fast_read == 3)//2xI/O Read
+ reg |= (AST_SPI_FULL_DUAL_IO << AST_SPI_DUAL_IO_SHIFT);
+
+ iowrite32(reg, (void __iomem *)AST_FMC_REG_BASE + ctrl_reg);
+
+ return;
+}
+
+static void chip_select_active(int bank)
+{
+ uint32_t reg;
+ uint32_t ctrl_reg;
+
+ // bank = 0,CE0 (0x10) ; bank = 1,CE1 (0x14) ; bank = 2,CE2 (0x18)
+ ctrl_reg = AST_FMC_CE0_CTRL_REG + (bank * AST_FMC_CTRL_REG_SIZE);
+
+ reg = ioread32((void __iomem *)AST_FMC_REG_BASE + ctrl_reg);
+ reg &= (~(AST_SPI_CMD_MODE_MASK | (AST_SPI_DATA_MASK << AST_SPI_DUAL_IO_SHIFT)) );
+ reg |= (AST_SPI_CE_LOW | AST_SPI_CMD_MODE_USER);
+ iowrite32(reg, (void __iomem *)AST_FMC_REG_BASE + ctrl_reg);
+}
+
+static void chip_select_deactive(int bank)
+{
+ uint32_t reg;
+ uint32_t ctrl_reg;
+
+ // bank = 0,CE0 (0x10) ; bank = 1,CE1 (0x14) ; bank = 2,CE2 (0x18)
+ ctrl_reg = AST_FMC_CE0_CTRL_REG + (bank * AST_FMC_CTRL_REG_SIZE);
+
+ reg = ioread32((void __iomem *)AST_FMC_REG_BASE + ctrl_reg);
+ reg &= (~(AST_SPI_CMD_MODE_MASK | (AST_SPI_DATA_MASK << AST_SPI_DUAL_IO_SHIFT)) );
+ reg |= (AST_SPI_CE_HI | AST_SPI_CMD_MODE_USER);
+ iowrite32(reg, (void __iomem *)AST_FMC_REG_BASE + ctrl_reg);
+}
+
+static int astspiflash_transfer(int bank, unsigned char *cmd, int cmdlen, SPI_DIR dir, unsigned char *data, unsigned long datalen)
+{
+ ulong base;
+ int i;
+ ulong offset = 0;
+
+ for(i = 0; i < bank; i++)
+ {
+ offset += ractrends_spiflash_flash_size[i];
+ }
+
+ base = AST_SPI_FLASH_VA_BASE + offset;
+
+ chip_select_active(bank);
+
+ if (cmd[0] == 0xBB)
+ {
+ *((volatile unsigned char *) base) = cmd[0];
+ reset_iomode(bank);
+ for (i = 1; i < cmdlen; i ++)
+ *((volatile unsigned char *) base) = cmd[i];
+ }
+ else if (cmd[0] == 0x3B)
+ {
+ for (i = 0; i < cmdlen; i ++)
+ *((volatile unsigned char *) base) = cmd[i];
+ reset_iomode(bank);
+ }
+ else
+ {
+ /* issue command */
+ for (i = 0; i < cmdlen; i ++)
+ *((volatile unsigned char *) base) = cmd[i];
+ }
+
+ if (dir == SPI_WRITE) {
+ /* write data to flash */
+ for (i = 0; i < datalen; i ++) {
+ *((volatile unsigned char *) base) = data[i];
+ }
+ } else if (dir == SPI_READ) {
+ /* read data from flash */
+ for (i = 0; i < datalen; i ++) {
+ data[i] = ((volatile unsigned char *) base)[i];
+ }
+ }
+
+ chip_select_deactive(bank);
+
+
+ reset_flash(bank);
+ return 0;
+}
+
+static const unsigned char clock_selection_table[] = {
+ 0x0F, /* 1 */
+ 0x07, /* 2 */
+ 0x0E, /* 3 */
+ 0x06, /* 4 */
+ 0x0D, /* 5 */
+ 0x05, /* 6 */
+ 0x0C, /* 7 */
+ 0x04, /* 8 */
+ 0x0B, /* 9 */
+ 0x03, /* 10 */
+ 0x0A, /* 11 */
+ 0x02, /* 12 */
+ 0x09, /* 13 */
+ 0x01, /* 14 */
+ 0x08, /* 15 */
+ 0x00, /* 16 */
+};
+
+static int astspiflash_configure_clock(int bank, unsigned int clock)
+{
+ uint32_t reg;
+ uint32_t cpu_clock;
+ uint32_t clock_divisor;
+ uint32_t ctrl_reg;
+#if defined(CONFIG_SOC_AST2500) || defined(CONFIG_SOC_AST2530)
+ uint32_t cpu_ratio;
+ uint32_t axi_ratio;
+#endif
+ // bank = 0,CE0 (0x10) ; bank = 1,CE1 (0x14) ; bank = 2,CE2 (0x18)
+ ctrl_reg = AST_FMC_CE0_CTRL_REG + (bank * AST_FMC_CTRL_REG_SIZE);
+
+ /* according to AST spec, clock of SPI controller can not exceed 50M Hz */
+ if (clock > (50 * 1000000))
+ clock = 50 * 1000000;
+
+ /* read CPU clock rate and CPU/AHB ratio from SCU */
+ reg = ioread32((void __iomem *)SCU_HW_STRAPPING_REG);
+
+ #if defined(CONFIG_SOC_AST2500) || defined(CONFIG_SOC_AST2530)
+ cpu_ratio = 2;
+
+ switch ((reg & 0x00000E00) >> 9) {
+ case 0x01:
+ axi_ratio = 2;
+ break;
+ case 0x02:
+ axi_ratio = 3;
+ break;
+ case 0x03:
+ axi_ratio = 4;
+ break;
+ case 0x04:
+ axi_ratio = 5;
+ break;
+ case 0x05:
+ axi_ratio = 6;
+ break;
+ case 0x06:
+ axi_ratio = 7;
+ break;
+ case 0x07:
+ axi_ratio = 8;
+ break;
+ default:
+ axi_ratio = 2;
+ break;
+ }
+
+ cpu_clock = 792 * 1000000;//Default H-PLL value
+ cpu_clock = cpu_clock / cpu_ratio / axi_ratio;
+ #else
+ switch ((reg & 0x00000300) >> 8) {
+ case 0x00:
+ cpu_clock = 384 * 1000000;
+ break;
+ case 0x01:
+ cpu_clock = 360 * 1000000;
+ break;
+ case 0x02:
+ cpu_clock = 336 * 1000000;
+ break;
+ case 0x03:
+ cpu_clock = 408 * 1000000;
+ break;
+ default:
+ cpu_clock = 408 * 1000000;
+ }
+
+ switch ((reg & 0x00000C00) >> 10) {
+ case 0x01:
+ cpu_clock /= 2;
+ break;
+ case 0x02:
+ cpu_clock /= 4;
+ break;
+ case 0x03:
+ cpu_clock /= 3;
+ break;
+ }
+ #endif
+
+ clock_divisor = 1;
+ while ((cpu_clock / clock_divisor) > clock) {
+ clock_divisor ++;
+ if (clock_divisor == 16)
+ break;
+ }
+
+ reg = ioread32((void __iomem *)AST_FMC_REG_BASE + ctrl_reg);
+ reg &= ~AST_SPI_CLOCK_MASK;
+ reg |= (clock_selection_table[clock_divisor - 1] << AST_SPI_CLOCK_SHIFT);
+ iowrite32(reg, (void __iomem *)AST_FMC_REG_BASE + ctrl_reg);
+
+ return 0;
+}
+
+struct spi_ctrl_driver astspi_driver = {
+ .name = "astspiflash",
+ .module = THIS_MODULE,
+ .max_read = (64 * 1024 * 1024), /* 32 MB */
+ #ifdef CONFIG_FLASH_OPERATION_MODE_MASK
+ .operation_mode_mask = CONFIG_FLASH_OPERATION_MODE_MASK,
+ #else
+ .operation_mode_mask = 0x00010003, //Default
+ #endif
+ .fast_read = 1,
+ .fast_write = 0,
+ .spi_transfer = astspiflash_transfer,
+ .spi_burst_read = astspiflash_transfer,
+ .spi_configure_clock = astspiflash_configure_clock,
+};
+
+static int astspi_init(void)
+{
+ sema_init(&astspi_driver.lock, 1);
+ register_spi_ctrl_driver(&astspi_driver);
+
+ g_fast_read = &astspi_driver.fast_read;
+
+ reset_flash(0); // CE0
+
+ reset_flash(1); // CE1
+
+ reset_flash(2); // CE2
+ #if !defined(CONFIG_SOC_AST2500) && !defined(CONFIG_SOC_AST2530)
+ reset_flash(3); // CE3
+ #endif
+
+ return 0;
+}
+
+static void astspi_exit(void)
+{
+ unregister_spi_ctrl_driver(&astspi_driver);
+}
+
+module_init(astspi_init);
+module_exit(astspi_exit);
+
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("American Megatrends Inc");
+MODULE_DESCRIPTION("AST SOC SPI flash controller driver");
diff --git a/drivers/mtd/spichips/atmel.c b/drivers/mtd/spichips/atmel.c
new file mode 100644
index 0000000..a7cfddb
--- /dev/null
+++ b/drivers/mtd/spichips/atmel.c
@@ -0,0 +1,133 @@
+/*
+ * Copyright (C) 2007 American Megatrends Inc
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#ifdef __UBOOT__
+#include <common.h>
+#endif
+#include "spiflash.h"
+#ifdef CFG_FLASH_SPI_DRIVER
+
+/* Name, ID1, ID2 , Size, Clock, Erase regions, address mode,{ Offset, Erase Size, Erase Block Count } */
+/* address mode: 0x00 -3 byte address
+ 0x01 - 4 byte address
+ 0x02 - Low byte: 3 byte address, High byte: 4 byte address*/
+static struct spi_flash_info atmel_data [] =
+{
+ /* Atmel 26F 64K Sectors */
+ { "Atmel at26f004" , 0x1F, 0x0004, 0x00010001, 0x100000 , 25 * 1000000, 1, 0x00, {{ 0, 64 * 1024, 8 },} },
+
+ /* Atmel 25DF 64K Sectors */
+ { "Atmel at25df041a" , 0x1F, 0x0144, 0x00010001, 0x100000 , 70 * 1000000, 1, 0x00, {{ 0, 64 * 1024, 8 },} },
+
+ /* Atmel 26DF 64K Sectors */
+ { "Atmel at26df081a" , 0x1F, 0x0145, 0x00010001, 0x100000 , 70 * 1000000, 1, 0x00, {{ 0, 64 * 1024, 16 },} },
+ { "Atmel at26df161a" , 0x1F, 0x0146, 0x00010001, 0x200000 , 25 * 1000000, 1, 0x00, {{ 0, 64 * 1024, 32 },} },
+ { "Atmel at26df161" , 0x1F, 0x0046, 0x00010001, 0x200000 , 25 * 1000000, 1, 0x00, {{ 0, 64 * 1024, 32 },} },
+ { "Atmel at26df321" , 0x1F, 0x0047, 0x00010001, 0x400000 , 25 * 1000000, 1, 0x00, {{ 0, 64 * 1024, 64 },} },
+ { "Atmel at25df321" , 0x1F, 0x0147, 0x00010001, 0x400000 , 85 * 1000000, 1, 0x00, {{ 0, 64 * 1024, 64 },} },
+};
+
+
+static
+int
+atmel_probe(int bank,struct spi_ctrl_driver *ctrl_drv, struct spi_flash_info *chip_info)
+{
+ int retval;
+ unsigned char status;
+
+ retval = spi_generic_probe(bank, ctrl_drv,chip_info,"atmel",atmel_data,ARRAY_SIZE(atmel_data));
+ if (retval == -1)
+ return retval;
+
+ if (spi_generic_read_status(bank,ctrl_drv,&status) < 0)
+ {
+ printk("atmel: Read SR Failed.Cannot Unprotect all sectors\n");
+ return retval;
+ }
+
+ /* If SRPL = 1 (Bit 7)and WP/ = 0 (Bit 4), then it is hardware locked */
+ if ((status & 0x80) && (!(status & 0x10)))
+ {
+ printk("atmel: Hardware Locked\n");
+ return retval;
+ }
+
+ /* Check if already unprotected */
+ if ((status & 0xC) == 0)
+ return retval;
+
+ /* if SRPL is set, we have to disable SRPL before unprotect */
+ if (status & 0x80)
+ {
+ if (spi_generic_write_status(bank,ctrl_drv,status& 0x7F) < 0)
+ {
+ printk("atmel: Clearing SRPL failed .Cannot Unprotect all sectors\n");
+ return retval;
+ }
+ }
+
+ /* Unprotect all sectors */
+ if (spi_generic_write_status(bank,ctrl_drv,0x0) < 0)
+ printk("atmel: Unable to Unprotect all sectors\n");
+
+
+ return retval;
+}
+
+struct spi_chip_driver atmel_driver =
+{
+ .name = "atmel",
+ .module = THIS_MODULE,
+ .probe = atmel_probe,
+ .erase_sector = spi_generic_erase,
+ .read_bytes = spi_generic_read,
+ .write_bytes = spi_generic_write,
+ /* Atmel supports individual protect and unprotect of sectors */
+ /* if needed implement the functions and add here */
+};
+
+int
+atmel_init(void)
+{
+ sema_init(&atmel_driver.lock, 1);
+#ifdef __UBOOT__ /* MIPS */
+ atmel_driver.probe = atmel_probe;
+ atmel_driver.erase_sector = spi_generic_erase;
+ atmel_driver.read_bytes = spi_generic_read;
+ atmel_driver.write_bytes = spi_generic_write;
+#endif
+ register_spi_chip_driver(&atmel_driver);
+ return 0;
+}
+
+void
+atmel_exit(void)
+{
+ sema_init(&atmel_driver.lock, 1);
+ unregister_spi_chip_driver(&atmel_driver);
+ return;
+}
+
+module_init(atmel_init);
+module_exit(atmel_exit);
+
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("American Megatrends Inc");
+MODULE_DESCRIPTION("MTD SPI driver for Atmel flash chips");
+
+#endif
diff --git a/drivers/mtd/spichips/default.c b/drivers/mtd/spichips/default.c
new file mode 100644
index 0000000..93f31d7
--- /dev/null
+++ b/drivers/mtd/spichips/default.c
@@ -0,0 +1,106 @@
+/*
+ * Copyright (C) 2007 American Megatrends Inc
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+
+#ifdef __UBOOT__
+#include <common.h>
+#endif
+#include "spiflash.h"
+#ifdef CFG_FLASH_SPI_DRIVER
+
+#ifndef CONFIG_DEFAULT_SPI_NAME
+#define CONFIG_DEFAULT_SPI_NAME "Unknown SPI Device"
+#endif
+
+#ifndef CONFIG_DEFAULT_SPI_SIZE
+#define CONFIG_DEFAULT_SPI_SIZE 0
+#endif
+
+#ifndef CONFIG_DEFAULT_SPI_CLOCK
+#define CONFIG_DEFAULT_SPI_CLOCK (25 * 1000000)
+#endif
+
+#ifndef CONFIG_DEFAULT_SPI_ERASE_SIZE
+#define CONFIG_DEFAULT_SPI_ERASE_SIZE (64 *1024)
+#endif
+
+
+/* This driver is called at end when all probe failed. Some chips don't support read id
+ commands and user can provide the information here */
+
+/* Name, ID1, ID2 , Size, Clock, Erase regions, address mode,{ Offset, Erase Size, Erase Block Count } */
+/* address mode: 0x00 -3 byte address
+ 0x01 - 4 byte address
+ 0x02 - Low byte: 3 byte address, High byte: 4 byte address*/
+static struct spi_flash_info default_data [] =
+{
+ { CONFIG_DEFAULT_SPI_NAME , 0xFF, 0x0FFFF, 0x00010001, CONFIG_DEFAULT_SPI_SIZE , CONFIG_DEFAULT_SPI_CLOCK, 1, 0x00,
+ {{ 0, CONFIG_DEFAULT_SPI_ERASE_SIZE, CONFIG_DEFAULT_SPI_SIZE/CONFIG_DEFAULT_SPI_ERASE_SIZE },} },
+};
+
+static
+int
+default_probe(int bank,struct spi_ctrl_driver *ctrl_drv, struct spi_flash_info *chip_info)
+{
+ memcpy(chip_info,&default_data[0],sizeof(struct spi_flash_info));
+
+ if (spi_generic_write_status(bank,ctrl_drv,0x0) < 0)
+ printk("%s: Unable to Unprotect all sectors\n",CONFIG_DEFAULT_SPI_NAME);
+ return 0;
+}
+
+struct spi_chip_driver default_driver =
+{
+ .name = "default",
+ .module = THIS_MODULE,
+ .probe = default_probe,
+ .erase_sector = spi_generic_erase,
+ .read_bytes = spi_generic_read,
+ .write_bytes = spi_generic_write,
+};
+
+int
+default_init(void)
+{
+ sema_init(&default_driver.lock, 1);
+#ifdef __UBOOT__ /* MIPS */
+ default_driver.probe = default_probe;
+ default_driver.erase_sector = spi_generic_erase;
+ default_driver.read_bytes = spi_generic_read;
+ default_driver.write_bytes = spi_generic_write;
+#endif
+ register_spi_chip_driver(&default_driver);
+ return 0;
+}
+
+void
+default_exit(void)
+{
+ sema_init(&default_driver.lock, 1);
+ unregister_spi_chip_driver(&default_driver);
+ return;
+}
+
+module_init(default_init);
+module_exit(default_exit);
+
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("American Megatrends Inc");
+MODULE_DESCRIPTION("MTD SPI driver for Default flash chips");
+
+#endif
diff --git a/drivers/mtd/spichips/generic.c b/drivers/mtd/spichips/generic.c
new file mode 100644
index 0000000..50a70f6
--- /dev/null
+++ b/drivers/mtd/spichips/generic.c
@@ -0,0 +1,1052 @@
+/*
+ * Copyright (C) 2007-2013 American Megatrends Inc
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+
+#ifdef __UBOOT__
+#include <common.h>
+#endif
+#include "spiflash.h"
+#ifdef CFG_FLASH_SPI_DRIVER
+
+/* Flash opcodes. */
+#define OPCODE_WREN 0x06 /* Write enable */
+#define OPCODE_WRDI 0x04 /* Write disable*/
+#define OPCODE_RDID 0x9F /* Read JEDEC ID */
+#define OPCODE_RDSR 0x05 /* Read status register */
+#define OPCODE_WRSR 0x01 /* Write status register */
+#define OPCODE_READ 0x03 /* Read data bytes */
+#define OPCODE_FAST_READ 0x0B /* Read Fast read */
+#define OPCODE_DREAD 0x3B /* Dual Read Mode */
+#define OPCODE_2READ 0xBB /* 2 x I/O Read Mode */
+#define OPCODE_PP 0x02 /* Page program */
+#define OPCODE_SE 0xD8 /* Sector erase */
+#define OPCODE_DP 0xB9 /* Deep Power Down */
+#define OPCODE_RES 0xAB /* Read Electronic Signature */
+
+/* Status Register bits. */
+#define SR_WIP 0x01 /* Write in progress */
+#define SR_WEL 0x02 /* Write enable latch */
+#define SR_BP0 0x04 /* Block protect 0 */
+#define SR_BP1 0x08 /* Block protect 1 */
+#define SR_BP2 0x10 /* Block protect 2 */
+#define SR_SRWD 0x80 /* SR write protect */
+
+#define PROGRAM_PAGE_SIZE 256 /* Max Program Size */
+
+#define ADDR_16MB 0x1000000
+#define CMD_MX25XX_EN4B 0xb7 /* Enter 4-byte address mode */
+#define CMD_MX25XX_EX4B 0xe9 /* Exit 4-byte address mode */
+
+
+#define ADDRESS_3BYTE 0x00
+#define ADDRESS_4BYTE 0x01
+#define ADDRESS_LO3_HI4_BYTE 0x02
+
+#define ADDRESS_DIE_LO3_HI4_BYTE 0x06
+#define ADDR_32MB 0x2000000
+#define CMD_WX25XX_CS 0xc2 /* Die select */
+
+extern unsigned long ractrends_spiflash_flash_id[MAX_SPI_BANKS];
+
+static int wait_till_ready(int bank,struct spi_ctrl_driver *ctrl_drv);
+
+static
+int inline
+spi_error(int retval)
+{
+ printk("SPI Chip %s (%d) : Error (%d)\n",__FILE__,__LINE__,retval);
+ return retval;
+}
+
+static int
+spi_generic_read_flag_status(int bank, struct spi_ctrl_driver *ctrl_drv,unsigned char *status)
+{
+ int retval;
+ u8 code = 0x70;
+
+ /* Issue Controller Transfer Routine */
+ retval = ctrl_drv->spi_transfer(bank,&code, 1,SPI_READ,status, 1);
+
+ if (retval < 0)
+ return spi_error(retval);
+
+ return 0;
+}
+
+
+
+int
+spi_generic_read_status(int bank, struct spi_ctrl_driver *ctrl_drv,unsigned char *status)
+{
+ int retval;
+ u8 code = OPCODE_RDSR;
+
+ /* Issue Controller Transfer Routine */
+ retval = ctrl_drv->spi_transfer(bank,&code, 1,SPI_READ,status, 1);
+
+ if (retval < 0)
+ return spi_error(retval);
+
+ return 0;
+}
+
+int
+spi_generic_write_status(int bank,struct spi_ctrl_driver *ctrl_drv, unsigned char status)
+{
+ int retval;
+ u8 code = OPCODE_WRSR;
+
+ /* Send write enable */
+ spi_generic_write_enable(bank,ctrl_drv);
+
+ /* Issue Controller Transfer Routine */
+ retval = ctrl_drv->spi_transfer(bank,&code, 1,SPI_WRITE,&status, 1);
+ if (retval < 0)
+ return spi_error(retval);
+
+ return 0;
+}
+
+
+int
+spi_generic_write_enable(int bank,struct spi_ctrl_driver *ctrl_drv)
+{
+ u8 code = OPCODE_WREN;
+ int retval;
+
+ /* Issue Controller Transfer Routine */
+ retval = ctrl_drv->spi_transfer(bank,&code, 1,SPI_NONE, NULL, 0);
+ if (retval < 0)
+ return spi_error(retval);
+ return 0;
+}
+
+int
+spi_generic_write_disable(int bank, struct spi_ctrl_driver *ctrl_drv)
+{
+ u8 code = OPCODE_WRDI;
+ int retval;
+
+ /* Issue Controller Transfer Routine */
+ retval = ctrl_drv->spi_transfer(bank,&code, 1,SPI_NONE, NULL, 0);
+ if (retval < 0)
+ return spi_error(retval);
+ return 0;
+}
+
+int spi_generic_select_die(int bank, u8 die_num, struct spi_ctrl_driver *ctrl_drv)
+{
+ int retval;
+ u8 command[2];
+
+ command[0] = CMD_WX25XX_CS;
+ command[1] = die_num;
+
+ /* Wait until finished previous command. */
+ if (wait_till_ready(bank,ctrl_drv))
+ {
+ return -1;
+ }
+
+ retval = ctrl_drv->spi_transfer(bank, command, 2, SPI_NONE, NULL, 0);
+
+ if (retval < 0)
+ {
+ printk ("Could not select die.\n");
+ return spi_error(retval);
+ }
+ return 0;
+}
+
+int enter_4byte_addr_mode(int bank, struct spi_ctrl_driver *ctrl_drv)
+{
+ //enable 32 MB Address mode
+ u8 code = CMD_MX25XX_EN4B;
+ int retval;
+
+ //printf("<ENTER> 4 BYTE\n");
+ /* Wait until finished previous command. */
+ if (wait_till_ready(bank,ctrl_drv))
+ {
+ return -1;
+ }
+
+
+ /* Issue Controller Transfer Routine */
+ if ((ractrends_spiflash_flash_id[bank] == 0x002019BA) || (ractrends_spiflash_flash_id[bank] == 0x002020BA) || (ractrends_spiflash_flash_id[bank] == 0x002021BA))
+ spi_generic_write_enable(bank,ctrl_drv);
+ retval = ctrl_drv->spi_transfer(bank, &code, 1, SPI_NONE, NULL, 0);
+ if ((ractrends_spiflash_flash_id[bank] == 0x002019BA) || (ractrends_spiflash_flash_id[bank] == 0x002021BA))
+ spi_generic_write_disable(bank,ctrl_drv);
+ if (retval < 0)
+ {
+ printk ("Could not Enter into 4-byte address mode\n");
+ return spi_error(retval);
+ }
+ return 0;
+}
+
+int exit_4byte_addr_mode(int bank, struct spi_ctrl_driver *ctrl_drv)
+{
+ //Disable 32 MB Address mode
+ u8 code = CMD_MX25XX_EX4B;
+ int retval;
+
+ //printf("<EXIT> 4 BYTE\n");
+ /* Wait until finished previous command. */
+ if (wait_till_ready(bank,ctrl_drv))
+ {
+ return -1;
+ }
+
+
+ /* Issue Controller Transfer Routine */
+ if ((ractrends_spiflash_flash_id[bank] == 0x002019BA) || (ractrends_spiflash_flash_id[bank] == 0x002020BA) || (ractrends_spiflash_flash_id[bank] == 0x002021BA))
+ spi_generic_write_enable(bank,ctrl_drv);
+ retval = ctrl_drv->spi_transfer(bank, &code, 1, SPI_NONE, NULL, 0);
+ if ((ractrends_spiflash_flash_id[bank] == 0x002019BA) || (ractrends_spiflash_flash_id[bank] == 0x002020BA) || (ractrends_spiflash_flash_id[bank] == 0x002021BA))
+ spi_generic_write_disable(bank,ctrl_drv);
+ if (retval < 0)
+ {
+ printk ("Could not Exit from 4-byte address mode\n");
+ return spi_error(retval);
+ }
+ return 0;
+}
+
+int spi_generic_extended_address(int bank, SPI_DIR dir, u8 addr, struct spi_ctrl_driver *ctrl_drv)
+{
+ int retval;
+
+ if (dir == SPI_READ)
+ {
+ u8 code = 0xC8;
+ u8 reg_data;
+
+ ctrl_drv->spi_transfer(bank, &code, 1, SPI_READ, ®_data, 1);
+ retval = (int) reg_data;
+ }
+ else if (dir == SPI_WRITE)
+ {
+ u8 command[2];
+
+ command[0] = 0xC5;
+ command[1] = addr;
+ spi_generic_write_enable(bank, ctrl_drv);
+ ctrl_drv->spi_transfer(bank, command, 2, SPI_NONE, NULL, 0);
+ spi_generic_write_disable(bank, ctrl_drv);
+ retval = command[1];
+ }
+ else // SPI_NONE
+ {
+ retval = 0;
+ }
+
+ return retval;
+}
+
+// the function just for WINBOND W25Q256 only, always revise the extended address to the defalut
+int w25q256_force_extended_address(int bank, struct spi_ctrl_driver *ctrl_drv)
+{
+ int retval;
+ u8 code;
+ u8 reg_data;
+ u8 command[5];
+
+ code = 0xC8; // "Read Extended Address Register"
+ retval = ctrl_drv->spi_transfer(bank, &code, 1, SPI_READ, ®_data, 1);
+ if (reg_data == 0x01)
+ {
+ spi_generic_write_enable(bank,ctrl_drv);
+ command[0] = 0xC5; // "Write Extended Address Register" with the force address 0x00
+ command[1] = command[2] = command[3] = command[4] = 0x00;
+ retval = ctrl_drv->spi_transfer(bank, command, 5, SPI_NONE, NULL, 0);
+ spi_generic_write_disable(bank,ctrl_drv);
+ }
+ return 0;
+}
+
+/* Define max times to check status register before we give up. */
+#define MAX_READY_WAIT_COUNT 4000000
+
+static int
+wait_till_ready(int bank,struct spi_ctrl_driver *ctrl_drv)
+{
+ unsigned long count;
+ unsigned char sr;
+
+ for (count = 0; count < MAX_READY_WAIT_COUNT; count++)
+ {
+ if (spi_generic_read_status(bank,ctrl_drv,&sr) < 0)
+ {
+ printk("Error reading SPI Status Register\n");
+ break;
+ }
+ else
+ {
+ if (!(sr & SR_WIP))
+ return 0;
+ }
+ }
+
+ printk("spi_generic: Waiting for Ready Failed\n");
+ return 1;
+}
+
+static int
+require_read_flag_status(int bank,struct spi_ctrl_driver *ctrl_drv)
+{
+ unsigned long count;
+ unsigned char sr;
+
+ for (count = 0; count < MAX_READY_WAIT_COUNT; count++)
+ {
+ if (spi_generic_read_flag_status(bank,ctrl_drv,&sr) < 0)
+ {
+ printk("Error reading SPI Status Register\n");
+ break;
+ }
+ else
+ {
+ if (sr & SR_SRWD)
+ return 0;
+ }
+ }
+
+ printk("spi_generic %s() : Waiting for Ready Failed\n", __func__);
+ return 1;
+}
+
+
+
+int
+spi_generic_erase(struct map_info *map, unsigned long sect_addr)
+{
+ struct spi_flash_private *priv=map->fldrv_priv;
+ int bank = map->map_priv_1;
+ struct spi_ctrl_driver *ctrl_drv = priv->ctrl_drv;
+ int retval;
+ unsigned char command[5];
+ int cmd_size;
+ u8 address32 = priv->address32;
+ //unsigned long flash_size = priv->size;
+ u8 had_switch_die = 0;
+ u8 pwr_up_mode = 0;
+
+ down(&priv->chip_drv->lock);
+
+
+ /* Wait until finished previous command. */
+ if (wait_till_ready(bank,ctrl_drv))
+ {
+ up(&priv->chip_drv->lock);
+ return -1;
+ }
+
+ if (address32 == ADDRESS_DIE_LO3_HI4_BYTE) {
+ if(sect_addr>=ADDR_32MB){
+ spi_generic_select_die( bank, 1,ctrl_drv);
+ had_switch_die = 1;
+ sect_addr-=ADDR_32MB;
+ }
+ }
+
+ if (ractrends_spiflash_flash_id[bank] == 0x00EF1940)
+ {
+ u8 reg_data;
+
+ command[0] = 0x15; /* Read Status Register S23 ~ S16 */
+ cmd_size = 1;
+ retval = ctrl_drv->spi_transfer(bank,command, cmd_size ,SPI_READ, ®_data, 1);
+ pwr_up_mode = (reg_data & 0x2)>>1; /* S17(ADP) field */
+ }
+
+ /* Logic for 4 byte address mode Enter */
+ if ( ((sect_addr >= ADDR_16MB) && ((address32 == ADDRESS_LO3_HI4_BYTE )||(address32 == ADDRESS_DIE_LO3_HI4_BYTE))) || pwr_up_mode)
+ {
+ retval = enter_4byte_addr_mode(bank, ctrl_drv);
+ if (retval < 0)
+ {
+ printk ("Unable to enter 4 byte address mode\n");
+ if(had_switch_die == 1)
+ {
+ spi_generic_select_die( bank, 0,ctrl_drv);
+ }
+ up(&priv->chip_drv->lock);
+ return spi_error(retval);
+ }
+ }
+
+ if (ractrends_spiflash_flash_id[bank] == 0x00EF1940) w25q256_force_extended_address(bank, ctrl_drv);
+ if ((ractrends_spiflash_flash_id[bank] == 0x002020BA) || (ractrends_spiflash_flash_id[bank] == 0x002021BA) || (ractrends_spiflash_flash_id[bank] == 0x00C21A20))
+ spi_generic_extended_address(bank, SPI_WRITE, (sect_addr & 0xFF000000) >> 24, ctrl_drv);
+
+ if ( (((sect_addr >= ADDR_16MB) && ((address32 == ADDRESS_LO3_HI4_BYTE)||(address32 == ADDRESS_DIE_LO3_HI4_BYTE))) || (address32 == ADDRESS_4BYTE)) || pwr_up_mode)
+ {
+ /* Set up command buffer. */
+ command[0] = OPCODE_SE;
+ if (ractrends_spiflash_flash_id[bank] == 0x00011902) command[0] = 0xDC; // ERASE command in 4byte mode [spansion only]
+ if (address32 == ADDRESS_DIE_LO3_HI4_BYTE) command[0] = 0xDC; // ERASE command in 4byte mode
+ command[1] = sect_addr >> 24;
+ command[2] = sect_addr >> 16;
+ command[3] = sect_addr >> 8;
+ command[4] = sect_addr;
+
+ cmd_size = 5;
+ }
+ else {
+ /* Set up command buffer. */
+ command[0] = OPCODE_SE;
+ command[1] = sect_addr >> 16;
+ command[2] = sect_addr >> 8;
+ command[3] = sect_addr;
+
+ cmd_size = 4;
+ }
+
+ /* Issue Controller Transfer Routine */
+ spi_generic_write_enable(bank,ctrl_drv); /* Send write enable */
+ retval = ctrl_drv->spi_transfer(bank,command, cmd_size ,SPI_NONE, NULL, 0);
+ spi_generic_write_disable(bank,ctrl_drv); /* Send write disable */
+
+ if (ractrends_spiflash_flash_id[bank] == 0x002020BA || ractrends_spiflash_flash_id[bank] == 0x002021BA)
+ {
+ /* requires the read flag status with at latest one byte. */
+ if (require_read_flag_status(bank,ctrl_drv))
+ {
+ up(&priv->chip_drv->lock);
+ return -1;
+ }
+ }
+
+ if (retval < 0)
+ {
+ //if 4 byte mode exit
+ if ( ((sect_addr >= ADDR_16MB) && ((address32 == ADDRESS_LO3_HI4_BYTE)||(address32 == ADDRESS_DIE_LO3_HI4_BYTE))) || pwr_up_mode)
+ {
+ retval = exit_4byte_addr_mode(bank, ctrl_drv);
+ if (retval < 0)
+ {
+ printk ("Unable to exit 4 byte address mode\n");
+ }
+ }
+
+ if (ractrends_spiflash_flash_id[bank] == 0x00EF1940) w25q256_force_extended_address(bank, ctrl_drv);
+ if ((ractrends_spiflash_flash_id[bank] == 0x002020BA) || (ractrends_spiflash_flash_id[bank] == 0x002021BA) || (ractrends_spiflash_flash_id[bank] == 0x00C21A20))
+ spi_generic_extended_address(bank, SPI_WRITE, 0x00, ctrl_drv);
+
+ if(had_switch_die == 1)
+ {
+ spi_generic_select_die( bank, 0,ctrl_drv);
+ }
+ up(&priv->chip_drv->lock);
+ return spi_error(retval);
+ }
+
+ if ( ((sect_addr >= ADDR_16MB) && ((address32 == ADDRESS_LO3_HI4_BYTE)||(address32 == ADDRESS_DIE_LO3_HI4_BYTE))) || pwr_up_mode)
+ {
+ retval = exit_4byte_addr_mode(bank, ctrl_drv);
+ if (retval < 0)
+ {
+ printk ("Unable to exit 4 byte address mode\n");
+ }
+ }
+
+ if (ractrends_spiflash_flash_id[bank] == 0x00EF1940) w25q256_force_extended_address(bank, ctrl_drv);
+ if ((ractrends_spiflash_flash_id[bank] == 0x002020BA) || (ractrends_spiflash_flash_id[bank] == 0x002021BA) || (ractrends_spiflash_flash_id[bank] == 0x00C21A20))
+ spi_generic_extended_address(bank, SPI_WRITE, 0x00, ctrl_drv);
+
+ if(had_switch_die == 1)
+ {
+ spi_generic_select_die( bank, 0,ctrl_drv);
+ }
+ up(&priv->chip_drv->lock);
+ return retval;
+}
+
+
+int
+spi_generic_read(struct map_info *map, loff_t addr, size_t bytes, unsigned char *buff)
+{
+ struct spi_flash_private *priv=map->fldrv_priv;
+ int bank = map->map_priv_1;
+ struct spi_ctrl_driver *ctrl_drv = priv->ctrl_drv;
+ int retval = 0;
+ size_t transfer;
+ unsigned char command[6];
+ int cmd_size;
+ int (*readfn)(int bank,unsigned char *,int , SPI_DIR, unsigned char *, unsigned long); //unsigned long);
+ int end_addr = (addr+bytes-1);
+ u8 address32 = priv->address32;
+ //unsigned long flash_size = priv->size;
+ u8 had_switch_die = 0;
+ u8 pwr_up_mode = 0;
+
+ /* Some time zero bytes length are sent */
+ if (bytes==0)
+ return 0;
+
+ if (ractrends_spiflash_flash_id[bank] == 0x00EF1940)
+ {
+ u8 reg_data;
+
+ command[0] = 0x15; /* Read Status Register S23 ~ S16 */
+ cmd_size = 1;
+ retval = ctrl_drv->spi_transfer(bank,command, cmd_size ,SPI_READ, ®_data, 1);
+ pwr_up_mode = (reg_data & 0x2)>>1; /* S17(ADP) field */
+ }
+
+ if (address32 == ADDRESS_DIE_LO3_HI4_BYTE)
+ {
+ if (addr < ADDR_32MB && end_addr >= ADDR_32MB)
+ {
+ int ErrorCode;
+ transfer = (ADDR_32MB - addr);
+ ErrorCode = spi_generic_read(map, addr, transfer, buff);
+ if (ErrorCode != 0) return ErrorCode;
+
+ //fix address
+ bytes-=transfer;
+ addr+=transfer;
+ buff+=transfer;
+
+ end_addr = (addr+bytes-1);
+ if (bytes==0) return 0;
+ }
+ }
+ down(&priv->chip_drv->lock);
+
+
+
+ /* Wait until finished previous command. */
+ if (wait_till_ready(bank,ctrl_drv))
+ {
+ up(&priv->chip_drv->lock);
+ return -1;
+ }
+
+ if (address32 == ADDRESS_DIE_LO3_HI4_BYTE){
+ if(addr >= ADDR_32MB){
+ spi_generic_select_die( bank, 1,ctrl_drv);
+ had_switch_die = 1;
+ addr-=ADDR_32MB;
+ end_addr = (addr+bytes-1);
+ }
+ }
+
+ if (ctrl_drv->spi_burst_read)
+ readfn = ctrl_drv->spi_burst_read;
+ else
+ readfn = ctrl_drv->spi_transfer;
+
+ transfer=bytes;
+
+
+ /* Logic for 4 byte address mode Enter */
+ if ( (( end_addr >= ADDR_16MB) && ((address32 == ADDRESS_LO3_HI4_BYTE )||(address32 == ADDRESS_DIE_LO3_HI4_BYTE))) || pwr_up_mode)
+ {
+ //printk ("Trying to enter 4 byte mode\n");
+ retval = enter_4byte_addr_mode(bank, ctrl_drv);
+ if (retval < 0)
+ {
+ printk ("Unable to enter 4 byte address mode\n");
+ if(had_switch_die == 1)
+ {
+ spi_generic_select_die( bank, 0,ctrl_drv);
+ }
+ up(&priv->chip_drv->lock);
+ return spi_error(retval);
+ }
+ }
+
+ if (ractrends_spiflash_flash_id[bank] == 0x00EF1940) w25q256_force_extended_address(bank, ctrl_drv);
+ if ((ractrends_spiflash_flash_id[bank] == 0x002020BA) || (ractrends_spiflash_flash_id[bank] == 0x002021BA) || (ractrends_spiflash_flash_id[bank] == 0x00C21A20))
+ spi_generic_extended_address(bank, SPI_WRITE, (addr & 0xFF000000) >> 24, ctrl_drv);
+
+ while (bytes)
+ {
+ if (ctrl_drv->spi_burst_read)
+ transfer=bytes;
+ else
+ {
+ transfer=ctrl_drv->max_read;
+ if (transfer > bytes)
+ transfer = bytes;
+ }
+
+ if (!ctrl_drv->fast_read)
+ {
+ if ( ((( end_addr >= ADDR_16MB) && ((address32 == ADDRESS_LO3_HI4_BYTE)||(address32 == ADDRESS_DIE_LO3_HI4_BYTE))) || (address32 == ADDRESS_4BYTE)) || pwr_up_mode )
+ {
+ /* Set up command buffer. */ /* Normal Read */
+ command[0] = OPCODE_READ;
+ if (ractrends_spiflash_flash_id[bank] == 0x00011902) command[0] = 0x13; // READ command in 4byte mode [spansion only]
+ if (address32 == ADDRESS_DIE_LO3_HI4_BYTE) command[0] = 0x13; // READ command in 4byte mode
+ command[1] = addr >> 24;
+ command[2] = addr >> 16;
+ command[3] = addr >> 8;
+ command[4] = addr;
+
+ cmd_size = 5;
+ }
+ else {
+
+ /* Set up command buffer. */ /* Normal Read */
+ command[0] = OPCODE_READ;
+ command[1] = addr >> 16;
+ command[2] = addr >> 8;
+ command[3] = addr;
+
+ cmd_size = 4;
+ }
+ /* Issue Controller Transfer Routine */
+ retval = (*readfn)(bank,command, cmd_size ,SPI_READ, buff, (unsigned long)transfer);
+ }
+ else if (ctrl_drv->fast_read == 1) // Need to check Fast Read in 4 byte address mode
+ {
+ if ( ((( end_addr >= ADDR_16MB) && ((address32 == ADDRESS_LO3_HI4_BYTE)||(address32 == ADDRESS_DIE_LO3_HI4_BYTE))) || (address32 == ADDRESS_4BYTE)) || pwr_up_mode )
+ {
+ /* Set up command buffer. */ /* Fast Read */
+ command[0] = OPCODE_FAST_READ;
+ if (ractrends_spiflash_flash_id[bank] == 0x00011902) command[0] = 0x0C; // FAST_READ command in 4byte mode [spansion only]
+ if (address32 == ADDRESS_DIE_LO3_HI4_BYTE) command[0] = 0x0C; // FAST_READ command in 4byte mode
+ command[1] = addr >> 24;
+ command[2] = addr >> 16;
+ command[3] = addr >> 8;
+ command[4] = addr;
+ command[5] = 0; /* dummy data */
+
+ cmd_size = 6;
+ }
+ else
+ {
+ /* Set up command buffer. */ /* Fast Read */
+ command[0] = OPCODE_FAST_READ;
+ command[1] = addr >> 16;
+ command[2] = addr >> 8;
+ command[3] = addr;
+ command[4] = 0; /* dummy data */
+
+ cmd_size = 5;
+ }
+ /* Issue Controller Transfer Routine */
+ retval = (*readfn)(bank,command, cmd_size ,SPI_READ, buff, (unsigned long)transfer);
+ }
+ else if (ctrl_drv->fast_read == 2) // Need to check Dual Read in 4 byte address mode
+ {
+ if ( ((( end_addr >= ADDR_16MB) && ((address32 == ADDRESS_LO3_HI4_BYTE)||(address32 == ADDRESS_DIE_LO3_HI4_BYTE))) || (address32 == ADDRESS_4BYTE)) || pwr_up_mode )
+ {
+ /* Set up command buffer. */ /* Dual Read */
+ command[0] = OPCODE_DREAD;
+ command[1] = addr >> 24;
+ command[2] = addr >> 16;
+ command[3] = addr >> 8;
+ command[4] = addr;
+ command[5] = 0; /* dummy data */
+
+ cmd_size = 6;
+ }
+ else
+ {
+ /* Set up command buffer. */ /* Dual Read */
+ command[0] = OPCODE_DREAD;
+ command[1] = addr >> 16;
+ command[2] = addr >> 8;
+ command[3] = addr;
+ command[4] = 0; /* dummy data */
+
+ cmd_size = 5;
+ }
+ /* Issue Controller Transfer Routine */
+ retval = (*readfn)(bank,command, cmd_size ,SPI_READ, buff, (unsigned long)transfer);
+ }
+ else if (ctrl_drv->fast_read == 3) // Need to check 2xI/O Read in 4 byte address mode
+ {
+ if ( ((( end_addr >= ADDR_16MB) && ((address32 == ADDRESS_LO3_HI4_BYTE)||(address32 == ADDRESS_DIE_LO3_HI4_BYTE))) || (address32 == ADDRESS_4BYTE)) || pwr_up_mode )
+ {
+ /* Set up command buffer. */ /* 2xI/O Read */
+ command[0] = OPCODE_2READ;
+ command[1] = addr >> 24;
+ command[2] = addr >> 16;
+ command[3] = addr >> 8;
+ command[4] = addr;
+ command[5] = 0; /* dummy data */
+
+ cmd_size = 6;
+ }
+ else
+ {
+ /* Set up command buffer. */ /* 2xI/O Read */
+ command[0] = OPCODE_2READ;
+ command[1] = addr >> 16;
+ command[2] = addr >> 8;
+ command[3] = addr;
+ command[4] = 0; /* dummy data */
+
+ cmd_size = 5;
+ }
+ /* Issue Controller Transfer Routine */
+ retval = (*readfn)(bank,command, cmd_size ,SPI_READ, buff, (unsigned long)transfer);
+ }
+
+ if (retval < 0)
+ {
+ //if 4 byte mode, exit
+ if ( (( end_addr >= ADDR_16MB) && ((address32 == ADDRESS_LO3_HI4_BYTE)||(address32 == ADDRESS_DIE_LO3_HI4_BYTE))) || pwr_up_mode)
+ {
+ retval = exit_4byte_addr_mode(bank, ctrl_drv);
+ if (retval < 0)
+ {
+ printk ("Unable to exit 4 byte address mode\n");
+ }
+ }
+
+ if (ractrends_spiflash_flash_id[bank] == 0x00EF1940) w25q256_force_extended_address(bank, ctrl_drv);
+ if ((ractrends_spiflash_flash_id[bank] == 0x002020BA) || (ractrends_spiflash_flash_id[bank] == 0x002021BA) || (ractrends_spiflash_flash_id[bank] == 0x00C21A20))
+ spi_generic_extended_address(bank, SPI_WRITE, 0x00, ctrl_drv);
+
+ if(had_switch_die == 1)
+ {
+ spi_generic_select_die( bank, 0,ctrl_drv);
+ }
+ up(&priv->chip_drv->lock);
+ return spi_error(retval);
+ }
+
+ bytes-=transfer;
+ addr+=transfer;
+ buff+=transfer;
+ }
+
+ //if 4 byte mode exit
+ if ( (( end_addr >= ADDR_16MB) && ((address32 == ADDRESS_LO3_HI4_BYTE)||(address32 == ADDRESS_DIE_LO3_HI4_BYTE))) || pwr_up_mode)
+ {
+ //printk ("Trying to exit 4 byte mode\n");
+ retval = exit_4byte_addr_mode(bank, ctrl_drv);
+ if (retval < 0)
+ {
+ printk ("Unable to exit 4 byte address mode\n");
+ }
+ }
+
+ if (ractrends_spiflash_flash_id[bank] == 0x00EF1940) w25q256_force_extended_address(bank, ctrl_drv);
+ if ((ractrends_spiflash_flash_id[bank] == 0x002020BA) || (ractrends_spiflash_flash_id[bank] == 0x002021BA) || (ractrends_spiflash_flash_id[bank] == 0x00C21A20))
+ spi_generic_extended_address(bank, SPI_WRITE, 0x00, ctrl_drv);
+
+ if(had_switch_die == 1)
+ {
+ spi_generic_select_die( bank, 0,ctrl_drv);
+ }
+ up(&priv->chip_drv->lock);
+ return 0;
+}
+
+
+int
+spi_generic_write(struct map_info *map, loff_t addr, size_t bytes, const unsigned char *buff)
+{
+ struct spi_flash_private *priv=map->fldrv_priv;
+ int bank = map->map_priv_1;
+ struct spi_ctrl_driver *ctrl_drv = priv->ctrl_drv;
+
+ int retval;
+ unsigned char command[5];
+ size_t transfer;
+ int cmd_size = 0;
+ int end_addr = (addr+bytes-1);
+ u8 address32 = priv->address32;
+ //unsigned long flash_size = priv->size;
+ u8 had_switch_die = 0;
+ u8 pwr_up_mode = 0;
+
+ /* Some time zero bytes length are sent */
+ if (bytes==0)
+ return 0;
+
+ if (ractrends_spiflash_flash_id[bank] == 0x00EF1940)
+ {
+ u8 reg_data;
+
+ command[0] = 0x15; /* Read Status Register S23 ~ S16 */
+ cmd_size = 1;
+ retval = ctrl_drv->spi_transfer(bank,command, cmd_size ,SPI_READ, ®_data, 1);
+ pwr_up_mode = (reg_data & 0x2)>>1; /* S17(ADP) field */
+ }
+
+ if (address32 == ADDRESS_DIE_LO3_HI4_BYTE)
+ {
+ if (addr < ADDR_32MB && end_addr >= ADDR_32MB)
+ {
+ int ErrorCode;
+ transfer = (ADDR_32MB - addr);
+ ErrorCode = spi_generic_write(map, addr, transfer, buff);
+ if (ErrorCode != 0) return ErrorCode;
+
+ //fix address
+ bytes-=transfer;
+ addr+=transfer;
+ buff+=transfer;
+
+ end_addr = (addr+bytes-1);
+ if (bytes==0) return 0;
+ }
+ }
+
+ down(&priv->chip_drv->lock);
+
+ if (address32 == ADDRESS_DIE_LO3_HI4_BYTE){
+ if(addr >= ADDR_32MB){
+ spi_generic_select_die( bank, 1,ctrl_drv);
+ had_switch_die = 1;
+ addr-=ADDR_32MB;
+ end_addr = (addr+bytes-1);
+ }
+ }
+
+ /* Logic for 4 byte address mode Enter */
+ if ( (( end_addr >= ADDR_16MB) && ((address32 == ADDRESS_LO3_HI4_BYTE)||(address32 == ADDRESS_DIE_LO3_HI4_BYTE))) || pwr_up_mode)
+ {
+ retval = enter_4byte_addr_mode(bank, ctrl_drv);
+ if (retval < 0)
+ {
+ printk ("Unable to enter 4 byte address mode\n");
+ if(had_switch_die == 1)
+ {
+ spi_generic_select_die( bank, 0,ctrl_drv);
+ }
+ up(&priv->chip_drv->lock);
+ return spi_error(retval);
+ }
+ }
+
+ if (ractrends_spiflash_flash_id[bank] == 0x00EF1940) w25q256_force_extended_address(bank, ctrl_drv);
+ if ((ractrends_spiflash_flash_id[bank] == 0x002020BA) || (ractrends_spiflash_flash_id[bank] == 0x002021BA) || (ractrends_spiflash_flash_id[bank] == 0x00C21A20))
+ spi_generic_extended_address(bank, SPI_WRITE, (addr & 0xFF000000) >> 24, ctrl_drv);
+
+ while (bytes)
+ {
+ /* Wait until finished previous command. */
+ if (wait_till_ready(bank,ctrl_drv))
+ {
+ if(had_switch_die == 1)
+ {
+ spi_generic_select_die( bank, 0,ctrl_drv);
+ }
+ up(&priv->chip_drv->lock);
+ return -1;
+ }
+
+ transfer = PROGRAM_PAGE_SIZE;
+ if (bytes < transfer)
+ transfer = bytes;
+
+ if (!ctrl_drv->fast_write)
+ {
+ if ( (((end_addr >= ADDR_16MB) && (address32 == ADDRESS_LO3_HI4_BYTE)) || (address32 == ADDRESS_4BYTE)) || pwr_up_mode)
+ {
+ /* Set up command buffer. */
+ command[0] = OPCODE_PP;
+ if (ractrends_spiflash_flash_id[bank] == 0x00011902) command[0] = 0x12; // PROGRAM command in 4byte mode [spansion only]
+ if (address32 == ADDRESS_DIE_LO3_HI4_BYTE) command[0] = 0x12; // PROGRAM command in 4byte mode
+ command[1] = addr >> 24;
+ command[2] = addr >> 16;
+ command[3] = addr >> 8;
+ command[4] = addr;
+ cmd_size = 5;
+ }
+ else {
+ /* Set up command buffer. */
+ command[0] = OPCODE_PP;
+ command[1] = addr >> 16;
+ command[2] = addr >> 8;
+ command[3] = addr;
+ cmd_size = 4;
+ }
+ }
+
+ /* Issue Controller Transfer Routine */
+ spi_generic_write_enable(bank,ctrl_drv); /* Send write enable */
+ retval = ctrl_drv->spi_transfer(bank,command,cmd_size ,SPI_WRITE,
+ (unsigned char *)buff, transfer);
+ spi_generic_write_disable(bank,ctrl_drv); /* Send write disable */
+
+ if (ractrends_spiflash_flash_id[bank] == 0x002020BA || ractrends_spiflash_flash_id[bank] == 0x002021BA)
+ {
+ /* requires the read flag status with at latest one byte. */
+ if (require_read_flag_status(bank,ctrl_drv))
+ {
+ up(&priv->chip_drv->lock);
+ return -1;
+ }
+ }
+
+ if (retval < 0)
+ {
+ //if 4 byte mode exit
+ if ( (( end_addr >= ADDR_16MB) && ((address32 == ADDRESS_LO3_HI4_BYTE)||(address32 == ADDRESS_DIE_LO3_HI4_BYTE))) || pwr_up_mode)
+ {
+ retval = exit_4byte_addr_mode(bank, ctrl_drv);
+ if (retval < 0)
+ {
+ printk ("Unable to exit 4 byte address mode\n");
+ }
+ }
+
+ if (ractrends_spiflash_flash_id[bank] == 0x00EF1940) w25q256_force_extended_address(bank, ctrl_drv);
+ if ((ractrends_spiflash_flash_id[bank] == 0x002020BA) || (ractrends_spiflash_flash_id[bank] == 0x002021BA) || (ractrends_spiflash_flash_id[bank] == 0x00C21A20))
+ spi_generic_extended_address(bank, SPI_WRITE, 0x00, ctrl_drv);
+
+ if(had_switch_die == 1)
+ {
+ spi_generic_select_die( bank, 0,ctrl_drv);
+ }
+ up(&priv->chip_drv->lock);
+ return spi_error(retval);
+ }
+ addr+=(transfer-retval);
+ buff+=(transfer-retval);
+ bytes-=(transfer-retval);
+ }
+
+ //if 4 byte mode exit
+ if ( (( end_addr >= ADDR_16MB) && ((address32 == ADDRESS_LO3_HI4_BYTE)||(address32 == ADDRESS_DIE_LO3_HI4_BYTE))) || pwr_up_mode)
+ {
+ retval = exit_4byte_addr_mode(bank, ctrl_drv);
+ if (retval < 0)
+ {
+ printk ("Unable to exit 4 byte address mode\n");
+ }
+ }
+
+ if (ractrends_spiflash_flash_id[bank] == 0x00EF1940) w25q256_force_extended_address(bank, ctrl_drv);
+ if ((ractrends_spiflash_flash_id[bank] == 0x002020BA) || (ractrends_spiflash_flash_id[bank] == 0x002021BA) || (ractrends_spiflash_flash_id[bank] == 0x00C21A20))
+ spi_generic_extended_address(bank, SPI_WRITE, 0x00, ctrl_drv);
+
+ if(had_switch_die == 1)
+ {
+ spi_generic_select_die( bank, 0,ctrl_drv);
+ }
+ up(&priv->chip_drv->lock);
+ return 0;
+}
+
+/***********************************************************************************/
+extern int spi_verbose;
+int
+spi_generic_probe(int bank,struct spi_ctrl_driver *ctrl_drv, struct spi_flash_info *chip_info,
+ char *spi_name,struct spi_flash_info *spi_list, int spi_list_len)
+{
+ int retval;
+ u32 val;
+ int i;
+ u16 opread;
+ u16 opwrite;
+ u8 code = OPCODE_RDID;
+ //int address_mode = 0;
+
+ if (spi_verbose == 2)
+ printk("SPI: probing for %s devices ...\n",spi_name);
+
+ /* Send write enable */
+ retval =spi_generic_write_enable(bank,ctrl_drv);
+ if (retval < 0)
+ return -1;
+
+ /* Issue Controller Transfer Routine */
+ val = 0;
+ retval = ctrl_drv->spi_transfer(bank,&code, 1,SPI_READ,(unsigned char *)&val, 3);
+ val &= 0x00FFFFFF;
+
+ if (retval < 0)
+ {
+ spi_error(retval);
+ return -1;
+ }
+
+ /* Send write disable */
+ retval = spi_generic_write_disable(bank,ctrl_drv);
+ if (retval < 0)
+ return -1;
+
+ /* Match the ID against the table entries */
+ for (i = 0; i < spi_list_len; i++)
+ {
+ if ((spi_list[i].mfr_id == ((val)& 0xFF)) && (spi_list[i].dev_id == ((val >> 8)& 0xFFFF)))
+ {
+ /* Check Operation Mode */
+ //for Read Operation
+ opread = (spi_list[i].operationmode & 0xFFFF);
+ opread &= ctrl_drv->operation_mode_mask;
+ if (opread > 0x7)
+ {
+ ctrl_drv->fast_read = 3;
+ }
+ else if ((0x3 < opread) && (opread <= 0x7))
+ {
+ ctrl_drv->fast_read = 2;
+ }
+ else if ((0x1 < opread) && (opread <= 0x3))
+ {
+ ctrl_drv->fast_read = 1;
+ }
+ else if (opread <= 0x1)
+ {
+ ctrl_drv->fast_read = 0;
+ }
+
+ //for Write Operation
+ opwrite = (spi_list[i].operationmode >> 16);
+ opwrite &= (ctrl_drv->operation_mode_mask >> 16);
+ if (opwrite <= 0x1)
+ {
+ ctrl_drv->fast_write = 0;
+ }
+
+ break;
+ }
+ }
+
+ if (i == spi_list_len)
+ {
+// if (spi_verbose == 2)
+// printk("%s : Unrecognized ID (0x%x) got \n",spi_name,val);
+ return -1;
+ }
+ memcpy(chip_info,&spi_list[i],sizeof(struct spi_flash_info));
+
+ if (spi_verbose > 0)
+ printk(KERN_INFO"Found SPI Chip %s \n",spi_list[i].name);
+
+ return 0;
+
+}
+
+EXPORT_SYMBOL(spi_generic_probe);
+EXPORT_SYMBOL(spi_generic_erase);
+EXPORT_SYMBOL(spi_generic_read);
+EXPORT_SYMBOL(spi_generic_write);
+EXPORT_SYMBOL(spi_generic_write_disable);
+EXPORT_SYMBOL(spi_generic_write_enable);
+EXPORT_SYMBOL(spi_generic_read_status);
+EXPORT_SYMBOL(spi_generic_write_status);
+
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("American Megatrends Inc");
+MODULE_DESCRIPTION("MTD SPI driver for Generic SPI flash chips");
+
+#endif
diff --git a/drivers/mtd/spichips/intels33.c b/drivers/mtd/spichips/intels33.c
new file mode 100644
index 0000000..6900319
--- /dev/null
+++ b/drivers/mtd/spichips/intels33.c
@@ -0,0 +1,96 @@
+/*
+ * Copyright (C) 2007 American Megatrends Inc
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+
+#ifdef __UBOOT__
+#include <common.h>
+#endif
+#include "spiflash.h"
+#ifdef CFG_FLASH_SPI_DRIVER
+
+/* Name, ID1, ID2 , Size, Clock, Erase regions, address mode,{ Offset, Erase Size, Erase Block Count } */
+/* address mode: 0x00 -3 byte address
+ 0x01 - 4 byte address
+ 0x02 - Low byte: 3 byte address, High byte: 4 byte address*/
+static struct spi_flash_info s33_data [] =
+{
+ /* Intel S33 64 K Sectors */
+ { "Intel S33 16Mb" , 0x89, 0x1189, 0x00010001, 0x200000 , 68 * 1000000, 1, 0x00, {{ 0, 64 * 1024, 32 },} },
+ { "Intel S33 32Mb" , 0x89, 0x1289, 0x00010001, 0x400000 , 68 * 1000000, 1, 0x00, {{ 0, 64 * 1024, 64 },} },
+ { "Intel S33 64Mb" , 0x89, 0x1389, 0x00010001, 0x800000 , 68 * 1000000, 1, 0x00, {{ 0, 64 * 1024, 128 },} },
+};
+
+
+static
+int
+s33_probe(int bank,struct spi_ctrl_driver *ctrl_drv, struct spi_flash_info *chip_info)
+{
+ int retval;
+ retval = spi_generic_probe(bank,ctrl_drv,chip_info,"intel s33",
+ s33_data,ARRAY_SIZE(s33_data));
+
+ if (retval == -1)
+ return retval;
+
+ /* UnProctect all sectors */
+ /* SRWD=0 (Bit 7) BP0,BP1,BP2 = 0 (Bit 2,3,4) */
+ if (spi_generic_write_status(bank,ctrl_drv,0x0) < 0)
+ printk("intel s33: Unable to Unprotect all sectors\n");
+ return retval;
+}
+
+struct spi_chip_driver s33_driver =
+{
+ .name = "intel s33",
+ .module = THIS_MODULE,
+ .probe = s33_probe,
+ .erase_sector = spi_generic_erase,
+ .read_bytes = spi_generic_read,
+ .write_bytes = spi_generic_write,
+};
+
+int
+s33_init(void)
+{
+ sema_init(&s33_driver.lock, 1);
+#ifdef __UBOOT__ /* MIPS */
+ s33_driver.probe = s33_probe;
+ s33_driver.erase_sector = spi_generic_erase;
+ s33_driver.read_bytes = spi_generic_read;
+ s33_driver.write_bytes = spi_generic_write;
+#endif
+ register_spi_chip_driver(&s33_driver);
+ return 0;
+}
+
+void
+s33_exit(void)
+{
+ sema_init(&s33_driver.lock, 1);
+ unregister_spi_chip_driver(&s33_driver);
+ return;
+}
+
+module_init(s33_init);
+module_exit(s33_exit);
+
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("American Megatrends Inc");
+MODULE_DESCRIPTION("MTD SPI driver for Intel S33 flash chips");
+
+#endif
diff --git a/drivers/mtd/spichips/m25pxx.c b/drivers/mtd/spichips/m25pxx.c
new file mode 100644
index 0000000..448fe06
--- /dev/null
+++ b/drivers/mtd/spichips/m25pxx.c
@@ -0,0 +1,121 @@
+/*
+ * Copyright (C) 2007 American Megatrends Inc
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+
+#ifdef __UBOOT__
+#include <common.h>
+#endif
+#include "spiflash.h"
+#ifdef CFG_FLASH_SPI_DRIVER
+
+/* Name, ID1, ID2 , Size, Clock, Erase regions, address mode,{ Offset, Erase Size, Erase Block Count } */
+/* address mode: 0x00 -3 byte address
+ 0x01 - 4 byte address
+ 0x02 - Low byte: 3 byte address, High byte: 4 byte address*/
+static struct spi_flash_info m25pxx_data [] =
+{
+ /* ST Micro 32K Sectors */
+ { "ST Micro m25p05A" , 0x20, 0x1020, 0x00010001, 0x010000 , 50 * 1000000, 1, 0x00, {{ 0, 32 * 1024, 2 },} },
+ { "ST Micro m25p10A" , 0x20, 0x1120, 0x00010001, 0x020000 , 50 * 1000000, 1, 0x00, {{ 0, 32 * 1024, 4 },} },
+
+ /* ST Micro 64 K Sectors */
+ { "ST Micro m25p20" , 0x20, 0x1220, 0x00010001, 0x040000 , 75 * 1000000, 1, 0x00, {{ 0, 64 * 1024, 4 },} },
+ { "ST Micro m25p40" , 0x20, 0x1320, 0x00010001, 0x080000 , 75 * 1000000, 1, 0x00, {{ 0, 64 * 1024, 8 },} },
+ { "ST Micro m25p80" , 0x20, 0x1420, 0x00010001, 0x100000 , 75 * 1000000, 1, 0x00, {{ 0, 64 * 1024, 16 },} },
+ { "ST Micro m25p16" , 0x20, 0x1520, 0x00010001, 0x200000 , 75 * 1000000, 1, 0x00, {{ 0, 64 * 1024, 32 },} },
+ { "ST Micro m25p32" , 0x20, 0x1620, 0x00010001, 0x400000 , 75 * 1000000, 1, 0x00, {{ 0, 64 * 1024, 64 },} },
+ { "ST Micro m25p64" , 0x20, 0x1720, 0x00010001, 0x800000 , 75 * 1000000, 1, 0x00, {{ 0, 64 * 1024, 128 },} },
+ { "ST Micro m25px64" , 0x20, 0x1771, 0x00010001, 0x800000 , 75 * 1000000, 1, 0x00, {{ 0, 64 * 1024, 128 },} },
+
+ /* ST Micro 256K Sectors */
+ { "ST Micro m25p128" , 0x20, 0x1820, 0x00010001, 0x1000000, 50 * 1000000, 1, 0x00, {{ 0, 256 * 1024, 64 },} },
+
+ /* ST Micro 64 K Sectors, 25MHz speed */
+ { "ST Micro m45p20" , 0x20, 0x1240, 0x00010001, 0x040000 , 25 * 1000000, 1, 0x00, {{ 0, 64 * 1024, 4 },} },
+ { "ST Micro m45p40" , 0x20, 0x1340, 0x00010001, 0x080000 , 25 * 1000000, 1, 0x00, {{ 0, 64 * 1024, 8 },} },
+ { "ST Micro m45p80" , 0x20, 0x1440, 0x00010001, 0x100000 , 25 * 1000000, 1, 0x00, {{ 0, 64 * 1024, 16 },} },
+ { "ST Micro m45p16" , 0x20, 0x1540, 0x00010001, 0x200000 , 25 * 1000000, 1, 0x00, {{ 0, 64 * 1024, 32 },} },
+ { "ST Micro m45p32" , 0x20, 0x1640, 0x00010001, 0x400000 , 25 * 1000000, 1, 0x00, {{ 0, 64 * 1024, 64 },} },
+ { "ST Micro m45p64" , 0x20, 0x1740, 0x00010001, 0x800000 , 25 * 1000000, 1, 0x00, {{ 0, 64 * 1024, 128 },} },
+
+};
+
+
+static
+int
+m25pxx_probe(int bank,struct spi_ctrl_driver *ctrl_drv, struct spi_flash_info *chip_info)
+{
+ int retval;
+ retval = spi_generic_probe(bank,ctrl_drv,chip_info,"m25pxx",
+ m25pxx_data,ARRAY_SIZE(m25pxx_data));
+
+ if (retval == -1)
+ return retval;
+
+ /* UnProctect all sectors */
+ /* SRWD=0 (Bit 7) BP0,BP1,BP2 = 0 (Bit 2,3,4) */
+ if (spi_generic_write_status(bank,ctrl_drv,0x0) < 0)
+ printk("m25pxx: Unable to Unprotect all sectors\n");
+
+ return retval;
+}
+
+struct spi_chip_driver m25pxx_driver =
+{
+ .name = "m25pxx",
+ .module = THIS_MODULE,
+ .probe = m25pxx_probe,
+ .erase_sector = spi_generic_erase,
+ .read_bytes = spi_generic_read,
+ .write_bytes = spi_generic_write,
+};
+
+
+
+int
+m25pxx_init(void)
+{
+ sema_init(&m25pxx_driver.lock, 1);
+#ifdef __UBOOT__ /* MIPS */
+ m25pxx_driver.probe = m25pxx_probe;
+ m25pxx_driver.erase_sector = spi_generic_erase;
+ m25pxx_driver.read_bytes = spi_generic_read;
+ m25pxx_driver.write_bytes = spi_generic_write;
+#endif
+ register_spi_chip_driver(&m25pxx_driver);
+ return 0;
+}
+
+
+void
+m25pxx_exit(void)
+{
+ sema_init(&m25pxx_driver.lock, 1);
+ unregister_spi_chip_driver(&m25pxx_driver);
+ return;
+}
+
+
+module_init(m25pxx_init);
+module_exit(m25pxx_exit);
+
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("American Megatrends Inc");
+MODULE_DESCRIPTION("MTD SPI driver for ST M25Pxx flash chips");
+
+#endif
diff --git a/drivers/mtd/spichips/macronix.c b/drivers/mtd/spichips/macronix.c
new file mode 100644
index 0000000..176d101
--- /dev/null
+++ b/drivers/mtd/spichips/macronix.c
@@ -0,0 +1,208 @@
+/*
+ * Copyright (C) 2007 American Megatrends Inc
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+
+#ifdef __UBOOT__
+#include <common.h>
+#endif
+#include "spiflash.h"
+#ifdef CFG_FLASH_SPI_DRIVER
+
+#define CMD_MX25XX_RDSCUR 0x2B /* Read security register */
+#define CMD_MX25XX_RDCR 0x15 /* Read configuration register */
+
+/* Security register */
+#define SCUR_BIT2 0x04
+
+/* Configuration register */
+#define CR_BIT5 0x20
+
+#define ADDRESS_3BYTE 0x00
+#define ADDRESS_4BYTE 0x01
+#define ADDRESS_LO3_HI4_BYTE 0x02
+#define MX25L25x35E_MFR_ID 0xC2
+#define MX25L25x35E_DEV_ID 0x1920
+
+
+/* Name, ID1, ID2 , Size, Clock, Erase regions, address mode,{ Offset, Erase Size, Erase Block Count } */
+/* address mode: 0x00 -3 byte address
+ 0x01 - 4 byte address
+ 0x02 - Low byte: 3 byte address, High byte: 4 byte address*/
+static struct spi_flash_info macronix_data [] =
+{
+ /* Macronix 64 K Sectors */
+ { "Macronix MX25L1605D" , 0xC2, 0x1520, 0x0001000B, 0x200000 , 66 * 1000000, 1, 0x00, {{ 0, 64 * 1024, 32 },} },
+ { "Macronix MX25L3205D" , 0xC2, 0x1620, 0x0001000B, 0x400000 , 66 * 1000000, 1, 0x00, {{ 0, 64 * 1024, 64 },} },
+ { "Macronix MX25L6405D" , 0xC2, 0x1720, 0x0001000B, 0x800000 , 66 * 1000000, 1, 0x00, {{ 0, 64 * 1024, 128 },} },
+ { "Macronix MX25L12805D", 0xC2, 0x1820, 0x00010001, 0x1000000, 50 * 1000000, 1, 0x00, {{ 0, 64 * 1024, 256 },} },
+ { "Macronix MX25L25635E", 0xC2, 0x1920, 0x0001000F, 0x2000000, 50 * 1000000, 1, 0x02, {{ 0, 64 * 1024, 512 },} },
+ { "Macronix MX25L25735E", 0xC2, 0x1920, 0x0001000F, 0x2000000, 50 * 1000000, 1, 0x01, {{ 0, 64 * 1024, 512 },} },
+ { "Macronix MX66L51235F", 0xC2, 0x1A20, 0x0001000F, 0x4000000, 50 * 1000000, 1, 0x02, {{ 0, 64 * 1024, 1024 },} },
+ { "EON EN25QH256", 0x1C, 0x1970, 0x0001000F, 0x2000000, 50 * 1000000, 1, 0x02, {{ 0, 64 * 1024, 512 },} },
+
+};
+
+/* to dinstinguish between MX25L25635/MX25L25735 E and F type */
+static int read_security_register(int bank, struct spi_ctrl_driver *ctrl_drv)
+{
+ u8 code = CMD_MX25XX_RDSCUR;
+ int retval;
+ unsigned char scur_reg;
+
+ /* Issue Controller Transfer Routine*/
+ retval = ctrl_drv->spi_transfer(bank,&code, 1,SPI_READ,&scur_reg, 1);
+ if (retval < 0)
+ {
+ printk ("Could not read security register\n");
+ return -1;
+
+ }
+
+ /* 0x00 - 3 byte mode
+ 0x04 - 4 byte mode */
+ scur_reg &= SCUR_BIT2;
+
+ if(scur_reg == 0x04)
+ return ADDRESS_4BYTE; // MX25L25735E
+ else
+ return ADDRESS_LO3_HI4_BYTE; // MX25L25635E, MX25L25635F, MX25L25735F
+
+ return 0;
+}
+
+/* to dinstinguish MX25L25635/MX25L25735 F type */
+static int read_configuration_register(int bank, struct spi_ctrl_driver *ctrl_drv)
+{
+ u8 code = CMD_MX25XX_RDCR;
+ int retval;
+ unsigned char conf_reg;
+
+ /* Issue Controller Transfer Routine */
+ retval = ctrl_drv->spi_transfer(bank,&code,1,SPI_READ,&conf_reg,1);
+ if (retval < 0)
+ {
+ printk ("Could not read configuration register\n");
+ return -1;
+ }
+
+ if (conf_reg == 0xFF) conf_reg = 0x00; // invalid value (maybe unsupported the RDCR command)
+
+ /* 0x00 - 3 byte mode
+ 0x20 - 4 byte mode */
+ conf_reg &= CR_BIT5;
+
+ if(conf_reg == CR_BIT5)
+ return ADDRESS_4BYTE; // MX25L25735F
+ else
+ return ADDRESS_LO3_HI4_BYTE; // MX25L25635E or MX25L25635F
+
+ return 0;
+}
+
+static
+int
+macronix_probe(int bank,struct spi_ctrl_driver *ctrl_drv, struct spi_flash_info *chip_info)
+{
+ int retval;
+ int address_mode = 0;
+ int i=0;
+
+ retval = spi_generic_probe(bank,ctrl_drv,chip_info,"macronix",
+ macronix_data,ARRAY_SIZE(macronix_data));
+
+ if (retval == -1)
+ return retval;
+
+ /* MX25L25635E, MX25L25735E, MX25L25635F, MX25L25735F - the same ID code */
+ if((chip_info->mfr_id == MX25L25x35E_MFR_ID) && (chip_info->dev_id == MX25L25x35E_DEV_ID))
+ {
+ address_mode = read_security_register(bank, ctrl_drv);
+ if (address_mode == ADDRESS_LO3_HI4_BYTE) address_mode = read_configuration_register(bank, ctrl_drv);
+
+ if (address_mode == -1)
+ return address_mode;
+
+ if(chip_info->address32 != address_mode)
+ {
+ memset(chip_info,0,sizeof(struct spi_flash_info));
+ for (i = 0; i < (ARRAY_SIZE(macronix_data)); i++)
+ {
+ if((macronix_data[i].mfr_id == MX25L25x35E_MFR_ID) && (macronix_data[i].dev_id == MX25L25x35E_DEV_ID))
+ {
+ if(macronix_data[i].address32 == address_mode)
+ {
+
+ break;
+ }
+ }
+
+ }
+ memcpy(chip_info,¯onix_data[i],sizeof(struct spi_flash_info));
+
+ }
+
+ }
+
+ /* UnProctect all sectors */
+ /* SRWD=0 (Bit 7) BP0,BP1,BP2 = 0 (Bit 2,3,4) */
+ if (spi_generic_write_status(bank,ctrl_drv,0x0) < 0)
+ printk("macronix: Unable to Unprotect all sectors\n");
+
+ return retval;
+}
+
+struct spi_chip_driver macronix_driver =
+{
+ .name = "macronix",
+ .module = THIS_MODULE,
+ .probe = macronix_probe,
+ .erase_sector = spi_generic_erase,
+ .read_bytes = spi_generic_read,
+ .write_bytes = spi_generic_write,
+};
+
+int
+macronix_init(void)
+{
+ sema_init(¯onix_driver.lock, 1);
+#ifdef __UBOOT__ /* MIPS */
+ macronix_driver.probe = macronix_probe;
+ macronix_driver.erase_sector = spi_generic_erase;
+ macronix_driver.read_bytes = spi_generic_read;
+ macronix_driver.write_bytes = spi_generic_write;
+#endif
+ register_spi_chip_driver(¯onix_driver);
+ return 0;
+}
+
+void
+macronix_exit(void)
+{
+ sema_init(¯onix_driver.lock, 1);
+ unregister_spi_chip_driver(¯onix_driver);
+ return;
+}
+
+module_init(macronix_init);
+module_exit(macronix_exit);
+
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("American Megatrends Inc");
+MODULE_DESCRIPTION("MTD SPI driver for Macronix flash chips");
+
+#endif
diff --git a/drivers/mtd/spichips/micron.c b/drivers/mtd/spichips/micron.c
new file mode 100644
index 0000000..e9f44ab
--- /dev/null
+++ b/drivers/mtd/spichips/micron.c
@@ -0,0 +1,104 @@
+/*
+ * Copyright (C) 2007-2013 American Megatrends Inc
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+
+#ifdef __UBOOT__
+#include <common.h>
+#endif
+#include "spiflash.h"
+#ifdef CFG_FLASH_SPI_DRIVER
+
+/* Name, ID1, ID2 , Size, Clock, Erase regions, address mode, { Offset, Erase Size, Erase Block Count } */
+/* address mode: 0x00 -3 byte address
+ 0x01 - 4 byte address
+ 0x02 - Low byte: 3 byte address, High byte: 4 byte address*/
+
+static struct spi_flash_info micron_data [] =
+{
+ /* Micron 64 K Sectors */
+ { "Micron/Numonyx N25Q00A" , 0x20, 0x21BA, 0x00010001, 0x8000000 , 108 * 1000000, 1, 0x00, {{ 0, 64 * 1024, 2048 },} },
+ { "Micron/Numonyx N25Q512A" , 0x20, 0x20BA, 0x00010001, 0x4000000 , 108 * 1000000, 1, 0x00, {{ 0, 64 * 1024, 1024 },} },
+ { "Micron/Numonyx N25Q256A" , 0x20, 0x19BA, 0x00010001, 0x2000000 , 108 * 1000000, 1, 0x02, {{ 0, 64 * 1024, 512 },} },
+ { "Micron/Numonyx n25q128" , 0x20, 0x18BA, 0x00010001, 0x1000000, 50 * 1000000, 1, 0x00, {{ 0, 64 * 1024, 256 },} },
+};
+
+
+static
+int
+micron_probe(int bank,struct spi_ctrl_driver *ctrl_drv, struct spi_flash_info *chip_info)
+{
+ int retval;
+
+ retval = spi_generic_probe(bank,ctrl_drv,chip_info,"micron",
+ micron_data,ARRAY_SIZE(micron_data));
+
+ if (retval == -1)
+ return retval;
+
+ /* UnProctect all sectors */
+ /* SRWD=0 (Bit 7) BP0,BP1,BP2 = 0 (Bit 2,3,4) */
+ if (spi_generic_write_status(bank,ctrl_drv,0x0) < 0)
+ printk("micron: Unable to Unprotect all sectors\n");
+
+ return retval;
+}
+
+struct spi_chip_driver micron_driver =
+{
+ .name = "micron",
+ .module = THIS_MODULE,
+ .probe = micron_probe,
+ .erase_sector = spi_generic_erase,
+ .read_bytes = spi_generic_read,
+ .write_bytes = spi_generic_write,
+};
+
+
+
+int
+micron_init(void)
+{
+ sema_init(µn_driver.lock,1);
+#ifdef __UBOOT__ /* MIPS */
+ micron_driver.probe = micron_probe;
+ micron_driver.erase_sector = spi_generic_erase;
+ micron_driver.read_bytes = spi_generic_read;
+ micron_driver.write_bytes = spi_generic_write;
+#endif
+ register_spi_chip_driver(µn_driver);
+ return 0;
+}
+
+
+void
+micron_exit(void)
+{
+ sema_init(µn_driver.lock,1);
+ unregister_spi_chip_driver(µn_driver);
+ return;
+}
+
+
+module_init(micron_init);
+module_exit(micron_exit);
+
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("American Megatrends Inc");
+MODULE_DESCRIPTION("MTD SPI driver for micron flash chips");
+
+#endif
diff --git a/drivers/mtd/spichips/spansion.c b/drivers/mtd/spichips/spansion.c
new file mode 100644
index 0000000..33a7bca
--- /dev/null
+++ b/drivers/mtd/spichips/spansion.c
@@ -0,0 +1,103 @@
+/*
+ * Copyright (C) 2007 American Megatrends Inc
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+
+#ifdef __UBOOT__
+#include <common.h>
+#endif
+#include "spiflash.h"
+#ifdef CFG_FLASH_SPI_DRIVER
+
+/* Name, ID1, ID2 , Size, Clock, Erase regions, address mode,{ Offset, Erase Size, Erase Block Count } */
+/* address mode: 0x00 -3 byte address
+ 0x01 - 4 byte address
+ 0x02 - Low byte: 3 byte address, High byte: 4 byte address*/
+
+static struct spi_flash_info spansion_data [] =
+{
+ /* Spansion 64 K Sectors */
+ { "Spansion S25FL064A" , 0x01, 0x1602, 0x00010001, 0x800000 , 104 * 1000000, 1, 0x00, {{ 0, 64 * 1024, 128 },} },
+ { "Spansion S25FL128P" , 0x01, 0x1820, 0x00010001, 0x1000000 , 104 * 1000000, 1, 0x00, {{ 0, 64 * 1024, 256 },} },
+ { "Spansion S25FL256S" , 0x01, 0x1902, 0x00010001, 0x2000000 , 104 * 1000000, 1, 0x02, {{ 0, 64 * 1024, 512 },} },
+
+};
+
+
+static
+int
+spansion_probe(int bank,struct spi_ctrl_driver *ctrl_drv, struct spi_flash_info *chip_info)
+{
+ int retval;
+ retval = spi_generic_probe(bank,ctrl_drv,chip_info,"spansion",
+ spansion_data,ARRAY_SIZE(spansion_data));
+
+ if (retval == -1)
+ return retval;
+
+ /* UnProctect all sectors */
+ /* SRWD=0 (Bit 7) BP0,BP1,BP2 = 0 (Bit 2,3,4) */
+ if (spi_generic_write_status(bank,ctrl_drv,0x0) < 0)
+ printk("spansion: Unable to Unprotect all sectors\n");
+
+ return retval;
+}
+
+struct spi_chip_driver spansion_driver =
+{
+ .name = "spansion",
+ .module = THIS_MODULE,
+ .probe = spansion_probe,
+ .erase_sector = spi_generic_erase,
+ .read_bytes = spi_generic_read,
+ .write_bytes = spi_generic_write,
+};
+
+
+
+int
+spansion_init(void)
+{
+ sema_init(&spansion_driver.lock, 1);
+#ifdef __UBOOT__ /* MIPS */
+ spansion_driver.probe = spansion_probe;
+ spansion_driver.erase_sector = spi_generic_erase;
+ spansion_driver.read_bytes = spi_generic_read;
+ spansion_driver.write_bytes = spi_generic_write;
+#endif
+ register_spi_chip_driver(&spansion_driver);
+ return 0;
+}
+
+
+void
+spansion_exit(void)
+{
+ sema_init(&spansion_driver.lock, 1);
+ unregister_spi_chip_driver(&spansion_driver);
+ return;
+}
+
+
+module_init(spansion_init);
+module_exit(spansion_exit);
+
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("American Megatrends Inc");
+MODULE_DESCRIPTION("MTD SPI driver for Spansion flash chips");
+
+#endif
diff --git a/drivers/mtd/spichips/spiaccess.c b/drivers/mtd/spichips/spiaccess.c
new file mode 100644
index 0000000..5412f72
--- /dev/null
+++ b/drivers/mtd/spichips/spiaccess.c
@@ -0,0 +1,433 @@
+/*
+ * Copyright (C) 2007 American Megatrends Inc
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#include "spiflash.h"
+
+int spi_verbose = 1;
+
+
+/*----------------------------------------------------------------------------------*/
+/* Low level functions which finally talk to the chip driver */
+/*----------------------------------------------------------------------------------*/
+static void inline
+chip_unlock_sector(struct map_info *map, unsigned long sect_addr,int unlock)
+{
+ struct spi_flash_private *priv=map->fldrv_priv;
+
+ if (!priv->chip_drv->unlock_sector)
+ return;
+ (*priv->chip_drv->unlock_sector)(map,sect_addr,unlock);
+ return;
+}
+
+static int inline
+chip_is_sector_locked(struct map_info *map, unsigned long sect_addr)
+{
+ struct spi_flash_private *priv=map->fldrv_priv;
+
+ if (!priv->chip_drv->is_sector_locked)
+ return 0;
+ return (*priv->chip_drv->is_sector_locked)(map,sect_addr);
+}
+
+static int inline
+chip_read_bytes(struct map_info *map, loff_t addr, size_t bytes, unsigned char *buf)
+{
+ struct spi_flash_private *priv=map->fldrv_priv;
+
+ if (!priv->chip_drv->read_bytes)
+ return -1;
+ return (*priv->chip_drv->read_bytes)(map,addr,bytes,buf);
+}
+
+static int inline
+chip_write_bytes(struct map_info *map, loff_t addr, size_t bytes, const unsigned char *buf)
+{
+ struct spi_flash_private *priv=map->fldrv_priv;
+
+ if (!priv->chip_drv->write_bytes)
+ return -1;
+ return (*priv->chip_drv->write_bytes)(map,addr,bytes,buf);
+}
+
+static int inline
+chip_erase_sector(struct map_info *map, unsigned long sect_addr)
+{
+ struct spi_flash_private *priv=map->fldrv_priv;
+
+ if (!priv->chip_drv->erase_sector)
+ return -1;
+ return (*priv->chip_drv->erase_sector)(map,sect_addr);
+}
+
+
+void
+spi_flash_sync(struct mtd_info *mtd)
+{
+ struct map_info *map = mtd->priv;
+ struct spi_flash_private *priv = map->fldrv_priv;
+
+ if (!priv->chip_drv->sync)
+ return;
+ (*priv->chip_drv->sync)(map);
+ return;
+}
+
+int
+spi_flash_suspend(struct mtd_info *mtd)
+{
+ struct map_info *map = mtd->priv;
+ struct spi_flash_private *priv = map->fldrv_priv;
+
+ if (!priv->chip_drv->suspend)
+ return -EINVAL;
+ return (*priv->chip_drv->suspend)(map);
+}
+
+void
+spi_flash_resume(struct mtd_info *mtd)
+{
+ struct map_info *map = mtd->priv;
+ struct spi_flash_private *priv = map->fldrv_priv;
+
+ if (!priv->chip_drv->resume)
+ return;
+ (*priv->chip_drv->resume)(map);
+ return;
+}
+
+
+/*----------------------------------------------------------------------------------*/
+/* Intermediate Functions which interfaces mtd functionss to chip driver fucntions */
+/*----------------------------------------------------------------------------------*/
+static int
+spi_flash_do_unlock(struct mtd_info *mtd, loff_t ofs, uint32_t len,
+ int is_unlock)
+{
+ struct map_info *map;
+ struct mtd_erase_region_info *merip;
+ int eraseoffset, erasesize, eraseblocks;
+ int i;
+ int retval = 0;
+ int lock_status;
+
+ map = mtd->priv;
+
+ /* Pass the whole chip through sector by sector and check for each
+ sector if the sector and the given interval overlap */
+ for(i = 0; i < mtd->numeraseregions; i++)
+ {
+ merip = &mtd->eraseregions[i];
+
+ eraseoffset = merip->offset;
+ erasesize = merip->erasesize;
+ eraseblocks = merip->numblocks;
+
+ if (ofs > eraseoffset + erasesize)
+ continue;
+
+ while (eraseblocks > 0)
+ {
+ if (ofs < eraseoffset + erasesize && ofs + len > eraseoffset)
+ {
+ chip_unlock_sector(map, eraseoffset, is_unlock);
+
+ lock_status = chip_is_sector_locked(map, eraseoffset);
+
+ if (is_unlock && lock_status)
+ {
+ printk("Cannot unlock sector at address %x length %xx\n",
+ eraseoffset, merip->erasesize);
+ retval = -1;
+ }
+ else if (!is_unlock && !lock_status)
+ {
+ printk("Cannot lock sector at address %x length %x\n",
+ eraseoffset, merip->erasesize);
+ retval = -1;
+ }
+ }
+ eraseoffset += erasesize;
+ eraseblocks --;
+ }
+ }
+ return retval;
+}
+
+static int
+read_one_chip(struct map_info *map, struct flchip *chip,
+ loff_t adr, size_t len, u_char *buf)
+{
+ uint32_t i;
+ size_t bytes;
+
+ chip->state = FL_READY;
+
+ bytes = SPI_READ_PAGE_SIZE;
+ i = 0;
+ while (len >= bytes)
+ {
+ if (0 != chip_read_bytes(map,adr,bytes,&buf [i]))
+ {
+ printk (KERN_ERR "spi_read failed in read_one_chip function\n");
+ return -1;
+ }
+ len -= bytes;
+ i += bytes;
+ adr += bytes;
+ }
+
+ if (0 != len)
+ {
+ if (0 != chip_read_bytes(map, adr, len, &buf [i]))
+ {
+ printk (KERN_ERR "spi_read failed in read_one_chip function\n");
+ return -1;
+ }
+ }
+
+ return 0;
+}
+
+static int
+write_one_chip(struct map_info *map, struct flchip *chip,
+ loff_t addr, size_t len, const u_char * buf)
+{
+ uint32_t page_size, page_offset;
+ uint32_t i;
+
+ chip->state = FL_WRITING;
+
+ /* what page do we start with? */
+ page_offset = addr % SPI_WRITE_PAGE_SIZE;
+
+ /* do all the bytes fit onto one page? */
+ if (page_offset + len <= SPI_WRITE_PAGE_SIZE)
+ {
+ if (0 != chip_write_bytes (map, addr, len, buf))
+ {
+ printk (KERN_ERR "spi writing in the spi_write_bytes function failed\n");
+ return -1;
+ }
+ }
+ else
+ {
+ /* the size of data remaining on the first page */
+ page_size = SPI_WRITE_PAGE_SIZE - page_offset;
+ if (0 != chip_write_bytes (map, addr, page_size, buf))
+ {
+ printk (KERN_ERR "spi writing in the spi_write_bytes function failed\n");
+ return -1;
+ }
+ /* write everything in PAGESIZE chunks */
+ for (i = page_size; i < len; i += page_size)
+ {
+ page_size = len - i;
+ if (page_size > SPI_WRITE_PAGE_SIZE)
+ page_size = SPI_WRITE_PAGE_SIZE;
+ if (0 != chip_write_bytes (map, (addr + i), page_size, (buf + i)))
+ {
+ printk (KERN_ERR "spi writing in the spi_write_bytes function failed\n");
+ return -1;
+ }
+ }
+ }
+
+ chip->state = FL_READY;
+
+ return 0;
+
+}
+
+static int
+erase_one_block(struct map_info *map, struct flchip *chip,ulong addr)
+{
+ int retval = 0;
+
+ chip->state = FL_ERASING;
+
+ retval = chip_erase_sector (map,addr);
+
+ chip->state = FL_READY;
+
+ return (retval);
+}
+/*----------------------------------------------------------------------------------*/
+/* MTD Functions */
+/*----------------------------------------------------------------------------------*/
+int
+spi_flash_unlock(struct mtd_info *mtd, loff_t ofs, uint64_t len)
+{
+ return spi_flash_do_unlock(mtd, ofs, len, 1);
+}
+
+int
+spi_flash_lock(struct mtd_info *mtd, loff_t ofs, uint64_t len)
+{
+ return spi_flash_do_unlock(mtd, ofs, len, 0);
+}
+
+int
+spi_flash_read(struct mtd_info *mtd, loff_t from, size_t len,
+ size_t *retlen, u_char *buf)
+{
+ struct map_info *map = mtd->priv;
+ struct spi_flash_private *private = map->fldrv_priv;
+ unsigned long ofs;
+ int ret = 0;
+
+ if ((from + len) > mtd->size)
+ {
+ printk(KERN_WARNING "%s: read request past end of device "
+ "(0x%lx)\n", map->name, (unsigned long)from + len);
+ return -EINVAL;
+ }
+
+ ofs = from;
+
+ *retlen = 0;
+ ret = read_one_chip(map, &private->chips,ofs,len,buf);
+
+ if (0 == ret)
+ *retlen = len;
+ else
+ ret = -EINVAL;
+
+ return ret;
+
+}
+
+int
+spi_flash_write(struct mtd_info *mtd, loff_t to , size_t len,
+ size_t *retlen, const u_char *buf)
+{
+
+ struct map_info *map = mtd->priv;
+ struct spi_flash_private *private = map->fldrv_priv;
+
+ if (to > mtd->size)
+ {
+ printk (KERN_ERR "write address > size of spi flash\n");
+ return -EINVAL;
+ }
+
+ if ((len + to) > mtd->size)
+ {
+ printk (KERN_ERR "write address + size > size of spi flash\n");
+ return -EINVAL;
+ }
+
+ *retlen = 0;
+ if (!len)
+ return 0;
+
+ if (0 == write_one_chip(map, &private->chips, to, len, buf))
+ {
+ *retlen = len;
+ return 0;
+ }
+
+ return -EINVAL;
+}
+
+
+int
+spi_flash_erase(struct mtd_info *mtd, struct erase_info *instr)
+{
+ struct map_info *map = mtd->priv;
+ struct spi_flash_private *private = map->fldrv_priv;
+ unsigned long adr, len;
+ int ret = 0;
+ int i;
+ int 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, check 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++;
+ }
+
+ /* As before, drop back one to point at the region in which
+ * the address actually falls.
+ */
+ i--;
+
+ if ((instr->addr + instr->len) & (regions[i].erasesize-1))
+ return -EINVAL;
+
+
+ adr = instr->addr;
+ len = instr->len;
+ i = first;
+
+ while (len)
+ {
+ ret = erase_one_block(map, &private->chips, adr);
+
+ if (ret)
+ return ret;
+
+ adr += regions[i].erasesize;
+ len -= regions[i].erasesize;
+ }
+
+ instr->state = MTD_ERASE_DONE;
+ mtd_erase_callback(instr);
+
+ return 0;
+}
diff --git a/drivers/mtd/spichips/spiflash.h b/drivers/mtd/spichips/spiflash.h
new file mode 100644
index 0000000..2ec2eb4
--- /dev/null
+++ b/drivers/mtd/spichips/spiflash.h
@@ -0,0 +1,178 @@
+/*
+ * Copyright (C) 2007 American Megatrends Inc
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#ifndef __LINUX_SPI_H__
+#define __LINUX_SPI_H__
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/types.h>
+#include <linux/kernel.h>
+#include <linux/sched.h>
+#include <linux/errno.h>
+#include <linux/init.h>
+#include <linux/slab.h>
+#include <linux/list.h>
+#include <linux/string.h>
+#include <linux/spinlock.h>
+#include <linux/device.h>
+#include <linux/interrupt.h>
+#include <linux/mtd/mtd.h>
+#include <linux/mtd/map.h>
+#include <linux/mtd/partitions.h>
+#include <linux/mtd/flashchip.h>
+#include <linux/dma-mapping.h>
+#include <linux/wait.h>
+#include <linux/delay.h>
+#include <asm/delay.h>
+#include <linux/semaphore.h>
+#define CFG_FLASH_SPI_DRIVER 1 /* Need for compile the modules */
+/*---------------------------------------------------------------------------
+ The folllowing should match exactly with its uboot counterpart spiflash.h
+----------------------------------------------------------------------------*/
+
+#define DEVICE_TYPE_X8 (8 / 8)
+#define DEVICE_TYPE_X16 (16 / 8)
+#define DEVICE_TYPE_X32 (32 / 8)
+
+#define SPI_READ_PAGE_SIZE (4*1024) /* 4K page size */
+#define SPI_WRITE_PAGE_SIZE 256
+
+#define MAX_ERASE_REGIONS 4
+
+struct spi_flash_info
+{
+ const char *name;
+ const __u8 mfr_id;
+ const __u16 dev_id;
+ const __u32 operationmode;
+ const uint64_t size;
+ const unsigned int max_clock;
+ const int numeraseregions;
+ const __u8 address32;
+ const struct mtd_erase_region_info regions[MAX_ERASE_REGIONS];
+};
+
+typedef enum spidir
+{
+ SPI_NONE = 0,
+ SPI_READ = 1,
+ SPI_WRITE = 2
+} SPI_DIR;
+
+struct spi_ctrl_driver
+{
+ struct module *module;
+ struct semaphore lock;
+ char *name;
+ struct list_head list;
+
+ /* Supports operation mode */
+ int operation_mode_mask;
+
+ /* Supports fast read at higher frequency */
+ int fast_read;
+
+ /* Supports fast write at higher frequency */
+ int fast_write;
+
+ /* Max datasize to be used to read type functions in spi_transfer*/
+ int max_read;
+
+ /* spi_transfer can be used for all type of spi access */
+ int (*spi_transfer)(int bank,unsigned char *cmd,int cmdlen, SPI_DIR dir,
+ unsigned char *data, unsigned long datalen);
+
+ /* spi_burst_read is not NULL, if the ctrl supports read large data continuosly */
+ int (*spi_burst_read)(int bank,unsigned char *cmd,int cmdlen, SPI_DIR dir,
+ unsigned char *data, unsigned long datalen);
+
+ int (*spi_configure_clock)(int bank, unsigned int clock);
+
+#ifdef __UBOOT__
+ int (*spi_init)(void);
+#endif
+};
+
+struct spi_chip_driver
+{
+ struct module *module;
+ struct semaphore lock;
+ char *name;
+ struct list_head list;
+ int (*probe)(int bank,struct spi_ctrl_driver *ctlr_drv, struct spi_flash_info *chip_info);
+ void (*unlock_sector) (struct map_info *map, unsigned long sect_addr,int unlock);
+ int (*is_sector_locked)(struct map_info *map, unsigned long sect_addr);
+ int (*erase_sector) (struct map_info *map, unsigned long sect_addr);
+ int (*read_bytes) (struct map_info *map, loff_t addr, size_t bytes, unsigned char *buf);
+ int (*write_bytes) (struct map_info *map, loff_t addr, size_t bytes, const unsigned char *buf);
+ void (*sync) (struct map_info *map);
+ int (*suspend) (struct map_info *map);
+ void (*resume) (struct map_info *map);
+};
+
+struct spi_flash_private
+{
+ int device_type;
+ int interleave;
+ int numchips;
+ unsigned long chipshift;
+ __u8 address32;
+ struct flchip chips;
+ struct spi_chip_driver *chip_drv;
+ struct spi_ctrl_driver *ctrl_drv;
+};
+
+/* SPI Core Functions to register,access chip and controller drivers */
+struct spi_chip_driver *get_spi_chip_driver_by_index (int index);
+struct spi_chip_driver *get_spi_chip_driver_by_name (const char *name);
+struct spi_ctrl_driver *get_spi_ctrl_driver_by_index (int index);
+struct spi_ctrl_driver *get_spi_ctrl_driver_by_name (const char *name);
+void register_spi_chip_driver(struct spi_chip_driver *drv);
+void unregister_spi_chip_driver(struct spi_chip_driver *drv);
+void register_spi_ctrl_driver(struct spi_ctrl_driver *drv);
+void unregister_spi_ctrl_driver(struct spi_ctrl_driver *drv);
+
+/* Functions registered to MTD for accessing the chips */
+int spi_flash_read(struct mtd_info *, loff_t, size_t, size_t *, u_char *);
+int spi_flash_write(struct mtd_info *, loff_t, size_t, size_t *,const u_char *);
+int spi_flash_erase(struct mtd_info *, struct erase_info *);
+void spi_flash_sync(struct mtd_info *);
+int spi_flash_suspend(struct mtd_info *);
+void spi_flash_resume(struct mtd_info *);
+int spi_flash_unlock(struct mtd_info *mtd, loff_t ofs, uint64_t len);
+int spi_flash_lock(struct mtd_info *mtd, loff_t ofs, uint64_t len);
+
+/* Generic spi funtions which can be used by any spi device (if uses generic algo) */
+int spi_generic_write_enable(int bank,struct spi_ctrl_driver *ctrl_drv);
+int spi_generic_read_enable(int bank,struct spi_ctrl_driver *ctrl_drv);
+int spi_generic_read_status(int bank,struct spi_ctrl_driver *ctrl_drv,unsigned char *status);
+int spi_generic_write_status(int bank,struct spi_ctrl_driver *ctrl_drv, unsigned char status);
+int spi_generic_erase(struct map_info *map, unsigned long sect_addr);
+int spi_generic_read(struct map_info *map, loff_t addr, size_t bytes, unsigned char *buff);
+int spi_generic_write(struct map_info *map, loff_t addr, size_t bytes, const unsigned char *buff);
+int spi_generic_probe(int bank, struct spi_ctrl_driver *ctrl_drv, struct spi_flash_info *chip_info,
+ char *spi_name,struct spi_flash_info *spi_list, int spi_list_len);
+
+#ifdef CONFIG_SPX_FEATURE_GLOBAL_BKUP_FLASH_BANKS
+#define MAX_SPI_BANKS (CONFIG_SPX_FEATURE_GLOBAL_FLASH_BANKS + CONFIG_SPX_FEATURE_GLOBAL_BKUP_FLASH_BANKS)
+#else
+#define MAX_SPI_BANKS CONFIG_SPX_FEATURE_GLOBAL_FLASH_BANKS
+#endif
+
+#endif
diff --git a/drivers/mtd/spichips/spimtd.c b/drivers/mtd/spichips/spimtd.c
new file mode 100644
index 0000000..3c3a3c0
--- /dev/null
+++ b/drivers/mtd/spichips/spimtd.c
@@ -0,0 +1,241 @@
+/*
+ * Copyright (C) 2007 American Megatrends Inc
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#include "spiflash.h"
+
+static struct mtd_info * spi_flash_probe(struct map_info *map);
+static void spi_flash_destroy(struct mtd_info *mtd);
+
+static struct mtd_chip_driver spi_flash_chipdrv =
+{
+ .probe = spi_flash_probe,
+ .destroy = spi_flash_destroy,
+ .name = "spi_probe",
+ .module = THIS_MODULE
+};
+
+unsigned long ractrends_spiflash_flash_id[MAX_SPI_BANKS];
+unsigned long ractrends_spiflash_flash_size[MAX_SPI_BANKS];
+
+/*------------------------------------------------------------------------------*/
+/* Probe Function */
+/*------------------------------------------------------------------------------*/
+static
+int
+probe_spi_chips(struct map_info *map,struct spi_flash_private *private,
+ struct spi_flash_info *spi_info)
+{
+ int bank = map->map_priv_1;
+ int req = 0;
+ int ctrl,chip;
+ int gotindex;
+ struct spi_chip_driver *chip_drv;
+ struct spi_ctrl_driver *ctrl_drv;
+
+ gotindex=0;
+
+ /* For Every Controller driver */
+ ctrl = 0;
+ ctrl_drv = get_spi_ctrl_driver_by_index(ctrl);
+ while (ctrl_drv != NULL)
+ {
+ /* For Every Chip driver */
+ chip = 0;
+ chip_drv = get_spi_chip_driver_by_index(chip);
+ while (chip_drv != NULL)
+ {
+ /* Probe for the chip on the controller */
+ if (chip_drv->probe(bank,ctrl_drv,spi_info) == 0)
+ {
+ /* If success, check if it is the requested index */
+ if (req == gotindex)
+ {
+ private->chip_drv = chip_drv;
+ private->ctrl_drv = ctrl_drv;
+ return 0;
+ }
+ gotindex++;
+ }
+ /* Try Next chip */
+ chip++;
+ chip_drv = get_spi_chip_driver_by_index(chip);
+ }
+ /* Try next controller */
+ ctrl++;
+ ctrl_drv = get_spi_ctrl_driver_by_index(ctrl);
+ }
+ return -1;
+}
+
+static int configure_spi_clock(struct spi_ctrl_driver *ctrl_drv, int bank, unsigned int clock)
+{
+ if (ctrl_drv->spi_configure_clock == NULL)
+ return 0;
+
+ return ctrl_drv->spi_configure_clock(bank, clock);
+}
+
+/*--------------------------------------------------------------------------------------*/
+/* Interfaces to MTD Module */
+/*--------------------------------------------------------------------------------------*/
+static struct mtd_info *
+spi_flash_probe(struct map_info *map)
+{
+ struct mtd_info *mtd;
+ struct spi_flash_private *private;
+
+ struct spi_flash_info spi_info;
+ struct flchip chips;
+ int j,i;
+
+
+ private = kmalloc(sizeof(*private) + sizeof(struct flchip) , GFP_KERNEL);
+ if (!private)
+ {
+ printk(KERN_WARNING
+ "%s: kmalloc failed for private structure\n", map->name);
+ return NULL;
+ }
+ memset(private,0,sizeof(*private) + (sizeof(struct flchip)));
+
+ mtd = (struct mtd_info*)kmalloc(sizeof(*mtd), GFP_KERNEL);
+ if (!mtd)
+ {
+ printk(KERN_WARNING
+ "%s: kmalloc failed for info structure\n", map->name);
+ return NULL;
+ }
+ memset(mtd, 0, sizeof(*mtd));
+
+ mtd->priv = map;
+
+ memset(&spi_info, 0, sizeof(spi_info));
+ if (probe_spi_chips(map,private,&spi_info) == -1)
+ {
+ printk(KERN_WARNING
+ "%s: No spi compatible flash device found\n",
+ map->name);
+ map->fldrv_priv = NULL;
+ kfree(mtd);
+ kfree(private);
+ return NULL;
+ }
+
+ /* Fill flash ID and size in public array */
+ ractrends_spiflash_flash_id[map->map_priv_1] = ((spi_info.mfr_id << 16) | spi_info.dev_id);
+ ractrends_spiflash_flash_size[map->map_priv_1] = spi_info.size;
+
+ configure_spi_clock(private->ctrl_drv, map->map_priv_1, spi_info.max_clock);
+
+ chips.start = 0;
+ chips.state = FL_READY;
+
+
+ /* Fill in the mtd structures */
+ mtd->size = spi_info.size;
+ mtd->numeraseregions = spi_info.numeraseregions;
+
+ /* Allocate memory for erase regions */
+ mtd->eraseregions = kmalloc(sizeof(struct mtd_erase_region_info) *
+ mtd->numeraseregions, GFP_KERNEL);
+ if (!mtd->eraseregions)
+ {
+ printk(KERN_WARNING "%s: Failed to allocate "
+ "memory for MTD erase region info\n", map->name);
+ kfree(mtd);
+ kfree(private);
+ map->fldrv_priv = NULL;
+ return NULL;
+ }
+
+ /* Fill in the mtd erase structures */
+ for (j = 0; j < spi_info.numeraseregions; j++)
+ {
+ mtd->eraseregions[j].offset = spi_info.regions[j].offset;
+ mtd->eraseregions[j].erasesize = spi_info.regions[j].erasesize;
+ mtd->eraseregions[j].numblocks = spi_info.regions[j].numblocks;
+ if (mtd->erasesize < mtd->eraseregions[j].erasesize)
+ mtd->erasesize = mtd->eraseregions[j].erasesize;
+ }
+
+
+ /* Fill in the remaining mtd structure */
+ mtd->type = MTD_NORFLASH;
+ mtd->flags = MTD_CAP_NORFLASH;
+ mtd->name = map->name;
+ mtd->_erase = spi_flash_erase;
+ mtd->_read = spi_flash_read;
+ mtd->_write = spi_flash_write;
+ mtd->_sync = spi_flash_sync;
+ mtd->_suspend = spi_flash_suspend;
+ mtd->_resume = spi_flash_resume;
+ mtd->_lock = spi_flash_lock;
+ mtd->_unlock = spi_flash_unlock;
+ mtd->writesize = 1;
+
+ /* Fill in the private structure */
+ private->numchips = 1;
+ private->device_type = DEVICE_TYPE_X8;
+ private->interleave = 1;
+ private->address32 = spi_info.address32;
+ memcpy(&private->chips, &chips,sizeof(struct flchip) * private->numchips);
+ for (i = 0; i < private->numchips; i++)
+ {
+ init_waitqueue_head(&private->chips.wq);
+ mutex_init(&private->chips.mutex);
+ }
+
+ /* Fill in the map structure */
+ map->fldrv_priv = private;
+ map->bankwidth = 1;
+ map->fldrv = &spi_flash_chipdrv;
+ __module_get(THIS_MODULE);
+
+ return mtd;
+}
+
+
+static void
+spi_flash_destroy(struct mtd_info *mtd)
+{
+ struct map_info *map = mtd->priv;
+ struct spi_flash_private *private = map->fldrv_priv;
+ kfree(private);
+}
+
+
+int __init
+spi_flash_init(void)
+{
+ register_mtd_chip_driver(&spi_flash_chipdrv);
+ return 0;
+}
+
+void __exit
+spi_flash_exit(void)
+{
+ unregister_mtd_chip_driver(&spi_flash_chipdrv);
+}
+
+module_init(spi_flash_init);
+module_exit(spi_flash_exit);
+
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("American Megatrends Inc");
+MODULE_DESCRIPTION("Core SPI with MTD Interface");
+
diff --git a/drivers/mtd/spichips/spireg.c b/drivers/mtd/spichips/spireg.c
new file mode 100644
index 0000000..09aaa51
--- /dev/null
+++ b/drivers/mtd/spichips/spireg.c
@@ -0,0 +1,180 @@
+/*
+ * Copyright (C) 2007 American Megatrends Inc
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#ifdef __UBOOT__
+#include <common.h>
+#endif
+#include "spiflash.h"
+#ifdef CFG_FLASH_SPI_DRIVER
+
+DEFINE_SPINLOCK(spi_chip_drvs_lock);
+LIST_HEAD(spi_chip_drvs_list);
+DEFINE_SPINLOCK(spi_ctrl_drvs_lock);
+LIST_HEAD(spi_ctrl_drvs_list);
+
+void
+register_spi_chip_driver(struct spi_chip_driver *drv)
+{
+ spin_lock(&spi_chip_drvs_lock);
+ list_add(&drv->list, &spi_chip_drvs_list);
+ spin_unlock(&spi_chip_drvs_lock);
+}
+
+void
+unregister_spi_chip_driver(struct spi_chip_driver *drv)
+{
+ spin_lock(&spi_chip_drvs_lock);
+ list_del(&drv->list);
+ spin_unlock(&spi_chip_drvs_lock);
+}
+
+void
+register_spi_ctrl_driver(struct spi_ctrl_driver *drv)
+{
+ spin_lock(&spi_ctrl_drvs_lock);
+ list_add(&drv->list, &spi_ctrl_drvs_list);
+ spin_unlock(&spi_ctrl_drvs_lock);
+}
+
+void
+unregister_spi_ctrl_driver(struct spi_ctrl_driver *drv)
+{
+ spin_lock(&spi_ctrl_drvs_lock);
+ list_del(&drv->list);
+ spin_unlock(&spi_ctrl_drvs_lock);
+}
+
+struct spi_chip_driver *
+get_spi_chip_driver_by_name (const char *name)
+{
+ struct list_head *pos;
+ struct spi_chip_driver *ret = NULL, *this;
+
+ spin_lock(&spi_chip_drvs_lock);
+
+ list_for_each(pos, &spi_chip_drvs_list) {
+ this = list_entry(pos, typeof(*this), list);
+
+ if (!strcmp(this->name, name)) {
+ ret = this;
+ break;
+ }
+ }
+ if (ret && !try_module_get(ret->module))
+ ret = NULL;
+
+ spin_unlock(&spi_chip_drvs_lock);
+
+ return ret;
+}
+
+struct spi_chip_driver *
+get_spi_chip_driver_by_index (int index)
+{
+ struct list_head *pos;
+ struct spi_chip_driver *ret = NULL, *this;
+ int got;
+
+ spin_lock(&spi_chip_drvs_lock);
+
+ got=0;
+ list_for_each(pos, &spi_chip_drvs_list) {
+ this = list_entry(pos, typeof(*this), list);
+
+ if (index == got) {
+ ret = this;
+ break;
+ }
+ got++;
+ }
+ if (ret && !try_module_get(ret->module))
+ ret = NULL;
+
+ spin_unlock(&spi_chip_drvs_lock);
+
+ return ret;
+}
+
+
+struct spi_ctrl_driver *
+get_spi_ctrl_driver_by_name (const char *name)
+{
+ struct list_head *pos;
+ struct spi_ctrl_driver *ret = NULL, *this;
+
+ spin_lock(&spi_ctrl_drvs_lock);
+
+ list_for_each(pos, &spi_ctrl_drvs_list) {
+ this = list_entry(pos, typeof(*this), list);
+
+ if (!strcmp(this->name, name)) {
+ ret = this;
+ break;
+ }
+ }
+ if (ret && !try_module_get(ret->module))
+ ret = NULL;
+
+ spin_unlock(&spi_ctrl_drvs_lock);
+
+ return ret;
+}
+
+struct spi_ctrl_driver *
+get_spi_ctrl_driver_by_index (int index)
+{
+ struct list_head *pos;
+ struct spi_ctrl_driver *ret = NULL, *this;
+ int got;
+
+ spin_lock(&spi_ctrl_drvs_lock);
+
+ got=0;
+ list_for_each(pos, &spi_ctrl_drvs_list) {
+ this = list_entry(pos, typeof(*this), list);
+
+ if (index == got) {
+ ret = this;
+ break;
+ }
+ got++;
+ }
+ if (ret && !try_module_get(ret->module))
+ ret = NULL;
+
+ spin_unlock(&spi_ctrl_drvs_lock);
+
+ return ret;
+}
+
+
+
+EXPORT_SYMBOL(get_spi_chip_driver_by_name);
+EXPORT_SYMBOL(get_spi_chip_driver_by_index);
+EXPORT_SYMBOL(get_spi_ctrl_driver_by_name);
+EXPORT_SYMBOL(get_spi_ctrl_driver_by_index);
+EXPORT_SYMBOL(register_spi_ctrl_driver);
+EXPORT_SYMBOL(unregister_spi_ctrl_driver);
+EXPORT_SYMBOL(register_spi_chip_driver);
+EXPORT_SYMBOL(unregister_spi_chip_driver);
+
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("American Megatrends Inc");
+MODULE_DESCRIPTION("Core routines for (un)registering spi chip and controller drivers");
+
+#endif
diff --git a/drivers/mtd/spichips/winbond.c b/drivers/mtd/spichips/winbond.c
new file mode 100644
index 0000000..03b203c
--- /dev/null
+++ b/drivers/mtd/spichips/winbond.c
@@ -0,0 +1,98 @@
+/*
+ * Copyright (C) 2007 American Megatrends Inc
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#ifdef __UBOOT__
+#include <common.h>
+#endif
+#include "spiflash.h"
+#ifdef CFG_FLASH_SPI_DRIVER
+
+/* Name, ID1, ID2 , Size, Clock, Erase regions, address mode,{ Offset, Erase Size, Erase Block Count } */
+/* address mode: 0x00 -3 byte address
+ 0x01 - 4 byte address
+ 0x02 - Low byte: 3 byte address, High byte: 4 byte address*/
+static struct spi_flash_info winbond_data [] =
+{
+ /* Winbond 64 K Sectors */
+ { "Winbond W25X64" , 0xEF, 0x1730, 0x00010007, 0x800000 , 75 * 1000000, 1, 0x00, {{ 0, 64 * 1024, 128 },} },
+ { "Winbond W25Q32" , 0xEF, 0x1640, 0x0001000F, 0x400000 , 75 * 1000000 , 1, 0x00, {{ 0, 64 * 1024, 128 },} },
+ { "Winbond W25Q64" , 0xEF, 0x1740, 0x0001000F, 0x800000 , 80 * 1000000, 1, 0x00, {{ 0, 64 * 1024, 128 },} },
+ { "Winbond W25Q128", 0xEF, 0x1840, 0x0001000F, 0x1000000, 104 * 1000000, 1, 0x00, {{ 0, 64 * 1024, 256 },} },
+ { "Winbond W25Q256", 0xEF, 0x1940, 0x0001000F, 0x2000000, 104 * 1000000, 1, 0x02, {{ 0, 64 * 1024, 512 },} },
+ { "Winbond W25M512", 0xEF, 0x1971, 0x0001000f, 0x4000000, 104 * 1000000, 2, 0x06, {{ 0, 64 * 1024, 512 },{ 0x2000000, 64 * 1024, 512 },} },
+};
+
+static
+int
+winbond_probe(int bank,struct spi_ctrl_driver *ctrl_drv, struct spi_flash_info *chip_info)
+{
+ int retval;
+ retval = spi_generic_probe(bank,ctrl_drv,chip_info,"winbond",
+ winbond_data,ARRAY_SIZE(winbond_data));
+
+ if (retval == -1)
+ return retval;
+
+ /* UnProctect all sectors */
+ /* SRWD=0 (Bit 7) BP0,BP1,BP2 = 0 (Bit 2,3,4) */
+ if (spi_generic_write_status(bank,ctrl_drv,0x0) < 0)
+ printk("winbond: Unable to Unprotect all sectors\n");
+
+ return retval;
+}
+
+struct spi_chip_driver winbond_driver =
+{
+ .name = "winbond",
+ .module = THIS_MODULE,
+ .probe = winbond_probe,
+ .erase_sector = spi_generic_erase,
+ .read_bytes = spi_generic_read,
+ .write_bytes = spi_generic_write,
+};
+
+int
+winbond_init(void)
+{
+ sema_init(&winbond_driver.lock, 1);
+#ifdef __UBOOT__ /* MIPS */
+ winbond_driver.probe = winbond_probe;
+ winbond_driver.erase_sector = spi_generic_erase;
+ winbond_driver.read_bytes = spi_generic_read;
+ winbond_driver.write_bytes = spi_generic_write;
+#endif
+ register_spi_chip_driver(&winbond_driver);
+ return 0;
+}
+
+void
+winbond_exit(void)
+{
+ sema_init(&winbond_driver.lock, 1);
+ unregister_spi_chip_driver(&winbond_driver);
+ return;
+}
+
+module_init(winbond_init);
+module_exit(winbond_exit);
+
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("American Megatrends Inc");
+MODULE_DESCRIPTION("MTD SPI driver for Winbond flash chips");
+
+#endif
--
1.9.1
这个叫 垒丝柱, 淘宝有卖:
邮票孔拆焊风嘴不用定制,直接有现成的,刚好gk7102 S3两种核心板可用,到了试一下
https://whycan.cn/files/members/428/none.png
还有这种玩意, 真是涨见识了。。。