Skip to content
GitLab
Menu
Projects
Groups
Snippets
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
Menu
Open sidebar
packages
kernel
linux
Commits
086e5551
Commit
086e5551
authored
Jan 12, 2020
by
Lorenzo "Palinuro" Faletra
Browse files
Import Upstream version 5.4.8
parent
d2ab784c
Changes
624
Hide whitespace changes
Inline
Side-by-side
drivers/acpi/button.c
View file @
086e5551
...
...
@@ -78,6 +78,17 @@ static const struct dmi_system_id lid_blacklst[] = {
DMI_MATCH
(
DMI_BIOS_VERSION
,
"BYT70A.YNCHENG.WIN.007"
),
},
},
{
/*
* Medion Akoya E2215T, notification of the LID device only
* happens on close, not on open and _LID always returns closed.
*/
.
matches
=
{
DMI_MATCH
(
DMI_SYS_VENDOR
,
"MEDION"
),
DMI_MATCH
(
DMI_PRODUCT_NAME
,
"E2215T MD60198"
),
},
.
driver_data
=
(
void
*
)(
long
)
ACPI_BUTTON_LID_INIT_OPEN
,
},
{}
};
...
...
drivers/ata/libata-core.c
View file @
086e5551
...
...
@@ -6708,6 +6708,9 @@ void ata_host_detach(struct ata_host *host)
{
int
i
;
/* Ensure ata_port probe has completed */
async_synchronize_full
();
for
(
i
=
0
;
i
<
host
->
n_ports
;
i
++
)
ata_port_detach
(
host
->
ports
[
i
]);
...
...
drivers/base/firmware_loader/builtin/Makefile
View file @
086e5551
...
...
@@ -8,7 +8,8 @@ fwdir := $(addprefix $(srctree)/,$(filter-out /%,$(fwdir)))$(filter /%,$(fwdir))
obj-y
:=
$(
addsuffix
.gen.o,
$(
subst
$(quote)
,,
$(CONFIG_EXTRA_FIRMWARE)
))
FWNAME
=
$(
patsubst
$(obj)
/%.gen.S,%,
$@
)
FWSTR
=
$(
subst
/,_,
$(
subst
.,_,
$(
subst
-,_,
$(FWNAME)
)))
comma
:=
,
FWSTR
=
$(
subst
$(comma)
,_,
$(
subst
/,_,
$(
subst
.,_,
$(
subst
-,_,
$(FWNAME)
))))
ASM_WORD
=
$(
if
$(CONFIG_64BIT)
,.quad,.long
)
ASM_ALIGN
=
$(
if
$(CONFIG_64BIT)
,3,2
)
PROGBITS
=
$(
if
$(CONFIG_ARM)
,%,@
)
progbits
...
...
drivers/block/loop.c
View file @
086e5551
...
...
@@ -417,18 +417,20 @@ static int lo_read_transfer(struct loop_device *lo, struct request *rq,
return
ret
;
}
static
int
lo_discard
(
struct
loop_device
*
lo
,
struct
request
*
rq
,
loff_t
pos
)
static
int
lo_fallocate
(
struct
loop_device
*
lo
,
struct
request
*
rq
,
loff_t
pos
,
int
mode
)
{
/*
* We use
punch hole to reclaim the free space
used by the
*
image
a.k.a. discard. However we do not support
discard
if
* encryption is enabled, because it may give an attacker
*
useful
information.
* We use
fallocate to manipulate the space mappings
used by the
image
* a.k.a. discard
/zerorange
. However we do not support
this
if
* encryption is enabled, because it may give an attacker
useful
* information.
*/
struct
file
*
file
=
lo
->
lo_backing_file
;
int
mode
=
FALLOC_FL_PUNCH_HOLE
|
FALLOC_FL_KEEP_SIZE
;
int
ret
;
mode
|=
FALLOC_FL_KEEP_SIZE
;
if
((
!
file
->
f_op
->
fallocate
)
||
lo
->
lo_encrypt_key_size
)
{
ret
=
-
EOPNOTSUPP
;
goto
out
;
...
...
@@ -596,9 +598,17 @@ static int do_req_filebacked(struct loop_device *lo, struct request *rq)
switch
(
req_op
(
rq
))
{
case
REQ_OP_FLUSH
:
return
lo_req_flush
(
lo
,
rq
);
case
REQ_OP_DISCARD
:
case
REQ_OP_WRITE_ZEROES
:
return
lo_discard
(
lo
,
rq
,
pos
);
/*
* If the caller doesn't want deallocation, call zeroout to
* write zeroes the range. Otherwise, punch them out.
*/
return
lo_fallocate
(
lo
,
rq
,
pos
,
(
rq
->
cmd_flags
&
REQ_NOUNMAP
)
?
FALLOC_FL_ZERO_RANGE
:
FALLOC_FL_PUNCH_HOLE
);
case
REQ_OP_DISCARD
:
return
lo_fallocate
(
lo
,
rq
,
pos
,
FALLOC_FL_PUNCH_HOLE
);
case
REQ_OP_WRITE
:
if
(
lo
->
transfer
)
return
lo_write_transfer
(
lo
,
rq
,
pos
);
...
...
drivers/block/nbd.c
View file @
086e5551
...
...
@@ -1296,10 +1296,10 @@ static int nbd_start_device_ioctl(struct nbd_device *nbd, struct block_device *b
mutex_unlock
(
&
nbd
->
config_lock
);
ret
=
wait_event_interruptible
(
config
->
recv_wq
,
atomic_read
(
&
config
->
recv_threads
)
==
0
);
if
(
ret
)
{
if
(
ret
)
sock_shutdown
(
nbd
);
flush_workqueue
(
nbd
->
recv_workq
);
}
flush_workqueue
(
nbd
->
recv_workq
);
mutex_lock
(
&
nbd
->
config_lock
);
nbd_bdev_reset
(
bdev
);
/* user requested, ignore socket errors */
...
...
drivers/bluetooth/btusb.c
View file @
086e5551
...
...
@@ -3807,8 +3807,8 @@ static int btusb_probe(struct usb_interface *intf,
btusb_check_needs_reset_resume
(
intf
);
}
#ifdef
CONFIG_BT_HCIBTUSB_RTL
if
(
id
->
driver_info
&
BTUSB_REALTEK
)
{
if
(
IS_ENABLED
(
CONFIG_BT_HCIBTUSB_RTL
)
&&
(
id
->
driver_info
&
BTUSB_REALTEK
)
)
{
hdev
->
setup
=
btrtl_setup_realtek
;
hdev
->
shutdown
=
btrtl_shutdown_realtek
;
hdev
->
cmd_timeout
=
btusb_rtl_cmd_timeout
;
...
...
@@ -3819,7 +3819,6 @@ static int btusb_probe(struct usb_interface *intf,
*/
set_bit
(
BTUSB_WAKEUP_DISABLE
,
&
data
->
flags
);
}
#endif
if
(
id
->
driver_info
&
BTUSB_AMP
)
{
/* AMP controllers do not support SCO packets */
...
...
drivers/cdrom/cdrom.c
View file @
086e5551
...
...
@@ -996,6 +996,12 @@ static void cdrom_count_tracks(struct cdrom_device_info *cdi, tracktype *tracks)
tracks
->
xa
=
0
;
tracks
->
error
=
0
;
cd_dbg
(
CD_COUNT_TRACKS
,
"entering cdrom_count_tracks
\n
"
);
if
(
!
CDROM_CAN
(
CDC_PLAY_AUDIO
))
{
tracks
->
error
=
CDS_NO_INFO
;
return
;
}
/* Grab the TOC header so we can see how many tracks there are */
ret
=
cdi
->
ops
->
audio_ioctl
(
cdi
,
CDROMREADTOCHDR
,
&
header
);
if
(
ret
)
{
...
...
@@ -1162,7 +1168,8 @@ int cdrom_open(struct cdrom_device_info *cdi, struct block_device *bdev,
ret
=
open_for_data
(
cdi
);
if
(
ret
)
goto
err
;
cdrom_mmc3_profile
(
cdi
);
if
(
CDROM_CAN
(
CDC_GENERIC_PACKET
))
cdrom_mmc3_profile
(
cdi
);
if
(
mode
&
FMODE_WRITE
)
{
ret
=
-
EROFS
;
if
(
cdrom_open_write
(
cdi
))
...
...
@@ -2882,6 +2889,9 @@ int cdrom_get_last_written(struct cdrom_device_info *cdi, long *last_written)
it doesn't give enough information or fails. then we return
the toc contents. */
use_toc:
if
(
!
CDROM_CAN
(
CDC_PLAY_AUDIO
))
return
-
ENOSYS
;
toc
.
cdte_format
=
CDROM_MSF
;
toc
.
cdte_track
=
CDROM_LEADOUT
;
if
((
ret
=
cdi
->
ops
->
audio_ioctl
(
cdi
,
CDROMREADTOCENTRY
,
&
toc
)))
...
...
drivers/char/hw_random/omap3-rom-rng.c
View file @
086e5551
...
...
@@ -121,7 +121,8 @@ static int omap3_rom_rng_remove(struct platform_device *pdev)
{
cancel_delayed_work_sync
(
&
idle_work
);
hwrng_unregister
(
&
omap3_rom_rng_ops
);
clk_disable_unprepare
(
rng_clk
);
if
(
!
rng_idle
)
clk_disable_unprepare
(
rng_clk
);
return
0
;
}
...
...
drivers/char/ipmi/ipmi_msghandler.c
View file @
086e5551
...
...
@@ -448,6 +448,8 @@ enum ipmi_stat_indexes {
#define IPMI_IPMB_NUM_SEQ 64
struct
ipmi_smi
{
struct
module
*
owner
;
/* What interface number are we? */
int
intf_num
;
...
...
@@ -1220,6 +1222,11 @@ int ipmi_create_user(unsigned int if_num,
if
(
rv
)
goto
out_kfree
;
if
(
!
try_module_get
(
intf
->
owner
))
{
rv
=
-
ENODEV
;
goto
out_kfree
;
}
/* Note that each existing user holds a refcount to the interface. */
kref_get
(
&
intf
->
refcount
);
...
...
@@ -1349,6 +1356,7 @@ static void _ipmi_destroy_user(struct ipmi_user *user)
}
kref_put
(
&
intf
->
refcount
,
intf_free
);
module_put
(
intf
->
owner
);
}
int
ipmi_destroy_user
(
struct
ipmi_user
*
user
)
...
...
@@ -2459,7 +2467,7 @@ static int __get_device_id(struct ipmi_smi *intf, struct bmc_device *bmc)
* been recently fetched, this will just use the cached data. Otherwise
* it will run a new fetch.
*
* Except for the first time this is called (in ipmi_
register
_smi()),
* Except for the first time this is called (in ipmi_
add
_smi()),
* this will always return good data;
*/
static
int
__bmc_get_device_id
(
struct
ipmi_smi
*
intf
,
struct
bmc_device
*
bmc
,
...
...
@@ -3377,10 +3385,11 @@ static void redo_bmc_reg(struct work_struct *work)
kref_put
(
&
intf
->
refcount
,
intf_free
);
}
int
ipmi_register_smi
(
const
struct
ipmi_smi_handlers
*
handlers
,
void
*
send_info
,
struct
device
*
si_dev
,
unsigned
char
slave_addr
)
int
ipmi_add_smi
(
struct
module
*
owner
,
const
struct
ipmi_smi_handlers
*
handlers
,
void
*
send_info
,
struct
device
*
si_dev
,
unsigned
char
slave_addr
)
{
int
i
,
j
;
int
rv
;
...
...
@@ -3406,7 +3415,7 @@ int ipmi_register_smi(const struct ipmi_smi_handlers *handlers,
return
rv
;
}
intf
->
owner
=
owner
;
intf
->
bmc
=
&
intf
->
tmp_bmc
;
INIT_LIST_HEAD
(
&
intf
->
bmc
->
intfs
);
mutex_init
(
&
intf
->
bmc
->
dyn_mutex
);
...
...
@@ -3514,7 +3523,7 @@ int ipmi_register_smi(const struct ipmi_smi_handlers *handlers,
return
rv
;
}
EXPORT_SYMBOL
(
ipmi_
register
_smi
);
EXPORT_SYMBOL
(
ipmi_
add
_smi
);
static
void
deliver_smi_err_response
(
struct
ipmi_smi
*
intf
,
struct
ipmi_smi_msg
*
msg
,
...
...
drivers/char/tpm/tpm-dev-common.c
View file @
086e5551
...
...
@@ -61,6 +61,12 @@ static void tpm_dev_async_work(struct work_struct *work)
mutex_lock
(
&
priv
->
buffer_mutex
);
priv
->
command_enqueued
=
false
;
ret
=
tpm_try_get_ops
(
priv
->
chip
);
if
(
ret
)
{
priv
->
response_length
=
ret
;
goto
out
;
}
ret
=
tpm_dev_transmit
(
priv
->
chip
,
priv
->
space
,
priv
->
data_buffer
,
sizeof
(
priv
->
data_buffer
));
tpm_put_ops
(
priv
->
chip
);
...
...
@@ -68,6 +74,7 @@ static void tpm_dev_async_work(struct work_struct *work)
priv
->
response_length
=
ret
;
mod_timer
(
&
priv
->
user_read_timer
,
jiffies
+
(
120
*
HZ
));
}
out:
mutex_unlock
(
&
priv
->
buffer_mutex
);
wake_up_interruptible
(
&
priv
->
async_wait
);
}
...
...
@@ -204,6 +211,7 @@ ssize_t tpm_common_write(struct file *file, const char __user *buf,
if
(
file
->
f_flags
&
O_NONBLOCK
)
{
priv
->
command_enqueued
=
true
;
queue_work
(
tpm_dev_wq
,
&
priv
->
async_work
);
tpm_put_ops
(
priv
->
chip
);
mutex_unlock
(
&
priv
->
buffer_mutex
);
return
size
;
}
...
...
drivers/char/tpm/tpm_tis_core.c
View file @
086e5551
...
...
@@ -899,13 +899,13 @@ int tpm_tis_core_init(struct device *dev, struct tpm_tis_data *priv, int irq,
if
(
wait_startup
(
chip
,
0
)
!=
0
)
{
rc
=
-
ENODEV
;
goto
out_err
;
goto
err_start
;
}
/* Take control of the TPM's interrupt hardware and shut it off */
rc
=
tpm_tis_read32
(
priv
,
TPM_INT_ENABLE
(
priv
->
locality
),
&
intmask
);
if
(
rc
<
0
)
goto
out_err
;
goto
err_start
;
intmask
|=
TPM_INTF_CMD_READY_INT
|
TPM_INTF_LOCALITY_CHANGE_INT
|
TPM_INTF_DATA_AVAIL_INT
|
TPM_INTF_STS_VALID_INT
;
...
...
@@ -914,21 +914,21 @@ int tpm_tis_core_init(struct device *dev, struct tpm_tis_data *priv, int irq,
rc
=
tpm_chip_start
(
chip
);
if
(
rc
)
goto
out_err
;
goto
err_start
;
rc
=
tpm2_probe
(
chip
);
tpm_chip_stop
(
chip
);
if
(
rc
)
goto
out_err
;
goto
err_probe
;
rc
=
tpm_tis_read32
(
priv
,
TPM_DID_VID
(
0
),
&
vendor
);
if
(
rc
<
0
)
goto
out_err
;
goto
err_probe
;
priv
->
manufacturer_id
=
vendor
;
rc
=
tpm_tis_read8
(
priv
,
TPM_RID
(
0
),
&
rid
);
if
(
rc
<
0
)
goto
out_err
;
goto
err_probe
;
dev_info
(
dev
,
"%s TPM (device-id 0x%X, rev-id %d)
\n
"
,
(
chip
->
flags
&
TPM_CHIP_FLAG_TPM2
)
?
"2.0"
:
"1.2"
,
...
...
@@ -937,13 +937,13 @@ int tpm_tis_core_init(struct device *dev, struct tpm_tis_data *priv, int irq,
probe
=
probe_itpm
(
chip
);
if
(
probe
<
0
)
{
rc
=
-
ENODEV
;
goto
out_err
;
goto
err_probe
;
}
/* Figure out the capabilities */
rc
=
tpm_tis_read32
(
priv
,
TPM_INTF_CAPS
(
priv
->
locality
),
&
intfcaps
);
if
(
rc
<
0
)
goto
out_err
;
goto
err_probe
;
dev_dbg
(
dev
,
"TPM interface capabilities (0x%x):
\n
"
,
intfcaps
);
...
...
@@ -977,10 +977,9 @@ int tpm_tis_core_init(struct device *dev, struct tpm_tis_data *priv, int irq,
if
(
tpm_get_timeouts
(
chip
))
{
dev_err
(
dev
,
"Could not get TPM timeouts and durations
\n
"
);
rc
=
-
ENODEV
;
goto
out_err
;
goto
err_probe
;
}
tpm_chip_start
(
chip
);
chip
->
flags
|=
TPM_CHIP_FLAG_IRQ
;
if
(
irq
)
{
tpm_tis_probe_irq_single
(
chip
,
intmask
,
IRQF_SHARED
,
...
...
@@ -991,18 +990,20 @@ int tpm_tis_core_init(struct device *dev, struct tpm_tis_data *priv, int irq,
}
else
{
tpm_tis_probe_irq
(
chip
,
intmask
);
}
tpm_chip_stop
(
chip
);
}
tpm_chip_stop
(
chip
);
rc
=
tpm_chip_register
(
chip
);
if
(
rc
)
goto
out_err
;
if
(
chip
->
ops
->
clk_enable
!=
NULL
)
chip
->
ops
->
clk_enable
(
chip
,
false
);
goto
err_start
;
return
0
;
out_err:
err_probe:
tpm_chip_stop
(
chip
);
err_start:
if
((
chip
->
ops
!=
NULL
)
&&
(
chip
->
ops
->
clk_enable
!=
NULL
))
chip
->
ops
->
clk_enable
(
chip
,
false
);
...
...
drivers/clk/clk-gpio.c
View file @
086e5551
...
...
@@ -280,7 +280,7 @@ static int gpio_clk_driver_probe(struct platform_device *pdev)
else
clk
=
clk_register_gpio_gate
(
&
pdev
->
dev
,
node
->
name
,
parent_names
?
parent_names
[
0
]
:
NULL
,
gpiod
,
0
);
CLK_SET_RATE_PARENT
);
if
(
IS_ERR
(
clk
))
return
PTR_ERR
(
clk
);
...
...
drivers/clk/imx/clk-composite-8m.c
View file @
086e5551
...
...
@@ -142,6 +142,7 @@ struct clk *imx8m_clk_composite_flags(const char *name,
mux
->
reg
=
reg
;
mux
->
shift
=
PCG_PCS_SHIFT
;
mux
->
mask
=
PCG_PCS_MASK
;
mux
->
lock
=
&
imx_ccm_lock
;
div
=
kzalloc
(
sizeof
(
*
div
),
GFP_KERNEL
);
if
(
!
div
)
...
...
@@ -161,6 +162,7 @@ struct clk *imx8m_clk_composite_flags(const char *name,
gate_hw
=
&
gate
->
hw
;
gate
->
reg
=
reg
;
gate
->
bit_idx
=
PCG_CGC_SHIFT
;
gate
->
lock
=
&
imx_ccm_lock
;
hw
=
clk_hw_register_composite
(
NULL
,
name
,
parent_names
,
num_parents
,
mux_hw
,
&
clk_mux_ops
,
div_hw
,
...
...
drivers/clk/imx/clk-imx7ulp.c
View file @
086e5551
...
...
@@ -40,6 +40,7 @@ static const struct clk_div_table ulp_div_table[] = {
{
.
val
=
5
,
.
div
=
16
,
},
{
.
val
=
6
,
.
div
=
32
,
},
{
.
val
=
7
,
.
div
=
64
,
},
{
/* sentinel */
},
};
static
const
int
pcc2_uart_clk_ids
[]
__initconst
=
{
...
...
drivers/clk/imx/clk-pll14xx.c
View file @
086e5551
...
...
@@ -153,7 +153,7 @@ static int clk_pll14xx_wait_lock(struct clk_pll14xx *pll)
{
u32
val
;
return
readl_poll_timeout
(
pll
->
base
,
val
,
val
&
LOCK_
TIMEOUT_
US
,
0
,
return
readl_poll_timeout
(
pll
->
base
,
val
,
val
&
LOCK_
STAT
US
,
0
,
LOCK_TIMEOUT_US
);
}
...
...
drivers/clk/pxa/clk-pxa27x.c
View file @
086e5551
...
...
@@ -459,6 +459,7 @@ struct dummy_clk {
};
static
struct
dummy_clk
dummy_clks
[]
__initdata
=
{
DUMMY_CLK
(
NULL
,
"pxa27x-gpio"
,
"osc_32_768khz"
),
DUMMY_CLK
(
NULL
,
"pxa-rtc"
,
"osc_32_768khz"
),
DUMMY_CLK
(
NULL
,
"sa1100-rtc"
,
"osc_32_768khz"
),
DUMMY_CLK
(
"UARTCLK"
,
"pxa2xx-ir"
,
"STUART"
),
};
...
...
drivers/clk/qcom/clk-rcg2.c
View file @
086e5551
...
...
@@ -220,6 +220,8 @@ static int _freq_tbl_determine_rate(struct clk_hw *hw, const struct freq_tbl *f,
if
(
clk_flags
&
CLK_SET_RATE_PARENT
)
{
rate
=
f
->
freq
;
if
(
f
->
pre_div
)
{
if
(
!
rate
)
rate
=
req
->
rate
;
rate
/=
2
;
rate
*=
f
->
pre_div
+
1
;
}
...
...
drivers/clk/qcom/clk-smd-rpm.c
View file @
086e5551
...
...
@@ -648,6 +648,7 @@ static const struct rpm_smd_clk_desc rpm_clk_qcs404 = {
};
/* msm8998 */
DEFINE_CLK_SMD_RPM
(
msm8998
,
pcnoc_clk
,
pcnoc_a_clk
,
QCOM_SMD_RPM_BUS_CLK
,
0
);
DEFINE_CLK_SMD_RPM
(
msm8998
,
snoc_clk
,
snoc_a_clk
,
QCOM_SMD_RPM_BUS_CLK
,
1
);
DEFINE_CLK_SMD_RPM
(
msm8998
,
cnoc_clk
,
cnoc_a_clk
,
QCOM_SMD_RPM_BUS_CLK
,
2
);
DEFINE_CLK_SMD_RPM
(
msm8998
,
ce1_clk
,
ce1_a_clk
,
QCOM_SMD_RPM_CE_CLK
,
0
);
...
...
@@ -670,6 +671,8 @@ DEFINE_CLK_SMD_RPM_XO_BUFFER_PINCTRL(msm8998, rf_clk2_pin, rf_clk2_a_pin, 5);
DEFINE_CLK_SMD_RPM_XO_BUFFER
(
msm8998
,
rf_clk3
,
rf_clk3_a
,
6
);
DEFINE_CLK_SMD_RPM_XO_BUFFER_PINCTRL
(
msm8998
,
rf_clk3_pin
,
rf_clk3_a_pin
,
6
);
static
struct
clk_smd_rpm
*
msm8998_clks
[]
=
{
[
RPM_SMD_PCNOC_CLK
]
=
&
msm8998_pcnoc_clk
,
[
RPM_SMD_PCNOC_A_CLK
]
=
&
msm8998_pcnoc_a_clk
,
[
RPM_SMD_SNOC_CLK
]
=
&
msm8998_snoc_clk
,
[
RPM_SMD_SNOC_A_CLK
]
=
&
msm8998_snoc_a_clk
,
[
RPM_SMD_CNOC_CLK
]
=
&
msm8998_cnoc_clk
,
...
...
drivers/clk/qcom/common.c
View file @
086e5551
...
...
@@ -29,6 +29,9 @@ struct freq_tbl *qcom_find_freq(const struct freq_tbl *f, unsigned long rate)
if
(
!
f
)
return
NULL
;
if
(
!
f
->
freq
)
return
f
;
for
(;
f
->
freq
;
f
++
)
if
(
rate
<=
f
->
freq
)
return
f
;
...
...
drivers/clocksource/asm9260_timer.c
View file @
086e5551
...
...
@@ -194,6 +194,10 @@ static int __init asm9260_timer_init(struct device_node *np)
}
clk
=
of_clk_get
(
np
,
0
);
if
(
IS_ERR
(
clk
))
{
pr_err
(
"Failed to get clk!
\n
"
);
return
PTR_ERR
(
clk
);
}
ret
=
clk_prepare_enable
(
clk
);
if
(
ret
)
{
...
...
Prev
1
2
3
4
5
6
7
8
…
32
Next
Write
Preview
Supports
Markdown
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