Skip to content
GitLab
Explore
Sign in
Primary navigation
Search or go to…
Project
L
linux-seco-intel
Manage
Activity
Members
Labels
Plan
Issues
0
Issue boards
Milestones
Wiki
Code
Merge requests
0
Repository
Branches
Commits
Tags
Repository graph
Compare revisions
Snippets
Locked files
Build
Pipelines
Jobs
Pipeline schedules
Artifacts
Deploy
Releases
Package Registry
Container Registry
Model registry
Operate
Environments
Terraform modules
Monitor
Incidents
Analyze
Value stream analytics
Contributor analytics
CI/CD analytics
Repository analytics
Code review analytics
Issue analytics
Model experiments
Help
Help
Support
GitLab documentation
Compare GitLab plans
Community forum
Contribute to GitLab
Provide feedback
Keyboard shortcuts
?
Snippets
Groups
Projects
Show more breadcrumbs
Nicola Sparnacci
linux-seco-intel
Commits
b14a8a80
Commit
b14a8a80
authored
8 years ago
by
Mark Brown
Browse files
Options
Downloads
Plain Diff
Merge remote-tracking branches 'spi/fix/atmel', 'spi/fix/mvbeu' and 'spi/fix/spidev' into spi-linus
parents
69973b83
39fe33f9
7243e0b2
e634b76c
No related branches found
Branches containing commit
No related tags found
Tags containing commit
No related merge requests found
Changes
3
Hide whitespace changes
Inline
Side-by-side
Showing
3 changed files
drivers/spi/spi-atmel.c
+44
-12
44 additions, 12 deletions
drivers/spi/spi-atmel.c
drivers/spi/spi-orion.c
+54
-29
54 additions, 29 deletions
drivers/spi/spi-orion.c
tools/spi/spidev_test.c
+1
-1
1 addition, 1 deletion
tools/spi/spidev_test.c
with
99 additions
and
42 deletions
drivers/spi/spi-atmel.c
+
44
−
12
View file @
b14a8a80
...
...
@@ -24,6 +24,7 @@
#include
<linux/io.h>
#include
<linux/gpio.h>
#include
<linux/of_gpio.h>
#include
<linux/pinctrl/consumer.h>
#include
<linux/pm_runtime.h>
...
...
@@ -295,6 +296,7 @@ struct atmel_spi {
int
irq
;
struct
clk
*
clk
;
struct
platform_device
*
pdev
;
unsigned
long
spi_clk
;
struct
spi_transfer
*
current_transfer
;
int
current_remaining_bytes
;
...
...
@@ -864,7 +866,7 @@ static int atmel_spi_set_xfer_speed(struct atmel_spi *as,
unsigned
long
bus_hz
;
/* v1 chips start out at half the peripheral bus speed. */
bus_hz
=
clk_get_rate
(
as
->
clk
)
;
bus_hz
=
as
->
spi_
clk
;
if
(
!
atmel_spi_is_v2
(
as
))
bus_hz
/=
2
;
...
...
@@ -1204,7 +1206,6 @@ static int atmel_spi_setup(struct spi_device *spi)
u32
csr
;
unsigned
int
bits
=
spi
->
bits_per_word
;
unsigned
int
npcs_pin
;
int
ret
;
as
=
spi_master_get_devdata
(
spi
->
master
);
...
...
@@ -1247,16 +1248,9 @@ static int atmel_spi_setup(struct spi_device *spi)
if
(
!
asd
)
return
-
ENOMEM
;
if
(
as
->
use_cs_gpios
)
{
ret
=
gpio_request
(
npcs_pin
,
dev_name
(
&
spi
->
dev
));
if
(
ret
)
{
kfree
(
asd
);
return
ret
;
}
if
(
as
->
use_cs_gpios
)
gpio_direction_output
(
npcs_pin
,
!
(
spi
->
mode
&
SPI_CS_HIGH
));
}
asd
->
npcs_pin
=
npcs_pin
;
spi
->
controller_state
=
asd
;
...
...
@@ -1471,13 +1465,11 @@ static int atmel_spi_transfer_one_message(struct spi_master *master,
static
void
atmel_spi_cleanup
(
struct
spi_device
*
spi
)
{
struct
atmel_spi_device
*
asd
=
spi
->
controller_state
;
unsigned
gpio
=
(
unsigned
long
)
spi
->
controller_data
;
if
(
!
asd
)
return
;
spi
->
controller_state
=
NULL
;
gpio_free
(
gpio
);
kfree
(
asd
);
}
...
...
@@ -1499,6 +1491,39 @@ static void atmel_get_caps(struct atmel_spi *as)
}
/*-------------------------------------------------------------------------*/
static
int
atmel_spi_gpio_cs
(
struct
platform_device
*
pdev
)
{
struct
spi_master
*
master
=
platform_get_drvdata
(
pdev
);
struct
atmel_spi
*
as
=
spi_master_get_devdata
(
master
);
struct
device_node
*
np
=
master
->
dev
.
of_node
;
int
i
;
int
ret
=
0
;
int
nb
=
0
;
if
(
!
as
->
use_cs_gpios
)
return
0
;
if
(
!
np
)
return
0
;
nb
=
of_gpio_named_count
(
np
,
"cs-gpios"
);
for
(
i
=
0
;
i
<
nb
;
i
++
)
{
int
cs_gpio
=
of_get_named_gpio
(
pdev
->
dev
.
of_node
,
"cs-gpios"
,
i
);
if
(
cs_gpio
==
-
EPROBE_DEFER
)
return
cs_gpio
;
if
(
gpio_is_valid
(
cs_gpio
))
{
ret
=
devm_gpio_request
(
&
pdev
->
dev
,
cs_gpio
,
dev_name
(
&
pdev
->
dev
));
if
(
ret
)
return
ret
;
}
}
return
0
;
}
static
int
atmel_spi_probe
(
struct
platform_device
*
pdev
)
{
...
...
@@ -1577,6 +1602,10 @@ static int atmel_spi_probe(struct platform_device *pdev)
master
->
num_chipselect
=
4
;
}
ret
=
atmel_spi_gpio_cs
(
pdev
);
if
(
ret
)
goto
out_unmap_regs
;
as
->
use_dma
=
false
;
as
->
use_pdc
=
false
;
if
(
as
->
caps
.
has_dma_support
)
{
...
...
@@ -1606,6 +1635,9 @@ static int atmel_spi_probe(struct platform_device *pdev)
ret
=
clk_prepare_enable
(
clk
);
if
(
ret
)
goto
out_free_irq
;
as
->
spi_clk
=
clk_get_rate
(
clk
);
spi_writel
(
as
,
CR
,
SPI_BIT
(
SWRST
));
spi_writel
(
as
,
CR
,
SPI_BIT
(
SWRST
));
/* AT91SAM9263 Rev B workaround */
if
(
as
->
caps
.
has_wdrbt
)
{
...
...
This diff is collapsed.
Click to expand it.
drivers/spi/spi-orion.c
+
54
−
29
View file @
b14a8a80
...
...
@@ -138,37 +138,62 @@ static int orion_spi_baudrate_set(struct spi_device *spi, unsigned int speed)
tclk_hz
=
clk_get_rate
(
orion_spi
->
clk
);
if
(
devdata
->
typ
==
ARMADA_SPI
)
{
unsigned
int
clk
,
spr
,
sppr
,
sppr2
,
err
;
unsigned
int
best_spr
,
best_sppr
,
best_err
;
best_err
=
speed
;
best_spr
=
0
;
best_sppr
=
0
;
/* Iterate over the valid range looking for best fit */
for
(
sppr
=
0
;
sppr
<
8
;
sppr
++
)
{
sppr2
=
0x1
<<
sppr
;
spr
=
tclk_hz
/
sppr2
;
spr
=
DIV_ROUND_UP
(
spr
,
speed
);
if
((
spr
==
0
)
||
(
spr
>
15
))
continue
;
clk
=
tclk_hz
/
(
spr
*
sppr2
);
err
=
speed
-
clk
;
if
(
err
<
best_err
)
{
best_spr
=
spr
;
best_sppr
=
sppr
;
best_err
=
err
;
}
}
/*
* Given the core_clk (tclk_hz) and the target rate (speed) we
* determine the best values for SPR (in [0 .. 15]) and SPPR (in
* [0..7]) such that
*
* core_clk / (SPR * 2 ** SPPR)
*
* is as big as possible but not bigger than speed.
*/
if
((
best_sppr
==
0
)
&&
(
best_spr
==
0
))
return
-
EINVAL
;
/* best integer divider: */
unsigned
divider
=
DIV_ROUND_UP
(
tclk_hz
,
speed
);
unsigned
spr
,
sppr
;
if
(
divider
<
16
)
{
/* This is the easy case, divider is less than 16 */
spr
=
divider
;
sppr
=
0
;
}
else
{
unsigned
two_pow_sppr
;
/*
* Find the highest bit set in divider. This and the
* three next bits define SPR (apart from rounding).
* SPPR is then the number of zero bits that must be
* appended:
*/
sppr
=
fls
(
divider
)
-
4
;
/*
* As SPR only has 4 bits, we have to round divider up
* to the next multiple of 2 ** sppr.
*/
two_pow_sppr
=
1
<<
sppr
;
divider
=
(
divider
+
two_pow_sppr
-
1
)
&
-
two_pow_sppr
;
/*
* recalculate sppr as rounding up divider might have
* increased it enough to change the position of the
* highest set bit. In this case the bit that now
* doesn't make it into SPR is 0, so there is no need to
* round again.
*/
sppr
=
fls
(
divider
)
-
4
;
spr
=
divider
>>
sppr
;
/*
* Now do range checking. SPR is constructed to have a
* width of 4 bits, so this is fine for sure. So we
* still need to check for sppr to fit into 3 bits:
*/
if
(
sppr
>
7
)
return
-
EINVAL
;
}
prescale
=
((
best_sppr
&
0x6
)
<<
5
)
|
((
best_sppr
&
0x1
)
<<
4
)
|
best_spr
;
prescale
=
((
sppr
&
0x6
)
<<
5
)
|
((
sppr
&
0x1
)
<<
4
)
|
spr
;
}
else
{
/*
* the supported rates are: 4,6,8...30
...
...
This diff is collapsed.
Click to expand it.
tools/spi/spidev_test.c
+
1
−
1
View file @
b14a8a80
...
...
@@ -315,7 +315,7 @@ static void transfer_file(int fd, char *filename)
pabort
(
"can't stat input file"
);
tx_fd
=
open
(
filename
,
O_RDONLY
);
if
(
fd
<
0
)
if
(
tx_
fd
<
0
)
pabort
(
"can't open input file"
);
tx
=
malloc
(
sb
.
st_size
);
...
...
This diff is collapsed.
Click to expand it.
Preview
0%
Loading
Try again
or
attach a new file
.
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Save comment
Cancel
Please
register
or
sign in
to comment