summaryrefslogtreecommitdiffstats
path: root/arch/mips/mti-malta
diff options
context:
space:
mode:
Diffstat (limited to 'arch/mips/mti-malta')
-rw-r--r--arch/mips/mti-malta/Makefile3
-rw-r--r--arch/mips/mti-malta/malta-init.c6
-rw-r--r--arch/mips/mti-malta/malta-int.c19
-rw-r--r--arch/mips/mti-malta/malta-memory.c4
-rw-r--r--arch/mips/mti-malta/malta-pm.c96
-rw-r--r--arch/mips/mti-malta/malta-reset.c14
-rw-r--r--arch/mips/mti-malta/malta-setup.c4
-rw-r--r--arch/mips/mti-malta/malta-smtc.c162
8 files changed, 109 insertions, 199 deletions
diff --git a/arch/mips/mti-malta/Makefile b/arch/mips/mti-malta/Makefile
index eae0ba3876d..b9510ea8db5 100644
--- a/arch/mips/mti-malta/Makefile
+++ b/arch/mips/mti-malta/Makefile
@@ -9,5 +9,4 @@ obj-y := malta-amon.o malta-display.o malta-init.o \
malta-int.o malta-memory.o malta-platform.o \
malta-reset.o malta-setup.o malta-time.o
-# FIXME FIXME FIXME
-obj-$(CONFIG_MIPS_MT_SMTC) += malta-smtc.o
+obj-$(CONFIG_MIPS_MALTA_PM) += malta-pm.o
diff --git a/arch/mips/mti-malta/malta-init.c b/arch/mips/mti-malta/malta-init.c
index 4f9e44d358b..0f60256d378 100644
--- a/arch/mips/mti-malta/malta-init.c
+++ b/arch/mips/mti-malta/malta-init.c
@@ -116,8 +116,6 @@ phys_t mips_cpc_default_phys_base(void)
return CPC_BASE_ADDR;
}
-extern struct plat_smp_ops msmtc_smp_ops;
-
void __init prom_init(void)
{
mips_display_message("LINUX");
@@ -304,8 +302,4 @@ mips_pci_controller:
return;
if (!register_vsmp_smp_ops())
return;
-
-#ifdef CONFIG_MIPS_MT_SMTC
- register_smp_ops(&msmtc_smp_ops);
-#endif
}
diff --git a/arch/mips/mti-malta/malta-int.c b/arch/mips/mti-malta/malta-int.c
index b71ee809191..ecc2785f785 100644
--- a/arch/mips/mti-malta/malta-int.c
+++ b/arch/mips/mti-malta/malta-int.c
@@ -504,28 +504,9 @@ void __init arch_init_irq(void)
} else if (cpu_has_vint) {
set_vi_handler(MIPSCPU_INT_I8259A, malta_hw0_irqdispatch);
set_vi_handler(MIPSCPU_INT_COREHI, corehi_irqdispatch);
-#ifdef CONFIG_MIPS_MT_SMTC
- setup_irq_smtc(MIPS_CPU_IRQ_BASE+MIPSCPU_INT_I8259A, &i8259irq,
- (0x100 << MIPSCPU_INT_I8259A));
- setup_irq_smtc(MIPS_CPU_IRQ_BASE+MIPSCPU_INT_COREHI,
- &corehi_irqaction, (0x100 << MIPSCPU_INT_COREHI));
- /*
- * Temporary hack to ensure that the subsidiary device
- * interrupts coing in via the i8259A, but associated
- * with low IRQ numbers, will restore the Status.IM
- * value associated with the i8259A.
- */
- {
- int i;
-
- for (i = 0; i < 16; i++)
- irq_hwmask[i] = (0x100 << MIPSCPU_INT_I8259A);
- }
-#else /* Not SMTC */
setup_irq(MIPS_CPU_IRQ_BASE+MIPSCPU_INT_I8259A, &i8259irq);
setup_irq(MIPS_CPU_IRQ_BASE+MIPSCPU_INT_COREHI,
&corehi_irqaction);
-#endif /* CONFIG_MIPS_MT_SMTC */
} else {
setup_irq(MIPS_CPU_IRQ_BASE+MIPSCPU_INT_I8259A, &i8259irq);
setup_irq(MIPS_CPU_IRQ_BASE+MIPSCPU_INT_COREHI,
diff --git a/arch/mips/mti-malta/malta-memory.c b/arch/mips/mti-malta/malta-memory.c
index f2364e41968..6d977309675 100644
--- a/arch/mips/mti-malta/malta-memory.c
+++ b/arch/mips/mti-malta/malta-memory.c
@@ -26,8 +26,8 @@ unsigned long physical_memsize = 0L;
fw_memblock_t * __init fw_getmdesc(int eva)
{
- char *memsize_str, *ememsize_str __maybe_unused = NULL, *ptr;
- unsigned long memsize = 0, ememsize __maybe_unused = 0;
+ char *memsize_str, *ememsize_str = NULL, *ptr;
+ unsigned long memsize = 0, ememsize = 0;
static char cmdline[COMMAND_LINE_SIZE] __initdata;
int tmp;
diff --git a/arch/mips/mti-malta/malta-pm.c b/arch/mips/mti-malta/malta-pm.c
new file mode 100644
index 00000000000..c1e456c01a4
--- /dev/null
+++ b/arch/mips/mti-malta/malta-pm.c
@@ -0,0 +1,96 @@
+/*
+ * Copyright (C) 2014 Imagination Technologies
+ * Author: Paul Burton <paul.burton@imgtec.com>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.
+ */
+
+#include <linux/delay.h>
+#include <linux/init.h>
+#include <linux/io.h>
+#include <linux/pci.h>
+
+#include <asm/mach-malta/malta-pm.h>
+
+static struct pci_bus *pm_pci_bus;
+static resource_size_t pm_io_offset;
+
+int mips_pm_suspend(unsigned state)
+{
+ int spec_devid;
+ u16 sts;
+
+ if (!pm_pci_bus || !pm_io_offset)
+ return -ENODEV;
+
+ /* Ensure the power button status is clear */
+ while (1) {
+ sts = inw(pm_io_offset + PIIX4_FUNC3IO_PMSTS);
+ if (!(sts & PIIX4_FUNC3IO_PMSTS_PWRBTN_STS))
+ break;
+ outw(sts, pm_io_offset + PIIX4_FUNC3IO_PMSTS);
+ }
+
+ /* Enable entry to suspend */
+ outw(state | PIIX4_FUNC3IO_PMCNTRL_SUS_EN,
+ pm_io_offset + PIIX4_FUNC3IO_PMCNTRL);
+
+ /* If the special cycle occurs too soon this doesn't work... */
+ mdelay(10);
+
+ /*
+ * The PIIX4 will enter the suspend state only after seeing a special
+ * cycle with the correct magic data on the PCI bus. Generate that
+ * cycle now.
+ */
+ spec_devid = PCI_DEVID(0, PCI_DEVFN(0x1f, 0x7));
+ pci_bus_write_config_dword(pm_pci_bus, spec_devid, 0,
+ PIIX4_SUSPEND_MAGIC);
+
+ /* Give the system some time to power down */
+ mdelay(1000);
+
+ return 0;
+}
+
+static int __init malta_pm_setup(void)
+{
+ struct pci_dev *dev;
+ int res, io_region = PCI_BRIDGE_RESOURCES;
+
+ /* Find a reference to the PCI bus */
+ pm_pci_bus = pci_find_next_bus(NULL);
+ if (!pm_pci_bus) {
+ pr_warn("malta-pm: failed to find reference to PCI bus\n");
+ return -ENODEV;
+ }
+
+ /* Find the PIIX4 PM device */
+ dev = pci_get_subsys(PCI_VENDOR_ID_INTEL,
+ PCI_DEVICE_ID_INTEL_82371AB_3, PCI_ANY_ID,
+ PCI_ANY_ID, NULL);
+ if (!dev) {
+ pr_warn("malta-pm: failed to find PIIX4 PM\n");
+ return -ENODEV;
+ }
+
+ /* Request access to the PIIX4 PM IO registers */
+ res = pci_request_region(dev, io_region, "PIIX4 PM IO registers");
+ if (res) {
+ pr_warn("malta-pm: failed to request PM IO registers (%d)\n",
+ res);
+ pci_dev_put(dev);
+ return -ENODEV;
+ }
+
+ /* Find the offset to the PIIX4 PM IO registers */
+ pm_io_offset = pci_resource_start(dev, io_region);
+
+ pci_dev_put(dev);
+ return 0;
+}
+
+late_initcall(malta_pm_setup);
diff --git a/arch/mips/mti-malta/malta-reset.c b/arch/mips/mti-malta/malta-reset.c
index d627d4b2b47..2fd2cc2c503 100644
--- a/arch/mips/mti-malta/malta-reset.c
+++ b/arch/mips/mti-malta/malta-reset.c
@@ -10,6 +10,7 @@
#include <linux/pm.h>
#include <asm/reboot.h>
+#include <asm/mach-malta/malta-pm.h>
#define SOFTRES_REG 0x1f000500
#define GORESET 0x42
@@ -24,17 +25,22 @@ static void mips_machine_restart(char *command)
static void mips_machine_halt(void)
{
- unsigned int __iomem *softres_reg =
- ioremap(SOFTRES_REG, sizeof(unsigned int));
+ while (true);
+}
- __raw_writel(GORESET, softres_reg);
+static void mips_machine_power_off(void)
+{
+ mips_pm_suspend(PIIX4_FUNC3IO_PMCNTRL_SUS_TYP_SOFF);
+
+ pr_info("Failed to power down, resetting\n");
+ mips_machine_restart(NULL);
}
static int __init mips_reboot_setup(void)
{
_machine_restart = mips_machine_restart;
_machine_halt = mips_machine_halt;
- pm_power_off = mips_machine_halt;
+ pm_power_off = mips_machine_power_off;
return 0;
}
diff --git a/arch/mips/mti-malta/malta-setup.c b/arch/mips/mti-malta/malta-setup.c
index bf621516aff..db7c9e5826a 100644
--- a/arch/mips/mti-malta/malta-setup.c
+++ b/arch/mips/mti-malta/malta-setup.c
@@ -77,11 +77,7 @@ const char *get_system_type(void)
return "MIPS Malta";
}
-#if defined(CONFIG_MIPS_MT_SMTC)
-const char display_string[] = " SMTC LINUX ON MALTA ";
-#else
const char display_string[] = " LINUX ON MALTA ";
-#endif /* CONFIG_MIPS_MT_SMTC */
#ifdef CONFIG_BLK_DEV_FD
static void __init fd_activate(void)
diff --git a/arch/mips/mti-malta/malta-smtc.c b/arch/mips/mti-malta/malta-smtc.c
deleted file mode 100644
index c4849904f01..00000000000
--- a/arch/mips/mti-malta/malta-smtc.c
+++ /dev/null
@@ -1,162 +0,0 @@
-/*
- * Malta Platform-specific hooks for SMP operation
- */
-#include <linux/irq.h>
-#include <linux/init.h>
-
-#include <asm/mipsregs.h>
-#include <asm/mipsmtregs.h>
-#include <asm/smtc.h>
-#include <asm/smtc_ipi.h>
-
-/* VPE/SMP Prototype implements platform interfaces directly */
-
-/*
- * Cause the specified action to be performed on a targeted "CPU"
- */
-
-static void msmtc_send_ipi_single(int cpu, unsigned int action)
-{
- /* "CPU" may be TC of same VPE, VPE of same CPU, or different CPU */
- smtc_send_ipi(cpu, LINUX_SMP_IPI, action);
-}
-
-static void msmtc_send_ipi_mask(const struct cpumask *mask, unsigned int action)
-{
- unsigned int i;
-
- for_each_cpu(i, mask)
- msmtc_send_ipi_single(i, action);
-}
-
-/*
- * Post-config but pre-boot cleanup entry point
- */
-static void msmtc_init_secondary(void)
-{
- int myvpe;
-
- /* Don't enable Malta I/O interrupts (IP2) for secondary VPEs */
- myvpe = read_c0_tcbind() & TCBIND_CURVPE;
- if (myvpe != 0) {
- /* Ideally, this should be done only once per VPE, but... */
- clear_c0_status(ST0_IM);
- set_c0_status((0x100 << cp0_compare_irq)
- | (0x100 << MIPS_CPU_IPI_IRQ));
- if (cp0_perfcount_irq >= 0)
- set_c0_status(0x100 << cp0_perfcount_irq);
- }
-
- smtc_init_secondary();
-}
-
-/*
- * Platform "CPU" startup hook
- */
-static void msmtc_boot_secondary(int cpu, struct task_struct *idle)
-{
- smtc_boot_secondary(cpu, idle);
-}
-
-/*
- * SMP initialization finalization entry point
- */
-static void msmtc_smp_finish(void)
-{
- smtc_smp_finish();
-}
-
-/*
- * Hook for after all CPUs are online
- */
-
-static void msmtc_cpus_done(void)
-{
-}
-
-/*
- * Platform SMP pre-initialization
- *
- * As noted above, we can assume a single CPU for now
- * but it may be multithreaded.
- */
-
-static void __init msmtc_smp_setup(void)
-{
- /*
- * we won't get the definitive value until
- * we've run smtc_prepare_cpus later, but
- * we would appear to need an upper bound now.
- */
- smp_num_siblings = smtc_build_cpu_map(0);
-}
-
-static void __init msmtc_prepare_cpus(unsigned int max_cpus)
-{
- smtc_prepare_cpus(max_cpus);
-}
-
-struct plat_smp_ops msmtc_smp_ops = {
- .send_ipi_single = msmtc_send_ipi_single,
- .send_ipi_mask = msmtc_send_ipi_mask,
- .init_secondary = msmtc_init_secondary,
- .smp_finish = msmtc_smp_finish,
- .cpus_done = msmtc_cpus_done,
- .boot_secondary = msmtc_boot_secondary,
- .smp_setup = msmtc_smp_setup,
- .prepare_cpus = msmtc_prepare_cpus,
-};
-
-#ifdef CONFIG_MIPS_MT_SMTC_IRQAFF
-/*
- * IRQ affinity hook
- */
-
-
-int plat_set_irq_affinity(struct irq_data *d, const struct cpumask *affinity,
- bool force)
-{
- cpumask_t tmask;
- int cpu = 0;
- void smtc_set_irq_affinity(unsigned int irq, cpumask_t aff);
-
- /*
- * On the legacy Malta development board, all I/O interrupts
- * are routed through the 8259 and combined in a single signal
- * to the CPU daughterboard, and on the CoreFPGA2/3 34K models,
- * that signal is brought to IP2 of both VPEs. To avoid racing
- * concurrent interrupt service events, IP2 is enabled only on
- * one VPE, by convention VPE0. So long as no bits are ever
- * cleared in the affinity mask, there will never be any
- * interrupt forwarding. But as soon as a program or operator
- * sets affinity for one of the related IRQs, we need to make
- * sure that we don't ever try to forward across the VPE boundary,
- * at least not until we engineer a system where the interrupt
- * _ack() or _end() function can somehow know that it corresponds
- * to an interrupt taken on another VPE, and perform the appropriate
- * restoration of Status.IM state using MFTR/MTTR instead of the
- * normal local behavior. We also ensure that no attempt will
- * be made to forward to an offline "CPU".
- */
-
- cpumask_copy(&tmask, affinity);
- for_each_cpu(cpu, affinity) {
- if ((cpu_data[cpu].vpe_id != 0) || !cpu_online(cpu))
- cpu_clear(cpu, tmask);
- }
- cpumask_copy(d->affinity, &tmask);
-
- if (cpus_empty(tmask))
- /*
- * We could restore a default mask here, but the
- * runtime code can anyway deal with the null set
- */
- printk(KERN_WARNING
- "IRQ affinity leaves no legal CPU for IRQ %d\n", d->irq);
-
- /* Do any generic SMTC IRQ affinity setup */
- smtc_set_irq_affinity(d->irq, tmask);
-
- return IRQ_SET_MASK_OK_NOCOPY;
-}
-#endif /* CONFIG_MIPS_MT_SMTC_IRQAFF */