* [PATCH 3/3] [POWERPC] MPC8349E-mITX: Vitesse 7385 PHY is not connected to the MDIO bus
From: Vitaly Bordug @ 2007-12-06 22:51 UTC (permalink / raw)
To: Paul Mackerras; +Cc: netdev, linuxppc-dev
In-Reply-To: <20071206225121.31080.86606.stgit@localhost.localdomain>
...thus use fixed-link to register proper "Fixed PHY"
Signed-off-by: Anton Vorontsov <avorontsov@ru.mvista.com>
Signed-off-by: Vitaly Bordug <vitb@kernel.crashing.org>
---
arch/powerpc/boot/dts/mpc8349emitx.dts | 11 ++---------
1 files changed, 2 insertions(+), 9 deletions(-)
diff --git a/arch/powerpc/boot/dts/mpc8349emitx.dts b/arch/powerpc/boot/dts/mpc8349emitx.dts
index 5072f6d..877ee6d 100644
--- a/arch/powerpc/boot/dts/mpc8349emitx.dts
+++ b/arch/powerpc/boot/dts/mpc8349emitx.dts
@@ -115,14 +115,6 @@
reg = <1c>;
device_type = "ethernet-phy";
};
-
- /* Vitesse 7385 */
- phy1f: ethernet-phy@1f {
- interrupt-parent = < &ipic >;
- interrupts = <12 8>;
- reg = <1f>;
- device_type = "ethernet-phy";
- };
};
ethernet@24000 {
@@ -159,7 +151,8 @@
local-mac-address = [ 00 00 00 00 00 00 ];
interrupts = <23 8 24 8 25 8>;
interrupt-parent = < &ipic >;
- phy-handle = < &phy1f >;
+ /* Vitesse 7385 isn't on the MDIO bus */
+ fixed-link = <1 1 d#1000 0 0>;
linux,network-index = <1>;
};
^ permalink raw reply related
* Re: [PATCH 1/5] PowerPC 74xx: Katana Qp device tree
From: Mark A. Greer @ 2007-12-06 23:27 UTC (permalink / raw)
To: David Gibson; +Cc: linuxppc-dev
In-Reply-To: <20071204025032.GH32577@localhost.localdomain>
David, et. al.,
This is a big blob patch of what I've changed for the prpmc2800. It
includes the necessary changes in the kernel which you can probably
ignore but they're there for reference. If you like the dts, then I'll
split the blob up into logical pieces and Andrei can make similar
changes for the Katana Qp.
Let me know what you think.
Mark
---
This patch is based on the latest powerpc.git tree
(44032af0e7d5467b12f998dbf2f1cd23c5324fd5) with the following patches
applied:
http://patchwork.ozlabs.org/linuxppc/patch?id=14339
http://patchwork.ozlabs.org/linuxppc/patch?id=14397
http://patchwork.ozlabs.org/linuxppc/patch?id=14396
http://patchwork.ozlabs.org/linuxppc/patch?id=14631
http://patchwork.ozlabs.org/linuxppc/patch?id=14632
http://patchwork.ozlabs.org/linuxppc/patch?id=14633
http://patchwork.ozlabs.org/linuxppc/patch?id=15007
arch/powerpc/boot/dts/prpmc2800.dts | 320 +++++++--------
arch/powerpc/boot/mpsc.c | 2
arch/powerpc/boot/serial.c | 2
arch/powerpc/platforms/embedded6xx/prpmc2800.c | 4
arch/powerpc/sysdev/mv64x60_dev.c | 29 -
arch/powerpc/sysdev/mv64x60_pci.c | 6
arch/powerpc/sysdev/mv64x60_pic.c | 4
arch/powerpc/sysdev/mv64x60_udbg.c | 4
8 files changed, 181 insertions(+), 190 deletions(-)
diff --git a/arch/powerpc/boot/dts/prpmc2800.dts b/arch/powerpc/boot/dts/prpmc2800.dts
index 24944ca..080130e 100644
--- a/arch/powerpc/boot/dts/prpmc2800.dts
+++ b/arch/powerpc/boot/dts/prpmc2800.dts
@@ -11,6 +11,8 @@
* if it can determine the exact PrPMC type.
*/
+/dts-v1/;
+
/ {
#address-cells = <1>;
#size-cells = <1>;
@@ -25,64 +27,64 @@
PowerPC,7447 {
device_type = "cpu";
reg = <0>;
- clock-frequency = <2bb0b140>; /* Default (733 MHz) */
- bus-frequency = <7f28155>; /* 133.333333 MHz */
- timebase-frequency = <1fca055>; /* 33.333333 MHz */
- i-cache-line-size = <20>;
- d-cache-line-size = <20>;
- i-cache-size = <8000>;
- d-cache-size = <8000>;
+ clock-frequency = <733333333>; /* Default */
+ bus-frequency = <133333333>;
+ timebase-frequency = <33333333>;
+ i-cache-line-size = <0x20>;
+ d-cache-line-size = <0x20>;
+ i-cache-size = <0x8000>;
+ d-cache-size = <0x8000>;
};
};
memory {
device_type = "memory";
- reg = <00000000 20000000>; /* Default (512MB) */
+ reg = <0x00000000 0x20000000>; /* Default (512MB) */
};
mv64x60@f1000000 { /* Marvell Discovery */
#address-cells = <1>;
#size-cells = <1>;
model = "mv64360"; /* Default */
- compatible = "marvell,mv64x60";
- clock-frequency = <7f28155>; /* 133.333333 MHz */
- reg = <f1000000 00010000>;
- virtual-reg = <f1000000>;
- ranges = <88000000 88000000 01000000 /* PCI 0 I/O Space */
- 80000000 80000000 08000000 /* PCI 0 MEM Space */
- a0000000 a0000000 04000000 /* User FLASH */
- 00000000 f1000000 00010000 /* Bridge's regs */
- f2000000 f2000000 00040000>; /* Integrated SRAM */
+ compatible = "marvell,mv64360";
+ clock-frequency = <133333333>;
+ reg = <0xf1000000 0x00010000>;
+ virtual-reg = <0xf1000000>;
+ ranges = <0x88000000 0x88000000 0x01000000 /* PCI 0 I/O Space */
+ 0x80000000 0x80000000 0x08000000 /* PCI 0 MEM Space */
+ 0xa0000000 0xa0000000 0x04000000 /* User FLASH */
+ 0x00000000 0xf1000000 0x00010000 /* Bridge's regs */
+ 0xf2000000 0xf2000000 0x00040000>;/* Integrated SRAM*/
flash@a0000000 {
compatible = "cfi-flash";
- reg = <a0000000 04000000>;
+ reg = <0xa0000000 0x04000000>;
bank-width = <4>;
device-width = <2>;
#address-cells = <1>;
#size-cells = <1>;
fw@0 {
label = "FW Image A";
- reg = <00000000 00100000>;
+ reg = <0x00000000 0x00100000>;
read-only;
};
cfg@100000 {
label = "FW Config Data"; /* RW */
- reg = <00100000 00040000>;
+ reg = <0x00100000 0x00040000>;
};
kernel@140000 {
label = "Kernel Image";
- reg = <00140000 00400000>;
+ reg = <0x00140000 0x00400000>;
read-only;
};
fs@540000 {
label = "Filesystem";
- reg = <00540000 039c0000>;
+ reg = <0x00540000 0x039c0000>;
read-only;
};
fw@3f00000 {
label = "FW Image B";
- reg = <03f00000 00100000>;
+ reg = <0x03f00000 0x00100000>;
read-only;
};
};
@@ -91,171 +93,167 @@
#address-cells = <1>;
#size-cells = <0>;
device_type = "mdio";
- compatible = "marvell,mv64x60-mdio";
- ethernet-phy@1 {
+ compatible = "marvell,mv64360-mdio";
+ phy0: ethernet-phy@1 {
device_type = "ethernet-phy";
compatible = "broadcom,bcm5421";
- interrupts = <4c>; /* GPP 12 */
- interrupt-parent = <&/mv64x60/pic>;
+ interrupts = <76>; /* GPP 12 */
+ interrupt-parent = <&pic>;
reg = <1>;
};
- ethernet-phy@3 {
+ phy1: ethernet-phy@3 {
device_type = "ethernet-phy";
compatible = "broadcom,bcm5421";
- interrupts = <4c>; /* GPP 12 */
- interrupt-parent = <&/mv64x60/pic>;
+ interrupts = <76>; /* GPP 12 */
+ interrupt-parent = <&pic>;
reg = <3>;
};
};
- ethernet@2000 {
- reg = <2000 2000>;
- eth0 {
+ multiethernet@2000 {
+ reg = <0x2000 0x2000>;
+ ethernet@0 {
device_type = "network";
- compatible = "marvell,mv64x60-eth";
- block-index = <0>;
- interrupts = <20>;
- interrupt-parent = <&/mv64x60/pic>;
- phy = <&/mv64x60/mdio/ethernet-phy@1>;
+ compatible = "marvell,mv64360-eth";
+ reg = <0>;
+ interrupts = <32>;
+ interrupt-parent = <&pic>;
+ phy = <&phy0>;
local-mac-address = [ 00 00 00 00 00 00 ];
};
- eth1 {
+ ethernet@1 {
device_type = "network";
- compatible = "marvell,mv64x60-eth";
- block-index = <1>;
- interrupts = <21>;
- interrupt-parent = <&/mv64x60/pic>;
- phy = <&/mv64x60/mdio/ethernet-phy@3>;
+ compatible = "marvell,mv64360-eth";
+ reg = <1>;
+ interrupts = <33>;
+ interrupt-parent = <&pic>;
+ phy = <&phy1>;
local-mac-address = [ 00 00 00 00 00 00 ];
};
};
- sdma@4000 {
- device_type = "dma";
- compatible = "marvell,mv64x60-sdma";
- reg = <4000 c18>;
- virtual-reg = <f1004000>;
+ sdma0: sdma@4000 {
+ compatible = "marvell,mv64360-sdma";
+ reg = <0x4000 0xc18>;
+ virtual-reg = <0xf1004000>;
interrupt-base = <0>;
- interrupts = <24>;
- interrupt-parent = <&/mv64x60/pic>;
+ interrupts = <36>;
+ interrupt-parent = <&pic>;
};
- sdma@6000 {
- device_type = "dma";
- compatible = "marvell,mv64x60-sdma";
- reg = <6000 c18>;
- virtual-reg = <f1006000>;
+ sdma1: sdma@6000 {
+ compatible = "marvell,mv64360-sdma";
+ reg = <0x6000 0xc18>;
+ virtual-reg = <0xf1006000>;
interrupt-base = <0>;
- interrupts = <26>;
- interrupt-parent = <&/mv64x60/pic>;
+ interrupts = <38>;
+ interrupt-parent = <&pic>;
};
- brg@b200 {
- compatible = "marvell,mv64x60-brg";
- reg = <b200 8>;
+ brg0: brg@b200 {
+ compatible = "marvell,mv64360-brg";
+ reg = <0xb200 0x8>;
clock-src = <8>;
- clock-frequency = <7ed6b40>;
- current-speed = <2580>;
+ clock-frequency = <133000000>;
+ current-speed = <9600>;
bcr = <0>;
};
- brg@b208 {
- compatible = "marvell,mv64x60-brg";
- reg = <b208 8>;
+ brg1: brg@b208 {
+ compatible = "marvell,mv64360-brg";
+ reg = <0xb208 0x8>;
clock-src = <8>;
- clock-frequency = <7ed6b40>;
- current-speed = <2580>;
+ clock-frequency = <133000000>;
+ current-speed = <9600>;
bcr = <0>;
};
- cunit@f200 {
- reg = <f200 200>;
+ cunit: cunit@f200 {
+ reg = <0xf200 0x200>;
};
- mpscrouting@b400 {
- reg = <b400 c>;
+ mpscrouting: mpscrouting@b400 {
+ reg = <0xb400 0xc>;
};
- mpscintr@b800 {
- reg = <b800 100>;
- virtual-reg = <f100b800>;
+ mpscintr: mpscintr@b800 {
+ reg = <0xb800 0x100>;
+ virtual-reg = <0xf100b800>;
};
- mpsc@8000 {
+ mpsc0: mpsc@8000 {
device_type = "serial";
- compatible = "marvell,mpsc";
- reg = <8000 38>;
- virtual-reg = <f1008000>;
- sdma = <&/mv64x60/sdma@4000>;
- brg = <&/mv64x60/brg@b200>;
- cunit = <&/mv64x60/cunit@f200>;
- mpscrouting = <&/mv64x60/mpscrouting@b400>;
- mpscintr = <&/mv64x60/mpscintr@b800>;
- block-index = <0>;
- max_idle = <28>;
+ compatible = "marvell,mv64360-mpsc";
+ reg = <0x8000 0x38>;
+ virtual-reg = <0xf1008000>;
+ sdma = <&sdma0>;
+ brg = <&brg0>;
+ cunit = <&cunit>;
+ mpscrouting = <&mpscrouting>;
+ mpscintr = <&mpscintr>;
+ cell-index = <0>;
+ max_idle = <40>;
chr_1 = <0>;
chr_2 = <0>;
chr_10 = <3>;
mpcr = <0>;
- interrupts = <28>;
- interrupt-parent = <&/mv64x60/pic>;
+ interrupts = <40>;
+ interrupt-parent = <&pic>;
};
- mpsc@9000 {
+ mpsc1: mpsc@9000 {
device_type = "serial";
- compatible = "marvell,mpsc";
- reg = <9000 38>;
- virtual-reg = <f1009000>;
- sdma = <&/mv64x60/sdma@6000>;
- brg = <&/mv64x60/brg@b208>;
- cunit = <&/mv64x60/cunit@f200>;
- mpscrouting = <&/mv64x60/mpscrouting@b400>;
- mpscintr = <&/mv64x60/mpscintr@b800>;
- block-index = <1>;
- max_idle = <28>;
+ compatible = "marvell,mv64360-mpsc";
+ reg = <0x9000 0x38>;
+ virtual-reg = <0xf1009000>;
+ sdma = <&sdma1>;
+ brg = <&brg1>;
+ cunit = <&cunit>;
+ mpscrouting = <&mpscrouting>;
+ mpscintr = <&mpscintr>;
+ cell-index = <1>;
+ max_idle = <40>;
chr_1 = <0>;
chr_2 = <0>;
chr_10 = <3>;
mpcr = <0>;
- interrupts = <2a>;
- interrupt-parent = <&/mv64x60/pic>;
+ interrupts = <42>;
+ interrupt-parent = <&pic>;
};
wdt@b410 { /* watchdog timer */
- compatible = "marvell,mv64x60-wdt";
- reg = <b410 8>;
- timeout = <a>; /* wdt timeout in seconds */
+ compatible = "marvell,mv64360-wdt";
+ reg = <0xb410 0x8>;
};
i2c@c000 {
device_type = "i2c";
- compatible = "marvell,mv64x60-i2c";
- reg = <c000 20>;
- virtual-reg = <f100c000>;
+ compatible = "marvell,mv64360-i2c";
+ reg = <0xc000 0x20>;
+ virtual-reg = <0xf100c000>;
freq_m = <8>;
freq_n = <3>;
- timeout = <3e8>; /* 1000 = 1 second */
retries = <1>;
- interrupts = <25>;
- interrupt-parent = <&/mv64x60/pic>;
+ interrupts = <37>;
+ interrupt-parent = <&pic>;
};
- pic {
+ pic: pic@0 {
#interrupt-cells = <1>;
#address-cells = <0>;
- compatible = "marvell,mv64x60-pic";
- reg = <0000 88>;
+ compatible = "marvell,mv64360-pic";
+ reg = <0x0000 0x88>;
interrupt-controller;
};
mpp@f000 {
- compatible = "marvell,mv64x60-mpp";
- reg = <f000 10>;
+ compatible = "marvell,mv64360-mpp";
+ reg = <0xf000 0x10>;
};
gpp@f100 {
- compatible = "marvell,mv64x60-gpp";
- reg = <f100 20>;
+ compatible = "marvell,mv64360-gpp";
+ reg = <0xf100 0x20>;
};
pci@80000000 {
@@ -263,68 +261,70 @@
#size-cells = <2>;
#interrupt-cells = <1>;
device_type = "pci";
- compatible = "marvell,mv64x60-pci";
- reg = <0cf8 8>;
- ranges = <01000000 0 0 88000000 0 01000000
- 02000000 0 80000000 80000000 0 08000000>;
- bus-range = <0 ff>;
- clock-frequency = <3EF1480>;
- interrupt-pci-iack = <0c34>;
- interrupt-parent = <&/mv64x60/pic>;
- interrupt-map-mask = <f800 0 0 7>;
+ compatible = "marvell,mv64360-pci";
+ reg = <0x0cf8 0x8>;
+ ranges = <0x01000000 0x0 0x0
+ 0x88000000 0x0 0x01000000
+ 0x02000000 0x0 0x80000000
+ 0x80000000 0x0 0x08000000>;
+ bus-range = <0x0 0xff>;
+ clock-frequency = <66000000>;
+ interrupt-pci-iack = <0x0c34>;
+ interrupt-parent = <&pic>;
+ interrupt-map-mask = <0xf800 0 0 7>;
interrupt-map = <
/* IDSEL 0x0a */
- 5000 0 0 1 &/mv64x60/pic 50
- 5000 0 0 2 &/mv64x60/pic 51
- 5000 0 0 3 &/mv64x60/pic 5b
- 5000 0 0 4 &/mv64x60/pic 5d
+ 0x5000 0 0 1 &pic 80
+ 0x5000 0 0 2 &pic 81
+ 0x5000 0 0 3 &pic 91
+ 0x5000 0 0 4 &pic 93
/* IDSEL 0x0b */
- 5800 0 0 1 &/mv64x60/pic 5b
- 5800 0 0 2 &/mv64x60/pic 5d
- 5800 0 0 3 &/mv64x60/pic 50
- 5800 0 0 4 &/mv64x60/pic 51
+ 0x5800 0 0 1 &pic 91
+ 0x5800 0 0 2 &pic 93
+ 0x5800 0 0 3 &pic 80
+ 0x5800 0 0 4 &pic 81
/* IDSEL 0x0c */
- 6000 0 0 1 &/mv64x60/pic 5b
- 6000 0 0 2 &/mv64x60/pic 5d
- 6000 0 0 3 &/mv64x60/pic 50
- 6000 0 0 4 &/mv64x60/pic 51
+ 0x6000 0 0 1 &pic 91
+ 0x6000 0 0 2 &pic 93
+ 0x6000 0 0 3 &pic 80
+ 0x6000 0 0 4 &pic 81
/* IDSEL 0x0d */
- 6800 0 0 1 &/mv64x60/pic 5d
- 6800 0 0 2 &/mv64x60/pic 50
- 6800 0 0 3 &/mv64x60/pic 51
- 6800 0 0 4 &/mv64x60/pic 5b
+ 0x6800 0 0 1 &pic 93
+ 0x6800 0 0 2 &pic 80
+ 0x6800 0 0 3 &pic 81
+ 0x6800 0 0 4 &pic 91
>;
};
- cpu-error@0070 {
- compatible = "marvell,mv64x60-cpu-error";
- reg = <0070 10 0128 28>;
- interrupts = <03>;
- interrupt-parent = <&/mv64x60/pic>;
+ cpu-error@70 {
+ compatible = "marvell,mv64360-cpu-error";
+ reg = <0x0070 0x10 0x0128 0x28>;
+ interrupts = <3>;
+ interrupt-parent = <&pic>;
};
- sram-ctrl@0380 {
- compatible = "marvell,mv64x60-sram-ctrl";
- reg = <0380 80>;
- interrupts = <0d>;
- interrupt-parent = <&/mv64x60/pic>;
+ sram-ctrl@380 {
+ compatible = "marvell,mv64360-sram-ctrl";
+ reg = <0x0380 0x80>;
+ interrupts = <13>;
+ interrupt-parent = <&pic>;
};
pci-error@1d40 {
- compatible = "marvell,mv64x60-pci-error";
- reg = <1d40 40 0c28 4>;
- interrupts = <0c>;
- interrupt-parent = <&/mv64x60/pic>;
+ compatible = "marvell,mv64360-pci-error";
+ reg = <0x1d40 0x40 0x0c28 0x4>;
+ interrupts = <12>;
+ interrupt-parent = <&pic>;
};
mem-ctrl@1400 {
- compatible = "marvell,mv64x60-mem-ctrl";
- reg = <1400 60>;
- interrupts = <11>;
- interrupt-parent = <&/mv64x60/pic>;
+ compatible = "marvell,mv64360-mem-ctrl";
+ reg = <0x1400 0x60>;
+ interrupts = <17>;
+ interrupt-parent = <&pic>;
};
};
diff --git a/arch/powerpc/boot/mpsc.c b/arch/powerpc/boot/mpsc.c
index 802ea53..425ad88 100644
--- a/arch/powerpc/boot/mpsc.c
+++ b/arch/powerpc/boot/mpsc.c
@@ -141,7 +141,7 @@ int mpsc_console_init(void *devp, struct serial_console_data *scdp)
if (mpscintr_base == NULL)
goto err_out;
- n = getprop(devp, "block-index", &v, sizeof(v));
+ n = getprop(devp, "cell-index", &v, sizeof(v));
if (n != sizeof(v))
goto err_out;
reg_set = (int)v;
diff --git a/arch/powerpc/boot/serial.c b/arch/powerpc/boot/serial.c
index cafeece..cbcbb20 100644
--- a/arch/powerpc/boot/serial.c
+++ b/arch/powerpc/boot/serial.c
@@ -119,7 +119,7 @@ int serial_console_init(void)
if (dt_is_compatible(devp, "ns16550"))
rc = ns16550_console_init(devp, &serial_cd);
- else if (dt_is_compatible(devp, "marvell,mpsc"))
+ else if (dt_is_compatible(devp, "marvell,mv64360-mpsc"))
rc = mpsc_console_init(devp, &serial_cd);
else if (dt_is_compatible(devp, "fsl,cpm1-scc-uart") ||
dt_is_compatible(devp, "fsl,cpm1-smc-uart") ||
diff --git a/arch/powerpc/platforms/embedded6xx/prpmc2800.c b/arch/powerpc/platforms/embedded6xx/prpmc2800.c
index a01e219..1a1baf9 100644
--- a/arch/powerpc/platforms/embedded6xx/prpmc2800.c
+++ b/arch/powerpc/platforms/embedded6xx/prpmc2800.c
@@ -50,13 +50,13 @@ static void __init prpmc2800_setup_arch(void)
* ioremap mpp and gpp registers in case they are later
* needed by prpmc2800_reset_board().
*/
- np = of_find_compatible_node(NULL, NULL, "marvell,mv64x60-mpp");
+ np = of_find_compatible_node(NULL, NULL, "marvell,mv64360-mpp");
reg = of_get_property(np, "reg", NULL);
paddr = of_translate_address(np, reg);
of_node_put(np);
mv64x60_mpp_reg_base = ioremap(paddr, reg[1]);
- np = of_find_compatible_node(NULL, NULL, "marvell,mv64x60-gpp");
+ np = of_find_compatible_node(NULL, NULL, "marvell,mv64360-gpp");
reg = of_get_property(np, "reg", NULL);
paddr = of_translate_address(np, reg);
of_node_put(np);
diff --git a/arch/powerpc/sysdev/mv64x60_dev.c b/arch/powerpc/sysdev/mv64x60_dev.c
index 304056c..aac28ee 100644
--- a/arch/powerpc/sysdev/mv64x60_dev.c
+++ b/arch/powerpc/sysdev/mv64x60_dev.c
@@ -127,7 +127,7 @@ static int __init mv64x60_mpsc_device_setup(struct device_node *np, int id)
if (err)
return err;
- prop = of_get_property(np, "block-index", NULL);
+ prop = of_get_property(np, "cell-index", NULL);
if (!prop)
return -ENODEV;
port_number = *(int *)prop;
@@ -248,7 +248,7 @@ static int __init mv64x60_eth_device_setup(struct device_node *np, int id)
memset(&pdata, 0, sizeof(pdata));
- prop = of_get_property(np, "block-index", NULL);
+ prop = of_get_property(np, "reg", NULL);
if (!prop)
return -ENODEV;
pdata.port_number = *prop;
@@ -344,6 +344,7 @@ static int __init mv64x60_i2c_device_setup(struct device_node *np, int id)
of_irq_to_resource(np, 0, &r[1]);
memset(&pdata, 0, sizeof(pdata));
+ pdata.timeout = 1000; /* Default: 1 second */
prop = of_get_property(np, "freq_m", NULL);
if (!prop)
@@ -355,12 +356,6 @@ static int __init mv64x60_i2c_device_setup(struct device_node *np, int id)
return -ENODEV;
pdata.freq_n = *prop;
- prop = of_get_property(np, "timeout", NULL);
- if (prop)
- pdata.timeout = *prop;
- else
- pdata.timeout = 1000; /* 1 second */
-
prop = of_get_property(np, "retries", NULL);
if (prop)
pdata.retries = *prop;
@@ -406,11 +401,7 @@ static int __init mv64x60_wdt_device_setup(struct device_node *np, int id)
return err;
memset(&pdata, 0, sizeof(pdata));
-
- prop = of_get_property(np, "timeout", NULL);
- if (!prop)
- return -ENODEV;
- pdata.timeout = *prop;
+ pdata.timeout = 10; /* Default: 10 seconds */
np = of_get_parent(np);
if (!np)
@@ -452,22 +443,22 @@ static int __init mv64x60_device_setup(void)
int err;
id = 0;
- for_each_compatible_node(np, "serial", "marvell,mpsc")
+ for_each_compatible_node(np, "serial", "marvell,mv64360-mpsc")
if ((err = mv64x60_mpsc_device_setup(np, id++)))
goto error;
id = 0;
- for_each_compatible_node(np, "network", "marvell,mv64x60-eth")
+ for_each_compatible_node(np, "network", "marvell,mv64360-eth")
if ((err = mv64x60_eth_device_setup(np, id++)))
goto error;
id = 0;
- for_each_compatible_node(np, "i2c", "marvell,mv64x60-i2c")
+ for_each_compatible_node(np, "i2c", "marvell,mv64360-i2c")
if ((err = mv64x60_i2c_device_setup(np, id++)))
goto error;
/* support up to one watchdog timer */
- np = of_find_compatible_node(np, NULL, "marvell,mv64x60-wdt");
+ np = of_find_compatible_node(np, NULL, "marvell,mv64360-wdt");
if (np) {
if ((err = mv64x60_wdt_device_setup(np, id)))
goto error;
@@ -495,10 +486,10 @@ static int __init mv64x60_add_mpsc_console(void)
if (!np)
goto not_mpsc;
- if (!of_device_is_compatible(np, "marvell,mpsc"))
+ if (!of_device_is_compatible(np, "marvell,mv64360-mpsc"))
goto not_mpsc;
- prop = of_get_property(np, "block-index", NULL);
+ prop = of_get_property(np, "cell-index", NULL);
if (!prop)
goto not_mpsc;
diff --git a/arch/powerpc/sysdev/mv64x60_pci.c b/arch/powerpc/sysdev/mv64x60_pci.c
index d21ab8f..1456015 100644
--- a/arch/powerpc/sysdev/mv64x60_pci.c
+++ b/arch/powerpc/sysdev/mv64x60_pci.c
@@ -86,14 +86,14 @@ static int __init mv64x60_sysfs_init(void)
struct platform_device *pdev;
const unsigned int *prop;
- np = of_find_compatible_node(NULL, NULL, "marvell,mv64x60");
+ np = of_find_compatible_node(NULL, NULL, "marvell,mv64360");
if (!np)
return 0;
prop = of_get_property(np, "hs_reg_valid", NULL);
of_node_put(np);
- pdev = platform_device_register_simple("marvell,mv64x60", 0, NULL, 0);
+ pdev = platform_device_register_simple("marvell,mv64360", 0, NULL, 0);
if (IS_ERR(pdev))
return PTR_ERR(pdev);
@@ -166,6 +166,6 @@ void __init mv64x60_pci_init(void)
{
struct device_node *np;
- for_each_compatible_node(np, "pci", "marvell,mv64x60-pci")
+ for_each_compatible_node(np, "pci", "marvell,mv64360-pci")
mv64x60_add_bridge(np);
}
diff --git a/arch/powerpc/sysdev/mv64x60_pic.c b/arch/powerpc/sysdev/mv64x60_pic.c
index 19e6ef2..2aa4ed0 100644
--- a/arch/powerpc/sysdev/mv64x60_pic.c
+++ b/arch/powerpc/sysdev/mv64x60_pic.c
@@ -238,13 +238,13 @@ void __init mv64x60_init_irq(void)
const unsigned int *reg;
unsigned long flags;
- np = of_find_compatible_node(NULL, NULL, "marvell,mv64x60-gpp");
+ np = of_find_compatible_node(NULL, NULL, "marvell,mv64360-gpp");
reg = of_get_property(np, "reg", &size);
paddr = of_translate_address(np, reg);
mv64x60_gpp_reg_base = ioremap(paddr, reg[1]);
of_node_put(np);
- np = of_find_compatible_node(NULL, NULL, "marvell,mv64x60-pic");
+ np = of_find_compatible_node(NULL, NULL, "marvell,mv64360-pic");
reg = of_get_property(np, "reg", &size);
paddr = of_translate_address(np, reg);
mv64x60_irq_reg_base = ioremap(paddr, reg[1]);
diff --git a/arch/powerpc/sysdev/mv64x60_udbg.c b/arch/powerpc/sysdev/mv64x60_udbg.c
index 35c77c7..2792dc8 100644
--- a/arch/powerpc/sysdev/mv64x60_udbg.c
+++ b/arch/powerpc/sysdev/mv64x60_udbg.c
@@ -85,7 +85,7 @@ static void mv64x60_udbg_init(void)
if (!stdout)
return;
- for_each_compatible_node(np, "serial", "marvell,mpsc") {
+ for_each_compatible_node(np, "serial", "marvell,mv64360-mpsc") {
if (np == stdout)
break;
}
@@ -94,7 +94,7 @@ static void mv64x60_udbg_init(void)
if (!np)
return;
- block_index = of_get_property(np, "block-index", NULL);
+ block_index = of_get_property(np, "cell-index", NULL);
if (!block_index)
goto error;
^ permalink raw reply related
* Re: [PATCH] pci: Fix bus resource assignment on 32 bits with 64b resources
From: Greg KH @ 2007-12-07 1:00 UTC (permalink / raw)
To: Benjamin Herrenschmidt; +Cc: linuxppc-dev, linux-pci, linux-kernel
In-Reply-To: <1196927934.7033.39.camel@pasglop>
On Thu, Dec 06, 2007 at 06:58:54PM +1100, Benjamin Herrenschmidt wrote:
>
> On Wed, 2007-12-05 at 22:39 -0800, Greg KH wrote:
> > > that is it can be either unsigned int, unsigned long or unsigned
> > long
> > > long... and we have no way to reliably printk that.
> >
> > We do this already just fine. Take a look in the kernel, I think we
> > just always cast it to long long to be uniform.
>
> I wanted to avoid that for two reasons:
>
> - casts are fugly
> - it adds support code to cast & handle 64 bits to 32 bits platforms
> that wouldn't normally need it
But that is how we already handle this today, in numerous places in the
kernel for this very type.
So, you can disagree that this is what we need to do, and if so, feel
free to fix up a whole lot of files in the tree :)
thanks,
greg k-h
^ permalink raw reply
* Please pull powerpc.git merge branch
From: Paul Mackerras @ 2007-12-07 1:04 UTC (permalink / raw)
To: torvalds; +Cc: linuxppc-dev
Linus,
I have added another commit to my powerpc.git tree merge branch, so
please do:
git pull \
master.kernel.org:/pub/scm/linux/kernel/git/paulus/powerpc.git merge
(the mirroring seems to be slow today).
The diffstat and log below reflect the new commit plus the 4 in my
last pull request.
Thanks,
Paul.
arch/powerpc/configs/bamboo_defconfig | 22 +-
arch/powerpc/configs/cell_defconfig | 176 ++++++++++--------
arch/powerpc/configs/celleb_defconfig | 170 +++++++++--------
arch/powerpc/configs/chrp32_defconfig | 163 +++++++++--------
arch/powerpc/configs/ebony_defconfig | 25 +--
arch/powerpc/configs/ep88xc_defconfig | 92 +++++----
arch/powerpc/configs/g5_defconfig | 150 ++++++++-------
arch/powerpc/configs/holly_defconfig | 136 +++++++-------
arch/powerpc/configs/iseries_defconfig | 123 ++++++------
arch/powerpc/configs/kilauea_defconfig | 79 +++-----
arch/powerpc/configs/linkstation_defconfig | 152 ++++++++-------
arch/powerpc/configs/lite5200_defconfig | 119 ++++++------
arch/powerpc/configs/maple_defconfig | 126 ++++++-------
arch/powerpc/configs/mpc7448_hpc2_defconfig | 137 +++++++-------
arch/powerpc/configs/mpc8272_ads_defconfig | 106 ++++++-----
arch/powerpc/configs/mpc8313_rdb_defconfig | 173 +++++++++---------
arch/powerpc/configs/mpc832x_mds_defconfig | 155 ++++++++--------
arch/powerpc/configs/mpc832x_rdb_defconfig | 167 ++++++++---------
arch/powerpc/configs/mpc834x_itx_defconfig | 156 ++++++++--------
arch/powerpc/configs/mpc834x_itxgp_defconfig | 161 +++++++++-------
arch/powerpc/configs/mpc834x_mds_defconfig | 149 +++++++--------
arch/powerpc/configs/mpc836x_mds_defconfig | 155 ++++++++--------
arch/powerpc/configs/mpc8540_ads_defconfig | 101 +++++-----
arch/powerpc/configs/mpc8544_ds_defconfig | 130 +++++++------
arch/powerpc/configs/mpc8560_ads_defconfig | 104 +++++------
arch/powerpc/configs/mpc8568mds_defconfig | 161 ++++++++--------
arch/powerpc/configs/mpc8572_ds_defconfig | 130 +++++++------
arch/powerpc/configs/mpc85xx_cds_defconfig | 126 ++++++-------
arch/powerpc/configs/mpc8610_hpcd_defconfig | 114 +++++-------
arch/powerpc/configs/mpc8641_hpcn_defconfig | 131 +++++++------
arch/powerpc/configs/mpc866_ads_defconfig | 107 +++++------
arch/powerpc/configs/mpc885_ads_defconfig | 98 +++++-----
arch/powerpc/configs/pasemi_defconfig | 8 +
arch/powerpc/configs/pmac32_defconfig | 217 ++++++++++++++--------
arch/powerpc/configs/ppc64_defconfig | 9 +
arch/powerpc/configs/pq2fads_defconfig | 148 +++++++++------
arch/powerpc/configs/prpmc2800_defconfig | 150 ++++++++-------
arch/powerpc/configs/ps3_defconfig | 177 +++++++++---------
arch/powerpc/configs/pseries_defconfig | 156 +++++++++-------
arch/powerpc/configs/sequoia_defconfig | 111 ++++++-----
arch/powerpc/configs/walnut_defconfig | 22 +-
arch/powerpc/kernel/process.c | 2
arch/ppc/platforms/4xx/xparameters/xparameters.h | 8 +
arch/ppc/syslib/virtex_devices.c | 8 -
include/asm-powerpc/time.h | 8 -
45 files changed, 2662 insertions(+), 2456 deletions(-)
Geoff Levand (1):
[POWERPC] PS3: Update ps3_defconfig
Grant Likely (1):
[POWERPC] virtex bug fix: Use canonical value for AC97 interrupt xparams
Paul Mackerras (1):
[POWERPC] Update defconfigs
Stephen Rothwell (1):
[POWERPC] Update iseries_defconfig
Tony Breeds (1):
[POWERPC] Fix hardware IRQ time accounting problem.
^ permalink raw reply
* Re: MPC85xx DMA drivers, first testing results.
From: Timur Tabi @ 2007-12-07 1:31 UTC (permalink / raw)
To: Clemens Koller; +Cc: linuxppc-dev@ozlabs.org
In-Reply-To: <47586E72.3050106@anagramm.de>
Clemens Koller wrote:
> Hi There!
>
> I just tried to use the fsldma on the mpc8540. It seems to work fine
> here, but I would be glad if somebody can confirm before I move on:
>
> I added the following to my mpc8540ads compatible board's .dts
> (see my comments, where the not yet available documentation
> was unclear):
>
> dma@21000 {
> #address-cells = <1>;
> #size-cells = <1>;
> compatible = "fsl,mpc8540-dma", "fsl,eloplus-dma";
> device-id = <0>;
> reg = <21300 4>; /* DGSR - DMA general status register */
> /* reg = <21000 4>;*/ /* or use offset of DMA machine ??? */
> ranges = <0 21100 200>; /* we have 4 DMA channels at 21100, size=80 each */
> dma-channel@0 {
> compatible = "fsl,mpc8540-dma-channel", "fsl,eloplus-dma-channel";
> device-id = <0>; /* or cell-index ??? */
> reg = <0 80>;
> interrupt-parent = <&mpic>;
> interrupts = <14 2>;
> };
Do this:
dma@21300 {
#address-cells = <1>;
#size-cells = <1>;
compatible = "fsl,mpc8540-dma", "fsl,eloplus-dma";
cell-index = <0>;
reg = <21300 4>; /* DMA general status register */
ranges = <0 21100 200>;
dma-channel@0 {
compatible = "fsl,mpc8540-dma-channel",
"fsl,eloplus-dma-channel";
cell-index = <0>;
reg = <0 80>;
interrupt-parent = <&mpic>;
interrupts = <14 2>;
};
--
Timur Tabi
Linux Kernel Developer @ Freescale
^ permalink raw reply
* Re: [PATCH] add MPC837x MDS board default device tree
From: David Gibson @ 2007-12-07 2:01 UTC (permalink / raw)
To: Li Yang; +Cc: linuxppc-dev
In-Reply-To: <1196851073-11801-1-git-send-email-leoli@freescale.com>
On Wed, Dec 05, 2007 at 06:37:53PM +0800, Li Yang wrote:
> Signed-off-by: Li Yang <leoli@freescale.com>
> ---
> Update SATA nodes; remove serdes nodes; add aliases and labels.
>
> arch/powerpc/boot/dts/mpc8377_mds.dts | 270 +++++++++++++++++++++++++++++++
> arch/powerpc/boot/dts/mpc8378_mds.dts | 256 +++++++++++++++++++++++++++++
> arch/powerpc/boot/dts/mpc8379_mds.dts | 284 +++++++++++++++++++++++++++++++++
> 3 files changed, 810 insertions(+), 0 deletions(-)
> create mode 100644 arch/powerpc/boot/dts/mpc8377_mds.dts
> create mode 100644 arch/powerpc/boot/dts/mpc8378_mds.dts
> create mode 100644 arch/powerpc/boot/dts/mpc8379_mds.dts
>
> diff --git a/arch/powerpc/boot/dts/mpc8377_mds.dts b/arch/powerpc/boot/dts/mpc8377_mds.dts
> new file mode 100644
> index 0000000..919ffd0
> --- /dev/null
> +++ b/arch/powerpc/boot/dts/mpc8377_mds.dts
[snip]
> + aliases {
> + ethernet0 = "/soc@e0000000/ethernet@24000";
> + ethernet1 = "/soc@e0000000/ethernet@25000";
> + serial0 = "/soc@e0000000/serial@4500";
> + serial1 = "/soc@e0000000/serial@4600";
> + pci0 = "/pci@e0008500";
You can use path references for these now.
> + };
> +
> + cpus {
> + #address-cells = <1>;
> + #size-cells = <0>;
> +
> + PowerPC,837x@0 {
This should absolutely not have a "x" in it. Either have an exact
model, or just use "cpu@9" (in which case you can put the model in
"compatible").
[snip]
> + i2c@3000 {
> + device_type = "i2c";
Drop the device_type. No "i2c" device_type class is defined.
[snip]
> + /* phy type (ULPI, UTMI, UTMI_WIDE, SERIAL) */
> + usb@23000 {
> + device_type = "usb";
Drop device_type here too.
> + compatible = "fsl-usb2-dr";
> + reg = <23000 1000>;
> + #address-cells = <1>;
> + #size-cells = <0>;
> + interrupt-parent = < &ipic >;
> + interrupts = <26 8>;
> + phy_type = "utmi_wide";
> + };
> +
> + mdio@24520 {
> + device_type = "mdio";
> + compatible = "gianfar";
Grr... not your fault, but this crap in the gianfar driver where it
uses the same compatible property for the mdio and MAC has to be
fixed.
[snip]
> + serial1:serial@4600 {
Standard style puts a space after the colon.
> + device_type = "serial";
> + compatible = "ns16550";
> + reg = <4600 100>;
> + clock-frequency = <0>;
> + interrupts = <a 8>;
> + interrupt-parent = < &ipic >;
> + };
> +
> + crypto@30000 {
> + model = "SEC3";
> + compatible = "talitos";
This driver, also, needs fixing to recognize a better formatted
compatible property.
--
David Gibson | I'll have my music baroque, and my code
david AT gibson.dropbear.id.au | minimalist, thank you. NOT _the_ _other_
| _way_ _around_!
http://www.ozlabs.org/~dgibson
^ permalink raw reply
* Re: [PATCH 8/25] powerpc: Improve support for 4xx indirect DCRs
From: Josh Boyer @ 2007-12-07 2:19 UTC (permalink / raw)
To: Benjamin Herrenschmidt; +Cc: linuxppc-dev
In-Reply-To: <20071206080117.754FEDDE45@ozlabs.org>
On Thu, 06 Dec 2007 19:00:06 +1100
Benjamin Herrenschmidt <benh@kernel.crashing.org> wrote:
> Accessing indirect DCRs is done via a pair of address/data DCRs.
>
> Such accesses are thus inherently racy, vs. interrupts, preemption
> and possibly SMP if 4xx SMP cores are ever used.
>
> This updates the mfdcri/mtdcri macros in dcr-native.h (which were
> so far unused) to use a spinlock.
>
> In addition, add some common definitions to a new dcr-regs.h file.
>
> Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>
> ---
>
>
> arch/powerpc/sysdev/dcr.c | 1
> include/asm-powerpc/dcr-native.h | 30 +++++++++++-----
> include/asm-powerpc/dcr-regs.h | 72 +++++++++++++++++++++++++++++++++++++++
> include/asm-powerpc/dcr.h | 1
> 4 files changed, 96 insertions(+), 8 deletions(-)
>
> Index: linux-work/arch/powerpc/sysdev/dcr.c
> ===================================================================
> --- linux-work.orig/arch/powerpc/sysdev/dcr.c 2007-11-28 13:34:45.000000000 +1100
> +++ linux-work/arch/powerpc/sysdev/dcr.c 2007-11-28 13:34:48.000000000 +1100
> @@ -139,3 +139,4 @@ void dcr_unmap(dcr_host_t host, unsigned
> EXPORT_SYMBOL_GPL(dcr_unmap);
>
> #endif /* !defined(CONFIG_PPC_DCR_NATIVE) */
> +
Somehow I doubt this single extraneous whitespace addition is really
needed.
> Index: linux-work/include/asm-powerpc/dcr-native.h
> ===================================================================
> --- linux-work.orig/include/asm-powerpc/dcr-native.h 2007-11-28 13:33:51.000000000 +1100
> +++ linux-work/include/asm-powerpc/dcr-native.h 2007-11-28 15:22:22.000000000 +1100
> @@ -22,6 +22,8 @@
> #ifdef __KERNEL__
> #ifndef __ASSEMBLY__
>
> +#include <linux/spinlock.h>
> +
> typedef struct {
> unsigned int base;
> } dcr_host_t;
> @@ -55,18 +57,30 @@ do { \
> } while (0)
>
> /* R/W of indirect DCRs make use of standard naming conventions for DCRs */
> -#define mfdcri(base, reg) \
> -({ \
> - mtdcr(base ## _CFGADDR, base ## _ ## reg); \
> - mfdcr(base ## _CFGDATA); \
> +extern spinlock_t dcr_ind_lock;
> +
> +#define mfdcri(base, reg) \
> +({ \
> + unsigned long flags; \
> + unsigned int val; \
> + spin_lock_irqsave(&dcr_ind_lock, flags); \
> + mtdcr(DCRN_ ## base ## _CONFIG_ADDR, reg); \
> + val = mfdcr(DCRN_ ## base ## _CONFIG_DATA); \
> + spin_unlock_irqrestore(&dcr_ind_lock, flags); \
> + val; \
> })
>
> -#define mtdcri(base, reg, data) \
> -do { \
> - mtdcr(base ## _CFGADDR, base ## _ ## reg); \
> - mtdcr(base ## _CFGDATA, data); \
> +#define mtdcri(base, reg, data) \
> +do { \
> + unsigned long flags; \
> + spin_lock_irqsave(&dcr_ind_lock, flags); \
> + mtdcr(DCRN_ ## base ## _CONFIG_ADDR, reg); \
> + mtdcr(DCRN_ ## base ## _CONFIG_DATA, data); \
> + spin_unlock_irqrestore(&dcr_ind_lock, flags); \
> } while (0)
>
> +
> +
More bogus whitespace.
> #endif /* __ASSEMBLY__ */
> #endif /* __KERNEL__ */
> #endif /* _ASM_POWERPC_DCR_NATIVE_H */
> Index: linux-work/include/asm-powerpc/dcr.h
> ===================================================================
> --- linux-work.orig/include/asm-powerpc/dcr.h 2007-11-28 13:40:13.000000000 +1100
> +++ linux-work/include/asm-powerpc/dcr.h 2007-11-28 13:49:37.000000000 +1100
> @@ -40,6 +40,7 @@ extern unsigned int dcr_resource_len(str
> unsigned int index);
> #endif /* CONFIG_PPC_MERGE */
>
> +
You really like whitespace. Again I don't see anything needed for this
file :)
> #endif /* CONFIG_PPC_DCR */
> #endif /* __KERNEL__ */
> #endif /* _ASM_POWERPC_DCR_H */
> Index: linux-work/include/asm-powerpc/dcr-regs.h
> ===================================================================
> --- /dev/null 1970-01-01 00:00:00.000000000 +0000
> +++ linux-work/include/asm-powerpc/dcr-regs.h 2007-11-28 14:43:25.000000000 +1100
> @@ -0,0 +1,72 @@
> +/*
> + * Common DCR / SDR / CPR register definitions used on various IBM/AMCC
> + * 4xx processors
> + *
> + * Copyright 2007 Benjamin Herrenschmidt, IBM Corp
> + * <benh@kernel.crashing.org>
> + *
> + * Mostly lifted from asm-ppc/ibm4xx.h by
> + *
> + * Copyright (c) 1999 Grant Erickson <grant@lcse.umn.edu>
> + *
> + */
> +
> +#ifndef __DCR_REGS_H__
> +#define __DCR_REGS_H__
> +
> +/*
> + * Most DCRs used for controlling devices such as the MAL, DMA engine,
> + * etc... are obtained for the device tree.
> + *
> + * The definitions in this files are fixed DCRs and indirect DCRs that
> + * are commonly used outside of specific drivers or refer to core
> + * common registers that may occasionally have to be tweaked outside
> + * of the driver main register set
> + */
> +
> +/* CPRs (440GX and 440SP/440SPe) */
> +#define DCRN_CPR0_CONFIG_ADDR 0xc
> +#define DCRN_CPR0_CONFIG_DATA 0xd
> +
> +/* SDRs (440GX and 440SP/440SPe) */
> +#define DCRN_SDR0_CONFIG_ADDR 0xe
> +#define DCRN_SDR0_CONFIG_DATA 0xf
> +
> +#define SDR0_PFC0 0x4100
> +#define SDR0_PFC1 0x4101
> +#define SDR0_PFC1_EPS 0x1c00000
> +#define SDR0_PFC1_EPS_SHIFT 22
> +#define SDR0_PFC1_RMII 0x02000000
> +#define SDR0_MFR 0x4300
> +#define SDR0_MFR_TAH0 0x80000000 /* TAHOE0 Enable */
> +#define SDR0_MFR_TAH1 0x40000000 /* TAHOE1 Enable */
> +#define SDR0_MFR_PCM 0x10000000 /* PPC440GP irq compat mode */
> +#define SDR0_MFR_ECS 0x08000000 /* EMAC int clk */
> +#define SDR0_MFR_T0TXFL 0x00080000
> +#define SDR0_MFR_T0TXFH 0x00040000
> +#define SDR0_MFR_T1TXFL 0x00020000
> +#define SDR0_MFR_T1TXFH 0x00010000
> +#define SDR0_MFR_E0TXFL 0x00008000
> +#define SDR0_MFR_E0TXFH 0x00004000
> +#define SDR0_MFR_E0RXFL 0x00002000
> +#define SDR0_MFR_E0RXFH 0x00001000
> +#define SDR0_MFR_E1TXFL 0x00000800
> +#define SDR0_MFR_E1TXFH 0x00000400
> +#define SDR0_MFR_E1RXFL 0x00000200
> +#define SDR0_MFR_E1RXFH 0x00000100
> +#define SDR0_MFR_E2TXFL 0x00000080
> +#define SDR0_MFR_E2TXFH 0x00000040
> +#define SDR0_MFR_E2RXFL 0x00000020
> +#define SDR0_MFR_E2RXFH 0x00000010
> +#define SDR0_MFR_E3TXFL 0x00000008
> +#define SDR0_MFR_E3TXFH 0x00000004
> +#define SDR0_MFR_E3RXFL 0x00000002
> +#define SDR0_MFR_E3RXFH 0x00000001
> +#define SDR0_UART0 0x0120
> +#define SDR0_UART1 0x0121
> +#define SDR0_UART2 0x0122
> +#define SDR0_UART3 0x0123
> +#define SDR0_CUST0 0x4000
> +
> +
> +#endif /* __DCR_REGS_H__ */
^ permalink raw reply
* dtc: Convert #address-cells and #size-cells related checks
From: David Gibson @ 2007-12-07 3:05 UTC (permalink / raw)
To: Jon Loeliger; +Cc: linuxppc-dev
This patch converts checks related to #address-cells and #size-cells
to the new framework. Specifically, it reimplements the check that
"reg" properties have a valid size based on the relevant
#address-cells and #size-cells values. The new implementation uses
the correct default value, unlike the old-style check which assumed
the values were inherited by default.
It also implements a new, similar test for "ranges" properties.
Finally, since relying on the default values of these variables is
considered not-good-practice these days, it implements a "style" check
which will give a warning if the tree ever relies on the default
values (that is if any node with either "reg" or "ranges" appears
under a parent which has no #address-cells or #size-cells property).
Index: dtc/checks.c
===================================================================
--- dtc.orig/checks.c 2007-12-07 12:54:59.000000000 +1100
+++ dtc/checks.c 2007-12-07 13:16:38.000000000 +1100
@@ -355,6 +355,127 @@ CHECK_IS_STRING(device_type_is_string, "
CHECK_IS_STRING(model_is_string, "model", WARN);
CHECK_IS_STRING(status_is_string, "status", WARN);
+static void fixup_addr_size_cells(struct check *c, struct node *dt,
+ struct node *node)
+{
+ struct property *prop;
+
+ node->addr_cells = -1;
+ node->size_cells = -1;
+
+ prop = get_property(node, "#address-cells");
+ if (prop)
+ node->addr_cells = propval_cell(prop);
+
+ prop = get_property(node, "#size-cells");
+ if (prop)
+ node->size_cells = propval_cell(prop);
+}
+CHECK(addr_size_cells, NULL, fixup_addr_size_cells, NULL, NULL, WARN,
+ &address_cells_is_cell, &size_cells_is_cell);
+
+#define node_addr_cells(n) \
+ (((n)->addr_cells == -1) ? 2 : (n)->addr_cells)
+#define node_size_cells(n) \
+ (((n)->size_cells == -1) ? 1 : (n)->size_cells)
+
+static void check_reg_format(struct check *c, struct node *dt,
+ struct node *node)
+{
+ struct property *prop;
+ int addr_cells, size_cells, entrylen;
+
+ prop = get_property(node, "reg");
+ if (!prop)
+ return; /* No "reg", that's fine */
+
+ if (!node->parent) {
+ FAIL(c, "Root node has a \"reg\" property");
+ return;
+ }
+
+ if (prop->val.len == 0)
+ FAIL(c, "\"reg\" property in %s is empty", node->fullpath);
+
+ addr_cells = node_addr_cells(node->parent);
+ size_cells = node_size_cells(node->parent);
+ entrylen = (addr_cells + size_cells) * sizeof(cell_t);
+
+ if ((prop->val.len % entrylen) != 0)
+ FAIL(c, "\"reg\" property in %s has invalid length (%d bytes) "
+ "(#address-cells == %d, #size-cells == %d)",
+ node->fullpath, prop->val.len, addr_cells, size_cells);
+}
+NODE_CHECK(reg_format, NULL, WARN, &addr_size_cells);
+
+static void check_ranges_format(struct check *c, struct node *dt,
+ struct node *node)
+{
+ struct property *prop;
+ int c_addr_cells, p_addr_cells, c_size_cells, p_size_cells, entrylen;
+
+ prop = get_property(node, "ranges");
+ if (!prop)
+ return;
+
+ if (!node->parent) {
+ FAIL(c, "Root node has a \"ranges\" property");
+ return;
+ }
+
+ p_addr_cells = node_addr_cells(node->parent);
+ p_size_cells = node_size_cells(node->parent);
+ c_addr_cells = node_addr_cells(node);
+ c_size_cells = node_size_cells(node);
+ entrylen = (p_addr_cells + c_addr_cells + c_size_cells) * sizeof(cell_t);
+
+ if (prop->val.len == 0) {
+ if (p_addr_cells != c_addr_cells)
+ FAIL(c, "%s has empty \"ranges\" property but its "
+ "#address-cells (%d) differs from %s (%d)",
+ node->fullpath, c_addr_cells, node->parent->fullpath,
+ p_addr_cells);
+ if (p_size_cells != c_size_cells)
+ FAIL(c, "%s has empty \"ranges\" property but its "
+ "#size-cells (%d) differs from %s (%d)",
+ node->fullpath, c_size_cells, node->parent->fullpath,
+ p_size_cells);
+ } else if ((prop->val.len % entrylen) != 0) {
+ FAIL(c, "\"ranges\" property in %s has invalid length (%d bytes) "
+ "(parent #address-cells == %d, child #address-cells == %d, "
+ "#size-cells == %d)", node->fullpath, prop->val.len,
+ p_addr_cells, c_addr_cells, c_size_cells);
+ }
+}
+NODE_CHECK(ranges_format, NULL, WARN, &addr_size_cells);
+
+/*
+ * Style checks
+ */
+static void check_avoid_default_addr_size(struct check *c, struct node *dt,
+ struct node *node)
+{
+ struct property *reg, *ranges;
+
+ if (!node->parent)
+ return; /* Ignore root node */
+
+ reg = get_property(node, "reg");
+ ranges = get_property(node, "ranges");
+
+ if (!reg && !ranges)
+ return;
+
+ if ((node->parent->addr_cells == -1))
+ FAIL(c, "Relying on default #address-cells value for %s",
+ node->fullpath);
+
+ if ((node->parent->size_cells == -1))
+ FAIL(c, "Relying on default #size-cells value for %s",
+ node->fullpath);
+}
+NODE_CHECK(avoid_default_addr_size, NULL, WARN, &addr_size_cells);
+
static struct check *check_table[] = {
&duplicate_node_names, &duplicate_property_names,
&name_is_string, &name_properties,
@@ -363,6 +484,10 @@ static struct check *check_table[] = {
&address_cells_is_cell, &size_cells_is_cell, &interrupt_cells_is_cell,
&device_type_is_string, &model_is_string, &status_is_string,
+
+ &addr_size_cells, ®_format, &ranges_format,
+
+ &avoid_default_addr_size,
};
int check_semantics(struct node *dt, int outversion, int boot_cpuid_phys);
@@ -487,10 +612,6 @@ static int check_root(struct node *root)
int ok = 1;
CHECK_HAVE_STRING(root, "model");
-
- CHECK_HAVE(root, "#address-cells");
- CHECK_HAVE(root, "#size-cells");
-
CHECK_HAVE_WARN(root, "compatible");
return ok;
@@ -509,19 +630,16 @@ static int check_cpus(struct node *root,
return 0;
}
- CHECK_HAVE_WARN(cpus, "#address-cells");
- CHECK_HAVE_WARN(cpus, "#size-cells");
+ if (cpus->addr_cells != 1)
+ DO_ERR("%s has bad #address-cells value %d (should be 1)\n",
+ cpus->fullpath, cpus->addr_cells);
+ if (cpus->size_cells != 0)
+ DO_ERR("%s has bad #size-cells value %d (should be 0)\n",
+ cpus->fullpath, cpus->size_cells);
for_each_child(cpus, cpu) {
CHECK_HAVE_STREQ(cpu, "device_type", "cpu");
- if (cpu->addr_cells != 1)
- DO_ERR("%s has bad #address-cells value %d (should be 1)\n",
- cpu->fullpath, cpu->addr_cells);
- if (cpu->size_cells != 0)
- DO_ERR("%s has bad #size-cells value %d (should be 0)\n",
- cpu->fullpath, cpu->size_cells);
-
CHECK_HAVE_ONECELL(cpu, "reg");
if (prop) {
cell_t unitnum;
@@ -618,47 +736,10 @@ static int check_chosen(struct node *roo
return ok;
}
-static int check_addr_size_reg(struct node *node,
- int p_addr_cells, int p_size_cells)
-{
- int addr_cells = p_addr_cells;
- int size_cells = p_size_cells;
- struct property *prop;
- struct node *child;
- int ok = 1;
-
- node->addr_cells = addr_cells;
- node->size_cells = size_cells;
-
- prop = get_property(node, "reg");
- if (prop) {
- int reg_entry_len = (addr_cells + size_cells) * sizeof(cell_t);
- if ((prop->val.len % reg_entry_len) != 0)
- DO_ERR("\"reg\" property in %s has invalid length (%d bytes) for given #address-cells (%d) and #size-cells (%d)\n",
- node->fullpath, prop->val.len,
- addr_cells, size_cells);
- }
-
- prop = get_property(node, "#address-cells");
- if (prop)
- addr_cells = propval_cell(prop);
-
- prop = get_property(node, "#size-cells");
- if (prop)
- size_cells = propval_cell(prop);
-
- for_each_child(node, child) {
- ok = ok && check_addr_size_reg(child, addr_cells, size_cells);
- }
-
- return ok;
-}
-
int check_semantics(struct node *dt, int outversion, int boot_cpuid_phys)
{
int ok = 1;
- ok = ok && check_addr_size_reg(dt, -1, -1);
ok = ok && check_root(dt);
ok = ok && check_cpus(dt, outversion, boot_cpuid_phys);
ok = ok && check_memory(dt);
Index: dtc/tests/bad-empty-ranges.dts
===================================================================
--- /dev/null 1970-01-01 00:00:00.000000000 +0000
+++ dtc/tests/bad-empty-ranges.dts 2007-12-07 12:56:18.000000000 +1100
@@ -0,0 +1,11 @@
+/dts-v1/;
+
+/ {
+ #address-cells = <2>;
+ #size-cells = <2>;
+ node {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ ranges;
+ };
+};
Index: dtc/tests/bad-reg-ranges.dts
===================================================================
--- /dev/null 1970-01-01 00:00:00.000000000 +0000
+++ dtc/tests/bad-reg-ranges.dts 2007-12-07 12:56:18.000000000 +1100
@@ -0,0 +1,12 @@
+/dts-v1/;
+
+/ {
+ #address-cells = <2>;
+ #size-cells = <2>;
+ node {
+ reg = <0 0>;
+ #address-cells = <1>;
+ #size-cells = <1>;
+ ranges = <0 0 0>;
+ };
+};
Index: dtc/tests/default-addr-size.dts
===================================================================
--- /dev/null 1970-01-01 00:00:00.000000000 +0000
+++ dtc/tests/default-addr-size.dts 2007-12-07 13:20:25.000000000 +1100
@@ -0,0 +1,7 @@
+/dts-v1/;
+
+/ {
+ node {
+ reg = <0 0 0>;
+ };
+};
Index: dtc/tests/run_tests.sh
===================================================================
--- dtc.orig/tests/run_tests.sh 2007-12-07 13:19:14.000000000 +1100
+++ dtc/tests/run_tests.sh 2007-12-07 13:21:22.000000000 +1100
@@ -170,7 +170,9 @@ dtc_tests () {
run_test dtc-checkfails.sh address_cells_is_cell size_cells_is_cell interrupt_cells_is_cell -- -I dts -O dtb bad-ncells.dts
run_test dtc-checkfails.sh device_type_is_string model_is_string status_is_string -- -I dts -O dtb bad-string-props.dts
-
+ run_test dtc-checkfails.sh reg_format ranges_format -- -I dts -O dtb bad-reg-ranges.dts
+ run_test dtc-checkfails.sh ranges_format -- -I dts -O dtb bad-empty-ranges.dts
+ run_test dtc-checkfails.sh avoid_default_addr_size -- -I dts -O dtb default-addr-size.dts
}
while getopts "vt:m" ARG ; do
--
David Gibson | I'll have my music baroque, and my code
david AT gibson.dropbear.id.au | minimalist, thank you. NOT _the_ _other_
| _way_ _around_!
http://www.ozlabs.org/~dgibson
^ permalink raw reply
* dtc: Convert check for obsolete /chosen property
From: David Gibson @ 2007-12-07 3:06 UTC (permalink / raw)
To: Jon Loeliger; +Cc: linuxppc-dev
This converts the test for the obsolete "interrupt-controller"
property in /chosen to the new framework. That was the only thing
left in the old-style check_chosen() function, so that function is
removed, too.
Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
Index: dtc/checks.c
===================================================================
--- dtc.orig/checks.c 2007-12-07 13:46:11.000000000 +1100
+++ dtc/checks.c 2007-12-07 13:53:24.000000000 +1100
@@ -476,6 +476,23 @@ static void check_avoid_default_addr_siz
}
NODE_CHECK(avoid_default_addr_size, NULL, WARN, &addr_size_cells);
+static void check_obsolete_chosen_interrupt_controller(struct check *c,
+ struct node *dt)
+{
+ struct node *chosen;
+ struct property *prop;
+
+ chosen = get_node_by_path(dt, "/chosen");
+ if (!chosen)
+ return;
+
+ prop = get_property(chosen, "interrupt-controller");
+ if (prop)
+ FAIL(c, "/chosen has obsolete \"interrupt-controller\" "
+ "property");
+}
+TREE_CHECK(obsolete_chosen_interrupt_controller, NULL, WARN);
+
static struct check *check_table[] = {
&duplicate_node_names, &duplicate_property_names,
&name_is_string, &name_properties,
@@ -488,6 +505,7 @@ static struct check *check_table[] = {
&addr_size_cells, ®_format, &ranges_format,
&avoid_default_addr_size,
+ &obsolete_chosen_interrupt_controller,
};
int check_semantics(struct node *dt, int outversion, int boot_cpuid_phys);
@@ -715,27 +733,6 @@ static int check_memory(struct node *roo
return ok;
}
-static int check_chosen(struct node *root)
-{
- struct node *chosen;
- struct property *prop;
- int ok = 1;
-
- chosen = get_subnode(root, "chosen");
- if (!chosen)
- return ok;
-
- /* give warning for obsolete interrupt-controller property */
- do {
- if ((prop = get_property(chosen, "interrupt-controller")) != NULL) {
- WARNMSG("%s has obsolete \"%s\" property\n",
- chosen->fullpath, "interrupt-controller");
- }
- } while (0);
-
- return ok;
-}
-
int check_semantics(struct node *dt, int outversion, int boot_cpuid_phys)
{
int ok = 1;
@@ -743,7 +740,6 @@ int check_semantics(struct node *dt, int
ok = ok && check_root(dt);
ok = ok && check_cpus(dt, outversion, boot_cpuid_phys);
ok = ok && check_memory(dt);
- ok = ok && check_chosen(dt);
if (! ok)
return 0;
Index: dtc/tests/obsolete-chosen-interrupt-controller.dts
===================================================================
--- /dev/null 1970-01-01 00:00:00.000000000 +0000
+++ dtc/tests/obsolete-chosen-interrupt-controller.dts 2007-12-07 13:51:34.000000000 +1100
@@ -0,0 +1,13 @@
+/dts-v1/;
+
+/ {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ PIC: pic@0 {
+ reg = <0x0 0x10>;
+ interrupt-controller;
+ };
+ chosen {
+ interrupt-controller = <&PIC>;
+ };
+};
Index: dtc/tests/run_tests.sh
===================================================================
--- dtc.orig/tests/run_tests.sh 2007-12-07 13:51:44.000000000 +1100
+++ dtc/tests/run_tests.sh 2007-12-07 13:52:06.000000000 +1100
@@ -173,6 +173,7 @@ dtc_tests () {
run_test dtc-checkfails.sh reg_format ranges_format -- -I dts -O dtb bad-reg-ranges.dts
run_test dtc-checkfails.sh ranges_format -- -I dts -O dtb bad-empty-ranges.dts
run_test dtc-checkfails.sh avoid_default_addr_size -- -I dts -O dtb default-addr-size.dts
+ run_test dtc-checkfails.sh obsolete_chosen_interrupt_controller -- -I dts -O dtb obsolete-chosen-interrupt-controller.dts
}
while getopts "vt:m" ARG ; do
--
David Gibson | I'll have my music baroque, and my code
david AT gibson.dropbear.id.au | minimalist, thank you. NOT _the_ _other_
| _way_ _around_!
http://www.ozlabs.org/~dgibson
^ permalink raw reply
* Re: [PATCH 16/25] powerpc: EP405 boards support for arch/powerpc
From: Josh Boyer @ 2007-12-07 3:05 UTC (permalink / raw)
To: Benjamin Herrenschmidt; +Cc: linuxppc-dev
In-Reply-To: <20071206080127.1F2ACDDED0@ozlabs.org>
On Thu, 06 Dec 2007 19:00:15 +1100
Benjamin Herrenschmidt <benh@kernel.crashing.org> wrote:
>
> Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>
> ---
> Index: linux-work/arch/powerpc/boot/dts/ep405.dts
> ===================================================================
> --- /dev/null 1970-01-01 00:00:00.000000000 +0000
> +++ linux-work/arch/powerpc/boot/dts/ep405.dts 2007-12-03 12:58:45.000000000 +1100
> @@ -0,0 +1,221 @@
> +/*
> + * Device Tree Source for EP405
> + *
> + * Copyright 2007 IBM Corp.
> + * Josh Boyer <jwboyer@linux.vnet.ibm.com>
I still don't think I wrote this ;)
<snip>
> +static struct of_device_id ep405_of_bus[] = {
> + { .compatible = "ibm,plb3", },
> + { .compatible = "ibm,opb", },
> + { .compatible = "ibm,ebc", },
> + {},
> +};
> +
> +static int __init ep405_device_probe(void)
> +{
> + if (!machine_is(ep405))
> + return 0;
> +
> + /* FIXME: do bus probe here */
I should really remove this stupid FIXME from my files so people stop
copying it into theirs ;)
> + of_platform_bus_probe(NULL, ep405_of_bus, NULL);
> +
> + return 0;
> +}
> +device_initcall(ep405_device_probe);
> +
> +static void __init ep405_init_bcsr(void)
> +{
> + const u8 *irq_routing;
> + int i;
> +
> + /* Find the bloody thing & map it */
> + bcsr_node = of_find_compatible_node(NULL, NULL, "ep405-bcsr");
> + if (bcsr_node == NULL) {
> + printk(KERN_ERR "EP405 BCSR not found !\n");
> + return;
> + }
> + bcsr_regs = of_iomap(bcsr_node, 0);
> + if (bcsr_regs == NULL) {
> + printk(KERN_ERR "EP405 BCSR failed to map !\n");
> + return;
> + }
Is there a reason you have bcsr_node and bcsr_regs as static globals
and leave the mapping present? I can't see another use of them outside
of this function, which only gets called once.
> +
> + /* Get the irq-routing property and apply the routing to the CPLD */
> + irq_routing = of_get_property(bcsr_node, "irq-routing", NULL);
> + if (irq_routing == NULL)
> + return;
> + for (i = 0; i < 16; i++) {
> + u8 irq = irq_routing[i];
> + out_8(bcsr_regs + BCSR_XIRQ_SELECT, i);
> + out_8(bcsr_regs + BCSR_XIRQ_ROUTING, irq);
> + }
> + in_8(bcsr_regs + BCSR_XIRQ_SELECT);
> + mb();
> + out_8(bcsr_regs + BCSR_GPIO_IRQ_PAR_CTRL, 0xfe);
> +}
> +
> +static void __init ep405_setup_arch(void)
> +{
> + /* Find & init the BCSR CPLD */
> + ep405_init_bcsr();
> +}
> +
> +static int __init ep405_probe(void)
> +{
> + unsigned long root = of_get_flat_dt_root();
> +
> + if (!of_flat_dt_is_compatible(root, "ep405"))
> + return 0;
> +
> + return 1;
> +}
> +
> +define_machine(ep405) {
> + .name = "EP405",
> + .probe = ep405_probe,
> + .setup_arch = ep405_setup_arch,
> + .progress = udbg_progress,
> + .init_IRQ = uic_init_tree,
> + .get_irq = uic_get_irq,
> + .calibrate_decr = generic_calibrate_decr,
> +};
josh
^ permalink raw reply
* Re: [PATCH 18/25] powerpc: Base support for 440GX Taishan eval board
From: Josh Boyer @ 2007-12-07 3:17 UTC (permalink / raw)
To: Benjamin Herrenschmidt; +Cc: linuxppc-dev
In-Reply-To: <20071206080129.737E8DE09F@ozlabs.org>
On Thu, 06 Dec 2007 19:00:18 +1100
Benjamin Herrenschmidt <benh@kernel.crashing.org> wrote:
> From: Hugh Blemings <hugh@blemings.org>
>
>
> Signed-off-by: Hugh Blemings <hugh@blemings.org>
> Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>
> ---
> Index: linux-work/arch/powerpc/platforms/44x/Kconfig
> ===================================================================
> --- linux-work.orig/arch/powerpc/platforms/44x/Kconfig 2007-12-03 12:05:58.000000000 +1100
> +++ linux-work/arch/powerpc/platforms/44x/Kconfig 2007-12-03 13:52:59.000000000 +1100
> @@ -22,6 +22,14 @@ config SEQUOIA
> help
> This option enables support for the AMCC PPC440EPX evaluation board.
>
> +config TAISHAN
> + bool "Taishan"
> + depends on 44x
> + default n
> + select 440GX
> + help
> + This option enables support for the IBM PPC440GX "Taishan" evaluation board.
AMCC Taishan board.
> +
> #config LUAN
> # bool "Luan"
> # depends on 44x
> @@ -58,6 +66,10 @@ config 440GP
>
> config 440GX
> bool
> + select IBM_NEW_EMAC_EMAC4
> + select IBM_NEW_EMAC_RGMII
> + select IBM_NEW_EMAC_ZMII #test only
> + select IBM_NEW_EMAC_TAH #test only
>
> config 440SP
> bool
> Index: linux-work/arch/powerpc/platforms/44x/Makefile
> ===================================================================
> --- linux-work.orig/arch/powerpc/platforms/44x/Makefile 2007-12-03 11:48:01.000000000 +1100
> +++ linux-work/arch/powerpc/platforms/44x/Makefile 2007-12-03 13:52:59.000000000 +1100
> @@ -1,4 +1,5 @@
> obj-$(CONFIG_44x) := misc_44x.o
> obj-$(CONFIG_EBONY) += ebony.o
> +obj-$(CONFIG_TAISHAN) += taishan.o
> obj-$(CONFIG_BAMBOO) += bamboo.o
> obj-$(CONFIG_SEQUOIA) += sequoia.o
> Index: linux-work/arch/powerpc/platforms/44x/taishan.c
> ===================================================================
> --- /dev/null 1970-01-01 00:00:00.000000000 +0000
> +++ linux-work/arch/powerpc/platforms/44x/taishan.c 2007-12-03 13:39:01.000000000 +1100
> @@ -0,0 +1,74 @@
> +/*
> + * Taishan board specific routines based off ebony.c code
> + * original copyrights below
> + *
> + * Matt Porter <mporter@kernel.crashing.org>
> + * Copyright 2002-2005 MontaVista Software Inc.
> + *
> + * Eugene Surovegin <eugene.surovegin@zultys.com> or <ebs@ebshome.net>
> + * Copyright (c) 2003-2005 Zultys Technologies
> + *
> + * Rewritten and ported to the merged powerpc tree:
> + * Copyright 2007 David Gibson <dwg@au1.ibm.com>, IBM Corporation.
> + *
> + * Modified from ebony.c for taishan:
> + * Copyright 2007 Hugh Blemings <hugh@au.ibm.com>, IBM Corporation.
> + *
> + * 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/init.h>
> +#include <linux/of_platform.h>
> +
> +#include <asm/machdep.h>
> +#include <asm/prom.h>
> +#include <asm/udbg.h>
> +#include <asm/time.h>
> +#include <asm/uic.h>
> +#include <asm/pci-bridge.h>
> +
> +#include "44x.h"
> +
> +static struct of_device_id taishan_of_bus[] = {
> + { .compatible = "ibm,plb4", },
> + { .compatible = "ibm,opb", },
> + { .compatible = "ibm,ebc", },
> + {},
> +};
> +
> +static int __init taishan_device_probe(void)
> +{
> + if (!machine_is(taishan))
> + return 0;
> +
> + of_platform_bus_probe(NULL, taishan_of_bus, NULL);
> +
> + return 0;
> +}
> +device_initcall(taishan_device_probe);
> +
> +/*
> + * Called very early, MMU is off, device-tree isn't unflattened
> + */
> +static int __init taishan_probe(void)
> +{
> + unsigned long root = of_get_flat_dt_root();
> +
> + if (!of_flat_dt_is_compatible(root, "ibm,taishan"))
> + return 0;
amcc,taishan
> +
> + return 1;
> +}
> +
> +define_machine(taishan) {
> + .name = "Taishan",
> + .probe = taishan_probe,
> + .progress = udbg_progress,
> + .init_IRQ = uic_init_tree,
> + .get_irq = uic_get_irq,
> + .restart = ppc44x_reset_system,
> + .calibrate_decr = generic_calibrate_decr,
> +};
> Index: linux-work/arch/powerpc/boot/dts/taishan.dts
> ===================================================================
> --- /dev/null 1970-01-01 00:00:00.000000000 +0000
> +++ linux-work/arch/powerpc/boot/dts/taishan.dts 2007-12-03 13:39:01.000000000 +1100
> @@ -0,0 +1,414 @@
> +/*
> + * Device Tree Source for IBM/AMCC Taishan
> + *
<snip>
> + *
> + * To build:
> + * dtc -I dts -O asm -o taishan.S -b 0 taishan.dts
> + * dtc -I dts -O dtb -o taishan.dtb -b 0 taishan.dts
Remove this please. It's not really needed anymore.
> + */
> +
> +/ {
> + #address-cells = <2>;
> + #size-cells = <1>;
> + model = "ibm,taishan";
> + compatible = "ibm,taishan";
amcc,taishan
> + dcr-parent = <&/cpus/PowerPC,440GX@0>;
> +
> + cpus {
> + #address-cells = <1>;
> + #size-cells = <0>;
> +
> + PowerPC,440GX@0 {
> + device_type = "cpu";
> + reg = <0>;
> + clock-frequency = <2FAF0800>; // 800MHz
> + timebase-frequency = <0>; // Filled in by zImage
> + i-cache-line-size = <32>;
> + d-cache-line-size = <32>;
> + i-cache-size = <8000>; /* 32 kB */
> + d-cache-size = <8000>; /* 32 kB */
> + dcr-controller;
> + dcr-access-method = "native";
> + };
> + };
> +
> + memory {
> + device_type = "memory";
> + reg = <0 0 0>; // Filled in by zImage
> + };
> +
> +
> + UICB0: interrupt-controller-base {
> + compatible = "ibm,uic-440gx", "ibm,uic";
> + interrupt-controller;
> + cell-index = <3>;
> + dcr-reg = <200 009>;
> + #address-cells = <0>;
> + #size-cells = <0>;
> + #interrupt-cells = <2>;
> + };
> +
> +
> + UIC0: interrupt-controller0 {
> + compatible = "ibm,uic-440gx", "ibm,uic"; /* Should be AMCC ? */
This I think is fine as ibm,uic. Unless AMCC actually changed the UIC
to have differences, it was found on the IBM boards first :)
> + interrupt-controller;
> + cell-index = <0>;
> + dcr-reg = <0c0 009>;
> + #address-cells = <0>;
> + #size-cells = <0>;
> + #interrupt-cells = <2>;
> + interrupts = <01 4 00 4>; /* cascade - first non-critical */
> + interrupt-parent = <&UICB0>;
> +
> + };
> +
> + UIC1: interrupt-controller1 {
> + compatible = "ibm,uic-440gx", "ibm,uic";
> + interrupt-controller;
> + cell-index = <1>;
> + dcr-reg = <0d0 009>;
> + #address-cells = <0>;
> + #size-cells = <0>;
> + #interrupt-cells = <2>;
> + interrupts = <03 4 02 4>; /* cascade */
> + interrupt-parent = <&UICB0>;
> + };
> +
> + UIC2: interrupt-controller2 {
> + compatible = "ibm,uic-440gx", "ibm,uic";
> + interrupt-controller;
> + cell-index = <2>; /* was 1 */
> + dcr-reg = <210 009>;
> + #address-cells = <0>;
> + #size-cells = <0>;
> + #interrupt-cells = <2>;
> + interrupts = <05 4 04 4>; /* cascade */
> + interrupt-parent = <&UICB0>;
> + };
> +
> +
> + CPC0: cpc {
> + compatible = "ibm,cpc-440gp";
> + dcr-reg = <0b0 003 0e0 010>;
> + // FIXME: anything else?
> + };
> +
> + plb {
> + compatible = "ibm,plb-440gx", "ibm,plb4";
> + #address-cells = <2>;
> + #size-cells = <1>;
> + ranges;
> + clock-frequency = <9896800>; // 160MHz
> +
> + SDRAM0: memory-controller {
> + compatible = "ibm,sdram-440gp";
> + dcr-reg = <010 2>;
> + // FIXME: anything else?
> + };
> +
> + SRAM0: sram {
> + compatible = "ibm,sram-440gp";
> + dcr-reg = <020 8 00a 1>;
> + };
> +
> + DMA0: dma {
> + // FIXME: ???
> + compatible = "ibm,dma-440gp";
> + dcr-reg = <100 027>;
> + };
> +
> + MAL0: mcmal {
> + compatible = "ibm,mcmal-440gx", "ibm,mcmal2";
> + dcr-reg = <180 62>;
> + num-tx-chans = <4>;
> + num-rx-chans = <4>;
> + interrupt-parent = <&MAL0>;
> + interrupts = <0 1 2 3 4>;
> + #interrupt-cells = <1>;
> + #address-cells = <0>;
> + #size-cells = <0>;
> + interrupt-map = </*TXEOB*/ 0 &UIC0 a 4
> + /*RXEOB*/ 1 &UIC0 b 4
> + /*SERR*/ 2 &UIC1 0 4
> + /*TXDE*/ 3 &UIC1 1 4
> + /*RXDE*/ 4 &UIC1 2 4>;
> + interrupt-map-mask = <ffffffff>;
> + };
> +
> + POB0: opb {
> + compatible = "ibm,opb-440gx", "ibm,opb";
> + #address-cells = <1>;
> + #size-cells = <1>;
> + /* Wish there was a nicer way of specifying a full 32-bit
> + range */
> + ranges = <00000000 1 00000000 80000000
> + 80000000 1 80000000 80000000>;
> + dcr-reg = <090 00b>;
> + interrupt-parent = <&UIC1>;
> + interrupts = <7 4>;
> + clock-frequency = <4C4B400>; // 80MHz
> +
> +
> + /* Put EBC0 back **FIXME** */
Hrm?
> +
> + EBC0: ebc {
> + compatible = "ibm,ebc-440gx", "ibm,ebc";
> + dcr-reg = <012 2>;
> + #address-cells = <2>;
> + #size-cells = <1>;
> + clock-frequency = <4C4B400>; // 80MHz
> + // ranges property is supplied by zImage
> + // based on firmware's configuration of the
> + // EBC bridge
> + interrupts = <5 4>;
> + interrupt-parent = <&UIC1>;
> +
> +// small-flash@0,80000 {
> +// device_type = "rom";
> +// compatible = "direct-mapped";
> +// probe-type = "JEDEC";
> +// bank-width = <1>;
> +// partitions = <0 80000>;
> +// partition-names = "OpenBIOS";
> +// reg = <0 80000 80000>;
> +// };
You can probably just omit the child EBC nodes for now. Adding them
when they're right is pretty easy.
> +
> +// ds1743@1,0 {
> +// /* NVRAM & RTC */
> +// compatible = "ds1743";
> +// reg = <1 0 2000>;
> +// };
> +
> +// large-flash@2,0 {
> +// device_type = "rom";
> +// compatible = "direct-mapped";
> +// probe-type = "JEDEC";
> +// bank-width = <1>;
> +// partitions = <0 380000
> +// 380000 80000>;
> +// partition-names = "fs", "firmware";
> +// reg = <2 0 400000>;
> +// };
> +
> +// ir@3,0 {
> +// reg = <3 0 10>;
> +// };
> +
> +// fpga@7,0 {
> +// compatible = "Ebony-FPGA";
> +// reg = <7 0 10>;
> +// };
> + };
> +
> +
> + PCIX0: pci@20ec00000 {
> + device_type = "pci";
> + #interrupt-cells = <1>;
> + #size-cells = <2>;
> + #address-cells = <3>;
> + compatible = "ibm,plb440gp-pcix", "ibm,plb-pcix";
> + primary;
> + large-inbound-windows;
> + enable-msi-hole;
> + reg = <2 0ec00000 8 /* Config space access */
> + 0 0 0 /* no IACK cycles */
> + 2 0ed00000 4 /* Special cycles */
> + 2 0ec80000 100 /* Internal registers */
> + 2 0ec80100 fc>; /* Internal messaging registers */
> +
> + /* Outbound ranges, one memory and one IO,
> + * later cannot be changed
> + */
> + ranges = <02000000 0 80000000 00000003 80000000 0 80000000
> + 01000000 0 00000000 00000002 08000000 0 00010000>;
> +
> + /* Inbound 2GB range starting at 0 */
> + dma-ranges = <42000000 0 0 0 0 0 80000000>;
> +
> + /* Ebony has all 4 IRQ pins tied together per slot */
This isn't an Ebony board. Does Taishan do the same?
> + interrupt-map-mask = <f800 0 0 7>;
> + interrupt-map = <
> + /* IDSEL 1 */
> + 0800 0 0 1 &UIC0 17 8
> + 0800 0 0 2 &UIC0 18 8
> + 0800 0 0 3 &UIC0 19 8
> + 0800 0 0 4 &UIC0 1a 8
> +
> + /* IDSEL 2 */
> + 1000 0 0 1 &UIC0 18 8
> + 1000 0 0 2 &UIC0 19 8
> + 1000 0 0 3 &UIC0 1a 8
> + 1000 0 0 4 &UIC0 17 8
> + >;
> + };
> + };
> +
> + chosen {
> + linux,stdout-path = "/plb/opb/serial@40000300";
> + };
> +};
josh
^ permalink raw reply
* Re: [PATCH 19/25] powerpc: Wire up PCI on Bamboo board
From: Josh Boyer @ 2007-12-07 3:19 UTC (permalink / raw)
To: Benjamin Herrenschmidt; +Cc: linuxppc-dev
In-Reply-To: <20071206080130.2B29FDE0BA@ozlabs.org>
On Thu, 06 Dec 2007 19:00:19 +1100
Benjamin Herrenschmidt <benh@kernel.crashing.org> wrote:
> This adds the device-tree bits & call to ppc4xx_pci_find_bridges()
> to make PCI work on the Bamboo board
>
> Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>
> ---
>
> arch/powerpc/boot/dts/bamboo.dts | 40 ++++++++++++++++++++++++++++++++++++++-
> 1 file changed, 39 insertions(+), 1 deletion(-)
>
> Index: linux-work/arch/powerpc/boot/dts/bamboo.dts
> ===================================================================
> --- linux-work.orig/arch/powerpc/boot/dts/bamboo.dts 2007-11-30 13:40:21.000000000 +1100
> +++ linux-work/arch/powerpc/boot/dts/bamboo.dts 2007-11-30 13:40:45.000000000 +1100
> @@ -239,10 +239,48 @@
> zmii-channel = <1>;
> };
> };
> +
> + PCI0: pci@ec000000 {
> + device_type = "pci";
> + #interrupt-cells = <1>;
> + #size-cells = <2>;
> + #address-cells = <3>;
> + compatible = "ibm,plb440ep-pci", "ibm,plb-pci";
> + primary;
> + reg = <0 eec00000 8 /* Config space access */
> + 0 eed80000 4 /* IACK */
> + 0 eed80000 4 /* Special cycle */
> + 0 ef480000 40>; /* Internal registers */
> +
> + /* Outbound ranges, one memory and one IO,
> + * later cannot be changed. Chip supports a second
> + * IO range but we don't use it for now
> + */
> + ranges = <02000000 0 a0000000 0 a0000000 0 20000000
> + 01000000 0 00000000 0 e8000000 0 00010000>;
> +
> + /* Inbound 2GB range starting at 0 */
> + dma-ranges = <42000000 0 0 0 0 0 80000000>;
> +
> + /* Walnut has all 4 IRQ pins tied together per slot */
Not a Walnut board.
> + interrupt-map-mask = <f800 0 0 0>;
> + interrupt-map = <
> + /* IDSEL 1 */
> + 0800 0 0 0 &UIC0 1c 8
> +
> + /* IDSEL 2 */
> + 1000 0 0 0 &UIC0 1b 8
> +
> + /* IDSEL 3 */
> + 1800 0 0 0 &UIC0 1a 8
> +
> + /* IDSEL 4 */
> + 2000 0 0 0 &UIC0 19 8
> + >;
> + };
> };
>
> chosen {
> linux,stdout-path = "/plb/opb/serial@ef600300";
> - bootargs = "console=ttyS0,115200";
Did you remove that for a reason?
josh
^ permalink raw reply
* Re: [PATCH 21/25] powerpc: Adds decoding of 440SPE memory size to boot wrapper library
From: Josh Boyer @ 2007-12-07 3:22 UTC (permalink / raw)
To: Benjamin Herrenschmidt; +Cc: linuxppc-dev
In-Reply-To: <20071206080132.0CCE9DE109@ozlabs.org>
On Thu, 06 Dec 2007 19:00:20 +1100
Benjamin Herrenschmidt <benh@kernel.crashing.org> wrote:
> This adds a function to the bootwrapper 4xx library to decode memory
> size on 440SPE processors.
Why did you rename the fixup_memsize function? Could you add that to
the changelog, and perhaps a bit about adding the SDRAM0_{READ,WRITE}
macros.
josh
^ permalink raw reply
* Re: [PATCH 23/25] powerpc: Rework 4xx clock probing in boot wrapper
From: Josh Boyer @ 2007-12-07 3:27 UTC (permalink / raw)
To: Benjamin Herrenschmidt; +Cc: linuxppc-dev
In-Reply-To: <20071206080133.D24A9DE136@ozlabs.org>
On Thu, 06 Dec 2007 19:00:22 +1100
Benjamin Herrenschmidt <benh@kernel.crashing.org> wrote:
> Index: linux-work/arch/powerpc/boot/reg.h
> ===================================================================
> --- linux-work.orig/arch/powerpc/boot/reg.h 2007-12-03 14:26:09.000000000 +1100
> +++ linux-work/arch/powerpc/boot/reg.h 2007-12-03 14:26:09.000000000 +1100
> @@ -24,6 +24,14 @@ static inline u32 mfpvr(void)
> : "=r" (rval)); rval; })
> #define mtspr(rn, v) asm volatile("mtspr " __stringify(rn) ",%0" : : "r" (v))
>
> +#define __stringify_1(x) #x
> +#define __stringify(x) __stringify_1(x)
> +
> +#define mfspr(rn) ({unsigned long rval; \
> + asm volatile("mfspr %0," __stringify(rn) \
> + : "=r" (rval)); rval; })
> +#define mtspr(rn, v) asm volatile("mtspr " __stringify(rn) ",%0" : : "r" (v))
> +
You felt like duplicating this? It was added in the previous patch. :)
josh
^ permalink raw reply
* dtc: Reinstate full old-style reference-to-path for v0 dts files
From: David Gibson @ 2007-12-07 3:38 UTC (permalink / raw)
To: Jon Loeliger; +Cc: linuxppc-dev
Commit 7c44c2f9cb1cc2df7aacd13decfc4e64b73d1730 broke backwards
compatibility more badly than I realised. Contrary to what I thought
there are in-kernel, in-use dts files which relied on
references-to-path with paths including a comma, which no longer
compile after that commit.
So, this patch reinstates full support for bare references-to-path in
dts-v0 input. This means there will be some rather surprising lexical
corner cases when using path-expanded references in v0 files. But,
since path-expanded references are new, v0 files shouldn't typically
be using them anyway. If the corner cases cause a problem, you can
always convert to dts-v1 which handles the lexical issues here more
nicely.
Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
Index: dtc/dtc-lexer.l
===================================================================
--- dtc.orig/dtc-lexer.l 2007-12-07 14:22:19.000000000 +1100
+++ dtc/dtc-lexer.l 2007-12-07 14:32:04.000000000 +1100
@@ -27,7 +27,6 @@
PROPNODECHAR [a-zA-Z0-9,._+*#?@-]
PATHCHAR ({PROPNODECHAR}|[/])
-LEGACYPATHCHAR [a-zA-Z0-9_@/]
LABEL [a-zA-Z_][a-zA-Z0-9_]*
%{
@@ -158,7 +157,7 @@ static int dts_version; /* = 0 */
return DT_REF;
}
-<INITIAL>"&/"{LEGACYPATHCHAR}+ { /* old-style path reference */
+<INITIAL>"&/"{PATHCHAR}+ { /* old-style path reference */
yylloc.filenum = srcpos_filenum;
yylloc.first_line = yylineno;
DPRINT("Ref: %s\n", yytext+1);
--
David Gibson | I'll have my music baroque, and my code
david AT gibson.dropbear.id.au | minimalist, thank you. NOT _the_ _other_
| _way_ _around_!
http://www.ozlabs.org/~dgibson
^ permalink raw reply
* Re: dtc: Reinstate full old-style reference-to-path for v0 dts files
From: Josh Boyer @ 2007-12-07 3:39 UTC (permalink / raw)
To: David Gibson; +Cc: linuxppc-dev
In-Reply-To: <20071207033826.GD26412@localhost.localdomain>
On Fri, 7 Dec 2007 14:38:26 +1100
David Gibson <david@gibson.dropbear.id.au> wrote:
> Commit 7c44c2f9cb1cc2df7aacd13decfc4e64b73d1730 broke backwards
> compatibility more badly than I realised. Contrary to what I thought
> there are in-kernel, in-use dts files which relied on
> references-to-path with paths including a comma, which no longer
> compile after that commit.
There won't be shortly. I'm reworking them anyway.
josh
^ permalink raw reply
* Re: [PATCH 1/3] POWERPC: don't cast a pointer to pointer of list_head
From: Nick Piggin @ 2007-12-07 4:07 UTC (permalink / raw)
To: Li Zefan; +Cc: linuxppc-dev, Andrew Morton, paulus, LKML
In-Reply-To: <4757C1DA.6060603@cn.fujitsu.com>
On Thursday 06 December 2007 20:33, Li Zefan wrote:
> The casting is safe only when the list_head member is the
> first member of the structure.
Even so, I don't think too safe :) It might technically work,
but it could break more easily.
So even if you find places where list_head is the first member of
a structure, it would be nice to explicitly use the list_head member
and avoid casts IMO.
Thanks,
Nick
> Signed-off-by: Li Zefan <lizf@cn.fujitsu.com>
>
> ---
> arch/ppc/syslib/ocp.c | 2 +-
> 1 files changed, 1 insertions(+), 1 deletions(-)
>
> diff --git a/arch/ppc/syslib/ocp.c b/arch/ppc/syslib/ocp.c
> index 3f5be2c..d42d408 100644
> --- a/arch/ppc/syslib/ocp.c
> +++ b/arch/ppc/syslib/ocp.c
> @@ -376,7 +376,7 @@ ocp_remove_one_device(unsigned int vendor, unsigned int
> function, int index)
>
> down_write(&ocp_devices_sem);
> dev = __ocp_find_device(vendor, function, index);
> - list_del((struct list_head *)dev);
> + list_del(&dev->link);
> up_write(&ocp_devices_sem);
>
> DBG(("ocp: ocp_remove_one_device(vendor: %x, function: %x, index: %d)...
> done.\n", vendor, function, index));
^ permalink raw reply
* Re: dtc: Reinstate full old-style reference-to-path for v0 dts files
From: David Gibson @ 2007-12-07 4:16 UTC (permalink / raw)
To: Josh Boyer; +Cc: linuxppc-dev
In-Reply-To: <20071206213928.1f6a2e1f@zod.rchland.ibm.com>
On Thu, Dec 06, 2007 at 09:39:28PM -0600, Josh Boyer wrote:
> On Fri, 7 Dec 2007 14:38:26 +1100
> David Gibson <david@gibson.dropbear.id.au> wrote:
>
> > Commit 7c44c2f9cb1cc2df7aacd13decfc4e64b73d1730 broke backwards
> > compatibility more badly than I realised. Contrary to what I thought
> > there are in-kernel, in-use dts files which relied on
> > references-to-path with paths including a comma, which no longer
> > compile after that commit.
>
> There won't be shortly. I'm reworking them anyway.
I know, but I'd prefer that there was a broken range of dtc versions
than a broken range of kernel versions.
--
David Gibson | I'll have my music baroque, and my code
david AT gibson.dropbear.id.au | minimalist, thank you. NOT _the_ _other_
| _way_ _around_!
http://www.ozlabs.org/~dgibson
^ permalink raw reply
* dtc: Make dtc-checfails.sh script catch deaths-by-signal
From: David Gibson @ 2007-12-07 4:37 UTC (permalink / raw)
To: Jon Loeliger; +Cc: linuxppc-dev
Since commit 5ba0086bfd0fa6ab25f7ce1870417301a26c104f, the
dtc-checkfails.sh script does not check the return code from dtc.
That's reasonable, since depending on the checks we're testing, dtc
could either complete succesfully or return an error.
However, it's never right for dtc to SEGV or otherwise be killed by a
signal. So the script should catch that, and fail the testcase if it
happens. This patch implements this behaviour.
Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
Index: dtc/tests/dtc-checkfails.sh
===================================================================
--- dtc.orig/tests/dtc-checkfails.sh 2007-12-07 15:34:17.000000000 +1100
+++ dtc/tests/dtc-checkfails.sh 2007-12-07 15:35:22.000000000 +1100
@@ -17,6 +17,10 @@ rm -f $TMPFILE $LOG
verbose_run_log "$LOG" "$DTC" -o /dev/null "$@"
ret="$?"
+if [ "$ret" -gt 127 ]; then
+ FAIL "dtc killed by signal (ret=$ret)"
+fi
+
for c in $CHECKS; do
if ! grep -E "^(ERROR)|(Warning) \($c\):" $LOG > /dev/null; then
FAIL "Failed to trigger check \"%c\""
--
David Gibson | I'll have my music baroque, and my code
david AT gibson.dropbear.id.au | minimalist, thank you. NOT _the_ _other_
| _way_ _around_!
http://www.ozlabs.org/~dgibson
^ permalink raw reply
* RE: USB configuration
From: Misbah khan @ 2007-12-07 5:07 UTC (permalink / raw)
To: linuxppc-embedded
In-Reply-To: <BLU106-W40541C7A5C29E0CF526F13CA6F0@phx.gbl>
I have inserted a USB card reader, and the following dmesg it shows .....
---------------------------------------------------------------------------=
----
mpc8272ads: Init
PCI: Probing PCI hardware
PCI: Cannot allocate resource region 0 of device 0000:00:00.0
PCI: Cannot allocate resource region 1 of device 0000:00:00.0
SCSI subsystem initialized
Linux Kernel Card Services
options: [pci] [cardbus]
usbcore: registered new driver usbfs
usbcore: registered new driver hub
Serial: CPM driver $Revision: 0.01 $
ttyCPM0 at MMIO 0xf0011a00 (irq =3D 40) is a CPM UART
ttyCPM1 at MMIO 0xf0011a60 (irq =3D 43) is a CPM UART
io scheduler noop registered
io scheduler anticipatory registered
io scheduler deadline registered
io scheduler cfq registered
loop: loaded (max 8 devices)
fs_enet.c:v1.0 (Aug 8, 2005)
fs_enet: eth0 Phy @ 0x0, type DM9161 (0x0181b881)
fs_enet: eth1 Phy @ 0x3, type DM9161 (0x0181b881)
Uniform Multi-Platform E-IDE driver Revision: 7.00alpha2
ide: Assuming 33MHz system bus speed for PIO modes; override with idebus=3D=
xx
st: Version 20041025, fixed bufsize 32768, s/g segs 256
osst :I: Tape driver with OnStream support version 0.99.1
osst :I: $Id: osst.c,v 1.70 2003/12/23 14:22:12 wriede Exp $
ohci_hcd: 2004 Nov 08 USB 1.1 'Open' Host Controller (OHCI) Driver (PCI)
ohci_hcd: block sizes: ed 64 td 64
drivers/usb/serial/usb-serial.c: USB Serial support registered for Generic
usbcore: registered new driver usbserial_generic
usbcore: registered new driver usbserial
drivers/usb/serial/usb-serial.c: USB Serial Driver core v2.0
NET: Registered protocol family 2
IP: routing cache hash table of 512 buckets, 4Kbytes
TCP: Hash tables configured (established 4096 bind 8192)
NET: Registered protocol family 1
NET: Registered protocol family 17
IP-Config: Complete:
device=3Deth1, addr=3D192.168.33.136, mask=3D255.255.248.0,
gw=3D192.168.32.47,
host=3Dcashel, domain=3D, nis-domain=3D(none),
bootserver=3D192.168.33.96, rootserver=3D192.168.33.96, rootpath=3D
Looking up port of RPC 100003/2 on 192.168.33.96
Looking up port of RPC 100005/1 on 192.168.33.96
VFS: Mounted root (nfs filesystem).
Freeing unused kernel memory: 104k init
---------------------------------------------------------------------------=
-----------
This doesent gives me the clear explaination of whether USB is working
properly....
I would appreciate if you could share with me the basic steps to be followe=
d
to confirm that the USB support that i had configured is being tested in al=
l
aspects.
Misbah
Pedro Luis D. L. wrote:
>=20
>=20
>=20
>> Date: Thu, 6 Dec 2007 05:27:14 -0800
>> From: misbah_khan@engineer.com
>> To: linuxppc-embedded@ozlabs.org
>> Subject: USB configuration
>>=20
>>=20
>> HI all ...
>=20
> Hi,
>=20
>> I have configured the Montavista Kernel for USB support and for
>> PPC8272-ADS
>> board I need to know that how could i test that my USB is working ????
>>=20
>=20
> Try to attach an USB device, like a pendrive, to an USB port. Then type:=
=20
> dmesg | tail
>=20
> If the USB support is working properly, you should see some output saying
> which device have you attached and where is it mapped.
> If you plug a memory stick, you can try to mount it and check that the
> filesystem is correct.
>=20
> Pedro.
>=20
>> Its creating the directory :- /proc/bus/usb/ but doesent contain any fil=
e
>> under it ????
>>=20
>>=20
>> its also creating the directory :- /sys/bus/usb/ but doesent contain
>> any
>> file under it ????
>>=20
>>=20
>> Please let me know the procedure to test whether my USB configuration is
>> all
>> right ????
>>=20
>> Thank u=20
>> Misbah <><
>> --=20
>> View this message in context:
>> http://www.nabble.com/USB-configuration-tf4956061.html#a14192347
>> Sent from the linuxppc-embedded mailing list archive at Nabble.com.
>>=20
>> _______________________________________________
>> Linuxppc-embedded mailing list
>> Linuxppc-embedded@ozlabs.org
>> https://ozlabs.org/mailman/listinfo/linuxppc-embedded
>=20
> _________________________________________________________________
> Tecnolog=C3=ADa, moda, motor, viajes,=E2=80=A6suscr=C3=ADbete a nuestros =
boletines para
> estar a la =C3=BAltima
> http://newsletters.msn.com/hm/maintenanceeses.asp?L=3DES&C=3DES&P=3DWCMai=
ntenance&Brand=3DWL&RU=3Dhttp%3a%2f%2fmail.live.com
> _______________________________________________
> Linuxppc-embedded mailing list
> Linuxppc-embedded@ozlabs.org
> https://ozlabs.org/mailman/listinfo/linuxppc-embedded
>=20
>=20
--=20
View this message in context: http://www.nabble.com/USB-configuration-tf495=
6061.html#a14206951
Sent from the linuxppc-embedded mailing list archive at Nabble.com.
^ permalink raw reply
* Re: [PATCH 1/3] POWERPC: don't cast a pointer to pointer of list_head
From: Li Zefan @ 2007-12-07 5:05 UTC (permalink / raw)
To: Nick Piggin; +Cc: linuxppc-dev, Andrew Morton, paulus, LKML
In-Reply-To: <200712071507.10161.nickpiggin@yahoo.com.au>
Nick Piggin 写道:
> On Thursday 06 December 2007 20:33, Li Zefan wrote:
>> The casting is safe only when the list_head member is the
>> first member of the structure.
>
> Even so, I don't think too safe :) It might technically work,
> but it could break more easily.
>
> So even if you find places where list_head is the first member of
> a structure, it would be nice to explicitly use the list_head member
> and avoid casts IMO.
>
This is exactly what I think. Those patches actually fix no bugs, but
avoid this kind of technically and currently correct casting.
>
>> Signed-off-by: Li Zefan <lizf@cn.fujitsu.com>
>>
>> ---
>> arch/ppc/syslib/ocp.c | 2 +-
>> 1 files changed, 1 insertions(+), 1 deletions(-)
>>
>> diff --git a/arch/ppc/syslib/ocp.c b/arch/ppc/syslib/ocp.c
>> index 3f5be2c..d42d408 100644
>> --- a/arch/ppc/syslib/ocp.c
>> +++ b/arch/ppc/syslib/ocp.c
>> @@ -376,7 +376,7 @@ ocp_remove_one_device(unsigned int vendor, unsigned int
>> function, int index)
>>
>> down_write(&ocp_devices_sem);
>> dev = __ocp_find_device(vendor, function, index);
>> - list_del((struct list_head *)dev);
>> + list_del(&dev->link);
>> up_write(&ocp_devices_sem);
>>
>> DBG(("ocp: ocp_remove_one_device(vendor: %x, function: %x, index: %d)...
>> done.\n", vendor, function, index));
>
>
^ permalink raw reply
* [PATCH 1/3] [POWERPC] iSeries: DeCamelCase vpdinfo.c
From: Stephen Rothwell @ 2007-12-07 5:08 UTC (permalink / raw)
To: ppc-dev
In-Reply-To: <20071206180045.0eb1db98.sfr@canb.auug.org.au>
This is a purely mechanical transformation.
Signed-off-by: Stephen Rothwell <sfr@canb.auug.org.au>
---
arch/powerpc/platforms/iseries/pci.c | 2 +-
arch/powerpc/platforms/iseries/pci.h | 2 +-
arch/powerpc/platforms/iseries/vpdinfo.c | 188 +++++++++++++++---------------
3 files changed, 95 insertions(+), 97 deletions(-)
These three follow on from the 19 I posted last night.
diff --git a/arch/powerpc/platforms/iseries/pci.c b/arch/powerpc/platforms/iseries/pci.c
index 3071a30..5466975 100644
--- a/arch/powerpc/platforms/iseries/pci.c
+++ b/arch/powerpc/platforms/iseries/pci.c
@@ -227,7 +227,7 @@ void __init iSeries_pci_final_fixup(void)
pdev->sysdata = node;
PCI_DN(node)->pcidev = pdev;
allocate_device_bars(pdev);
- iSeries_Device_Information(pdev, num_dev, bus, *sub_bus);
+ iseries_device_information(pdev, num_dev, bus, *sub_bus);
iommu_devnode_init_iSeries(pdev, node);
}
iSeries_activate_IRQs();
diff --git a/arch/powerpc/platforms/iseries/pci.h b/arch/powerpc/platforms/iseries/pci.h
index b142873..5f517cf 100644
--- a/arch/powerpc/platforms/iseries/pci.h
+++ b/arch/powerpc/platforms/iseries/pci.h
@@ -47,7 +47,7 @@ struct pci_dev; /* For Forward Reference */
#define ISERIES_GET_DEVICE_FROM_SUBBUS(subbus) ((subbus >> 5) & 0x7)
#define ISERIES_GET_FUNCTION_FROM_SUBBUS(subbus) ((subbus >> 2) & 0x7)
-extern void iSeries_Device_Information(struct pci_dev *PciDev, int count,
+extern void iseries_device_information(struct pci_dev *pdev, int count,
u16 bus, HvSubBusNumber subbus);
#ifdef CONFIG_PCI
extern void iSeries_pcibios_init(void);
diff --git a/arch/powerpc/platforms/iseries/vpdinfo.c b/arch/powerpc/platforms/iseries/vpdinfo.c
index 25dc0bb..f9415bf 100644
--- a/arch/powerpc/platforms/iseries/vpdinfo.c
+++ b/arch/powerpc/platforms/iseries/vpdinfo.c
@@ -44,113 +44,111 @@
/*
* Bus Vpd Tags
*/
-#define VpdEndOfAreaTag 0x79
-#define VpdIdStringTag 0x82
-#define VpdVendorAreaTag 0x84
+#define VPD_END_OF_AREA 0x79
+#define VPD_ID_STRING 0x82
+#define VPD_VENDOR_AREA 0x84
/*
* Mfg Area Tags
*/
-#define VpdFruFrameId 0x4649 // "FI"
-#define VpdSlotMapFormat 0x4D46 // "MF"
-#define VpdSlotMap 0x534D // "SM"
+#define VPD_FRU_FRAME_ID 0x4649 /* "FI" */
+#define VPD_SLOT_MAP_FORMAT 0x4D46 /* "MF" */
+#define VPD_SLOT_MAP 0x534D /* "SM" */
/*
* Structures of the areas
*/
-struct MfgVpdAreaStruct {
- u16 Tag;
- u8 TagLength;
- u8 AreaData1;
- u8 AreaData2;
+struct mfg_vpd_area {
+ u16 tag;
+ u8 length;
+ u8 data1;
+ u8 data2;
};
-typedef struct MfgVpdAreaStruct MfgArea;
#define MFG_ENTRY_SIZE 3
-struct SlotMapStruct {
- u8 AgentId;
- u8 SecondaryAgentId;
- u8 PhbId;
- char CardLocation[3];
- char Parms[8];
- char Reserved[2];
+struct slot_map {
+ u8 agent;
+ u8 secondary_agent;
+ u8 phb;
+ char card_location[3];
+ char parms[8];
+ char reserved[2];
};
-typedef struct SlotMapStruct SlotMap;
#define SLOT_ENTRY_SIZE 16
/*
* Parse the Slot Area
*/
-static void __init iSeries_Parse_SlotArea(SlotMap *MapPtr, int MapLen,
- HvAgentId agent, u8 *PhbId, char card[4])
+static void __init iseries_parse_slot_area(struct slot_map *map, int len,
+ HvAgentId agent, u8 *phb, char card[4])
{
- int SlotMapLen = MapLen;
- SlotMap *SlotMapPtr = MapPtr;
+ int slot_map_len = len;
+ struct slot_map *slot_map = map;
/*
* Parse Slot label until we find the one requested
*/
- while (SlotMapLen > 0) {
- if (SlotMapPtr->AgentId == agent) {
+ while (slot_map_len > 0) {
+ if (slot_map->agent == agent) {
/*
* If Phb wasn't found, grab the entry first one found.
*/
- if (*PhbId == 0xff)
- *PhbId = SlotMapPtr->PhbId;
+ if (*phb == 0xff)
+ *phb = slot_map->phb;
/* Found it, extract the data. */
- if (SlotMapPtr->PhbId == *PhbId) {
- memcpy(card, &SlotMapPtr->CardLocation, 3);
+ if (slot_map->phb == *phb) {
+ memcpy(card, &slot_map->card_location, 3);
card[3] = 0;
break;
}
}
/* Point to the next Slot */
- SlotMapPtr = (SlotMap *)((char *)SlotMapPtr + SLOT_ENTRY_SIZE);
- SlotMapLen -= SLOT_ENTRY_SIZE;
+ slot_map = (struct slot_map *)((char *)slot_map + SLOT_ENTRY_SIZE);
+ slot_map_len -= SLOT_ENTRY_SIZE;
}
}
/*
* Parse the Mfg Area
*/
-static void __init iSeries_Parse_MfgArea(u8 *AreaData, int AreaLen,
- HvAgentId agent, u8 *PhbId,
+static void __init iseries_parse_mfg_area(u8 *area, int len,
+ HvAgentId agent, u8 *phb,
u8 *frame, char card[4])
{
- MfgArea *MfgAreaPtr = (MfgArea *)AreaData;
- int MfgAreaLen = AreaLen;
- u16 SlotMapFmt = 0;
+ struct mfg_vpd_area *mfg_area = (struct mfg_vpd_area *)area;
+ int mfg_area_len = len;
+ u16 slot_map_fmt = 0;
/* Parse Mfg Data */
- while (MfgAreaLen > 0) {
- int MfgTagLen = MfgAreaPtr->TagLength;
+ while (mfg_area_len > 0) {
+ int mfg_tag_len = mfg_area->length;
/* Frame ID (FI 4649020310 ) */
- if (MfgAreaPtr->Tag == VpdFruFrameId) /* FI */
- *frame = MfgAreaPtr->AreaData1;
+ if (mfg_area->tag == VPD_FRU_FRAME_ID)
+ *frame = mfg_area->data1;
/* Slot Map Format (MF 4D46020004 ) */
- else if (MfgAreaPtr->Tag == VpdSlotMapFormat) /* MF */
- SlotMapFmt = (MfgAreaPtr->AreaData1 * 256)
- + MfgAreaPtr->AreaData2;
+ else if (mfg_area->tag == VPD_SLOT_MAP_FORMAT)
+ slot_map_fmt = (mfg_area->data1 * 256)
+ + mfg_area->data2;
/* Slot Map (SM 534D90 */
- else if (MfgAreaPtr->Tag == VpdSlotMap) { /* SM */
- SlotMap *SlotMapPtr;
+ else if (mfg_area->tag == VPD_SLOT_MAP) {
+ struct slot_map *slot_map;
- if (SlotMapFmt == 0x1004)
- SlotMapPtr = (SlotMap *)((char *)MfgAreaPtr
+ if (slot_map_fmt == 0x1004)
+ slot_map = (struct slot_map *)((char *)mfg_area
+ MFG_ENTRY_SIZE + 1);
else
- SlotMapPtr = (SlotMap *)((char *)MfgAreaPtr
+ slot_map = (struct slot_map *)((char *)mfg_area
+ MFG_ENTRY_SIZE);
- iSeries_Parse_SlotArea(SlotMapPtr, MfgTagLen,
- agent, PhbId, card);
+ iseries_parse_slot_area(slot_map, mfg_tag_len,
+ agent, phb, card);
}
/*
* Point to the next Mfg Area
* Use defined size, sizeof give wrong answer
*/
- MfgAreaPtr = (MfgArea *)((char *)MfgAreaPtr + MfgTagLen
+ mfg_area = (struct mfg_vpd_area *)((char *)mfg_area + mfg_tag_len
+ MFG_ENTRY_SIZE);
- MfgAreaLen -= (MfgTagLen + MFG_ENTRY_SIZE);
+ mfg_area_len -= (mfg_tag_len + MFG_ENTRY_SIZE);
}
}
@@ -158,79 +156,79 @@ static void __init iSeries_Parse_MfgArea(u8 *AreaData, int AreaLen,
* Look for "BUS".. Data is not Null terminated.
* PHBID of 0xFF indicates PHB was not found in VPD Data.
*/
-static int __init iSeries_Parse_PhbId(u8 *AreaPtr, int AreaLength)
+static int __init iseries_parse_phbid(u8 *area, int len)
{
- u8 *PhbPtr = AreaPtr;
- int DataLen = AreaLength;
- char PhbId = 0xFF;
+ u8 *phb_ptr = area;
+ int data_len = len;
+ char phb = 0xFF;
- while (DataLen > 0) {
- if ((*PhbPtr == 'B') && (*(PhbPtr + 1) == 'U')
- && (*(PhbPtr + 2) == 'S')) {
- PhbPtr += 3;
- while (*PhbPtr == ' ')
- ++PhbPtr;
- PhbId = (*PhbPtr & 0x0F);
+ while (data_len > 0) {
+ if ((*phb_ptr == 'B') && (*(phb_ptr + 1) == 'U')
+ && (*(phb_ptr + 2) == 'S')) {
+ phb_ptr += 3;
+ while (*phb_ptr == ' ')
+ ++phb_ptr;
+ phb = (*phb_ptr & 0x0F);
break;
}
- ++PhbPtr;
- --DataLen;
+ ++phb_ptr;
+ --data_len;
}
- return PhbId;
+ return phb;
}
/*
* Parse out the VPD Areas
*/
-static void __init iSeries_Parse_Vpd(u8 *VpdData, int VpdDataLen,
+static void __init iseries_parse_vpd(u8 *data, int vpd_data_len,
HvAgentId agent, u8 *frame, char card[4])
{
- u8 *TagPtr = VpdData;
- int DataLen = VpdDataLen - 3;
- u8 PhbId = 0xff;
+ u8 *tag_ptr = data;
+ int data_len = vpd_data_len - 3;
+ u8 phb = 0xff;
- while ((*TagPtr != VpdEndOfAreaTag) && (DataLen > 0)) {
- int AreaLen = *(TagPtr + 1) + (*(TagPtr + 2) * 256);
- u8 *AreaData = TagPtr + 3;
+ while ((*tag_ptr != VPD_END_OF_AREA) && (data_len > 0)) {
+ int len = *(tag_ptr + 1) + (*(tag_ptr + 2) * 256);
+ u8 *area = tag_ptr + 3;
- if (*TagPtr == VpdIdStringTag)
- PhbId = iSeries_Parse_PhbId(AreaData, AreaLen);
- else if (*TagPtr == VpdVendorAreaTag)
- iSeries_Parse_MfgArea(AreaData, AreaLen,
- agent, &PhbId, frame, card);
+ if (*tag_ptr == VPD_ID_STRING)
+ phb = iseries_parse_phbid(area, len);
+ else if (*tag_ptr == VPD_VENDOR_AREA)
+ iseries_parse_mfg_area(area, len,
+ agent, &phb, frame, card);
/* Point to next Area. */
- TagPtr = AreaData + AreaLen;
- DataLen -= AreaLen;
+ tag_ptr = area + len;
+ data_len -= len;
}
}
-static int __init iSeries_Get_Location_Code(u16 bus, HvAgentId agent,
+static int __init iseries_get_location_code(u16 bus, HvAgentId agent,
u8 *frame, char card[4])
{
int status = 0;
- int BusVpdLen = 0;
- u8 *BusVpdPtr = kmalloc(BUS_VPDSIZE, GFP_KERNEL);
+ int bus_vpd_len = 0;
+ u8 *bus_vpd = kmalloc(BUS_VPDSIZE, GFP_KERNEL);
- if (BusVpdPtr == NULL) {
+ if (bus_vpd == NULL) {
printk("PCI: Bus VPD Buffer allocation failure.\n");
return 0;
}
- BusVpdLen = HvCallPci_getBusVpd(bus, iseries_hv_addr(BusVpdPtr),
+ bus_vpd_len = HvCallPci_getBusVpd(bus, iseries_hv_addr(bus_vpd),
BUS_VPDSIZE);
- if (BusVpdLen == 0) {
+ if (bus_vpd_len == 0) {
printk("PCI: Bus VPD Buffer zero length.\n");
goto out_free;
}
- /* printk("PCI: BusVpdPtr: %p, %d\n",BusVpdPtr, BusVpdLen); */
+ /* printk("PCI: bus_vpd: %p, %d\n",bus_vpd, bus_vpd_len); */
/* Make sure this is what I think it is */
- if (*BusVpdPtr != VpdIdStringTag) { /* 0x82 */
+ if (*bus_vpd != VPD_ID_STRING) {
printk("PCI: Bus VPD Buffer missing starting tag.\n");
goto out_free;
}
- iSeries_Parse_Vpd(BusVpdPtr, BusVpdLen, agent, frame, card);
+ iseries_parse_vpd(bus_vpd, bus_vpd_len, agent, frame, card);
status = 1;
out_free:
- kfree(BusVpdPtr);
+ kfree(bus_vpd);
return status;
}
@@ -243,7 +241,7 @@ out_free:
* PCI: Bus 0, Device 26, Vendor 0x12AE Frame 1, Card C10 Ethernet
* controller
*/
-void __init iSeries_Device_Information(struct pci_dev *PciDev, int count,
+void __init iseries_device_information(struct pci_dev *pdev, int count,
u16 bus, HvSubBusNumber subbus)
{
u8 frame = 0;
@@ -253,10 +251,10 @@ void __init iSeries_Device_Information(struct pci_dev *PciDev, int count,
agent = ISERIES_PCI_AGENTID(ISERIES_GET_DEVICE_FROM_SUBBUS(subbus),
ISERIES_GET_FUNCTION_FROM_SUBBUS(subbus));
- if (iSeries_Get_Location_Code(bus, agent, &frame, card)) {
+ if (iseries_get_location_code(bus, agent, &frame, card)) {
printk("%d. PCI: Bus%3d, Device%3d, Vendor %04X Frame%3d, "
"Card %4s 0x%04X\n", count, bus,
- PCI_SLOT(PciDev->devfn), PciDev->vendor, frame,
- card, (int)(PciDev->class >> 8));
+ PCI_SLOT(pdev->devfn), pdev->vendor, frame,
+ card, (int)(pdev->class >> 8));
}
}
--
1.5.3.7
--
Cheers,
Stephen Rothwell sfr@canb.auug.org.au
http://www.canb.auug.org.au/~sfr/
^ permalink raw reply related
* [PATCH 2/3] [POWERPC] iSeries: clean up and simplify vdpinfo.c
From: Stephen Rothwell @ 2007-12-07 5:09 UTC (permalink / raw)
To: ppc-dev
In-Reply-To: <20071206180045.0eb1db98.sfr@canb.auug.org.au>
Signed-off-by: Stephen Rothwell <sfr@canb.auug.org.au>
---
arch/powerpc/platforms/iseries/vpdinfo.c | 100 ++++++++++++++----------------
1 files changed, 46 insertions(+), 54 deletions(-)
diff --git a/arch/powerpc/platforms/iseries/vpdinfo.c b/arch/powerpc/platforms/iseries/vpdinfo.c
index f9415bf..aec82e3 100644
--- a/arch/powerpc/platforms/iseries/vpdinfo.c
+++ b/arch/powerpc/platforms/iseries/vpdinfo.c
@@ -82,62 +82,56 @@ struct slot_map {
static void __init iseries_parse_slot_area(struct slot_map *map, int len,
HvAgentId agent, u8 *phb, char card[4])
{
- int slot_map_len = len;
- struct slot_map *slot_map = map;
-
/*
* Parse Slot label until we find the one requested
*/
- while (slot_map_len > 0) {
- if (slot_map->agent == agent) {
+ while (len > 0) {
+ if (map->agent == agent) {
/*
* If Phb wasn't found, grab the entry first one found.
*/
if (*phb == 0xff)
- *phb = slot_map->phb;
+ *phb = map->phb;
/* Found it, extract the data. */
- if (slot_map->phb == *phb) {
- memcpy(card, &slot_map->card_location, 3);
+ if (map->phb == *phb) {
+ memcpy(card, &map->card_location, 3);
card[3] = 0;
break;
}
}
/* Point to the next Slot */
- slot_map = (struct slot_map *)((char *)slot_map + SLOT_ENTRY_SIZE);
- slot_map_len -= SLOT_ENTRY_SIZE;
+ map = (struct slot_map *)((char *)map + SLOT_ENTRY_SIZE);
+ len -= SLOT_ENTRY_SIZE;
}
}
/*
* Parse the Mfg Area
*/
-static void __init iseries_parse_mfg_area(u8 *area, int len,
- HvAgentId agent, u8 *phb,
- u8 *frame, char card[4])
+static void __init iseries_parse_mfg_area(struct mfg_vpd_area *area, int len,
+ HvAgentId agent, u8 *phb, u8 *frame, char card[4])
{
- struct mfg_vpd_area *mfg_area = (struct mfg_vpd_area *)area;
- int mfg_area_len = len;
u16 slot_map_fmt = 0;
/* Parse Mfg Data */
- while (mfg_area_len > 0) {
- int mfg_tag_len = mfg_area->length;
+ while (len > 0) {
+ int mfg_tag_len = area->length;
/* Frame ID (FI 4649020310 ) */
- if (mfg_area->tag == VPD_FRU_FRAME_ID)
- *frame = mfg_area->data1;
+ if (area->tag == VPD_FRU_FRAME_ID)
+ *frame = area->data1;
/* Slot Map Format (MF 4D46020004 ) */
- else if (mfg_area->tag == VPD_SLOT_MAP_FORMAT)
- slot_map_fmt = (mfg_area->data1 * 256)
- + mfg_area->data2;
+ else if (area->tag == VPD_SLOT_MAP_FORMAT)
+ slot_map_fmt = (area->data1 * 256)
+ + area->data2;
/* Slot Map (SM 534D90 */
- else if (mfg_area->tag == VPD_SLOT_MAP) {
+ else if (area->tag == VPD_SLOT_MAP) {
struct slot_map *slot_map;
if (slot_map_fmt == 0x1004)
- slot_map = (struct slot_map *)((char *)mfg_area
+ slot_map = (struct slot_map *)((char *)area
+ MFG_ENTRY_SIZE + 1);
else
- slot_map = (struct slot_map *)((char *)mfg_area
+ slot_map = (struct slot_map *)((char *)area
+ MFG_ENTRY_SIZE);
iseries_parse_slot_area(slot_map, mfg_tag_len,
agent, phb, card);
@@ -146,9 +140,9 @@ static void __init iseries_parse_mfg_area(u8 *area, int len,
* Point to the next Mfg Area
* Use defined size, sizeof give wrong answer
*/
- mfg_area = (struct mfg_vpd_area *)((char *)mfg_area + mfg_tag_len
+ area = (struct mfg_vpd_area *)((char *)area + mfg_tag_len
+ MFG_ENTRY_SIZE);
- mfg_area_len -= (mfg_tag_len + MFG_ENTRY_SIZE);
+ len -= (mfg_tag_len + MFG_ENTRY_SIZE);
}
}
@@ -156,48 +150,46 @@ static void __init iseries_parse_mfg_area(u8 *area, int len,
* Look for "BUS".. Data is not Null terminated.
* PHBID of 0xFF indicates PHB was not found in VPD Data.
*/
-static int __init iseries_parse_phbid(u8 *area, int len)
+static u8 __init iseries_parse_phbid(u8 *area, int len)
{
- u8 *phb_ptr = area;
- int data_len = len;
- char phb = 0xFF;
-
- while (data_len > 0) {
- if ((*phb_ptr == 'B') && (*(phb_ptr + 1) == 'U')
- && (*(phb_ptr + 2) == 'S')) {
- phb_ptr += 3;
- while (*phb_ptr == ' ')
- ++phb_ptr;
- phb = (*phb_ptr & 0x0F);
- break;
+ while (len > 0) {
+ if ((*area == 'B') && (*(area + 1) == 'U')
+ && (*(area + 2) == 'S')) {
+ area += 3;
+ while (*area == ' ')
+ area++;
+ return *area & 0x0F;
}
- ++phb_ptr;
- --data_len;
+ area++;
+ len--;
}
- return phb;
+ return 0xff;
}
/*
* Parse out the VPD Areas
*/
-static void __init iseries_parse_vpd(u8 *data, int vpd_data_len,
+static void __init iseries_parse_vpd(u8 *data, int data_len,
HvAgentId agent, u8 *frame, char card[4])
{
- u8 *tag_ptr = data;
- int data_len = vpd_data_len - 3;
u8 phb = 0xff;
- while ((*tag_ptr != VPD_END_OF_AREA) && (data_len > 0)) {
- int len = *(tag_ptr + 1) + (*(tag_ptr + 2) * 256);
- u8 *area = tag_ptr + 3;
+ while (data_len > 0) {
+ int len;
+ u8 tag = *data;
- if (*tag_ptr == VPD_ID_STRING)
- phb = iseries_parse_phbid(area, len);
- else if (*tag_ptr == VPD_VENDOR_AREA)
- iseries_parse_mfg_area(area, len,
+ if (tag == VPD_END_OF_AREA)
+ break;
+ len = *(data + 1) + (*(data + 2) * 256);
+ data += 3;
+ data_len -= 3;
+ if (tag == VPD_ID_STRING)
+ phb = iseries_parse_phbid(data, len);
+ else if (tag == VPD_VENDOR_AREA)
+ iseries_parse_mfg_area((struct mfg_vpd_area *)data, len,
agent, &phb, frame, card);
/* Point to next Area. */
- tag_ptr = area + len;
+ data += len;
data_len -= len;
}
}
--
1.5.3.7
--
Cheers,
Stephen Rothwell sfr@canb.auug.org.au
http://www.canb.auug.org.au/~sfr/
^ permalink raw reply related
* [PATCH 3/3] [POWERPC] iSeries: merge vpdinfo.c intp pci.c
From: Stephen Rothwell @ 2007-12-07 5:10 UTC (permalink / raw)
To: ppc-dev
In-Reply-To: <20071206180045.0eb1db98.sfr@canb.auug.org.au>
There was only one global function in vpdinfo.c and it was only called
from pci.c, so merge them and make the function static.
Signed-off-by: Stephen Rothwell <sfr@canb.auug.org.au>
---
arch/powerpc/platforms/iseries/Makefile | 2 +-
arch/powerpc/platforms/iseries/pci.c | 218 ++++++++++++++++++++++++++
arch/powerpc/platforms/iseries/pci.h | 6 -
arch/powerpc/platforms/iseries/vpdinfo.c | 252 ------------------------------
4 files changed, 219 insertions(+), 259 deletions(-)
delete mode 100644 arch/powerpc/platforms/iseries/vpdinfo.c
diff --git a/arch/powerpc/platforms/iseries/Makefile b/arch/powerpc/platforms/iseries/Makefile
index a65f1b4..cc7161f 100644
--- a/arch/powerpc/platforms/iseries/Makefile
+++ b/arch/powerpc/platforms/iseries/Makefile
@@ -5,7 +5,7 @@ extra-y += dt.o
obj-y += exception.o
obj-y += hvlog.o hvlpconfig.o lpardata.o setup.o dt_mod.o mf.o lpevents.o \
hvcall.o proc.o htab.o iommu.o misc.o irq.o
-obj-$(CONFIG_PCI) += pci.o vpdinfo.o
+obj-$(CONFIG_PCI) += pci.o
obj-$(CONFIG_SMP) += smp.o
obj-$(CONFIG_VIOPATH) += viopath.o vio.o
obj-$(CONFIG_MODULES) += ksyms.o
diff --git a/arch/powerpc/platforms/iseries/pci.c b/arch/powerpc/platforms/iseries/pci.c
index 5466975..68f248b 100644
--- a/arch/powerpc/platforms/iseries/pci.c
+++ b/arch/powerpc/platforms/iseries/pci.c
@@ -1,5 +1,6 @@
/*
* Copyright (C) 2001 Allan Trautman, IBM Corporation
+ * Copyright (C) 2005,2007 Stephen Rothwell, IBM Corp
*
* iSeries specific routines for PCI.
*
@@ -26,6 +27,7 @@
#include <linux/module.h>
#include <linux/pci.h>
+#include <asm/types.h>
#include <asm/io.h>
#include <asm/irq.h>
#include <asm/prom.h>
@@ -35,6 +37,7 @@
#include <asm/abs_addr.h>
#include <asm/firmware.h>
+#include <asm/iseries/hv_types.h>
#include <asm/iseries/hv_call_xm.h>
#include <asm/iseries/mf.h>
#include <asm/iseries/iommu.h>
@@ -80,6 +83,221 @@ static inline u64 iseries_ds_addr(struct device_node *node)
}
/*
+ * Size of Bus VPD data
+ */
+#define BUS_VPDSIZE 1024
+
+/*
+ * Bus Vpd Tags
+ */
+#define VPD_END_OF_AREA 0x79
+#define VPD_ID_STRING 0x82
+#define VPD_VENDOR_AREA 0x84
+
+/*
+ * Mfg Area Tags
+ */
+#define VPD_FRU_FRAME_ID 0x4649 /* "FI" */
+#define VPD_SLOT_MAP_FORMAT 0x4D46 /* "MF" */
+#define VPD_SLOT_MAP 0x534D /* "SM" */
+
+/*
+ * Structures of the areas
+ */
+struct mfg_vpd_area {
+ u16 tag;
+ u8 length;
+ u8 data1;
+ u8 data2;
+};
+#define MFG_ENTRY_SIZE 3
+
+struct slot_map {
+ u8 agent;
+ u8 secondary_agent;
+ u8 phb;
+ char card_location[3];
+ char parms[8];
+ char reserved[2];
+};
+#define SLOT_ENTRY_SIZE 16
+
+/*
+ * Parse the Slot Area
+ */
+static void __init iseries_parse_slot_area(struct slot_map *map, int len,
+ HvAgentId agent, u8 *phb, char card[4])
+{
+ /*
+ * Parse Slot label until we find the one requested
+ */
+ while (len > 0) {
+ if (map->agent == agent) {
+ /*
+ * If Phb wasn't found, grab the entry first one found.
+ */
+ if (*phb == 0xff)
+ *phb = map->phb;
+ /* Found it, extract the data. */
+ if (map->phb == *phb) {
+ memcpy(card, &map->card_location, 3);
+ card[3] = 0;
+ break;
+ }
+ }
+ /* Point to the next Slot */
+ map = (struct slot_map *)((char *)map + SLOT_ENTRY_SIZE);
+ len -= SLOT_ENTRY_SIZE;
+ }
+}
+
+/*
+ * Parse the Mfg Area
+ */
+static void __init iseries_parse_mfg_area(struct mfg_vpd_area *area, int len,
+ HvAgentId agent, u8 *phb, u8 *frame, char card[4])
+{
+ u16 slot_map_fmt = 0;
+
+ /* Parse Mfg Data */
+ while (len > 0) {
+ int mfg_tag_len = area->length;
+ /* Frame ID (FI 4649020310 ) */
+ if (area->tag == VPD_FRU_FRAME_ID)
+ *frame = area->data1;
+ /* Slot Map Format (MF 4D46020004 ) */
+ else if (area->tag == VPD_SLOT_MAP_FORMAT)
+ slot_map_fmt = (area->data1 * 256)
+ + area->data2;
+ /* Slot Map (SM 534D90 */
+ else if (area->tag == VPD_SLOT_MAP) {
+ struct slot_map *slot_map;
+
+ if (slot_map_fmt == 0x1004)
+ slot_map = (struct slot_map *)((char *)area
+ + MFG_ENTRY_SIZE + 1);
+ else
+ slot_map = (struct slot_map *)((char *)area
+ + MFG_ENTRY_SIZE);
+ iseries_parse_slot_area(slot_map, mfg_tag_len,
+ agent, phb, card);
+ }
+ /*
+ * Point to the next Mfg Area
+ * Use defined size, sizeof give wrong answer
+ */
+ area = (struct mfg_vpd_area *)((char *)area + mfg_tag_len
+ + MFG_ENTRY_SIZE);
+ len -= (mfg_tag_len + MFG_ENTRY_SIZE);
+ }
+}
+
+/*
+ * Look for "BUS".. Data is not Null terminated.
+ * PHBID of 0xFF indicates PHB was not found in VPD Data.
+ */
+static u8 __init iseries_parse_phbid(u8 *area, int len)
+{
+ while (len > 0) {
+ if ((*area == 'B') && (*(area + 1) == 'U')
+ && (*(area + 2) == 'S')) {
+ area += 3;
+ while (*area == ' ')
+ area++;
+ return *area & 0x0F;
+ }
+ area++;
+ len--;
+ }
+ return 0xff;
+}
+
+/*
+ * Parse out the VPD Areas
+ */
+static void __init iseries_parse_vpd(u8 *data, int data_len,
+ HvAgentId agent, u8 *frame, char card[4])
+{
+ u8 phb = 0xff;
+
+ while (data_len > 0) {
+ int len;
+ u8 tag = *data;
+
+ if (tag == VPD_END_OF_AREA)
+ break;
+ len = *(data + 1) + (*(data + 2) * 256);
+ data += 3;
+ data_len -= 3;
+ if (tag == VPD_ID_STRING)
+ phb = iseries_parse_phbid(data, len);
+ else if (tag == VPD_VENDOR_AREA)
+ iseries_parse_mfg_area((struct mfg_vpd_area *)data, len,
+ agent, &phb, frame, card);
+ /* Point to next Area. */
+ data += len;
+ data_len -= len;
+ }
+}
+
+static int __init iseries_get_location_code(u16 bus, HvAgentId agent,
+ u8 *frame, char card[4])
+{
+ int status = 0;
+ int bus_vpd_len = 0;
+ u8 *bus_vpd = kmalloc(BUS_VPDSIZE, GFP_KERNEL);
+
+ if (bus_vpd == NULL) {
+ printk("PCI: Bus VPD Buffer allocation failure.\n");
+ return 0;
+ }
+ bus_vpd_len = HvCallPci_getBusVpd(bus, iseries_hv_addr(bus_vpd),
+ BUS_VPDSIZE);
+ if (bus_vpd_len == 0) {
+ printk("PCI: Bus VPD Buffer zero length.\n");
+ goto out_free;
+ }
+ /* printk("PCI: bus_vpd: %p, %d\n",bus_vpd, bus_vpd_len); */
+ /* Make sure this is what I think it is */
+ if (*bus_vpd != VPD_ID_STRING) {
+ printk("PCI: Bus VPD Buffer missing starting tag.\n");
+ goto out_free;
+ }
+ iseries_parse_vpd(bus_vpd, bus_vpd_len, agent, frame, card);
+ status = 1;
+out_free:
+ kfree(bus_vpd);
+ return status;
+}
+
+/*
+ * Prints the device information.
+ * - Pass in pci_dev* pointer to the device.
+ * - Pass in the device count
+ *
+ * Format:
+ * PCI: Bus 0, Device 26, Vendor 0x12AE Frame 1, Card C10 Ethernet
+ * controller
+ */
+static void __init iseries_device_information(struct pci_dev *pdev, int count,
+ u16 bus, HvSubBusNumber subbus)
+{
+ u8 frame = 0;
+ char card[4];
+ HvAgentId agent;
+
+ agent = ISERIES_PCI_AGENTID(ISERIES_GET_DEVICE_FROM_SUBBUS(subbus),
+ ISERIES_GET_FUNCTION_FROM_SUBBUS(subbus));
+
+ if (iseries_get_location_code(bus, agent, &frame, card)) {
+ printk("%d. PCI: Bus%3d, Device%3d, Vendor %04X Frame%3d, "
+ "Card %4s 0x%04X\n", count, bus,
+ PCI_SLOT(pdev->devfn), pdev->vendor, frame,
+ card, (int)(pdev->class >> 8));
+ }
+}
+
+/*
* iomm_table_allocate_entry
*
* Adds pci_dev entry in address translation table
diff --git a/arch/powerpc/platforms/iseries/pci.h b/arch/powerpc/platforms/iseries/pci.h
index 5f517cf..180aa74 100644
--- a/arch/powerpc/platforms/iseries/pci.h
+++ b/arch/powerpc/platforms/iseries/pci.h
@@ -30,10 +30,6 @@
* End Change Activity
*/
-#include <asm/iseries/hv_types.h>
-
-struct pci_dev; /* For Forward Reference */
-
/*
* Decodes Linux DevFn to iSeries DevFn, bridge device, or function.
* For Linux, see PCI_SLOT and PCI_FUNC in include/linux/pci.h
@@ -47,8 +43,6 @@ struct pci_dev; /* For Forward Reference */
#define ISERIES_GET_DEVICE_FROM_SUBBUS(subbus) ((subbus >> 5) & 0x7)
#define ISERIES_GET_FUNCTION_FROM_SUBBUS(subbus) ((subbus >> 2) & 0x7)
-extern void iseries_device_information(struct pci_dev *pdev, int count,
- u16 bus, HvSubBusNumber subbus);
#ifdef CONFIG_PCI
extern void iSeries_pcibios_init(void);
extern void iSeries_pci_final_fixup(void);
diff --git a/arch/powerpc/platforms/iseries/vpdinfo.c b/arch/powerpc/platforms/iseries/vpdinfo.c
deleted file mode 100644
index aec82e3..0000000
--- a/arch/powerpc/platforms/iseries/vpdinfo.c
+++ /dev/null
@@ -1,252 +0,0 @@
-/*
- * This code gets the card location of the hardware
- * Copyright (C) 2001 <Allan H Trautman> <IBM Corp>
- * Copyright (C) 2005 Stephen Rothwel, 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.
- *
- * 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
- *
- * Change Activity:
- * Created, Feb 2, 2001
- * Ported to ppc64, August 20, 2001
- * End Change Activity
- */
-#include <linux/init.h>
-#include <linux/module.h>
-#include <linux/pci.h>
-
-#include <asm/types.h>
-#include <asm/resource.h>
-#include <asm/abs_addr.h>
-#include <asm/iseries/hv_types.h>
-
-#include "pci.h"
-#include "call_pci.h"
-
-/*
- * Size of Bus VPD data
- */
-#define BUS_VPDSIZE 1024
-
-/*
- * Bus Vpd Tags
- */
-#define VPD_END_OF_AREA 0x79
-#define VPD_ID_STRING 0x82
-#define VPD_VENDOR_AREA 0x84
-
-/*
- * Mfg Area Tags
- */
-#define VPD_FRU_FRAME_ID 0x4649 /* "FI" */
-#define VPD_SLOT_MAP_FORMAT 0x4D46 /* "MF" */
-#define VPD_SLOT_MAP 0x534D /* "SM" */
-
-/*
- * Structures of the areas
- */
-struct mfg_vpd_area {
- u16 tag;
- u8 length;
- u8 data1;
- u8 data2;
-};
-#define MFG_ENTRY_SIZE 3
-
-struct slot_map {
- u8 agent;
- u8 secondary_agent;
- u8 phb;
- char card_location[3];
- char parms[8];
- char reserved[2];
-};
-#define SLOT_ENTRY_SIZE 16
-
-/*
- * Parse the Slot Area
- */
-static void __init iseries_parse_slot_area(struct slot_map *map, int len,
- HvAgentId agent, u8 *phb, char card[4])
-{
- /*
- * Parse Slot label until we find the one requested
- */
- while (len > 0) {
- if (map->agent == agent) {
- /*
- * If Phb wasn't found, grab the entry first one found.
- */
- if (*phb == 0xff)
- *phb = map->phb;
- /* Found it, extract the data. */
- if (map->phb == *phb) {
- memcpy(card, &map->card_location, 3);
- card[3] = 0;
- break;
- }
- }
- /* Point to the next Slot */
- map = (struct slot_map *)((char *)map + SLOT_ENTRY_SIZE);
- len -= SLOT_ENTRY_SIZE;
- }
-}
-
-/*
- * Parse the Mfg Area
- */
-static void __init iseries_parse_mfg_area(struct mfg_vpd_area *area, int len,
- HvAgentId agent, u8 *phb, u8 *frame, char card[4])
-{
- u16 slot_map_fmt = 0;
-
- /* Parse Mfg Data */
- while (len > 0) {
- int mfg_tag_len = area->length;
- /* Frame ID (FI 4649020310 ) */
- if (area->tag == VPD_FRU_FRAME_ID)
- *frame = area->data1;
- /* Slot Map Format (MF 4D46020004 ) */
- else if (area->tag == VPD_SLOT_MAP_FORMAT)
- slot_map_fmt = (area->data1 * 256)
- + area->data2;
- /* Slot Map (SM 534D90 */
- else if (area->tag == VPD_SLOT_MAP) {
- struct slot_map *slot_map;
-
- if (slot_map_fmt == 0x1004)
- slot_map = (struct slot_map *)((char *)area
- + MFG_ENTRY_SIZE + 1);
- else
- slot_map = (struct slot_map *)((char *)area
- + MFG_ENTRY_SIZE);
- iseries_parse_slot_area(slot_map, mfg_tag_len,
- agent, phb, card);
- }
- /*
- * Point to the next Mfg Area
- * Use defined size, sizeof give wrong answer
- */
- area = (struct mfg_vpd_area *)((char *)area + mfg_tag_len
- + MFG_ENTRY_SIZE);
- len -= (mfg_tag_len + MFG_ENTRY_SIZE);
- }
-}
-
-/*
- * Look for "BUS".. Data is not Null terminated.
- * PHBID of 0xFF indicates PHB was not found in VPD Data.
- */
-static u8 __init iseries_parse_phbid(u8 *area, int len)
-{
- while (len > 0) {
- if ((*area == 'B') && (*(area + 1) == 'U')
- && (*(area + 2) == 'S')) {
- area += 3;
- while (*area == ' ')
- area++;
- return *area & 0x0F;
- }
- area++;
- len--;
- }
- return 0xff;
-}
-
-/*
- * Parse out the VPD Areas
- */
-static void __init iseries_parse_vpd(u8 *data, int data_len,
- HvAgentId agent, u8 *frame, char card[4])
-{
- u8 phb = 0xff;
-
- while (data_len > 0) {
- int len;
- u8 tag = *data;
-
- if (tag == VPD_END_OF_AREA)
- break;
- len = *(data + 1) + (*(data + 2) * 256);
- data += 3;
- data_len -= 3;
- if (tag == VPD_ID_STRING)
- phb = iseries_parse_phbid(data, len);
- else if (tag == VPD_VENDOR_AREA)
- iseries_parse_mfg_area((struct mfg_vpd_area *)data, len,
- agent, &phb, frame, card);
- /* Point to next Area. */
- data += len;
- data_len -= len;
- }
-}
-
-static int __init iseries_get_location_code(u16 bus, HvAgentId agent,
- u8 *frame, char card[4])
-{
- int status = 0;
- int bus_vpd_len = 0;
- u8 *bus_vpd = kmalloc(BUS_VPDSIZE, GFP_KERNEL);
-
- if (bus_vpd == NULL) {
- printk("PCI: Bus VPD Buffer allocation failure.\n");
- return 0;
- }
- bus_vpd_len = HvCallPci_getBusVpd(bus, iseries_hv_addr(bus_vpd),
- BUS_VPDSIZE);
- if (bus_vpd_len == 0) {
- printk("PCI: Bus VPD Buffer zero length.\n");
- goto out_free;
- }
- /* printk("PCI: bus_vpd: %p, %d\n",bus_vpd, bus_vpd_len); */
- /* Make sure this is what I think it is */
- if (*bus_vpd != VPD_ID_STRING) {
- printk("PCI: Bus VPD Buffer missing starting tag.\n");
- goto out_free;
- }
- iseries_parse_vpd(bus_vpd, bus_vpd_len, agent, frame, card);
- status = 1;
-out_free:
- kfree(bus_vpd);
- return status;
-}
-
-/*
- * Prints the device information.
- * - Pass in pci_dev* pointer to the device.
- * - Pass in the device count
- *
- * Format:
- * PCI: Bus 0, Device 26, Vendor 0x12AE Frame 1, Card C10 Ethernet
- * controller
- */
-void __init iseries_device_information(struct pci_dev *pdev, int count,
- u16 bus, HvSubBusNumber subbus)
-{
- u8 frame = 0;
- char card[4];
- HvAgentId agent;
-
- agent = ISERIES_PCI_AGENTID(ISERIES_GET_DEVICE_FROM_SUBBUS(subbus),
- ISERIES_GET_FUNCTION_FROM_SUBBUS(subbus));
-
- if (iseries_get_location_code(bus, agent, &frame, card)) {
- printk("%d. PCI: Bus%3d, Device%3d, Vendor %04X Frame%3d, "
- "Card %4s 0x%04X\n", count, bus,
- PCI_SLOT(pdev->devfn), pdev->vendor, frame,
- card, (int)(pdev->class >> 8));
- }
-}
--
1.5.3.7
--
Cheers,
Stephen Rothwell sfr@canb.auug.org.au
http://www.canb.auug.org.au/~sfr/
^ permalink raw reply related
* [RFC][POWERPC] Provide a way to protect 4k subpages when using 64k pages
From: Paul Mackerras @ 2007-12-07 6:09 UTC (permalink / raw)
To: linuxppc-dev, linux-kernel
Using 64k pages on 64-bit PowerPC systems makes life difficult for
emulators that are trying to emulate an ISA, such as x86, which use a
smaller page size, since the emulator can no longer use the MMU and
the normal system calls for controlling page protections. Of course,
the emulator can emulate the MMU by checking and possibly remapping
the address for each memory access in software, but that is pretty
slow.
This patch provides a facility for such programs to control the access
permissions on individual 4k sub-pages of a 64k page. The idea is
that the emulator supplies an array of protection masks to apply to a
specified range of virtual addresses. These masks are applied at the
level where hardware PTEs are inserted into the hardware page table
based on the Linux PTEs, so the Linux PTEs are not affected. Note
that this new mechanism does not allow any access that would otherwise
be prohibited; it can only prohibit accesses that would otherwise be
allowed. This new facility is only available on 64-bit PowerPC and
only when the kernel is configured for 64k pages.
The masks are supplied using a new subpage_prot system call, which
takes a starting virtual address and length, and a pointer to an array
of protection masks in memory. The array has a 32-bit word per 64k
page to be protected; each 32-bit word consists of 16 2-bit fields,
for which 0 allows any access (that is otherwise allowed), 1 prevents
write accesses, and 2 or 3 prevent any access.
Implicit in this is that the regions of the address space that are
protected are switched to use 4k hardware pages rather than 64k
hardware pages (on machines with hardware 64k page support). In fact
the whole process is switched to use 4k hardware pages when the
subpage_prot system call is used, but this could be improved in future
to switch only the affected segments.
I have re-purposed the ioperm system call for this. The old ioperm
system call never did anything (except return an ENOSYS error) and in
fact never could have actually been useful for anything on the PowerPC
architecture, so nothing ever used it.
Signed-off-by: Paul Mackerras <paulus@samba.org>
---
diff --git a/arch/powerpc/Kconfig b/arch/powerpc/Kconfig
index 232c298..0f5b968 100644
--- a/arch/powerpc/Kconfig
+++ b/arch/powerpc/Kconfig
@@ -340,6 +340,14 @@ config PPC_64K_PAGES
while on hardware with such support, it will be used to map
normal application pages.
+config PPC_SUBPAGE_PROT
+ bool "Support setting protections for 4k subpages"
+ depends on PPC_64K_PAGES
+ help
+ This option adds support for a system call to allow user programs
+ to set access permissions (read/write, readonly, or no access)
+ on the 4k subpages of each 64k page.
+
config SCHED_SMT
bool "SMT (Hyperthreading) scheduler support"
depends on PPC64 && SMP
diff --git a/arch/powerpc/kernel/head_64.S b/arch/powerpc/kernel/head_64.S
index c349868..11b4f6d 100644
--- a/arch/powerpc/kernel/head_64.S
+++ b/arch/powerpc/kernel/head_64.S
@@ -903,6 +903,7 @@ handle_page_fault:
* the PTE insertion
*/
12: bl .save_nvgprs
+ mr r5,r3
addi r3,r1,STACK_FRAME_OVERHEAD
ld r4,_DAR(r1)
bl .low_hash_fault
diff --git a/arch/powerpc/kernel/syscalls.c b/arch/powerpc/kernel/syscalls.c
index 3b1d5dd..5aabf48 100644
--- a/arch/powerpc/kernel/syscalls.c
+++ b/arch/powerpc/kernel/syscalls.c
@@ -36,12 +36,14 @@
#include <linux/file.h>
#include <linux/init.h>
#include <linux/personality.h>
+#include <linux/hugetlb.h>
#include <asm/uaccess.h>
#include <asm/semaphore.h>
#include <asm/syscalls.h>
#include <asm/time.h>
#include <asm/unistd.h>
+#include <asm/tlbflush.h>
/*
* sys_ipc() is the de-multiplexer for the SysV IPC calls..
@@ -328,3 +330,174 @@ void do_show_syscall_exit(unsigned long r3)
{
printk(" -> %lx, current=%p cpu=%d\n", r3, current, smp_processor_id());
}
+
+#ifdef CONFIG_PPC_SUBPAGE_PROT
+/*
+ * Clear the subpage protection map for an address range, allowing
+ * all accesses that are allowed by the pte permissions.
+ */
+static void subpage_prot_clear(unsigned long addr, unsigned long len)
+{
+ struct mm_struct *mm = current->mm;
+ pgd_t *pgd;
+ pud_t *pud;
+ pmd_t *pmd, *spm;
+ pte_t *pte;
+ u32 *spp;
+ spinlock_t *ptl;
+ int i, nw;
+ unsigned long next, limit;
+
+ down_write(&mm->mmap_sem);
+ for (limit = addr + len; addr < limit; addr = next) {
+ next = pmd_addr_end(addr, limit);
+ pgd = pgd_offset(mm, addr);
+ if (pgd_none(*pgd))
+ continue; /* can't happen with 3-level tables */
+ pud = pud_offset(pgd, addr);
+ if (pud_none(*pud))
+ continue;
+ pmd = pmd_offset(pud, addr);
+ if (!pmd)
+ continue;
+ for (; addr < next; ++pmd) {
+ spm = pmd + PTRS_PER_PMD;
+ spp = (u32 *) pmd_val(*spm);
+ i = (addr >> PAGE_SHIFT) & (PTRS_PER_PTE - 1);
+ nw = PTRS_PER_PTE - i;
+ if (addr + (nw << PAGE_SHIFT) > next)
+ nw = (next - addr) >> PAGE_SHIFT;
+ if (!spp) {
+ addr += nw * PAGE_SIZE;
+ continue;
+ }
+
+ /* See if we can dispose of the whole array here */
+ if (nw == PTRS_PER_PTE) {
+ spin_lock(&mm->page_table_lock);
+ pmd_val(*spm) = 0;
+ spin_unlock(&mm->page_table_lock);
+ kfree(spp);
+ } else
+ memset(spp + i, 0, nw * sizeof(u32));
+
+ /* now flush any existing HPTEs for the range */
+ pte = pte_offset_map_lock(mm, pmd, addr, &ptl);
+ arch_enter_lazy_mmu_mode();
+ for (; nw > 0; --nw) {
+ pte_update(mm, addr, pte, 0, 0);
+ addr += PAGE_SIZE;
+ ++pte;
+ }
+ arch_leave_lazy_mmu_mode();
+ pte_unmap_unlock(pte - 1, ptl);
+ }
+ }
+ up_write(&mm->mmap_sem);
+}
+
+/*
+ * Copy in a subpage protection map for an address range.
+ * The map has 2 bits per 4k subpage, so 32 bits per 64k page.
+ * Each 2-bit field is 0 to allow any access, 1 to prevent writes,
+ * 2 or 3 to prevent all accesses.
+ * Note that the normal page protections also apply; the subpage
+ * protection mechanism is an additional constraint, so putting 0
+ * in a 2-bit field won't allow writes to a page that is otherwise
+ * write-protected.
+ */
+long sys_subpage_prot(unsigned long addr, unsigned long len, u32 __user *map)
+{
+ struct mm_struct *mm = current->mm;
+ pgd_t *pgd;
+ pud_t *pud;
+ pmd_t *pmd, *spm;
+ pte_t *pte;
+ u32 *spp;
+ spinlock_t *ptl;
+ int i, nw;
+ unsigned long next, limit;
+ int err;
+
+ /* Check parameters */
+ if ((addr & ~PAGE_MASK) || (len & ~PAGE_MASK) ||
+ addr >= TASK_SIZE || len >= TASK_SIZE || addr + len > TASK_SIZE)
+ return -EINVAL;
+
+ if (is_hugepage_only_range(mm, addr, len))
+ return -EINVAL;
+
+ if (!map) {
+ /* Clear out the protection map for the address range */
+ subpage_prot_clear(addr, len);
+ return 0;
+ }
+
+ if (!access_ok(VERIFY_READ, map, (len >> PAGE_SHIFT) * sizeof(u32)))
+ return -EFAULT;
+
+ down_write(&mm->mmap_sem);
+ for (limit = addr + len; addr < limit; ) {
+ pgd = pgd_offset(mm, addr);
+ pud = pud_alloc(mm, pgd, addr);
+ err = -ENOMEM;
+ if (!pud)
+ goto out; /* can't happen with 3-level tables */
+ pmd = pmd_alloc(mm, pud, addr);
+ if (!pmd)
+ goto out;
+ next = pmd_addr_end(addr, limit);
+ while (addr < next) {
+ local_irq_disable();
+ demote_segment_4k(mm, addr);
+ slb_flush_and_rebolt();
+ local_irq_enable();
+
+ spm = pmd + PTRS_PER_PMD;
+ spp = (u32 *) pmd_val(*spm);
+ if (!spp) {
+ spp = kzalloc(PTRS_PER_PTE * sizeof(u32),
+ GFP_KERNEL);
+ err = -ENOMEM;
+ if (!spp)
+ goto out;
+ spin_lock(&mm->page_table_lock);
+ if (!pmd_val(*spm))
+ pmd_val(*spm) = (unsigned long) spp;
+ else {
+ kfree(spp);
+ spp = (u32 *) pmd_val(*spm);
+ }
+ spin_unlock(&mm->page_table_lock);
+ }
+ i = (addr >> PAGE_SHIFT) & (PTRS_PER_PTE - 1);
+ spp += i;
+ nw = PTRS_PER_PTE - i;
+ if (addr + (nw << PAGE_SHIFT) > next)
+ nw = (next - addr) >> PAGE_SHIFT;
+ err = -EFAULT;
+ if (__copy_from_user(spp, map, nw * sizeof(u32)))
+ goto out;
+ map += nw;
+
+ /* now flush any existing HPTEs for the range */
+ pte = pte_offset_map_lock(mm, pmd, addr, &ptl);
+ arch_enter_lazy_mmu_mode();
+ for (; nw > 0; --nw) {
+ pte_update(mm, addr, pte, 0, 0);
+ addr += PAGE_SIZE;
+ ++pte;
+ }
+ arch_leave_lazy_mmu_mode();
+ pte_unmap_unlock(pte - 1, ptl);
+ ++pmd;
+ }
+ }
+ err = 0;
+ out:
+ up_write(&mm->mmap_sem);
+ return err;
+}
+#else
+cond_syscall(subpage_prot);
+#endif
diff --git a/arch/powerpc/mm/hash_low_64.S b/arch/powerpc/mm/hash_low_64.S
index e935edd..21d2484 100644
--- a/arch/powerpc/mm/hash_low_64.S
+++ b/arch/powerpc/mm/hash_low_64.S
@@ -331,7 +331,8 @@ htab_pte_insert_failure:
*****************************************************************************/
/* _hash_page_4K(unsigned long ea, unsigned long access, unsigned long vsid,
- * pte_t *ptep, unsigned long trap, int local, int ssize)
+ * pte_t *ptep, unsigned long trap, int local, int ssize,
+ * int subpg_prot)
*/
/*
@@ -429,12 +430,19 @@ END_FTR_SECTION_IFSET(CPU_FTR_1T_SEGMENT)
xor r28,r28,r0 /* hash */
/* Convert linux PTE bits into HW equivalents */
-4: andi. r3,r30,0x1fe /* Get basic set of flags */
- xori r3,r3,HPTE_R_N /* _PAGE_EXEC -> NOEXEC */
+4:
+#ifdef CONFIG_PPC_SUBPAGE_PROT
+ andc r10,r30,r10
+ andi. r3,r10,0x1fe /* Get basic set of flags */
+ rlwinm r0,r10,32-9+1,30,30 /* _PAGE_RW -> _PAGE_USER (r0) */
+#else
+ andi. r3,r30,0x1fe /* Get basic set of flags */
rlwinm r0,r30,32-9+1,30,30 /* _PAGE_RW -> _PAGE_USER (r0) */
+#endif
+ xori r3,r3,HPTE_R_N /* _PAGE_EXEC -> NOEXEC */
rlwinm r4,r30,32-7+1,30,30 /* _PAGE_DIRTY -> _PAGE_USER (r4) */
and r0,r0,r4 /* _PAGE_RW & _PAGE_DIRTY ->r0 bit 30*/
- andc r0,r30,r0 /* r0 = pte & ~r0 */
+ andc r0,r3,r0 /* r0 = pte & ~r0 */
rlwimi r3,r0,32-1,31,31 /* Insert result into PP lsb */
ori r3,r3,HPTE_R_C /* Always add "C" bit for perf. */
diff --git a/arch/powerpc/mm/hash_utils_64.c b/arch/powerpc/mm/hash_utils_64.c
index f09730b..7b62359 100644
--- a/arch/powerpc/mm/hash_utils_64.c
+++ b/arch/powerpc/mm/hash_utils_64.c
@@ -643,7 +643,7 @@ unsigned int hash_page_do_lazy_icache(unsigned int pp, pte_t pte, int trap)
* For now this makes the whole process use 4k pages.
*/
#ifdef CONFIG_PPC_64K_PAGES
-static void demote_segment_4k(struct mm_struct *mm, unsigned long addr)
+void demote_segment_4k(struct mm_struct *mm, unsigned long addr)
{
if (mm->context.user_psize == MMU_PAGE_4K)
return;
@@ -654,10 +654,59 @@ static void demote_segment_4k(struct mm_struct *mm, unsigned long addr)
}
#endif /* CONFIG_PPC_64K_PAGES */
+#ifdef CONFIG_PPC_SUBPAGE_PROT
+/*
+ * This looks up a 2-bit protection code for a 4k subpage of a 64k page.
+ * Userspace sets the subpage permissions using the subpage_prot system call.
+ *
+ * Result is 0: full permissions, _PAGE_RW: read-only,
+ * _PAGE_USER or _PAGE_USER|_PAGE_RW: no access.
+ */
+static int subpage_protection(pgd_t *pgdir, unsigned long ea)
+{
+ u32 spp = 0;
+ pgd_t *pg;
+ pud_t *pu;
+ pmd_t *pm;
+ u32 *p;
+
+ if (is_kernel_addr(ea))
+ return 0;
+ pg = pgdir + pgd_index(ea);
+ if (pgd_none(*pg))
+ return 0; /* can't happen with 3-level tables */
+ pu = pud_offset(pg, ea);
+ if (pud_none(*pu))
+ return 0;
+ pm = pmd_offset(pu, ea);
+ pm += PTRS_PER_PMD;
+ if (!pmd_val(*pm))
+ return 0;
+
+ /* pick up 32 bits of permissions for this 64k page */
+ p = ((u32 *)pmd_val(*pm)) + ((ea >> PAGE_SHIFT) & (PTRS_PER_PTE - 1));
+ spp = *p;
+
+ /* extract 2-bit bitfield for this 4k subpage */
+ spp >>= 30 - 2 * ((ea >> 12) & 0xf);
+
+ /* turn 0,1,2,3 into combination of _PAGE_USER and _PAGE_RW */
+ spp = ((spp & 2) ? _PAGE_USER : 0) | ((spp & 1) ? _PAGE_RW : 0);
+ return spp;
+}
+
+#else /* CONFIG_PPC_SUBPAGE_PROT */
+static inline int subpage_protection(pgd_t *pgdir, unsigned long ea)
+{
+ return 0;
+}
+#endif
+
/* Result code is:
* 0 - handled
* 1 - normal page fault
* -1 - critical hash insertion error
+ * -2 - access not permitted by subpage protection mechanism
*/
int hash_page(unsigned long ea, unsigned long access, unsigned long trap)
{
@@ -808,7 +857,14 @@ int hash_page(unsigned long ea, unsigned long access, unsigned long trap)
rc = __hash_page_64K(ea, access, vsid, ptep, trap, local, ssize);
else
#endif /* CONFIG_PPC_HAS_HASH_64K */
- rc = __hash_page_4K(ea, access, vsid, ptep, trap, local, ssize);
+ {
+ int spp = subpage_protection(pgdir, ea);
+ if (access & spp)
+ rc = -2;
+ else
+ rc = __hash_page_4K(ea, access, vsid, ptep, trap,
+ local, ssize, spp);
+ }
#ifndef CONFIG_PPC_64K_PAGES
DBG_LOW(" o-pte: %016lx\n", pte_val(*ptep));
@@ -880,7 +936,8 @@ void hash_preload(struct mm_struct *mm, unsigned long ea,
__hash_page_64K(ea, access, vsid, ptep, trap, local, ssize);
else
#endif /* CONFIG_PPC_HAS_HASH_64K */
- __hash_page_4K(ea, access, vsid, ptep, trap, local, ssize);
+ __hash_page_4K(ea, access, vsid, ptep, trap, local, ssize,
+ subpage_protection(pgdir, ea));
local_irq_restore(flags);
}
@@ -925,19 +982,17 @@ void flush_hash_range(unsigned long number, int local)
* low_hash_fault is called when we the low level hash code failed
* to instert a PTE due to an hypervisor error
*/
-void low_hash_fault(struct pt_regs *regs, unsigned long address)
+void low_hash_fault(struct pt_regs *regs, unsigned long address, int rc)
{
if (user_mode(regs)) {
- siginfo_t info;
-
- info.si_signo = SIGBUS;
- info.si_errno = 0;
- info.si_code = BUS_ADRERR;
- info.si_addr = (void __user *)address;
- force_sig_info(SIGBUS, &info, current);
- return;
- }
- bad_page_fault(regs, address, SIGBUS);
+#ifdef CONFIG_PPC_SUBPAGE_PROT
+ if (rc == -2)
+ _exception(SIGSEGV, regs, SEGV_ACCERR, address);
+ else
+#endif
+ _exception(SIGBUS, regs, BUS_ADRERR, address);
+ } else
+ bad_page_fault(regs, address, SIGBUS);
}
#ifdef CONFIG_DEBUG_PAGEALLOC
diff --git a/arch/powerpc/mm/pgtable_64.c b/arch/powerpc/mm/pgtable_64.c
index 3ef0ad2..88940a3 100644
--- a/arch/powerpc/mm/pgtable_64.c
+++ b/arch/powerpc/mm/pgtable_64.c
@@ -232,3 +232,14 @@ EXPORT_SYMBOL(__ioremap_at);
EXPORT_SYMBOL(iounmap);
EXPORT_SYMBOL(__iounmap);
EXPORT_SYMBOL(__iounmap_at);
+
+#ifdef CONFIG_PPC_SUBPAGE_PROT
+void pmd_clear(pmd_t *pmd)
+{
+ pmd_val(*pmd) = 0;
+ if (pmd_val(pmd[PTRS_PER_PMD])) {
+ kfree((void *)pmd_val(pmd[PTRS_PER_PMD]));
+ pmd_val(pmd[PTRS_PER_PMD]) = 0;
+ }
+}
+#endif /* CONFIG_PPC_SUBPAGE_PROT */
diff --git a/include/asm-powerpc/mmu-hash64.h b/include/asm-powerpc/mmu-hash64.h
index 82328de..351e6e8 100644
--- a/include/asm-powerpc/mmu-hash64.h
+++ b/include/asm-powerpc/mmu-hash64.h
@@ -264,7 +264,7 @@ static inline unsigned long hpt_hash(unsigned long va, unsigned int shift,
extern int __hash_page_4K(unsigned long ea, unsigned long access,
unsigned long vsid, pte_t *ptep, unsigned long trap,
- unsigned int local, int ssize);
+ unsigned int local, int ssize, int subpage_prot);
extern int __hash_page_64K(unsigned long ea, unsigned long access,
unsigned long vsid, pte_t *ptep, unsigned long trap,
unsigned int local, int ssize);
@@ -277,6 +277,7 @@ extern int hash_huge_page(struct mm_struct *mm, unsigned long access,
extern int htab_bolt_mapping(unsigned long vstart, unsigned long vend,
unsigned long pstart, unsigned long mode,
int psize, int ssize);
+extern void demote_segment_4k(struct mm_struct *mm, unsigned long addr);
extern void htab_initialize(void);
extern void htab_initialize_secondary(void);
diff --git a/include/asm-powerpc/pgtable-64k.h b/include/asm-powerpc/pgtable-64k.h
index bd54b77..57430da 100644
--- a/include/asm-powerpc/pgtable-64k.h
+++ b/include/asm-powerpc/pgtable-64k.h
@@ -11,7 +11,11 @@
#ifndef __ASSEMBLY__
#define PTE_TABLE_SIZE (sizeof(real_pte_t) << PTE_INDEX_SIZE)
-#define PMD_TABLE_SIZE (sizeof(pmd_t) << PMD_INDEX_SIZE)
+#ifndef CONFIG_PPC_SUBPAGE_PROT
+# define PMD_TABLE_SIZE (sizeof(pmd_t) << PMD_INDEX_SIZE)
+#else
+# define PMD_TABLE_SIZE ((sizeof(pmd_t) << PMD_INDEX_SIZE) * 2)
+#endif
#define PGD_TABLE_SIZE (sizeof(pgd_t) << PGD_INDEX_SIZE)
#endif /* __ASSEMBLY__ */
diff --git a/include/asm-powerpc/pgtable-ppc64.h b/include/asm-powerpc/pgtable-ppc64.h
index dd4c26d..a5546e8 100644
--- a/include/asm-powerpc/pgtable-ppc64.h
+++ b/include/asm-powerpc/pgtable-ppc64.h
@@ -192,7 +192,11 @@ static inline pte_t pfn_pte(unsigned long pfn, pgprot_t pgprot)
#define pmd_bad(pmd) (!is_kernel_addr(pmd_val(pmd)) \
|| (pmd_val(pmd) & PMD_BAD_BITS))
#define pmd_present(pmd) (pmd_val(pmd) != 0)
-#define pmd_clear(pmdp) (pmd_val(*(pmdp)) = 0)
+#ifndef CONFIG_PPC_SUBPAGE_PROT
+# define pmd_clear(pmdp) (pmd_val(*(pmdp)) = 0)
+#else
+extern void pmd_clear(pmd_t *pmdp);
+#endif
#define pmd_page_vaddr(pmd) (pmd_val(pmd) & ~PMD_MASKED_BITS)
#define pmd_page(pmd) virt_to_page(pmd_page_vaddr(pmd))
diff --git a/include/asm-powerpc/systbl.h b/include/asm-powerpc/systbl.h
index 11d5383..73f9ab5 100644
--- a/include/asm-powerpc/systbl.h
+++ b/include/asm-powerpc/systbl.h
@@ -104,7 +104,7 @@ COMPAT_SYS_SPU(setpriority)
SYSCALL(ni_syscall)
COMPAT_SYS(statfs)
COMPAT_SYS(fstatfs)
-SYSCALL(ni_syscall)
+SYSCALL(subpage_prot)
COMPAT_SYS_SPU(socketcall)
COMPAT_SYS_SPU(syslog)
COMPAT_SYS_SPU(setitimer)
diff --git a/include/asm-powerpc/unistd.h b/include/asm-powerpc/unistd.h
index 97d82b6..bc7eebc 100644
--- a/include/asm-powerpc/unistd.h
+++ b/include/asm-powerpc/unistd.h
@@ -111,7 +111,7 @@
#define __NR_profil 98
#define __NR_statfs 99
#define __NR_fstatfs 100
-#define __NR_ioperm 101
+#define __NR_subpage_prot 101
#define __NR_socketcall 102
#define __NR_syslog 103
#define __NR_setitimer 104
^ permalink raw reply related
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