Commit ccce6deb authored by Alan Cox's avatar Alan Cox Committed by Live-CD User

serial: move the flags into the tty_port field

Fortunately the serial layer was designed to use the same flag values but
with different names. It has its own SUSPENDED flag which is a free slot in
the ASYNC flags so we allocate it in the ASYNC flags instead.
Signed-off-by: default avatarAlan Cox <alan@linux.intel.com>
Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@suse.de>
parent 91312cdb
...@@ -29,10 +29,10 @@ ...@@ -29,10 +29,10 @@
#include <linux/console.h> #include <linux/console.h>
#include <linux/proc_fs.h> #include <linux/proc_fs.h>
#include <linux/seq_file.h> #include <linux/seq_file.h>
#include <linux/serial_core.h>
#include <linux/smp_lock.h> #include <linux/smp_lock.h>
#include <linux/device.h> #include <linux/device.h>
#include <linux/serial.h> /* for serial_state and serial_icounter_struct */ #include <linux/serial.h> /* for serial_state and serial_icounter_struct */
#include <linux/serial_core.h>
#include <linux/delay.h> #include <linux/delay.h>
#include <linux/mutex.h> #include <linux/mutex.h>
...@@ -146,7 +146,7 @@ static int uart_startup(struct uart_state *state, int init_hw) ...@@ -146,7 +146,7 @@ static int uart_startup(struct uart_state *state, int init_hw)
unsigned long page; unsigned long page;
int retval = 0; int retval = 0;
if (state->flags & UIF_INITIALIZED) if (port->flags & ASYNC_INITIALIZED)
return 0; return 0;
/* /*
...@@ -189,14 +189,14 @@ static int uart_startup(struct uart_state *state, int init_hw) ...@@ -189,14 +189,14 @@ static int uart_startup(struct uart_state *state, int init_hw)
uart_set_mctrl(uport, TIOCM_RTS | TIOCM_DTR); uart_set_mctrl(uport, TIOCM_RTS | TIOCM_DTR);
} }
if (state->flags & UIF_CTS_FLOW) { if (port->flags & ASYNC_CTS_FLOW) {
spin_lock_irq(&uport->lock); spin_lock_irq(&uport->lock);
if (!(uport->ops->get_mctrl(uport) & TIOCM_CTS)) if (!(uport->ops->get_mctrl(uport) & TIOCM_CTS))
port->tty->hw_stopped = 1; port->tty->hw_stopped = 1;
spin_unlock_irq(&uport->lock); spin_unlock_irq(&uport->lock);
} }
state->flags |= UIF_INITIALIZED; set_bit(ASYNCB_INITIALIZED, &port->flags);
clear_bit(TTY_IO_ERROR, &port->tty->flags); clear_bit(TTY_IO_ERROR, &port->tty->flags);
} }
...@@ -214,7 +214,7 @@ static int uart_startup(struct uart_state *state, int init_hw) ...@@ -214,7 +214,7 @@ static int uart_startup(struct uart_state *state, int init_hw)
*/ */
static void uart_shutdown(struct uart_state *state) static void uart_shutdown(struct uart_state *state)
{ {
struct uart_port *port = state->uart_port; struct uart_port *uport = state->uart_port;
struct tty_struct *tty = state->port.tty; struct tty_struct *tty = state->port.tty;
/* /*
...@@ -223,14 +223,12 @@ static void uart_shutdown(struct uart_state *state) ...@@ -223,14 +223,12 @@ static void uart_shutdown(struct uart_state *state)
if (tty) if (tty)
set_bit(TTY_IO_ERROR, &tty->flags); set_bit(TTY_IO_ERROR, &tty->flags);
if (state->flags & UIF_INITIALIZED) { if (test_and_clear_bit(ASYNCB_INITIALIZED, &state->port.flags)) {
state->flags &= ~UIF_INITIALIZED;
/* /*
* Turn off DTR and RTS early. * Turn off DTR and RTS early.
*/ */
if (!tty || (tty->termios->c_cflag & HUPCL)) if (!tty || (tty->termios->c_cflag & HUPCL))
uart_clear_mctrl(port, TIOCM_DTR | TIOCM_RTS); uart_clear_mctrl(uport, TIOCM_DTR | TIOCM_RTS);
/* /*
* clear delta_msr_wait queue to avoid mem leaks: we may free * clear delta_msr_wait queue to avoid mem leaks: we may free
...@@ -244,12 +242,12 @@ static void uart_shutdown(struct uart_state *state) ...@@ -244,12 +242,12 @@ static void uart_shutdown(struct uart_state *state)
/* /*
* Free the IRQ and disable the port. * Free the IRQ and disable the port.
*/ */
port->ops->shutdown(port); uport->ops->shutdown(uport);
/* /*
* Ensure that the IRQ handler isn't running on another CPU. * Ensure that the IRQ handler isn't running on another CPU.
*/ */
synchronize_irq(port->irq); synchronize_irq(uport->irq);
} }
/* /*
...@@ -429,15 +427,16 @@ EXPORT_SYMBOL(uart_get_divisor); ...@@ -429,15 +427,16 @@ EXPORT_SYMBOL(uart_get_divisor);
static void static void
uart_change_speed(struct uart_state *state, struct ktermios *old_termios) uart_change_speed(struct uart_state *state, struct ktermios *old_termios)
{ {
struct tty_struct *tty = state->port.tty; struct tty_port *port = &state->port;
struct uart_port *port = state->uart_port; struct tty_struct *tty = port->tty;
struct uart_port *uport = state->uart_port;
struct ktermios *termios; struct ktermios *termios;
/* /*
* If we have no tty, termios, or the port does not exist, * If we have no tty, termios, or the port does not exist,
* then we can't set the parameters for this port. * then we can't set the parameters for this port.
*/ */
if (!tty || !tty->termios || port->type == PORT_UNKNOWN) if (!tty || !tty->termios || uport->type == PORT_UNKNOWN)
return; return;
termios = tty->termios; termios = tty->termios;
...@@ -446,16 +445,16 @@ uart_change_speed(struct uart_state *state, struct ktermios *old_termios) ...@@ -446,16 +445,16 @@ uart_change_speed(struct uart_state *state, struct ktermios *old_termios)
* Set flags based on termios cflag * Set flags based on termios cflag
*/ */
if (termios->c_cflag & CRTSCTS) if (termios->c_cflag & CRTSCTS)
state->flags |= UIF_CTS_FLOW; set_bit(ASYNCB_CTS_FLOW, &port->flags);
else else
state->flags &= ~UIF_CTS_FLOW; clear_bit(ASYNCB_CTS_FLOW, &port->flags);
if (termios->c_cflag & CLOCAL) if (termios->c_cflag & CLOCAL)
state->flags &= ~UIF_CHECK_CD; clear_bit(ASYNCB_CHECK_CD, &port->flags);
else else
state->flags |= UIF_CHECK_CD; set_bit(ASYNCB_CHECK_CD, &port->flags);
port->ops->set_termios(port, termios, old_termios); uport->ops->set_termios(uport, termios, old_termios);
} }
static inline int static inline int
...@@ -848,7 +847,7 @@ static int uart_set_info(struct uart_state *state, ...@@ -848,7 +847,7 @@ static int uart_set_info(struct uart_state *state,
retval = 0; retval = 0;
if (uport->type == PORT_UNKNOWN) if (uport->type == PORT_UNKNOWN)
goto exit; goto exit;
if (state->flags & UIF_INITIALIZED) { if (port->flags & ASYNC_INITIALIZED) {
if (((old_flags ^ uport->flags) & UPF_SPD_MASK) || if (((old_flags ^ uport->flags) & UPF_SPD_MASK) ||
old_custom_divisor != uport->custom_divisor) { old_custom_divisor != uport->custom_divisor) {
/* /*
...@@ -1306,7 +1305,7 @@ static void uart_close(struct tty_struct *tty, struct file *filp) ...@@ -1306,7 +1305,7 @@ static void uart_close(struct tty_struct *tty, struct file *filp)
* At this point, we stop accepting input. To do this, we * At this point, we stop accepting input. To do this, we
* disable the receive line status interrupts. * disable the receive line status interrupts.
*/ */
if (state->flags & UIF_INITIALIZED) { if (port->flags & ASYNC_INITIALIZED) {
unsigned long flags; unsigned long flags;
spin_lock_irqsave(&port->lock, flags); spin_lock_irqsave(&port->lock, flags);
uport->ops->stop_rx(uport); uport->ops->stop_rx(uport);
...@@ -1337,7 +1336,7 @@ static void uart_close(struct tty_struct *tty, struct file *filp) ...@@ -1337,7 +1336,7 @@ static void uart_close(struct tty_struct *tty, struct file *filp)
/* /*
* Wake up anyone trying to open this port. * Wake up anyone trying to open this port.
*/ */
state->flags &= ~UIF_NORMAL_ACTIVE; clear_bit(ASYNCB_NORMAL_ACTIVE, &port->flags);
wake_up_interruptible(&port->open_wait); wake_up_interruptible(&port->open_wait);
done: done:
...@@ -1418,11 +1417,11 @@ static void uart_hangup(struct tty_struct *tty) ...@@ -1418,11 +1417,11 @@ static void uart_hangup(struct tty_struct *tty)
pr_debug("uart_hangup(%d)\n", state->uart_port->line); pr_debug("uart_hangup(%d)\n", state->uart_port->line);
mutex_lock(&state->mutex); mutex_lock(&state->mutex);
if (state->flags & UIF_NORMAL_ACTIVE) { if (port->flags & ASYNC_NORMAL_ACTIVE) {
uart_flush_buffer(tty); uart_flush_buffer(tty);
uart_shutdown(state); uart_shutdown(state);
port->count = 0; port->count = 0;
state->flags &= ~UIF_NORMAL_ACTIVE; clear_bit(ASYNCB_NORMAL_ACTIVE, &port->flags);
port->tty = NULL; port->tty = NULL;
wake_up_interruptible(&port->open_wait); wake_up_interruptible(&port->open_wait);
wake_up_interruptible(&state->delta_msr_wait); wake_up_interruptible(&state->delta_msr_wait);
...@@ -1493,7 +1492,7 @@ uart_block_til_ready(struct file *filp, struct uart_state *state) ...@@ -1493,7 +1492,7 @@ uart_block_til_ready(struct file *filp, struct uart_state *state)
/* /*
* If the port has been closed, tell userspace/restart open. * If the port has been closed, tell userspace/restart open.
*/ */
if (!(state->flags & UIF_INITIALIZED)) if (!(port->flags & ASYNC_INITIALIZED))
break; break;
/* /*
...@@ -1662,8 +1661,8 @@ static int uart_open(struct tty_struct *tty, struct file *filp) ...@@ -1662,8 +1661,8 @@ static int uart_open(struct tty_struct *tty, struct file *filp)
/* /*
* If this is the first open to succeed, adjust things to suit. * If this is the first open to succeed, adjust things to suit.
*/ */
if (retval == 0 && !(state->flags & UIF_NORMAL_ACTIVE)) { if (retval == 0 && !(port->flags & ASYNC_NORMAL_ACTIVE)) {
state->flags |= UIF_NORMAL_ACTIVE; set_bit(ASYNCB_NORMAL_ACTIVE, &port->flags);
uart_update_termios(state); uart_update_termios(state);
} }
...@@ -1985,63 +1984,64 @@ static int serial_match_port(struct device *dev, void *data) ...@@ -1985,63 +1984,64 @@ static int serial_match_port(struct device *dev, void *data)
return dev->devt == devt; /* Actually, only one tty per port */ return dev->devt == devt; /* Actually, only one tty per port */
} }
int uart_suspend_port(struct uart_driver *drv, struct uart_port *port) int uart_suspend_port(struct uart_driver *drv, struct uart_port *uport)
{ {
struct uart_state *state = drv->state + port->line; struct uart_state *state = drv->state + uport->line;
struct tty_port *port = &state->port;
struct device *tty_dev; struct device *tty_dev;
struct uart_match match = {port, drv}; struct uart_match match = {uport, drv};
mutex_lock(&state->mutex); mutex_lock(&state->mutex);
if (!console_suspend_enabled && uart_console(port)) { if (!console_suspend_enabled && uart_console(uport)) {
/* we're going to avoid suspending serial console */ /* we're going to avoid suspending serial console */
mutex_unlock(&state->mutex); mutex_unlock(&state->mutex);
return 0; return 0;
} }
tty_dev = device_find_child(port->dev, &match, serial_match_port); tty_dev = device_find_child(uport->dev, &match, serial_match_port);
if (device_may_wakeup(tty_dev)) { if (device_may_wakeup(tty_dev)) {
enable_irq_wake(port->irq); enable_irq_wake(uport->irq);
put_device(tty_dev); put_device(tty_dev);
mutex_unlock(&state->mutex); mutex_unlock(&state->mutex);
return 0; return 0;
} }
port->suspended = 1; uport->suspended = 1;
if (state->flags & UIF_INITIALIZED) { if (port->flags & ASYNC_INITIALIZED) {
const struct uart_ops *ops = port->ops; const struct uart_ops *ops = uport->ops;
int tries; int tries;
state->flags = (state->flags & ~UIF_INITIALIZED) set_bit(ASYNCB_SUSPENDED, &port->flags);
| UIF_SUSPENDED; clear_bit(ASYNCB_INITIALIZED, &port->flags);
spin_lock_irq(&port->lock); spin_lock_irq(&uport->lock);
ops->stop_tx(port); ops->stop_tx(uport);
ops->set_mctrl(port, 0); ops->set_mctrl(uport, 0);
ops->stop_rx(port); ops->stop_rx(uport);
spin_unlock_irq(&port->lock); spin_unlock_irq(&uport->lock);
/* /*
* Wait for the transmitter to empty. * Wait for the transmitter to empty.
*/ */
for (tries = 3; !ops->tx_empty(port) && tries; tries--) for (tries = 3; !ops->tx_empty(uport) && tries; tries--)
msleep(10); msleep(10);
if (!tries) if (!tries)
printk(KERN_ERR "%s%s%s%d: Unable to drain " printk(KERN_ERR "%s%s%s%d: Unable to drain "
"transmitter\n", "transmitter\n",
port->dev ? dev_name(port->dev) : "", uport->dev ? dev_name(uport->dev) : "",
port->dev ? ": " : "", uport->dev ? ": " : "",
drv->dev_name, drv->dev_name,
drv->tty_driver->name_base + port->line); drv->tty_driver->name_base + uport->line);
ops->shutdown(port); ops->shutdown(uport);
} }
/* /*
* Disable the console device before suspending. * Disable the console device before suspending.
*/ */
if (uart_console(port)) if (uart_console(uport))
console_stop(port->cons); console_stop(uport->cons);
uart_change_pm(state, 3); uart_change_pm(state, 3);
...@@ -2050,67 +2050,68 @@ int uart_suspend_port(struct uart_driver *drv, struct uart_port *port) ...@@ -2050,67 +2050,68 @@ int uart_suspend_port(struct uart_driver *drv, struct uart_port *port)
return 0; return 0;
} }
int uart_resume_port(struct uart_driver *drv, struct uart_port *port) int uart_resume_port(struct uart_driver *drv, struct uart_port *uport)
{ {
struct uart_state *state = drv->state + port->line; struct uart_state *state = drv->state + uport->line;
struct tty_port *port = &state->port;
struct device *tty_dev; struct device *tty_dev;
struct uart_match match = {port, drv}; struct uart_match match = {uport, drv};
mutex_lock(&state->mutex); mutex_lock(&state->mutex);
if (!console_suspend_enabled && uart_console(port)) { if (!console_suspend_enabled && uart_console(uport)) {
/* no need to resume serial console, it wasn't suspended */ /* no need to resume serial console, it wasn't suspended */
mutex_unlock(&state->mutex); mutex_unlock(&state->mutex);
return 0; return 0;
} }
tty_dev = device_find_child(port->dev, &match, serial_match_port); tty_dev = device_find_child(uport->dev, &match, serial_match_port);
if (!port->suspended && device_may_wakeup(tty_dev)) { if (!uport->suspended && device_may_wakeup(tty_dev)) {
disable_irq_wake(port->irq); disable_irq_wake(uport->irq);
mutex_unlock(&state->mutex); mutex_unlock(&state->mutex);
return 0; return 0;
} }
port->suspended = 0; uport->suspended = 0;
/* /*
* Re-enable the console device after suspending. * Re-enable the console device after suspending.
*/ */
if (uart_console(port)) { if (uart_console(uport)) {
struct ktermios termios; struct ktermios termios;
/* /*
* First try to use the console cflag setting. * First try to use the console cflag setting.
*/ */
memset(&termios, 0, sizeof(struct ktermios)); memset(&termios, 0, sizeof(struct ktermios));
termios.c_cflag = port->cons->cflag; termios.c_cflag = uport->cons->cflag;
/* /*
* If that's unset, use the tty termios setting. * If that's unset, use the tty termios setting.
*/ */
if (state->port.tty && termios.c_cflag == 0) if (port->tty && termios.c_cflag == 0)
termios = *state->port.tty->termios; termios = *port->tty->termios;
uart_change_pm(state, 0); uart_change_pm(state, 0);
port->ops->set_termios(port, &termios, NULL); uport->ops->set_termios(uport, &termios, NULL);
console_start(port->cons); console_start(uport->cons);
} }
if (state->flags & UIF_SUSPENDED) { if (port->flags & ASYNC_SUSPENDED) {
const struct uart_ops *ops = port->ops; const struct uart_ops *ops = uport->ops;
int ret; int ret;
uart_change_pm(state, 0); uart_change_pm(state, 0);
spin_lock_irq(&port->lock); spin_lock_irq(&uport->lock);
ops->set_mctrl(port, 0); ops->set_mctrl(uport, 0);
spin_unlock_irq(&port->lock); spin_unlock_irq(&uport->lock);
ret = ops->startup(port); ret = ops->startup(uport);
if (ret == 0) { if (ret == 0) {
uart_change_speed(state, NULL); uart_change_speed(state, NULL);
spin_lock_irq(&port->lock); spin_lock_irq(&uport->lock);
ops->set_mctrl(port, port->mctrl); ops->set_mctrl(uport, uport->mctrl);
ops->start_tx(port); ops->start_tx(uport);
spin_unlock_irq(&port->lock); spin_unlock_irq(&uport->lock);
state->flags |= UIF_INITIALIZED; set_bit(ASYNCB_INITIALIZED, &port->flags);
} else { } else {
/* /*
* Failed to resume - maybe hardware went away? * Failed to resume - maybe hardware went away?
...@@ -2120,7 +2121,7 @@ int uart_resume_port(struct uart_driver *drv, struct uart_port *port) ...@@ -2120,7 +2121,7 @@ int uart_resume_port(struct uart_driver *drv, struct uart_port *port)
uart_shutdown(state); uart_shutdown(state);
} }
state->flags &= ~UIF_SUSPENDED; clear_bit(ASYNCB_SUSPENDED, &port->flags);
} }
mutex_unlock(&state->mutex); mutex_unlock(&state->mutex);
......
...@@ -122,6 +122,7 @@ struct serial_uart_config { ...@@ -122,6 +122,7 @@ struct serial_uart_config {
/* Internal flags used only by kernel */ /* Internal flags used only by kernel */
#define ASYNCB_INITIALIZED 31 /* Serial port was initialized */ #define ASYNCB_INITIALIZED 31 /* Serial port was initialized */
#define ASYNCB_SUSPENDED 30 /* Serial port is suspended */
#define ASYNCB_NORMAL_ACTIVE 29 /* Normal device is active */ #define ASYNCB_NORMAL_ACTIVE 29 /* Normal device is active */
#define ASYNCB_BOOT_AUTOCONF 28 /* Autoconfigure port on bootup */ #define ASYNCB_BOOT_AUTOCONF 28 /* Autoconfigure port on bootup */
#define ASYNCB_CLOSING 27 /* Serial port is closing */ #define ASYNCB_CLOSING 27 /* Serial port is closing */
...@@ -133,6 +134,7 @@ struct serial_uart_config { ...@@ -133,6 +134,7 @@ struct serial_uart_config {
#define ASYNCB_FIRST_KERNEL 22 #define ASYNCB_FIRST_KERNEL 22
#define ASYNC_HUP_NOTIFY (1U << ASYNCB_HUP_NOTIFY) #define ASYNC_HUP_NOTIFY (1U << ASYNCB_HUP_NOTIFY)
#define ASYNC_SUSPENDED (1U << ASYNCB_SUSPENDED)
#define ASYNC_FOURPORT (1U << ASYNCB_FOURPORT) #define ASYNC_FOURPORT (1U << ASYNCB_FOURPORT)
#define ASYNC_SAK (1U << ASYNCB_SAK) #define ASYNC_SAK (1U << ASYNCB_SAK)
#define ASYNC_SPLIT_TERMIOS (1U << ASYNCB_SPLIT_TERMIOS) #define ASYNC_SPLIT_TERMIOS (1U << ASYNCB_SPLIT_TERMIOS)
......
...@@ -20,6 +20,8 @@ ...@@ -20,6 +20,8 @@
#ifndef LINUX_SERIAL_CORE_H #ifndef LINUX_SERIAL_CORE_H
#define LINUX_SERIAL_CORE_H #define LINUX_SERIAL_CORE_H
#include <linux/serial.h>
/* /*
* The type definitions. These are from Ted Ts'o's serial.h * The type definitions. These are from Ted Ts'o's serial.h
*/ */
...@@ -356,19 +358,6 @@ struct uart_state { ...@@ -356,19 +358,6 @@ struct uart_state {
int pm_state; int pm_state;
struct circ_buf xmit; struct circ_buf xmit;
uif_t flags;
/*
* Definitions for info->flags. These are _private_ to serial_core, and
* are specific to this structure. They may be queried by low level drivers.
*
* FIXME: use the ASY_ definitions
*/
#define UIF_CHECK_CD ((__force uif_t) (1 << 25))
#define UIF_CTS_FLOW ((__force uif_t) (1 << 26))
#define UIF_NORMAL_ACTIVE ((__force uif_t) (1 << 29))
#define UIF_INITIALIZED ((__force uif_t) (1 << 31))
#define UIF_SUSPENDED ((__force uif_t) (1 << 30))
struct tasklet_struct tlet; struct tasklet_struct tlet;
wait_queue_head_t delta_msr_wait; wait_queue_head_t delta_msr_wait;
...@@ -509,22 +498,23 @@ static inline int uart_handle_break(struct uart_port *port) ...@@ -509,22 +498,23 @@ static inline int uart_handle_break(struct uart_port *port)
* @status: new carrier detect status, nonzero if active * @status: new carrier detect status, nonzero if active
*/ */
static inline void static inline void
uart_handle_dcd_change(struct uart_port *port, unsigned int status) uart_handle_dcd_change(struct uart_port *uport, unsigned int status)
{ {
struct uart_state *state = port->state; struct uart_state *state = uport->state;
struct tty_port *port = &state->port;
port->icount.dcd++; uport->icount.dcd++;
#ifdef CONFIG_HARD_PPS #ifdef CONFIG_HARD_PPS
if ((port->flags & UPF_HARDPPS_CD) && status) if ((uport->flags & UPF_HARDPPS_CD) && status)
hardpps(); hardpps();
#endif #endif
if (state->flags & UIF_CHECK_CD) { if (port->flags & ASYNC_CHECK_CD) {
if (status) if (status)
wake_up_interruptible(&state->port.open_wait); wake_up_interruptible(&port->open_wait);
else if (state->port.tty) else if (port->tty)
tty_hangup(state->port.tty); tty_hangup(port->tty);
} }
} }
...@@ -534,24 +524,24 @@ uart_handle_dcd_change(struct uart_port *port, unsigned int status) ...@@ -534,24 +524,24 @@ uart_handle_dcd_change(struct uart_port *port, unsigned int status)
* @status: new clear to send status, nonzero if active * @status: new clear to send status, nonzero if active
*/ */
static inline void static inline void
uart_handle_cts_change(struct uart_port *port, unsigned int status) uart_handle_cts_change(struct uart_port *uport, unsigned int status)
{ {
struct uart_state *state = port->state; struct tty_port *port = &uport->state->port;
struct tty_struct *tty = state->port.tty; struct tty_struct *tty = port->tty;
port->icount.cts++; uport->icount.cts++;
if (state->flags & UIF_CTS_FLOW) { if (port->flags & ASYNC_CTS_FLOW) {
if (tty->hw_stopped) { if (tty->hw_stopped) {
if (status) { if (status) {
tty->hw_stopped = 0; tty->hw_stopped = 0;
port->ops->start_tx(port); uport->ops->start_tx(uport);
uart_write_wakeup(port); uart_write_wakeup(uport);
} }
} else { } else {
if (!status) { if (!status) {
tty->hw_stopped = 1; tty->hw_stopped = 1;
port->ops->stop_tx(port); uport->ops->stop_tx(uport);
} }
} }
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment