Skip to content

Commit

Permalink
Merge rsync://rsync.kernel.org/pub/scm/linux/kernel/git/paulus/ppc64-2.6
Browse files Browse the repository at this point in the history
  • Loading branch information
Linus Torvalds committed Jun 23, 2005
2 parents fed2fc1 + d7152fe commit 24665cd
Show file tree
Hide file tree
Showing 44 changed files with 2,918 additions and 754 deletions.
7 changes: 7 additions & 0 deletions MAINTAINERS
Original file line number Diff line number Diff line change
Expand Up @@ -504,6 +504,13 @@ L: bonding-devel@lists.sourceforge.net
W: http://sourceforge.net/projects/bonding/
S: Supported

BROADBAND PROCESSOR ARCHITECTURE
P: Arnd Bergmann
M: arnd@arndb.de
L: linuxppc64-dev@ozlabs.org
W: http://linuxppc64.org
S: Supported

BTTV VIDEO4LINUX DRIVER
P: Gerd Knorr
M: kraxel@bytesex.org
Expand Down
21 changes: 20 additions & 1 deletion arch/ppc64/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,10 @@ config PPC_PSERIES
bool " IBM pSeries & new iSeries"
default y

config PPC_BPA
bool " Broadband Processor Architecture"
depends on PPC_MULTIPLATFORM

config PPC_PMAC
depends on PPC_MULTIPLATFORM
bool " Apple G5 based machines"
Expand Down Expand Up @@ -106,6 +110,21 @@ config PPC_OF
bool
default y

config XICS
depends on PPC_PSERIES
bool
default y

config MPIC
depends on PPC_PSERIES || PPC_PMAC || PPC_MAPLE
bool
default y

config BPA_IIC
depends on PPC_BPA
bool
default y

# VMX is pSeries only for now until somebody writes the iSeries
# exception vectors for it
config ALTIVEC
Expand Down Expand Up @@ -292,7 +311,7 @@ config MSCHUNKS

config PPC_RTAS
bool
depends on PPC_PSERIES
depends on PPC_PSERIES || PPC_BPA
default y

config RTAS_PROC
Expand Down
2 changes: 2 additions & 0 deletions arch/ppc64/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -90,12 +90,14 @@ boot := arch/ppc64/boot
boottarget-$(CONFIG_PPC_PSERIES) := zImage zImage.initrd
boottarget-$(CONFIG_PPC_MAPLE) := zImage zImage.initrd
boottarget-$(CONFIG_PPC_ISERIES) := vmlinux.sminitrd vmlinux.initrd vmlinux.sm
boottarget-$(CONFIG_PPC_BPA) := zImage zImage.initrd
$(boottarget-y): vmlinux
$(Q)$(MAKE) $(build)=$(boot) $(boot)/$@

bootimage-$(CONFIG_PPC_PSERIES) := $(boot)/zImage
bootimage-$(CONFIG_PPC_PMAC) := vmlinux
bootimage-$(CONFIG_PPC_MAPLE) := $(boot)/zImage
bootimage-$(CONFIG_PPC_BPA) := zImage
bootimage-$(CONFIG_PPC_ISERIES) := vmlinux
BOOTIMAGE := $(bootimage-y)
install: vmlinux
Expand Down
11 changes: 9 additions & 2 deletions arch/ppc64/kernel/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -27,17 +27,21 @@ obj-$(CONFIG_PPC_ISERIES) += HvCall.o HvLpConfig.o LparData.o \
mf.o HvLpEvent.o iSeries_proc.o iSeries_htab.o \
iSeries_iommu.o

obj-$(CONFIG_PPC_MULTIPLATFORM) += nvram.o i8259.o prom_init.o prom.o mpic.o
obj-$(CONFIG_PPC_MULTIPLATFORM) += nvram.o i8259.o prom_init.o prom.o

obj-$(CONFIG_PPC_PSERIES) += pSeries_pci.o pSeries_lpar.o pSeries_hvCall.o \
pSeries_nvram.o rtasd.o ras.o pSeries_reconfig.o \
xics.o rtas.o pSeries_setup.o pSeries_iommu.o
pSeries_setup.o pSeries_iommu.o

obj-$(CONFIG_PPC_BPA) += bpa_setup.o bpa_iommu.o bpa_nvram.o \
bpa_iic.o spider-pic.o

