void nautilus_kill_arch(int mode) { struct pci_bus *bus = pci_isa_hose->bus; u32 pmuport; int off; switch (mode) { case LINUX_REBOOT_CMD_RESTART: if (! alpha_using_srm) { u8 t8; pci_bus_read_config_byte(bus, 0x38, 0x43, &t8); pci_bus_write_config_byte(bus, 0x38, 0x43, t8 | 0x80); outb(1, 0x92); outb(0, 0x92); /* */ } break; case LINUX_REBOOT_CMD_POWER_OFF: /* */ off = 0x2000; /* */ pci_bus_read_config_dword(bus, 0x88, 0x10, &pmuport); if (!pmuport) { /* */ off = 0x3400; /* */ pci_bus_read_config_dword(bus, 0x88, 0xe0, &pmuport); } pmuport &= 0xfffe; outw(0xffff, pmuport); /* */ outw(off, pmuport + 4); /* */ break; } }
void nautilus_kill_arch(int mode) { struct pci_bus *bus = pci_isa_hose->bus; u32 pmuport; int off; switch (mode) { case LINUX_REBOOT_CMD_RESTART: if (! alpha_using_srm) { u8 t8; pci_bus_read_config_byte(bus, 0x38, 0x43, &t8); pci_bus_write_config_byte(bus, 0x38, 0x43, t8 | 0x80); outb(1, 0x92); outb(0, 0x92); /* NOTREACHED */ } break; case LINUX_REBOOT_CMD_POWER_OFF: /* Assume M1543C */ off = 0x2000; /* SLP_TYPE = 0, SLP_EN = 1 */ pci_bus_read_config_dword(bus, 0x88, 0x10, &pmuport); if (!pmuport) { /* M1535D/D+ */ off = 0x3400; /* SLP_TYPE = 5, SLP_EN = 1 */ pci_bus_read_config_dword(bus, 0x88, 0xe0, &pmuport); } pmuport &= 0xfffe; outw(0xffff, pmuport); /* Clear pending events. */ outw(off, pmuport + 4); /* NOTREACHED */ break; } }
void acpi_reboot(void) { struct acpi_generic_address *rr; struct pci_bus *bus0; u8 reset_value; unsigned int devfn; if (acpi_disabled) return; rr = &acpi_gbl_FADT.reset_register; /* * For those systems that have not been whitelisted, check the ACPI * flags and the register layout. */ if (!dmi_check_system(reboot_dmi_whitelist)) { /* Is the reset register supported? */ if (!(acpi_gbl_FADT.flags & ACPI_FADT_RESET_REGISTER)) return; /* Is the width and ofset as specified? */ if (rr->bit_width != 8 || rr->bit_offset != 0) return; } reset_value = acpi_gbl_FADT.reset_value; /* The reset register can only exist in I/O, Memory or PCI config space * on a device on bus 0. */ switch (rr->space_id) { case ACPI_ADR_SPACE_PCI_CONFIG: /* The reset register can only live on bus 0. */ bus0 = pci_find_bus(0, 0); if (!bus0) return; /* Form PCI device/function pair. */ devfn = PCI_DEVFN((rr->address >> 32) & 0xffff, (rr->address >> 16) & 0xffff); printk(KERN_DEBUG "Resetting with ACPI PCI RESET_REG."); /* Write the value that resets us. */ pci_bus_write_config_byte(bus0, devfn, (rr->address & 0xffff), reset_value); break; case ACPI_ADR_SPACE_SYSTEM_MEMORY: case ACPI_ADR_SPACE_SYSTEM_IO: printk(KERN_DEBUG "ACPI MEMORY or I/O RESET_REG.\n"); acpi_hw_low_level_write(8, reset_value, rr); break; } /* Wait ten seconds */ acpi_os_stall(10000000); }
void acpi_reboot(void) { struct acpi_generic_address *rr; struct pci_bus *bus0; u8 reset_value; unsigned int devfn; if (acpi_disabled) return; rr = &acpi_gbl_FADT.reset_register; /* */ if (acpi_gbl_FADT.header.revision < 2) return; /* */ if (!(acpi_gbl_FADT.flags & ACPI_FADT_RESET_REGISTER)) return; reset_value = acpi_gbl_FADT.reset_value; /* */ switch (rr->space_id) { case ACPI_ADR_SPACE_PCI_CONFIG: /* */ bus0 = pci_find_bus(0, 0); if (!bus0) return; /* */ devfn = PCI_DEVFN((rr->address >> 32) & 0xffff, (rr->address >> 16) & 0xffff); printk(KERN_DEBUG "Resetting with ACPI PCI RESET_REG."); /* */ pci_bus_write_config_byte(bus0, devfn, (rr->address & 0xffff), reset_value); break; case ACPI_ADR_SPACE_SYSTEM_MEMORY: case ACPI_ADR_SPACE_SYSTEM_IO: printk(KERN_DEBUG "ACPI MEMORY or I/O RESET_REG.\n"); acpi_reset(); break; } }
void acpi_reboot(void) { struct acpi_generic_address *rr; struct pci_bus *bus0; unsigned int devfn; u8 reset_value; if (acpi_disabled) return; rr = &acpi_gbl_FADT.reset_register; /* ACPI reset register was only introduced with v2 of the FADT */ if (acpi_gbl_FADT.header.revision < 2) return; /* Is the reset register supported? The spec says we should be * checking the bit width and bit offset, but Windows ignores * these fields */ if (!(acpi_gbl_FADT.flags & ACPI_FADT_RESET_REGISTER)) return; reset_value = acpi_gbl_FADT.reset_value; /* The reset register can only exist in I/O, Memory or PCI config space * on a device on bus 0. */ switch (rr->space_id) { case ACPI_ADR_SPACE_PCI_CONFIG: /* The reset register can only live on bus 0. */ bus0 = pci_find_bus(0, 0); if (!bus0) return; /* Form PCI device/function pair. */ devfn = PCI_DEVFN((rr->address >> 32) & 0xffff, (rr->address >> 16) & 0xffff); printk(KERN_DEBUG "Resetting with ACPI PCI RESET_REG.\n"); /* Write the value that resets us. */ pci_bus_write_config_byte(bus0, devfn, (rr->address & 0xffff), reset_value); break; case ACPI_ADR_SPACE_SYSTEM_MEMORY: case ACPI_ADR_SPACE_SYSTEM_IO: printk(KERN_DEBUG "ACPI MEMORY or I/O RESET_REG.\n"); acpi_reset(); break; } }
int pci_write_config_byte(const struct pci_dev *dev, int where, u8 val) { if (pci_dev_is_disconnected(dev)) return PCIBIOS_DEVICE_NOT_FOUND; return pci_bus_write_config_byte(dev->bus, dev->devfn, where, val); }
static void __init cns3xxx_pcie_hw_init(struct cns3xxx_pcie *cnspci) { int port = cnspci->port; struct pci_sys_data sd = { .private_data = cnspci, }; struct pci_bus bus = { .number = 0, .ops = &cns3xxx_pcie_ops, .sysdata = &sd, }; u16 mem_base = cnspci->res_mem.start >> 16; u16 mem_limit = cnspci->res_mem.end >> 16; u16 io_base = cnspci->res_io.start >> 16; u16 io_limit = cnspci->res_io.end >> 16; u32 devfn = 0; u8 tmp8; u16 pos; u16 dc; pci_bus_write_config_byte(&bus, devfn, PCI_PRIMARY_BUS, 0); pci_bus_write_config_byte(&bus, devfn, PCI_SECONDARY_BUS, 1); pci_bus_write_config_byte(&bus, devfn, PCI_SUBORDINATE_BUS, 1); pci_bus_read_config_byte(&bus, devfn, PCI_PRIMARY_BUS, &tmp8); pci_bus_read_config_byte(&bus, devfn, PCI_SECONDARY_BUS, &tmp8); pci_bus_read_config_byte(&bus, devfn, PCI_SUBORDINATE_BUS, &tmp8); pci_bus_write_config_word(&bus, devfn, PCI_MEMORY_BASE, mem_base); pci_bus_write_config_word(&bus, devfn, PCI_MEMORY_LIMIT, mem_limit); pci_bus_write_config_word(&bus, devfn, PCI_IO_BASE_UPPER16, io_base); pci_bus_write_config_word(&bus, devfn, PCI_IO_LIMIT_UPPER16, io_limit); if (!cnspci->linked) return; /* Set Device Max_Read_Request_Size to 128 byte */ bus.number = 1; /* directly connected PCIe device */ devfn = PCI_DEVFN(0, 0); pos = pci_bus_find_capability(&bus, devfn, PCI_CAP_ID_EXP); pci_bus_read_config_word(&bus, devfn, pos + PCI_EXP_DEVCTL, &dc); if (dc & PCI_EXP_DEVCTL_READRQ) { dc &= ~PCI_EXP_DEVCTL_READRQ; pci_bus_write_config_word(&bus, devfn, pos + PCI_EXP_DEVCTL, dc); pci_bus_read_config_word(&bus, devfn, pos + PCI_EXP_DEVCTL, &dc); if (dc & PCI_EXP_DEVCTL_READRQ) pr_warn("PCIe: Unable to set device Max_Read_Request_Size\n"); else pr_info("PCIe: Max_Read_Request_Size set to 128 bytes\n"); } /* Disable PCIe0 Interrupt Mask INTA to INTD */ __raw_writel(~0x3FFF, MISC_PCIE_INT_MASK(port)); } static int cns3xxx_pcie_abort_handler(unsigned long addr, unsigned int fsr, struct pt_regs *regs) { if (fsr & (1 << 10)) regs->ARM_pc += 4; return 0; } void __init cns3xxx_pcie_init_late(void) { int i; void *private_data; struct hw_pci hw_pci = { .nr_controllers = 1, .ops = &cns3xxx_pcie_ops, .setup = cns3xxx_pci_setup, .map_irq = cns3xxx_pcie_map_irq, .private_data = &private_data, }; pcibios_min_io = 0; pcibios_min_mem = 0; hook_fault_code(16 + 6, cns3xxx_pcie_abort_handler, SIGBUS, 0, "imprecise external abort"); for (i = 0; i < ARRAY_SIZE(cns3xxx_pcie); i++) { cns3xxx_pwr_clk_en(0x1 << PM_CLK_GATE_REG_OFFSET_PCIE(i)); cns3xxx_pwr_soft_rst(0x1 << PM_SOFT_RST_REG_OFFST_PCIE(i)); cns3xxx_pcie_check_link(&cns3xxx_pcie[i]); cns3xxx_pcie_hw_init(&cns3xxx_pcie[i]); private_data = &cns3xxx_pcie[i]; pci_common_init(&hw_pci); } pci_assign_unassigned_resources(); }