aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--arch/ia64/pci/pci.c8
-rw-r--r--arch/x86/include/asm/pci.h3
-rw-r--r--arch/x86/pci/acpi.c9
-rw-r--r--drivers/acpi/pci_root.c18
-rw-r--r--drivers/pci/pci-acpi.c19
-rw-r--r--drivers/pci/probe.c16
-rw-r--r--include/acpi/acpi_bus.h1
-rw-r--r--include/linux/pci.h2
8 files changed, 38 insertions, 38 deletions
diff --git a/arch/ia64/pci/pci.c b/arch/ia64/pci/pci.c
index 5faa66c5c2a8..00e59c7ad3c0 100644
--- a/arch/ia64/pci/pci.c
+++ b/arch/ia64/pci/pci.c
@@ -396,6 +396,14 @@ out1:
396 return NULL; 396 return NULL;
397} 397}
398 398
399int pcibios_root_bridge_prepare(struct pci_host_bridge *bridge)
400{
401 struct pci_controller *controller = bridge->bus->sysdata;
402
403 ACPI_HANDLE_SET(&bridge->dev, controller->acpi_handle);
404 return 0;
405}
406
399static int __devinit is_valid_resource(struct pci_dev *dev, int idx) 407static int __devinit is_valid_resource(struct pci_dev *dev, int idx)
400{ 408{
401 unsigned int i, type_mask = IORESOURCE_IO | IORESOURCE_MEM; 409 unsigned int i, type_mask = IORESOURCE_IO | IORESOURCE_MEM;
diff --git a/arch/x86/include/asm/pci.h b/arch/x86/include/asm/pci.h
index dba7805176bf..9f437e97e9e8 100644
--- a/arch/x86/include/asm/pci.h
+++ b/arch/x86/include/asm/pci.h
@@ -14,6 +14,9 @@
14struct pci_sysdata { 14struct pci_sysdata {
15 int domain; /* PCI domain */ 15 int domain; /* PCI domain */
16 int node; /* NUMA node */ 16 int node; /* NUMA node */
17#ifdef CONFIG_ACPI
18 void *acpi; /* ACPI-specific data */
19#endif
17#ifdef CONFIG_X86_64 20#ifdef CONFIG_X86_64
18 void *iommu; /* IOMMU private data */ 21 void *iommu; /* IOMMU private data */
19#endif 22#endif
diff --git a/arch/x86/pci/acpi.c b/arch/x86/pci/acpi.c
index 0c01261fe5a8..3d49094ed3e8 100644
--- a/arch/x86/pci/acpi.c
+++ b/arch/x86/pci/acpi.c
@@ -522,6 +522,7 @@ struct pci_bus * __devinit pci_acpi_scan_root(struct acpi_pci_root *root)
522 sd = &info->sd; 522 sd = &info->sd;
523 sd->domain = domain; 523 sd->domain = domain;
524 sd->node = node; 524 sd->node = node;
525 sd->acpi = device->handle;
525 /* 526 /*
526 * Maybe the desired pci bus has been already scanned. In such case 527 * Maybe the desired pci bus has been already scanned. In such case
527 * it is unnecessary to scan the pci bus with the given domain,busnum. 528 * it is unnecessary to scan the pci bus with the given domain,busnum.
@@ -593,6 +594,14 @@ struct pci_bus * __devinit pci_acpi_scan_root(struct acpi_pci_root *root)
593 return bus; 594 return bus;
594} 595}
595 596
597int pcibios_root_bridge_prepare(struct pci_host_bridge *bridge)
598{
599 struct pci_sysdata *sd = bridge->bus->sysdata;
600
601 ACPI_HANDLE_SET(&bridge->dev, sd->acpi);
602 return 0;
603}
604
596int __init pci_acpi_init(void) 605int __init pci_acpi_init(void)
597{ 606{
598 struct pci_dev *dev = NULL; 607 struct pci_dev *dev = NULL;
diff --git a/drivers/acpi/pci_root.c b/drivers/acpi/pci_root.c
index 471b2dcb1c67..bf5108ad4d63 100644
--- a/drivers/acpi/pci_root.c
+++ b/drivers/acpi/pci_root.c
@@ -107,24 +107,6 @@ void acpi_pci_unregister_driver(struct acpi_pci_driver *driver)
107} 107}
108EXPORT_SYMBOL(acpi_pci_unregister_driver); 108EXPORT_SYMBOL(acpi_pci_unregister_driver);
109 109
110acpi_handle acpi_get_pci_rootbridge_handle(unsigned int seg, unsigned int bus)
111{
112 struct acpi_pci_root *root;
113 acpi_handle handle = NULL;
114
115 mutex_lock(&acpi_pci_root_lock);
116 list_for_each_entry(root, &acpi_pci_roots, node)
117 if ((root->segment == (u16) seg) &&
118 (root->secondary.start == (u16) bus)) {
119 handle = root->device->handle;
120 break;
121 }
122 mutex_unlock(&acpi_pci_root_lock);
123 return handle;
124}
125
126EXPORT_SYMBOL_GPL(acpi_get_pci_rootbridge_handle);
127
128/** 110/**
129 * acpi_is_root_bridge - determine whether an ACPI CA node is a PCI root bridge 111 * acpi_is_root_bridge - determine whether an ACPI CA node is a PCI root bridge
130 * @handle - the ACPI CA node in question. 112 * @handle - the ACPI CA node in question.
diff --git a/drivers/pci/pci-acpi.c b/drivers/pci/pci-acpi.c
index 42736e213f25..1c2587c40299 100644
--- a/drivers/pci/pci-acpi.c
+++ b/drivers/pci/pci-acpi.c
@@ -302,24 +302,6 @@ static int acpi_pci_find_device(struct device *dev, acpi_handle *handle)
302 return 0; 302 return 0;
303} 303}
304 304
305static int acpi_pci_find_root_bridge(struct device *dev, acpi_handle *handle)
306{
307 int num;
308 unsigned int seg, bus;
309
310 /*
311 * The string should be the same as root bridge's name
312 * Please look at 'pci_scan_bus_parented'
313 */
314 num = sscanf(dev_name(dev), "pci%04x:%02x", &seg, &bus);
315 if (num != 2)
316 return -ENODEV;
317 *handle = acpi_get_pci_rootbridge_handle(seg, bus);
318 if (!*handle)
319 return -ENODEV;
320 return 0;
321}
322
323static void pci_acpi_setup(struct device *dev) 305static void pci_acpi_setup(struct device *dev)
324{ 306{
325 struct pci_dev *pci_dev = to_pci_dev(dev); 307 struct pci_dev *pci_dev = to_pci_dev(dev);
@@ -378,7 +360,6 @@ static void pci_acpi_cleanup(struct device *dev)
378static struct acpi_bus_type acpi_pci_bus = { 360static struct acpi_bus_type acpi_pci_bus = {
379 .bus = &pci_bus_type, 361 .bus = &pci_bus_type,
380 .find_device = acpi_pci_find_device, 362 .find_device = acpi_pci_find_device,
381 .find_bridge = acpi_pci_find_root_bridge,
382 .setup = pci_acpi_setup, 363 .setup = pci_acpi_setup,
383 .cleanup = pci_acpi_cleanup, 364 .cleanup = pci_acpi_cleanup,
384}; 365};
diff --git a/drivers/pci/probe.c b/drivers/pci/probe.c
index 2dcd22d9c816..bbe4be7fc685 100644
--- a/drivers/pci/probe.c
+++ b/drivers/pci/probe.c
@@ -1632,6 +1632,18 @@ unsigned int pci_scan_child_bus(struct pci_bus *bus)
1632 return max; 1632 return max;
1633} 1633}
1634 1634
1635/**
1636 * pcibios_root_bridge_prepare - Platform-specific host bridge setup.
1637 * @bridge: Host bridge to set up.
1638 *
1639 * Default empty implementation. Replace with an architecture-specific setup
1640 * routine, if necessary.
1641 */
1642int __weak pcibios_root_bridge_prepare(struct pci_host_bridge *bridge)
1643{
1644 return 0;
1645}
1646
1635struct pci_bus *pci_create_root_bus(struct device *parent, int bus, 1647struct pci_bus *pci_create_root_bus(struct device *parent, int bus,
1636 struct pci_ops *ops, void *sysdata, struct list_head *resources) 1648 struct pci_ops *ops, void *sysdata, struct list_head *resources)
1637{ 1649{
@@ -1665,6 +1677,10 @@ struct pci_bus *pci_create_root_bus(struct device *parent, int bus,
1665 bridge->dev.parent = parent; 1677 bridge->dev.parent = parent;
1666 bridge->dev.release = pci_release_bus_bridge_dev; 1678 bridge->dev.release = pci_release_bus_bridge_dev;
1667 dev_set_name(&bridge->dev, "pci%04x:%02x", pci_domain_nr(b), bus); 1679 dev_set_name(&bridge->dev, "pci%04x:%02x", pci_domain_nr(b), bus);
1680 error = pcibios_root_bridge_prepare(bridge);
1681 if (error)
1682 goto bridge_dev_reg_err;
1683
1668 error = device_register(&bridge->dev); 1684 error = device_register(&bridge->dev);
1669 if (error) 1685 if (error)
1670 goto bridge_dev_reg_err; 1686 goto bridge_dev_reg_err;
diff --git a/include/acpi/acpi_bus.h b/include/acpi/acpi_bus.h
index a9e1421cd007..796ccc3247df 100644
--- a/include/acpi/acpi_bus.h
+++ b/include/acpi/acpi_bus.h
@@ -402,7 +402,6 @@ struct acpi_pci_root {
402/* helper */ 402/* helper */
403acpi_handle acpi_get_child(acpi_handle, u64); 403acpi_handle acpi_get_child(acpi_handle, u64);
404int acpi_is_root_bridge(acpi_handle); 404int acpi_is_root_bridge(acpi_handle);
405acpi_handle acpi_get_pci_rootbridge_handle(unsigned int, unsigned int);
406struct acpi_pci_root *acpi_pci_find_root(acpi_handle handle); 405struct acpi_pci_root *acpi_pci_find_root(acpi_handle handle);
407#define DEVICE_ACPI_HANDLE(dev) ((acpi_handle)ACPI_HANDLE(dev)) 406#define DEVICE_ACPI_HANDLE(dev) ((acpi_handle)ACPI_HANDLE(dev))
408 407
diff --git a/include/linux/pci.h b/include/linux/pci.h
index 907b455ab603..6860f4dec997 100644
--- a/include/linux/pci.h
+++ b/include/linux/pci.h
@@ -378,6 +378,8 @@ void pci_set_host_bridge_release(struct pci_host_bridge *bridge,
378 void (*release_fn)(struct pci_host_bridge *), 378 void (*release_fn)(struct pci_host_bridge *),
379 void *release_data); 379 void *release_data);
380 380
381int pcibios_root_bridge_prepare(struct pci_host_bridge *bridge);
382
381/* 383/*
382 * The first PCI_BRIDGE_RESOURCE_NUM PCI bus resources (those that correspond 384 * The first PCI_BRIDGE_RESOURCE_NUM PCI bus resources (those that correspond
383 * to P2P or CardBus bridge windows) go in a table. Additional ones (for 385 * to P2P or CardBus bridge windows) go in a table. Additional ones (for
, 0x00010000, 0x00020000, 0x00080000, 0x00040000, 0x00800000, 0x00400000, 0x00100000, 0x00200000 }; /* ------------------------------------------------------------------------- */ static irqreturn_t m8xx_interrupt(int irq, void *dev); #define PCMCIA_BMT_LIMIT (15*4) /* Bus Monitor Timeout value */ /* ------------------------------------------------------------------------- */ /* board specific stuff: */ /* voltage_set(), hardware_enable() and hardware_disable() */ /* ------------------------------------------------------------------------- */ /* RPX Boards from Embedded Planet */ #if defined(CONFIG_RPXCLASSIC) || defined(CONFIG_RPXLITE) /* The RPX boards seems to have it's bus monitor timeout set to 6*8 clocks. * SYPCR is write once only, therefore must the slowest memory be faster * than the bus monitor or we will get a machine check due to the bus timeout. */ #define PCMCIA_BOARD_MSG "RPX CLASSIC or RPX LITE" #undef PCMCIA_BMT_LIMIT #define PCMCIA_BMT_LIMIT (6*8) static int voltage_set(int slot, int vcc, int vpp) { u32 reg = 0; switch (vcc) { case 0: break; case 33: reg |= BCSR1_PCVCTL4; break; case 50: reg |= BCSR1_PCVCTL5; break; default: return 1; } switch (vpp) { case 0: break; case 33: case 50: if (vcc == vpp) reg |= BCSR1_PCVCTL6; else return 1; break; case 120: reg |= BCSR1_PCVCTL7; default: return 1; } if (!((vcc == 50) || (vcc == 0))) return 1; /* first, turn off all power */ out_be32(((u32 *) RPX_CSR_ADDR), in_be32(((u32 *) RPX_CSR_ADDR)) & ~(BCSR1_PCVCTL4 | BCSR1_PCVCTL5 | BCSR1_PCVCTL6 | BCSR1_PCVCTL7)); /* enable new powersettings */ out_be32(((u32 *) RPX_CSR_ADDR), in_be32(((u32 *) RPX_CSR_ADDR)) | reg); return 0; } #define socket_get(_slot_) PCMCIA_SOCKET_KEY_5V #define hardware_enable(_slot_) /* No hardware to enable */ #define hardware_disable(_slot_) /* No hardware to disable */ #endif /* CONFIG_RPXCLASSIC */ /* FADS Boards from Motorola */ #if defined(CONFIG_FADS) #define PCMCIA_BOARD_MSG "FADS" static int voltage_set(int slot, int vcc, int vpp) { u32 reg = 0; switch (vcc) { case 0: break; case 33: reg |= BCSR1_PCCVCC0; break; case 50: reg |= BCSR1_PCCVCC1; break; default: return 1; } switch (vpp) { case 0: break; case 33: case 50: if (vcc == vpp) reg |= BCSR1_PCCVPP1; else return 1; break; case 120: if ((vcc == 33) || (vcc == 50)) reg |= BCSR1_PCCVPP0; else return 1; default: return 1; } /* first, turn off all power */ out_be32((u32 *) BCSR1, in_be32((u32 *) BCSR1) & ~(BCSR1_PCCVCC_MASK | BCSR1_PCCVPP_MASK)); /* enable new powersettings */ out_be32((u32 *) BCSR1, in_be32((u32 *) BCSR1) | reg); return 0; } #define socket_get(_slot_) PCMCIA_SOCKET_KEY_5V static void hardware_enable(int slot) { out_be32((u32 *) BCSR1, in_be32((u32 *) BCSR1) & ~BCSR1_PCCEN); } static void hardware_disable(int slot) { out_be32((u32 *) BCSR1, in_be32((u32 *) BCSR1) | BCSR1_PCCEN); } #endif /* MPC885ADS Boards */ #if defined(CONFIG_MPC885ADS) #define PCMCIA_BOARD_MSG "MPC885ADS" #define socket_get(_slot_) PCMCIA_SOCKET_KEY_5V static inline void hardware_enable(int slot) { m8xx_pcmcia_ops.hw_ctrl(slot, 1); } static inline void hardware_disable(int slot) { m8xx_pcmcia_ops.hw_ctrl(slot, 0); } static inline int voltage_set(int slot, int vcc, int vpp) { return m8xx_pcmcia_ops.voltage_set(slot, vcc, vpp); } #endif /* ------------------------------------------------------------------------- */ /* Motorola MBX860 */ #if defined(CONFIG_MBX) #define PCMCIA_BOARD_MSG "MBX" static int voltage_set(int slot, int vcc, int vpp) { u8 reg = 0; switch (vcc) { case 0: break; case 33: reg |= CSR2_VCC_33; break; case 50: reg |= CSR2_VCC_50; break; default: return 1; } switch (vpp) { case 0: break; case 33: case 50: if (vcc == vpp) reg |= CSR2_VPP_VCC; else return 1; break; case 120: if ((vcc == 33) || (vcc == 50)) reg |= CSR2_VPP_12; else return 1; default: return 1; } /* first, turn off all power */ out_8((u8 *) MBX_CSR2_ADDR, in_8((u8 *) MBX_CSR2_ADDR) & ~(CSR2_VCC_MASK | CSR2_VPP_MASK)); /* enable new powersettings */ out_8((u8 *) MBX_CSR2_ADDR, in_8((u8 *) MBX_CSR2_ADDR) | reg); return 0; } #define socket_get(_slot_) PCMCIA_SOCKET_KEY_5V #define hardware_enable(_slot_) /* No hardware to enable */ #define hardware_disable(_slot_) /* No hardware to disable */ #endif /* CONFIG_MBX */ #if defined(CONFIG_PRxK) #include <asm/cpld.h> extern volatile fpga_pc_regs *fpga_pc; #define PCMCIA_BOARD_MSG "MPC855T" static int voltage_set(int slot, int vcc, int vpp) { u8 reg = 0; u8 regread; cpld_regs *ccpld = get_cpld(); switch (vcc) { case 0: break; case 33: reg |= PCMCIA_VCC_33; break; case 50: reg |= PCMCIA_VCC_50; break; default: return 1; } switch (vpp) { case 0: break; case 33: case 50: if (vcc == vpp) reg |= PCMCIA_VPP_VCC; else return 1; break; case 120: if ((vcc == 33) || (vcc == 50)) reg |= PCMCIA_VPP_12; else return 1; default: return 1; } reg = reg >> (slot << 2); regread = in_8(&ccpld->fpga_pc_ctl); if (reg != (regread & ((PCMCIA_VCC_MASK | PCMCIA_VPP_MASK) >> (slot << 2)))) { /* enable new powersettings */ regread = regread & ~((PCMCIA_VCC_MASK | PCMCIA_VPP_MASK) >> (slot << 2)); out_8(&ccpld->fpga_pc_ctl, reg | regread); msleep(100); } return 0; } #define socket_get(_slot_) PCMCIA_SOCKET_KEY_LV #define hardware_enable(_slot_) /* No hardware to enable */ #define hardware_disable(_slot_) /* No hardware to disable */ #endif /* CONFIG_PRxK */ static u32 pending_events[PCMCIA_SOCKETS_NO]; static DEFINE_SPINLOCK(pending_event_lock); static irqreturn_t m8xx_interrupt(int irq, void *dev) { struct socket_info *s; struct event_table *e; unsigned int i, events, pscr, pipr, per; pcmconf8xx_t *pcmcia = socket[0].pcmcia; pr_debug("m8xx_pcmcia: Interrupt!\n"); /* get interrupt sources */ pscr = in_be32(&pcmcia->pcmc_pscr); pipr = in_be32(&pcmcia->pcmc_pipr); per = in_be32(&pcmcia->pcmc_per); for (i = 0; i < PCMCIA_SOCKETS_NO; i++) { s = &socket[i]; e = &s->events[0]; events = 0; while (e->regbit) { if (pscr & e->regbit) events |= e->eventbit; e++; } /* * report only if both card detect signals are the same * not too nice done, * we depend on that CD2 is the bit to the left of CD1... */ if (events & SS_DETECT) if (((pipr & M8XX_PCMCIA_CD2(i)) >> 1) ^ (pipr & M8XX_PCMCIA_CD1(i))) { events &= ~SS_DETECT; } #ifdef PCMCIA_GLITCHY_CD /* * I've experienced CD problems with my ADS board. * We make an extra check to see if there was a * real change of Card detection. */ if ((events & SS_DETECT) && ((pipr & (M8XX_PCMCIA_CD2(i) | M8XX_PCMCIA_CD1(i))) == 0) && (s->state.Vcc | s->state.Vpp)) { events &= ~SS_DETECT; /*printk( "CD glitch workaround - CD = 0x%08x!\n", (pipr & (M8XX_PCMCIA_CD2(i) | M8XX_PCMCIA_CD1(i)))); */ } #endif /* call the handler */ pr_debug("m8xx_pcmcia: slot %u: events = 0x%02x, pscr = 0x%08x, " "pipr = 0x%08x\n", i, events, pscr, pipr); if (events) { spin_lock(&pending_event_lock); pending_events[i] |= events; spin_unlock(&pending_event_lock); /* * Turn off RDY_L bits in the PER mask on * CD interrupt receival. * * They can generate bad interrupts on the * ACS4,8,16,32. - marcelo */ per &= ~M8XX_PCMCIA_RDY_L(0); per &= ~M8XX_PCMCIA_RDY_L(1); out_be32(&pcmcia->pcmc_per, per); if (events) pcmcia_parse_events(&socket[i].socket, events); } } /* clear the interrupt sources */ out_be32(&pcmcia->pcmc_pscr, pscr); pr_debug("m8xx_pcmcia: Interrupt done.\n"); return IRQ_HANDLED; } static u32 m8xx_get_graycode(u32 size) { u32 k; for (k = 0; k < M8XX_SIZES_NO; k++) if (m8xx_size_to_gray[k] == size) break; if ((k == M8XX_SIZES_NO) || (m8xx_size_to_gray[k] == -1)) k = -1; return k; } static u32 m8xx_get_speed(u32 ns, u32 is_io, u32 bus_freq) { u32 reg, clocks, psst, psl, psht; if (!ns) { /* * We get called with IO maps setup to 0ns * if not specified by the user. * They should be 255ns. */ if (is_io) ns = 255; else ns = 100; /* fast memory if 0 */ } /* * In PSST, PSL, PSHT fields we tell the controller * timing parameters in CLKOUT clock cycles. * CLKOUT is the same as GCLK2_50. */ /* how we want to adjust the timing - in percent */ #define ADJ 180 /* 80 % longer accesstime - to be sure */ clocks = ((bus_freq / 1000) * ns) / 1000; clocks = (clocks * ADJ) / (100 * 1000); if (clocks >= PCMCIA_BMT_LIMIT) { printk("Max access time limit reached\n"); clocks = PCMCIA_BMT_LIMIT - 1; } psst = clocks / 7; /* setup time */ psht = clocks / 7; /* hold time */ psl = (clocks * 5) / 7; /* strobe length */ psst += clocks - (psst + psht + psl); reg = psst << 12; reg |= psl << 7; reg |= psht << 16; return reg; } static int m8xx_get_status(struct pcmcia_socket *sock, unsigned int *value) { int lsock = container_of(sock, struct socket_info, socket)->slot; struct socket_info *s = &socket[lsock]; unsigned int pipr, reg; pcmconf8xx_t *pcmcia = s->pcmcia; pipr = in_be32(&pcmcia->pcmc_pipr); *value = ((pipr & (M8XX_PCMCIA_CD1(lsock) | M8XX_PCMCIA_CD2(lsock))) == 0) ? SS_DETECT : 0; *value |= (pipr & M8XX_PCMCIA_WP(lsock)) ? SS_WRPROT : 0; if (s->state.flags & SS_IOCARD) *value |= (pipr & M8XX_PCMCIA_BVD1(lsock)) ? SS_STSCHG : 0; else { *value |= (pipr & M8XX_PCMCIA_RDY(lsock)) ? SS_READY : 0; *value |= (pipr & M8XX_PCMCIA_BVD1(lsock)) ? SS_BATDEAD : 0; *value |= (pipr & M8XX_PCMCIA_BVD2(lsock)) ? SS_BATWARN : 0; } if (s->state.Vcc | s->state.Vpp) *value |= SS_POWERON; /* * Voltage detection: * This driver only supports 16-Bit pc-cards. * Cardbus is not handled here. * * To determine what voltage to use we must read the VS1 and VS2 pin. * Depending on what socket type is present, * different combinations mean different things. * * Card Key Socket Key VS1 VS2 Card Vcc for CIS parse * * 5V 5V, LV* NC NC 5V only 5V (if available) * * 5V 5V, LV* GND NC 5 or 3.3V as low as possible * * 5V 5V, LV* GND GND 5, 3.3, x.xV as low as possible * * LV* 5V - - shall not fit into socket * * LV* LV* GND NC 3.3V only 3.3V * * LV* LV* NC GND x.xV x.xV (if avail.) * * LV* LV* GND GND 3.3 or x.xV as low as possible * * *LV means Low Voltage * * * That gives us the following table: * * Socket VS1 VS2 Voltage * * 5V NC NC 5V * 5V NC GND none (should not be possible) * 5V GND NC >= 3.3V * 5V GND GND >= x.xV * * LV NC NC 5V (if available) * LV NC GND x.xV (if available) * LV GND NC 3.3V * LV GND GND >= x.xV * * So, how do I determine if I have a 5V or a LV * socket on my board? Look at the socket! * * * Socket with 5V key: * ++--------------------------------------------+ * || | * || || * || || * | | * +---------------------------------------------+ * * Socket with LV key: * ++--------------------------------------------+ * || | * | || * | || * | | * +---------------------------------------------+ * *