Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
openeuler
Kernel
提交
75c971dd
K
Kernel
项目概览
openeuler
/
Kernel
大约 2 年 前同步成功
通知
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看板
未验证
提交
75c971dd
编写于
8月 15, 2022
作者:
M
Mark Brown
浏览文件
操作
浏览文件
下载
差异文件
Merge remote-tracking branch 'spi/for-5.20' into spi-6.0
上级
568035b0
2fd92c7b
变更
6
隐藏空白更改
内联
并排
Showing
6 changed file
with
112 addition
and
39 deletion
+112
-39
Documentation/devicetree/bindings/spi/cdns,qspi-nor-peripheral-props.yaml
...vicetree/bindings/spi/cdns,qspi-nor-peripheral-props.yaml
+1
-1
Documentation/devicetree/bindings/spi/cdns,qspi-nor.yaml
Documentation/devicetree/bindings/spi/cdns,qspi-nor.yaml
+1
-1
Documentation/devicetree/bindings/spi/spi-peripheral-props.yaml
...ntation/devicetree/bindings/spi/spi-peripheral-props.yaml
+1
-1
MAINTAINERS
MAINTAINERS
+1
-1
drivers/spi/spi-meson-spicc.c
drivers/spi/spi-meson-spicc.c
+101
-28
drivers/spi/spi.c
drivers/spi/spi.c
+7
-7
未找到文件。
Documentation/devicetree/bindings/spi/cdns,qspi-nor-peripheral-props.yaml
浏览文件 @
75c971dd
...
...
@@ -10,7 +10,7 @@ description:
See spi-peripheral-props.yaml for more info.
maintainers
:
-
Pratyush Yadav <p.yadav
@ti.com>
-
Vaishnav Achath <vaishnav.a
@ti.com>
properties
:
# cdns,qspi-nor.yaml
...
...
Documentation/devicetree/bindings/spi/cdns,qspi-nor.yaml
浏览文件 @
75c971dd
...
...
@@ -7,7 +7,7 @@ $schema: http://devicetree.org/meta-schemas/core.yaml#
title
:
Cadence Quad SPI controller
maintainers
:
-
Pratyush Yadav <p.yadav
@ti.com>
-
Vaishnav Achath <vaishnav.a
@ti.com>
allOf
:
-
$ref
:
spi-controller.yaml#
...
...
Documentation/devicetree/bindings/spi/spi-peripheral-props.yaml
浏览文件 @
75c971dd
...
...
@@ -16,7 +16,7 @@ description:
their own separate schema that should be referenced from here.
maintainers
:
-
Pratyush Yadav <p.yadav@ti.com
>
-
Mark Brown <broonie@kernel.org
>
properties
:
reg
:
...
...
MAINTAINERS
浏览文件 @
75c971dd
...
...
@@ -2178,7 +2178,7 @@ M: Jean-Marie Verdun <verdun@hpe.com>
M: Nick Hawkins <nick.hawkins@hpe.com>
S: Maintained
F: Documentation/devicetree/bindings/arm/hpe,gxp.yaml
F: Documentation/devicetree/bindings/spi/hpe,gxp-spi.yaml
F: Documentation/devicetree/bindings/spi/hpe,gxp-spi
fi
.yaml
F: Documentation/devicetree/bindings/timer/hpe,gxp-timer.yaml
F: arch/arm/boot/dts/hpe-bmc*
F: arch/arm/boot/dts/hpe-gxp*
...
...
drivers/spi/spi-meson-spicc.c
浏览文件 @
75c971dd
...
...
@@ -156,6 +156,7 @@ struct meson_spicc_device {
void
__iomem
*
base
;
struct
clk
*
core
;
struct
clk
*
pclk
;
struct
clk_divider
pow2_div
;
struct
clk
*
clk
;
struct
spi_message
*
message
;
struct
spi_transfer
*
xfer
;
...
...
@@ -168,6 +169,8 @@ struct meson_spicc_device {
unsigned
long
xfer_remain
;
};
#define pow2_clk_to_spicc(_div) container_of(_div, struct meson_spicc_device, pow2_div)
static
void
meson_spicc_oen_enable
(
struct
meson_spicc_device
*
spicc
)
{
u32
conf
;
...
...
@@ -421,7 +424,7 @@ static int meson_spicc_prepare_message(struct spi_master *master,
{
struct
meson_spicc_device
*
spicc
=
spi_master_get_devdata
(
master
);
struct
spi_device
*
spi
=
message
->
spi
;
u32
conf
=
0
;
u32
conf
=
readl_relaxed
(
spicc
->
base
+
SPICC_CONREG
)
&
SPICC_DATARATE_MASK
;
/* Store current message */
spicc
->
message
=
message
;
...
...
@@ -458,8 +461,6 @@ static int meson_spicc_prepare_message(struct spi_master *master,
/* Select CS */
conf
|=
FIELD_PREP
(
SPICC_CS_MASK
,
spi
->
chip_select
);
/* Default Clock rate core/4 */
/* Default 8bit word */
conf
|=
FIELD_PREP
(
SPICC_BITLENGTH_MASK
,
8
-
1
);
...
...
@@ -476,12 +477,16 @@ static int meson_spicc_prepare_message(struct spi_master *master,
static
int
meson_spicc_unprepare_transfer
(
struct
spi_master
*
master
)
{
struct
meson_spicc_device
*
spicc
=
spi_master_get_devdata
(
master
);
u32
conf
=
readl_relaxed
(
spicc
->
base
+
SPICC_CONREG
)
&
SPICC_DATARATE_MASK
;
/* Disable all IRQs */
writel
(
0
,
spicc
->
base
+
SPICC_INTREG
);
device_reset_optional
(
&
spicc
->
pdev
->
dev
);
/* Set default configuration, keeping datarate field */
writel_relaxed
(
conf
,
spicc
->
base
+
SPICC_CONREG
);
return
0
;
}
...
...
@@ -518,14 +523,60 @@ static void meson_spicc_cleanup(struct spi_device *spi)
* Clk path for G12A series:
* pclk -> pow2 fixed div -> pow2 div -> mux -> out
* pclk -> enh fixed div -> enh div -> mux -> out
*
* The pow2 divider is tied to the controller HW state, and the
* divider is only valid when the controller is initialized.
*
* A set of clock ops is added to make sure we don't read/set this
* clock rate while the controller is in an unknown state.
*/
static
int
meson_spicc_clk_init
(
struct
meson_spicc_device
*
spicc
)
static
unsigned
long
meson_spicc_pow2_recalc_rate
(
struct
clk_hw
*
hw
,
unsigned
long
parent_rate
)
{
struct
clk_divider
*
divider
=
to_clk_divider
(
hw
);
struct
meson_spicc_device
*
spicc
=
pow2_clk_to_spicc
(
divider
);
if
(
!
spicc
->
master
->
cur_msg
||
!
spicc
->
master
->
busy
)
return
0
;
return
clk_divider_ops
.
recalc_rate
(
hw
,
parent_rate
);
}
static
int
meson_spicc_pow2_determine_rate
(
struct
clk_hw
*
hw
,
struct
clk_rate_request
*
req
)
{
struct
clk_divider
*
divider
=
to_clk_divider
(
hw
);
struct
meson_spicc_device
*
spicc
=
pow2_clk_to_spicc
(
divider
);
if
(
!
spicc
->
master
->
cur_msg
||
!
spicc
->
master
->
busy
)
return
-
EINVAL
;
return
clk_divider_ops
.
determine_rate
(
hw
,
req
);
}
static
int
meson_spicc_pow2_set_rate
(
struct
clk_hw
*
hw
,
unsigned
long
rate
,
unsigned
long
parent_rate
)
{
struct
clk_divider
*
divider
=
to_clk_divider
(
hw
);
struct
meson_spicc_device
*
spicc
=
pow2_clk_to_spicc
(
divider
);
if
(
!
spicc
->
master
->
cur_msg
||
!
spicc
->
master
->
busy
)
return
-
EINVAL
;
return
clk_divider_ops
.
set_rate
(
hw
,
rate
,
parent_rate
);
}
const
struct
clk_ops
meson_spicc_pow2_clk_ops
=
{
.
recalc_rate
=
meson_spicc_pow2_recalc_rate
,
.
determine_rate
=
meson_spicc_pow2_determine_rate
,
.
set_rate
=
meson_spicc_pow2_set_rate
,
};
static
int
meson_spicc_pow2_clk_init
(
struct
meson_spicc_device
*
spicc
)
{
struct
device
*
dev
=
&
spicc
->
pdev
->
dev
;
struct
clk_fixed_factor
*
pow2_fixed_div
,
*
enh_fixed_div
;
struct
clk_divider
*
pow2_div
,
*
enh_div
;
struct
clk_mux
*
mux
;
struct
clk_fixed_factor
*
pow2_fixed_div
;
struct
clk_init_data
init
;
struct
clk
*
clk
;
struct
clk_parent_data
parent_data
[
2
];
...
...
@@ -560,31 +611,45 @@ static int meson_spicc_clk_init(struct meson_spicc_device *spicc)
if
(
WARN_ON
(
IS_ERR
(
clk
)))
return
PTR_ERR
(
clk
);
pow2_div
=
devm_kzalloc
(
dev
,
sizeof
(
*
pow2_div
),
GFP_KERNEL
);
if
(
!
pow2_div
)
return
-
ENOMEM
;
snprintf
(
name
,
sizeof
(
name
),
"%s#pow2_div"
,
dev_name
(
dev
));
init
.
name
=
name
;
init
.
ops
=
&
clk_divider_ops
;
init
.
flags
=
CLK_SET_RATE_PARENT
;
init
.
ops
=
&
meson_spicc_pow2_clk_ops
;
/*
* Set NOCACHE here to make sure we read the actual HW value
* since we reset the HW after each transfer.
*/
init
.
flags
=
CLK_SET_RATE_PARENT
|
CLK_GET_RATE_NOCACHE
;
parent_data
[
0
].
hw
=
&
pow2_fixed_div
->
hw
;
init
.
num_parents
=
1
;
pow2_div
->
shift
=
16
,
pow2_div
->
width
=
3
,
pow2_div
->
flags
=
CLK_DIVIDER_POWER_OF_TWO
,
pow2_div
->
reg
=
spicc
->
base
+
SPICC_CONREG
;
pow2_div
->
hw
.
init
=
&
init
;
spicc
->
pow2_div
.
shift
=
16
,
spicc
->
pow2_div
.
width
=
3
,
spicc
->
pow2_div
.
flags
=
CLK_DIVIDER_POWER_OF_TWO
,
spicc
->
pow2_div
.
reg
=
spicc
->
base
+
SPICC_CONREG
;
spicc
->
pow2_div
.
hw
.
init
=
&
init
;
clk
=
devm_clk_register
(
dev
,
&
pow2_div
->
hw
);
if
(
WARN_ON
(
IS_ERR
(
clk
)))
return
PTR_ERR
(
clk
);
spicc
->
clk
=
devm_clk_register
(
dev
,
&
spicc
->
pow2_div
.
hw
);
if
(
WARN_ON
(
IS_ERR
(
spicc
->
clk
)))
return
PTR_ERR
(
spicc
->
clk
);
if
(
!
spicc
->
data
->
has_enhance_clk_div
)
{
spicc
->
clk
=
clk
;
return
0
;
}
return
0
;
}
static
int
meson_spicc_enh_clk_init
(
struct
meson_spicc_device
*
spicc
)
{
struct
device
*
dev
=
&
spicc
->
pdev
->
dev
;
struct
clk_fixed_factor
*
enh_fixed_div
;
struct
clk_divider
*
enh_div
;
struct
clk_mux
*
mux
;
struct
clk_init_data
init
;
struct
clk
*
clk
;
struct
clk_parent_data
parent_data
[
2
];
char
name
[
64
];
memset
(
&
init
,
0
,
sizeof
(
init
));
memset
(
&
parent_data
,
0
,
sizeof
(
parent_data
));
init
.
parent_data
=
parent_data
;
/* algorithm for enh div: rate = freq / 2 / (N + 1) */
...
...
@@ -637,7 +702,7 @@ static int meson_spicc_clk_init(struct meson_spicc_device *spicc)
snprintf
(
name
,
sizeof
(
name
),
"%s#sel"
,
dev_name
(
dev
));
init
.
name
=
name
;
init
.
ops
=
&
clk_mux_ops
;
parent_data
[
0
].
hw
=
&
pow2_div
->
hw
;
parent_data
[
0
].
hw
=
&
spicc
->
pow2_div
.
hw
;
parent_data
[
1
].
hw
=
&
enh_div
->
hw
;
init
.
num_parents
=
2
;
init
.
flags
=
CLK_SET_RATE_PARENT
;
...
...
@@ -754,12 +819,20 @@ static int meson_spicc_probe(struct platform_device *pdev)
meson_spicc_oen_enable
(
spicc
);
ret
=
meson_spicc_clk_init
(
spicc
);
ret
=
meson_spicc_
pow2_
clk_init
(
spicc
);
if
(
ret
)
{
dev_err
(
&
pdev
->
dev
,
"clock registration failed
\n
"
);
dev_err
(
&
pdev
->
dev
,
"
pow2
clock registration failed
\n
"
);
goto
out_clk
;
}
if
(
spicc
->
data
->
has_enhance_clk_div
)
{
ret
=
meson_spicc_enh_clk_init
(
spicc
);
if
(
ret
)
{
dev_err
(
&
pdev
->
dev
,
"clock registration failed
\n
"
);
goto
out_clk
;
}
}
ret
=
devm_spi_register_master
(
&
pdev
->
dev
,
master
);
if
(
ret
)
{
dev_err
(
&
pdev
->
dev
,
"spi master registration failed
\n
"
);
...
...
drivers/spi/spi.c
浏览文件 @
75c971dd
...
...
@@ -95,7 +95,7 @@ static ssize_t driver_override_show(struct device *dev,
}
static
DEVICE_ATTR_RW
(
driver_override
);
static
struct
spi_statistics
*
spi_alloc_pcpu_stats
(
struct
device
*
dev
)
static
struct
spi_statistics
__percpu
*
spi_alloc_pcpu_stats
(
struct
device
*
dev
)
{
struct
spi_statistics
__percpu
*
pcpu_stats
;
...
...
@@ -162,7 +162,7 @@ static struct device_attribute dev_attr_spi_device_##field = { \
}
#define SPI_STATISTICS_SHOW_NAME(name, file, field) \
static ssize_t spi_statistics_##name##_show(struct spi_statistics *stat, \
static ssize_t spi_statistics_##name##_show(struct spi_statistics
__percpu
*stat, \
char *buf) \
{ \
ssize_t len; \
...
...
@@ -309,7 +309,7 @@ static const struct attribute_group *spi_master_groups[] = {
NULL
,
};
static
void
spi_statistics_add_transfer_stats
(
struct
spi_statistics
*
pcpu_stats
,
static
void
spi_statistics_add_transfer_stats
(
struct
spi_statistics
__percpu
*
pcpu_stats
,
struct
spi_transfer
*
xfer
,
struct
spi_controller
*
ctlr
)
{
...
...
@@ -1275,8 +1275,8 @@ static int spi_transfer_wait(struct spi_controller *ctlr,
struct
spi_message
*
msg
,
struct
spi_transfer
*
xfer
)
{
struct
spi_statistics
*
statm
=
ctlr
->
pcpu_statistics
;
struct
spi_statistics
*
stats
=
msg
->
spi
->
pcpu_statistics
;
struct
spi_statistics
__percpu
*
statm
=
ctlr
->
pcpu_statistics
;
struct
spi_statistics
__percpu
*
stats
=
msg
->
spi
->
pcpu_statistics
;
u32
speed_hz
=
xfer
->
speed_hz
;
unsigned
long
long
ms
;
...
...
@@ -1432,8 +1432,8 @@ static int spi_transfer_one_message(struct spi_controller *ctlr,
struct
spi_transfer
*
xfer
;
bool
keep_cs
=
false
;
int
ret
=
0
;
struct
spi_statistics
*
statm
=
ctlr
->
pcpu_statistics
;
struct
spi_statistics
*
stats
=
msg
->
spi
->
pcpu_statistics
;
struct
spi_statistics
__percpu
*
statm
=
ctlr
->
pcpu_statistics
;
struct
spi_statistics
__percpu
*
stats
=
msg
->
spi
->
pcpu_statistics
;
spi_set_cs
(
msg
->
spi
,
true
,
false
);
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录