Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
L
linux
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
Analytics
Analytics
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Commits
Issue Boards
Open sidebar
nexedi
linux
Commits
1973d5b7
Commit
1973d5b7
authored
Aug 17, 2020
by
Mark Brown
Browse files
Options
Browse Files
Download
Plain Diff
Merge existing fixes from spi/for-5.9
parents
9123e3a7
8cb61d65
Changes
4
Hide whitespace changes
Inline
Side-by-side
Showing
4 changed files
with
86 additions
and
39 deletions
+86
-39
Documentation/devicetree/bindings/spi/spi-fsl-lpspi.yaml
Documentation/devicetree/bindings/spi/spi-fsl-lpspi.yaml
+1
-0
drivers/spi/Kconfig
drivers/spi/Kconfig
+3
-0
drivers/spi/spi-stm32.c
drivers/spi/spi-stm32.c
+62
-38
drivers/spi/spi.c
drivers/spi/spi.c
+20
-1
No files found.
Documentation/devicetree/bindings/spi/spi-fsl-lpspi.yaml
View file @
1973d5b7
...
...
@@ -39,6 +39,7 @@ properties:
spi common code does not support use of CS signals discontinuously.
i.MX8DXL-EVK board only uses CS1 without using CS0. Therefore, add
this property to re-config the chipselect value in the LPSPI driver.
type
:
boolean
required
:
-
compatible
...
...
drivers/spi/Kconfig
View file @
1973d5b7
...
...
@@ -1017,4 +1017,7 @@ config SPI_SLAVE_SYSTEM_CONTROL
endif # SPI_SLAVE
config SPI_DYNAMIC
def_bool ACPI || OF_DYNAMIC || SPI_SLAVE
endif # SPI
drivers/spi/spi-stm32.c
View file @
1973d5b7
...
...
@@ -13,6 +13,7 @@
#include <linux/iopoll.h>
#include <linux/module.h>
#include <linux/of_platform.h>
#include <linux/pinctrl/consumer.h>
#include <linux/pm_runtime.h>
#include <linux/reset.h>
#include <linux/spi/spi.h>
...
...
@@ -441,7 +442,8 @@ static int stm32_spi_prepare_mbr(struct stm32_spi *spi, u32 speed_hz,
{
u32
div
,
mbrdiv
;
div
=
DIV_ROUND_UP
(
spi
->
clk_rate
,
speed_hz
);
/* Ensure spi->clk_rate is even */
div
=
DIV_ROUND_UP
(
spi
->
clk_rate
&
~
0x1
,
speed_hz
);
/*
* SPI framework set xfer->speed_hz to master->max_speed_hz if
...
...
@@ -467,20 +469,27 @@ static int stm32_spi_prepare_mbr(struct stm32_spi *spi, u32 speed_hz,
/**
* stm32h7_spi_prepare_fthlv - Determine FIFO threshold level
* @spi: pointer to the spi controller data structure
* @xfer_len: length of the message to be transferred
*/
static
u32
stm32h7_spi_prepare_fthlv
(
struct
stm32_spi
*
spi
)
static
u32
stm32h7_spi_prepare_fthlv
(
struct
stm32_spi
*
spi
,
u32
xfer_len
)
{
u32
fthlv
,
half_fifo
;
u32
fthlv
,
half_fifo
,
packet
;
/* data packet should not exceed 1/2 of fifo space */
half_fifo
=
(
spi
->
fifo_size
/
2
);
/* data_packet should not exceed transfer length */
if
(
half_fifo
>
xfer_len
)
packet
=
xfer_len
;
else
packet
=
half_fifo
;
if
(
spi
->
cur_bpw
<=
8
)
fthlv
=
half_fifo
;
fthlv
=
packet
;
else
if
(
spi
->
cur_bpw
<=
16
)
fthlv
=
half_fifo
/
2
;
fthlv
=
packet
/
2
;
else
fthlv
=
half_fifo
/
4
;
fthlv
=
packet
/
4
;
/* align packet size with data registers access */
if
(
spi
->
cur_bpw
>
8
)
...
...
@@ -488,6 +497,9 @@ static u32 stm32h7_spi_prepare_fthlv(struct stm32_spi *spi)
else
fthlv
-=
(
fthlv
%
4
);
/* multiple of 4 */
if
(
!
fthlv
)
fthlv
=
1
;
return
fthlv
;
}
...
...
@@ -966,13 +978,13 @@ static irqreturn_t stm32h7_spi_irq_thread(int irq, void *dev_id)
if
(
!
spi
->
cur_usedma
&&
(
spi
->
rx_buf
&&
(
spi
->
rx_len
>
0
)))
stm32h7_spi_read_rxfifo
(
spi
,
false
);
writel_relaxed
(
mask
,
spi
->
base
+
STM32H7_SPI_IFCR
);
writel_relaxed
(
sr
&
mask
,
spi
->
base
+
STM32H7_SPI_IFCR
);
spin_unlock_irqrestore
(
&
spi
->
lock
,
flags
);
if
(
end
)
{
spi_finalize_current_transfer
(
master
);
stm32h7_spi_disable
(
spi
);
spi_finalize_current_transfer
(
master
);
}
return
IRQ_HANDLED
;
...
...
@@ -1393,7 +1405,7 @@ static void stm32h7_spi_set_bpw(struct stm32_spi *spi)
cfg1_setb
|=
(
bpw
<<
STM32H7_SPI_CFG1_DSIZE_SHIFT
)
&
STM32H7_SPI_CFG1_DSIZE
;
spi
->
cur_fthlv
=
stm32h7_spi_prepare_fthlv
(
spi
);
spi
->
cur_fthlv
=
stm32h7_spi_prepare_fthlv
(
spi
,
spi
->
cur_xferlen
);
fthlv
=
spi
->
cur_fthlv
-
1
;
cfg1_clrb
|=
STM32H7_SPI_CFG1_FTHLV
;
...
...
@@ -1585,39 +1597,33 @@ static int stm32_spi_transfer_one_setup(struct stm32_spi *spi,
unsigned
long
flags
;
unsigned
int
comm_type
;
int
nb_words
,
ret
=
0
;
int
mbr
;
spin_lock_irqsave
(
&
spi
->
lock
,
flags
);
if
(
spi
->
cur_bpw
!=
transfer
->
bits_per_word
)
{
spi
->
cur_bpw
=
transfer
->
bits_per_word
;
spi
->
cfg
->
set_bpw
(
spi
);
}
if
(
spi
->
cur_speed
!=
transfer
->
speed_hz
)
{
int
mbr
;
spi
->
cur_xferlen
=
transfer
->
len
;
/* Update spi->cur_speed with real clock speed */
mbr
=
stm32_spi_prepare_mbr
(
spi
,
transfer
->
speed_hz
,
spi
->
cfg
->
baud_rate_div_min
,
spi
->
cfg
->
baud_rate_div_max
);
if
(
mbr
<
0
)
{
ret
=
mbr
;
goto
out
;
}
spi
->
cur_bpw
=
transfer
->
bits_per_word
;
spi
->
cfg
->
set_bpw
(
spi
);
transfer
->
speed_hz
=
spi
->
cur_speed
;
stm32_spi_set_mbr
(
spi
,
mbr
);
/* Update spi->cur_speed with real clock speed */
mbr
=
stm32_spi_prepare_mbr
(
spi
,
transfer
->
speed_hz
,
spi
->
cfg
->
baud_rate_div_min
,
spi
->
cfg
->
baud_rate_div_max
);
if
(
mbr
<
0
)
{
ret
=
mbr
;
goto
out
;
}
transfer
->
speed_hz
=
spi
->
cur_speed
;
stm32_spi_set_mbr
(
spi
,
mbr
);
comm_type
=
stm32_spi_communication_type
(
spi_dev
,
transfer
);
if
(
spi
->
cur_comm
!=
comm_type
)
{
ret
=
spi
->
cfg
->
set_mode
(
spi
,
comm_type
);
ret
=
spi
->
cfg
->
set_mode
(
spi
,
comm_type
);
if
(
ret
<
0
)
goto
out
;
if
(
ret
<
0
)
goto
out
;
spi
->
cur_comm
=
comm_type
;
}
spi
->
cur_comm
=
comm_type
;
if
(
spi
->
cfg
->
set_data_idleness
)
spi
->
cfg
->
set_data_idleness
(
spi
,
transfer
->
len
);
...
...
@@ -1635,8 +1641,6 @@ static int stm32_spi_transfer_one_setup(struct stm32_spi *spi,
goto
out
;
}
spi
->
cur_xferlen
=
transfer
->
len
;
dev_dbg
(
spi
->
dev
,
"transfer communication mode set to %d
\n
"
,
spi
->
cur_comm
);
dev_dbg
(
spi
->
dev
,
...
...
@@ -1996,6 +2000,8 @@ static int stm32_spi_remove(struct platform_device *pdev)
pm_runtime_disable
(
&
pdev
->
dev
);
pinctrl_pm_select_sleep_state
(
&
pdev
->
dev
);
return
0
;
}
...
...
@@ -2007,13 +2013,18 @@ static int stm32_spi_runtime_suspend(struct device *dev)
clk_disable_unprepare
(
spi
->
clk
);
return
0
;
return
pinctrl_pm_select_sleep_state
(
dev
)
;
}
static
int
stm32_spi_runtime_resume
(
struct
device
*
dev
)
{
struct
spi_master
*
master
=
dev_get_drvdata
(
dev
);
struct
stm32_spi
*
spi
=
spi_master_get_devdata
(
master
);
int
ret
;
ret
=
pinctrl_pm_select_default_state
(
dev
);
if
(
ret
)
return
ret
;
return
clk_prepare_enable
(
spi
->
clk
);
}
...
...
@@ -2043,10 +2054,23 @@ static int stm32_spi_resume(struct device *dev)
return
ret
;
ret
=
spi_master_resume
(
master
);
if
(
ret
)
if
(
ret
)
{
clk_disable_unprepare
(
spi
->
clk
);
return
ret
;
}
return
ret
;
ret
=
pm_runtime_get_sync
(
dev
);
if
(
ret
)
{
dev_err
(
dev
,
"Unable to power device:%d
\n
"
,
ret
);
return
ret
;
}
spi
->
cfg
->
config
(
spi
);
pm_runtime_mark_last_busy
(
dev
);
pm_runtime_put_autosuspend
(
dev
);
return
0
;
}
#endif
...
...
drivers/spi/spi.c
View file @
1973d5b7
...
...
@@ -475,6 +475,12 @@ static LIST_HEAD(spi_controller_list);
*/
static
DEFINE_MUTEX
(
board_lock
);
/*
* Prevents addition of devices with same chip select and
* addition of devices below an unregistering controller.
*/
static
DEFINE_MUTEX
(
spi_add_lock
);
/**
* spi_alloc_device - Allocate a new SPI device
* @ctlr: Controller to which device is connected
...
...
@@ -554,7 +560,6 @@ static int spi_dev_check(struct device *dev, void *data)
*/
int
spi_add_device
(
struct
spi_device
*
spi
)
{
static
DEFINE_MUTEX
(
spi_add_lock
);
struct
spi_controller
*
ctlr
=
spi
->
controller
;
struct
device
*
dev
=
ctlr
->
dev
.
parent
;
int
status
;
...
...
@@ -582,6 +587,13 @@ int spi_add_device(struct spi_device *spi)
goto
done
;
}
/* Controller may unregister concurrently */
if
(
IS_ENABLED
(
CONFIG_SPI_DYNAMIC
)
&&
!
device_is_registered
(
&
ctlr
->
dev
))
{
status
=
-
ENODEV
;
goto
done
;
}
/* Descriptors take precedence */
if
(
ctlr
->
cs_gpiods
)
spi
->
cs_gpiod
=
ctlr
->
cs_gpiods
[
spi
->
chip_select
];
...
...
@@ -2795,6 +2807,10 @@ void spi_unregister_controller(struct spi_controller *ctlr)
struct
spi_controller
*
found
;
int
id
=
ctlr
->
bus_num
;
/* Prevent addition of new devices, unregister existing ones */
if
(
IS_ENABLED
(
CONFIG_SPI_DYNAMIC
))
mutex_lock
(
&
spi_add_lock
);
device_for_each_child
(
&
ctlr
->
dev
,
NULL
,
__unregister
);
/* First make sure that this controller was ever added */
...
...
@@ -2815,6 +2831,9 @@ void spi_unregister_controller(struct spi_controller *ctlr)
if
(
found
==
ctlr
)
idr_remove
(
&
spi_master_idr
,
id
);
mutex_unlock
(
&
board_lock
);
if
(
IS_ENABLED
(
CONFIG_SPI_DYNAMIC
))
mutex_unlock
(
&
spi_add_lock
);
}
EXPORT_SYMBOL_GPL
(
spi_unregister_controller
);
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment