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
e1a7d167
Commit
e1a7d167
authored
5 years ago
by
Mark Brown
Browse files
Options
Browse Files
Download
Plain Diff
Merge branch 'spi-5.1' into spi-5.2
parents
9fda6693
a026525d
Changes
7
Show whitespace changes
Inline
Side-by-side
Showing
7 changed files
with
173 additions
and
71 deletions
+173
-71
drivers/spi/spi-fsl-lpspi.c
drivers/spi/spi-fsl-lpspi.c
+2
-2
drivers/spi/spi-gpio.c
drivers/spi/spi-gpio.c
+0
-1
drivers/spi/spi-pic32.c
drivers/spi/spi-pic32.c
+1
-1
drivers/spi/spi-tegra114.c
drivers/spi/spi-tegra114.c
+146
-62
drivers/spi/spi-tegra20-slink.c
drivers/spi/spi-tegra20-slink.c
+9
-3
drivers/spi/spi-topcliff-pch.c
drivers/spi/spi-topcliff-pch.c
+13
-2
drivers/spi/spi.c
drivers/spi/spi.c
+2
-0
No files found.
drivers/spi/spi-fsl-lpspi.c
View file @
e1a7d167
...
...
@@ -77,7 +77,7 @@
#define CFGR1_PCSPOL BIT(8)
#define CFGR1_NOSTALL BIT(3)
#define CFGR1_MASTER BIT(0)
#define FSR_
RXCOUNT (BIT(16)|BIT(17)|BIT(18)
)
#define FSR_
TXCOUNT (0xFF
)
#define RSR_RXEMPTY BIT(1)
#define TCR_CPOL BIT(31)
#define TCR_CPHA BIT(30)
...
...
@@ -771,7 +771,7 @@ static irqreturn_t fsl_lpspi_isr(int irq, void *dev_id)
}
if
(
temp_SR
&
SR_MBF
||
readl
(
fsl_lpspi
->
base
+
IMX7ULP_FSR
)
&
FSR_
R
XCOUNT
)
{
readl
(
fsl_lpspi
->
base
+
IMX7ULP_FSR
)
&
FSR_
T
XCOUNT
)
{
writel
(
SR_FCF
,
fsl_lpspi
->
base
+
IMX7ULP_SR
);
fsl_lpspi_intctrl
(
fsl_lpspi
,
IER_FCIE
);
return
IRQ_HANDLED
;
...
...
This diff is collapsed.
Click to expand it.
drivers/spi/spi-gpio.c
View file @
e1a7d167
...
...
@@ -35,7 +35,6 @@
* platform_device->driver_data ... points to spi_gpio
*
* spi->controller_state ... reserved for bitbang framework code
* spi->controller_data ... holds chipselect GPIO
*
* spi->master->dev.driver_data ... points to spi_gpio->bitbang
*/
...
...
This diff is collapsed.
Click to expand it.
drivers/spi/spi-pic32.c
View file @
e1a7d167
...
...
@@ -559,7 +559,7 @@ static int pic32_spi_one_transfer(struct spi_master *master,
dev_err
(
&
spi
->
dev
,
"wait error/timedout
\n
"
);
if
(
dma_issued
)
{
dmaengine_terminate_all
(
master
->
dma_rx
);
dmaengine_terminate_all
(
master
->
dma_
r
x
);
dmaengine_terminate_all
(
master
->
dma_
t
x
);
}
ret
=
-
ETIMEDOUT
;
}
else
{
...
...
This diff is collapsed.
Click to expand it.
drivers/spi/spi-tegra114.c
View file @
e1a7d167
...
...
@@ -307,10 +307,16 @@ static unsigned tegra_spi_fill_tx_fifo_from_client_txbuf(
x
|=
(
u32
)(
*
tx_buf
++
)
<<
(
i
*
8
);
tegra_spi_writel
(
tspi
,
x
,
SPI_TX_FIFO
);
}
tspi
->
cur_tx_pos
+=
written_words
*
tspi
->
bytes_per_word
;
}
else
{
unsigned
int
write_bytes
;
max_n_32bit
=
min
(
tspi
->
curr_dma_words
,
tx_empty_count
);
written_words
=
max_n_32bit
;
nbytes
=
written_words
*
tspi
->
bytes_per_word
;
if
(
nbytes
>
t
->
len
-
tspi
->
cur_pos
)
nbytes
=
t
->
len
-
tspi
->
cur_pos
;
write_bytes
=
nbytes
;
for
(
count
=
0
;
count
<
max_n_32bit
;
count
++
)
{
u32
x
=
0
;
...
...
@@ -319,8 +325,10 @@ static unsigned tegra_spi_fill_tx_fifo_from_client_txbuf(
x
|=
(
u32
)(
*
tx_buf
++
)
<<
(
i
*
8
);
tegra_spi_writel
(
tspi
,
x
,
SPI_TX_FIFO
);
}
tspi
->
cur_tx_pos
+=
write_bytes
;
}
tspi
->
cur_tx_pos
+=
written_words
*
tspi
->
bytes_per_word
;
return
written_words
;
}
...
...
@@ -344,20 +352,27 @@ static unsigned int tegra_spi_read_rx_fifo_to_client_rxbuf(
for
(
i
=
0
;
len
&&
(
i
<
4
);
i
++
,
len
--
)
*
rx_buf
++
=
(
x
>>
i
*
8
)
&
0xFF
;
}
tspi
->
cur_rx_pos
+=
tspi
->
curr_dma_words
*
tspi
->
bytes_per_word
;
read_words
+=
tspi
->
curr_dma_words
;
tspi
->
cur_rx_pos
+=
tspi
->
curr_dma_words
*
tspi
->
bytes_per_word
;
}
else
{
u32
rx_mask
=
((
u32
)
1
<<
t
->
bits_per_word
)
-
1
;
u8
bytes_per_word
=
tspi
->
bytes_per_word
;
unsigned
int
read_bytes
;
len
=
rx_full_count
*
bytes_per_word
;
if
(
len
>
t
->
len
-
tspi
->
cur_pos
)
len
=
t
->
len
-
tspi
->
cur_pos
;
read_bytes
=
len
;
for
(
count
=
0
;
count
<
rx_full_count
;
count
++
)
{
u32
x
=
tegra_spi_readl
(
tspi
,
SPI_RX_FIFO
)
&
rx_mask
;
for
(
i
=
0
;
(
i
<
tspi
->
bytes_per_word
);
i
++
)
for
(
i
=
0
;
len
&&
(
i
<
bytes_per_word
);
i
++
,
len
--
)
*
rx_buf
++
=
(
x
>>
(
i
*
8
))
&
0xFF
;
}
tspi
->
cur_rx_pos
+=
rx_full_count
*
tspi
->
bytes_per_word
;
read_words
+=
rx_full_count
;
tspi
->
cur_rx_pos
+=
read_bytes
;
}
return
read_words
;
}
...
...
@@ -372,12 +387,17 @@ static void tegra_spi_copy_client_txbuf_to_spi_txbuf(
unsigned
len
=
tspi
->
curr_dma_words
*
tspi
->
bytes_per_word
;
memcpy
(
tspi
->
tx_dma_buf
,
t
->
tx_buf
+
tspi
->
cur_pos
,
len
);
tspi
->
cur_tx_pos
+=
tspi
->
curr_dma_words
*
tspi
->
bytes_per_word
;
}
else
{
unsigned
int
i
;
unsigned
int
count
;
u8
*
tx_buf
=
(
u8
*
)
t
->
tx_buf
+
tspi
->
cur_tx_pos
;
unsigned
consume
=
tspi
->
curr_dma_words
*
tspi
->
bytes_per_word
;
unsigned
int
write_bytes
;
if
(
consume
>
t
->
len
-
tspi
->
cur_pos
)
consume
=
t
->
len
-
tspi
->
cur_pos
;
write_bytes
=
consume
;
for
(
count
=
0
;
count
<
tspi
->
curr_dma_words
;
count
++
)
{
u32
x
=
0
;
...
...
@@ -386,8 +406,9 @@ static void tegra_spi_copy_client_txbuf_to_spi_txbuf(
x
|=
(
u32
)(
*
tx_buf
++
)
<<
(
i
*
8
);
tspi
->
tx_dma_buf
[
count
]
=
x
;
}
tspi
->
cur_tx_pos
+=
write_bytes
;
}
tspi
->
cur_tx_pos
+=
tspi
->
curr_dma_words
*
tspi
->
bytes_per_word
;
/* Make the dma buffer to read by dma */
dma_sync_single_for_device
(
tspi
->
dev
,
tspi
->
tx_dma_phys
,
...
...
@@ -405,20 +426,28 @@ static void tegra_spi_copy_spi_rxbuf_to_client_rxbuf(
unsigned
len
=
tspi
->
curr_dma_words
*
tspi
->
bytes_per_word
;
memcpy
(
t
->
rx_buf
+
tspi
->
cur_rx_pos
,
tspi
->
rx_dma_buf
,
len
);
tspi
->
cur_rx_pos
+=
tspi
->
curr_dma_words
*
tspi
->
bytes_per_word
;
}
else
{
unsigned
int
i
;
unsigned
int
count
;
unsigned
char
*
rx_buf
=
t
->
rx_buf
+
tspi
->
cur_rx_pos
;
u32
rx_mask
=
((
u32
)
1
<<
t
->
bits_per_word
)
-
1
;
unsigned
consume
=
tspi
->
curr_dma_words
*
tspi
->
bytes_per_word
;
unsigned
int
read_bytes
;
if
(
consume
>
t
->
len
-
tspi
->
cur_pos
)
consume
=
t
->
len
-
tspi
->
cur_pos
;
read_bytes
=
consume
;
for
(
count
=
0
;
count
<
tspi
->
curr_dma_words
;
count
++
)
{
u32
x
=
tspi
->
rx_dma_buf
[
count
]
&
rx_mask
;
for
(
i
=
0
;
(
i
<
tspi
->
bytes_per_word
);
i
++
)
for
(
i
=
0
;
consume
&&
(
i
<
tspi
->
bytes_per_word
);
i
++
,
consume
--
)
*
rx_buf
++
=
(
x
>>
(
i
*
8
))
&
0xFF
;
}
tspi
->
cur_rx_pos
+=
read_bytes
;
}
tspi
->
cur_rx_pos
+=
tspi
->
curr_dma_words
*
tspi
->
bytes_per_word
;
/* Make the dma buffer to read by dma */
dma_sync_single_for_device
(
tspi
->
dev
,
tspi
->
rx_dma_phys
,
...
...
@@ -470,22 +499,39 @@ static int tegra_spi_start_rx_dma(struct tegra_spi_data *tspi, int len)
return
0
;
}
static
int
tegra_spi_start_dma_based_transfer
(
struct
tegra_spi_data
*
tspi
,
struct
spi_transfer
*
t
)
static
int
tegra_spi_flush_fifos
(
struct
tegra_spi_data
*
tspi
)
{
u32
val
;
unsigned
int
len
;
int
ret
=
0
;
unsigned
long
timeout
=
jiffies
+
HZ
;
u32
status
;
/* Make sure that Rx and Tx fifo are empty */
status
=
tegra_spi_readl
(
tspi
,
SPI_FIFO_STATUS
);
if
((
status
&
SPI_FIFO_EMPTY
)
!=
SPI_FIFO_EMPTY
)
{
dev_err
(
tspi
->
dev
,
"Rx/Tx fifo are not empty status 0x%08x
\n
"
,
(
unsigned
)
status
);
status
|=
SPI_RX_FIFO_FLUSH
|
SPI_TX_FIFO_FLUSH
;
tegra_spi_writel
(
tspi
,
status
,
SPI_FIFO_STATUS
);
while
((
status
&
SPI_FIFO_EMPTY
)
!=
SPI_FIFO_EMPTY
)
{
status
=
tegra_spi_readl
(
tspi
,
SPI_FIFO_STATUS
);
if
(
time_after
(
jiffies
,
timeout
))
{
dev_err
(
tspi
->
dev
,
"timeout waiting for fifo flush
\n
"
);
return
-
EIO
;
}
udelay
(
1
);
}
}
return
0
;
}
static
int
tegra_spi_start_dma_based_transfer
(
struct
tegra_spi_data
*
tspi
,
struct
spi_transfer
*
t
)
{
u32
val
;
unsigned
int
len
;
int
ret
=
0
;
u8
dma_burst
;
struct
dma_slave_config
dma_sconfig
=
{
0
};
val
=
SPI_DMA_BLK_SET
(
tspi
->
curr_dma_words
-
1
);
tegra_spi_writel
(
tspi
,
val
,
SPI_DMA_BLK
);
...
...
@@ -496,12 +542,16 @@ static int tegra_spi_start_dma_based_transfer(
len
=
tspi
->
curr_dma_words
*
4
;
/* Set attention level based on length of transfer */
if
(
len
&
0xF
)
if
(
len
&
0xF
)
{
val
|=
SPI_TX_TRIG_1
|
SPI_RX_TRIG_1
;
else
if
(((
len
)
>>
4
)
&
0x1
)
dma_burst
=
1
;
}
else
if
(((
len
)
>>
4
)
&
0x1
)
{
val
|=
SPI_TX_TRIG_4
|
SPI_RX_TRIG_4
;
else
dma_burst
=
4
;
}
else
{
val
|=
SPI_TX_TRIG_8
|
SPI_RX_TRIG_8
;
dma_burst
=
8
;
}
if
(
tspi
->
cur_direction
&
DATA_DIR_TX
)
val
|=
SPI_IE_TX
;
...
...
@@ -512,7 +562,18 @@ static int tegra_spi_start_dma_based_transfer(
tegra_spi_writel
(
tspi
,
val
,
SPI_DMA_CTL
);
tspi
->
dma_control_reg
=
val
;
dma_sconfig
.
device_fc
=
true
;
if
(
tspi
->
cur_direction
&
DATA_DIR_TX
)
{
dma_sconfig
.
dst_addr
=
tspi
->
phys
+
SPI_TX_FIFO
;
dma_sconfig
.
dst_addr_width
=
DMA_SLAVE_BUSWIDTH_4_BYTES
;
dma_sconfig
.
dst_maxburst
=
dma_burst
;
ret
=
dmaengine_slave_config
(
tspi
->
tx_dma_chan
,
&
dma_sconfig
);
if
(
ret
<
0
)
{
dev_err
(
tspi
->
dev
,
"DMA slave config failed: %d
\n
"
,
ret
);
return
ret
;
}
tegra_spi_copy_client_txbuf_to_spi_txbuf
(
tspi
,
t
);
ret
=
tegra_spi_start_tx_dma
(
tspi
,
len
);
if
(
ret
<
0
)
{
...
...
@@ -523,6 +584,16 @@ static int tegra_spi_start_dma_based_transfer(
}
if
(
tspi
->
cur_direction
&
DATA_DIR_RX
)
{
dma_sconfig
.
src_addr
=
tspi
->
phys
+
SPI_RX_FIFO
;
dma_sconfig
.
src_addr_width
=
DMA_SLAVE_BUSWIDTH_4_BYTES
;
dma_sconfig
.
src_maxburst
=
dma_burst
;
ret
=
dmaengine_slave_config
(
tspi
->
rx_dma_chan
,
&
dma_sconfig
);
if
(
ret
<
0
)
{
dev_err
(
tspi
->
dev
,
"DMA slave config failed: %d
\n
"
,
ret
);
return
ret
;
}
/* Make the dma buffer to read by dma */
dma_sync_single_for_device
(
tspi
->
dev
,
tspi
->
rx_dma_phys
,
tspi
->
dma_buf_size
,
DMA_FROM_DEVICE
);
...
...
@@ -582,7 +653,6 @@ static int tegra_spi_init_dma_param(struct tegra_spi_data *tspi,
u32
*
dma_buf
;
dma_addr_t
dma_phys
;
int
ret
;
struct
dma_slave_config
dma_sconfig
;
dma_chan
=
dma_request_slave_channel_reason
(
tspi
->
dev
,
dma_to_memory
?
"rx"
:
"tx"
);
...
...
@@ -602,19 +672,6 @@ static int tegra_spi_init_dma_param(struct tegra_spi_data *tspi,
return
-
ENOMEM
;
}
if
(
dma_to_memory
)
{
dma_sconfig
.
src_addr
=
tspi
->
phys
+
SPI_RX_FIFO
;
dma_sconfig
.
src_addr_width
=
DMA_SLAVE_BUSWIDTH_4_BYTES
;
dma_sconfig
.
src_maxburst
=
0
;
}
else
{
dma_sconfig
.
dst_addr
=
tspi
->
phys
+
SPI_TX_FIFO
;
dma_sconfig
.
dst_addr_width
=
DMA_SLAVE_BUSWIDTH_4_BYTES
;
dma_sconfig
.
dst_maxburst
=
0
;
}
ret
=
dmaengine_slave_config
(
dma_chan
,
&
dma_sconfig
);
if
(
ret
)
goto
scrub
;
if
(
dma_to_memory
)
{
tspi
->
rx_dma_chan
=
dma_chan
;
tspi
->
rx_dma_buf
=
dma_buf
;
...
...
@@ -625,11 +682,6 @@ static int tegra_spi_init_dma_param(struct tegra_spi_data *tspi,
tspi
->
tx_dma_phys
=
dma_phys
;
}
return
0
;
scrub:
dma_free_coherent
(
tspi
->
dev
,
tspi
->
dma_buf_size
,
dma_buf
,
dma_phys
);
dma_release_channel
(
dma_chan
);
return
ret
;
}
static
void
tegra_spi_deinit_dma_param
(
struct
tegra_spi_data
*
tspi
,
...
...
@@ -735,6 +787,8 @@ static int tegra_spi_start_transfer_one(struct spi_device *spi,
if
(
tspi
->
is_packed
)
command1
|=
SPI_PACKED
;
else
command1
&=
~
SPI_PACKED
;
command1
&=
~
(
SPI_CS_SEL_MASK
|
SPI_TX_EN
|
SPI_RX_EN
);
tspi
->
cur_direction
=
0
;
...
...
@@ -753,6 +807,9 @@ static int tegra_spi_start_transfer_one(struct spi_device *spi,
dev_dbg
(
tspi
->
dev
,
"The def 0x%x and written 0x%x
\n
"
,
tspi
->
def_command1_reg
,
(
unsigned
)
command1
);
ret
=
tegra_spi_flush_fifos
(
tspi
);
if
(
ret
<
0
)
return
ret
;
if
(
total_fifo_words
>
SPI_FIFO_DEPTH
)
ret
=
tegra_spi_start_dma_based_transfer
(
tspi
,
t
);
else
...
...
@@ -804,6 +861,19 @@ static void tegra_spi_transfer_delay(int delay)
udelay
(
delay
%
1000
);
}
static
void
tegra_spi_transfer_end
(
struct
spi_device
*
spi
)
{
struct
tegra_spi_data
*
tspi
=
spi_master_get_devdata
(
spi
->
master
);
int
cs_val
=
(
spi
->
mode
&
SPI_CS_HIGH
)
?
0
:
1
;
if
(
cs_val
)
tspi
->
command1_reg
|=
SPI_CS_SW_VAL
;
else
tspi
->
command1_reg
&=
~
SPI_CS_SW_VAL
;
tegra_spi_writel
(
tspi
,
tspi
->
command1_reg
,
SPI_COMMAND1
);
tegra_spi_writel
(
tspi
,
tspi
->
def_command1_reg
,
SPI_COMMAND1
);
}
static
int
tegra_spi_transfer_one_message
(
struct
spi_master
*
master
,
struct
spi_message
*
msg
)
{
...
...
@@ -843,7 +913,17 @@ static int tegra_spi_transfer_one_message(struct spi_master *master,
if
(
WARN_ON
(
ret
==
0
))
{
dev_err
(
tspi
->
dev
,
"spi transfer timeout, err %d
\n
"
,
ret
);
if
(
tspi
->
is_curr_dma_xfer
&&
(
tspi
->
cur_direction
&
DATA_DIR_TX
))
dmaengine_terminate_all
(
tspi
->
tx_dma_chan
);
if
(
tspi
->
is_curr_dma_xfer
&&
(
tspi
->
cur_direction
&
DATA_DIR_RX
))
dmaengine_terminate_all
(
tspi
->
rx_dma_chan
);
ret
=
-
EIO
;
tegra_spi_flush_fifos
(
tspi
);
reset_control_assert
(
tspi
->
rst
);
udelay
(
2
);
reset_control_deassert
(
tspi
->
rst
);
goto
complete_xfer
;
}
...
...
@@ -856,8 +936,7 @@ static int tegra_spi_transfer_one_message(struct spi_master *master,
complete_xfer:
if
(
ret
<
0
||
skip
)
{
tegra_spi_writel
(
tspi
,
tspi
->
def_command1_reg
,
SPI_COMMAND1
);
tegra_spi_transfer_end
(
spi
);
tegra_spi_transfer_delay
(
xfer
->
delay_usecs
);
goto
exit
;
}
else
if
(
list_is_last
(
&
xfer
->
transfer_list
,
...
...
@@ -865,13 +944,11 @@ static int tegra_spi_transfer_one_message(struct spi_master *master,
if
(
xfer
->
cs_change
)
tspi
->
cs_control
=
spi
;
else
{
tegra_spi_writel
(
tspi
,
tspi
->
def_command1_reg
,
SPI_COMMAND1
);
tegra_spi_transfer_end
(
spi
);
tegra_spi_transfer_delay
(
xfer
->
delay_usecs
);
}
}
else
if
(
xfer
->
cs_change
)
{
tegra_spi_writel
(
tspi
,
tspi
->
def_command1_reg
,
SPI_COMMAND1
);
tegra_spi_transfer_end
(
spi
);
tegra_spi_transfer_delay
(
xfer
->
delay_usecs
);
}
...
...
@@ -894,11 +971,13 @@ static irqreturn_t handle_cpu_based_xfer(struct tegra_spi_data *tspi)
tspi
->
status_reg
);
dev_err
(
tspi
->
dev
,
"CpuXfer 0x%08x:0x%08x
\n
"
,
tspi
->
command1_reg
,
tspi
->
dma_control_reg
);
tegra_spi_flush_fifos
(
tspi
);
complete
(
&
tspi
->
xfer_completion
);
spin_unlock_irqrestore
(
&
tspi
->
lock
,
flags
);
reset_control_assert
(
tspi
->
rst
);
udelay
(
2
);
reset_control_deassert
(
tspi
->
rst
);
complete
(
&
tspi
->
xfer_completion
);
goto
exit
;
return
IRQ_HANDLED
;
}
if
(
tspi
->
cur_direction
&
DATA_DIR_RX
)
...
...
@@ -966,11 +1045,12 @@ static irqreturn_t handle_dma_based_xfer(struct tegra_spi_data *tspi)
tspi
->
status_reg
);
dev_err
(
tspi
->
dev
,
"DmaXfer 0x%08x:0x%08x
\n
"
,
tspi
->
command1_reg
,
tspi
->
dma_control_reg
);
tegra_spi_flush_fifos
(
tspi
);
complete
(
&
tspi
->
xfer_completion
);
spin_unlock_irqrestore
(
&
tspi
->
lock
,
flags
);
reset_control_assert
(
tspi
->
rst
);
udelay
(
2
);
reset_control_deassert
(
tspi
->
rst
);
complete
(
&
tspi
->
xfer_completion
);
spin_unlock_irqrestore
(
&
tspi
->
lock
,
flags
);
return
IRQ_HANDLED
;
}
...
...
@@ -1072,27 +1152,19 @@ static int tegra_spi_probe(struct platform_device *pdev)
spi_irq
=
platform_get_irq
(
pdev
,
0
);
tspi
->
irq
=
spi_irq
;
ret
=
request_threaded_irq
(
tspi
->
irq
,
tegra_spi_isr
,
tegra_spi_isr_thread
,
IRQF_ONESHOT
,
dev_name
(
&
pdev
->
dev
),
tspi
);
if
(
ret
<
0
)
{
dev_err
(
&
pdev
->
dev
,
"Failed to register ISR for IRQ %d
\n
"
,
tspi
->
irq
);
goto
exit_free_master
;
}
tspi
->
clk
=
devm_clk_get
(
&
pdev
->
dev
,
"spi"
);
if
(
IS_ERR
(
tspi
->
clk
))
{
dev_err
(
&
pdev
->
dev
,
"can not get clock
\n
"
);
ret
=
PTR_ERR
(
tspi
->
clk
);
goto
exit_free_
irq
;
goto
exit_free_
master
;
}
tspi
->
rst
=
devm_reset_control_get_exclusive
(
&
pdev
->
dev
,
"spi"
);
if
(
IS_ERR
(
tspi
->
rst
))
{
dev_err
(
&
pdev
->
dev
,
"can not get reset
\n
"
);
ret
=
PTR_ERR
(
tspi
->
rst
);
goto
exit_free_
irq
;
goto
exit_free_
master
;
}
tspi
->
max_buf_size
=
SPI_FIFO_DEPTH
<<
2
;
...
...
@@ -1100,7 +1172,7 @@ static int tegra_spi_probe(struct platform_device *pdev)
ret
=
tegra_spi_init_dma_param
(
tspi
,
true
);
if
(
ret
<
0
)
goto
exit_free_
irq
;
goto
exit_free_
master
;
ret
=
tegra_spi_init_dma_param
(
tspi
,
false
);
if
(
ret
<
0
)
goto
exit_rx_dma_free
;
...
...
@@ -1122,18 +1194,32 @@ static int tegra_spi_probe(struct platform_device *pdev)
dev_err
(
&
pdev
->
dev
,
"pm runtime get failed, e = %d
\n
"
,
ret
);
goto
exit_pm_disable
;
}
reset_control_assert
(
tspi
->
rst
);
udelay
(
2
);
reset_control_deassert
(
tspi
->
rst
);
tspi
->
def_command1_reg
=
SPI_M_S
;
tegra_spi_writel
(
tspi
,
tspi
->
def_command1_reg
,
SPI_COMMAND1
);
pm_runtime_put
(
&
pdev
->
dev
);
ret
=
request_threaded_irq
(
tspi
->
irq
,
tegra_spi_isr
,
tegra_spi_isr_thread
,
IRQF_ONESHOT
,
dev_name
(
&
pdev
->
dev
),
tspi
);
if
(
ret
<
0
)
{
dev_err
(
&
pdev
->
dev
,
"Failed to register ISR for IRQ %d
\n
"
,
tspi
->
irq
);
goto
exit_pm_disable
;
}
master
->
dev
.
of_node
=
pdev
->
dev
.
of_node
;
ret
=
devm_spi_register_master
(
&
pdev
->
dev
,
master
);
if
(
ret
<
0
)
{
dev_err
(
&
pdev
->
dev
,
"can not register to master err %d
\n
"
,
ret
);
goto
exit_
pm_disable
;
goto
exit_
free_irq
;
}
return
ret
;
exit_free_irq:
free_irq
(
spi_irq
,
tspi
);
exit_pm_disable:
pm_runtime_disable
(
&
pdev
->
dev
);
if
(
!
pm_runtime_status_suspended
(
&
pdev
->
dev
))
...
...
@@ -1141,8 +1227,6 @@ static int tegra_spi_probe(struct platform_device *pdev)
tegra_spi_deinit_dma_param
(
tspi
,
false
);
exit_rx_dma_free:
tegra_spi_deinit_dma_param
(
tspi
,
true
);
exit_free_irq:
free_irq
(
spi_irq
,
tspi
);
exit_free_master:
spi_master_put
(
master
);
return
ret
;
...
...
This diff is collapsed.
Click to expand it.
drivers/spi/spi-tegra20-slink.c
View file @
e1a7d167
...
...
@@ -717,9 +717,6 @@ static int tegra_slink_start_transfer_one(struct spi_device *spi,
command2
=
tspi
->
command2_reg
;
command2
&=
~
(
SLINK_RXEN
|
SLINK_TXEN
);
tegra_slink_writel
(
tspi
,
command
,
SLINK_COMMAND
);
tspi
->
command_reg
=
command
;
tspi
->
cur_direction
=
0
;
if
(
t
->
rx_buf
)
{
command2
|=
SLINK_RXEN
;
...
...
@@ -729,9 +726,18 @@ static int tegra_slink_start_transfer_one(struct spi_device *spi,
command2
|=
SLINK_TXEN
;
tspi
->
cur_direction
|=
DATA_DIR_TX
;
}
/*
* Writing to the command2 register bevore the command register prevents
* a spike in chip_select line 0. This selects the chip_select line
* before changing the chip_select value.
*/
tegra_slink_writel
(
tspi
,
command2
,
SLINK_COMMAND2
);
tspi
->
command2_reg
=
command2
;
tegra_slink_writel
(
tspi
,
command
,
SLINK_COMMAND
);
tspi
->
command_reg
=
command
;
if
(
total_fifo_words
>
SLINK_FIFO_DEPTH
)
ret
=
tegra_slink_start_dma_based_transfer
(
tspi
,
t
);
else
...
...
This diff is collapsed.
Click to expand it.
drivers/spi/spi-topcliff-pch.c
View file @
e1a7d167
...
...
@@ -1299,18 +1299,27 @@ static void pch_free_dma_buf(struct pch_spi_board_data *board_dat,
dma
->
rx_buf_virt
,
dma
->
rx_buf_dma
);
}
static
void
pch_alloc_dma_buf
(
struct
pch_spi_board_data
*
board_dat
,
static
int
pch_alloc_dma_buf
(
struct
pch_spi_board_data
*
board_dat
,
struct
pch_spi_data
*
data
)
{
struct
pch_spi_dma_ctrl
*
dma
;
int
ret
;
dma
=
&
data
->
dma
;
ret
=
0
;
/* Get Consistent memory for Tx DMA */
dma
->
tx_buf_virt
=
dma_alloc_coherent
(
&
board_dat
->
pdev
->
dev
,
PCH_BUF_SIZE
,
&
dma
->
tx_buf_dma
,
GFP_KERNEL
);
if
(
!
dma
->
tx_buf_virt
)
ret
=
-
ENOMEM
;
/* Get Consistent memory for Rx DMA */
dma
->
rx_buf_virt
=
dma_alloc_coherent
(
&
board_dat
->
pdev
->
dev
,
PCH_BUF_SIZE
,
&
dma
->
rx_buf_dma
,
GFP_KERNEL
);
if
(
!
dma
->
rx_buf_virt
)
ret
=
-
ENOMEM
;
return
ret
;
}
static
int
pch_spi_pd_probe
(
struct
platform_device
*
plat_dev
)
...
...
@@ -1387,7 +1396,9 @@ static int pch_spi_pd_probe(struct platform_device *plat_dev)
if
(
use_dma
)
{
dev_info
(
&
plat_dev
->
dev
,
"Use DMA for data transfers
\n
"
);
pch_alloc_dma_buf
(
board_dat
,
data
);
ret
=
pch_alloc_dma_buf
(
board_dat
,
data
);
if
(
ret
)
goto
err_spi_register_master
;
}
ret
=
spi_register_master
(
master
);
...
...
This diff is collapsed.
Click to expand it.
drivers/spi/spi.c
View file @
e1a7d167
...
...
@@ -2199,6 +2199,8 @@ static int spi_get_gpio_descs(struct spi_controller *ctlr)
*/
cs
[
i
]
=
devm_gpiod_get_index_optional
(
dev
,
"cs"
,
i
,
GPIOD_OUT_LOW
);
if
(
IS_ERR
(
cs
[
i
]))
return
PTR_ERR
(
cs
[
i
]);
if
(
cs
[
i
])
{
/*
...
...
This diff is collapsed.
Click to expand it.
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