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
3822b509
Commit
3822b509
authored
Aug 30, 2008
by
David S. Miller
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
sparc64: Convert SUN4V PCI controller driver into a real driver.
Signed-off-by:
David S. Miller
<
davem@davemloft.net
>
parent
6d19c88f
Changes
2
Show whitespace changes
Inline
Side-by-side
Showing
2 changed files
with
83 additions
and
42 deletions
+83
-42
arch/sparc64/kernel/pci.c
arch/sparc64/kernel/pci.c
+0
-2
arch/sparc64/kernel/pci_sun4v.c
arch/sparc64/kernel/pci_sun4v.c
+83
-40
No files found.
arch/sparc64/kernel/pci.c
View file @
3822b509
...
...
@@ -167,7 +167,6 @@ void pci_config_write32(u32 *addr, u32 val)
/* Probe for all PCI controllers in the system. */
extern
void
sabre_init
(
struct
device_node
*
,
const
char
*
);
extern
void
psycho_init
(
struct
device_node
*
,
const
char
*
);
extern
void
sun4v_pci_init
(
struct
device_node
*
,
const
char
*
);
extern
void
fire_pci_init
(
struct
device_node
*
,
const
char
*
);
static
struct
{
...
...
@@ -179,7 +178,6 @@ static struct {
{
"pci108e,a001"
,
sabre_init
},
{
"SUNW,psycho"
,
psycho_init
},
{
"pci108e,8000"
,
psycho_init
},
{
"SUNW,sun4v-pci"
,
sun4v_pci_init
},
{
"pciex108e,80f0"
,
fire_pci_init
},
};
#define PCI_NUM_CONTROLLER_TYPES ARRAY_SIZE(pci_controller_table)
...
...
arch/sparc64/kernel/pci_sun4v.c
View file @
3822b509
...
...
@@ -13,12 +13,10 @@
#include <linux/irq.h>
#include <linux/msi.h>
#include <linux/log2.h>
#include <linux/of_device.h>
#include <asm/iommu.h>
#include <asm/irq.h>
#include <asm/upa.h>
#include <asm/pstate.h>
#include <asm/oplib.h>
#include <asm/hypervisor.h>
#include <asm/prom.h>
...
...
@@ -27,6 +25,9 @@
#include "pci_sun4v.h"
#define DRIVER_NAME "pci_sun4v"
#define PFX DRIVER_NAME ": "
static
unsigned
long
vpci_major
=
1
;
static
unsigned
long
vpci_minor
=
1
;
...
...
@@ -583,7 +584,7 @@ static unsigned long __init probe_existing_entries(struct pci_pbm_info *pbm,
return
cnt
;
}
static
void
__init
pci_sun4v_iommu_init
(
struct
pci_pbm_info
*
pbm
)
static
int
__init
pci_sun4v_iommu_init
(
struct
pci_pbm_info
*
pbm
)
{
struct
iommu
*
iommu
=
pbm
->
iommu
;
struct
property
*
prop
;
...
...
@@ -603,9 +604,9 @@ static void __init pci_sun4v_iommu_init(struct pci_pbm_info *pbm)
}
if
((
vdma
[
0
]
|
vdma
[
1
])
&
~
IO_PAGE_MASK
)
{
pr
om_printf
(
"PCI-SUN4V: s
trange virtual-dma[%08x:%08x].
\n
"
,
pr
intk
(
KERN_ERR
PFX
"S
trange virtual-dma[%08x:%08x].
\n
"
,
vdma
[
0
],
vdma
[
1
]);
prom_halt
()
;
return
-
EINVAL
;
};
dma_mask
=
(
roundup_pow_of_two
(
vdma
[
1
])
-
1UL
);
...
...
@@ -625,8 +626,8 @@ static void __init pci_sun4v_iommu_init(struct pci_pbm_info *pbm)
sz
=
(
sz
+
7UL
)
&
~
7UL
;
iommu
->
arena
.
map
=
kzalloc
(
sz
,
GFP_KERNEL
);
if
(
!
iommu
->
arena
.
map
)
{
pr
om_printf
(
"PCI_IOMMU:
Error, kmalloc(arena.map) failed.
\n
"
);
prom_halt
()
;
pr
intk
(
KERN_ERR
PFX
"
Error, kmalloc(arena.map) failed.
\n
"
);
return
-
ENOMEM
;
}
iommu
->
arena
.
limit
=
num_tsb_entries
;
...
...
@@ -634,6 +635,8 @@ static void __init pci_sun4v_iommu_init(struct pci_pbm_info *pbm)
if
(
sz
)
printk
(
"%s: Imported %lu TSB entries from OBP
\n
"
,
pbm
->
name
,
sz
);
return
0
;
}
#ifdef CONFIG_PCI_MSI
...
...
@@ -890,10 +893,11 @@ static void pci_sun4v_msi_init(struct pci_pbm_info *pbm)
}
#endif
/* !(CONFIG_PCI_MSI) */
static
void
__init
pci_sun4v_pbm_init
(
struct
pci_controller_info
*
p
,
static
int
__init
pci_sun4v_pbm_init
(
struct
pci_controller_info
*
p
,
struct
device_node
*
dp
,
u32
devhandle
)
{
struct
pci_pbm_info
*
pbm
;
int
err
;
if
(
devhandle
&
0x40
)
pbm
=
&
p
->
pbm_B
;
...
...
@@ -905,7 +909,6 @@ static void __init pci_sun4v_pbm_init(struct pci_controller_info *p,
pbm
->
numa_node
=
of_node_to_nid
(
dp
);
pbm
->
scan_bus
=
pci_sun4v_scan_bus
;
pbm
->
pci_ops
=
&
sun4v_pci_ops
;
pbm
->
config_space_reg_bits
=
12
;
...
...
@@ -924,50 +927,58 @@ static void __init pci_sun4v_pbm_init(struct pci_controller_info *p,
pci_determine_mem_io_space
(
pbm
);
pci_get_pbm_props
(
pbm
);
pci_sun4v_iommu_init
(
pbm
);
err
=
pci_sun4v_iommu_init
(
pbm
);
if
(
err
)
return
err
;
pci_sun4v_msi_init
(
pbm
);
pci_sun4v_scan_bus
(
pbm
);
return
0
;
}
void
__init
sun4v_pci_init
(
struct
device_node
*
dp
,
char
*
model_name
)
static
int
__devinit
pci_sun4v_probe
(
struct
of_device
*
op
,
const
struct
of_device_id
*
match
)
{
const
struct
linux_prom64_registers
*
regs
;
static
int
hvapi_negotiated
=
0
;
struct
pci_controller_info
*
p
;
struct
pci_pbm_info
*
pbm
;
struct
device_node
*
dp
;
struct
iommu
*
iommu
;
struct
property
*
prop
;
struct
linux_prom64_registers
*
regs
;
u32
devhandle
;
int
i
;
dp
=
op
->
node
;
if
(
!
hvapi_negotiated
++
)
{
int
err
=
sun4v_hvapi_register
(
HV_GRP_PCI
,
vpci_major
,
&
vpci_minor
);
if
(
err
)
{
pr
om_printf
(
"SUN4V_PCI:
Could not register hvapi, "
pr
intk
(
KERN_ERR
PFX
"
Could not register hvapi, "
"err=%d
\n
"
,
err
);
prom_halt
()
;
return
err
;
}
printk
(
"SUN4V_PCI:
Registered hvapi major[%lu] minor[%lu]
\n
"
,
printk
(
KERN_INFO
PFX
"
Registered hvapi major[%lu] minor[%lu]
\n
"
,
vpci_major
,
vpci_minor
);
dma_ops
=
&
sun4v_dma_ops
;
}
prop
=
of_find
_property
(
dp
,
"reg"
,
NULL
);
if
(
!
prop
)
{
pr
om_printf
(
"SUN4V_PCI:
Could not find config registers
\n
"
);
prom_halt
()
;
regs
=
of_get
_property
(
dp
,
"reg"
,
NULL
);
if
(
!
regs
)
{
pr
intk
(
KERN_ERR
PFX
"
Could not find config registers
\n
"
);
return
-
ENODEV
;
}
regs
=
prop
->
value
;
devhandle
=
(
regs
->
phys_addr
>>
32UL
)
&
0x0fffffff
;
for
(
pbm
=
pci_pbm_root
;
pbm
;
pbm
=
pbm
->
next
)
{
if
(
pbm
->
devhandle
==
(
devhandle
^
0x40
))
{
pci_sun4v_pbm_init
(
pbm
->
parent
,
dp
,
devhandle
);
return
;
return
pci_sun4v_pbm_init
(
pbm
->
parent
,
dp
,
devhandle
);
}
}
...
...
@@ -975,31 +986,63 @@ void __init sun4v_pci_init(struct device_node *dp, char *model_name)
unsigned
long
page
=
get_zeroed_page
(
GFP_ATOMIC
);
if
(
!
page
)
goto
fatal_memory_error
;
return
-
ENOMEM
;
per_cpu
(
iommu_batch
,
i
).
pglist
=
(
u64
*
)
page
;
}
p
=
kzalloc
(
sizeof
(
struct
pci_controller_info
),
GFP_ATOMIC
);
if
(
!
p
)
goto
fatal_memory_error
;
if
(
!
p
)
{
printk
(
KERN_ERR
PFX
"Could not allocate pci_controller_info
\n
"
);
goto
out_free
;
}
iommu
=
kzalloc
(
sizeof
(
struct
iommu
),
GFP_ATOMIC
);
if
(
!
iommu
)
goto
fatal_memory_error
;
if
(
!
iommu
)
{
printk
(
KERN_ERR
PFX
"Could not allocate pbm A iommu
\n
"
);
goto
out_free
;
}
p
->
pbm_A
.
iommu
=
iommu
;
iommu
=
kzalloc
(
sizeof
(
struct
iommu
),
GFP_ATOMIC
);
if
(
!
iommu
)
goto
fatal_memory_error
;
if
(
!
iommu
)
{
printk
(
KERN_ERR
PFX
"Could not allocate pbm B iommu
\n
"
);
goto
out_free
;
}
p
->
pbm_B
.
iommu
=
iommu
;
pci_sun4v_pbm_init
(
p
,
dp
,
devhandle
);
return
;
return
pci_sun4v_pbm_init
(
p
,
dp
,
devhandle
);
fatal_memory_error:
prom_printf
(
"SUN4V_PCI: Fatal memory allocation error.
\n
"
);
prom_halt
();
out_free:
if
(
p
)
{
if
(
p
->
pbm_A
.
iommu
)
kfree
(
p
->
pbm_A
.
iommu
);
if
(
p
->
pbm_B
.
iommu
)
kfree
(
p
->
pbm_B
.
iommu
);
kfree
(
p
);
}
return
-
ENOMEM
;
}
static
struct
of_device_id
pci_sun4v_match
[]
=
{
{
.
name
=
"pci"
,
.
compatible
=
"SUNW,sun4v-pci"
,
},
{},
};
static
struct
of_platform_driver
pci_sun4v_driver
=
{
.
name
=
DRIVER_NAME
,
.
match_table
=
pci_sun4v_match
,
.
probe
=
pci_sun4v_probe
,
};
static
int
__init
pci_sun4v_init
(
void
)
{
return
of_register_driver
(
&
pci_sun4v_driver
,
&
of_bus_type
);
}
subsys_initcall
(
pci_sun4v_init
);
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