Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
openeuler
raspberrypi-kernel
提交
bc266185
R
raspberrypi-kernel
项目概览
openeuler
/
raspberrypi-kernel
通知
13
Star
1
Fork
0
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
0
列表
看板
标记
里程碑
合并请求
0
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
R
raspberrypi-kernel
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
0
Issue
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
提交
Issue看板
提交
bc266185
编写于
1月 30, 2012
作者:
G
Grant Likely
浏览文件
操作
浏览文件
下载
差异文件
Merge branch 'spi/s3c64xx' of
git://git.kernel.org/pub/scm/linux/kernel/git/broonie/misc
Conflicts: drivers/spi/spi-s3c64xx.c
上级
dcd6c922
b97b6621
变更
1
隐藏空白更改
内联
并排
Showing
1 changed file
with
103 addition
and
11 deletion
+103
-11
drivers/spi/spi-s3c64xx.c
drivers/spi/spi-s3c64xx.c
+103
-11
未找到文件。
drivers/spi/spi-s3c64xx.c
浏览文件 @
bc266185
...
...
@@ -20,10 +20,12 @@
#include <linux/init.h>
#include <linux/module.h>
#include <linux/workqueue.h>
#include <linux/interrupt.h>
#include <linux/delay.h>
#include <linux/clk.h>
#include <linux/dma-mapping.h>
#include <linux/platform_device.h>
#include <linux/pm_runtime.h>
#include <linux/spi/spi.h>
#include <mach/dma.h>
...
...
@@ -153,6 +155,7 @@ struct s3c64xx_spi_dma_data {
* @tx_dmach: Controller's DMA channel for Tx.
* @sfr_start: BUS address of SPI controller regs.
* @regs: Pointer to ioremap'ed controller registers.
* @irq: interrupt
* @xfer_completion: To indicate completion of xfer task.
* @cur_mode: Stores the active configuration of the controller.
* @cur_bpw: Stores the active bits per word settings.
...
...
@@ -780,6 +783,8 @@ static void s3c64xx_spi_work(struct work_struct *work)
while
(
!
acquire_dma
(
sdd
))
msleep
(
10
);
pm_runtime_get_sync
(
&
sdd
->
pdev
->
dev
);
spin_lock_irqsave
(
&
sdd
->
lock
,
flags
);
while
(
!
list_empty
(
&
sdd
->
queue
)
...
...
@@ -808,6 +813,8 @@ static void s3c64xx_spi_work(struct work_struct *work)
/* Free DMA channels */
sdd
->
ops
->
release
(
sdd
->
rx_dma
.
ch
,
&
s3c64xx_spi_dma_client
);
sdd
->
ops
->
release
(
sdd
->
tx_dma
.
ch
,
&
s3c64xx_spi_dma_client
);
pm_runtime_put
(
&
sdd
->
pdev
->
dev
);
}
static
int
s3c64xx_spi_transfer
(
struct
spi_device
*
spi
,
...
...
@@ -890,6 +897,8 @@ static int s3c64xx_spi_setup(struct spi_device *spi)
goto
setup_exit
;
}
pm_runtime_get_sync
(
&
sdd
->
pdev
->
dev
);
/* Check if we can provide the requested rate */
if
(
!
sci
->
clk_from_cmu
)
{
u32
psr
,
speed
;
...
...
@@ -922,6 +931,8 @@ static int s3c64xx_spi_setup(struct spi_device *spi)
err
=
-
EINVAL
;
}
pm_runtime_put
(
&
sdd
->
pdev
->
dev
);
setup_exit:
/* setup() returns with device de-selected */
...
...
@@ -930,6 +941,33 @@ static int s3c64xx_spi_setup(struct spi_device *spi)
return
err
;
}
static
irqreturn_t
s3c64xx_spi_irq
(
int
irq
,
void
*
data
)
{
struct
s3c64xx_spi_driver_data
*
sdd
=
data
;
struct
spi_master
*
spi
=
sdd
->
master
;
unsigned
int
val
;
val
=
readl
(
sdd
->
regs
+
S3C64XX_SPI_PENDING_CLR
);
val
&=
S3C64XX_SPI_PND_RX_OVERRUN_CLR
|
S3C64XX_SPI_PND_RX_UNDERRUN_CLR
|
S3C64XX_SPI_PND_TX_OVERRUN_CLR
|
S3C64XX_SPI_PND_TX_UNDERRUN_CLR
;
writel
(
val
,
sdd
->
regs
+
S3C64XX_SPI_PENDING_CLR
);
if
(
val
&
S3C64XX_SPI_PND_RX_OVERRUN_CLR
)
dev_err
(
&
spi
->
dev
,
"RX overrun
\n
"
);
if
(
val
&
S3C64XX_SPI_PND_RX_UNDERRUN_CLR
)
dev_err
(
&
spi
->
dev
,
"RX underrun
\n
"
);
if
(
val
&
S3C64XX_SPI_PND_TX_OVERRUN_CLR
)
dev_err
(
&
spi
->
dev
,
"TX overrun
\n
"
);
if
(
val
&
S3C64XX_SPI_PND_TX_UNDERRUN_CLR
)
dev_err
(
&
spi
->
dev
,
"TX underrun
\n
"
);
return
IRQ_HANDLED
;
}
static
void
s3c64xx_spi_hwinit
(
struct
s3c64xx_spi_driver_data
*
sdd
,
int
channel
)
{
struct
s3c64xx_spi_info
*
sci
=
sdd
->
cntrlr_info
;
...
...
@@ -970,7 +1008,7 @@ static int __init s3c64xx_spi_probe(struct platform_device *pdev)
struct
s3c64xx_spi_driver_data
*
sdd
;
struct
s3c64xx_spi_info
*
sci
;
struct
spi_master
*
master
;
int
ret
;
int
ret
,
irq
;
char
clk_name
[
16
];
if
(
pdev
->
id
<
0
)
{
...
...
@@ -1006,6 +1044,12 @@ static int __init s3c64xx_spi_probe(struct platform_device *pdev)
return
-
ENXIO
;
}
irq
=
platform_get_irq
(
pdev
,
0
);
if
(
irq
<
0
)
{
dev_warn
(
&
pdev
->
dev
,
"Failed to get IRQ: %d
\n
"
,
irq
);
return
irq
;
}
master
=
spi_alloc_master
(
&
pdev
->
dev
,
sizeof
(
struct
s3c64xx_spi_driver_data
));
if
(
master
==
NULL
)
{
...
...
@@ -1100,10 +1144,21 @@ static int __init s3c64xx_spi_probe(struct platform_device *pdev)
INIT_WORK
(
&
sdd
->
work
,
s3c64xx_spi_work
);
INIT_LIST_HEAD
(
&
sdd
->
queue
);
ret
=
request_irq
(
irq
,
s3c64xx_spi_irq
,
0
,
"spi-s3c64xx"
,
sdd
);
if
(
ret
!=
0
)
{
dev_err
(
&
pdev
->
dev
,
"Failed to request IRQ %d: %d
\n
"
,
irq
,
ret
);
goto
err8
;
}
writel
(
S3C64XX_SPI_INT_RX_OVERRUN_EN
|
S3C64XX_SPI_INT_RX_UNDERRUN_EN
|
S3C64XX_SPI_INT_TX_OVERRUN_EN
|
S3C64XX_SPI_INT_TX_UNDERRUN_EN
,
sdd
->
regs
+
S3C64XX_SPI_INT_EN
);
if
(
spi_register_master
(
master
))
{
dev_err
(
&
pdev
->
dev
,
"cannot register SPI master
\n
"
);
ret
=
-
EBUSY
;
goto
err
8
;
goto
err
9
;
}
dev_dbg
(
&
pdev
->
dev
,
"Samsung SoC SPI Driver loaded for Bus SPI-%d "
...
...
@@ -1113,8 +1168,12 @@ static int __init s3c64xx_spi_probe(struct platform_device *pdev)
mem_res
->
end
,
mem_res
->
start
,
sdd
->
rx_dma
.
dmach
,
sdd
->
tx_dma
.
dmach
);
pm_runtime_enable
(
&
pdev
->
dev
);
return
0
;
err9:
free_irq
(
irq
,
sdd
);
err8:
destroy_workqueue
(
sdd
->
workqueue
);
err7:
...
...
@@ -1144,6 +1203,8 @@ static int s3c64xx_spi_remove(struct platform_device *pdev)
struct
resource
*
mem_res
;
unsigned
long
flags
;
pm_runtime_disable
(
&
pdev
->
dev
);
spin_lock_irqsave
(
&
sdd
->
lock
,
flags
);
sdd
->
state
|=
SUSPND
;
spin_unlock_irqrestore
(
&
sdd
->
lock
,
flags
);
...
...
@@ -1153,6 +1214,10 @@ static int s3c64xx_spi_remove(struct platform_device *pdev)
spi_unregister_master
(
master
);
writel
(
0
,
sdd
->
regs
+
S3C64XX_SPI_INT_EN
);
free_irq
(
platform_get_irq
(
pdev
,
0
),
sdd
);
destroy_workqueue
(
sdd
->
workqueue
);
clk_disable
(
sdd
->
src_clk
);
...
...
@@ -1174,9 +1239,9 @@ static int s3c64xx_spi_remove(struct platform_device *pdev)
}
#ifdef CONFIG_PM
static
int
s3c64xx_spi_suspend
(
struct
platform_device
*
pdev
,
pm_message_t
state
)
static
int
s3c64xx_spi_suspend
(
struct
device
*
dev
)
{
struct
spi_master
*
master
=
spi_master_get
(
platform_get_drvdata
(
p
dev
));
struct
spi_master
*
master
=
spi_master_get
(
dev_get_drvdata
(
dev
));
struct
s3c64xx_spi_driver_data
*
sdd
=
spi_master_get_devdata
(
master
);
unsigned
long
flags
;
...
...
@@ -1196,9 +1261,10 @@ static int s3c64xx_spi_suspend(struct platform_device *pdev, pm_message_t state)
return
0
;
}
static
int
s3c64xx_spi_resume
(
struct
platform_device
*
p
dev
)
static
int
s3c64xx_spi_resume
(
struct
device
*
dev
)
{
struct
spi_master
*
master
=
spi_master_get
(
platform_get_drvdata
(
pdev
));
struct
platform_device
*
pdev
=
to_platform_device
(
dev
);
struct
spi_master
*
master
=
spi_master_get
(
dev_get_drvdata
(
dev
));
struct
s3c64xx_spi_driver_data
*
sdd
=
spi_master_get_devdata
(
master
);
struct
s3c64xx_spi_info
*
sci
=
sdd
->
cntrlr_info
;
unsigned
long
flags
;
...
...
@@ -1217,19 +1283,45 @@ static int s3c64xx_spi_resume(struct platform_device *pdev)
return
0
;
}
#else
#define s3c64xx_spi_suspend NULL
#define s3c64xx_spi_resume NULL
#endif
/* CONFIG_PM */
#ifdef CONFIG_PM_RUNTIME
static
int
s3c64xx_spi_runtime_suspend
(
struct
device
*
dev
)
{
struct
spi_master
*
master
=
spi_master_get
(
dev_get_drvdata
(
dev
));
struct
s3c64xx_spi_driver_data
*
sdd
=
spi_master_get_devdata
(
master
);
clk_disable
(
sdd
->
clk
);
clk_disable
(
sdd
->
src_clk
);
return
0
;
}
static
int
s3c64xx_spi_runtime_resume
(
struct
device
*
dev
)
{
struct
spi_master
*
master
=
spi_master_get
(
dev_get_drvdata
(
dev
));
struct
s3c64xx_spi_driver_data
*
sdd
=
spi_master_get_devdata
(
master
);
clk_enable
(
sdd
->
src_clk
);
clk_enable
(
sdd
->
clk
);
return
0
;
}
#endif
/* CONFIG_PM_RUNTIME */
static
const
struct
dev_pm_ops
s3c64xx_spi_pm
=
{
SET_SYSTEM_SLEEP_PM_OPS
(
s3c64xx_spi_suspend
,
s3c64xx_spi_resume
)
SET_RUNTIME_PM_OPS
(
s3c64xx_spi_runtime_suspend
,
s3c64xx_spi_runtime_resume
,
NULL
)
};
static
struct
platform_driver
s3c64xx_spi_driver
=
{
.
driver
=
{
.
name
=
"s3c64xx-spi"
,
.
owner
=
THIS_MODULE
,
.
pm
=
&
s3c64xx_spi_pm
,
},
.
remove
=
s3c64xx_spi_remove
,
.
suspend
=
s3c64xx_spi_suspend
,
.
resume
=
s3c64xx_spi_resume
,
};
MODULE_ALIAS
(
"platform:s3c64xx-spi"
);
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录