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
2dc745b6
Commit
2dc745b6
authored
Sep 01, 2013
by
Mark Brown
Browse files
Options
Browse Files
Download
Plain Diff
Merge remote-tracking branch 'spi/topic/s3c64xx' into spi-next
parents
121a3966
c12f9643
Changes
1
Show whitespace changes
Inline
Side-by-side
Showing
1 changed file
with
43 additions
and
69 deletions
+43
-69
drivers/spi/spi-s3c64xx.c
drivers/spi/spi-s3c64xx.c
+43
-69
No files found.
drivers/spi/spi-s3c64xx.c
View file @
2dc745b6
...
@@ -172,7 +172,6 @@ struct s3c64xx_spi_port_config {
...
@@ -172,7 +172,6 @@ struct s3c64xx_spi_port_config {
* @master: Pointer to the SPI Protocol master.
* @master: Pointer to the SPI Protocol master.
* @cntrlr_info: Platform specific data for the controller this driver manages.
* @cntrlr_info: Platform specific data for the controller this driver manages.
* @tgl_spi: Pointer to the last CS left untoggled by the cs_change hint.
* @tgl_spi: Pointer to the last CS left untoggled by the cs_change hint.
* @queue: To log SPI xfer requests.
* @lock: Controller specific lock.
* @lock: Controller specific lock.
* @state: Set of FLAGS to indicate status.
* @state: Set of FLAGS to indicate status.
* @rx_dmach: Controller's DMA channel for Rx.
* @rx_dmach: Controller's DMA channel for Rx.
...
@@ -193,7 +192,6 @@ struct s3c64xx_spi_driver_data {
...
@@ -193,7 +192,6 @@ struct s3c64xx_spi_driver_data {
struct
spi_master
*
master
;
struct
spi_master
*
master
;
struct
s3c64xx_spi_info
*
cntrlr_info
;
struct
s3c64xx_spi_info
*
cntrlr_info
;
struct
spi_device
*
tgl_spi
;
struct
spi_device
*
tgl_spi
;
struct
list_head
queue
;
spinlock_t
lock
;
spinlock_t
lock
;
unsigned
long
sfr_start
;
unsigned
long
sfr_start
;
struct
completion
xfer_completion
;
struct
completion
xfer_completion
;
...
@@ -338,8 +336,10 @@ static int acquire_dma(struct s3c64xx_spi_driver_data *sdd)
...
@@ -338,8 +336,10 @@ static int acquire_dma(struct s3c64xx_spi_driver_data *sdd)
req
.
cap
=
DMA_SLAVE
;
req
.
cap
=
DMA_SLAVE
;
req
.
client
=
&
s3c64xx_spi_dma_client
;
req
.
client
=
&
s3c64xx_spi_dma_client
;
sdd
->
rx_dma
.
ch
=
(
void
*
)
sdd
->
ops
->
request
(
sdd
->
rx_dma
.
dmach
,
&
req
,
dev
,
"rx"
);
sdd
->
rx_dma
.
ch
=
(
struct
dma_chan
*
)(
unsigned
long
)
sdd
->
ops
->
request
(
sdd
->
tx_dma
.
ch
=
(
void
*
)
sdd
->
ops
->
request
(
sdd
->
tx_dma
.
dmach
,
&
req
,
dev
,
"tx"
);
sdd
->
rx_dma
.
dmach
,
&
req
,
dev
,
"rx"
);
sdd
->
tx_dma
.
ch
=
(
struct
dma_chan
*
)(
unsigned
long
)
sdd
->
ops
->
request
(
sdd
->
tx_dma
.
dmach
,
&
req
,
dev
,
"tx"
);
return
1
;
return
1
;
}
}
...
@@ -386,9 +386,10 @@ static void prepare_dma(struct s3c64xx_spi_dma_data *dma,
...
@@ -386,9 +386,10 @@ static void prepare_dma(struct s3c64xx_spi_dma_data *dma,
{
{
struct
s3c64xx_spi_driver_data
*
sdd
;
struct
s3c64xx_spi_driver_data
*
sdd
;
struct
dma_slave_config
config
;
struct
dma_slave_config
config
;
struct
scatterlist
sg
;
struct
dma_async_tx_descriptor
*
desc
;
struct
dma_async_tx_descriptor
*
desc
;
memset
(
&
config
,
0
,
sizeof
(
config
));
if
(
dma
->
direction
==
DMA_DEV_TO_MEM
)
{
if
(
dma
->
direction
==
DMA_DEV_TO_MEM
)
{
sdd
=
container_of
((
void
*
)
dma
,
sdd
=
container_of
((
void
*
)
dma
,
struct
s3c64xx_spi_driver_data
,
rx_dma
);
struct
s3c64xx_spi_driver_data
,
rx_dma
);
...
@@ -407,14 +408,8 @@ static void prepare_dma(struct s3c64xx_spi_dma_data *dma,
...
@@ -407,14 +408,8 @@ static void prepare_dma(struct s3c64xx_spi_dma_data *dma,
dmaengine_slave_config
(
dma
->
ch
,
&
config
);
dmaengine_slave_config
(
dma
->
ch
,
&
config
);
}
}
sg_init_table
(
&
sg
,
1
);
desc
=
dmaengine_prep_slave_single
(
dma
->
ch
,
buf
,
len
,
sg_dma_len
(
&
sg
)
=
len
;
dma
->
direction
,
DMA_PREP_INTERRUPT
);
sg_set_page
(
&
sg
,
pfn_to_page
(
PFN_DOWN
(
buf
)),
len
,
offset_in_page
(
buf
));
sg_dma_address
(
&
sg
)
=
buf
;
desc
=
dmaengine_prep_slave_sg
(
dma
->
ch
,
&
sg
,
1
,
dma
->
direction
,
DMA_PREP_INTERRUPT
);
desc
->
callback
=
s3c64xx_spi_dmacb
;
desc
->
callback
=
s3c64xx_spi_dmacb
;
desc
->
callback_param
=
dma
;
desc
->
callback_param
=
dma
;
...
@@ -431,15 +426,13 @@ static int s3c64xx_spi_prepare_transfer(struct spi_master *spi)
...
@@ -431,15 +426,13 @@ static int s3c64xx_spi_prepare_transfer(struct spi_master *spi)
dma_cap_mask_t
mask
;
dma_cap_mask_t
mask
;
int
ret
;
int
ret
;
if
(
is_polling
(
sdd
))
if
(
!
is_polling
(
sdd
))
{
return
0
;
dma_cap_zero
(
mask
);
dma_cap_zero
(
mask
);
dma_cap_set
(
DMA_SLAVE
,
mask
);
dma_cap_set
(
DMA_SLAVE
,
mask
);
/* Acquire DMA channels */
/* Acquire DMA channels */
sdd
->
rx_dma
.
ch
=
dma_request_slave_channel_compat
(
mask
,
filter
,
sdd
->
rx_dma
.
ch
=
dma_request_slave_channel_compat
(
mask
,
filter
,
(
void
*
)
sdd
->
rx_dma
.
dmach
,
dev
,
"rx"
);
(
void
*
)
sdd
->
rx_dma
.
dmach
,
dev
,
"rx"
);
if
(
!
sdd
->
rx_dma
.
ch
)
{
if
(
!
sdd
->
rx_dma
.
ch
)
{
dev_err
(
dev
,
"Failed to get RX DMA channel
\n
"
);
dev_err
(
dev
,
"Failed to get RX DMA channel
\n
"
);
ret
=
-
EBUSY
;
ret
=
-
EBUSY
;
...
@@ -447,12 +440,13 @@ static int s3c64xx_spi_prepare_transfer(struct spi_master *spi)
...
@@ -447,12 +440,13 @@ static int s3c64xx_spi_prepare_transfer(struct spi_master *spi)
}
}
sdd
->
tx_dma
.
ch
=
dma_request_slave_channel_compat
(
mask
,
filter
,
sdd
->
tx_dma
.
ch
=
dma_request_slave_channel_compat
(
mask
,
filter
,
(
void
*
)
sdd
->
tx_dma
.
dmach
,
dev
,
"tx"
);
(
void
*
)
sdd
->
tx_dma
.
dmach
,
dev
,
"tx"
);
if
(
!
sdd
->
tx_dma
.
ch
)
{
if
(
!
sdd
->
tx_dma
.
ch
)
{
dev_err
(
dev
,
"Failed to get TX DMA channel
\n
"
);
dev_err
(
dev
,
"Failed to get TX DMA channel
\n
"
);
ret
=
-
EBUSY
;
ret
=
-
EBUSY
;
goto
out_rx
;
goto
out_rx
;
}
}
}
ret
=
pm_runtime_get_sync
(
&
sdd
->
pdev
->
dev
);
ret
=
pm_runtime_get_sync
(
&
sdd
->
pdev
->
dev
);
if
(
ret
<
0
)
{
if
(
ret
<
0
)
{
...
@@ -1053,8 +1047,6 @@ static int s3c64xx_spi_setup(struct spi_device *spi)
...
@@ -1053,8 +1047,6 @@ static int s3c64xx_spi_setup(struct spi_device *spi)
struct
s3c64xx_spi_csinfo
*
cs
=
spi
->
controller_data
;
struct
s3c64xx_spi_csinfo
*
cs
=
spi
->
controller_data
;
struct
s3c64xx_spi_driver_data
*
sdd
;
struct
s3c64xx_spi_driver_data
*
sdd
;
struct
s3c64xx_spi_info
*
sci
;
struct
s3c64xx_spi_info
*
sci
;
struct
spi_message
*
msg
;
unsigned
long
flags
;
int
err
;
int
err
;
sdd
=
spi_master_get_devdata
(
spi
->
master
);
sdd
=
spi_master_get_devdata
(
spi
->
master
);
...
@@ -1068,6 +1060,7 @@ static int s3c64xx_spi_setup(struct spi_device *spi)
...
@@ -1068,6 +1060,7 @@ static int s3c64xx_spi_setup(struct spi_device *spi)
return
-
ENODEV
;
return
-
ENODEV
;
}
}
if
(
!
spi_get_ctldata
(
spi
))
{
/* Request gpio only if cs line is asserted by gpio pins */
/* Request gpio only if cs line is asserted by gpio pins */
if
(
sdd
->
cs_gpio
)
{
if
(
sdd
->
cs_gpio
)
{
err
=
gpio_request_one
(
cs
->
line
,
GPIOF_OUT_INIT_HIGH
,
err
=
gpio_request_one
(
cs
->
line
,
GPIOF_OUT_INIT_HIGH
,
...
@@ -1080,25 +1073,10 @@ static int s3c64xx_spi_setup(struct spi_device *spi)
...
@@ -1080,25 +1073,10 @@ static int s3c64xx_spi_setup(struct spi_device *spi)
}
}
}
}
if
(
!
spi_get_ctldata
(
spi
))
spi_set_ctldata
(
spi
,
cs
);
spi_set_ctldata
(
spi
,
cs
);
sci
=
sdd
->
cntrlr_info
;
spin_lock_irqsave
(
&
sdd
->
lock
,
flags
);
list_for_each_entry
(
msg
,
&
sdd
->
queue
,
queue
)
{
/* Is some mssg is already queued for this device */
if
(
msg
->
spi
==
spi
)
{
dev_err
(
&
spi
->
dev
,
"setup: attempt while mssg in queue!
\n
"
);
spin_unlock_irqrestore
(
&
sdd
->
lock
,
flags
);
err
=
-
EBUSY
;
goto
err_msgq
;
}
}
}
s
pin_unlock_irqrestore
(
&
sdd
->
lock
,
flags
)
;
s
ci
=
sdd
->
cntrlr_info
;
pm_runtime_get_sync
(
&
sdd
->
pdev
->
dev
);
pm_runtime_get_sync
(
&
sdd
->
pdev
->
dev
);
...
@@ -1146,7 +1124,6 @@ static int s3c64xx_spi_setup(struct spi_device *spi)
...
@@ -1146,7 +1124,6 @@ static int s3c64xx_spi_setup(struct spi_device *spi)
/* setup() returns with device de-selected */
/* setup() returns with device de-selected */
disable_cs
(
sdd
,
spi
);
disable_cs
(
sdd
,
spi
);
err_msgq:
gpio_free
(
cs
->
line
);
gpio_free
(
cs
->
line
);
spi_set_ctldata
(
spi
,
NULL
);
spi_set_ctldata
(
spi
,
NULL
);
...
@@ -1361,16 +1338,14 @@ static int s3c64xx_spi_probe(struct platform_device *pdev)
...
@@ -1361,16 +1338,14 @@ static int s3c64xx_spi_probe(struct platform_device *pdev)
if
(
!
sdd
->
pdev
->
dev
.
of_node
)
{
if
(
!
sdd
->
pdev
->
dev
.
of_node
)
{
res
=
platform_get_resource
(
pdev
,
IORESOURCE_DMA
,
0
);
res
=
platform_get_resource
(
pdev
,
IORESOURCE_DMA
,
0
);
if
(
!
res
)
{
if
(
!
res
)
{
dev_warn
(
&
pdev
->
dev
,
"Unable to get SPI tx dma "
dev_warn
(
&
pdev
->
dev
,
"Unable to get SPI tx dma resource. Switching to poll mode
\n
"
);
"resource. Switching to poll mode
\n
"
);
sdd
->
port_conf
->
quirks
=
S3C64XX_SPI_QUIRK_POLL
;
sdd
->
port_conf
->
quirks
=
S3C64XX_SPI_QUIRK_POLL
;
}
else
}
else
sdd
->
tx_dma
.
dmach
=
res
->
start
;
sdd
->
tx_dma
.
dmach
=
res
->
start
;
res
=
platform_get_resource
(
pdev
,
IORESOURCE_DMA
,
1
);
res
=
platform_get_resource
(
pdev
,
IORESOURCE_DMA
,
1
);
if
(
!
res
)
{
if
(
!
res
)
{
dev_warn
(
&
pdev
->
dev
,
"Unable to get SPI rx dma "
dev_warn
(
&
pdev
->
dev
,
"Unable to get SPI rx dma resource. Switching to poll mode
\n
"
);
"resource. Switching to poll mode
\n
"
);
sdd
->
port_conf
->
quirks
=
S3C64XX_SPI_QUIRK_POLL
;
sdd
->
port_conf
->
quirks
=
S3C64XX_SPI_QUIRK_POLL
;
}
else
}
else
sdd
->
rx_dma
.
dmach
=
res
->
start
;
sdd
->
rx_dma
.
dmach
=
res
->
start
;
...
@@ -1440,7 +1415,6 @@ static int s3c64xx_spi_probe(struct platform_device *pdev)
...
@@ -1440,7 +1415,6 @@ static int s3c64xx_spi_probe(struct platform_device *pdev)
spin_lock_init
(
&
sdd
->
lock
);
spin_lock_init
(
&
sdd
->
lock
);
init_completion
(
&
sdd
->
xfer_completion
);
init_completion
(
&
sdd
->
xfer_completion
);
INIT_LIST_HEAD
(
&
sdd
->
queue
);
ret
=
devm_request_irq
(
&
pdev
->
dev
,
irq
,
s3c64xx_spi_irq
,
0
,
ret
=
devm_request_irq
(
&
pdev
->
dev
,
irq
,
s3c64xx_spi_irq
,
0
,
"spi-s3c64xx"
,
sdd
);
"spi-s3c64xx"
,
sdd
);
...
@@ -1462,8 +1436,8 @@ static int s3c64xx_spi_probe(struct platform_device *pdev)
...
@@ -1462,8 +1436,8 @@ static int s3c64xx_spi_probe(struct platform_device *pdev)
dev_dbg
(
&
pdev
->
dev
,
"Samsung SoC SPI Driver loaded for Bus SPI-%d with %d Slaves attached
\n
"
,
dev_dbg
(
&
pdev
->
dev
,
"Samsung SoC SPI Driver loaded for Bus SPI-%d with %d Slaves attached
\n
"
,
sdd
->
port_id
,
master
->
num_chipselect
);
sdd
->
port_id
,
master
->
num_chipselect
);
dev_dbg
(
&
pdev
->
dev
,
"
\t
IOmem=[
0x%x-0x%x
]
\t
DMA=[Rx-%d, Tx-%d]
\n
"
,
dev_dbg
(
&
pdev
->
dev
,
"
\t
IOmem=[
%pR
]
\t
DMA=[Rx-%d, Tx-%d]
\n
"
,
mem_res
->
end
,
mem_res
->
start
,
mem_res
,
sdd
->
rx_dma
.
dmach
,
sdd
->
tx_dma
.
dmach
);
sdd
->
rx_dma
.
dmach
,
sdd
->
tx_dma
.
dmach
);
pm_runtime_enable
(
&
pdev
->
dev
);
pm_runtime_enable
(
&
pdev
->
dev
);
...
...
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