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
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
Show 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);
...
@@ -1069,7 +1069,6 @@ EXPORT_SYMBOL_GPL(spi_finalize_current_transfer);
* __spi_pump_messages - function which processes spi message queue
* __spi_pump_messages - function which processes spi message queue
* @master: master to process queue for
* @master: master to process queue for
* @in_kthread: true if we are in the context of the message pump thread
* @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
* 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
* needs processing and if so call out to the driver to initialize hardware
...
@@ -1079,8 +1078,7 @@ EXPORT_SYMBOL_GPL(spi_finalize_current_transfer);
...
@@ -1079,8 +1078,7 @@ EXPORT_SYMBOL_GPL(spi_finalize_current_transfer);
* inside spi_sync(); the queue extraction handling at the top of the
* inside spi_sync(); the queue extraction handling at the top of the
* function should deal with this safely.
* function should deal with this safely.
*/
*/
static
void
__spi_pump_messages
(
struct
spi_master
*
master
,
bool
in_kthread
,
static
void
__spi_pump_messages
(
struct
spi_master
*
master
,
bool
in_kthread
)
bool
bus_locked
)
{
{
unsigned
long
flags
;
unsigned
long
flags
;
bool
was_busy
=
false
;
bool
was_busy
=
false
;
...
@@ -1152,6 +1150,8 @@ static void __spi_pump_messages(struct spi_master *master, bool in_kthread,
...
@@ -1152,6 +1150,8 @@ static void __spi_pump_messages(struct spi_master *master, bool in_kthread,
master
->
busy
=
true
;
master
->
busy
=
true
;
spin_unlock_irqrestore
(
&
master
->
queue_lock
,
flags
);
spin_unlock_irqrestore
(
&
master
->
queue_lock
,
flags
);
mutex_lock
(
&
master
->
io_mutex
);
if
(
!
was_busy
&&
master
->
auto_runtime_pm
)
{
if
(
!
was_busy
&&
master
->
auto_runtime_pm
)
{
ret
=
pm_runtime_get_sync
(
master
->
dev
.
parent
);
ret
=
pm_runtime_get_sync
(
master
->
dev
.
parent
);
if
(
ret
<
0
)
{
if
(
ret
<
0
)
{
...
@@ -1176,9 +1176,6 @@ static void __spi_pump_messages(struct spi_master *master, bool in_kthread,
...
@@ -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
);
trace_spi_message_start
(
master
->
cur_msg
);
if
(
master
->
prepare_message
)
{
if
(
master
->
prepare_message
)
{
...
@@ -1208,8 +1205,7 @@ static void __spi_pump_messages(struct spi_master *master, bool in_kthread,
...
@@ -1208,8 +1205,7 @@ static void __spi_pump_messages(struct spi_master *master, bool in_kthread,
}
}
out:
out:
if
(
!
bus_locked
)
mutex_unlock
(
&
master
->
io_mutex
);
mutex_unlock
(
&
master
->
bus_lock_mutex
);
/* Prod the scheduler in case transfer_one() was busy waiting */
/* Prod the scheduler in case transfer_one() was busy waiting */
if
(
!
ret
)
if
(
!
ret
)
...
@@ -1225,7 +1221,7 @@ static void spi_pump_messages(struct kthread_work *work)
...
@@ -1225,7 +1221,7 @@ static void spi_pump_messages(struct kthread_work *work)
struct
spi_master
*
master
=
struct
spi_master
*
master
=
container_of
(
work
,
struct
spi_master
,
pump_messages
);
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
)
static
int
spi_init_queue
(
struct
spi_master
*
master
)
...
@@ -1887,6 +1883,7 @@ int spi_register_master(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
->
queue_lock
);
spin_lock_init
(
&
master
->
bus_lock_spinlock
);
spin_lock_init
(
&
master
->
bus_lock_spinlock
);
mutex_init
(
&
master
->
bus_lock_mutex
);
mutex_init
(
&
master
->
bus_lock_mutex
);
mutex_init
(
&
master
->
io_mutex
);
master
->
bus_lock_flag
=
0
;
master
->
bus_lock_flag
=
0
;
init_completion
(
&
master
->
xfer_completion
);
init_completion
(
&
master
->
xfer_completion
);
if
(
!
master
->
max_dma_len
)
if
(
!
master
->
max_dma_len
)
...
@@ -2767,6 +2764,7 @@ int spi_flash_read(struct spi_device *spi,
...
@@ -2767,6 +2764,7 @@ int spi_flash_read(struct spi_device *spi,
}
}
mutex_lock
(
&
master
->
bus_lock_mutex
);
mutex_lock
(
&
master
->
bus_lock_mutex
);
mutex_lock
(
&
master
->
io_mutex
);
if
(
master
->
dma_rx
)
{
if
(
master
->
dma_rx
)
{
rx_dev
=
master
->
dma_rx
->
device
->
dev
;
rx_dev
=
master
->
dma_rx
->
device
->
dev
;
ret
=
spi_map_buf
(
master
,
rx_dev
,
&
msg
->
rx_sg
,
ret
=
spi_map_buf
(
master
,
rx_dev
,
&
msg
->
rx_sg
,
...
@@ -2779,6 +2777,7 @@ int spi_flash_read(struct spi_device *spi,
...
@@ -2779,6 +2777,7 @@ int spi_flash_read(struct spi_device *spi,
if
(
msg
->
cur_msg_mapped
)
if
(
msg
->
cur_msg_mapped
)
spi_unmap_buf
(
master
,
rx_dev
,
&
msg
->
rx_sg
,
spi_unmap_buf
(
master
,
rx_dev
,
&
msg
->
rx_sg
,
DMA_FROM_DEVICE
);
DMA_FROM_DEVICE
);
mutex_unlock
(
&
master
->
io_mutex
);
mutex_unlock
(
&
master
->
bus_lock_mutex
);
mutex_unlock
(
&
master
->
bus_lock_mutex
);
if
(
master
->
auto_runtime_pm
)
if
(
master
->
auto_runtime_pm
)
...
@@ -2800,8 +2799,7 @@ static void spi_complete(void *arg)
...
@@ -2800,8 +2799,7 @@ static void spi_complete(void *arg)
complete
(
arg
);
complete
(
arg
);
}
}
static
int
__spi_sync
(
struct
spi_device
*
spi
,
struct
spi_message
*
message
,
static
int
__spi_sync
(
struct
spi_device
*
spi
,
struct
spi_message
*
message
)
int
bus_locked
)
{
{
DECLARE_COMPLETION_ONSTACK
(
done
);
DECLARE_COMPLETION_ONSTACK
(
done
);
int
status
;
int
status
;
...
@@ -2819,9 +2817,6 @@ static int __spi_sync(struct spi_device *spi, struct spi_message *message,
...
@@ -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
(
&
master
->
statistics
,
spi_sync
);
SPI_STATISTICS_INCREMENT_FIELD
(
&
spi
->
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
/* If we're not using the legacy transfer method then we will
* try to transfer in the calling context so special case.
* try to transfer in the calling context so special case.
* This code would be less tricky if we could remove the
* 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,
...
@@ -2839,9 +2834,6 @@ static int __spi_sync(struct spi_device *spi, struct spi_message *message,
status
=
spi_async_locked
(
spi
,
message
);
status
=
spi_async_locked
(
spi
,
message
);
}
}
if
(
!
bus_locked
)
mutex_unlock
(
&
master
->
bus_lock_mutex
);
if
(
status
==
0
)
{
if
(
status
==
0
)
{
/* Push out the messages in the calling context if we
/* Push out the messages in the calling context if we
* can.
* can.
...
@@ -2851,7 +2843,7 @@ static int __spi_sync(struct spi_device *spi, struct spi_message *message,
...
@@ -2851,7 +2843,7 @@ static int __spi_sync(struct spi_device *spi, struct spi_message *message,
spi_sync_immediate
);
spi_sync_immediate
);
SPI_STATISTICS_INCREMENT_FIELD
(
&
spi
->
statistics
,
SPI_STATISTICS_INCREMENT_FIELD
(
&
spi
->
statistics
,
spi_sync_immediate
);
spi_sync_immediate
);
__spi_pump_messages
(
master
,
false
,
bus_locked
);
__spi_pump_messages
(
master
,
false
);
}
}
wait_for_completion
(
&
done
);
wait_for_completion
(
&
done
);
...
@@ -2884,7 +2876,13 @@ static int __spi_sync(struct spi_device *spi, struct spi_message *message,
...
@@ -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
)
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
);
EXPORT_SYMBOL_GPL
(
spi_sync
);
...
@@ -2906,7 +2904,7 @@ 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
)
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
);
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)
...
@@ -312,8 +312,9 @@ static inline void spi_unregister_driver(struct spi_driver *sdrv)
* @flags: other constraints relevant to this driver
* @flags: other constraints relevant to this driver
* @max_transfer_size: function that returns the max transfer size for
* @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.
* 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_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
* @bus_lock_flag: indicates that the SPI bus is locked for exclusive use
* @setup: updates the device mode and clocking records used by a
* @setup: updates the device mode and clocking records used by a
* device's SPI controller; protocol code may call this. This
* device's SPI controller; protocol code may call this. This
...
@@ -446,6 +447,9 @@ struct spi_master {
...
@@ -446,6 +447,9 @@ struct spi_master {
*/
*/
size_t
(
*
max_transfer_size
)(
struct
spi_device
*
spi
);
size_t
(
*
max_transfer_size
)(
struct
spi_device
*
spi
);
/* I/O mutex */
struct
mutex
io_mutex
;
/* lock and mutex for SPI bus locking */
/* lock and mutex for SPI bus locking */
spinlock_t
bus_lock_spinlock
;
spinlock_t
bus_lock_spinlock
;
struct
mutex
bus_lock_mutex
;
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