obj-$(CONFIG_EEH) += eeh.o
obj-$(CONFIG_PROC_FS) += proc_ppc64.o
obj-$(CONFIG_RTAS_FLASH) += rtas_flash.o
obj-$(CONFIG_SMP) += smp.o
obj-$(CONFIG_MODULES) += module.o ppc_ksyms.o
obj-$(CONFIG_PPC_RTAS) += rtas.o rtas_pci.o
obj-$(CONFIG_RTAS_PROC) += rtas-proc.o
obj-$(CONFIG_SCANLOG) += scanlog.o
obj-$(CONFIG_VIOPATH) += viopath.o
Expand All @@ -46,6 +50,8 @@ obj-$(CONFIG_HVC_CONSOLE) += hvconsole.o
obj-$(CONFIG_BOOTX_TEXT) += btext.o
obj-$(CONFIG_HVCS) += hvcserver.o
obj-$(CONFIG_IBMVIO) += vio.o
obj-$(CONFIG_XICS) += xics.o
obj-$(CONFIG_MPIC) += mpic.o

obj-$(CONFIG_PPC_PMAC) += pmac_setup.o pmac_feature.o pmac_pci.o \
pmac_time.o pmac_nvram.o pmac_low_i2c.o
Expand All @@ -58,6 +64,7 @@ ifdef CONFIG_SMP
obj-$(CONFIG_PPC_PMAC) += pmac_smp.o smp-tbsync.o
obj-$(CONFIG_PPC_ISERIES) += iSeries_smp.o
obj-$(CONFIG_PPC_PSERIES) += pSeries_smp.o
obj-$(CONFIG_PPC_BPA) += pSeries_smp.o
obj-$(CONFIG_PPC_MAPLE) += smp-tbsync.o
endif

Expand Down
270 changes: 270 additions & 0 deletions arch/ppc64/kernel/bpa_iic.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,270 @@
/*
* BPA Internal Interrupt Controller
*
* (C) Copyright IBM Deutschland Entwicklung GmbH 2005
*
* Author: Arnd Bergmann <arndb@de.ibm.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, or (at your option)
* any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/

#include <linux/config.h>
#include <linux/interrupt.h>
#include <linux/irq.h>
#include <linux/percpu.h>
#include <linux/types.h>

#include <asm/io.h>
#include <asm/pgtable.h>
#include <asm/prom.h>
#include <asm/ptrace.h>

#include "bpa_iic.h"

struct iic_pending_bits {
u32 data;
u8 flags;
u8 class;
u8 source;
u8 prio;
};

enum iic_pending_flags {
IIC_VALID = 0x80,
IIC_IPI = 0x40,
};

struct iic_regs {
struct iic_pending_bits pending;
struct iic_pending_bits pending_destr;
u64 generate;
u64 prio;
};

struct iic {
struct iic_regs __iomem *regs;
};

static DEFINE_PER_CPU(struct iic, iic);

void iic_local_enable(void)
{
out_be64(&__get_cpu_var(iic).regs->prio, 0xff);
}

void iic_local_disable(void)
{
out_be64(&__get_cpu_var(iic).regs->prio, 0x0);
}

static unsigned int iic_startup(unsigned int irq)
{
return 0;
}

static void iic_enable(unsigned int irq)
{
iic_local_enable();
}

static void iic_disable(unsigned int irq)
{
}

static void iic_end(unsigned int irq)
{
iic_local_enable();
}

static struct hw_interrupt_type iic_pic = {
.typename = " BPA-IIC ",
.startup = iic_startup,
.enable = iic_enable,
.disable = iic_disable,
.end = iic_end,
};

static int iic_external_get_irq(struct iic_pending_bits pending)
{
int irq;
unsigned char node, unit;

node = pending.source >> 4;
unit = pending.source & 0xf;
irq = -1;

/*
* This mapping is specific to the Broadband
* Engine. We might need to get the numbers
* from the device tree to support future CPUs.
*/
switch (unit) {
case 0x00:
case 0x0b:
/*
* One of these units can be connected
* to an external interrupt controller.
*/
if (pending.prio > 0x3f ||
pending.class != 2)
break;
irq = IIC_EXT_OFFSET
+ spider_get_irq(pending.prio + node * IIC_NODE_STRIDE)
+ node * IIC_NODE_STRIDE;
break;
case 0x01 ... 0x04:
case 0x07 ... 0x0a:
/*
* These units are connected to the SPEs
*/
if (pending.class > 2)
break;
irq = IIC_SPE_OFFSET
+ pending.class * IIC_CLASS_STRIDE
+ node * IIC_NODE_STRIDE
+ unit;
break;
}
if (irq == -1)
printk(KERN_WARNING "Unexpected interrupt class %02x, "
"source %02x, prio %02x, cpu %02x\n", pending.class,
pending.source, pending.prio, smp_processor_id());
return irq;
}

