* Re: apm_emulation regression
From: Rafael J. Wysocki @ 2007-12-14 0:10 UTC (permalink / raw)
To: Johannes Berg; +Cc: linux-pm, ralf, linuxppc-dev list
In-Reply-To: <1197482587.6558.145.camel@johannes.berg>
On Wednesday, 12 of December 2007, Johannes Berg wrote:
>
> On Wed, 2007-12-12 at 13:45 +1100, Benjamin Herrenschmidt wrote:
> > I only just noticed a huge regression that was introduced when we moved
> > PowerPC to the generic APM emulation code instead of our own. I'm in
> > large part to blame since I acked the patch...
> >
> > Basically, what we lost is the mechanism for notifying user applications
> > and waiting for their ACK before proceeding to system suspend. The new
> > generic code will still do that ... only when the actual suspend request
> > initiates from an APM suspend ioctl.
>
> Indeed.
>
> > For any other suspend (via our private PMU ioctl or via the sysfs
> > interface), userspace will -not- be notified.
>
> Right.
>
> > That basically means X will break. That's why X broke on the latest
> > ubuntu until I whacked some new scripts in them to force console
> > switching, among other things. Possibly other apps that relied
> > on /dev/apm_bios to be notified of system suspend/resume broke as well.
>
> Ah. I guess I never noticed because I had the scripts to do console
> switching all along.
>
> > Now the question is that is it still work trying to fix it ? That would
> > probably require APM emulation hooking at a fairly high level into the
> > generic PM code to trigger the signaling & waiting of processes before
> > freeze & device suspend among others...
>
> Yeah, bit icky... but doable. Rafael, any ideas?
Hmm.
I'm not that familiar with the APM emulation code, but the description of the
problem above suggests that the APM emulation can install a suspend
notifier for this purpose.
Greetings,
Rafael
^ permalink raw reply
* Re: [PATCH 2/7] [POWERPC] Xilinx: clear data caches.
From: Benjamin Herrenschmidt @ 2007-12-14 0:09 UTC (permalink / raw)
To: Stephen Neuendorffer; +Cc: linuxppc-dev, simekm2
In-Reply-To: <1197590848.15741.199.camel@pasglop>
On Fri, 2007-12-14 at 11:07 +1100, Benjamin Herrenschmidt wrote:
> On Thu, 2007-12-13 at 15:43 -0800, Stephen Neuendorffer wrote:
> > This code is needed to boot without a boot loader.
> >
> > Grant: I'm not sure where the right place to put this is. I'm assuming we'll actually need some boot code that is not generic? Also, note that there is a V4FX errata workaround in arch/ppc/boot/head.S, which probably also needs to get pulled to powerpc.
> >
> > Signed-off-by: Stephen Neuendorffer <stephen.neuendorffer@xilinx.com>
> > ---
> > arch/powerpc/boot/raw-platform.c | 22 ++++++++++++++++++++++
> > 1 files changed, 22 insertions(+), 0 deletions(-)
>
> This raw-platform.c file doesn't seem like a good place for code that is
> totally platform specific ...
Maybe best is to do that in asm ? The problem when you are in C code is
that you may already have hit stale cache entries. "raw" platforms
probably need to perform various CPU-specific initializations anyway,
prior to entering C code, in a custom crt0.S, so that's probably the
best place to do the cache clearing.
Ben.
^ permalink raw reply
* How is a device tree used to specifiy flash?
From: Bruce_Leonard @ 2007-12-13 23:28 UTC (permalink / raw)
To: linuxppc-embedded
Okay I just don't get it, but that's not a surprise. I'm booting a 2.6.23
kernel on an MPC8347 using u-boot 1.3.0. I'm trying to use the device
tree to spec my single Spansion/AMD NOR flash part and I can't get the
kernel to recognize the part. Or maybe I just don't know how to tell if
the kernel is recognizing the part. It's possible that everything is fine
and I'm just to dumb to know it.
So I've got a Spansion S29GL128N flash part and the following entry in my
device tree:
flash@ff000000 {
compatible = "amd,s29g128n", "cfi-flash";
reg = <ff000000 01000000>;
bank-width = <2>;
device-width = <1>;
#address-cells = <1>;
#size-cells = <1>;
bit@200000 {
label = "bit";
reg = <200000 a0000>;
};
kernel@400000 {
label = "kernel";
reg = <400000 140000>;
};
blob@600000 {
label = "blob";
reg = <600000 20000>;
};
uboot@f00000 {
label = "uboot";
reg = <f00000 60000>;
read-only;
};
};
I've got the following in my .config for the kernel (I think this is all
that's relavent but I'm not sure);
#
# Device Drivers
#
#
# Generic Driver Options
#
CONFIG_STANDALONE=y
CONFIG_PREVENT_FIRMWARE_BUILD=y
# CONFIG_FW_LOADER is not set
# CONFIG_DEBUG_DRIVER is not set
# CONFIG_DEBUG_DEVRES is not set
# CONFIG_SYS_HYPERVISOR is not set
# CONFIG_CONNECTOR is not set
CONFIG_MTD=y
CONFIG_MTD_DEBUG=y
CONFIG_MTD_DEBUG_VERBOSE=3
# CONFIG_MTD_CONCAT is not set
CONFIG_MTD_PARTITIONS=y
# CONFIG_MTD_REDBOOT_PARTS is not set
CONFIG_MTD_CMDLINE_PARTS=y
#
# User Modules And Translation Layers
#
CONFIG_MTD_CHAR=y
# CONFIG_MTD_BLKDEVS is not set
# CONFIG_MTD_BLOCK is not set
# CONFIG_MTD_BLOCK_RO is not set
# CONFIG_FTL is not set
# CONFIG_NFTL is not set
# CONFIG_INFTL is not set
# CONFIG_RFD_FTL is not set
# CONFIG_SSFDC is not set
#
# RAM/ROM/Flash chip drivers
#
CONFIG_MTD_CFI=y
# CONFIG_MTD_JEDECPROBE is not set
CONFIG_MTD_GEN_PROBE=y
# CONFIG_MTD_CFI_ADV_OPTIONS is not set
CONFIG_MTD_MAP_BANK_WIDTH_1=y
CONFIG_MTD_MAP_BANK_WIDTH_2=y
CONFIG_MTD_MAP_BANK_WIDTH_4=y
# CONFIG_MTD_MAP_BANK_WIDTH_8 is not set
# CONFIG_MTD_MAP_BANK_WIDTH_16 is not set
# CONFIG_MTD_MAP_BANK_WIDTH_32 is not set
CONFIG_MTD_CFI_I1=y
CONFIG_MTD_CFI_I2=y
# CONFIG_MTD_CFI_I4 is not set
# CONFIG_MTD_CFI_I8 is not set
# CONFIG_MTD_CFI_INTELEXT is not set
CONFIG_MTD_CFI_AMDSTD=y
# CONFIG_MTD_CFI_STAA is not set
CONFIG_MTD_CFI_UTIL=y
# CONFIG_MTD_RAM is not set
# CONFIG_MTD_ROM is not set
# CONFIG_MTD_ABSENT is not set
#
# Mapping drivers for chip access
#
# CONFIG_MTD_COMPLEX_MAPPINGS is not set
# CONFIG_MTD_PHYSMAP is not set
CONFIG_MTD_PHYSMAP_OF=y
# CONFIG_MTD_PLATRAM is not set
#
# Self-contained MTD device drivers
#
# CONFIG_MTD_PMC551 is not set
# CONFIG_MTD_SLRAM is not set
# CONFIG_MTD_PHRAM is not set
# CONFIG_MTD_MTDRAM is not set
# CONFIG_MTD_BLOCK2MTD is not set
#
# Disk-On-Chip Device Drivers
#
# CONFIG_MTD_DOC2000 is not set
# CONFIG_MTD_DOC2001 is not set
# CONFIG_MTD_DOC2001PLUS is not set
# CONFIG_MTD_NAND is not set
# CONFIG_MTD_ONENAND is not set
#
# UBI - Unsorted block images
#
# CONFIG_MTD_UBI is not set
CONFIG_OF_DEVICE=y
# CONFIG_PARPORT is not set
CONFIG_BLK_DEV=y
# CONFIG_BLK_DEV_FD is not set
# CONFIG_BLK_CPQ_DA is not set
# CONFIG_BLK_CPQ_CISS_DA is not set
# CONFIG_BLK_DEV_DAC960 is not set
# CONFIG_BLK_DEV_UMEM is not set
# CONFIG_BLK_DEV_COW_COMMON is not set
# CONFIG_BLK_DEV_LOOP is not set
CONFIG_BLK_DEV_NBD=y
# CONFIG_BLK_DEV_SX8 is not set
# CONFIG_BLK_DEV_UB is not set
# CONFIG_BLK_DEV_RAM is not set
# CONFIG_CDROM_PKTCDVD is not set
# CONFIG_ATA_OVER_ETH is not set
# CONFIG_MISC_DEVICES is not set
# CONFIG_IDE is not set
With this device tree and this .config the kernel never probes the flash
part and 'cat /dev/mtd1' says the device doesn't exist. If I then use
Kconfig to specify the start of flash, the size of flash, and the bank
width, dmesg shows that the part has been probed and 'cat /dev/mtd' spews
out all sorts of stuff.
What black magic is there that doesn't showup in booting-without-of.txt
that I'm missing?
Thanks for any feedback.
Bruce
^ permalink raw reply
* RE: [PATCH 2/7] [POWERPC] Xilinx: clear data caches.
From: Stephen Neuendorffer @ 2007-12-14 0:36 UTC (permalink / raw)
To: benh; +Cc: linuxppc-dev, simekm2
In-Reply-To: <1197590981.15741.201.camel@pasglop>
Unfortunately, I think your right... The asm code seems so clean at the
moment, I don't really want be the one to start tarnishing it with a
bunch of little fixups.. :)
Steve
> -----Original Message-----
> From: Benjamin Herrenschmidt [mailto:benh@kernel.crashing.org]=20
> Sent: Thursday, December 13, 2007 4:10 PM
> To: Stephen Neuendorffer
> Cc: grant.likely@secretlab.ca; simekm2@fel.cvut.cz;=20
> jwilliams@itee.uq.edu.au; linuxppc-dev@ozlabs.org
> Subject: Re: [PATCH 2/7] [POWERPC] Xilinx: clear data caches.
>=20
>=20
> On Fri, 2007-12-14 at 11:07 +1100, Benjamin Herrenschmidt wrote:
> > On Thu, 2007-12-13 at 15:43 -0800, Stephen Neuendorffer wrote:
> > > This code is needed to boot without a boot loader.
> > >=20
> > > Grant: I'm not sure where the right place to put this=20
> is. I'm assuming we'll actually need some boot code that is=20
> not generic? Also, note that there is a V4FX errata=20
> workaround in arch/ppc/boot/head.S, which probably also needs=20
> to get pulled to powerpc.
> > >=20
> > > Signed-off-by: Stephen Neuendorffer=20
> <stephen.neuendorffer@xilinx.com>
> > > ---
> > > arch/powerpc/boot/raw-platform.c | 22 ++++++++++++++++++++++
> > > 1 files changed, 22 insertions(+), 0 deletions(-)
> >=20
> > This raw-platform.c file doesn't seem like a good place for=20
> code that is
> > totally platform specific ...
>=20
> Maybe best is to do that in asm ? The problem when you are in=20
> C code is
> that you may already have hit stale cache entries. "raw" platforms
> probably need to perform various CPU-specific initializations anyway,
> prior to entering C code, in a custom crt0.S, so that's probably the
> best place to do the cache clearing.
>=20
> Ben.
>=20
>=20
>=20
^ permalink raw reply
* Re: How is a device tree used to specifiy flash?
From: Josh Boyer @ 2007-12-14 1:57 UTC (permalink / raw)
To: Bruce_Leonard; +Cc: linuxppc-embedded
In-Reply-To: <OFE841AC61.3D44C925-ON882573B0.007FA29F-882573B0.0080F67D@selinc.com>
On Thu, 13 Dec 2007 15:28:37 -0800
Bruce_Leonard@selinc.com wrote:
> Okay I just don't get it, but that's not a surprise. I'm booting a 2.6.23
> kernel on an MPC8347 using u-boot 1.3.0. I'm trying to use the device
> tree to spec my single Spansion/AMD NOR flash part and I can't get the
> kernel to recognize the part. Or maybe I just don't know how to tell if
> the kernel is recognizing the part. It's possible that everything is fine
> and I'm just to dumb to know it.
>
> So I've got a Spansion S29GL128N flash part and the following entry in my
> device tree:
>
> flash@ff000000 {
What bus is this node under in your DTS file? Make sure that bus is
getting probed in the platform code.
josh
^ permalink raw reply
* Re: How is a device tree used to specifiy flash?
From: Bruce_Leonard @ 2007-12-14 2:27 UTC (permalink / raw)
To: Josh Boyer; +Cc: linuxppc-embedded
In-Reply-To: <20071213195759.0de2a917@vader.jdub.homelinux.org>
> >
> > flash@ff000000 {
>
> What bus is this node under in your DTS file? Make sure that bus is
> getting probed in the platform code.
>
Well, I was starting to wonder about that. This node isn't under any bus
in the DTS file. It's at the same level as the CPU node. Does it need to
be under a localbus node like the pq2fads.dts? I've attached the entire
DTS this time which may help.
Bruce
/ {
model = "MPC8349EMITX";
compatible = "MPC8349EMITX", "MPC834xMITX", "MPC83xxMITX";
#address-cells = <1>;
#size-cells = <1>;
cpus {
#cpus = <1>;
#address-cells = <1>;
#size-cells = <0>;
PowerPC,8349@0 {
device_type = "cpu";
reg = <0>;
d-cache-line-size = <20>;
i-cache-line-size = <20>;
d-cache-size = <8000>;
i-cache-size = <8000>;
timebase-frequency = <0>; // from bootloader
bus-frequency = <0>; // from bootloader
clock-frequency = <0>; // from bootloader
32-bit;
};
};
memory {
device_type = "memory";
reg = <00000000 20000000>;
};
flash@ff000000 {
compatible = "amd,s29g128n", "cfi-flash";
reg = <ff000000 01000000>;
bank-width = <2>;
device-width = <1>;
#address-cells = <1>;
#size-cells = <1>;
bit@200000 {
label = "bit";
reg = <200000 a0000>;
};
kernel@400000 {
label = "kernel";
reg = <400000 140000>;
};
blob@600000 {
label = "blob";
reg = <600000 20000>;
};
uboot@f00000 {
label = "uboot";
reg = <f00000 60000>;
read-only;
};
};
soc8349@e0000000 {
#address-cells = <1>;
#size-cells = <1>;
#interrupt-cells = <2>;
device_type = "soc";
ranges = <0 e0000000 00100000>;
reg = <e0000000 00000200>;
bus-frequency = <0>; // from bootloader
wdt@200 {
device_type = "watchdog";
compatible = "mpc83xx_wdt";
reg = <200 100>;
};
i2c@3000 {
device_type = "i2c";
compatible = "fsl-i2c";
reg = <3000 100>;
interrupts = <e 8>;
interrupt-parent = < &ipic >;
dfsrr;
rtc@68 {
#address-cells = <1>;
#size-cells = <0>;
device_type = "rtc";
compatible = "stm,m41t00";
reg = <68 8>;
};
};
i2c@3100 {
device_type = "i2c";
compatible = "fsl-i2c";
reg = <3100 100>;
interrupts = <f 8>;
interrupt-parent = < &ipic >;
dfsrr;
};
spi@7000 {
device_type = "spi";
compatible = "mpc83xx_spi";
reg = <7000 1000>;
interrupts = <10 8>;
interrupt-parent = < &ipic >;
mode = <0>;
};
usb@22000 {
device_type = "usb";
compatible = "fsl-usb2-mph";
reg = <22000 1000>;
#address-cells = <1>;
#size-cells = <0>;
interrupt-parent = < &ipic >;
interrupts = <27 8>;
phy_type = "ulpi";
// port1;
port0;
};
// usb@23000 {
// device_type = "usb";
// compatible = "fsl-usb2-dr";
// reg = <23000 1000>;
// #address-cells = <1>;
// #size-cells = <0>;
// interrupt-parent = < &ipic >;
// interrupts = <26 8>;
// phy_type = "ulpi";
// };
mdio@24520 {
device_type = "mdio";
compatible = "gianfar";
reg = <24520 20>;
#address-cells = <1>;
#size-cells = <0>;
/* Vitesse 8201 */
phy0: ethernet-phy@1c {
interrupt-parent = < &ipic >;
interrupts = <12 8>;
reg = <0>;
device_type = "ethernet-phy";
};
/* Vitesse 7385 */
phy1: ethernet-phy@1f {
interrupt-parent = < &ipic >;
interrupts = <12 8>;
reg = <1>;
device_type = "ethernet-phy";
};
};
ethernet@24000 {
device_type = "network";
model = "TSEC";
compatible = "gianfar";
reg = <24000 1000>;
address = [ 00 00 00 00 00 00 ];
local-mac-address = [ 00 00 00 00 00 00 ];
interrupts = <20 8 21 8 22 8>;
interrupt-parent = < &ipic >;
phy-handle = < &phy0 >;
};
ethernet@25000 {
#address-cells = <1>;
#size-cells = <0>;
device_type = "network";
model = "TSEC";
compatible = "gianfar";
reg = <25000 1000>;
address = [ 00 00 00 00 00 00 ];
local-mac-address = [ 00 00 00 00 00 00 ];
interrupts = <23 8 24 8 25 8>;
interrupt-parent = < &ipic >;
phy-handle = < &phy1 >;
};
serial@4500 {
device_type = "serial";
compatible = "ns16550";
reg = <4500 100>;
clock-frequency = <0>; // from bootloader
interrupts = <9 8>;
interrupt-parent = < &ipic >;
};
serial@4600 {
device_type = "serial";
compatible = "ns16550";
reg = <4600 100>;
clock-frequency = <0>; // from bootloader
interrupts = <a 8>;
interrupt-parent = < &ipic >;
};
pci@8500 {
interrupt-map-mask = <f800 0 0 7>;
interrupt-map = <
// IDSEL 0x12 - FPGA
9000 0 0 1 &ipic 15 8 // INTA -
UARTS
9000 0 0 2 &ipic 16 8 // INTB -
IRIG
// IDSEL 0x13 - PCI Enet
9800 0 0 1 &ipic 14 8 // INTA
// IDSEL 0x14 - PCI104 Slot 1
a000 0 0 1 &ipic 12 8 // INTA
a000 0 0 2 &ipic 13 8 // INTB
a000 0 0 3 &ipic 15 8 // INTC
a000 0 0 4 &ipic 16 8 // INTD
// IDSEL 0x15 - PCI104 Slot 2
a800 0 0 1 &ipic 13 8 // INTA
a800 0 0 2 &ipic 15 8 // INTB
a800 0 0 3 &ipic 16 8 // INTC
a800 0 0 4 &ipic 12 8 // INTD
// IDSEL 0x16 - PCI104 Slot 3
b000 0 0 1 &ipic 15 8 // INTA
b000 0 0 2 &ipic 16 8 // INTB
b000 0 0 3 &ipic 12 8 // INTC
b000 0 0 4 &ipic 13 8 // INTD
>;
interrupt-parent = < &ipic >;
interrupts = <42 8>;
bus-range = <0 0>;
ranges = <42000000 0 80000000 80000000 0 10000000
02000000 0 90000000 90000000 0 08000000
01000000 0 98000000 98000000 0
08000000>;
clock-frequency = <1f78a40>;
#interrupt-cells = <1>;
#size-cells = <2>;
#address-cells = <3>;
reg = <8500 100>;
compatible = "83xx";
device_type = "pci";
};
crypto@30000 {
device_type = "crypto";
model = "SEC2";
compatible = "talitos";
reg = <30000 10000>;
interrupts = <b 8>;
interrupt-parent = < &ipic >;
num-channels = <4>;
channel-fifo-len = <18>;
exec-units-mask = <0000007e>;
descriptor-types-mask = <01010ebf>;
};
ipic: pic@700 {
interrupt-controller;
#address-cells = <0>;
#interrupt-cells = <2>;
reg = <700 100>;
built-in;
device_type = "ipic";
};
};
};
^ permalink raw reply
* Re: How is a device tree used to specifiy flash?
From: Jon Smirl @ 2007-12-14 2:28 UTC (permalink / raw)
To: Bruce_Leonard@selinc.com; +Cc: linuxppc-embedded
In-Reply-To: <OFE841AC61.3D44C925-ON882573B0.007FA29F-882573B0.0080F67D@selinc.com>
To get this working on the mpc5200 I had to add the localbus node
above the flash.
lpb@ff000000 {
compatible = "fsl,lpb";
ranges = <0 ff000000 01000000>;
flash@00000000 {
compatible = "cfi-flash";
reg = <00000000 01000000>;
bank-width = <2>;
#size-cells = <1>;
#address-cells = <1>;
partition@0 {
label = "ubootl";
reg = <00000000 00040000>;
};
partition@40000 {
label = "kernel";
reg = <00040000 001c0000>;
};
partition@200000 {
label = "jffs2";
reg = <00200000 00D00000>;
};
partition@f00000 {
label = "uboot";
reg = <00f00000 00040000>;
};
partition@f40000 {
label = "oftree";
reg = <00f40000 00040000>;
};
partition@f80000 {
label = "space";
reg = <00f80000 00080000>;
};
};
};
--
Jon Smirl
jonsmirl@gmail.com
^ permalink raw reply
* Re: How is a device tree used to specifiy flash?
From: Bruce_Leonard @ 2007-12-14 2:48 UTC (permalink / raw)
To: Jon Smirl; +Cc: linuxppc-embedded
In-Reply-To: <9e4733910712131828v532e6aaep316c72e14d92c921@mail.gmail.com>
"Jon Smirl" <jonsmirl@gmail.com> wrote on 12/13/2007 06:28:28 PM:
> To get this working on the mpc5200 I had to add the localbus node
> above the flash.
>
> lpb@ff000000 {
> compatible = "fsl,lpb";
> ranges = <0 ff000000 01000000>;
>
Thanks. I'll give it a try. Do you know if the "fsl,lpb" compaibility
extends to the 83xx code?
Bruce
^ permalink raw reply
* Re: [PATCH] ipic: ack only for edge interrupts
From: Kumar Gala @ 2007-12-14 4:29 UTC (permalink / raw)
To: Li Yang; +Cc: linuxppc-dev
In-Reply-To: <1196766100-7411-1-git-send-email-leoli@freescale.com>
On Dec 4, 2007, at 5:01 AM, Li Yang wrote:
> Only external interrupts in edge detect mode support ack operation.
> Therefore, in most cases ack is not needed. The patch makes ipic
> ack only when it's needed. This could boost over all system
> performance.
>
> Signed-off-by: Li Yang <leoli@freescale.com>
> Cc: Benjamin Herrenschmidt <benh@kernel.crashing.org>
> ---
> Update to use different irq_chip for level and edge interrupts as Ben
> suggested.
> Supercedes [PATCH] ipic: change ack operation that register is
> accessed
> only when needed
>
> arch/powerpc/sysdev/ipic.c | 113 ++++++++++++++++
> +---------------------------
> arch/powerpc/sysdev/ipic.h | 6 +--
> 2 files changed, 45 insertions(+), 74 deletions(-)
applied.
- k
^ permalink raw reply
* [PATCH 0/6] xics.c and time.c optimizations
From: Milton Miller @ 2007-12-14 4:51 UTC (permalink / raw)
To: Paul Mackerras; +Cc: linuxppc-dev
The following patches against for-2.2.25 do some optimizations related
to the usage smp_processor_id().
The xics one has been tested on SMP on 2.6.23, and still applies cleanly.
In time.c I started with the per_cpu to __get_cpu_var transformations
which affect ppc64 (the calls were added in 2.6.24), and from there
went looking for redundant global accesses from objdump -d --reloc.
I primarly looked at the pseries_defconfig and checked the results on
chrp32_defconfig.
Optimization results were checked on debian using
gcc version 4.1.2 20061115 (prerelease) (Debian 4.1.1-21)
milton
^ permalink raw reply
* [PATCH 1/6] push down or eliminate smp_processor_id in xics
From: Milton Miller @ 2007-12-14 4:52 UTC (permalink / raw)
To: Paul Mackerras; +Cc: linuxppc-dev
In-Reply-To: <mm-cpu-0@bga.com>
Delay callling smp_processor_id until its needed.
The per-processor interrupt request register and current processor
priority register are only accessed on the current cpu. In fact the
hypervisor doesn't even let us choose this.
The only function to use cpu twice is xics_migrate_irqs_away, not a fast
path. But we can cache the result of get_hard_processor_id() instead of
calling get_hard_smp_processor_id(cpu) in a loop across the call to rtas.
Years ago the irq code passed smp_processor_id into get_irq, I thought
we might initialize the CPPR third party at boot as an extra measure of
saftey, and it made the code symetric with the qirr (queued interrupt for
software generated interrupts), but now it is just extra and sometimes
unneeded work to pass it down.
Signed-off-by: Milton Miller <miltonm@bga.com>
---
Index: kernel/arch/powerpc/platforms/pseries/xics.c
===================================================================
--- kernel.orig/arch/powerpc/platforms/pseries/xics.c 2007-10-10 03:44:55.000000000 -0500
+++ kernel/arch/powerpc/platforms/pseries/xics.c 2007-10-10 04:28:58.000000000 -0500
@@ -87,19 +87,25 @@ static int ibm_int_off;
/* Direct HW low level accessors */
-static inline unsigned int direct_xirr_info_get(int n_cpu)
+static inline unsigned int direct_xirr_info_get(void)
{
- return in_be32(&xics_per_cpu[n_cpu]->xirr.word);
+ int cpu = smp_processor_id();
+
+ return in_be32(&xics_per_cpu[cpu]->xirr.word);
}
-static inline void direct_xirr_info_set(int n_cpu, int value)
+static inline void direct_xirr_info_set(int value)
{
- out_be32(&xics_per_cpu[n_cpu]->xirr.word, value);
+ int cpu = smp_processor_id();
+
+ out_be32(&xics_per_cpu[cpu]->xirr.word, value);
}
-static inline void direct_cppr_info(int n_cpu, u8 value)
+static inline void direct_cppr_info(u8 value)
{
- out_8(&xics_per_cpu[n_cpu]->xirr.bytes[0], value);
+ int cpu = smp_processor_id();
+
+ out_8(&xics_per_cpu[cpu]->xirr.bytes[0], value);
}
static inline void direct_qirr_info(int n_cpu, u8 value)
@@ -111,7 +117,7 @@ static inline void direct_qirr_info(int
/* LPAR low level accessors */
-static inline unsigned int lpar_xirr_info_get(int n_cpu)
+static inline unsigned int lpar_xirr_info_get(void)
{
unsigned long lpar_rc;
unsigned long return_value;
@@ -122,7 +128,7 @@ static inline unsigned int lpar_xirr_inf
return (unsigned int)return_value;
}
-static inline void lpar_xirr_info_set(int n_cpu, int value)
+static inline void lpar_xirr_info_set(int value)
{
unsigned long lpar_rc;
unsigned long val64 = value & 0xffffffff;
@@ -133,7 +139,7 @@ static inline void lpar_xirr_info_set(in
val64);
}
-static inline void lpar_cppr_info(int n_cpu, u8 value)
+static inline void lpar_cppr_info(u8 value)
{
unsigned long lpar_rc;
@@ -275,21 +281,19 @@ static unsigned int xics_startup(unsigne
static void xics_eoi_direct(unsigned int virq)
{
- int cpu = smp_processor_id();
unsigned int irq = (unsigned int)irq_map[virq].hwirq;
iosync();
- direct_xirr_info_set(cpu, (0xff << 24) | irq);
+ direct_xirr_info_set((0xff << 24) | irq);
}
static void xics_eoi_lpar(unsigned int virq)
{
- int cpu = smp_processor_id();
unsigned int irq = (unsigned int)irq_map[virq].hwirq;
iosync();
- lpar_xirr_info_set(cpu, (0xff << 24) | irq);
+ lpar_xirr_info_set((0xff << 24) | irq);
}
static inline unsigned int xics_remap_irq(unsigned int vec)
@@ -312,16 +316,12 @@ static inline unsigned int xics_remap_ir
static unsigned int xics_get_irq_direct(void)
{
- unsigned int cpu = smp_processor_id();
-
- return xics_remap_irq(direct_xirr_info_get(cpu));
+ return xics_remap_irq(direct_xirr_info_get());
}
static unsigned int xics_get_irq_lpar(void)
{
- unsigned int cpu = smp_processor_id();
-
- return xics_remap_irq(lpar_xirr_info_get(cpu));
+ return xics_remap_irq(lpar_xirr_info_get());
}
#ifdef CONFIG_SMP
@@ -387,12 +387,12 @@ void xics_cause_IPI(int cpu)
#endif /* CONFIG_SMP */
-static void xics_set_cpu_priority(int cpu, unsigned char cppr)
+static void xics_set_cpu_priority(unsigned char cppr)
{
if (firmware_has_feature(FW_FEATURE_LPAR))
- lpar_cppr_info(cpu, cppr);
+ lpar_cppr_info(cppr);
else
- direct_cppr_info(cpu, cppr);
+ direct_cppr_info(cppr);
iosync();
}
@@ -440,9 +440,7 @@ static void xics_set_affinity(unsigned i
void xics_setup_cpu(void)
{
- int cpu = smp_processor_id();
-
- xics_set_cpu_priority(cpu, 0xff);
+ xics_set_cpu_priority(0xff);
/*
* Put the calling processor into the GIQ. This is really only
@@ -783,7 +781,7 @@ void xics_teardown_cpu(int secondary)
unsigned int ipi;
struct irq_desc *desc;
- xics_set_cpu_priority(cpu, 0);
+ xics_set_cpu_priority(0);
/*
* Clear IPI
@@ -824,10 +822,11 @@ void xics_teardown_cpu(int secondary)
void xics_migrate_irqs_away(void)
{
int status;
- unsigned int irq, virq, cpu = smp_processor_id();
+ int cpu = smp_processor_id(), hw_cpu = hard_smp_processor_id();
+ unsigned int irq, virq;
/* Reject any interrupt that was queued to us... */
- xics_set_cpu_priority(cpu, 0);
+ xics_set_cpu_priority(0);
/* remove ourselves from the global interrupt queue */
status = rtas_set_indicator_fast(GLOBAL_INTERRUPT_QUEUE,
@@ -835,7 +834,7 @@ void xics_migrate_irqs_away(void)
WARN_ON(status < 0);
/* Allow IPIs again... */
- xics_set_cpu_priority(cpu, DEFAULT_PRIORITY);
+ xics_set_cpu_priority(DEFAULT_PRIORITY);
for_each_irq(virq) {
struct irq_desc *desc;
@@ -874,7 +873,7 @@ void xics_migrate_irqs_away(void)
* The irq has to be migrated only in the single cpu
* case.
*/
- if (xics_status[0] != get_hard_smp_processor_id(cpu))
+ if (xics_status[0] != hw_cpu)
goto unlock;
printk(KERN_WARNING "IRQ %u affinity broken off cpu %u\n",
Index: kernel/arch/powerpc/platforms/pseries/xics.h
===================================================================
--- kernel.orig/arch/powerpc/platforms/pseries/xics.h 2007-10-10 03:46:30.000000000 -0500
+++ kernel/arch/powerpc/platforms/pseries/xics.h 2007-10-10 03:48:57.000000000 -0500
@@ -21,9 +21,6 @@ extern void xics_cause_IPI(int cpu);
extern void xics_request_IPIs(void);
extern void xics_migrate_irqs_away(void);
-/* first argument is ignored for now*/
-void pSeriesLP_cppr_info(int n_cpu, u8 value);
-
struct xics_ipi_struct {
volatile unsigned long value;
} ____cacheline_aligned;
^ permalink raw reply
* [PATCH 2/6] init_decrementer_clockevent can be static __init
From: Milton Miller @ 2007-12-14 4:52 UTC (permalink / raw)
To: Paul Mackerras; +Cc: linuxppc-dev
In-Reply-To: <mm-cpu-0@bga.com>
as its only called from time_init, which is __init.
Also remove unneeded forward declaration.
Signed-off-by: Milton Miller <miltonm@bga.com>
---
Index: kernel/arch/powerpc/kernel/time.c
===================================================================
--- kernel.orig/arch/powerpc/kernel/time.c 2007-12-13 17:46:59.000000000 -0600
+++ kernel/arch/powerpc/kernel/time.c 2007-12-13 17:56:37.000000000 -0600
@@ -117,7 +117,6 @@ static struct clock_event_device decreme
};
static DEFINE_PER_CPU(struct clock_event_device, decrementers);
-void init_decrementer_clockevent(void);
static DEFINE_PER_CPU(u64, decrementer_next_tb);
#ifdef CONFIG_PPC_ISERIES
@@ -836,7 +835,7 @@ static void register_decrementer_clockev
clockevents_register_device(dec);
}
-void init_decrementer_clockevent(void)
+static void __init init_decrementer_clockevent(void)
{
int cpu = smp_processor_id();
^ permalink raw reply
* any more patches for 2.6.24?
From: Paul Mackerras @ 2007-12-14 4:52 UTC (permalink / raw)
To: linuxppc-dev
Currently I have just this one bugfix queued up to go to Linus for
2.6.24:
Stephen Rothwell (1):
[POWERPC] iSeries: don't printk with HV spinlock held
Does anyone else have bugfixes that need to go in 2.6.24?
Paul.
^ permalink raw reply
* [PATCH 3/6] use __get_cpu_var in time.c
From: Milton Miller @ 2007-12-14 4:52 UTC (permalink / raw)
To: Paul Mackerras; +Cc: linuxppc-dev
In-Reply-To: <mm-cpu-0@bga.com>
use __get_cpu_var(x) instead of per_cpu(x, smp_processor_id()), as it
is optimied on ppc64 to access the current cpus per-cpu offset directly.
Its local_paca.offset instead of TOC->paca[local_paca->processor_id].offset.
This is the trivial portion, two functions with one use each.
Signed-off-by: Milton Miller <miltonm@bga.com>
---
Index: kernel/arch/powerpc/kernel/time.c
===================================================================
--- kernel.orig/arch/powerpc/kernel/time.c 2007-12-13 20:37:03.000000000 -0600
+++ kernel/arch/powerpc/kernel/time.c 2007-12-13 20:37:03.000000000 -0600
@@ -327,7 +327,7 @@ void calculate_steal_time(void)
if (!cpu_has_feature(CPU_FTR_PURR))
return;
- pme = &per_cpu(cpu_purr_data, smp_processor_id());
+ pme = &__get_cpu_var(cpu_purr_data);
if (!pme->initialized)
return; /* this can happen in early boot */
tb = mftb();
@@ -352,7 +352,7 @@ static void snapshot_purr(void)
if (!cpu_has_feature(CPU_FTR_PURR))
return;
local_irq_save(flags);
- pme = &per_cpu(cpu_purr_data, smp_processor_id());
+ pme = &__get_cpu_var(cpu_purr_data);
pme->tb = mftb();
pme->purr = mfspr(SPRN_PURR);
pme->initialized = 1;
^ permalink raw reply
* [PATCH 4/6] timer interrupt: use a struct for two per_cpu varables
From: Milton Miller @ 2007-12-14 4:52 UTC (permalink / raw)
To: Paul Mackerras; +Cc: linuxppc-dev
In-Reply-To: <mm-cpu-0@bga.com>
timer_interrupt was calculating per_cpu_offset several times, having to
start from the toc because of potential aliasing issues.
Placing both decrementer per_cpu varables in a struct and calculating
the address once with __get_cpu_var results in better code on both 32
and 64 bit.
Signed-off-by: Milton Miller <miltonm@bga.com>
---
Index: kernel/arch/powerpc/kernel/time.c
===================================================================
--- kernel.orig/arch/powerpc/kernel/time.c 2007-12-13 17:56:37.000000000 -0600
+++ kernel/arch/powerpc/kernel/time.c 2007-12-13 18:07:13.000000000 -0600
@@ -116,8 +116,12 @@ static struct clock_event_device decreme
.features = CLOCK_EVT_FEAT_ONESHOT,
};
-static DEFINE_PER_CPU(struct clock_event_device, decrementers);
-static DEFINE_PER_CPU(u64, decrementer_next_tb);
+struct decrementer_clock {
+ struct clock_event_device event;
+ u64 next_tb;
+};
+
+static DEFINE_PER_CPU(struct decrementer_clock, decrementers);
#ifdef CONFIG_PPC_ISERIES
static unsigned long __initdata iSeries_recal_titan;
@@ -555,8 +559,8 @@ void __init iSeries_time_init_early(void
void timer_interrupt(struct pt_regs * regs)
{
struct pt_regs *old_regs;
- int cpu = smp_processor_id();
- struct clock_event_device *evt = &per_cpu(decrementers, cpu);
+ struct decrementer_clock *decrementer = &__get_cpu_var(decrementers);
+ struct clock_event_device *evt = &decrementer->event;
u64 now;
/* Ensure a positive value is written to the decrementer, or else
@@ -569,9 +573,9 @@ void timer_interrupt(struct pt_regs * re
#endif
now = get_tb_or_rtc();
- if (now < per_cpu(decrementer_next_tb, cpu)) {
+ if (now < decrementer->next_tb) {
/* not time for this event yet */
- now = per_cpu(decrementer_next_tb, cpu) - now;
+ now = decrementer->next_tb - now;
if (now <= DECREMENTER_MAX)
set_dec((int)now);
return;
@@ -810,7 +814,7 @@ void __init clocksource_init(void)
static int decrementer_set_next_event(unsigned long evt,
struct clock_event_device *dev)
{
- __get_cpu_var(decrementer_next_tb) = get_tb_or_rtc() + evt;
+ __get_cpu_var(decrementers).next_tb = get_tb_or_rtc() + evt;
set_dec(evt);
return 0;
}
@@ -824,7 +828,7 @@ static void decrementer_set_mode(enum cl
static void register_decrementer_clockevent(int cpu)
{
- struct clock_event_device *dec = &per_cpu(decrementers, cpu);
+ struct clock_event_device *dec = &per_cpu(decrementers, cpu).event;
*dec = decrementer_clockevent;
dec->cpumask = cpumask_of_cpu(cpu);
^ permalink raw reply
* [PATCH 5/6] depend on ->initialized in calc_steal_time
From: Milton Miller @ 2007-12-14 4:52 UTC (permalink / raw)
To: Paul Mackerras; +Cc: linuxppc-dev
In-Reply-To: <mm-cpu-0@bga.com>
If CPU_FTR_PURR is not set, we will never set cpu_purr_data->initialized.
Checking via __get_cpu_var on 64 bit avoids one dependent load compared
to cpu_has_feature in the not present case, and is always required when
it is present. The code is under CONFIG_VIRT_CPU_ACCOUNTING so 32 bit
will not be affected.
Signed-off-by: Milton Miller <miltonm@bga.com>
---
Index: kernel/arch/powerpc/kernel/time.c
===================================================================
--- kernel.orig/arch/powerpc/kernel/time.c 2007-12-13 18:16:10.000000000 -0600
+++ kernel/arch/powerpc/kernel/time.c 2007-12-13 18:23:55.000000000 -0600
@@ -329,11 +329,9 @@ void calculate_steal_time(void)
s64 stolen;
struct cpu_purr_data *pme;
- if (!cpu_has_feature(CPU_FTR_PURR))
- return;
pme = &__get_cpu_var(cpu_purr_data);
if (!pme->initialized)
- return; /* this can happen in early boot */
+ return; /* !CPU_FTR_PURR or early in early boot */
tb = mftb();
purr = mfspr(SPRN_PURR);
stolen = (tb - pme->tb) - (purr - pme->purr);
^ permalink raw reply
* [PATCH 6/6] optimize account_system_vtime
From: Milton Miller @ 2007-12-14 4:52 UTC (permalink / raw)
To: Paul Mackerras; +Cc: linuxppc-dev
In-Reply-To: <mm-cpu-0@bga.com>
We have multiple calls to has_feature being inlined, but gcc can't
be sure that the store via get_paca() doesn't alias the path to
cur_cpu_spec->feature.
Reorder to put the calls to read_purr and read_spurr adjacent to each
other. To add a sense of consistency, reorder the remaining lines to
perform parallel steps on purr and scaled purr of each line instead of
calculating and then using one value before going on to the next.
In addition, we can tell gcc that no SPURR means no PURR. The test is
completely hidden in the PURR case, and in the !PURR case the second test
is eliminated resulting in the simple register copy in the out-of-line
branch.
Further, gcc sees get_paca()->system_time referenced several times and
allocates a register to address it (shadowing r13) instead of caching its
value. Reading into a local varable saves the shadow of r13 and removes
a potentially duplicate load (between the nested if and its parent).
Signed-off-by: Milton Miller <miltonm@bga.com>
---
The purr and spurr fields of the paca are only used in this c code,
but system_time and user_time are also used in asm and I decided to
leave all of these fields in the paca.
Index: kernel/arch/powerpc/kernel/time.c
===================================================================
--- kernel.orig/arch/powerpc/kernel/time.c 2007-12-13 21:58:10.000000000 -0600
+++ kernel/arch/powerpc/kernel/time.c 2007-12-13 22:00:36.000000000 -0600
@@ -219,7 +219,11 @@ static u64 read_purr(void)
*/
static u64 read_spurr(u64 purr)
{
- if (cpu_has_feature(CPU_FTR_SPURR))
+ /*
+ * cpus without PURR won't have a SPURR
+ * We already know the former when we use this, so tell gcc
+ */
+ if (cpu_has_feature(CPU_FTR_PURR) && cpu_has_feature(CPU_FTR_SPURR))
return mfspr(SPRN_SPURR);
return purr;
}
@@ -230,29 +234,30 @@ static u64 read_spurr(u64 purr)
*/
void account_system_vtime(struct task_struct *tsk)
{
- u64 now, nowscaled, delta, deltascaled;
+ u64 now, nowscaled, delta, deltascaled, sys_time;
unsigned long flags;
local_irq_save(flags);
now = read_purr();
- delta = now - get_paca()->startpurr;
- get_paca()->startpurr = now;
nowscaled = read_spurr(now);
+ delta = now - get_paca()->startpurr;
deltascaled = nowscaled - get_paca()->startspurr;
+ get_paca()->startpurr = now;
get_paca()->startspurr = nowscaled;
if (!in_interrupt()) {
/* deltascaled includes both user and system time.
* Hence scale it based on the purr ratio to estimate
* the system time */
+ sys_time = get_paca()->system_time;
if (get_paca()->user_time)
- deltascaled = deltascaled * get_paca()->system_time /
- (get_paca()->system_time + get_paca()->user_time);
- delta += get_paca()->system_time;
+ deltascaled = deltascaled * sys_time /
+ (sys_time + get_paca()->user_time);
+ delta += sys_time;
get_paca()->system_time = 0;
}
account_system_time(tsk, 0, delta);
- get_paca()->purrdelta = delta;
account_system_time_scaled(tsk, deltascaled);
+ get_paca()->purrdelta = delta;
get_paca()->spurrdelta = deltascaled;
local_irq_restore(flags);
}
^ permalink raw reply
* Re: [PATCH] mpc834x_mds: Fix whitespace and call of_platform_bus_probe().
From: Kumar Gala @ 2007-12-14 4:54 UTC (permalink / raw)
To: Scott Wood; +Cc: linuxppc-dev
In-Reply-To: <20071213171905.GA4630@loki.buserror.net>
On Dec 13, 2007, at 11:19 AM, Scott Wood wrote:
> Signed-off-by: Scott Wood <scottwood@freescale.com>
> ---
> arch/powerpc/platforms/83xx/mpc834x_mds.c | 21 +++++++++++++++++++--
> 1 files changed, 19 insertions(+), 2 deletions(-)
applied.
- k
^ permalink raw reply
* [PATCH 0/15] [POWERPC] PCI updates & merges
From: Benjamin Herrenschmidt @ 2007-12-14 4:56 UTC (permalink / raw)
To: linuxppc-dev
(THIS SERIES STILL NEEDS MORE TESTING)
(This version is rebased on top of current for-2.6.25, my remaining
4xx patches will apply on top of this)
This serie of patches converts the 32 bits PCI code to use the generic
pci_assign_unassigned_resources() instead of its own assignment code
which was unable to deal with unassigned PCI<->PCI bridges among
other issues.
It then merges the resource fixup and allocation code between 32 and
64 bits (mostly making 64 bits use the 32 bits code with a few fixups),
hopefully fixing the longstanding issue that not setting pci_probe_only
on ppc64 would generally not work.
We also add flags to control the behaviour of the PCI code, such as
letting some platforms force a full re-assignment (similar to what
pci-auto used to provide in arch/ppc) and remove a whole bunch of
hackish code that is made obsolete by that change.
32 bits platforms with 64 bits resources support will also need my
separate patch to fix the generic setup-bus.c for that situation.
Finally, I also merge the implementations of pcibios_enable_device()
and fixup the PowerMac code that used hooks in that area in ways
that don't work anymore.
^ permalink raw reply
* [PATCH 1/15] [POWERPC] pci32: remove bogus alignment message
From: Benjamin Herrenschmidt @ 2007-12-14 4:56 UTC (permalink / raw)
To: linuxppc-dev
In-Reply-To: <1197608163.200976.87755569596.qpush@grosgo>
There's a stale & bogus piece of code in 32 bits PCI code that
complains about ISA related alignment issues. Just remove it.
Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>
---
arch/powerpc/kernel/pci_32.c | 6 ------
1 file changed, 6 deletions(-)
--- linux-merge.orig/arch/powerpc/kernel/pci_32.c 2007-12-14 15:49:01.000000000 +1100
+++ linux-merge/arch/powerpc/kernel/pci_32.c 2007-12-14 15:49:27.000000000 +1100
@@ -199,12 +199,6 @@ void pcibios_align_resource(void *data,
if (res->flags & IORESOURCE_IO) {
resource_size_t start = res->start;
- if (size > 0x100) {
- printk(KERN_ERR "PCI: I/O Region %s/%d too large"
- " (%lld bytes)\n", pci_name(dev),
- dev->resource - res, (unsigned long long)size);
- }
-
if (start & 0x300) {
start = (start + 0x3ff) & ~0x3ff;
res->start = start;
^ permalink raw reply
* [PATCH 2/15] [POWERPC] pci32: use generic pci_assign_unassign_resources
From: Benjamin Herrenschmidt @ 2007-12-14 4:56 UTC (permalink / raw)
To: linuxppc-dev
In-Reply-To: <1197608163.200976.87755569596.qpush@grosgo>
This makes the 32 bits PowerPC PCI code use the generic code to assign
resources to devices that had unassigned or conflicting resources.
This allow to remove the local implementation that was incomplete and
could not assign for example a PCI<->PCI bridge from scratch, which is
needed on various embedded platforms.
Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>
---
arch/powerpc/kernel/pci_32.c | 191 +++----------------------------------------
1 file changed, 17 insertions(+), 174 deletions(-)
--- linux-merge.orig/arch/powerpc/kernel/pci_32.c 2007-12-14 15:49:27.000000000 +1100
+++ linux-merge/arch/powerpc/kernel/pci_32.c 2007-12-14 15:49:27.000000000 +1100
@@ -37,10 +37,6 @@ int pcibios_assign_bus_offset = 1;
void pcibios_make_OF_bus_map(void);
-static int pci_relocate_bridge_resource(struct pci_bus *bus, int i);
-static int probe_resource(struct pci_bus *parent, struct resource *pr,
- struct resource *res, struct resource **conflict);
-static void update_bridge_base(struct pci_bus *bus, int i);
static void pcibios_fixup_resources(struct pci_dev* dev);
static void fixup_broken_pcnet32(struct pci_dev* dev);
static int reparent_resources(struct resource *parent, struct resource *res);
@@ -134,7 +130,7 @@ pcibios_fixup_resources(struct pci_dev *
if (offset != 0) {
res->start = (res->start + offset) & mask;
res->end = (res->end + offset) & mask;
- DBG("Fixup res %d (%lx) of dev %s: %llx -> %llx\n",
+ DBG("PCI: Fixup res %d (0x%lx) of dev %s: %llx -> %llx\n",
i, res->flags, pci_name(dev),
(u64)res->start - offset, (u64)res->start);
}
@@ -267,9 +263,12 @@ pcibios_allocate_bus_resources(struct li
}
}
- DBG("PCI: bridge rsrc %llx..%llx (%lx), parent %p\n",
+ DBG("PCI: dev %s (bus 0x%02x) bridge rsrc %d: %016llx..%016llx "
+ "(f:0x%08lx), parent %p\n",
+ bus->self ? pci_name(bus->self) : "PHB", bus->number, i,
(u64)res->start, (u64)res->end, res->flags, pr);
- if (pr) {
+
+ if (pr && !(pr->flags & IORESOURCE_UNSET)) {
if (request_resource(pr, res) == 0)
continue;
/*
@@ -280,10 +279,11 @@ pcibios_allocate_bus_resources(struct li
if (reparent_resources(pr, res) == 0)
continue;
}
- printk(KERN_ERR "PCI: Cannot allocate resource region "
- "%d of PCI bridge %d\n", i, bus->number);
- if (pci_relocate_bridge_resource(bus, i))
- bus->resource[i] = NULL;
+ printk(KERN_WARNING
+ "PCI: Cannot allocate resource region "
+ "%d of PCI bridge %d, will remap\n",
+ i, bus->number);
+ res->flags |= IORESOURCE_UNSET;
}
pcibios_allocate_bus_resources(&bus->children);
}
@@ -324,112 +324,6 @@ reparent_resources(struct resource *pare
return 0;
}
-/*
- * A bridge has been allocated a range which is outside the range
- * of its parent bridge, so it needs to be moved.
- */
-static int __init
-pci_relocate_bridge_resource(struct pci_bus *bus, int i)
-{
- struct resource *res, *pr, *conflict;
- resource_size_t try, size;
- struct pci_bus *parent = bus->parent;
- int j;
-
- if (parent == NULL) {
- /* shouldn't ever happen */
- printk(KERN_ERR "PCI: can't move host bridge resource\n");
- return -1;
- }
- res = bus->resource[i];
- if (res == NULL)
- return -1;
- pr = NULL;
- for (j = 0; j < 4; j++) {
- struct resource *r = parent->resource[j];
- if (!r)
- continue;
- if ((res->flags ^ r->flags) & (IORESOURCE_IO | IORESOURCE_MEM))
- continue;
- if (!((res->flags ^ r->flags) & IORESOURCE_PREFETCH)) {
- pr = r;
- break;
- }
- if (res->flags & IORESOURCE_PREFETCH)
- pr = r;
- }
- if (pr == NULL)
- return -1;
- size = res->end - res->start;
- if (pr->start > pr->end || size > pr->end - pr->start)
- return -1;
- try = pr->end;
- for (;;) {
- res->start = try - size;
- res->end = try;
- if (probe_resource(bus->parent, pr, res, &conflict) == 0)
- break;
- if (conflict->start <= pr->start + size)
- return -1;
- try = conflict->start - 1;
- }
- if (request_resource(pr, res)) {
- DBG(KERN_ERR "PCI: huh? couldn't move to %llx..%llx\n",
- (u64)res->start, (u64)res->end);
- return -1; /* "can't happen" */
- }
- update_bridge_base(bus, i);
- printk(KERN_INFO "PCI: bridge %d resource %d moved to %llx..%llx\n",
- bus->number, i, (unsigned long long)res->start,
- (unsigned long long)res->end);
- return 0;
-}
-
-static int __init
-probe_resource(struct pci_bus *parent, struct resource *pr,
- struct resource *res, struct resource **conflict)
-{
- struct pci_bus *bus;
- struct pci_dev *dev;
- struct resource *r;
- int i;
-
- for (r = pr->child; r != NULL; r = r->sibling) {
- if (r->end >= res->start && res->end >= r->start) {
- *conflict = r;
- return 1;
- }
- }
- list_for_each_entry(bus, &parent->children, node) {
- for (i = 0; i < 4; ++i) {
- if ((r = bus->resource[i]) == NULL)
- continue;
- if (!r->flags || r->start > r->end || r == res)
- continue;
- if (pci_find_parent_resource(bus->self, r) != pr)
- continue;
- if (r->end >= res->start && res->end >= r->start) {
- *conflict = r;
- return 1;
- }
- }
- }
- list_for_each_entry(dev, &parent->devices, bus_list) {
- for (i = 0; i < 6; ++i) {
- r = &dev->resource[i];
- if (!r->flags || (r->flags & IORESOURCE_UNSET))
- continue;
- if (pci_find_parent_resource(dev, r) != pr)
- continue;
- if (r->end >= res->start && res->end >= r->start) {
- *conflict = r;
- return 1;
- }
- }
- }
- return 0;
-}
-
void __init
update_bridge_resource(struct pci_dev *dev, struct resource *res)
{
@@ -486,24 +380,16 @@ update_bridge_resource(struct pci_dev *d
pci_write_config_word(dev, PCI_COMMAND, cmd);
}
-static void __init
-update_bridge_base(struct pci_bus *bus, int i)
-{
- struct resource *res = bus->resource[i];
- struct pci_dev *dev = bus->self;
- update_bridge_resource(dev, res);
-}
-
static inline void alloc_resource(struct pci_dev *dev, int idx)
{
struct resource *pr, *r = &dev->resource[idx];
- DBG("PCI:%s: Resource %d: %016llx-%016llx (f=%lx)\n",
+ DBG("PCI: Allocating %s: Resource %d: %016llx..%016llx (f=%lx)\n",
pci_name(dev), idx, (u64)r->start, (u64)r->end, r->flags);
pr = pci_find_parent_resource(dev, r);
- if (!pr || request_resource(pr, r) < 0) {
- printk(KERN_WARNING "PCI: Remapping resource region %d"
- " of device %s\n", idx, pci_name(dev));
+ if (!pr || (pr->flags & IORESOURCE_UNSET) || request_resource(pr, r) < 0) {
+ printk(KERN_WARNING "PCI: Cannot allocate resource region %d"
+ " of device %s, will remap\n", idx, pci_name(dev));
if (pr)
DBG("PCI: parent is %p: %016llx-%016llx (f=%lx)\n",
pr, (u64)pr->start, (u64)pr->end, pr->flags);
@@ -552,50 +438,6 @@ pcibios_allocate_resources(int pass)
}
}
-static void __init
-pcibios_assign_resources(void)
-{
- struct pci_dev *dev = NULL;
- int idx;
- struct resource *r;
-
- for_each_pci_dev(dev) {
- int class = dev->class >> 8;
-
- /* Don't touch classless devices and host bridges */
- if (!class || class == PCI_CLASS_BRIDGE_HOST)
- continue;
-
- for (idx = 0; idx < 6; idx++) {
- r = &dev->resource[idx];
-
- /*
- * We shall assign a new address to this resource,
- * either because the BIOS (sic) forgot to do so
- * or because we have decided the old address was
- * unusable for some reason.
- */
- if ((r->flags & IORESOURCE_UNSET) && r->end &&
- (!ppc_md.pcibios_enable_device_hook ||
- !ppc_md.pcibios_enable_device_hook(dev, 1))) {
- int rc;
-
- r->flags &= ~IORESOURCE_UNSET;
- rc = pci_assign_resource(dev, idx);
- BUG_ON(rc);
- }
- }
-
-#if 0 /* don't assign ROMs */
- r = &dev->resource[PCI_ROM_RESOURCE];
- r->end -= r->start;
- r->start = 0;
- if (r->end)
- pci_assign_resource(dev, PCI_ROM_RESOURCE);
-#endif
- }
-}
-
#ifdef CONFIG_PPC_OF
/*
* Functions below are used on OpenFirmware machines.
@@ -1122,7 +964,8 @@ pcibios_init(void)
#ifdef CONFIG_PPC_PMAC
pcibios_fixup_p2p_bridges();
#endif /* CONFIG_PPC_PMAC */
- pcibios_assign_resources();
+ DBG("PCI: Assigning unassigned resouces...\n");
+ pci_assign_unassigned_resources();
/* Call machine dependent post-init code */
if (ppc_md.pcibios_after_init)
^ permalink raw reply
* [PATCH 3/15] [POWERPC] pci32: Remove PowerMac P2P bridge IO hack
From: Benjamin Herrenschmidt @ 2007-12-14 4:56 UTC (permalink / raw)
To: linuxppc-dev
In-Reply-To: <1197608163.200976.87755569596.qpush@grosgo>
The 32 bits PowerPC PCI code has a hack for use by some PowerMacs
to try to re-open PCI<->PCI bridge IO resources that were closed
by the firmware. This is no longer necessary as the generic code
will now do that for us.
Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>
---
arch/powerpc/kernel/pci_32.c | 215 -------------------------------------------
1 file changed, 1 insertion(+), 214 deletions(-)
--- linux-merge.orig/arch/powerpc/kernel/pci_32.c 2007-12-14 15:49:27.000000000 +1100
+++ linux-merge/arch/powerpc/kernel/pci_32.c 2007-12-14 15:49:28.000000000 +1100
@@ -711,217 +711,6 @@ void pcibios_make_OF_bus_map(void)
}
#endif /* CONFIG_PPC_OF */
-#ifdef CONFIG_PPC_PMAC
-/*
- * This set of routines checks for PCI<->PCI bridges that have closed
- * IO resources and have child devices. It tries to re-open an IO
- * window on them.
- *
- * This is a _temporary_ fix to workaround a problem with Apple's OF
- * closing IO windows on P2P bridges when the OF drivers of cards
- * below this bridge don't claim any IO range (typically ATI or
- * Adaptec).
- *
- * A more complete fix would be to use drivers/pci/setup-bus.c, which
- * involves a working pcibios_fixup_pbus_ranges(), some more care about
- * ordering when creating the host bus resources, and maybe a few more
- * minor tweaks
- */
-
-/* Initialize bridges with base/limit values we have collected */
-static void __init
-do_update_p2p_io_resource(struct pci_bus *bus, int enable_vga)
-{
- struct pci_dev *bridge = bus->self;
- struct pci_controller* hose = (struct pci_controller *)bridge->sysdata;
- u32 l;
- u16 w;
- struct resource res;
-
- if (bus->resource[0] == NULL)
- return;
- res = *(bus->resource[0]);
-
- DBG("Remapping Bus %d, bridge: %s\n", bus->number, pci_name(bridge));
- res.start -= ((unsigned long) hose->io_base_virt - isa_io_base);
- res.end -= ((unsigned long) hose->io_base_virt - isa_io_base);
- DBG(" IO window: %016llx-%016llx\n", res.start, res.end);
-
- /* Set up the top and bottom of the PCI I/O segment for this bus. */
- pci_read_config_dword(bridge, PCI_IO_BASE, &l);
- l &= 0xffff000f;
- l |= (res.start >> 8) & 0x00f0;
- l |= res.end & 0xf000;
- pci_write_config_dword(bridge, PCI_IO_BASE, l);
-
- if ((l & PCI_IO_RANGE_TYPE_MASK) == PCI_IO_RANGE_TYPE_32) {
- l = (res.start >> 16) | (res.end & 0xffff0000);
- pci_write_config_dword(bridge, PCI_IO_BASE_UPPER16, l);
- }
-
- pci_read_config_word(bridge, PCI_COMMAND, &w);
- w |= PCI_COMMAND_IO;
- pci_write_config_word(bridge, PCI_COMMAND, w);
-
-#if 0 /* Enabling this causes XFree 4.2.0 to hang during PCI probe */
- if (enable_vga) {
- pci_read_config_word(bridge, PCI_BRIDGE_CONTROL, &w);
- w |= PCI_BRIDGE_CTL_VGA;
- pci_write_config_word(bridge, PCI_BRIDGE_CONTROL, w);
- }
-#endif
-}
-
-/* This function is pretty basic and actually quite broken for the
- * general case, it's enough for us right now though. It's supposed
- * to tell us if we need to open an IO range at all or not and what
- * size.
- */
-static int __init
-check_for_io_childs(struct pci_bus *bus, struct resource* res, int *found_vga)
-{
- struct pci_dev *dev;
- int i;
- int rc = 0;
-
-#define push_end(res, mask) do { \
- BUG_ON((mask+1) & mask); \
- res->end = (res->end + mask) | mask; \
-} while (0)
-
- list_for_each_entry(dev, &bus->devices, bus_list) {
- u16 class = dev->class >> 8;
-
- if (class == PCI_CLASS_DISPLAY_VGA ||
- class == PCI_CLASS_NOT_DEFINED_VGA)
- *found_vga = 1;
- if (class >> 8 == PCI_BASE_CLASS_BRIDGE && dev->subordinate)
- rc |= check_for_io_childs(dev->subordinate, res, found_vga);
- if (class == PCI_CLASS_BRIDGE_CARDBUS)
- push_end(res, 0xfff);
-
- for (i=0; i<PCI_NUM_RESOURCES; i++) {
- struct resource *r;
- unsigned long r_size;
-
- if (dev->class >> 8 == PCI_CLASS_BRIDGE_PCI
- && i >= PCI_BRIDGE_RESOURCES)
- continue;
- r = &dev->resource[i];
- r_size = r->end - r->start;
- if (r_size < 0xfff)
- r_size = 0xfff;
- if (r->flags & IORESOURCE_IO && (r_size) != 0) {
- rc = 1;
- push_end(res, r_size);
- }
- }
- }
-
- return rc;
-}
-
-/* Here we scan all P2P bridges of a given level that have a closed
- * IO window. Note that the test for the presence of a VGA card should
- * be improved to take into account already configured P2P bridges,
- * currently, we don't see them and might end up configuring 2 bridges
- * with VGA pass through enabled
- */
-static void __init
-do_fixup_p2p_level(struct pci_bus *bus)
-{
- struct pci_bus *b;
- int i, parent_io;
- int has_vga = 0;
-
- for (parent_io=0; parent_io<4; parent_io++)
- if (bus->resource[parent_io]
- && bus->resource[parent_io]->flags & IORESOURCE_IO)
- break;
- if (parent_io >= 4)
- return;
-
- list_for_each_entry(b, &bus->children, node) {
- struct pci_dev *d = b->self;
- struct pci_controller* hose = (struct pci_controller *)d->sysdata;
- struct resource *res = b->resource[0];
- struct resource tmp_res;
- unsigned long max;
- int found_vga = 0;
-
- memset(&tmp_res, 0, sizeof(tmp_res));
- tmp_res.start = bus->resource[parent_io]->start;
-
- /* We don't let low addresses go through that closed P2P bridge, well,
- * that may not be necessary but I feel safer that way
- */
- if (tmp_res.start == 0)
- tmp_res.start = 0x1000;
-
- if (!list_empty(&b->devices) && res && res->flags == 0 &&
- res != bus->resource[parent_io] &&
- (d->class >> 8) == PCI_CLASS_BRIDGE_PCI &&
- check_for_io_childs(b, &tmp_res, &found_vga)) {
- u8 io_base_lo;
-
- printk(KERN_INFO "Fixing up IO bus %s\n", b->name);
-
- if (found_vga) {
- if (has_vga) {
- printk(KERN_WARNING "Skipping VGA, already active"
- " on bus segment\n");
- found_vga = 0;
- } else
- has_vga = 1;
- }
- pci_read_config_byte(d, PCI_IO_BASE, &io_base_lo);
-
- if ((io_base_lo & PCI_IO_RANGE_TYPE_MASK) == PCI_IO_RANGE_TYPE_32)
- max = ((unsigned long) hose->io_base_virt
- - isa_io_base) + 0xffffffff;
- else
- max = ((unsigned long) hose->io_base_virt
- - isa_io_base) + 0xffff;
-
- *res = tmp_res;
- res->flags = IORESOURCE_IO;
- res->name = b->name;
-
- /* Find a resource in the parent where we can allocate */
- for (i = 0 ; i < 4; i++) {
- struct resource *r = bus->resource[i];
- if (!r)
- continue;
- if ((r->flags & IORESOURCE_IO) == 0)
- continue;
- DBG("Trying to allocate from %016llx, size %016llx from parent"
- " res %d: %016llx -> %016llx\n",
- res->start, res->end, i, r->start, r->end);
-
- if (allocate_resource(r, res, res->end + 1, res->start, max,
- res->end + 1, NULL, NULL) < 0) {
- DBG("Failed !\n");
- continue;
- }
- do_update_p2p_io_resource(b, found_vga);
- break;
- }
- }
- do_fixup_p2p_level(b);
- }
-}
-
-static void
-pcibios_fixup_p2p_bridges(void)
-{
- struct pci_bus *b;
-
- list_for_each_entry(b, &pci_root_buses, node)
- do_fixup_p2p_level(b);
-}
-
-#endif /* CONFIG_PPC_PMAC */
-
static int __init
pcibios_init(void)
{
@@ -961,9 +750,7 @@ pcibios_init(void)
pcibios_allocate_bus_resources(&pci_root_buses);
pcibios_allocate_resources(0);
pcibios_allocate_resources(1);
-#ifdef CONFIG_PPC_PMAC
- pcibios_fixup_p2p_bridges();
-#endif /* CONFIG_PPC_PMAC */
+
DBG("PCI: Assigning unassigned resouces...\n");
pci_assign_unassigned_resources();
^ permalink raw reply
* [PATCH 4/15] [POWERPC] pci32: Add flags modifying the PCI code behaviour
From: Benjamin Herrenschmidt @ 2007-12-14 4:56 UTC (permalink / raw)
To: linuxppc-dev
In-Reply-To: <1197608163.200976.87755569596.qpush@grosgo>
This adds to the 32 bits PCI code some flags, replacing the old
pci_assign_all_busses global, that allow to control various
aspects of the PCI probing, such as whether to re-assign all
resources or not, or to not try to assign anything at all.
This also adds the flag x86 already has to avoid ISA alignment
on bridges that don't have ISA forwarding enabled (no legacy
devices on the top level bus) and sets it for PowerMacs.
Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>
---
arch/powerpc/kernel/pci_32.c | 42 ++++++++++++++++++++++++------
arch/powerpc/kernel/pci_64.c | 1
arch/powerpc/kernel/rtas_pci.c | 6 ++--
arch/powerpc/platforms/52xx/mpc52xx_pci.c | 2 -
arch/powerpc/platforms/82xx/pq2.c | 2 -
arch/powerpc/platforms/83xx/pci.c | 2 -
arch/powerpc/platforms/chrp/pci.c | 2 -
arch/powerpc/platforms/powermac/pci.c | 7 +++--
arch/powerpc/sysdev/fsl_pci.c | 2 -
arch/powerpc/sysdev/grackle.c | 2 -
include/asm-powerpc/pci-bridge.h | 20 ++++++++++++++
include/asm-powerpc/pci.h | 9 ++++--
12 files changed, 75 insertions(+), 22 deletions(-)
--- linux-merge.orig/arch/powerpc/kernel/pci_32.c 2007-12-14 15:49:28.000000000 +1100
+++ linux-merge/arch/powerpc/kernel/pci_32.c 2007-12-14 15:49:29.000000000 +1100
@@ -35,6 +35,9 @@ unsigned long isa_io_base = 0;
unsigned long pci_dram_offset = 0;
int pcibios_assign_bus_offset = 1;
+/* Default PCI flags is 0 */
+unsigned int ppc_pci_flags;
+
void pcibios_make_OF_bus_map(void);
static void pcibios_fixup_resources(struct pci_dev* dev);
@@ -48,7 +51,7 @@ static u8* pci_to_OF_bus_map;
/* By default, we don't re-assign bus numbers. We do this only on
* some pmacs
*/
-int pci_assign_all_buses;
+static int pci_assign_all_buses;
LIST_HEAD(hose_list);
@@ -174,6 +177,14 @@ void pcibios_bus_to_resource(struct pci_
}
EXPORT_SYMBOL(pcibios_bus_to_resource);
+static int skip_isa_ioresource_align(struct pci_dev *dev)
+{
+ if ((ppc_pci_flags & PPC_PCI_CAN_SKIP_ISA_ALIGN) &&
+ !(dev->bus->bridge_ctl & PCI_BRIDGE_CTL_ISA))
+ return 1;
+ return 0;
+}
+
/*
* We need to avoid collisions with `mirrored' VGA ports
* and other strange ISA hardware, so we always want the
@@ -195,6 +206,8 @@ void pcibios_align_resource(void *data,
if (res->flags & IORESOURCE_IO) {
resource_size_t start = res->start;
+ if (skip_isa_ioresource_align(dev))
+ return;
if (start & 0x300) {
start = (start + 0x3ff) & ~0x3ff;
res->start = start;
@@ -251,8 +264,13 @@ pcibios_allocate_bus_resources(struct li
continue;
if (bus->parent == NULL)
pr = (res->flags & IORESOURCE_IO)?
- &ioport_resource: &iomem_resource;
+ &ioport_resource : &iomem_resource;
else {
+ /* Don't bother with non-root busses when
+ * re-assigning all resources.
+ */
+ if (ppc_pci_flags & PPC_PCI_REASSIGN_ALL_RSRC)
+ continue;
pr = pci_find_parent_resource(bus->self, res);
if (pr == res) {
/* this happens when the generic PCI
@@ -720,6 +738,9 @@ pcibios_init(void)
printk(KERN_INFO "PCI: Probing PCI hardware\n");
+ if (ppc_pci_flags & PPC_PCI_REASSIGN_ALL_BUS)
+ pci_assign_all_buses = 1;
+
/* Scan all of the recorded PCI controllers. */
list_for_each_entry_safe(hose, tmp, &hose_list, list_node) {
if (pci_assign_all_buses)
@@ -746,13 +767,18 @@ pcibios_init(void)
if (ppc_md.pcibios_fixup)
ppc_md.pcibios_fixup();
- /* Allocate and assign resources */
+ /* Allocate and assign resources. If we re-assign everything, then
+ * we skip the allocate phase
+ */
pcibios_allocate_bus_resources(&pci_root_buses);
- pcibios_allocate_resources(0);
- pcibios_allocate_resources(1);
-
- DBG("PCI: Assigning unassigned resouces...\n");
- pci_assign_unassigned_resources();
+ if (!(ppc_pci_flags & PPC_PCI_REASSIGN_ALL_RSRC)) {
+ pcibios_allocate_resources(0);
+ pcibios_allocate_resources(1);
+ }
+ if (!(ppc_pci_flags & PPC_PCI_PROBE_ONLY)) {
+ DBG("PCI: Assigning unassigned resouces...\n");
+ pci_assign_unassigned_resources();
+ }
/* Call machine dependent post-init code */
if (ppc_md.pcibios_after_init)
Index: linux-merge/arch/powerpc/kernel/pci_64.c
===================================================================
--- linux-merge.orig/arch/powerpc/kernel/pci_64.c 2007-12-14 15:49:00.000000000 +1100
+++ linux-merge/arch/powerpc/kernel/pci_64.c 2007-12-14 15:49:29.000000000 +1100
@@ -40,7 +40,6 @@
#endif
unsigned long pci_probe_only = 1;
-int pci_assign_all_buses = 0;
static void fixup_resource(struct resource *res, struct pci_dev *dev);
static void do_bus_setup(struct pci_bus *bus);
Index: linux-merge/arch/powerpc/kernel/rtas_pci.c
===================================================================
--- linux-merge.orig/arch/powerpc/kernel/rtas_pci.c 2007-12-14 15:49:00.000000000 +1100
+++ linux-merge/arch/powerpc/kernel/rtas_pci.c 2007-12-14 15:49:29.000000000 +1100
@@ -311,10 +311,12 @@ void __init find_and_init_phbs(void)
if (prop)
pci_probe_only = *prop;
+#ifdef CONFIG_PPC32 /* Will be made generic soon */
prop = of_get_property(of_chosen,
"linux,pci-assign-all-buses", NULL);
- if (prop)
- pci_assign_all_buses = *prop;
+ if (prop && *prop)
+ ppc_pci_flags |= PPC_PCI_REASSIGN_ALL_BUS;
+#endif /* CONFIG_PPC32 */
}
}
Index: linux-merge/arch/powerpc/platforms/52xx/mpc52xx_pci.c
===================================================================
--- linux-merge.orig/arch/powerpc/platforms/52xx/mpc52xx_pci.c 2007-12-14 15:49:00.000000000 +1100
+++ linux-merge/arch/powerpc/platforms/52xx/mpc52xx_pci.c 2007-12-14 15:49:29.000000000 +1100
@@ -363,7 +363,7 @@ mpc52xx_add_bridge(struct device_node *n
pr_debug("Adding MPC52xx PCI host bridge %s\n", node->full_name);
- pci_assign_all_buses = 1;
+ ppc_pci_flags |= PPC_PCI_REASSIGN_ALL_BUS;
if (of_address_to_resource(node, 0, &rsrc) != 0) {
printk(KERN_ERR "Can't get %s resources\n", node->full_name);
Index: linux-merge/arch/powerpc/platforms/82xx/pq2.c
===================================================================
--- linux-merge.orig/arch/powerpc/platforms/82xx/pq2.c 2007-12-14 15:49:00.000000000 +1100
+++ linux-merge/arch/powerpc/platforms/82xx/pq2.c 2007-12-14 15:49:29.000000000 +1100
@@ -53,7 +53,7 @@ static void __init pq2_pci_add_bridge(st
if (of_address_to_resource(np, 0, &r) || r.end - r.start < 0x10b)
goto err;
- pci_assign_all_buses = 1;
+ ppc_pci_flags |= PPC_PCI_REASSIGN_ALL_BUS;
hose = pcibios_alloc_controller(np);
if (!hose)
Index: linux-merge/arch/powerpc/platforms/83xx/pci.c
===================================================================
--- linux-merge.orig/arch/powerpc/platforms/83xx/pci.c 2007-12-14 15:49:00.000000000 +1100
+++ linux-merge/arch/powerpc/platforms/83xx/pci.c 2007-12-14 15:49:29.000000000 +1100
@@ -54,7 +54,7 @@ int __init mpc83xx_add_bridge(struct dev
" bus 0\n", dev->full_name);
}
- pci_assign_all_buses = 1;
+ ppc_pci_flags |= PPC_PCI_REASSIGN_ALL_BUS;
hose = pcibios_alloc_controller(dev);
if (!hose)
return -ENOMEM;
Index: linux-merge/arch/powerpc/platforms/chrp/pci.c
===================================================================
--- linux-merge.orig/arch/powerpc/platforms/chrp/pci.c 2007-12-14 15:49:00.000000000 +1100
+++ linux-merge/arch/powerpc/platforms/chrp/pci.c 2007-12-14 15:49:29.000000000 +1100
@@ -198,7 +198,7 @@ static void __init setup_peg2(struct pci
printk ("RTAS supporting Pegasos OF not found, please upgrade"
" your firmware\n");
}
- pci_assign_all_buses = 1;
+ ppc_pci_flags |= PPC_PCI_REASSIGN_ALL_BUS;
/* keep the reference to the root node */
}
Index: linux-merge/arch/powerpc/platforms/powermac/pci.c
===================================================================
--- linux-merge.orig/arch/powerpc/platforms/powermac/pci.c 2007-12-14 15:49:00.000000000 +1100
+++ linux-merge/arch/powerpc/platforms/powermac/pci.c 2007-12-14 15:49:29.000000000 +1100
@@ -725,7 +725,7 @@ static void __init setup_bandit(struct p
static int __init setup_uninorth(struct pci_controller *hose,
struct resource *addr)
{
- pci_assign_all_buses = 1;
+ ppc_pci_flags |= PPC_PCI_REASSIGN_ALL_BUS;
has_uninorth = 1;
hose->ops = ¯isc_pci_ops;
hose->cfg_addr = ioremap(addr->start + 0x800000, 0x1000);
@@ -994,6 +994,9 @@ void __init pmac_pci_init(void)
struct device_node *np, *root;
struct device_node *ht = NULL;
+#ifdef CONFIG_PPC32
+ ppc_pci_flags = PPC_PCI_CAN_SKIP_ISA_ALIGN;
+#endif
root = of_find_node_by_path("/");
if (root == NULL) {
printk(KERN_CRIT "pmac_pci_init: can't find root "
@@ -1051,7 +1054,7 @@ void __init pmac_pci_init(void)
* some offset between bus number and domains for now when we
* assign all busses should help for now
*/
- if (pci_assign_all_buses)
+ if (ppc_pci_flags & PPC_PCI_REASSIGN_ALL_BUS)
pcibios_assign_bus_offset = 0x10;
#endif
}
Index: linux-merge/arch/powerpc/sysdev/fsl_pci.c
===================================================================
--- linux-merge.orig/arch/powerpc/sysdev/fsl_pci.c 2007-12-14 15:49:00.000000000 +1100
+++ linux-merge/arch/powerpc/sysdev/fsl_pci.c 2007-12-14 15:49:29.000000000 +1100
@@ -202,7 +202,7 @@ int __init fsl_add_bridge(struct device_
printk(KERN_WARNING "Can't get bus-range for %s, assume"
" bus 0\n", dev->full_name);
- pci_assign_all_buses = 1;
+ ppc_pci_flags |= PPC_PCI_REASSIGN_ALL_BUS;
hose = pcibios_alloc_controller(dev);
if (!hose)
return -ENOMEM;
Index: linux-merge/arch/powerpc/sysdev/grackle.c
===================================================================
--- linux-merge.orig/arch/powerpc/sysdev/grackle.c 2007-12-14 15:49:00.000000000 +1100
+++ linux-merge/arch/powerpc/sysdev/grackle.c 2007-12-14 15:49:29.000000000 +1100
@@ -57,7 +57,7 @@ void __init setup_grackle(struct pci_con
{
setup_indirect_pci(hose, 0xfec00000, 0xfee00000, 0);
if (machine_is_compatible("PowerMac1,1"))
- pci_assign_all_buses = 1;
+ ppc_pci_flags |= PPC_PCI_REASSIGN_ALL_BUS;
if (machine_is_compatible("AAPL,PowerBook1998"))
grackle_set_loop_snoop(hose, 1);
#if 0 /* Disabled for now, HW problems ??? */
Index: linux-merge/include/asm-powerpc/pci-bridge.h
===================================================================
--- linux-merge.orig/include/asm-powerpc/pci-bridge.h 2007-12-14 15:49:01.000000000 +1100
+++ linux-merge/include/asm-powerpc/pci-bridge.h 2007-12-14 15:49:29.000000000 +1100
@@ -13,6 +13,26 @@
struct device_node;
+extern unsigned int ppc_pci_flags;
+enum {
+ /* Force re-assigning all resources (ignore firmware
+ * setup completely)
+ */
+ PPC_PCI_REASSIGN_ALL_RSRC = 0x00000001,
+
+ /* Re-assign all bus numbers */
+ PPC_PCI_REASSIGN_ALL_BUS = 0x00000002,
+
+ /* Do not try to assign, just use existing setup */
+ PPC_PCI_PROBE_ONLY = 0x00000004,
+
+ /* Don't bother with ISA alignment unless the bridge has
+ * ISA forwarding enabled
+ */
+ PPC_PCI_CAN_SKIP_ISA_ALIGN = 0x00000008,
+};
+
+
/*
* Structure of a PCI controller (host bridge)
*/
Index: linux-merge/include/asm-powerpc/pci.h
===================================================================
--- linux-merge.orig/include/asm-powerpc/pci.h 2007-12-14 15:49:01.000000000 +1100
+++ linux-merge/include/asm-powerpc/pci.h 2007-12-14 15:49:29.000000000 +1100
@@ -38,9 +38,12 @@ struct pci_dev;
* Set this to 1 if you want the kernel to re-assign all PCI
* bus numbers
*/
-extern int pci_assign_all_buses;
-#define pcibios_assign_all_busses() (pci_assign_all_buses)
-
+#ifdef CONFIG_PPC64
+#define pcibios_assign_all_busses() 0
+#else
+#define pcibios_assign_all_busses() (ppc_pci_flags & \
+ PPC_PCI_REASSIGN_ALL_BUS)
+#endif
#define pcibios_scan_all_fns(a, b) 0
static inline void pcibios_set_master(struct pci_dev *dev)
^ permalink raw reply
* [PATCH 5/15] [POWERPC] pci32: Remove obsolete PowerMac bus number hack
From: Benjamin Herrenschmidt @ 2007-12-14 4:56 UTC (permalink / raw)
To: linuxppc-dev
In-Reply-To: <1197608163.200976.87755569596.qpush@grosgo>
The 32 bits PCI code carries an old hack that was only useful for G5
machines. Nowdays, the 32 bits kernel doesn't support any of those
machines anymore so the hack is basically never used, remove it.
Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>
---
arch/powerpc/kernel/pci_32.c | 11 -----------
1 file changed, 11 deletions(-)
--- linux-merge.orig/arch/powerpc/kernel/pci_32.c 2007-12-14 15:49:29.000000000 +1100
+++ linux-merge/arch/powerpc/kernel/pci_32.c 2007-12-14 15:49:29.000000000 +1100
@@ -922,17 +922,6 @@ long sys_pciconfig_iobase(long which, un
struct pci_controller* hose;
long result = -EOPNOTSUPP;
- /* Argh ! Please forgive me for that hack, but that's the
- * simplest way to get existing XFree to not lockup on some
- * G5 machines... So when something asks for bus 0 io base
- * (bus 0 is HT root), we return the AGP one instead.
- */
-#ifdef CONFIG_PPC_PMAC
- if (machine_is(powermac) && machine_is_compatible("MacRISC4"))
- if (bus == 0)
- bus = 0xf0;
-#endif /* CONFIG_PPC_PMAC */
-
hose = pci_bus_to_hose(bus);
if (!hose)
return -ENODEV;
^ permalink raw reply
* [PATCH 6/15] [POWERPC] pci32: Add platform option to enable /proc PCI domains
From: Benjamin Herrenschmidt @ 2007-12-14 4:56 UTC (permalink / raw)
To: linuxppc-dev
In-Reply-To: <1197608163.200976.87755569596.qpush@grosgo>
This adds flags the platforms can use to enable domain numbers
in /proc/bus/pci.
Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>
---
arch/powerpc/kernel/pci-common.c | 16 ++++++++++++++++
arch/powerpc/kernel/pci_64.c | 8 --------
include/asm-powerpc/pci-bridge.h | 5 +++++
include/asm-powerpc/pci.h | 14 ++++----------
4 files changed, 25 insertions(+), 18 deletions(-)
--- linux-merge.orig/arch/powerpc/kernel/pci-common.c 2007-12-14 15:49:00.000000000 +1100
+++ linux-merge/arch/powerpc/kernel/pci-common.c 2007-12-14 15:49:30.000000000 +1100
@@ -639,3 +639,19 @@ void __devinit pci_process_bridge_OF_ran
hose->mem_resources[memno-1] = tmp;
}
}
+
+/* Decide whether to display the domain number in /proc */
+int pci_proc_domain(struct pci_bus *bus)
+{
+ struct pci_controller *hose = pci_bus_to_host(bus);
+#ifdef CONFIG_PPC64
+ return hose->buid != 0;
+#else
+ if (!(ppc_pci_flags & PPC_PCI_ENABLE_PROC_DOMAINS))
+ return 0;
+ if (ppc_pci_flags & PPC_PCI_COMPAT_DOMAIN_0)
+ return hose->global_number != 0;
+ return 1;
+#endif
+}
+
Index: linux-merge/arch/powerpc/kernel/pci_64.c
===================================================================
--- linux-merge.orig/arch/powerpc/kernel/pci_64.c 2007-12-14 15:49:29.000000000 +1100
+++ linux-merge/arch/powerpc/kernel/pci_64.c 2007-12-14 15:49:30.000000000 +1100
@@ -570,14 +570,6 @@ int pcibios_enable_device(struct pci_dev
return 0;
}
-/* Decide whether to display the domain number in /proc */
-int pci_proc_domain(struct pci_bus *bus)
-{
- struct pci_controller *hose = pci_bus_to_host(bus);
- return hose->buid != 0;
-}
-
-
#ifdef CONFIG_HOTPLUG
int pcibios_unmap_io_space(struct pci_bus *bus)
Index: linux-merge/include/asm-powerpc/pci-bridge.h
===================================================================
--- linux-merge.orig/include/asm-powerpc/pci-bridge.h 2007-12-14 15:49:29.000000000 +1100
+++ linux-merge/include/asm-powerpc/pci-bridge.h 2007-12-14 15:49:30.000000000 +1100
@@ -30,6 +30,11 @@ enum {
* ISA forwarding enabled
*/
PPC_PCI_CAN_SKIP_ISA_ALIGN = 0x00000008,
+
+ /* Enable domain numbers in /proc */
+ PPC_PCI_ENABLE_PROC_DOMAINS = 0x00000010,
+ /* ... except for domain 0 */
+ PPC_PCI_COMPAT_DOMAIN_0 = 0x00000020,
};
Index: linux-merge/include/asm-powerpc/pci.h
===================================================================
--- linux-merge.orig/include/asm-powerpc/pci.h 2007-12-14 15:49:29.000000000 +1100
+++ linux-merge/include/asm-powerpc/pci.h 2007-12-14 15:49:30.000000000 +1100
@@ -98,9 +98,6 @@ static inline void pci_dma_burst_advice(
#define get_pci_dma_ops() NULL
#endif
-/* Decide whether to display the domain number in /proc */
-extern int pci_proc_domain(struct pci_bus *bus);
-
#else /* 32-bit */
#ifdef CONFIG_PCI
@@ -112,17 +109,14 @@ static inline void pci_dma_burst_advice(
*strategy_parameter = ~0UL;
}
#endif
-
-/* Set the name of the bus as it appears in /proc/bus/pci */
-static inline int pci_proc_domain(struct pci_bus *bus)
-{
- return 0;
-}
-
#endif /* CONFIG_PPC64 */
extern int pci_domain_nr(struct pci_bus *bus);
+/* Decide whether to display the domain number in /proc */
+extern int pci_proc_domain(struct pci_bus *bus);
+
+
struct vm_area_struct;
/* Map a range of PCI memory or I/O space for a device into user space */
int pci_mmap_page_range(struct pci_dev *pdev, struct vm_area_struct *vma,
^ permalink raw reply
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox