提交 952ecef7 编写于 作者: P Paul Mackerras

Merge Stephen Rothwell's patches

obj-$(CONFIG_PPC_PMAC) += powermac/
obj-$(CONFIG_4xx) += 4xx/
obj-$(CONFIG_83xx) += 83xx/
obj-$(CONFIG_85xx) += 85xx/
ifeq ($(CONFIG_PPC32),y)
obj-$(CONFIG_PPC_PMAC) += powermac/
endif
obj-$(CONFIG_4xx) += 4xx/
obj-$(CONFIG_83xx) += 83xx/
obj-$(CONFIG_85xx) += 85xx/
obj-$(CONFIG_PPC_ISERIES) += iseries/
obj-y += hvlog.o hvlpconfig.o lpardata.o setup.o mf.o lpevents.o \
hvcall.o proc.o htab.o iommu.o misc.o
obj-$(CONFIG_PCI) += pci.o irq.o vpdinfo.o
obj-$(CONFIG_IBMVIO) += vio.o
obj-$(CONFIG_SMP) += smp.o
obj-$(CONFIG_VIOPATH) += viopath.o
obj-$(CONFIG_MODULES) += ksyms.o
/*
* iSeries hashtable management.
* Derived from pSeries_htab.c
* Derived from pSeries_htab.c
*
* SMP scalability work:
* Copyright (C) 2001 Anton Blanchard <anton@au.ibm.com>, IBM
*
*
* 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
......@@ -18,7 +18,8 @@
#include <asm/abs_addr.h>
#include <linux/spinlock.h>
static spinlock_t iSeries_hlocks[64] __cacheline_aligned_in_smp = { [0 ... 63] = SPIN_LOCK_UNLOCKED};
static spinlock_t iSeries_hlocks[64] __cacheline_aligned_in_smp =
{ [0 ... 63] = SPIN_LOCK_UNLOCKED};
/*
* Very primitive algorithm for picking up a lock
......@@ -126,7 +127,7 @@ static long iSeries_hpte_remove(unsigned long hpte_group)
hpte_v = iSeries_hpte_getword0(hpte_group + slot_offset);
if (! (hpte_v & HPTE_V_BOLTED)) {
HvCallHpt_invalidateSetSwBitsGet(hpte_group +
HvCallHpt_invalidateSetSwBitsGet(hpte_group +
slot_offset, 0, 0);
iSeries_hunlock(hpte_group);
return i;
......@@ -143,9 +144,9 @@ static long iSeries_hpte_remove(unsigned long hpte_group)
/*
* The HyperVisor expects the "flags" argument in this form:
* bits 0..59 : reserved
* bit 60 : N
* bits 61..63 : PP2,PP1,PP0
* bits 0..59 : reserved
* bit 60 : N
* bits 61..63 : PP2,PP1,PP0
*/
static long iSeries_hpte_updatepp(unsigned long slot, unsigned long newpp,
unsigned long va, int large, int local)
......@@ -171,7 +172,7 @@ static long iSeries_hpte_updatepp(unsigned long slot, unsigned long newpp,
}
/*
* Functions used to find the PTE for a particular virtual address.
* Functions used to find the PTE for a particular virtual address.
* Only used during boot when bolting pages.
*
* Input : vpn : virtual page number
......@@ -189,7 +190,7 @@ static long iSeries_hpte_find(unsigned long vpn)
* 0x00000000xxxxxxxx : Entry found in primary group, slot x
* 0x80000000xxxxxxxx : Entry found in secondary group, slot x
*/
slot = HvCallHpt_findValid(&hpte, vpn);
slot = HvCallHpt_findValid(&hpte, vpn);
if (hpte.v & HPTE_V_VALID) {
if (slot < 0) {
slot &= 0x7fffffffffffffff;
......@@ -216,7 +217,7 @@ static void iSeries_hpte_updateboltedpp(unsigned long newpp, unsigned long ea)
vsid = get_kernel_vsid(ea);
va = (vsid << 28) | (ea & 0x0fffffff);
vpn = va >> PAGE_SHIFT;
slot = iSeries_hpte_find(vpn);
slot = iSeries_hpte_find(vpn);
if (slot == -1)
panic("updateboltedpp: Could not find page to bolt\n");
HvCallHpt_setPp(slot, newpp);
......@@ -234,7 +235,7 @@ static void iSeries_hpte_invalidate(unsigned long slot, unsigned long va,
iSeries_hlock(slot);
hpte_v = iSeries_hpte_getword0(slot);
if ((HPTE_V_AVPN_VAL(hpte_v) == avpn) && (hpte_v & HPTE_V_VALID))
HvCallHpt_invalidateSetSwBitsGet(slot, 0, 0);
......@@ -249,7 +250,7 @@ void hpte_init_iSeries(void)
ppc_md.hpte_updatepp = iSeries_hpte_updatepp;
ppc_md.hpte_updateboltedpp = iSeries_hpte_updateboltedpp;
ppc_md.hpte_insert = iSeries_hpte_insert;
ppc_md.hpte_remove = iSeries_hpte_remove;
ppc_md.hpte_remove = iSeries_hpte_remove;
htab_finish_init();
}
/*
* arch/ppc64/kernel/hvCall.S
*
*
* This file contains the code to perform calls to the
* iSeries LPAR hypervisor
*
......@@ -16,12 +13,12 @@
.text
/*
/*
* Hypervisor call
*
*
* Invoke the iSeries hypervisor via the System Call instruction
* Parameters are passed to this routine in registers r3 - r10
*
*
* r3 contains the HV function to be called
* r4-r10 contain the operands to the hypervisor function
*
......@@ -41,11 +38,11 @@ _GLOBAL(HvCall7)
mfcr r0
std r0,-8(r1)
stdu r1,-(STACK_FRAME_OVERHEAD+16)(r1)
/* r0 = 0xffffffffffffffff indicates a hypervisor call */
li r0,-1
/* Invoke the hypervisor */
sc
......@@ -55,7 +52,7 @@ _GLOBAL(HvCall7)
mtcrf 0xff,r0
/* return to caller, return value in r3 */
blr
_GLOBAL(HvCall0Ret16)
......@@ -92,7 +89,5 @@ _GLOBAL(HvCall7Ret16)
ld r0,-8(r1)
mtcrf 0xff,r0
ld r31,-16(r1)
blr
blr
/*
* HvCall.c
* Copyright (C) 2001 Mike Corrigan IBM Corporation
*
* This program is free software; you can redistribute it and/or modify
......
/*
* HvLpConfig.c
* Copyright (C) 2001 Kyle A. Lucke, IBM Corporation
*
* This program is free software; you can redistribute it and/or modify
......
/*
* arch/ppc64/kernel/iSeries_iommu.c
*
* Copyright (C) 2001 Mike Corrigan & Dave Engebretsen, IBM Corporation
*
* Rewrite, cleanup:
......@@ -91,15 +89,17 @@ static void tce_free_iSeries(struct iommu_table *tbl, long index, long npages)
*/
static struct iommu_table *iommu_table_find(struct iommu_table * tbl)
{
struct iSeries_Device_Node *dp;
struct device_node *dp;
list_for_each_entry(dp, &iSeries_Global_Device_List, Device_List) {
if ((dp->iommu_table != NULL) &&
(dp->iommu_table->it_type == TCE_PCI) &&
(dp->iommu_table->it_offset == tbl->it_offset) &&
(dp->iommu_table->it_index == tbl->it_index) &&
(dp->iommu_table->it_size == tbl->it_size))
return dp->iommu_table;
struct iommu_table *it = PCI_DN(dp)->iommu_table;
if ((it != NULL) &&
(it->it_type == TCE_PCI) &&
(it->it_offset == tbl->it_offset) &&
(it->it_index == tbl->it_index) &&
(it->it_size == tbl->it_size))
return it;
}
return NULL;
}
......@@ -113,7 +113,7 @@ static struct iommu_table *iommu_table_find(struct iommu_table * tbl)
* 2. TCE table per Bus.
* 3. TCE Table per IOA.
*/
static void iommu_table_getparms(struct iSeries_Device_Node* dn,
static void iommu_table_getparms(struct device_node *dn,
struct iommu_table* tbl)
{
struct iommu_table_cb *parms;
......@@ -125,7 +125,7 @@ static void iommu_table_getparms(struct iSeries_Device_Node* dn,
memset(parms, 0, sizeof(*parms));
parms->itc_busno = ISERIES_BUS(dn);
parms->itc_slotno = dn->LogicalSlot;
parms->itc_slotno = PCI_DN(dn)->LogicalSlot;
parms->itc_virtbus = 0;
HvCallXm_getTceTableParms(ISERIES_HV_ADDR(parms));
......@@ -145,18 +145,19 @@ static void iommu_table_getparms(struct iSeries_Device_Node* dn,
}
void iommu_devnode_init_iSeries(struct iSeries_Device_Node *dn)
void iommu_devnode_init_iSeries(struct device_node *dn)
{
struct iommu_table *tbl;
struct pci_dn *pdn = PCI_DN(dn);
tbl = kmalloc(sizeof(struct iommu_table), GFP_KERNEL);
iommu_table_getparms(dn, tbl);
/* Look for existing tce table */
dn->iommu_table = iommu_table_find(tbl);
if (dn->iommu_table == NULL)
dn->iommu_table = iommu_init_table(tbl);
pdn->iommu_table = iommu_table_find(tbl);
if (pdn->iommu_table == NULL)
pdn->iommu_table = iommu_init_table(tbl);
else
kfree(tbl);
}
......
/*
* (C) 2001-2005 PPC 64 Team, IBM Corp
*
* 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/module.h>
#include <asm/hw_irq.h>
#include <asm/iSeries/HvCallSc.h>
EXPORT_SYMBOL(HvCall0);
EXPORT_SYMBOL(HvCall1);
EXPORT_SYMBOL(HvCall2);
EXPORT_SYMBOL(HvCall3);
EXPORT_SYMBOL(HvCall4);
EXPORT_SYMBOL(HvCall5);
EXPORT_SYMBOL(HvCall6);
EXPORT_SYMBOL(HvCall7);
#ifdef CONFIG_SMP
EXPORT_SYMBOL(local_get_flags);
EXPORT_SYMBOL(local_irq_disable);
EXPORT_SYMBOL(local_irq_restore);
#endif
/*
/*
* Copyright 2001 Mike Corrigan, IBM Corp
*
* This program is free software; you can redistribute it and/or
......@@ -29,8 +29,8 @@
#include <asm/iSeries/ItSpCommArea.h>
/* The HvReleaseData is the root of the information shared between
* the hypervisor and Linux.
/* The HvReleaseData is the root of the information shared between
* the hypervisor and Linux.
*/
struct HvReleaseData hvReleaseData = {
.xDesc = 0xc8a5d9c4, /* "HvRD" ebcdic */
......@@ -79,7 +79,7 @@ extern void trap_0e_iSeries(void);
extern void performance_monitor_iSeries(void);
extern void data_access_slb_iSeries(void);
extern void instruction_access_slb_iSeries(void);
struct ItLpNaca itLpNaca = {
.xDesc = 0xd397d581, /* "LpNa" ebcdic */
.xSize = 0x0400, /* size of ItLpNaca */
......@@ -106,7 +106,7 @@ struct ItLpNaca itLpNaca = {
.xLoadAreaChunks = 0, /* chunks for load area */
.xPaseSysCallCRMask = 0, /* PASE mask */
.xSlicSegmentTablePtr = 0, /* seg table */
.xOldLpQueue = { 0 }, /* Old LP Queue */
.xOldLpQueue = { 0 }, /* Old LP Queue */
.xInterruptHdlr = {
(u64)system_reset_iSeries, /* 0x100 System Reset */
(u64)machine_check_iSeries, /* 0x200 Machine Check */
......@@ -134,7 +134,7 @@ struct ItLpNaca itLpNaca = {
EXPORT_SYMBOL(itLpNaca);
/* May be filled in by the hypervisor so cannot end up in the BSS */
struct ItIplParmsReal xItIplParmsReal __attribute__((__section__(".data")));
struct ItIplParmsReal xItIplParmsReal __attribute__((__section__(".data")));
/* May be filled in by the hypervisor so cannot end up in the BSS */
struct ItExtVpdPanel xItExtVpdPanel __attribute__((__section__(".data")));
......@@ -151,7 +151,7 @@ struct IoHriProcessorVpd xIoHriProcessorVpd[maxPhysicalProcessors] = {
.xPVR = 0x3600
}
};
/* Space for Main Store Vpd 27,200 bytes */
/* May be filled in by the hypervisor so cannot end up in the BSS */
u64 xMsVpd[3400] __attribute__((__section__(".data")));
......@@ -197,7 +197,7 @@ struct ItVpdAreas itVpdAreas = {
26992, /* 7 length of MS VPD */
0, /* 8 */
sizeof(struct ItLpNaca),/* 9 length of LP Naca */
0, /* 10 */
0, /* 10 */
256, /* 11 length of Recovery Log Buf */
sizeof(struct SpCommArea), /* 12 length of SP Comm Area */
0,0,0, /* 13 - 15 */
......@@ -207,7 +207,7 @@ struct ItVpdAreas itVpdAreas = {
0,0 /* 24 - 25 */
},
.xSlicVpdAdrs = { /* VPD addresses */
0,0,0, /* 0 - 2 */
0,0,0, /* 0 - 2 */
&xItExtVpdPanel, /* 3 Extended VPD */
&paca[0], /* 4 first Paca */
0, /* 5 */
......
/*
* ItLpQueue.c
* Copyright (C) 2001 Mike Corrigan IBM Corporation
*
* This program is free software; you can redistribute it and/or modify
......@@ -19,6 +18,7 @@
#include <asm/iSeries/ItLpQueue.h>
#include <asm/iSeries/HvLpEvent.h>
#include <asm/iSeries/HvCallEvent.h>
#include <asm/iSeries/ItLpNaca.h>
/*
* The LpQueue is used to pass event data from the hypervisor to
......@@ -43,7 +43,8 @@ static char *event_types[HvLpEvent_Type_NumTypes] = {
};
/* Array of LpEvent handler functions */
extern LpEventHandler lpEventHandler[HvLpEvent_Type_NumTypes];
static LpEventHandler lpEventHandler[HvLpEvent_Type_NumTypes];
static unsigned lpEventHandlerPaths[HvLpEvent_Type_NumTypes];
static struct HvLpEvent * get_next_hvlpevent(void)
{
......@@ -199,6 +200,70 @@ void setup_hvlpevent_queue(void)
hvlpevent_queue.xIndex = 0;
}
/* Register a handler for an LpEvent type */
int HvLpEvent_registerHandler(HvLpEvent_Type eventType, LpEventHandler handler)
{
if (eventType < HvLpEvent_Type_NumTypes) {
lpEventHandler[eventType] = handler;
return 0;
}
return 1;
}
EXPORT_SYMBOL(HvLpEvent_registerHandler);
int HvLpEvent_unregisterHandler(HvLpEvent_Type eventType)
{
might_sleep();
if (eventType < HvLpEvent_Type_NumTypes) {
if (!lpEventHandlerPaths[eventType]) {
lpEventHandler[eventType] = NULL;
/*
* We now sleep until all other CPUs have scheduled.
* This ensures that the deletion is seen by all
* other CPUs, and that the deleted handler isn't
* still running on another CPU when we return.
*/
synchronize_rcu();
return 0;
}
}
return 1;
}
EXPORT_SYMBOL(HvLpEvent_unregisterHandler);
/*
* lpIndex is the partition index of the target partition.
* needed only for VirtualIo, VirtualLan and SessionMgr. Zero
* indicates to use our partition index - for the other types.
*/
int HvLpEvent_openPath(HvLpEvent_Type eventType, HvLpIndex lpIndex)
{
if ((eventType < HvLpEvent_Type_NumTypes) &&
lpEventHandler[eventType]) {
if (lpIndex == 0)
lpIndex = itLpNaca.xLpIndex;
HvCallEvent_openLpEventPath(lpIndex, eventType);
++lpEventHandlerPaths[eventType];
return 0;
}
return 1;
}
int HvLpEvent_closePath(HvLpEvent_Type eventType, HvLpIndex lpIndex)
{
if ((eventType < HvLpEvent_Type_NumTypes) &&
lpEventHandler[eventType] &&
lpEventHandlerPaths[eventType]) {
if (lpIndex == 0)
lpIndex = itLpNaca.xLpIndex;
HvCallEvent_closeLpEventPath(lpIndex, eventType);
--lpEventHandlerPaths[eventType];
return 0;
}
return 1;
}
static int proc_lpevents_show(struct seq_file *m, void *v)
{
int cpu, i;
......
/*
* mf.c
* Copyright (C) 2001 Troy D. Armstrong IBM Corporation
* Copyright (C) 2004-2005 Stephen Rothwell IBM Corporation
*
* This modules exists as an interface between a Linux secondary partition
* running on an iSeries and the primary partition's Virtual Service
* Processor (VSP) object. The VSP has final authority over powering on/off
* all partitions in the iSeries. It also provides miscellaneous low-level
* machine facility type operations.
*
*
* 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.
*
* 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
* Copyright (C) 2001 Troy D. Armstrong IBM Corporation
* Copyright (C) 2004-2005 Stephen Rothwell IBM Corporation
*
* This modules exists as an interface between a Linux secondary partition
* running on an iSeries and the primary partition's Virtual Service
* Processor (VSP) object. The VSP has final authority over powering on/off
* all partitions in the iSeries. It also provides miscellaneous low-level
* machine facility type operations.
*
*
* 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.
*
* 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#include <linux/types.h>
#include <linux/errno.h>
......@@ -42,6 +41,10 @@
#include <asm/iSeries/HvLpConfig.h>
#include <asm/iSeries/ItLpQueue.h>
#include "setup.h"
extern int piranha_simulator;
/*
* This is the structure layout for the Machine Facilites LPAR event
* flows.
......@@ -1279,3 +1282,35 @@ static int __init mf_proc_init(void)
__initcall(mf_proc_init);
#endif /* CONFIG_PROC_FS */
/*
* Get the RTC from the virtual service processor
* This requires flowing LpEvents to the primary partition
*/
void iSeries_get_rtc_time(struct rtc_time *rtc_tm)
{
if (piranha_simulator)
return;
mf_get_rtc(rtc_tm);
rtc_tm->tm_mon--;
}
/*
* Set the RTC in the virtual service processor
* This requires flowing LpEvents to the primary partition
*/
int iSeries_set_rtc_time(struct rtc_time *tm)
{
mf_set_rtc(tm);
return 0;
}
void iSeries_get_boot_time(struct rtc_time *tm)
{
if (piranha_simulator)
return;
mf_get_boot_rtc(tm);
tm->tm_mon -= 1;
}
/*
* This file contains miscellaneous low-level functions.
* Copyright (C) 1995-2005 IBM Corp
*
* Largely rewritten by Cort Dougan (cort@cs.nmt.edu)
* and Paul Mackerras.
* Adapted for iSeries by Mike Corrigan (mikejc@us.ibm.com)
* PPC64 updates by Dave Engebretsen (engebret@us.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 of the License, or (at your option) any later version.
*/
#include <asm/processor.h>
#include <asm/asm-offsets.h>
.text
/* unsigned long local_save_flags(void) */
_GLOBAL(local_get_flags)
lbz r3,PACAPROCENABLED(r13)
blr
/* unsigned long local_irq_disable(void) */
_GLOBAL(local_irq_disable)
lbz r3,PACAPROCENABLED(r13)
li r4,0
stb r4,PACAPROCENABLED(r13)
blr /* Done */
/* void local_irq_restore(unsigned long flags) */
_GLOBAL(local_irq_restore)
lbz r5,PACAPROCENABLED(r13)
/* Check if things are setup the way we want _already_. */
cmpw 0,r3,r5
beqlr
/* are we enabling interrupts? */
cmpdi 0,r3,0
stb r3,PACAPROCENABLED(r13)
beqlr
/* Check pending interrupts */
/* A decrementer, IPI or PMC interrupt may have occurred
* while we were in the hypervisor (which enables) */
ld r4,PACALPPACA+LPPACAANYINT(r13)
cmpdi r4,0
beqlr
/*
* Handle pending interrupts in interrupt context
*/
li r0,0x5555
sc
blr
/*
* iSeries_pci.c
*
* Copyright (C) 2001 Allan Trautman, IBM Corporation
*
* iSeries specific routines for PCI.
*
*
* Based on code from pci.c and iSeries_pci.c 32bit
*
* 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.
*
*
* 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#include <linux/kernel.h>
#include <linux/list.h>
#include <linux/list.h>
#include <linux/string.h>
#include <linux/init.h>
#include <linux/module.h>
......@@ -43,14 +41,14 @@
#include <asm/iSeries/iSeries_pci.h>
#include <asm/iSeries/mf.h>
#include "pci.h"
#include <asm/ppc-pci.h>
extern unsigned long io_page_mask;
/*
* Forward declares of prototypes.
* Forward declares of prototypes.
*/
static struct iSeries_Device_Node *find_Device_Node(int bus, int devfn);
static struct device_node *find_Device_Node(int bus, int devfn);
static void scan_PHB_slots(struct pci_controller *Phb);
static void scan_EADS_bridge(HvBusNumber Bus, HvSubBusNumber SubBus, int IdSel);
static int scan_bridge_slot(HvBusNumber Bus, struct HvCallPci_BridgeInfo *Info);
......@@ -68,7 +66,7 @@ static long Pci_Cfg_Write_Count;
#endif
static long Pci_Error_Count;
static int Pci_Retry_Max = 3; /* Only retry 3 times */
static int Pci_Retry_Max = 3; /* Only retry 3 times */
static int Pci_Error_Flag = 1; /* Set Retry Error on. */
static struct pci_ops iSeries_pci_ops;
......@@ -87,7 +85,7 @@ static long current_iomm_table_entry;
/*
* Lookup Tables.
*/
static struct iSeries_Device_Node **iomm_table;
static struct device_node **iomm_table;
static u8 *iobar_table;
/*
......@@ -179,7 +177,7 @@ static void allocate_device_bars(struct pci_dev *dev)
for (bar_num = 0; bar_num <= PCI_ROM_RESOURCE; ++bar_num) {
bar_res = &dev->resource[bar_num];
iomm_table_allocate_entry(dev, bar_num);
}
}
}
/*
......@@ -201,29 +199,35 @@ static void pci_Log_Error(char *Error_Text, int Bus, int SubBus,
/*
* build_device_node(u16 Bus, int SubBus, u8 DevFn)
*/
static struct iSeries_Device_Node *build_device_node(HvBusNumber Bus,
static struct device_node *build_device_node(HvBusNumber Bus,
HvSubBusNumber SubBus, int AgentId, int Function)
{
struct iSeries_Device_Node *node;
struct device_node *node;
struct pci_dn *pdn;
PPCDBG(PPCDBG_BUSWALK,
"-build_device_node 0x%02X.%02X.%02X Function: %02X\n",
Bus, SubBus, AgentId, Function);
node = kmalloc(sizeof(struct iSeries_Device_Node), GFP_KERNEL);
node = kmalloc(sizeof(struct device_node), GFP_KERNEL);
if (node == NULL)
return NULL;
memset(node, 0, sizeof(struct iSeries_Device_Node));
memset(node, 0, sizeof(struct device_node));
pdn = kzalloc(sizeof(*pdn), GFP_KERNEL);
if (pdn == NULL) {
kfree(node);
return NULL;
}
node->data = pdn;
list_add_tail(&node->Device_List, &iSeries_Global_Device_List);
#if 0
node->DsaAddr = ((u64)Bus << 48) + ((u64)SubBus << 40) + ((u64)0x10 << 32);
pdn->DsaAddr = ((u64)Bus << 48) + ((u64)SubBus << 40) + ((u64)0x10 << 32);
#endif
node->DsaAddr.DsaAddr = 0;
node->DsaAddr.Dsa.busNumber = Bus;
node->DsaAddr.Dsa.subBusNumber = SubBus;
node->DsaAddr.Dsa.deviceId = 0x10;
node->DevFn = PCI_DEVFN(ISERIES_ENCODE_DEVICE(AgentId), Function);
pdn->DsaAddr.DsaAddr = 0;
pdn->DsaAddr.Dsa.busNumber = Bus;
pdn->DsaAddr.Dsa.subBusNumber = SubBus;
pdn->DsaAddr.Dsa.deviceId = 0x10;
pdn->devfn = PCI_DEVFN(ISERIES_ENCODE_DEVICE(AgentId), Function);
return node;
}
......@@ -278,28 +282,28 @@ unsigned long __init find_and_init_phbs(void)
/*
* iSeries_pcibios_init
*
*
* Chance to initialize and structures or variable before PCI Bus walk.
*/
void iSeries_pcibios_init(void)
{
PPCDBG(PPCDBG_BUSWALK, "iSeries_pcibios_init Entry.\n");
PPCDBG(PPCDBG_BUSWALK, "iSeries_pcibios_init Entry.\n");
iomm_table_initialize();
find_and_init_phbs();
io_page_mask = -1;
PPCDBG(PPCDBG_BUSWALK, "iSeries_pcibios_init Exit.\n");
PPCDBG(PPCDBG_BUSWALK, "iSeries_pcibios_init Exit.\n");
}
/*
* iSeries_pci_final_fixup(void)
* iSeries_pci_final_fixup(void)
*/
void __init iSeries_pci_final_fixup(void)
{
struct pci_dev *pdev = NULL;
struct iSeries_Device_Node *node;
int DeviceCount = 0;
struct device_node *node;
int DeviceCount = 0;
PPCDBG(PPCDBG_BUSWALK, "iSeries_pcibios_fixup Entry.\n");
PPCDBG(PPCDBG_BUSWALK, "iSeries_pcibios_fixup Entry.\n");
/* Fix up at the device node and pci_dev relationship */
mf_display_src(0xC9000100);
......@@ -313,7 +317,7 @@ void __init iSeries_pci_final_fixup(void)
if (node != NULL) {
++DeviceCount;
pdev->sysdata = (void *)node;
node->PciDev = pdev;
PCI_DN(node)->pcidev = pdev;
PPCDBG(PPCDBG_BUSWALK,
"pdev 0x%p <==> DevNode 0x%p\n",
pdev, node);
......@@ -323,7 +327,7 @@ void __init iSeries_pci_final_fixup(void)
} else
printk("PCI: Device Tree not found for 0x%016lX\n",
(unsigned long)pdev);
pdev->irq = node->Irq;
pdev->irq = PCI_DN(node)->Irq;
}
iSeries_activate_IRQs();
mf_display_src(0xC9000200);
......@@ -332,24 +336,24 @@ void __init iSeries_pci_final_fixup(void)
void pcibios_fixup_bus(struct pci_bus *PciBus)
{
PPCDBG(PPCDBG_BUSWALK, "iSeries_pcibios_fixup_bus(0x%04X) Entry.\n",
PciBus->number);
PciBus->number);
}
void pcibios_fixup_resources(struct pci_dev *pdev)
{
PPCDBG(PPCDBG_BUSWALK, "fixup_resources pdev %p\n", pdev);
}
}
/*
* Loop through each node function to find usable EADs bridges.
* Loop through each node function to find usable EADs bridges.
*/
static void scan_PHB_slots(struct pci_controller *Phb)
{
struct HvCallPci_DeviceInfo *DevInfo;
HvBusNumber bus = Phb->local_number; /* System Bus */
HvBusNumber bus = Phb->local_number; /* System Bus */
const HvSubBusNumber SubBus = 0; /* EADs is always 0. */
int HvRc = 0;
int IdSel;
int IdSel;
const int MaxAgents = 8;
DevInfo = (struct HvCallPci_DeviceInfo*)
......@@ -358,10 +362,10 @@ static void scan_PHB_slots(struct pci_controller *Phb)
return;
/*
* Probe for EADs Bridges
* Probe for EADs Bridges
*/
for (IdSel = 1; IdSel < MaxAgents; ++IdSel) {
HvRc = HvCallPci_getDeviceInfo(bus, SubBus, IdSel,
HvRc = HvCallPci_getDeviceInfo(bus, SubBus, IdSel,
ISERIES_HV_ADDR(DevInfo),
sizeof(struct HvCallPci_DeviceInfo));
if (HvRc == 0) {
......@@ -393,19 +397,19 @@ static void scan_EADS_bridge(HvBusNumber bus, HvSubBusNumber SubBus,
/* Note: hvSubBus and irq is always be 0 at this level! */
for (Function = 0; Function < 8; ++Function) {
AgentId = ISERIES_PCI_AGENTID(IdSel, Function);
AgentId = ISERIES_PCI_AGENTID(IdSel, Function);
HvRc = HvCallXm_connectBusUnit(bus, SubBus, AgentId, 0);
if (HvRc == 0) {
if (HvRc == 0) {
printk("found device at bus %d idsel %d func %d (AgentId %x)\n",
bus, IdSel, Function, AgentId);
/* Connect EADs: 0x18.00.12 = 0x00 */
/* Connect EADs: 0x18.00.12 = 0x00 */
PPCDBG(PPCDBG_BUSWALK,
"PCI:Connect EADs: 0x%02X.%02X.%02X\n",
bus, SubBus, AgentId);
HvRc = HvCallPci_getBusUnitInfo(bus, SubBus, AgentId,
HvRc = HvCallPci_getBusUnitInfo(bus, SubBus, AgentId,
ISERIES_HV_ADDR(BridgeInfo),
sizeof(struct HvCallPci_BridgeInfo));
if (HvRc == 0) {
if (HvRc == 0) {
printk("bridge info: type %x subbus %x maxAgents %x maxsubbus %x logslot %x\n",
BridgeInfo->busUnitInfo.deviceType,
BridgeInfo->subBusNumber,
......@@ -428,7 +432,7 @@ static void scan_EADS_bridge(HvBusNumber bus, HvSubBusNumber SubBus,
printk("PCI: Invalid Bridge Configuration(0x%02X)",
BridgeInfo->busUnitInfo.deviceType);
}
} else if (HvRc != 0x000B)
} else if (HvRc != 0x000B)
pci_Log_Error("EADs Connect",
bus, SubBus, AgentId, HvRc);
}
......@@ -441,7 +445,7 @@ static void scan_EADS_bridge(HvBusNumber bus, HvSubBusNumber SubBus,
static int scan_bridge_slot(HvBusNumber Bus,
struct HvCallPci_BridgeInfo *BridgeInfo)
{
struct iSeries_Device_Node *node;
struct device_node *node;
HvSubBusNumber SubBus = BridgeInfo->subBusNumber;
u16 VendorId = 0;
int HvRc = 0;
......@@ -451,16 +455,16 @@ static int scan_bridge_slot(HvBusNumber Bus,
HvAgentId EADsIdSel = ISERIES_PCI_AGENTID(IdSel, Function);
/* iSeries_allocate_IRQ.: 0x18.00.12(0xA3) */
Irq = iSeries_allocate_IRQ(Bus, 0, EADsIdSel);
Irq = iSeries_allocate_IRQ(Bus, 0, EADsIdSel);
PPCDBG(PPCDBG_BUSWALK,
"PCI:- allocate and assign IRQ 0x%02X.%02X.%02X = 0x%02X\n",
Bus, 0, EADsIdSel, Irq);
/*
* Connect all functions of any device found.
* Connect all functions of any device found.
*/
for (IdSel = 1; IdSel <= BridgeInfo->maxAgents; ++IdSel) {
for (Function = 0; Function < 8; ++Function) {
for (IdSel = 1; IdSel <= BridgeInfo->maxAgents; ++IdSel) {
for (Function = 0; Function < 8; ++Function) {
HvAgentId AgentId = ISERIES_PCI_AGENTID(IdSel, Function);
HvRc = HvCallXm_connectBusUnit(Bus, SubBus,
AgentId, Irq);
......@@ -484,15 +488,15 @@ static int scan_bridge_slot(HvBusNumber Bus,
"PCI:- FoundDevice: 0x%02X.%02X.%02X = 0x%04X, irq %d\n",
Bus, SubBus, AgentId, VendorId, Irq);
HvRc = HvCallPci_configStore8(Bus, SubBus, AgentId,
PCI_INTERRUPT_LINE, Irq);
PCI_INTERRUPT_LINE, Irq);
if (HvRc != 0)
pci_Log_Error("PciCfgStore Irq Failed!",
Bus, SubBus, AgentId, HvRc);
++DeviceCount;
node = build_device_node(Bus, SubBus, EADsIdSel, Function);
node->Irq = Irq;
node->LogicalSlot = BridgeInfo->logicalSlotNumber;
PCI_DN(node)->Irq = Irq;
PCI_DN(node)->LogicalSlot = BridgeInfo->logicalSlotNumber;
} /* for (Function = 0; Function < 8; ++Function) */
} /* for (IdSel = 1; IdSel <= MaxAgents; ++IdSel) */
......@@ -542,15 +546,16 @@ EXPORT_SYMBOL(iSeries_memcpy_fromio);
/*
* Look down the chain to find the matching Device Device
*/
static struct iSeries_Device_Node *find_Device_Node(int bus, int devfn)
static struct device_node *find_Device_Node(int bus, int devfn)
{
struct list_head *pos;
list_for_each(pos, &iSeries_Global_Device_List) {
struct iSeries_Device_Node *node =
list_entry(pos, struct iSeries_Device_Node, Device_List);
struct device_node *node =
list_entry(pos, struct device_node, Device_List);
if ((bus == ISERIES_BUS(node)) && (devfn == node->DevFn))
if ((bus == ISERIES_BUS(node)) &&
(devfn == PCI_DN(node)->devfn))
return node;
}
return NULL;
......@@ -562,12 +567,12 @@ static struct iSeries_Device_Node *find_Device_Node(int bus, int devfn)
* Sanity Check Node PciDev to passed pci_dev
* If none is found, returns a NULL which the client must handle.
*/
static struct iSeries_Device_Node *get_Device_Node(struct pci_dev *pdev)
static struct device_node *get_Device_Node(struct pci_dev *pdev)
{
struct iSeries_Device_Node *node;
struct device_node *node;
node = pdev->sysdata;
if (node == NULL || node->PciDev != pdev)
if (node == NULL || PCI_DN(node)->pcidev != pdev)
node = find_Device_Node(pdev->bus->number, pdev->devfn);
return node;
}
......@@ -595,7 +600,7 @@ static u64 hv_cfg_write_func[4] = {
static int iSeries_pci_read_config(struct pci_bus *bus, unsigned int devfn,
int offset, int size, u32 *val)
{
struct iSeries_Device_Node *node = find_Device_Node(bus->number, devfn);
struct device_node *node = find_Device_Node(bus->number, devfn);
u64 fn;
struct HvCallPci_LoadReturn ret;
......@@ -607,7 +612,7 @@ static int iSeries_pci_read_config(struct pci_bus *bus, unsigned int devfn,
}
fn = hv_cfg_read_func[(size - 1) & 3];
HvCall3Ret16(fn, &ret, node->DsaAddr.DsaAddr, offset, 0);
HvCall3Ret16(fn, &ret, PCI_DN(node)->DsaAddr.DsaAddr, offset, 0);
if (ret.rc != 0) {
*val = ~0;
......@@ -625,7 +630,7 @@ static int iSeries_pci_read_config(struct pci_bus *bus, unsigned int devfn,
static int iSeries_pci_write_config(struct pci_bus *bus, unsigned int devfn,
int offset, int size, u32 val)
{
struct iSeries_Device_Node *node = find_Device_Node(bus->number, devfn);
struct device_node *node = find_Device_Node(bus->number, devfn);
u64 fn;
u64 ret;
......@@ -635,7 +640,7 @@ static int iSeries_pci_write_config(struct pci_bus *bus, unsigned int devfn,
return PCIBIOS_BAD_REGISTER_NUMBER;
fn = hv_cfg_write_func[(size - 1) & 3];
ret = HvCall4(fn, node->DsaAddr.DsaAddr, offset, val, 0);
ret = HvCall4(fn, PCI_DN(node)->DsaAddr.DsaAddr, offset, val, 0);
if (ret != 0)
return PCIBIOS_DEVICE_NOT_FOUND;
......@@ -657,14 +662,16 @@ static struct pci_ops iSeries_pci_ops = {
* PCI: Device 23.90 ReadL Retry( 1)
* PCI: Device 23.90 ReadL Retry Successful(1)
*/
static int CheckReturnCode(char *TextHdr, struct iSeries_Device_Node *DevNode,
static int CheckReturnCode(char *TextHdr, struct device_node *DevNode,
int *retry, u64 ret)
{
if (ret != 0) {
struct pci_dn *pdn = PCI_DN(DevNode);
++Pci_Error_Count;
(*retry)++;
printk("PCI: %s: Device 0x%04X:%02X I/O Error(%2d): 0x%04X\n",
TextHdr, DevNode->DsaAddr.Dsa.busNumber, DevNode->DevFn,
TextHdr, pdn->DsaAddr.Dsa.busNumber, pdn->devfn,
*retry, (int)ret);
/*
* Bump the retry and check for retry count exceeded.
......@@ -687,14 +694,14 @@ static int CheckReturnCode(char *TextHdr, struct iSeries_Device_Node *DevNode,
* Note: Make sure the passed variable end up on the stack to avoid
* the exposure of being device global.
*/
static inline struct iSeries_Device_Node *xlate_iomm_address(
static inline struct device_node *xlate_iomm_address(
const volatile void __iomem *IoAddress,
u64 *dsaptr, u64 *BarOffsetPtr)
{
unsigned long OrigIoAddr;
unsigned long BaseIoAddr;
unsigned long TableIndex;
struct iSeries_Device_Node *DevNode;
struct device_node *DevNode;
OrigIoAddr = (unsigned long __force)IoAddress;
if ((OrigIoAddr < BASE_IO_MEMORY) || (OrigIoAddr >= max_io_memory))
......@@ -705,7 +712,7 @@ static inline struct iSeries_Device_Node *xlate_iomm_address(
if (DevNode != NULL) {
int barnum = iobar_table[TableIndex];
*dsaptr = DevNode->DsaAddr.DsaAddr | (barnum << 24);
*dsaptr = PCI_DN(DevNode)->DsaAddr.DsaAddr | (barnum << 24);
*BarOffsetPtr = BaseIoAddr % IOMM_TABLE_ENTRY_SIZE;
} else
panic("PCI: Invalid PCI IoAddress detected!\n");
......@@ -727,7 +734,7 @@ u8 iSeries_Read_Byte(const volatile void __iomem *IoAddress)
u64 dsa;
int retry = 0;
struct HvCallPci_LoadReturn ret;
struct iSeries_Device_Node *DevNode =
struct device_node *DevNode =
xlate_iomm_address(IoAddress, &dsa, &BarOffset);
if (DevNode == NULL) {
......@@ -757,7 +764,7 @@ u16 iSeries_Read_Word(const volatile void __iomem *IoAddress)
u64 dsa;
int retry = 0;
struct HvCallPci_LoadReturn ret;
struct iSeries_Device_Node *DevNode =
struct device_node *DevNode =
xlate_iomm_address(IoAddress, &dsa, &BarOffset);
if (DevNode == NULL) {
......@@ -788,7 +795,7 @@ u32 iSeries_Read_Long(const volatile void __iomem *IoAddress)
u64 dsa;
int retry = 0;
struct HvCallPci_LoadReturn ret;
struct iSeries_Device_Node *DevNode =
struct device_node *DevNode =
xlate_iomm_address(IoAddress, &dsa, &BarOffset);
if (DevNode == NULL) {
......@@ -826,7 +833,7 @@ void iSeries_Write_Byte(u8 data, volatile void __iomem *IoAddress)
u64 dsa;
int retry = 0;
u64 rc;
struct iSeries_Device_Node *DevNode =
struct device_node *DevNode =
xlate_iomm_address(IoAddress, &dsa, &BarOffset);
if (DevNode == NULL) {
......@@ -854,7 +861,7 @@ void iSeries_Write_Word(u16 data, volatile void __iomem *IoAddress)
u64 dsa;
int retry = 0;
u64 rc;
struct iSeries_Device_Node *DevNode =
struct device_node *DevNode =
xlate_iomm_address(IoAddress, &dsa, &BarOffset);
if (DevNode == NULL) {
......@@ -882,7 +889,7 @@ void iSeries_Write_Long(u32 data, volatile void __iomem *IoAddress)
u64 dsa;
int retry = 0;
u64 rc;
struct iSeries_Device_Node *DevNode =
struct device_node *DevNode =
xlate_iomm_address(IoAddress, &dsa, &BarOffset);
if (DevNode == NULL) {
......
/*
* iSeries_proc.c
* Copyright (C) 2001 Kyle A. Lucke IBM Corporation
* Copyright (C) 2001 Mike Corrigan & Dave Engebretsen IBM Corporation
*
......@@ -68,12 +67,15 @@ static int proc_titantod_show(struct seq_file *m, void *v)
unsigned long tb_ticks = (tb0 - startTb);
unsigned long titan_jiffies = titan_usec / (1000000/HZ);
unsigned long titan_jiff_usec = titan_jiffies * (1000000/HZ);
unsigned long titan_jiff_rem_usec = titan_usec - titan_jiff_usec;
unsigned long titan_jiff_rem_usec =
titan_usec - titan_jiff_usec;
unsigned long tb_jiffies = tb_ticks / tb_ticks_per_jiffy;
unsigned long tb_jiff_ticks = tb_jiffies * tb_ticks_per_jiffy;
unsigned long tb_jiff_rem_ticks = tb_ticks - tb_jiff_ticks;
unsigned long tb_jiff_rem_usec = tb_jiff_rem_ticks / tb_ticks_per_usec;
unsigned long new_tb_ticks_per_jiffy = (tb_ticks * (1000000/HZ))/titan_usec;
unsigned long tb_jiff_rem_usec =
tb_jiff_rem_ticks / tb_ticks_per_usec;
unsigned long new_tb_ticks_per_jiffy =
(tb_ticks * (1000000/HZ))/titan_usec;
seq_printf(m, " titan elapsed = %lu uSec\n", titan_usec);
seq_printf(m, " tb elapsed = %lu ticks\n", tb_ticks);
......
......@@ -2,8 +2,6 @@
* Copyright (c) 2000 Mike Corrigan <mikejc@us.ibm.com>
* Copyright (c) 1999-2000 Grant Erickson <grant@lcse.umn.edu>
*
* Module name: iSeries_setup.c
*
* Description:
* Architecture- / platform-specific boot-time initialization code for
* the IBM iSeries LPAR. Adapted from original code by Grant Erickson and
......@@ -42,7 +40,6 @@
#include <asm/firmware.h>
#include <asm/time.h>
#include "iSeries_setup.h"
#include <asm/naca.h>
#include <asm/paca.h>
#include <asm/cache.h>
......@@ -62,6 +59,8 @@
#include <asm/iSeries/ItVpdAreas.h>
#include <asm/iSeries/LparMap.h>
#include "setup.h"
extern void hvlog(char *fmt, ...);
#ifdef DEBUG
......
......@@ -2,8 +2,6 @@
* Copyright (c) 2000 Mike Corrigan <mikejc@us.ibm.com>
* Copyright (c) 1999-2000 Grant Erickson <grant@lcse.umn.edu>
*
* Module name: as400_setup.h
*
* Description:
* Architecture- / platform-specific boot-time initialization code for
* the IBM AS/400 LPAR. Adapted from original code by Grant Erickson and
......
......@@ -47,17 +47,17 @@
static unsigned long iSeries_smp_message[NR_CPUS];
void iSeries_smp_message_recv( struct pt_regs * regs )
void iSeries_smp_message_recv(struct pt_regs *regs)
{
int cpu = smp_processor_id();
int msg;
if ( num_online_cpus() < 2 )
if (num_online_cpus() < 2)
return;
for ( msg = 0; msg < 4; ++msg )
if ( test_and_clear_bit( msg, &iSeries_smp_message[cpu] ) )
smp_message_recv( msg, regs );
for (msg = 0; msg < 4; msg++)
if (test_and_clear_bit(msg, &iSeries_smp_message[cpu]))
smp_message_recv(msg, regs);
}
static inline void smp_iSeries_do_message(int cpu, int msg)
......@@ -74,8 +74,8 @@ static void smp_iSeries_message_pass(int target, int msg)
smp_iSeries_do_message(target, msg);
else {
for_each_online_cpu(i) {
if (target == MSG_ALL_BUT_SELF
&& i == smp_processor_id())
if ((target == MSG_ALL_BUT_SELF) &&
(i == smp_processor_id()))
continue;
smp_iSeries_do_message(i, msg);
}
......@@ -89,7 +89,7 @@ static int smp_iSeries_probe(void)
static void smp_iSeries_kick_cpu(int nr)
{
BUG_ON(nr < 0 || nr >= NR_CPUS);
BUG_ON((nr < 0) || (nr >= NR_CPUS));
/* Verify that our partition has a processor nr */
if (paca[nr].lppaca.dyn_proc_status >= 2)
......
/* -*- linux-c -*-
* arch/ppc64/kernel/viopath.c
*
* iSeries Virtual I/O Message Path code
*
......@@ -7,7 +6,7 @@
* Ryan Arnold <ryanarn@us.ibm.com>
* Colin Devilbiss <devilbis@us.ibm.com>
*
* (C) Copyright 2000-2003 IBM Corporation
* (C) Copyright 2000-2005 IBM Corporation
*
* This code is used by the iSeries virtual disk, cd,
* tape, and console to communicate with OS/400 in another
......
/*
* File iSeries_vpdInfo.c created by Allan Trautman on Fri Feb 2 2001.
*
* This code gets the card location of the hardware
* Copyright (C) 2001 <Allan H Trautman> <IBM Corp>
* Copyright (C) 2005 Stephen Rothwel, IBM Corp
......@@ -242,7 +240,7 @@ static void __init iSeries_Get_Location_Code(u16 bus, HvAgentId agent,
*/
void __init iSeries_Device_Information(struct pci_dev *PciDev, int count)
{
struct iSeries_Device_Node *DevNode = PciDev->sysdata;
struct device_node *DevNode = PciDev->sysdata;
u16 bus;
u8 frame;
char card[4];
......
......@@ -84,6 +84,7 @@ head-y := arch/ppc64/kernel/head.o
libs-y += arch/ppc64/lib/
core-y += arch/ppc64/kernel/
core-y += arch/ppc64/mm/
core-y += arch/powerpc/platforms/
core-$(CONFIG_XMON) += arch/ppc64/xmon/
drivers-$(CONFIG_OPROFILE) += arch/powerpc/oprofile/
......
/*
* Copyright 2001 Mike Corrigan IBM Corp
*
* 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/stddef.h>
#include <linux/kernel.h>
#include <linux/module.h>
#include <asm/system.h>
#include <asm/iSeries/HvLpEvent.h>
#include <asm/iSeries/HvCallEvent.h>
#include <asm/iSeries/ItLpNaca.h>
/* Array of LpEvent handler functions */
LpEventHandler lpEventHandler[HvLpEvent_Type_NumTypes];
unsigned lpEventHandlerPaths[HvLpEvent_Type_NumTypes];
/* Register a handler for an LpEvent type */
int HvLpEvent_registerHandler( HvLpEvent_Type eventType, LpEventHandler handler )
{
int rc = 1;
if ( eventType < HvLpEvent_Type_NumTypes ) {
lpEventHandler[eventType] = handler;
rc = 0;
}
return rc;
}
int HvLpEvent_unregisterHandler( HvLpEvent_Type eventType )
{
int rc = 1;
might_sleep();
if ( eventType < HvLpEvent_Type_NumTypes ) {
if ( !lpEventHandlerPaths[eventType] ) {
lpEventHandler[eventType] = NULL;
rc = 0;
/* We now sleep until all other CPUs have scheduled. This ensures that
* the deletion is seen by all other CPUs, and that the deleted handler
* isn't still running on another CPU when we return. */
synchronize_rcu();
}
}
return rc;
}
EXPORT_SYMBOL(HvLpEvent_registerHandler);
EXPORT_SYMBOL(HvLpEvent_unregisterHandler);
/* (lpIndex is the partition index of the target partition.
* needed only for VirtualIo, VirtualLan and SessionMgr. Zero
* indicates to use our partition index - for the other types)
*/
int HvLpEvent_openPath( HvLpEvent_Type eventType, HvLpIndex lpIndex )
{
int rc = 1;
if ( eventType < HvLpEvent_Type_NumTypes &&
lpEventHandler[eventType] ) {
if ( lpIndex == 0 )
lpIndex = itLpNaca.xLpIndex;
HvCallEvent_openLpEventPath( lpIndex, eventType );
++lpEventHandlerPaths[eventType];
rc = 0;
}
return rc;
}
int HvLpEvent_closePath( HvLpEvent_Type eventType, HvLpIndex lpIndex )
{
int rc = 1;
if ( eventType < HvLpEvent_Type_NumTypes &&
lpEventHandler[eventType] &&
lpEventHandlerPaths[eventType] ) {
if ( lpIndex == 0 )
lpIndex = itLpNaca.xLpIndex;
HvCallEvent_closeLpEventPath( lpIndex, eventType );
--lpEventHandlerPaths[eventType];
rc = 0;
}
return rc;
}
......@@ -16,17 +16,10 @@ obj-y += vdso32/ vdso64/
obj-$(CONFIG_PPC_OF) += of_device.o
pci-obj-$(CONFIG_PPC_ISERIES) += iSeries_pci.o iSeries_irq.o \
iSeries_VpdInfo.o
pci-obj-$(CONFIG_PPC_MULTIPLATFORM) += pci_dn.o pci_direct_iommu.o
obj-$(CONFIG_PCI) += pci.o pci_iommu.o iomap.o $(pci-obj-y)
obj-$(CONFIG_PPC_ISERIES) += HvCall.o HvLpConfig.o LparData.o \
iSeries_setup.o ItLpQueue.o hvCall.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
obj-$(CONFIG_PPC_PSERIES) += pSeries_pci.o pSeries_lpar.o pSeries_hvCall.o \
......@@ -45,14 +38,12 @@ 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
obj-$(CONFIG_LPARCFG) += lparcfg.o
obj-$(CONFIG_HVC_CONSOLE) += hvconsole.o
obj-$(CONFIG_BOOTX_TEXT) += btext.o
obj-$(CONFIG_HVCS) += hvcserver.o
vio-obj-$(CONFIG_PPC_PSERIES) += pSeries_vio.o
vio-obj-$(CONFIG_PPC_ISERIES) += iSeries_vio.o
obj-$(CONFIG_IBMVIO) += vio.o $(vio-obj-y)
obj-$(CONFIG_XICS) += xics.o
obj-$(CONFIG_MPIC) += mpic.o
......@@ -68,7 +59,6 @@ obj-$(CONFIG_U3_DART) += u3_iommu.o
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
......
......@@ -39,8 +39,8 @@
#include <asm/pmac_feature.h>
#include <asm/abs_addr.h>
#include <asm/system.h>
#include <asm/ppc-pci.h>
#include "pci.h"
#include "bpa_iommu.h"
static inline unsigned long
......
......@@ -43,8 +43,8 @@
#include <asm/time.h>
#include <asm/nvram.h>
#include <asm/cputable.h>
#include <asm/ppc-pci.h>
#include "pci.h"
#include "bpa_iic.h"
#include "bpa_iommu.h"
......
......@@ -33,7 +33,7 @@
#include <asm/rtas.h>
#include <asm/atomic.h>
#include <asm/systemcfg.h>
#include "pci.h"
#include <asm/ppc-pci.h>
#undef DEBUG
......
......@@ -1253,7 +1253,7 @@ unrecov_slb:
*
* On iSeries, the hypervisor must fill in at least one entry before
* we get control (with relocate on). The address is give to the hv
* as a page number (see xLparMap in LparData.c), so this must be at a
* as a page number (see xLparMap in lpardata.c), so this must be at a
* fixed address (the linker can't compute (u64)&initial_stab >>
* PAGE_SHIFT).
*/
......
......@@ -23,8 +23,7 @@
#include <asm/pci-bridge.h>
#include <asm/machdep.h>
#include <asm/iommu.h>
#include "pci.h"
#include <asm/ppc-pci.h>
#ifdef DEBUG
#define DBG(x...) printk(x)
......
......@@ -64,44 +64,6 @@ _GLOBAL(get_srr1)
_GLOBAL(get_sp)
mr r3,r1
blr
#ifdef CONFIG_PPC_ISERIES
/* unsigned long local_save_flags(void) */
_GLOBAL(local_get_flags)
lbz r3,PACAPROCENABLED(r13)
blr
/* unsigned long local_irq_disable(void) */
_GLOBAL(local_irq_disable)
lbz r3,PACAPROCENABLED(r13)
li r4,0
stb r4,PACAPROCENABLED(r13)
blr /* Done */
/* void local_irq_restore(unsigned long flags) */
_GLOBAL(local_irq_restore)
lbz r5,PACAPROCENABLED(r13)
/* Check if things are setup the way we want _already_. */
cmpw 0,r3,r5
beqlr
/* are we enabling interrupts? */
cmpdi 0,r3,0
stb r3,PACAPROCENABLED(r13)
beqlr
/* Check pending interrupts */
/* A decrementer, IPI or PMC interrupt may have occurred
* while we were in the hypervisor (which enables) */
ld r4,PACALPPACA+LPPACAANYINT(r13)
cmpdi r4,0
beqlr
/*
* Handle pending interrupts in interrupt context
*/
li r0,0x5555
sc
blr
#endif /* CONFIG_PPC_ISERIES */
#ifdef CONFIG_IRQSTACKS
_GLOBAL(call_do_softirq)
......
......@@ -47,7 +47,7 @@
#include <asm/systemcfg.h>
#include <asm/firmware.h>
#include <asm/tce.h>
#include "pci.h"
#include <asm/ppc-pci.h>
#define DBG(fmt...)
......
......@@ -29,8 +29,7 @@
#include <asm/pci-bridge.h>
#include <asm/prom.h>
#include "pci.h"
#include <asm/ppc-pci.h>
static int __initdata s7a_workaround = -1;
......
......@@ -63,9 +63,9 @@
#include <asm/firmware.h>
#include <asm/pmc.h>
#include <asm/mpic.h>
#include <asm/ppc-pci.h>
#include "i8259.h"
#include "pci.h"
#ifdef DEBUG
#define DBG(fmt...) udbg_printf(fmt)
......
......@@ -31,8 +31,7 @@
#include <asm/irq.h>
#include <asm/machdep.h>
#include <asm/udbg.h>
#include "pci.h"
#include <asm/ppc-pci.h>
#ifdef DEBUG
#define DBG(fmt...) udbg_printf(fmt)
......
......@@ -27,8 +27,7 @@
#include <asm/machdep.h>
#include <asm/pmac_feature.h>
#include <asm/abs_addr.h>
#include "pci.h"
#include <asm/ppc-pci.h>
static void *pci_direct_alloc_coherent(struct device *hwdev, size_t size,
dma_addr_t *dma_handle, unsigned int __nocast flag)
......
......@@ -30,8 +30,7 @@
#include <asm/prom.h>
#include <asm/pci-bridge.h>
#include <asm/pSeries_reconfig.h>
#include "pci.h"
#include <asm/ppc-pci.h>
/*
* Traverse_func that inits the PCI fields of the device node.
......
......@@ -37,7 +37,7 @@
#include <asm/iommu.h>
#include <asm/pci-bridge.h>
#include <asm/machdep.h>
#include "pci.h"
#include <asm/ppc-pci.h>
#ifdef CONFIG_PPC_ISERIES
#include <asm/iSeries/iSeries_pci.h>
......@@ -61,13 +61,7 @@ static inline struct iommu_table *devnode_table(struct device *dev)
} else
pdev = to_pci_dev(dev);
#ifdef CONFIG_PPC_ISERIES
return ISERIES_DEVNODE(pdev)->iommu_table;
#endif /* CONFIG_PPC_ISERIES */
#ifdef CONFIG_PPC_MULTIPLATFORM
return PCI_DN(PCI_GET_DN(pdev))->iommu_table;
#endif /* CONFIG_PPC_MULTIPLATFORM */
}
......
......@@ -27,8 +27,8 @@
#include <asm/machdep.h>
#include <asm/pmac_feature.h>
#include <asm/iommu.h>
#include <asm/ppc-pci.h>
#include "pci.h"
#include "pmac.h"
#define DEBUG
......
......@@ -19,7 +19,6 @@
#include <asm/hw_irq.h>
#include <asm/abs_addr.h>
#include <asm/cacheflush.h>
#include <asm/iSeries/HvCallSc.h>
EXPORT_SYMBOL(strcpy);
EXPORT_SYMBOL(strncpy);
......@@ -46,17 +45,6 @@ EXPORT_SYMBOL(__strnlen_user);
EXPORT_SYMBOL(reloc_offset);
#ifdef CONFIG_PPC_ISERIES
EXPORT_SYMBOL(HvCall0);
EXPORT_SYMBOL(HvCall1);
EXPORT_SYMBOL(HvCall2);
EXPORT_SYMBOL(HvCall3);
EXPORT_SYMBOL(HvCall4);
EXPORT_SYMBOL(HvCall5);
EXPORT_SYMBOL(HvCall6);
EXPORT_SYMBOL(HvCall7);
#endif
EXPORT_SYMBOL(_insb);
EXPORT_SYMBOL(_outsb);
EXPORT_SYMBOL(_insw);
......@@ -77,14 +65,6 @@ EXPORT_SYMBOL(giveup_altivec);
EXPORT_SYMBOL(__flush_icache_range);
EXPORT_SYMBOL(flush_dcache_range);
#ifdef CONFIG_SMP
#ifdef CONFIG_PPC_ISERIES
EXPORT_SYMBOL(local_get_flags);
EXPORT_SYMBOL(local_irq_disable);
EXPORT_SYMBOL(local_irq_restore);
#endif
#endif
EXPORT_SYMBOL(memcpy);
EXPORT_SYMBOL(memset);
EXPORT_SYMBOL(memmove);
......
......@@ -39,8 +39,7 @@
#include <asm/iommu.h>
#include <asm/rtas.h>
#include <asm/mpic.h>
#include "pci.h"
#include <asm/ppc-pci.h>
/* RTAS tokens */
static int read_pci_config;
......
......@@ -43,11 +43,8 @@
#include <asm/time.h>
#include <asm/rtas.h>
#include <asm/iSeries/mf.h>
#include <asm/machdep.h>
extern int piranha_simulator;
/*
* We sponge a minor off of the misc major. No need slurping
* up another valuable major dev number for this. If you add
......@@ -265,40 +262,6 @@ static int rtc_read_proc(char *page, char **start, off_t off,
return len;
}
#ifdef CONFIG_PPC_ISERIES
/*
* Get the RTC from the virtual service processor
* This requires flowing LpEvents to the primary partition
*/
void iSeries_get_rtc_time(struct rtc_time *rtc_tm)
{
if (piranha_simulator)
return;
mf_get_rtc(rtc_tm);
rtc_tm->tm_mon--;
}
/*
* Set the RTC in the virtual service processor
* This requires flowing LpEvents to the primary partition
*/
int iSeries_set_rtc_time(struct rtc_time *tm)
{
mf_set_rtc(tm);
return 0;
}
void iSeries_get_boot_time(struct rtc_time *tm)
{
if ( piranha_simulator )
return;
mf_get_boot_rtc(tm);
tm->tm_mon -= 1;
}
#endif
#ifdef CONFIG_PPC_RTAS
#define MAX_RTC_WAIT 5000 /* 5 sec */
#define RTAS_CLOCK_BUSY (-2)
......
......@@ -53,8 +53,7 @@
#include <asm/time.h>
#include <asm/mmu_context.h>
#include <asm/systemcfg.h>
#include "pci.h"
#include <asm/ppc-pci.h>
/* readdir & getdents */
#define NAME_OFFSET(de) ((int) ((de)->d_name - (char __user *) (de)))
......
......@@ -45,8 +45,7 @@
#include <asm/cacheflush.h>
#include <asm/lmb.h>
#include <asm/dart.h>
#include "pci.h"
#include <asm/ppc-pci.h>
extern int iommu_force_on;
......
......@@ -6,8 +6,8 @@
* as published by the Free Software Foundation; either version
* 2 of the License, or (at your option) any later version.
*/
#ifndef __PPC_KERNEL_PCI_H__
#define __PPC_KERNEL_PCI_H__
#ifndef _ASM_POWERPC_PPC_PCI_H
#define _ASM_POWERPC_PPC_PCI_H
#include <linux/pci.h>
#include <asm/pci-bridge.h>
......@@ -51,4 +51,4 @@ extern unsigned long pci_probe_only;
extern unsigned long pci_assign_all_buses;
extern int pci_read_irq_line(struct pci_dev *pci_dev);
#endif /* __PPC_KERNEL_PCI_H__ */
#endif /* _ASM_POWERPC_PPC_PCI_H */
......@@ -30,21 +30,19 @@
* End Change Activity
*/
#include <asm/iSeries/HvCallPci.h>
#include <asm/abs_addr.h>
#include <asm/prom.h>
#include <asm/pci-bridge.h>
struct pci_dev; /* For Forward Reference */
struct iSeries_Device_Node;
/*
* Gets iSeries Bus, SubBus, DevFn using iSeries_Device_Node structure
* Gets iSeries Bus, SubBus, DevFn using device_node structure
*/
#define ISERIES_BUS(DevPtr) DevPtr->DsaAddr.Dsa.busNumber
#define ISERIES_SUBBUS(DevPtr) DevPtr->DsaAddr.Dsa.subBusNumber
#define ISERIES_DEVICE(DevPtr) DevPtr->DsaAddr.Dsa.deviceId
#define ISERIES_DSA(DevPtr) DevPtr->DsaAddr.DsaAddr
#define ISERIES_DEVNODE(PciDev) ((struct iSeries_Device_Node *)PciDev->sysdata)
#define ISERIES_BUS(DevPtr) PCI_DN(DevPtr)->DsaAddr.Dsa.busNumber
#define ISERIES_SUBBUS(DevPtr) PCI_DN(DevPtr)->DsaAddr.Dsa.subBusNumber
#define ISERIES_DEVNODE(PciDev) ((struct device_node *)PciDev->sysdata)
#define EADsMaxAgents 7
......@@ -67,22 +65,6 @@ struct iSeries_Device_Node;
#define ISERIES_HV_ADDR(virtaddr) \
(0x8000000000000000 | virt_to_abs(virtaddr))
/*
* iSeries Device Information
*/
struct iSeries_Device_Node {
struct list_head Device_List;
struct pci_dev *PciDev;
union HvDsaMap DsaAddr; /* Direct Select Address */
/* busNumber, subBusNumber, */
/* deviceId, barNumber */
int DevFn; /* Linux devfn */
int Irq; /* Assigned IRQ */
int Flags; /* Possible flags(disable/bist)*/
u8 LogicalSlot; /* Hv Slot Index for Tces */
struct iommu_table *iommu_table;/* Device TCE Table */
};
extern void iSeries_Device_Information(struct pci_dev*, int);
#endif /* _ISERIES_64_PCI_H */
......@@ -49,6 +49,7 @@ struct iommu_table {
};
struct scatterlist;
struct device_node;
#ifdef CONFIG_PPC_MULTIPLATFORM
......@@ -70,9 +71,8 @@ extern void iommu_devnode_init_pSeries(struct device_node *dn);
#ifdef CONFIG_PPC_ISERIES
struct iSeries_Device_Node;
/* Creates table for an individual device node */
extern void iommu_devnode_init_iSeries(struct iSeries_Device_Node *dn);
extern void iommu_devnode_init_iSeries(struct device_node *dn);
#endif /* CONFIG_PPC_ISERIES */
......
......@@ -4,6 +4,8 @@
#include <linux/pci.h>
#include <asm/iSeries/HvCallPci.h>
/*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
......@@ -71,6 +73,14 @@ struct pci_dn {
struct iommu_table *iommu_table; /* for phb's or bridges */
struct pci_dev *pcidev; /* back-pointer to the pci device */
struct device_node *node; /* back-pointer to the device_node */
#ifdef CONFIG_PPC_ISERIES
union HvDsaMap DsaAddr; /* Direct Select Address */
/* busNumber, subBusNumber, */
/* deviceId, barNumber */
int Irq; /* Assigned IRQ */
int Flags; /* Possible flags(disable/bist)*/
u8 LogicalSlot; /* Hv Slot Index for Tces */
#endif
u32 config_space[16]; /* saved PCI config space */
};
......
......@@ -137,6 +137,9 @@ struct device_node {
struct kref kref;
unsigned long _flags;
void *data;
#ifdef CONFIG_PPC_ISERIES
struct list_head Device_List;
#endif
};
extern struct device_node *of_chosen;
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册