/* Get an IRQ number from the pending state register of the IIC */
int iic_get_irq(struct pt_regs *regs)
{
struct iic *iic;
int irq;
struct iic_pending_bits pending;

iic = &__get_cpu_var(iic);
*(unsigned long *) &pending =
in_be64((unsigned long __iomem *) &iic->regs->pending_destr);

irq = -1;
if (pending.flags & IIC_VALID) {
if (pending.flags & IIC_IPI) {
irq = IIC_IPI_OFFSET + (pending.prio >> 4);
/*
if (irq > 0x80)
printk(KERN_WARNING "Unexpected IPI prio %02x"
"on CPU %02x\n", pending.prio,
smp_processor_id());
*/
} else {
irq = iic_external_get_irq(pending);
}
}
return irq;
}

static struct iic_regs __iomem *find_iic(int cpu)
{
struct device_node *np;
int nodeid = cpu / 2;
unsigned long regs;
struct iic_regs __iomem *iic_regs;

for (np = of_find_node_by_type(NULL, "cpu");
np;
np = of_find_node_by_type(np, "cpu")) {
if (nodeid == *(int *)get_property(np, "node-id", NULL))
break;
}

if (!np) {
printk(KERN_WARNING "IIC: CPU %d not found\n", cpu);
iic_regs = NULL;
} else {
regs = *(long *)get_property(np, "iic", NULL);

/* hack until we have decided on the devtree info */
regs += 0x400;
if (cpu & 1)
regs += 0x20;

printk(KERN_DEBUG "IIC for CPU %d at %lx\n", cpu, regs);
iic_regs = __ioremap(regs, sizeof(struct iic_regs),
_PAGE_NO_CACHE);
}
return iic_regs;
}

#ifdef CONFIG_SMP
void iic_setup_cpu(void)
{
out_be64(&__get_cpu_var(iic).regs->prio, 0xff);
}

void iic_cause_IPI(int cpu, int mesg)
{
out_be64(&per_cpu(iic, cpu).regs->generate, mesg);
}

static irqreturn_t iic_ipi_action(int irq, void *dev_id, struct pt_regs *regs)
{

smp_message_recv(irq - IIC_IPI_OFFSET, regs);
return IRQ_HANDLED;
}

static void iic_request_ipi(int irq, const char *name)
{
/* IPIs are marked SA_INTERRUPT as they must run with irqs
* disabled */
get_irq_desc(irq)->handler = &iic_pic;
get_irq_desc(irq)->status |= IRQ_PER_CPU;
request_irq(irq, iic_ipi_action, SA_INTERRUPT, name, NULL);
}

void iic_request_IPIs(void)
{
iic_request_ipi(IIC_IPI_OFFSET + PPC_MSG_CALL_FUNCTION, "IPI-call");
iic_request_ipi(IIC_IPI_OFFSET + PPC_MSG_RESCHEDULE, "IPI-resched");
#ifdef CONFIG_DEBUGGER
iic_request_ipi(IIC_IPI_OFFSET + PPC_MSG_DEBUGGER_BREAK, "IPI-debug");
#endif /* CONFIG_DEBUGGER */
}
#endif /* CONFIG_SMP */

static void iic_setup_spe_handlers(void)
{
int be, isrc;

/* Assume two threads per BE are present */
for (be=0; be < num_present_cpus() / 2; be++) {
for (isrc = 0; isrc < IIC_CLASS_STRIDE * 3; isrc++) {
int irq = IIC_NODE_STRIDE * be + IIC_SPE_OFFSET + isrc;
get_irq_desc(irq)->handler = &iic_pic;
}
}
}

void iic_init_IRQ(void)
{
int cpu, irq_offset;
struct iic *iic;

irq_offset = 0;
for_each_cpu(cpu) {
iic = &per_cpu(iic, cpu);
iic->regs = find_iic(cpu);
if (iic->regs)
out_be64(&iic->regs->prio, 0xff);
}
iic_setup_spe_handlers();
}
Loading

0 comments on commit 24665cd

Please sign in to comment.