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
dec34e8b
Commit
dec34e8b
authored
Jul 25, 2016
by
Mark Brown
Browse files
Options
Browse Files
Download
Plain Diff
Merge remote-tracking branch 'spi/fix/locking' into spi-next
parents
56432b73
ef4d96ec
Changes
2
Hide whitespace changes
Inline
Side-by-side
Showing
2 changed files
with
23 additions
and
21 deletions
+23
-21
drivers/spi/spi.c
drivers/spi/spi.c
+18
-20
include/linux/spi/spi.h
include/linux/spi/spi.h
+5
-1
No files found.
drivers/spi/spi.c
View file @
dec34e8b
...
...
@@ -1069,7 +1069,6 @@ EXPORT_SYMBOL_GPL(spi_finalize_current_transfer);
* __spi_pump_messages - function which processes spi message queue
* @master: master to process queue for
* @in_kthread: true if we are in the context of the message pump thread
* @bus_locked: true if the bus mutex is held when calling this function
*
* This function checks if there is any spi message in the queue that
* needs processing and if so call out to the driver to initialize hardware
...
...
@@ -1079,8 +1078,7 @@ EXPORT_SYMBOL_GPL(spi_finalize_current_transfer);
* inside spi_sync(); the queue extraction handling at the top of the
* function should deal with this safely.
*/
static
void
__spi_pump_messages
(
struct
spi_master
*
master
,
bool
in_kthread
,
bool
bus_locked
)
static
void
__spi_pump_messages
(
struct
spi_master
*
master
,
bool
in_kthread
)
{
unsigned
long
flags
;
bool
was_busy
=
false
;
...
...
@@ -1152,6 +1150,8 @@ static void __spi_pump_messages(struct spi_master *master, bool in_kthread,
master
->
busy
=
true
;
spin_unlock_irqrestore
(
&
master
->
queue_lock
,
flags
);
mutex_lock
(
&
master
->
io_mutex
);
if
(
!
was_busy
&&
master
->
auto_runtime_pm
)
{
ret
=
pm_runtime_get_sync
(
master
->
dev
.
parent
);
if
(
ret
<
0
)
{
...
...
@@ -1176,9 +1176,6 @@ static void __spi_pump_messages(struct spi_master *master, bool in_kthread,
}
}
if
(
!
bus_locked
)
mutex_lock
(
&
master
->
bus_lock_mutex
);
trace_spi_message_start
(
master
->
cur_msg
);
if
(
master
->
prepare_message
)
{
...
...
@@ -1208,8 +1205,7 @@ static void __spi_pump_messages(struct spi_master *master, bool in_kthread,
}
out:
if
(
!
bus_locked
)
mutex_unlock
(
&
master
->
bus_lock_mutex
);
mutex_unlock
(
&
master
->
io_mutex
);
/* Prod the scheduler in case transfer_one() was busy waiting */
if
(
!
ret
)
...
...
@@ -1225,7 +1221,7 @@ static void spi_pump_messages(struct kthread_work *work)
struct
spi_master
*
master
=
container_of
(
work
,
struct
spi_master
,
pump_messages
);
__spi_pump_messages
(
master
,
true
,
master
->
bus_lock_flag
);
__spi_pump_messages
(
master
,
true
);
}
static
int
spi_init_queue
(
struct
spi_master
*
master
)
...
...
@@ -1887,6 +1883,7 @@ int spi_register_master(struct spi_master *master)
spin_lock_init
(
&
master
->
queue_lock
);
spin_lock_init
(
&
master
->
bus_lock_spinlock
);
mutex_init
(
&
master
->
bus_lock_mutex
);
mutex_init
(
&
master
->
io_mutex
);
master
->
bus_lock_flag
=
0
;
init_completion
(
&
master
->
xfer_completion
);
if
(
!
master
->
max_dma_len
)
...
...
@@ -2767,6 +2764,7 @@ int spi_flash_read(struct spi_device *spi,
}
mutex_lock
(
&
master
->
bus_lock_mutex
);
mutex_lock
(
&
master
->
io_mutex
);
if
(
master
->
dma_rx
)
{
rx_dev
=
master
->
dma_rx
->
device
->
dev
;
ret
=
spi_map_buf
(
master
,
rx_dev
,
&
msg
->
rx_sg
,
...
...
@@ -2779,6 +2777,7 @@ int spi_flash_read(struct spi_device *spi,
if
(
msg
->
cur_msg_mapped
)
spi_unmap_buf
(
master
,
rx_dev
,
&
msg
->
rx_sg
,
DMA_FROM_DEVICE
);
mutex_unlock
(
&
master
->
io_mutex
);
mutex_unlock
(
&
master
->
bus_lock_mutex
);
if
(
master
->
auto_runtime_pm
)
...
...
@@ -2800,8 +2799,7 @@ static void spi_complete(void *arg)
complete
(
arg
);
}
static
int
__spi_sync
(
struct
spi_device
*
spi
,
struct
spi_message
*
message
,
int
bus_locked
)
static
int
__spi_sync
(
struct
spi_device
*
spi
,
struct
spi_message
*
message
)
{
DECLARE_COMPLETION_ONSTACK
(
done
);
int
status
;
...
...
@@ -2819,9 +2817,6 @@ static int __spi_sync(struct spi_device *spi, struct spi_message *message,
SPI_STATISTICS_INCREMENT_FIELD
(
&
master
->
statistics
,
spi_sync
);
SPI_STATISTICS_INCREMENT_FIELD
(
&
spi
->
statistics
,
spi_sync
);
if
(
!
bus_locked
)
mutex_lock
(
&
master
->
bus_lock_mutex
);
/* If we're not using the legacy transfer method then we will
* try to transfer in the calling context so special case.
* This code would be less tricky if we could remove the
...
...
@@ -2839,9 +2834,6 @@ static int __spi_sync(struct spi_device *spi, struct spi_message *message,
status
=
spi_async_locked
(
spi
,
message
);
}
if
(
!
bus_locked
)
mutex_unlock
(
&
master
->
bus_lock_mutex
);
if
(
status
==
0
)
{
/* Push out the messages in the calling context if we
* can.
...
...
@@ -2851,7 +2843,7 @@ static int __spi_sync(struct spi_device *spi, struct spi_message *message,
spi_sync_immediate
);
SPI_STATISTICS_INCREMENT_FIELD
(
&
spi
->
statistics
,
spi_sync_immediate
);
__spi_pump_messages
(
master
,
false
,
bus_locked
);
__spi_pump_messages
(
master
,
false
);
}
wait_for_completion
(
&
done
);
...
...
@@ -2884,7 +2876,13 @@ static int __spi_sync(struct spi_device *spi, struct spi_message *message,
*/
int
spi_sync
(
struct
spi_device
*
spi
,
struct
spi_message
*
message
)
{
return
__spi_sync
(
spi
,
message
,
spi
->
master
->
bus_lock_flag
);
int
ret
;
mutex_lock
(
&
spi
->
master
->
bus_lock_mutex
);
ret
=
__spi_sync
(
spi
,
message
);
mutex_unlock
(
&
spi
->
master
->
bus_lock_mutex
);
return
ret
;
}
EXPORT_SYMBOL_GPL
(
spi_sync
);
...
...
@@ -2906,7 +2904,7 @@ EXPORT_SYMBOL_GPL(spi_sync);
*/
int
spi_sync_locked
(
struct
spi_device
*
spi
,
struct
spi_message
*
message
)
{
return
__spi_sync
(
spi
,
message
,
1
);
return
__spi_sync
(
spi
,
message
);
}
EXPORT_SYMBOL_GPL
(
spi_sync_locked
);
...
...
include/linux/spi/spi.h
View file @
dec34e8b
...
...
@@ -312,8 +312,9 @@ static inline void spi_unregister_driver(struct spi_driver *sdrv)
* @flags: other constraints relevant to this driver
* @max_transfer_size: function that returns the max transfer size for
* a &spi_device; may be %NULL, so the default %SIZE_MAX will be used.
* @io_mutex: mutex for physical bus access
* @bus_lock_spinlock: spinlock for SPI bus locking
* @bus_lock_mutex: mutex for
SPI bus locking
* @bus_lock_mutex: mutex for
exclusion of multiple callers
* @bus_lock_flag: indicates that the SPI bus is locked for exclusive use
* @setup: updates the device mode and clocking records used by a
* device's SPI controller; protocol code may call this. This
...
...
@@ -446,6 +447,9 @@ struct spi_master {
*/
size_t
(
*
max_transfer_size
)(
struct
spi_device
*
spi
);
/* I/O mutex */
struct
mutex
io_mutex
;
/* lock and mutex for SPI bus locking */
spinlock_t
bus_lock_spinlock
;
struct
mutex
bus_lock_mutex
;
...
...
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