Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
L
linux-davinci
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Redmine
Redmine
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Operations
Operations
Metrics
Environments
Analytics
Analytics
CI / CD
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
linux
linux-davinci
Commits
eddce368
Commit
eddce368
authored
Dec 17, 2008
by
Paul Mackerras
Browse files
Options
Browse Files
Download
Plain Diff
Merge branch 'next' of master.kernel.org:/pub/scm/linux/kernel/git/jwboyer/powerpc-4xx into next
parents
b53c7583
cd85400a
Changes
4
Show whitespace changes
Inline
Side-by-side
Showing
4 changed files
with
230 additions
and
105 deletions
+230
-105
arch/powerpc/boot/dts/bamboo.dts
arch/powerpc/boot/dts/bamboo.dts
+2
-1
arch/powerpc/boot/dts/canyonlands.dts
arch/powerpc/boot/dts/canyonlands.dts
+14
-0
arch/powerpc/configs/ppc44x_defconfig
arch/powerpc/configs/ppc44x_defconfig
+6
-6
arch/powerpc/sysdev/ppc4xx_pci.c
arch/powerpc/sysdev/ppc4xx_pci.c
+208
-98
No files found.
arch/powerpc/boot/dts/bamboo.dts
View file @
eddce368
...
...
@@ -269,7 +269,8 @@
* later cannot be changed. Chip supports a second
* IO range but we don'
t
use
it
for
now
*/
ranges
=
<
0x02000000
0x00000000
0xa0000000
0x00000000
0xa0000000
0x00000000
0x20000000
ranges
=
<
0x02000000
0x00000000
0xa0000000
0x00000000
0xa0000000
0x00000000
0x40000000
0x02000000
0x00000000
0x00000000
0x00000000
0xe0000000
0x00000000
0x00100000
0x01000000
0x00000000
0x00000000
0x00000000
0xe8000000
0x00000000
0x00010000
>;
/*
Inbound
2
GB
range
starting
at
0
*/
...
...
arch/powerpc/boot/dts/canyonlands.dts
View file @
eddce368
...
...
@@ -40,6 +40,7 @@
d
-
cache
-
size
=
<
32768
>;
dcr
-
controller
;
dcr
-
access
-
method
=
"native"
;
next
-
level
-
cache
=
<&
L2C0
>;
};
};
...
...
@@ -104,6 +105,16 @@
dcr
-
reg
=
<
0x00c
0x002
>;
};
L2C0
:
l2c
{
compatible
=
"ibm,l2-cache-460ex"
,
"ibm,l2-cache"
;
dcr
-
reg
=
<
0x020
0x008
/*
Internal
SRAM
DCR
's */
0x030 0x008>; /* L2 cache DCR'
s
*/
cache
-
line
-
size
=
<
32
>;
/*
32
bytes
*/
cache
-
size
=
<
262144
>;
/*
L2
,
256
K
*/
interrupt
-
parent
=
<&
UIC1
>;
interrupts
=
<
11
1
>;
};
plb
{
compatible
=
"ibm,plb-460ex"
,
"ibm,plb4"
;
#
address
-
cells
=
<
2
>;
...
...
@@ -343,6 +354,7 @@
*
later
cannot
be
changed
*/
ranges
=
<
0x02000000
0x00000000
0x80000000
0x0000000d
0x80000000
0x00000000
0x80000000
0x02000000
0x00000000
0x00000000
0x0000000c
0x0ee00000
0x00000000
0x00100000
0x01000000
0x00000000
0x00000000
0x0000000c
0x08000000
0x00000000
0x00010000
>;
/*
Inbound
2
GB
range
starting
at
0
*/
...
...
@@ -373,6 +385,7 @@
*
later
cannot
be
changed
*/
ranges
=
<
0x02000000
0x00000000
0x80000000
0x0000000e
0x00000000
0x00000000
0x80000000
0x02000000
0x00000000
0x00000000
0x0000000f
0x00000000
0x00000000
0x00100000
0x01000000
0x00000000
0x00000000
0x0000000f
0x80000000
0x00000000
0x00010000
>;
/*
Inbound
2
GB
range
starting
at
0
*/
...
...
@@ -414,6 +427,7 @@
*
later
cannot
be
changed
*/
ranges
=
<
0x02000000
0x00000000
0x80000000
0x0000000e
0x80000000
0x00000000
0x80000000
0x02000000
0x00000000
0x00000000
0x0000000f
0x00100000
0x00000000
0x00100000
0x01000000
0x00000000
0x00000000
0x0000000f
0x80010000
0x00000000
0x00010000
>;
/*
Inbound
2
GB
range
starting
at
0
*/
...
...
arch/powerpc/configs/ppc44x_defconfig
View file @
eddce368
...
...
@@ -267,7 +267,7 @@ CONFIG_PCI_SYSCALL=y
# CONFIG_PCIEPORTBUS is not set
CONFIG_ARCH_SUPPORTS_MSI=y
# CONFIG_PCI_MSI is not set
CONFIG_PCI_LEGACY=y
# CONFIG_PCI_LEGACY is not set
# CONFIG_PCI_DEBUG is not set
# CONFIG_PCCARD is not set
# CONFIG_HOTPLUG_PCI is not set
...
...
@@ -354,7 +354,7 @@ CONFIG_IPV6_NDISC_NODETYPE=y
# CONFIG_IP_SCTP is not set
# CONFIG_TIPC is not set
# CONFIG_ATM is not set
# CONFIG_BRIDGE is not set
CONFIG_BRIDGE=m
# CONFIG_NET_DSA is not set
# CONFIG_VLAN_8021Q is not set
# CONFIG_DECNET is not set
...
...
@@ -579,7 +579,7 @@ CONFIG_NETDEVICES=y
# CONFIG_BONDING is not set
# CONFIG_MACVLAN is not set
# CONFIG_EQUALIZER is not set
# CONFIG_TUN is not set
CONFIG_TUN=m
# CONFIG_VETH is not set
# CONFIG_ARCNET is not set
# CONFIG_PHYLIB is not set
...
...
@@ -1001,11 +1001,11 @@ CONFIG_USB_OHCI_LITTLE_ENDIAN=y
# CONFIG_USB_TMC is not set
#
# NOTE: USB_STORAGE
enables SCSI, and 'SCSI disk support'
# NOTE: USB_STORAGE
depends on SCSI but BLK_DEV_SD may also be needed;
#
#
#
may also be needed;
see USB_STORAGE Help for more information
# see USB_STORAGE Help for more information
#
CONFIG_USB_STORAGE=m
# CONFIG_USB_STORAGE_DEBUG is not set
...
...
@@ -1418,6 +1418,6 @@ CONFIG_CRYPTO_LZO=m
# CONFIG_PPC_CLOCK is not set
CONFIG_VIRTUALIZATION=y
CONFIG_KVM=y
CONFIG_KVM_
BOOKE_HOST
=y
CONFIG_KVM_
440
=y
# CONFIG_VIRTIO_PCI is not set
# CONFIG_VIRTIO_BALLOON is not set
arch/powerpc/sysdev/ppc4xx_pci.c
View file @
eddce368
...
...
@@ -194,11 +194,41 @@ static int __init ppc4xx_parse_dma_ranges(struct pci_controller *hose,
* 4xx PCI 2.x part
*/
static
int
__init
ppc4xx_setup_one_pci_PMM
(
struct
pci_controller
*
hose
,
void
__iomem
*
reg
,
u64
plb_addr
,
u64
pci_addr
,
u64
size
,
unsigned
int
flags
,
int
index
)
{
u32
ma
,
pcila
,
pciha
;
if
((
plb_addr
+
size
)
>
0xffffffffull
||
!
is_power_of_2
(
size
)
||
size
<
0x1000
||
(
plb_addr
&
(
size
-
1
))
!=
0
)
{
printk
(
KERN_WARNING
"%s: Resource out of range
\n
"
,
hose
->
dn
->
full_name
);
return
-
1
;
}
ma
=
(
0xffffffffu
<<
ilog2
(
size
))
|
1
;
if
(
flags
&
IORESOURCE_PREFETCH
)
ma
|=
2
;
pciha
=
RES_TO_U32_HIGH
(
pci_addr
);
pcila
=
RES_TO_U32_LOW
(
pci_addr
);
writel
(
plb_addr
,
reg
+
PCIL0_PMM0LA
+
(
0x10
*
index
));
writel
(
pcila
,
reg
+
PCIL0_PMM0PCILA
+
(
0x10
*
index
));
writel
(
pciha
,
reg
+
PCIL0_PMM0PCIHA
+
(
0x10
*
index
));
writel
(
ma
,
reg
+
PCIL0_PMM0MA
+
(
0x10
*
index
));
return
0
;
}
static
void
__init
ppc4xx_configure_pci_PMMs
(
struct
pci_controller
*
hose
,
void
__iomem
*
reg
)
{
u32
la
,
ma
,
pcila
,
pciha
;
int
i
,
j
;
int
i
,
j
,
found_isa_hole
=
0
;
/* Setup outbound memory windows */
for
(
i
=
j
=
0
;
i
<
3
;
i
++
)
{
...
...
@@ -213,28 +243,29 @@ static void __init ppc4xx_configure_pci_PMMs(struct pci_controller *hose,
break
;
}
/* Calculate register values */
la
=
res
->
start
;
pciha
=
RES_TO_U32_HIGH
(
res
->
start
-
hose
->
pci_mem_offset
);
pcila
=
RES_TO_U32_LOW
(
res
->
start
-
hose
->
pci_mem_offset
);
/* Configure the resource */
if
(
ppc4xx_setup_one_pci_PMM
(
hose
,
reg
,
res
->
start
,
res
->
start
-
hose
->
pci_mem_offset
,
res
->
end
+
1
-
res
->
start
,
res
->
flags
,
j
)
==
0
)
{
j
++
;
ma
=
res
->
end
+
1
-
res
->
start
;
if
(
!
is_power_of_2
(
ma
)
||
ma
<
0x1000
||
ma
>
0xffffffffu
)
{
printk
(
KERN_WARNING
"%s: Resource out of range
\n
"
,
hose
->
dn
->
full_name
);
continue
;
/* If the resource PCI address is 0 then we have our
* ISA memory hole
*/
if
(
res
->
start
==
hose
->
pci_mem_offset
)
found_isa_hole
=
1
;
}
ma
=
(
0xffffffffu
<<
ilog2
(
ma
))
|
0x1
;
if
(
res
->
flags
&
IORESOURCE_PREFETCH
)
ma
|=
0x2
;
/* Program register values */
writel
(
la
,
reg
+
PCIL0_PMM0LA
+
(
0x10
*
j
));
writel
(
pcila
,
reg
+
PCIL0_PMM0PCILA
+
(
0x10
*
j
));
writel
(
pciha
,
reg
+
PCIL0_PMM0PCIHA
+
(
0x10
*
j
));
writel
(
ma
,
reg
+
PCIL0_PMM0MA
+
(
0x10
*
j
));
j
++
;
}
/* Handle ISA memory hole if not already covered */
if
(
j
<=
2
&&
!
found_isa_hole
&&
hose
->
isa_mem_size
)
if
(
ppc4xx_setup_one_pci_PMM
(
hose
,
reg
,
hose
->
isa_mem_phys
,
0
,
hose
->
isa_mem_size
,
0
,
j
)
==
0
)
printk
(
KERN_INFO
"%s: Legacy ISA memory support enabled
\n
"
,
hose
->
dn
->
full_name
);
}
static
void
__init
ppc4xx_configure_pci_PTMs
(
struct
pci_controller
*
hose
,
...
...
@@ -352,41 +383,32 @@ static void __init ppc4xx_probe_pci_bridge(struct device_node *np)
* 4xx PCI-X part
*/
static
void
__init
ppc4xx_configure_pcix_POMs
(
struct
pci_controller
*
hose
,
void
__iomem
*
reg
)
static
int
__init
ppc4xx_setup_one_pcix_POM
(
struct
pci_controller
*
hose
,
void
__iomem
*
reg
,
u64
plb_addr
,
u64
pci_addr
,
u64
size
,
unsigned
int
flags
,
int
index
)
{
u32
lah
,
lal
,
pciah
,
pcial
,
sa
;
int
i
,
j
;
/* Setup outbound memory windows */
for
(
i
=
j
=
0
;
i
<
3
;
i
++
)
{
struct
resource
*
res
=
&
hose
->
mem_resources
[
i
];
/* we only care about memory windows */
if
(
!
(
res
->
flags
&
IORESOURCE_MEM
))
continue
;
if
(
j
>
1
)
{
printk
(
KERN_WARNING
"%s: Too many ranges
\n
"
,
if
(
!
is_power_of_2
(
size
)
||
size
<
0x1000
||
(
plb_addr
&
(
size
-
1
))
!=
0
)
{
printk
(
KERN_WARNING
"%s: Resource out of range
\n
"
,
hose
->
dn
->
full_name
);
break
;
return
-
1
;
}
/* Calculate register values */
lah
=
RES_TO_U32_HIGH
(
res
->
start
);
lal
=
RES_TO_U32_LOW
(
res
->
start
);
pciah
=
RES_TO_U32_HIGH
(
res
->
start
-
hose
->
pci_mem_offset
);
pcial
=
RES_TO_U32_LOW
(
res
->
start
-
hose
->
pci_mem_offset
);
sa
=
res
->
end
+
1
-
res
->
start
;
if
(
!
is_power_of_2
(
sa
)
||
sa
<
0x100000
||
sa
>
0xffffffffu
)
{
printk
(
KERN_WARNING
"%s: Resource out of range
\n
"
,
hose
->
dn
->
full_name
);
continue
;
}
sa
=
(
0xffffffffu
<<
ilog2
(
sa
))
|
0x1
;
lah
=
RES_TO_U32_HIGH
(
plb_addr
);
lal
=
RES_TO_U32_LOW
(
plb_addr
);
pciah
=
RES_TO_U32_HIGH
(
pci_addr
);
pcial
=
RES_TO_U32_LOW
(
pci_addr
);
sa
=
(
0xffffffffu
<<
ilog2
(
size
))
|
0x1
;
/* Program register values */
if
(
j
==
0
)
{
if
(
index
==
0
)
{
writel
(
lah
,
reg
+
PCIX0_POM0LAH
);
writel
(
lal
,
reg
+
PCIX0_POM0LAL
);
writel
(
pciah
,
reg
+
PCIX0_POM0PCIAH
);
...
...
@@ -399,8 +421,51 @@ static void __init ppc4xx_configure_pcix_POMs(struct pci_controller *hose,
writel
(
pcial
,
reg
+
PCIX0_POM1PCIAL
);
writel
(
sa
,
reg
+
PCIX0_POM1SA
);
}
return
0
;
}
static
void
__init
ppc4xx_configure_pcix_POMs
(
struct
pci_controller
*
hose
,
void
__iomem
*
reg
)
{
int
i
,
j
,
found_isa_hole
=
0
;
/* Setup outbound memory windows */
for
(
i
=
j
=
0
;
i
<
3
;
i
++
)
{
struct
resource
*
res
=
&
hose
->
mem_resources
[
i
];
/* we only care about memory windows */
if
(
!
(
res
->
flags
&
IORESOURCE_MEM
))
continue
;
if
(
j
>
1
)
{
printk
(
KERN_WARNING
"%s: Too many ranges
\n
"
,
hose
->
dn
->
full_name
);
break
;
}
/* Configure the resource */
if
(
ppc4xx_setup_one_pcix_POM
(
hose
,
reg
,
res
->
start
,
res
->
start
-
hose
->
pci_mem_offset
,
res
->
end
+
1
-
res
->
start
,
res
->
flags
,
j
)
==
0
)
{
j
++
;
/* If the resource PCI address is 0 then we have our
* ISA memory hole
*/
if
(
res
->
start
==
hose
->
pci_mem_offset
)
found_isa_hole
=
1
;
}
}
/* Handle ISA memory hole if not already covered */
if
(
j
<=
1
&&
!
found_isa_hole
&&
hose
->
isa_mem_size
)
if
(
ppc4xx_setup_one_pcix_POM
(
hose
,
reg
,
hose
->
isa_mem_phys
,
0
,
hose
->
isa_mem_size
,
0
,
j
)
==
0
)
printk
(
KERN_INFO
"%s: Legacy ISA memory support enabled
\n
"
,
hose
->
dn
->
full_name
);
}
static
void
__init
ppc4xx_configure_pcix_PIMs
(
struct
pci_controller
*
hose
,
...
...
@@ -1317,48 +1382,42 @@ static struct pci_ops ppc4xx_pciex_pci_ops =
.
write
=
ppc4xx_pciex_write_config
,
};
static
void
__init
ppc4xx_configure_pciex_POMs
(
struct
ppc4xx_pciex_port
*
port
,
static
int
__init
ppc4xx_setup_one_pciex_POM
(
struct
ppc4xx_pciex_port
*
port
,
struct
pci_controller
*
hose
,
void
__iomem
*
mbase
)
void
__iomem
*
mbase
,
u64
plb_addr
,
u64
pci_addr
,
u64
size
,
unsigned
int
flags
,
int
index
)
{
u32
lah
,
lal
,
pciah
,
pcial
,
sa
;
int
i
,
j
;
/* Setup outbound memory windows */
for
(
i
=
j
=
0
;
i
<
3
;
i
++
)
{
struct
resource
*
res
=
&
hose
->
mem_resources
[
i
];
/* we only care about memory windows */
if
(
!
(
res
->
flags
&
IORESOURCE_MEM
))
continue
;
if
(
j
>
1
)
{
printk
(
KERN_WARNING
"%s: Too many ranges
\n
"
,
port
->
node
->
full_name
);
break
;
if
(
!
is_power_of_2
(
size
)
||
(
index
<
2
&&
size
<
0x100000
)
||
(
index
==
2
&&
size
<
0x100
)
||
(
plb_addr
&
(
size
-
1
))
!=
0
)
{
printk
(
KERN_WARNING
"%s: Resource out of range
\n
"
,
hose
->
dn
->
full_name
);
return
-
1
;
}
/* Calculate register values */
lah
=
RES_TO_U32_HIGH
(
res
->
start
);
lal
=
RES_TO_U32_LOW
(
res
->
start
);
pciah
=
RES_TO_U32_HIGH
(
res
->
start
-
hose
->
pci_mem_offset
);
pcial
=
RES_TO_U32_LOW
(
res
->
start
-
hose
->
pci_mem_offset
);
sa
=
res
->
end
+
1
-
res
->
start
;
if
(
!
is_power_of_2
(
sa
)
||
sa
<
0x100000
||
sa
>
0xffffffffu
)
{
printk
(
KERN_WARNING
"%s: Resource out of range
\n
"
,
port
->
node
->
full_name
);
continue
;
}
sa
=
(
0xffffffffu
<<
ilog2
(
sa
))
|
0x1
;
lah
=
RES_TO_U32_HIGH
(
plb_addr
);
lal
=
RES_TO_U32_LOW
(
plb_addr
);
pciah
=
RES_TO_U32_HIGH
(
pci_addr
);
pcial
=
RES_TO_U32_LOW
(
pci_addr
);
sa
=
(
0xffffffffu
<<
ilog2
(
size
))
|
0x1
;
/* Program register values */
switch
(
j
)
{
switch
(
index
)
{
case
0
:
out_le32
(
mbase
+
PECFG_POM0LAH
,
pciah
);
out_le32
(
mbase
+
PECFG_POM0LAL
,
pcial
);
dcr_write
(
port
->
dcrs
,
DCRO_PEGPL_OMR1BAH
,
lah
);
dcr_write
(
port
->
dcrs
,
DCRO_PEGPL_OMR1BAL
,
lal
);
dcr_write
(
port
->
dcrs
,
DCRO_PEGPL_OMR1MSKH
,
0x7fffffff
);
/* Note that 3 here means enabled | single region */
dcr_write
(
port
->
dcrs
,
DCRO_PEGPL_OMR1MSKL
,
sa
|
3
);
break
;
case
1
:
...
...
@@ -1367,23 +1426,74 @@ static void __init ppc4xx_configure_pciex_POMs(struct ppc4xx_pciex_port *port,
dcr_write
(
port
->
dcrs
,
DCRO_PEGPL_OMR2BAH
,
lah
);
dcr_write
(
port
->
dcrs
,
DCRO_PEGPL_OMR2BAL
,
lal
);
dcr_write
(
port
->
dcrs
,
DCRO_PEGPL_OMR2MSKH
,
0x7fffffff
);
/* Note that 3 here means enabled | single region */
dcr_write
(
port
->
dcrs
,
DCRO_PEGPL_OMR2MSKL
,
sa
|
3
);
break
;
}
j
++
;
}
/* Configure IO, always 64K starting at 0 */
if
(
hose
->
io_resource
.
flags
&
IORESOURCE_IO
)
{
lah
=
RES_TO_U32_HIGH
(
hose
->
io_base_phys
);
lal
=
RES_TO_U32_LOW
(
hose
->
io_base_phys
);
out_le32
(
mbase
+
PECFG_POM2LAH
,
0
);
out_le32
(
mbase
+
PECFG_POM2LAL
,
0
);
case
2
:
out_le32
(
mbase
+
PECFG_POM2LAH
,
pciah
);
out_le32
(
mbase
+
PECFG_POM2LAL
,
pcial
);
dcr_write
(
port
->
dcrs
,
DCRO_PEGPL_OMR3BAH
,
lah
);
dcr_write
(
port
->
dcrs
,
DCRO_PEGPL_OMR3BAL
,
lal
);
dcr_write
(
port
->
dcrs
,
DCRO_PEGPL_OMR3MSKH
,
0x7fffffff
);
dcr_write
(
port
->
dcrs
,
DCRO_PEGPL_OMR3MSKL
,
0xffff0000
|
3
);
/* Note that 3 here means enabled | IO space !!! */
dcr_write
(
port
->
dcrs
,
DCRO_PEGPL_OMR3MSKL
,
sa
|
3
);
break
;
}
return
0
;
}
static
void
__init
ppc4xx_configure_pciex_POMs
(
struct
ppc4xx_pciex_port
*
port
,
struct
pci_controller
*
hose
,
void
__iomem
*
mbase
)
{
int
i
,
j
,
found_isa_hole
=
0
;
/* Setup outbound memory windows */
for
(
i
=
j
=
0
;
i
<
3
;
i
++
)
{
struct
resource
*
res
=
&
hose
->
mem_resources
[
i
];
/* we only care about memory windows */
if
(
!
(
res
->
flags
&
IORESOURCE_MEM
))
continue
;
if
(
j
>
1
)
{
printk
(
KERN_WARNING
"%s: Too many ranges
\n
"
,
port
->
node
->
full_name
);
break
;
}
/* Configure the resource */
if
(
ppc4xx_setup_one_pciex_POM
(
port
,
hose
,
mbase
,
res
->
start
,
res
->
start
-
hose
->
pci_mem_offset
,
res
->
end
+
1
-
res
->
start
,
res
->
flags
,
j
)
==
0
)
{
j
++
;
/* If the resource PCI address is 0 then we have our
* ISA memory hole
*/
if
(
res
->
start
==
hose
->
pci_mem_offset
)
found_isa_hole
=
1
;
}
}
/* Handle ISA memory hole if not already covered */
if
(
j
<=
1
&&
!
found_isa_hole
&&
hose
->
isa_mem_size
)
if
(
ppc4xx_setup_one_pciex_POM
(
port
,
hose
,
mbase
,
hose
->
isa_mem_phys
,
0
,
hose
->
isa_mem_size
,
0
,
j
)
==
0
)
printk
(
KERN_INFO
"%s: Legacy ISA memory support enabled
\n
"
,
hose
->
dn
->
full_name
);
/* Configure IO, always 64K starting at 0. We hard wire it to 64K !
* Note also that it -has- to be region index 2 on this HW
*/
if
(
hose
->
io_resource
.
flags
&
IORESOURCE_IO
)
ppc4xx_setup_one_pciex_POM
(
port
,
hose
,
mbase
,
hose
->
io_base_phys
,
0
,
0x10000
,
IORESOURCE_IO
,
2
);
}
static
void
__init
ppc4xx_configure_pciex_PIMs
(
struct
ppc4xx_pciex_port
*
port
,
...
...
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