linux-stable/arch/alpha/kernel/sys_wildfire.c
Mike Rapoport fdb7d9b7ac alpha: remove DISCONTIGMEM and NUMA
Patch series "Remove DISCONTIGMEM memory model", v3.

SPARSEMEM memory model was supposed to entirely replace DISCONTIGMEM a
(long) while ago.  The last architectures that used DISCONTIGMEM were
updated to use other memory models in v5.11 and it is about the time to
entirely remove DISCONTIGMEM from the kernel.

This set removes DISCONTIGMEM from alpha, arc and m68k, simplifies memory
model selection in mm/Kconfig and replaces usage of redundant
CONFIG_NEED_MULTIPLE_NODES and CONFIG_FLAT_NODE_MEM_MAP with CONFIG_NUMA
and CONFIG_FLATMEM respectively.

I've also removed NUMA support on alpha that was BROKEN for more than 15
years.

There were also minor updates all over arch/ to remove mentions of
DISCONTIGMEM in comments and #ifdefs.

This patch (of 9):

NUMA is marked broken on alpha for more than 15 years and DISCONTIGMEM was
replaced with SPARSEMEM in v5.11.

Remove both NUMA and DISCONTIGMEM support from alpha.

Link: https://lkml.kernel.org/r/20210608091316.3622-1-rppt@kernel.org
Link: https://lkml.kernel.org/r/20210608091316.3622-2-rppt@kernel.org
Signed-off-by: Mike Rapoport <rppt@linux.ibm.com>
Acked-by: Arnd Bergmann <arnd@arndb.de>
Acked-by: David Hildenbrand <david@redhat.com>
Cc: Geert Uytterhoeven <geert@linux-m68k.org>
Cc: Ivan Kokshaysky <ink@jurassic.park.msu.ru>
Cc: Jonathan Corbet <corbet@lwn.net>
Cc: Matt Turner <mattst88@gmail.com>
Cc: Richard Henderson <rth@twiddle.net>
Cc: Vineet Gupta <vgupta@synopsys.com>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
2021-06-29 10:53:55 -07:00

341 lines
8.4 KiB
C

