aboutsummaryrefslogtreecommitdiff
path: root/arch/mips/cavium-octeon
diff options
context:
space:
mode:
Diffstat (limited to 'arch/mips/cavium-octeon')
-rw-r--r--arch/mips/cavium-octeon/Kconfig36
-rw-r--r--arch/mips/cavium-octeon/Makefile5
-rw-r--r--arch/mips/cavium-octeon/Platform8
-rw-r--r--arch/mips/cavium-octeon/csrc-octeon.c1
-rw-r--r--arch/mips/cavium-octeon/executive/cvmx-cmd-queue.c1
-rw-r--r--arch/mips/cavium-octeon/executive/cvmx-helper-board.c40
-rw-r--r--arch/mips/cavium-octeon/executive/cvmx-helper-util.c4
-rw-r--r--arch/mips/cavium-octeon/executive/cvmx-helper.c176
-rw-r--r--arch/mips/cavium-octeon/executive/cvmx-pko.c3
-rw-r--r--arch/mips/cavium-octeon/executive/cvmx-spi.c1
-rw-r--r--arch/mips/cavium-octeon/octeon-irq.c47
-rw-r--r--arch/mips/cavium-octeon/octeon-platform.c48
-rw-r--r--arch/mips/cavium-octeon/octeon_3xxx.dts19
-rw-r--r--arch/mips/cavium-octeon/serial.c109
-rw-r--r--arch/mips/cavium-octeon/setup.c119
-rw-r--r--arch/mips/cavium-octeon/smp.c36
16 files changed, 387 insertions, 266 deletions
diff --git a/arch/mips/cavium-octeon/Kconfig b/arch/mips/cavium-octeon/Kconfig
index 75a6df7fd26..60286665793 100644
--- a/arch/mips/cavium-octeon/Kconfig
+++ b/arch/mips/cavium-octeon/Kconfig
@@ -10,26 +10,6 @@ config CAVIUM_CN63XXP1
non-CN63XXP1 hardware, so it is recommended to select "n"
unless it is known the workarounds are needed.
-config CAVIUM_OCTEON_2ND_KERNEL
- bool "Build the kernel to be used as a 2nd kernel on the same chip"
- default "n"
- help
- This option configures this kernel to be linked at a different
- address and use the 2nd uart for output. This allows a kernel built
- with this option to be run at the same time as one built without this
- option.
-
-config CAVIUM_OCTEON_HW_FIX_UNALIGNED
- bool "Enable hardware fixups of unaligned loads and stores"
- default "y"
- help
- Configure the Octeon hardware to automatically fix unaligned loads
- and stores. Normally unaligned accesses are fixed using a kernel
- exception handler. This option enables the hardware automatic fixups,
- which requires only an extra 3 cycles. Disable this option if you
- are running code that relies on address exceptions on unaligned
- accesses.
-
config CAVIUM_OCTEON_CVMSEG_SIZE
int "Number of L1 cache lines reserved for CVMSEG memory"
range 0 54
@@ -41,6 +21,19 @@ config CAVIUM_OCTEON_CVMSEG_SIZE
legally range is from zero to 54 cache blocks (i.e. CVMSEG LM is
between zero and 6192 bytes).
+endif # CPU_CAVIUM_OCTEON
+
+if CAVIUM_OCTEON_SOC
+
+config CAVIUM_OCTEON_2ND_KERNEL
+ bool "Build the kernel to be used as a 2nd kernel on the same chip"
+ default "n"
+ help
+ This option configures this kernel to be linked at a different
+ address and use the 2nd uart for output. This allows a kernel built
+ with this option to be run at the same time as one built without this
+ option.
+
config CAVIUM_OCTEON_LOCK_L2
bool "Lock often used kernel code in the L2"
default "y"
@@ -93,7 +86,6 @@ config SWIOTLB
select IOMMU_HELPER
select NEED_SG_DMA_LENGTH
-
config OCTEON_ILM
tristate "Module to measure interrupt latency using Octeon CIU Timer"
help
@@ -103,4 +95,4 @@ config OCTEON_ILM
To compile this driver as a module, choose M here. The module
will be called octeon-ilm
-endif # CPU_CAVIUM_OCTEON
+endif # CAVIUM_OCTEON_SOC
diff --git a/arch/mips/cavium-octeon/Makefile b/arch/mips/cavium-octeon/Makefile
index 3595affb977..4e952043c92 100644
--- a/arch/mips/cavium-octeon/Makefile
+++ b/arch/mips/cavium-octeon/Makefile
@@ -12,11 +12,12 @@
CFLAGS_octeon-platform.o = -I$(src)/../../../scripts/dtc/libfdt
CFLAGS_setup.o = -I$(src)/../../../scripts/dtc/libfdt
-obj-y := cpu.o setup.o serial.o octeon-platform.o octeon-irq.o csrc-octeon.o
-obj-y += dma-octeon.o flash_setup.o
+obj-y := cpu.o setup.o octeon-platform.o octeon-irq.o csrc-octeon.o
+obj-y += dma-octeon.o
obj-y += octeon-memcpy.o
obj-y += executive/
+obj-$(CONFIG_MTD) += flash_setup.o
obj-$(CONFIG_SMP) += smp.o
obj-$(CONFIG_OCTEON_ILM) += oct_ilm.o
diff --git a/arch/mips/cavium-octeon/Platform b/arch/mips/cavium-octeon/Platform
index 1e43ccf1a79..8a301cb12d6 100644
--- a/arch/mips/cavium-octeon/Platform
+++ b/arch/mips/cavium-octeon/Platform
@@ -1,11 +1,11 @@
#
# Cavium Octeon
#
-platform-$(CONFIG_CPU_CAVIUM_OCTEON) += cavium-octeon/
-cflags-$(CONFIG_CPU_CAVIUM_OCTEON) += \
+platform-$(CONFIG_CAVIUM_OCTEON_SOC) += cavium-octeon/
+cflags-$(CONFIG_CAVIUM_OCTEON_SOC) += \
-I$(srctree)/arch/mips/include/asm/mach-cavium-octeon
ifdef CONFIG_CAVIUM_OCTEON_2ND_KERNEL
-load-$(CONFIG_CPU_CAVIUM_OCTEON) += 0xffffffff84100000
+load-$(CONFIG_CAVIUM_OCTEON_SOC) += 0xffffffff84100000
else
-load-$(CONFIG_CPU_CAVIUM_OCTEON) += 0xffffffff81100000
+load-$(CONFIG_CAVIUM_OCTEON_SOC) += 0xffffffff81100000
endif
diff --git a/arch/mips/cavium-octeon/csrc-octeon.c b/arch/mips/cavium-octeon/csrc-octeon.c
index 02193953eb9..b752c4ed0b7 100644
--- a/arch/mips/cavium-octeon/csrc-octeon.c
+++ b/arch/mips/cavium-octeon/csrc-octeon.c
@@ -12,6 +12,7 @@
#include <linux/smp.h>
#include <asm/cpu-info.h>
+#include <asm/cpu-type.h>
#include <asm/time.h>
#include <asm/octeon/octeon.h>
diff --git a/arch/mips/cavium-octeon/executive/cvmx-cmd-queue.c b/arch/mips/cavium-octeon/executive/cvmx-cmd-queue.c
index 132bccc66a9..8241fc6aa17 100644
--- a/arch/mips/cavium-octeon/executive/cvmx-cmd-queue.c
+++ b/arch/mips/cavium-octeon/executive/cvmx-cmd-queue.c
@@ -47,6 +47,7 @@
* state. It points to a bootmem named block.
*/
__cvmx_cmd_queue_all_state_t *__cvmx_cmd_queue_state_ptr;
+EXPORT_SYMBOL_GPL(__cvmx_cmd_queue_state_ptr);
/**
* Initialize the Global queue state pointer.
diff --git a/arch/mips/cavium-octeon/executive/cvmx-helper-board.c b/arch/mips/cavium-octeon/executive/cvmx-helper-board.c
index 7c649778189..b764df64be4 100644
--- a/arch/mips/cavium-octeon/executive/cvmx-helper-board.c
+++ b/arch/mips/cavium-octeon/executive/cvmx-helper-board.c
@@ -181,6 +181,11 @@ int cvmx_helper_board_get_mii_address(int ipd_port)
return ipd_port - 16 + 4;
else
return -1;
+ case CVMX_BOARD_TYPE_UBNT_E100:
+ if (ipd_port >= 0 && ipd_port <= 2)
+ return 7 - ipd_port;
+ else
+ return -1;
}
/* Some unknown board. Somebody forgot to update this function... */
@@ -706,6 +711,41 @@ int __cvmx_helper_board_hardware_enable(int interface)
}
}
}
+ } else if (cvmx_sysinfo_get()->board_type ==
+ CVMX_BOARD_TYPE_UBNT_E100) {
+ cvmx_write_csr(CVMX_ASXX_RX_CLK_SETX(0, interface), 0);
+ cvmx_write_csr(CVMX_ASXX_TX_CLK_SETX(0, interface), 0x10);
+ cvmx_write_csr(CVMX_ASXX_RX_CLK_SETX(1, interface), 0);
+ cvmx_write_csr(CVMX_ASXX_TX_CLK_SETX(1, interface), 0x10);
+ cvmx_write_csr(CVMX_ASXX_RX_CLK_SETX(2, interface), 0);
+ cvmx_write_csr(CVMX_ASXX_TX_CLK_SETX(2, interface), 0x10);
}
return 0;
}
+
+/**
+ * Get the clock type used for the USB block based on board type.
+ * Used by the USB code for auto configuration of clock type.
+ *
+ * Return USB clock type enumeration
+ */
+enum cvmx_helper_board_usb_clock_types __cvmx_helper_board_usb_get_clock_type(void)
+{
+ switch (cvmx_sysinfo_get()->board_type) {
+ case CVMX_BOARD_TYPE_BBGW_REF:
+ case CVMX_BOARD_TYPE_LANAI2_A:
+ case CVMX_BOARD_TYPE_LANAI2_U:
+ case CVMX_BOARD_TYPE_LANAI2_G:
+ case CVMX_BOARD_TYPE_NIC10E_66:
+ case CVMX_BOARD_TYPE_UBNT_E100:
+ return USB_CLOCK_TYPE_CRYSTAL_12;
+ case CVMX_BOARD_TYPE_NIC10E:
+ return USB_CLOCK_TYPE_REF_12;
+ default:
+ break;
+ }
+ /* Most boards except NIC10e use a 12MHz crystal */
+ if (OCTEON_IS_MODEL(OCTEON_FAM_2))
+ return USB_CLOCK_TYPE_CRYSTAL_12;
+ return USB_CLOCK_TYPE_REF_48;
+}
diff --git a/arch/mips/cavium-octeon/executive/cvmx-helper-util.c b/arch/mips/cavium-octeon/executive/cvmx-helper-util.c
index 65d2bc9a0bd..453d7f66459 100644
--- a/arch/mips/cavium-octeon/executive/cvmx-helper-util.c
+++ b/arch/mips/cavium-octeon/executive/cvmx-helper-util.c
@@ -251,6 +251,7 @@ int cvmx_helper_setup_red(int pass_thresh, int drop_thresh)
return 0;
}
+EXPORT_SYMBOL_GPL(cvmx_helper_setup_red);
/**
* Setup the common GMX settings that determine the number of
@@ -384,6 +385,7 @@ int cvmx_helper_get_ipd_port(int interface, int port)
}
return -1;
}
+EXPORT_SYMBOL_GPL(cvmx_helper_get_ipd_port);
/**
* Returns the interface number for an IPD/PKO port number.
@@ -408,6 +410,7 @@ int cvmx_helper_get_interface_num(int ipd_port)
return -1;
}
+EXPORT_SYMBOL_GPL(cvmx_helper_get_interface_num);
/**
* Returns the interface index number for an IPD/PKO port
@@ -431,3 +434,4 @@ int cvmx_helper_get_interface_index_num(int ipd_port)
return -1;
}
+EXPORT_SYMBOL_GPL(cvmx_helper_get_interface_index_num);
diff --git a/arch/mips/cavium-octeon/executive/cvmx-helper.c b/arch/mips/cavium-octeon/executive/cvmx-helper.c
index d63d20dfbfb..7e5cf7a5e2f 100644
--- a/arch/mips/cavium-octeon/executive/cvmx-helper.c
+++ b/arch/mips/cavium-octeon/executive/cvmx-helper.c
@@ -67,7 +67,7 @@ void (*cvmx_override_pko_queue_priority) (int pko_port,
void (*cvmx_override_ipd_port_setup) (int ipd_port);
/* Port count per interface */
-static int interface_port_count[4] = { 0, 0, 0, 0 };
+static int interface_port_count[5];
/* Port last configured link info index by IPD/PKO port */
static cvmx_helper_link_info_t
@@ -88,6 +88,7 @@ int cvmx_helper_get_number_of_interfaces(void)
else
return 3;
}
+EXPORT_SYMBOL_GPL(cvmx_helper_get_number_of_interfaces);
/**
* Return the number of ports on an interface. Depending on the
@@ -102,6 +103,159 @@ int cvmx_helper_ports_on_interface(int interface)
{
return interface_port_count[interface];
}
+EXPORT_SYMBOL_GPL(cvmx_helper_ports_on_interface);
+
+/**
+ * @INTERNAL
+ * Return interface mode for CN68xx.
+ */
+static cvmx_helper_interface_mode_t __cvmx_get_mode_cn68xx(int interface)
+{
+ union cvmx_mio_qlmx_cfg qlm_cfg;
+ switch (interface) {
+ case 0:
+ qlm_cfg.u64 = cvmx_read_csr(CVMX_MIO_QLMX_CFG(0));
+ /* QLM is disabled when QLM SPD is 15. */
+ if (qlm_cfg.s.qlm_spd == 15)
+ return CVMX_HELPER_INTERFACE_MODE_DISABLED;
+
+ if (qlm_cfg.s.qlm_cfg == 2)
+ return CVMX_HELPER_INTERFACE_MODE_SGMII;
+ else if (qlm_cfg.s.qlm_cfg == 3)
+ return CVMX_HELPER_INTERFACE_MODE_XAUI;
+ else
+ return CVMX_HELPER_INTERFACE_MODE_DISABLED;
+ case 2:
+ case 3:
+ case 4:
+ qlm_cfg.u64 = cvmx_read_csr(CVMX_MIO_QLMX_CFG(interface));
+ /* QLM is disabled when QLM SPD is 15. */
+ if (qlm_cfg.s.qlm_spd == 15)
+ return CVMX_HELPER_INTERFACE_MODE_DISABLED;
+
+ if (qlm_cfg.s.qlm_cfg == 2)
+ return CVMX_HELPER_INTERFACE_MODE_SGMII;
+ else if (qlm_cfg.s.qlm_cfg == 3)
+ return CVMX_HELPER_INTERFACE_MODE_XAUI;
+ else
+ return CVMX_HELPER_INTERFACE_MODE_DISABLED;
+ case 7:
+ qlm_cfg.u64 = cvmx_read_csr(CVMX_MIO_QLMX_CFG(3));
+ /* QLM is disabled when QLM SPD is 15. */
+ if (qlm_cfg.s.qlm_spd == 15) {
+ return CVMX_HELPER_INTERFACE_MODE_DISABLED;
+ } else if (qlm_cfg.s.qlm_cfg != 0) {
+ qlm_cfg.u64 = cvmx_read_csr(CVMX_MIO_QLMX_CFG(1));
+ if (qlm_cfg.s.qlm_cfg != 0)
+ return CVMX_HELPER_INTERFACE_MODE_DISABLED;
+ }
+ return CVMX_HELPER_INTERFACE_MODE_NPI;
+ case 8:
+ return CVMX_HELPER_INTERFACE_MODE_LOOP;
+ default:
+ return CVMX_HELPER_INTERFACE_MODE_DISABLED;
+ }
+}
+
+/**
+ * @INTERNAL
+ * Return interface mode for an Octeon II
+ */
+static cvmx_helper_interface_mode_t __cvmx_get_mode_octeon2(int interface)
+{
+ union cvmx_gmxx_inf_mode mode;
+
+ if (OCTEON_IS_MODEL(OCTEON_CN68XX))
+ return __cvmx_get_mode_cn68xx(interface);
+
+ if (interface == 2)
+ return CVMX_HELPER_INTERFACE_MODE_NPI;
+
+ if (interface == 3)
+ return CVMX_HELPER_INTERFACE_MODE_LOOP;
+
+ /* Only present in CN63XX & CN66XX Octeon model */
+ if ((OCTEON_IS_MODEL(OCTEON_CN63XX) &&
+ (interface == 4 || interface == 5)) ||
+ (OCTEON_IS_MODEL(OCTEON_CN66XX) &&
+ interface >= 4 && interface <= 7)) {
+ return CVMX_HELPER_INTERFACE_MODE_DISABLED;
+ }
+
+ if (OCTEON_IS_MODEL(OCTEON_CN66XX)) {
+ union cvmx_mio_qlmx_cfg mio_qlm_cfg;
+
+ /* QLM2 is SGMII0 and QLM1 is SGMII1 */
+ if (interface == 0)
+ mio_qlm_cfg.u64 = cvmx_read_csr(CVMX_MIO_QLMX_CFG(2));
+ else if (interface == 1)
+ mio_qlm_cfg.u64 = cvmx_read_csr(CVMX_MIO_QLMX_CFG(1));
+ else
+ return CVMX_HELPER_INTERFACE_MODE_DISABLED;
+
+ if (mio_qlm_cfg.s.qlm_spd == 15)
+ return CVMX_HELPER_INTERFACE_MODE_DISABLED;
+
+ if (mio_qlm_cfg.s.qlm_cfg == 9)
+ return CVMX_HELPER_INTERFACE_MODE_SGMII;
+ else if (mio_qlm_cfg.s.qlm_cfg == 11)
+ return CVMX_HELPER_INTERFACE_MODE_XAUI;
+ else
+ return CVMX_HELPER_INTERFACE_MODE_DISABLED;
+ } else if (OCTEON_IS_MODEL(OCTEON_CN61XX)) {
+ union cvmx_mio_qlmx_cfg qlm_cfg;
+
+ if (interface == 0) {
+ qlm_cfg.u64 = cvmx_read_csr(CVMX_MIO_QLMX_CFG(2));
+ if (qlm_cfg.s.qlm_cfg == 2)
+ return CVMX_HELPER_INTERFACE_MODE_SGMII;
+ else if (qlm_cfg.s.qlm_cfg == 3)
+ return CVMX_HELPER_INTERFACE_MODE_XAUI;
+ else
+ return CVMX_HELPER_INTERFACE_MODE_DISABLED;
+ } else if (interface == 1) {
+ qlm_cfg.u64 = cvmx_read_csr(CVMX_MIO_QLMX_CFG(0));
+ if (qlm_cfg.s.qlm_cfg == 2)
+ return CVMX_HELPER_INTERFACE_MODE_SGMII;
+ else if (qlm_cfg.s.qlm_cfg == 3)
+ return CVMX_HELPER_INTERFACE_MODE_XAUI;
+ else
+ return CVMX_HELPER_INTERFACE_MODE_DISABLED;
+ }
+ } else if (OCTEON_IS_MODEL(OCTEON_CNF71XX)) {
+ if (interface == 0) {
+ union cvmx_mio_qlmx_cfg qlm_cfg;
+ qlm_cfg.u64 = cvmx_read_csr(CVMX_MIO_QLMX_CFG(0));
+ if (qlm_cfg.s.qlm_cfg == 2)
+ return CVMX_HELPER_INTERFACE_MODE_SGMII;
+ }
+ return CVMX_HELPER_INTERFACE_MODE_DISABLED;
+ }
+
+ if (interface == 1 && OCTEON_IS_MODEL(OCTEON_CN63XX))
+ return CVMX_HELPER_INTERFACE_MODE_DISABLED;
+
+ mode.u64 = cvmx_read_csr(CVMX_GMXX_INF_MODE(interface));
+
+ if (OCTEON_IS_MODEL(OCTEON_CN63XX)) {
+ switch (mode.cn63xx.mode) {
+ case 0:
+ return CVMX_HELPER_INTERFACE_MODE_SGMII;
+ case 1:
+ return CVMX_HELPER_INTERFACE_MODE_XAUI;
+ default:
+ return CVMX_HELPER_INTERFACE_MODE_DISABLED;
+ }
+ } else {
+ if (!mode.s.en)
+ return CVMX_HELPER_INTERFACE_MODE_DISABLED;
+
+ if (mode.s.type)
+ return CVMX_HELPER_INTERFACE_MODE_GMII;
+ else
+ return CVMX_HELPER_INTERFACE_MODE_RGMII;
+ }
+}
/**
* Get the operating mode of an interface. Depending on the Octeon
@@ -116,6 +270,20 @@ int cvmx_helper_ports_on_interface(int interface)
cvmx_helper_interface_mode_t cvmx_helper_interface_get_mode(int interface)
{
union cvmx_gmxx_inf_mode mode;
+
+ if (interface < 0 ||
+ interface >= cvmx_helper_get_number_of_interfaces())
+ return CVMX_HELPER_INTERFACE_MODE_DISABLED;
+
+ /*
+ * Octeon II models
+ */
+ if (OCTEON_IS_MODEL(OCTEON_CN6XXX) || OCTEON_IS_MODEL(OCTEON_CNF71XX))
+ return __cvmx_get_mode_octeon2(interface);
+
+ /*
+ * Octeon and Octeon Plus models
+ */
if (interface == 2)
return CVMX_HELPER_INTERFACE_MODE_NPI;
@@ -179,6 +347,7 @@ cvmx_helper_interface_mode_t cvmx_helper_interface_get_mode(int interface)
return CVMX_HELPER_INTERFACE_MODE_RGMII;
}
}
+EXPORT_SYMBOL_GPL(cvmx_helper_interface_get_mode);
/**
* Configure the IPD/PIP tagging and QoS options for a specific
@@ -825,6 +994,7 @@ int cvmx_helper_ipd_and_packet_input_enable(void)
__cvmx_helper_errata_fix_ipd_ptr_alignment();
return 0;
}
+EXPORT_SYMBOL_GPL(cvmx_helper_ipd_and_packet_input_enable);
/**
* Initialize the PIP, IPD, and PKO hardware to support
@@ -903,6 +1073,7 @@ int cvmx_helper_initialize_packet_io_global(void)
#endif
return result;
}
+EXPORT_SYMBOL_GPL(cvmx_helper_initialize_packet_io_global);
/**
* Does core local initialization for packet io
@@ -947,6 +1118,7 @@ cvmx_helper_link_info_t cvmx_helper_link_autoconf(int ipd_port)
*/
return port_link_info[ipd_port];
}
+EXPORT_SYMBOL_GPL(cvmx_helper_link_autoconf);
/**
* Return the link state of an IPD/PKO port as returned by
@@ -1005,6 +1177,7 @@ cvmx_helper_link_info_t cvmx_helper_link_get(int ipd_port)
}
return result;
}
+EXPORT_SYMBOL_GPL(cvmx_helper_link_get);
/**
* Configure an IPD/PKO port for the specified link state. This
@@ -1060,6 +1233,7 @@ int cvmx_helper_link_set(int ipd_port, cvmx_helper_link_info_t link_info)
port_link_info[ipd_port].u64 = link_info.u64;
return result;
}
+EXPORT_SYMBOL_GPL(cvmx_helper_link_set);
/**
* Configure a port for internal and/or external loopback. Internal loopback
diff --git a/arch/mips/cavium-octeon/executive/cvmx-pko.c b/arch/mips/cavium-octeon/executive/cvmx-pko.c
index f2c87754159..008b881cdf6 100644
--- a/arch/mips/cavium-octeon/executive/cvmx-pko.c
+++ b/arch/mips/cavium-octeon/executive/cvmx-pko.c
@@ -140,7 +140,7 @@ void cvmx_pko_disable(void)
pko_reg_flags.s.ena_pko = 0;
cvmx_write_csr(CVMX_PKO_REG_FLAGS, pko_reg_flags.u64);
}
-
+EXPORT_SYMBOL_GPL(cvmx_pko_disable);
/**
* Reset the packet output.
@@ -182,6 +182,7 @@ void cvmx_pko_shutdown(void)
}
__cvmx_pko_reset();
}
+EXPORT_SYMBOL_GPL(cvmx_pko_shutdown);
/**
* Configure a output port and the associated queues for use.
diff --git a/arch/mips/cavium-octeon/executive/cvmx-spi.c b/arch/mips/cavium-octeon/executive/cvmx-spi.c
index ef5198d13a0..459e3b1eb61 100644
--- a/arch/mips/cavium-octeon/executive/cvmx-spi.c
+++ b/arch/mips/cavium-octeon/executive/cvmx-spi.c
@@ -177,6 +177,7 @@ int cvmx_spi_restart_interface(int interface, cvmx_spi_mode_t mode, int timeout)
return res;
}
+EXPORT_SYMBOL_GPL(cvmx_spi_restart_interface);
/**
* Callback to perform SPI4 reset
diff --git a/arch/mips/cavium-octeon/octeon-irq.c b/arch/mips/cavium-octeon/octeon-irq.c
index 156aa6143e1..1b82ac6921e 100644
--- a/arch/mips/cavium-octeon/octeon-irq.c
+++ b/arch/mips/cavium-octeon/octeon-irq.c
@@ -607,7 +607,7 @@ static void octeon_irq_ciu_gpio_ack(struct irq_data *data)
static void octeon_irq_handle_gpio(unsigned int irq, struct irq_desc *desc)
{
- if (irqd_get_trigger_type(irq_desc_get_irq_data(desc)) & IRQ_TYPE_EDGE_BOTH)
+ if (irq_get_trigger_type(irq) & IRQ_TYPE_EDGE_BOTH)
handle_edge_irq(irq, desc);
else
handle_level_irq(irq, desc);
@@ -635,7 +635,7 @@ static void octeon_irq_cpu_offline_ciu(struct irq_data *data)
cpumask_clear(&new_affinity);
cpumask_set_cpu(cpumask_first(cpu_online_mask), &new_affinity);
}
- __irq_set_affinity_locked(data, &new_affinity);
+ irq_set_affinity_locked(data, &new_affinity, false);
}
static int octeon_irq_ciu_set_affinity(struct irq_data *data,
@@ -975,10 +975,6 @@ static int octeon_irq_ciu_xlat(struct irq_domain *d,
if (ciu > 1 || bit > 63)
return -EINVAL;
- /* These are the GPIO lines */
- if (ciu == 0 && bit >= 16 && bit < 32)
- return -EINVAL;
-
*out_hwirq = (ciu << 6) | bit;
*out_type = 0;
@@ -1007,6 +1003,10 @@ static int octeon_irq_ciu_map(struct irq_domain *d,
if (!octeon_irq_virq_in_range(virq))
return -EINVAL;
+ /* Don't map irq if it is reserved for GPIO. */
+ if (line == 0 && bit >= 16 && bit <32)
+ return 0;
+
if (line > 1 || octeon_irq_ciu_to_irq[line][bit] != 0)
return -EINVAL;
@@ -1032,9 +1032,8 @@ static int octeon_irq_gpio_map_common(struct irq_domain *d,
if (!octeon_irq_virq_in_range(virq))
return -EINVAL;
- hw += gpiod->base_hwirq;
- line = hw >> 6;
- bit = hw & 63;
+ line = (hw + gpiod->base_hwirq) >> 6;
+ bit = (hw + gpiod->base_hwirq) & 63;
if (line > line_limit || octeon_irq_ciu_to_irq[line][bit] != 0)
return -EINVAL;
@@ -1096,7 +1095,7 @@ static void octeon_irq_ip3_ciu(void)
static bool octeon_irq_use_ip4;
-static void __cpuinit octeon_irq_local_enable_ip4(void *arg)
+static void octeon_irq_local_enable_ip4(void *arg)
{
set_c0_status(STATUSF_IP4);
}
@@ -1111,21 +1110,21 @@ static void (*octeon_irq_ip2)(void);
static void (*octeon_irq_ip3)(void);
static void (*octeon_irq_ip4)(void);
-void __cpuinitdata (*octeon_irq_setup_secondary)(void);
+void (*octeon_irq_setup_secondary)(void);
-void __cpuinit octeon_irq_set_ip4_handler(octeon_irq_ip4_handler_t h)
+void octeon_irq_set_ip4_handler(octeon_irq_ip4_handler_t h)
{
octeon_irq_ip4 = h;
octeon_irq_use_ip4 = true;
on_each_cpu(octeon_irq_local_enable_ip4, NULL, 1);
}
-static void __cpuinit octeon_irq_percpu_enable(void)
+static void octeon_irq_percpu_enable(void)
{
irq_cpu_online();
}
-static void __cpuinit octeon_irq_init_ciu_percpu(void)
+static void octeon_irq_init_ciu_percpu(void)
{
int coreid = cvmx_get_core_num();
@@ -1168,7 +1167,7 @@ static void octeon_irq_init_ciu2_percpu(void)
cvmx_read_csr(CVMX_CIU2_SUM_PPX_IP2(coreid));
}
-static void __cpuinit octeon_irq_setup_secondary_ciu(void)
+static void octeon_irq_setup_secondary_ciu(void)
{
octeon_irq_init_ciu_percpu();
octeon_irq_percpu_enable();
@@ -1261,11 +1260,13 @@ static void __init octeon_irq_init_ciu(void)
for (i = 0; i < 4; i++)
octeon_irq_force_ciu_mapping(ciu_domain, i + OCTEON_IRQ_PCI_MSI0, 0, i + 40);
+ octeon_irq_force_ciu_mapping(ciu_domain, OCTEON_IRQ_TWSI, 0, 45);
octeon_irq_force_ciu_mapping(ciu_domain, OCTEON_IRQ_RML, 0, 46);
for (i = 0; i < 4; i++)
octeon_irq_force_ciu_mapping(ciu_domain, i + OCTEON_IRQ_TIMER0, 0, i + 52);
octeon_irq_force_ciu_mapping(ciu_domain, OCTEON_IRQ_USB0, 0, 56);
+ octeon_irq_force_ciu_mapping(ciu_domain, OCTEON_IRQ_TWSI2, 0, 59);
/* CIU_1 */
for (i = 0; i < 16; i++)
@@ -1526,10 +1527,6 @@ static int octeon_irq_ciu2_xlat(struct irq_domain *d,
ciu = intspec[0];
bit = intspec[1];
- /* Line 7 are the GPIO lines */
- if (ciu > 6 || bit > 63)
- return -EINVAL;
-
*out_hwirq = (ciu << 6) | bit;
*out_type = 0;
@@ -1571,8 +1568,14 @@ static int octeon_irq_ciu2_map(struct irq_domain *d,
if (!octeon_irq_virq_in_range(virq))
return -EINVAL;
- /* Line 7 are the GPIO lines */
- if (line > 6 || octeon_irq_ciu_to_irq[line][bit] != 0)
+ /*
+ * Don't map irq if it is reserved for GPIO.
+ * (Line 7 are the GPIO lines.)
+ */
+ if (line == 7)
+ return 0;
+
+ if (line > 7 || octeon_irq_ciu_to_irq[line][bit] != 0)
return -EINVAL;
if (octeon_irq_ciu2_is_edge(line, bit))
@@ -1777,7 +1780,7 @@ asmlinkage void plat_irq_dispatch(void)
#ifdef CONFIG_HOTPLUG_CPU
-void fixup_irqs(void)
+void octeon_fixup_irqs(void)
{
irq_cpu_offline();
}
diff --git a/arch/mips/cavium-octeon/octeon-platform.c b/arch/mips/cavium-octeon/octeon-platform.c
index 389512e2abd..6df0f4d8f19 100644
--- a/arch/mips/cavium-octeon/octeon-platform.c
+++ b/arch/mips/cavium-octeon/octeon-platform.c
@@ -171,6 +171,7 @@ device_initcall(octeon_ohci_device_init);
static struct of_device_id __initdata octeon_ids[] = {
{ .compatible = "simple-bus", },
{ .compatible = "cavium,octeon-6335-uctl", },
+ { .compatible = "cavium,octeon-5750-usbn", },
{ .compatible = "cavium,octeon-3860-bootbus", },
{ .compatible = "cavium,mdio-mux", },
{ .compatible = "gpio-leds", },
@@ -334,15 +335,16 @@ static void __init octeon_fdt_pip_iface(int pip, int idx, u64 *pmac)
char name_buffer[20];
int iface;
int p;
- int count;
-
- count = cvmx_helper_interface_enumerate(idx);
+ int count = 0;
snprintf(name_buffer, sizeof(name_buffer), "interface@%d", idx);
iface = fdt_subnode_offset(initial_boot_params, pip, name_buffer);
if (iface < 0)
return;
+ if (cvmx_helper_interface_enumerate(idx) == 0)
+ count = cvmx_helper_ports_on_interface(idx);
+
for (p = 0; p < 16; p++)
octeon_fdt_pip_port(iface, idx, p, count - 1, pmac);
}
@@ -490,8 +492,15 @@ int __init octeon_prune_device_tree(void)
if (alias_prop) {
uart = fdt_path_offset(initial_boot_params, alias_prop);
- if (uart_mask & (1 << i))
+ if (uart_mask & (1 << i)) {
+ __be32 f;
+
+ f = cpu_to_be32(octeon_get_io_clock_rate());
+ fdt_setprop_inplace(initial_boot_params,
+ uart, "clock-frequency",
+ &f, sizeof(f));
continue;
+ }
pr_debug("Deleting uart%d\n", i);
fdt_nop_node(initial_boot_params, uart);
fdt_nop_property(initial_boot_params, aliases,
@@ -674,6 +683,37 @@ end_led:
}
}
+ /* DWC2 USB */
+ alias_prop = fdt_getprop(initial_boot_params, aliases,
+ "usbn", NULL);
+ if (alias_prop) {
+ int usbn = fdt_path_offset(initial_boot_params, alias_prop);
+
+ if (usbn >= 0 && (current_cpu_type() == CPU_CAVIUM_OCTEON2 ||
+ !octeon_has_feature(OCTEON_FEATURE_USB))) {
+ pr_debug("Deleting usbn\n");
+ fdt_nop_node(initial_boot_params, usbn);
+ fdt_nop_property(initial_boot_params, aliases, "usbn");
+ } else {
+ __be32 new_f[1];
+ enum cvmx_helper_board_usb_clock_types c;
+ c = __cvmx_helper_board_usb_get_clock_type();
+ switch (c) {
+ case USB_CLOCK_TYPE_REF_48:
+ new_f[0] = cpu_to_be32(48000000);
+ fdt_setprop_inplace(initial_boot_params, usbn,
+ "refclk-frequency", new_f, sizeof(new_f));
+ /* Fall through ...*/
+ case USB_CLOCK_TYPE_REF_12:
+ /* Missing "refclk-type" defaults to external. */
+ fdt_nop_property(initial_boot_params, usbn, "refclk-type");
+ break;
+ default:
+ break;
+ }
+ }
+ }
+
return 0;
}
diff --git a/arch/mips/cavium-octeon/octeon_3xxx.dts b/arch/mips/cavium-octeon/octeon_3xxx.dts
index 88cb42d4cc4..fa33115bde3 100644
--- a/arch/mips/cavium-octeon/octeon_3xxx.dts
+++ b/arch/mips/cavium-octeon/octeon_3xxx.dts
@@ -550,6 +550,24 @@
big-endian-regs;
};
};
+
+ usbn: usbn@1180068000000 {
+ compatible = "cavium,octeon-5750-usbn";
+ reg = <0x11800 0x68000000 0x0 0x1000>;
+ ranges; /* Direct mapping */
+ #address-cells = <2>;
+ #size-cells = <2>;
+ /* 12MHz, 24MHz and 48MHz allowed */
+ refclk-frequency = <12000000>;
+ /* Either "crystal" or "external" */
+ refclk-type = "crystal";
+
+ usbc@16f0010000000 {
+ compatible = "cavium,octeon-5750-usbc";
+ reg = <0x16f00 0x10000000 0x0 0x80000>;
+ interrupts = <0 56>;
+ };
+ };
};
aliases {
@@ -566,6 +584,7 @@
flash0 = &flash0;
cf0 = &cf0;
uctl = &uctl;
+ usbn = &usbn;
led0 = &led0;
};
};
diff --git a/arch/mips/cavium-octeon/serial.c b/arch/mips/cavium-octeon/serial.c
deleted file mode 100644
index f393f65f392..00000000000
--- a/arch/mips/cavium-octeon/serial.c
+++ /dev/null
@@ -1,109 +0,0 @@
-/*
- * This file is subject to the terms and conditions of the GNU General Public
- * License. See the file "COPYING" in the main directory of this archive
- * for more details.
- *
- * Copyright (C) 2004-2007 Cavium Networks
- */
-#include <linux/console.h>
-#include <linux/module.h>
-#include <linux/init.h>
-#include <linux/platform_device.h>
-#include <linux/serial.h>
-#include <linux/serial_8250.h>
-#include <linux/serial_reg.h>
-#include <linux/tty.h>
-#include <linux/irq.h>
-
-#include <asm/time.h>
-
-#include <asm/octeon/octeon.h>
-
-#define DEBUG_UART 1
-
-unsigned int octeon_serial_in(struct uart_port *up, int offset)
-{
- int rv = cvmx_read_csr((uint64_t)(up->membase + (offset << 3)));
- if (offset == UART_IIR && (rv & 0xf) == 7) {
- /* Busy interrupt, read the USR (39) and try again. */
- cvmx_read_csr((uint64_t)(up->membase + (39 << 3)));
- rv = cvmx_read_csr((uint64_t)(up->membase + (offset << 3)));
- }
- return rv;
-}
-
-void octeon_serial_out(struct uart_port *up, int offset, int value)
-{
- /*
- * If bits 6 or 7 of the OCTEON UART's LCR are set, it quits
- * working.
- */
- if (offset == UART_LCR)
- value &= 0x9f;
- cvmx_write_csr((uint64_t)(up->membase + (offset << 3)), (u8)value);
-}
-
-static int octeon_serial_probe(struct platform_device *pdev)
-{
- int irq, res;
- struct resource *res_mem;
- struct uart_8250_port up;
-
- /* All adaptors have an irq. */
- irq = platform_get_irq(pdev, 0);
- if (irq < 0)
- return irq;
-
- memset(&up, 0, sizeof(up));
-
- up.port.flags = ASYNC_SKIP_TEST | UPF_SHARE_IRQ | UPF_FIXED_TYPE;
- up.port.type = PORT_OCTEON;
- up.port.iotype = UPIO_MEM;
- up.port.regshift = 3;
- up.port.dev = &pdev->dev;
-
- if (octeon_is_simulation())
- /* Make simulator output fast*/
- up.port.uartclk = 115200 * 16;
- else
- up.port.uartclk = octeon_get_io_clock_rate();
-
- up.port.serial_in = octeon_serial_in;
- up.port.serial_out = octeon_serial_out;
- up.port.irq = irq;
-
- res_mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
- if (res_mem == NULL) {
- dev_err(&pdev->dev, "found no memory resource\n");
- return -ENXIO;
- }
- up.port.mapbase = res_mem->start;
- up.port.membase = ioremap(res_mem->start, resource_size(res_mem));
-
- res = serial8250_register_8250_port(&up);
-
- return res >= 0 ? 0 : res;
-}
-
-static struct of_device_id octeon_serial_match[] = {
- {
- .compatible = "cavium,octeon-3860-uart",
- },
- {},
-};
-MODULE_DEVICE_TABLE(of, octeon_serial_match);
-
-static struct platform_driver octeon_serial_driver = {
- .probe = octeon_serial_probe,
- .driver = {
- .owner = THIS_MODULE,
- .name = "octeon_serial",
- .of_match_table = octeon_serial_match,
- },
-};
-
-static int __init octeon_serial_init(void)
-{
- return platform_driver_register(&octeon_serial_driver);
-}
-late_initcall(octeon_serial_init);
diff --git a/arch/mips/cavium-octeon/setup.c b/arch/mips/cavium-octeon/setup.c
index c594a3d4f74..008e9c8b8ea 100644
--- a/arch/mips/cavium-octeon/setup.c
+++ b/arch/mips/cavium-octeon/setup.c
@@ -7,6 +7,8 @@
* Copyright (C) 2008, 2009 Wind River Systems
* written by Ralf Baechle <ralf@linux-mips.org>
*/
+#include <linux/compiler.h>
+#include <linux/vmalloc.h>
#include <linux/init.h>
#include <linux/kernel.h>
#include <linux/console.h>
@@ -40,12 +42,6 @@
#include <asm/octeon/pci-octeon.h>
#include <asm/octeon/cvmx-mio-defs.h>
-#ifdef CONFIG_CAVIUM_DECODE_RSL
-extern void cvmx_interrupt_rsl_decode(void);
-extern int __cvmx_interrupt_ecc_report_single_bit_errors;
-extern void cvmx_interrupt_rsl_enable(void);
-#endif
-
extern struct plat_smp_ops octeon_smp_ops;
#ifdef CONFIG_PCI
@@ -174,7 +170,10 @@ static int octeon_kexec_prepare(struct kimage *image)
static void octeon_generic_shutdown(void)
{
- int cpu, i;
+ int i;
+#ifdef CONFIG_SMP
+ int cpu;
+#endif
struct cvmx_bootmem_desc *bootmem_desc;
void *named_block_array_ptr;
@@ -425,13 +424,16 @@ static void octeon_restart(char *command)
*/
static void octeon_kill_core(void *arg)
{
- mb();
- if (octeon_is_simulation()) {
- /* The simulator needs the watchdog to stop for dead cores */
- cvmx_write_csr(CVMX_CIU_WDOGX(cvmx_get_core_num()), 0);
+ if (octeon_is_simulation())
/* A break instruction causes the simulator stop a core */
- asm volatile ("sync\nbreak");
- }
+ asm volatile ("break" ::: "memory");
+
+ local_irq_disable();
+ /* Disable watchdog on this core. */
+ cvmx_write_csr(CVMX_CIU_WDOGX(cvmx_get_core_num()), 0);
+ /* Spin in a low power mode. */
+ while (true)
+ asm volatile ("wait" ::: "memory");
}
@@ -457,18 +459,6 @@ static void octeon_halt(void)
}
/**
- * Handle all the error condition interrupts that might occur.
- *
- */
-#ifdef CONFIG_CAVIUM_DECODE_RSL
-static irqreturn_t octeon_rlm_interrupt(int cpl, void *dev_id)
-{
- cvmx_interrupt_rsl_decode();
- return IRQ_HANDLED;
-}
-#endif
-
-/**
* Return a string representing the system type
*
* Returns
@@ -706,7 +696,7 @@ void __init prom_init(void)
if (cvmx_read_csr(CVMX_L2D_FUS3) & (3ull << 34)) {
pr_info("Skipping L2 locking due to reduced L2 cache size\n");
} else {
- uint32_t ebase = read_c0_ebase() & 0x3ffff000;
+ uint32_t __maybe_unused ebase = read_c0_ebase() & 0x3ffff000;
#ifdef CONFIG_CAVIUM_OCTEON_LOCK_L2_TLB
/* TLB refill */
cvmx_l2c_lock_mem_region(ebase, 0x100);
@@ -739,17 +729,6 @@ void __init prom_init(void)
octeon_write_lcd("Linux");
#endif
-#ifdef CONFIG_CAVIUM_GDB
- /*
- * When debugging the linux kernel, force the cores to enter
- * the debug exception handler to break in.
- */
- if (octeon_get_boot_debug_flag()) {
- cvmx_write_csr(CVMX_CIU_DINT, 1 << cvmx_get_core_num());
- cvmx_read_csr(CVMX_CIU_DINT);
- }
-#endif
-
octeon_setup_delays();
/*
@@ -789,12 +768,6 @@ void __init prom_init(void)
MAX_MEMORY = 32ull << 30;
if (*p == '@')
RESERVE_LOW_MEM = memparse(p + 1, &p);
- } else if (strcmp(arg, "ecc_verbose") == 0) {
-#ifdef CONFIG_CAVIUM_REPORT_SINGLE_BIT_ECC
- __cvmx_interrupt_ecc_report_single_bit_errors = 1;
- pr_notice("Reporting of single bit ECC errors is "
- "turned on\n");
-#endif
#ifdef CONFIG_KEXEC
} else if (strncmp(arg, "crashkernel=", 12) == 0) {
crashk_size = memparse(arg+12, &p);
@@ -990,7 +963,7 @@ void __init plat_mem_setup(void)
cvmx_bootmem_unlock();
/* Add the memory region for the kernel. */
kernel_start = (unsigned long) _text;
- kernel_size = ALIGN(_end - _text, 0x100000);
+ kernel_size = _end - _text;
/* Adjust for physical offset. */
kernel_start &= ~0xffffffff80000000ULL;
@@ -1009,7 +982,7 @@ void __init plat_mem_setup(void)
if (total == 0)
panic("Unable to allocate memory from "
- "cvmx_bootmem_phy_alloc\n");
+ "cvmx_bootmem_phy_alloc");
}
/*
@@ -1058,50 +1031,31 @@ void prom_free_prom_memory(void)
panic("Core-14449 WAR not in place (%04x).\n"
"Please build kernel with proper options (CONFIG_CAVIUM_CN63XXP1).", insn);
}
-#ifdef CONFIG_CAVIUM_DECODE_RSL
- cvmx_interrupt_rsl_enable();
-
- /* Add an interrupt handler for general failures. */
- if (request_irq(OCTEON_IRQ_RML, octeon_rlm_interrupt, IRQF_SHARED,
- "RML/RSL", octeon_rlm_interrupt)) {
- panic("Unable to request_irq(OCTEON_IRQ_RML)");
- }
-#endif
}
int octeon_prune_device_tree(void);
extern const char __dtb_octeon_3xxx_begin;
-extern const char __dtb_octeon_3xxx_end;
extern const char __dtb_octeon_68xx_begin;
-extern const char __dtb_octeon_68xx_end;
void __init device_tree_init(void)
{
- int dt_size;
- struct boot_param_header *fdt;
+ const void *fdt;
bool do_prune;
if (octeon_bootinfo->minor_version >= 3 && octeon_bootinfo->fdt_addr) {
fdt = phys_to_virt(octeon_bootinfo->fdt_addr);
if (fdt_check_header(fdt))
panic("Corrupt Device Tree passed to kernel.");
- dt_size = be32_to_cpu(fdt->totalsize);
do_prune = false;
} else if (OCTEON_IS_MODEL(OCTEON_CN68XX)) {
- fdt = (struct boot_param_header *)&__dtb_octeon_68xx_begin;
- dt_size = &__dtb_octeon_68xx_end - &__dtb_octeon_68xx_begin;
+ fdt = &__dtb_octeon_68xx_begin;
do_prune = true;
} else {
- fdt = (struct boot_param_header *)&__dtb_octeon_3xxx_begin;
- dt_size = &__dtb_octeon_3xxx_end - &__dtb_octeon_3xxx_begin;
+ fdt = &__dtb_octeon_3xxx_begin;
do_prune = true;
}
- /* Copy the default tree from init memory. */
- initial_boot_params = early_init_dt_alloc_memory_arch(dt_size, 8);
- if (initial_boot_params == NULL)
- panic("Could not allocate initial_boot_params\n");
- memcpy(initial_boot_params, fdt, dt_size);
+ initial_boot_params = (void *)fdt;
if (do_prune) {
octeon_prune_device_tree();
@@ -1109,7 +1063,7 @@ void __init device_tree_init(void)
} else {
pr_info("Using passed Device Tree.\n");
}
- unflatten_device_tree();
+ unflatten_and_copy_device_tree();
}
static int __initdata disable_octeon_edac_p;
@@ -1159,3 +1113,30 @@ static int __init edac_devinit(void)
return err;
}
device_initcall(edac_devinit);
+
+static void __initdata *octeon_dummy_iospace;
+
+static int __init octeon_no_pci_init(void)
+{
+ /*
+ * Initially assume there is no PCI. The PCI/PCIe platform code will
+ * later re-initialize these to correct values if they are present.
+ */
+ octeon_dummy_iospace = vzalloc(IO_SPACE_LIMIT);
+ set_io_port_base((unsigned long)octeon_dummy_iospace);
+ ioport_resource.start = MAX_RESOURCE;
+ ioport_resource.end = 0;
+ return 0;
+}
+core_initcall(octeon_no_pci_init);
+
+static int __init octeon_no_pci_release(void)
+{
+ /*
+ * Release the allocated memory if a real IO space is there.
+ */
+ if ((unsigned long)octeon_dummy_iospace != mips_io_port_base)
+ vfree(octeon_dummy_iospace);
+ return 0;
+}
+late_initcall(octeon_no_pci_release);
diff --git a/arch/mips/cavium-octeon/smp.c b/arch/mips/cavium-octeon/smp.c
index 295137dfdc3..a7b3ae104d8 100644
--- a/arch/mips/cavium-octeon/smp.c
+++ b/arch/mips/cavium-octeon/smp.c
@@ -6,7 +6,6 @@
* Copyright (C) 2004-2008, 2009, 2010 Cavium Networks
*/
#include <linux/cpu.h>
-#include <linux/init.h>
#include <linux/delay.h>
#include <linux/smp.h>
#include <linux/interrupt.h>
@@ -173,7 +172,7 @@ static void octeon_boot_secondary(int cpu, struct task_struct *idle)
* After we've done initial boot, this function is called to allow the
* board code to clean up state, if needed
*/
-static void __cpuinit octeon_init_secondary(void)
+static void octeon_init_secondary(void)
{
unsigned int sr;
@@ -219,15 +218,6 @@ void octeon_prepare_cpus(unsigned int max_cpus)
*/
static void octeon_smp_finish(void)
{
-#ifdef CONFIG_CAVIUM_GDB
- unsigned long tmp;
- /* Pulse MCD0 signal on Ctrl-C to stop all the cores. Also set the MCD0
- to be not masked by this core so we know the signal is received by
- someone */
- asm volatile ("dmfc0 %0, $22\n"
- "ori %0, %0, 0x9100\n" "dmtc0 %0, $22\n" : "=r" (tmp));
-#endif
-
octeon_user_io_init();
/* to generate the first CPU timer interrupt */
@@ -235,28 +225,11 @@ static void octeon_smp_finish(void)
local_irq_enable();
}
-/**
- * Hook for after all CPUs are online
- */
-static void octeon_cpus_done(void)
-{
-#ifdef CONFIG_CAVIUM_GDB
- unsigned long tmp;
- /* Pulse MCD0 signal on Ctrl-C to stop all the cores. Also set the MCD0
- to be not masked by this core so we know the signal is received by
- someone */
- asm volatile ("dmfc0 %0, $22\n"
- "ori %0, %0, 0x9100\n" "dmtc0 %0, $22\n" : "=r" (tmp));
-#endif
-}
-
#ifdef CONFIG_HOTPLUG_CPU
/* State of each CPU. */
DEFINE_PER_CPU(int, cpu_state);
-extern void fixup_irqs(void);
-
static int octeon_cpu_disable(void)
{
unsigned int cpu = smp_processor_id();
@@ -267,7 +240,7 @@ static int octeon_cpu_disable(void)
set_cpu_online(cpu, false);
cpu_clear(cpu, cpu_callin_map);
local_irq_disable();
- fixup_irqs();
+ octeon_fixup_irqs();
local_irq_enable();
flush_cache_all();
@@ -375,7 +348,7 @@ static int octeon_update_boot_vector(unsigned int cpu)
return 0;
}
-static int __cpuinit octeon_cpu_callback(struct notifier_block *nfb,
+static int octeon_cpu_callback(struct notifier_block *nfb,
unsigned long action, void *hcpu)
{
unsigned int cpu = (unsigned long)hcpu;
@@ -394,7 +367,7 @@ static int __cpuinit octeon_cpu_callback(struct notifier_block *nfb,
return NOTIFY_OK;
}
-static int __cpuinit register_cavium_notifier(void)
+static int register_cavium_notifier(void)
{
hotcpu_notifier(octeon_cpu_callback, 0);
return 0;
@@ -408,7 +381,6 @@ struct plat_smp_ops octeon_smp_ops = {
.send_ipi_mask = octeon_send_ipi_mask,
.init_secondary = octeon_init_secondary,
.smp_finish = octeon_smp_finish,
- .cpus_done = octeon_cpus_done,
.boot_secondary = octeon_boot_secondary,
.smp_setup = octeon_smp_setup,
.prepare_cpus = octeon_prepare_cpus,