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
a4f2ca3e
Commit
a4f2ca3e
authored
Aug 29, 2013
by
Mark Brown
Browse files
Options
Browse Files
Download
Plain Diff
Merge remote-tracking branch 'spi/topic/xilinx' into spi-pdata
parents
d9740f6a
9ca1273b
Changes
1
Hide whitespace changes
Inline
Side-by-side
Showing
1 changed file
with
66 additions
and
106 deletions
+66
-106
drivers/spi/spi-xilinx.c
drivers/spi/spi-xilinx.c
+66
-106
No files found.
drivers/spi/spi-xilinx.c
View file @
a4f2ca3e
...
...
@@ -80,10 +80,9 @@ struct xilinx_spi {
/* bitbang has to be first */
struct
spi_bitbang
bitbang
;
struct
completion
done
;
struct
resource
mem
;
/* phys mem */
void
__iomem
*
regs
;
/* virt. address of the control registers */
u32
irq
;
int
irq
;
u8
*
rx_ptr
;
/* pointer in the Tx buffer */
const
u8
*
tx_ptr
;
/* pointer in the Rx buffer */
...
...
@@ -340,17 +339,34 @@ static const struct of_device_id xilinx_spi_of_match[] = {
};
MODULE_DEVICE_TABLE
(
of
,
xilinx_spi_of_match
);
struct
spi_master
*
xilinx_spi_init
(
struct
device
*
dev
,
struct
resource
*
mem
,
u32
irq
,
s16
bus_num
,
int
num_cs
,
int
bits_per_word
)
static
int
xilinx_spi_probe
(
struct
platform_device
*
pdev
)
{
struct
spi_master
*
master
;
struct
xilinx_spi
*
xspi
;
int
ret
;
struct
xspi_platform_data
*
pdata
;
struct
resource
*
res
;
int
ret
,
num_cs
=
0
,
bits_per_word
=
8
;
struct
spi_master
*
master
;
u32
tmp
;
u8
i
;
pdata
=
pdev
->
dev
.
platform_data
;
if
(
pdata
)
{
num_cs
=
pdata
->
num_chipselect
;
bits_per_word
=
pdata
->
bits_per_word
;
}
else
{
of_property_read_u32
(
pdev
->
dev
.
of_node
,
"xlnx,num-ss-bits"
,
&
num_cs
);
}
master
=
spi_alloc_master
(
dev
,
sizeof
(
struct
xilinx_spi
));
if
(
!
num_cs
)
{
dev_err
(
&
pdev
->
dev
,
"Missing slave select configuration data
\n
"
);
return
-
EINVAL
;
}
master
=
spi_alloc_master
(
&
pdev
->
dev
,
sizeof
(
struct
xilinx_spi
));
if
(
!
master
)
return
NULL
;
return
-
ENODEV
;
/* the spi->mode bits understood by this driver: */
master
->
mode_bits
=
SPI_CPOL
|
SPI_CPHA
;
...
...
@@ -362,22 +378,16 @@ struct spi_master *xilinx_spi_init(struct device *dev, struct resource *mem,
xspi
->
bitbang
.
txrx_bufs
=
xilinx_spi_txrx_bufs
;
init_completion
(
&
xspi
->
done
);
if
(
!
request_mem_region
(
mem
->
start
,
resource_size
(
mem
),
XILINX_SPI_NAME
))
res
=
platform_get_resource
(
pdev
,
IORESOURCE_MEM
,
0
);
xspi
->
regs
=
devm_ioremap_resource
(
&
pdev
->
dev
,
res
);
if
(
IS_ERR
(
xspi
->
regs
))
{
ret
=
PTR_ERR
(
xspi
->
regs
);
goto
put_master
;
xspi
->
regs
=
ioremap
(
mem
->
start
,
resource_size
(
mem
));
if
(
xspi
->
regs
==
NULL
)
{
dev_warn
(
dev
,
"ioremap failure
\n
"
);
goto
map_failed
;
}
master
->
bus_num
=
bus_num
;
master
->
bus_num
=
pdev
->
dev
.
id
;
master
->
num_chipselect
=
num_cs
;
master
->
dev
.
of_node
=
dev
->
of_node
;
xspi
->
mem
=
*
mem
;
xspi
->
irq
=
irq
;
master
->
dev
.
of_node
=
pdev
->
dev
.
of_node
;
/*
* Detect endianess on the IP via loop bit in CR. Detection
...
...
@@ -407,113 +417,63 @@ struct spi_master *xilinx_spi_init(struct device *dev, struct resource *mem,
}
else
if
(
xspi
->
bits_per_word
==
32
)
{
xspi
->
tx_fn
=
xspi_tx32
;
xspi
->
rx_fn
=
xspi_rx32
;
}
else
goto
unmap_io
;
}
else
{
ret
=
-
EINVAL
;
goto
put_master
;
}
/* SPI controller initializations */
xspi_init_hw
(
xspi
);
xspi
->
irq
=
platform_get_irq
(
pdev
,
0
);
if
(
xspi
->
irq
<
0
)
{
ret
=
xspi
->
irq
;
goto
put_master
;
}
/* Register for SPI Interrupt */
ret
=
request_irq
(
xspi
->
irq
,
xilinx_spi_irq
,
0
,
XILINX_SPI_NAME
,
xspi
);
ret
=
devm_request_irq
(
&
pdev
->
dev
,
xspi
->
irq
,
xilinx_spi_irq
,
0
,
dev_name
(
&
pdev
->
dev
),
xspi
);
if
(
ret
)
goto
unmap_io
;
goto
put_master
;
ret
=
spi_bitbang_start
(
&
xspi
->
bitbang
);
if
(
ret
)
{
dev_err
(
dev
,
"spi_bitbang_start FAILED
\n
"
);
goto
free_irq
;
}
dev_info
(
dev
,
"at 0x%08llX mapped to 0x%p, irq=%d
\n
"
,
(
unsigned
long
long
)
mem
->
start
,
xspi
->
regs
,
xspi
->
irq
);
return
master
;
free_irq:
free_irq
(
xspi
->
irq
,
xspi
);
unmap_io:
iounmap
(
xspi
->
regs
);
map_failed:
release_mem_region
(
mem
->
start
,
resource_size
(
mem
));
put_master:
spi_master_put
(
master
);
return
NULL
;
}
EXPORT_SYMBOL
(
xilinx_spi_init
);
void
xilinx_spi_deinit
(
struct
spi_master
*
master
)
{
struct
xilinx_spi
*
xspi
;
xspi
=
spi_master_get_devdata
(
master
);
spi_bitbang_stop
(
&
xspi
->
bitbang
);
free_irq
(
xspi
->
irq
,
xspi
);
iounmap
(
xspi
->
regs
);
release_mem_region
(
xspi
->
mem
.
start
,
resource_size
(
&
xspi
->
mem
));
spi_master_put
(
xspi
->
bitbang
.
master
);
}
EXPORT_SYMBOL
(
xilinx_spi_deinit
);
static
int
xilinx_spi_probe
(
struct
platform_device
*
dev
)
{
struct
xspi_platform_data
*
pdata
;
struct
resource
*
r
;
int
irq
,
num_cs
=
0
,
bits_per_word
=
8
;
struct
spi_master
*
master
;
u8
i
;
pdata
=
dev
->
dev
.
platform_data
;
if
(
pdata
)
{
num_cs
=
pdata
->
num_chipselect
;
bits_per_word
=
pdata
->
bits_per_word
;
}
#ifdef CONFIG_OF
if
(
dev
->
dev
.
of_node
)
{
const
__be32
*
prop
;
int
len
;
/* number of slave select bits is required */
prop
=
of_get_property
(
dev
->
dev
.
of_node
,
"xlnx,num-ss-bits"
,
&
len
);
if
(
prop
&&
len
>=
sizeof
(
*
prop
))
num_cs
=
__be32_to_cpup
(
prop
);
}
#endif
if
(
!
num_cs
)
{
dev_err
(
&
dev
->
dev
,
"Missing slave select configuration data
\n
"
);
return
-
EINVAL
;
dev_err
(
&
pdev
->
dev
,
"spi_bitbang_start FAILED
\n
"
);
goto
put_master
;
}
r
=
platform_get_resource
(
dev
,
IORESOURCE_MEM
,
0
);
if
(
!
r
)
return
-
ENODEV
;
irq
=
platform_get_irq
(
dev
,
0
);
if
(
irq
<
0
)
return
-
ENXIO
;
master
=
xilinx_spi_init
(
&
dev
->
dev
,
r
,
irq
,
dev
->
id
,
num_cs
,
bits_per_word
);
if
(
!
master
)
return
-
ENODEV
;
dev_info
(
&
pdev
->
dev
,
"at 0x%08llX mapped to 0x%p, irq=%d
\n
"
,
(
unsigned
long
long
)
res
->
start
,
xspi
->
regs
,
xspi
->
irq
);
if
(
pdata
)
{
for
(
i
=
0
;
i
<
pdata
->
num_devices
;
i
++
)
spi_new_device
(
master
,
pdata
->
devices
+
i
);
}
platform_set_drvdata
(
dev
,
master
);
platform_set_drvdata
(
p
dev
,
master
);
return
0
;
put_master:
spi_master_put
(
master
);
return
ret
;
}
static
int
xilinx_spi_remove
(
struct
platform_device
*
dev
)
static
int
xilinx_spi_remove
(
struct
platform_device
*
p
dev
)
{
xilinx_spi_deinit
(
platform_get_drvdata
(
dev
));
struct
spi_master
*
master
=
platform_get_drvdata
(
pdev
);
struct
xilinx_spi
*
xspi
=
spi_master_get_devdata
(
master
);
void
__iomem
*
regs_base
=
xspi
->
regs
;
spi_bitbang_stop
(
&
xspi
->
bitbang
);
/* Disable all the interrupts just in case */
xspi
->
write_fn
(
0
,
regs_base
+
XIPIF_V123B_IIER_OFFSET
);
/* Disable the global IPIF interrupt */
xspi
->
write_fn
(
0
,
regs_base
+
XIPIF_V123B_DGIER_OFFSET
);
spi_master_put
(
xspi
->
bitbang
.
master
);
return
0
;
}
...
...
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