// SPDX-License-Identifier: GPL-2.0
/*
* linux/arch/alpha/kernel/sys_wildfire.c
*
* Wildfire support.
*
* Copyright (C) 2000 Andrea Arcangeli <andrea@suse.de> SuSE
*/
#include <linux/kernel.h>
#include <linux/types.h>
#include <linux/mm.h>
#include <linux/sched.h>
#include <linux/pci.h>
#include <linux/init.h>
#include <linux/bitops.h>
#include <asm/ptrace.h>
#include <asm/dma.h>
#include <asm/irq.h>
#include <asm/mmu_context.h>
#include <asm/io.h>
#include <asm/core_wildfire.h>
#include <asm/hwrpb.h>
#include <asm/tlbflush.h>
#include "proto.h"
#include "irq_impl.h"
#include "pci_impl.h"
#include "machvec_impl.h"
static unsigned long cached_irq_mask[WILDFIRE_NR_IRQS/(sizeof(long)*8)];
DEFINE_SPINLOCK(wildfire_irq_lock);
static int doing_init_irq_hw = 0;
static void
wildfire_update_irq_hw(unsigned int irq)
{
int qbbno = (irq >> 8) & (WILDFIRE_MAX_QBB - 1);
int pcano = (irq >> 6) & (WILDFIRE_PCA_PER_QBB - 1);
wildfire_pca *pca;
volatile unsigned long * enable0;
if (!WILDFIRE_PCA_EXISTS(qbbno, pcano)) {
if (!doing_init_irq_hw) {
printk(KERN_ERR "wildfire_update_irq_hw:"
" got irq %d for non-existent PCA %d"
" on QBB %d.\n",
irq, pcano, qbbno);
}
return;
}
pca = WILDFIRE_pca(qbbno, pcano);
enable0 = (unsigned long *) &pca->pca_int[0].enable; /* ??? */
*enable0 = cached_irq_mask[qbbno * WILDFIRE_PCA_PER_QBB + pcano];
mb();
*enable0;
}
static void __init
wildfire_init_irq_hw(void)
{
#if 0
register wildfire_pca * pca = WILDFIRE_pca(0, 0);
volatile unsigned long * enable0, * enable1, * enable2, *enable3;
volatile unsigned long * target0, * target1, * target2, *target3;
enable0 = (unsigned long *) &pca->pca_int[0].enable;
enable1 = (unsigned long *) &pca->pca_int[1].enable;
enable2 = (unsigned long *) &pca->pca_int[2].enable;
enable3 = (unsigned long *) &pca->pca_int[3].enable;
target0 = (unsigned long *) &pca->pca_int[0].target;
target1 = (unsigned long *) &pca->pca_int[1].target;
target2 = (unsigned long *) &pca->pca_int[2].target;
target3 = (unsigned long *) &pca->pca_int[3].target;
*enable0 = *enable1 = *enable2 = *enable3 = 0;
*target0 = (1UL<<8) | WILDFIRE_QBB(0);
*target1 = *target2 = *target3 = 0;
mb();
*enable0; *enable1; *enable2; *enable3;
*target0; *target1; *target2; *target3;
#else
int i;
doing_init_irq_hw = 1;
/* Need to update only once for every possible PCA. */
for (i = 0; i < WILDFIRE_NR_IRQS; i+=WILDFIRE_IRQ_PER_PCA)
wildfire_update_irq_hw(i);
doing_init_irq_hw = 0;
#endif
}
static void
wildfire_enable_irq(struct irq_data *d)
{
unsigned int irq = d->irq;
if (irq < 16)
i8259a_enable_irq(d);
spin_lock(&wildfire_irq_lock);
set_bit(irq, &cached_irq_mask);
wildfire_update_irq_hw(irq);
spin_unlock(&wildfire_irq_lock);
}
static void
wildfire_disable_irq(struct irq_data *d)
{
unsigned int irq = d->irq;
if (irq < 16)
i8259a_disable_irq(d);
spin_lock(&wildfire_irq_lock);
clear_bit(irq, &cached_irq_mask);
wildfire_update_irq_hw(irq);
spin_unlock(&wildfire_irq_lock);
}
static void
wildfire_mask_and_ack_irq(struct irq_data *d)
{
unsigned int irq = d->irq;
if (irq < 16)
i8259a_mask_and_ack_irq(d);
spin_lock(&wildfire_irq_lock);
clear_bit(irq, &cached_irq_mask);
wildfire_update_irq_hw(irq);
spin_unlock(&wildfire_irq_lock);
}
static struct irq_chip wildfire_irq_type = {
.name = "WILDFIRE",
.irq_unmask = wildfire_enable_irq,
.irq_mask = wildfire_disable_irq,
.irq_mask_ack = wildfire_mask_and_ack_irq,
};
static void __init
wildfire_init_irq_per_pca(int qbbno, int pcano)
{
int i, irq_bias;
irq_bias = qbbno * (WILDFIRE_PCA_PER_QBB * WILDFIRE_IRQ_PER_PCA)
+ pcano * WILDFIRE_IRQ_PER_PCA;
#if 0
unsigned long io_bias;
/* Only need the following for first PCI bus per PCA. */
io_bias = WILDFIRE_IO(qbbno, pcano<<1) - WILDFIRE_IO_BIAS;
outb(0, DMA1_RESET_REG + io_bias);
outb(0, DMA2_RESET_REG + io_bias);
outb(DMA_MODE_CASCADE, DMA2_MODE_REG + io_bias);
outb(0, DMA2_MASK_REG + io_bias);
#endif
#if 0
/* ??? Not sure how to do this, yet... */
init_i8259a_irqs(); /* ??? */
#endif
for (i = 0; i < 16; ++i) {
if (i == 2)
continue;
irq_set_chip_and_handler(i + irq_bias, &wildfire_irq_type,
handle_level_irq);
irq_set_status_flags(i + irq_bias, IRQ_LEVEL);
}
irq_set_chip_and_handler(36 + irq_bias, &wildfire_irq_type,
handle_level_irq);
irq_set_status_flags(36 + irq_bias, IRQ_LEVEL);
for (i = 40; i < 64; ++i) {
irq_set_chip_and_handler(i + irq_bias, &wildfire_irq_type,
handle_level_irq);
irq_set_status_flags(i + irq_bias, IRQ_LEVEL);
}
if (request_irq(32 + irq_bias, no_action, 0, "isa_enable", NULL))
pr_err("Failed to register isa_enable interrupt\n");
}
static void __init
wildfire_init_irq(void)
{
int qbbno, pcano;
#if 1
wildfire_init_irq_hw();
init_i8259a_irqs();
#endif
for (qbbno = 0; qbbno < WILDFIRE_MAX_QBB; qbbno++) {
if (WILDFIRE_QBB_EXISTS(qbbno)) {
for (pcano = 0; pcano < WILDFIRE_PCA_PER_QBB; pcano++) {
if (WILDFIRE_PCA_EXISTS(qbbno, pcano)) {
wildfire_init_irq_per_pca(qbbno, pcano);
}
}
}
}
}
static void
wildfire_device_interrupt(unsigned long vector)
{
int irq;
irq = (vector - 0x800) >> 4;
/*
* bits 10-8: source QBB ID
* bits 7-6: PCA
* bits 5-0: irq in PCA
*/
handle_irq(irq);
return;
}
/*
* PCI Fixup configuration.
*
* Summary per PCA (2 PCI or HIPPI buses):
*
* Bit Meaning
* 0-15 ISA
*
*32 ISA summary
*33 SMI
*34 NMI
*36 builtin QLogic SCSI (or slot 0 if no IO module)
*40 Interrupt Line A from slot 2 PCI0
*41 Interrupt Line B from slot 2 PCI0
*42 Interrupt Line C from slot 2 PCI0
*43 Interrupt Line D from slot 2 PCI0
*44 Interrupt Line A from slot 3 PCI0
*45 Interrupt Line B from slot 3 PCI0
*46 Interrupt Line C from slot 3 PCI0
*47 Interrupt Line D from slot 3 PCI0
*
*48 Interrupt Line A from slot 4 PCI1
*49 Interrupt Line B from slot 4 PCI1
*50 Interrupt Line C from slot 4 PCI1
*51 Interrupt Line D from slot 4 PCI1
*52 Interrupt Line A from slot 5 PCI1
*53 Interrupt Line B from slot 5 PCI1
*54 Interrupt Line C from slot 5 PCI1
*55 Interrupt Line D from slot 5 PCI1
*56 Interrupt Line A from slot 6 PCI1
*57 Interrupt Line B from slot 6 PCI1
*58 Interrupt Line C from slot 6 PCI1
*50 Interrupt Line D from slot 6 PCI1
*60 Interrupt Line A from slot 7 PCI1
*61 Interrupt Line B from slot 7 PCI1
*62 Interrupt Line C from slot 7 PCI1
*63 Interrupt Line D from slot 7 PCI1
*
*
* IdSel
* 0 Cypress Bridge I/O (ISA summary interrupt)
* 1 64 bit PCI 0 option slot 1 (SCSI QLogic builtin)
* 2 64 bit PCI 0 option slot 2
* 3 64 bit PCI 0 option slot 3
* 4 64 bit PCI 1 option slot 4
* 5 64 bit PCI 1 option slot 5
* 6 64 bit PCI 1 option slot 6
* 7 64 bit PCI 1 option slot 7
*/
static int
wildfire_map_irq(const struct pci_dev *dev, u8 slot, u8 pin)
{
static char irq_tab[8][5] = {
/*INT INTA INTB INTC INTD */
{ -1, -1, -1, -1, -1}, /* IdSel 0 ISA Bridge */
{ 36, 36, 36+1, 36+2, 36+3}, /* IdSel 1 SCSI builtin */
{ 40, 40, 40+1, 40+2, 40+3}, /* IdSel 2 PCI 0 slot 2 */
{ 44, 44, 44+1, 44+2, 44+3}, /* IdSel 3 PCI 0 slot 3 */
{ 48, 48, 48+1, 48+2, 48+3}, /* IdSel 4 PCI 1 slot 4 */
{ 52, 52, 52+1, 52+2, 52+3}, /* IdSel 5 PCI 1 slot 5 */
{ 56, 56, 56+1, 56+2, 56+3}, /* IdSel 6 PCI 1 slot 6 */
{ 60, 60, 60+1, 60+2, 60+3}, /* IdSel 7 PCI 1 slot 7 */
};
long min_idsel = 0, max_idsel = 7, irqs_per_slot = 5;
struct pci_controller *hose = dev->sysdata;
int irq = COMMON_TABLE_LOOKUP;
if (irq > 0) {
int qbbno = hose->index >> 3;
int pcano = (hose->index >> 1) & 3;
irq += (qbbno << 8) + (pcano << 6);
}
return irq;
}
/*
* The System Vectors
*/
struct alpha_machine_vector wildfire_mv __initmv = {
.vector_name = "WILDFIRE",
DO_EV6_MMU,
DO_DEFAULT_RTC,
DO_WILDFIRE_IO,
.machine_check = wildfire_machine_check,
.max_isa_dma_address = ALPHA_MAX_ISA_DMA_ADDRESS,
.min_io_address = DEFAULT_IO_BASE,
.min_mem_address = DEFAULT_MEM_BASE,
.nr_irqs = WILDFIRE_NR_IRQS,
.device_interrupt = wildfire_device_interrupt,
.init_arch = wildfire_init_arch,
.init_irq = wildfire_init_irq,
.init_rtc = common_init_rtc,
.init_pci = common_init_pci,
.kill_arch = wildfire_kill_arch,
.pci_map_irq = wildfire_map_irq,
.pci_swizzle = common_swizzle,
};
ALIAS_MV(wildfire)