Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
openeuler
Kernel
提交
b29bc3df
K
Kernel
项目概览
openeuler
/
Kernel
1 年多 前同步成功
通知
8
Star
0
Fork
0
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
0
列表
看板
标记
里程碑
合并请求
0
DevOps
流水线
流水线任务
计划
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
K
Kernel
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
0
Issue
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
DevOps
DevOps
流水线
流水线任务
计划
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
流水线任务
提交
Issue看板
提交
b29bc3df
编写于
9月 01, 2013
作者:
M
Mark Brown
浏览文件
操作
浏览文件
下载
差异文件
Merge remote-tracking branch 'spi/topic/bitbang' into spi-next
上级
c3dbe2b7
2e29db40
变更
5
隐藏空白更改
内联
并排
Showing
5 changed file
with
113 addition
and
193 deletion
+113
-193
drivers/spi/spi-altera.c
drivers/spi/spi-altera.c
+0
-12
drivers/spi/spi-bitbang.c
drivers/spi/spi-bitbang.c
+113
-147
drivers/spi/spi-nuc900.c
drivers/spi/spi-nuc900.c
+0
-13
drivers/spi/spi-xilinx.c
drivers/spi/spi-xilinx.c
+0
-16
include/linux/spi/spi_bitbang.h
include/linux/spi/spi_bitbang.h
+0
-5
未找到文件。
drivers/spi/spi-altera.c
浏览文件 @
b29bc3df
...
...
@@ -103,16 +103,6 @@ static void altera_spi_chipsel(struct spi_device *spi, int value)
}
}
static
int
altera_spi_setupxfer
(
struct
spi_device
*
spi
,
struct
spi_transfer
*
t
)
{
return
0
;
}
static
int
altera_spi_setup
(
struct
spi_device
*
spi
)
{
return
0
;
}
static
inline
unsigned
int
hw_txbyte
(
struct
altera_spi
*
hw
,
int
count
)
{
if
(
hw
->
tx
)
{
...
...
@@ -224,7 +214,6 @@ static int altera_spi_probe(struct platform_device *pdev)
master
->
bus_num
=
pdev
->
id
;
master
->
num_chipselect
=
16
;
master
->
mode_bits
=
SPI_CS_HIGH
;
master
->
setup
=
altera_spi_setup
;
hw
=
spi_master_get_devdata
(
master
);
platform_set_drvdata
(
pdev
,
hw
);
...
...
@@ -233,7 +222,6 @@ static int altera_spi_probe(struct platform_device *pdev)
hw
->
bitbang
.
master
=
spi_master_get
(
master
);
if
(
!
hw
->
bitbang
.
master
)
return
err
;
hw
->
bitbang
.
setup_transfer
=
altera_spi_setupxfer
;
hw
->
bitbang
.
chipselect
=
altera_spi_chipsel
;
hw
->
bitbang
.
txrx_bufs
=
altera_spi_txrx
;
...
...
drivers/spi/spi-bitbang.c
浏览文件 @
b29bc3df
...
...
@@ -255,150 +255,140 @@ static int spi_bitbang_bufs(struct spi_device *spi, struct spi_transfer *t)
* Drivers can provide word-at-a-time i/o primitives, or provide
* transfer-at-a-time ones to leverage dma or fifo hardware.
*/
static
void
bitbang_work
(
struct
work_struct
*
work
)
static
int
spi_bitbang_prepare_hardware
(
struct
spi_master
*
spi
)
{
struct
spi_bitbang
*
bitbang
=
container_of
(
work
,
struct
spi_bitbang
,
work
);
struct
spi_bitbang
*
bitbang
;
unsigned
long
flags
;
struct
spi_message
*
m
,
*
_m
;
bitbang
=
spi_master_get_devdata
(
spi
);
spin_lock_irqsave
(
&
bitbang
->
lock
,
flags
);
bitbang
->
busy
=
1
;
list_for_each_entry_safe
(
m
,
_m
,
&
bitbang
->
queue
,
queue
)
{
struct
spi_device
*
spi
;
unsigned
nsecs
;
struct
spi_transfer
*
t
=
NULL
;
unsigned
tmp
;
unsigned
cs_change
;
int
status
;
int
do_setup
=
-
1
;
list_del
(
&
m
->
queue
);
spin_unlock_irqrestore
(
&
bitbang
->
lock
,
flags
);
/* FIXME this is made-up ... the correct value is known to
* word-at-a-time bitbang code, and presumably chipselect()
* should enforce these requirements too?
*/
nsecs
=
100
;
spin_unlock_irqrestore
(
&
bitbang
->
lock
,
flags
);
spi
=
m
->
spi
;
tmp
=
0
;
cs_change
=
1
;
status
=
0
;
return
0
;
}
list_for_each_entry
(
t
,
&
m
->
transfers
,
transfer_list
)
{
/* override speed or wordsize? */
if
(
t
->
speed_hz
||
t
->
bits_per_word
)
do_setup
=
1
;
/* init (-1) or override (1) transfer params */
if
(
do_setup
!=
0
)
{
status
=
bitbang
->
setup_transfer
(
spi
,
t
);
if
(
status
<
0
)
break
;
if
(
do_setup
==
-
1
)
do_setup
=
0
;
}
/* set up default clock polarity, and activate chip;
* this implicitly updates clock and spi modes as
* previously recorded for this device via setup().
* (and also deselects any other chip that might be
* selected ...)
*/
if
(
cs_change
)
{
bitbang
->
chipselect
(
spi
,
BITBANG_CS_ACTIVE
);
ndelay
(
nsecs
);
}
cs_change
=
t
->
cs_change
;
if
(
!
t
->
tx_buf
&&
!
t
->
rx_buf
&&
t
->
len
)
{
status
=
-
EINVAL
;
break
;
}
static
int
spi_bitbang_transfer_one
(
struct
spi_master
*
master
,
struct
spi_message
*
m
)
{
struct
spi_bitbang
*
bitbang
;
unsigned
nsecs
;
struct
spi_transfer
*
t
=
NULL
;
unsigned
cs_change
;
int
status
;
int
do_setup
=
-
1
;
struct
spi_device
*
spi
=
m
->
spi
;
bitbang
=
spi_master_get_devdata
(
master
);
/* FIXME this is made-up ... the correct value is known to
* word-at-a-time bitbang code, and presumably chipselect()
* should enforce these requirements too?
*/
nsecs
=
100
;
/* transfer data. the lower level code handles any
* new dma mappings it needs. our caller always gave
* us dma-safe buffers.
*/
if
(
t
->
len
)
{
/* REVISIT dma API still needs a designated
* DMA_ADDR_INVALID; ~0 might be better.
*/
if
(
!
m
->
is_dma_mapped
)
t
->
rx_dma
=
t
->
tx_dma
=
0
;
status
=
bitbang
->
txrx_bufs
(
spi
,
t
);
}
if
(
status
>
0
)
m
->
actual_length
+=
status
;
if
(
status
!=
t
->
len
)
{
/* always report some kind of error */
if
(
status
>=
0
)
status
=
-
EREMOTEIO
;
cs_change
=
1
;
status
=
0
;
list_for_each_entry
(
t
,
&
m
->
transfers
,
transfer_list
)
{
/* override speed or wordsize? */
if
(
t
->
speed_hz
||
t
->
bits_per_word
)
do_setup
=
1
;
/* init (-1) or override (1) transfer params */
if
(
do_setup
!=
0
)
{
status
=
bitbang
->
setup_transfer
(
spi
,
t
);
if
(
status
<
0
)
break
;
}
status
=
0
;
/* protocol tweaks before next transfer */
if
(
t
->
delay_usecs
)
udelay
(
t
->
delay_usecs
);
if
(
cs_change
&&
!
list_is_last
(
&
t
->
transfer_list
,
&
m
->
transfers
))
{
/* sometimes a short mid-message deselect of the chip
* may be needed to terminate a mode or command
*/
ndelay
(
nsecs
);
bitbang
->
chipselect
(
spi
,
BITBANG_CS_INACTIVE
);
ndelay
(
nsecs
);
}
if
(
do_setup
==
-
1
)
do_setup
=
0
;
}
m
->
status
=
status
;
m
->
complete
(
m
->
context
);
/* set up default clock polarity, and activate chip;
* this implicitly updates clock and spi modes as
* previously recorded for this device via setup().
* (and also deselects any other chip that might be
* selected ...)
*/
if
(
cs_change
)
{
bitbang
->
chipselect
(
spi
,
BITBANG_CS_ACTIVE
);
ndelay
(
nsecs
);
}
cs_change
=
t
->
cs_change
;
if
(
!
t
->
tx_buf
&&
!
t
->
rx_buf
&&
t
->
len
)
{
status
=
-
EINVAL
;
break
;
}
/*
normally deactivate chipselect ... unless no error and
*
cs_change has hinted that the next message will probably
*
be for this chip too
.
/*
transfer data. the lower level code handles any
*
new dma mappings it needs. our caller always gave
*
us dma-safe buffers
.
*/
if
(
!
(
status
==
0
&&
cs_change
))
{
if
(
t
->
len
)
{
/* REVISIT dma API still needs a designated
* DMA_ADDR_INVALID; ~0 might be better.
*/
if
(
!
m
->
is_dma_mapped
)
t
->
rx_dma
=
t
->
tx_dma
=
0
;
status
=
bitbang
->
txrx_bufs
(
spi
,
t
);
}
if
(
status
>
0
)
m
->
actual_length
+=
status
;
if
(
status
!=
t
->
len
)
{
/* always report some kind of error */
if
(
status
>=
0
)
status
=
-
EREMOTEIO
;
break
;
}
status
=
0
;
/* protocol tweaks before next transfer */
if
(
t
->
delay_usecs
)
udelay
(
t
->
delay_usecs
);
if
(
cs_change
&&
!
list_is_last
(
&
t
->
transfer_list
,
&
m
->
transfers
))
{
/* sometimes a short mid-message deselect of the chip
* may be needed to terminate a mode or command
*/
ndelay
(
nsecs
);
bitbang
->
chipselect
(
spi
,
BITBANG_CS_INACTIVE
);
ndelay
(
nsecs
);
}
}
m
->
status
=
status
;
spin_lock_irqsave
(
&
bitbang
->
lock
,
flags
);
/* normally deactivate chipselect ... unless no error and
* cs_change has hinted that the next message will probably
* be for this chip too.
*/
if
(
!
(
status
==
0
&&
cs_change
))
{
ndelay
(
nsecs
);
bitbang
->
chipselect
(
spi
,
BITBANG_CS_INACTIVE
);
ndelay
(
nsecs
);
}
bitbang
->
busy
=
0
;
spin_unlock_irqrestore
(
&
bitbang
->
lock
,
flags
);
spi_finalize_current_message
(
master
);
return
status
;
}
/**
* spi_bitbang_transfer - default submit to transfer queue
*/
int
spi_bitbang_transfer
(
struct
spi_device
*
spi
,
struct
spi_message
*
m
)
static
int
spi_bitbang_unprepare_hardware
(
struct
spi_master
*
spi
)
{
struct
spi_bitbang
*
bitbang
;
struct
spi_bitbang
*
bitbang
;
unsigned
long
flags
;
int
status
=
0
;
m
->
actual_length
=
0
;
m
->
status
=
-
EINPROGRESS
;
bitbang
=
spi_master_get_devdata
(
spi
->
master
);
bitbang
=
spi_master_get_devdata
(
spi
);
spin_lock_irqsave
(
&
bitbang
->
lock
,
flags
);
if
(
!
spi
->
max_speed_hz
)
status
=
-
ENETDOWN
;
else
{
list_add_tail
(
&
m
->
queue
,
&
bitbang
->
queue
);
queue_work
(
bitbang
->
workqueue
,
&
bitbang
->
work
);
}
bitbang
->
busy
=
0
;
spin_unlock_irqrestore
(
&
bitbang
->
lock
,
flags
);
return
status
;
return
0
;
}
EXPORT_SYMBOL_GPL
(
spi_bitbang_transfer
);
/*----------------------------------------------------------------------*/
...
...
@@ -428,20 +418,22 @@ EXPORT_SYMBOL_GPL(spi_bitbang_transfer);
int
spi_bitbang_start
(
struct
spi_bitbang
*
bitbang
)
{
struct
spi_master
*
master
=
bitbang
->
master
;
int
status
;
if
(
!
master
||
!
bitbang
->
chipselect
)
return
-
EINVAL
;
INIT_WORK
(
&
bitbang
->
work
,
bitbang_work
);
spin_lock_init
(
&
bitbang
->
lock
);
INIT_LIST_HEAD
(
&
bitbang
->
queue
);
if
(
!
master
->
mode_bits
)
master
->
mode_bits
=
SPI_CPOL
|
SPI_CPHA
|
bitbang
->
flags
;
if
(
!
master
->
transfer
)
master
->
transfer
=
spi_bitbang_transfer
;
if
(
master
->
transfer
||
master
->
transfer_one_message
)
return
-
EINVAL
;
master
->
prepare_transfer_hardware
=
spi_bitbang_prepare_hardware
;
master
->
unprepare_transfer_hardware
=
spi_bitbang_unprepare_hardware
;
master
->
transfer_one_message
=
spi_bitbang_transfer_one
;
if
(
!
bitbang
->
txrx_bufs
)
{
bitbang
->
use_dma
=
0
;
bitbang
->
txrx_bufs
=
spi_bitbang_bufs
;
...
...
@@ -452,34 +444,12 @@ int spi_bitbang_start(struct spi_bitbang *bitbang)
master
->
setup
=
spi_bitbang_setup
;
master
->
cleanup
=
spi_bitbang_cleanup
;
}
}
else
if
(
!
master
->
setup
)
return
-
EINVAL
;
if
(
master
->
transfer
==
spi_bitbang_transfer
&&
!
bitbang
->
setup_transfer
)
return
-
EINVAL
;
/* this task is the only thing to touch the SPI bits */
bitbang
->
busy
=
0
;
bitbang
->
workqueue
=
create_singlethread_workqueue
(
dev_name
(
master
->
dev
.
parent
));
if
(
bitbang
->
workqueue
==
NULL
)
{
status
=
-
EBUSY
;
goto
err1
;
}
/* driver may get busy before register() returns, especially
* if someone registered boardinfo for devices
*/
status
=
spi_register_master
(
master
);
if
(
status
<
0
)
goto
err2
;
return
status
;
err2:
destroy_workqueue
(
bitbang
->
workqueue
);
err1:
return
status
;
return
spi_register_master
(
master
);
}
EXPORT_SYMBOL_GPL
(
spi_bitbang_start
);
...
...
@@ -490,10 +460,6 @@ int spi_bitbang_stop(struct spi_bitbang *bitbang)
{
spi_unregister_master
(
bitbang
->
master
);
WARN_ON
(
!
list_empty
(
&
bitbang
->
queue
));
destroy_workqueue
(
bitbang
->
workqueue
);
return
0
;
}
EXPORT_SYMBOL_GPL
(
spi_bitbang_stop
);
...
...
drivers/spi/spi-nuc900.c
浏览文件 @
b29bc3df
...
...
@@ -174,17 +174,6 @@ static void nuc900_spi_gobusy(struct nuc900_spi *hw)
spin_unlock_irqrestore
(
&
hw
->
lock
,
flags
);
}
static
int
nuc900_spi_setupxfer
(
struct
spi_device
*
spi
,
struct
spi_transfer
*
t
)
{
return
0
;
}
static
int
nuc900_spi_setup
(
struct
spi_device
*
spi
)
{
return
0
;
}
static
inline
unsigned
int
hw_txbyte
(
struct
nuc900_spi
*
hw
,
int
count
)
{
return
hw
->
tx
?
hw
->
tx
[
count
]
:
0
;
...
...
@@ -377,10 +366,8 @@ static int nuc900_spi_probe(struct platform_device *pdev)
master
->
num_chipselect
=
hw
->
pdata
->
num_cs
;
master
->
bus_num
=
hw
->
pdata
->
bus_num
;
hw
->
bitbang
.
master
=
hw
->
master
;
hw
->
bitbang
.
setup_transfer
=
nuc900_spi_setupxfer
;
hw
->
bitbang
.
chipselect
=
nuc900_spi_chipsel
;
hw
->
bitbang
.
txrx_bufs
=
nuc900_spi_txrx
;
hw
->
bitbang
.
master
->
setup
=
nuc900_spi_setup
;
hw
->
res
=
platform_get_resource
(
pdev
,
IORESOURCE_MEM
,
0
);
if
(
hw
->
res
==
NULL
)
{
...
...
drivers/spi/spi-xilinx.c
浏览文件 @
b29bc3df
...
...
@@ -233,21 +233,6 @@ static int xilinx_spi_setup_transfer(struct spi_device *spi,
return
0
;
}
static
int
xilinx_spi_setup
(
struct
spi_device
*
spi
)
{
/* always return 0, we can not check the number of bits.
* There are cases when SPI setup is called before any driver is
* there, in that case the SPI core defaults to 8 bits, which we
* do not support in some cases. But if we return an error, the
* SPI device would not be registered and no driver can get hold of it
* When the driver is there, it will call SPI setup again with the
* correct number of bits per transfer.
* If a driver setups with the wrong bit number, it will fail when
* it tries to do a transfer
*/
return
0
;
}
static
void
xilinx_spi_fill_tx_fifo
(
struct
xilinx_spi
*
xspi
)
{
u8
sr
;
...
...
@@ -375,7 +360,6 @@ struct spi_master *xilinx_spi_init(struct device *dev, struct resource *mem,
xspi
->
bitbang
.
chipselect
=
xilinx_spi_chipselect
;
xspi
->
bitbang
.
setup_transfer
=
xilinx_spi_setup_transfer
;
xspi
->
bitbang
.
txrx_bufs
=
xilinx_spi_txrx_bufs
;
xspi
->
bitbang
.
master
->
setup
=
xilinx_spi_setup
;
init_completion
(
&
xspi
->
done
);
if
(
!
request_mem_region
(
mem
->
start
,
resource_size
(
mem
),
...
...
include/linux/spi/spi_bitbang.h
浏览文件 @
b29bc3df
...
...
@@ -4,11 +4,7 @@
#include <linux/workqueue.h>
struct
spi_bitbang
{
struct
workqueue_struct
*
workqueue
;
struct
work_struct
work
;
spinlock_t
lock
;
struct
list_head
queue
;
u8
busy
;
u8
use_dma
;
u8
flags
;
/* extra spi->mode support */
...
...
@@ -41,7 +37,6 @@ struct spi_bitbang {
*/
extern
int
spi_bitbang_setup
(
struct
spi_device
*
spi
);
extern
void
spi_bitbang_cleanup
(
struct
spi_device
*
spi
);
extern
int
spi_bitbang_transfer
(
struct
spi_device
*
spi
,
struct
spi_message
*
m
);
extern
int
spi_bitbang_setup_transfer
(
struct
spi_device
*
spi
,
struct
spi_transfer
*
t
);
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录