* [PATCH 21/22] [POWERPC] fsl_soc: add support for fsl_spi
From: Kumar Gala @ 2007-09-13 21:07 UTC (permalink / raw)
To: linuxppc-dev
In-Reply-To: <1189717711656-git-send-email-galak@kernel.crashing.org>
From: Anton Vorontsov <avorontsov@ru.mvista.com>
Add helper function to setup SPI bus/device information
Signed-off-by: Anton Vorontsov <avorontsov@ru.mvista.com>
Signed-off-by: Kumar Gala <galak@kernel.crashing.org>
---
arch/powerpc/sysdev/fsl_soc.c | 87 +++++++++++++++++++++++++++++++++++++++++
arch/powerpc/sysdev/fsl_soc.h | 7 +++
2 files changed, 94 insertions(+), 0 deletions(-)
diff --git a/arch/powerpc/sysdev/fsl_soc.c b/arch/powerpc/sysdev/fsl_soc.c
index 7012e51..d028e8d 100644
--- a/arch/powerpc/sysdev/fsl_soc.c
+++ b/arch/powerpc/sysdev/fsl_soc.c
@@ -24,6 +24,7 @@
#include <linux/platform_device.h>
#include <linux/of_platform.h>
#include <linux/phy.h>
+#include <linux/spi/spi.h>
#include <linux/fsl_devices.h>
#include <linux/fs_enet_pd.h>
#include <linux/fs_uart_pd.h>
@@ -1199,3 +1200,89 @@ err:
arch_initcall(cpm_smc_uart_of_init);
#endif /* CONFIG_8xx */
+
+int __init fsl_spi_init(struct spi_board_info *board_infos,
+ unsigned int num_board_infos,
+ void (*activate_cs)(u8 cs, u8 polarity),
+ void (*deactivate_cs)(u8 cs, u8 polarity))
+{
+ struct device_node *np;
+ unsigned int i;
+ const u32 *sysclk;
+
+ np = of_find_node_by_type(NULL, "qe");
+ if (!np)
+ return -ENODEV;
+
+ sysclk = of_get_property(np, "bus-frequency", NULL);
+ if (!sysclk)
+ return -ENODEV;
+
+ for (np = NULL, i = 1;
+ (np = of_find_compatible_node(np, "spi", "fsl_spi")) != NULL;
+ i++) {
+ int ret = 0;
+ unsigned int j;
+ const void *prop;
+ struct resource res[2];
+ struct platform_device *pdev;
+ struct fsl_spi_platform_data pdata = {
+ .activate_cs = activate_cs,
+ .deactivate_cs = deactivate_cs,
+ };
+
+ memset(res, 0, sizeof(res));
+
+ pdata.sysclk = *sysclk;
+
+ prop = of_get_property(np, "reg", NULL);
+ if (!prop)
+ goto err;
+ pdata.bus_num = *(u32 *)prop;
+
+ prop = of_get_property(np, "mode", NULL);
+ if (prop && !strcmp(prop, "cpu-qe"))
+ pdata.qe_mode = 1;
+
+ for (j = 0; j < num_board_infos; j++) {
+ if (board_infos[j].bus_num == pdata.bus_num)
+ pdata.max_chipselect++;
+ }
+
+ if (!pdata.max_chipselect)
+ goto err;
+
+ ret = of_address_to_resource(np, 0, &res[0]);
+ if (ret)
+ goto err;
+
+ ret = of_irq_to_resource(np, 0, &res[1]);
+ if (ret == NO_IRQ)
+ goto err;
+
+ pdev = platform_device_alloc("mpc83xx_spi", i);
+ if (!pdev)
+ goto err;
+
+ ret = platform_device_add_data(pdev, &pdata, sizeof(pdata));
+ if (ret)
+ goto unreg;
+
+ ret = platform_device_add_resources(pdev, res,
+ ARRAY_SIZE(res));
+ if (ret)
+ goto unreg;
+
+ ret = platform_device_register(pdev);
+ if (ret)
+ goto unreg;
+
+ continue;
+unreg:
+ platform_device_del(pdev);
+err:
+ continue;
+ }
+
+ return spi_register_board_info(board_infos, num_board_infos);
+}
diff --git a/arch/powerpc/sysdev/fsl_soc.h b/arch/powerpc/sysdev/fsl_soc.h
index 04e145b..618d91d 100644
--- a/arch/powerpc/sysdev/fsl_soc.h
+++ b/arch/powerpc/sysdev/fsl_soc.h
@@ -8,5 +8,12 @@ extern phys_addr_t get_immrbase(void);
extern u32 get_brgfreq(void);
extern u32 get_baudrate(void);
+struct spi_board_info;
+
+extern int fsl_spi_init(struct spi_board_info *board_infos,
+ unsigned int num_board_infos,
+ void (*activate_cs)(u8 cs, u8 polarity),
+ void (*deactivate_cs)(u8 cs, u8 polarity));
+
#endif
#endif
--
1.5.2.4
^ permalink raw reply related
* [PATCH 20/22] [POWERPC] 52xx: Fix mpc52xx_uart_of_assign to use correct index
From: Kumar Gala @ 2007-09-13 21:07 UTC (permalink / raw)
To: linuxppc-dev; +Cc: John Rigby
In-Reply-To: <11897177102281-git-send-email-galak@kernel.crashing.org>
From: John Rigby <jrigby@freescale.com>
Use idx as index into mpc52xx_uart_nodes instead of i
Signed-off-by: John Rigby <jrigby@freescale.com>
Signed-off-by: Kumar Gala <galak@kernel.crashing.org>
---
drivers/serial/mpc52xx_uart.c | 2 +-
1 files changed, 1 insertions(+), 1 deletions(-)
diff --git a/drivers/serial/mpc52xx_uart.c b/drivers/serial/mpc52xx_uart.c
index 35f8b86..035cca0 100644
--- a/drivers/serial/mpc52xx_uart.c
+++ b/drivers/serial/mpc52xx_uart.c
@@ -1051,7 +1051,7 @@ mpc52xx_uart_of_assign(struct device_node *np, int idx)
/* If the slot is already occupied, then swap slots */
if (mpc52xx_uart_nodes[idx] && (free_idx != -1))
mpc52xx_uart_nodes[free_idx] = mpc52xx_uart_nodes[idx];
- mpc52xx_uart_nodes[i] = np;
+ mpc52xx_uart_nodes[idx] = np;
}
static void
--
1.5.2.4
^ permalink raw reply related
* [PATCH 22/22] [POWERPC] MPC832x_RDB: Update dts to use SPI1 in QE, register mmc_spi stub
From: Kumar Gala @ 2007-09-13 21:08 UTC (permalink / raw)
To: linuxppc-dev
In-Reply-To: <11897177132273-git-send-email-galak@kernel.crashing.org>
From: Anton Vorontsov <avorontsov@ru.mvista.com>
mmc_spi already tested to work. When it will hit mainline
the only change that will be needed is replacing "spidev"
with "mmc_spi".
Signed-off-by: Anton Vorontsov <avorontsov@ru.mvista.com>
Signed-off-by: Kumar Gala <galak@kernel.crashing.org>
---
arch/powerpc/boot/dts/mpc832x_rdb.dts | 2 +-
arch/powerpc/platforms/83xx/mpc832x_rdb.c | 46 +++++++++++++++++++++++++++++
2 files changed, 47 insertions(+), 1 deletions(-)
diff --git a/arch/powerpc/boot/dts/mpc832x_rdb.dts b/arch/powerpc/boot/dts/mpc832x_rdb.dts
index cdc4a94..388c8a7 100644
--- a/arch/powerpc/boot/dts/mpc832x_rdb.dts
+++ b/arch/powerpc/boot/dts/mpc832x_rdb.dts
@@ -175,7 +175,7 @@
reg = <4c0 40>;
interrupts = <2>;
interrupt-parent = <&qeic>;
- mode = "cpu";
+ mode = "cpu-qe";
};
spi@500 {
diff --git a/arch/powerpc/platforms/83xx/mpc832x_rdb.c b/arch/powerpc/platforms/83xx/mpc832x_rdb.c
index e6c1760..24a790c 100644
--- a/arch/powerpc/platforms/83xx/mpc832x_rdb.c
+++ b/arch/powerpc/platforms/83xx/mpc832x_rdb.c
@@ -15,6 +15,7 @@
*/
#include <linux/pci.h>
+#include <linux/spi/spi.h>
#include <asm/of_platform.h>
#include <asm/time.h>
@@ -22,6 +23,7 @@
#include <asm/udbg.h>
#include <asm/qe.h>
#include <asm/qe_ic.h>
+#include <sysdev/fsl_soc.h>
#include "mpc83xx.h"
@@ -32,6 +34,50 @@
#define DBG(fmt...)
#endif
+static void mpc83xx_spi_activate_cs(u8 cs, u8 polarity)
+{
+ pr_debug("%s %d %d\n", __func__, cs, polarity);
+ par_io_data_set(3, 13, polarity);
+}
+
+static void mpc83xx_spi_deactivate_cs(u8 cs, u8 polarity)
+{
+ pr_debug("%s %d %d\n", __func__, cs, polarity);
+ par_io_data_set(3, 13, !polarity);
+}
+
+static struct spi_board_info mpc832x_spi_boardinfo = {
+ .bus_num = 0x4c0,
+ .chip_select = 0,
+ .max_speed_hz = 50000000,
+ /*
+ * XXX: This is spidev (spi in userspace) stub, should
+ * be replaced by "mmc_spi" when mmc_spi will hit mainline.
+ */
+ .modalias = "spidev",
+};
+
+static int __init mpc832x_spi_init(void)
+{
+ if (!machine_is(mpc832x_rdb))
+ return 0;
+
+ par_io_config_pin(3, 0, 3, 0, 1, 0); /* SPI1 MOSI, I/O */
+ par_io_config_pin(3, 1, 3, 0, 1, 0); /* SPI1 MISO, I/O */
+ par_io_config_pin(3, 2, 3, 0, 1, 0); /* SPI1 CLK, I/O */
+ par_io_config_pin(3, 3, 2, 0, 1, 0); /* SPI1 SEL, I */
+
+ par_io_config_pin(3, 13, 1, 0, 0, 0); /* !SD_CS, O */
+ par_io_config_pin(3, 14, 2, 0, 0, 0); /* SD_INSERT, I */
+ par_io_config_pin(3, 15, 2, 0, 0, 0); /* SD_PROTECT,I */
+
+ return fsl_spi_init(&mpc832x_spi_boardinfo, 1,
+ mpc83xx_spi_activate_cs,
+ mpc83xx_spi_deactivate_cs);
+}
+
+device_initcall(mpc832x_spi_init);
+
/* ************************************************************************
*
* Setup the architecture
--
1.5.2.4
^ permalink raw reply related
* [PATCH 18/22] [POWERPC] add clrsetbits macros
From: Kumar Gala @ 2007-09-13 21:07 UTC (permalink / raw)
To: linuxppc-dev; +Cc: Timur Tabi
In-Reply-To: <11897177071168-git-send-email-galak@kernel.crashing.org>
From: Timur Tabi <timur@freescale.com>
This patch adds the clrsetbits_xxx() macros, which are used to set and clear
multiple bits in a single read-modify-write operation. Specify the bits to
clear in the 'clear' parameter and the bits to set in the 'set' parameter.
These macros can also be used to set a multiple-bit bit pattern using a mask,
by specifying the mask in the 'clear' parameter and the new bit pattern in the
'set' parameter. There are big-endian and little-endian versions for 8, 16,
32, and 64 bits.
Signed-off-by: Timur Tabi <timur@freescale.com>
Signed-off-by: Kumar Gala <galak@kernel.crashing.org>
---
include/asm-powerpc/io.h | 23 +++++++++++++++++++++++
1 files changed, 23 insertions(+), 0 deletions(-)
diff --git a/include/asm-powerpc/io.h b/include/asm-powerpc/io.h
index 4c0b550..6805efb 100644
--- a/include/asm-powerpc/io.h
+++ b/include/asm-powerpc/io.h
@@ -737,6 +737,29 @@ static inline void * bus_to_virt(unsigned long address)
#define setbits8(_addr, _v) out_8((_addr), in_8(_addr) | (_v))
#define clrbits8(_addr, _v) out_8((_addr), in_8(_addr) & ~(_v))
+/* Clear and set bits in one shot. These macros can be used to clear and
+ * set multiple bits in a register using a single read-modify-write. These
+ * macros can also be used to set a multiple-bit bit pattern using a mask,
+ * by specifying the mask in the 'clear' parameter and the new bit pattern
+ * in the 'set' parameter.
+ */
+
+#define clrsetbits(type, addr, clear, set) \
+ out_##type((addr), (in_##type(addr) & ~(clear)) | (set))
+
+#ifdef __powerpc64__
+#define clrsetbits_be64(addr, clear, set) clrsetbits(be64, addr, clear, set)
+#define clrsetbits_le64(addr, clear, set) clrsetbits(le64, addr, clear, set)
+#endif
+
+#define clrsetbits_be32(addr, clear, set) clrsetbits(be32, addr, clear, set)
+#define clrsetbits_le32(addr, clear, set) clrsetbits(le32, addr, clear, set)
+
+#define clrsetbits_be16(addr, clear, set) clrsetbits(be16, addr, clear, set)
+#define clrsetbits_le16(addr, clear, set) clrsetbits(le32, addr, clear, set)
+
+#define clrsetbits_8(addr, clear, set) clrsetbits(8, addr, clear, set)
+
#endif /* __KERNEL__ */
#endif /* _ASM_POWERPC_IO_H */
--
1.5.2.4
^ permalink raw reply related
* [PATCH 19/22] [POWERPC] 86xx: Fix definition of global-utilites structure
From: Kumar Gala @ 2007-09-13 21:07 UTC (permalink / raw)
To: linuxppc-dev; +Cc: Timur Tabi
In-Reply-To: <11897177091972-git-send-email-galak@kernel.crashing.org>
From: Timur Tabi <timur@freescale.com>
The current definition of struct ccsr_guts in immap_86xx.h was for 85xx.
This patch fixes that and replaces the vague integer types with sized types
of the correct endianness. The unused struct ccsr_pci is also deleted.
Signed-off-by: Timur Tabi <timur@freescale.com>
Signed-off-by: Kumar Gala <galak@kernel.crashing.org>
---
include/asm-powerpc/immap_86xx.h | 151 ++++++++++++--------------------------
1 files changed, 46 insertions(+), 105 deletions(-)
diff --git a/include/asm-powerpc/immap_86xx.h b/include/asm-powerpc/immap_86xx.h
index 59b9e07..c83d7ad 100644
--- a/include/asm-powerpc/immap_86xx.h
+++ b/include/asm-powerpc/immap_86xx.h
@@ -1,124 +1,65 @@
-/*
+/**
* MPC86xx Internal Memory Map
*
- * Author: Jeff Brown
+ * Authors: Jeff Brown
+ * Timur Tabi <timur@freescale.com>
*
- * Copyright 2004 Freescale Semiconductor, Inc
+ * Copyright 2004,2007 Freescale Semiconductor, Inc
*
* 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 header file defines structures for various 86xx SOC devices that are
+ * used by multiple source files.
*/
#ifndef __ASM_POWERPC_IMMAP_86XX_H__
#define __ASM_POWERPC_IMMAP_86XX_H__
#ifdef __KERNEL__
-/* Eventually this should define all the IO block registers in 86xx */
-
-/* PCI Registers */
-typedef struct ccsr_pci {
- uint cfg_addr; /* 0x.000 - PCI Configuration Address Register */
- uint cfg_data; /* 0x.004 - PCI Configuration Data Register */
- uint int_ack; /* 0x.008 - PCI Interrupt Acknowledge Register */
- char res1[3060];
- uint potar0; /* 0x.c00 - PCI Outbound Transaction Address Register 0 */
- uint potear0; /* 0x.c04 - PCI Outbound Translation Extended Address Register 0 */
- uint powbar0; /* 0x.c08 - PCI Outbound Window Base Address Register 0 */
- char res2[4];
- uint powar0; /* 0x.c10 - PCI Outbound Window Attributes Register 0 */
- char res3[12];
- uint potar1; /* 0x.c20 - PCI Outbound Transaction Address Register 1 */
- uint potear1; /* 0x.c24 - PCI Outbound Translation Extended Address Register 1 */
- uint powbar1; /* 0x.c28 - PCI Outbound Window Base Address Register 1 */
- char res4[4];
- uint powar1; /* 0x.c30 - PCI Outbound Window Attributes Register 1 */
- char res5[12];
- uint potar2; /* 0x.c40 - PCI Outbound Transaction Address Register 2 */
- uint potear2; /* 0x.c44 - PCI Outbound Translation Extended Address Register 2 */
- uint powbar2; /* 0x.c48 - PCI Outbound Window Base Address Register 2 */
- char res6[4];
- uint powar2; /* 0x.c50 - PCI Outbound Window Attributes Register 2 */
- char res7[12];
- uint potar3; /* 0x.c60 - PCI Outbound Transaction Address Register 3 */
- uint potear3; /* 0x.c64 - PCI Outbound Translation Extended Address Register 3 */
- uint powbar3; /* 0x.c68 - PCI Outbound Window Base Address Register 3 */
- char res8[4];
- uint powar3; /* 0x.c70 - PCI Outbound Window Attributes Register 3 */
- char res9[12];
- uint potar4; /* 0x.c80 - PCI Outbound Transaction Address Register 4 */
- uint potear4; /* 0x.c84 - PCI Outbound Translation Extended Address Register 4 */
- uint powbar4; /* 0x.c88 - PCI Outbound Window Base Address Register 4 */
- char res10[4];
- uint powar4; /* 0x.c90 - PCI Outbound Window Attributes Register 4 */
- char res11[268];
- uint pitar3; /* 0x.da0 - PCI Inbound Translation Address Register 3 */
- char res12[4];
- uint piwbar3; /* 0x.da8 - PCI Inbound Window Base Address Register 3 */
- uint piwbear3; /* 0x.dac - PCI Inbound Window Base Extended Address Register 3 */
- uint piwar3; /* 0x.db0 - PCI Inbound Window Attributes Register 3 */
- char res13[12];
- uint pitar2; /* 0x.dc0 - PCI Inbound Translation Address Register 2 */
- char res14[4];
- uint piwbar2; /* 0x.dc8 - PCI Inbound Window Base Address Register 2 */
- uint piwbear2; /* 0x.dcc - PCI Inbound Window Base Extended Address Register 2 */
- uint piwar2; /* 0x.dd0 - PCI Inbound Window Attributes Register 2 */
- char res15[12];
- uint pitar1; /* 0x.de0 - PCI Inbound Translation Address Register 1 */
- char res16[4];
- uint piwbar1; /* 0x.de8 - PCI Inbound Window Base Address Register 1 */
- char res17[4];
- uint piwar1; /* 0x.df0 - PCI Inbound Window Attributes Register 1 */
- char res18[12];
- uint err_dr; /* 0x.e00 - PCI Error Detect Register */
- uint err_cap_dr; /* 0x.e04 - PCI Error Capture Disable Register */
- uint err_en; /* 0x.e08 - PCI Error Enable Register */
- uint err_attrib; /* 0x.e0c - PCI Error Attributes Capture Register */
- uint err_addr; /* 0x.e10 - PCI Error Address Capture Register */
- uint err_ext_addr; /* 0x.e14 - PCI Error Extended Address Capture Register */
- uint err_dl; /* 0x.e18 - PCI Error Data Low Capture Register */
- uint err_dh; /* 0x.e1c - PCI Error Data High Capture Register */
- uint gas_timr; /* 0x.e20 - PCI Gasket Timer Register */
- uint pci_timr; /* 0x.e24 - PCI Timer Register */
- char res19[472];
-} ccsr_pci_t;
-
/* Global Utility Registers */
-typedef struct ccsr_guts {
- uint porpllsr; /* 0x.0000 - POR PLL Ratio Status Register */
- uint porbmsr; /* 0x.0004 - POR Boot Mode Status Register */
- uint porimpscr; /* 0x.0008 - POR I/O Impedance Status and Control Register */
- uint pordevsr; /* 0x.000c - POR I/O Device Status Register */
- uint pordbgmsr; /* 0x.0010 - POR Debug Mode Status Register */
- char res1[12];
- uint gpporcr; /* 0x.0020 - General-Purpose POR Configuration Register */
- char res2[12];
- uint gpiocr; /* 0x.0030 - GPIO Control Register */
- char res3[12];
- uint gpoutdr; /* 0x.0040 - General-Purpose Output Data Register */
- char res4[12];
- uint gpindr; /* 0x.0050 - General-Purpose Input Data Register */
- char res5[12];
- uint pmuxcr; /* 0x.0060 - Alternate Function Signal Multiplex Control */
- char res6[12];
- uint devdisr; /* 0x.0070 - Device Disable Control */
- char res7[12];
- uint powmgtcsr; /* 0x.0080 - Power Management Status and Control Register */
- char res8[12];
- uint mcpsumr; /* 0x.0090 - Machine Check Summary Register */
- char res9[12];
- uint pvr; /* 0x.00a0 - Processor Version Register */
- uint svr; /* 0x.00a4 - System Version Register */
- char res10[3416];
- uint clkocr; /* 0x.0e00 - Clock Out Select Register */
- char res11[12];
- uint ddrdllcr; /* 0x.0e10 - DDR DLL Control Register */
- char res12[12];
- uint lbcdllcr; /* 0x.0e20 - LBC DLL Control Register */
- char res13[61916];
-} ccsr_guts_t;
+struct ccsr_guts {
+ __be32 porpllsr; /* 0x.0000 - POR PLL Ratio Status Register */
+ __be32 porbmsr; /* 0x.0004 - POR Boot Mode Status Register */
+ __be32 porimpscr; /* 0x.0008 - POR I/O Impedance Status and Control Register */
+ __be32 pordevsr; /* 0x.000c - POR I/O Device Status Register */
+ __be32 pordbgmsr; /* 0x.0010 - POR Debug Mode Status Register */
+ u8 res1[0x20 - 0x14];
+ __be32 porcir; /* 0x.0020 - POR Configuration Information Register */
+ u8 res2[0x30 - 0x24];
+ __be32 gpiocr; /* 0x.0030 - GPIO Control Register */
+ u8 res3[0x40 - 0x34];
+ __be32 gpoutdr; /* 0x.0040 - General-Purpose Output Data Register */
+ u8 res4[0x50 - 0x44];
+ __be32 gpindr; /* 0x.0050 - General-Purpose Input Data Register */
+ u8 res5[0x60 - 0x54];
+ __be32 pmuxcr; /* 0x.0060 - Alternate Function Signal Multiplex Control */
+ u8 res6[0x70 - 0x64];
+ __be32 devdisr; /* 0x.0070 - Device Disable Control */
+ u8 res7[0x80 - 0x74];
+ __be32 powmgtcsr; /* 0x.0080 - Power Management Status and Control Register */
+ u8 res8[0x90 - 0x84];
+ __be32 mcpsumr; /* 0x.0090 - Machine Check Summary Register */
+ __be32 rstrscr; /* 0x.0094 - Reset Request Status and Control Register */
+ u8 res9[0xA0 - 0x98];
+ __be32 pvr; /* 0x.00a0 - Processor Version Register */
+ __be32 svr; /* 0x.00a4 - System Version Register */
+ u8 res10[0xB0 - 0xA8];
+ __be32 rstcr; /* 0x.00b0 - Reset Control Register */
+ u8 res11[0xB20 - 0xB4];
+ __be32 ddr1clkdr; /* 0x.0b20 - DDRC1 Clock Disable Register */
+ __be32 ddr2clkdr; /* 0x.0b24 - DDRC2 Clock Disable Register */
+ u8 res12[0xE00 - 0xB28];
+ __be32 clkocr; /* 0x.0e00 - Clock Out Select Register */
+ u8 res13[0xF04 - 0xE04];
+ __be32 srds1cr0; /* 0x.0f04 - SerDes1 Control Register 0 */
+ __be32 srds1cr1; /* 0x.0f08 - SerDes1 Control Register 0 */
+ u8 res14[0xF40 - 0xF0C];
+ __be32 srds2cr0; /* 0x.0f40 - SerDes1 Control Register 0 */
+ __be32 srds2cr1; /* 0x.0f44 - SerDes1 Control Register 0 */
+};
#endif /* __ASM_POWERPC_IMMAP_86XX_H__ */
#endif /* __KERNEL__ */
--
1.5.2.4
^ permalink raw reply related
* Re: [PATCH 10/10] mpc82xx: Add pq2fads board support.
From: Kumar Gala @ 2007-09-13 21:15 UTC (permalink / raw)
To: Scott Wood; +Cc: linuxppc-dev
In-Reply-To: <20070913160539.GA32696@ld0162-tx32.am.freescale.net>
On Sep 13, 2007, at 11:05 AM, Scott Wood wrote:
> On Thu, Sep 13, 2007 at 01:39:58AM -0500, Kumar Gala wrote:
>>> + CS: chipselect {
>>
>> We need to document this in booting-without-of.
>
> OK.
cool. Want to make sure we can encompass the 83xx/85xx/86xx local
bus in there.
>>> + PIC: interrupt-controller@10c00 {
>>> + #interrupt-cells = <2>;
>>> + interrupt-controller;
>>> + reg = <10c00 80>;
>>> + compatible = "fsl,mpc8280-pic", "fsl,pq2-pic";
>>
>> this should also have a "fsl,cpm2-pic" or something of that form.
>> (exact same pic exists on 8560, 85xx+CPM)
>
> OK... I did it as pq2 rather than cpm2 because IIRC it wasn't
> described
> under the CPM section of the manual, so I didn't know if 85xx CPM2 had
> the same thing.
No problem. The cpm2_* code in the kernel is used on 85xx's that
have a CPM and I don't think we have that much ifdef for 85xx
specific CPM foo. Only thing I can think of is this bit in cpm2.h:
#if defined(CONFIG_8272) || defined(CONFIG_MPC8555)
#define CPM_DATAONLY_SIZE ((uint)(8 * 1024) - CPM_DATAONLY_BASE)
#define CPM_FCC_SPECIAL_BASE ((uint)0x00009000)
#else
- k
^ permalink raw reply
* Re: [PATCH 10/10] mpc82xx: Add pq2fads board support.
From: Scott Wood @ 2007-09-13 21:20 UTC (permalink / raw)
To: Kumar Gala; +Cc: linuxppc-dev
In-Reply-To: <E7B70993-BC1A-4DB1-9497-D2D8994AB366@kernel.crashing.org>
Kumar Gala wrote:
> No problem. The cpm2_* code in the kernel is used on 85xx's that have a
> CPM and I don't think we have that much ifdef for 85xx specific CPM
> foo. Only thing I can think of is this bit in cpm2.h:
>
> #if defined(CONFIG_8272) || defined(CONFIG_MPC8555)
> #define CPM_DATAONLY_SIZE ((uint)(8 * 1024) - CPM_DATAONLY_BASE)
> #define CPM_FCC_SPECIAL_BASE ((uint)0x00009000)
> #else
CPM_FCC_SPECIAL_BASE doesn't appear to be used anywhere in arch/powerpc.
CPM_DATAONLY_SIZE shouldn't be used anymore after this patchset.
-Scott
^ permalink raw reply
* Re: [PATCH] [POWERPC] 85xx: Add basic Uniprocessor MPC8572 DS port
From: Kumar Gala @ 2007-09-13 21:23 UTC (permalink / raw)
To: Segher Boessenkool; +Cc: linuxppc-dev
In-Reply-To: <5bba19e33a518178eb46f2a1758cff40@kernel.crashing.org>
On Sep 13, 2007, at 11:53 AM, Segher Boessenkool wrote:
>>> What is a "front side cache"? What exactly does it cache? If it's
>>> a cache for one CPU only, that fact should be shown in the device
>>> tree somehow.
>>
>> Its in front of the memory controllers. Its not specific to a
>> given CPU.
>
> Ah, I see. That relationship is implicit in the device tree already,
> both this cache controller and that memory controller are child nodes
> of the same soc node, so your device tree is fine.
>
> Just for my own understanding, is this a coherent cache? (I'm too
> lazy to read the manual ;-) )
yes its coherent. Our caches tend to be coherent.
- k
^ permalink raw reply
* Patches for 2.6.24 ??
From: Kumar Gala @ 2007-09-13 21:22 UTC (permalink / raw)
To: linuxppc-dev@ozlabs.org list; +Cc: linux-ppc-embedded ((((E-Mail))))
Guys,
If you have things you want or think should go into 2.6.24 please
speak up now!
- k
^ permalink raw reply
* Re: [PATCH v3] [POWERPC] 85xx: Add basic Uniprocessor MPC8572 DS port
From: Segher Boessenkool @ 2007-09-13 22:30 UTC (permalink / raw)
To: Kumar Gala; +Cc: linuxppc-dev
In-Reply-To: <96A13129-D16E-440D-B317-29BED85852D9@kernel.crashing.org>
>>>>> + PowerPC,8572@0 {
>>>>
>>>> Maybe it would be good to use "PowerPC,e500" instead -- it would
>>>> make it easier to probe for the actual CPU type, that way. Not
>>>> that Linux uses the name/compatible here at all ;-)
>>>
>>> I thought about this, not sure what the best solution is.
>>
>> Since the CPU cores on all these SoCs are identical (well, there
>> might be a few revisions, or different cache sizes or such -- minor
>> differences that can be probed for separately), it probably is a
>> good idea to name them in the tree instead of having each client
>> have its own table.
>>
>> Or is there anything about the CPU that can be derived from "8572"
>> but not from "e500"?
>
> Only in so much that we need something that states what the actual
> processor is.
You mean, something needs to say "8572"? I think the "soc" node
would be best for that.
It's all not terribly important, just something to think about.
>>>> And then there's the pci_bridge thing we're discussing on IRC, of
>>>> course -- basically, get rid of the pci_bridge pseudo-node, and
>>>> move the interrupt-map for the south-bridge devices into the
>>>> south-bridge node.
>>>
>>> Leaving the interrupt-map in the PHB because that works and moving
>>> it down has issues.
>>
>> Okay, fair enough. Are you looking at resolving those kernel issues?
>
> No. I've had enough of this device tree foo for a while :)
Heh okay :-)
> [I'm happy to test any patches related to this, if someone else comes
> up with them]
Well I don't know what the problem is ("it doesn't work" doesn't
say much), and don't have your hardware to test. Maybe we can do
it on IRC again ;-)
Segher
^ permalink raw reply
* Re: [PATCH] PowerPC: usb ehci of_platform bindings for Sequoia 440EPx
From: Segher Boessenkool @ 2007-09-13 22:36 UTC (permalink / raw)
To: Valentine Barshak; +Cc: linuxppc-dev
In-Reply-To: <20070913182453.GA26541@ru.mvista.com>
> EHCI OF bindings for PowerPC 440EPx Sequoia.
Those aren't bindings, they are examples. Bindings are pieces
of documentation that describe what device-specific properties
mean what, what standard properties are required with what
values, etc.
Examples are good to have, of course.
One thing you really need to document is what "ehci-be-desc"
and friends mean. I can give you one comment already: for
devices that are usually little-endian, but an implementation
implements registers as big-endian, precedent is to show that
in the device tree by including an (empty) "big-endian" property,
rather than inventing new "compatible" values.
Segher
^ permalink raw reply
* Re: [PATCH 04/22] [POWERPC] Update mpc7448hpc2 device tree to be compatible for tsi109 chip
From: Segher Boessenkool @ 2007-09-13 22:54 UTC (permalink / raw)
To: Kumar Gala; +Cc: linuxppc-dev
In-Reply-To: <11897176851400-git-send-email-galak@kernel.crashing.org>
> Update mpc7448hpc2 device tree to be compatible for tsi109 chip.
Do all those boards have a tsi109? If not, this patch is
incorrect. If they do, is tsi109 actually backward-compatible
to tsi108? That is, will a driver that knows about tsi108
only work correctly on a tsi109?
Also, all those names really should have a manufacturer
prefix ("XXX,...").
Segher
^ permalink raw reply
* Re: Flash on ep8248e standard motherboards
From: Erik Christiansen @ 2007-09-14 0:46 UTC (permalink / raw)
To: linuxppc-embedded
In-Reply-To: <46E944BE.1010007@qstreams.com>
On Thu, Sep 13, 2007 at 10:10:06AM -0400, Ben Warren wrote:
> >
> MIRRORX16 is the correct type for Spansion GL series NOR flash. AMD spun
> off their flash business a while ago and renamed it Spansion. If you
> look on the datasheet you'll see that Spansion calls the GL technology
> 'MirrorBit', and in all likelihood the device has a 16-bit data bus. The
> AMD algorithm may work but the MIRRORX16 definitely will.
Yes, the "Flash Organisation" section of the ep8248e manual shows two
16-bit devices. (That's what seemed erroneous in the BDI2000 config file
supplied with the card. ;-)
Many thanks for putting me on the right track w.r.t. CHIPTYPE. It'll
save me trying all the wrong guesses first.
Regards,
Erik
^ permalink raw reply
* Re: oftree and external connected devices
From: David Gibson @ 2007-09-14 1:22 UTC (permalink / raw)
To: Olof Johansson; +Cc: linuxppc-dev
In-Reply-To: <20070913132913.GA9031@lixom.net>
On Thu, Sep 13, 2007 at 08:29:13AM -0500, Olof Johansson wrote:
> On Thu, Sep 13, 2007 at 01:26:26PM +0200, Juergen Beisert wrote:
> > Hi,
> >
> > I'm using an MPC5200B based system with various external connected devices to
> > its LocalPlusBus. On other architectures I would register them as platform
> > devices (no chance to autodetect these devices). But on PowerPC architecture?
>
> If it's a special case of something that it's unlikely that you'll reuse
> the driver for, I'd say go ahead with a platform driver. There's nothing in the
> PPC kernel that stops it from working.
>
> We're just trying to avoid it for common devices that platforms might share,
> and instead of describing hardware in the platform devices setup, describe it
> in the device tree instead.
>
> So it depends on how much work you want to invest in it, and if you're
> planning on ever submitting the driver upstream. If you are, going
> with a simple device tree definiton would be best (the kernel side,
> to move a platform driver to instead be an of_platform driver is easy,
> and can be done afterwards).
>
> > Is the oftree description also intended to describe these kind of external
> > devices, or only SoC's internal devices? If its also intended for external
> > devices, how to do so? Are there any examples? I didn't find anything useful
> > yet.
>
> It can be used to describe on-board or off-board devices alike.
And should be used to describe any devices that can't otherwise be
probed, whether they're on-board or not.
--
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: Patches added to powerpc.git for-2.6.24 branch
From: Michael Neuling @ 2007-09-14 1:43 UTC (permalink / raw)
To: Paul Mackerras; +Cc: linuxppc-dev
In-Reply-To: <18153.30975.926456.819248@cargo.ozlabs.ibm.com>
Paulus,
Could you take this as well for 2.6.24?
Remove barriers from the SLB shadow buffer update
http://patchwork.ozlabs.org/linuxppc/patch?id=13116
Mikey
In message <18153.30975.926456.819248@cargo.ozlabs.ibm.com> you wrote:
> David Gibson (2):
> [POWERPC] Move bootwrapper's strchr() and strncmp() from .h to string.S
> [POWERPC] Document and implement an improved flash device binding for p
owerpc
>
> Geert Uytterhoeven (1):
> [POWERPC] PS3: Add new LV1 error codes
>
> Geoff Levand (1):
> [POWERPC] PS3: Enhance storage probe debug output
>
> Jeremy Kerr (1):
> [POWERPC] PS3: Fix CONFIG_SMP=n, CONFIG_KEXEC=y build
>
> Josh Boyer (6):
> [POWERPC] Remove dtc build cruft from DTS files
> [POWERPC] Fix bus probe on Bamboo board
> [POWERPC] Walnut DTS
> [POWERPC] Walnut defconfig
> [POWERPC] Walnut board support
> [POWERPC] Walnut zImage wrapper
>
> Kumar Gala (3):
> [POWERPC] Remove old includes from arch/ppc
> [POWERPC] Copy over headers from arch/ppc to arch/powerpc that we need
> [POWERPC] Stop include asm-ppc when building ARCH=powerpc for ppc32
>
> Linas Vepstas (4):
> [POWERPC] IOMMU virtual merge is no longer experimental
> [POWERPC] prom_init whitespace cleanup, typo fix
> [POWERPC] prom.c whitespace cleanup
> [POWERPC] setup_64.c and prom.c comment cleanup
>
> Michael Ellerman (5):
> [POWERPC] Add an optional device_node pointer to the irq_host
> [POWERPC] Invert null match behaviour for irq_hosts
> [POWERPC] Provide a default irq_host match, which matches on an exact o
f_node
> [POWERPC] Initialise hwirq for legacy irqs
> [POWERPC] Export virq mapping via debugfs
>
> Olof Johansson (10):
> [POWERPC] Export new __io{re,un}map_at() symbols
> [POWERPC] pasemi: Add pasemi_pci_getcfgaddr()
> [POWERPC] pasemi: Add workaround for erratum 5945
> [POWERPC] pasemi: Export more SPRs to sysfs when CONFIG_DEBUG_KERNEL=y
> [POWERPC] pasemi: Print more information at machine check
> [POWERPC] pasemi: Move pasemi_idle_init() to late_initcall()
> [POWERPC] Remove unused platform_machine_check()
> [POWERPC] Move lowlevel runlatch calls under cpu feature control
> [POWERPC] Remove warning in arch/powerpc/kernel/sysfs.c
> [POWERPC] Add workaround for MPICs with broken register reads
>
> Scott Wood (5):
> [POWERPC] bootwrapper: flatdevtree fixes
> [POWERPC] bootwrapper: Add strtoull()
> [POWERPC] bootwrapper: Add get_path()
> [POWERPC] bootwrapper: Only print MAC addresses when the node is actual
ly present
> [POWERPC] Check _PAGE_RW and _PAGE_PRESENT on kernel addresses
>
> Valentine Barshak (4):
> [POWERPC] PowerPC 440EPx: Sequoia device tree
> [POWERPC] PowerPC 440EPx: Sequoia defconfig
> [POWERPC] PowerPC 440EPx: Sequoia board support
> [POWERPC] PowerPC 440EPx: Sequoia bootwrapper
>
> _______________________________________________
> Linuxppc-dev mailing list
> Linuxppc-dev@ozlabs.org
> https://ozlabs.org/mailman/listinfo/linuxppc-dev
>
^ permalink raw reply
* Re: [PATCH 2/9] 8xx: Infrastructure code cleanup.
From: David Gibson @ 2007-09-14 4:09 UTC (permalink / raw)
To: Vitaly Bordug; +Cc: linuxppc-dev
In-Reply-To: <20070913121640.5764f656@localhost.localdomain>
On Thu, Sep 13, 2007 at 12:16:40PM +0400, Vitaly Bordug wrote:
[snip]
> > This looks bogus. You're replacing the old crap immr_map() functions,
> > which ioremap()ed the registers every time, with a much simpler
> > version which uses an established-once mapping of the register
> > region. AFAICT, anywah.
> >
> > So far, so good - but your immr_unmap() still does an iounmap() which
> > is surely wrong - it should now be a no-op, leaving the mpc8xx_immr
> > mapping intact. You probably get away with it by accident, because I
> > imagine attempting to unmap an unaligned chunk of the region will just
> > fail.
> >
>
> yes, it should do nop instead of iounmap.
> > In fact, with this patch in place, I'd like to see another patch which
> > removes all calls to immr_map() and immr_unmap(), simply accessing the
> > common mapping directly.
> >
> Sorry, but originally, that stuff was created to get rid of BSP
> ifdefs in drivers. For PQ family, it is a common practice to have
> single driver handling all 3 CPU families, which use the same logic,
> but immr structure differs a little bit.
>
> At this point it's clear case-by-case ioremapping does not have firm
> benefit, but getting back to the way it was is useless either. In
> ideal world, we'd have all those stuff put into dts and have
> specific drivers be a shim layer between core hw and IO drivers.
Err.. I don't understand what you're getting at. As the code stands
after Scott's cleanup, the map() and unmap() calls can certainly be
trivially removed, regardless of the history for them.
And, yes, the drivers should certainly uses addresses from the device
tree, rather than that revolting structure covering all the inbuilt
device retgisters.
--
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
* [PATCH 2/2] fsl/embedded6xx: don't cast the result of of_get_property
From: Jeremy Kerr @ 2007-09-14 5:46 UTC (permalink / raw)
To: linuxppc-dev
In-Reply-To: <1189748800.165136.731062325870.1.gpush@pokey>
Use a temporary variable of the correct type instead.
Also, this allows us to check the return value in ls_uarts_init, to
avoid dereferencing a null pointer if required properties aren't
present.
Signed-off-by: Jeremy Kerr <jk@ozlabs.org>
---
arch/powerpc/platforms/embedded6xx/ls_uart.c | 14 +++++++++-----
arch/powerpc/sysdev/fsl_soc.c | 18 ++++++++++--------
2 files changed, 19 insertions(+), 13 deletions(-)
diff --git a/arch/powerpc/platforms/embedded6xx/ls_uart.c b/arch/powerpc/platforms/embedded6xx/ls_uart.c
index d0bee9f..9d4b40c 100644
--- a/arch/powerpc/platforms/embedded6xx/ls_uart.c
+++ b/arch/powerpc/platforms/embedded6xx/ls_uart.c
@@ -103,20 +103,24 @@ static void __init ls_uart_init(void)
static int __init ls_uarts_init(void)
{
struct device_node *avr;
- phys_addr_t phys_addr;
+ const u32 *avr_clock_prop, *phys_addr;
int len;
avr = of_find_node_by_path("/soc10x/serial@80004500");
if (!avr)
return -EINVAL;
- avr_clock = *(u32*)of_get_property(avr, "clock-frequency", &len);
- phys_addr = ((u32*)of_get_property(avr, "reg", &len))[0];
+ phys_addr = of_get_property(avr, "reg", &len);
+ avr_clock_prop = of_get_property(avr, "clock-frequency", &len);
- if (!avr_clock || !phys_addr)
+ if (!avr_clock_prop || !phys_addr)
return -EINVAL;
- avr_addr = ioremap(phys_addr, 32);
+ avr_clock = *avr_clock_prop;
+ if (!avr_clock || !phys_addr[0])
+ return -EINVAL;
+
+ avr_addr = ioremap(phys_addr[0], 32);
if (!avr_addr)
return -EFAULT;
diff --git a/arch/powerpc/sysdev/fsl_soc.c b/arch/powerpc/sysdev/fsl_soc.c
index 1cf29c9..564d5e5 100644
--- a/arch/powerpc/sysdev/fsl_soc.c
+++ b/arch/powerpc/sysdev/fsl_soc.c
@@ -673,6 +673,7 @@ static int __init fs_enet_of_init(void)
struct fs_platform_info fs_enet_data;
const unsigned int *id, *phy_addr, *phy_irq;
const void *mac_addr;
+ const u32 *clk;
const phandle *ph;
const char *model;
@@ -740,10 +741,10 @@ static int __init fs_enet_of_init(void)
goto unreg;
}
- fs_enet_data.clk_rx = *((u32 *)of_get_property(np,
- "rx-clock", NULL));
- fs_enet_data.clk_tx = *((u32 *)of_get_property(np,
- "tx-clock", NULL));
+ clk = of_get_property(np, "rx-clock", NULL);
+ fs_enet_data.clk_rx = *clk;
+ clk = of_get_property(np, "tx-clock", NULL);
+ fs_enet_data.clk_tx = *clk;
if (strstr(model, "FCC")) {
int fcc_index = *id - 1;
@@ -844,6 +845,7 @@ static int __init cpm_uart_of_init(void)
struct resource r[3];
struct fs_uart_platform_info cpm_uart_data;
const int *id;
+ const u32 *clk;
const char *model;
memset(r, 0, sizeof(r));
@@ -882,10 +884,10 @@ static int __init cpm_uart_of_init(void)
cpm_uart_data.tx_buf_size = 32;
cpm_uart_data.rx_num_fifo = 4;
cpm_uart_data.rx_buf_size = 32;
- cpm_uart_data.clk_rx = *((u32 *)of_get_property(np,
- "rx-clock", NULL));
- cpm_uart_data.clk_tx = *((u32 *)of_get_property(np,
- "tx-clock", NULL));
+ clk = of_get_property(np, "rx-clock", NULL);
+ cpm_uart_data.clk_rx = *clk;
+ clk = of_get_property(np, "tx-clock", NULL);
+ cpm_uart_data.clk_tx = *clk;
ret =
platform_device_add_data(cpm_uart_dev, &cpm_uart_data,
^ permalink raw reply related
* [PATCH 1/2] cell: don't cast the result of of_get_property()
From: Jeremy Kerr @ 2007-09-14 5:46 UTC (permalink / raw)
To: linuxppc-dev
The cast to u32 * isn't required, of_get_property returns a void *.
Signed-off-by: Jeremy Kerr <jk@ozlabs.org>
---
arch/powerpc/platforms/cell/spu_manage.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/arch/powerpc/platforms/cell/spu_manage.c b/arch/powerpc/platforms/cell/spu_manage.c
index 0e14f53..1b01070 100644
--- a/arch/powerpc/platforms/cell/spu_manage.c
+++ b/arch/powerpc/platforms/cell/spu_manage.c
@@ -377,10 +377,10 @@ static int qs20_reg_memory[QS20_SPES_PER_BE] = { 1, 1, 0, 0, 0, 0, 0, 0 };
static struct spu *spu_lookup_reg(int node, u32 reg)
{
struct spu *spu;
- u32 *spu_reg;
+ const u32 *spu_reg;
list_for_each_entry(spu, &cbe_spu_info[node].spus, cbe_list) {
- spu_reg = (u32*)of_get_property(spu_devnode(spu), "reg", NULL);
+ spu_reg = of_get_property(spu_devnode(spu), "reg", NULL);
if (*spu_reg == reg)
return spu;
}
^ permalink raw reply related
* rtc-ds1742.c should use resource_size_t for base address
From: David Gibson @ 2007-09-14 5:54 UTC (permalink / raw)
To: Andrew Morton, Atsushi Nemoto; +Cc: linuxppc-dev, linux-kernel, rtc-linux
Currently the rtc driver, rtc-ds1742.c uses an unsigned long to store
the base mmio address of the NVRAM/RTC. This breaks on systems like
PowerPC 440, which is a 32-bit core with 36-bit physical addresses: IO
on the system, including the RTC, is typically above the 4GB point,
and cannot fit into an unsigned long.
This patch fixes the problem by replacing the unsigned long with a
resource_size_t. Tested on Ebony (PPC440) (with additional patches to
instantiate the ds1742 platform device appropriately).
Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
Index: working-2.6/drivers/rtc/rtc-ds1742.c
===================================================================
--- working-2.6.orig/drivers/rtc/rtc-ds1742.c 2007-09-14 15:43:31.000000000 +1000
+++ working-2.6/drivers/rtc/rtc-ds1742.c 2007-09-14 15:44:09.000000000 +1000
@@ -55,7 +55,7 @@ struct rtc_plat_data {
void __iomem *ioaddr_rtc;
size_t size_nvram;
size_t size;
- unsigned long baseaddr;
+ resource_size_t baseaddr;
unsigned long last_jiffies;
};
--
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
* [PATCH 19/25] spufs: Internal __spufs_get_foo() routines should take a spu_context *
From: Jeremy Kerr @ 2007-09-14 6:32 UTC (permalink / raw)
To: linuxppc-dev
In-Reply-To: <1189751574.98527.127994196313.1.gpush@pokey>
From: Michael Ellerman <michael@ellerman.id.au>
The SPUFS attribute get routines take a void * because the generic attribute
code doesn't know what sort of data it's passing around.
However our internal __spufs_get_foo() routines can take a spu_context *
directly, which saves plonking it in and out of a void * again.
Signed-off-by: Michael Ellerman <michael@ellerman.id.au>
Signed-off-by: Jeremy Kerr <jk@ozlabs.org>
Acked-by: Arnd Bergmann <arnd.bergmann@de.ibm.com>
---
arch/powerpc/platforms/cell/spufs/file.c | 40 ++++++++++++------------------
arch/powerpc/platforms/cell/spufs/spufs.h | 2 -
2 files changed, 17 insertions(+), 25 deletions(-)
diff --git a/arch/powerpc/platforms/cell/spufs/file.c b/arch/powerpc/platforms/cell/spufs/file.c
index 6095fb1..4cd34e5 100644
--- a/arch/powerpc/platforms/cell/spufs/file.c
+++ b/arch/powerpc/platforms/cell/spufs/file.c
@@ -1085,9 +1085,8 @@ static void spufs_signal1_type_set(void *data, u64 val)
spu_release(ctx);
}
-static u64 __spufs_signal1_type_get(void *data)
+static u64 __spufs_signal1_type_get(struct spu_context *ctx)
{
- struct spu_context *ctx = data;
return ctx->ops->signal1_type_get(ctx);
}
@@ -1097,7 +1096,7 @@ static u64 spufs_signal1_type_get(void *data)
u64 ret;
spu_acquire(ctx);
- ret = __spufs_signal1_type_get(data);
+ ret = __spufs_signal1_type_get(ctx);
spu_release(ctx);
return ret;
@@ -1114,9 +1113,8 @@ static void spufs_signal2_type_set(void *data, u64 val)
spu_release(ctx);
}
-static u64 __spufs_signal2_type_get(void *data)
+static u64 __spufs_signal2_type_get(struct spu_context *ctx)
{
- struct spu_context *ctx = data;
return ctx->ops->signal2_type_get(ctx);
}
@@ -1126,7 +1124,7 @@ static u64 spufs_signal2_type_get(void *data)
u64 ret;
spu_acquire(ctx);
- ret = __spufs_signal2_type_get(data);
+ ret = __spufs_signal2_type_get(ctx);
spu_release(ctx);
return ret;
@@ -1629,9 +1627,8 @@ static void spufs_decr_set(void *data, u64 val)
spu_release_saved(ctx);
}
-static u64 __spufs_decr_get(void *data)
+static u64 __spufs_decr_get(struct spu_context *ctx)
{
- struct spu_context *ctx = data;
struct spu_lscsa *lscsa = ctx->csa.lscsa;
return lscsa->decr.slot[0];
}
@@ -1641,7 +1638,7 @@ static u64 spufs_decr_get(void *data)
struct spu_context *ctx = data;
u64 ret;
spu_acquire_saved(ctx);
- ret = __spufs_decr_get(data);
+ ret = __spufs_decr_get(ctx);
spu_release_saved(ctx);
return ret;
}
@@ -1659,9 +1656,8 @@ static void spufs_decr_status_set(void *data, u64 val)
spu_release_saved(ctx);
}
-static u64 __spufs_decr_status_get(void *data)
+static u64 __spufs_decr_status_get(struct spu_context *ctx)
{
- struct spu_context *ctx = data;
if (ctx->csa.priv2.mfc_control_RW & MFC_CNTL_DECREMENTER_RUNNING)
return SPU_DECR_STATUS_RUNNING;
else
@@ -1673,7 +1669,7 @@ static u64 spufs_decr_status_get(void *data)
struct spu_context *ctx = data;
u64 ret;
spu_acquire_saved(ctx);
- ret = __spufs_decr_status_get(data);
+ ret = __spufs_decr_status_get(ctx);
spu_release_saved(ctx);
return ret;
}
@@ -1689,9 +1685,8 @@ static void spufs_event_mask_set(void *data, u64 val)
spu_release_saved(ctx);
}
-static u64 __spufs_event_mask_get(void *data)
+static u64 __spufs_event_mask_get(struct spu_context *ctx)
{
- struct spu_context *ctx = data;
struct spu_lscsa *lscsa = ctx->csa.lscsa;
return lscsa->event_mask.slot[0];
}
@@ -1701,16 +1696,15 @@ static u64 spufs_event_mask_get(void *data)
struct spu_context *ctx = data;
u64 ret;
spu_acquire_saved(ctx);
- ret = __spufs_event_mask_get(data);
+ ret = __spufs_event_mask_get(ctx);
spu_release_saved(ctx);
return ret;
}
DEFINE_SIMPLE_ATTRIBUTE(spufs_event_mask_ops, spufs_event_mask_get,
spufs_event_mask_set, "0x%llx\n")
-static u64 __spufs_event_status_get(void *data)
+static u64 __spufs_event_status_get(struct spu_context *ctx)
{
- struct spu_context *ctx = data;
struct spu_state *state = &ctx->csa;
u64 stat;
stat = state->spu_chnlcnt_RW[0];
@@ -1725,7 +1719,7 @@ static u64 spufs_event_status_get(void *data)
u64 ret = 0;
spu_acquire_saved(ctx);
- ret = __spufs_event_status_get(data);
+ ret = __spufs_event_status_get(ctx);
spu_release_saved(ctx);
return ret;
}
@@ -1770,16 +1764,15 @@ static u64 spufs_id_get(void *data)
}
DEFINE_SIMPLE_ATTRIBUTE(spufs_id_ops, spufs_id_get, NULL, "0x%llx\n")
-static u64 __spufs_object_id_get(void *data)
+static u64 __spufs_object_id_get(struct spu_context *ctx)
{
- struct spu_context *ctx = data;
return ctx->object_id;
}
static u64 spufs_object_id_get(void *data)
{
/* FIXME: Should there really be no locking here? */
- return __spufs_object_id_get(data);
+ return __spufs_object_id_get((struct spu_context *)data);
}
static void spufs_object_id_set(void *data, u64 id)
@@ -1791,9 +1784,8 @@ static void spufs_object_id_set(void *data, u64 id)
DEFINE_SIMPLE_ATTRIBUTE(spufs_object_id_ops, spufs_object_id_get,
spufs_object_id_set, "0x%llx\n");
-static u64 __spufs_lslr_get(void *data)
+static u64 __spufs_lslr_get(struct spu_context *ctx)
{
- struct spu_context *ctx = data;
return ctx->csa.priv2.spu_lslr_RW;
}
@@ -1803,7 +1795,7 @@ static u64 spufs_lslr_get(void *data)
u64 ret;
spu_acquire_saved(ctx);
- ret = __spufs_lslr_get(data);
+ ret = __spufs_lslr_get(ctx);
spu_release_saved(ctx);
return ret;
diff --git a/arch/powerpc/platforms/cell/spufs/spufs.h b/arch/powerpc/platforms/cell/spufs/spufs.h
index 3dbffeb..f869a4b 100644
--- a/arch/powerpc/platforms/cell/spufs/spufs.h
+++ b/arch/powerpc/platforms/cell/spufs/spufs.h
@@ -296,7 +296,7 @@ struct spufs_coredump_reader {
char *name;
ssize_t (*read)(struct spu_context *ctx,
char __user *buffer, size_t size, loff_t *pos);
- u64 (*get)(void *data);
+ u64 (*get)(struct spu_context *ctx);
size_t size;
};
extern struct spufs_coredump_reader spufs_coredump_read[];
^ permalink raw reply related
* [PATCH 09/25] cell: remove DEBUG for spu callbacks
From: Jeremy Kerr @ 2007-09-14 6:32 UTC (permalink / raw)
To: linuxppc-dev
In-Reply-To: <1189751574.98527.127994196313.1.gpush@pokey>
We don't want SPE programs to be able to flood the kernel log by
invoking the SPE callback handler, so don't enable DEBUG for
spu_callbacks.c by default.
Signed-off-by: Jeremy Kerr <jk@ozlabs.org>
---
arch/powerpc/platforms/cell/spu_callbacks.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/arch/powerpc/platforms/cell/spu_callbacks.c b/arch/powerpc/platforms/cell/spu_callbacks.c
index ab39e22..dceb8b6 100644
--- a/arch/powerpc/platforms/cell/spu_callbacks.c
+++ b/arch/powerpc/platforms/cell/spu_callbacks.c
@@ -2,7 +2,7 @@
* System call callback functions for SPUs
*/
-#define DEBUG
+#undef DEBUG
#include <linux/kallsyms.h>
#include <linux/module.h>
^ permalink raw reply related
* [PATCH 21/25] spufs: Combine spufs_coredump_calls with spufs_calls
From: Jeremy Kerr @ 2007-09-14 6:32 UTC (permalink / raw)
To: linuxppc-dev
In-Reply-To: <1189751574.98527.127994196313.1.gpush@pokey>
From: Michael Ellerman <michael@ellerman.id.au>
Because spufs might be built as a module, we can't have other parts of the
kernel calling directly into it, we need stub routines that check first if the
module is loaded.
Currently we have two structures which hold callbacks for these stubs, the
syscalls are in spufs_calls and the coredump calls are in spufs_coredump_calls.
In both cases the logic for registering/unregistering is essentially the same,
so we can simplify things by combining the two.
Signed-off-by: Michael Ellerman <michael@ellerman.id.au>
Signed-off-by: Jeremy Kerr <jk@ozlabs.org>
Acked-by: Arnd Bergmann <arnd.bergmann@de.ibm.com>
---
arch/powerpc/platforms/cell/Makefile | 2
arch/powerpc/platforms/cell/spu_coredump.c | 83 ---------------------------
arch/powerpc/platforms/cell/spu_syscalls.c | 30 +++++++++
arch/powerpc/platforms/cell/spufs/coredump.c | 10 ---
arch/powerpc/platforms/cell/spufs/inode.c | 6 -
arch/powerpc/platforms/cell/spufs/spufs.h | 4 +
arch/powerpc/platforms/cell/spufs/syscalls.c | 2
include/asm-powerpc/spu.h | 12 ---
8 files changed, 41 insertions(+), 108 deletions(-)
diff --git a/arch/powerpc/platforms/cell/Makefile b/arch/powerpc/platforms/cell/Makefile
index 40f78e9..61d12f1 100644
--- a/arch/powerpc/platforms/cell/Makefile
+++ b/arch/powerpc/platforms/cell/Makefile
@@ -19,7 +19,7 @@ spu-manage-$(CONFIG_PPC_CELLEB) += spu_manage.o
spu-manage-$(CONFIG_PPC_CELL_NATIVE) += spu_manage.o
obj-$(CONFIG_SPU_BASE) += spu_callbacks.o spu_base.o \
- spu_coredump.o spu_syscalls.o \
+ spu_syscalls.o \
$(spu-priv1-y) \
$(spu-manage-y) \
spufs/
diff --git a/arch/powerpc/platforms/cell/spu_coredump.c b/arch/powerpc/platforms/cell/spu_coredump.c
deleted file mode 100644
index 656a8c5..0000000
--- a/arch/powerpc/platforms/cell/spu_coredump.c
+++ /dev/null
@@ -1,83 +0,0 @@
-/*
- * SPU core dump code
- *
- * (C) Copyright 2006 IBM Corp.
- *
- * Author: Dwayne Grant McConnell <decimal@us.ibm.com>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2, or (at your option)
- * any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- */
-
-#include <linux/file.h>
-#include <linux/module.h>
-#include <linux/syscalls.h>
-
-#include <asm/spu.h>
-
-static struct spu_coredump_calls *spu_coredump_calls;
-static DEFINE_MUTEX(spu_coredump_mutex);
-
-int arch_notes_size(void)
-{
- int ret;
-
- mutex_lock(&spu_coredump_mutex);
-
- if (spu_coredump_calls && try_module_get(spu_coredump_calls->owner)) {
- ret = spu_coredump_calls->arch_notes_size();
- module_put(spu_coredump_calls->owner);
- } else {
- ret = 0;
- }
-
- mutex_unlock(&spu_coredump_mutex);
-
- return ret;
-}
-
-void arch_write_notes(struct file *file)
-{
- mutex_lock(&spu_coredump_mutex);
- if (spu_coredump_calls && try_module_get(spu_coredump_calls->owner)) {
- spu_coredump_calls->arch_write_notes(file);
- module_put(spu_coredump_calls->owner);
- }
- mutex_unlock(&spu_coredump_mutex);
-}
-
-int register_arch_coredump_calls(struct spu_coredump_calls *calls)
-{
- int ret = 0;
-
-
- mutex_lock(&spu_coredump_mutex);
- if (spu_coredump_calls)
- ret = -EBUSY;
- else
- spu_coredump_calls = calls;
- mutex_unlock(&spu_coredump_mutex);
- return ret;
-}
-EXPORT_SYMBOL_GPL(register_arch_coredump_calls);
-
-void unregister_arch_coredump_calls(struct spu_coredump_calls *calls)
-{
- BUG_ON(spu_coredump_calls != calls);
-
- mutex_lock(&spu_coredump_mutex);
- spu_coredump_calls = NULL;
- mutex_unlock(&spu_coredump_mutex);
-}
-EXPORT_SYMBOL_GPL(unregister_arch_coredump_calls);
diff --git a/arch/powerpc/platforms/cell/spu_syscalls.c b/arch/powerpc/platforms/cell/spu_syscalls.c
index 76815c5..cf00251 100644
--- a/arch/powerpc/platforms/cell/spu_syscalls.c
+++ b/arch/powerpc/platforms/cell/spu_syscalls.c
@@ -2,6 +2,7 @@
* SPU file system -- system call stubs
*
* (C) Copyright IBM Deutschland Entwicklung GmbH 2005
+ * (C) Copyright 2006-2007, IBM Corporation
*
* Author: Arnd Bergmann <arndb@de.ibm.com>
*
@@ -108,6 +109,35 @@ asmlinkage long sys_spu_run(int fd, __u32 __user *unpc, __u32 __user *ustatus)
return ret;
}
+int arch_notes_size(void)
+{
+ struct spufs_calls *calls;
+ int ret;
+
+ calls = spufs_calls_get();
+ if (!calls)
+ return 0;
+
+ ret = calls->coredump_extra_notes_size();
+
+ spufs_calls_put(calls);
+
+ return ret;
+}
+
+void arch_write_notes(struct file *file)
+{
+ struct spufs_calls *calls;
+
+ calls = spufs_calls_get();
+ if (!calls)
+ return;
+
+ calls->coredump_extra_notes_write(file);
+
+ spufs_calls_put(calls);
+}
+
int register_spu_syscalls(struct spufs_calls *calls)
{
int ret = 0;
diff --git a/arch/powerpc/platforms/cell/spufs/coredump.c b/arch/powerpc/platforms/cell/spufs/coredump.c
index fc988fd..6c20e44 100644
--- a/arch/powerpc/platforms/cell/spufs/coredump.c
+++ b/arch/powerpc/platforms/cell/spufs/coredump.c
@@ -122,7 +122,7 @@ static struct spu_context *coredump_next_context(int *fd)
return ctx;
}
-static int spufs_arch_notes_size(void)
+int spufs_coredump_extra_notes_size(void)
{
struct spu_context *ctx;
int size = 0, rc, fd;
@@ -185,7 +185,7 @@ out:
free_page((unsigned long)buf);
}
-static void spufs_arch_write_notes(struct file *file)
+void spufs_coredump_extra_notes_write(struct file *file)
{
struct spu_context *ctx;
int fd, j;
@@ -200,9 +200,3 @@ static void spufs_arch_write_notes(struct file *file)
spu_release_saved(ctx);
}
}
-
-struct spu_coredump_calls spufs_coredump_calls = {
- .arch_notes_size = spufs_arch_notes_size,
- .arch_write_notes = spufs_arch_write_notes,
- .owner = THIS_MODULE,
-};
diff --git a/arch/powerpc/platforms/cell/spufs/inode.c b/arch/powerpc/platforms/cell/spufs/inode.c
index e210a4b..1109874 100644
--- a/arch/powerpc/platforms/cell/spufs/inode.c
+++ b/arch/powerpc/platforms/cell/spufs/inode.c
@@ -790,16 +790,11 @@ static int __init spufs_init(void)
ret = register_spu_syscalls(&spufs_calls);
if (ret)
goto out_fs;
- ret = register_arch_coredump_calls(&spufs_coredump_calls);
- if (ret)
- goto out_syscalls;
spufs_init_isolated_loader();
return 0;
-out_syscalls:
- unregister_spu_syscalls(&spufs_calls);
out_fs:
unregister_filesystem(&spufs_type);
out_sched:
@@ -815,7 +810,6 @@ static void __exit spufs_exit(void)
{
spu_sched_exit();
spufs_exit_isolated_loader();
- unregister_arch_coredump_calls(&spufs_coredump_calls);
unregister_spu_syscalls(&spufs_calls);
unregister_filesystem(&spufs_type);
kmem_cache_destroy(spufs_inode_cache);
diff --git a/arch/powerpc/platforms/cell/spufs/spufs.h b/arch/powerpc/platforms/cell/spufs/spufs.h
index f869a4b..c7b4e03 100644
--- a/arch/powerpc/platforms/cell/spufs/spufs.h
+++ b/arch/powerpc/platforms/cell/spufs/spufs.h
@@ -204,6 +204,10 @@ extern struct spufs_calls spufs_calls;
long spufs_run_spu(struct spu_context *ctx, u32 *npc, u32 *status);
long spufs_create(struct nameidata *nd, unsigned int flags,
mode_t mode, struct file *filp);
+/* ELF coredump callbacks for writing SPU ELF notes */
+extern int spufs_coredump_extra_notes_size(void);
+extern void spufs_coredump_extra_notes_write(struct file *file);
+
extern const struct file_operations spufs_context_fops;
/* gang management */
diff --git a/arch/powerpc/platforms/cell/spufs/syscalls.c b/arch/powerpc/platforms/cell/spufs/syscalls.c
index 22b138d..2c34f71 100644
--- a/arch/powerpc/platforms/cell/spufs/syscalls.c
+++ b/arch/powerpc/platforms/cell/spufs/syscalls.c
@@ -84,5 +84,7 @@ static long do_spu_create(const char __user *pathname, unsigned int flags,
struct spufs_calls spufs_calls = {
.create_thread = do_spu_create,
.spu_run = do_spu_run,
+ .coredump_extra_notes_size = spufs_coredump_extra_notes_size,
+ .coredump_extra_notes_write = spufs_coredump_extra_notes_write,
.owner = THIS_MODULE,
};
diff --git a/include/asm-powerpc/spu.h b/include/asm-powerpc/spu.h
index eb1159c..f1b10a1 100644
--- a/include/asm-powerpc/spu.h
+++ b/include/asm-powerpc/spu.h
@@ -244,13 +244,8 @@ struct spufs_calls {
struct file *neighbor);
long (*spu_run)(struct file *filp, __u32 __user *unpc,
__u32 __user *ustatus);
- struct module *owner;
-};
-
-/* coredump calls implemented in spufs */
-struct spu_coredump_calls {
- asmlinkage int (*arch_notes_size)(void);
- asmlinkage void (*arch_write_notes)(struct file *file);
+ int (*coredump_extra_notes_size)(void);
+ void (*coredump_extra_notes_write)(struct file *file);
struct module *owner;
};
@@ -277,9 +272,6 @@ struct spu_coredump_calls {
int register_spu_syscalls(struct spufs_calls *calls);
void unregister_spu_syscalls(struct spufs_calls *calls);
-int register_arch_coredump_calls(struct spu_coredump_calls *calls);
-void unregister_arch_coredump_calls(struct spu_coredump_calls *calls);
-
int spu_add_sysdev_attr(struct sysdev_attribute *attr);
void spu_remove_sysdev_attr(struct sysdev_attribute *attr);
^ permalink raw reply related
* [PATCH 10/25] spusched: fix null pointer dereference in find_victim
From: Jeremy Kerr @ 2007-09-14 6:32 UTC (permalink / raw)
To: linuxppc-dev
In-Reply-To: <1189751574.98527.127994196313.1.gpush@pokey>
From: Christoph Hellwig <hch@lst.de>
find_victim can dereference a NULL pointer when iterating over the list
of victim spus because list_mutex only guarantees spu->ct to be stable,
but of course not to be non-NULL.
Also fix find_victim to not call spu_unbind_context without list_mutex
because that violates the above guarantee.
Signed-off-by: Christoph Hellwig <hch@lst.de>
Signed-off-by: Arnd Bergmann <arnd.bergmann@de.ibm.com>
Signed-off-by: Jeremy Kerr <jk@ozlabs.org>
---
arch/powerpc/platforms/cell/spufs/sched.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/arch/powerpc/platforms/cell/spufs/sched.c b/arch/powerpc/platforms/cell/spufs/sched.c
index 17806e0..4d257b3 100644
--- a/arch/powerpc/platforms/cell/spufs/sched.c
+++ b/arch/powerpc/platforms/cell/spufs/sched.c
@@ -594,7 +594,7 @@ static struct spu *find_victim(struct spu_context *ctx)
list_for_each_entry(spu, &cbe_spu_info[node].spus, cbe_list) {
struct spu_context *tmp = spu->ctx;
- if (tmp->prio > ctx->prio &&
+ if (tmp && tmp->prio > ctx->prio &&
(!victim || tmp->prio > victim->prio))
victim = spu->ctx;
}
@@ -626,9 +626,9 @@ static struct spu *find_victim(struct spu_context *ctx)
mutex_lock(&cbe_spu_info[node].list_mutex);
cbe_spu_info[node].nr_active--;
+ spu_unbind_context(spu, victim);
mutex_unlock(&cbe_spu_info[node].list_mutex);
- spu_unbind_context(spu, victim);
victim->stats.invol_ctx_switch++;
spu->stats.invol_ctx_switch++;
mutex_unlock(&victim->state_mutex);
^ permalink raw reply related
* [PATCH 23/25] spufs: Handle errors in SPU coredump code, and support coredump to a pipe
From: Jeremy Kerr @ 2007-09-14 6:32 UTC (permalink / raw)
To: linuxppc-dev
In-Reply-To: <1189751574.98527.127994196313.1.gpush@pokey>
From: Michael Ellerman <michael@ellerman.id.au>
Rework spufs_coredump_extra_notes_write() to check for and return errors.
If we're coredumping to a pipe we can't trust file->f_pos, we need to
maintain the foffset value passed to us. The cleanest way to do this is
to have the low level write routine increment foffset when we've
successfully written.
Signed-off-by: Michael Ellerman <michael@ellerman.id.au>
Signed-off-by: Jeremy Kerr <jk@ozlabs.org>
---
arch/powerpc/platforms/cell/spu_syscalls.c | 8 --
arch/powerpc/platforms/cell/spufs/coredump.c | 89 ++++++++++++++++++---------
arch/powerpc/platforms/cell/spufs/spufs.h | 2
include/asm-powerpc/spu.h | 2
4 files changed, 67 insertions(+), 34 deletions(-)
diff --git a/arch/powerpc/platforms/cell/spu_syscalls.c b/arch/powerpc/platforms/cell/spu_syscalls.c
index d9b2fd2..0b69107 100644
--- a/arch/powerpc/platforms/cell/spu_syscalls.c
+++ b/arch/powerpc/platforms/cell/spu_syscalls.c
@@ -129,19 +129,17 @@ int elf_coredump_extra_notes_size(void)
int elf_coredump_extra_notes_write(struct file *file, loff_t *foffset)
{
struct spufs_calls *calls;
+ int ret;
calls = spufs_calls_get();
if (!calls)
return 0;
- calls->coredump_extra_notes_write(file);
+ ret = calls->coredump_extra_notes_write(file, foffset);
spufs_calls_put(calls);
- /* Fudge foffset for now */
- *foffset = file->f_pos;
-
- return 0;
+ return ret;
}
int register_spu_syscalls(struct spufs_calls *calls)
diff --git a/arch/powerpc/platforms/cell/spufs/coredump.c b/arch/powerpc/platforms/cell/spufs/coredump.c
index 6c20e44..6b8aef6 100644
--- a/arch/powerpc/platforms/cell/spufs/coredump.c
+++ b/arch/powerpc/platforms/cell/spufs/coredump.c
@@ -51,19 +51,34 @@ static ssize_t do_coredump_read(int num, struct spu_context *ctx, void *buffer,
* These are the only things you should do on a core-file: use only these
* functions to write out all the necessary info.
*/
-static int spufs_dump_write(struct file *file, const void *addr, int nr)
+static int spufs_dump_write(struct file *file, const void *addr, int nr, loff_t *foffset)
{
- return file->f_op->write(file, addr, nr, &file->f_pos) == nr;
+ ssize_t written;
+
+ written = file->f_op->write(file, addr, nr, &file->f_pos);
+ *foffset += written;
+
+ if (written != nr)
+ return -EIO;
+
+ return 0;
}
-static int spufs_dump_seek(struct file *file, loff_t off)
+static int spufs_dump_align(struct file *file, char *buf, loff_t new_off,
+ loff_t *foffset)
{
- if (file->f_op->llseek) {
- if (file->f_op->llseek(file, off, 0) != off)
- return 0;
- } else
- file->f_pos = off;
- return 1;
+ int rc, size;
+
+ size = min((loff_t)PAGE_SIZE, new_off - *foffset);
+ memset(buf, 0, size);
+
+ rc = 0;
+ while (rc == 0 && new_off > *foffset) {
+ size = min((loff_t)PAGE_SIZE, new_off - *foffset);
+ rc = spufs_dump_write(file, buf, size, foffset);
+ }
+
+ return rc;
}
static int spufs_ctx_note_size(struct spu_context *ctx, int dfd)
@@ -141,11 +156,11 @@ int spufs_coredump_extra_notes_size(void)
return size;
}
-static void spufs_arch_write_note(struct spu_context *ctx, int i,
- struct file *file, int dfd)
+static int spufs_arch_write_note(struct spu_context *ctx, int i,
+ struct file *file, int dfd, loff_t *foffset)
{
loff_t pos = 0;
- int sz, rc, total = 0;
+ int sz, rc, nread, total = 0;
const int bufsz = PAGE_SIZE;
char *name;
char fullname[80], *buf;
@@ -153,7 +168,7 @@ static void spufs_arch_write_note(struct spu_context *ctx, int i,
buf = (void *)get_zeroed_page(GFP_KERNEL);
if (!buf)
- return;
+ return -ENOMEM;
name = spufs_coredump_read[i].name;
sz = spufs_coredump_read[i].size;
@@ -163,40 +178,60 @@ static void spufs_arch_write_note(struct spu_context *ctx, int i,
en.n_descsz = sz;
en.n_type = NT_SPU;
- if (!spufs_dump_write(file, &en, sizeof(en)))
+ rc = spufs_dump_write(file, &en, sizeof(en), foffset);
+ if (rc)
goto out;
- if (!spufs_dump_write(file, fullname, en.n_namesz))
+
+ rc = spufs_dump_write(file, fullname, en.n_namesz, foffset);
+ if (rc)
goto out;
- if (!spufs_dump_seek(file, roundup((unsigned long)file->f_pos, 4)))
+
+ rc = spufs_dump_align(file, buf, roundup(*foffset, 4), foffset);
+ if (rc)
goto out;
do {
- rc = do_coredump_read(i, ctx, buf, bufsz, &pos);
- if (rc > 0) {
- if (!spufs_dump_write(file, buf, rc))
+ nread = do_coredump_read(i, ctx, buf, bufsz, &pos);
+ if (nread > 0) {
+ rc = spufs_dump_write(file, buf, nread, foffset);
+ if (rc)
goto out;
- total += rc;
+ total += nread;
}
- } while (rc == bufsz && total < sz);
+ } while (nread == bufsz && total < sz);
+
+ if (nread < 0) {
+ rc = nread;
+ goto out;
+ }
+
+ rc = spufs_dump_align(file, buf, roundup(*foffset - total + sz, 4),
+ foffset);
- spufs_dump_seek(file, roundup((unsigned long)file->f_pos
- - total + sz, 4));
out:
free_page((unsigned long)buf);
+ return rc;
}
-void spufs_coredump_extra_notes_write(struct file *file)
+int spufs_coredump_extra_notes_write(struct file *file, loff_t *foffset)
{
struct spu_context *ctx;
- int fd, j;
+ int fd, j, rc;
fd = 0;
while ((ctx = coredump_next_context(&fd)) != NULL) {
spu_acquire_saved(ctx);
- for (j = 0; spufs_coredump_read[j].name != NULL; j++)
- spufs_arch_write_note(ctx, j, file, fd);
+ for (j = 0; spufs_coredump_read[j].name != NULL; j++) {
+ rc = spufs_arch_write_note(ctx, j, file, fd, foffset);
+ if (rc) {
+ spu_release_saved(ctx);
+ return rc;
+ }
+ }
spu_release_saved(ctx);
}
+
+ return 0;
}
diff --git a/arch/powerpc/platforms/cell/spufs/spufs.h b/arch/powerpc/platforms/cell/spufs/spufs.h
index c7b4e03..ca47b99 100644
--- a/arch/powerpc/platforms/cell/spufs/spufs.h
+++ b/arch/powerpc/platforms/cell/spufs/spufs.h
@@ -206,7 +206,7 @@ long spufs_create(struct nameidata *nd, unsigned int flags,
mode_t mode, struct file *filp);
/* ELF coredump callbacks for writing SPU ELF notes */
extern int spufs_coredump_extra_notes_size(void);
-extern void spufs_coredump_extra_notes_write(struct file *file);
+extern int spufs_coredump_extra_notes_write(struct file *file, loff_t *foffset);
extern const struct file_operations spufs_context_fops;
diff --git a/include/asm-powerpc/spu.h b/include/asm-powerpc/spu.h
index f1b10a1..b1accce 100644
--- a/include/asm-powerpc/spu.h
+++ b/include/asm-powerpc/spu.h
@@ -245,7 +245,7 @@ struct spufs_calls {
long (*spu_run)(struct file *filp, __u32 __user *unpc,
__u32 __user *ustatus);
int (*coredump_extra_notes_size)(void);
- void (*coredump_extra_notes_write)(struct file *file);
+ int (*coredump_extra_notes_write)(struct file *file, loff_t *foffset);
struct module *owner;
};
^ permalink raw reply related
* [PATCH 12/25] spufs: Remove ctx_info and ctx_info_list
From: Jeremy Kerr @ 2007-09-14 6:32 UTC (permalink / raw)
To: linuxppc-dev
In-Reply-To: <1189751574.98527.127994196313.1.gpush@pokey>
From: Michael Ellerman <michael@ellerman.id.au>
Remove the ctx_info struct entirely, and also the ctx_info_list. This fixes
a race where two processes can clobber each other's ctx_info structs.
Instead of using the list, we just repeat the search through the file
descriptor table.
Signed-off-by: Michael Ellerman <michael@ellerman.id.au>
Signed-off-by: Jeremy Kerr <jk@ozlabs.org>
---
arch/powerpc/platforms/cell/spufs/coredump.c | 79 ++++++---------------------
1 file changed, 19 insertions(+), 60 deletions(-)
diff --git a/arch/powerpc/platforms/cell/spufs/coredump.c b/arch/powerpc/platforms/cell/spufs/coredump.c
index 99f8e0b..6663669 100644
--- a/arch/powerpc/platforms/cell/spufs/coredump.c
+++ b/arch/powerpc/platforms/cell/spufs/coredump.c
@@ -31,15 +31,6 @@
#include "spufs.h"
-struct spufs_ctx_info {
- struct list_head list;
- int dfd;
- int memsize; /* in bytes */
- struct spu_context *ctx;
-};
-
-static LIST_HEAD(ctx_info_list);
-
static ssize_t do_coredump_read(int num, struct spu_context *ctx, void __user *buffer,
size_t size, loff_t *off)
{
@@ -73,25 +64,17 @@ static int spufs_dump_seek(struct file *file, loff_t off)
return 1;
}
-static void spufs_fill_memsize(struct spufs_ctx_info *ctx_info)
+static u64 ctx_ls_size(struct spu_context *ctx)
{
- struct spu_context *ctx;
- unsigned long long lslr;
-
- ctx = ctx_info->ctx;
- lslr = ctx->csa.priv2.spu_lslr_RW;
- ctx_info->memsize = lslr + 1;
+ return ctx->csa.priv2.spu_lslr_RW + 1;
}
-static int spufs_ctx_note_size(struct spufs_ctx_info *ctx_info)
+static int spufs_ctx_note_size(struct spu_context *ctx, int dfd)
{
- int dfd, memsize, i, sz, total = 0;
+ int i, sz, total = 0;
char *name;
char fullname[80];
- dfd = ctx_info->dfd;
- memsize = ctx_info->memsize;
-
for (i = 0; spufs_coredump_read[i].name; i++) {
name = spufs_coredump_read[i].name;
sz = spufs_coredump_read[i].size;
@@ -101,7 +84,7 @@ static int spufs_ctx_note_size(struct spufs_ctx_info *ctx_info)
total += sizeof(struct elf_note);
total += roundup(strlen(fullname) + 1, 4);
if (!strcmp(name, "mem"))
- total += roundup(memsize, 4);
+ total += roundup(ctx_ls_size(ctx), 4);
else
total += roundup(sz, 4);
}
@@ -109,25 +92,6 @@ static int spufs_ctx_note_size(struct spufs_ctx_info *ctx_info)
return total;
}
-static int spufs_add_one_context(struct spu_context *ctx, int dfd)
-{
- struct spufs_ctx_info *ctx_info;
- int size;
-
- ctx_info = kzalloc(sizeof(*ctx_info), GFP_KERNEL);
- if (unlikely(!ctx_info))
- return -ENOMEM;
-
- ctx_info->dfd = dfd;
- ctx_info->ctx = ctx;
-
- spufs_fill_memsize(ctx_info);
-
- size = spufs_ctx_note_size(ctx_info);
- list_add(&ctx_info->list, &ctx_info_list);
- return size;
-}
-
/*
* The additional architecture-specific notes for Cell are various
* context files in the spu context.
@@ -171,7 +135,7 @@ static int spufs_arch_notes_size(void)
fd = 0;
while ((ctx = coredump_next_context(&fd)) != NULL) {
- rc = spufs_add_one_context(ctx, fd);
+ rc = spufs_ctx_note_size(ctx, fd);
if (rc < 0)
break;
@@ -181,12 +145,11 @@ static int spufs_arch_notes_size(void)
return size;
}
-static void spufs_arch_write_note(struct spufs_ctx_info *ctx_info, int i,
- struct file *file)
+static void spufs_arch_write_note(struct spu_context *ctx, int i,
+ struct file *file, int dfd)
{
- struct spu_context *ctx;
loff_t pos = 0;
- int sz, dfd, rc, total = 0;
+ int sz, rc, total = 0;
const int bufsz = PAGE_SIZE;
char *name;
char fullname[80], *buf;
@@ -196,18 +159,13 @@ static void spufs_arch_write_note(struct spufs_ctx_info *ctx_info, int i,
if (!buf)
return;
- dfd = ctx_info->dfd;
name = spufs_coredump_read[i].name;
if (!strcmp(name, "mem"))
- sz = ctx_info->memsize;
+ sz = ctx_ls_size(ctx);
else
sz = spufs_coredump_read[i].size;
- ctx = ctx_info->ctx;
- if (!ctx)
- goto out;
-
sprintf(fullname, "SPU/%d/%s", dfd, name);
en.n_namesz = strlen(fullname) + 1;
en.n_descsz = sz;
@@ -237,16 +195,17 @@ out:
static void spufs_arch_write_notes(struct file *file)
{
- int j;
- struct spufs_ctx_info *ctx_info, *next;
+ struct spu_context *ctx;
+ int fd, j;
+
+ fd = 0;
+ while ((ctx = coredump_next_context(&fd)) != NULL) {
+ spu_acquire_saved(ctx);
- list_for_each_entry_safe(ctx_info, next, &ctx_info_list, list) {
- spu_acquire_saved(ctx_info->ctx);
for (j = 0; j < spufs_coredump_num_notes; j++)
- spufs_arch_write_note(ctx_info, j, file);
- spu_release_saved(ctx_info->ctx);
- list_del(&ctx_info->list);
- kfree(ctx_info);
+ spufs_arch_write_note(ctx, j, file, fd);
+
+ spu_release_saved(ctx);
}
}
^ 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