Commit 0ad578ef authored by Arnd Bergmann's avatar Arnd Bergmann

Merge tag 'renesas-sh-sci-for-v3.11' of...

Merge tag 'renesas-sh-sci-for-v3.11' of git://git.kernel.org/pub/scm/linux/kernel/git/horms/renesas into next/late

Renesas sh-sci updates for v3.11

HSCIF support by Ulrich Hecht.

* tag 'renesas-sh-sci-for-v3.11' of git://git.kernel.org/pub/scm/linux/kernel/git/horms/renesas:
  serial: sh-sci: Initialise variables before access in sci_set_termios()
  ARM: shmobile: r8a7790: don't use external clock for SCIFs
  ARM: shmobile: r8a7790: HSCIF support
  serial: sh-sci: HSCIF support
Signed-off-by: default avatarArnd Bergmann <arnd@arndb.de>
parents 4022acdb d4759ded
...@@ -98,10 +98,18 @@ void __init r8a7790_pinmux_init(void) ...@@ -98,10 +98,18 @@ void __init r8a7790_pinmux_init(void)
[index] = { \ [index] = { \
SCIF_COMMON(PORT_SCIF, baseaddr, irq), \ SCIF_COMMON(PORT_SCIF, baseaddr, irq), \
.scbrr_algo_id = SCBRR_ALGO_2, \ .scbrr_algo_id = SCBRR_ALGO_2, \
.scscr = SCSCR_RE | SCSCR_TE | SCSCR_CKE1, \ .scscr = SCSCR_RE | SCSCR_TE, \
}
#define HSCIF_DATA(index, baseaddr, irq) \
[index] = { \
SCIF_COMMON(PORT_HSCIF, baseaddr, irq), \
.scbrr_algo_id = SCBRR_ALGO_6, \
.scscr = SCSCR_RE | SCSCR_TE, \
} }
enum { SCIFA0, SCIFA1, SCIFB0, SCIFB1, SCIFB2, SCIFA2, SCIF0, SCIF1 }; enum { SCIFA0, SCIFA1, SCIFB0, SCIFB1, SCIFB2, SCIFA2, SCIF0, SCIF1,
HSCIF0, HSCIF1 };
static struct plat_sci_port scif[] __initdata = { static struct plat_sci_port scif[] __initdata = {
SCIFA_DATA(SCIFA0, 0xe6c40000, gic_spi(144)), /* SCIFA0 */ SCIFA_DATA(SCIFA0, 0xe6c40000, gic_spi(144)), /* SCIFA0 */
...@@ -112,6 +120,8 @@ static struct plat_sci_port scif[] __initdata = { ...@@ -112,6 +120,8 @@ static struct plat_sci_port scif[] __initdata = {
SCIFA_DATA(SCIFA2, 0xe6c60000, gic_spi(151)), /* SCIFA2 */ SCIFA_DATA(SCIFA2, 0xe6c60000, gic_spi(151)), /* SCIFA2 */
SCIF_DATA(SCIF0, 0xe6e60000, gic_spi(152)), /* SCIF0 */ SCIF_DATA(SCIF0, 0xe6e60000, gic_spi(152)), /* SCIF0 */
SCIF_DATA(SCIF1, 0xe6e68000, gic_spi(153)), /* SCIF1 */ SCIF_DATA(SCIF1, 0xe6e68000, gic_spi(153)), /* SCIF1 */
HSCIF_DATA(HSCIF0, 0xe62c0000, gic_spi(154)), /* HSCIF0 */
HSCIF_DATA(HSCIF1, 0xe62c8000, gic_spi(155)), /* HSCIF1 */
}; };
static inline void r8a7790_register_scif(int idx) static inline void r8a7790_register_scif(int idx)
...@@ -149,6 +159,8 @@ void __init r8a7790_add_standard_devices(void) ...@@ -149,6 +159,8 @@ void __init r8a7790_add_standard_devices(void)
r8a7790_register_scif(SCIFA2); r8a7790_register_scif(SCIFA2);
r8a7790_register_scif(SCIF0); r8a7790_register_scif(SCIF0);
r8a7790_register_scif(SCIF1); r8a7790_register_scif(SCIF1);
r8a7790_register_scif(HSCIF0);
r8a7790_register_scif(HSCIF1);
r8a7790_register_irqc(0); r8a7790_register_irqc(0);
} }
......
...@@ -146,6 +146,7 @@ static struct plat_sci_reg sci_regmap[SCIx_NR_REGTYPES][SCIx_NR_REGS] = { ...@@ -146,6 +146,7 @@ static struct plat_sci_reg sci_regmap[SCIx_NR_REGTYPES][SCIx_NR_REGS] = {
[SCRFDR] = sci_reg_invalid, [SCRFDR] = sci_reg_invalid,
[SCSPTR] = sci_reg_invalid, [SCSPTR] = sci_reg_invalid,
[SCLSR] = sci_reg_invalid, [SCLSR] = sci_reg_invalid,
[HSSRR] = sci_reg_invalid,
}, },
/* /*
...@@ -165,6 +166,7 @@ static struct plat_sci_reg sci_regmap[SCIx_NR_REGTYPES][SCIx_NR_REGS] = { ...@@ -165,6 +166,7 @@ static struct plat_sci_reg sci_regmap[SCIx_NR_REGTYPES][SCIx_NR_REGS] = {
[SCRFDR] = sci_reg_invalid, [SCRFDR] = sci_reg_invalid,
[SCSPTR] = sci_reg_invalid, [SCSPTR] = sci_reg_invalid,
[SCLSR] = sci_reg_invalid, [SCLSR] = sci_reg_invalid,
[HSSRR] = sci_reg_invalid,
}, },
/* /*
...@@ -183,6 +185,7 @@ static struct plat_sci_reg sci_regmap[SCIx_NR_REGTYPES][SCIx_NR_REGS] = { ...@@ -183,6 +185,7 @@ static struct plat_sci_reg sci_regmap[SCIx_NR_REGTYPES][SCIx_NR_REGS] = {
[SCRFDR] = sci_reg_invalid, [SCRFDR] = sci_reg_invalid,
[SCSPTR] = sci_reg_invalid, [SCSPTR] = sci_reg_invalid,
[SCLSR] = sci_reg_invalid, [SCLSR] = sci_reg_invalid,
[HSSRR] = sci_reg_invalid,
}, },
/* /*
...@@ -201,6 +204,7 @@ static struct plat_sci_reg sci_regmap[SCIx_NR_REGTYPES][SCIx_NR_REGS] = { ...@@ -201,6 +204,7 @@ static struct plat_sci_reg sci_regmap[SCIx_NR_REGTYPES][SCIx_NR_REGS] = {
[SCRFDR] = { 0x3c, 16 }, [SCRFDR] = { 0x3c, 16 },
[SCSPTR] = sci_reg_invalid, [SCSPTR] = sci_reg_invalid,
[SCLSR] = sci_reg_invalid, [SCLSR] = sci_reg_invalid,
[HSSRR] = sci_reg_invalid,
}, },
/* /*
...@@ -220,6 +224,7 @@ static struct plat_sci_reg sci_regmap[SCIx_NR_REGTYPES][SCIx_NR_REGS] = { ...@@ -220,6 +224,7 @@ static struct plat_sci_reg sci_regmap[SCIx_NR_REGTYPES][SCIx_NR_REGS] = {
[SCRFDR] = sci_reg_invalid, [SCRFDR] = sci_reg_invalid,
[SCSPTR] = { 0x20, 16 }, [SCSPTR] = { 0x20, 16 },
[SCLSR] = { 0x24, 16 }, [SCLSR] = { 0x24, 16 },
[HSSRR] = sci_reg_invalid,
}, },
/* /*
...@@ -238,6 +243,7 @@ static struct plat_sci_reg sci_regmap[SCIx_NR_REGTYPES][SCIx_NR_REGS] = { ...@@ -238,6 +243,7 @@ static struct plat_sci_reg sci_regmap[SCIx_NR_REGTYPES][SCIx_NR_REGS] = {
[SCRFDR] = sci_reg_invalid, [SCRFDR] = sci_reg_invalid,
[SCSPTR] = sci_reg_invalid, [SCSPTR] = sci_reg_invalid,
[SCLSR] = sci_reg_invalid, [SCLSR] = sci_reg_invalid,
[HSSRR] = sci_reg_invalid,
}, },
/* /*
...@@ -256,6 +262,26 @@ static struct plat_sci_reg sci_regmap[SCIx_NR_REGTYPES][SCIx_NR_REGS] = { ...@@ -256,6 +262,26 @@ static struct plat_sci_reg sci_regmap[SCIx_NR_REGTYPES][SCIx_NR_REGS] = {
[SCRFDR] = sci_reg_invalid, [SCRFDR] = sci_reg_invalid,
[SCSPTR] = { 0x20, 16 }, [SCSPTR] = { 0x20, 16 },
[SCLSR] = { 0x24, 16 }, [SCLSR] = { 0x24, 16 },
[HSSRR] = sci_reg_invalid,
},
/*
* Common HSCIF definitions.
*/
[SCIx_HSCIF_REGTYPE] = {
[SCSMR] = { 0x00, 16 },
[SCBRR] = { 0x04, 8 },
[SCSCR] = { 0x08, 16 },
[SCxTDR] = { 0x0c, 8 },
[SCxSR] = { 0x10, 16 },
[SCxRDR] = { 0x14, 8 },
[SCFCR] = { 0x18, 16 },
[SCFDR] = { 0x1c, 16 },
[SCTFDR] = sci_reg_invalid,
[SCRFDR] = sci_reg_invalid,
[SCSPTR] = { 0x20, 16 },
[SCLSR] = { 0x24, 16 },
[HSSRR] = { 0x40, 16 },
}, },
/* /*
...@@ -275,6 +301,7 @@ static struct plat_sci_reg sci_regmap[SCIx_NR_REGTYPES][SCIx_NR_REGS] = { ...@@ -275,6 +301,7 @@ static struct plat_sci_reg sci_regmap[SCIx_NR_REGTYPES][SCIx_NR_REGS] = {
[SCRFDR] = sci_reg_invalid, [SCRFDR] = sci_reg_invalid,
[SCSPTR] = sci_reg_invalid, [SCSPTR] = sci_reg_invalid,
[SCLSR] = { 0x24, 16 }, [SCLSR] = { 0x24, 16 },
[HSSRR] = sci_reg_invalid,
}, },
/* /*
...@@ -294,6 +321,7 @@ static struct plat_sci_reg sci_regmap[SCIx_NR_REGTYPES][SCIx_NR_REGS] = { ...@@ -294,6 +321,7 @@ static struct plat_sci_reg sci_regmap[SCIx_NR_REGTYPES][SCIx_NR_REGS] = {
[SCRFDR] = { 0x20, 16 }, [SCRFDR] = { 0x20, 16 },
[SCSPTR] = { 0x24, 16 }, [SCSPTR] = { 0x24, 16 },
[SCLSR] = { 0x28, 16 }, [SCLSR] = { 0x28, 16 },
[HSSRR] = sci_reg_invalid,
}, },
/* /*
...@@ -313,6 +341,7 @@ static struct plat_sci_reg sci_regmap[SCIx_NR_REGTYPES][SCIx_NR_REGS] = { ...@@ -313,6 +341,7 @@ static struct plat_sci_reg sci_regmap[SCIx_NR_REGTYPES][SCIx_NR_REGS] = {
[SCRFDR] = sci_reg_invalid, [SCRFDR] = sci_reg_invalid,
[SCSPTR] = sci_reg_invalid, [SCSPTR] = sci_reg_invalid,
[SCLSR] = sci_reg_invalid, [SCLSR] = sci_reg_invalid,
[HSSRR] = sci_reg_invalid,
}, },
}; };
...@@ -374,6 +403,9 @@ static int sci_probe_regmap(struct plat_sci_port *cfg) ...@@ -374,6 +403,9 @@ static int sci_probe_regmap(struct plat_sci_port *cfg)
*/ */
cfg->regtype = SCIx_SH4_SCIF_REGTYPE; cfg->regtype = SCIx_SH4_SCIF_REGTYPE;
break; break;
case PORT_HSCIF:
cfg->regtype = SCIx_HSCIF_REGTYPE;
break;
default: default:
printk(KERN_ERR "Can't probe register map for given port\n"); printk(KERN_ERR "Can't probe register map for given port\n");
return -EINVAL; return -EINVAL;
...@@ -1798,6 +1830,42 @@ static unsigned int sci_scbrr_calc(unsigned int algo_id, unsigned int bps, ...@@ -1798,6 +1830,42 @@ static unsigned int sci_scbrr_calc(unsigned int algo_id, unsigned int bps,
return ((freq + 16 * bps) / (32 * bps) - 1); return ((freq + 16 * bps) / (32 * bps) - 1);
} }
/* calculate sample rate, BRR, and clock select for HSCIF */
static void sci_baud_calc_hscif(unsigned int bps, unsigned long freq,
int *brr, unsigned int *srr,
unsigned int *cks)
{
int sr, c, br, err;
int min_err = 1000; /* 100% */
/* Find the combination of sample rate and clock select with the
smallest deviation from the desired baud rate. */
for (sr = 8; sr <= 32; sr++) {
for (c = 0; c <= 3; c++) {
/* integerized formulas from HSCIF documentation */
br = freq / (sr * (1 << (2 * c + 1)) * bps) - 1;
if (br < 0 || br > 255)
continue;
err = freq / ((br + 1) * bps * sr *
(1 << (2 * c + 1)) / 1000) - 1000;
if (min_err > err) {
min_err = err;
*brr = br;
*srr = sr - 1;
*cks = c;
}
}
}
if (min_err == 1000) {
WARN_ON(1);
/* use defaults */
*brr = 255;
*srr = 15;
*cks = 0;
}
}
static void sci_reset(struct uart_port *port) static void sci_reset(struct uart_port *port)
{ {
struct plat_sci_reg *reg; struct plat_sci_reg *reg;
...@@ -1819,8 +1887,9 @@ static void sci_set_termios(struct uart_port *port, struct ktermios *termios, ...@@ -1819,8 +1887,9 @@ static void sci_set_termios(struct uart_port *port, struct ktermios *termios,
{ {
struct sci_port *s = to_sci_port(port); struct sci_port *s = to_sci_port(port);
struct plat_sci_reg *reg; struct plat_sci_reg *reg;
unsigned int baud, smr_val, max_baud, cks; unsigned int baud, smr_val, max_baud, cks = 0;
int t = -1; int t = -1;
unsigned int srr = 15;
/* /*
* earlyprintk comes here early on with port->uartclk set to zero. * earlyprintk comes here early on with port->uartclk set to zero.
...@@ -1833,8 +1902,17 @@ static void sci_set_termios(struct uart_port *port, struct ktermios *termios, ...@@ -1833,8 +1902,17 @@ static void sci_set_termios(struct uart_port *port, struct ktermios *termios,
max_baud = port->uartclk ? port->uartclk / 16 : 115200; max_baud = port->uartclk ? port->uartclk / 16 : 115200;
baud = uart_get_baud_rate(port, termios, old, 0, max_baud); baud = uart_get_baud_rate(port, termios, old, 0, max_baud);
if (likely(baud && port->uartclk)) if (likely(baud && port->uartclk)) {
t = sci_scbrr_calc(s->cfg->scbrr_algo_id, baud, port->uartclk); if (s->cfg->scbrr_algo_id == SCBRR_ALGO_6) {
sci_baud_calc_hscif(baud, port->uartclk, &t, &srr,
&cks);
} else {
t = sci_scbrr_calc(s->cfg->scbrr_algo_id, baud,
port->uartclk);
for (cks = 0; t >= 256 && cks <= 3; cks++)
t >>= 2;
}
}
sci_port_enable(s); sci_port_enable(s);
...@@ -1853,15 +1931,15 @@ static void sci_set_termios(struct uart_port *port, struct ktermios *termios, ...@@ -1853,15 +1931,15 @@ static void sci_set_termios(struct uart_port *port, struct ktermios *termios,
uart_update_timeout(port, termios->c_cflag, baud); uart_update_timeout(port, termios->c_cflag, baud);
for (cks = 0; t >= 256 && cks <= 3; cks++)
t >>= 2;
dev_dbg(port->dev, "%s: SMR %x, cks %x, t %x, SCSCR %x\n", dev_dbg(port->dev, "%s: SMR %x, cks %x, t %x, SCSCR %x\n",
__func__, smr_val, cks, t, s->cfg->scscr); __func__, smr_val, cks, t, s->cfg->scscr);
if (t >= 0) { if (t >= 0) {
serial_port_out(port, SCSMR, (smr_val & ~3) | cks); serial_port_out(port, SCSMR, (smr_val & ~3) | cks);
serial_port_out(port, SCBRR, t); serial_port_out(port, SCBRR, t);
reg = sci_getreg(port, HSSRR);
if (reg->size)
serial_port_out(port, HSSRR, srr | HSCIF_SRE);
udelay((1000000+(baud-1)) / baud); /* Wait one bit interval */ udelay((1000000+(baud-1)) / baud); /* Wait one bit interval */
} else } else
serial_port_out(port, SCSMR, smr_val); serial_port_out(port, SCSMR, smr_val);
...@@ -1947,6 +2025,8 @@ static const char *sci_type(struct uart_port *port) ...@@ -1947,6 +2025,8 @@ static const char *sci_type(struct uart_port *port)
return "scifa"; return "scifa";
case PORT_SCIFB: case PORT_SCIFB:
return "scifb"; return "scifb";
case PORT_HSCIF:
return "hscif";
} }
return NULL; return NULL;
...@@ -1960,6 +2040,9 @@ static inline unsigned long sci_port_size(struct uart_port *port) ...@@ -1960,6 +2040,9 @@ static inline unsigned long sci_port_size(struct uart_port *port)
* from platform resource data at such a time that ports begin to * from platform resource data at such a time that ports begin to
* behave more erratically. * behave more erratically.
*/ */
if (port->type == PORT_HSCIF)
return 96;
else
return 64; return 64;
} }
...@@ -2085,6 +2168,9 @@ static int sci_init_single(struct platform_device *dev, ...@@ -2085,6 +2168,9 @@ static int sci_init_single(struct platform_device *dev,
case PORT_SCIFB: case PORT_SCIFB:
port->fifosize = 256; port->fifosize = 256;
break; break;
case PORT_HSCIF:
port->fifosize = 128;
break;
case PORT_SCIFA: case PORT_SCIFA:
port->fifosize = 64; port->fifosize = 64;
break; break;
...@@ -2325,7 +2411,7 @@ static inline int sci_probe_earlyprintk(struct platform_device *pdev) ...@@ -2325,7 +2411,7 @@ static inline int sci_probe_earlyprintk(struct platform_device *pdev)
#endif /* CONFIG_SERIAL_SH_SCI_CONSOLE */ #endif /* CONFIG_SERIAL_SH_SCI_CONSOLE */
static char banner[] __initdata = static char banner[] __initdata =
KERN_INFO "SuperH SCI(F) driver initialized\n"; KERN_INFO "SuperH (H)SCI(F) driver initialized\n";
static struct uart_driver sci_uart_driver = { static struct uart_driver sci_uart_driver = {
.owner = THIS_MODULE, .owner = THIS_MODULE,
...@@ -2484,4 +2570,4 @@ module_exit(sci_exit); ...@@ -2484,4 +2570,4 @@ module_exit(sci_exit);
MODULE_LICENSE("GPL"); MODULE_LICENSE("GPL");
MODULE_ALIAS("platform:sh-sci"); MODULE_ALIAS("platform:sh-sci");
MODULE_AUTHOR("Paul Mundt"); MODULE_AUTHOR("Paul Mundt");
MODULE_DESCRIPTION("SuperH SCI(F) serial driver"); MODULE_DESCRIPTION("SuperH (H)SCI(F) serial driver");
...@@ -5,7 +5,7 @@ ...@@ -5,7 +5,7 @@
#include <linux/sh_dma.h> #include <linux/sh_dma.h>
/* /*
* Generic header for SuperH SCI(F) (used by sh/sh64/h8300 and related parts) * Generic header for SuperH (H)SCI(F) (used by sh/sh64/h8300 and related parts)
*/ */
#define SCIx_NOT_SUPPORTED (-1) #define SCIx_NOT_SUPPORTED (-1)
...@@ -16,6 +16,7 @@ enum { ...@@ -16,6 +16,7 @@ enum {
SCBRR_ALGO_3, /* (((clk * 2) + 16 * bps) / (16 * bps) - 1) */ SCBRR_ALGO_3, /* (((clk * 2) + 16 * bps) / (16 * bps) - 1) */
SCBRR_ALGO_4, /* (((clk * 2) + 16 * bps) / (32 * bps) - 1) */ SCBRR_ALGO_4, /* (((clk * 2) + 16 * bps) / (32 * bps) - 1) */
SCBRR_ALGO_5, /* (((clk * 1000 / 32) / bps) - 1) */ SCBRR_ALGO_5, /* (((clk * 1000 / 32) / bps) - 1) */
SCBRR_ALGO_6, /* HSCIF variable sample rate algorithm */
}; };
#define SCSCR_TIE (1 << 7) #define SCSCR_TIE (1 << 7)
...@@ -37,7 +38,7 @@ enum { ...@@ -37,7 +38,7 @@ enum {
#define SCI_DEFAULT_ERROR_MASK (SCI_PER | SCI_FER) #define SCI_DEFAULT_ERROR_MASK (SCI_PER | SCI_FER)
/* SCxSR SCIF */ /* SCxSR SCIF, HSCIF */
#define SCIF_ER 0x0080 #define SCIF_ER 0x0080
#define SCIF_TEND 0x0040 #define SCIF_TEND 0x0040
#define SCIF_TDFE 0x0020 #define SCIF_TDFE 0x0020
...@@ -55,6 +56,9 @@ enum { ...@@ -55,6 +56,9 @@ enum {
#define SCSPTR_SPB2IO (1 << 1) #define SCSPTR_SPB2IO (1 << 1)
#define SCSPTR_SPB2DT (1 << 0) #define SCSPTR_SPB2DT (1 << 0)
/* HSSRR HSCIF */
#define HSCIF_SRE 0x8000
/* Offsets into the sci_port->irqs array */ /* Offsets into the sci_port->irqs array */
enum { enum {
SCIx_ERI_IRQ, SCIx_ERI_IRQ,
...@@ -90,6 +94,7 @@ enum { ...@@ -90,6 +94,7 @@ enum {
SCIx_SH4_SCIF_NO_SCSPTR_REGTYPE, SCIx_SH4_SCIF_NO_SCSPTR_REGTYPE,
SCIx_SH4_SCIF_FIFODATA_REGTYPE, SCIx_SH4_SCIF_FIFODATA_REGTYPE,
SCIx_SH7705_SCIF_REGTYPE, SCIx_SH7705_SCIF_REGTYPE,
SCIx_HSCIF_REGTYPE,
SCIx_NR_REGTYPES, SCIx_NR_REGTYPES,
}; };
...@@ -115,6 +120,7 @@ enum { ...@@ -115,6 +120,7 @@ enum {
SCSMR, SCBRR, SCSCR, SCxSR, SCSMR, SCBRR, SCSCR, SCxSR,
SCFCR, SCFDR, SCxTDR, SCxRDR, SCFCR, SCFDR, SCxTDR, SCxRDR,
SCLSR, SCTFDR, SCRFDR, SCSPTR, SCLSR, SCTFDR, SCRFDR, SCSPTR,
HSSRR,
SCIx_NR_REGS, SCIx_NR_REGS,
}; };
...@@ -137,7 +143,7 @@ struct plat_sci_port { ...@@ -137,7 +143,7 @@ struct plat_sci_port {
unsigned long mapbase; /* resource base */ unsigned long mapbase; /* resource base */
unsigned int irqs[SCIx_NR_IRQS]; /* ERI, RXI, TXI, BRI */ unsigned int irqs[SCIx_NR_IRQS]; /* ERI, RXI, TXI, BRI */
unsigned int gpios[SCIx_NR_FNS]; /* SCK, RXD, TXD, CTS, RTS */ unsigned int gpios[SCIx_NR_FNS]; /* SCK, RXD, TXD, CTS, RTS */
unsigned int type; /* SCI / SCIF / IRDA */ unsigned int type; /* SCI / SCIF / IRDA / HSCIF */
upf_t flags; /* UPF_* flags */ upf_t flags; /* UPF_* flags */
unsigned long capabilities; /* Port features/capabilities */ unsigned long capabilities; /* Port features/capabilities */
......
...@@ -226,4 +226,7 @@ ...@@ -226,4 +226,7 @@
/* Rocketport EXPRESS/INFINITY */ /* Rocketport EXPRESS/INFINITY */
#define PORT_RP2 102 #define PORT_RP2 102
/* SH-SCI */
#define PORT_HSCIF 103
#endif /* _UAPILINUX_SERIAL_CORE_H */ #endif /* _UAPILINUX_SERIAL_CORE_H */
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