Commit cd7acce7 authored by Benjamin Herrenschmidt's avatar Benjamin Herrenschmidt Committed by Linus Torvalds

[PATCH] ppc64/ppc: Cleanup PCI skipping

The g5 code has special hooks to "hide" some PCI devices when they are off.

Currently, this code involves some calls to match a pci_dev from the open
firmware node and such things that are causing some problems with the
latest version of my sungem driver who wants to do some of this in atomic
contexts.

This patch moves that to a list of struct device_node instead, which also
ends up simplifying the code.

Later, I'll go back to manipulating PCI devices in a clean way when Brian
King's PCI blocking patch gets in, but only after I change sungem again to
never call these in atomic context.  This is a 3 step transition basically
Signed-off-by: default avatarBenjamin Herrenschmidt <benh@kernel.crashing.org>
Signed-off-by: default avatarAndrew Morton <akpm@osdl.org>
Signed-off-by: default avatarLinus Torvalds <torvalds@osdl.org>
parent 0ded95d6
...@@ -56,7 +56,7 @@ extern int powersave_lowspeed; ...@@ -56,7 +56,7 @@ extern int powersave_lowspeed;
#endif #endif
extern int powersave_nap; extern int powersave_nap;
extern struct pci_dev *k2_skiplist[2]; extern struct device_node *k2_skiplist[2];
/* /*
...@@ -1328,24 +1328,15 @@ g5_gmac_enable(struct device_node* node, long param, long value) ...@@ -1328,24 +1328,15 @@ g5_gmac_enable(struct device_node* node, long param, long value)
{ {
struct macio_chip* macio = &macio_chips[0]; struct macio_chip* macio = &macio_chips[0];
unsigned long flags; unsigned long flags;
struct pci_dev *pdev;
u8 pbus, pid; u8 pbus, pid;
/* XXX FIXME: We should fix pci_device_from_OF_node here, and
* get to a real pci_dev or we'll get into trouble with PCI
* domains the day we get overlapping numbers (like if we ever
* decide to show the HT root
*/
if (pci_device_from_OF_node(node, &pbus, &pid) == 0)
pdev = pci_find_slot(pbus, pid);
LOCK(flags); LOCK(flags);
if (value) { if (value) {
MACIO_BIS(KEYLARGO_FCR1, K2_FCR1_GMAC_CLK_ENABLE); MACIO_BIS(KEYLARGO_FCR1, K2_FCR1_GMAC_CLK_ENABLE);
mb(); mb();
k2_skiplist[0] = NULL; k2_skiplist[0] = NULL;
} else { } else {
k2_skiplist[0] = pdev; k2_skiplist[0] = node;
mb(); mb();
MACIO_BIC(KEYLARGO_FCR1, K2_FCR1_GMAC_CLK_ENABLE); MACIO_BIC(KEYLARGO_FCR1, K2_FCR1_GMAC_CLK_ENABLE);
} }
...@@ -1361,16 +1352,6 @@ g5_fw_enable(struct device_node* node, long param, long value) ...@@ -1361,16 +1352,6 @@ g5_fw_enable(struct device_node* node, long param, long value)
{ {
struct macio_chip* macio = &macio_chips[0]; struct macio_chip* macio = &macio_chips[0];
unsigned long flags; unsigned long flags;
struct pci_dev *pdev;
u8 pbus, pid;
/* XXX FIXME: We should fix pci_device_from_OF_node here, and
* get to a real pci_dev or we'll get into trouble with PCI
* domains the day we get overlapping numbers (like if we ever
* decide to show the HT root
*/
if (pci_device_from_OF_node(node, &pbus, &pid) == 0)
pdev = pci_find_slot(pbus, pid);
LOCK(flags); LOCK(flags);
if (value) { if (value) {
...@@ -1378,7 +1359,7 @@ g5_fw_enable(struct device_node* node, long param, long value) ...@@ -1378,7 +1359,7 @@ g5_fw_enable(struct device_node* node, long param, long value)
mb(); mb();
k2_skiplist[1] = NULL; k2_skiplist[1] = NULL;
} else { } else {
k2_skiplist[1] = pdev; k2_skiplist[1] = node;
mb(); mb();
MACIO_BIC(KEYLARGO_FCR1, K2_FCR1_FW_CLK_ENABLE); MACIO_BIC(KEYLARGO_FCR1, K2_FCR1_FW_CLK_ENABLE);
} }
......
...@@ -52,7 +52,7 @@ static struct pci_controller *u3_agp; ...@@ -52,7 +52,7 @@ static struct pci_controller *u3_agp;
extern u8 pci_cache_line_size; extern u8 pci_cache_line_size;
extern int pcibios_assign_bus_offset; extern int pcibios_assign_bus_offset;
struct pci_dev *k2_skiplist[2]; struct device_node *k2_skiplist[2];
/* /*
* Magic constants for enabling cache coherency in the bandit/PSX bridge. * Magic constants for enabling cache coherency in the bandit/PSX bridge.
...@@ -325,8 +325,7 @@ u3_ht_read_config(struct pci_bus *bus, unsigned int devfn, int offset, ...@@ -325,8 +325,7 @@ u3_ht_read_config(struct pci_bus *bus, unsigned int devfn, int offset,
* cycle accesses. Fix that here. * cycle accesses. Fix that here.
*/ */
for (i=0; i<2; i++) for (i=0; i<2; i++)
if (k2_skiplist[i] && k2_skiplist[i]->bus == bus && if (k2_skiplist[i] == np) {
k2_skiplist[i]->devfn == devfn) {
switch (len) { switch (len) {
case 1: case 1:
*val = 0xff; break; *val = 0xff; break;
...@@ -375,8 +374,7 @@ u3_ht_write_config(struct pci_bus *bus, unsigned int devfn, int offset, ...@@ -375,8 +374,7 @@ u3_ht_write_config(struct pci_bus *bus, unsigned int devfn, int offset,
* cycle accesses. Fix that here. * cycle accesses. Fix that here.
*/ */
for (i=0; i<2; i++) for (i=0; i<2; i++)
if (k2_skiplist[i] && k2_skiplist[i]->bus == bus && if (k2_skiplist[i] == np)
k2_skiplist[i]->devfn == devfn)
return PCIBIOS_SUCCESSFUL; return PCIBIOS_SUCCESSFUL;
addr = u3_ht_cfg_access(hose, bus->number, devfn, offset); addr = u3_ht_cfg_access(hose, bus->number, devfn, offset);
......
...@@ -111,7 +111,7 @@ static u32* uninorth_base __pmacdata; ...@@ -111,7 +111,7 @@ static u32* uninorth_base __pmacdata;
static u32 uninorth_rev __pmacdata; static u32 uninorth_rev __pmacdata;
static void *u3_ht; static void *u3_ht;
extern struct pci_dev *k2_skiplist[2]; extern struct device_node *k2_skiplist[2];
/* /*
* For each motherboard family, we have a table of functions pointers * For each motherboard family, we have a table of functions pointers
...@@ -160,30 +160,17 @@ static long __pmac g5_gmac_enable(struct device_node* node, long param, long val ...@@ -160,30 +160,17 @@ static long __pmac g5_gmac_enable(struct device_node* node, long param, long val
{ {
struct macio_chip* macio = &macio_chips[0]; struct macio_chip* macio = &macio_chips[0];
unsigned long flags; unsigned long flags;
struct pci_dev *pdev = NULL;
if (node == NULL) if (node == NULL)
return -ENODEV; return -ENODEV;
/* XXX FIXME: We should fix pci_device_from_OF_node here, and
* get to a real pci_dev or we'll get into trouble with PCI
* domains the day we get overlapping numbers (like if we ever
* decide to show the HT root.
* Note that we only get the slot when value is 0. This is called
* early during boot with value 1 to enable all devices, at which
* point, we don't yet have probed pci_find_slot, so it would fail
* to look for the slot at this point.
*/
if (!value)
pdev = pci_find_slot(node->busno, node->devfn);
LOCK(flags); LOCK(flags);
if (value) { if (value) {
MACIO_BIS(KEYLARGO_FCR1, K2_FCR1_GMAC_CLK_ENABLE); MACIO_BIS(KEYLARGO_FCR1, K2_FCR1_GMAC_CLK_ENABLE);
mb(); mb();
k2_skiplist[0] = NULL; k2_skiplist[0] = NULL;
} else { } else {
k2_skiplist[0] = pdev; k2_skiplist[0] = node;
mb(); mb();
MACIO_BIC(KEYLARGO_FCR1, K2_FCR1_GMAC_CLK_ENABLE); MACIO_BIC(KEYLARGO_FCR1, K2_FCR1_GMAC_CLK_ENABLE);
} }
...@@ -198,30 +185,17 @@ static long __pmac g5_fw_enable(struct device_node* node, long param, long value ...@@ -198,30 +185,17 @@ static long __pmac g5_fw_enable(struct device_node* node, long param, long value
{ {
struct macio_chip* macio = &macio_chips[0]; struct macio_chip* macio = &macio_chips[0];
unsigned long flags; unsigned long flags;
struct pci_dev *pdev = NULL;
/* XXX FIXME: We should fix pci_device_from_OF_node here, and
* get to a real pci_dev or we'll get into trouble with PCI
* domains the day we get overlapping numbers (like if we ever
* decide to show the HT root
* Note that we only get the slot when value is 0. This is called
* early during boot with value 1 to enable all devices, at which
* point, we don't yet have probed pci_find_slot, so it would fail
* to look for the slot at this point.
*/
if (node == NULL) if (node == NULL)
return -ENODEV; return -ENODEV;
if (!value)
pdev = pci_find_slot(node->busno, node->devfn);
LOCK(flags); LOCK(flags);
if (value) { if (value) {
MACIO_BIS(KEYLARGO_FCR1, K2_FCR1_FW_CLK_ENABLE); MACIO_BIS(KEYLARGO_FCR1, K2_FCR1_FW_CLK_ENABLE);
mb(); mb();
k2_skiplist[1] = NULL; k2_skiplist[1] = NULL;
} else { } else {
k2_skiplist[1] = pdev; k2_skiplist[1] = node;
mb(); mb();
MACIO_BIC(KEYLARGO_FCR1, K2_FCR1_FW_CLK_ENABLE); MACIO_BIC(KEYLARGO_FCR1, K2_FCR1_FW_CLK_ENABLE);
} }
......
...@@ -43,7 +43,7 @@ ...@@ -43,7 +43,7 @@
* assuming we won't have both UniNorth and Bandit */ * assuming we won't have both UniNorth and Bandit */
static int has_uninorth; static int has_uninorth;
static struct pci_controller *u3_agp; static struct pci_controller *u3_agp;
struct pci_dev *k2_skiplist[2]; struct device_node *k2_skiplist[2];
static int __init fixup_one_level_bus_range(struct device_node *node, int higher) static int __init fixup_one_level_bus_range(struct device_node *node, int higher)
{ {
...@@ -233,15 +233,6 @@ static int u3_ht_skip_device(struct pci_controller *hose, ...@@ -233,15 +233,6 @@ static int u3_ht_skip_device(struct pci_controller *hose,
struct device_node *busdn, *dn; struct device_node *busdn, *dn;
int i; int i;
/*
* When a device in K2 is powered down, we die on config
* cycle accesses. Fix that here.
*/
for (i=0; i<2; i++)
if (k2_skiplist[i] && k2_skiplist[i]->bus == bus &&
k2_skiplist[i]->devfn == devfn)
return 1;
/* We only allow config cycles to devices that are in OF device-tree /* We only allow config cycles to devices that are in OF device-tree
* as we are apparently having some weird things going on with some * as we are apparently having some weird things going on with some
* revs of K2 on recent G5s * revs of K2 on recent G5s
...@@ -256,6 +247,14 @@ static int u3_ht_skip_device(struct pci_controller *hose, ...@@ -256,6 +247,14 @@ static int u3_ht_skip_device(struct pci_controller *hose,
if (dn == NULL) if (dn == NULL)
return -1; return -1;
/*
* When a device in K2 is powered down, we die on config
* cycle accesses. Fix that here.
*/
for (i=0; i<2; i++)
if (k2_skiplist[i] == dn)
return 1;
return 0; return 0;
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment