Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
L
linux
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
Analytics
Analytics
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Commits
Issue Boards
Open sidebar
Kirill Smelkov
linux
Commits
428d4d65
Commit
428d4d65
authored
Apr 07, 2015
by
Michael Ellerman
Browse files
Options
Browse Files
Download
Plain Diff
Merge branch 'next-eeh' of
git://git.kernel.org/pub/scm/linux/kernel/git/benh/powerpc
into next
parents
28ea605c
027fa02f
Changes
28
Expand all
Hide whitespace changes
Inline
Side-by-side
Showing
28 changed files
with
1652 additions
and
1648 deletions
+1652
-1648
arch/powerpc/include/asm/device.h
arch/powerpc/include/asm/device.h
+6
-0
arch/powerpc/include/asm/eeh.h
arch/powerpc/include/asm/eeh.h
+14
-15
arch/powerpc/include/asm/machdep.h
arch/powerpc/include/asm/machdep.h
+1
-1
arch/powerpc/include/asm/pci-bridge.h
arch/powerpc/include/asm/pci-bridge.h
+15
-13
arch/powerpc/include/asm/ppc-pci.h
arch/powerpc/include/asm/ppc-pci.h
+5
-0
arch/powerpc/kernel/eeh.c
arch/powerpc/kernel/eeh.c
+108
-68
arch/powerpc/kernel/eeh_cache.c
arch/powerpc/kernel/eeh_cache.c
+11
-14
arch/powerpc/kernel/eeh_dev.c
arch/powerpc/kernel/eeh_dev.c
+7
-7
arch/powerpc/kernel/eeh_driver.c
arch/powerpc/kernel/eeh_driver.c
+0
-22
arch/powerpc/kernel/eeh_pe.c
arch/powerpc/kernel/eeh_pe.c
+72
-57
arch/powerpc/kernel/of_platform.c
arch/powerpc/kernel/of_platform.c
+1
-1
arch/powerpc/kernel/pci-hotplug.c
arch/powerpc/kernel/pci-hotplug.c
+1
-1
arch/powerpc/kernel/pci_dn.c
arch/powerpc/kernel/pci_dn.c
+176
-4
arch/powerpc/kernel/pci_of_scan.c
arch/powerpc/kernel/pci_of_scan.c
+1
-1
arch/powerpc/kernel/rtas_pci.c
arch/powerpc/kernel/rtas_pci.c
+1
-1
arch/powerpc/platforms/powernv/Makefile
arch/powerpc/platforms/powernv/Makefile
+1
-1
arch/powerpc/platforms/powernv/eeh-ioda.c
arch/powerpc/platforms/powernv/eeh-ioda.c
+0
-1149
arch/powerpc/platforms/powernv/eeh-powernv.c
arch/powerpc/platforms/powernv/eeh-powernv.c
+1155
-145
arch/powerpc/platforms/powernv/pci-ioda.c
arch/powerpc/platforms/powernv/pci-ioda.c
+4
-6
arch/powerpc/platforms/powernv/pci.c
arch/powerpc/platforms/powernv/pci.c
+26
-43
arch/powerpc/platforms/powernv/pci.h
arch/powerpc/platforms/powernv/pci.h
+3
-26
arch/powerpc/platforms/pseries/eeh_pseries.c
arch/powerpc/platforms/pseries/eeh_pseries.c
+35
-63
arch/powerpc/platforms/pseries/msi.c
arch/powerpc/platforms/pseries/msi.c
+4
-2
arch/powerpc/platforms/pseries/pci_dlpar.c
arch/powerpc/platforms/pseries/pci_dlpar.c
+1
-1
arch/powerpc/platforms/pseries/setup.c
arch/powerpc/platforms/pseries/setup.c
+1
-1
drivers/net/ethernet/sfc/efx.c
drivers/net/ethernet/sfc/efx.c
+1
-3
drivers/net/ethernet/sfc/siena.c
drivers/net/ethernet/sfc/siena.c
+1
-2
drivers/pci/hotplug/rpadlpar_core.c
drivers/pci/hotplug/rpadlpar_core.c
+1
-1
No files found.
arch/powerpc/include/asm/device.h
View file @
428d4d65
...
@@ -8,6 +8,9 @@
...
@@ -8,6 +8,9 @@
struct
dma_map_ops
;
struct
dma_map_ops
;
struct
device_node
;
struct
device_node
;
#ifdef CONFIG_PPC64
struct
pci_dn
;
#endif
/*
/*
* Arch extensions to struct device.
* Arch extensions to struct device.
...
@@ -34,6 +37,9 @@ struct dev_archdata {
...
@@ -34,6 +37,9 @@ struct dev_archdata {
#ifdef CONFIG_SWIOTLB
#ifdef CONFIG_SWIOTLB
dma_addr_t
max_direct_dma_addr
;
dma_addr_t
max_direct_dma_addr
;
#endif
#endif
#ifdef CONFIG_PPC64
struct
pci_dn
*
pci_data
;
#endif
#ifdef CONFIG_EEH
#ifdef CONFIG_EEH
struct
eeh_dev
*
edev
;
struct
eeh_dev
*
edev
;
#endif
#endif
...
...
arch/powerpc/include/asm/eeh.h
View file @
428d4d65
...
@@ -29,7 +29,7 @@
...
@@ -29,7 +29,7 @@
struct
pci_dev
;
struct
pci_dev
;
struct
pci_bus
;
struct
pci_bus
;
struct
device_node
;
struct
pci_dn
;
#ifdef CONFIG_EEH
#ifdef CONFIG_EEH
...
@@ -136,14 +136,14 @@ struct eeh_dev {
...
@@ -136,14 +136,14 @@ struct eeh_dev {
struct
eeh_pe
*
pe
;
/* Associated PE */
struct
eeh_pe
*
pe
;
/* Associated PE */
struct
list_head
list
;
/* Form link list in the PE */
struct
list_head
list
;
/* Form link list in the PE */
struct
pci_controller
*
phb
;
/* Associated PHB */
struct
pci_controller
*
phb
;
/* Associated PHB */
struct
device_node
*
dn
;
/* Associated
device node */
struct
pci_dn
*
pdn
;
/* Associated PCI
device node */
struct
pci_dev
*
pdev
;
/* Associated PCI device */
struct
pci_dev
*
pdev
;
/* Associated PCI device */
struct
pci_bus
*
bus
;
/* PCI bus for partial hotplug */
struct
pci_bus
*
bus
;
/* PCI bus for partial hotplug */
};
};
static
inline
struct
device_node
*
eeh_dev_to_of_node
(
struct
eeh_dev
*
edev
)
static
inline
struct
pci_dn
*
eeh_dev_to_pdn
(
struct
eeh_dev
*
edev
)
{
{
return
edev
?
edev
->
dn
:
NULL
;
return
edev
?
edev
->
p
dn
:
NULL
;
}
}
static
inline
struct
pci_dev
*
eeh_dev_to_pci_dev
(
struct
eeh_dev
*
edev
)
static
inline
struct
pci_dev
*
eeh_dev_to_pci_dev
(
struct
eeh_dev
*
edev
)
...
@@ -200,8 +200,7 @@ struct eeh_ops {
...
@@ -200,8 +200,7 @@ struct eeh_ops {
char
*
name
;
char
*
name
;
int
(
*
init
)(
void
);
int
(
*
init
)(
void
);
int
(
*
post_init
)(
void
);
int
(
*
post_init
)(
void
);
void
*
(
*
of_probe
)(
struct
device_node
*
dn
,
void
*
flag
);
void
*
(
*
probe
)(
struct
pci_dn
*
pdn
,
void
*
data
);
int
(
*
dev_probe
)(
struct
pci_dev
*
dev
,
void
*
flag
);
int
(
*
set_option
)(
struct
eeh_pe
*
pe
,
int
option
);
int
(
*
set_option
)(
struct
eeh_pe
*
pe
,
int
option
);
int
(
*
get_pe_addr
)(
struct
eeh_pe
*
pe
);
int
(
*
get_pe_addr
)(
struct
eeh_pe
*
pe
);
int
(
*
get_state
)(
struct
eeh_pe
*
pe
,
int
*
state
);
int
(
*
get_state
)(
struct
eeh_pe
*
pe
,
int
*
state
);
...
@@ -211,10 +210,10 @@ struct eeh_ops {
...
@@ -211,10 +210,10 @@ struct eeh_ops {
int
(
*
configure_bridge
)(
struct
eeh_pe
*
pe
);
int
(
*
configure_bridge
)(
struct
eeh_pe
*
pe
);
int
(
*
err_inject
)(
struct
eeh_pe
*
pe
,
int
type
,
int
func
,
int
(
*
err_inject
)(
struct
eeh_pe
*
pe
,
int
type
,
int
func
,
unsigned
long
addr
,
unsigned
long
mask
);
unsigned
long
addr
,
unsigned
long
mask
);
int
(
*
read_config
)(
struct
device_node
*
dn
,
int
where
,
int
size
,
u32
*
val
);
int
(
*
read_config
)(
struct
pci_dn
*
p
dn
,
int
where
,
int
size
,
u32
*
val
);
int
(
*
write_config
)(
struct
device_node
*
dn
,
int
where
,
int
size
,
u32
val
);
int
(
*
write_config
)(
struct
pci_dn
*
p
dn
,
int
where
,
int
size
,
u32
val
);
int
(
*
next_error
)(
struct
eeh_pe
**
pe
);
int
(
*
next_error
)(
struct
eeh_pe
**
pe
);
int
(
*
restore_config
)(
struct
device_node
*
dn
);
int
(
*
restore_config
)(
struct
pci_dn
*
p
dn
);
};
};
extern
int
eeh_subsystem_flags
;
extern
int
eeh_subsystem_flags
;
...
@@ -272,7 +271,7 @@ void eeh_pe_restore_bars(struct eeh_pe *pe);
...
@@ -272,7 +271,7 @@ void eeh_pe_restore_bars(struct eeh_pe *pe);
const
char
*
eeh_pe_loc_get
(
struct
eeh_pe
*
pe
);
const
char
*
eeh_pe_loc_get
(
struct
eeh_pe
*
pe
);
struct
pci_bus
*
eeh_pe_bus_get
(
struct
eeh_pe
*
pe
);
struct
pci_bus
*
eeh_pe_bus_get
(
struct
eeh_pe
*
pe
);
void
*
eeh_dev_init
(
struct
device_node
*
dn
,
void
*
data
);
void
*
eeh_dev_init
(
struct
pci_dn
*
p
dn
,
void
*
data
);
void
eeh_dev_phb_init_dynamic
(
struct
pci_controller
*
phb
);
void
eeh_dev_phb_init_dynamic
(
struct
pci_controller
*
phb
);
int
eeh_init
(
void
);
int
eeh_init
(
void
);
int
__init
eeh_ops_register
(
struct
eeh_ops
*
ops
);
int
__init
eeh_ops_register
(
struct
eeh_ops
*
ops
);
...
@@ -280,8 +279,8 @@ int __exit eeh_ops_unregister(const char *name);
...
@@ -280,8 +279,8 @@ int __exit eeh_ops_unregister(const char *name);
int
eeh_check_failure
(
const
volatile
void
__iomem
*
token
);
int
eeh_check_failure
(
const
volatile
void
__iomem
*
token
);
int
eeh_dev_check_failure
(
struct
eeh_dev
*
edev
);
int
eeh_dev_check_failure
(
struct
eeh_dev
*
edev
);
void
eeh_addr_cache_build
(
void
);
void
eeh_addr_cache_build
(
void
);
void
eeh_add_device_early
(
struct
device_node
*
);
void
eeh_add_device_early
(
struct
pci_dn
*
);
void
eeh_add_device_tree_early
(
struct
device_node
*
);
void
eeh_add_device_tree_early
(
struct
pci_dn
*
);
void
eeh_add_device_late
(
struct
pci_dev
*
);
void
eeh_add_device_late
(
struct
pci_dev
*
);
void
eeh_add_device_tree_late
(
struct
pci_bus
*
);
void
eeh_add_device_tree_late
(
struct
pci_bus
*
);
void
eeh_add_sysfs_files
(
struct
pci_bus
*
);
void
eeh_add_sysfs_files
(
struct
pci_bus
*
);
...
@@ -323,7 +322,7 @@ static inline int eeh_init(void)
...
@@ -323,7 +322,7 @@ static inline int eeh_init(void)
return
0
;
return
0
;
}
}
static
inline
void
*
eeh_dev_init
(
struct
device_node
*
dn
,
void
*
data
)
static
inline
void
*
eeh_dev_init
(
struct
pci_dn
*
p
dn
,
void
*
data
)
{
{
return
NULL
;
return
NULL
;
}
}
...
@@ -339,9 +338,9 @@ static inline int eeh_check_failure(const volatile void __iomem *token)
...
@@ -339,9 +338,9 @@ static inline int eeh_check_failure(const volatile void __iomem *token)
static
inline
void
eeh_addr_cache_build
(
void
)
{
}
static
inline
void
eeh_addr_cache_build
(
void
)
{
}
static
inline
void
eeh_add_device_early
(
struct
device_node
*
dn
)
{
}
static
inline
void
eeh_add_device_early
(
struct
pci_dn
*
p
dn
)
{
}
static
inline
void
eeh_add_device_tree_early
(
struct
device_node
*
dn
)
{
}
static
inline
void
eeh_add_device_tree_early
(
struct
pci_dn
*
p
dn
)
{
}
static
inline
void
eeh_add_device_late
(
struct
pci_dev
*
dev
)
{
}
static
inline
void
eeh_add_device_late
(
struct
pci_dev
*
dev
)
{
}
...
...
arch/powerpc/include/asm/machdep.h
View file @
428d4d65
...
@@ -125,7 +125,7 @@ struct machdep_calls {
...
@@ -125,7 +125,7 @@ struct machdep_calls {
unsigned
int
(
*
get_irq
)(
void
);
unsigned
int
(
*
get_irq
)(
void
);
/* PCI stuff */
/* PCI stuff */
/* Called after
scanning the bus, before
allocating resources */
/* Called after allocating resources */
void
(
*
pcibios_fixup
)(
void
);
void
(
*
pcibios_fixup
)(
void
);
int
(
*
pci_probe_mode
)(
struct
pci_bus
*
);
int
(
*
pci_probe_mode
)(
struct
pci_bus
*
);
void
(
*
pci_irq_fixup
)(
struct
pci_dev
*
dev
);
void
(
*
pci_irq_fixup
)(
struct
pci_dev
*
dev
);
...
...
arch/powerpc/include/asm/pci-bridge.h
View file @
428d4d65
...
@@ -89,6 +89,7 @@ struct pci_controller {
...
@@ -89,6 +89,7 @@ struct pci_controller {
#ifdef CONFIG_PPC64
#ifdef CONFIG_PPC64
unsigned
long
buid
;
unsigned
long
buid
;
struct
pci_dn
*
pci_data
;
#endif
/* CONFIG_PPC64 */
#endif
/* CONFIG_PPC64 */
void
*
private_data
;
void
*
private_data
;
...
@@ -154,9 +155,15 @@ static inline int isa_vaddr_is_ioport(void __iomem *address)
...
@@ -154,9 +155,15 @@ static inline int isa_vaddr_is_ioport(void __iomem *address)
struct
iommu_table
;
struct
iommu_table
;
struct
pci_dn
{
struct
pci_dn
{
int
flags
;
int
busno
;
/* pci bus number */
int
busno
;
/* pci bus number */
int
devfn
;
/* pci device and function number */
int
devfn
;
/* pci device and function number */
int
vendor_id
;
/* Vendor ID */
int
device_id
;
/* Device ID */
int
class_code
;
/* Device class code */
struct
pci_dn
*
parent
;
struct
pci_controller
*
phb
;
/* for pci devices */
struct
pci_controller
*
phb
;
/* for pci devices */
struct
iommu_table
*
iommu_table
;
/* for phb's or bridges */
struct
iommu_table
*
iommu_table
;
/* for phb's or bridges */
struct
device_node
*
node
;
/* back-pointer to the device_node */
struct
device_node
*
node
;
/* back-pointer to the device_node */
...
@@ -171,14 +178,17 @@ struct pci_dn {
...
@@ -171,14 +178,17 @@ struct pci_dn {
#ifdef CONFIG_PPC_POWERNV
#ifdef CONFIG_PPC_POWERNV
int
pe_number
;
int
pe_number
;
#endif
#endif
struct
list_head
child_list
;
struct
list_head
list
;
};
};
/* Get the pointer to a device_node's pci_dn */
/* Get the pointer to a device_node's pci_dn */
#define PCI_DN(dn) ((struct pci_dn *) (dn)->data)
#define PCI_DN(dn) ((struct pci_dn *) (dn)->data)
extern
struct
pci_dn
*
pci_get_pdn_by_devfn
(
struct
pci_bus
*
bus
,
int
devfn
);
extern
struct
pci_dn
*
pci_get_pdn
(
struct
pci_dev
*
pdev
);
extern
struct
pci_dn
*
pci_get_pdn
(
struct
pci_dev
*
pdev
);
extern
void
*
update_dn_pci_info
(
struct
device_node
*
dn
,
void
*
data
);
extern
void
*
update_dn_pci_info
(
struct
device_node
*
dn
,
void
*
data
);
static
inline
int
pci_device_from_OF_node
(
struct
device_node
*
np
,
static
inline
int
pci_device_from_OF_node
(
struct
device_node
*
np
,
u8
*
bus
,
u8
*
devfn
)
u8
*
bus
,
u8
*
devfn
)
...
@@ -191,20 +201,12 @@ static inline int pci_device_from_OF_node(struct device_node *np,
...
@@ -191,20 +201,12 @@ static inline int pci_device_from_OF_node(struct device_node *np,
}
}
#if defined(CONFIG_EEH)
#if defined(CONFIG_EEH)
static
inline
struct
eeh_dev
*
of_node_to_eeh_dev
(
struct
device_node
*
dn
)
static
inline
struct
eeh_dev
*
pdn_to_eeh_dev
(
struct
pci_dn
*
p
dn
)
{
{
/*
return
pdn
?
pdn
->
edev
:
NULL
;
* For those OF nodes whose parent isn't PCI bridge, they
* don't have PCI_DN actually. So we have to skip them for
* any EEH operations.
*/
if
(
!
dn
||
!
PCI_DN
(
dn
))
return
NULL
;
return
PCI_DN
(
dn
)
->
edev
;
}
}
#else
#else
#define
of_node_to_eeh_dev(x)
(NULL)
#define
pdn_to_eeh_dev(x)
(NULL)
#endif
#endif
/** Find the bus corresponding to the indicated device node */
/** Find the bus corresponding to the indicated device node */
...
...
arch/powerpc/include/asm/ppc-pci.h
View file @
428d4d65
...
@@ -33,9 +33,14 @@ extern struct pci_dev *isa_bridge_pcidev; /* may be NULL if no ISA bus */
...
@@ -33,9 +33,14 @@ extern struct pci_dev *isa_bridge_pcidev; /* may be NULL if no ISA bus */
/* PCI device_node operations */
/* PCI device_node operations */
struct
device_node
;
struct
device_node
;
struct
pci_dn
;
typedef
void
*
(
*
traverse_func
)(
struct
device_node
*
me
,
void
*
data
);
typedef
void
*
(
*
traverse_func
)(
struct
device_node
*
me
,
void
*
data
);
void
*
traverse_pci_devices
(
struct
device_node
*
start
,
traverse_func
pre
,
void
*
traverse_pci_devices
(
struct
device_node
*
start
,
traverse_func
pre
,
void
*
data
);
void
*
data
);
void
*
traverse_pci_dn
(
struct
pci_dn
*
root
,
void
*
(
*
fn
)(
struct
pci_dn
*
,
void
*
),
void
*
data
);
extern
void
pci_devs_phb_init
(
void
);
extern
void
pci_devs_phb_init
(
void
);
extern
void
pci_devs_phb_init_dynamic
(
struct
pci_controller
*
phb
);
extern
void
pci_devs_phb_init_dynamic
(
struct
pci_controller
*
phb
);
...
...
arch/powerpc/kernel/eeh.c
View file @
428d4d65
This diff is collapsed.
Click to expand it.
arch/powerpc/kernel/eeh_cache.c
View file @
428d4d65
...
@@ -171,30 +171,27 @@ eeh_addr_cache_insert(struct pci_dev *dev, unsigned long alo,
...
@@ -171,30 +171,27 @@ eeh_addr_cache_insert(struct pci_dev *dev, unsigned long alo,
static
void
__eeh_addr_cache_insert_dev
(
struct
pci_dev
*
dev
)
static
void
__eeh_addr_cache_insert_dev
(
struct
pci_dev
*
dev
)
{
{
struct
device_node
*
dn
;
struct
pci_dn
*
p
dn
;
struct
eeh_dev
*
edev
;
struct
eeh_dev
*
edev
;
int
i
;
int
i
;
dn
=
pci_device_to_OF_node
(
dev
);
pdn
=
pci_get_pdn_by_devfn
(
dev
->
bus
,
dev
->
devfn
);
if
(
!
dn
)
{
if
(
!
p
dn
)
{
pr_warn
(
"PCI: no pci dn found for dev=%s
\n
"
,
pr_warn
(
"PCI: no pci dn found for dev=%s
\n
"
,
pci_name
(
dev
));
pci_name
(
dev
));
return
;
return
;
}
}
edev
=
of_node_to_eeh_dev
(
dn
);
edev
=
pdn_to_eeh_dev
(
p
dn
);
if
(
!
edev
)
{
if
(
!
edev
)
{
pr_warn
(
"PCI: no EEH dev found for
dn=
%s
\n
"
,
pr_warn
(
"PCI: no EEH dev found for %s
\n
"
,
dn
->
full_name
);
pci_name
(
dev
)
);
return
;
return
;
}
}
/* Skip any devices for which EEH is not enabled. */
/* Skip any devices for which EEH is not enabled. */
if
(
!
edev
->
pe
)
{
if
(
!
edev
->
pe
)
{
#ifdef DEBUG
dev_dbg
(
&
dev
->
dev
,
"EEH: Skip building address cache
\n
"
);
pr_info
(
"PCI: skip building address cache for=%s - %s
\n
"
,
pci_name
(
dev
),
dn
->
full_name
);
#endif
return
;
return
;
}
}
...
@@ -282,18 +279,18 @@ void eeh_addr_cache_rmv_dev(struct pci_dev *dev)
...
@@ -282,18 +279,18 @@ void eeh_addr_cache_rmv_dev(struct pci_dev *dev)
*/
*/
void
eeh_addr_cache_build
(
void
)
void
eeh_addr_cache_build
(
void
)
{
{
struct
device_node
*
dn
;
struct
pci_dn
*
p
dn
;
struct
eeh_dev
*
edev
;
struct
eeh_dev
*
edev
;
struct
pci_dev
*
dev
=
NULL
;
struct
pci_dev
*
dev
=
NULL
;
spin_lock_init
(
&
pci_io_addr_cache_root
.
piar_lock
);
spin_lock_init
(
&
pci_io_addr_cache_root
.
piar_lock
);
for_each_pci_dev
(
dev
)
{
for_each_pci_dev
(
dev
)
{
dn
=
pci_device_to_OF_node
(
dev
);
pdn
=
pci_get_pdn_by_devfn
(
dev
->
bus
,
dev
->
devfn
);
if
(
!
dn
)
if
(
!
p
dn
)
continue
;
continue
;
edev
=
of_node_to_eeh_dev
(
dn
);
edev
=
pdn_to_eeh_dev
(
p
dn
);
if
(
!
edev
)
if
(
!
edev
)
continue
;
continue
;
...
...
arch/powerpc/kernel/eeh_dev.c
View file @
428d4d65
...
@@ -43,13 +43,13 @@
...
@@ -43,13 +43,13 @@
/**
/**
* eeh_dev_init - Create EEH device according to OF node
* eeh_dev_init - Create EEH device according to OF node
* @
dn:
device node
* @
pdn: PCI
device node
* @data: PHB
* @data: PHB
*
*
* It will create EEH device according to the given OF node. The function
* It will create EEH device according to the given OF node. The function
* might be called by PCI emunation, DR, PHB hotplug.
* might be called by PCI emunation, DR, PHB hotplug.
*/
*/
void
*
eeh_dev_init
(
struct
device_node
*
dn
,
void
*
data
)
void
*
eeh_dev_init
(
struct
pci_dn
*
p
dn
,
void
*
data
)
{
{
struct
pci_controller
*
phb
=
data
;
struct
pci_controller
*
phb
=
data
;
struct
eeh_dev
*
edev
;
struct
eeh_dev
*
edev
;
...
@@ -63,8 +63,8 @@ void *eeh_dev_init(struct device_node *dn, void *data)
...
@@ -63,8 +63,8 @@ void *eeh_dev_init(struct device_node *dn, void *data)
}
}
/* Associate EEH device with OF node */
/* Associate EEH device with OF node */
PCI_DN
(
dn
)
->
edev
=
edev
;
pdn
->
edev
=
edev
;
edev
->
dn
=
dn
;
edev
->
pdn
=
p
dn
;
edev
->
phb
=
phb
;
edev
->
phb
=
phb
;
INIT_LIST_HEAD
(
&
edev
->
list
);
INIT_LIST_HEAD
(
&
edev
->
list
);
...
@@ -80,16 +80,16 @@ void *eeh_dev_init(struct device_node *dn, void *data)
...
@@ -80,16 +80,16 @@ void *eeh_dev_init(struct device_node *dn, void *data)
*/
*/
void
eeh_dev_phb_init_dynamic
(
struct
pci_controller
*
phb
)
void
eeh_dev_phb_init_dynamic
(
struct
pci_controller
*
phb
)
{
{
struct
device_node
*
dn
=
phb
->
dn
;
struct
pci_dn
*
root
=
phb
->
pci_data
;
/* EEH PE for PHB */
/* EEH PE for PHB */
eeh_phb_pe_create
(
phb
);
eeh_phb_pe_create
(
phb
);
/* EEH device for PHB */
/* EEH device for PHB */
eeh_dev_init
(
dn
,
phb
);
eeh_dev_init
(
root
,
phb
);
/* EEH devices for children OF nodes */
/* EEH devices for children OF nodes */
traverse_pci_d
evices
(
dn
,
eeh_dev_init
,
phb
);
traverse_pci_d
n
(
root
,
eeh_dev_init
,
phb
);
}
}
/**
/**
...
...
arch/powerpc/kernel/eeh_driver.c
View file @
428d4d65
...
@@ -83,28 +83,6 @@ static inline void eeh_pcid_put(struct pci_dev *pdev)
...
@@ -83,28 +83,6 @@ static inline void eeh_pcid_put(struct pci_dev *pdev)
module_put
(
pdev
->
driver
->
driver
.
owner
);
module_put
(
pdev
->
driver
->
driver
.
owner
);
}
}
#if 0
static void print_device_node_tree(struct pci_dn *pdn, int dent)
{
int i;
struct device_node *pc;
if (!pdn)
return;
for (i = 0; i < dent; i++)
printk(" ");
printk("dn=%s mode=%x \tcfg_addr=%x pe_addr=%x \tfull=%s\n",
pdn->node->name, pdn->eeh_mode, pdn->eeh_config_addr,
pdn->eeh_pe_config_addr, pdn->node->full_name);
dent += 3;
pc = pdn->node->child;
while (pc) {
print_device_node_tree(PCI_DN(pc), dent);
pc = pc->sibling;
}
}
#endif
/**
/**
* eeh_disable_irq - Disable interrupt for the recovering device
* eeh_disable_irq - Disable interrupt for the recovering device
* @dev: PCI device
* @dev: PCI device
...
...
arch/powerpc/kernel/eeh_pe.c
View file @
428d4d65
...
@@ -291,27 +291,25 @@ struct eeh_pe *eeh_pe_get(struct eeh_dev *edev)
...
@@ -291,27 +291,25 @@ struct eeh_pe *eeh_pe_get(struct eeh_dev *edev)
*/
*/
static
struct
eeh_pe
*
eeh_pe_get_parent
(
struct
eeh_dev
*
edev
)
static
struct
eeh_pe
*
eeh_pe_get_parent
(
struct
eeh_dev
*
edev
)
{
{
struct
device_node
*
dn
;
struct
eeh_dev
*
parent
;
struct
eeh_dev
*
parent
;
struct
pci_dn
*
pdn
=
eeh_dev_to_pdn
(
edev
);
/*
/*
* It might have the case for the indirect parent
* It might have the case for the indirect parent
* EEH device already having associated PE, but
* EEH device already having associated PE, but
* the direct parent EEH device doesn't have yet.
* the direct parent EEH device doesn't have yet.
*/
*/
dn
=
edev
->
dn
->
parent
;
pdn
=
pdn
?
pdn
->
parent
:
NULL
;
while
(
dn
)
{
while
(
p
dn
)
{
/* We're poking out of PCI territory */
/* We're poking out of PCI territory */
if
(
!
PCI_DN
(
dn
))
return
NULL
;
parent
=
pdn_to_eeh_dev
(
pdn
);
if
(
!
parent
)
parent
=
of_node_to_eeh_dev
(
dn
);
return
NULL
;
/* We're poking out of PCI territory */
if
(
!
parent
)
return
NULL
;
if
(
parent
->
pe
)
if
(
parent
->
pe
)
return
parent
->
pe
;
return
parent
->
pe
;
dn
=
dn
->
parent
;
pdn
=
p
dn
->
parent
;
}
}
return
NULL
;
return
NULL
;
...
@@ -330,6 +328,13 @@ int eeh_add_to_parent_pe(struct eeh_dev *edev)
...
@@ -330,6 +328,13 @@ int eeh_add_to_parent_pe(struct eeh_dev *edev)
{
{
struct
eeh_pe
*
pe
,
*
parent
;
struct
eeh_pe
*
pe
,
*
parent
;
/* Check if the PE number is valid */
if
(
!
eeh_has_flag
(
EEH_VALID_PE_ZERO
)
&&
!
edev
->
pe_config_addr
)
{
pr_err
(
"%s: Invalid PE#0 for edev 0x%x on PHB#%d
\n
"
,
__func__
,
edev
->
config_addr
,
edev
->
phb
->
global_number
);
return
-
EINVAL
;
}
/*
/*
* Search the PE has been existing or not according
* Search the PE has been existing or not according
* to the PE address. If that has been existing, the
* to the PE address. If that has been existing, the
...
@@ -338,21 +343,18 @@ int eeh_add_to_parent_pe(struct eeh_dev *edev)
...
@@ -338,21 +343,18 @@ int eeh_add_to_parent_pe(struct eeh_dev *edev)
*/
*/
pe
=
eeh_pe_get
(
edev
);
pe
=
eeh_pe_get
(
edev
);
if
(
pe
&&
!
(
pe
->
type
&
EEH_PE_INVALID
))
{
if
(
pe
&&
!
(
pe
->
type
&
EEH_PE_INVALID
))
{
if
(
!
edev
->
pe_config_addr
)
{
pr_err
(
"%s: PE with addr 0x%x already exists
\n
"
,
__func__
,
edev
->
config_addr
);
return
-
EEXIST
;
}
/* Mark the PE as type of PCI bus */
/* Mark the PE as type of PCI bus */
pe
->
type
=
EEH_PE_BUS
;
pe
->
type
=
EEH_PE_BUS
;
edev
->
pe
=
pe
;
edev
->
pe
=
pe
;
/* Put the edev to PE */
/* Put the edev to PE */
list_add_tail
(
&
edev
->
list
,
&
pe
->
edevs
);
list_add_tail
(
&
edev
->
list
,
&
pe
->
edevs
);
pr_debug
(
"EEH: Add %s to Bus PE#%x
\n
"
,
pr_debug
(
"EEH: Add %04x:%02x:%02x.%01x to Bus PE#%x
\n
"
,
edev
->
dn
->
full_name
,
pe
->
addr
);
edev
->
phb
->
global_number
,
edev
->
config_addr
>>
8
,
PCI_SLOT
(
edev
->
config_addr
&
0xFF
),
PCI_FUNC
(
edev
->
config_addr
&
0xFF
),
pe
->
addr
);
return
0
;
return
0
;
}
else
if
(
pe
&&
(
pe
->
type
&
EEH_PE_INVALID
))
{
}
else
if
(
pe
&&
(
pe
->
type
&
EEH_PE_INVALID
))
{
list_add_tail
(
&
edev
->
list
,
&
pe
->
edevs
);
list_add_tail
(
&
edev
->
list
,
&
pe
->
edevs
);
...
@@ -368,9 +370,14 @@ int eeh_add_to_parent_pe(struct eeh_dev *edev)
...
@@ -368,9 +370,14 @@ int eeh_add_to_parent_pe(struct eeh_dev *edev)
parent
->
type
&=
~
(
EEH_PE_INVALID
|
EEH_PE_KEEP
);
parent
->
type
&=
~
(
EEH_PE_INVALID
|
EEH_PE_KEEP
);
parent
=
parent
->
parent
;
parent
=
parent
->
parent
;
}
}
pr_debug
(
"EEH: Add %s to Device PE#%x, Parent PE#%x
\n
"
,
edev
->
dn
->
full_name
,
pe
->
addr
,
pe
->
parent
->
addr
);
pr_debug
(
"EEH: Add %04x:%02x:%02x.%01x to Device "
"PE#%x, Parent PE#%x
\n
"
,
edev
->
phb
->
global_number
,
edev
->
config_addr
>>
8
,
PCI_SLOT
(
edev
->
config_addr
&
0xFF
),
PCI_FUNC
(
edev
->
config_addr
&
0xFF
),
pe
->
addr
,
pe
->
parent
->
addr
);
return
0
;
return
0
;
}
}
...
@@ -409,8 +416,13 @@ int eeh_add_to_parent_pe(struct eeh_dev *edev)
...
@@ -409,8 +416,13 @@ int eeh_add_to_parent_pe(struct eeh_dev *edev)
list_add_tail
(
&
pe
->
child
,
&
parent
->
child_list
);
list_add_tail
(
&
pe
->
child
,
&
parent
->
child_list
);
list_add_tail
(
&
edev
->
list
,
&
pe
->
edevs
);
list_add_tail
(
&
edev
->
list
,
&
pe
->
edevs
);
edev
->
pe
=
pe
;
edev
->
pe
=
pe
;
pr_debug
(
"EEH: Add %s to Device PE#%x, Parent PE#%x
\n
"
,
pr_debug
(
"EEH: Add %04x:%02x:%02x.%01x to "
edev
->
dn
->
full_name
,
pe
->
addr
,
pe
->
parent
->
addr
);
"Device PE#%x, Parent PE#%x
\n
"
,
edev
->
phb
->
global_number
,
edev
->
config_addr
>>
8
,
PCI_SLOT
(
edev
->
config_addr
&
0xFF
),
PCI_FUNC
(
edev
->
config_addr
&
0xFF
),
pe
->
addr
,
pe
->
parent
->
addr
);
return
0
;
return
0
;
}
}
...
@@ -430,8 +442,11 @@ int eeh_rmv_from_parent_pe(struct eeh_dev *edev)
...
@@ -430,8 +442,11 @@ int eeh_rmv_from_parent_pe(struct eeh_dev *edev)
int
cnt
;
int
cnt
;
if
(
!
edev
->
pe
)
{
if
(
!
edev
->
pe
)
{
pr_debug
(
"%s: No PE found for EEH device %s
\n
"
,
pr_debug
(
"%s: No PE found for device %04x:%02x:%02x.%01x
\n
"
,
__func__
,
edev
->
dn
->
full_name
);
__func__
,
edev
->
phb
->
global_number
,
edev
->
config_addr
>>
8
,
PCI_SLOT
(
edev
->
config_addr
&
0xFF
),
PCI_FUNC
(
edev
->
config_addr
&
0xFF
));
return
-
EEXIST
;
return
-
EEXIST
;
}
}
...
@@ -653,9 +668,9 @@ void eeh_pe_state_clear(struct eeh_pe *pe, int state)
...
@@ -653,9 +668,9 @@ void eeh_pe_state_clear(struct eeh_pe *pe, int state)
* blocked on normal path during the stage. So we need utilize
* blocked on normal path during the stage. So we need utilize
* eeh operations, which is always permitted.
* eeh operations, which is always permitted.
*/
*/
static
void
eeh_bridge_check_link
(
struct
eeh_dev
*
edev
,
static
void
eeh_bridge_check_link
(
struct
eeh_dev
*
edev
)
struct
device_node
*
dn
)
{
{
struct
pci_dn
*
pdn
=
eeh_dev_to_pdn
(
edev
);
int
cap
;
int
cap
;
uint32_t
val
;
uint32_t
val
;
int
timeout
=
0
;
int
timeout
=
0
;
...
@@ -675,32 +690,32 @@ static void eeh_bridge_check_link(struct eeh_dev *edev,
...
@@ -675,32 +690,32 @@ static void eeh_bridge_check_link(struct eeh_dev *edev,
/* Check slot status */
/* Check slot status */
cap
=
edev
->
pcie_cap
;
cap
=
edev
->
pcie_cap
;
eeh_ops
->
read_config
(
dn
,
cap
+
PCI_EXP_SLTSTA
,
2
,
&
val
);
eeh_ops
->
read_config
(
p
dn
,
cap
+
PCI_EXP_SLTSTA
,
2
,
&
val
);
if
(
!
(
val
&
PCI_EXP_SLTSTA_PDS
))
{
if
(
!
(
val
&
PCI_EXP_SLTSTA_PDS
))
{
pr_debug
(
" No card in the slot (0x%04x) !
\n
"
,
val
);
pr_debug
(
" No card in the slot (0x%04x) !
\n
"
,
val
);
return
;
return
;
}
}
/* Check power status if we have the capability */
/* Check power status if we have the capability */
eeh_ops
->
read_config
(
dn
,
cap
+
PCI_EXP_SLTCAP
,
2
,
&
val
);
eeh_ops
->
read_config
(
p
dn
,
cap
+
PCI_EXP_SLTCAP
,
2
,
&
val
);
if
(
val
&
PCI_EXP_SLTCAP_PCP
)
{
if
(
val
&
PCI_EXP_SLTCAP_PCP
)
{
eeh_ops
->
read_config
(
dn
,
cap
+
PCI_EXP_SLTCTL
,
2
,
&
val
);
eeh_ops
->
read_config
(
p
dn
,
cap
+
PCI_EXP_SLTCTL
,
2
,
&
val
);
if
(
val
&
PCI_EXP_SLTCTL_PCC
)
{
if
(
val
&
PCI_EXP_SLTCTL_PCC
)
{
pr_debug
(
" In power-off state, power it on ...
\n
"
);
pr_debug
(
" In power-off state, power it on ...
\n
"
);
val
&=
~
(
PCI_EXP_SLTCTL_PCC
|
PCI_EXP_SLTCTL_PIC
);
val
&=
~
(
PCI_EXP_SLTCTL_PCC
|
PCI_EXP_SLTCTL_PIC
);
val
|=
(
0x0100
&
PCI_EXP_SLTCTL_PIC
);
val
|=
(
0x0100
&
PCI_EXP_SLTCTL_PIC
);
eeh_ops
->
write_config
(
dn
,
cap
+
PCI_EXP_SLTCTL
,
2
,
val
);
eeh_ops
->
write_config
(
p
dn
,
cap
+
PCI_EXP_SLTCTL
,
2
,
val
);
msleep
(
2
*
1000
);
msleep
(
2
*
1000
);
}
}
}
}
/* Enable link */
/* Enable link */
eeh_ops
->
read_config
(
dn
,
cap
+
PCI_EXP_LNKCTL
,
2
,
&
val
);
eeh_ops
->
read_config
(
p
dn
,
cap
+
PCI_EXP_LNKCTL
,
2
,
&
val
);
val
&=
~
PCI_EXP_LNKCTL_LD
;
val
&=
~
PCI_EXP_LNKCTL_LD
;
eeh_ops
->
write_config
(
dn
,
cap
+
PCI_EXP_LNKCTL
,
2
,
val
);
eeh_ops
->
write_config
(
p
dn
,
cap
+
PCI_EXP_LNKCTL
,
2
,
val
);
/* Check link */
/* Check link */
eeh_ops
->
read_config
(
dn
,
cap
+
PCI_EXP_LNKCAP
,
4
,
&
val
);
eeh_ops
->
read_config
(
p
dn
,
cap
+
PCI_EXP_LNKCAP
,
4
,
&
val
);
if
(
!
(
val
&
PCI_EXP_LNKCAP_DLLLARC
))
{
if
(
!
(
val
&
PCI_EXP_LNKCAP_DLLLARC
))
{
pr_debug
(
" No link reporting capability (0x%08x)
\n
"
,
val
);
pr_debug
(
" No link reporting capability (0x%08x)
\n
"
,
val
);
msleep
(
1000
);
msleep
(
1000
);
...
@@ -713,7 +728,7 @@ static void eeh_bridge_check_link(struct eeh_dev *edev,
...
@@ -713,7 +728,7 @@ static void eeh_bridge_check_link(struct eeh_dev *edev,
msleep
(
20
);
msleep
(
20
);
timeout
+=
20
;
timeout
+=
20
;
eeh_ops
->
read_config
(
dn
,
cap
+
PCI_EXP_LNKSTA
,
2
,
&
val
);
eeh_ops
->
read_config
(
p
dn
,
cap
+
PCI_EXP_LNKSTA
,
2
,
&
val
);
if
(
val
&
PCI_EXP_LNKSTA_DLLLA
)
if
(
val
&
PCI_EXP_LNKSTA_DLLLA
)
break
;
break
;
}
}
...
@@ -728,9 +743,9 @@ static void eeh_bridge_check_link(struct eeh_dev *edev,
...
@@ -728,9 +743,9 @@ static void eeh_bridge_check_link(struct eeh_dev *edev,
#define BYTE_SWAP(OFF) (8*((OFF)/4)+3-(OFF))
#define BYTE_SWAP(OFF) (8*((OFF)/4)+3-(OFF))
#define SAVED_BYTE(OFF) (((u8 *)(edev->config_space))[BYTE_SWAP(OFF)])
#define SAVED_BYTE(OFF) (((u8 *)(edev->config_space))[BYTE_SWAP(OFF)])
static
void
eeh_restore_bridge_bars
(
struct
eeh_dev
*
edev
,
static
void
eeh_restore_bridge_bars
(
struct
eeh_dev
*
edev
)
struct
device_node
*
dn
)
{
{
struct
pci_dn
*
pdn
=
eeh_dev_to_pdn
(
edev
);
int
i
;
int
i
;
/*
/*
...
@@ -738,49 +753,49 @@ static void eeh_restore_bridge_bars(struct eeh_dev *edev,
...
@@ -738,49 +753,49 @@ static void eeh_restore_bridge_bars(struct eeh_dev *edev,
* Bus numbers and windows: 0x18 - 0x30
* Bus numbers and windows: 0x18 - 0x30
*/
*/
for
(
i
=
4
;
i
<
13
;
i
++
)
for
(
i
=
4
;
i
<
13
;
i
++
)
eeh_ops
->
write_config
(
dn
,
i
*
4
,
4
,
edev
->
config_space
[
i
]);
eeh_ops
->
write_config
(
p
dn
,
i
*
4
,
4
,
edev
->
config_space
[
i
]);
/* Rom: 0x38 */
/* Rom: 0x38 */
eeh_ops
->
write_config
(
dn
,
14
*
4
,
4
,
edev
->
config_space
[
14
]);
eeh_ops
->
write_config
(
p
dn
,
14
*
4
,
4
,
edev
->
config_space
[
14
]);
/* Cache line & Latency timer: 0xC 0xD */
/* Cache line & Latency timer: 0xC 0xD */
eeh_ops
->
write_config
(
dn
,
PCI_CACHE_LINE_SIZE
,
1
,
eeh_ops
->
write_config
(
p
dn
,
PCI_CACHE_LINE_SIZE
,
1
,
SAVED_BYTE
(
PCI_CACHE_LINE_SIZE
));
SAVED_BYTE
(
PCI_CACHE_LINE_SIZE
));
eeh_ops
->
write_config
(
dn
,
PCI_LATENCY_TIMER
,
1
,
eeh_ops
->
write_config
(
p
dn
,
PCI_LATENCY_TIMER
,
1
,
SAVED_BYTE
(
PCI_LATENCY_TIMER
));
SAVED_BYTE
(
PCI_LATENCY_TIMER
));
/* Max latency, min grant, interrupt ping and line: 0x3C */
/* Max latency, min grant, interrupt ping and line: 0x3C */
eeh_ops
->
write_config
(
dn
,
15
*
4
,
4
,
edev
->
config_space
[
15
]);
eeh_ops
->
write_config
(
p
dn
,
15
*
4
,
4
,
edev
->
config_space
[
15
]);
/* PCI Command: 0x4 */
/* PCI Command: 0x4 */
eeh_ops
->
write_config
(
dn
,
PCI_COMMAND
,
4
,
edev
->
config_space
[
1
]);
eeh_ops
->
write_config
(
p
dn
,
PCI_COMMAND
,
4
,
edev
->
config_space
[
1
]);
/* Check the PCIe link is ready */
/* Check the PCIe link is ready */
eeh_bridge_check_link
(
edev
,
dn
);
eeh_bridge_check_link
(
edev
);
}
}
static
void
eeh_restore_device_bars
(
struct
eeh_dev
*
edev
,
static
void
eeh_restore_device_bars
(
struct
eeh_dev
*
edev
)
struct
device_node
*
dn
)
{
{
struct
pci_dn
*
pdn
=
eeh_dev_to_pdn
(
edev
);
int
i
;
int
i
;
u32
cmd
;
u32
cmd
;
for
(
i
=
4
;
i
<
10
;
i
++
)
for
(
i
=
4
;
i
<
10
;
i
++
)
eeh_ops
->
write_config
(
dn
,
i
*
4
,
4
,
edev
->
config_space
[
i
]);
eeh_ops
->
write_config
(
p
dn
,
i
*
4
,
4
,
edev
->
config_space
[
i
]);
/* 12 == Expansion ROM Address */
/* 12 == Expansion ROM Address */
eeh_ops
->
write_config
(
dn
,
12
*
4
,
4
,
edev
->
config_space
[
12
]);
eeh_ops
->
write_config
(
p
dn
,
12
*
4
,
4
,
edev
->
config_space
[
12
]);
eeh_ops
->
write_config
(
dn
,
PCI_CACHE_LINE_SIZE
,
1
,
eeh_ops
->
write_config
(
p
dn
,
PCI_CACHE_LINE_SIZE
,
1
,
SAVED_BYTE
(
PCI_CACHE_LINE_SIZE
));
SAVED_BYTE
(
PCI_CACHE_LINE_SIZE
));
eeh_ops
->
write_config
(
dn
,
PCI_LATENCY_TIMER
,
1
,
eeh_ops
->
write_config
(
p
dn
,
PCI_LATENCY_TIMER
,
1
,
SAVED_BYTE
(
PCI_LATENCY_TIMER
));
SAVED_BYTE
(
PCI_LATENCY_TIMER
));
/* max latency, min grant, interrupt pin and line */
/* max latency, min grant, interrupt pin and line */
eeh_ops
->
write_config
(
dn
,
15
*
4
,
4
,
edev
->
config_space
[
15
]);
eeh_ops
->
write_config
(
p
dn
,
15
*
4
,
4
,
edev
->
config_space
[
15
]);
/*
/*
* Restore PERR & SERR bits, some devices require it,
* Restore PERR & SERR bits, some devices require it,
* don't touch the other command bits
* don't touch the other command bits
*/
*/
eeh_ops
->
read_config
(
dn
,
PCI_COMMAND
,
4
,
&
cmd
);
eeh_ops
->
read_config
(
p
dn
,
PCI_COMMAND
,
4
,
&
cmd
);
if
(
edev
->
config_space
[
1
]
&
PCI_COMMAND_PARITY
)
if
(
edev
->
config_space
[
1
]
&
PCI_COMMAND_PARITY
)
cmd
|=
PCI_COMMAND_PARITY
;
cmd
|=
PCI_COMMAND_PARITY
;
else
else
...
@@ -789,7 +804,7 @@ static void eeh_restore_device_bars(struct eeh_dev *edev,
...
@@ -789,7 +804,7 @@ static void eeh_restore_device_bars(struct eeh_dev *edev,
cmd
|=
PCI_COMMAND_SERR
;
cmd
|=
PCI_COMMAND_SERR
;
else
else
cmd
&=
~
PCI_COMMAND_SERR
;
cmd
&=
~
PCI_COMMAND_SERR
;
eeh_ops
->
write_config
(
dn
,
PCI_COMMAND
,
4
,
cmd
);
eeh_ops
->
write_config
(
p
dn
,
PCI_COMMAND
,
4
,
cmd
);
}
}
/**
/**
...
@@ -804,16 +819,16 @@ static void eeh_restore_device_bars(struct eeh_dev *edev,
...
@@ -804,16 +819,16 @@ static void eeh_restore_device_bars(struct eeh_dev *edev,
static
void
*
eeh_restore_one_device_bars
(
void
*
data
,
void
*
flag
)
static
void
*
eeh_restore_one_device_bars
(
void
*
data
,
void
*
flag
)
{
{
struct
eeh_dev
*
edev
=
(
struct
eeh_dev
*
)
data
;
struct
eeh_dev
*
edev
=
(
struct
eeh_dev
*
)
data
;
struct
device_node
*
dn
=
eeh_dev_to_of_node
(
edev
);
struct
pci_dn
*
pdn
=
eeh_dev_to_pdn
(
edev
);
/* Do special restore for bridges */
/* Do special restore for bridges */
if
(
edev
->
mode
&
EEH_DEV_BRIDGE
)
if
(
edev
->
mode
&
EEH_DEV_BRIDGE
)
eeh_restore_bridge_bars
(
edev
,
dn
);
eeh_restore_bridge_bars
(
edev
);
else
else
eeh_restore_device_bars
(
edev
,
dn
);
eeh_restore_device_bars
(
edev
);
if
(
eeh_ops
->
restore_config
)
if
(
eeh_ops
->
restore_config
&&
pdn
)
eeh_ops
->
restore_config
(
dn
);
eeh_ops
->
restore_config
(
p
dn
);
return
NULL
;
return
NULL
;
}
}
...
...
arch/powerpc/kernel/of_platform.c
View file @
428d4d65
...
@@ -72,7 +72,7 @@ static int of_pci_phb_probe(struct platform_device *dev)
...
@@ -72,7 +72,7 @@ static int of_pci_phb_probe(struct platform_device *dev)
/* Register devices with EEH */
/* Register devices with EEH */
if
(
dev
->
dev
.
of_node
->
child
)
if
(
dev
->
dev
.
of_node
->
child
)
eeh_add_device_tree_early
(
dev
->
dev
.
of_node
);
eeh_add_device_tree_early
(
PCI_DN
(
dev
->
dev
.
of_node
)
);
/* Scan the bus */
/* Scan the bus */
pcibios_scan_phb
(
phb
);
pcibios_scan_phb
(
phb
);
...
...
arch/powerpc/kernel/pci-hotplug.c
View file @
428d4d65
...
@@ -75,7 +75,7 @@ void pcibios_add_pci_devices(struct pci_bus * bus)
...
@@ -75,7 +75,7 @@ void pcibios_add_pci_devices(struct pci_bus * bus)
struct
pci_dev
*
dev
;
struct
pci_dev
*
dev
;
struct
device_node
*
dn
=
pci_bus_to_OF_node
(
bus
);
struct
device_node
*
dn
=
pci_bus_to_OF_node
(
bus
);
eeh_add_device_tree_early
(
dn
);
eeh_add_device_tree_early
(
PCI_DN
(
dn
)
);
mode
=
PCI_PROBE_NORMAL
;
mode
=
PCI_PROBE_NORMAL
;
if
(
ppc_md
.
pci_probe_mode
)
if
(
ppc_md
.
pci_probe_mode
)
...
...
arch/powerpc/kernel/pci_dn.c
View file @
428d4d65
...
@@ -32,12 +32,108 @@
...
@@ -32,12 +32,108 @@
#include <asm/ppc-pci.h>
#include <asm/ppc-pci.h>
#include <asm/firmware.h>
#include <asm/firmware.h>
/*
* The function is used to find the firmware data of one
* specific PCI device, which is attached to the indicated
* PCI bus. For VFs, their firmware data is linked to that
* one of PF's bridge. For other devices, their firmware
* data is linked to that of their bridge.
*/
static
struct
pci_dn
*
pci_bus_to_pdn
(
struct
pci_bus
*
bus
)
{
struct
pci_bus
*
pbus
;
struct
device_node
*
dn
;
struct
pci_dn
*
pdn
;
/*
* We probably have virtual bus which doesn't
* have associated bridge.
*/
pbus
=
bus
;
while
(
pbus
)
{
if
(
pci_is_root_bus
(
pbus
)
||
pbus
->
self
)
break
;
pbus
=
pbus
->
parent
;
}
/*
* Except virtual bus, all PCI buses should
* have device nodes.
*/
dn
=
pci_bus_to_OF_node
(
pbus
);
pdn
=
dn
?
PCI_DN
(
dn
)
:
NULL
;
return
pdn
;
}
struct
pci_dn
*
pci_get_pdn_by_devfn
(
struct
pci_bus
*
bus
,
int
devfn
)
{
struct
device_node
*
dn
=
NULL
;
struct
pci_dn
*
parent
,
*
pdn
;
struct
pci_dev
*
pdev
=
NULL
;
/* Fast path: fetch from PCI device */
list_for_each_entry
(
pdev
,
&
bus
->
devices
,
bus_list
)
{
if
(
pdev
->
devfn
==
devfn
)
{
if
(
pdev
->
dev
.
archdata
.
pci_data
)
return
pdev
->
dev
.
archdata
.
pci_data
;
dn
=
pci_device_to_OF_node
(
pdev
);
break
;
}
}
/* Fast path: fetch from device node */
pdn
=
dn
?
PCI_DN
(
dn
)
:
NULL
;
if
(
pdn
)
return
pdn
;
/* Slow path: fetch from firmware data hierarchy */
parent
=
pci_bus_to_pdn
(
bus
);
if
(
!
parent
)
return
NULL
;
list_for_each_entry
(
pdn
,
&
parent
->
child_list
,
list
)
{
if
(
pdn
->
busno
==
bus
->
number
&&
pdn
->
devfn
==
devfn
)
return
pdn
;
}
return
NULL
;
}
struct
pci_dn
*
pci_get_pdn
(
struct
pci_dev
*
pdev
)
struct
pci_dn
*
pci_get_pdn
(
struct
pci_dev
*
pdev
)
{
{
struct
device_node
*
dn
=
pci_device_to_OF_node
(
pdev
);
struct
device_node
*
dn
;
if
(
!
dn
)
struct
pci_dn
*
parent
,
*
pdn
;
/* Search device directly */
if
(
pdev
->
dev
.
archdata
.
pci_data
)
return
pdev
->
dev
.
archdata
.
pci_data
;
/* Check device node */
dn
=
pci_device_to_OF_node
(
pdev
);
pdn
=
dn
?
PCI_DN
(
dn
)
:
NULL
;
if
(
pdn
)
return
pdn
;
/*
* VFs don't have device nodes. We hook their
* firmware data to PF's bridge.
*/
parent
=
pci_bus_to_pdn
(
pdev
->
bus
);
if
(
!
parent
)
return
NULL
;
return
NULL
;
return
PCI_DN
(
dn
);
list_for_each_entry
(
pdn
,
&
parent
->
child_list
,
list
)
{
if
(
pdn
->
busno
==
pdev
->
bus
->
number
&&
pdn
->
devfn
==
pdev
->
devfn
)
return
pdn
;
}
return
NULL
;
}
}
/*
/*
...
@@ -49,6 +145,7 @@ void *update_dn_pci_info(struct device_node *dn, void *data)
...
@@ -49,6 +145,7 @@ void *update_dn_pci_info(struct device_node *dn, void *data)
struct
pci_controller
*
phb
=
data
;
struct
pci_controller
*
phb
=
data
;
const
__be32
*
type
=
of_get_property
(
dn
,
"ibm,pci-config-space-type"
,
NULL
);
const
__be32
*
type
=
of_get_property
(
dn
,
"ibm,pci-config-space-type"
,
NULL
);
const
__be32
*
regs
;
const
__be32
*
regs
;
struct
device_node
*
parent
;
struct
pci_dn
*
pdn
;
struct
pci_dn
*
pdn
;
pdn
=
zalloc_maybe_bootmem
(
sizeof
(
*
pdn
),
GFP_KERNEL
);
pdn
=
zalloc_maybe_bootmem
(
sizeof
(
*
pdn
),
GFP_KERNEL
);
...
@@ -69,7 +166,25 @@ void *update_dn_pci_info(struct device_node *dn, void *data)
...
@@ -69,7 +166,25 @@ void *update_dn_pci_info(struct device_node *dn, void *data)
pdn
->
devfn
=
(
addr
>>
8
)
&
0xff
;
pdn
->
devfn
=
(
addr
>>
8
)
&
0xff
;
}
}
/* vendor/device IDs and class code */
regs
=
of_get_property
(
dn
,
"vendor-id"
,
NULL
);
pdn
->
vendor_id
=
regs
?
of_read_number
(
regs
,
1
)
:
0
;
regs
=
of_get_property
(
dn
,
"device-id"
,
NULL
);
pdn
->
device_id
=
regs
?
of_read_number
(
regs
,
1
)
:
0
;
regs
=
of_get_property
(
dn
,
"class-code"
,
NULL
);
pdn
->
class_code
=
regs
?
of_read_number
(
regs
,
1
)
:
0
;
/* Extended config space */
pdn
->
pci_ext_config_space
=
(
type
&&
of_read_number
(
type
,
1
)
==
1
);
pdn
->
pci_ext_config_space
=
(
type
&&
of_read_number
(
type
,
1
)
==
1
);
/* Attach to parent node */
INIT_LIST_HEAD
(
&
pdn
->
child_list
);
INIT_LIST_HEAD
(
&
pdn
->
list
);
parent
=
of_get_parent
(
dn
);
pdn
->
parent
=
parent
?
PCI_DN
(
parent
)
:
NULL
;
if
(
pdn
->
parent
)
list_add_tail
(
&
pdn
->
list
,
&
pdn
->
parent
->
child_list
);
return
NULL
;
return
NULL
;
}
}
...
@@ -131,6 +246,46 @@ void *traverse_pci_devices(struct device_node *start, traverse_func pre,
...
@@ -131,6 +246,46 @@ void *traverse_pci_devices(struct device_node *start, traverse_func pre,
return
NULL
;
return
NULL
;
}
}
static
struct
pci_dn
*
pci_dn_next_one
(
struct
pci_dn
*
root
,
struct
pci_dn
*
pdn
)
{
struct
list_head
*
next
=
pdn
->
child_list
.
next
;
if
(
next
!=
&
pdn
->
child_list
)
return
list_entry
(
next
,
struct
pci_dn
,
list
);
while
(
1
)
{
if
(
pdn
==
root
)
return
NULL
;
next
=
pdn
->
list
.
next
;
if
(
next
!=
&
pdn
->
parent
->
child_list
)
break
;
pdn
=
pdn
->
parent
;
}
return
list_entry
(
next
,
struct
pci_dn
,
list
);
}
void
*
traverse_pci_dn
(
struct
pci_dn
*
root
,
void
*
(
*
fn
)(
struct
pci_dn
*
,
void
*
),
void
*
data
)
{
struct
pci_dn
*
pdn
=
root
;
void
*
ret
;
/* Only scan the child nodes */
for
(
pdn
=
pci_dn_next_one
(
root
,
pdn
);
pdn
;
pdn
=
pci_dn_next_one
(
root
,
pdn
))
{
ret
=
fn
(
pdn
,
data
);
if
(
ret
)
return
ret
;
}
return
NULL
;
}
/**
/**
* pci_devs_phb_init_dynamic - setup pci devices under this PHB
* pci_devs_phb_init_dynamic - setup pci devices under this PHB
* phb: pci-to-host bridge (top-level bridge connecting to cpu)
* phb: pci-to-host bridge (top-level bridge connecting to cpu)
...
@@ -147,8 +302,12 @@ void pci_devs_phb_init_dynamic(struct pci_controller *phb)
...
@@ -147,8 +302,12 @@ void pci_devs_phb_init_dynamic(struct pci_controller *phb)
/* PHB nodes themselves must not match */
/* PHB nodes themselves must not match */
update_dn_pci_info
(
dn
,
phb
);
update_dn_pci_info
(
dn
,
phb
);
pdn
=
dn
->
data
;
pdn
=
dn
->
data
;
if
(
pdn
)
if
(
pdn
)
{
pdn
->
devfn
=
pdn
->
busno
=
-
1
;
pdn
->
devfn
=
pdn
->
busno
=
-
1
;
pdn
->
vendor_id
=
pdn
->
device_id
=
pdn
->
class_code
=
0
;
pdn
->
phb
=
phb
;
phb
->
pci_data
=
pdn
;
}
/* Update dn->phb ptrs for new phb and children devices */
/* Update dn->phb ptrs for new phb and children devices */
traverse_pci_devices
(
dn
,
update_dn_pci_info
,
phb
);
traverse_pci_devices
(
dn
,
update_dn_pci_info
,
phb
);
...
@@ -171,3 +330,16 @@ void __init pci_devs_phb_init(void)
...
@@ -171,3 +330,16 @@ void __init pci_devs_phb_init(void)
list_for_each_entry_safe
(
phb
,
tmp
,
&
hose_list
,
list_node
)
list_for_each_entry_safe
(
phb
,
tmp
,
&
hose_list
,
list_node
)
pci_devs_phb_init_dynamic
(
phb
);
pci_devs_phb_init_dynamic
(
phb
);
}
}
static
void
pci_dev_pdn_setup
(
struct
pci_dev
*
pdev
)
{
struct
pci_dn
*
pdn
;
if
(
pdev
->
dev
.
archdata
.
pci_data
)
return
;
/* Setup the fast path */
pdn
=
pci_get_pdn
(
pdev
);
pdev
->
dev
.
archdata
.
pci_data
=
pdn
;
}
DECLARE_PCI_FIXUP_EARLY
(
PCI_ANY_ID
,
PCI_ANY_ID
,
pci_dev_pdn_setup
);
arch/powerpc/kernel/pci_of_scan.c
View file @
428d4d65
...
@@ -305,7 +305,7 @@ static struct pci_dev *of_scan_pci_dev(struct pci_bus *bus,
...
@@ -305,7 +305,7 @@ static struct pci_dev *of_scan_pci_dev(struct pci_bus *bus,
const
__be32
*
reg
;
const
__be32
*
reg
;
int
reglen
,
devfn
;
int
reglen
,
devfn
;
#ifdef CONFIG_EEH
#ifdef CONFIG_EEH
struct
eeh_dev
*
edev
=
of_node_to_eeh_dev
(
dn
);
struct
eeh_dev
*
edev
=
pdn_to_eeh_dev
(
PCI_DN
(
dn
)
);
#endif
#endif
pr_debug
(
" * %s
\n
"
,
dn
->
full_name
);
pr_debug
(
" * %s
\n
"
,
dn
->
full_name
);
...
...
arch/powerpc/kernel/rtas_pci.c
View file @
428d4d65
...
@@ -113,7 +113,7 @@ static int rtas_pci_read_config(struct pci_bus *bus,
...
@@ -113,7 +113,7 @@ static int rtas_pci_read_config(struct pci_bus *bus,
ret
=
rtas_read_config
(
pdn
,
where
,
size
,
val
);
ret
=
rtas_read_config
(
pdn
,
where
,
size
,
val
);
if
(
*
val
==
EEH_IO_ERROR_VALUE
(
size
)
&&
if
(
*
val
==
EEH_IO_ERROR_VALUE
(
size
)
&&
eeh_dev_check_failure
(
of_node_to_eeh_dev
(
dn
)))
eeh_dev_check_failure
(
pdn_to_eeh_dev
(
p
dn
)))
return
PCIBIOS_DEVICE_NOT_FOUND
;
return
PCIBIOS_DEVICE_NOT_FOUND
;
return
ret
;
return
ret
;
...
...
arch/powerpc/platforms/powernv/Makefile
View file @
428d4d65
...
@@ -5,7 +5,7 @@ obj-y += opal-msglog.o opal-hmi.o opal-power.o
...
@@ -5,7 +5,7 @@ obj-y += opal-msglog.o opal-hmi.o opal-power.o
obj-$(CONFIG_SMP)
+=
smp.o subcore.o subcore-asm.o
obj-$(CONFIG_SMP)
+=
smp.o subcore.o subcore-asm.o
obj-$(CONFIG_PCI)
+=
pci.o pci-p5ioc2.o pci-ioda.o
obj-$(CONFIG_PCI)
+=
pci.o pci-p5ioc2.o pci-ioda.o
obj-$(CONFIG_EEH)
+=
eeh-
ioda.o eeh-
powernv.o
obj-$(CONFIG_EEH)
+=
eeh-powernv.o
obj-$(CONFIG_PPC_SCOM)
+=
opal-xscom.o
obj-$(CONFIG_PPC_SCOM)
+=
opal-xscom.o
obj-$(CONFIG_MEMORY_FAILURE)
+=
opal-memory-errors.o
obj-$(CONFIG_MEMORY_FAILURE)
+=
opal-memory-errors.o
obj-$(CONFIG_TRACEPOINTS)
+=
opal-tracepoints.o
obj-$(CONFIG_TRACEPOINTS)
+=
opal-tracepoints.o
arch/powerpc/platforms/powernv/eeh-ioda.c
deleted
100644 → 0
View file @
28ea605c
This diff is collapsed.
Click to expand it.
arch/powerpc/platforms/powernv/eeh-powernv.c
View file @
428d4d65
This diff is collapsed.
Click to expand it.
arch/powerpc/platforms/powernv/pci-ioda.c
View file @
428d4d65
...
@@ -1777,7 +1777,8 @@ static void pnv_ioda_setup_pe_seg(struct pci_controller *hose,
...
@@ -1777,7 +1777,8 @@ static void pnv_ioda_setup_pe_seg(struct pci_controller *hose,
region
.
start
+=
phb
->
ioda
.
io_segsize
;
region
.
start
+=
phb
->
ioda
.
io_segsize
;
index
++
;
index
++
;
}
}
}
else
if
(
res
->
flags
&
IORESOURCE_MEM
)
{
}
else
if
((
res
->
flags
&
IORESOURCE_MEM
)
&&
!
pnv_pci_is_mem_pref_64
(
res
->
flags
))
{
region
.
start
=
res
->
start
-
region
.
start
=
res
->
start
-
hose
->
mem_offset
[
0
]
-
hose
->
mem_offset
[
0
]
-
phb
->
ioda
.
m32_pci_base
;
phb
->
ioda
.
m32_pci_base
;
...
@@ -2078,9 +2079,6 @@ static void __init pnv_pci_init_ioda_phb(struct device_node *np,
...
@@ -2078,9 +2079,6 @@ static void __init pnv_pci_init_ioda_phb(struct device_node *np,
phb
->
get_pe_state
=
pnv_ioda_get_pe_state
;
phb
->
get_pe_state
=
pnv_ioda_get_pe_state
;
phb
->
freeze_pe
=
pnv_ioda_freeze_pe
;
phb
->
freeze_pe
=
pnv_ioda_freeze_pe
;
phb
->
unfreeze_pe
=
pnv_ioda_unfreeze_pe
;
phb
->
unfreeze_pe
=
pnv_ioda_unfreeze_pe
;
#ifdef CONFIG_EEH
phb
->
eeh_ops
=
&
ioda_eeh_ops
;
#endif
/* Setup RID -> PE mapping function */
/* Setup RID -> PE mapping function */
phb
->
bdfn_to_pe
=
pnv_ioda_bdfn_to_pe
;
phb
->
bdfn_to_pe
=
pnv_ioda_bdfn_to_pe
;
...
@@ -2121,8 +2119,8 @@ static void __init pnv_pci_init_ioda_phb(struct device_node *np,
...
@@ -2121,8 +2119,8 @@ static void __init pnv_pci_init_ioda_phb(struct device_node *np,
*/
*/
if
(
is_kdump_kernel
())
{
if
(
is_kdump_kernel
())
{
pr_info
(
" Issue PHB reset ...
\n
"
);
pr_info
(
" Issue PHB reset ...
\n
"
);
ioda
_eeh_phb_reset
(
hose
,
EEH_RESET_FUNDAMENTAL
);
pnv
_eeh_phb_reset
(
hose
,
EEH_RESET_FUNDAMENTAL
);
ioda
_eeh_phb_reset
(
hose
,
EEH_RESET_DEACTIVATE
);
pnv
_eeh_phb_reset
(
hose
,
EEH_RESET_DEACTIVATE
);
}
}
/* Remove M64 resource if we can't configure it successfully */
/* Remove M64 resource if we can't configure it successfully */
...
...
arch/powerpc/platforms/powernv/pci.c
View file @
428d4d65
...
@@ -366,9 +366,9 @@ static void pnv_pci_handle_eeh_config(struct pnv_phb *phb, u32 pe_no)
...
@@ -366,9 +366,9 @@ static void pnv_pci_handle_eeh_config(struct pnv_phb *phb, u32 pe_no)
spin_unlock_irqrestore
(
&
phb
->
lock
,
flags
);
spin_unlock_irqrestore
(
&
phb
->
lock
,
flags
);
}
}
static
void
pnv_pci_config_check_eeh
(
struct
pnv_phb
*
phb
,
static
void
pnv_pci_config_check_eeh
(
struct
pci_dn
*
pdn
)
struct
device_node
*
dn
)
{
{
struct
pnv_phb
*
phb
=
pdn
->
phb
->
private_data
;
u8
fstate
;
u8
fstate
;
__be16
pcierr
;
__be16
pcierr
;
int
pe_no
;
int
pe_no
;
...
@@ -379,7 +379,7 @@ static void pnv_pci_config_check_eeh(struct pnv_phb *phb,
...
@@ -379,7 +379,7 @@ static void pnv_pci_config_check_eeh(struct pnv_phb *phb,
* setup that yet. So all ER errors should be mapped to
* setup that yet. So all ER errors should be mapped to
* reserved PE.
* reserved PE.
*/
*/
pe_no
=
PCI_DN
(
dn
)
->
pe_number
;
pe_no
=
pdn
->
pe_number
;
if
(
pe_no
==
IODA_INVALID_PE
)
{
if
(
pe_no
==
IODA_INVALID_PE
)
{
if
(
phb
->
type
==
PNV_PHB_P5IOC2
)
if
(
phb
->
type
==
PNV_PHB_P5IOC2
)
pe_no
=
0
;
pe_no
=
0
;
...
@@ -407,8 +407,7 @@ static void pnv_pci_config_check_eeh(struct pnv_phb *phb,
...
@@ -407,8 +407,7 @@ static void pnv_pci_config_check_eeh(struct pnv_phb *phb,
}
}
cfg_dbg
(
" -> EEH check, bdfn=%04x PE#%d fstate=%x
\n
"
,
cfg_dbg
(
" -> EEH check, bdfn=%04x PE#%d fstate=%x
\n
"
,
(
PCI_DN
(
dn
)
->
busno
<<
8
)
|
(
PCI_DN
(
dn
)
->
devfn
),
(
pdn
->
busno
<<
8
)
|
(
pdn
->
devfn
),
pe_no
,
fstate
);
pe_no
,
fstate
);
/* Clear the frozen state if applicable */
/* Clear the frozen state if applicable */
if
(
fstate
==
OPAL_EEH_STOPPED_MMIO_FREEZE
||
if
(
fstate
==
OPAL_EEH_STOPPED_MMIO_FREEZE
||
...
@@ -425,10 +424,9 @@ static void pnv_pci_config_check_eeh(struct pnv_phb *phb,
...
@@ -425,10 +424,9 @@ static void pnv_pci_config_check_eeh(struct pnv_phb *phb,
}
}
}
}
int
pnv_pci_cfg_read
(
struct
device_node
*
dn
,
int
pnv_pci_cfg_read
(
struct
pci_dn
*
p
dn
,
int
where
,
int
size
,
u32
*
val
)
int
where
,
int
size
,
u32
*
val
)
{
{
struct
pci_dn
*
pdn
=
PCI_DN
(
dn
);
struct
pnv_phb
*
phb
=
pdn
->
phb
->
private_data
;
struct
pnv_phb
*
phb
=
pdn
->
phb
->
private_data
;
u32
bdfn
=
(
pdn
->
busno
<<
8
)
|
pdn
->
devfn
;
u32
bdfn
=
(
pdn
->
busno
<<
8
)
|
pdn
->
devfn
;
s64
rc
;
s64
rc
;
...
@@ -462,10 +460,9 @@ int pnv_pci_cfg_read(struct device_node *dn,
...
@@ -462,10 +460,9 @@ int pnv_pci_cfg_read(struct device_node *dn,
return
PCIBIOS_SUCCESSFUL
;
return
PCIBIOS_SUCCESSFUL
;
}
}
int
pnv_pci_cfg_write
(
struct
device_node
*
dn
,
int
pnv_pci_cfg_write
(
struct
pci_dn
*
p
dn
,
int
where
,
int
size
,
u32
val
)
int
where
,
int
size
,
u32
val
)
{
{
struct
pci_dn
*
pdn
=
PCI_DN
(
dn
);
struct
pnv_phb
*
phb
=
pdn
->
phb
->
private_data
;
struct
pnv_phb
*
phb
=
pdn
->
phb
->
private_data
;
u32
bdfn
=
(
pdn
->
busno
<<
8
)
|
pdn
->
devfn
;
u32
bdfn
=
(
pdn
->
busno
<<
8
)
|
pdn
->
devfn
;
...
@@ -489,18 +486,17 @@ int pnv_pci_cfg_write(struct device_node *dn,
...
@@ -489,18 +486,17 @@ int pnv_pci_cfg_write(struct device_node *dn,
}
}
#if CONFIG_EEH
#if CONFIG_EEH
static
bool
pnv_pci_cfg_check
(
struct
pci_controller
*
hose
,
static
bool
pnv_pci_cfg_check
(
struct
pci_dn
*
pdn
)
struct
device_node
*
dn
)
{
{
struct
eeh_dev
*
edev
=
NULL
;
struct
eeh_dev
*
edev
=
NULL
;
struct
pnv_phb
*
phb
=
hose
->
private_data
;
struct
pnv_phb
*
phb
=
pdn
->
phb
->
private_data
;
/* EEH not enabled ? */
/* EEH not enabled ? */
if
(
!
(
phb
->
flags
&
PNV_PHB_FLAG_EEH
))
if
(
!
(
phb
->
flags
&
PNV_PHB_FLAG_EEH
))
return
true
;
return
true
;
/* PE reset or device removed ? */
/* PE reset or device removed ? */
edev
=
of_node_to_eeh_dev
(
dn
)
;
edev
=
pdn
->
edev
;
if
(
edev
)
{
if
(
edev
)
{
if
(
edev
->
pe
&&
if
(
edev
->
pe
&&
(
edev
->
pe
->
state
&
EEH_PE_CFG_BLOCKED
))
(
edev
->
pe
->
state
&
EEH_PE_CFG_BLOCKED
))
...
@@ -513,8 +509,7 @@ static bool pnv_pci_cfg_check(struct pci_controller *hose,
...
@@ -513,8 +509,7 @@ static bool pnv_pci_cfg_check(struct pci_controller *hose,
return
true
;
return
true
;
}
}
#else
#else
static
inline
pnv_pci_cfg_check
(
struct
pci_controller
*
hose
,
static
inline
pnv_pci_cfg_check
(
struct
pci_dn
*
pdn
)
struct
device_node
*
dn
)
{
{
return
true
;
return
true
;
}
}
...
@@ -524,32 +519,26 @@ static int pnv_pci_read_config(struct pci_bus *bus,
...
@@ -524,32 +519,26 @@ static int pnv_pci_read_config(struct pci_bus *bus,
unsigned
int
devfn
,
unsigned
int
devfn
,
int
where
,
int
size
,
u32
*
val
)
int
where
,
int
size
,
u32
*
val
)
{
{
struct
device_node
*
dn
,
*
busdn
=
pci_bus_to_OF_node
(
bus
);
struct
pci_dn
*
pdn
;
struct
pci_dn
*
pdn
;
struct
pnv_phb
*
phb
;
struct
pnv_phb
*
phb
;
bool
found
=
false
;
int
ret
;
int
ret
;
*
val
=
0xFFFFFFFF
;
*
val
=
0xFFFFFFFF
;
for
(
dn
=
busdn
->
child
;
dn
;
dn
=
dn
->
sibling
)
{
pdn
=
pci_get_pdn_by_devfn
(
bus
,
devfn
);
pdn
=
PCI_DN
(
dn
);
if
(
!
pdn
)
if
(
pdn
&&
pdn
->
devfn
==
devfn
)
{
return
PCIBIOS_DEVICE_NOT_FOUND
;
phb
=
pdn
->
phb
->
private_data
;
found
=
true
;
break
;
}
}
if
(
!
found
||
!
pnv_pci_cfg_check
(
pdn
->
phb
,
dn
))
if
(
!
pnv_pci_cfg_check
(
p
dn
))
return
PCIBIOS_DEVICE_NOT_FOUND
;
return
PCIBIOS_DEVICE_NOT_FOUND
;
ret
=
pnv_pci_cfg_read
(
dn
,
where
,
size
,
val
);
ret
=
pnv_pci_cfg_read
(
pdn
,
where
,
size
,
val
);
if
(
phb
->
flags
&
PNV_PHB_FLAG_EEH
)
{
phb
=
pdn
->
phb
->
private_data
;
if
(
phb
->
flags
&
PNV_PHB_FLAG_EEH
&&
pdn
->
edev
)
{
if
(
*
val
==
EEH_IO_ERROR_VALUE
(
size
)
&&
if
(
*
val
==
EEH_IO_ERROR_VALUE
(
size
)
&&
eeh_dev_check_failure
(
of_node_to_eeh_dev
(
dn
)
))
eeh_dev_check_failure
(
pdn
->
edev
))
return
PCIBIOS_DEVICE_NOT_FOUND
;
return
PCIBIOS_DEVICE_NOT_FOUND
;
}
else
{
}
else
{
pnv_pci_config_check_eeh
(
p
hb
,
dn
);
pnv_pci_config_check_eeh
(
pdn
);
}
}
return
ret
;
return
ret
;
...
@@ -559,27 +548,21 @@ static int pnv_pci_write_config(struct pci_bus *bus,
...
@@ -559,27 +548,21 @@ static int pnv_pci_write_config(struct pci_bus *bus,
unsigned
int
devfn
,
unsigned
int
devfn
,
int
where
,
int
size
,
u32
val
)
int
where
,
int
size
,
u32
val
)
{
{
struct
device_node
*
dn
,
*
busdn
=
pci_bus_to_OF_node
(
bus
);
struct
pci_dn
*
pdn
;
struct
pci_dn
*
pdn
;
struct
pnv_phb
*
phb
;
struct
pnv_phb
*
phb
;
bool
found
=
false
;
int
ret
;
int
ret
;
for
(
dn
=
busdn
->
child
;
dn
;
dn
=
dn
->
sibling
)
{
pdn
=
pci_get_pdn_by_devfn
(
bus
,
devfn
);
pdn
=
PCI_DN
(
dn
);
if
(
!
pdn
)
if
(
pdn
&&
pdn
->
devfn
==
devfn
)
{
return
PCIBIOS_DEVICE_NOT_FOUND
;
phb
=
pdn
->
phb
->
private_data
;
found
=
true
;
break
;
}
}
if
(
!
found
||
!
pnv_pci_cfg_check
(
pdn
->
phb
,
dn
))
if
(
!
pnv_pci_cfg_check
(
p
dn
))
return
PCIBIOS_DEVICE_NOT_FOUND
;
return
PCIBIOS_DEVICE_NOT_FOUND
;
ret
=
pnv_pci_cfg_write
(
dn
,
where
,
size
,
val
);
ret
=
pnv_pci_cfg_write
(
pdn
,
where
,
size
,
val
);
phb
=
pdn
->
phb
->
private_data
;
if
(
!
(
phb
->
flags
&
PNV_PHB_FLAG_EEH
))
if
(
!
(
phb
->
flags
&
PNV_PHB_FLAG_EEH
))
pnv_pci_config_check_eeh
(
p
hb
,
dn
);
pnv_pci_config_check_eeh
(
pdn
);
return
ret
;
return
ret
;
}
}
...
...
arch/powerpc/platforms/powernv/pci.h
View file @
428d4d65
...
@@ -75,22 +75,6 @@ struct pnv_ioda_pe {
...
@@ -75,22 +75,6 @@ struct pnv_ioda_pe {
struct
list_head
list
;
struct
list_head
list
;
};
};
/* IOC dependent EEH operations */
#ifdef CONFIG_EEH
struct
pnv_eeh_ops
{
int
(
*
post_init
)(
struct
pci_controller
*
hose
);
int
(
*
set_option
)(
struct
eeh_pe
*
pe
,
int
option
);
int
(
*
get_state
)(
struct
eeh_pe
*
pe
);
int
(
*
reset
)(
struct
eeh_pe
*
pe
,
int
option
);
int
(
*
get_log
)(
struct
eeh_pe
*
pe
,
int
severity
,
char
*
drv_log
,
unsigned
long
len
);
int
(
*
configure_bridge
)(
struct
eeh_pe
*
pe
);
int
(
*
err_inject
)(
struct
eeh_pe
*
pe
,
int
type
,
int
func
,
unsigned
long
addr
,
unsigned
long
mask
);
int
(
*
next_error
)(
struct
eeh_pe
**
pe
);
};
#endif
/* CONFIG_EEH */
#define PNV_PHB_FLAG_EEH (1 << 0)
#define PNV_PHB_FLAG_EEH (1 << 0)
struct
pnv_phb
{
struct
pnv_phb
{
...
@@ -104,10 +88,6 @@ struct pnv_phb {
...
@@ -104,10 +88,6 @@ struct pnv_phb {
int
initialized
;
int
initialized
;
spinlock_t
lock
;
spinlock_t
lock
;
#ifdef CONFIG_EEH
struct
pnv_eeh_ops
*
eeh_ops
;
#endif
#ifdef CONFIG_DEBUG_FS
#ifdef CONFIG_DEBUG_FS
int
has_dbgfs
;
int
has_dbgfs
;
struct
dentry
*
dbgfs
;
struct
dentry
*
dbgfs
;
...
@@ -213,15 +193,12 @@ struct pnv_phb {
...
@@ -213,15 +193,12 @@ struct pnv_phb {
};
};
extern
struct
pci_ops
pnv_pci_ops
;
extern
struct
pci_ops
pnv_pci_ops
;
#ifdef CONFIG_EEH
extern
struct
pnv_eeh_ops
ioda_eeh_ops
;
#endif
void
pnv_pci_dump_phb_diag_data
(
struct
pci_controller
*
hose
,
void
pnv_pci_dump_phb_diag_data
(
struct
pci_controller
*
hose
,
unsigned
char
*
log_buff
);
unsigned
char
*
log_buff
);
int
pnv_pci_cfg_read
(
struct
device_node
*
dn
,
int
pnv_pci_cfg_read
(
struct
pci_dn
*
p
dn
,
int
where
,
int
size
,
u32
*
val
);
int
where
,
int
size
,
u32
*
val
);
int
pnv_pci_cfg_write
(
struct
device_node
*
dn
,
int
pnv_pci_cfg_write
(
struct
pci_dn
*
p
dn
,
int
where
,
int
size
,
u32
val
);
int
where
,
int
size
,
u32
val
);
extern
void
pnv_pci_setup_iommu_table
(
struct
iommu_table
*
tbl
,
extern
void
pnv_pci_setup_iommu_table
(
struct
iommu_table
*
tbl
,
void
*
tce_mem
,
u64
tce_size
,
void
*
tce_mem
,
u64
tce_size
,
...
@@ -232,6 +209,6 @@ extern void pnv_pci_init_ioda2_phb(struct device_node *np);
...
@@ -232,6 +209,6 @@ extern void pnv_pci_init_ioda2_phb(struct device_node *np);
extern
void
pnv_pci_ioda_tce_invalidate
(
struct
iommu_table
*
tbl
,
extern
void
pnv_pci_ioda_tce_invalidate
(
struct
iommu_table
*
tbl
,
__be64
*
startp
,
__be64
*
endp
,
bool
rm
);
__be64
*
startp
,
__be64
*
endp
,
bool
rm
);
extern
void
pnv_pci_reset_secondary_bus
(
struct
pci_dev
*
dev
);
extern
void
pnv_pci_reset_secondary_bus
(
struct
pci_dev
*
dev
);
extern
int
ioda
_eeh_phb_reset
(
struct
pci_controller
*
hose
,
int
option
);
extern
int
pnv
_eeh_phb_reset
(
struct
pci_controller
*
hose
,
int
option
);
#endif
/* __POWERNV_PCI_H */
#endif
/* __POWERNV_PCI_H */
arch/powerpc/platforms/pseries/eeh_pseries.c
View file @
428d4d65
...
@@ -118,9 +118,8 @@ static int pseries_eeh_init(void)
...
@@ -118,9 +118,8 @@ static int pseries_eeh_init(void)
return
0
;
return
0
;
}
}
static
int
pseries_eeh_cap_start
(
struct
device_node
*
dn
)
static
int
pseries_eeh_cap_start
(
struct
pci_dn
*
p
dn
)
{
{
struct
pci_dn
*
pdn
=
PCI_DN
(
dn
);
u32
status
;
u32
status
;
if
(
!
pdn
)
if
(
!
pdn
)
...
@@ -134,10 +133,9 @@ static int pseries_eeh_cap_start(struct device_node *dn)
...
@@ -134,10 +133,9 @@ static int pseries_eeh_cap_start(struct device_node *dn)
}
}
static
int
pseries_eeh_find_cap
(
struct
device_node
*
dn
,
int
cap
)
static
int
pseries_eeh_find_cap
(
struct
pci_dn
*
p
dn
,
int
cap
)
{
{
struct
pci_dn
*
pdn
=
PCI_DN
(
dn
);
int
pos
=
pseries_eeh_cap_start
(
pdn
);
int
pos
=
pseries_eeh_cap_start
(
dn
);
int
cnt
=
48
;
/* Maximal number of capabilities */
int
cnt
=
48
;
/* Maximal number of capabilities */
u32
id
;
u32
id
;
...
@@ -160,10 +158,9 @@ static int pseries_eeh_find_cap(struct device_node *dn, int cap)
...
@@ -160,10 +158,9 @@ static int pseries_eeh_find_cap(struct device_node *dn, int cap)
return
0
;
return
0
;
}
}
static
int
pseries_eeh_find_ecap
(
struct
device_node
*
dn
,
int
cap
)
static
int
pseries_eeh_find_ecap
(
struct
pci_dn
*
p
dn
,
int
cap
)
{
{
struct
pci_dn
*
pdn
=
PCI_DN
(
dn
);
struct
eeh_dev
*
edev
=
pdn_to_eeh_dev
(
pdn
);
struct
eeh_dev
*
edev
=
of_node_to_eeh_dev
(
dn
);
u32
header
;
u32
header
;
int
pos
=
256
;
int
pos
=
256
;
int
ttl
=
(
4096
-
256
)
/
8
;
int
ttl
=
(
4096
-
256
)
/
8
;
...
@@ -191,53 +188,44 @@ static int pseries_eeh_find_ecap(struct device_node *dn, int cap)
...
@@ -191,53 +188,44 @@ static int pseries_eeh_find_ecap(struct device_node *dn, int cap)
}
}
/**
/**
* pseries_eeh_
of_
probe - EEH probe on the given device
* pseries_eeh_probe - EEH probe on the given device
* @
dn: OF
node
* @
pdn: PCI device
node
* @
flag
: Unused
* @
data
: Unused
*
*
* When EEH module is installed during system boot, all PCI devices
* When EEH module is installed during system boot, all PCI devices
* are checked one by one to see if it supports EEH. The function
* are checked one by one to see if it supports EEH. The function
* is introduced for the purpose.
* is introduced for the purpose.
*/
*/
static
void
*
pseries_eeh_
of_probe
(
struct
device_node
*
dn
,
void
*
flag
)
static
void
*
pseries_eeh_
probe
(
struct
pci_dn
*
pdn
,
void
*
data
)
{
{
struct
eeh_dev
*
edev
;
struct
eeh_dev
*
edev
;
struct
eeh_pe
pe
;
struct
eeh_pe
pe
;
struct
pci_dn
*
pdn
=
PCI_DN
(
dn
);
const
__be32
*
classp
,
*
vendorp
,
*
devicep
;
u32
class_code
;
const
__be32
*
regs
;
u32
pcie_flags
;
u32
pcie_flags
;
int
enable
=
0
;
int
enable
=
0
;
int
ret
;
int
ret
;
/* Retrieve OF node and eeh device */
/* Retrieve OF node and eeh device */
edev
=
of_node_to_eeh_dev
(
dn
);
edev
=
pdn_to_eeh_dev
(
p
dn
);
if
(
edev
->
pe
||
!
of_device_is_available
(
dn
)
)
if
(
!
edev
||
edev
->
pe
)
return
NULL
;
return
NULL
;
/* Retrieve class/vendor/device IDs */
/* Check class/vendor/device IDs */
classp
=
of_get_property
(
dn
,
"class-code"
,
NULL
);
if
(
!
pdn
->
vendor_id
||
!
pdn
->
device_id
||
!
pdn
->
class_code
)
vendorp
=
of_get_property
(
dn
,
"vendor-id"
,
NULL
);
devicep
=
of_get_property
(
dn
,
"device-id"
,
NULL
);
/* Skip for bad OF node or PCI-ISA bridge */
if
(
!
classp
||
!
vendorp
||
!
devicep
)
return
NULL
;
if
(
dn
->
type
&&
!
strcmp
(
dn
->
type
,
"isa"
))
return
NULL
;
return
NULL
;
class_code
=
of_read_number
(
classp
,
1
);
/* Skip for PCI-ISA bridge */
if
((
pdn
->
class_code
>>
8
)
==
PCI_CLASS_BRIDGE_ISA
)
return
NULL
;
/*
/*
* Update class code and mode of eeh device. We need
* Update class code and mode of eeh device. We need
* correctly reflects that current device is root port
* correctly reflects that current device is root port
* or PCIe switch downstream port.
* or PCIe switch downstream port.
*/
*/
edev
->
class_code
=
class_code
;
edev
->
class_code
=
pdn
->
class_code
;
edev
->
pcix_cap
=
pseries_eeh_find_cap
(
dn
,
PCI_CAP_ID_PCIX
);
edev
->
pcix_cap
=
pseries_eeh_find_cap
(
p
dn
,
PCI_CAP_ID_PCIX
);
edev
->
pcie_cap
=
pseries_eeh_find_cap
(
dn
,
PCI_CAP_ID_EXP
);
edev
->
pcie_cap
=
pseries_eeh_find_cap
(
p
dn
,
PCI_CAP_ID_EXP
);
edev
->
aer_cap
=
pseries_eeh_find_ecap
(
dn
,
PCI_EXT_CAP_ID_ERR
);
edev
->
aer_cap
=
pseries_eeh_find_ecap
(
p
dn
,
PCI_EXT_CAP_ID_ERR
);
edev
->
mode
&=
0xFFFFFF00
;
edev
->
mode
&=
0xFFFFFF00
;
if
((
edev
->
class_code
>>
8
)
==
PCI_CLASS_BRIDGE_PCI
)
{
if
((
edev
->
class_code
>>
8
)
==
PCI_CLASS_BRIDGE_PCI
)
{
edev
->
mode
|=
EEH_DEV_BRIDGE
;
edev
->
mode
|=
EEH_DEV_BRIDGE
;
...
@@ -252,24 +240,16 @@ static void *pseries_eeh_of_probe(struct device_node *dn, void *flag)
...
@@ -252,24 +240,16 @@ static void *pseries_eeh_of_probe(struct device_node *dn, void *flag)
}
}
}
}
/* Retrieve the device address */
regs
=
of_get_property
(
dn
,
"reg"
,
NULL
);
if
(
!
regs
)
{
pr_warn
(
"%s: OF node property %s::reg not found
\n
"
,
__func__
,
dn
->
full_name
);
return
NULL
;
}
/* Initialize the fake PE */
/* Initialize the fake PE */
memset
(
&
pe
,
0
,
sizeof
(
struct
eeh_pe
));
memset
(
&
pe
,
0
,
sizeof
(
struct
eeh_pe
));
pe
.
phb
=
edev
->
phb
;
pe
.
phb
=
edev
->
phb
;
pe
.
config_addr
=
of_read_number
(
regs
,
1
);
pe
.
config_addr
=
(
pdn
->
busno
<<
16
)
|
(
pdn
->
devfn
<<
8
);
/* Enable EEH on the device */
/* Enable EEH on the device */
ret
=
eeh_ops
->
set_option
(
&
pe
,
EEH_OPT_ENABLE
);
ret
=
eeh_ops
->
set_option
(
&
pe
,
EEH_OPT_ENABLE
);
if
(
!
ret
)
{
if
(
!
ret
)
{
edev
->
config_addr
=
of_read_number
(
regs
,
1
);
/* Retrieve PE address */
/* Retrieve PE address */
edev
->
config_addr
=
(
pdn
->
busno
<<
16
)
|
(
pdn
->
devfn
<<
8
);
edev
->
pe_config_addr
=
eeh_ops
->
get_pe_addr
(
&
pe
);
edev
->
pe_config_addr
=
eeh_ops
->
get_pe_addr
(
&
pe
);
pe
.
addr
=
edev
->
pe_config_addr
;
pe
.
addr
=
edev
->
pe_config_addr
;
...
@@ -285,16 +265,17 @@ static void *pseries_eeh_of_probe(struct device_node *dn, void *flag)
...
@@ -285,16 +265,17 @@ static void *pseries_eeh_of_probe(struct device_node *dn, void *flag)
eeh_add_flag
(
EEH_ENABLED
);
eeh_add_flag
(
EEH_ENABLED
);
eeh_add_to_parent_pe
(
edev
);
eeh_add_to_parent_pe
(
edev
);
pr_debug
(
"%s: EEH enabled on %s PHB#%d-PE#%x, config addr#%x
\n
"
,
pr_debug
(
"%s: EEH enabled on %02x:%02x.%01x PHB#%d-PE#%x
\n
"
,
__func__
,
dn
->
full_name
,
pe
.
phb
->
global_number
,
__func__
,
pdn
->
busno
,
PCI_SLOT
(
pdn
->
devfn
),
pe
.
addr
,
pe
.
config_addr
);
PCI_FUNC
(
pdn
->
devfn
),
pe
.
phb
->
global_number
,
}
else
if
(
dn
->
parent
&&
of_node_to_eeh_dev
(
dn
->
parent
)
&&
pe
.
addr
);
(
of_node_to_eeh_dev
(
dn
->
parent
))
->
pe
)
{
}
else
if
(
pdn
->
parent
&&
pdn_to_eeh_dev
(
pdn
->
parent
)
&&
(
pdn_to_eeh_dev
(
pdn
->
parent
))
->
pe
)
{
/* This device doesn't support EEH, but it may have an
/* This device doesn't support EEH, but it may have an
* EEH parent, in which case we mark it as supported.
* EEH parent, in which case we mark it as supported.
*/
*/
edev
->
config_addr
=
of_node_to_eeh_dev
(
dn
->
parent
)
->
config_addr
;
edev
->
config_addr
=
pdn_to_eeh_dev
(
p
dn
->
parent
)
->
config_addr
;
edev
->
pe_config_addr
=
of_node_to_eeh_dev
(
dn
->
parent
)
->
pe_config_addr
;
edev
->
pe_config_addr
=
pdn_to_eeh_dev
(
p
dn
->
parent
)
->
pe_config_addr
;
eeh_add_to_parent_pe
(
edev
);
eeh_add_to_parent_pe
(
edev
);
}
}
}
}
...
@@ -670,45 +651,36 @@ static int pseries_eeh_configure_bridge(struct eeh_pe *pe)
...
@@ -670,45 +651,36 @@ static int pseries_eeh_configure_bridge(struct eeh_pe *pe)
/**
/**
* pseries_eeh_read_config - Read PCI config space
* pseries_eeh_read_config - Read PCI config space
* @
dn:
device node
* @
pdn: PCI
device node
* @where: PCI address
* @where: PCI address
* @size: size to read
* @size: size to read
* @val: return value
* @val: return value
*
*
* Read config space from the speicifed device
* Read config space from the speicifed device
*/
*/
static
int
pseries_eeh_read_config
(
struct
device_node
*
dn
,
int
where
,
int
size
,
u32
*
val
)
static
int
pseries_eeh_read_config
(
struct
pci_dn
*
p
dn
,
int
where
,
int
size
,
u32
*
val
)
{
{
struct
pci_dn
*
pdn
;
pdn
=
PCI_DN
(
dn
);
return
rtas_read_config
(
pdn
,
where
,
size
,
val
);
return
rtas_read_config
(
pdn
,
where
,
size
,
val
);
}
}
/**
/**
* pseries_eeh_write_config - Write PCI config space
* pseries_eeh_write_config - Write PCI config space
* @
dn:
device node
* @
pdn: PCI
device node
* @where: PCI address
* @where: PCI address
* @size: size to write
* @size: size to write
* @val: value to be written
* @val: value to be written
*
*
* Write config space to the specified device
* Write config space to the specified device
*/
*/
static
int
pseries_eeh_write_config
(
struct
device_node
*
dn
,
int
where
,
int
size
,
u32
val
)
static
int
pseries_eeh_write_config
(
struct
pci_dn
*
p
dn
,
int
where
,
int
size
,
u32
val
)
{
{
struct
pci_dn
*
pdn
;
pdn
=
PCI_DN
(
dn
);
return
rtas_write_config
(
pdn
,
where
,
size
,
val
);
return
rtas_write_config
(
pdn
,
where
,
size
,
val
);
}
}
static
struct
eeh_ops
pseries_eeh_ops
=
{
static
struct
eeh_ops
pseries_eeh_ops
=
{
.
name
=
"pseries"
,
.
name
=
"pseries"
,
.
init
=
pseries_eeh_init
,
.
init
=
pseries_eeh_init
,
.
of_probe
=
pseries_eeh_of_probe
,
.
probe
=
pseries_eeh_probe
,
.
dev_probe
=
NULL
,
.
set_option
=
pseries_eeh_set_option
,
.
set_option
=
pseries_eeh_set_option
,
.
get_pe_addr
=
pseries_eeh_get_pe_addr
,
.
get_pe_addr
=
pseries_eeh_get_pe_addr
,
.
get_state
=
pseries_eeh_get_state
,
.
get_state
=
pseries_eeh_get_state
,
...
...
arch/powerpc/platforms/pseries/msi.c
View file @
428d4d65
...
@@ -195,6 +195,7 @@ static struct device_node *find_pe_total_msi(struct pci_dev *dev, int *total)
...
@@ -195,6 +195,7 @@ static struct device_node *find_pe_total_msi(struct pci_dev *dev, int *total)
static
struct
device_node
*
find_pe_dn
(
struct
pci_dev
*
dev
,
int
*
total
)
static
struct
device_node
*
find_pe_dn
(
struct
pci_dev
*
dev
,
int
*
total
)
{
{
struct
device_node
*
dn
;
struct
device_node
*
dn
;
struct
pci_dn
*
pdn
;
struct
eeh_dev
*
edev
;
struct
eeh_dev
*
edev
;
/* Found our PE and assume 8 at that point. */
/* Found our PE and assume 8 at that point. */
...
@@ -204,10 +205,11 @@ static struct device_node *find_pe_dn(struct pci_dev *dev, int *total)
...
@@ -204,10 +205,11 @@ static struct device_node *find_pe_dn(struct pci_dev *dev, int *total)
return
NULL
;
return
NULL
;
/* Get the top level device in the PE */
/* Get the top level device in the PE */
edev
=
of_node_to_eeh_dev
(
dn
);
edev
=
pdn_to_eeh_dev
(
PCI_DN
(
dn
)
);
if
(
edev
->
pe
)
if
(
edev
->
pe
)
edev
=
list_first_entry
(
&
edev
->
pe
->
edevs
,
struct
eeh_dev
,
list
);
edev
=
list_first_entry
(
&
edev
->
pe
->
edevs
,
struct
eeh_dev
,
list
);
dn
=
eeh_dev_to_of_node
(
edev
);
pdn
=
eeh_dev_to_pdn
(
edev
);
dn
=
pdn
?
pdn
->
node
:
NULL
;
if
(
!
dn
)
if
(
!
dn
)
return
NULL
;
return
NULL
;
...
...
arch/powerpc/platforms/pseries/pci_dlpar.c
View file @
428d4d65
...
@@ -82,7 +82,7 @@ struct pci_controller *init_phb_dynamic(struct device_node *dn)
...
@@ -82,7 +82,7 @@ struct pci_controller *init_phb_dynamic(struct device_node *dn)
eeh_dev_phb_init_dynamic
(
phb
);
eeh_dev_phb_init_dynamic
(
phb
);
if
(
dn
->
child
)
if
(
dn
->
child
)
eeh_add_device_tree_early
(
dn
);
eeh_add_device_tree_early
(
PCI_DN
(
dn
)
);
pcibios_scan_phb
(
phb
);
pcibios_scan_phb
(
phb
);
pcibios_finish_adding_to_bus
(
phb
->
bus
);
pcibios_finish_adding_to_bus
(
phb
->
bus
);
...
...
arch/powerpc/platforms/pseries/setup.c
View file @
428d4d65
...
@@ -265,7 +265,7 @@ static int pci_dn_reconfig_notifier(struct notifier_block *nb, unsigned long act
...
@@ -265,7 +265,7 @@ static int pci_dn_reconfig_notifier(struct notifier_block *nb, unsigned long act
update_dn_pci_info
(
np
,
pci
->
phb
);
update_dn_pci_info
(
np
,
pci
->
phb
);
/* Create EEH device for the OF node */
/* Create EEH device for the OF node */
eeh_dev_init
(
np
,
pci
->
phb
);
eeh_dev_init
(
PCI_DN
(
np
)
,
pci
->
phb
);
}
}
break
;
break
;
default:
default:
...
...
drivers/net/ethernet/sfc/efx.c
View file @
428d4d65
...
@@ -2523,9 +2523,7 @@ int efx_try_recovery(struct efx_nic *efx)
...
@@ -2523,9 +2523,7 @@ int efx_try_recovery(struct efx_nic *efx)
* schedule a 'recover or reset', leading to this recovery handler.
* schedule a 'recover or reset', leading to this recovery handler.
* Manually call the eeh failure check function.
* Manually call the eeh failure check function.
*/
*/
struct
eeh_dev
*
eehdev
=
struct
eeh_dev
*
eehdev
=
pci_dev_to_eeh_dev
(
efx
->
pci_dev
);
of_node_to_eeh_dev
(
pci_device_to_OF_node
(
efx
->
pci_dev
));
if
(
eeh_dev_check_failure
(
eehdev
))
{
if
(
eeh_dev_check_failure
(
eehdev
))
{
/* The EEH mechanisms will handle the error and reset the
/* The EEH mechanisms will handle the error and reset the
* device if necessary.
* device if necessary.
...
...
drivers/net/ethernet/sfc/siena.c
View file @
428d4d65
...
@@ -205,8 +205,7 @@ static int siena_map_reset_flags(u32 *flags)
...
@@ -205,8 +205,7 @@ static int siena_map_reset_flags(u32 *flags)
*/
*/
static
void
siena_monitor
(
struct
efx_nic
*
efx
)
static
void
siena_monitor
(
struct
efx_nic
*
efx
)
{
{
struct
eeh_dev
*
eehdev
=
struct
eeh_dev
*
eehdev
=
pci_dev_to_eeh_dev
(
efx
->
pci_dev
);
of_node_to_eeh_dev
(
pci_device_to_OF_node
(
efx
->
pci_dev
));
eeh_dev_check_failure
(
eehdev
);
eeh_dev_check_failure
(
eehdev
);
}
}
...
...
drivers/pci/hotplug/rpadlpar_core.c
View file @
428d4d65
...
@@ -146,7 +146,7 @@ static void dlpar_pci_add_bus(struct device_node *dn)
...
@@ -146,7 +146,7 @@ static void dlpar_pci_add_bus(struct device_node *dn)
struct
pci_controller
*
phb
=
pdn
->
phb
;
struct
pci_controller
*
phb
=
pdn
->
phb
;
struct
pci_dev
*
dev
=
NULL
;
struct
pci_dev
*
dev
=
NULL
;
eeh_add_device_tree_early
(
dn
);
eeh_add_device_tree_early
(
p
dn
);
/* Add EADS device to PHB bus, adding new entry to bus->devices */
/* Add EADS device to PHB bus, adding new entry to bus->devices */
dev
=
of_create_pci_dev
(
dn
,
phb
->
bus
,
pdn
->
devfn
);
dev
=
of_create_pci_dev
(
dn
,
phb
->
bus
,
pdn
->
devfn
);
...
...
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