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
Kirill Smelkov
linux
Commits
a34d4197
Commit
a34d4197
authored
Dec 28, 2020
by
Mark Brown
Browse files
Options
Browse Files
Download
Plain Diff
Merge existing fixes from spi/for-5.11
parents
5c8fe583
a590370d
Changes
2
Hide whitespace changes
Inline
Side-by-side
Showing
2 changed files
with
82 additions
and
6 deletions
+82
-6
drivers/spi/spi-geni-qcom.c
drivers/spi/spi-geni-qcom.c
+80
-4
drivers/spi/spi-stm32.c
drivers/spi/spi-stm32.c
+2
-2
No files found.
drivers/spi/spi-geni-qcom.c
View file @
a34d4197
...
...
@@ -83,6 +83,7 @@ struct spi_geni_master {
spinlock_t
lock
;
int
irq
;
bool
cs_flag
;
bool
abort_failed
;
};
static
int
get_spi_clk_cfg
(
unsigned
int
speed_hz
,
...
...
@@ -141,8 +142,49 @@ static void handle_fifo_timeout(struct spi_master *spi,
spin_unlock_irq
(
&
mas
->
lock
);
time_left
=
wait_for_completion_timeout
(
&
mas
->
abort_done
,
HZ
);
if
(
!
time_left
)
if
(
!
time_left
)
{
dev_err
(
mas
->
dev
,
"Failed to cancel/abort m_cmd
\n
"
);
/*
* No need for a lock since SPI core has a lock and we never
* access this from an interrupt.
*/
mas
->
abort_failed
=
true
;
}
}
static
bool
spi_geni_is_abort_still_pending
(
struct
spi_geni_master
*
mas
)
{
struct
geni_se
*
se
=
&
mas
->
se
;
u32
m_irq
,
m_irq_en
;
if
(
!
mas
->
abort_failed
)
return
false
;
/*
* The only known case where a transfer times out and then a cancel
* times out then an abort times out is if something is blocking our
* interrupt handler from running. Avoid starting any new transfers
* until that sorts itself out.
*/
spin_lock_irq
(
&
mas
->
lock
);
m_irq
=
readl
(
se
->
base
+
SE_GENI_M_IRQ_STATUS
);
m_irq_en
=
readl
(
se
->
base
+
SE_GENI_M_IRQ_EN
);
spin_unlock_irq
(
&
mas
->
lock
);
if
(
m_irq
&
m_irq_en
)
{
dev_err
(
mas
->
dev
,
"Interrupts pending after abort: %#010x
\n
"
,
m_irq
&
m_irq_en
);
return
true
;
}
/*
* If we're here the problem resolved itself so no need to check more
* on future transfers.
*/
mas
->
abort_failed
=
false
;
return
false
;
}
static
void
spi_geni_set_cs
(
struct
spi_device
*
slv
,
bool
set_flag
)
...
...
@@ -158,10 +200,21 @@ static void spi_geni_set_cs(struct spi_device *slv, bool set_flag)
if
(
set_flag
==
mas
->
cs_flag
)
return
;
mas
->
cs_flag
=
set_flag
;
pm_runtime_get_sync
(
mas
->
dev
);
if
(
spi_geni_is_abort_still_pending
(
mas
))
{
dev_err
(
mas
->
dev
,
"Can't set chip select
\n
"
);
goto
exit
;
}
spin_lock_irq
(
&
mas
->
lock
);
if
(
mas
->
cur_xfer
)
{
dev_err
(
mas
->
dev
,
"Can't set CS when prev xfer running
\n
"
);
spin_unlock_irq
(
&
mas
->
lock
);
goto
exit
;
}
mas
->
cs_flag
=
set_flag
;
reinit_completion
(
&
mas
->
cs_done
);
if
(
set_flag
)
geni_se_setup_m_cmd
(
se
,
SPI_CS_ASSERT
,
0
);
...
...
@@ -170,9 +223,12 @@ static void spi_geni_set_cs(struct spi_device *slv, bool set_flag)
spin_unlock_irq
(
&
mas
->
lock
);
time_left
=
wait_for_completion_timeout
(
&
mas
->
cs_done
,
HZ
);
if
(
!
time_left
)
if
(
!
time_left
)
{
dev_warn
(
mas
->
dev
,
"Timeout setting chip select
\n
"
);
handle_fifo_timeout
(
spi
,
NULL
);
}
exit:
pm_runtime_put
(
mas
->
dev
);
}
...
...
@@ -280,6 +336,9 @@ static int spi_geni_prepare_message(struct spi_master *spi,
int
ret
;
struct
spi_geni_master
*
mas
=
spi_master_get_devdata
(
spi
);
if
(
spi_geni_is_abort_still_pending
(
mas
))
return
-
EBUSY
;
ret
=
setup_fifo_params
(
spi_msg
->
spi
,
spi
);
if
(
ret
)
dev_err
(
mas
->
dev
,
"Couldn't select mode %d
\n
"
,
ret
);
...
...
@@ -354,6 +413,12 @@ static bool geni_spi_handle_tx(struct spi_geni_master *mas)
unsigned
int
bytes_per_fifo_word
=
geni_byte_per_fifo_word
(
mas
);
unsigned
int
i
=
0
;
/* Stop the watermark IRQ if nothing to send */
if
(
!
mas
->
cur_xfer
)
{
writel
(
0
,
se
->
base
+
SE_GENI_TX_WATERMARK_REG
);
return
false
;
}
max_bytes
=
(
mas
->
tx_fifo_depth
-
mas
->
tx_wm
)
*
bytes_per_fifo_word
;
if
(
mas
->
tx_rem_bytes
<
max_bytes
)
max_bytes
=
mas
->
tx_rem_bytes
;
...
...
@@ -396,6 +461,14 @@ static void geni_spi_handle_rx(struct spi_geni_master *mas)
if
(
rx_last_byte_valid
&&
rx_last_byte_valid
<
4
)
rx_bytes
-=
bytes_per_fifo_word
-
rx_last_byte_valid
;
}
/* Clear out the FIFO and bail if nowhere to put it */
if
(
!
mas
->
cur_xfer
)
{
for
(
i
=
0
;
i
<
DIV_ROUND_UP
(
rx_bytes
,
bytes_per_fifo_word
);
i
++
)
readl
(
se
->
base
+
SE_GENI_RX_FIFOn
);
return
;
}
if
(
mas
->
rx_rem_bytes
<
rx_bytes
)
rx_bytes
=
mas
->
rx_rem_bytes
;
...
...
@@ -495,6 +568,9 @@ static int spi_geni_transfer_one(struct spi_master *spi,
{
struct
spi_geni_master
*
mas
=
spi_master_get_devdata
(
spi
);
if
(
spi_geni_is_abort_still_pending
(
mas
))
return
-
EBUSY
;
/* Terminate and return success for 0 byte length transfer */
if
(
!
xfer
->
len
)
return
0
;
...
...
drivers/spi/spi-stm32.c
View file @
a34d4197
...
...
@@ -493,9 +493,9 @@ static u32 stm32h7_spi_prepare_fthlv(struct stm32_spi *spi, u32 xfer_len)
/* align packet size with data registers access */
if
(
spi
->
cur_bpw
>
8
)
fthlv
-=
(
fthlv
%
2
);
/* multiple of 2 */
fthlv
+=
(
fthlv
%
2
)
?
1
:
0
;
else
fthlv
-=
(
fthlv
%
4
);
/* multiple of 4 */
fthlv
+=
(
fthlv
%
4
)
?
(
4
-
(
fthlv
%
4
))
:
0
;
if
(
!
fthlv
)
fthlv
=
1
;
...
...
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