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
b50c6ac8
Commit
b50c6ac8
authored
Mar 04, 2019
by
Mark Brown
Browse files
Options
Browse Files
Download
Plain Diff
Merge branch 'spi-5.0' into spi-linus
parents
1c163f4c
b89fefda
Changes
11
Hide whitespace changes
Inline
Side-by-side
Showing
11 changed files
with
91 additions
and
76 deletions
+91
-76
drivers/spi/spi-dw.c
drivers/spi/spi-dw.c
+18
-18
drivers/spi/spi-fsl-dspi.c
drivers/spi/spi-fsl-dspi.c
+1
-1
drivers/spi/spi-fsl-lpspi.c
drivers/spi/spi-fsl-lpspi.c
+48
-44
drivers/spi/spi-gpio.c
drivers/spi/spi-gpio.c
+2
-2
drivers/spi/spi-mem.c
drivers/spi/spi-mem.c
+2
-1
drivers/spi/spi-npcm-pspi.c
drivers/spi/spi-npcm-pspi.c
+2
-1
drivers/spi/spi-omap2-mcspi.c
drivers/spi/spi-omap2-mcspi.c
+2
-2
drivers/spi/spi-pxa2xx.c
drivers/spi/spi-pxa2xx.c
+1
-0
drivers/spi/spi-sprd.c
drivers/spi/spi-sprd.c
+6
-4
drivers/spi/spi-ti-qspi.c
drivers/spi/spi-ti-qspi.c
+3
-3
drivers/spi/spi-topcliff-pch.c
drivers/spi/spi-topcliff-pch.c
+6
-0
No files found.
drivers/spi/spi-dw.c
View file @
b50c6ac8
...
...
@@ -54,41 +54,41 @@ static ssize_t dw_spi_show_regs(struct file *file, char __user *user_buf,
if
(
!
buf
)
return
0
;
len
+=
snprintf
(
buf
+
len
,
SPI_REGS_BUFSIZE
-
len
,
len
+=
s
c
nprintf
(
buf
+
len
,
SPI_REGS_BUFSIZE
-
len
,
"%s registers:
\n
"
,
dev_name
(
&
dws
->
master
->
dev
));
len
+=
snprintf
(
buf
+
len
,
SPI_REGS_BUFSIZE
-
len
,
len
+=
s
c
nprintf
(
buf
+
len
,
SPI_REGS_BUFSIZE
-
len
,
"=================================
\n
"
);
len
+=
snprintf
(
buf
+
len
,
SPI_REGS_BUFSIZE
-
len
,
len
+=
s
c
nprintf
(
buf
+
len
,
SPI_REGS_BUFSIZE
-
len
,
"CTRL0:
\t\t
0x%08x
\n
"
,
dw_readl
(
dws
,
DW_SPI_CTRL0
));
len
+=
snprintf
(
buf
+
len
,
SPI_REGS_BUFSIZE
-
len
,
len
+=
s
c
nprintf
(
buf
+
len
,
SPI_REGS_BUFSIZE
-
len
,
"CTRL1:
\t\t
0x%08x
\n
"
,
dw_readl
(
dws
,
DW_SPI_CTRL1
));
len
+=
snprintf
(
buf
+
len
,
SPI_REGS_BUFSIZE
-
len
,
len
+=
s
c
nprintf
(
buf
+
len
,
SPI_REGS_BUFSIZE
-
len
,
"SSIENR:
\t
0x%08x
\n
"
,
dw_readl
(
dws
,
DW_SPI_SSIENR
));
len
+=
snprintf
(
buf
+
len
,
SPI_REGS_BUFSIZE
-
len
,
len
+=
s
c
nprintf
(
buf
+
len
,
SPI_REGS_BUFSIZE
-
len
,
"SER:
\t\t
0x%08x
\n
"
,
dw_readl
(
dws
,
DW_SPI_SER
));
len
+=
snprintf
(
buf
+
len
,
SPI_REGS_BUFSIZE
-
len
,
len
+=
s
c
nprintf
(
buf
+
len
,
SPI_REGS_BUFSIZE
-
len
,
"BAUDR:
\t\t
0x%08x
\n
"
,
dw_readl
(
dws
,
DW_SPI_BAUDR
));
len
+=
snprintf
(
buf
+
len
,
SPI_REGS_BUFSIZE
-
len
,
len
+=
s
c
nprintf
(
buf
+
len
,
SPI_REGS_BUFSIZE
-
len
,
"TXFTLR:
\t
0x%08x
\n
"
,
dw_readl
(
dws
,
DW_SPI_TXFLTR
));
len
+=
snprintf
(
buf
+
len
,
SPI_REGS_BUFSIZE
-
len
,
len
+=
s
c
nprintf
(
buf
+
len
,
SPI_REGS_BUFSIZE
-
len
,
"RXFTLR:
\t
0x%08x
\n
"
,
dw_readl
(
dws
,
DW_SPI_RXFLTR
));
len
+=
snprintf
(
buf
+
len
,
SPI_REGS_BUFSIZE
-
len
,
len
+=
s
c
nprintf
(
buf
+
len
,
SPI_REGS_BUFSIZE
-
len
,
"TXFLR:
\t\t
0x%08x
\n
"
,
dw_readl
(
dws
,
DW_SPI_TXFLR
));
len
+=
snprintf
(
buf
+
len
,
SPI_REGS_BUFSIZE
-
len
,
len
+=
s
c
nprintf
(
buf
+
len
,
SPI_REGS_BUFSIZE
-
len
,
"RXFLR:
\t\t
0x%08x
\n
"
,
dw_readl
(
dws
,
DW_SPI_RXFLR
));
len
+=
snprintf
(
buf
+
len
,
SPI_REGS_BUFSIZE
-
len
,
len
+=
s
c
nprintf
(
buf
+
len
,
SPI_REGS_BUFSIZE
-
len
,
"SR:
\t\t
0x%08x
\n
"
,
dw_readl
(
dws
,
DW_SPI_SR
));
len
+=
snprintf
(
buf
+
len
,
SPI_REGS_BUFSIZE
-
len
,
len
+=
s
c
nprintf
(
buf
+
len
,
SPI_REGS_BUFSIZE
-
len
,
"IMR:
\t\t
0x%08x
\n
"
,
dw_readl
(
dws
,
DW_SPI_IMR
));
len
+=
snprintf
(
buf
+
len
,
SPI_REGS_BUFSIZE
-
len
,
len
+=
s
c
nprintf
(
buf
+
len
,
SPI_REGS_BUFSIZE
-
len
,
"ISR:
\t\t
0x%08x
\n
"
,
dw_readl
(
dws
,
DW_SPI_ISR
));
len
+=
snprintf
(
buf
+
len
,
SPI_REGS_BUFSIZE
-
len
,
len
+=
s
c
nprintf
(
buf
+
len
,
SPI_REGS_BUFSIZE
-
len
,
"DMACR:
\t\t
0x%08x
\n
"
,
dw_readl
(
dws
,
DW_SPI_DMACR
));
len
+=
snprintf
(
buf
+
len
,
SPI_REGS_BUFSIZE
-
len
,
len
+=
s
c
nprintf
(
buf
+
len
,
SPI_REGS_BUFSIZE
-
len
,
"DMATDLR:
\t
0x%08x
\n
"
,
dw_readl
(
dws
,
DW_SPI_DMATDLR
));
len
+=
snprintf
(
buf
+
len
,
SPI_REGS_BUFSIZE
-
len
,
len
+=
s
c
nprintf
(
buf
+
len
,
SPI_REGS_BUFSIZE
-
len
,
"DMARDLR:
\t
0x%08x
\n
"
,
dw_readl
(
dws
,
DW_SPI_DMARDLR
));
len
+=
snprintf
(
buf
+
len
,
SPI_REGS_BUFSIZE
-
len
,
len
+=
s
c
nprintf
(
buf
+
len
,
SPI_REGS_BUFSIZE
-
len
,
"=================================
\n
"
);
ret
=
simple_read_from_buffer
(
user_buf
,
count
,
ppos
,
buf
,
len
);
...
...
drivers/spi/spi-fsl-dspi.c
View file @
b50c6ac8
...
...
@@ -67,7 +67,7 @@
#define SPI_SR 0x2c
#define SPI_SR_EOQF 0x10000000
#define SPI_SR_TCFQF 0x80000000
#define SPI_SR_CLEAR 0x
daad
0000
#define SPI_SR_CLEAR 0x
9aaf
0000
#define SPI_RSER_TFFFE BIT(25)
#define SPI_RSER_TFFFD BIT(24)
...
...
drivers/spi/spi-fsl-lpspi.c
View file @
b50c6ac8
...
...
@@ -48,10 +48,13 @@
#define CR_RTF BIT(8)
#define CR_RST BIT(1)
#define CR_MEN BIT(0)
#define SR_MBF BIT(24)
#define SR_TCF BIT(10)
#define SR_FCF BIT(9)
#define SR_RDF BIT(1)
#define SR_TDF BIT(0)
#define IER_TCIE BIT(10)
#define IER_FCIE BIT(9)
#define IER_RDIE BIT(1)
#define IER_TDIE BIT(0)
#define CFGR1_PCSCFG BIT(27)
...
...
@@ -59,6 +62,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 RSR_RXEMPTY BIT(1)
#define TCR_CPOL BIT(31)
#define TCR_CPHA BIT(30)
...
...
@@ -161,28 +165,10 @@ static int lpspi_unprepare_xfer_hardware(struct spi_controller *controller)
return
0
;
}
static
int
fsl_lpspi_txfifo_empty
(
struct
fsl_lpspi_data
*
fsl_lpspi
)
{
u32
txcnt
;
unsigned
long
orig_jiffies
=
jiffies
;
do
{
txcnt
=
readl
(
fsl_lpspi
->
base
+
IMX7ULP_FSR
)
&
0xff
;
if
(
time_after
(
jiffies
,
orig_jiffies
+
msecs_to_jiffies
(
500
)))
{
dev_dbg
(
fsl_lpspi
->
dev
,
"txfifo empty timeout
\n
"
);
return
-
ETIMEDOUT
;
}
cond_resched
();
}
while
(
txcnt
);
return
0
;
}
static
void
fsl_lpspi_write_tx_fifo
(
struct
fsl_lpspi_data
*
fsl_lpspi
)
{
u8
txfifo_cnt
;
u32
temp
;
txfifo_cnt
=
readl
(
fsl_lpspi
->
base
+
IMX7ULP_FSR
)
&
0xff
;
...
...
@@ -193,9 +179,15 @@ static void fsl_lpspi_write_tx_fifo(struct fsl_lpspi_data *fsl_lpspi)
txfifo_cnt
++
;
}
if
(
!
fsl_lpspi
->
remain
&&
(
txfifo_cnt
<
fsl_lpspi
->
txfifosize
))
writel
(
0
,
fsl_lpspi
->
base
+
IMX7ULP_TDR
);
else
if
(
txfifo_cnt
<
fsl_lpspi
->
txfifosize
)
{
if
(
!
fsl_lpspi
->
is_slave
)
{
temp
=
readl
(
fsl_lpspi
->
base
+
IMX7ULP_TCR
);
temp
&=
~
TCR_CONTC
;
writel
(
temp
,
fsl_lpspi
->
base
+
IMX7ULP_TCR
);
}
fsl_lpspi_intctrl
(
fsl_lpspi
,
IER_FCIE
);
}
else
fsl_lpspi_intctrl
(
fsl_lpspi
,
IER_TDIE
);
}
...
...
@@ -276,10 +268,6 @@ static int fsl_lpspi_config(struct fsl_lpspi_data *fsl_lpspi)
u32
temp
;
int
ret
;
temp
=
CR_RST
;
writel
(
temp
,
fsl_lpspi
->
base
+
IMX7ULP_CR
);
writel
(
0
,
fsl_lpspi
->
base
+
IMX7ULP_CR
);
if
(
!
fsl_lpspi
->
is_slave
)
{
ret
=
fsl_lpspi_set_bitrate
(
fsl_lpspi
);
if
(
ret
)
...
...
@@ -370,6 +358,24 @@ static int fsl_lpspi_wait_for_completion(struct spi_controller *controller)
return
0
;
}
static
int
fsl_lpspi_reset
(
struct
fsl_lpspi_data
*
fsl_lpspi
)
{
u32
temp
;
/* Disable all interrupt */
fsl_lpspi_intctrl
(
fsl_lpspi
,
0
);
/* W1C for all flags in SR */
temp
=
0x3F
<<
8
;
writel
(
temp
,
fsl_lpspi
->
base
+
IMX7ULP_SR
);
/* Clear FIFO and disable module */
temp
=
CR_RRF
|
CR_RTF
;
writel
(
temp
,
fsl_lpspi
->
base
+
IMX7ULP_CR
);
return
0
;
}
static
int
fsl_lpspi_transfer_one
(
struct
spi_controller
*
controller
,
struct
spi_device
*
spi
,
struct
spi_transfer
*
t
)
...
...
@@ -391,11 +397,7 @@ static int fsl_lpspi_transfer_one(struct spi_controller *controller,
if
(
ret
)
return
ret
;
ret
=
fsl_lpspi_txfifo_empty
(
fsl_lpspi
);
if
(
ret
)
return
ret
;
fsl_lpspi_read_rx_fifo
(
fsl_lpspi
);
fsl_lpspi_reset
(
fsl_lpspi
);
return
0
;
}
...
...
@@ -408,7 +410,6 @@ static int fsl_lpspi_transfer_one_msg(struct spi_controller *controller,
struct
spi_device
*
spi
=
msg
->
spi
;
struct
spi_transfer
*
xfer
;
bool
is_first_xfer
=
true
;
u32
temp
;
int
ret
=
0
;
msg
->
status
=
0
;
...
...
@@ -428,13 +429,6 @@ static int fsl_lpspi_transfer_one_msg(struct spi_controller *controller,
}
complete:
if
(
!
fsl_lpspi
->
is_slave
)
{
/* de-assert SS, then finalize current message */
temp
=
readl
(
fsl_lpspi
->
base
+
IMX7ULP_TCR
);
temp
&=
~
TCR_CONTC
;
writel
(
temp
,
fsl_lpspi
->
base
+
IMX7ULP_TCR
);
}
msg
->
status
=
ret
;
spi_finalize_current_message
(
controller
);
...
...
@@ -443,20 +437,30 @@ static int fsl_lpspi_transfer_one_msg(struct spi_controller *controller,
static
irqreturn_t
fsl_lpspi_isr
(
int
irq
,
void
*
dev_id
)
{
u32
temp_SR
,
temp_IER
;
struct
fsl_lpspi_data
*
fsl_lpspi
=
dev_id
;
u32
temp
;
temp_IER
=
readl
(
fsl_lpspi
->
base
+
IMX7ULP_IER
);
fsl_lpspi_intctrl
(
fsl_lpspi
,
0
);
temp
=
readl
(
fsl_lpspi
->
base
+
IMX7ULP_SR
);
temp
_SR
=
readl
(
fsl_lpspi
->
base
+
IMX7ULP_SR
);
fsl_lpspi_read_rx_fifo
(
fsl_lpspi
);
if
(
temp
&
SR_TDF
)
{
if
(
(
temp_SR
&
SR_TDF
)
&&
(
temp_IER
&
IER_TDIE
)
)
{
fsl_lpspi_write_tx_fifo
(
fsl_lpspi
);
return
IRQ_HANDLED
;
}
if
(
!
fsl_lpspi
->
remain
)
complete
(
&
fsl_lpspi
->
xfer_done
);
if
(
temp_SR
&
SR_MBF
||
readl
(
fsl_lpspi
->
base
+
IMX7ULP_FSR
)
&
FSR_RXCOUNT
)
{
writel
(
SR_FCF
,
fsl_lpspi
->
base
+
IMX7ULP_SR
);
fsl_lpspi_intctrl
(
fsl_lpspi
,
IER_FCIE
);
return
IRQ_HANDLED
;
}
if
(
temp_SR
&
SR_FCF
&&
(
temp_IER
&
IER_FCIE
))
{
writel
(
SR_FCF
,
fsl_lpspi
->
base
+
IMX7ULP_SR
);
complete
(
&
fsl_lpspi
->
xfer_done
);
return
IRQ_HANDLED
;
}
...
...
drivers/spi/spi-gpio.c
View file @
b50c6ac8
...
...
@@ -428,7 +428,8 @@ static int spi_gpio_probe(struct platform_device *pdev)
return
status
;
master
->
bits_per_word_mask
=
SPI_BPW_RANGE_MASK
(
1
,
32
);
master
->
mode_bits
=
SPI_3WIRE
|
SPI_3WIRE_HIZ
|
SPI_CPHA
|
SPI_CPOL
;
master
->
mode_bits
=
SPI_3WIRE
|
SPI_3WIRE_HIZ
|
SPI_CPHA
|
SPI_CPOL
|
SPI_CS_HIGH
;
master
->
flags
=
master_flags
;
master
->
bus_num
=
pdev
->
id
;
/* The master needs to think there is a chipselect even if not connected */
...
...
@@ -455,7 +456,6 @@ static int spi_gpio_probe(struct platform_device *pdev)
spi_gpio
->
bitbang
.
txrx_word
[
SPI_MODE_3
]
=
spi_gpio_spec_txrx_word_mode3
;
}
spi_gpio
->
bitbang
.
setup_transfer
=
spi_bitbang_setup_transfer
;
spi_gpio
->
bitbang
.
flags
=
SPI_CS_HIGH
;
status
=
spi_bitbang_start
(
&
spi_gpio
->
bitbang
);
if
(
status
)
...
...
drivers/spi/spi-mem.c
View file @
b50c6ac8
...
...
@@ -537,7 +537,6 @@ EXPORT_SYMBOL_GPL(spi_mem_dirmap_create);
/**
* spi_mem_dirmap_destroy() - Destroy a direct mapping descriptor
* @desc: the direct mapping descriptor to destroy
* @info: direct mapping information
*
* This function destroys a direct mapping descriptor previously created by
* spi_mem_dirmap_create().
...
...
@@ -548,6 +547,8 @@ void spi_mem_dirmap_destroy(struct spi_mem_dirmap_desc *desc)
if
(
!
desc
->
nodirmap
&&
ctlr
->
mem_ops
&&
ctlr
->
mem_ops
->
dirmap_destroy
)
ctlr
->
mem_ops
->
dirmap_destroy
(
desc
);
kfree
(
desc
);
}
EXPORT_SYMBOL_GPL
(
spi_mem_dirmap_destroy
);
...
...
drivers/spi/spi-npcm-pspi.c
View file @
b50c6ac8
...
...
@@ -465,7 +465,8 @@ static int npcm_pspi_probe(struct platform_device *pdev)
static
int
npcm_pspi_remove
(
struct
platform_device
*
pdev
)
{
struct
npcm_pspi
*
priv
=
platform_get_drvdata
(
pdev
);
struct
spi_master
*
master
=
platform_get_drvdata
(
pdev
);
struct
npcm_pspi
*
priv
=
spi_master_get_devdata
(
master
);
npcm_pspi_reset_hw
(
priv
);
clk_disable_unprepare
(
priv
->
clk
);
...
...
drivers/spi/spi-omap2-mcspi.c
View file @
b50c6ac8
...
...
@@ -623,8 +623,8 @@ omap2_mcspi_txrx_dma(struct spi_device *spi, struct spi_transfer *xfer)
cfg
.
dst_addr
=
cs
->
phys
+
OMAP2_MCSPI_TX0
;
cfg
.
src_addr_width
=
width
;
cfg
.
dst_addr_width
=
width
;
cfg
.
src_maxburst
=
es
;
cfg
.
dst_maxburst
=
es
;
cfg
.
src_maxburst
=
1
;
cfg
.
dst_maxburst
=
1
;
rx
=
xfer
->
rx_buf
;
tx
=
xfer
->
tx_buf
;
...
...
drivers/spi/spi-pxa2xx.c
View file @
b50c6ac8
...
...
@@ -1696,6 +1696,7 @@ static int pxa2xx_spi_probe(struct platform_device *pdev)
platform_info
->
enable_dma
=
false
;
}
else
{
master
->
can_dma
=
pxa2xx_spi_can_dma
;
master
->
max_dma_len
=
MAX_DMA_LEN
;
}
}
...
...
drivers/spi/spi-sprd.c
View file @
b50c6ac8
...
...
@@ -380,7 +380,7 @@ static int sprd_spi_txrx_bufs(struct spi_device *sdev, struct spi_transfer *t)
{
struct
sprd_spi
*
ss
=
spi_controller_get_devdata
(
sdev
->
controller
);
u32
trans_len
=
ss
->
trans_len
,
len
;
int
ret
,
write_size
=
0
;
int
ret
,
write_size
=
0
,
read_size
=
0
;
while
(
trans_len
)
{
len
=
trans_len
>
SPRD_SPI_FIFO_SIZE
?
SPRD_SPI_FIFO_SIZE
:
...
...
@@ -416,13 +416,15 @@ static int sprd_spi_txrx_bufs(struct spi_device *sdev, struct spi_transfer *t)
goto
complete
;
if
(
ss
->
trans_mode
&
SPRD_SPI_RX_MODE
)
ss
->
read_bufs
(
ss
,
len
);
read_size
+=
ss
->
read_bufs
(
ss
,
len
);
trans_len
-=
len
;
}
ret
=
write_size
;
if
(
ss
->
trans_mode
&
SPRD_SPI_TX_MODE
)
ret
=
write_size
;
else
ret
=
read_size
;
complete:
sprd_spi_enter_idle
(
ss
);
...
...
drivers/spi/spi-ti-qspi.c
View file @
b50c6ac8
...
...
@@ -490,8 +490,8 @@ static void ti_qspi_enable_memory_map(struct spi_device *spi)
ti_qspi_write
(
qspi
,
MM_SWITCH
,
QSPI_SPI_SWITCH_REG
);
if
(
qspi
->
ctrl_base
)
{
regmap_update_bits
(
qspi
->
ctrl_base
,
qspi
->
ctrl_reg
,
MEM_CS_
EN
(
spi
->
chip_select
)
,
MEM_CS_
MASK
);
MEM_CS_
MASK
,
MEM_CS_
EN
(
spi
->
chip_select
)
);
}
qspi
->
mmap_enabled
=
true
;
}
...
...
@@ -503,7 +503,7 @@ static void ti_qspi_disable_memory_map(struct spi_device *spi)
ti_qspi_write
(
qspi
,
0
,
QSPI_SPI_SWITCH_REG
);
if
(
qspi
->
ctrl_base
)
regmap_update_bits
(
qspi
->
ctrl_base
,
qspi
->
ctrl_reg
,
0
,
MEM_CS_MASK
);
MEM_CS_MASK
,
0
);
qspi
->
mmap_enabled
=
false
;
}
...
...
drivers/spi/spi-topcliff-pch.c
View file @
b50c6ac8
...
...
@@ -1008,6 +1008,9 @@ static void pch_spi_handle_dma(struct pch_spi_data *data, int *bpw)
/* RX */
dma
->
sg_rx_p
=
kcalloc
(
num
,
sizeof
(
*
dma
->
sg_rx_p
),
GFP_ATOMIC
);
if
(
!
dma
->
sg_rx_p
)
return
;
sg_init_table
(
dma
->
sg_rx_p
,
num
);
/* Initialize SG table */
/* offset, length setting */
sg
=
dma
->
sg_rx_p
;
...
...
@@ -1068,6 +1071,9 @@ static void pch_spi_handle_dma(struct pch_spi_data *data, int *bpw)
}
dma
->
sg_tx_p
=
kcalloc
(
num
,
sizeof
(
*
dma
->
sg_tx_p
),
GFP_ATOMIC
);
if
(
!
dma
->
sg_tx_p
)
return
;
sg_init_table
(
dma
->
sg_tx_p
,
num
);
/* Initialize SG table */
/* offset, length setting */
sg
=
dma
->
sg_tx_p
;
...
...
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